Image.cpp

Go to the documentation of this file.
00001 /* -*- c++ -*- */
00002 /////////////////////////////////////////////////////////////////////////////
00003 //
00004 // Image.cpp -- Copyright (c) 2006-2007 David Henry
00005 // last modification: may. 7, 2007
00006 //
00007 // This code is licenced under the MIT license.
00008 //
00009 // This software is provided "as is" without express or implied
00010 // warranties. You may freely copy and compile this source into
00011 // applications you distribute provided that the copyright text
00012 // below is included in the resulting source code.
00013 //
00014 // Implementation of image loader classes for TGA and JPEG image formats.
00015 //
00016 /////////////////////////////////////////////////////////////////////////////
00017 
00018 #include <GL/glew.h>
00019 #include "Image.h"
00020 
00021 
00022 /////////////////////////////////////////////////////////////////////////////
00023 //
00024 // class ImageBuffer implementation.
00025 //
00026 /////////////////////////////////////////////////////////////////////////////
00027 
00028 // --------------------------------------------------------------------------
00029 // ImageBuffer::ImageBuffer
00030 //
00031 // Constructor.  Load a file into memory buffer.
00032 // --------------------------------------------------------------------------
00033 
00034 ImageBuffer::ImageBuffer (const string &filename)
00035   : _filename (filename), _data (NULL), _length (0)
00036 {
00037   // Open file
00038   std::ifstream ifs (filename.c_str(), std::ios::in | std::ios::binary);
00039 
00040   if (ifs.fail ())
00041     throw ImageException ("Couldn't open file", filename);
00042 
00043   // Get file length
00044   ifs.seekg (0, std::ios::end);
00045   _length = ifs.tellg ();
00046   ifs.seekg (0, std::ios::beg);
00047 
00048   try
00049     {
00050       // Allocate memory for holding file data
00051       _data = new GLubyte[_length];
00052 
00053       // Read whole file data
00054       ifs.read (reinterpret_cast<char *> (_data), _length);
00055       ifs.close ();
00056     }
00057   catch (...)
00058     {
00059       delete [] _data;
00060       throw;
00061     }
00062 }
00063 
00064 
00065 // --------------------------------------------------------------------------
00066 // ImageBuffer::~ImageBuffer
00067 //
00068 // Destructor.  Free memory buffer.
00069 // --------------------------------------------------------------------------
00070 
00071 ImageBuffer::~ImageBuffer ()
00072 {
00073   delete [] _data;
00074   _data = NULL;
00075 }
00076 
00077 
00078 /////////////////////////////////////////////////////////////////////////////
00079 //
00080 // class Image implementation.
00081 //
00082 /////////////////////////////////////////////////////////////////////////////
00083 
00084 // --------------------------------------------------------------------------
00085 // Image::Image
00086 //
00087 // Constructors.  Create an image from a pixel buffer.  It allows to
00088 // create an image from an other source of data than an ImageBuffer.
00089 // This is also the copy constructor to use if you want pixel data
00090 // to be copied, since the Image(const Image&) constructor is protected.
00091 // --------------------------------------------------------------------------
00092 
00093 Image::Image (const string &name, GLsizei w, GLsizei h, GLint numMipMaps,
00094               GLenum format, GLint components, const GLubyte *pixels,
00095               bool stdCoordSystem)
00096   : _width (w), _height (h), _numMipmaps (numMipMaps),
00097     _format (format), _components (components), _name (name),
00098     _standardCoordSystem (stdCoordSystem)
00099 {
00100   // NOTE: pixels should be a valid pointer. w, h and components
00101   // have to be non-zero positive values.
00102 
00103   long size = _width * _height * _components;
00104 
00105   if (size <= 0)
00106     throw std::invalid_argument
00107       ("Image::Image: Invalid width, height or component value");
00108 
00109   if (!pixels)
00110     throw std::invalid_argument
00111       ("Image::Image: Invalid pixel data source");
00112 
00113   // allocate memory for pixel data
00114   _pixels = new GLubyte[size];
00115 
00116   // Copy pixel data from buffer
00117   memcpy (_pixels, pixels, size);
00118 }
00119 
00120 
00121 // --------------------------------------------------------------------------
00122 // Image::~Image
00123 //
00124 // Destructor.  Delete all memory allocated for this object, i.e. pixel
00125 // data.
00126 // --------------------------------------------------------------------------
00127 
00128 Image::~Image ()
00129 {
00130   delete [] _pixels;
00131   _pixels = NULL;
00132 }
00133 
00134 
00135 // --------------------------------------------------------------------------
00136 // Image::isPowerOfTwo
00137 //
00138 // Check if the image dimensions are powers of two.
00139 // --------------------------------------------------------------------------
00140 
00141 bool
00142 Image::isPowerOfTwo () const
00143 {
00144   GLsizei m;
00145   for (m = 1; m < _width; m *= 2)
00146     ;
00147 
00148   if (m != _width)
00149     return false;
00150 
00151   for (m = 1; m < _height; m *= 2)
00152     ;
00153 
00154   if (m != _height)
00155     return false;
00156 
00157   return true;
00158 }
00159 
00160 
00161 /////////////////////////////////////////////////////////////////////////////
00162 //
00163 // class ImageTGA implementation.
00164 //
00165 /////////////////////////////////////////////////////////////////////////////
00166 
00167 // Pixel's component table access
00168 int ImageTGA::rgbaTable[4] = { 2, 1, 0, 3 };
00169 int ImageTGA::bgraTable[4] = { 0, 1, 2, 3 };
00170 
00171 
00172 // --------------------------------------------------------------------------
00173 // ImageTGA::ImageTGA
00174 //
00175 // Constructor.  Read a TGA image from memory.
00176 // --------------------------------------------------------------------------
00177 
00178 ImageTGA::ImageTGA (const ImageBuffer &ibuff)
00179   : _header (NULL)
00180 {
00181   const GLubyte *colormap = NULL;
00182   const GLubyte *data_ptr;
00183 
00184   try
00185     {
00186       _name = ibuff.filename ();
00187       data_ptr = ibuff.data ();
00188       _standardCoordSystem = true;
00189 
00190       // Read TGA header
00191       _header = reinterpret_cast<const TGA_Header *>(data_ptr);
00192       data_ptr += sizeof (TGA_Header) + _header->id_lenght;
00193 
00194       // Get image information
00195       getTextureInfo ();
00196 
00197       // Memory allocation for pixel data
00198       _pixels = new GLubyte[_width * _height * _components];
00199 
00200       // Read color map, if present
00201       if (_header->colormap_type)
00202         {
00203           // NOTE: color map is stored in BGR
00204           colormap = data_ptr;
00205           data_ptr += _header->cm_length * (_header->cm_size >> 3);
00206         }
00207 
00208       // Decode image data
00209       switch (_header->image_type)
00210         {
00211         case 0:
00212           // No data
00213           break;
00214 
00215         case 1:
00216           // Uncompressed 8 bits color index
00217           readTGA8bits (data_ptr, colormap);
00218           break;
00219 
00220         case 2:
00221           // Uncompressed 16-24-32 bits
00222           switch (_header->pixel_depth)
00223             {
00224             case 16:
00225               readTGA16bits (data_ptr);
00226               break;
00227 
00228             case 24:
00229               readTGA24bits (data_ptr);
00230               break;
00231 
00232             case 32:
00233               readTGA32bits (data_ptr);
00234               break;
00235             }
00236 
00237           break;
00238 
00239         case 3:
00240           // Uncompressed 8 or 16 bits grayscale
00241           if (_header->pixel_depth == 8)
00242             readTGAgray8bits (data_ptr);
00243           else // 16 bits
00244             readTGAgray16bits (data_ptr);
00245 
00246           break;
00247 
00248         case 9:
00249           // RLE compressed 8 bits color index
00250           readTGA8bitsRLE (data_ptr, colormap);
00251           break;
00252 
00253         case 10:
00254           // RLE compressed 16-24-32 bits
00255           switch (_header->pixel_depth)
00256             {
00257             case 16:
00258               readTGA16bitsRLE (data_ptr);
00259               break;
00260 
00261             case 24:
00262               readTGA24bitsRLE (data_ptr);
00263               break;
00264 
00265             case 32:
00266               readTGA32bitsRLE (data_ptr);
00267               break;
00268             }
00269 
00270           break;
00271 
00272         case 11:
00273           // RLE compressed 8 or 16 bits grayscale
00274           if (_header->pixel_depth == 8)
00275             readTGAgray8bitsRLE (data_ptr);
00276           else // 16 bits
00277             readTGAgray16bitsRLE (data_ptr);
00278 
00279           break;
00280 
00281         default:
00282           // Image type is not correct, free memory and quit
00283           throw ImageException ("Unknown TGA image type", _name);
00284         }
00285     }
00286   catch (...)
00287     {
00288       delete [] _pixels;
00289       throw;
00290     }
00291 }
00292 
00293 
00294 // --------------------------------------------------------------------------
00295 // ImageTGA::getTextureInfo
00296 //
00297 // Extract OpenGL texture informations from TGA header.
00298 // --------------------------------------------------------------------------
00299 
00300 void
00301 ImageTGA::getTextureInfo ()
00302 {
00303   _width = _header->width;
00304   _height = _header->height;
00305 
00306   switch (_header->image_type)
00307     {
00308     case 3:  // grayscale 8 bits
00309     case 11: // grayscale 8 bits (RLE)
00310       {
00311         if (_header->pixel_depth == 8)
00312           {
00313             _format = GL_LUMINANCE;
00314             _components = 1;
00315           }
00316         else // 16 bits
00317           {
00318             _format = GL_LUMINANCE_ALPHA;
00319             _components = 2;
00320           }
00321 
00322         break;
00323       }
00324 
00325     case 1:    // 8 bits color index
00326     case 2:    // BGR 16-24-32 bits
00327     case 9:    // 8 bits color index (RLE)
00328     case 10:   // BGR 16-24-32 bits (RLE)
00329       {
00330         // 8 bits and 16 bits images will be converted to 24 bits
00331         if (_header->pixel_depth <= 24)
00332           {
00333             _format = GLEW_EXT_bgra ? GL_BGR : GL_RGB;
00334             _components = 3;
00335           }
00336         else // 32 bits
00337           {
00338             _format = GLEW_EXT_bgra ? GL_BGRA : GL_RGBA;
00339             _components = 4;
00340           }
00341 
00342         break;
00343       }
00344     }
00345 }
00346 
00347 
00348 // --------------------------------------------------------------------------
00349 // ImageTGA::readTGA8bits
00350 //
00351 // Read 8 bits pixel data from TGA file.
00352 // --------------------------------------------------------------------------
00353 
00354 void
00355 ImageTGA::readTGA8bits (const GLubyte *data, const GLubyte *colormap)
00356 {
00357   const GLubyte *pData = data;
00358   int *compTable = GLEW_EXT_bgra ? bgraTable : rgbaTable;
00359 
00360   for (int i = 0; i < _width * _height; ++i)
00361     {
00362       // Read index color byte
00363       GLubyte color = *(pData++);
00364 
00365       // Convert to BGR/RGB 24 bits
00366       _pixels[(i * 3) + compTable[0]] = colormap[(color * 3) + 0];
00367       _pixels[(i * 3) + compTable[1]] = colormap[(color * 3) + 1];
00368       _pixels[(i * 3) + compTable[2]] = colormap[(color * 3) + 2];
00369     }
00370 }
00371 
00372 
00373 // --------------------------------------------------------------------------
00374 // ImageTGA::readTGA16bits
00375 //
00376 // Read 16 bits pixel data from TGA file.
00377 // --------------------------------------------------------------------------
00378 
00379 void
00380 ImageTGA::readTGA16bits (const GLubyte *data)
00381 {
00382   const GLubyte *pData = data;
00383   int *compTable = GLEW_EXT_bgra ? bgraTable : rgbaTable;
00384 
00385   for (int i = 0; i < _width * _height; ++i, pData += 2)
00386     {
00387       // Read color word
00388       unsigned short color = pData[0] + (pData[1] << 8);
00389 
00390       // convert to BGR/RGB 24 bits
00391       _pixels[(i * 3) + compTable[2]] = (((color & 0x7C00) >> 10) << 3);
00392       _pixels[(i * 3) + compTable[1]] = (((color & 0x03E0) >>  5) << 3);
00393       _pixels[(i * 3) + compTable[0]] = (((color & 0x001F) >>  0) << 3);
00394     }
00395 }
00396 
00397 
00398 // --------------------------------------------------------------------------
00399 // ImageTGA::readTGA24bits
00400 //
00401 // Read 24 bits pixel data from TGA file.
00402 // --------------------------------------------------------------------------
00403 
00404 void
00405 ImageTGA::readTGA24bits (const GLubyte *data)
00406 {
00407   if (GLEW_EXT_bgra)
00408     {
00409       memcpy (_pixels, data, _width * _height * 3);
00410     }
00411   else
00412     {
00413       const GLubyte *pData = data;
00414 
00415       for (int i = 0; i < _width * _height; ++i)
00416         {
00417           // Read RGB 24 bits pixel
00418           _pixels[(i * 3) + rgbaTable[0]] = *(pData++);
00419           _pixels[(i * 3) + rgbaTable[1]] = *(pData++);
00420           _pixels[(i * 3) + rgbaTable[2]] = *(pData++);
00421         }
00422     }
00423 }
00424 
00425 
00426 // --------------------------------------------------------------------------
00427 // ImageTGA::readTGA32bits
00428 //
00429 // Read 32 bits pixel data from TGA file.
00430 // --------------------------------------------------------------------------
00431 
00432 void
00433 ImageTGA::readTGA32bits (const GLubyte *data)
00434 {
00435   if (GLEW_EXT_bgra)
00436     {
00437       memcpy (_pixels, data, _width * _height * 4);
00438     }
00439   else
00440     {
00441       const GLubyte *pData = data;
00442 
00443       for (int i = 0; i < _width * _height; ++i)
00444         {
00445           // Read RGB 32 bits pixel
00446           _pixels[(i * 4) + rgbaTable[0]] = *(pData++);
00447           _pixels[(i * 4) + rgbaTable[1]] = *(pData++);
00448           _pixels[(i * 4) + rgbaTable[2]] = *(pData++);
00449           _pixels[(i * 4) + rgbaTable[3]] = *(pData++);
00450         }
00451     }
00452 }
00453 
00454 
00455 // --------------------------------------------------------------------------
00456 // ImageTGA::readTGAgray8bits
00457 //
00458 // Read grey 8 bits pixel data from TGA file.
00459 // --------------------------------------------------------------------------
00460 
00461 void
00462 ImageTGA::readTGAgray8bits (const GLubyte *data)
00463 {
00464   memcpy (_pixels, data, _width * _height);
00465 }
00466 
00467 
00468 // --------------------------------------------------------------------------
00469 // ImageTGA::readTGAgray16bits
00470 //
00471 // Read grey 16 bits pixel data from TGA file.
00472 // --------------------------------------------------------------------------
00473 
00474 void
00475 ImageTGA::readTGAgray16bits (const GLubyte *data)
00476 {
00477   memcpy (_pixels, data, _width * _height * 2);
00478 }
00479 
00480 
00481 // --------------------------------------------------------------------------
00482 // ImageTGA::readTGA8bitsRLE
00483 //
00484 // Read 8 bits pixel data from TGA file with RLE compression.
00485 // --------------------------------------------------------------------------
00486 
00487 void
00488 ImageTGA::readTGA8bitsRLE (const GLubyte *data, const GLubyte *colormap)
00489 {
00490   GLubyte *ptr = _pixels;
00491   const GLubyte *pData = data;
00492   int *compTable = GLEW_EXT_bgra ? bgraTable : rgbaTable;
00493 
00494   while (ptr < _pixels + (_width * _height) * 3)
00495     {
00496       // Read first byte
00497       GLubyte packet_header = *(pData++);
00498       int size = 1 + (packet_header & 0x7f);
00499 
00500       if (packet_header & 0x80)
00501         {
00502           // Run-length packet
00503           GLubyte color = *(pData++);
00504 
00505           for (int i = 0; i < size; ++i, ptr += 3)
00506             {
00507               ptr[0] = colormap[(color * 3) + compTable[0]];
00508               ptr[1] = colormap[(color * 3) + compTable[1]];
00509               ptr[2] = colormap[(color * 3) + compTable[2]];
00510             }
00511         }
00512       else
00513         {
00514           // Non run-length packet
00515           for (int i = 0; i < size; ++i, ptr += 3)
00516             {
00517               GLubyte color = *(pData++);
00518 
00519               ptr[0] = colormap[(color * 3) + compTable[0]];
00520               ptr[1] = colormap[(color * 3) + compTable[1]];
00521               ptr[2] = colormap[(color * 3) + compTable[2]];
00522             }
00523         }
00524     }
00525 }
00526 
00527 
00528 // --------------------------------------------------------------------------
00529 // ImageTGA::readTGA16bitsRLE
00530 //
00531 // Read 16 bits pixel data from TGA file with RLE compression.
00532 // --------------------------------------------------------------------------
00533 
00534 void
00535 ImageTGA::readTGA16bitsRLE (const GLubyte *data)
00536 {
00537   const GLubyte *pData = data;
00538   GLubyte *ptr = _pixels;
00539   int *compTable = GLEW_EXT_bgra ? bgraTable : rgbaTable;
00540 
00541   while (ptr < _pixels + (_width * _height) * 3)
00542     {
00543       // Read first byte
00544       GLubyte packet_header = *(pData++);
00545       int size = 1 + (packet_header & 0x7f);
00546 
00547       if (packet_header & 0x80)
00548         {
00549           // Run-length packet
00550           unsigned short color = pData[0] + (pData[1] << 8);
00551           pData += 2;
00552 
00553           for (int i = 0; i < size; ++i, ptr += 3)
00554             {
00555               ptr[compTable[2]] = (((color & 0x7C00) >> 10) << 3);
00556               ptr[compTable[1]] = (((color & 0x03E0) >>  5) << 3);
00557               ptr[compTable[0]] = (((color & 0x001F) >>  0) << 3);
00558             }
00559         }
00560       else
00561         {
00562           // Non run-length packet
00563           for (int i = 0; i < size; ++i, ptr += 3)
00564             {
00565               unsigned short color = pData[0] + (pData[1] << 8);
00566               pData += 2;
00567 
00568               ptr[compTable[2]] = (((color & 0x7C00) >> 10) << 3);
00569               ptr[compTable[1]] = (((color & 0x03E0) >>  5) << 3);
00570               ptr[compTable[0]] = (((color & 0x001F) >>  0) << 3);
00571             }
00572         }
00573     }
00574 }
00575 
00576 
00577 // --------------------------------------------------------------------------
00578 // ImageTGA::readTGA24bitsRLE
00579 //
00580 // Read 24 bits pixel data from TGA file with RLE compression.
00581 // --------------------------------------------------------------------------
00582 
00583 void
00584 ImageTGA::readTGA24bitsRLE (const GLubyte *data)
00585 {
00586   const GLubyte *pData = data;
00587   GLubyte *ptr = _pixels;
00588   int *compTable = GLEW_EXT_bgra ? bgraTable : rgbaTable;
00589 
00590   while (ptr < _pixels + (_width * _height) * 3)
00591     {
00592       // Read first byte
00593       GLubyte packet_header = *(pData++);
00594       int size = 1 + (packet_header & 0x7f);
00595 
00596       if (packet_header & 0x80)
00597         {
00598           // Run-length packet
00599           for (int i = 0; i < size; ++i, ptr += 3)
00600             {
00601               ptr[0] = pData[compTable[0]];
00602               ptr[1] = pData[compTable[1]];
00603               ptr[2] = pData[compTable[2]];
00604             }
00605 
00606           pData += 3;
00607         }
00608       else
00609         {
00610           // Non run-length packet
00611           for (int i = 0; i < size; ++i, ptr += 3)
00612             {
00613               ptr[0] = pData[compTable[0]];
00614               ptr[1] = pData[compTable[1]];
00615               ptr[2] = pData[compTable[2]];
00616               pData += 3;
00617             }
00618         }
00619     }
00620 }
00621 
00622 
00623 // --------------------------------------------------------------------------
00624 // ImageTGA::readTGA32bitsRLE
00625 //
00626 // Read 32 bits pixel data from TGA file with RLE compression.
00627 // --------------------------------------------------------------------------
00628 
00629 void
00630 ImageTGA::readTGA32bitsRLE (const GLubyte *data)
00631 {
00632   const GLubyte *pData = data;
00633   GLubyte *ptr = _pixels;
00634   int *compTable = GLEW_EXT_bgra ? bgraTable : rgbaTable;
00635 
00636   while (ptr < _pixels + (_width * _height) * 4)
00637     {
00638       // Read first byte
00639       GLubyte packet_header = *(pData++);
00640       int size = 1 + (packet_header & 0x7f);
00641 
00642       if (packet_header & 0x80)
00643         {
00644           // Run-length packet */
00645           for (int i = 0; i < size; ++i, ptr += 4)
00646             {
00647               ptr[0] = pData[compTable[0]];
00648               ptr[1] = pData[compTable[1]];
00649               ptr[2] = pData[compTable[2]];
00650               ptr[3] = pData[compTable[3]];
00651             }
00652 
00653           pData += 4;
00654         }
00655       else
00656         {
00657           // Non run-length packet
00658           for (int i = 0; i < size; ++i, ptr += 4)
00659             {
00660               ptr[0] = pData[compTable[0]];
00661               ptr[1] = pData[compTable[1]];
00662               ptr[2] = pData[compTable[2]];
00663               ptr[3] = pData[compTable[3]];
00664               pData += 4;
00665             }
00666         }
00667     }
00668 }
00669 
00670 
00671 // --------------------------------------------------------------------------
00672 // ImageTGA::readTGAgray8bitsRLE
00673 //
00674 // Read grey 8 bits pixel data from TGA file with RLE compression.
00675 // --------------------------------------------------------------------------
00676 
00677 void
00678 ImageTGA::readTGAgray8bitsRLE (const GLubyte *data)
00679 {
00680   const GLubyte *pData = data;
00681   GLubyte *ptr = _pixels;
00682 
00683   while (ptr < _pixels + (_width * _height))
00684     {
00685       // Read first byte
00686       GLubyte packet_header = *(pData++);
00687       int size = 1 + (packet_header & 0x7f);
00688 
00689       if (packet_header & 0x80)
00690         {
00691           // Run-length packet
00692           GLubyte color = *(pData++);
00693 
00694           memset (ptr, color, size);
00695           ptr += size;
00696         }
00697       else
00698         {
00699           // Non run-length packet
00700           memcpy (ptr, pData, size);
00701           ptr += size;
00702           pData += size;
00703         }
00704     }
00705 }
00706 
00707 
00708 // --------------------------------------------------------------------------
00709 // ImageTGA::readTGAgray16bitsRLE
00710 //
00711 // Read grey 16 bits pixel data from TGA file with RLE compression.
00712 // --------------------------------------------------------------------------
00713 
00714 void
00715 ImageTGA::readTGAgray16bitsRLE (const GLubyte *data)
00716 {
00717   const GLubyte *pData = data;
00718   GLubyte *ptr = _pixels;
00719 
00720   while (ptr < _pixels + (_width * _height) * 2)
00721     {
00722       // Read first byte
00723       GLubyte packet_header = *(pData++);
00724       int size = 1 + (packet_header & 0x7f);
00725 
00726       if (packet_header & 0x80)
00727         {
00728           // Run-length packet
00729           GLubyte color = *(pData++);
00730           GLubyte alpha = *(pData++);
00731 
00732           for (int i = 0; i < size; ++i, ptr += 2)
00733             {
00734               ptr[0] = color;
00735               ptr[1] = alpha;
00736             }
00737         }
00738       else
00739         {
00740           // Non run-length packet
00741           memcpy (ptr, pData, size * 2);
00742           ptr += size * 2;
00743           pData += size * 2;
00744         }
00745     }
00746 }
00747 
00748 
00749 /////////////////////////////////////////////////////////////////////////////
00750 //
00751 // class ImageJPEG implementation.
00752 //
00753 /////////////////////////////////////////////////////////////////////////////
00754 
00755 // --------------------------------------------------------------------------
00756 // ImageJPEG::ImageJPEG
00757 //
00758 // Constructor.  Read a JPEG image from memory, using libjpeg.
00759 // --------------------------------------------------------------------------
00760 
00761 ImageJPEG::ImageJPEG (const ImageBuffer &ibuff)
00762 {
00763   jpeg_decompress_struct cinfo;
00764   my_error_mgr jerr;
00765   jpeg_source_mgr jsrc;
00766   JSAMPROW j;
00767 
00768   try
00769     {
00770       _name = ibuff.filename ();
00771       _standardCoordSystem = true;
00772 
00773       // Create and configure decompress object
00774       jpeg_create_decompress (&cinfo);
00775       cinfo.err = jpeg_std_error (&jerr.pub);
00776       cinfo.src = &jsrc;
00777 
00778       // Configure error manager
00779       jerr.pub.error_exit = errorExit_callback;
00780       jerr.pub.output_message = outputMessage_callback;
00781 
00782       if (setjmp (jerr.setjmp_buffer))
00783         throw ImageException (jerr.errorMsg, _name);
00784 
00785       // Configure source manager
00786       jsrc.next_input_byte = ibuff.data ();
00787       jsrc.bytes_in_buffer = ibuff.length ();
00788 
00789       jsrc.init_source = initSource_callback;
00790       jsrc.fill_input_buffer = fillInputBuffer_callback;
00791       jsrc.skip_input_data = skipInputData_callback;
00792       jsrc.resync_to_restart = jpeg_resync_to_restart;
00793       jsrc.term_source = termSource_callback;
00794 
00795       // Read file's header and prepare for decompression
00796       jpeg_read_header (&cinfo, TRUE);
00797       jpeg_start_decompress (&cinfo);
00798 
00799       // Initialize image's member variables
00800       _width = cinfo.image_width;
00801       _height = cinfo.image_height;
00802       _components = cinfo.num_components;
00803       _format = (cinfo.num_components == 1) ? GL_LUMINANCE : GL_RGB;
00804       _pixels = new GLubyte[_width * _height * _components];
00805 
00806       // Read scanlines
00807       for (int i = 0; i < _height; ++i)
00808         {
00809           //j = &_pixels[_width * i * _components];
00810           j = (_pixels + ((_height - (i + 1)) * _width * _components));
00811           jpeg_read_scanlines (&cinfo, &j, 1);
00812         }
00813 
00814       // Finish decompression and release memory
00815       jpeg_finish_decompress (&cinfo);
00816       jpeg_destroy_decompress (&cinfo);
00817     }
00818   catch (...)
00819     {
00820       delete [] _pixels;
00821       jpeg_destroy_decompress (&cinfo);
00822 
00823       throw;
00824     }
00825 }
00826 
00827 
00828 // --------------------------------------------------------------------------
00829 // ImageJPEG::initSource_callback
00830 // ImageJPEG::fillInputBuffer_callback
00831 // ImageJPEG::skipInputData_callback
00832 // ImageJPEG::termSource_callback
00833 //
00834 // Callback functions used by libjpeg for reading data from memory.
00835 // --------------------------------------------------------------------------
00836 
00837 void
00838 ImageJPEG::initSource_callback (j_decompress_ptr cinfo)
00839 {
00840   // Nothing to do here
00841 }
00842 
00843 
00844 boolean
00845 ImageJPEG::fillInputBuffer_callback (j_decompress_ptr cinfo)
00846 {
00847   JOCTET eoi_buffer[2] = { 0xFF, JPEG_EOI };
00848   struct jpeg_source_mgr *jsrc = cinfo->src;
00849 
00850   // Create a fake EOI marker
00851   jsrc->next_input_byte = eoi_buffer;
00852   jsrc->bytes_in_buffer = 2;
00853 
00854   return TRUE;
00855 }
00856 
00857 
00858 void
00859 ImageJPEG::skipInputData_callback (j_decompress_ptr cinfo, long num_bytes)
00860 {
00861   struct jpeg_source_mgr *jsrc = cinfo->src;
00862 
00863   if (num_bytes > 0)
00864     {
00865       while (num_bytes > static_cast<long>(jsrc->bytes_in_buffer))
00866         {
00867           num_bytes -= static_cast<long>(jsrc->bytes_in_buffer);
00868           fillInputBuffer_callback (cinfo);
00869         }
00870 
00871       jsrc->next_input_byte += num_bytes;
00872       jsrc->bytes_in_buffer -= num_bytes;
00873     }
00874 }
00875 
00876 
00877 void
00878 ImageJPEG::termSource_callback (j_decompress_ptr cinfo)
00879 {
00880   // Nothing to do here
00881 }
00882 
00883 
00884 // --------------------------------------------------------------------------
00885 // ImageJPEG::errorExit
00886 // ImageJPEG::outputMessage
00887 //
00888 // Callback functions used by libjpeg for error handling.
00889 // --------------------------------------------------------------------------
00890 
00891 void
00892 ImageJPEG::errorExit_callback (j_common_ptr cinfo)
00893 {
00894   my_error_ptr jerr = reinterpret_cast<my_error_ptr>(cinfo->err);
00895 
00896   // Create the error message
00897   char message[JMSG_LENGTH_MAX];
00898   (*cinfo->err->format_message) (cinfo, message);
00899   jerr->errorMsg.assign (message);
00900 
00901   // Return control to the setjmp point
00902   longjmp (jerr->setjmp_buffer, 1);
00903 }
00904 
00905 
00906 void
00907 ImageJPEG::outputMessage_callback (j_common_ptr cinfo)
00908 {
00909   my_error_ptr jerr = reinterpret_cast<my_error_ptr>(cinfo->err);
00910 
00911   // Create the error message
00912   char message[JMSG_LENGTH_MAX];
00913   (*cinfo->err->format_message) (cinfo, message);
00914   jerr->errorMsg.assign (message);
00915 
00916   // Send it to stderr, adding a newline
00917   std::cerr << "libjpeg: " << jerr->errorMsg << std::endl;
00918 }