Main Page | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

imageFilePNG.cpp

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <png.h>
00003 
00004 #include "imageFilePNG.hpp"
00005 
00006 //------------------------------------------------------------------------
00007 void pngError(png_structp png_ptr, png_const_charp msg)
00008 //------------------------------------------------------------------------
00009 {
00010     if(png_ptr)
00011     {
00012         printf("libpng error: %s\n", msg);
00013     }   
00014 }
00015 
00016 //------------------------------------------------------------------------
00017 void pngWarning(png_structp png_ptr, png_const_charp msg)
00018 //------------------------------------------------------------------------
00019 {
00020     if(png_ptr)
00021     {
00022         printf("libpng warning: %s\n", msg);
00023     }   
00024 }
00025 
00026 //------------------------------------------------------------------------
00027 imageFilePNG::imageFilePNG() 
00028 //------------------------------------------------------------------------
00029 {
00030 }
00031 
00032 //------------------------------------------------------------------------
00033 imageFilePNG::~imageFilePNG()
00034 //------------------------------------------------------------------------
00035 {
00036 }
00037 
00038 //------------------------------------------------------------------------
00039 bool imageFilePNG::loadImage(String filename)
00040 //------------------------------------------------------------------------
00041 {
00042     FILE * fp;
00043     png_structp pngRead;
00044     png_infop pngInfo;
00045     UInt8 pngHeader[8];
00046     bool res = true;
00047     Int32 i;
00048 
00049     // open the PNG input file
00050     if (!(fp = fopen(filename, "rb")))
00051     {
00052         return false;
00053     }
00054     
00055     fread(pngHeader, 1, 8, fp);
00056     if (0 != png_sig_cmp(pngHeader, 0, 8))
00057     {
00058         printf(__FILE__"This is not a valid PNG\n");
00059         return false;
00060     }
00061 
00062     // create the two png(-info) structures
00063     pngRead = png_create_read_struct(PNG_LIBPNG_VER_STRING, (void *)this, (png_error_ptr)pngError, (png_error_ptr)pngWarning);
00064     if(0 == pngRead)
00065     {
00066         return false;
00067     }
00068 
00069     pngInfo = png_create_info_struct(pngRead);
00070     if(0 == pngInfo)
00071     {
00072         png_destroy_read_struct(&pngRead, NULL, NULL);
00073         return false;
00074     }  
00075 
00076     do {
00077     
00078         png_init_io(pngRead, fp);
00079         png_set_sig_bytes(pngRead, 8);
00080     
00081         // read all PNG info up to image data  
00082         png_read_info(pngRead, pngInfo);
00083     
00084         Int32 bitWidth;
00085         Int32 colorType;
00086         Int32 width;
00087         Int32 height;
00088         
00089         // get width, height, bit-depth and color-type
00090         png_get_IHDR(pngRead, pngInfo, (unsigned long *)&width, (unsigned long *)&height, &bitWidth, &colorType, NULL, NULL, NULL);
00091     
00092         //We support only 8 pit per Pixel        
00093         if (8 != bitWidth)
00094         {
00095             printf(__FILE__"Bitwidths other than 8 are not supported\n");
00096             res = false;
00097             break;
00098         }
00099         
00100         Int32 numberOfBytes = 0;
00101         Int32 bytesPerRow = 0;
00102         imageFile::ePixelFormat pixelFormat = imageFile::NONE;
00103 
00104         //Check for supported color types
00105         if ((PNG_COLOR_TYPE_GRAY == colorType) || (PNG_COLOR_TYPE_GRAY == colorType))
00106         {
00107             pixelFormat = imageFile::G8;
00108             numberOfBytes = width * height;
00109             bytesPerRow = width;
00110         }
00111         else if (PNG_COLOR_TYPE_RGB == colorType)
00112         {
00113             pixelFormat = imageFile::RGB888;
00114             numberOfBytes = width * height * 3;
00115             bytesPerRow = width * 3;
00116         }
00117         else if (PNG_COLOR_TYPE_RGB_ALPHA == colorType)
00118         {
00119             pixelFormat = imageFile::RGBA8888;
00120             numberOfBytes = width * height * 4;
00121             bytesPerRow = width * 4;
00122         }
00123         else
00124         {
00125             printf(__FILE__"Color type not supported\n");
00126             res = false;
00127             break;
00128         }
00129 
00130          //Throw away old content before loading the new image data
00131         cleanup();
00132         
00133         mPixelFormat = pixelFormat;
00134         mWidth = width;
00135         mHeight = height;
00136 
00137         //allocate image data
00138         mPixels = new UInt8[numberOfBytes];
00139 
00140         //allocate row pointers
00141         UInt8 ** rowPointers = new UInt8*[height];
00142             
00143         //Initialize row pointers    
00144         for (i = 0; i < height; i++)
00145         {
00146             rowPointers[i] = mPixels + i * bytesPerRow;
00147         }
00148     
00149         // now we can go ahead and just read the whole image    
00150         png_read_image(pngRead, rowPointers);
00151     
00152         // read the additional chunks in the PNG file (not really needed)    
00153         png_read_end(pngRead, NULL);
00154     
00155         // and we're done
00156     
00157         delete [] rowPointers;
00158 
00159     }while(0);
00160 
00161     png_destroy_read_struct(&pngRead, &pngInfo, NULL);
00162        
00163     fclose(fp);
00164    
00165     return res;
00166 }
00167 
00168 //------------------------------------------------------------------------
00169 bool imageFilePNG::writeImage(String filename)
00170 //------------------------------------------------------------------------
00171 {
00172     FILE * fp;
00173     png_structp pngWrite;
00174     png_infop pngInfo;
00175     bool res = true;
00176     Int32 i;
00177 
00178     // open the PNG output file
00179     if (!(fp = fopen(filename, "wb")))
00180     {
00181         return false;
00182     }
00183 
00184     // prepare the standard PNG structures
00185 
00186     pngWrite = png_create_write_struct(PNG_LIBPNG_VER_STRING, (void *)this, (png_error_ptr)pngError, (png_error_ptr)pngWarning);
00187     if (0 == pngWrite)
00188     {
00189         fclose(fp);
00190         return false;
00191     }
00192 
00193     pngInfo = png_create_info_struct(pngWrite);
00194     if (0 == pngInfo) 
00195     {
00196         fclose(fp);
00197         png_destroy_write_struct(&pngWrite, (png_infopp) NULL);
00198         return false;
00199     }
00200 
00201     do
00202     {
00203         png_init_io(pngWrite, fp);
00204 
00205         Int32 colorType = 0;
00206         Int32 channels = 0;
00207 
00208         if(imageFile::RGB888 == mPixelFormat)
00209         {
00210             colorType = PNG_COLOR_TYPE_RGB;
00211             channels = 3;
00212         }
00213         else if(imageFile::RGBA8888 == mPixelFormat)
00214         {
00215             colorType = PNG_COLOR_TYPE_RGBA;
00216             channels = 4;
00217         }
00218         else if(imageFile::G8== mPixelFormat)
00219         {
00220             colorType = PNG_COLOR_TYPE_GRAY;
00221             channels = 1;
00222         }
00223         else
00224         {
00225             res = false;
00226             break;
00227         }
00228         
00229         // we're going to write a very simple 3x8 bit RGB image
00230         png_set_IHDR(pngWrite, pngInfo, mWidth, mHeight, 8, colorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
00231         
00232         // write the file header information
00233         png_write_info(pngWrite, pngInfo);
00234                
00235         // row_bytes is the width x number of channels
00236         UInt32 bytesPerRow = mWidth * channels;
00237         
00238         // we can allocate memory for an array of row-pointers
00239         
00240         png_bytepp ppbRowPointers = new png_bytep[mHeight];
00241         
00242         // set the individual row-pointers to point at the correct offsets  
00243         for (i = 0; i < mHeight; i++)
00244         {
00245             ppbRowPointers[i] = mPixels + i * bytesPerRow;
00246         }
00247         
00248         // write out the entire image data in one call
00249         
00250         png_write_image (pngWrite, ppbRowPointers);
00251         
00252         // write the additional chunks to the PNG file (not really needed)
00253         
00254         png_write_end(pngWrite, pngInfo);
00255         
00256         // and we're done
00257         
00258         delete [] ppbRowPointers;
00259 
00260             
00261     }while(0);
00262     
00263     png_destroy_write_struct(&pngWrite, (png_infopp) NULL);
00264 
00265     fclose(fp);
00266     return res;
00267 }
00268 
00269 

Generated on Wed Nov 30 08:06:26 2005 for Diplomarbeit by  doxygen 1.4.4