Home | History | Annotate | Download | only in dbregtest
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "PgmImage.h"
     18 #include <cassert>
     19 
     20 using namespace std;
     21 
     22 PgmImage::PgmImage(std::string filename) :
     23 m_w(0),m_h(0),m_colors(255),m_format(PGM_BINARY_GRAYMAP),m_over_allocation(256)
     24 {
     25     if ( !ReadPGM(filename) )
     26         return;
     27 }
     28 
     29 PgmImage::PgmImage(int w, int h, int format) :
     30 m_colors(255),m_w(w),m_h(h),m_format(format),m_over_allocation(256)
     31 {
     32     SetFormat(format);
     33 }
     34 
     35 PgmImage::PgmImage(unsigned char *data, int w, int h) :
     36 m_colors(255),m_w(w),m_h(h),m_format(PGM_BINARY_GRAYMAP),m_over_allocation(256)
     37 {
     38     SetData(data);
     39 }
     40 
     41 PgmImage::PgmImage(std::vector<unsigned char> &data, int w, int h) :
     42 m_colors(255),m_w(w),m_h(h),m_format(PGM_BINARY_GRAYMAP),m_over_allocation(256)
     43 {
     44     if ( data.size() == w*h )
     45         SetData(&data[0]);
     46     else
     47         //throw (std::exception("Size of data is not w*h."));
     48         throw (std::exception());
     49 }
     50 
     51 PgmImage::PgmImage(const PgmImage &im) :
     52 m_colors(255),m_w(0),m_h(0),m_format(PGM_BINARY_GRAYMAP),m_over_allocation(256)
     53 {
     54     DeepCopy(im, *this);
     55 }
     56 
     57 PgmImage& PgmImage::operator= (const PgmImage &im)
     58 {
     59     if (this == &im) return *this;
     60     DeepCopy(im, *this);
     61     return *this;
     62 }
     63 
     64 void PgmImage::DeepCopy(const PgmImage& src, PgmImage& dst)
     65 {
     66     dst.m_data = src.m_data;
     67 
     68     // PGM data
     69     dst.m_w = src.m_w;
     70     dst.m_h = src.m_h;
     71     dst.m_format = src.m_format;
     72     dst.m_colors = src.m_colors;
     73 
     74     dst.m_comment = src.m_comment;
     75     SetupRowPointers();
     76 }
     77 
     78 PgmImage::~PgmImage()
     79 {
     80 
     81 }
     82 
     83 void PgmImage::SetFormat(int format)
     84 {
     85     m_format = format;
     86 
     87     switch (format)
     88     {
     89     case PGM_BINARY_GRAYMAP:
     90         m_data.resize(m_w*m_h+m_over_allocation);
     91         break;
     92     case PGM_BINARY_PIXMAP:
     93         m_data.resize(m_w*m_h*3+m_over_allocation);
     94         break;
     95     default:
     96         return;
     97         break;
     98     }
     99     SetupRowPointers();
    100 }
    101 
    102 void PgmImage::SetData(const unsigned char * data)
    103 {
    104     m_data.resize(m_w*m_h+m_over_allocation);
    105     memcpy(&m_data[0],data,m_w*m_h);
    106     SetupRowPointers();
    107 }
    108 
    109 bool PgmImage::ReadPGM(const std::string filename)
    110 {
    111     ifstream in(filename.c_str(),std::ios::in | std::ios::binary);
    112     if ( !in.is_open() )
    113         return false;
    114 
    115     // read the header:
    116     string format_header,size_header,colors_header;
    117 
    118     getline(in,format_header);
    119     stringstream s;
    120     s << format_header;
    121 
    122     s >> format_header >> m_w >> m_h >> m_colors;
    123     s.clear();
    124 
    125     if ( m_w == 0 )
    126     {
    127         while ( in.peek() == '#' )
    128             getline(in,m_comment);
    129 
    130         getline(in,size_header);
    131 
    132         while ( in.peek() == '#' )
    133             getline(in,m_comment);
    134 
    135             m_colors = 0;
    136 
    137         // parse header
    138         s << size_header;
    139         s >> m_w >> m_h >> m_colors;
    140         s.clear();
    141 
    142         if ( m_colors == 0 )
    143         {
    144             getline(in,colors_header);
    145             s << colors_header;
    146             s >> m_colors;
    147         }
    148     }
    149 
    150     if ( format_header == "P5" )
    151         m_format = PGM_BINARY_GRAYMAP;
    152     else if (format_header == "P6" )
    153         m_format = PGM_BINARY_PIXMAP;
    154     else
    155         m_format = PGM_FORMAT_INVALID;
    156 
    157     switch(m_format)
    158     {
    159     case(PGM_BINARY_GRAYMAP):
    160         m_data.resize(m_w*m_h+m_over_allocation);
    161         in.read((char *)(&m_data[0]),m_data.size());
    162         break;
    163     case(PGM_BINARY_PIXMAP):
    164         m_data.resize(m_w*m_h*3+m_over_allocation);
    165         in.read((char *)(&m_data[0]),m_data.size());
    166         break;
    167     default:
    168         return false;
    169         break;
    170     }
    171     in.close();
    172 
    173     SetupRowPointers();
    174 
    175     return true;
    176 }
    177 
    178 bool PgmImage::WritePGM(const std::string filename, const std::string comment)
    179 {
    180     string format_header;
    181 
    182     switch(m_format)
    183     {
    184     case PGM_BINARY_GRAYMAP:
    185         format_header = "P5\n";
    186         break;
    187     case PGM_BINARY_PIXMAP:
    188         format_header = "P6\n";
    189         break;
    190     default:
    191         return false;
    192         break;
    193     }
    194 
    195     ofstream out(filename.c_str(),std::ios::out |ios::binary);
    196     out << format_header << "# " << comment << '\n' << m_w << " " << m_h << '\n' << m_colors << '\n';
    197 
    198     out.write((char *)(&m_data[0]), m_data.size());
    199 
    200     out.close();
    201 
    202     return true;
    203 }
    204 
    205 void PgmImage::SetupRowPointers()
    206 {
    207     int i;
    208     m_rows.resize(m_h);
    209 
    210     switch (m_format)
    211     {
    212     case PGM_BINARY_GRAYMAP:
    213         for(i=0;i<m_h;i++)
    214         {
    215             m_rows[i]=&m_data[m_w*i];
    216         }
    217         break;
    218     case PGM_BINARY_PIXMAP:
    219         for(i=0;i<m_h;i++)
    220         {
    221             m_rows[i]=&m_data[(m_w*3)*i];
    222         }
    223         break;
    224     }
    225 }
    226 
    227 void PgmImage::ConvertToGray()
    228 {
    229     if ( m_format != PGM_BINARY_PIXMAP ) return;
    230 
    231     // Y = 0.3*R + 0.59*G + 0.11*B;
    232     for ( int i = 0; i < m_w*m_h; ++i )
    233         m_data[i] = (unsigned char)(0.3*m_data[3*i]+0.59*m_data[3*i+1]+0.11*m_data[3*i+2]);
    234 
    235     m_data.resize(m_w*m_h+m_over_allocation);
    236     m_format = PGM_BINARY_GRAYMAP;
    237 
    238     SetupRowPointers();
    239 }
    240 
    241 std::ostream& operator<< (std::ostream& o, const PgmImage& im)
    242 {
    243     o << "PGM Image Info:\n";
    244     o << "Size: " << im.m_w << " x " << im.m_h << "\n";
    245     o << "Comment: " << im.m_comment << "\n";
    246     switch (im.m_format)
    247     {
    248     case PgmImage::PGM_BINARY_PIXMAP:
    249         o << "Format: RGB binary pixmap";
    250         break;
    251     case PgmImage::PGM_BINARY_GRAYMAP:
    252         o << "Format: PPM binary graymap";
    253         break;
    254     default:
    255         o << "Format: Invalid";
    256         break;
    257     }
    258     o << endl;
    259     return o;
    260 }
    261