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 > 10499 |
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
bool CxImagePNG::Decode(CxFile *hFile)
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 > 10499 |
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 76-91
bool CxImagePNG::Decode(CxFile *hFile)
Link Here
|
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 |
#if PNG_LIBPNG_VER > 10499 |
88 |
png_uint_32 _width,_height; |
89 |
int _bit_depth,_color_type,_interlace_type,_compression_type,_filter_type; |
90 |
png_get_IHDR(png_ptr,info_ptr,&_width,&_height,&_bit_depth,&_color_type, |
91 |
&_interlace_type,&_compression_type,&_filter_type); |
92 |
|
93 |
if (info.nEscape == -1){ |
94 |
head.biWidth = _width; |
95 |
head.biHeight= _height; |
96 |
info.dwType = CXIMAGE_FORMAT_PNG; |
97 |
longjmp(png_jmpbuf(png_ptr), 1); |
98 |
} |
99 |
#else |
79 |
if (info.nEscape == -1){ |
100 |
if (info.nEscape == -1){ |
80 |
head.biWidth = info_ptr->width; |
101 |
head.biWidth = info_ptr->width; |
81 |
head.biHeight= info_ptr->height; |
102 |
head.biHeight= info_ptr->height; |
82 |
info.dwType = CXIMAGE_FORMAT_PNG; |
103 |
info.dwType = CXIMAGE_FORMAT_PNG; |
83 |
longjmp(png_ptr->jmpbuf, 1); |
104 |
longjmp(png_ptr->jmpbuf, 1); |
84 |
} |
105 |
} |
|
|
106 |
#endif |
85 |
|
107 |
|
86 |
/* calculate new number of channels */ |
108 |
/* calculate new number of channels */ |
87 |
int channels=0; |
109 |
int channels=0; |
|
|
110 |
#if PNG_LIBPNG_VER > 10499 |
111 |
switch(_color_type){ |
112 |
#else |
88 |
switch(info_ptr->color_type){ |
113 |
switch(info_ptr->color_type){ |
|
|
114 |
#endif |
89 |
case PNG_COLOR_TYPE_GRAY: |
115 |
case PNG_COLOR_TYPE_GRAY: |
90 |
case PNG_COLOR_TYPE_PALETTE: |
116 |
case PNG_COLOR_TYPE_PALETTE: |
91 |
channels = 1; |
117 |
channels = 1; |
Lines 101-120
bool CxImagePNG::Decode(CxFile *hFile)
Link Here
|
101 |
break; |
127 |
break; |
102 |
default: |
128 |
default: |
103 |
strcpy(info.szLastError,"unknown PNG color type"); |
129 |
strcpy(info.szLastError,"unknown PNG color type"); |
|
|
130 |
#if PNG_LIBPNG_VER > 10499 |
131 |
longjmp(png_jmpbuf(png_ptr), 1); |
132 |
#else |
104 |
longjmp(png_ptr->jmpbuf, 1); |
133 |
longjmp(png_ptr->jmpbuf, 1); |
|
|
134 |
#endif |
105 |
} |
135 |
} |
106 |
|
136 |
|
107 |
//find the right pixel depth used for cximage |
137 |
//find the right pixel depth used for cximage |
|
|
138 |
#if PNG_LIBPNG_VER > 10499 |
139 |
int pixel_depth = _bit_depth * png_get_channels(png_ptr,info_ptr); |
140 |
#else |
108 |
int pixel_depth = info_ptr->pixel_depth; |
141 |
int pixel_depth = info_ptr->pixel_depth; |
|
|
142 |
#endif |
109 |
if (channels == 1 && pixel_depth>8) pixel_depth=8; |
143 |
if (channels == 1 && pixel_depth>8) pixel_depth=8; |
110 |
if (channels == 2) pixel_depth=8; |
144 |
if (channels == 2) pixel_depth=8; |
111 |
if (channels >= 3) pixel_depth=24; |
145 |
if (channels >= 3) pixel_depth=24; |
112 |
|
146 |
|
|
|
147 |
#if PNG_LIBPNG_VER > 10499 |
148 |
if (!Create(_width, _height, pixel_depth, CXIMAGE_FORMAT_PNG)){ |
149 |
longjmp(png_jmpbuf(png_ptr), 1); |
150 |
#else |
113 |
if (!Create(info_ptr->width, info_ptr->height, pixel_depth, CXIMAGE_FORMAT_PNG)){ |
151 |
if (!Create(info_ptr->width, info_ptr->height, pixel_depth, CXIMAGE_FORMAT_PNG)){ |
114 |
longjmp(png_ptr->jmpbuf, 1); |
152 |
longjmp(png_ptr->jmpbuf, 1); |
|
|
153 |
#endif |
115 |
} |
154 |
} |
116 |
|
155 |
|
117 |
/* get metrics */ |
156 |
/* get metrics */ |
|
|
157 |
#if PNG_LIBPNG_VER > 10499 |
158 |
png_uint_32 _x_pixels_per_unit,_y_pixels_per_unit; |
159 |
int _phys_unit_type; |
160 |
png_get_pHYs(png_ptr,info_ptr,&_x_pixels_per_unit,&_y_pixels_per_unit,&_phys_unit_type); |
161 |
switch (_phys_unit_type) |
162 |
{ |
163 |
case PNG_RESOLUTION_UNKNOWN: |
164 |
SetXDPI(_x_pixels_per_unit); |
165 |
SetYDPI(_y_pixels_per_unit); |
166 |
break; |
167 |
case PNG_RESOLUTION_METER: |
168 |
SetXDPI((long)floor(_x_pixels_per_unit * 254.0 / 10000.0 + 0.5)); |
169 |
SetYDPI((long)floor(_y_pixels_per_unit * 254.0 / 10000.0 + 0.5)); |
170 |
break; |
171 |
} |
172 |
#else |
118 |
switch (info_ptr->phys_unit_type) |
173 |
switch (info_ptr->phys_unit_type) |
119 |
{ |
174 |
{ |
120 |
case PNG_RESOLUTION_UNKNOWN: |
175 |
case PNG_RESOLUTION_UNKNOWN: |
Lines 126-171
bool CxImagePNG::Decode(CxFile *hFile)
Link Here
|
126 |
SetYDPI((long)floor(info_ptr->y_pixels_per_unit * 254.0 / 10000.0 + 0.5)); |
181 |
SetYDPI((long)floor(info_ptr->y_pixels_per_unit * 254.0 / 10000.0 + 0.5)); |
127 |
break; |
182 |
break; |
128 |
} |
183 |
} |
|
|
184 |
#endif |
129 |
|
185 |
|
|
|
186 |
#if PNG_LIBPNG_VER > 10499 |
187 |
int _num_palette; |
188 |
png_colorp _palette; |
189 |
png_uint_32 _palette_ret; |
190 |
_palette_ret = png_get_PLTE(png_ptr,info_ptr,&_palette,&_num_palette); |
191 |
if (_palette_ret && _num_palette>0){ |
192 |
SetPalette((rgb_color*)_palette,_num_palette); |
193 |
SetClrImportant(_num_palette); |
194 |
} else if (_bit_depth ==2) { //<DP> needed for 2 bpp grayscale PNGs |
195 |
#else |
130 |
if (info_ptr->num_palette>0){ |
196 |
if (info_ptr->num_palette>0){ |
131 |
SetPalette((rgb_color*)info_ptr->palette,info_ptr->num_palette); |
197 |
SetPalette((rgb_color*)info_ptr->palette,info_ptr->num_palette); |
132 |
SetClrImportant(info_ptr->num_palette); |
198 |
SetClrImportant(info_ptr->num_palette); |
133 |
} else if (info_ptr->bit_depth ==2) { //<DP> needed for 2 bpp grayscale PNGs |
199 |
} else if (info_ptr->bit_depth ==2) { //<DP> needed for 2 bpp grayscale PNGs |
|
|
200 |
#endif |
134 |
SetPaletteColor(0,0,0,0); |
201 |
SetPaletteColor(0,0,0,0); |
135 |
SetPaletteColor(1,85,85,85); |
202 |
SetPaletteColor(1,85,85,85); |
136 |
SetPaletteColor(2,170,170,170); |
203 |
SetPaletteColor(2,170,170,170); |
137 |
SetPaletteColor(3,255,255,255); |
204 |
SetPaletteColor(3,255,255,255); |
138 |
} else SetGrayPalette(); //<DP> needed for grayscale PNGs |
205 |
} else SetGrayPalette(); //<DP> needed for grayscale PNGs |
139 |
|
206 |
|
|
|
207 |
#if PNG_LIBPNG_VER > 10499 |
208 |
int nshift = max(0,(_bit_depth>>3)-1)<<3; |
209 |
#else |
140 |
int nshift = max(0,(info_ptr->bit_depth>>3)-1)<<3; |
210 |
int nshift = max(0,(info_ptr->bit_depth>>3)-1)<<3; |
|
|
211 |
#endif |
141 |
|
212 |
|
|
|
213 |
#if PNG_LIBPNG_VER > 10499 |
214 |
png_bytep _trans_alpha; |
215 |
int _num_trans; |
216 |
png_color_16p _trans_color; |
217 |
png_uint_32 _trans_ret; |
218 |
_trans_ret = png_get_tRNS(png_ptr,info_ptr,&_trans_alpha,&_num_trans,&_trans_color); |
219 |
if (_trans_ret && _num_trans!=0){ //palette transparency |
220 |
if (_num_trans==1){ |
221 |
if (_color_type == PNG_COLOR_TYPE_PALETTE){ |
222 |
#else |
142 |
if (info_ptr->num_trans!=0){ //palette transparency |
223 |
if (info_ptr->num_trans!=0){ //palette transparency |
143 |
if (info_ptr->num_trans==1){ |
224 |
if (info_ptr->num_trans==1){ |
144 |
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE){ |
225 |
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE){ |
|
|
226 |
#endif |
227 |
#if PNG_LIBPNG_VER > 10499 |
228 |
info.nBkgndIndex = _trans_color->index; |
229 |
#else |
145 |
#if PNG_LIBPNG_VER > 10399 |
230 |
#if PNG_LIBPNG_VER > 10399 |
146 |
info.nBkgndIndex = info_ptr->trans_color.index; |
231 |
info.nBkgndIndex = info_ptr->trans_color.index; |
147 |
#else |
232 |
#else |
148 |
info.nBkgndIndex = info_ptr->trans_values.index; |
233 |
info.nBkgndIndex = info_ptr->trans_values.index; |
149 |
#endif |
234 |
#endif |
|
|
235 |
#endif |
150 |
} else{ |
236 |
} else{ |
|
|
237 |
#if PNG_LIBPNG_VER > 10499 |
238 |
info.nBkgndIndex = _trans_color->gray>>nshift; |
239 |
#else |
151 |
#if PNG_LIBPNG_VER > 10399 |
240 |
#if PNG_LIBPNG_VER > 10399 |
152 |
info.nBkgndIndex = info_ptr->trans_color.gray>>nshift; |
241 |
info.nBkgndIndex = info_ptr->trans_color.gray>>nshift; |
153 |
#else |
242 |
#else |
154 |
info.nBkgndIndex = info_ptr->trans_values.gray>>nshift; |
243 |
info.nBkgndIndex = info_ptr->trans_values.gray>>nshift; |
155 |
#endif |
244 |
#endif |
|
|
245 |
#endif |
156 |
} |
246 |
} |
157 |
} |
247 |
} |
|
|
248 |
#if PNG_LIBPNG_VER > 10499 |
249 |
if (_num_trans>1 && _trans_alpha!=NULL){ |
250 |
#else |
158 |
if (info_ptr->num_trans>1){ |
251 |
if (info_ptr->num_trans>1){ |
|
|
252 |
#endif |
159 |
RGBQUAD* pal=GetPalette(); |
253 |
RGBQUAD* pal=GetPalette(); |
160 |
if (pal){ |
254 |
if (pal){ |
161 |
DWORD ip; |
255 |
DWORD ip; |
|
|
256 |
#if PNG_LIBPNG_VER > 10499 |
257 |
for (ip=0;ip<min(head.biClrUsed,(unsigned long)_num_trans);ip++) |
258 |
pal[ip].rgbReserved=_trans_alpha[ip]; |
259 |
#else |
162 |
for (ip=0;ip<min(head.biClrUsed,(unsigned long)info_ptr->num_trans);ip++) |
260 |
for (ip=0;ip<min(head.biClrUsed,(unsigned long)info_ptr->num_trans);ip++) |
163 |
#if PNG_LIBPNG_VER > 10399 |
261 |
#if PNG_LIBPNG_VER > 10399 |
164 |
pal[ip].rgbReserved=info_ptr->trans_alpha[ip]; |
262 |
pal[ip].rgbReserved=info_ptr->trans_alpha[ip]; |
165 |
#else |
263 |
#else |
166 |
pal[ip].rgbReserved=info_ptr->trans[ip]; |
264 |
pal[ip].rgbReserved=info_ptr->trans[ip]; |
167 |
#endif |
265 |
#endif |
|
|
266 |
#endif |
267 |
#if PNG_LIBPNG_VER > 10499 |
268 |
for (ip=_num_trans;ip<head.biClrUsed;ip++){ |
269 |
#else |
168 |
for (ip=info_ptr->num_trans;ip<head.biClrUsed;ip++){ |
270 |
for (ip=info_ptr->num_trans;ip<head.biClrUsed;ip++){ |
|
|
271 |
#endif |
169 |
pal[ip].rgbReserved=255; |
272 |
pal[ip].rgbReserved=255; |
170 |
} |
273 |
} |
171 |
info.bAlphaPaletteEnabled=true; |
274 |
info.bAlphaPaletteEnabled=true; |
Lines 178-183
bool CxImagePNG::Decode(CxFile *hFile)
Link Here
|
178 |
int num_trans; |
281 |
int num_trans; |
179 |
png_color_16 *image_background; |
282 |
png_color_16 *image_background; |
180 |
if (png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &image_background)){ |
283 |
if (png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &image_background)){ |
|
|
284 |
#if PNG_LIBPNG_VER > 10499 |
285 |
info.nBkgndColor.rgbRed = (BYTE)(_trans_color->red>>nshift); |
286 |
info.nBkgndColor.rgbGreen = (BYTE)(_trans_color->green>>nshift); |
287 |
info.nBkgndColor.rgbBlue = (BYTE)(_trans_color->blue>>nshift); |
288 |
#else |
181 |
#if PNG_LIBPNG_VER > 10399 |
289 |
#if PNG_LIBPNG_VER > 10399 |
182 |
info.nBkgndColor.rgbRed = (BYTE)(info_ptr->trans_color.red>>nshift); |
290 |
info.nBkgndColor.rgbRed = (BYTE)(info_ptr->trans_color.red>>nshift); |
183 |
info.nBkgndColor.rgbGreen = (BYTE)(info_ptr->trans_color.green>>nshift); |
291 |
info.nBkgndColor.rgbGreen = (BYTE)(info_ptr->trans_color.green>>nshift); |
Lines 187-192
bool CxImagePNG::Decode(CxFile *hFile)
Link Here
|
187 |
info.nBkgndColor.rgbGreen = (BYTE)(info_ptr->trans_values.green>>nshift); |
295 |
info.nBkgndColor.rgbGreen = (BYTE)(info_ptr->trans_values.green>>nshift); |
188 |
info.nBkgndColor.rgbBlue = (BYTE)(info_ptr->trans_values.blue>>nshift); |
296 |
info.nBkgndColor.rgbBlue = (BYTE)(info_ptr->trans_values.blue>>nshift); |
189 |
#endif |
297 |
#endif |
|
|
298 |
#endif |
190 |
info.nBkgndColor.rgbReserved = 0; |
299 |
info.nBkgndColor.rgbReserved = 0; |
191 |
info.nBkgndIndex = 0; |
300 |
info.nBkgndIndex = 0; |
192 |
} |
301 |
} |
Lines 202-216
bool CxImagePNG::Decode(CxFile *hFile)
Link Here
|
202 |
} |
311 |
} |
203 |
|
312 |
|
204 |
// <vho> - flip the RGB pixels to BGR (or RGBA to BGRA) |
313 |
// <vho> - flip the RGB pixels to BGR (or RGBA to BGRA) |
|
|
314 |
#if PNG_LIBPNG_VER > 10499 |
315 |
if (_color_type & PNG_COLOR_MASK_COLOR){ |
316 |
#else |
205 |
if (info_ptr->color_type & PNG_COLOR_MASK_COLOR){ |
317 |
if (info_ptr->color_type & PNG_COLOR_MASK_COLOR){ |
|
|
318 |
#endif |
206 |
png_set_bgr(png_ptr); |
319 |
png_set_bgr(png_ptr); |
207 |
} |
320 |
} |
208 |
|
321 |
|
209 |
// <vho> - handle cancel |
322 |
// <vho> - handle cancel |
|
|
323 |
#if PNG_LIBPNG_VER > 10499 |
324 |
if (info.nEscape) longjmp(png_jmpbuf(png_ptr), 1); |
325 |
#else |
210 |
if (info.nEscape) longjmp(png_ptr->jmpbuf, 1); |
326 |
if (info.nEscape) longjmp(png_ptr->jmpbuf, 1); |
|
|
327 |
#endif |
211 |
|
328 |
|
212 |
// row_bytes is the width x number of channels x (bit-depth / 8) |
329 |
// row_bytes is the width x number of channels x (bit-depth / 8) |
|
|
330 |
#if PNG_LIBPNG_VER > 10499 |
331 |
row_pointers = new BYTE[png_get_rowbytes(png_ptr,info_ptr) + 8]; |
332 |
#else |
213 |
row_pointers = new BYTE[info_ptr->rowbytes + 8]; |
333 |
row_pointers = new BYTE[info_ptr->rowbytes + 8]; |
|
|
334 |
#endif |
214 |
|
335 |
|
215 |
// turn on interlace handling |
336 |
// turn on interlace handling |
216 |
int number_passes = png_set_interlace_handling(png_ptr); |
337 |
int number_passes = png_set_interlace_handling(png_ptr); |
Lines 221-228
bool CxImagePNG::Decode(CxFile *hFile)
Link Here
|
221 |
SetCodecOption(0); |
342 |
SetCodecOption(0); |
222 |
} |
343 |
} |
223 |
|
344 |
|
|
|
345 |
#if PNG_LIBPNG_VER > 10499 |
346 |
int chan_offset = _bit_depth >> 3; |
347 |
#else |
224 |
int chan_offset = info_ptr->bit_depth >> 3; |
348 |
int chan_offset = info_ptr->bit_depth >> 3; |
|
|
349 |
#endif |
350 |
#if PNG_LIBPNG_VER > 10499 |
351 |
int pixel_offset = (_bit_depth * png_get_channels(png_ptr,info_ptr)) >> 3; |
352 |
#else |
225 |
int pixel_offset = info_ptr->pixel_depth >> 3; |
353 |
int pixel_offset = info_ptr->pixel_depth >> 3; |
|
|
354 |
#endif |
226 |
|
355 |
|
227 |
for (int pass=0; pass < number_passes; pass++) { |
356 |
for (int pass=0; pass < number_passes; pass++) { |
228 |
iter.Upset(); |
357 |
iter.Upset(); |
Lines 230-236
bool CxImagePNG::Decode(CxFile *hFile)
Link Here
|
230 |
do { |
359 |
do { |
231 |
|
360 |
|
232 |
// <vho> - handle cancel |
361 |
// <vho> - handle cancel |
|
|
362 |
#if PNG_LIBPNG_VER > 10499 |
363 |
if (info.nEscape) longjmp(png_jmpbuf(png_ptr), 1); |
364 |
#else |
233 |
if (info.nEscape) longjmp(png_ptr->jmpbuf, 1); |
365 |
if (info.nEscape) longjmp(png_ptr->jmpbuf, 1); |
|
|
366 |
#endif |
234 |
|
367 |
|
235 |
#if CXIMAGE_SUPPORT_ALPHA // <vho> |
368 |
#if CXIMAGE_SUPPORT_ALPHA // <vho> |
236 |
if (AlphaIsValid()) { |
369 |
if (AlphaIsValid()) { |
Lines 241-247
bool CxImagePNG::Decode(CxFile *hFile)
Link Here
|
241 |
BYTE* prow= iter.GetRow(ay); |
374 |
BYTE* prow= iter.GetRow(ay); |
242 |
|
375 |
|
243 |
//recover data from previous scan |
376 |
//recover data from previous scan |
|
|
377 |
#if PNG_LIBPNG_VER > 10499 |
378 |
if (_interlace_type && pass>0 && pass!=7){ |
379 |
#else |
244 |
if (info_ptr->interlace_type && pass>0 && pass!=7){ |
380 |
if (info_ptr->interlace_type && pass>0 && pass!=7){ |
|
|
381 |
#endif |
245 |
for(ax=0;ax<head.biWidth;ax++){ |
382 |
for(ax=0;ax<head.biWidth;ax++){ |
246 |
long px = ax * pixel_offset; |
383 |
long px = ax * pixel_offset; |
247 |
if (channels == 2){ |
384 |
if (channels == 2){ |
Lines 278-287
bool CxImagePNG::Decode(CxFile *hFile)
Link Here
|
278 |
#endif // CXIMAGE_SUPPORT_ALPHA // vho |
415 |
#endif // CXIMAGE_SUPPORT_ALPHA // vho |
279 |
{ |
416 |
{ |
280 |
//recover data from previous scan |
417 |
//recover data from previous scan |
|
|
418 |
#if PNG_LIBPNG_VER > 10499 |
419 |
if (_interlace_type && pass>0){ |
420 |
iter.GetRow(row_pointers, png_get_rowbytes(png_ptr,info_ptr)); |
421 |
//re-expand buffer for images with bit depth > 8 |
422 |
if (_bit_depth > 8){ |
423 |
#else |
281 |
if (info_ptr->interlace_type && pass>0){ |
424 |
if (info_ptr->interlace_type && pass>0){ |
282 |
iter.GetRow(row_pointers, info_ptr->rowbytes); |
425 |
iter.GetRow(row_pointers, info_ptr->rowbytes); |
283 |
//re-expand buffer for images with bit depth > 8 |
426 |
//re-expand buffer for images with bit depth > 8 |
284 |
if (info_ptr->bit_depth > 8){ |
427 |
if (info_ptr->bit_depth > 8){ |
|
|
428 |
#endif |
285 |
for(long ax=(head.biWidth*channels-1);ax>=0;ax--) |
429 |
for(long ax=(head.biWidth*channels-1);ax>=0;ax--) |
286 |
row_pointers[ax*chan_offset] = row_pointers[ax]; |
430 |
row_pointers[ax*chan_offset] = row_pointers[ax]; |
287 |
} |
431 |
} |
Lines 291-305
bool CxImagePNG::Decode(CxFile *hFile)
Link Here
|
291 |
png_read_row(png_ptr, row_pointers, NULL); |
435 |
png_read_row(png_ptr, row_pointers, NULL); |
292 |
|
436 |
|
293 |
//shrink 16 bit depth images down to 8 bits |
437 |
//shrink 16 bit depth images down to 8 bits |
|
|
438 |
#if PNG_LIBPNG_VER > 10499 |
439 |
if (_bit_depth > 8){ |
440 |
#else |
294 |
if (info_ptr->bit_depth > 8){ |
441 |
if (info_ptr->bit_depth > 8){ |
|
|
442 |
#endif |
295 |
for(long ax=0;ax<(head.biWidth*channels);ax++) |
443 |
for(long ax=0;ax<(head.biWidth*channels);ax++) |
296 |
row_pointers[ax] = row_pointers[ax*chan_offset]; |
444 |
row_pointers[ax] = row_pointers[ax*chan_offset]; |
297 |
} |
445 |
} |
298 |
|
446 |
|
299 |
//copy the pixels |
447 |
//copy the pixels |
|
|
448 |
#if PNG_LIBPNG_VER > 10499 |
449 |
iter.SetRow(row_pointers, png_get_rowbytes(png_ptr,info_ptr)); |
450 |
#else |
300 |
iter.SetRow(row_pointers, info_ptr->rowbytes); |
451 |
iter.SetRow(row_pointers, info_ptr->rowbytes); |
|
|
452 |
#endif |
301 |
//<DP> expand 2 bpp images only in the last pass |
453 |
//<DP> expand 2 bpp images only in the last pass |
|
|
454 |
#if PNG_LIBPNG_VER > 10499 |
455 |
if (_bit_depth==2 && pass==(number_passes-1)) |
456 |
#else |
302 |
if (info_ptr->bit_depth==2 && pass==(number_passes-1)) |
457 |
if (info_ptr->bit_depth==2 && pass==(number_passes-1)) |
|
|
458 |
#endif |
303 |
expand2to4bpp(iter.GetRow()); |
459 |
expand2to4bpp(iter.GetRow()); |
304 |
|
460 |
|
305 |
//go on |
461 |
//go on |
Lines 361-369
bool CxImagePNG::Encode(CxFile *hFile)
Link Here
|
361 |
/* Set error handling. REQUIRED if you aren't supplying your own |
517 |
/* Set error handling. REQUIRED if you aren't supplying your own |
362 |
* error hadnling functions in the png_create_write_struct() call. |
518 |
* error hadnling functions in the png_create_write_struct() call. |
363 |
*/ |
519 |
*/ |
|
|
520 |
#if PNG_LIBPNG_VER > 10499 |
521 |
if (setjmp(png_jmpbuf(png_ptr))){ |
522 |
#else |
364 |
if (setjmp(png_ptr->jmpbuf)){ |
523 |
if (setjmp(png_ptr->jmpbuf)){ |
365 |
/* If we get here, we had a problem reading the file */ |
524 |
/* If we get here, we had a problem reading the file */ |
366 |
if (info_ptr->palette) free(info_ptr->palette); |
525 |
if (info_ptr->palette) free(info_ptr->palette); |
|
|
526 |
#endif |
367 |
png_destroy_write_struct(&png_ptr, (png_infopp)&info_ptr); |
527 |
png_destroy_write_struct(&png_ptr, (png_infopp)&info_ptr); |
368 |
cx_throw("Error saving PNG file"); |
528 |
cx_throw("Error saving PNG file"); |
369 |
} |
529 |
} |
Lines 372-380
bool CxImagePNG::Encode(CxFile *hFile)
Link Here
|
372 |
//png_init_io(png_ptr, hFile); |
532 |
//png_init_io(png_ptr, hFile); |
373 |
|
533 |
|
374 |
// use custom I/O functions |
534 |
// 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); |
535 |
png_set_write_fn(png_ptr,hFile,/*(png_rw_ptr)*/user_write_data,/*(png_flush_ptr)*/user_flush_data); |
376 |
|
536 |
|
377 |
/* set the file information here */ |
537 |
/* set the file information here */ |
|
|
538 |
#if PNG_LIBPNG_VER > 10499 |
539 |
/* use variables to hold the values so it isnt necessary to png_get them later */ |
540 |
png_uint_32 _width,_height; |
541 |
int _bit_depth,_color_type,_interlace_type,_compression_type,_filter_type; |
542 |
png_byte _channels,_pixel_depth; |
543 |
|
544 |
_width = GetWidth(); |
545 |
_height = GetHeight(); |
546 |
_pixel_depth = (BYTE)GetBpp(); |
547 |
_channels = (GetBpp()>8) ? (BYTE)3: (BYTE)1; |
548 |
_bit_depth = (BYTE)(GetBpp()/_channels); |
549 |
_compression_type = PNG_COMPRESSION_TYPE_DEFAULT; |
550 |
_filter_type = PNG_FILTER_TYPE_DEFAULT; |
551 |
#else |
378 |
info_ptr->width = GetWidth(); |
552 |
info_ptr->width = GetWidth(); |
379 |
info_ptr->height = GetHeight(); |
553 |
info_ptr->height = GetHeight(); |
380 |
info_ptr->pixel_depth = (BYTE)GetBpp(); |
554 |
info_ptr->pixel_depth = (BYTE)GetBpp(); |
Lines 382-394
bool CxImagePNG::Encode(CxFile *hFile)
Link Here
|
382 |
info_ptr->bit_depth = (BYTE)(GetBpp()/info_ptr->channels); |
556 |
info_ptr->bit_depth = (BYTE)(GetBpp()/info_ptr->channels); |
383 |
info_ptr->compression_type = info_ptr->filter_type = 0; |
557 |
info_ptr->compression_type = info_ptr->filter_type = 0; |
384 |
info_ptr->valid = 0; |
558 |
info_ptr->valid = 0; |
|
|
559 |
#endif |
385 |
|
560 |
|
386 |
switch(GetCodecOption(CXIMAGE_FORMAT_PNG)){ |
561 |
switch(GetCodecOption(CXIMAGE_FORMAT_PNG)){ |
387 |
case 1: |
562 |
case 1: |
|
|
563 |
#if PNG_LIBPNG_VER > 10499 |
564 |
_interlace_type = PNG_INTERLACE_ADAM7; |
565 |
#else |
388 |
info_ptr->interlace_type = PNG_INTERLACE_ADAM7; |
566 |
info_ptr->interlace_type = PNG_INTERLACE_ADAM7; |
|
|
567 |
#endif |
389 |
break; |
568 |
break; |
390 |
default: |
569 |
default: |
|
|
570 |
#if PNG_LIBPNG_VER > 10499 |
571 |
_interlace_type = PNG_INTERLACE_NONE; |
572 |
#else |
391 |
info_ptr->interlace_type = PNG_INTERLACE_NONE; |
573 |
info_ptr->interlace_type = PNG_INTERLACE_NONE; |
|
|
574 |
#endif |
392 |
} |
575 |
} |
393 |
|
576 |
|
394 |
/* set compression level */ |
577 |
/* set compression level */ |
Lines 398-416
bool CxImagePNG::Encode(CxFile *hFile)
Link Here
|
398 |
|
581 |
|
399 |
if (GetNumColors()){ |
582 |
if (GetNumColors()){ |
400 |
if (bGrayScale){ |
583 |
if (bGrayScale){ |
|
|
584 |
#if PNG_LIBPNG_VER > 10499 |
585 |
_color_type = PNG_COLOR_TYPE_GRAY; |
586 |
#else |
401 |
info_ptr->color_type = PNG_COLOR_TYPE_GRAY; |
587 |
info_ptr->color_type = PNG_COLOR_TYPE_GRAY; |
|
|
588 |
#endif |
402 |
} else { |
589 |
} else { |
|
|
590 |
#if PNG_LIBPNG_VER > 10499 |
591 |
_color_type = PNG_COLOR_TYPE_PALETTE; |
592 |
#else |
403 |
info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; |
593 |
info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; |
|
|
594 |
#endif |
404 |
} |
595 |
} |
405 |
} else { |
596 |
} else { |
|
|
597 |
#if PNG_LIBPNG_VER > 10499 |
598 |
_color_type = PNG_COLOR_TYPE_RGB; |
599 |
#else |
406 |
info_ptr->color_type = PNG_COLOR_TYPE_RGB; |
600 |
info_ptr->color_type = PNG_COLOR_TYPE_RGB; |
|
|
601 |
#endif |
407 |
} |
602 |
} |
408 |
#if CXIMAGE_SUPPORT_ALPHA |
603 |
#if CXIMAGE_SUPPORT_ALPHA |
409 |
if (AlphaIsValid()){ |
604 |
if (AlphaIsValid()){ |
|
|
605 |
#if PNG_LIBPNG_VER > 10499 |
606 |
_color_type |= PNG_COLOR_MASK_ALPHA; |
607 |
_channels++; |
608 |
_bit_depth = 8; |
609 |
_pixel_depth += 8; |
610 |
#else |
410 |
info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; |
611 |
info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; |
411 |
info_ptr->channels++; |
612 |
info_ptr->channels++; |
412 |
info_ptr->bit_depth = 8; |
613 |
info_ptr->bit_depth = 8; |
413 |
info_ptr->pixel_depth += 8; |
614 |
info_ptr->pixel_depth += 8; |
|
|
615 |
#endif |
414 |
} |
616 |
} |
415 |
#endif |
617 |
#endif |
416 |
|
618 |
|
Lines 427-440
bool CxImagePNG::Encode(CxFile *hFile)
Link Here
|
427 |
/* set metrics */ |
629 |
/* set metrics */ |
428 |
png_set_pHYs(png_ptr, info_ptr, head.biXPelsPerMeter, head.biYPelsPerMeter, PNG_RESOLUTION_METER); |
630 |
png_set_pHYs(png_ptr, info_ptr, head.biXPelsPerMeter, head.biYPelsPerMeter, PNG_RESOLUTION_METER); |
429 |
|
631 |
|
|
|
632 |
#if PNG_LIBPNG_VER > 10499 |
633 |
png_set_IHDR(png_ptr,info_ptr,_width,_height,_bit_depth,_color_type,_interlace_type, |
634 |
_compression_type,_filter_type); |
635 |
#else |
430 |
png_set_IHDR(png_ptr, info_ptr, info_ptr->width, info_ptr->height, info_ptr->bit_depth, |
636 |
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, |
637 |
info_ptr->color_type, info_ptr->interlace_type, |
432 |
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); |
638 |
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); |
|
|
639 |
#endif |
433 |
|
640 |
|
434 |
//<DP> simple transparency |
641 |
//<DP> simple transparency |
435 |
if (info.nBkgndIndex >= 0){ |
642 |
if (info.nBkgndIndex >= 0){ |
|
|
643 |
#if PNG_LIBPNG_VER <= 10499 |
436 |
info_ptr->num_trans = 1; |
644 |
info_ptr->num_trans = 1; |
437 |
info_ptr->valid |= PNG_INFO_tRNS; |
645 |
info_ptr->valid |= PNG_INFO_tRNS; |
|
|
646 |
#endif |
647 |
#if PNG_LIBPNG_VER > 10499 |
648 |
png_color_16 _trans_color; |
649 |
_trans_color.index = (BYTE)info.nBkgndIndex; |
650 |
_trans_color.red = tc.rgbRed; |
651 |
_trans_color.green = tc.rgbGreen; |
652 |
_trans_color.blue = tc.rgbBlue; |
653 |
_trans_color.gray = _trans_color.index; |
654 |
png_set_tRNS(png_ptr,info_ptr,(png_bytep)trans,1,&_trans_color); |
655 |
#else |
438 |
#if PNG_LIBPNG_VER > 10399 |
656 |
#if PNG_LIBPNG_VER > 10399 |
439 |
info_ptr->trans_alpha = trans; |
657 |
info_ptr->trans_alpha = trans; |
440 |
info_ptr->trans_color.index = (BYTE)info.nBkgndIndex; |
658 |
info_ptr->trans_color.index = (BYTE)info.nBkgndIndex; |
Lines 450-455
bool CxImagePNG::Encode(CxFile *hFile)
Link Here
|
450 |
info_ptr->trans_values.blue = tc.rgbBlue; |
668 |
info_ptr->trans_values.blue = tc.rgbBlue; |
451 |
info_ptr->trans_values.gray = info_ptr->trans_values.index; |
669 |
info_ptr->trans_values.gray = info_ptr->trans_values.index; |
452 |
#endif |
670 |
#endif |
|
|
671 |
#endif |
453 |
|
672 |
|
454 |
// the transparency indexes start from 0 for non grayscale palette |
673 |
// the transparency indexes start from 0 for non grayscale palette |
455 |
if (!bGrayScale && head.biClrUsed && info.nBkgndIndex) |
674 |
if (!bGrayScale && head.biClrUsed && info.nBkgndIndex) |
Lines 457-466
bool CxImagePNG::Encode(CxFile *hFile)
Link Here
|
457 |
} |
676 |
} |
458 |
|
677 |
|
459 |
/* set the palette if there is one */ |
678 |
/* set the palette if there is one */ |
|
|
679 |
#if PNG_LIBPNG_VER > 10499 |
680 |
png_colorp _palette = NULL; |
681 |
if (GetPalette()){ |
682 |
/* png_set_PLTE() will be called once the palette is ready */ |
683 |
#else |
460 |
if (GetPalette()){ |
684 |
if (GetPalette()){ |
461 |
if (!bGrayScale){ |
685 |
if (!bGrayScale){ |
462 |
info_ptr->valid |= PNG_INFO_PLTE; |
686 |
info_ptr->valid |= PNG_INFO_PLTE; |
463 |
} |
687 |
} |
|
|
688 |
#endif |
464 |
|
689 |
|
465 |
int nc = GetClrImportant(); |
690 |
int nc = GetClrImportant(); |
466 |
if (nc==0) nc = GetNumColors(); |
691 |
if (nc==0) nc = GetNumColors(); |
Lines 468-487
bool CxImagePNG::Encode(CxFile *hFile)
Link Here
|
468 |
if (info.bAlphaPaletteEnabled){ |
693 |
if (info.bAlphaPaletteEnabled){ |
469 |
for(WORD ip=0; ip<nc;ip++) |
694 |
for(WORD ip=0; ip<nc;ip++) |
470 |
trans[ip]=GetPaletteColor((BYTE)ip).rgbReserved; |
695 |
trans[ip]=GetPaletteColor((BYTE)ip).rgbReserved; |
|
|
696 |
#if PNG_LIBPNG_VER <= 10499 |
471 |
info_ptr->num_trans = (WORD)nc; |
697 |
info_ptr->num_trans = (WORD)nc; |
472 |
info_ptr->valid |= PNG_INFO_tRNS; |
698 |
info_ptr->valid |= PNG_INFO_tRNS; |
|
|
699 |
#endif |
700 |
#if PNG_LIBPNG_VER > 10499 |
701 |
png_set_tRNS(png_ptr,info_ptr,(png_bytep)trans,nc,NULL); |
702 |
#else |
473 |
#if PNG_LIBPNG_VER > 10399 |
703 |
#if PNG_LIBPNG_VER > 10399 |
474 |
info_ptr->trans_alpha = trans; |
704 |
info_ptr->trans_alpha = trans; |
475 |
#else |
705 |
#else |
476 |
info_ptr->trans = trans; |
706 |
info_ptr->trans = trans; |
477 |
#endif |
707 |
#endif |
|
|
708 |
#endif |
478 |
} |
709 |
} |
479 |
|
710 |
|
480 |
// copy the palette colors |
711 |
// copy the palette colors |
|
|
712 |
#if PNG_LIBPNG_VER > 10499 |
713 |
_palette = new png_color[nc]; |
714 |
for (int i=0; i<nc; i++) |
715 |
GetPaletteColor(i, &_palette[i].red, &_palette[i].green, &_palette[i].blue); |
716 |
|
717 |
png_set_PLTE(png_ptr,info_ptr,_palette,nc); |
718 |
#else |
481 |
info_ptr->palette = new png_color[nc]; |
719 |
info_ptr->palette = new png_color[nc]; |
482 |
info_ptr->num_palette = (png_uint_16) nc; |
720 |
info_ptr->num_palette = (png_uint_16) nc; |
483 |
for (int i=0; i<nc; i++) |
721 |
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); |
722 |
GetPaletteColor(i, &info_ptr->palette[i].red, &info_ptr->palette[i].green, &info_ptr->palette[i].blue); |
|
|
723 |
#endif |
485 |
} |
724 |
} |
486 |
|
725 |
|
487 |
#if CXIMAGE_SUPPORT_ALPHA // <vho> |
726 |
#if CXIMAGE_SUPPORT_ALPHA // <vho> |
Lines 495-502
bool CxImagePNG::Encode(CxFile *hFile)
Link Here
|
495 |
} } } |
734 |
} } } |
496 |
#endif // CXIMAGE_SUPPORT_ALPHA // <vho> |
735 |
#endif // CXIMAGE_SUPPORT_ALPHA // <vho> |
497 |
|
736 |
|
|
|
737 |
#if PNG_LIBPNG_VER > 10499 |
738 |
int row_size = max(info.dwEffWidth, (_width * _channels * _bit_depth / 8)); |
739 |
#else |
498 |
int row_size = max(info.dwEffWidth, info_ptr->width*info_ptr->channels*(info_ptr->bit_depth/8)); |
740 |
int row_size = max(info.dwEffWidth, info_ptr->width*info_ptr->channels*(info_ptr->bit_depth/8)); |
499 |
info_ptr->rowbytes = row_size; |
741 |
info_ptr->rowbytes = row_size; |
|
|
742 |
#endif |
500 |
BYTE *row_pointers = new BYTE[row_size]; |
743 |
BYTE *row_pointers = new BYTE[row_size]; |
501 |
|
744 |
|
502 |
/* write the file information */ |
745 |
/* write the file information */ |
Lines 514-520
bool CxImagePNG::Encode(CxFile *hFile)
Link Here
|
514 |
if (AlphaIsValid()){ |
757 |
if (AlphaIsValid()){ |
515 |
for (long ax=head.biWidth-1; ax>=0;ax--){ |
758 |
for (long ax=head.biWidth-1; ax>=0;ax--){ |
516 |
c = BlindGetPixelColor(ax,ay); |
759 |
c = BlindGetPixelColor(ax,ay); |
|
|
760 |
#if PNG_LIBPNG_VER > 10499 |
761 |
int px = ax * _channels; |
762 |
#else |
517 |
int px = ax * info_ptr->channels; |
763 |
int px = ax * info_ptr->channels; |
|
|
764 |
#endif |
518 |
if (!bGrayScale){ |
765 |
if (!bGrayScale){ |
519 |
row_pointers[px++]=c.rgbRed; |
766 |
row_pointers[px++]=c.rgbRed; |
520 |
row_pointers[px++]=c.rgbGreen; |
767 |
row_pointers[px++]=c.rgbGreen; |
Lines 529-535
bool CxImagePNG::Encode(CxFile *hFile)
Link Here
|
529 |
#endif //CXIMAGE_SUPPORT_ALPHA // <vho> |
776 |
#endif //CXIMAGE_SUPPORT_ALPHA // <vho> |
530 |
{ |
777 |
{ |
531 |
iter.GetRow(row_pointers, row_size); |
778 |
iter.GetRow(row_pointers, row_size); |
|
|
779 |
#if PNG_LIBPNG_VER > 10499 |
780 |
if (_color_type == PNG_COLOR_TYPE_RGB) //HACK BY OP |
781 |
#else |
532 |
if (info_ptr->color_type == PNG_COLOR_TYPE_RGB) //HACK BY OP |
782 |
if (info_ptr->color_type == PNG_COLOR_TYPE_RGB) //HACK BY OP |
|
|
783 |
#endif |
533 |
RGBtoBGR(row_pointers, row_size); |
784 |
RGBtoBGR(row_pointers, row_size); |
534 |
png_write_row(png_ptr, row_pointers); |
785 |
png_write_row(png_ptr, row_pointers); |
535 |
} |
786 |
} |
Lines 546-554
bool CxImagePNG::Encode(CxFile *hFile)
Link Here
|
546 |
png_write_end(png_ptr, info_ptr); |
797 |
png_write_end(png_ptr, info_ptr); |
547 |
|
798 |
|
548 |
/* if you malloced the palette, free it here */ |
799 |
/* if you malloced the palette, free it here */ |
|
|
800 |
#if PNG_LIBPNG_VER > 10499 |
801 |
if (_palette){ |
802 |
delete [] (_palette); |
803 |
#else |
549 |
if (info_ptr->palette){ |
804 |
if (info_ptr->palette){ |
550 |
delete [] (info_ptr->palette); |
805 |
delete [] (info_ptr->palette); |
551 |
info_ptr->palette = NULL; |
806 |
info_ptr->palette = NULL; |
|
|
807 |
#endif |
552 |
} |
808 |
} |
553 |
|
809 |
|
554 |
/* clean up after the write, and free any memory allocated */ |
810 |
/* clean up after the write, and free any memory allocated */ |