Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

image.H

Go to the documentation of this file.
00001 /**********************************************************************
00002  * image.H
00003  **********************************************************************/
00004 #ifndef IMAGE_H_HAS_BEEN_INCLUDED
00005 #define IMAGE_H_HAS_BEEN_INCLUDED
00006 
00007 #include "std/fstream.H"
00008 #include <cmath>
00009 #include "std/support.H"
00010 #include "mlib/points.H"
00011 #include "mlib/point2i.H"
00012 
00013 //
00014 //  getPower2Size - returns smallest power of two that is >= size
00015 //
00016 inline unsigned int
00017 getPower2Size(int n)
00018 {
00019    return (1 << ((n>0) ? (int)ceil(log((double) n)/log(2.0)) : 0));
00020 }
00021 
00022 typedef unsigned int  uint;
00023 typedef unsigned char uchar;
00024 
00025 /**********************************************************************
00026  * Image:
00027  *
00028  *    Contains an image stored bottom-up (the first row in the image is
00029  *    the row that appears at the bottom of the image) that can be read or
00030  *    written in pnm or png format
00031  *    
00032  **********************************************************************/
00033 class Image {
00034  protected:
00035    uint         _width;         // width
00036    uint         _height;        // height
00037    uint         _bpp;           // bytes per pixel
00038    uchar*       _data;          // pixel data
00039    bool         _no_delete;
00040 
00041    enum { PNG_BYTES_TO_CHECK = 8 };
00042    FILE* open_png(char* file);
00043 
00044  public:
00045    Image() : _width(0), _height(0), _bpp(0), _data(0), _no_delete(0) {}
00046    Image(Cstr_ptr& file) :
00047       _width(0),
00048       _height(0),
00049       _bpp(0),
00050       _data(0),
00051       _no_delete(false) {
00052       if (file)
00053          load_file(**file);
00054    }
00055    Image(uint w, uint h, uint bpp, uchar* data, bool nd=1) {
00056       set(w,h,bpp,data,nd);
00057    }
00058    Image(uint w, uint h, uint bpp) :
00059       _width(0), _height(0), _bpp(0), _data(0), _no_delete(false) {
00060       resize(w,h,bpp);
00061    }
00062    virtual ~Image() { clear(); }
00063 
00064    void set(int w, int h, uint bpp, uchar* data, bool nd=1) {
00065       if (bpp < 1 || bpp > 4) {
00066          err_msg("Image::Image: %d bytes/pixel not supported", bpp);
00067       } else {
00068          clear();
00069          _width = w;
00070          _height = h;
00071          _bpp = bpp;
00072          _data = data;
00073          _no_delete = nd;
00074       }
00075    }
00076 
00077    void freedata() {
00078       if (!_no_delete) {
00079          delete [] _data;
00080       }
00081       _data = 0;
00082    }
00083    
00084    void clear() {
00085       freedata();
00086       _width = _height = _bpp = 0;
00087       _no_delete = 0;
00088    }
00089 
00090    bool resize(uint w, uint h, uint b) {
00091       // if current size is different from
00092       // desired size:
00093       //   let go current data (if any)
00094       //   set new width, height and bpp
00095       //   allocate new data
00096       //   but don't initialize it
00097       if (_width != w || _height != h || _bpp != b) {
00098          _width = w;
00099          _height = h;
00100          _bpp = b;
00101          if (!_no_delete)
00102             delete [] _data;
00103          _data = 0;
00104          _no_delete = 0;
00105          if ((_data = new uchar [ size() ]) == 0) {
00106             err_ret("Image::resize: can't allocate data");
00107             return 0;
00108          }
00109       }
00110       return 1;
00111    }
00112    bool resize(uint w, uint h) { return resize(w,h,_bpp); }
00113 
00114    int copy_tile(const Image& tile, uint i, uint j);
00115 
00116    // accessors:
00117    uint      width()    const { return _width; }
00118    uint      height()   const { return _height; }
00119    uint      bpp()      const { return _bpp; }
00120    uint      size()     const { return _width*_height*_bpp; }
00121    uint      row_size() const { return _width*_bpp; }
00122    mlib::Point2i   dims()     const { return mlib::Point2i(_width,_height); }
00123    uchar*    data()     const { return _data; }
00124    uchar*    row(int k) const { return _data + k*row_size(); }
00125    uchar*    copy();
00126 
00127    uchar pixel(uint x, uint y) const {
00128       if (x >= _width || y >= _height)
00129          return 0;
00130       return row(y)[x * _bpp];
00131    }
00132    uint pixel_rgba(uint x, uint y) const;   
00133    uint pixel_r(uint x, uint y) const;
00134    uint pixel_g(uint x, uint y) const;
00135    uint pixel_b(uint x, uint y) const;      
00136    uint pixel_a(uint x, uint y) const;
00137 
00138    bool empty() const { return !(_width && _height && _bpp && _data); }
00139 
00140    // expand the image so dimensions are each a power of 2.
00141    // return true if anything changed:
00142    bool expand_power2();
00143 
00144    int  resize_rows_mult_4();
00145    int  load_file(char* file);
00146    int  read_png(char* file);
00147    int  read_png(FILE* fp);
00148    int  write_png(char* file) const;
00149 
00150    int  read_pnm(char* file);
00151    int  read_pgm(istream& in, bool ascii);
00152    int  read_ppm(istream& in, bool ascii);
00153    int  write_pnm(char* file) const;
00154 
00155    static int write_png(int w, int h, uint bpp, uchar* data, Cstr_ptr& file) {
00156       Image img(w,h,bpp,data,1);
00157       return img.write_png(**file);
00158    }
00159 };
00160 
00161 #endif  // IMAGE_H_HAS_BEEN_INCLUDED
00162 
00163 /* end of file image.H */

Generated on Mon Sep 18 11:39:31 2006 for jot by  doxygen 1.4.4