1e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen/*
2e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * Copyright (C) 2011 The Android Open Source Project
3e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen *
4e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * Licensed under the Apache License, Version 2.0 (the "License");
5e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * you may not use this file except in compliance with the License.
6e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * You may obtain a copy of the License at
7e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen *
8e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen *      http://www.apache.org/licenses/LICENSE-2.0
9e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen *
10e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * Unless required by applicable law or agreed to in writing, software
11e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * distributed under the License is distributed on an "AS IS" BASIS,
12e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * See the License for the specific language governing permissions and
14e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * limitations under the License.
15e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen */
16e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
17e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#pragma once
18e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
19e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#include <vector>
20e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#include <iostream>
21e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#include <fstream>
22e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#include <sstream>
23e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen#include <memory.h>
24e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
25e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen/*!
26e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen * Simple class to manipulate PGM/PPM images. Not suitable for heavy lifting.
27e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen */
28e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenclass PgmImage
29e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen{
30e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    friend std::ostream& operator<< (std::ostream& o, const PgmImage& im);
31e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenpublic:
32e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    enum {PGM_BINARY_GRAYMAP,PGM_BINARY_PIXMAP,PGM_FORMAT_INVALID};
33e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    /*!
34e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    * Constructor from a PGM file name.
35e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    */
36e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    PgmImage(std::string filename);
37e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    /*!
38e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    * Constructor to allocate an image of given size and type.
39e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    */
40e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    PgmImage(int w, int h, int format = PGM_BINARY_GRAYMAP);
41e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    /*!
42e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    * Constructor to allocate an image of given size and copy the data in.
43e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    */
44e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    PgmImage(unsigned char *data, int w, int h);
45e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    /*!
46e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    * Constructor to allocate an image of given size and copy the data in.
47e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    */
48e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    PgmImage(std::vector<unsigned char> &data, int w, int h);
49e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
50e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    PgmImage(const PgmImage &im);
51e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
52e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    PgmImage& operator= (const PgmImage &im);
53e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    ~PgmImage();
54e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
55e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    int GetHeight() const { return m_h; }
56e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    int GetWidth() const { return m_w; }
57e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
58e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    //! Copy pixels from data pointer
59e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    void SetData(const unsigned char * data);
60e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
61e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    //! Get a data pointer to unaligned memory area
62e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    unsigned char * GetDataPointer() { if ( m_data.size() > 0 ) return &m_data[0]; else return NULL; }
63e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    unsigned char ** GetRowPointers() { if ( m_rows.size() == m_h ) return &m_rows[0]; else return NULL; }
64e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
65e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    //! Read a PGM file from disk
66e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    bool ReadPGM(const std::string filename);
67e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    //! Write a PGM file to disk
68e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    bool WritePGM(const std::string filename, const std::string comment="");
69e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
70e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    //! Get image format (returns PGM_BINARY_GRAYMAP, PGM_BINARY_PIXMAP or PGM_FORMAT_INVALID)
71e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    int GetFormat() const { return m_format; }
72e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
73e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    //! Set image format (returns PGM_BINARY_GRAYMAP, PGM_BINARY_PIXMAP). Image data becomes invalid.
74e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    void SetFormat(int format);
75e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
76e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    //! If the image is PGM_BINARY_PIXMAP, convert it to PGM_BINARY_GRAYMAP via Y = 0.3*R + 0.59*G + 0.11*B.
77e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    void ConvertToGray();
78e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenprotected:
79e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    // Generic functions:
80e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    void DeepCopy(const PgmImage& src, PgmImage& dst);
81e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    void SetupRowPointers();
82e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
83e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    // PGM data
84e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    int m_w;
85e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    int m_h;
86e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    int m_format;
87e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    int m_colors;
88e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    int m_over_allocation;
89e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    std::vector<unsigned char> m_data;
90e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    std::string m_comment;
91e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
92e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen    std::vector<unsigned char *> m_rows;
93e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen};
94e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chen
95e295e32b68cf04f0d99138bf4a6d25555f3aef99Wei-Ta Chenstd::ostream& operator<< (std::ostream& o, const PgmImage& im);
96