src/PNGImage.cpp

Go to the documentation of this file.
00001 
00002 #include <cassert>
00003 #include <string>
00004 #include <fstream>
00005 
00006 #include "PNGImage.h"
00007 #include "RGBAColor.h"
00008 #include "pngHelper.h"
00009 
00010 
00016 PNGImage::PNGImage(int resX, int resY)
00017     : Image(resX, resY)
00018 {
00019 }
00020 
00021 
00024 PNGImage::~PNGImage()
00025 {
00026 }
00027 
00028 
00034 bool PNGImage::read(const std::string & fileName)
00035 {
00036     std::ifstream ifile(fileName.c_str());
00037     if(!ifile.good() )
00038     {
00039         throw PNGFileOpenException(fileName);
00040     }
00041 
00042 
00043     // store here image data
00044     int channels;
00045     int bit_depth;
00046     int color_type          = PNG_COLOR_TYPE_RGB;
00047     unsigned char* buffer   = NULL;
00048 
00049     // read png file
00050     read_png(fileName.c_str(), buffer, mResX, mResY, channels, bit_depth, color_type, true);
00051 
00052     // check supported color types
00053     if (!(color_type == PNG_COLOR_TYPE_GRAY
00054         || color_type == PNG_COLOR_TYPE_RGB
00055         || color_type == PNG_COLOR_TYPE_RGBA))
00056     {
00057         std::cerr << "Image::ReadPNG(" << fileName << "): not supported color type!" << std::endl;
00058         delete [] buffer;
00059         return false;
00060     }
00061 
00062     // currently only support 8 bit
00063     if (bit_depth != 8)
00064     {
00065         std::cerr << "Image::ReadPNG(" << fileName << "): not supported bit depth!" << std::endl;
00066         delete [] buffer;
00067         return false;
00068     }
00069 
00070     LOG("Read PNG File : " << fileName);
00071 
00072     // check whenever we have gray scale png file
00073     bool grey = color_type == PNG_COLOR_TYPE_GRAY;
00074     bool rgba = color_type == PNG_COLOR_TYPE_RGBA;
00075 
00076     // create pixel buffer to store the data
00077     delete [] mPixels;
00078     mPixels = new RGBAColor[mResX * mResY];
00079 
00080     // copy and convert pixel data
00081     for (int y=0; y < mResY; y++)
00082     {
00083         for (int x=0; x < mResX; x++)
00084         {
00085             // convert values
00086             RGBAColor v = RGBAColor(float(buffer[(y * mResX + x) * channels + (grey ? 0 : 0)]) / 255.0,
00087                             float(buffer[(y * mResX + x) * channels + (grey ? 0 : 1)]) / 255.0,
00088                             float(buffer[(y * mResX + x) * channels + (grey ? 0 : 2)]) / 255.0,
00089                             rgba ? float(buffer[(y * mResX + x) * channels + (grey ? 0 : 3)]) / 255.0 : 1);
00090             // set pixel
00091             setPixel(v, x, y);
00092         }
00093     }
00094 
00095     // free up the used data
00096     delete [] buffer;
00097     return true;
00098 }
00099 
00100 
00105 void PNGImage::write(const std::string & fileName) const
00106 {
00107     // store here image data
00108     int channels    = 3;
00109     int bit_depth   = 8;
00110     int color_type  = PNG_COLOR_TYPE_RGB;
00111 
00112     // create pixel to store the data
00113     unsigned char * buffer = new unsigned char[mResX * mResY * channels];
00114 
00115     // copy and convert pixel data
00116     for (int y=0; y < mResY; y++)
00117     {
00118         for (int x=0; x < mResX; x++)
00119         {
00120             // get pixel
00121             const RGBAColor & p = pixel(x, y);
00122 
00123             // convert values
00124             buffer[(y * mResX + x) * channels + 0] = static_cast<unsigned char>(255.0 * p.r());
00125             buffer[(y * mResX + x) * channels + 1] = static_cast<unsigned char>(255.0 * p.g());
00126             buffer[(y * mResX + x) * channels + 2] = static_cast<unsigned char>(255.0 * p.b());
00127         }
00128     }
00129 
00130     // write file
00131     write_png(fileName.c_str(), buffer, mResX, mResY, channels, bit_depth, color_type, true);
00132 
00133     // free up the used data
00134     delete [] buffer;
00135 }
00136 
00137 

Generated on Fri Feb 1 00:01:42 2008 for Grayfall by  doxygen 1.5.1