Lines 15-21
Link Here
|
15 |
void CxImagePNG::ima_png_error(png_struct *png_ptr, char *message) |
15 |
void CxImagePNG::ima_png_error(png_struct *png_ptr, char *message) |
16 |
{ |
16 |
{ |
17 |
strcpy(info.szLastError,message); |
17 |
strcpy(info.szLastError,message); |
|
|
18 |
#if PNG_LIBPNG_VER > 10399 |
19 |
longjmp(png_jmpbuf(png_ptr), 1); |
20 |
#else |
18 |
longjmp(png_ptr->jmpbuf, 1); |
21 |
longjmp(png_ptr->jmpbuf, 1); |
|
|
22 |
#endif |
19 |
} |
23 |
} |
20 |
//////////////////////////////////////////////////////////////////////////////// |
24 |
//////////////////////////////////////////////////////////////////////////////// |
21 |
#if CXIMAGE_SUPPORT_DECODE |
25 |
#if CXIMAGE_SUPPORT_DECODE |
Lines 62-68
Link Here
|
62 |
/* Set error handling if you are using the setjmp/longjmp method (this is |
66 |
/* Set error handling if you are using the setjmp/longjmp method (this is |
63 |
* the normal method of doing things with libpng). REQUIRED unless you |
67 |
* the normal method of doing things with libpng). REQUIRED unless you |
64 |
* set up your own error handlers in the png_create_read_struct() earlier. */ |
68 |
* set up your own error handlers in the png_create_read_struct() earlier. */ |
|
|
69 |
#if PNG_LIBPNG_VER > 10399 |
70 |
if (setjmp(png_jmpbuf(png_ptr))) { |
71 |
#else |
65 |
if (setjmp(png_ptr->jmpbuf)) { |
72 |
if (setjmp(png_ptr->jmpbuf)) { |
|
|
73 |
#endif |
66 |
/* Free all of the memory associated with the png_ptr and info_ptr */ |
74 |
/* Free all of the memory associated with the png_ptr and info_ptr */ |
67 |
delete [] row_pointers; |
75 |
delete [] row_pointers; |
68 |
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); |
76 |
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); |
Lines 70-91
Link Here
|
70 |
} |
78 |
} |
71 |
|
79 |
|
72 |
// use custom I/O functions |
80 |
// use custom I/O functions |
73 |
png_set_read_fn(png_ptr, hFile, /*(png_rw_ptr)*/user_read_data); |
81 |
png_set_read_fn(png_ptr, hFile, /*(png_rw_ptr)*/user_read_data); |
74 |
png_set_error_fn(png_ptr,info.szLastError,/*(png_error_ptr)*/user_error_fn,NULL); |
82 |
png_set_error_fn(png_ptr,info.szLastError,/*(png_error_ptr)*/user_error_fn,NULL); |
75 |
|
83 |
|
76 |
/* read the file information */ |
84 |
/* read the file information */ |
77 |
png_read_info(png_ptr, info_ptr); |
85 |
png_read_info(png_ptr, info_ptr); |
78 |
|
86 |
|
|
|
87 |
png_uint_32 _width,_height; |
88 |
int _bit_depth,_color_type,_interlace_type,_compression_type,_filter_type; |
89 |
#if PNG_LIBPNG_VER > 10399 |
90 |
png_get_IHDR(png_ptr,info_ptr,&_width,&_height,&_bit_depth,&_color_type, |
91 |
&_interlace_type,&_compression_type,&_filter_type); |
92 |
#else |
93 |
_width=info_ptr->width; |
94 |
_height=info_ptr->height; |
95 |
_bit_depth=info_ptr->bit_depth; |
96 |
_color_type=info_ptr->color_type; |
97 |
_interlace_type=info_ptr->interlace_type; |
98 |
_compression_type=info_ptr->compression_type; |
99 |
_filter_type=info_ptr->filter_type; |
100 |
#endif |
101 |
|
79 |
if (info.nEscape == -1){ |
102 |
if (info.nEscape == -1){ |
80 |
head.biWidth = info_ptr->width; |
103 |
head.biWidth = _width; |
81 |
head.biHeight= info_ptr->height; |
104 |
head.biHeight= _height; |
82 |
info.dwType = CXIMAGE_FORMAT_PNG; |
105 |
info.dwType = CXIMAGE_FORMAT_PNG; |
|
|
106 |
#if PNG_LIBPNG_VER > 10399 |
107 |
longjmp(png_jmpbuf(png_ptr), 1); |
108 |
#else |
83 |
longjmp(png_ptr->jmpbuf, 1); |
109 |
longjmp(png_ptr->jmpbuf, 1); |
|
|
110 |
#endif |
84 |
} |
111 |
} |
85 |
|
112 |
|
86 |
/* calculate new number of channels */ |
113 |
/* calculate new number of channels */ |
87 |
int channels=0; |
114 |
int channels=0; |
88 |
switch(info_ptr->color_type){ |
115 |
switch(_color_type){ |
89 |
case PNG_COLOR_TYPE_GRAY: |
116 |
case PNG_COLOR_TYPE_GRAY: |
90 |
case PNG_COLOR_TYPE_PALETTE: |
117 |
case PNG_COLOR_TYPE_PALETTE: |
91 |
channels = 1; |
118 |
channels = 1; |
Lines 101-171
Link Here
|
101 |
break; |
128 |
break; |
102 |
default: |
129 |
default: |
103 |
strcpy(info.szLastError,"unknown PNG color type"); |
130 |
strcpy(info.szLastError,"unknown PNG color type"); |
|
|
131 |
#if PNG_LIBPNG_VER > 10399 |
132 |
longjmp(png_jmpbuf(png_ptr), 1); |
133 |
#else |
104 |
longjmp(png_ptr->jmpbuf, 1); |
134 |
longjmp(png_ptr->jmpbuf, 1); |
|
|
135 |
#endif |
105 |
} |
136 |
} |
106 |
|
137 |
|
107 |
//find the right pixel depth used for cximage |
138 |
//find the right pixel depth used for cximage |
|
|
139 |
#if PNG_LIBPNG_VER > 10399 |
140 |
int pixel_depth = _bit_depth * png_get_channels(png_ptr,info_ptr); |
141 |
#else |
108 |
int pixel_depth = info_ptr->pixel_depth; |
142 |
int pixel_depth = info_ptr->pixel_depth; |
|
|
143 |
#endif |
109 |
if (channels == 1 && pixel_depth>8) pixel_depth=8; |
144 |
if (channels == 1 && pixel_depth>8) pixel_depth=8; |
110 |
if (channels == 2) pixel_depth=8; |
145 |
if (channels == 2) pixel_depth=8; |
111 |
if (channels >= 3) pixel_depth=24; |
146 |
if (channels >= 3) pixel_depth=24; |
112 |
|
147 |
|
113 |
if (!Create(info_ptr->width, info_ptr->height, pixel_depth, CXIMAGE_FORMAT_PNG)){ |
148 |
if (!Create(_width, _height, pixel_depth, CXIMAGE_FORMAT_PNG)){ |
|
|
149 |
#if PNG_LIBPNG_VER > 10399 |
150 |
longjmp(png_jmpbuf(png_ptr), 1); |
151 |
#else |
114 |
longjmp(png_ptr->jmpbuf, 1); |
152 |
longjmp(png_ptr->jmpbuf, 1); |
|
|
153 |
#endif |
115 |
} |
154 |
} |
116 |
|
155 |
|
117 |
/* get metrics */ |
156 |
/* get metrics */ |
118 |
switch (info_ptr->phys_unit_type) |
157 |
png_uint_32 _x_pixels_per_unit,_y_pixels_per_unit; |
|
|
158 |
int _phys_unit_type; |
159 |
#if PNG_LIBPNG_VER > 10399 |
160 |
png_get_pHYs(png_ptr,info_ptr,&_x_pixels_per_unit,&_y_pixels_per_unit,&_phys_unit_type); |
161 |
#else |
162 |
_x_pixels_per_unit=info_ptr->x_pixels_per_unit; |
163 |
_y_pixels_per_unit=info_ptr->y_pixels_per_unit; |
164 |
_phys_unit_type=info_ptr->phys_unit_type; |
165 |
#endif |
166 |
switch (_phys_unit_type) |
119 |
{ |
167 |
{ |
120 |
case PNG_RESOLUTION_UNKNOWN: |
168 |
case PNG_RESOLUTION_UNKNOWN: |
121 |
SetXDPI(info_ptr->x_pixels_per_unit); |
169 |
SetXDPI(_x_pixels_per_unit); |
122 |
SetYDPI(info_ptr->y_pixels_per_unit); |
170 |
SetYDPI(_y_pixels_per_unit); |
123 |
break; |
171 |
break; |
124 |
case PNG_RESOLUTION_METER: |
172 |
case PNG_RESOLUTION_METER: |
125 |
SetXDPI((long)floor(info_ptr->x_pixels_per_unit * 254.0 / 10000.0 + 0.5)); |
173 |
SetXDPI((long)floor(_x_pixels_per_unit * 254.0 / 10000.0 + 0.5)); |
126 |
SetYDPI((long)floor(info_ptr->y_pixels_per_unit * 254.0 / 10000.0 + 0.5)); |
174 |
SetYDPI((long)floor(_y_pixels_per_unit * 254.0 / 10000.0 + 0.5)); |
127 |
break; |
175 |
break; |
128 |
} |
176 |
} |
129 |
|
177 |
|
130 |
if (info_ptr->num_palette>0){ |
178 |
int _num_palette; |
131 |
SetPalette((rgb_color*)info_ptr->palette,info_ptr->num_palette); |
179 |
png_colorp _palette; |
132 |
SetClrImportant(info_ptr->num_palette); |
180 |
#if PNG_LIBPNG_VER > 10399 |
133 |
} else if (info_ptr->bit_depth ==2) { //<DP> needed for 2 bpp grayscale PNGs |
181 |
png_get_PLTE(png_ptr,info_ptr,&_palette,&_num_palette); |
|
|
182 |
#else |
183 |
_num_palette=info_ptr->num_palette; |
184 |
_palette=info_ptr->palette; |
185 |
#endif |
186 |
if (_num_palette>0){ |
187 |
SetPalette((rgb_color*)_palette,_num_palette); |
188 |
SetClrImportant(_num_palette); |
189 |
} else if (_bit_depth ==2) { //<DP> needed for 2 bpp grayscale PNGs |
134 |
SetPaletteColor(0,0,0,0); |
190 |
SetPaletteColor(0,0,0,0); |
135 |
SetPaletteColor(1,85,85,85); |
191 |
SetPaletteColor(1,85,85,85); |
136 |
SetPaletteColor(2,170,170,170); |
192 |
SetPaletteColor(2,170,170,170); |
137 |
SetPaletteColor(3,255,255,255); |
193 |
SetPaletteColor(3,255,255,255); |
138 |
} else SetGrayPalette(); //<DP> needed for grayscale PNGs |
194 |
} else SetGrayPalette(); //<DP> needed for grayscale PNGs |
139 |
|
195 |
|
140 |
int nshift = max(0,(info_ptr->bit_depth>>3)-1)<<3; |
196 |
int nshift = max(0,(_bit_depth>>3)-1)<<3; |
141 |
|
197 |
|
142 |
if (info_ptr->num_trans!=0){ //palette transparency |
198 |
png_bytep _trans_alpha; |
143 |
if (info_ptr->num_trans==1){ |
199 |
int _num_trans; |
144 |
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE){ |
200 |
png_color_16p _trans_color; |
|
|
201 |
#if PNG_LIBPNG_VER > 10399 |
202 |
png_get_tRNS(png_ptr,info_ptr,&_trans_alpha,&_num_trans,&_trans_color); |
203 |
#else |
204 |
_num_trans=info_ptr->num_trans; |
205 |
#endif |
206 |
if (_num_trans!=0){ //palette transparency |
207 |
if (_num_trans==1){ |
208 |
if (_color_type == PNG_COLOR_TYPE_PALETTE){ |
145 |
#if PNG_LIBPNG_VER > 10399 |
209 |
#if PNG_LIBPNG_VER > 10399 |
146 |
info.nBkgndIndex = info_ptr->trans_color.index; |
210 |
info.nBkgndIndex = _trans_color->index; |
147 |
#else |
211 |
#else |
148 |
info.nBkgndIndex = info_ptr->trans_values.index; |
212 |
info.nBkgndIndex = info_ptr->trans_values.index; |
149 |
#endif |
213 |
#endif |
150 |
} else{ |
214 |
} else{ |
151 |
#if PNG_LIBPNG_VER > 10399 |
215 |
#if PNG_LIBPNG_VER > 10399 |
152 |
info.nBkgndIndex = info_ptr->trans_color.gray>>nshift; |
216 |
info.nBkgndIndex = _trans_color->gray>>nshift; |
153 |
#else |
217 |
#else |
154 |
info.nBkgndIndex = info_ptr->trans_values.gray>>nshift; |
218 |
info.nBkgndIndex = info_ptr->trans_values.gray>>nshift; |
155 |
#endif |
219 |
#endif |
156 |
} |
220 |
} |
157 |
} |
221 |
} |
158 |
if (info_ptr->num_trans>1){ |
222 |
if (_num_trans>1){ |
159 |
RGBQUAD* pal=GetPalette(); |
223 |
RGBQUAD* pal=GetPalette(); |
160 |
if (pal){ |
224 |
if (pal){ |
161 |
DWORD ip; |
225 |
DWORD ip; |
162 |
for (ip=0;ip<min(head.biClrUsed,(unsigned long)info_ptr->num_trans);ip++) |
226 |
for (ip=0;ip<min(head.biClrUsed,(unsigned long)_num_trans);ip++) |
163 |
#if PNG_LIBPNG_VER > 10399 |
227 |
#if PNG_LIBPNG_VER > 10399 |
164 |
pal[ip].rgbReserved=info_ptr->trans_alpha[ip]; |
228 |
pal[ip].rgbReserved=_trans_alpha[ip]; |
165 |
#else |
229 |
#else |
166 |
pal[ip].rgbReserved=info_ptr->trans[ip]; |
230 |
pal[ip].rgbReserved=info_ptr->trans[ip]; |
167 |
#endif |
231 |
#endif |
168 |
for (ip=info_ptr->num_trans;ip<head.biClrUsed;ip++){ |
232 |
for (ip=_num_trans;ip<head.biClrUsed;ip++){ |
169 |
pal[ip].rgbReserved=255; |
233 |
pal[ip].rgbReserved=255; |
170 |
} |
234 |
} |
171 |
info.bAlphaPaletteEnabled=true; |
235 |
info.bAlphaPaletteEnabled=true; |
Lines 174-187
Link Here
|
174 |
} |
238 |
} |
175 |
|
239 |
|
176 |
if (channels == 3){ //check RGB binary transparency |
240 |
if (channels == 3){ //check RGB binary transparency |
177 |
png_bytep trans; |
241 |
/* seems unnecessary to call again, but the conditional must be important so... */ |
178 |
int num_trans; |
242 |
if (png_get_tRNS(png_ptr,info_ptr,&_trans_alpha,&_num_trans,&_trans_color)){ |
179 |
png_color_16 *image_background; |
243 |
#if PNG_LIBPNG_VER > 10399 |
180 |
if (png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &image_background)){ |
244 |
info.nBkgndColor.rgbRed = (BYTE)(_trans_color->red>>nshift); |
181 |
#if PNG_LIBPNG_VER > 10399 |
245 |
info.nBkgndColor.rgbGreen = (BYTE)(_trans_color->green>>nshift); |
182 |
info.nBkgndColor.rgbRed = (BYTE)(info_ptr->trans_color.red>>nshift); |
246 |
info.nBkgndColor.rgbBlue = (BYTE)(_trans_color->blue>>nshift); |
183 |
info.nBkgndColor.rgbGreen = (BYTE)(info_ptr->trans_color.green>>nshift); |
|
|
184 |
info.nBkgndColor.rgbBlue = (BYTE)(info_ptr->trans_color.blue>>nshift); |
185 |
#else |
247 |
#else |
186 |
info.nBkgndColor.rgbRed = (BYTE)(info_ptr->trans_values.red>>nshift); |
248 |
info.nBkgndColor.rgbRed = (BYTE)(info_ptr->trans_values.red>>nshift); |
187 |
info.nBkgndColor.rgbGreen = (BYTE)(info_ptr->trans_values.green>>nshift); |
249 |
info.nBkgndColor.rgbGreen = (BYTE)(info_ptr->trans_values.green>>nshift); |
Lines 202-216
Link Here
|
202 |
} |
264 |
} |
203 |
|
265 |
|
204 |
// <vho> - flip the RGB pixels to BGR (or RGBA to BGRA) |
266 |
// <vho> - flip the RGB pixels to BGR (or RGBA to BGRA) |
205 |
if (info_ptr->color_type & PNG_COLOR_MASK_COLOR){ |
267 |
if (_color_type & PNG_COLOR_MASK_COLOR){ |
206 |
png_set_bgr(png_ptr); |
268 |
png_set_bgr(png_ptr); |
207 |
} |
269 |
} |
208 |
|
270 |
|
209 |
// <vho> - handle cancel |
271 |
// <vho> - handle cancel |
210 |
if (info.nEscape) longjmp(png_ptr->jmpbuf, 1); |
272 |
if (info.nEscape) |
|
|
273 |
#if PNG_LIBPNG_VER > 10399 |
274 |
longjmp(png_jmpbuf(png_ptr), 1); |
275 |
#else |
276 |
longjmp(png_ptr->jmpbuf, 1); |
277 |
#endif |
211 |
|
278 |
|
212 |
// row_bytes is the width x number of channels x (bit-depth / 8) |
279 |
// row_bytes is the width x number of channels x (bit-depth / 8) |
|
|
280 |
#if PNG_LIBPNG_VER > 10399 |
281 |
row_pointers = new BYTE[png_get_rowbytes(png_ptr,info_ptr) + 8]; |
282 |
#else |
213 |
row_pointers = new BYTE[info_ptr->rowbytes + 8]; |
283 |
row_pointers = new BYTE[info_ptr->rowbytes + 8]; |
|
|
284 |
#endif |
214 |
|
285 |
|
215 |
// turn on interlace handling |
286 |
// turn on interlace handling |
216 |
int number_passes = png_set_interlace_handling(png_ptr); |
287 |
int number_passes = png_set_interlace_handling(png_ptr); |
Lines 221-228
Link Here
|
221 |
SetCodecOption(0); |
292 |
SetCodecOption(0); |
222 |
} |
293 |
} |
223 |
|
294 |
|
224 |
int chan_offset = info_ptr->bit_depth >> 3; |
295 |
int chan_offset = _bit_depth >> 3; |
|
|
296 |
#if PNG_LIBPNG_VER > 10399 |
297 |
int pixel_offset = (_bit_depth * png_get_channels(png_ptr,info_ptr)) >> 3; |
298 |
#else |
225 |
int pixel_offset = info_ptr->pixel_depth >> 3; |
299 |
int pixel_offset = info_ptr->pixel_depth >> 3; |
|
|
300 |
#endif |
226 |
|
301 |
|
227 |
for (int pass=0; pass < number_passes; pass++) { |
302 |
for (int pass=0; pass < number_passes; pass++) { |
228 |
iter.Upset(); |
303 |
iter.Upset(); |
Lines 230-236
Link Here
|
230 |
do { |
305 |
do { |
231 |
|
306 |
|
232 |
// <vho> - handle cancel |
307 |
// <vho> - handle cancel |
233 |
if (info.nEscape) longjmp(png_ptr->jmpbuf, 1); |
308 |
if (info.nEscape) |
|
|
309 |
#if PNG_LIBPNG_VER > 10399 |
310 |
longjmp(png_jmpbuf(png_ptr), 1); |
311 |
#else |
312 |
longjmp(png_ptr->jmpbuf, 1); |
313 |
#endif |
234 |
|
314 |
|
235 |
#if CXIMAGE_SUPPORT_ALPHA // <vho> |
315 |
#if CXIMAGE_SUPPORT_ALPHA // <vho> |
236 |
if (AlphaIsValid()) { |
316 |
if (AlphaIsValid()) { |
Lines 241-247
Link Here
|
241 |
BYTE* prow= iter.GetRow(ay); |
321 |
BYTE* prow= iter.GetRow(ay); |
242 |
|
322 |
|
243 |
//recover data from previous scan |
323 |
//recover data from previous scan |
244 |
if (info_ptr->interlace_type && pass>0 && pass!=7){ |
324 |
if (_interlace_type && pass>0 && pass!=7){ |
245 |
for(ax=0;ax<head.biWidth;ax++){ |
325 |
for(ax=0;ax<head.biWidth;ax++){ |
246 |
long px = ax * pixel_offset; |
326 |
long px = ax * pixel_offset; |
247 |
if (channels == 2){ |
327 |
if (channels == 2){ |
Lines 278-287
Link Here
|
278 |
#endif // CXIMAGE_SUPPORT_ALPHA // vho |
358 |
#endif // CXIMAGE_SUPPORT_ALPHA // vho |
279 |
{ |
359 |
{ |
280 |
//recover data from previous scan |
360 |
//recover data from previous scan |
281 |
if (info_ptr->interlace_type && pass>0){ |
361 |
if (_interlace_type && pass>0){ |
|
|
362 |
#if PNG_LIBPNG_VER > 10399 |
363 |
iter.GetRow(row_pointers, png_get_rowbytes(png_ptr,info_ptr)); |
364 |
#else |
282 |
iter.GetRow(row_pointers, info_ptr->rowbytes); |
365 |
iter.GetRow(row_pointers, info_ptr->rowbytes); |
|
|
366 |
#endif |
283 |
//re-expand buffer for images with bit depth > 8 |
367 |
//re-expand buffer for images with bit depth > 8 |
284 |
if (info_ptr->bit_depth > 8){ |
368 |
if (_bit_depth > 8){ |
285 |
for(long ax=(head.biWidth*channels-1);ax>=0;ax--) |
369 |
for(long ax=(head.biWidth*channels-1);ax>=0;ax--) |
286 |
row_pointers[ax*chan_offset] = row_pointers[ax]; |
370 |
row_pointers[ax*chan_offset] = row_pointers[ax]; |
287 |
} |
371 |
} |
Lines 291-305
Link Here
|
291 |
png_read_row(png_ptr, row_pointers, NULL); |
375 |
png_read_row(png_ptr, row_pointers, NULL); |
292 |
|
376 |
|
293 |
//shrink 16 bit depth images down to 8 bits |
377 |
//shrink 16 bit depth images down to 8 bits |
294 |
if (info_ptr->bit_depth > 8){ |
378 |
if (_bit_depth > 8){ |
295 |
for(long ax=0;ax<(head.biWidth*channels);ax++) |
379 |
for(long ax=0;ax<(head.biWidth*channels);ax++) |
296 |
row_pointers[ax] = row_pointers[ax*chan_offset]; |
380 |
row_pointers[ax] = row_pointers[ax*chan_offset]; |
297 |
} |
381 |
} |
298 |
|
382 |
|
299 |
//copy the pixels |
383 |
//copy the pixels |
|
|
384 |
#if PNG_LIBPNG_VER > 10399 |
385 |
iter.SetRow(row_pointers, png_get_rowbytes(png_ptr,info_ptr)); |
386 |
#else |
300 |
iter.SetRow(row_pointers, info_ptr->rowbytes); |
387 |
iter.SetRow(row_pointers, info_ptr->rowbytes); |
|
|
388 |
#endif |
301 |
//<DP> expand 2 bpp images only in the last pass |
389 |
//<DP> expand 2 bpp images only in the last pass |
302 |
if (info_ptr->bit_depth==2 && pass==(number_passes-1)) |
390 |
if (_bit_depth==2 && pass==(number_passes-1)) |
303 |
expand2to4bpp(iter.GetRow()); |
391 |
expand2to4bpp(iter.GetRow()); |
304 |
|
392 |
|
305 |
//go on |
393 |
//go on |
Lines 361-369
Link Here
|
361 |
/* Set error handling. REQUIRED if you aren't supplying your own |
449 |
/* Set error handling. REQUIRED if you aren't supplying your own |
362 |
* error hadnling functions in the png_create_write_struct() call. |
450 |
* error hadnling functions in the png_create_write_struct() call. |
363 |
*/ |
451 |
*/ |
|
|
452 |
#if PNG_LIBPNG_VER > 10399 |
453 |
if (setjmp(png_jmpbuf(png_ptr))){ |
454 |
#else |
364 |
if (setjmp(png_ptr->jmpbuf)){ |
455 |
if (setjmp(png_ptr->jmpbuf)){ |
365 |
/* If we get here, we had a problem reading the file */ |
456 |
/* If we get here, we had a problem reading the file */ |
366 |
if (info_ptr->palette) free(info_ptr->palette); |
457 |
if (info_ptr->palette) free(info_ptr->palette); |
|
|
458 |
#endif |
367 |
png_destroy_write_struct(&png_ptr, (png_infopp)&info_ptr); |
459 |
png_destroy_write_struct(&png_ptr, (png_infopp)&info_ptr); |
368 |
cx_throw("Error saving PNG file"); |
460 |
cx_throw("Error saving PNG file"); |
369 |
} |
461 |
} |
Lines 372-380
Link Here
|
372 |
//png_init_io(png_ptr, hFile); |
464 |
//png_init_io(png_ptr, hFile); |
373 |
|
465 |
|
374 |
// use custom I/O functions |
466 |
// use custom I/O functions |
375 |
png_set_write_fn(png_ptr,hFile,/*(png_rw_ptr)*/user_write_data,/*(png_flush_ptr)*/user_flush_data); |
467 |
png_set_write_fn(png_ptr,hFile,/*(png_rw_ptr)*/user_write_data,/*(png_flush_ptr)*/user_flush_data); |
376 |
|
468 |
|
377 |
/* set the file information here */ |
469 |
/* set the file information here */ |
|
|
470 |
#if PNG_LIBPNG_VER > 10399 |
471 |
/* use variables to hold the values so it isnt necessary to png_get them later */ |
472 |
png_uint_32 _width,_height; |
473 |
int _bit_depth,_color_type,_interlace_type,_compression_type,_filter_type; |
474 |
png_byte _channels,_pixel_depth; |
475 |
|
476 |
_width = GetWidth(); |
477 |
_height = GetHeight(); |
478 |
_pixel_depth = (BYTE)GetBpp(); |
479 |
_channels = (GetBpp()>8) ? (BYTE)3: (BYTE)1; |
480 |
_bit_depth = (BYTE)(GetBpp()/_channels); |
481 |
_compression_type = PNG_COMPRESSION_TYPE_DEFAULT; |
482 |
_filter_type = PNG_FILTER_TYPE_DEFAULT; |
483 |
#else |
378 |
info_ptr->width = GetWidth(); |
484 |
info_ptr->width = GetWidth(); |
379 |
info_ptr->height = GetHeight(); |
485 |
info_ptr->height = GetHeight(); |
380 |
info_ptr->pixel_depth = (BYTE)GetBpp(); |
486 |
info_ptr->pixel_depth = (BYTE)GetBpp(); |
Lines 382-394
Link Here
|
382 |
info_ptr->bit_depth = (BYTE)(GetBpp()/info_ptr->channels); |
488 |
info_ptr->bit_depth = (BYTE)(GetBpp()/info_ptr->channels); |
383 |
info_ptr->compression_type = info_ptr->filter_type = 0; |
489 |
info_ptr->compression_type = info_ptr->filter_type = 0; |
384 |
info_ptr->valid = 0; |
490 |
info_ptr->valid = 0; |
|
|
491 |
#endif |
385 |
|
492 |
|
386 |
switch(GetCodecOption(CXIMAGE_FORMAT_PNG)){ |
493 |
switch(GetCodecOption(CXIMAGE_FORMAT_PNG)){ |
387 |
case 1: |
494 |
case 1: |
|
|
495 |
#if PNG_LIBPNG_VER > 10399 |
496 |
_interlace_type = PNG_INTERLACE_ADAM7; |
497 |
#else |
388 |
info_ptr->interlace_type = PNG_INTERLACE_ADAM7; |
498 |
info_ptr->interlace_type = PNG_INTERLACE_ADAM7; |
|
|
499 |
#endif |
389 |
break; |
500 |
break; |
390 |
default: |
501 |
default: |
|
|
502 |
#if PNG_LIBPNG_VER > 10399 |
503 |
_interlace_type = PNG_INTERLACE_NONE; |
504 |
#else |
391 |
info_ptr->interlace_type = PNG_INTERLACE_NONE; |
505 |
info_ptr->interlace_type = PNG_INTERLACE_NONE; |
|
|
506 |
#endif |
392 |
} |
507 |
} |
393 |
|
508 |
|
394 |
/* set compression level */ |
509 |
/* set compression level */ |
Lines 398-419
Link Here
|
398 |
|
513 |
|
399 |
if (GetNumColors()){ |
514 |
if (GetNumColors()){ |
400 |
if (bGrayScale){ |
515 |
if (bGrayScale){ |
|
|
516 |
#if PNG_LIBPNG_VER > 10399 |
517 |
_color_type = PNG_COLOR_TYPE_GRAY; |
518 |
#else |
401 |
info_ptr->color_type = PNG_COLOR_TYPE_GRAY; |
519 |
info_ptr->color_type = PNG_COLOR_TYPE_GRAY; |
|
|
520 |
#endif |
402 |
} else { |
521 |
} else { |
|
|
522 |
#if PNG_LIBPNG_VER > 10399 |
523 |
_color_type = PNG_COLOR_TYPE_PALETTE; |
524 |
#else |
403 |
info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; |
525 |
info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; |
|
|
526 |
#endif |
404 |
} |
527 |
} |
405 |
} else { |
528 |
} else { |
|
|
529 |
#if PNG_LIBPNG_VER > 10399 |
530 |
_color_type = PNG_COLOR_TYPE_RGB; |
531 |
#else |
406 |
info_ptr->color_type = PNG_COLOR_TYPE_RGB; |
532 |
info_ptr->color_type = PNG_COLOR_TYPE_RGB; |
|
|
533 |
#endif |
407 |
} |
534 |
} |
408 |
#if CXIMAGE_SUPPORT_ALPHA |
535 |
#if CXIMAGE_SUPPORT_ALPHA |
409 |
if (AlphaIsValid()){ |
536 |
if (AlphaIsValid()){ |
|
|
537 |
#if PNG_LIBPNG_VER > 10399 |
538 |
_color_type |= PNG_COLOR_MASK_ALPHA; |
539 |
_channels++; |
540 |
_bit_depth = 8; |
541 |
_pixel_depth += 8; |
542 |
#else |
410 |
info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; |
543 |
info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; |
411 |
info_ptr->channels++; |
544 |
info_ptr->channels++; |
412 |
info_ptr->bit_depth = 8; |
545 |
info_ptr->bit_depth = 8; |
413 |
info_ptr->pixel_depth += 8; |
546 |
info_ptr->pixel_depth += 8; |
|
|
547 |
#endif |
414 |
} |
548 |
} |
415 |
#endif |
549 |
#endif |
416 |
|
550 |
|
|
|
551 |
#if PNG_LIBPNG_VER > 10399 |
552 |
/* set the header here, since we're done modifying these values */ |
553 |
png_set_IHDR(png_ptr,info_ptr,_width,_height,_bit_depth,_color_type,_interlace_type, |
554 |
_compression_type,_filter_type); |
555 |
#endif |
556 |
|
417 |
/* set background */ |
557 |
/* set background */ |
418 |
png_color_16 image_background={ 0, 255, 255, 255, 0 }; |
558 |
png_color_16 image_background={ 0, 255, 255, 255, 0 }; |
419 |
RGBQUAD tc = GetTransColor(); |
559 |
RGBQUAD tc = GetTransColor(); |
Lines 427-448
Link Here
|
427 |
/* set metrics */ |
567 |
/* set metrics */ |
428 |
png_set_pHYs(png_ptr, info_ptr, head.biXPelsPerMeter, head.biYPelsPerMeter, PNG_RESOLUTION_METER); |
568 |
png_set_pHYs(png_ptr, info_ptr, head.biXPelsPerMeter, head.biYPelsPerMeter, PNG_RESOLUTION_METER); |
429 |
|
569 |
|
|
|
570 |
#if PNG_LIBPNG_VER <= 10399 |
430 |
png_set_IHDR(png_ptr, info_ptr, info_ptr->width, info_ptr->height, info_ptr->bit_depth, |
571 |
png_set_IHDR(png_ptr, info_ptr, info_ptr->width, info_ptr->height, info_ptr->bit_depth, |
431 |
info_ptr->color_type, info_ptr->interlace_type, |
572 |
info_ptr->color_type, info_ptr->interlace_type, |
432 |
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); |
573 |
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); |
|
|
574 |
#endif |
433 |
|
575 |
|
434 |
//<DP> simple transparency |
576 |
//<DP> simple transparency |
435 |
if (info.nBkgndIndex >= 0){ |
577 |
if (info.nBkgndIndex >= 0){ |
436 |
info_ptr->num_trans = 1; |
|
|
437 |
info_ptr->valid |= PNG_INFO_tRNS; |
438 |
#if PNG_LIBPNG_VER > 10399 |
578 |
#if PNG_LIBPNG_VER > 10399 |
439 |
info_ptr->trans_alpha = trans; |
579 |
png_color_16 _trans_color; |
440 |
info_ptr->trans_color.index = (BYTE)info.nBkgndIndex; |
580 |
_trans_color.index = (BYTE)info.nBkgndIndex; |
441 |
info_ptr->trans_color.red = tc.rgbRed; |
581 |
_trans_color.red = tc.rgbRed; |
442 |
info_ptr->trans_color.green = tc.rgbGreen; |
582 |
_trans_color.green = tc.rgbGreen; |
443 |
info_ptr->trans_color.blue = tc.rgbBlue; |
583 |
_trans_color.blue = tc.rgbBlue; |
444 |
info_ptr->trans_color.gray = info_ptr->trans_color.index; |
584 |
_trans_color.gray = _trans_color.index; |
445 |
#else |
585 |
#else |
|
|
586 |
info_ptr->num_trans = 1; |
587 |
info_ptr->valid |= PNG_INFO_tRNS; |
446 |
info_ptr->trans = trans; |
588 |
info_ptr->trans = trans; |
447 |
info_ptr->trans_values.index = (BYTE)info.nBkgndIndex; |
589 |
info_ptr->trans_values.index = (BYTE)info.nBkgndIndex; |
448 |
info_ptr->trans_values.red = tc.rgbRed; |
590 |
info_ptr->trans_values.red = tc.rgbRed; |
Lines 454-487
Link Here
|
454 |
// the transparency indexes start from 0 for non grayscale palette |
596 |
// the transparency indexes start from 0 for non grayscale palette |
455 |
if (!bGrayScale && head.biClrUsed && info.nBkgndIndex) |
597 |
if (!bGrayScale && head.biClrUsed && info.nBkgndIndex) |
456 |
SwapIndex(0,(BYTE)info.nBkgndIndex); |
598 |
SwapIndex(0,(BYTE)info.nBkgndIndex); |
|
|
599 |
|
600 |
#if PNG_LIBPNG_VER > 10399 |
601 |
png_set_tRNS(png_ptr,info_ptr,(png_bytep)trans,1,&_trans_color); |
602 |
#endif |
457 |
} |
603 |
} |
458 |
|
604 |
|
459 |
/* set the palette if there is one */ |
605 |
/* set the palette if there is one */ |
|
|
606 |
#if PNG_LIBPNG_VER > 10399 |
607 |
png_colorp _palette; |
608 |
#endif |
460 |
if (GetPalette()){ |
609 |
if (GetPalette()){ |
|
|
610 |
#if PNG_LIBPNG_VER <= 10399 |
461 |
if (!bGrayScale){ |
611 |
if (!bGrayScale){ |
462 |
info_ptr->valid |= PNG_INFO_PLTE; |
612 |
info_ptr->valid |= PNG_INFO_PLTE; |
463 |
} |
613 |
} |
|
|
614 |
#endif |
464 |
|
615 |
|
465 |
int nc = GetClrImportant(); |
616 |
int nc = GetClrImportant(); |
466 |
if (nc==0) nc = GetNumColors(); |
617 |
if (nc==0) nc = GetNumColors(); |
467 |
|
618 |
|
|
|
619 |
// copy the palette colors |
620 |
#if PNG_LIBPNG_VER > 10399 |
621 |
_palette = new png_color[nc]; |
622 |
#else |
623 |
info_ptr->palette = new png_color[nc]; |
624 |
info_ptr->num_palette = (png_uint_16) nc; |
625 |
#endif |
626 |
for (int i=0; i<nc; i++) |
627 |
#if PNG_LIBPNG_VER > 10399 |
628 |
GetPaletteColor(i, &_palette[i].red, &_palette[i].green, &_palette[i].blue); |
629 |
|
630 |
png_set_PLTE(png_ptr,info_ptr,_palette,nc); |
631 |
#else |
632 |
GetPaletteColor(i, &info_ptr->palette[i].red, &info_ptr->palette[i].green, &info_ptr->palette[i].blue); |
633 |
#endif |
634 |
|
468 |
if (info.bAlphaPaletteEnabled){ |
635 |
if (info.bAlphaPaletteEnabled){ |
469 |
for(WORD ip=0; ip<nc;ip++) |
636 |
for(WORD ip=0; ip<nc;ip++) |
470 |
trans[ip]=GetPaletteColor((BYTE)ip).rgbReserved; |
637 |
trans[ip]=GetPaletteColor((BYTE)ip).rgbReserved; |
471 |
info_ptr->num_trans = (WORD)nc; |
|
|
472 |
info_ptr->valid |= PNG_INFO_tRNS; |
473 |
#if PNG_LIBPNG_VER > 10399 |
638 |
#if PNG_LIBPNG_VER > 10399 |
474 |
info_ptr->trans_alpha = trans; |
639 |
png_set_tRNS(png_ptr,info_ptr,(png_bytep)trans,nc,NULL); |
475 |
#else |
640 |
#else |
|
|
641 |
info_ptr->num_trans = (WORD)nc; |
642 |
info_ptr->valid |= PNG_INFO_tRNS; |
476 |
info_ptr->trans = trans; |
643 |
info_ptr->trans = trans; |
477 |
#endif |
644 |
#endif |
478 |
} |
645 |
} |
479 |
|
|
|
480 |
// copy the palette colors |
481 |
info_ptr->palette = new png_color[nc]; |
482 |
info_ptr->num_palette = (png_uint_16) nc; |
483 |
for (int i=0; i<nc; i++) |
484 |
GetPaletteColor(i, &info_ptr->palette[i].red, &info_ptr->palette[i].green, &info_ptr->palette[i].blue); |
485 |
} |
646 |
} |
486 |
|
647 |
|
487 |
#if CXIMAGE_SUPPORT_ALPHA // <vho> |
648 |
#if CXIMAGE_SUPPORT_ALPHA // <vho> |
Lines 495-502
Link Here
|
495 |
} } } |
656 |
} } } |
496 |
#endif // CXIMAGE_SUPPORT_ALPHA // <vho> |
657 |
#endif // CXIMAGE_SUPPORT_ALPHA // <vho> |
497 |
|
658 |
|
|
|
659 |
#if PNG_LIBPNG_VER > 10399 |
660 |
int row_size = max(info.dwEffWidth, (_width * _channels * _bit_depth / 8)); |
661 |
#else |
498 |
int row_size = max(info.dwEffWidth, info_ptr->width*info_ptr->channels*(info_ptr->bit_depth/8)); |
662 |
int row_size = max(info.dwEffWidth, info_ptr->width*info_ptr->channels*(info_ptr->bit_depth/8)); |
499 |
info_ptr->rowbytes = row_size; |
663 |
info_ptr->rowbytes = row_size; |
|
|
664 |
#endif |
500 |
BYTE *row_pointers = new BYTE[row_size]; |
665 |
BYTE *row_pointers = new BYTE[row_size]; |
501 |
|
666 |
|
502 |
/* write the file information */ |
667 |
/* write the file information */ |
Lines 514-520
Link Here
|
514 |
if (AlphaIsValid()){ |
679 |
if (AlphaIsValid()){ |
515 |
for (long ax=head.biWidth-1; ax>=0;ax--){ |
680 |
for (long ax=head.biWidth-1; ax>=0;ax--){ |
516 |
c = BlindGetPixelColor(ax,ay); |
681 |
c = BlindGetPixelColor(ax,ay); |
|
|
682 |
#if PNG_LIBPNG_VER > 10399 |
683 |
int px = ax * _channels; |
684 |
#else |
517 |
int px = ax * info_ptr->channels; |
685 |
int px = ax * info_ptr->channels; |
|
|
686 |
#endif |
518 |
if (!bGrayScale){ |
687 |
if (!bGrayScale){ |
519 |
row_pointers[px++]=c.rgbRed; |
688 |
row_pointers[px++]=c.rgbRed; |
520 |
row_pointers[px++]=c.rgbGreen; |
689 |
row_pointers[px++]=c.rgbGreen; |
Lines 529-535
Link Here
|
529 |
#endif //CXIMAGE_SUPPORT_ALPHA // <vho> |
698 |
#endif //CXIMAGE_SUPPORT_ALPHA // <vho> |
530 |
{ |
699 |
{ |
531 |
iter.GetRow(row_pointers, row_size); |
700 |
iter.GetRow(row_pointers, row_size); |
|
|
701 |
#if PNG_LIBPNG_VER > 10399 |
702 |
if (_color_type == PNG_COLOR_TYPE_RGB) //HACK BY OP |
703 |
#else |
532 |
if (info_ptr->color_type == PNG_COLOR_TYPE_RGB) //HACK BY OP |
704 |
if (info_ptr->color_type == PNG_COLOR_TYPE_RGB) //HACK BY OP |
|
|
705 |
#endif |
533 |
RGBtoBGR(row_pointers, row_size); |
706 |
RGBtoBGR(row_pointers, row_size); |
534 |
png_write_row(png_ptr, row_pointers); |
707 |
png_write_row(png_ptr, row_pointers); |
535 |
} |
708 |
} |
Lines 546-554
Link Here
|
546 |
png_write_end(png_ptr, info_ptr); |
719 |
png_write_end(png_ptr, info_ptr); |
547 |
|
720 |
|
548 |
/* if you malloced the palette, free it here */ |
721 |
/* if you malloced the palette, free it here */ |
|
|
722 |
#if PNG_LIBPNG_VER > 10399 |
723 |
if (_palette){ |
724 |
delete [] (_palette); |
725 |
#else |
549 |
if (info_ptr->palette){ |
726 |
if (info_ptr->palette){ |
550 |
delete [] (info_ptr->palette); |
727 |
delete [] (info_ptr->palette); |
551 |
info_ptr->palette = NULL; |
728 |
info_ptr->palette = NULL; |
|
|
729 |
#endif |
552 |
} |
730 |
} |
553 |
|
731 |
|
554 |
/* clean up after the write, and free any memory allocated */ |
732 |
/* clean up after the write, and free any memory allocated */ |