Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef __IMAGE_H__
00019 #define __IMAGE_H__
00020
00021 #ifdef _WIN32
00022 #ifndef WIN32_LEAN_AND_MEAN
00023 #define WIN32_LEAN_AND_MEAN
00024 #endif // WIN32_LEAN_AND_MEAN
00025 #include <windows.h>
00026 #endif // _WIN32
00027
00028 #include <GL/gl.h>
00029 #include <stdexcept>
00030 #include <iostream>
00031 #include <fstream>
00032 #include <string>
00033 #include <csetjmp>
00034
00035 #include <string.h>
00036
00037 extern "C" {
00038 #include <jpeglib.h>
00039 }
00040
00041 using std::cout;
00042 using std::endl;
00043 using std::string;
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 class ImageException : public std::runtime_error
00077 {
00078 public:
00079
00080 ImageException (const string &error)
00081 : std::runtime_error (error) { }
00082 ImageException (const string &error, const string &filename)
00083 : std::runtime_error (error), _which (filename) { }
00084 virtual ~ImageException () throw () { }
00085
00086 public:
00087
00088 virtual const char *which () const throw () {
00089 return _which.c_str ();
00090 }
00091
00092 private:
00093
00094 string _which;
00095 };
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 class ImageBuffer
00106 {
00107 public:
00108
00109 ImageBuffer (const string &filename);
00110
00111 ImageBuffer (const ImageBuffer &that)
00112 : _filename (that._filename), _data (NULL), _length (that._length)
00113 {
00114 _data = new GLubyte[_length];
00115 memcpy (_data, that._data, _length);
00116 }
00117
00118 ~ImageBuffer ();
00119
00120 private:
00121
00122 ImageBuffer ();
00123
00124 public:
00125
00126 const string &filename () const { return _filename; }
00127 const GLubyte *data () const { return _data; }
00128 size_t length () const { return _length; }
00129
00130 ImageBuffer &operator= (const ImageBuffer &rhs)
00131 {
00132 this->~ImageBuffer ();
00133 new (this) ImageBuffer (rhs);
00134 return *this;
00135 }
00136
00137 private:
00138
00139 string _filename;
00140
00141 GLubyte *_data;
00142 size_t _length;
00143 };
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 class Image
00154 {
00155 protected:
00156
00157 Image ()
00158 : _width (0), _height (0), _numMipmaps (0),
00159 _format (0), _components (0), _pixels (NULL),
00160 _standardCoordSystem (true) { }
00161
00162 private:
00163
00164 Image (const Image &img);
00165
00166 public:
00167
00168 Image (const string &name, GLsizei w, GLsizei h, GLint numMipMaps,
00169 GLenum format, GLint components, const GLubyte *pixels,
00170 bool stdCoordSystem);
00171
00172 virtual ~Image();
00173
00174 public:
00175 bool isPowerOfTwo () const;
00176
00177
00178 GLsizei width () const { return _width; }
00179 GLsizei height () const { return _height; }
00180 GLint numMipmaps () const { return _numMipmaps; }
00181 GLenum format () const { return _format; }
00182 GLint components () const { return _components; }
00183 const GLubyte *pixels () const { return _pixels; }
00184 const string &name () const { return _name; }
00185 bool stdCoordSystem () const { return _standardCoordSystem; }
00186
00187 protected:
00188
00189 GLsizei _width;
00190 GLsizei _height;
00191 GLint _numMipmaps;
00192
00193
00194
00195 GLenum _format;
00196 GLint _components;
00197
00198
00199 GLubyte *_pixels;
00200
00201 string _name;
00202
00203
00204
00205 bool _standardCoordSystem;
00206 };
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 class ImageTGA : public Image
00219 {
00220 public:
00221
00222 ImageTGA (const ImageBuffer &ibuff);
00223
00224 private:
00225
00226 void getTextureInfo ();
00227
00228 void readTGA8bits (const GLubyte *data, const GLubyte *colormap);
00229 void readTGA16bits (const GLubyte *data);
00230 void readTGA24bits (const GLubyte *data);
00231 void readTGA32bits (const GLubyte *data);
00232 void readTGAgray8bits (const GLubyte *data);
00233 void readTGAgray16bits (const GLubyte *data);
00234
00235 void readTGA8bitsRLE (const GLubyte *data, const GLubyte *colormap);
00236 void readTGA16bitsRLE (const GLubyte *data);
00237 void readTGA24bitsRLE (const GLubyte *data);
00238 void readTGA32bitsRLE (const GLubyte *data);
00239 void readTGAgray8bitsRLE (const GLubyte *data);
00240 void readTGAgray16bitsRLE (const GLubyte *data);
00241
00242 private:
00243
00244 #pragma pack(push, 1)
00245
00246 struct TGA_Header
00247 {
00248 GLubyte id_lenght;
00249 GLubyte colormap_type;
00250 GLubyte image_type;
00251
00252 short cm_first_entry;
00253 short cm_length;
00254 GLubyte cm_size;
00255
00256 short x_origin;
00257 short y_origin;
00258
00259 short width;
00260 short height;
00261
00262 GLubyte pixel_depth;
00263 GLubyte image_descriptor;
00264
00265 };
00266 #pragma pack(pop)
00267
00268 const TGA_Header *_header;
00269
00270
00271
00272
00273
00274
00275
00276 static int rgbaTable[4];
00277 static int bgraTable[4];
00278 };
00279
00280
00281
00282
00283
00284
00285
00286
00287 class ImageJPEG : public Image
00288 {
00289 public:
00290
00291 ImageJPEG (const ImageBuffer &ibuff);
00292
00293 private:
00294
00295 struct my_error_mgr
00296 {
00297 jpeg_error_mgr pub;
00298 jmp_buf setjmp_buffer;
00299
00300 string errorMsg;
00301 };
00302
00303 typedef my_error_mgr *my_error_ptr;
00304
00305 private:
00306
00307 static void initSource_callback (j_decompress_ptr cinfo);
00308 static boolean fillInputBuffer_callback (j_decompress_ptr cinfo);
00309 static void skipInputData_callback (j_decompress_ptr cinfo,
00310 long num_bytes);
00311 static void termSource_callback (j_decompress_ptr cinfo);
00312
00313
00314 static void errorExit_callback (j_common_ptr cinfo);
00315 static void outputMessage_callback (j_common_ptr cinfo);
00316 };
00317
00318
00319
00320
00321
00322
00323
00324
00325 class ImageFactory
00326 {
00327 public:
00328
00329 static Image *createImage (const ImageBuffer &ibuff)
00330 {
00331 string ext;
00332 Image *result;
00333
00334
00335 const string &filename = ibuff.filename ();
00336 ext.assign (filename, filename.find_last_of ('.') + 1, string::npos);
00337
00338 if (ext.compare ("tga") == 0)
00339 {
00340 result = new ImageTGA (ibuff);
00341 }
00342 else if (ext.compare ("jpg") == 0)
00343 {
00344 result = new ImageJPEG (ibuff);
00345 }
00346 else
00347 {
00348 throw ImageException ("Unhandled image file format", filename);
00349 }
00350
00351 return result;
00352 }
00353 };
00354
00355 #endif // __IMAGE_H__