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
00044 int channels;
00045 int bit_depth;
00046 int color_type = PNG_COLOR_TYPE_RGB;
00047 unsigned char* buffer = NULL;
00048
00049
00050 read_png(fileName.c_str(), buffer, mResX, mResY, channels, bit_depth, color_type, true);
00051
00052
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
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
00073 bool grey = color_type == PNG_COLOR_TYPE_GRAY;
00074 bool rgba = color_type == PNG_COLOR_TYPE_RGBA;
00075
00076
00077 delete [] mPixels;
00078 mPixels = new RGBAColor[mResX * mResY];
00079
00080
00081 for (int y=0; y < mResY; y++)
00082 {
00083 for (int x=0; x < mResX; x++)
00084 {
00085
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
00091 setPixel(v, x, y);
00092 }
00093 }
00094
00095
00096 delete [] buffer;
00097 return true;
00098 }
00099
00100
00105 void PNGImage::write(const std::string & fileName) const
00106 {
00107
00108 int channels = 3;
00109 int bit_depth = 8;
00110 int color_type = PNG_COLOR_TYPE_RGB;
00111
00112
00113 unsigned char * buffer = new unsigned char[mResX * mResY * channels];
00114
00115
00116 for (int y=0; y < mResY; y++)
00117 {
00118 for (int x=0; x < mResX; x++)
00119 {
00120
00121 const RGBAColor & p = pixel(x, y);
00122
00123
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
00131 write_png(fileName.c_str(), buffer, mResX, mResY, channels, bit_depth, color_type, true);
00132
00133
00134 delete [] buffer;
00135 }
00136
00137