00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef IMAGE_H_HAS_BEEN_INCLUDED
00027 #define IMAGE_H_HAS_BEEN_INCLUDED
00028
00029 #define OUTSIDE_GLUE_CORE
00030
00031 #include "std/config.H"
00032 #include <math.h>
00033 #include "std/list.H"
00034 #include "std/strings.H"
00035 #include "mlib/point2i.H"
00036
00037 namespace InSpace {
00038
00039
00040
00041
00042 inline unsigned int
00043 getPower2Size(int n)
00044 {
00045 return (1 << ((n>0) ? (int)ceil(log((double) n)/log(2.0)) : 0));
00046 }
00047
00048 typedef unsigned int uint;
00049 typedef unsigned char uchar;
00050
00051 typedef const class Image cImage;
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 class Image {
00062 protected:
00063 uint _width;
00064 uint _height;
00065 uint _bpp;
00066 uchar* _data;
00067 bool _no_delete;
00068
00069 enum { PNG_BYTES_TO_CHECK = 8 };
00070 FILE* open_png(char* file);
00071
00072 str_ptr _file;
00073
00074 public:
00075 Image() : _width(0), _height(0), _bpp(1), _data(0), _no_delete(0) {}
00076 Image(Cstr_ptr& file) :
00077 _width(0),
00078 _height(0),
00079 _bpp(1),
00080 _data(0),
00081 _no_delete(0)
00082 {
00083 if (file)
00084 load_file(file);
00085 }
00086 Image(cImage &img) { *this = img; }
00087 Image(uint w, uint h, uint bpp, uchar* data, bool nd=1) {
00088 set(w,h,bpp,data,nd);
00089 }
00090 Image(uint w, uint h, uint bpp) :
00091 _width(0), _height(0), _bpp(1), _data(0), _no_delete(0) {
00092 resize(w,h,bpp);
00093 }
00094
00095 void operator=(const Image &img) {
00096 if (img._file) {
00097 _data = 0; clear();
00098 load_file(img._file);
00099 } else {
00100 set(img._width, img._height, img._bpp, img.copy(), true);
00101 }
00102 }
00103
00104 void set(int w, int h, uint bpp, uchar* data, bool nd=1) {
00105 if (bpp < 1 || bpp > 4) {
00106 err_msg("Image::Image: %d bytes/pixel not supported", bpp);
00107 clear();
00108 } else {
00109 clear();
00110 _width = w;
00111 _height = h;
00112 _bpp = bpp;
00113 _data = data;
00114 _no_delete = nd;
00115 }
00116 }
00117
00118 void clear() {
00119 if (!_no_delete)
00120 delete [] _data;
00121 _width = _height = 0;
00122 _bpp = 1;
00123 _data = 0;
00124 _no_delete = 0;
00125 _file = str_ptr::null_str();
00126 }
00127
00128 int resize(uint w, uint h, uint b) {
00129
00130
00131
00132
00133
00134
00135 if (_width != w || _height != h || _bpp != b) {
00136 _width = w;
00137 _height = h;
00138 _bpp = b;
00139 if (!_no_delete)
00140 delete [] _data;
00141 _data = 0;
00142 _no_delete = 0;
00143 if ((_data = new uchar [ size() ]) == 0) {
00144 err_ret("Image::resize: can't allocate data");
00145 return 0;
00146 }
00147 }
00148 return 1;
00149 }
00150
00151 int copy_tile(const Image& tile, uint i, uint j);
00152
00153 virtual ~Image() { clear(); }
00154
00155
00156 int width() const { return _width; }
00157 int height() const { return _height; }
00158 uint bpp() const { return _bpp; }
00159 int size() const { return _width*_height*_bpp; }
00160 int row_size() const { return _width*_bpp; }
00161 point2i dims() const { return point2i(_width,_height); }
00162 uchar* data() const { return _data; }
00163 uchar* row(int k) const { return _data + k*row_size(); }
00164 Cstr_ptr &file() const { return _file;}
00165 uchar* copy() const;
00166
00167 bool empty() const { return !(_width && _height && _bpp && _data); }
00168
00169 void expand_power2();
00170 int resize_rows_mult_4();
00171 int load_file(Cstr_ptr &file);
00172
00173 int read_png(Cstr_ptr &file);
00174 int write_png(char* file) const;
00175
00176 int read_pnm (Cstr_ptr &file);
00177 int read_pnm (istream &in);
00178 int read_pgm (istream& in, bool ascii);
00179 int read_ppm (istream& in, bool ascii);
00180 int write_pnm(char* file, bool ascii=false) const;
00181 int write_pnm(ostream &os, bool ascii) const;
00182
00183 static int write_png(int w, int h, uint bpp, uchar* data, Cstr_ptr& file) {
00184 Image img(w,h,bpp,data,1);
00185 return img.write_png(**file);
00186 }
00187 friend ostream & operator<<(ostream &os, cImage &img);
00188 friend istream & operator>>(istream &is, Image &img);
00189 };
00190
00191
00192 }
00193 #endif // IMAGE_H_HAS_BEEN_INCLUDED
00194