Page principale | Hiérarchie des classes | Liste des classes | Liste des fichiers | Membres de classe | Membres de fichier

PNG.cpp

Aller à la documentation de ce fichier.
00001 /// \file 00002 /// Implémentation des classes permettant de manipuler des fichiers au format PNG 00003 #include "PNG.hpp" 00004 /////////////////////////////////////////////////////////////////////////////// 00005 /// PNG 00006 /////////////////////////////////////////////////////////////////////////////// 00007 PNG::PNG(string fileName){ 00008 p = new PNG_Reader(fileName); 00009 } 00010 PNG::PNG(int width, int height, EPNG_TYPE type, string fileName){ 00011 p = new PNG_Writer(width, height, type, fileName); 00012 } 00013 PNG::PNG(const PNG& png){ 00014 p = png.p; 00015 ++p->use; 00016 } 00017 PNG& PNG::operator=(const PNG& rhs){ 00018 rhs.p->use++; 00019 if(--p->use == 0){ 00020 delete p; 00021 } 00022 p = rhs.p; 00023 return *this; 00024 } 00025 PNG::~PNG(){ 00026 if(--p->use == 0){ 00027 delete p; 00028 } 00029 } 00030 EPNG_TYPE PNG::getType()const{ 00031 return p->getType(); 00032 } 00033 string PNG::toString()const{ 00034 return p->toString(); 00035 } 00036 int PNG::getWidth()const{ 00037 return p->getWidth(); 00038 } 00039 int PNG::getHeight()const{ 00040 return p->getHeight(); 00041 } 00042 /* 00043 void PNG::setFileName(const string fileName){ 00044 p->setFileName(fileName); 00045 } 00046 */ 00047 Color PNG::getColor(int i, int j)const{ 00048 return p->getColor(i, j); 00049 } 00050 void PNG::setColor(int i, int j, Color color){ 00051 p->setColor(i, j, color); 00052 } 00053 void PNG::setColor(int i, int j, float gray){ 00054 p->setColor(i, j , gray); 00055 } 00056 void PNG::setColor(int i, int j, float red, float green, float blue){ 00057 p->setColor(i, j, red, green, blue); 00058 } 00059 void PNG::read(){ 00060 p->read(); 00061 } 00062 00063 void PNG::write(){ 00064 p->write(); 00065 } 00066 Histogram* PNG::getHistogram()const{ 00067 return p->getHistogram(); 00068 } 00069 /////////////////////////////////////////////////////////////////////////////// 00070 /// PNG_Base 00071 /////////////////////////////////////////////////////////////////////////////// 00072 PNG_Base::PNG_Base(): 00073 use(1), 00074 fp(NULL), 00075 png_ptr(NULL), 00076 info_ptr(NULL) 00077 {} 00078 int PNG_Base::getWidth()const{ 00079 return width; 00080 }; 00081 int PNG_Base::getHeight()const{ 00082 return height; 00083 } 00084 EPNG_TYPE PNG_Base::getType()const{ 00085 switch(color_type){ 00086 case 0 : // GRAY 00087 { 00088 return PNG_GRAY; 00089 } 00090 break; 00091 case 2 : // RGB 00092 { 00093 return PNG_COLOR; 00094 } 00095 break; 00096 } 00097 } 00098 string PNG_Base::toString()const{ 00099 std::ostringstream o; 00100 o << "width\t\t" << width << endl; 00101 o << "height\t\t" << height << endl; 00102 o << "bit_depth\t" << (int)bit_depth << endl; 00103 o << "color_type\t" << (int)color_type << endl; 00104 o << "rowbytes\t" << (int)rowbytes << endl; 00105 return o.str(); 00106 } 00107 Histogram* PNG_Base::getHistogram()const{ 00108 Histogram* ret = new Histogram(); 00109 for(int j = 0; j < height; j++){ 00110 for(int i = 0; i < width; i++){ 00111 Pixel pixel(i, j, getColor(i, j)); 00112 ret->addPixel(pixel); 00113 } 00114 } 00115 return ret; 00116 } 00117 00118 /////////////////////////////////////////////////////////////////////////////// 00119 /// PNGReader 00120 /////////////////////////////////////////////////////////////////////////////// 00121 void PNG_Reader::read(){ 00122 const int PNG_BYTES_TO_CHECK = 4; 00123 png_structp png_ptr; 00124 png_infop info_ptr; 00125 00126 FILE *fp = fopen(fileName.c_str(), "rb"); 00127 if(fp == NULL){ 00128 throw std::runtime_error(" IMPOSSIBLE D'OUVRIE LE FICHIER " + fileName); 00129 } 00130 unsigned char buf[PNG_BYTES_TO_CHECK]; 00131 if(fread(buf, 1, PNG_BYTES_TO_CHECK, fp) != PNG_BYTES_TO_CHECK){ 00132 throw std::runtime_error(" LE FICHIER " + fileName + " N'EST PAS AU FORMAT PNG "); 00133 } 00134 if(png_sig_cmp(&buf[0], (png_size_t)0, PNG_BYTES_TO_CHECK)){ 00135 throw std::runtime_error(" LE FICHIER " + fileName + " N'EST PAS AU FORMAT PNG "); 00136 } 00137 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 00138 if (png_ptr == NULL) { 00139 fclose(fp); 00140 throw std::runtime_error(" ERREUR A LA CREATION DE LA STRUCTURE PNG "); 00141 } 00142 info_ptr = png_create_info_struct(png_ptr); 00143 if (info_ptr == NULL) { 00144 fclose(fp); 00145 png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); 00146 throw std::runtime_error(" ERRUUR A LA CREATION D'INFORMATION PNG "); 00147 } 00148 if(setjmp(png_jmpbuf(png_ptr))) { 00149 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); 00150 fclose(fp); 00151 throw std::runtime_error(" ERREUR A LA CREATION DE LA STRUCTURE INTERNE PNG "); 00152 } 00153 png_init_io(png_ptr, fp); 00154 png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); 00155 00156 // high-level read 00157 png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, png_voidp_NULL); 00158 width = (int)png_get_image_width(png_ptr, info_ptr); 00159 height = (int)png_get_image_height(png_ptr, info_ptr); 00160 bit_depth = (int)png_get_bit_depth(png_ptr, info_ptr); 00161 color_type = (int)png_get_color_type(png_ptr, info_ptr); 00162 rowbytes = png_get_rowbytes(png_ptr, info_ptr); 00163 00164 fclose(fp); 00165 pData = png_get_rows(png_ptr, info_ptr); 00166 } 00167 Color PNG_Reader::getColor(int x, int y)const{ 00168 x = (x < 0 ? 0 : x); 00169 x = (x >= width ? width - 1 : x); 00170 00171 y = (y < 0 ? 0 : y); 00172 y = (y >= height ? height - 1 : y); 00173 00174 switch(color_type){ 00175 case 0 : // GRAY 00176 { 00177 int gray = pData[y][x]; 00178 return Color(gray); 00179 } 00180 break; 00181 case 2 : // RGB 00182 { 00183 int r = pData[y][x * 3]; 00184 int g = pData[y][x * 3 + 1]; 00185 int b = pData[y][x * 3 + 2]; 00186 return Color(r, g, b, true); 00187 00188 } 00189 break; 00190 } 00191 } 00192 /////////////////////////////////////////////////////////////////////////////// 00193 /// PNG_Writer 00194 /////////////////////////////////////////////////////////////////////////////// 00195 PNG_Writer::PNG_Writer(int _width, int _height, EPNG_TYPE type, string _fileName){ 00196 width = _width; 00197 height = _height; 00198 fileName = _fileName; 00199 00200 buffer.resize(width * height); 00201 switch(type){ 00202 case PNG_GRAY: 00203 color_type = 0; 00204 bit_depth = 8; 00205 rowbytes = width; 00206 break; 00207 case PNG_COLOR: 00208 color_type = 2; 00209 bit_depth = 8; 00210 rowbytes = width * 3; 00211 break; 00212 default: 00213 throw std::runtime_error(" TYPE DE FICHIER PNG NON SUPPORTE "); 00214 } 00215 pData = make_pixels(); 00216 } 00217 void PNG_Writer::write(){ 00218 for(int i = 0; i < height; i++){ 00219 for(int j = 0; j < width; j++){ 00220 _setColor(j, i, buffer[j + i * width]); 00221 } 00222 } 00223 FILE *fp; 00224 png_structp png_ptr; 00225 png_infop info_ptr; 00226 00227 fp = fopen(fileName.c_str(), "wb"); 00228 if (fp == NULL){ 00229 throw std::runtime_error(" ECRITURE FICHIER PNG " + fileName); 00230 } 00231 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 00232 if (png_ptr == NULL) { 00233 fclose(fp); 00234 throw std::runtime_error(" CREATION STRUCTURE D'ECRITURE PNG "); 00235 } 00236 info_ptr = png_create_info_struct(png_ptr); 00237 if (info_ptr == NULL) { 00238 fclose(fp); 00239 png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); 00240 throw std::runtime_error(" CREATION INFORMATION PNG "); 00241 } 00242 00243 if (setjmp(png_jmpbuf(png_ptr))) { 00244 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); 00245 fclose(fp); 00246 throw std::runtime_error(" CREATION INFORMATION INTERNE PNG "); 00247 } 00248 png_init_io(png_ptr, fp); 00249 switch(color_type){ 00250 case 0: 00251 png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, PNG_COLOR_TYPE_GRAY, 00252 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); 00253 break; 00254 case 2: 00255 png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, PNG_COLOR_TYPE_RGB, 00256 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); 00257 break; 00258 } 00259 png_set_rows(png_ptr, info_ptr, pData); 00260 png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, png_voidp_NULL); 00261 00262 fclose(fp); 00263 } 00264 00265 png_bytep* PNG_Writer::make_pixels() { 00266 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 00267 if (png_ptr == NULL) { 00268 throw std::runtime_error(" CREATION INFORMATION PNG "); 00269 } 00270 png_bytep *row_pointers = (unsigned char **)png_malloc(png_ptr, height*sizeof(png_bytep)); 00271 for (int i = 0; i < height; i++) 00272 row_pointers[i] = (unsigned char *)png_malloc(png_ptr, rowbytes); 00273 return row_pointers; 00274 } 00275 void PNG_Writer::_setColor(int x, int y, float gray){ 00276 switch(color_type){ 00277 case 0 : // GREY 00278 { 00279 pData[y][x] = (int)gray; 00280 } 00281 break; 00282 case 2 : // TRUE COLOR 00283 { 00284 pData[y][x * 3] = (int)gray; 00285 pData[y][x * 3 + 1] = (int)gray; 00286 pData[y][x * 3 + 2] = (int)gray; 00287 } 00288 break; 00289 } 00290 } 00291 void PNG_Writer::_setColor(int x, int y, float r, float g, float b){ 00292 Color p = Color(r, g, b, true); 00293 switch(color_type){ 00294 case 0 : // GREY 00295 { 00296 pData[y][x] = (int)p.getGray(); 00297 } 00298 break; 00299 case 2 : // TRUE COLOR 00300 { 00301 pData[y][x * 3] = (int)p.getRed(); 00302 pData[y][x * 3 + 1] = (int)p.getGreen(); 00303 pData[y][x * 3 + 2] = (int)p.getBlue(); 00304 } 00305 break; 00306 } 00307 } 00308 void PNG_Writer::_setColor(int x, int y, Color c){ 00309 switch(color_type){ 00310 case 0 : // GREY 00311 { 00312 pData[y][x] = (int)c.getGray(); 00313 } 00314 break; 00315 case 2 : // TRUE COLOR 00316 { 00317 pData[y][x * 3] = (int)c.getRed(); 00318 pData[y][x * 3 + 1] = (int)c.getGreen(); 00319 pData[y][x * 3 + 2] = (int)c.getBlue(); 00320 } 00321 break; 00322 } 00323 } 00324 void PNG_Writer::setColor(int x, int y, Color color){ 00325 buffer[y * width + x] = color; 00326 } 00327 void PNG_Writer::setColor(int x, int y, float gray){ 00328 Color c = Color(gray); 00329 buffer[y * width + x] = c; 00330 } 00331 void PNG_Writer::setColor(int x, int y, float r, float g, float b){ 00332 Color c = Color(r, g, b, true); 00333 buffer[y * width + x] = c; 00334 } 00335 00336 Color PNG_Writer::getColor(int x, int y) const{ 00337 return buffer[width * y + x]; 00338 }

Généré le Sun Jun 27 15:59:32 2004 pour segment par doxygen 1.3.7