fix compile against newer giflib
[rofl0r-obeditor.git] / src / images__pngFile.cpp
blob47ce50033a75d4bb5cfab888b9bfbf9895de6252
1 /*
2 * pngFile.cpp
4 * Created on: 11 nov. 2008
5 * Author: pat
6 */
8 //============================================================================
9 // Name : libpng_test.cpp
10 // Author :
11 // Version :
12 // Copyright : Your copyright notice
13 // Description : Hello World in C++, Ansi-style
14 //============================================================================
18 #include "wx/wxprec.h"
19 #ifndef WX_PRECOMP
20 #include "wx/wx.h"
21 #endif
23 #include <stdlib.h>
24 #include <iostream>
25 #include <wx/image.h>
26 #include <wx/palette.h>
28 #include "png.h"
29 #include "images__pngFile.h"
30 #include "images__MyPalette.h"
32 using namespace std;
35 //*************************************************
37 wxIndexedPNG::wxIndexedPNG()
39 Init();
43 //*************************************************
45 void wxIndexedPNG::Init()
47 type = pIMG_PNG;
49 width = height = 0;
50 bit_depth = 8;
51 color_type= 3;
52 interlace_type = 0;
53 compression_type = 0;
54 filter_method = 0;
56 palette = NULL;
57 num_palette = 0;
59 gamma = 0;
60 srgb_intent = 0;
62 trans = NULL;
63 num_trans = 0;
64 trans_values = NULL;
65 background = NULL;
67 row_pointers = NULL;
71 //*************************************************
73 wxIndexedPNG::~wxIndexedPNG()
75 Reset();
80 //*************************************************
82 void wxIndexedPNG::Reset()
84 if( palette != NULL )
85 delete[] palette;
87 if( trans != NULL )
88 delete[] trans;
90 if( trans_values != NULL )
91 delete trans_values;
93 if( row_pointers != NULL )
95 for( int i = 0; i < height; i++)
97 if( row_pointers[i] != NULL )
99 delete[] row_pointers[i];
102 delete[] row_pointers;
104 row_pointers = NULL;
108 //*************************************************
110 bool wxIndexedPNG::IsOk()
112 return !( palette == NULL || color_type != 3 || height == 0 || width == 0 || row_pointers == NULL );
116 //*************************************************
118 wxIndexedPNG::wxIndexedPNG( const wxString& str_pngFile )
120 Init();
121 LoadFrom( str_pngFile );
125 //*************************************************
127 wxIndexedPNG::wxIndexedPNG( wxImage& _image )
129 Init();
130 LoadFrom( _image );
134 //*************************************************
136 bool wxIndexedPNG::LoadFrom( const wxString& str_pngFile )
138 Reset();
139 return ReadPng( str_pngFile ) == 0;
143 //*************************************************
145 bool wxIndexedPNG::LoadFrom( wxImage& _img )
147 Reset();
148 if( ! _img.IsOk() )
149 return false;
151 // Some arg vérifications
152 wxPalette _pal = _img.GetPalette();
154 if( _img.GetHeight() <= 0 || _img.GetWidth() <= 0 )
155 return false;
157 // copy the palette
158 if( ! SetPalette( _pal ) )
159 return false;
161 // Get the dimensions
162 height = _img.GetHeight();
163 width = _img.GetWidth();
165 // Copy the image
166 row_pointers = new png_bytep[height];
167 for( int i = 0; i < height; i++)
169 row_pointers[i] = new png_byte[width];
170 for(int j=0; j< width; j++ )
172 // Getting the RGB of the pixel
173 unsigned char r = _img.GetRed( i,j);
174 unsigned char g = _img.GetGreen( i,j);
175 unsigned char b = _img.GetBlue( i,j);
177 // Getting the index of the current pixel
178 int _ind = _pal.GetPixel( r,g,b );
179 if( _ind == wxNOT_FOUND )
180 _ind = 0;
182 // Save the index
183 row_pointers[i][j] = (png_byte) _ind;
187 return true;
190 //*************************************************
192 int wxIndexedPNG::GetIndex( const int x, const int y)
194 if( !IsOk() || x >= width || y >= height )
195 return -1;
197 return row_pointers[y][x];
201 //*************************************************
203 MyPalette* wxIndexedPNG::GetPalette()
205 MyPalette *res = NULL;
206 if( !IsOk() )
207 return res;
210 unsigned char r[num_palette], g[num_palette], b[num_palette];
211 for( int i = 0; i < num_palette; i ++)
213 r[i] = palette[i].red;
214 g[i] = palette[i].green;
215 b[i] = palette[i].blue;
218 res = new MyPalette();
219 res->Create( num_palette, r, g, b );
220 return res;
224 //*************************************************
226 bool wxIndexedPNG::SetPalette( wxPalette _pal )
228 if( !IsOk() || !_pal.IsOk() || _pal.GetColoursCount() <= 0 || _pal.GetColoursCount() > 256 )
229 return false;
231 if( palette != NULL )
232 delete[] palette;
234 num_palette = _pal.GetColoursCount();
235 palette = new png_color[num_palette];
237 unsigned char r,g,b;
238 for( int i = 0; i < num_palette; i ++)
240 _pal.GetRGB( i, &r,&g,&b );
241 palette[i].red = r;
242 palette[i].green = g;
243 palette[i].blue = b;
245 return true;
249 //*************************************************
251 bool wxIndexedPNG::Remap( unsigned char *remap, int sz_remap )
253 if( ! IsOk() )
254 return false;
256 for( int i = 0; i < height; i++)
258 for(int j=0; j< width; j++ )
260 // Out of bound, remap too small
261 if( row_pointers[i][j] >= sz_remap )
262 return false;
264 row_pointers[i][j] = remap[ row_pointers[i][j] ];
267 return true;
270 //*************************************************
272 unsigned char * wxIndexedPNG::GetDatas( int& datas_size )
274 if( ! IsOk() )
276 datas_size = 0;
277 return NULL;
280 datas_size = height * width * sizeof(png_byte);
281 png_byte *res = new png_byte[ datas_size ];
283 for( int i = 0; i < height; i++)
285 for(int j=0; j< width; j++ )
287 res[i*width + j] = row_pointers[i][j];
291 return res;
295 //*************************************************
297 void wxIndexedPNG::SetDatas( unsigned char *_datas, int datas_size )
299 if( ! IsOk() || _datas == NULL || datas_size == 0 )
300 return;
302 datas_size = datas_size / sizeof(png_byte);
303 png_byte *datas = (png_byte*) _datas;
305 for( int i = 0; i < height; i++)
307 for(int j=0; j< width; j++ )
309 row_pointers[i][j] = datas[i*width + j];
315 //*************************************************
317 bool wxIndexedPNG::SetPixel( int x, int y, int ind )
319 if( ! IsOk() || x > width || y > height )
320 return false;
322 row_pointers[y][x] = ind;
323 return true;
327 //*************************************************
329 bool wxIndexedPNG::SaveAs( const wxString& str_pngFile )
331 return WritePng( str_pngFile ) == 0;
335 //*************************************************
337 int wxIndexedPNG::ReadPng( const wxString& str_fn)
339 FILE *fp = fopen((char*)str_fn.c_str(), "rb");
340 if (!fp)
341 return 1;
343 png_structp png_ptr = png_create_read_struct
344 (PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
345 NULL, NULL);
346 if (!png_ptr)
348 fclose(fp);
349 return 1;
352 png_infop info_ptr = png_create_info_struct(png_ptr);
353 if (!info_ptr)
355 png_destroy_read_struct(&png_ptr,
356 (png_infopp)NULL, (png_infopp)NULL);
357 fclose(fp);
358 return 1;
361 png_infop end_info = png_create_info_struct(png_ptr);
362 if (!end_info)
364 png_destroy_read_struct(&png_ptr, &info_ptr,
365 (png_infopp)NULL);
366 fclose(fp);
367 return 1;
370 if (setjmp(png_jmpbuf(png_ptr)))
372 png_destroy_read_struct(&png_ptr, &info_ptr,
373 &end_info);
374 fclose(fp);
375 Reset();
376 return 1;
379 png_init_io(png_ptr, fp);
381 png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY , NULL);
383 png_uint_32 t_width, t_height;
384 png_get_IHDR(png_ptr, info_ptr, &t_width, &t_height,
385 &bit_depth, &color_type, &interlace_type,
386 &compression_type, &filter_method);
387 width = t_width;
388 height = t_height;
390 // Handle only paletted png
391 if( color_type != PNG_COLOR_TYPE_PALETTE || width == 0 || height == 0)
393 png_destroy_read_struct(&png_ptr, &info_ptr,
394 &end_info);
395 fclose(fp);
396 Reset();
397 return 1;
400 png_byte *t_trans = NULL;
401 png_color_16 *t_background = NULL;
403 png_get_gAMA(png_ptr, info_ptr, &gamma);
404 png_get_sRGB(png_ptr, info_ptr, &srgb_intent);
405 png_get_tRNS(png_ptr, info_ptr, &t_trans, &num_trans, &trans_values);
406 png_get_bKGD(png_ptr, info_ptr, &t_background);
408 // Copy background and transvalues
409 if( t_background != NULL )
410 background = new png_color_16(*t_background);
412 if( num_trans > 0 )
414 trans = new png_byte[num_trans];
415 for( int i =0; i< num_trans; i++)
416 trans[i] = t_trans[i];
420 png_colorp t_palette = NULL;
421 png_get_PLTE(png_ptr, info_ptr, &t_palette,
422 &num_palette);
424 // Copy the palette
425 if( num_palette > 0 )
427 palette = new png_color[num_palette];
428 for( int i =0; i < num_palette; i++ )
429 palette[i] = t_palette[i];
433 png_read_update_info(png_ptr, info_ptr);
435 png_uint_32 rowbytes = png_get_rowbytes(png_ptr, info_ptr);
436 png_bytep *temp_row_pointers = png_get_rows(png_ptr, info_ptr);
437 row_pointers = new png_bytep[height];
438 for(int i=0;i<height;i++)
439 row_pointers[i] = new png_byte[rowbytes];
441 int color_found = 0;
442 png_byte prev_byte = 0;
443 for( int i = 0; i < height; i++ )
445 for( size_t j = 0; j < rowbytes; j++ )
447 row_pointers[i][j] = temp_row_pointers[i][j];
448 if( row_pointers[i][j] != prev_byte && color_found < 10)
450 prev_byte = row_pointers[i][j];
451 color_found ++;
452 cout << "coulor found at ("<< i <<","<< j<<") : " << (int)prev_byte << endl;
456 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
457 fclose( fp );
458 return 0;
462 //*************************************************
464 int wxIndexedPNG::WritePng( const wxString& str_fn )
465 { // Writing a copy from scratch
466 FILE *fp = fopen((char*)str_fn.c_str(), "wb");
467 if (!fp)
468 return 1;
470 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
471 if (!png_ptr)
473 fclose( fp );
474 return 1;
477 png_infop info_ptr = png_create_info_struct(png_ptr);
478 if (!info_ptr)
480 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
481 fclose( fp );
482 return 1;
485 if (setjmp(png_jmpbuf(png_ptr)))
487 png_destroy_write_struct(&png_ptr, &info_ptr );
488 fclose(fp);
489 Reset();
490 return 1;
494 png_init_io(png_ptr, fp);
496 png_set_IHDR(png_ptr, info_ptr, width, height,
497 bit_depth, color_type, interlace_type,
498 compression_type, filter_method);
500 if( palette != NULL )
501 png_set_PLTE(png_ptr, info_ptr, palette, num_palette);
503 png_set_gAMA(png_ptr, info_ptr, gamma);
504 png_set_sBIT(png_ptr, info_ptr, &sig_bit);
506 png_set_tRNS(png_ptr, info_ptr, trans, num_trans, trans_values);
508 if( background != NULL )
509 png_set_bKGD(png_ptr, info_ptr, background);
511 if( row_pointers != NULL )
512 png_set_rows( png_ptr, info_ptr, row_pointers);
514 png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
516 png_destroy_write_struct(&png_ptr, &info_ptr);
517 fclose( fp );
518 return 0;