OLD | NEW |
1 | 1 |
2 /* pngrtran.c - transforms the data in a row for PNG readers | 2 /* pngrtran.c - transforms the data in a row for PNG readers |
3 * | 3 * |
4 * Last changed in libpng 1.6.2 [April 25, 2013] | 4 * Last changed in libpng 1.2.45 [July 7, 2011] |
5 * Copyright (c) 1998-2013 Glenn Randers-Pehrson | 5 * Copyright (c) 1998-2011 Glenn Randers-Pehrson |
6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) | 6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) |
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) | 7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) |
8 * | 8 * |
9 * This code is released under the libpng license. | 9 * This code is released under the libpng license. |
10 * For conditions of distribution and use, see the disclaimer | 10 * For conditions of distribution and use, see the disclaimer |
11 * and license in png.h | 11 * and license in png.h |
12 * | 12 * |
13 * This file contains functions optionally called by an application | 13 * This file contains functions optionally called by an application |
14 * in order to tell libpng how to handle data when reading a PNG. | 14 * in order to tell libpng how to handle data when reading a PNG. |
15 * Transformations that are used in both reading and writing are | 15 * Transformations that are used in both reading and writing are |
16 * in pngtrans.c. | 16 * in pngtrans.c. |
17 */ | 17 */ |
18 | 18 |
19 #include "pngpriv.h" | 19 #define PNG_INTERNAL |
20 | 20 #define PNG_NO_PEDANTIC_WARNINGS |
| 21 #include "png.h" |
21 #ifdef PNG_READ_SUPPORTED | 22 #ifdef PNG_READ_SUPPORTED |
22 | 23 |
23 /* Set the action on getting a CRC error for an ancillary or critical chunk. */ | 24 /* Set the action on getting a CRC error for an ancillary or critical chunk. */ |
24 void PNGAPI | 25 void PNGAPI |
25 png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action) | 26 png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action) |
26 { | 27 { |
27 png_debug(1, "in png_set_crc_action"); | 28 png_debug(1, "in png_set_crc_action"); |
28 | 29 |
29 if (png_ptr == NULL) | 30 if (png_ptr == NULL) |
30 return; | 31 return; |
31 | 32 |
32 /* Tell libpng how we react to CRC errors in critical chunks */ | 33 /* Tell libpng how we react to CRC errors in critical chunks */ |
33 switch (crit_action) | 34 switch (crit_action) |
34 { | 35 { |
35 case PNG_CRC_NO_CHANGE: /* Leave setting as is */ | 36 case PNG_CRC_NO_CHANGE: /* Leave setting as is */ |
36 break; | 37 break; |
37 | 38 |
38 case PNG_CRC_WARN_USE: /* Warn/use data */ | 39 case PNG_CRC_WARN_USE: /* Warn/use data */ |
39 png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; | 40 png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; |
40 png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE; | 41 png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE; |
41 break; | 42 break; |
42 | 43 |
43 case PNG_CRC_QUIET_USE: /* Quiet/use data */ | 44 case PNG_CRC_QUIET_USE: /* Quiet/use data */ |
44 png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; | 45 png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; |
45 png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE | | 46 png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE | |
46 PNG_FLAG_CRC_CRITICAL_IGNORE; | 47 PNG_FLAG_CRC_CRITICAL_IGNORE; |
47 break; | 48 break; |
48 | 49 |
49 case PNG_CRC_WARN_DISCARD: /* Not a valid action for critical data */ | 50 case PNG_CRC_WARN_DISCARD: /* Not a valid action for critical data */ |
50 png_warning(png_ptr, | 51 png_warning(png_ptr, |
51 "Can't discard critical data on CRC error"); | 52 "Can't discard critical data on CRC error."); |
52 case PNG_CRC_ERROR_QUIT: /* Error/quit */ | 53 case PNG_CRC_ERROR_QUIT: /* Error/quit */ |
53 | 54 |
54 case PNG_CRC_DEFAULT: | 55 case PNG_CRC_DEFAULT: |
55 default: | 56 default: |
56 png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; | 57 png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; |
57 break; | 58 break; |
58 } | 59 } |
59 | 60 |
60 /* Tell libpng how we react to CRC errors in ancillary chunks */ | 61 /* Tell libpng how we react to CRC errors in ancillary chunks */ |
61 switch (ancil_action) | 62 switch (ancil_action) |
(...skipping 19 matching lines...) Expand all Loading... |
81 | 82 |
82 case PNG_CRC_WARN_DISCARD: /* Warn/discard data */ | 83 case PNG_CRC_WARN_DISCARD: /* Warn/discard data */ |
83 | 84 |
84 case PNG_CRC_DEFAULT: | 85 case PNG_CRC_DEFAULT: |
85 default: | 86 default: |
86 png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; | 87 png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; |
87 break; | 88 break; |
88 } | 89 } |
89 } | 90 } |
90 | 91 |
91 #ifdef PNG_READ_TRANSFORMS_SUPPORTED | 92 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ |
92 /* Is it OK to set a transformation now? Only if png_start_read_image or | 93 defined(PNG_FLOATING_POINT_SUPPORTED) |
93 * png_read_update_info have not been called. It is not necessary for the IHDR | 94 /* Handle alpha and tRNS via a background color */ |
94 * to have been read in all cases, the parameter allows for this check too. | 95 void PNGAPI |
95 */ | 96 png_set_background(png_structp png_ptr, |
96 static int | 97 png_color_16p background_color, int background_gamma_code, |
97 png_rtran_ok(png_structrp png_ptr, int need_IHDR) | 98 int need_expand, double background_gamma) |
98 { | 99 { |
99 if (png_ptr != NULL) | 100 png_debug(1, "in png_set_background"); |
100 { | 101 |
101 if (png_ptr->flags & PNG_FLAG_ROW_INIT) | 102 if (png_ptr == NULL) |
102 png_app_error(png_ptr, | |
103 "invalid after png_start_read_image or png_read_update_info"); | |
104 | |
105 else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0) | |
106 png_app_error(png_ptr, "invalid before the PNG header has been read"); | |
107 | |
108 else | |
109 { | |
110 /* Turn on failure to initialize correctly for all transforms. */ | |
111 png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; | |
112 | |
113 return 1; /* Ok */ | |
114 } | |
115 } | |
116 | |
117 return 0; /* no png_error possible! */ | |
118 } | |
119 #endif | |
120 | |
121 #ifdef PNG_READ_BACKGROUND_SUPPORTED | |
122 /* Handle alpha and tRNS via a background color */ | |
123 void PNGFAPI | |
124 png_set_background_fixed(png_structrp png_ptr, | |
125 png_const_color_16p background_color, int background_gamma_code, | |
126 int need_expand, png_fixed_point background_gamma) | |
127 { | |
128 png_debug(1, "in png_set_background_fixed"); | |
129 | |
130 if (!png_rtran_ok(png_ptr, 0) || background_color == NULL) | |
131 return; | 103 return; |
132 | |
133 if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) | 104 if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) |
134 { | 105 { |
135 png_warning(png_ptr, "Application must supply a known background gamma"); | 106 png_warning(png_ptr, "Application must supply a known background gamma"); |
136 return; | 107 return; |
137 } | 108 } |
138 | 109 |
139 png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA; | 110 png_ptr->transformations |= PNG_BACKGROUND; |
140 png_ptr->transformations &= ~PNG_ENCODE_ALPHA; | 111 png_memcpy(&(png_ptr->background), background_color, |
141 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; | 112 png_sizeof(png_color_16)); |
142 | 113 png_ptr->background_gamma = (float)background_gamma; |
143 png_ptr->background = *background_color; | |
144 png_ptr->background_gamma = background_gamma; | |
145 png_ptr->background_gamma_type = (png_byte)(background_gamma_code); | 114 png_ptr->background_gamma_type = (png_byte)(background_gamma_code); |
146 if (need_expand) | 115 png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0); |
147 png_ptr->transformations |= PNG_BACKGROUND_EXPAND; | |
148 else | |
149 png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; | |
150 } | |
151 | |
152 # ifdef PNG_FLOATING_POINT_SUPPORTED | |
153 void PNGAPI | |
154 png_set_background(png_structrp png_ptr, | |
155 png_const_color_16p background_color, int background_gamma_code, | |
156 int need_expand, double background_gamma) | |
157 { | |
158 png_set_background_fixed(png_ptr, background_color, background_gamma_code, | |
159 need_expand, png_fixed(png_ptr, background_gamma, "png_set_background")); | |
160 } | |
161 # endif /* FLOATING_POINT */ | |
162 #endif /* READ_BACKGROUND */ | |
163 | |
164 /* Scale 16-bit depth files to 8-bit depth. If both of these are set then the | |
165 * one that pngrtran does first (scale) happens. This is necessary to allow the | |
166 * TRANSFORM and API behavior to be somewhat consistent, and it's simpler. | |
167 */ | |
168 #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED | |
169 void PNGAPI | |
170 png_set_scale_16(png_structrp png_ptr) | |
171 { | |
172 png_debug(1, "in png_set_scale_16"); | |
173 | |
174 if (!png_rtran_ok(png_ptr, 0)) | |
175 return; | |
176 | |
177 png_ptr->transformations |= PNG_SCALE_16_TO_8; | |
178 } | 116 } |
179 #endif | 117 #endif |
180 | 118 |
181 #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED | 119 #ifdef PNG_READ_16_TO_8_SUPPORTED |
182 /* Chop 16-bit depth files to 8-bit depth */ | 120 /* Strip 16 bit depth files to 8 bit depth */ |
183 void PNGAPI | 121 void PNGAPI |
184 png_set_strip_16(png_structrp png_ptr) | 122 png_set_strip_16(png_structp png_ptr) |
185 { | 123 { |
186 png_debug(1, "in png_set_strip_16"); | 124 png_debug(1, "in png_set_strip_16"); |
187 | 125 |
188 if (!png_rtran_ok(png_ptr, 0)) | 126 if (png_ptr == NULL) |
189 return; | 127 return; |
190 | |
191 png_ptr->transformations |= PNG_16_TO_8; | 128 png_ptr->transformations |= PNG_16_TO_8; |
192 } | 129 } |
193 #endif | 130 #endif |
194 | 131 |
195 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED | 132 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED |
196 void PNGAPI | 133 void PNGAPI |
197 png_set_strip_alpha(png_structrp png_ptr) | 134 png_set_strip_alpha(png_structp png_ptr) |
198 { | 135 { |
199 png_debug(1, "in png_set_strip_alpha"); | 136 png_debug(1, "in png_set_strip_alpha"); |
200 | 137 |
201 if (!png_rtran_ok(png_ptr, 0)) | 138 if (png_ptr == NULL) |
202 return; | 139 return; |
203 | 140 png_ptr->flags |= PNG_FLAG_STRIP_ALPHA; |
204 png_ptr->transformations |= PNG_STRIP_ALPHA; | |
205 } | 141 } |
206 #endif | 142 #endif |
207 | 143 |
208 #if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED) | 144 #ifdef PNG_READ_DITHER_SUPPORTED |
209 static png_fixed_point | 145 /* Dither file to 8 bit. Supply a palette, the current number |
210 translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma, | |
211 int is_screen) | |
212 { | |
213 /* Check for flag values. The main reason for having the old Mac value as a | |
214 * flag is that it is pretty near impossible to work out what the correct | |
215 * value is from Apple documentation - a working Mac system is needed to | |
216 * discover the value! | |
217 */ | |
218 if (output_gamma == PNG_DEFAULT_sRGB || | |
219 output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB) | |
220 { | |
221 /* If there is no sRGB support this just sets the gamma to the standard | |
222 * sRGB value. (This is a side effect of using this function!) | |
223 */ | |
224 # ifdef PNG_READ_sRGB_SUPPORTED | |
225 png_ptr->flags |= PNG_FLAG_ASSUME_sRGB; | |
226 # else | |
227 PNG_UNUSED(png_ptr) | |
228 # endif | |
229 if (is_screen) | |
230 output_gamma = PNG_GAMMA_sRGB; | |
231 else | |
232 output_gamma = PNG_GAMMA_sRGB_INVERSE; | |
233 } | |
234 | |
235 else if (output_gamma == PNG_GAMMA_MAC_18 || | |
236 output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18) | |
237 { | |
238 if (is_screen) | |
239 output_gamma = PNG_GAMMA_MAC_OLD; | |
240 else | |
241 output_gamma = PNG_GAMMA_MAC_INVERSE; | |
242 } | |
243 | |
244 return output_gamma; | |
245 } | |
246 | |
247 # ifdef PNG_FLOATING_POINT_SUPPORTED | |
248 static png_fixed_point | |
249 convert_gamma_value(png_structrp png_ptr, double output_gamma) | |
250 { | |
251 /* The following silently ignores cases where fixed point (times 100,000) | |
252 * gamma values are passed to the floating point API. This is safe and it | |
253 * means the fixed point constants work just fine with the floating point | |
254 * API. The alternative would just lead to undetected errors and spurious | |
255 * bug reports. Negative values fail inside the _fixed API unless they | |
256 * correspond to the flag values. | |
257 */ | |
258 if (output_gamma > 0 && output_gamma < 128) | |
259 output_gamma *= PNG_FP_1; | |
260 | |
261 /* This preserves -1 and -2 exactly: */ | |
262 output_gamma = floor(output_gamma + .5); | |
263 | |
264 if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN) | |
265 png_fixed_error(png_ptr, "gamma value"); | |
266 | |
267 return (png_fixed_point)output_gamma; | |
268 } | |
269 # endif | |
270 #endif /* READ_ALPHA_MODE || READ_GAMMA */ | |
271 | |
272 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED | |
273 void PNGFAPI | |
274 png_set_alpha_mode_fixed(png_structrp png_ptr, int mode, | |
275 png_fixed_point output_gamma) | |
276 { | |
277 int compose = 0; | |
278 png_fixed_point file_gamma; | |
279 | |
280 png_debug(1, "in png_set_alpha_mode"); | |
281 | |
282 if (!png_rtran_ok(png_ptr, 0)) | |
283 return; | |
284 | |
285 output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/); | |
286 | |
287 /* Validate the value to ensure it is in a reasonable range. The value | |
288 * is expected to be 1 or greater, but this range test allows for some | |
289 * viewing correction values. The intent is to weed out users of this API | |
290 * who use the inverse of the gamma value accidentally! Since some of these | |
291 * values are reasonable this may have to be changed. | |
292 */ | |
293 if (output_gamma < 70000 || output_gamma > 300000) | |
294 png_error(png_ptr, "output gamma out of expected range"); | |
295 | |
296 /* The default file gamma is the inverse of the output gamma; the output | |
297 * gamma may be changed below so get the file value first: | |
298 */ | |
299 file_gamma = png_reciprocal(output_gamma); | |
300 | |
301 /* There are really 8 possibilities here, composed of any combination | |
302 * of: | |
303 * | |
304 * premultiply the color channels | |
305 * do not encode non-opaque pixels | |
306 * encode the alpha as well as the color channels | |
307 * | |
308 * The differences disappear if the input/output ('screen') gamma is 1.0, | |
309 * because then the encoding is a no-op and there is only the choice of | |
310 * premultiplying the color channels or not. | |
311 * | |
312 * png_set_alpha_mode and png_set_background interact because both use | |
313 * png_compose to do the work. Calling both is only useful when | |
314 * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along | |
315 * with a default gamma value. Otherwise PNG_COMPOSE must not be set. | |
316 */ | |
317 switch (mode) | |
318 { | |
319 case PNG_ALPHA_PNG: /* default: png standard */ | |
320 /* No compose, but it may be set by png_set_background! */ | |
321 png_ptr->transformations &= ~PNG_ENCODE_ALPHA; | |
322 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; | |
323 break; | |
324 | |
325 case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */ | |
326 compose = 1; | |
327 png_ptr->transformations &= ~PNG_ENCODE_ALPHA; | |
328 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; | |
329 /* The output is linear: */ | |
330 output_gamma = PNG_FP_1; | |
331 break; | |
332 | |
333 case PNG_ALPHA_OPTIMIZED: /* associated, non-opaque pixels linear */ | |
334 compose = 1; | |
335 png_ptr->transformations &= ~PNG_ENCODE_ALPHA; | |
336 png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA; | |
337 /* output_gamma records the encoding of opaque pixels! */ | |
338 break; | |
339 | |
340 case PNG_ALPHA_BROKEN: /* associated, non-linear, alpha encoded */ | |
341 compose = 1; | |
342 png_ptr->transformations |= PNG_ENCODE_ALPHA; | |
343 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; | |
344 break; | |
345 | |
346 default: | |
347 png_error(png_ptr, "invalid alpha mode"); | |
348 } | |
349 | |
350 /* Only set the default gamma if the file gamma has not been set (this has | |
351 * the side effect that the gamma in a second call to png_set_alpha_mode will | |
352 * be ignored.) | |
353 */ | |
354 if (png_ptr->colorspace.gamma == 0) | |
355 { | |
356 png_ptr->colorspace.gamma = file_gamma; | |
357 png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; | |
358 } | |
359 | |
360 /* But always set the output gamma: */ | |
361 png_ptr->screen_gamma = output_gamma; | |
362 | |
363 /* Finally, if pre-multiplying, set the background fields to achieve the | |
364 * desired result. | |
365 */ | |
366 if (compose) | |
367 { | |
368 /* And obtain alpha pre-multiplication by composing on black: */ | |
369 memset(&png_ptr->background, 0, (sizeof png_ptr->background)); | |
370 png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */ | |
371 png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE; | |
372 png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; | |
373 | |
374 if (png_ptr->transformations & PNG_COMPOSE) | |
375 png_error(png_ptr, | |
376 "conflicting calls to set alpha mode and background"); | |
377 | |
378 png_ptr->transformations |= PNG_COMPOSE; | |
379 } | |
380 } | |
381 | |
382 # ifdef PNG_FLOATING_POINT_SUPPORTED | |
383 void PNGAPI | |
384 png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma) | |
385 { | |
386 png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr, | |
387 output_gamma)); | |
388 } | |
389 # endif | |
390 #endif | |
391 | |
392 #ifdef PNG_READ_QUANTIZE_SUPPORTED | |
393 /* Dither file to 8-bit. Supply a palette, the current number | |
394 * of elements in the palette, the maximum number of elements | 146 * of elements in the palette, the maximum number of elements |
395 * allowed, and a histogram if possible. If the current number | 147 * allowed, and a histogram if possible. If the current number |
396 * of colors is greater then the maximum number, the palette will be | 148 * of colors is greater then the maximum number, the palette will be |
397 * modified to fit in the maximum number. "full_quantize" indicates | 149 * modified to fit in the maximum number. "full_dither" indicates |
398 * whether we need a quantizing cube set up for RGB images, or if we | 150 * whether we need a dithering cube set up for RGB images, or if we |
399 * simply are reducing the number of colors in a paletted image. | 151 * simply are reducing the number of colors in a paletted image. |
400 */ | 152 */ |
401 | 153 |
402 typedef struct png_dsort_struct | 154 typedef struct png_dsort_struct |
403 { | 155 { |
404 struct png_dsort_struct * next; | 156 struct png_dsort_struct FAR * next; |
405 png_byte left; | 157 png_byte left; |
406 png_byte right; | 158 png_byte right; |
407 } png_dsort; | 159 } png_dsort; |
408 typedef png_dsort * png_dsortp; | 160 typedef png_dsort FAR * png_dsortp; |
409 typedef png_dsort * * png_dsortpp; | 161 typedef png_dsort FAR * FAR * png_dsortpp; |
410 | 162 |
411 void PNGAPI | 163 void PNGAPI |
412 png_set_quantize(png_structrp png_ptr, png_colorp palette, | 164 png_set_dither(png_structp png_ptr, png_colorp palette, |
413 int num_palette, int maximum_colors, png_const_uint_16p histogram, | 165 int num_palette, int maximum_colors, png_uint_16p histogram, |
414 int full_quantize) | 166 int full_dither) |
415 { | 167 { |
416 png_debug(1, "in png_set_quantize"); | 168 png_debug(1, "in png_set_dither"); |
417 | 169 |
418 if (!png_rtran_ok(png_ptr, 0)) | 170 if (png_ptr == NULL) |
419 return; | 171 return; |
| 172 png_ptr->transformations |= PNG_DITHER; |
420 | 173 |
421 png_ptr->transformations |= PNG_QUANTIZE; | 174 if (!full_dither) |
422 | |
423 if (!full_quantize) | |
424 { | 175 { |
425 int i; | 176 int i; |
426 | 177 |
427 png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr, | 178 png_ptr->dither_index = (png_bytep)png_malloc(png_ptr, |
428 (png_uint_32)(num_palette * (sizeof (png_byte)))); | 179 (png_uint_32)(num_palette * png_sizeof(png_byte))); |
429 for (i = 0; i < num_palette; i++) | 180 for (i = 0; i < num_palette; i++) |
430 png_ptr->quantize_index[i] = (png_byte)i; | 181 png_ptr->dither_index[i] = (png_byte)i; |
431 } | 182 } |
432 | 183 |
433 if (num_palette > maximum_colors) | 184 if (num_palette > maximum_colors) |
434 { | 185 { |
435 if (histogram != NULL) | 186 if (histogram != NULL) |
436 { | 187 { |
437 /* This is easy enough, just throw out the least used colors. | 188 /* This is easy enough, just throw out the least used colors. |
438 * Perhaps not the best solution, but good enough. | 189 * Perhaps not the best solution, but good enough. |
439 */ | 190 */ |
440 | 191 |
441 int i; | 192 int i; |
442 | 193 |
443 /* Initialize an array to sort colors */ | 194 /* Initialize an array to sort colors */ |
444 png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr, | 195 png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr, |
445 (png_uint_32)(num_palette * (sizeof (png_byte)))); | 196 (png_uint_32)(num_palette * png_sizeof(png_byte))); |
446 | 197 |
447 /* Initialize the quantize_sort array */ | 198 /* Initialize the dither_sort array */ |
448 for (i = 0; i < num_palette; i++) | 199 for (i = 0; i < num_palette; i++) |
449 png_ptr->quantize_sort[i] = (png_byte)i; | 200 png_ptr->dither_sort[i] = (png_byte)i; |
450 | 201 |
451 /* Find the least used palette entries by starting a | 202 /* Find the least used palette entries by starting a |
452 * bubble sort, and running it until we have sorted | 203 * bubble sort, and running it until we have sorted |
453 * out enough colors. Note that we don't care about | 204 * out enough colors. Note that we don't care about |
454 * sorting all the colors, just finding which are | 205 * sorting all the colors, just finding which are |
455 * least used. | 206 * least used. |
456 */ | 207 */ |
457 | 208 |
458 for (i = num_palette - 1; i >= maximum_colors; i--) | 209 for (i = num_palette - 1; i >= maximum_colors; i--) |
459 { | 210 { |
460 int done; /* To stop early if the list is pre-sorted */ | 211 int done; /* To stop early if the list is pre-sorted */ |
461 int j; | 212 int j; |
462 | 213 |
463 done = 1; | 214 done = 1; |
464 for (j = 0; j < i; j++) | 215 for (j = 0; j < i; j++) |
465 { | 216 { |
466 if (histogram[png_ptr->quantize_sort[j]] | 217 if (histogram[png_ptr->dither_sort[j]] |
467 < histogram[png_ptr->quantize_sort[j + 1]]) | 218 < histogram[png_ptr->dither_sort[j + 1]]) |
468 { | 219 { |
469 png_byte t; | 220 png_byte t; |
470 | 221 |
471 t = png_ptr->quantize_sort[j]; | 222 t = png_ptr->dither_sort[j]; |
472 png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1]; | 223 png_ptr->dither_sort[j] = png_ptr->dither_sort[j + 1]; |
473 png_ptr->quantize_sort[j + 1] = t; | 224 png_ptr->dither_sort[j + 1] = t; |
474 done = 0; | 225 done = 0; |
475 } | 226 } |
476 } | 227 } |
477 | |
478 if (done) | 228 if (done) |
479 break; | 229 break; |
480 } | 230 } |
481 | 231 |
482 /* Swap the palette around, and set up a table, if necessary */ | 232 /* Swap the palette around, and set up a table, if necessary */ |
483 if (full_quantize) | 233 if (full_dither) |
484 { | 234 { |
485 int j = num_palette; | 235 int j = num_palette; |
486 | 236 |
487 /* Put all the useful colors within the max, but don't | 237 /* Put all the useful colors within the max, but don't |
488 * move the others. | 238 * move the others. |
489 */ | 239 */ |
490 for (i = 0; i < maximum_colors; i++) | 240 for (i = 0; i < maximum_colors; i++) |
491 { | 241 { |
492 if ((int)png_ptr->quantize_sort[i] >= maximum_colors) | 242 if ((int)png_ptr->dither_sort[i] >= maximum_colors) |
493 { | 243 { |
494 do | 244 do |
495 j--; | 245 j--; |
496 while ((int)png_ptr->quantize_sort[j] >= maximum_colors); | 246 while ((int)png_ptr->dither_sort[j] >= maximum_colors); |
497 | |
498 palette[i] = palette[j]; | 247 palette[i] = palette[j]; |
499 } | 248 } |
500 } | 249 } |
501 } | 250 } |
502 else | 251 else |
503 { | 252 { |
504 int j = num_palette; | 253 int j = num_palette; |
505 | 254 |
506 /* Move all the used colors inside the max limit, and | 255 /* Move all the used colors inside the max limit, and |
507 * develop a translation table. | 256 * develop a translation table. |
508 */ | 257 */ |
509 for (i = 0; i < maximum_colors; i++) | 258 for (i = 0; i < maximum_colors; i++) |
510 { | 259 { |
511 /* Only move the colors we need to */ | 260 /* Only move the colors we need to */ |
512 if ((int)png_ptr->quantize_sort[i] >= maximum_colors) | 261 if ((int)png_ptr->dither_sort[i] >= maximum_colors) |
513 { | 262 { |
514 png_color tmp_color; | 263 png_color tmp_color; |
515 | 264 |
516 do | 265 do |
517 j--; | 266 j--; |
518 while ((int)png_ptr->quantize_sort[j] >= maximum_colors); | 267 while ((int)png_ptr->dither_sort[j] >= maximum_colors); |
519 | 268 |
520 tmp_color = palette[j]; | 269 tmp_color = palette[j]; |
521 palette[j] = palette[i]; | 270 palette[j] = palette[i]; |
522 palette[i] = tmp_color; | 271 palette[i] = tmp_color; |
523 /* Indicate where the color went */ | 272 /* Indicate where the color went */ |
524 png_ptr->quantize_index[j] = (png_byte)i; | 273 png_ptr->dither_index[j] = (png_byte)i; |
525 png_ptr->quantize_index[i] = (png_byte)j; | 274 png_ptr->dither_index[i] = (png_byte)j; |
526 } | 275 } |
527 } | 276 } |
528 | 277 |
529 /* Find closest color for those colors we are not using */ | 278 /* Find closest color for those colors we are not using */ |
530 for (i = 0; i < num_palette; i++) | 279 for (i = 0; i < num_palette; i++) |
531 { | 280 { |
532 if ((int)png_ptr->quantize_index[i] >= maximum_colors) | 281 if ((int)png_ptr->dither_index[i] >= maximum_colors) |
533 { | 282 { |
534 int min_d, k, min_k, d_index; | 283 int min_d, k, min_k, d_index; |
535 | 284 |
536 /* Find the closest color to one we threw out */ | 285 /* Find the closest color to one we threw out */ |
537 d_index = png_ptr->quantize_index[i]; | 286 d_index = png_ptr->dither_index[i]; |
538 min_d = PNG_COLOR_DIST(palette[d_index], palette[0]); | 287 min_d = PNG_COLOR_DIST(palette[d_index], palette[0]); |
539 for (k = 1, min_k = 0; k < maximum_colors; k++) | 288 for (k = 1, min_k = 0; k < maximum_colors; k++) |
540 { | 289 { |
541 int d; | 290 int d; |
542 | 291 |
543 d = PNG_COLOR_DIST(palette[d_index], palette[k]); | 292 d = PNG_COLOR_DIST(palette[d_index], palette[k]); |
544 | 293 |
545 if (d < min_d) | 294 if (d < min_d) |
546 { | 295 { |
547 min_d = d; | 296 min_d = d; |
548 min_k = k; | 297 min_k = k; |
549 } | 298 } |
550 } | 299 } |
551 /* Point to closest color */ | 300 /* Point to closest color */ |
552 png_ptr->quantize_index[i] = (png_byte)min_k; | 301 png_ptr->dither_index[i] = (png_byte)min_k; |
553 } | 302 } |
554 } | 303 } |
555 } | 304 } |
556 png_free(png_ptr, png_ptr->quantize_sort); | 305 png_free(png_ptr, png_ptr->dither_sort); |
557 png_ptr->quantize_sort = NULL; | 306 png_ptr->dither_sort = NULL; |
558 } | 307 } |
559 else | 308 else |
560 { | 309 { |
561 /* This is much harder to do simply (and quickly). Perhaps | 310 /* This is much harder to do simply (and quickly). Perhaps |
562 * we need to go through a median cut routine, but those | 311 * we need to go through a median cut routine, but those |
563 * don't always behave themselves with only a few colors | 312 * don't always behave themselves with only a few colors |
564 * as input. So we will just find the closest two colors, | 313 * as input. So we will just find the closest two colors, |
565 * and throw out one of them (chosen somewhat randomly). | 314 * and throw out one of them (chosen somewhat randomly). |
566 * [We don't understand this at all, so if someone wants to | 315 * [We don't understand this at all, so if someone wants to |
567 * work on improving it, be our guest - AED, GRP] | 316 * work on improving it, be our guest - AED, GRP] |
568 */ | 317 */ |
569 int i; | 318 int i; |
570 int max_d; | 319 int max_d; |
571 int num_new_palette; | 320 int num_new_palette; |
572 png_dsortp t; | 321 png_dsortp t; |
573 png_dsortpp hash; | 322 png_dsortpp hash; |
574 | 323 |
575 t = NULL; | 324 t = NULL; |
576 | 325 |
577 /* Initialize palette index arrays */ | 326 /* Initialize palette index arrays */ |
578 png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, | 327 png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, |
579 (png_uint_32)(num_palette * (sizeof (png_byte)))); | 328 (png_uint_32)(num_palette * png_sizeof(png_byte))); |
580 png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, | 329 png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, |
581 (png_uint_32)(num_palette * (sizeof (png_byte)))); | 330 (png_uint_32)(num_palette * png_sizeof(png_byte))); |
582 | 331 |
583 /* Initialize the sort array */ | 332 /* Initialize the sort array */ |
584 for (i = 0; i < num_palette; i++) | 333 for (i = 0; i < num_palette; i++) |
585 { | 334 { |
586 png_ptr->index_to_palette[i] = (png_byte)i; | 335 png_ptr->index_to_palette[i] = (png_byte)i; |
587 png_ptr->palette_to_index[i] = (png_byte)i; | 336 png_ptr->palette_to_index[i] = (png_byte)i; |
588 } | 337 } |
589 | 338 |
590 hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 * | 339 hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 * |
591 (sizeof (png_dsortp)))); | 340 png_sizeof(png_dsortp))); |
592 | 341 |
593 num_new_palette = num_palette; | 342 num_new_palette = num_palette; |
594 | 343 |
595 /* Initial wild guess at how far apart the farthest pixel | 344 /* Initial wild guess at how far apart the farthest pixel |
596 * pair we will be eliminating will be. Larger | 345 * pair we will be eliminating will be. Larger |
597 * numbers mean more areas will be allocated, Smaller | 346 * numbers mean more areas will be allocated, Smaller |
598 * numbers run the risk of not saving enough data, and | 347 * numbers run the risk of not saving enough data, and |
599 * having to do this all over again. | 348 * having to do this all over again. |
600 * | 349 * |
601 * I have not done extensive checking on this number. | 350 * I have not done extensive checking on this number. |
602 */ | 351 */ |
603 max_d = 96; | 352 max_d = 96; |
604 | 353 |
605 while (num_new_palette > maximum_colors) | 354 while (num_new_palette > maximum_colors) |
606 { | 355 { |
607 for (i = 0; i < num_new_palette - 1; i++) | 356 for (i = 0; i < num_new_palette - 1; i++) |
608 { | 357 { |
609 int j; | 358 int j; |
610 | 359 |
611 for (j = i + 1; j < num_new_palette; j++) | 360 for (j = i + 1; j < num_new_palette; j++) |
612 { | 361 { |
613 int d; | 362 int d; |
614 | 363 |
615 d = PNG_COLOR_DIST(palette[i], palette[j]); | 364 d = PNG_COLOR_DIST(palette[i], palette[j]); |
616 | 365 |
617 if (d <= max_d) | 366 if (d <= max_d) |
618 { | 367 { |
619 | 368 |
620 t = (png_dsortp)png_malloc_warn(png_ptr, | 369 t = (png_dsortp)png_malloc_warn(png_ptr, |
621 (png_uint_32)(sizeof (png_dsort))); | 370 (png_uint_32)(png_sizeof(png_dsort))); |
622 | |
623 if (t == NULL) | 371 if (t == NULL) |
624 break; | 372 break; |
625 | |
626 t->next = hash[d]; | 373 t->next = hash[d]; |
627 t->left = (png_byte)i; | 374 t->left = (png_byte)i; |
628 t->right = (png_byte)j; | 375 t->right = (png_byte)j; |
629 hash[d] = t; | 376 hash[d] = t; |
630 } | 377 } |
631 } | 378 } |
632 if (t == NULL) | 379 if (t == NULL) |
633 break; | 380 break; |
634 } | 381 } |
635 | 382 |
636 if (t != NULL) | 383 if (t != NULL) |
637 for (i = 0; i <= max_d; i++) | 384 for (i = 0; i <= max_d; i++) |
638 { | 385 { |
639 if (hash[i] != NULL) | 386 if (hash[i] != NULL) |
640 { | 387 { |
641 png_dsortp p; | 388 png_dsortp p; |
642 | 389 |
643 for (p = hash[i]; p; p = p->next) | 390 for (p = hash[i]; p; p = p->next) |
644 { | 391 { |
645 if ((int)png_ptr->index_to_palette[p->left] | 392 if ((int)png_ptr->index_to_palette[p->left] |
646 < num_new_palette && | 393 < num_new_palette && |
647 (int)png_ptr->index_to_palette[p->right] | 394 (int)png_ptr->index_to_palette[p->right] |
648 < num_new_palette) | 395 < num_new_palette) |
649 { | 396 { |
650 int j, next_j; | 397 int j, next_j; |
651 | 398 |
652 if (num_new_palette & 0x01) | 399 if (num_new_palette & 0x01) |
653 { | 400 { |
654 j = p->left; | 401 j = p->left; |
655 next_j = p->right; | 402 next_j = p->right; |
656 } | 403 } |
657 else | 404 else |
658 { | 405 { |
659 j = p->right; | 406 j = p->right; |
660 next_j = p->left; | 407 next_j = p->left; |
661 } | 408 } |
662 | 409 |
663 num_new_palette--; | 410 num_new_palette--; |
664 palette[png_ptr->index_to_palette[j]] | 411 palette[png_ptr->index_to_palette[j]] |
665 = palette[num_new_palette]; | 412 = palette[num_new_palette]; |
666 if (!full_quantize) | 413 if (!full_dither) |
667 { | 414 { |
668 int k; | 415 int k; |
669 | 416 |
670 for (k = 0; k < num_palette; k++) | 417 for (k = 0; k < num_palette; k++) |
671 { | 418 { |
672 if (png_ptr->quantize_index[k] == | 419 if (png_ptr->dither_index[k] == |
673 png_ptr->index_to_palette[j]) | 420 png_ptr->index_to_palette[j]) |
674 png_ptr->quantize_index[k] = | 421 png_ptr->dither_index[k] = |
675 png_ptr->index_to_palette[next_j]; | 422 png_ptr->index_to_palette[next_j]; |
676 | 423 if ((int)png_ptr->dither_index[k] == |
677 if ((int)png_ptr->quantize_index[k] == | 424 num_new_palette) |
678 num_new_palette) | 425 png_ptr->dither_index[k] = |
679 png_ptr->quantize_index[k] = | 426 png_ptr->index_to_palette[j]; |
680 png_ptr->index_to_palette[j]; | |
681 } | 427 } |
682 } | 428 } |
683 | 429 |
684 png_ptr->index_to_palette[png_ptr->palette_to_index | 430 png_ptr->index_to_palette[png_ptr->palette_to_index |
685 [num_new_palette]] = png_ptr->index_to_palette[j]; | 431 [num_new_palette]] = png_ptr->index_to_palette[j]; |
686 | |
687 png_ptr->palette_to_index[png_ptr->index_to_palette[j]] | 432 png_ptr->palette_to_index[png_ptr->index_to_palette[j]] |
688 = png_ptr->palette_to_index[num_new_palette]; | 433 = png_ptr->palette_to_index[num_new_palette]; |
689 | 434 |
690 png_ptr->index_to_palette[j] = | 435 png_ptr->index_to_palette[j] = |
691 (png_byte)num_new_palette; | 436 (png_byte)num_new_palette; |
692 | |
693 png_ptr->palette_to_index[num_new_palette] = | 437 png_ptr->palette_to_index[num_new_palette] = |
694 (png_byte)j; | 438 (png_byte)j; |
695 } | 439 } |
696 if (num_new_palette <= maximum_colors) | 440 if (num_new_palette <= maximum_colors) |
697 break; | 441 break; |
698 } | 442 } |
699 if (num_new_palette <= maximum_colors) | 443 if (num_new_palette <= maximum_colors) |
700 break; | 444 break; |
701 } | 445 } |
702 } | 446 } |
(...skipping 21 matching lines...) Expand all Loading... |
724 png_ptr->index_to_palette = NULL; | 468 png_ptr->index_to_palette = NULL; |
725 } | 469 } |
726 num_palette = maximum_colors; | 470 num_palette = maximum_colors; |
727 } | 471 } |
728 if (png_ptr->palette == NULL) | 472 if (png_ptr->palette == NULL) |
729 { | 473 { |
730 png_ptr->palette = palette; | 474 png_ptr->palette = palette; |
731 } | 475 } |
732 png_ptr->num_palette = (png_uint_16)num_palette; | 476 png_ptr->num_palette = (png_uint_16)num_palette; |
733 | 477 |
734 if (full_quantize) | 478 if (full_dither) |
735 { | 479 { |
736 int i; | 480 int i; |
737 png_bytep distance; | 481 png_bytep distance; |
738 int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS + | 482 int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS + |
739 PNG_QUANTIZE_BLUE_BITS; | 483 PNG_DITHER_BLUE_BITS; |
740 int num_red = (1 << PNG_QUANTIZE_RED_BITS); | 484 int num_red = (1 << PNG_DITHER_RED_BITS); |
741 int num_green = (1 << PNG_QUANTIZE_GREEN_BITS); | 485 int num_green = (1 << PNG_DITHER_GREEN_BITS); |
742 int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS); | 486 int num_blue = (1 << PNG_DITHER_BLUE_BITS); |
743 png_size_t num_entries = ((png_size_t)1 << total_bits); | 487 png_size_t num_entries = ((png_size_t)1 << total_bits); |
744 | 488 |
745 png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr, | 489 png_ptr->palette_lookup = (png_bytep )png_calloc(png_ptr, |
746 (png_uint_32)(num_entries * (sizeof (png_byte)))); | 490 (png_uint_32)(num_entries * png_sizeof(png_byte))); |
747 | 491 |
748 distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * | 492 distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * |
749 (sizeof (png_byte)))); | 493 png_sizeof(png_byte))); |
750 | 494 png_memset(distance, 0xff, num_entries * png_sizeof(png_byte)); |
751 memset(distance, 0xff, num_entries * (sizeof (png_byte))); | |
752 | 495 |
753 for (i = 0; i < num_palette; i++) | 496 for (i = 0; i < num_palette; i++) |
754 { | 497 { |
755 int ir, ig, ib; | 498 int ir, ig, ib; |
756 int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS)); | 499 int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS)); |
757 int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS)); | 500 int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS)); |
758 int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS)); | 501 int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS)); |
759 | 502 |
760 for (ir = 0; ir < num_red; ir++) | 503 for (ir = 0; ir < num_red; ir++) |
761 { | 504 { |
762 /* int dr = abs(ir - r); */ | 505 /* int dr = abs(ir - r); */ |
763 int dr = ((ir > r) ? ir - r : r - ir); | 506 int dr = ((ir > r) ? ir - r : r - ir); |
764 int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS + | 507 int index_r = (ir << (PNG_DITHER_BLUE_BITS + |
765 PNG_QUANTIZE_GREEN_BITS)); | 508 PNG_DITHER_GREEN_BITS)); |
766 | 509 |
767 for (ig = 0; ig < num_green; ig++) | 510 for (ig = 0; ig < num_green; ig++) |
768 { | 511 { |
769 /* int dg = abs(ig - g); */ | 512 /* int dg = abs(ig - g); */ |
770 int dg = ((ig > g) ? ig - g : g - ig); | 513 int dg = ((ig > g) ? ig - g : g - ig); |
771 int dt = dr + dg; | 514 int dt = dr + dg; |
772 int dm = ((dr > dg) ? dr : dg); | 515 int dm = ((dr > dg) ? dr : dg); |
773 int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS); | 516 int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS); |
774 | 517 |
775 for (ib = 0; ib < num_blue; ib++) | 518 for (ib = 0; ib < num_blue; ib++) |
776 { | 519 { |
777 int d_index = index_g | ib; | 520 int d_index = index_g | ib; |
778 /* int db = abs(ib - b); */ | 521 /* int db = abs(ib - b); */ |
779 int db = ((ib > b) ? ib - b : b - ib); | 522 int db = ((ib > b) ? ib - b : b - ib); |
780 int dmax = ((dm > db) ? dm : db); | 523 int dmax = ((dm > db) ? dm : db); |
781 int d = dmax + dt + db; | 524 int d = dmax + dt + db; |
782 | 525 |
783 if (d < (int)distance[d_index]) | 526 if (d < (int)distance[d_index]) |
784 { | 527 { |
785 distance[d_index] = (png_byte)d; | 528 distance[d_index] = (png_byte)d; |
786 png_ptr->palette_lookup[d_index] = (png_byte)i; | 529 png_ptr->palette_lookup[d_index] = (png_byte)i; |
787 } | 530 } |
788 } | 531 } |
789 } | 532 } |
790 } | 533 } |
791 } | 534 } |
792 | 535 |
793 png_free(png_ptr, distance); | 536 png_free(png_ptr, distance); |
794 } | 537 } |
795 } | 538 } |
796 #endif /* PNG_READ_QUANTIZE_SUPPORTED */ | 539 #endif |
797 | 540 |
798 #ifdef PNG_READ_GAMMA_SUPPORTED | 541 #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) |
799 void PNGFAPI | 542 /* Transform the image from the file_gamma to the screen_gamma. We |
800 png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma, | 543 * only do transformations on images where the file_gamma and screen_gamma |
801 png_fixed_point file_gamma) | 544 * are not close reciprocals, otherwise it slows things down slightly, and |
| 545 * also needlessly introduces small errors. |
| 546 * |
| 547 * We will turn off gamma transformation later if no semitransparent entries |
| 548 * are present in the tRNS array for palette images. We can't do it here |
| 549 * because we don't necessarily have the tRNS chunk yet. |
| 550 */ |
| 551 void PNGAPI |
| 552 png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma) |
802 { | 553 { |
803 png_debug(1, "in png_set_gamma_fixed"); | 554 png_debug(1, "in png_set_gamma"); |
804 | 555 |
805 if (!png_rtran_ok(png_ptr, 0)) | 556 if (png_ptr == NULL) |
806 return; | 557 return; |
807 | 558 |
808 /* New in libpng-1.5.4 - reserve particular negative values as flags. */ | 559 if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) || |
809 scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/); | 560 (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) || |
810 file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/); | 561 (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) |
811 | 562 png_ptr->transformations |= PNG_GAMMA; |
812 /* Checking the gamma values for being >0 was added in 1.5.4 along with the | 563 png_ptr->gamma = (float)file_gamma; |
813 * premultiplied alpha support; this actually hides an undocumented feature | 564 png_ptr->screen_gamma = (float)scrn_gamma; |
814 * of the previous implementation which allowed gamma processing to be | |
815 * disabled in background handling. There is no evidence (so far) that this | |
816 * was being used; however, png_set_background itself accepted and must still | |
817 * accept '0' for the gamma value it takes, because it isn't always used. | |
818 * | |
819 * Since this is an API change (albeit a very minor one that removes an | |
820 * undocumented API feature) the following checks were only enabled in | |
821 * libpng-1.6.0. | |
822 */ | |
823 if (file_gamma <= 0) | |
824 png_error(png_ptr, "invalid file gamma in png_set_gamma"); | |
825 | |
826 if (scrn_gamma <= 0) | |
827 png_error(png_ptr, "invalid screen gamma in png_set_gamma"); | |
828 | |
829 /* Set the gamma values unconditionally - this overrides the value in the PNG | |
830 * file if a gAMA chunk was present. png_set_alpha_mode provides a | |
831 * different, easier, way to default the file gamma. | |
832 */ | |
833 png_ptr->colorspace.gamma = file_gamma; | |
834 png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; | |
835 png_ptr->screen_gamma = scrn_gamma; | |
836 } | 565 } |
837 | 566 #endif |
838 # ifdef PNG_FLOATING_POINT_SUPPORTED | |
839 void PNGAPI | |
840 png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma) | |
841 { | |
842 png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma), | |
843 convert_gamma_value(png_ptr, file_gamma)); | |
844 } | |
845 # endif /* FLOATING_POINT_SUPPORTED */ | |
846 #endif /* READ_GAMMA */ | |
847 | 567 |
848 #ifdef PNG_READ_EXPAND_SUPPORTED | 568 #ifdef PNG_READ_EXPAND_SUPPORTED |
849 /* Expand paletted images to RGB, expand grayscale images of | 569 /* Expand paletted images to RGB, expand grayscale images of |
850 * less than 8-bit depth to 8-bit depth, and expand tRNS chunks | 570 * less than 8-bit depth to 8-bit depth, and expand tRNS chunks |
851 * to alpha channels. | 571 * to alpha channels. |
852 */ | 572 */ |
853 void PNGAPI | 573 void PNGAPI |
854 png_set_expand(png_structrp png_ptr) | 574 png_set_expand(png_structp png_ptr) |
855 { | 575 { |
856 png_debug(1, "in png_set_expand"); | 576 png_debug(1, "in png_set_expand"); |
857 | 577 |
858 if (!png_rtran_ok(png_ptr, 0)) | 578 if (png_ptr == NULL) |
859 return; | 579 return; |
860 | 580 |
861 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); | 581 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); |
| 582 png_ptr->flags &= ~PNG_FLAG_ROW_INIT; |
862 } | 583 } |
863 | 584 |
864 /* GRR 19990627: the following three functions currently are identical | 585 /* GRR 19990627: the following three functions currently are identical |
865 * to png_set_expand(). However, it is entirely reasonable that someone | 586 * to png_set_expand(). However, it is entirely reasonable that someone |
866 * might wish to expand an indexed image to RGB but *not* expand a single, | 587 * might wish to expand an indexed image to RGB but *not* expand a single, |
867 * fully transparent palette entry to a full alpha channel--perhaps instead | 588 * fully transparent palette entry to a full alpha channel--perhaps instead |
868 * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace | 589 * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace |
869 * the transparent color with a particular RGB value, or drop tRNS entirely. | 590 * the transparent color with a particular RGB value, or drop tRNS entirely. |
870 * IOW, a future version of the library may make the transformations flag | 591 * IOW, a future version of the library may make the transformations flag |
871 * a bit more fine-grained, with separate bits for each of these three | 592 * a bit more fine-grained, with separate bits for each of these three |
872 * functions. | 593 * functions. |
873 * | 594 * |
874 * More to the point, these functions make it obvious what libpng will be | 595 * More to the point, these functions make it obvious what libpng will be |
875 * doing, whereas "expand" can (and does) mean any number of things. | 596 * doing, whereas "expand" can (and does) mean any number of things. |
876 * | 597 * |
877 * GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified | 598 * GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified |
878 * to expand only the sample depth but not to expand the tRNS to alpha | 599 * to expand only the sample depth but not to expand the tRNS to alpha |
879 * and its name was changed to png_set_expand_gray_1_2_4_to_8(). | 600 * and its name was changed to png_set_expand_gray_1_2_4_to_8(). |
880 */ | 601 */ |
881 | 602 |
882 /* Expand paletted images to RGB. */ | 603 /* Expand paletted images to RGB. */ |
883 void PNGAPI | 604 void PNGAPI |
884 png_set_palette_to_rgb(png_structrp png_ptr) | 605 png_set_palette_to_rgb(png_structp png_ptr) |
885 { | 606 { |
886 png_debug(1, "in png_set_palette_to_rgb"); | 607 png_debug(1, "in png_set_palette_to_rgb"); |
887 | 608 |
888 if (!png_rtran_ok(png_ptr, 0)) | 609 if (png_ptr == NULL) |
889 return; | 610 return; |
890 | 611 |
891 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); | 612 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); |
892 } | 613 png_ptr->flags &= ~PNG_FLAG_ROW_INIT; |
893 | 614 } |
| 615 |
| 616 #ifndef PNG_1_0_X |
894 /* Expand grayscale images of less than 8-bit depth to 8 bits. */ | 617 /* Expand grayscale images of less than 8-bit depth to 8 bits. */ |
895 void PNGAPI | 618 void PNGAPI |
896 png_set_expand_gray_1_2_4_to_8(png_structrp png_ptr) | 619 png_set_expand_gray_1_2_4_to_8(png_structp png_ptr) |
897 { | 620 { |
898 png_debug(1, "in png_set_expand_gray_1_2_4_to_8"); | 621 png_debug(1, "in png_set_expand_gray_1_2_4_to_8"); |
899 | 622 |
900 if (!png_rtran_ok(png_ptr, 0)) | 623 if (png_ptr == NULL) |
901 return; | 624 return; |
902 | 625 |
903 png_ptr->transformations |= PNG_EXPAND; | 626 png_ptr->transformations |= PNG_EXPAND; |
904 } | 627 png_ptr->flags &= ~PNG_FLAG_ROW_INIT; |
| 628 } |
| 629 #endif |
| 630 |
| 631 #if defined(PNG_1_0_X) || defined(PNG_1_2_X) |
| 632 /* Expand grayscale images of less than 8-bit depth to 8 bits. */ |
| 633 /* Deprecated as of libpng-1.2.9 */ |
| 634 void PNGAPI |
| 635 png_set_gray_1_2_4_to_8(png_structp png_ptr) |
| 636 { |
| 637 png_debug(1, "in png_set_gray_1_2_4_to_8"); |
| 638 |
| 639 if (png_ptr == NULL) |
| 640 return; |
| 641 |
| 642 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); |
| 643 } |
| 644 #endif |
| 645 |
905 | 646 |
906 /* Expand tRNS chunks to alpha channels. */ | 647 /* Expand tRNS chunks to alpha channels. */ |
907 void PNGAPI | 648 void PNGAPI |
908 png_set_tRNS_to_alpha(png_structrp png_ptr) | 649 png_set_tRNS_to_alpha(png_structp png_ptr) |
909 { | 650 { |
910 png_debug(1, "in png_set_tRNS_to_alpha"); | 651 png_debug(1, "in png_set_tRNS_to_alpha"); |
911 | 652 |
912 if (!png_rtran_ok(png_ptr, 0)) | |
913 return; | |
914 | |
915 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); | 653 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); |
| 654 png_ptr->flags &= ~PNG_FLAG_ROW_INIT; |
916 } | 655 } |
917 #endif /* defined(PNG_READ_EXPAND_SUPPORTED) */ | 656 #endif /* defined(PNG_READ_EXPAND_SUPPORTED) */ |
918 | 657 |
919 #ifdef PNG_READ_EXPAND_16_SUPPORTED | 658 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED |
920 /* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise | 659 void PNGAPI |
921 * it may not work correctly.) | 660 png_set_gray_to_rgb(png_structp png_ptr) |
| 661 { |
| 662 png_debug(1, "in png_set_gray_to_rgb"); |
| 663 |
| 664 png_ptr->transformations |= PNG_GRAY_TO_RGB; |
| 665 png_ptr->flags &= ~PNG_FLAG_ROW_INIT; |
| 666 } |
| 667 #endif |
| 668 |
| 669 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED |
| 670 #ifdef PNG_FLOATING_POINT_SUPPORTED |
| 671 /* Convert a RGB image to a grayscale of the same width. This allows us, |
| 672 * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image. |
922 */ | 673 */ |
923 void PNGAPI | 674 |
924 png_set_expand_16(png_structrp png_ptr) | 675 void PNGAPI |
925 { | 676 png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red, |
926 png_debug(1, "in png_set_expand_16"); | 677 double green) |
927 | 678 { |
928 if (!png_rtran_ok(png_ptr, 0)) | 679 int red_fixed, green_fixed; |
929 return; | 680 if (png_ptr == NULL) |
930 | 681 return; |
931 png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS); | 682 if (red > 21474.83647 || red < -21474.83648 || |
932 } | 683 green > 21474.83647 || green < -21474.83648) |
933 #endif | 684 { |
934 | 685 png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients"); |
935 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED | 686 red_fixed = -1; |
936 void PNGAPI | 687 green_fixed = -1; |
937 png_set_gray_to_rgb(png_structrp png_ptr) | 688 } |
938 { | 689 else |
939 png_debug(1, "in png_set_gray_to_rgb"); | 690 { |
940 | 691 red_fixed = (int)((float)red*100000.0 + 0.5); |
941 if (!png_rtran_ok(png_ptr, 0)) | 692 green_fixed = (int)((float)green*100000.0 + 0.5); |
942 return; | 693 } |
943 | 694 png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed); |
944 /* Because rgb must be 8 bits or more: */ | 695 } |
945 png_set_expand_gray_1_2_4_to_8(png_ptr); | 696 #endif |
946 png_ptr->transformations |= PNG_GRAY_TO_RGB; | 697 |
947 } | 698 void PNGAPI |
948 #endif | 699 png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, |
949 | 700 png_fixed_point red, png_fixed_point green) |
950 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED | |
951 void PNGFAPI | |
952 png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action, | |
953 png_fixed_point red, png_fixed_point green) | |
954 { | 701 { |
955 png_debug(1, "in png_set_rgb_to_gray"); | 702 png_debug(1, "in png_set_rgb_to_gray"); |
956 | 703 |
957 /* Need the IHDR here because of the check on color_type below. */ | 704 if (png_ptr == NULL) |
958 /* TODO: fix this */ | |
959 if (!png_rtran_ok(png_ptr, 1)) | |
960 return; | 705 return; |
961 | 706 |
962 switch(error_action) | 707 switch(error_action) |
963 { | 708 { |
964 case PNG_ERROR_ACTION_NONE: | 709 case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY; |
965 png_ptr->transformations |= PNG_RGB_TO_GRAY; | 710 break; |
966 break; | 711 |
967 | 712 case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN; |
968 case PNG_ERROR_ACTION_WARN: | 713 break; |
969 png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN; | 714 |
970 break; | 715 case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; |
971 | 716 } |
972 case PNG_ERROR_ACTION_ERROR: | |
973 png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; | |
974 break; | |
975 | |
976 default: | |
977 png_error(png_ptr, "invalid error action to rgb_to_gray"); | |
978 break; | |
979 } | |
980 | |
981 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) | 717 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
982 #ifdef PNG_READ_EXPAND_SUPPORTED | 718 #ifdef PNG_READ_EXPAND_SUPPORTED |
983 png_ptr->transformations |= PNG_EXPAND; | 719 png_ptr->transformations |= PNG_EXPAND; |
984 #else | 720 #else |
985 { | 721 { |
986 /* Make this an error in 1.6 because otherwise the application may assume | 722 png_warning(png_ptr, |
987 * that it just worked and get a memory overwrite. | 723 "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED."); |
988 */ | 724 png_ptr->transformations &= ~PNG_RGB_TO_GRAY; |
989 png_error(png_ptr, | 725 } |
990 "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED"); | 726 #endif |
991 | 727 { |
992 /* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */ | 728 png_uint_16 red_int, green_int; |
993 } | 729 if (red < 0 || green < 0) |
994 #endif | 730 { |
995 { | 731 red_int = 6968; /* .212671 * 32768 + .5 */ |
996 if (red >= 0 && green >= 0 && red + green <= PNG_FP_1) | 732 green_int = 23434; /* .715160 * 32768 + .5 */ |
997 { | 733 } |
998 png_uint_16 red_int, green_int; | 734 else if (red + green < 100000L) |
999 | 735 { |
1000 /* NOTE: this calculation does not round, but this behavior is retained | 736 red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L); |
1001 * for consistency, the inaccuracy is very small. The code here always | 737 green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L); |
1002 * overwrites the coefficients, regardless of whether they have been | 738 } |
1003 * defaulted or set already. | |
1004 */ | |
1005 red_int = (png_uint_16)(((png_uint_32)red*32768)/100000); | |
1006 green_int = (png_uint_16)(((png_uint_32)green*32768)/100000); | |
1007 | |
1008 png_ptr->rgb_to_gray_red_coeff = red_int; | |
1009 png_ptr->rgb_to_gray_green_coeff = green_int; | |
1010 png_ptr->rgb_to_gray_coefficients_set = 1; | |
1011 } | |
1012 | |
1013 else | 739 else |
1014 { | 740 { |
1015 if (red >= 0 && green >= 0) | 741 png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients"); |
1016 png_app_warning(png_ptr, | 742 red_int = 6968; |
1017 "ignoring out of range rgb_to_gray coefficients"); | 743 green_int = 23434; |
1018 | 744 } |
1019 /* Use the defaults, from the cHRM chunk if set, else the historical | 745 png_ptr->rgb_to_gray_red_coeff = red_int; |
1020 * values which are close to the sRGB/HDTV/ITU-Rec 709 values. See | 746 png_ptr->rgb_to_gray_green_coeff = green_int; |
1021 * png_do_rgb_to_gray for more discussion of the values. In this case | 747 png_ptr->rgb_to_gray_blue_coeff = |
1022 * the coefficients are not marked as 'set' and are not overwritten if | 748 (png_uint_16)(32768 - red_int - green_int); |
1023 * something has already provided a default. | 749 } |
1024 */ | 750 } |
1025 if (png_ptr->rgb_to_gray_red_coeff == 0 && | 751 #endif |
1026 png_ptr->rgb_to_gray_green_coeff == 0) | |
1027 { | |
1028 png_ptr->rgb_to_gray_red_coeff = 6968; | |
1029 png_ptr->rgb_to_gray_green_coeff = 23434; | |
1030 /* png_ptr->rgb_to_gray_blue_coeff = 2366; */ | |
1031 } | |
1032 } | |
1033 } | |
1034 } | |
1035 | |
1036 #ifdef PNG_FLOATING_POINT_SUPPORTED | |
1037 /* Convert a RGB image to a grayscale of the same width. This allows us, | |
1038 * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image. | |
1039 */ | |
1040 | |
1041 void PNGAPI | |
1042 png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red, | |
1043 double green) | |
1044 { | |
1045 png_set_rgb_to_gray_fixed(png_ptr, error_action, | |
1046 png_fixed(png_ptr, red, "rgb to gray red coefficient"), | |
1047 png_fixed(png_ptr, green, "rgb to gray green coefficient")); | |
1048 } | |
1049 #endif /* FLOATING POINT */ | |
1050 | |
1051 #endif /* RGB_TO_GRAY */ | |
1052 | 752 |
1053 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ | 753 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ |
| 754 defined(PNG_LEGACY_SUPPORTED) || \ |
1054 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) | 755 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) |
1055 void PNGAPI | 756 void PNGAPI |
1056 png_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr | 757 png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr |
1057 read_user_transform_fn) | 758 read_user_transform_fn) |
1058 { | 759 { |
1059 png_debug(1, "in png_set_read_user_transform_fn"); | 760 png_debug(1, "in png_set_read_user_transform_fn"); |
1060 | 761 |
| 762 if (png_ptr == NULL) |
| 763 return; |
| 764 |
1061 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED | 765 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED |
1062 png_ptr->transformations |= PNG_USER_TRANSFORM; | 766 png_ptr->transformations |= PNG_USER_TRANSFORM; |
1063 png_ptr->read_user_transform_fn = read_user_transform_fn; | 767 png_ptr->read_user_transform_fn = read_user_transform_fn; |
1064 #endif | 768 #endif |
1065 } | 769 #ifdef PNG_LEGACY_SUPPORTED |
1066 #endif | 770 if (read_user_transform_fn) |
1067 | 771 png_warning(png_ptr, |
1068 #ifdef PNG_READ_TRANSFORMS_SUPPORTED | 772 "This version of libpng does not support user transforms"); |
1069 #ifdef PNG_READ_GAMMA_SUPPORTED | 773 #endif |
1070 /* In the case of gamma transformations only do transformations on images where | |
1071 * the [file] gamma and screen_gamma are not close reciprocals, otherwise it | |
1072 * slows things down slightly, and also needlessly introduces small errors. | |
1073 */ | |
1074 static int /* PRIVATE */ | |
1075 png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma) | |
1076 { | |
1077 /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma | |
1078 * correction as a difference of the overall transform from 1.0 | |
1079 * | |
1080 * We want to compare the threshold with s*f - 1, if we get | |
1081 * overflow here it is because of wacky gamma values so we | |
1082 * turn on processing anyway. | |
1083 */ | |
1084 png_fixed_point gtest; | |
1085 return !png_muldiv(>est, screen_gamma, file_gamma, PNG_FP_1) || | |
1086 png_gamma_significant(gtest); | |
1087 } | 774 } |
1088 #endif | 775 #endif |
1089 | 776 |
1090 /* Initialize everything needed for the read. This includes modifying | 777 /* Initialize everything needed for the read. This includes modifying |
1091 * the palette. | 778 * the palette. |
1092 */ | 779 */ |
1093 | 780 void /* PRIVATE */ |
1094 /*For the moment 'png_init_palette_transformations' and | 781 png_init_read_transformations(png_structp png_ptr) |
1095 * 'png_init_rgb_transformations' only do some flag canceling optimizations. | 782 { |
1096 * The intent is that these two routines should have palette or rgb operations | 783 png_debug(1, "in png_init_read_transformations"); |
1097 * extracted from 'png_init_read_transformations'. | 784 |
1098 */ | 785 #ifdef PNG_USELESS_TESTS_SUPPORTED |
1099 static void /* PRIVATE */ | 786 if (png_ptr != NULL) |
1100 png_init_palette_transformations(png_structrp png_ptr) | 787 #endif |
1101 { | 788 { |
1102 /* Called to handle the (input) palette case. In png_do_read_transformations | 789 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ |
1103 * the first step is to expand the palette if requested, so this code must | 790 defined(PNG_READ_SHIFT_SUPPORTED) || \ |
1104 * take care to only make changes that are invariant with respect to the | 791 defined(PNG_READ_GAMMA_SUPPORTED) |
1105 * palette expansion, or only do them if there is no expansion. | 792 int color_type = png_ptr->color_type; |
1106 * | 793 #endif |
1107 * STRIP_ALPHA has already been handled in the caller (by setting num_trans | |
1108 * to 0.) | |
1109 */ | |
1110 int input_has_alpha = 0; | |
1111 int input_has_transparency = 0; | |
1112 | |
1113 if (png_ptr->num_trans > 0) | |
1114 { | |
1115 int i; | |
1116 | |
1117 /* Ignore if all the entries are opaque (unlikely!) */ | |
1118 for (i=0; i<png_ptr->num_trans; ++i) | |
1119 if (png_ptr->trans_alpha[i] == 255) | |
1120 continue; | |
1121 else if (png_ptr->trans_alpha[i] == 0) | |
1122 input_has_transparency = 1; | |
1123 else | |
1124 input_has_alpha = 1; | |
1125 } | |
1126 | |
1127 /* If no alpha we can optimize. */ | |
1128 if (!input_has_alpha) | |
1129 { | |
1130 /* Any alpha means background and associative alpha processing is | |
1131 * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA | |
1132 * and ENCODE_ALPHA are irrelevant. | |
1133 */ | |
1134 png_ptr->transformations &= ~PNG_ENCODE_ALPHA; | |
1135 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; | |
1136 | |
1137 if (!input_has_transparency) | |
1138 png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); | |
1139 } | |
1140 | 794 |
1141 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) | 795 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) |
1142 /* png_set_background handling - deals with the complexity of whether the | |
1143 * background color is in the file format or the screen format in the case | |
1144 * where an 'expand' will happen. | |
1145 */ | |
1146 | |
1147 /* The following code cannot be entered in the alpha pre-multiplication case | |
1148 * because PNG_BACKGROUND_EXPAND is cancelled below. | |
1149 */ | |
1150 if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && | |
1151 (png_ptr->transformations & PNG_EXPAND)) | |
1152 { | |
1153 { | |
1154 png_ptr->background.red = | |
1155 png_ptr->palette[png_ptr->background.index].red; | |
1156 png_ptr->background.green = | |
1157 png_ptr->palette[png_ptr->background.index].green; | |
1158 png_ptr->background.blue = | |
1159 png_ptr->palette[png_ptr->background.index].blue; | |
1160 | |
1161 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED | |
1162 if (png_ptr->transformations & PNG_INVERT_ALPHA) | |
1163 { | |
1164 if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) | |
1165 { | |
1166 /* Invert the alpha channel (in tRNS) unless the pixels are | |
1167 * going to be expanded, in which case leave it for later | |
1168 */ | |
1169 int i, istop = png_ptr->num_trans; | |
1170 | |
1171 for (i=0; i<istop; i++) | |
1172 png_ptr->trans_alpha[i] = (png_byte)(255 - | |
1173 png_ptr->trans_alpha[i]); | |
1174 } | |
1175 } | |
1176 #endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */ | |
1177 } | |
1178 } /* background expand and (therefore) no alpha association. */ | |
1179 #endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ | |
1180 } | |
1181 | |
1182 static void /* PRIVATE */ | |
1183 png_init_rgb_transformations(png_structrp png_ptr) | |
1184 { | |
1185 /* Added to libpng-1.5.4: check the color type to determine whether there | |
1186 * is any alpha or transparency in the image and simply cancel the | |
1187 * background and alpha mode stuff if there isn't. | |
1188 */ | |
1189 int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0; | |
1190 int input_has_transparency = png_ptr->num_trans > 0; | |
1191 | |
1192 /* If no alpha we can optimize. */ | |
1193 if (!input_has_alpha) | |
1194 { | |
1195 /* Any alpha means background and associative alpha processing is | |
1196 * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA | |
1197 * and ENCODE_ALPHA are irrelevant. | |
1198 */ | |
1199 # ifdef PNG_READ_ALPHA_MODE_SUPPORTED | |
1200 png_ptr->transformations &= ~PNG_ENCODE_ALPHA; | |
1201 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; | |
1202 # endif | |
1203 | |
1204 if (!input_has_transparency) | |
1205 png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); | |
1206 } | |
1207 | |
1208 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) | |
1209 /* png_set_background handling - deals with the complexity of whether the | |
1210 * background color is in the file format or the screen format in the case | |
1211 * where an 'expand' will happen. | |
1212 */ | |
1213 | |
1214 /* The following code cannot be entered in the alpha pre-multiplication case | |
1215 * because PNG_BACKGROUND_EXPAND is cancelled below. | |
1216 */ | |
1217 if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && | |
1218 (png_ptr->transformations & PNG_EXPAND) && | |
1219 !(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) | |
1220 /* i.e., GRAY or GRAY_ALPHA */ | |
1221 { | |
1222 { | |
1223 /* Expand background and tRNS chunks */ | |
1224 int gray = png_ptr->background.gray; | |
1225 int trans_gray = png_ptr->trans_color.gray; | |
1226 | |
1227 switch (png_ptr->bit_depth) | |
1228 { | |
1229 case 1: | |
1230 gray *= 0xff; | |
1231 trans_gray *= 0xff; | |
1232 break; | |
1233 | |
1234 case 2: | |
1235 gray *= 0x55; | |
1236 trans_gray *= 0x55; | |
1237 break; | |
1238 | |
1239 case 4: | |
1240 gray *= 0x11; | |
1241 trans_gray *= 0x11; | |
1242 break; | |
1243 | |
1244 default: | |
1245 | |
1246 case 8: | |
1247 /* FALL THROUGH (Already 8 bits) */ | |
1248 | |
1249 case 16: | |
1250 /* Already a full 16 bits */ | |
1251 break; | |
1252 } | |
1253 | |
1254 png_ptr->background.red = png_ptr->background.green = | |
1255 png_ptr->background.blue = (png_uint_16)gray; | |
1256 | |
1257 if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) | |
1258 { | |
1259 png_ptr->trans_color.red = png_ptr->trans_color.green = | |
1260 png_ptr->trans_color.blue = (png_uint_16)trans_gray; | |
1261 } | |
1262 } | |
1263 } /* background expand and (therefore) no alpha association. */ | |
1264 #endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ | |
1265 } | |
1266 | |
1267 void /* PRIVATE */ | |
1268 png_init_read_transformations(png_structrp png_ptr) | |
1269 { | |
1270 png_debug(1, "in png_init_read_transformations"); | |
1271 | |
1272 /* This internal function is called from png_read_start_row in pngrutil.c | |
1273 * and it is called before the 'rowbytes' calculation is done, so the code | |
1274 * in here can change or update the transformations flags. | |
1275 * | |
1276 * First do updates that do not depend on the details of the PNG image data | |
1277 * being processed. | |
1278 */ | |
1279 | |
1280 #ifdef PNG_READ_GAMMA_SUPPORTED | |
1281 /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds | |
1282 * png_set_alpha_mode and this is another source for a default file gamma so | |
1283 * the test needs to be performed later - here. In addition prior to 1.5.4 | |
1284 * the tests were repeated for the PALETTE color type here - this is no | |
1285 * longer necessary (and doesn't seem to have been necessary before.) | |
1286 */ | |
1287 { | |
1288 /* The following temporary indicates if overall gamma correction is | |
1289 * required. | |
1290 */ | |
1291 int gamma_correction = 0; | |
1292 | |
1293 if (png_ptr->colorspace.gamma != 0) /* has been set */ | |
1294 { | |
1295 if (png_ptr->screen_gamma != 0) /* screen set too */ | |
1296 gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma, | |
1297 png_ptr->screen_gamma); | |
1298 | |
1299 else | |
1300 /* Assume the output matches the input; a long time default behavior | |
1301 * of libpng, although the standard has nothing to say about this. | |
1302 */ | |
1303 png_ptr->screen_gamma = png_reciprocal(png_ptr->colorspace.gamma); | |
1304 } | |
1305 | |
1306 else if (png_ptr->screen_gamma != 0) | |
1307 /* The converse - assume the file matches the screen, note that this | |
1308 * perhaps undesireable default can (from 1.5.4) be changed by calling | |
1309 * png_set_alpha_mode (even if the alpha handling mode isn't required | |
1310 * or isn't changed from the default.) | |
1311 */ | |
1312 png_ptr->colorspace.gamma = png_reciprocal(png_ptr->screen_gamma); | |
1313 | |
1314 else /* neither are set */ | |
1315 /* Just in case the following prevents any processing - file and screen | |
1316 * are both assumed to be linear and there is no way to introduce a | |
1317 * third gamma value other than png_set_background with 'UNIQUE', and, | |
1318 * prior to 1.5.4 | |
1319 */ | |
1320 png_ptr->screen_gamma = png_ptr->colorspace.gamma = PNG_FP_1; | |
1321 | |
1322 /* We have a gamma value now. */ | |
1323 png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; | |
1324 | |
1325 /* Now turn the gamma transformation on or off as appropriate. Notice | |
1326 * that PNG_GAMMA just refers to the file->screen correction. Alpha | |
1327 * composition may independently cause gamma correction because it needs | |
1328 * linear data (e.g. if the file has a gAMA chunk but the screen gamma | |
1329 * hasn't been specified.) In any case this flag may get turned off in | |
1330 * the code immediately below if the transform can be handled outside the | |
1331 * row loop. | |
1332 */ | |
1333 if (gamma_correction) | |
1334 png_ptr->transformations |= PNG_GAMMA; | |
1335 | |
1336 else | |
1337 png_ptr->transformations &= ~PNG_GAMMA; | |
1338 } | |
1339 #endif | |
1340 | |
1341 /* Certain transformations have the effect of preventing other | |
1342 * transformations that happen afterward in png_do_read_transformations, | |
1343 * resolve the interdependencies here. From the code of | |
1344 * png_do_read_transformations the order is: | |
1345 * | |
1346 * 1) PNG_EXPAND (including PNG_EXPAND_tRNS) | |
1347 * 2) PNG_STRIP_ALPHA (if no compose) | |
1348 * 3) PNG_RGB_TO_GRAY | |
1349 * 4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY | |
1350 * 5) PNG_COMPOSE | |
1351 * 6) PNG_GAMMA | |
1352 * 7) PNG_STRIP_ALPHA (if compose) | |
1353 * 8) PNG_ENCODE_ALPHA | |
1354 * 9) PNG_SCALE_16_TO_8 | |
1355 * 10) PNG_16_TO_8 | |
1356 * 11) PNG_QUANTIZE (converts to palette) | |
1357 * 12) PNG_EXPAND_16 | |
1358 * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY | |
1359 * 14) PNG_INVERT_MONO | |
1360 * 15) PNG_SHIFT | |
1361 * 16) PNG_PACK | |
1362 * 17) PNG_BGR | |
1363 * 18) PNG_PACKSWAP | |
1364 * 19) PNG_FILLER (includes PNG_ADD_ALPHA) | |
1365 * 20) PNG_INVERT_ALPHA | |
1366 * 21) PNG_SWAP_ALPHA | |
1367 * 22) PNG_SWAP_BYTES | |
1368 * 23) PNG_USER_TRANSFORM [must be last] | |
1369 */ | |
1370 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED | |
1371 if ((png_ptr->transformations & PNG_STRIP_ALPHA) && | |
1372 !(png_ptr->transformations & PNG_COMPOSE)) | |
1373 { | |
1374 /* Stripping the alpha channel happens immediately after the 'expand' | |
1375 * transformations, before all other transformation, so it cancels out | |
1376 * the alpha handling. It has the side effect negating the effect of | |
1377 * PNG_EXPAND_tRNS too: | |
1378 */ | |
1379 png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA | | |
1380 PNG_EXPAND_tRNS); | |
1381 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; | |
1382 | |
1383 /* Kill the tRNS chunk itself too. Prior to 1.5.4 this did not happen | |
1384 * so transparency information would remain just so long as it wasn't | |
1385 * expanded. This produces unexpected API changes if the set of things | |
1386 * that do PNG_EXPAND_tRNS changes (perfectly possible given the | |
1387 * documentation - which says ask for what you want, accept what you | |
1388 * get.) This makes the behavior consistent from 1.5.4: | |
1389 */ | |
1390 png_ptr->num_trans = 0; | |
1391 } | |
1392 #endif /* STRIP_ALPHA supported, no COMPOSE */ | |
1393 | |
1394 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED | |
1395 /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA | |
1396 * settings will have no effect. | |
1397 */ | |
1398 if (!png_gamma_significant(png_ptr->screen_gamma)) | |
1399 { | |
1400 png_ptr->transformations &= ~PNG_ENCODE_ALPHA; | |
1401 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; | |
1402 } | |
1403 #endif | |
1404 | |
1405 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED | |
1406 /* Make sure the coefficients for the rgb to gray conversion are set | |
1407 * appropriately. | |
1408 */ | |
1409 if (png_ptr->transformations & PNG_RGB_TO_GRAY) | |
1410 png_colorspace_set_rgb_coefficients(png_ptr); | |
1411 #endif | |
1412 | 796 |
1413 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED | 797 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED |
1414 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) | 798 /* Detect gray background and attempt to enable optimization |
1415 /* Detect gray background and attempt to enable optimization for | 799 * for gray --> RGB case |
1416 * gray --> RGB case. | |
1417 * | 800 * |
1418 * Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or | 801 * Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or |
1419 * RGB_ALPHA (in which case need_expand is superfluous anyway), the | 802 * RGB_ALPHA (in which case need_expand is superfluous anyway), the |
1420 * background color might actually be gray yet not be flagged as such. | 803 * background color might actually be gray yet not be flagged as such. |
1421 * This is not a problem for the current code, which uses | 804 * This is not a problem for the current code, which uses |
1422 * PNG_BACKGROUND_IS_GRAY only to decide when to do the | 805 * PNG_BACKGROUND_IS_GRAY only to decide when to do the |
1423 * png_do_gray_to_rgb() transformation. | 806 * png_do_gray_to_rgb() transformation. |
1424 * | |
1425 * TODO: this code needs to be revised to avoid the complexity and | |
1426 * interdependencies. The color type of the background should be recorded in | |
1427 * png_set_background, along with the bit depth, then the code has a record | |
1428 * of exactly what color space the background is currently in. | |
1429 */ | 807 */ |
1430 if (png_ptr->transformations & PNG_BACKGROUND_EXPAND) | 808 if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && |
1431 { | 809 !(color_type & PNG_COLOR_MASK_COLOR)) |
1432 /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if | 810 { |
1433 * the file was grayscale the background value is gray. | 811 png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; |
1434 */ | 812 } else if ((png_ptr->transformations & PNG_BACKGROUND) && |
1435 if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) | 813 !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && |
1436 png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; | 814 (png_ptr->transformations & PNG_GRAY_TO_RGB) && |
1437 } | 815 png_ptr->background.red == png_ptr->background.green && |
1438 | 816 png_ptr->background.red == png_ptr->background.blue) |
1439 else if (png_ptr->transformations & PNG_COMPOSE) | 817 { |
1440 { | 818 png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; |
1441 /* PNG_COMPOSE: png_set_background was called with need_expand false, | 819 png_ptr->background.gray = png_ptr->background.red; |
1442 * so the color is in the color space of the output or png_set_alpha_mode | 820 } |
1443 * was called and the color is black. Ignore RGB_TO_GRAY because that | 821 #endif |
1444 * happens before GRAY_TO_RGB. | 822 |
1445 */ | 823 if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && |
1446 if (png_ptr->transformations & PNG_GRAY_TO_RGB) | 824 (png_ptr->transformations & PNG_EXPAND)) |
1447 { | 825 { |
1448 if (png_ptr->background.red == png_ptr->background.green && | 826 if (!(color_type & PNG_COLOR_MASK_COLOR)) /* i.e., GRAY or GRAY_ALPHA */ |
1449 png_ptr->background.red == png_ptr->background.blue) | 827 { |
| 828 /* Expand background and tRNS chunks */ |
| 829 switch (png_ptr->bit_depth) |
1450 { | 830 { |
1451 png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; | 831 case 1: |
1452 png_ptr->background.gray = png_ptr->background.red; | 832 png_ptr->background.gray *= (png_uint_16)0xff; |
| 833 png_ptr->background.red = png_ptr->background.green |
| 834 = png_ptr->background.blue = png_ptr->background.gray; |
| 835 if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) |
| 836 { |
| 837 png_ptr->trans_values.gray *= (png_uint_16)0xff; |
| 838 png_ptr->trans_values.red = png_ptr->trans_values.green |
| 839 = png_ptr->trans_values.blue = png_ptr->trans_values.gray; |
| 840 } |
| 841 break; |
| 842 |
| 843 case 2: |
| 844 png_ptr->background.gray *= (png_uint_16)0x55; |
| 845 png_ptr->background.red = png_ptr->background.green |
| 846 = png_ptr->background.blue = png_ptr->background.gray; |
| 847 if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) |
| 848 { |
| 849 png_ptr->trans_values.gray *= (png_uint_16)0x55; |
| 850 png_ptr->trans_values.red = png_ptr->trans_values.green |
| 851 = png_ptr->trans_values.blue = png_ptr->trans_values.gray; |
| 852 } |
| 853 break; |
| 854 |
| 855 case 4: |
| 856 png_ptr->background.gray *= (png_uint_16)0x11; |
| 857 png_ptr->background.red = png_ptr->background.green |
| 858 = png_ptr->background.blue = png_ptr->background.gray; |
| 859 if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) |
| 860 { |
| 861 png_ptr->trans_values.gray *= (png_uint_16)0x11; |
| 862 png_ptr->trans_values.red = png_ptr->trans_values.green |
| 863 = png_ptr->trans_values.blue = png_ptr->trans_values.gray; |
| 864 } |
| 865 break; |
| 866 |
| 867 case 8: |
| 868 |
| 869 case 16: |
| 870 png_ptr->background.red = png_ptr->background.green |
| 871 = png_ptr->background.blue = png_ptr->background.gray; |
| 872 break; |
1453 } | 873 } |
1454 } | 874 } |
1455 } | 875 else if (color_type == PNG_COLOR_TYPE_PALETTE) |
1456 #endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ | 876 { |
1457 #endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED */ | 877 png_ptr->background.red = |
1458 | 878 png_ptr->palette[png_ptr->background.index].red; |
1459 /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations | 879 png_ptr->background.green = |
1460 * can be performed directly on the palette, and some (such as rgb to gray) | 880 png_ptr->palette[png_ptr->background.index].green; |
1461 * can be optimized inside the palette. This is particularly true of the | 881 png_ptr->background.blue = |
1462 * composite (background and alpha) stuff, which can be pretty much all done | 882 png_ptr->palette[png_ptr->background.index].blue; |
1463 * in the palette even if the result is expanded to RGB or gray afterward. | 883 |
1464 * | 884 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED |
1465 * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and | 885 if (png_ptr->transformations & PNG_INVERT_ALPHA) |
1466 * earlier and the palette stuff is actually handled on the first row. This | 886 { |
1467 * leads to the reported bug that the palette returned by png_get_PLTE is not | 887 #ifdef PNG_READ_EXPAND_SUPPORTED |
1468 * updated. | 888 if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) |
1469 */ | 889 #endif |
1470 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) | 890 { |
1471 png_init_palette_transformations(png_ptr); | 891 /* Invert the alpha channel (in tRNS) unless the pixels are |
1472 | 892 * going to be expanded, in which case leave it for later |
1473 else | 893 */ |
1474 png_init_rgb_transformations(png_ptr); | 894 int i, istop; |
1475 | 895 istop=(int)png_ptr->num_trans; |
1476 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ | 896 for (i=0; i<istop; i++) |
1477 defined(PNG_READ_EXPAND_16_SUPPORTED) | 897 png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]); |
1478 if ((png_ptr->transformations & PNG_EXPAND_16) && | 898 } |
1479 (png_ptr->transformations & PNG_COMPOSE) && | 899 } |
1480 !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && | 900 #endif |
1481 png_ptr->bit_depth != 16) | 901 |
1482 { | 902 } |
1483 /* TODO: fix this. Because the expand_16 operation is after the compose | 903 } |
1484 * handling the background color must be 8, not 16, bits deep, but the | 904 #endif |
1485 * application will supply a 16-bit value so reduce it here. | 905 |
1486 * | 906 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) |
1487 * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at | 907 png_ptr->background_1 = png_ptr->background; |
1488 * present, so that case is ok (until do_expand_16 is moved.) | 908 #endif |
1489 * | 909 #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) |
1490 * NOTE: this discards the low 16 bits of the user supplied background | 910 |
1491 * color, but until expand_16 works properly there is no choice! | 911 if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0) |
1492 */ | 912 && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0) |
1493 # define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x)) | 913 < PNG_GAMMA_THRESHOLD)) |
1494 CHOP(png_ptr->background.red); | 914 { |
1495 CHOP(png_ptr->background.green); | 915 int i, k; |
1496 CHOP(png_ptr->background.blue); | 916 k=0; |
1497 CHOP(png_ptr->background.gray); | 917 for (i=0; i<png_ptr->num_trans; i++) |
1498 # undef CHOP | 918 { |
1499 } | 919 if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff) |
1500 #endif /* PNG_READ_BACKGROUND_SUPPORTED && PNG_READ_EXPAND_16_SUPPORTED */ | 920 k=1; /* Partial transparency is present */ |
1501 | 921 } |
1502 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ | 922 if (k == 0) |
1503 (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \ | 923 png_ptr->transformations &= ~PNG_GAMMA; |
1504 defined(PNG_READ_STRIP_16_TO_8_SUPPORTED)) | 924 } |
1505 if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) && | 925 |
1506 (png_ptr->transformations & PNG_COMPOSE) && | 926 if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) && |
1507 !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && | 927 png_ptr->gamma != 0.0) |
1508 png_ptr->bit_depth == 16) | 928 { |
1509 { | 929 png_build_gamma_table(png_ptr); |
1510 /* On the other hand, if a 16-bit file is to be reduced to 8-bits per | |
1511 * component this will also happen after PNG_COMPOSE and so the background | |
1512 * color must be pre-expanded here. | |
1513 * | |
1514 * TODO: fix this too. | |
1515 */ | |
1516 png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257); | |
1517 png_ptr->background.green = | |
1518 (png_uint_16)(png_ptr->background.green * 257); | |
1519 png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257); | |
1520 png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257); | |
1521 } | |
1522 #endif | |
1523 | |
1524 /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the | |
1525 * background support (see the comments in scripts/pnglibconf.dfa), this | |
1526 * allows pre-multiplication of the alpha channel to be implemented as | |
1527 * compositing on black. This is probably sub-optimal and has been done in | |
1528 * 1.5.4 betas simply to enable external critique and testing (i.e. to | |
1529 * implement the new API quickly, without lots of internal changes.) | |
1530 */ | |
1531 | |
1532 #ifdef PNG_READ_GAMMA_SUPPORTED | |
1533 # ifdef PNG_READ_BACKGROUND_SUPPORTED | |
1534 /* Includes ALPHA_MODE */ | |
1535 png_ptr->background_1 = png_ptr->background; | |
1536 # endif | |
1537 | |
1538 /* This needs to change - in the palette image case a whole set of tables are | |
1539 * built when it would be quicker to just calculate the correct value for | |
1540 * each palette entry directly. Also, the test is too tricky - why check | |
1541 * PNG_RGB_TO_GRAY if PNG_GAMMA is not set? The answer seems to be that | |
1542 * PNG_GAMMA is cancelled even if the gamma is known? The test excludes the | |
1543 * PNG_COMPOSE case, so apparently if there is no *overall* gamma correction | |
1544 * the gamma tables will not be built even if composition is required on a | |
1545 * gamma encoded value. | |
1546 * | |
1547 * In 1.5.4 this is addressed below by an additional check on the individual | |
1548 * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the | |
1549 * tables. | |
1550 */ | |
1551 if ((png_ptr->transformations & PNG_GAMMA) | |
1552 || ((png_ptr->transformations & PNG_RGB_TO_GRAY) | |
1553 && (png_gamma_significant(png_ptr->colorspace.gamma) || | |
1554 png_gamma_significant(png_ptr->screen_gamma))) | |
1555 || ((png_ptr->transformations & PNG_COMPOSE) | |
1556 && (png_gamma_significant(png_ptr->colorspace.gamma) | |
1557 || png_gamma_significant(png_ptr->screen_gamma) | |
1558 # ifdef PNG_READ_BACKGROUND_SUPPORTED | |
1559 || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE | |
1560 && png_gamma_significant(png_ptr->background_gamma)) | |
1561 # endif | |
1562 )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) | |
1563 && png_gamma_significant(png_ptr->screen_gamma)) | |
1564 ) | |
1565 { | |
1566 png_build_gamma_table(png_ptr, png_ptr->bit_depth); | |
1567 | 930 |
1568 #ifdef PNG_READ_BACKGROUND_SUPPORTED | 931 #ifdef PNG_READ_BACKGROUND_SUPPORTED |
1569 if (png_ptr->transformations & PNG_COMPOSE) | 932 if (png_ptr->transformations & PNG_BACKGROUND) |
1570 { | 933 { |
1571 /* Issue a warning about this combination: because RGB_TO_GRAY is | 934 if (color_type == PNG_COLOR_TYPE_PALETTE) |
1572 * optimized to do the gamma transform if present yet do_background has | |
1573 * to do the same thing if both options are set a | |
1574 * double-gamma-correction happens. This is true in all versions of | |
1575 * libpng to date. | |
1576 */ | |
1577 if (png_ptr->transformations & PNG_RGB_TO_GRAY) | |
1578 png_warning(png_ptr, | |
1579 "libpng does not support gamma+background+rgb_to_gray"); | |
1580 | |
1581 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) | |
1582 { | 935 { |
1583 /* We don't get to here unless there is a tRNS chunk with non-opaque | 936 /* Could skip if no transparency */ |
1584 * entries - see the checking code at the start of this function. | |
1585 */ | |
1586 png_color back, back_1; | 937 png_color back, back_1; |
1587 png_colorp palette = png_ptr->palette; | 938 png_colorp palette = png_ptr->palette; |
1588 int num_palette = png_ptr->num_palette; | 939 int num_palette = png_ptr->num_palette; |
1589 int i; | 940 int i; |
1590 if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE) | 941 if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE) |
1591 { | 942 { |
1592 | |
1593 back.red = png_ptr->gamma_table[png_ptr->background.red]; | 943 back.red = png_ptr->gamma_table[png_ptr->background.red]; |
1594 back.green = png_ptr->gamma_table[png_ptr->background.green]; | 944 back.green = png_ptr->gamma_table[png_ptr->background.green]; |
1595 back.blue = png_ptr->gamma_table[png_ptr->background.blue]; | 945 back.blue = png_ptr->gamma_table[png_ptr->background.blue]; |
1596 | 946 |
1597 back_1.red = png_ptr->gamma_to_1[png_ptr->background.red]; | 947 back_1.red = png_ptr->gamma_to_1[png_ptr->background.red]; |
1598 back_1.green = png_ptr->gamma_to_1[png_ptr->background.green]; | 948 back_1.green = png_ptr->gamma_to_1[png_ptr->background.green]; |
1599 back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue]; | 949 back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue]; |
1600 } | 950 } |
1601 else | 951 else |
1602 { | 952 { |
1603 png_fixed_point g, gs; | 953 double g, gs; |
1604 | 954 |
1605 switch (png_ptr->background_gamma_type) | 955 switch (png_ptr->background_gamma_type) |
1606 { | 956 { |
1607 case PNG_BACKGROUND_GAMMA_SCREEN: | 957 case PNG_BACKGROUND_GAMMA_SCREEN: |
1608 g = (png_ptr->screen_gamma); | 958 g = (png_ptr->screen_gamma); |
1609 gs = PNG_FP_1; | 959 gs = 1.0; |
1610 break; | 960 break; |
1611 | 961 |
1612 case PNG_BACKGROUND_GAMMA_FILE: | 962 case PNG_BACKGROUND_GAMMA_FILE: |
1613 g = png_reciprocal(png_ptr->colorspace.gamma); | 963 g = 1.0 / (png_ptr->gamma); |
1614 gs = png_reciprocal2(png_ptr->colorspace.gamma, | 964 gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); |
1615 png_ptr->screen_gamma); | |
1616 break; | 965 break; |
1617 | 966 |
1618 case PNG_BACKGROUND_GAMMA_UNIQUE: | 967 case PNG_BACKGROUND_GAMMA_UNIQUE: |
1619 g = png_reciprocal(png_ptr->background_gamma); | 968 g = 1.0 / (png_ptr->background_gamma); |
1620 gs = png_reciprocal2(png_ptr->background_gamma, | 969 gs = 1.0 / (png_ptr->background_gamma * |
1621 png_ptr->screen_gamma); | 970 png_ptr->screen_gamma); |
1622 break; | 971 break; |
1623 default: | 972 default: |
1624 g = PNG_FP_1; /* back_1 */ | 973 g = 1.0; /* back_1 */ |
1625 gs = PNG_FP_1; /* back */ | 974 gs = 1.0; /* back */ |
1626 break; | |
1627 } | 975 } |
1628 | 976 |
1629 if (png_gamma_significant(gs)) | 977 if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD) |
1630 { | |
1631 back.red = png_gamma_8bit_correct(png_ptr->background.red, | |
1632 gs); | |
1633 back.green = png_gamma_8bit_correct(png_ptr->background.green, | |
1634 gs); | |
1635 back.blue = png_gamma_8bit_correct(png_ptr->background.blue, | |
1636 gs); | |
1637 } | |
1638 | |
1639 else | |
1640 { | 978 { |
1641 back.red = (png_byte)png_ptr->background.red; | 979 back.red = (png_byte)png_ptr->background.red; |
1642 back.green = (png_byte)png_ptr->background.green; | 980 back.green = (png_byte)png_ptr->background.green; |
1643 back.blue = (png_byte)png_ptr->background.blue; | 981 back.blue = (png_byte)png_ptr->background.blue; |
1644 } | 982 } |
1645 | 983 else |
1646 if (png_gamma_significant(g)) | |
1647 { | 984 { |
1648 back_1.red = png_gamma_8bit_correct(png_ptr->background.red, | 985 back.red = (png_byte)(pow( |
1649 g); | 986 (double)png_ptr->background.red/255, gs) * 255.0 + .5); |
1650 back_1.green = png_gamma_8bit_correct( | 987 back.green = (png_byte)(pow( |
1651 png_ptr->background.green, g); | 988 (double)png_ptr->background.green/255, gs) * 255.0 |
1652 back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue, | 989 + .5); |
1653 g); | 990 back.blue = (png_byte)(pow( |
| 991 (double)png_ptr->background.blue/255, gs) * 255.0 + .5); |
1654 } | 992 } |
1655 | 993 |
1656 else | 994 back_1.red = (png_byte)(pow( |
1657 { | 995 (double)png_ptr->background.red/255, g) * 255.0 + .5); |
1658 back_1.red = (png_byte)png_ptr->background.red; | 996 back_1.green = (png_byte)(pow( |
1659 back_1.green = (png_byte)png_ptr->background.green; | 997 (double)png_ptr->background.green/255, g) * 255.0 + .5); |
1660 back_1.blue = (png_byte)png_ptr->background.blue; | 998 back_1.blue = (png_byte)(pow( |
1661 } | 999 (double)png_ptr->background.blue/255, g) * 255.0 + .5); |
1662 } | 1000 } |
1663 | |
1664 for (i = 0; i < num_palette; i++) | 1001 for (i = 0; i < num_palette; i++) |
1665 { | 1002 { |
1666 if (i < (int)png_ptr->num_trans && | 1003 if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff) |
1667 png_ptr->trans_alpha[i] != 0xff) | |
1668 { | 1004 { |
1669 if (png_ptr->trans_alpha[i] == 0) | 1005 if (png_ptr->trans[i] == 0) |
1670 { | 1006 { |
1671 palette[i] = back; | 1007 palette[i] = back; |
1672 } | 1008 } |
1673 else /* if (png_ptr->trans_alpha[i] != 0xff) */ | 1009 else /* if (png_ptr->trans[i] != 0xff) */ |
1674 { | 1010 { |
1675 png_byte v, w; | 1011 png_byte v, w; |
1676 | 1012 |
1677 v = png_ptr->gamma_to_1[palette[i].red]; | 1013 v = png_ptr->gamma_to_1[palette[i].red]; |
1678 png_composite(w, v, png_ptr->trans_alpha[i], back_1.red); | 1014 png_composite(w, v, png_ptr->trans[i], back_1.red); |
1679 palette[i].red = png_ptr->gamma_from_1[w]; | 1015 palette[i].red = png_ptr->gamma_from_1[w]; |
1680 | 1016 |
1681 v = png_ptr->gamma_to_1[palette[i].green]; | 1017 v = png_ptr->gamma_to_1[palette[i].green]; |
1682 png_composite(w, v, png_ptr->trans_alpha[i], back_1.green); | 1018 png_composite(w, v, png_ptr->trans[i], back_1.green); |
1683 palette[i].green = png_ptr->gamma_from_1[w]; | 1019 palette[i].green = png_ptr->gamma_from_1[w]; |
1684 | 1020 |
1685 v = png_ptr->gamma_to_1[palette[i].blue]; | 1021 v = png_ptr->gamma_to_1[palette[i].blue]; |
1686 png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue); | 1022 png_composite(w, v, png_ptr->trans[i], back_1.blue); |
1687 palette[i].blue = png_ptr->gamma_from_1[w]; | 1023 palette[i].blue = png_ptr->gamma_from_1[w]; |
1688 } | 1024 } |
1689 } | 1025 } |
1690 else | 1026 else |
1691 { | 1027 { |
1692 palette[i].red = png_ptr->gamma_table[palette[i].red]; | 1028 palette[i].red = png_ptr->gamma_table[palette[i].red]; |
1693 palette[i].green = png_ptr->gamma_table[palette[i].green]; | 1029 palette[i].green = png_ptr->gamma_table[palette[i].green]; |
1694 palette[i].blue = png_ptr->gamma_table[palette[i].blue]; | 1030 palette[i].blue = png_ptr->gamma_table[palette[i].blue]; |
1695 } | 1031 } |
1696 } | 1032 } |
1697 | 1033 /* Prevent the transformations being done again, and make sure |
1698 /* Prevent the transformations being done again. | 1034 * that the now spurious alpha channel is stripped - the code |
1699 * | 1035 * has just reduced background composition and gamma correction |
1700 * NOTE: this is highly dubious; it removes the transformations in | 1036 * to a simple alpha channel strip. |
1701 * place. This seems inconsistent with the general treatment of the | |
1702 * transformations elsewhere. | |
1703 */ | 1037 */ |
1704 png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA); | 1038 png_ptr->transformations &= ~PNG_BACKGROUND; |
1705 } /* color_type == PNG_COLOR_TYPE_PALETTE */ | 1039 png_ptr->transformations &= ~PNG_GAMMA; |
1706 | 1040 png_ptr->transformations |= PNG_STRIP_ALPHA; |
| 1041 } |
1707 /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ | 1042 /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ |
1708 else /* color_type != PNG_COLOR_TYPE_PALETTE */ | 1043 else |
| 1044 /* color_type != PNG_COLOR_TYPE_PALETTE */ |
1709 { | 1045 { |
1710 int gs_sig, g_sig; | 1046 double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1); |
1711 png_fixed_point g = PNG_FP_1; /* Correction to linear */ | 1047 double g = 1.0; |
1712 png_fixed_point gs = PNG_FP_1; /* Correction to screen */ | 1048 double gs = 1.0; |
1713 | 1049 |
1714 switch (png_ptr->background_gamma_type) | 1050 switch (png_ptr->background_gamma_type) |
1715 { | 1051 { |
1716 case PNG_BACKGROUND_GAMMA_SCREEN: | 1052 case PNG_BACKGROUND_GAMMA_SCREEN: |
1717 g = png_ptr->screen_gamma; | 1053 g = (png_ptr->screen_gamma); |
1718 /* gs = PNG_FP_1; */ | 1054 gs = 1.0; |
1719 break; | 1055 break; |
1720 | 1056 |
1721 case PNG_BACKGROUND_GAMMA_FILE: | 1057 case PNG_BACKGROUND_GAMMA_FILE: |
1722 g = png_reciprocal(png_ptr->colorspace.gamma); | 1058 g = 1.0 / (png_ptr->gamma); |
1723 gs = png_reciprocal2(png_ptr->colorspace.gamma, | 1059 gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); |
1724 png_ptr->screen_gamma); | |
1725 break; | 1060 break; |
1726 | 1061 |
1727 case PNG_BACKGROUND_GAMMA_UNIQUE: | 1062 case PNG_BACKGROUND_GAMMA_UNIQUE: |
1728 g = png_reciprocal(png_ptr->background_gamma); | 1063 g = 1.0 / (png_ptr->background_gamma); |
1729 gs = png_reciprocal2(png_ptr->background_gamma, | 1064 gs = 1.0 / (png_ptr->background_gamma * |
1730 png_ptr->screen_gamma); | 1065 png_ptr->screen_gamma); |
1731 break; | 1066 break; |
1732 | |
1733 default: | |
1734 png_error(png_ptr, "invalid background gamma type"); | |
1735 } | 1067 } |
1736 | 1068 |
1737 g_sig = png_gamma_significant(g); | 1069 png_ptr->background_1.gray = (png_uint_16)(pow( |
1738 gs_sig = png_gamma_significant(gs); | 1070 (double)png_ptr->background.gray / m, g) * m + .5); |
1739 | 1071 png_ptr->background.gray = (png_uint_16)(pow( |
1740 if (g_sig) | 1072 (double)png_ptr->background.gray / m, gs) * m + .5); |
1741 png_ptr->background_1.gray = png_gamma_correct(png_ptr, | |
1742 png_ptr->background.gray, g); | |
1743 | |
1744 if (gs_sig) | |
1745 png_ptr->background.gray = png_gamma_correct(png_ptr, | |
1746 png_ptr->background.gray, gs); | |
1747 | 1073 |
1748 if ((png_ptr->background.red != png_ptr->background.green) || | 1074 if ((png_ptr->background.red != png_ptr->background.green) || |
1749 (png_ptr->background.red != png_ptr->background.blue) || | 1075 (png_ptr->background.red != png_ptr->background.blue) || |
1750 (png_ptr->background.red != png_ptr->background.gray)) | 1076 (png_ptr->background.red != png_ptr->background.gray)) |
1751 { | 1077 { |
1752 /* RGB or RGBA with color background */ | 1078 /* RGB or RGBA with color background */ |
1753 if (g_sig) | 1079 png_ptr->background_1.red = (png_uint_16)(pow( |
1754 { | 1080 (double)png_ptr->background.red / m, g) * m + .5); |
1755 png_ptr->background_1.red = png_gamma_correct(png_ptr, | 1081 png_ptr->background_1.green = (png_uint_16)(pow( |
1756 png_ptr->background.red, g); | 1082 (double)png_ptr->background.green / m, g) * m + .5); |
1757 | 1083 png_ptr->background_1.blue = (png_uint_16)(pow( |
1758 png_ptr->background_1.green = png_gamma_correct(png_ptr, | 1084 (double)png_ptr->background.blue / m, g) * m + .5); |
1759 png_ptr->background.green, g); | 1085 png_ptr->background.red = (png_uint_16)(pow( |
1760 | 1086 (double)png_ptr->background.red / m, gs) * m + .5); |
1761 png_ptr->background_1.blue = png_gamma_correct(png_ptr, | 1087 png_ptr->background.green = (png_uint_16)(pow( |
1762 png_ptr->background.blue, g); | 1088 (double)png_ptr->background.green / m, gs) * m + .5); |
1763 } | 1089 png_ptr->background.blue = (png_uint_16)(pow( |
1764 | 1090 (double)png_ptr->background.blue / m, gs) * m + .5); |
1765 if (gs_sig) | |
1766 { | |
1767 png_ptr->background.red = png_gamma_correct(png_ptr, | |
1768 png_ptr->background.red, gs); | |
1769 | |
1770 png_ptr->background.green = png_gamma_correct(png_ptr, | |
1771 png_ptr->background.green, gs); | |
1772 | |
1773 png_ptr->background.blue = png_gamma_correct(png_ptr, | |
1774 png_ptr->background.blue, gs); | |
1775 } | |
1776 } | 1091 } |
1777 | |
1778 else | 1092 else |
1779 { | 1093 { |
1780 /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */ | 1094 /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */ |
1781 png_ptr->background_1.red = png_ptr->background_1.green | 1095 png_ptr->background_1.red = png_ptr->background_1.green |
1782 = png_ptr->background_1.blue = png_ptr->background_1.gray; | 1096 = png_ptr->background_1.blue = png_ptr->background_1.gray; |
1783 | |
1784 png_ptr->background.red = png_ptr->background.green | 1097 png_ptr->background.red = png_ptr->background.green |
1785 = png_ptr->background.blue = png_ptr->background.gray; | 1098 = png_ptr->background.blue = png_ptr->background.gray; |
1786 } | 1099 } |
1787 | 1100 } |
1788 /* The background is now in screen gamma: */ | 1101 } |
1789 png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN; | |
1790 } /* color_type != PNG_COLOR_TYPE_PALETTE */ | |
1791 }/* png_ptr->transformations & PNG_BACKGROUND */ | |
1792 | |
1793 else | 1102 else |
1794 /* Transformation does not include PNG_BACKGROUND */ | 1103 /* Transformation does not include PNG_BACKGROUND */ |
1795 #endif /* PNG_READ_BACKGROUND_SUPPORTED */ | 1104 #endif /* PNG_READ_BACKGROUND_SUPPORTED */ |
1796 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE | 1105 if (color_type == PNG_COLOR_TYPE_PALETTE) |
1797 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED | |
1798 /* RGB_TO_GRAY needs to have non-gamma-corrected values! */ | |
1799 && ((png_ptr->transformations & PNG_EXPAND) == 0 || | |
1800 (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) | |
1801 #endif | |
1802 ) | |
1803 { | 1106 { |
1804 png_colorp palette = png_ptr->palette; | 1107 png_colorp palette = png_ptr->palette; |
1805 int num_palette = png_ptr->num_palette; | 1108 int num_palette = png_ptr->num_palette; |
1806 int i; | 1109 int i; |
1807 | 1110 |
1808 /* NOTE: there are other transformations that should probably be in | |
1809 * here too. | |
1810 */ | |
1811 for (i = 0; i < num_palette; i++) | 1111 for (i = 0; i < num_palette; i++) |
1812 { | 1112 { |
1813 palette[i].red = png_ptr->gamma_table[palette[i].red]; | 1113 palette[i].red = png_ptr->gamma_table[palette[i].red]; |
1814 palette[i].green = png_ptr->gamma_table[palette[i].green]; | 1114 palette[i].green = png_ptr->gamma_table[palette[i].green]; |
1815 palette[i].blue = png_ptr->gamma_table[palette[i].blue]; | 1115 palette[i].blue = png_ptr->gamma_table[palette[i].blue]; |
1816 } | 1116 } |
1817 | 1117 |
1818 /* Done the gamma correction. */ | 1118 /* Done the gamma correction. */ |
1819 png_ptr->transformations &= ~PNG_GAMMA; | 1119 png_ptr->transformations &= ~PNG_GAMMA; |
1820 } /* color_type == PALETTE && !PNG_BACKGROUND transformation */ | 1120 } |
1821 } | 1121 } |
1822 #ifdef PNG_READ_BACKGROUND_SUPPORTED | 1122 #ifdef PNG_READ_BACKGROUND_SUPPORTED |
1823 else | 1123 else |
1824 #endif | 1124 #endif |
1825 #endif /* PNG_READ_GAMMA_SUPPORTED */ | 1125 #endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */ |
1826 | |
1827 #ifdef PNG_READ_BACKGROUND_SUPPORTED | 1126 #ifdef PNG_READ_BACKGROUND_SUPPORTED |
1828 /* No GAMMA transformation (see the hanging else 4 lines above) */ | 1127 /* No GAMMA transformation */ |
1829 if ((png_ptr->transformations & PNG_COMPOSE) && | 1128 if ((png_ptr->transformations & PNG_BACKGROUND) && |
1830 (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) | 1129 (color_type == PNG_COLOR_TYPE_PALETTE)) |
1831 { | 1130 { |
1832 int i; | 1131 int i; |
1833 int istop = (int)png_ptr->num_trans; | 1132 int istop = (int)png_ptr->num_trans; |
1834 png_color back; | 1133 png_color back; |
1835 png_colorp palette = png_ptr->palette; | 1134 png_colorp palette = png_ptr->palette; |
1836 | 1135 |
1837 back.red = (png_byte)png_ptr->background.red; | 1136 back.red = (png_byte)png_ptr->background.red; |
1838 back.green = (png_byte)png_ptr->background.green; | 1137 back.green = (png_byte)png_ptr->background.green; |
1839 back.blue = (png_byte)png_ptr->background.blue; | 1138 back.blue = (png_byte)png_ptr->background.blue; |
1840 | 1139 |
1841 for (i = 0; i < istop; i++) | 1140 for (i = 0; i < istop; i++) |
1842 { | 1141 { |
1843 if (png_ptr->trans_alpha[i] == 0) | 1142 if (png_ptr->trans[i] == 0) |
1844 { | 1143 { |
1845 palette[i] = back; | 1144 palette[i] = back; |
1846 } | 1145 } |
1847 | 1146 else if (png_ptr->trans[i] != 0xff) |
1848 else if (png_ptr->trans_alpha[i] != 0xff) | |
1849 { | 1147 { |
1850 /* The png_composite() macro is defined in png.h */ | 1148 /* The png_composite() macro is defined in png.h */ |
1851 png_composite(palette[i].red, palette[i].red, | 1149 png_composite(palette[i].red, palette[i].red, |
1852 png_ptr->trans_alpha[i], back.red); | 1150 png_ptr->trans[i], back.red); |
1853 | |
1854 png_composite(palette[i].green, palette[i].green, | 1151 png_composite(palette[i].green, palette[i].green, |
1855 png_ptr->trans_alpha[i], back.green); | 1152 png_ptr->trans[i], back.green); |
1856 | |
1857 png_composite(palette[i].blue, palette[i].blue, | 1153 png_composite(palette[i].blue, palette[i].blue, |
1858 png_ptr->trans_alpha[i], back.blue); | 1154 png_ptr->trans[i], back.blue); |
1859 } | 1155 } |
1860 } | 1156 } |
1861 | 1157 |
1862 png_ptr->transformations &= ~PNG_COMPOSE; | 1158 /* Handled alpha, still need to strip the channel. */ |
| 1159 png_ptr->transformations &= ~PNG_BACKGROUND; |
| 1160 png_ptr->transformations |= PNG_STRIP_ALPHA; |
1863 } | 1161 } |
1864 #endif /* PNG_READ_BACKGROUND_SUPPORTED */ | 1162 #endif /* PNG_READ_BACKGROUND_SUPPORTED */ |
1865 | 1163 |
1866 #ifdef PNG_READ_SHIFT_SUPPORTED | 1164 #ifdef PNG_READ_SHIFT_SUPPORTED |
1867 if ((png_ptr->transformations & PNG_SHIFT) && | 1165 if ((png_ptr->transformations & PNG_SHIFT) && |
1868 !(png_ptr->transformations & PNG_EXPAND) && | 1166 (color_type == PNG_COLOR_TYPE_PALETTE)) |
1869 (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) | |
1870 { | 1167 { |
1871 int i; | 1168 png_uint_16 i; |
1872 int istop = png_ptr->num_palette; | 1169 png_uint_16 istop = png_ptr->num_palette; |
1873 int shift = 8 - png_ptr->sig_bit.red; | 1170 int sr = 8 - png_ptr->sig_bit.red; |
| 1171 int sg = 8 - png_ptr->sig_bit.green; |
| 1172 int sb = 8 - png_ptr->sig_bit.blue; |
1874 | 1173 |
1875 png_ptr->transformations &= ~PNG_SHIFT; | 1174 if (sr < 0 || sr > 8) |
1876 | 1175 sr = 0; |
1877 /* significant bits can be in the range 1 to 7 for a meaninful result, if | 1176 if (sg < 0 || sg > 8) |
1878 * the number of significant bits is 0 then no shift is done (this is an | 1177 sg = 0; |
1879 * error condition which is silently ignored.) | 1178 if (sb < 0 || sb > 8) |
1880 */ | 1179 sb = 0; |
1881 if (shift > 0 && shift < 8) for (i=0; i<istop; ++i) | 1180 for (i = 0; i < istop; i++) |
1882 { | 1181 { |
1883 int component = png_ptr->palette[i].red; | 1182 png_ptr->palette[i].red >>= sr; |
1884 | 1183 png_ptr->palette[i].green >>= sg; |
1885 component >>= shift; | 1184 png_ptr->palette[i].blue >>= sb; |
1886 png_ptr->palette[i].red = (png_byte)component; | |
1887 } | |
1888 | |
1889 shift = 8 - png_ptr->sig_bit.green; | |
1890 if (shift > 0 && shift < 8) for (i=0; i<istop; ++i) | |
1891 { | |
1892 int component = png_ptr->palette[i].green; | |
1893 | |
1894 component >>= shift; | |
1895 png_ptr->palette[i].green = (png_byte)component; | |
1896 } | |
1897 | |
1898 shift = 8 - png_ptr->sig_bit.blue; | |
1899 if (shift > 0 && shift < 8) for (i=0; i<istop; ++i) | |
1900 { | |
1901 int component = png_ptr->palette[i].blue; | |
1902 | |
1903 component >>= shift; | |
1904 png_ptr->palette[i].blue = (png_byte)component; | |
1905 } | 1185 } |
1906 } | 1186 } |
1907 #endif /* PNG_READ_SHIFT_SUPPORTED */ | 1187 #endif /* PNG_READ_SHIFT_SUPPORTED */ |
| 1188 } |
| 1189 #if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \ |
| 1190 && !defined(PNG_READ_BACKGROUND_SUPPORTED) |
| 1191 if (png_ptr) |
| 1192 return; |
| 1193 #endif |
1908 } | 1194 } |
1909 | 1195 |
1910 /* Modify the info structure to reflect the transformations. The | 1196 /* Modify the info structure to reflect the transformations. The |
1911 * info should be updated so a PNG file could be written with it, | 1197 * info should be updated so a PNG file could be written with it, |
1912 * assuming the transformations result in valid PNG data. | 1198 * assuming the transformations result in valid PNG data. |
1913 */ | 1199 */ |
1914 void /* PRIVATE */ | 1200 void /* PRIVATE */ |
1915 png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr) | 1201 png_read_transform_info(png_structp png_ptr, png_infop info_ptr) |
1916 { | 1202 { |
1917 png_debug(1, "in png_read_transform_info"); | 1203 png_debug(1, "in png_read_transform_info"); |
1918 | 1204 |
1919 #ifdef PNG_READ_EXPAND_SUPPORTED | 1205 #ifdef PNG_READ_EXPAND_SUPPORTED |
1920 if (png_ptr->transformations & PNG_EXPAND) | 1206 if (png_ptr->transformations & PNG_EXPAND) |
1921 { | 1207 { |
1922 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) | 1208 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
1923 { | 1209 { |
1924 /* This check must match what actually happens in | 1210 if (png_ptr->num_trans) |
1925 * png_do_expand_palette; if it ever checks the tRNS chunk to see if | |
1926 * it is all opaque we must do the same (at present it does not.) | |
1927 */ | |
1928 if (png_ptr->num_trans > 0) | |
1929 info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA; | 1211 info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA; |
1930 | |
1931 else | 1212 else |
1932 info_ptr->color_type = PNG_COLOR_TYPE_RGB; | 1213 info_ptr->color_type = PNG_COLOR_TYPE_RGB; |
1933 | |
1934 info_ptr->bit_depth = 8; | 1214 info_ptr->bit_depth = 8; |
1935 info_ptr->num_trans = 0; | 1215 info_ptr->num_trans = 0; |
1936 } | 1216 } |
1937 else | 1217 else |
1938 { | 1218 { |
1939 if (png_ptr->num_trans) | 1219 if (png_ptr->num_trans) |
1940 { | 1220 { |
1941 if (png_ptr->transformations & PNG_EXPAND_tRNS) | 1221 if (png_ptr->transformations & PNG_EXPAND_tRNS) |
1942 info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; | 1222 info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; |
1943 } | 1223 } |
1944 if (info_ptr->bit_depth < 8) | 1224 if (info_ptr->bit_depth < 8) |
1945 info_ptr->bit_depth = 8; | 1225 info_ptr->bit_depth = 8; |
1946 | |
1947 info_ptr->num_trans = 0; | 1226 info_ptr->num_trans = 0; |
1948 } | 1227 } |
1949 } | 1228 } |
1950 #endif | 1229 #endif |
1951 | 1230 |
1952 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ | 1231 #ifdef PNG_READ_BACKGROUND_SUPPORTED |
1953 defined(PNG_READ_ALPHA_MODE_SUPPORTED) | 1232 if (png_ptr->transformations & PNG_BACKGROUND) |
1954 /* The following is almost certainly wrong unless the background value is in | 1233 { |
1955 * the screen space! | 1234 info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; |
1956 */ | 1235 info_ptr->num_trans = 0; |
1957 if (png_ptr->transformations & PNG_COMPOSE) | |
1958 info_ptr->background = png_ptr->background; | 1236 info_ptr->background = png_ptr->background; |
| 1237 } |
1959 #endif | 1238 #endif |
1960 | 1239 |
1961 #ifdef PNG_READ_GAMMA_SUPPORTED | 1240 #ifdef PNG_READ_GAMMA_SUPPORTED |
1962 /* The following used to be conditional on PNG_GAMMA (prior to 1.5.4), | 1241 if (png_ptr->transformations & PNG_GAMMA) |
1963 * however it seems that the code in png_init_read_transformations, which has | 1242 { |
1964 * been called before this from png_read_update_info->png_read_start_row | 1243 #ifdef PNG_FLOATING_POINT_SUPPORTED |
1965 * sometimes does the gamma transform and cancels the flag. | 1244 info_ptr->gamma = png_ptr->gamma; |
1966 * | 1245 #endif |
1967 * TODO: this looks wrong; the info_ptr should end up with a gamma equal to | 1246 #ifdef PNG_FIXED_POINT_SUPPORTED |
1968 * the screen_gamma value. The following probably results in weirdness if | 1247 info_ptr->int_gamma = png_ptr->int_gamma; |
1969 * the info_ptr is used by the app after the rows have been read. | 1248 #endif |
1970 */ | 1249 } |
1971 info_ptr->colorspace.gamma = png_ptr->colorspace.gamma; | |
1972 #endif | 1250 #endif |
1973 | 1251 |
1974 if (info_ptr->bit_depth == 16) | 1252 #ifdef PNG_READ_16_TO_8_SUPPORTED |
1975 { | 1253 if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16)) |
1976 # ifdef PNG_READ_16BIT_SUPPORTED | 1254 info_ptr->bit_depth = 8; |
1977 # ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED | 1255 #endif |
1978 if (png_ptr->transformations & PNG_SCALE_16_TO_8) | |
1979 info_ptr->bit_depth = 8; | |
1980 # endif | |
1981 | |
1982 # ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED | |
1983 if (png_ptr->transformations & PNG_16_TO_8) | |
1984 info_ptr->bit_depth = 8; | |
1985 # endif | |
1986 | |
1987 # else | |
1988 /* No 16 bit support: force chopping 16-bit input down to 8, in this case | |
1989 * the app program can chose if both APIs are available by setting the | |
1990 * correct scaling to use. | |
1991 */ | |
1992 # ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED | |
1993 /* For compatibility with previous versions use the strip method by | |
1994 * default. This code works because if PNG_SCALE_16_TO_8 is already | |
1995 * set the code below will do that in preference to the chop. | |
1996 */ | |
1997 png_ptr->transformations |= PNG_16_TO_8; | |
1998 info_ptr->bit_depth = 8; | |
1999 # else | |
2000 | |
2001 # ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED | |
2002 png_ptr->transformations |= PNG_SCALE_16_TO_8; | |
2003 info_ptr->bit_depth = 8; | |
2004 # else | |
2005 | |
2006 CONFIGURATION ERROR: you must enable at least one 16 to 8 method | |
2007 # endif | |
2008 # endif | |
2009 #endif /* !READ_16BIT_SUPPORTED */ | |
2010 } | |
2011 | 1256 |
2012 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED | 1257 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED |
2013 if (png_ptr->transformations & PNG_GRAY_TO_RGB) | 1258 if (png_ptr->transformations & PNG_GRAY_TO_RGB) |
2014 info_ptr->color_type = (png_byte)(info_ptr->color_type | | 1259 info_ptr->color_type |= PNG_COLOR_MASK_COLOR; |
2015 PNG_COLOR_MASK_COLOR); | |
2016 #endif | 1260 #endif |
2017 | 1261 |
2018 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED | 1262 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED |
2019 if (png_ptr->transformations & PNG_RGB_TO_GRAY) | 1263 if (png_ptr->transformations & PNG_RGB_TO_GRAY) |
2020 info_ptr->color_type = (png_byte)(info_ptr->color_type & | 1264 info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR; |
2021 ~PNG_COLOR_MASK_COLOR); | |
2022 #endif | 1265 #endif |
2023 | 1266 |
2024 #ifdef PNG_READ_QUANTIZE_SUPPORTED | 1267 #ifdef PNG_READ_DITHER_SUPPORTED |
2025 if (png_ptr->transformations & PNG_QUANTIZE) | 1268 if (png_ptr->transformations & PNG_DITHER) |
2026 { | 1269 { |
2027 if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || | 1270 if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || |
2028 (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && | 1271 (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && |
2029 png_ptr->palette_lookup && info_ptr->bit_depth == 8) | 1272 png_ptr->palette_lookup && info_ptr->bit_depth == 8) |
2030 { | 1273 { |
2031 info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; | 1274 info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; |
2032 } | 1275 } |
2033 } | 1276 } |
2034 #endif | 1277 #endif |
2035 | 1278 |
2036 #ifdef PNG_READ_EXPAND_16_SUPPORTED | |
2037 if (png_ptr->transformations & PNG_EXPAND_16 && info_ptr->bit_depth == 8 && | |
2038 info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) | |
2039 { | |
2040 info_ptr->bit_depth = 16; | |
2041 } | |
2042 #endif | |
2043 | |
2044 #ifdef PNG_READ_PACK_SUPPORTED | 1279 #ifdef PNG_READ_PACK_SUPPORTED |
2045 if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8)) | 1280 if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8)) |
2046 info_ptr->bit_depth = 8; | 1281 info_ptr->bit_depth = 8; |
2047 #endif | 1282 #endif |
2048 | 1283 |
2049 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) | 1284 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
2050 info_ptr->channels = 1; | 1285 info_ptr->channels = 1; |
2051 | |
2052 else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) | 1286 else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) |
2053 info_ptr->channels = 3; | 1287 info_ptr->channels = 3; |
2054 | |
2055 else | 1288 else |
2056 info_ptr->channels = 1; | 1289 info_ptr->channels = 1; |
2057 | 1290 |
2058 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED | 1291 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED |
2059 if (png_ptr->transformations & PNG_STRIP_ALPHA) | 1292 if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA) |
2060 { | 1293 info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; |
2061 info_ptr->color_type = (png_byte)(info_ptr->color_type & | |
2062 ~PNG_COLOR_MASK_ALPHA); | |
2063 info_ptr->num_trans = 0; | |
2064 } | |
2065 #endif | 1294 #endif |
2066 | 1295 |
2067 if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) | 1296 if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) |
2068 info_ptr->channels++; | 1297 info_ptr->channels++; |
2069 | 1298 |
2070 #ifdef PNG_READ_FILLER_SUPPORTED | 1299 #ifdef PNG_READ_FILLER_SUPPORTED |
2071 /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */ | 1300 /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */ |
2072 if ((png_ptr->transformations & PNG_FILLER) && | 1301 if ((png_ptr->transformations & PNG_FILLER) && |
2073 ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || | 1302 ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || |
2074 (info_ptr->color_type == PNG_COLOR_TYPE_GRAY))) | 1303 (info_ptr->color_type == PNG_COLOR_TYPE_GRAY))) |
2075 { | 1304 { |
2076 info_ptr->channels++; | 1305 info_ptr->channels++; |
2077 /* If adding a true alpha channel not just filler */ | 1306 /* If adding a true alpha channel not just filler */ |
| 1307 #ifndef PNG_1_0_X |
2078 if (png_ptr->transformations & PNG_ADD_ALPHA) | 1308 if (png_ptr->transformations & PNG_ADD_ALPHA) |
2079 info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; | 1309 info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; |
| 1310 #endif |
2080 } | 1311 } |
2081 #endif | 1312 #endif |
2082 | 1313 |
2083 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \ | 1314 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \ |
2084 defined(PNG_READ_USER_TRANSFORM_SUPPORTED) | 1315 defined(PNG_READ_USER_TRANSFORM_SUPPORTED) |
2085 if (png_ptr->transformations & PNG_USER_TRANSFORM) | 1316 if (png_ptr->transformations & PNG_USER_TRANSFORM) |
2086 { | 1317 { |
2087 if (info_ptr->bit_depth < png_ptr->user_transform_depth) | 1318 if (info_ptr->bit_depth < png_ptr->user_transform_depth) |
2088 info_ptr->bit_depth = png_ptr->user_transform_depth; | 1319 info_ptr->bit_depth = png_ptr->user_transform_depth; |
2089 | 1320 if (info_ptr->channels < png_ptr->user_transform_channels) |
2090 if (info_ptr->channels < png_ptr->user_transform_channels) | |
2091 info_ptr->channels = png_ptr->user_transform_channels; | 1321 info_ptr->channels = png_ptr->user_transform_channels; |
2092 } | 1322 } |
2093 #endif | 1323 #endif |
2094 | 1324 |
2095 info_ptr->pixel_depth = (png_byte)(info_ptr->channels * | 1325 info_ptr->pixel_depth = (png_byte)(info_ptr->channels * |
2096 info_ptr->bit_depth); | 1326 info_ptr->bit_depth); |
2097 | 1327 |
2098 info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width); | 1328 info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width); |
2099 | 1329 |
2100 /* Adding in 1.5.4: cache the above value in png_struct so that we can later | |
2101 * check in png_rowbytes that the user buffer won't get overwritten. Note | |
2102 * that the field is not always set - if png_read_update_info isn't called | |
2103 * the application has to either not do any transforms or get the calculation | |
2104 * right itself. | |
2105 */ | |
2106 png_ptr->info_rowbytes = info_ptr->rowbytes; | |
2107 | |
2108 #ifndef PNG_READ_EXPAND_SUPPORTED | 1330 #ifndef PNG_READ_EXPAND_SUPPORTED |
2109 if (png_ptr) | 1331 if (png_ptr) |
2110 return; | 1332 return; |
2111 #endif | 1333 #endif |
2112 } | 1334 } |
2113 | 1335 |
2114 /* Transform the row. The order of transformations is significant, | 1336 /* Transform the row. The order of transformations is significant, |
2115 * and is very touchy. If you add a transformation, take care to | 1337 * and is very touchy. If you add a transformation, take care to |
2116 * decide how it fits in with the other transformations here. | 1338 * decide how it fits in with the other transformations here. |
2117 */ | 1339 */ |
2118 void /* PRIVATE */ | 1340 void /* PRIVATE */ |
2119 png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info) | 1341 png_do_read_transformations(png_structp png_ptr) |
2120 { | 1342 { |
2121 png_debug(1, "in png_do_read_transformations"); | 1343 png_debug(1, "in png_do_read_transformations"); |
2122 | 1344 |
2123 if (png_ptr->row_buf == NULL) | 1345 if (png_ptr->row_buf == NULL) |
2124 { | 1346 { |
2125 /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this | 1347 #if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE) |
2126 * error is incredibly rare and incredibly easy to debug without this | 1348 char msg[50]; |
2127 * information. | 1349 |
| 1350 png_snprintf2(msg, 50, |
| 1351 "NULL row buffer for row %ld, pass %d", (long)png_ptr->row_number, |
| 1352 png_ptr->pass); |
| 1353 png_error(png_ptr, msg); |
| 1354 #else |
| 1355 png_error(png_ptr, "NULL row buffer"); |
| 1356 #endif |
| 1357 } |
| 1358 #ifdef PNG_WARN_UNINITIALIZED_ROW |
| 1359 if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) |
| 1360 /* Application has failed to call either png_read_start_image() |
| 1361 * or png_read_update_info() after setting transforms that expand |
| 1362 * pixels. This check added to libpng-1.2.19 |
2128 */ | 1363 */ |
2129 png_error(png_ptr, "NULL row buffer"); | 1364 #if (PNG_WARN_UNINITIALIZED_ROW==1) |
2130 } | |
2131 | |
2132 /* The following is debugging; prior to 1.5.4 the code was never compiled in; | |
2133 * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro | |
2134 * PNG_WARN_UNINITIALIZED_ROW removed. In 1.6 the new flag is set only for | |
2135 * all transformations, however in practice the ROW_INIT always gets done on | |
2136 * demand, if necessary. | |
2137 */ | |
2138 if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 && | |
2139 !(png_ptr->flags & PNG_FLAG_ROW_INIT)) | |
2140 { | |
2141 /* Application has failed to call either png_read_start_image() or | |
2142 * png_read_update_info() after setting transforms that expand pixels. | |
2143 * This check added to libpng-1.2.19 (but not enabled until 1.5.4). | |
2144 */ | |
2145 png_error(png_ptr, "Uninitialized row"); | 1365 png_error(png_ptr, "Uninitialized row"); |
2146 } | 1366 #else |
| 1367 png_warning(png_ptr, "Uninitialized row"); |
| 1368 #endif |
| 1369 #endif |
2147 | 1370 |
2148 #ifdef PNG_READ_EXPAND_SUPPORTED | 1371 #ifdef PNG_READ_EXPAND_SUPPORTED |
2149 if (png_ptr->transformations & PNG_EXPAND) | 1372 if (png_ptr->transformations & PNG_EXPAND) |
2150 { | 1373 { |
2151 if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) | 1374 if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE) |
2152 { | 1375 { |
2153 png_do_expand_palette(row_info, png_ptr->row_buf + 1, | 1376 png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1, |
2154 png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); | 1377 png_ptr->palette, png_ptr->trans, png_ptr->num_trans); |
2155 } | 1378 } |
2156 | |
2157 else | 1379 else |
2158 { | 1380 { |
2159 if (png_ptr->num_trans && | 1381 if (png_ptr->num_trans && |
2160 (png_ptr->transformations & PNG_EXPAND_tRNS)) | 1382 (png_ptr->transformations & PNG_EXPAND_tRNS)) |
2161 png_do_expand(row_info, png_ptr->row_buf + 1, | 1383 png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, |
2162 &(png_ptr->trans_color)); | 1384 &(png_ptr->trans_values)); |
2163 | |
2164 else | 1385 else |
2165 png_do_expand(row_info, png_ptr->row_buf + 1, | 1386 png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, |
2166 NULL); | 1387 NULL); |
2167 } | 1388 } |
2168 } | 1389 } |
2169 #endif | 1390 #endif |
2170 | 1391 |
2171 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED | 1392 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED |
2172 if ((png_ptr->transformations & PNG_STRIP_ALPHA) && | 1393 if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA) |
2173 !(png_ptr->transformations & PNG_COMPOSE) && | 1394 png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, |
2174 (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || | 1395 PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)); |
2175 row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) | |
2176 png_do_strip_channel(row_info, png_ptr->row_buf + 1, | |
2177 0 /* at_start == false, because SWAP_ALPHA happens later */); | |
2178 #endif | 1396 #endif |
2179 | 1397 |
2180 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED | 1398 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED |
2181 if (png_ptr->transformations & PNG_RGB_TO_GRAY) | 1399 if (png_ptr->transformations & PNG_RGB_TO_GRAY) |
2182 { | 1400 { |
2183 int rgb_error = | 1401 int rgb_error = |
2184 png_do_rgb_to_gray(png_ptr, row_info, | 1402 png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), |
2185 png_ptr->row_buf + 1); | 1403 png_ptr->row_buf + 1); |
2186 | |
2187 if (rgb_error) | 1404 if (rgb_error) |
2188 { | 1405 { |
2189 png_ptr->rgb_to_gray_status=1; | 1406 png_ptr->rgb_to_gray_status=1; |
2190 if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == | 1407 if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == |
2191 PNG_RGB_TO_GRAY_WARN) | 1408 PNG_RGB_TO_GRAY_WARN) |
2192 png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); | 1409 png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); |
2193 | |
2194 if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == | 1410 if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == |
2195 PNG_RGB_TO_GRAY_ERR) | 1411 PNG_RGB_TO_GRAY_ERR) |
2196 png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); | 1412 png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); |
2197 } | 1413 } |
2198 } | 1414 } |
2199 #endif | 1415 #endif |
2200 | 1416 |
2201 /* From Andreas Dilger e-mail to png-implement, 26 March 1998: | 1417 /* From Andreas Dilger e-mail to png-implement, 26 March 1998: |
2202 * | 1418 * |
2203 * In most cases, the "simple transparency" should be done prior to doing | 1419 * In most cases, the "simple transparency" should be done prior to doing |
(...skipping 24 matching lines...) Expand all Loading... |
2228 * in advance if the background was gray or RGB, and position the gray-to-RGB | 1444 * in advance if the background was gray or RGB, and position the gray-to-RGB |
2229 * transform appropriately, then it would save a lot of work/time. | 1445 * transform appropriately, then it would save a lot of work/time. |
2230 */ | 1446 */ |
2231 | 1447 |
2232 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED | 1448 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED |
2233 /* If gray -> RGB, do so now only if background is non-gray; else do later | 1449 /* If gray -> RGB, do so now only if background is non-gray; else do later |
2234 * for performance reasons | 1450 * for performance reasons |
2235 */ | 1451 */ |
2236 if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && | 1452 if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && |
2237 !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) | 1453 !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) |
2238 png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); | 1454 png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); |
2239 #endif | 1455 #endif |
2240 | 1456 |
2241 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ | 1457 #ifdef PNG_READ_BACKGROUND_SUPPORTED |
2242 defined(PNG_READ_ALPHA_MODE_SUPPORTED) | 1458 if ((png_ptr->transformations & PNG_BACKGROUND) && |
2243 if (png_ptr->transformations & PNG_COMPOSE) | 1459 ((png_ptr->num_trans != 0 ) || |
2244 png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr); | 1460 (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) |
| 1461 png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1, |
| 1462 &(png_ptr->trans_values), &(png_ptr->background) |
| 1463 #ifdef PNG_READ_GAMMA_SUPPORTED |
| 1464 , &(png_ptr->background_1), |
| 1465 png_ptr->gamma_table, png_ptr->gamma_from_1, |
| 1466 png_ptr->gamma_to_1, png_ptr->gamma_16_table, |
| 1467 png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1, |
| 1468 png_ptr->gamma_shift |
| 1469 #endif |
| 1470 ); |
2245 #endif | 1471 #endif |
2246 | 1472 |
2247 #ifdef PNG_READ_GAMMA_SUPPORTED | 1473 #ifdef PNG_READ_GAMMA_SUPPORTED |
2248 if ((png_ptr->transformations & PNG_GAMMA) && | 1474 if ((png_ptr->transformations & PNG_GAMMA) && |
2249 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED | 1475 #ifdef PNG_READ_BACKGROUND_SUPPORTED |
2250 /* Because RGB_TO_GRAY does the gamma transform. */ | 1476 !((png_ptr->transformations & PNG_BACKGROUND) && |
2251 !(png_ptr->transformations & PNG_RGB_TO_GRAY) && | |
2252 #endif | |
2253 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ | |
2254 defined(PNG_READ_ALPHA_MODE_SUPPORTED) | |
2255 /* Because PNG_COMPOSE does the gamma transform if there is something to | |
2256 * do (if there is an alpha channel or transparency.) | |
2257 */ | |
2258 !((png_ptr->transformations & PNG_COMPOSE) && | |
2259 ((png_ptr->num_trans != 0) || | 1477 ((png_ptr->num_trans != 0) || |
2260 (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) && | 1478 (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) && |
2261 #endif | 1479 #endif |
2262 /* Because png_init_read_transformations transforms the palette, unless | |
2263 * RGB_TO_GRAY will do the transform. | |
2264 */ | |
2265 (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) | 1480 (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) |
2266 png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr); | 1481 png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1, |
| 1482 png_ptr->gamma_table, png_ptr->gamma_16_table, |
| 1483 png_ptr->gamma_shift); |
2267 #endif | 1484 #endif |
2268 | 1485 |
2269 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED | 1486 #ifdef PNG_READ_16_TO_8_SUPPORTED |
2270 if ((png_ptr->transformations & PNG_STRIP_ALPHA) && | 1487 if (png_ptr->transformations & PNG_16_TO_8) |
2271 (png_ptr->transformations & PNG_COMPOSE) && | 1488 png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1); |
2272 (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || | |
2273 row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) | |
2274 png_do_strip_channel(row_info, png_ptr->row_buf + 1, | |
2275 0 /* at_start == false, because SWAP_ALPHA happens later */); | |
2276 #endif | 1489 #endif |
2277 | 1490 |
2278 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED | 1491 #ifdef PNG_READ_DITHER_SUPPORTED |
2279 if ((png_ptr->transformations & PNG_ENCODE_ALPHA) && | 1492 if (png_ptr->transformations & PNG_DITHER) |
2280 (row_info->color_type & PNG_COLOR_MASK_ALPHA)) | |
2281 png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr); | |
2282 #endif | |
2283 | |
2284 #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED | |
2285 if (png_ptr->transformations & PNG_SCALE_16_TO_8) | |
2286 png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1); | |
2287 #endif | |
2288 | |
2289 #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED | |
2290 /* There is no harm in doing both of these because only one has any effect, | |
2291 * by putting the 'scale' option first if the app asks for scale (either by | |
2292 * calling the API or in a TRANSFORM flag) this is what happens. | |
2293 */ | |
2294 if (png_ptr->transformations & PNG_16_TO_8) | |
2295 png_do_chop(row_info, png_ptr->row_buf + 1); | |
2296 #endif | |
2297 | |
2298 #ifdef PNG_READ_QUANTIZE_SUPPORTED | |
2299 if (png_ptr->transformations & PNG_QUANTIZE) | |
2300 { | 1493 { |
2301 png_do_quantize(row_info, png_ptr->row_buf + 1, | 1494 png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1, |
2302 png_ptr->palette_lookup, png_ptr->quantize_index); | 1495 png_ptr->palette_lookup, png_ptr->dither_index); |
2303 | 1496 if (png_ptr->row_info.rowbytes == (png_uint_32)0) |
2304 if (row_info->rowbytes == 0) | 1497 png_error(png_ptr, "png_do_dither returned rowbytes=0"); |
2305 png_error(png_ptr, "png_do_quantize returned rowbytes=0"); | |
2306 } | 1498 } |
2307 #endif /* PNG_READ_QUANTIZE_SUPPORTED */ | |
2308 | |
2309 #ifdef PNG_READ_EXPAND_16_SUPPORTED | |
2310 /* Do the expansion now, after all the arithmetic has been done. Notice | |
2311 * that previous transformations can handle the PNG_EXPAND_16 flag if this | |
2312 * is efficient (particularly true in the case of gamma correction, where | |
2313 * better accuracy results faster!) | |
2314 */ | |
2315 if (png_ptr->transformations & PNG_EXPAND_16) | |
2316 png_do_expand_16(row_info, png_ptr->row_buf + 1); | |
2317 #endif | |
2318 | |
2319 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED | |
2320 /* NOTE: moved here in 1.5.4 (from much later in this list.) */ | |
2321 if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && | |
2322 (png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) | |
2323 png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); | |
2324 #endif | 1499 #endif |
2325 | 1500 |
2326 #ifdef PNG_READ_INVERT_SUPPORTED | 1501 #ifdef PNG_READ_INVERT_SUPPORTED |
2327 if (png_ptr->transformations & PNG_INVERT_MONO) | 1502 if (png_ptr->transformations & PNG_INVERT_MONO) |
2328 png_do_invert(row_info, png_ptr->row_buf + 1); | 1503 png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); |
2329 #endif | 1504 #endif |
2330 | 1505 |
2331 #ifdef PNG_READ_SHIFT_SUPPORTED | 1506 #ifdef PNG_READ_SHIFT_SUPPORTED |
2332 if (png_ptr->transformations & PNG_SHIFT) | 1507 if (png_ptr->transformations & PNG_SHIFT) |
2333 png_do_unshift(row_info, png_ptr->row_buf + 1, | 1508 png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1, |
2334 &(png_ptr->shift)); | 1509 &(png_ptr->shift)); |
2335 #endif | 1510 #endif |
2336 | 1511 |
2337 #ifdef PNG_READ_PACK_SUPPORTED | 1512 #ifdef PNG_READ_PACK_SUPPORTED |
2338 if (png_ptr->transformations & PNG_PACK) | 1513 if (png_ptr->transformations & PNG_PACK) |
2339 png_do_unpack(row_info, png_ptr->row_buf + 1); | 1514 png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1); |
2340 #endif | |
2341 | |
2342 #ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED | |
2343 /* Added at libpng-1.5.10 */ | |
2344 if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && | |
2345 png_ptr->num_palette_max >= 0) | |
2346 png_do_check_palette_indexes(png_ptr, row_info); | |
2347 #endif | 1515 #endif |
2348 | 1516 |
2349 #ifdef PNG_READ_BGR_SUPPORTED | 1517 #ifdef PNG_READ_BGR_SUPPORTED |
2350 if (png_ptr->transformations & PNG_BGR) | 1518 if (png_ptr->transformations & PNG_BGR) |
2351 png_do_bgr(row_info, png_ptr->row_buf + 1); | 1519 png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); |
2352 #endif | 1520 #endif |
2353 | 1521 |
2354 #ifdef PNG_READ_PACKSWAP_SUPPORTED | 1522 #ifdef PNG_READ_PACKSWAP_SUPPORTED |
2355 if (png_ptr->transformations & PNG_PACKSWAP) | 1523 if (png_ptr->transformations & PNG_PACKSWAP) |
2356 png_do_packswap(row_info, png_ptr->row_buf + 1); | 1524 png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); |
| 1525 #endif |
| 1526 |
| 1527 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED |
| 1528 /* If gray -> RGB, do so now only if we did not do so above */ |
| 1529 if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && |
| 1530 (png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) |
| 1531 png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); |
2357 #endif | 1532 #endif |
2358 | 1533 |
2359 #ifdef PNG_READ_FILLER_SUPPORTED | 1534 #ifdef PNG_READ_FILLER_SUPPORTED |
2360 if (png_ptr->transformations & PNG_FILLER) | 1535 if (png_ptr->transformations & PNG_FILLER) |
2361 png_do_read_filler(row_info, png_ptr->row_buf + 1, | 1536 png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, |
2362 (png_uint_32)png_ptr->filler, png_ptr->flags); | 1537 (png_uint_32)png_ptr->filler, png_ptr->flags); |
2363 #endif | 1538 #endif |
2364 | 1539 |
2365 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED | 1540 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED |
2366 if (png_ptr->transformations & PNG_INVERT_ALPHA) | 1541 if (png_ptr->transformations & PNG_INVERT_ALPHA) |
2367 png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1); | 1542 png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); |
2368 #endif | 1543 #endif |
2369 | 1544 |
2370 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED | 1545 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED |
2371 if (png_ptr->transformations & PNG_SWAP_ALPHA) | 1546 if (png_ptr->transformations & PNG_SWAP_ALPHA) |
2372 png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1); | 1547 png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); |
2373 #endif | 1548 #endif |
2374 | 1549 |
2375 #ifdef PNG_READ_16BIT_SUPPORTED | |
2376 #ifdef PNG_READ_SWAP_SUPPORTED | 1550 #ifdef PNG_READ_SWAP_SUPPORTED |
2377 if (png_ptr->transformations & PNG_SWAP_BYTES) | 1551 if (png_ptr->transformations & PNG_SWAP_BYTES) |
2378 png_do_swap(row_info, png_ptr->row_buf + 1); | 1552 png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); |
2379 #endif | |
2380 #endif | 1553 #endif |
2381 | 1554 |
2382 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED | 1555 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED |
2383 if (png_ptr->transformations & PNG_USER_TRANSFORM) | 1556 if (png_ptr->transformations & PNG_USER_TRANSFORM) |
2384 { | 1557 { |
2385 if (png_ptr->read_user_transform_fn != NULL) | 1558 if (png_ptr->read_user_transform_fn != NULL) |
2386 (*(png_ptr->read_user_transform_fn)) /* User read transform function */ | 1559 (*(png_ptr->read_user_transform_fn)) /* User read transform function */ |
2387 (png_ptr, /* png_ptr */ | 1560 (png_ptr, /* png_ptr */ |
2388 row_info, /* row_info: */ | 1561 &(png_ptr->row_info), /* row_info: */ |
2389 /* png_uint_32 width; width of row */ | 1562 /* png_uint_32 width; width of row */ |
2390 /* png_size_t rowbytes; number of bytes in row */ | 1563 /* png_uint_32 rowbytes; number of bytes in row */ |
2391 /* png_byte color_type; color type of pixels */ | 1564 /* png_byte color_type; color type of pixels */ |
2392 /* png_byte bit_depth; bit depth of samples */ | 1565 /* png_byte bit_depth; bit depth of samples */ |
2393 /* png_byte channels; number of channels (1-4) */ | 1566 /* png_byte channels; number of channels (1-4) */ |
2394 /* png_byte pixel_depth; bits per pixel (depth*channels) */ | 1567 /* png_byte pixel_depth; bits per pixel (depth*channels) */ |
2395 png_ptr->row_buf + 1); /* start of pixel data for row */ | 1568 png_ptr->row_buf + 1); /* start of pixel data for row */ |
2396 #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED | 1569 #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED |
2397 if (png_ptr->user_transform_depth) | 1570 if (png_ptr->user_transform_depth) |
2398 row_info->bit_depth = png_ptr->user_transform_depth; | 1571 png_ptr->row_info.bit_depth = png_ptr->user_transform_depth; |
2399 | |
2400 if (png_ptr->user_transform_channels) | 1572 if (png_ptr->user_transform_channels) |
2401 row_info->channels = png_ptr->user_transform_channels; | 1573 png_ptr->row_info.channels = png_ptr->user_transform_channels; |
2402 #endif | 1574 #endif |
2403 row_info->pixel_depth = (png_byte)(row_info->bit_depth * | 1575 png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth * |
2404 row_info->channels); | 1576 png_ptr->row_info.channels); |
2405 | 1577 png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, |
2406 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width); | 1578 png_ptr->row_info.width); |
2407 } | 1579 } |
2408 #endif | 1580 #endif |
| 1581 |
2409 } | 1582 } |
2410 | 1583 |
2411 #ifdef PNG_READ_PACK_SUPPORTED | 1584 #ifdef PNG_READ_PACK_SUPPORTED |
2412 /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, | 1585 /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, |
2413 * without changing the actual values. Thus, if you had a row with | 1586 * without changing the actual values. Thus, if you had a row with |
2414 * a bit depth of 1, you would end up with bytes that only contained | 1587 * a bit depth of 1, you would end up with bytes that only contained |
2415 * the numbers 0 or 1. If you would rather they contain 0 and 255, use | 1588 * the numbers 0 or 1. If you would rather they contain 0 and 255, use |
2416 * png_do_shift() after this. | 1589 * png_do_shift() after this. |
2417 */ | 1590 */ |
2418 void /* PRIVATE */ | 1591 void /* PRIVATE */ |
2419 png_do_unpack(png_row_infop row_info, png_bytep row) | 1592 png_do_unpack(png_row_infop row_info, png_bytep row) |
2420 { | 1593 { |
2421 png_debug(1, "in png_do_unpack"); | 1594 png_debug(1, "in png_do_unpack"); |
2422 | 1595 |
| 1596 #ifdef PNG_USELESS_TESTS_SUPPORTED |
| 1597 if (row != NULL && row_info != NULL && row_info->bit_depth < 8) |
| 1598 #else |
2423 if (row_info->bit_depth < 8) | 1599 if (row_info->bit_depth < 8) |
| 1600 #endif |
2424 { | 1601 { |
2425 png_uint_32 i; | 1602 png_uint_32 i; |
2426 png_uint_32 row_width=row_info->width; | 1603 png_uint_32 row_width=row_info->width; |
2427 | 1604 |
2428 switch (row_info->bit_depth) | 1605 switch (row_info->bit_depth) |
2429 { | 1606 { |
2430 case 1: | 1607 case 1: |
2431 { | 1608 { |
2432 png_bytep sp = row + (png_size_t)((row_width - 1) >> 3); | 1609 png_bytep sp = row + (png_size_t)((row_width - 1) >> 3); |
2433 png_bytep dp = row + (png_size_t)row_width - 1; | 1610 png_bytep dp = row + (png_size_t)row_width - 1; |
2434 png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07); | 1611 png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07); |
2435 for (i = 0; i < row_width; i++) | 1612 for (i = 0; i < row_width; i++) |
2436 { | 1613 { |
2437 *dp = (png_byte)((*sp >> shift) & 0x01); | 1614 *dp = (png_byte)((*sp >> shift) & 0x01); |
2438 | |
2439 if (shift == 7) | 1615 if (shift == 7) |
2440 { | 1616 { |
2441 shift = 0; | 1617 shift = 0; |
2442 sp--; | 1618 sp--; |
2443 } | 1619 } |
2444 | |
2445 else | 1620 else |
2446 shift++; | 1621 shift++; |
2447 | 1622 |
2448 dp--; | 1623 dp--; |
2449 } | 1624 } |
2450 break; | 1625 break; |
2451 } | 1626 } |
2452 | 1627 |
2453 case 2: | 1628 case 2: |
2454 { | 1629 { |
2455 | 1630 |
2456 png_bytep sp = row + (png_size_t)((row_width - 1) >> 2); | 1631 png_bytep sp = row + (png_size_t)((row_width - 1) >> 2); |
2457 png_bytep dp = row + (png_size_t)row_width - 1; | 1632 png_bytep dp = row + (png_size_t)row_width - 1; |
2458 png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); | 1633 png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); |
2459 for (i = 0; i < row_width; i++) | 1634 for (i = 0; i < row_width; i++) |
2460 { | 1635 { |
2461 *dp = (png_byte)((*sp >> shift) & 0x03); | 1636 *dp = (png_byte)((*sp >> shift) & 0x03); |
2462 | |
2463 if (shift == 6) | 1637 if (shift == 6) |
2464 { | 1638 { |
2465 shift = 0; | 1639 shift = 0; |
2466 sp--; | 1640 sp--; |
2467 } | 1641 } |
2468 | |
2469 else | 1642 else |
2470 shift += 2; | 1643 shift += 2; |
2471 | 1644 |
2472 dp--; | 1645 dp--; |
2473 } | 1646 } |
2474 break; | 1647 break; |
2475 } | 1648 } |
2476 | 1649 |
2477 case 4: | 1650 case 4: |
2478 { | 1651 { |
2479 png_bytep sp = row + (png_size_t)((row_width - 1) >> 1); | 1652 png_bytep sp = row + (png_size_t)((row_width - 1) >> 1); |
2480 png_bytep dp = row + (png_size_t)row_width - 1; | 1653 png_bytep dp = row + (png_size_t)row_width - 1; |
2481 png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); | 1654 png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); |
2482 for (i = 0; i < row_width; i++) | 1655 for (i = 0; i < row_width; i++) |
2483 { | 1656 { |
2484 *dp = (png_byte)((*sp >> shift) & 0x0f); | 1657 *dp = (png_byte)((*sp >> shift) & 0x0f); |
2485 | |
2486 if (shift == 4) | 1658 if (shift == 4) |
2487 { | 1659 { |
2488 shift = 0; | 1660 shift = 0; |
2489 sp--; | 1661 sp--; |
2490 } | 1662 } |
2491 | |
2492 else | 1663 else |
2493 shift = 4; | 1664 shift = 4; |
2494 | 1665 |
2495 dp--; | 1666 dp--; |
2496 } | 1667 } |
2497 break; | 1668 break; |
2498 } | 1669 } |
2499 | |
2500 default: | |
2501 break; | |
2502 } | 1670 } |
2503 row_info->bit_depth = 8; | 1671 row_info->bit_depth = 8; |
2504 row_info->pixel_depth = (png_byte)(8 * row_info->channels); | 1672 row_info->pixel_depth = (png_byte)(8 * row_info->channels); |
2505 row_info->rowbytes = row_width * row_info->channels; | 1673 row_info->rowbytes = row_width * row_info->channels; |
2506 } | 1674 } |
2507 } | 1675 } |
2508 #endif | 1676 #endif |
2509 | 1677 |
2510 #ifdef PNG_READ_SHIFT_SUPPORTED | 1678 #ifdef PNG_READ_SHIFT_SUPPORTED |
2511 /* Reverse the effects of png_do_shift. This routine merely shifts the | 1679 /* Reverse the effects of png_do_shift. This routine merely shifts the |
2512 * pixels back to their significant bits values. Thus, if you have | 1680 * pixels back to their significant bits values. Thus, if you have |
2513 * a row of bit depth 8, but only 5 are significant, this will shift | 1681 * a row of bit depth 8, but only 5 are significant, this will shift |
2514 * the values back to 0 through 31. | 1682 * the values back to 0 through 31. |
2515 */ | 1683 */ |
2516 void /* PRIVATE */ | 1684 void /* PRIVATE */ |
2517 png_do_unshift(png_row_infop row_info, png_bytep row, | 1685 png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits) |
2518 png_const_color_8p sig_bits) | |
2519 { | 1686 { |
2520 int color_type; | |
2521 | |
2522 png_debug(1, "in png_do_unshift"); | 1687 png_debug(1, "in png_do_unshift"); |
2523 | 1688 |
2524 /* The palette case has already been handled in the _init routine. */ | 1689 if ( |
2525 color_type = row_info->color_type; | 1690 #ifdef PNG_USELESS_TESTS_SUPPORTED |
2526 | 1691 row != NULL && row_info != NULL && sig_bits != NULL && |
2527 if (color_type != PNG_COLOR_TYPE_PALETTE) | 1692 #endif |
| 1693 row_info->color_type != PNG_COLOR_TYPE_PALETTE) |
2528 { | 1694 { |
2529 int shift[4]; | 1695 int shift[4]; |
2530 int channels = 0; | 1696 int channels = 0; |
2531 int bit_depth = row_info->bit_depth; | 1697 int c; |
| 1698 png_uint_16 value = 0; |
| 1699 png_uint_32 row_width = row_info->width; |
2532 | 1700 |
2533 if (color_type & PNG_COLOR_MASK_COLOR) | 1701 if (row_info->color_type & PNG_COLOR_MASK_COLOR) |
2534 { | 1702 { |
2535 shift[channels++] = bit_depth - sig_bits->red; | 1703 shift[channels++] = row_info->bit_depth - sig_bits->red; |
2536 shift[channels++] = bit_depth - sig_bits->green; | 1704 shift[channels++] = row_info->bit_depth - sig_bits->green; |
2537 shift[channels++] = bit_depth - sig_bits->blue; | 1705 shift[channels++] = row_info->bit_depth - sig_bits->blue; |
| 1706 } |
| 1707 else |
| 1708 { |
| 1709 shift[channels++] = row_info->bit_depth - sig_bits->gray; |
| 1710 } |
| 1711 if (row_info->color_type & PNG_COLOR_MASK_ALPHA) |
| 1712 { |
| 1713 shift[channels++] = row_info->bit_depth - sig_bits->alpha; |
2538 } | 1714 } |
2539 | 1715 |
2540 else | 1716 for (c = 0; c < channels; c++) |
2541 { | 1717 { |
2542 shift[channels++] = bit_depth - sig_bits->gray; | 1718 if (shift[c] <= 0) |
| 1719 shift[c] = 0; |
| 1720 else |
| 1721 value = 1; |
2543 } | 1722 } |
2544 | 1723 |
2545 if (color_type & PNG_COLOR_MASK_ALPHA) | 1724 if (!value) |
| 1725 return; |
| 1726 |
| 1727 switch (row_info->bit_depth) |
2546 { | 1728 { |
2547 shift[channels++] = bit_depth - sig_bits->alpha; | 1729 case 2: |
2548 } | 1730 { |
| 1731 png_bytep bp; |
| 1732 png_uint_32 i; |
| 1733 png_uint_32 istop = row_info->rowbytes; |
2549 | 1734 |
2550 { | 1735 for (bp = row, i = 0; i < istop; i++) |
2551 int c, have_shift; | |
2552 | |
2553 for (c = have_shift = 0; c < channels; ++c) | |
2554 { | |
2555 /* A shift of more than the bit depth is an error condition but it | |
2556 * gets ignored here. | |
2557 */ | |
2558 if (shift[c] <= 0 || shift[c] >= bit_depth) | |
2559 shift[c] = 0; | |
2560 | |
2561 else | |
2562 have_shift = 1; | |
2563 } | |
2564 | |
2565 if (!have_shift) | |
2566 return; | |
2567 } | |
2568 | |
2569 switch (bit_depth) | |
2570 { | |
2571 default: | |
2572 /* Must be 1bpp gray: should not be here! */ | |
2573 /* NOTREACHED */ | |
2574 break; | |
2575 | |
2576 case 2: | |
2577 /* Must be 2bpp gray */ | |
2578 /* assert(channels == 1 && shift[0] == 1) */ | |
2579 { | |
2580 png_bytep bp = row; | |
2581 png_bytep bp_end = bp + row_info->rowbytes; | |
2582 | |
2583 while (bp < bp_end) | |
2584 { | 1736 { |
2585 int b = (*bp >> 1) & 0x55; | 1737 *bp >>= 1; |
2586 *bp++ = (png_byte)b; | 1738 *bp++ &= 0x55; |
2587 } | 1739 } |
2588 break; | 1740 break; |
2589 } | 1741 } |
2590 | 1742 |
2591 case 4: | 1743 case 4: |
2592 /* Must be 4bpp gray */ | |
2593 /* assert(channels == 1) */ | |
2594 { | 1744 { |
2595 png_bytep bp = row; | 1745 png_bytep bp = row; |
2596 png_bytep bp_end = bp + row_info->rowbytes; | 1746 png_uint_32 i; |
2597 int gray_shift = shift[0]; | 1747 png_uint_32 istop = row_info->rowbytes; |
2598 int mask = 0xf >> gray_shift; | 1748 png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) | |
| 1749 (png_byte)((int)0xf >> shift[0])); |
2599 | 1750 |
2600 mask |= mask << 4; | 1751 for (i = 0; i < istop; i++) |
2601 | |
2602 while (bp < bp_end) | |
2603 { | 1752 { |
2604 int b = (*bp >> gray_shift) & mask; | 1753 *bp >>= shift[0]; |
2605 *bp++ = (png_byte)b; | 1754 *bp++ &= mask; |
2606 } | 1755 } |
2607 break; | 1756 break; |
2608 } | 1757 } |
2609 | 1758 |
2610 case 8: | 1759 case 8: |
2611 /* Single byte components, G, GA, RGB, RGBA */ | |
2612 { | 1760 { |
2613 png_bytep bp = row; | 1761 png_bytep bp = row; |
2614 png_bytep bp_end = bp + row_info->rowbytes; | 1762 png_uint_32 i; |
2615 int channel = 0; | 1763 png_uint_32 istop = row_width * channels; |
2616 | 1764 |
2617 while (bp < bp_end) | 1765 for (i = 0; i < istop; i++) |
2618 { | 1766 { |
2619 int b = *bp >> shift[channel]; | 1767 *bp++ >>= shift[i%channels]; |
2620 if (++channel >= channels) | |
2621 channel = 0; | |
2622 *bp++ = (png_byte)b; | |
2623 } | 1768 } |
2624 break; | 1769 break; |
2625 } | 1770 } |
2626 | 1771 |
2627 #ifdef PNG_READ_16BIT_SUPPORTED | |
2628 case 16: | 1772 case 16: |
2629 /* Double byte components, G, GA, RGB, RGBA */ | |
2630 { | 1773 { |
2631 png_bytep bp = row; | 1774 png_bytep bp = row; |
2632 png_bytep bp_end = bp + row_info->rowbytes; | 1775 png_uint_32 i; |
2633 int channel = 0; | 1776 png_uint_32 istop = channels * row_width; |
2634 | 1777 |
2635 while (bp < bp_end) | 1778 for (i = 0; i < istop; i++) |
2636 { | 1779 { |
2637 int value = (bp[0] << 8) + bp[1]; | 1780 value = (png_uint_16)((*bp << 8) + *(bp + 1)); |
2638 | 1781 value >>= shift[i%channels]; |
2639 value >>= shift[channel]; | |
2640 if (++channel >= channels) | |
2641 channel = 0; | |
2642 *bp++ = (png_byte)(value >> 8); | 1782 *bp++ = (png_byte)(value >> 8); |
2643 *bp++ = (png_byte)(value & 0xff); | 1783 *bp++ = (png_byte)(value & 0xff); |
2644 } | 1784 } |
2645 break; | 1785 break; |
2646 } | 1786 } |
2647 #endif | |
2648 } | 1787 } |
2649 } | 1788 } |
2650 } | 1789 } |
2651 #endif | 1790 #endif |
2652 | 1791 |
2653 #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED | 1792 #ifdef PNG_READ_16_TO_8_SUPPORTED |
2654 /* Scale rows of bit depth 16 down to 8 accurately */ | 1793 /* Chop rows of bit depth 16 down to 8 */ |
2655 void /* PRIVATE */ | 1794 void /* PRIVATE */ |
2656 png_do_scale_16_to_8(png_row_infop row_info, png_bytep row) | |
2657 { | |
2658 png_debug(1, "in png_do_scale_16_to_8"); | |
2659 | |
2660 if (row_info->bit_depth == 16) | |
2661 { | |
2662 png_bytep sp = row; /* source */ | |
2663 png_bytep dp = row; /* destination */ | |
2664 png_bytep ep = sp + row_info->rowbytes; /* end+1 */ | |
2665 | |
2666 while (sp < ep) | |
2667 { | |
2668 /* The input is an array of 16 bit components, these must be scaled to | |
2669 * 8 bits each. For a 16 bit value V the required value (from the PNG | |
2670 * specification) is: | |
2671 * | |
2672 * (V * 255) / 65535 | |
2673 * | |
2674 * This reduces to round(V / 257), or floor((V + 128.5)/257) | |
2675 * | |
2676 * Represent V as the two byte value vhi.vlo. Make a guess that the | |
2677 * result is the top byte of V, vhi, then the correction to this value | |
2678 * is: | |
2679 * | |
2680 * error = floor(((V-vhi.vhi) + 128.5) / 257) | |
2681 * = floor(((vlo-vhi) + 128.5) / 257) | |
2682 * | |
2683 * This can be approximated using integer arithmetic (and a signed | |
2684 * shift): | |
2685 * | |
2686 * error = (vlo-vhi+128) >> 8; | |
2687 * | |
2688 * The approximate differs from the exact answer only when (vlo-vhi) is | |
2689 * 128; it then gives a correction of +1 when the exact correction is | |
2690 * 0. This gives 128 errors. The exact answer (correct for all 16 bit | |
2691 * input values) is: | |
2692 * | |
2693 * error = (vlo-vhi+128)*65535 >> 24; | |
2694 * | |
2695 * An alternative arithmetic calculation which also gives no errors is: | |
2696 * | |
2697 * (V * 255 + 32895) >> 16 | |
2698 */ | |
2699 | |
2700 png_int_32 tmp = *sp++; /* must be signed! */ | |
2701 tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24; | |
2702 *dp++ = (png_byte)tmp; | |
2703 } | |
2704 | |
2705 row_info->bit_depth = 8; | |
2706 row_info->pixel_depth = (png_byte)(8 * row_info->channels); | |
2707 row_info->rowbytes = row_info->width * row_info->channels; | |
2708 } | |
2709 } | |
2710 #endif | |
2711 | |
2712 #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED | |
2713 void /* PRIVATE */ | |
2714 /* Simply discard the low byte. This was the default behavior prior | |
2715 * to libpng-1.5.4. | |
2716 */ | |
2717 png_do_chop(png_row_infop row_info, png_bytep row) | 1795 png_do_chop(png_row_infop row_info, png_bytep row) |
2718 { | 1796 { |
2719 png_debug(1, "in png_do_chop"); | 1797 png_debug(1, "in png_do_chop"); |
2720 | 1798 |
| 1799 #ifdef PNG_USELESS_TESTS_SUPPORTED |
| 1800 if (row != NULL && row_info != NULL && row_info->bit_depth == 16) |
| 1801 #else |
2721 if (row_info->bit_depth == 16) | 1802 if (row_info->bit_depth == 16) |
| 1803 #endif |
2722 { | 1804 { |
2723 png_bytep sp = row; /* source */ | 1805 png_bytep sp = row; |
2724 png_bytep dp = row; /* destination */ | 1806 png_bytep dp = row; |
2725 png_bytep ep = sp + row_info->rowbytes; /* end+1 */ | 1807 png_uint_32 i; |
| 1808 png_uint_32 istop = row_info->width * row_info->channels; |
2726 | 1809 |
2727 while (sp < ep) | 1810 for (i = 0; i<istop; i++, sp += 2, dp++) |
2728 { | 1811 { |
2729 *dp++ = *sp; | 1812 #ifdef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED |
2730 sp += 2; /* skip low byte */ | 1813 /* This does a more accurate scaling of the 16-bit color |
| 1814 * value, rather than a simple low-byte truncation. |
| 1815 * |
| 1816 * What the ideal calculation should be: |
| 1817 * *dp = (((((png_uint_32)(*sp) << 8) | |
| 1818 * (png_uint_32)(*(sp + 1))) * 255 + 127) |
| 1819 * / (png_uint_32)65535L; |
| 1820 * |
| 1821 * GRR: no, I think this is what it really should be: |
| 1822 * *dp = (((((png_uint_32)(*sp) << 8) | |
| 1823 * (png_uint_32)(*(sp + 1))) + 128L) |
| 1824 * / (png_uint_32)257L; |
| 1825 * |
| 1826 * GRR: here's the exact calculation with shifts: |
| 1827 * temp = (((png_uint_32)(*sp) << 8) | |
| 1828 * (png_uint_32)(*(sp + 1))) + 128L; |
| 1829 * *dp = (temp - (temp >> 8)) >> 8; |
| 1830 * |
| 1831 * Approximate calculation with shift/add instead of multiply/divide: |
| 1832 * *dp = ((((png_uint_32)(*sp) << 8) | |
| 1833 * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8; |
| 1834 * |
| 1835 * What we actually do to avoid extra shifting and conversion: |
| 1836 */ |
| 1837 |
| 1838 *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0); |
| 1839 #else |
| 1840 /* Simply discard the low order byte */ |
| 1841 *dp = *sp; |
| 1842 #endif |
2731 } | 1843 } |
2732 | |
2733 row_info->bit_depth = 8; | 1844 row_info->bit_depth = 8; |
2734 row_info->pixel_depth = (png_byte)(8 * row_info->channels); | 1845 row_info->pixel_depth = (png_byte)(8 * row_info->channels); |
2735 row_info->rowbytes = row_info->width * row_info->channels; | 1846 row_info->rowbytes = row_info->width * row_info->channels; |
2736 } | 1847 } |
2737 } | 1848 } |
2738 #endif | 1849 #endif |
2739 | 1850 |
2740 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED | 1851 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED |
2741 void /* PRIVATE */ | 1852 void /* PRIVATE */ |
2742 png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) | 1853 png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) |
2743 { | 1854 { |
2744 png_debug(1, "in png_do_read_swap_alpha"); | 1855 png_debug(1, "in png_do_read_swap_alpha"); |
2745 | 1856 |
| 1857 #ifdef PNG_USELESS_TESTS_SUPPORTED |
| 1858 if (row != NULL && row_info != NULL) |
| 1859 #endif |
2746 { | 1860 { |
2747 png_uint_32 row_width = row_info->width; | 1861 png_uint_32 row_width = row_info->width; |
2748 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) | 1862 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) |
2749 { | 1863 { |
2750 /* This converts from RGBA to ARGB */ | 1864 /* This converts from RGBA to ARGB */ |
2751 if (row_info->bit_depth == 8) | 1865 if (row_info->bit_depth == 8) |
2752 { | 1866 { |
2753 png_bytep sp = row + row_info->rowbytes; | 1867 png_bytep sp = row + row_info->rowbytes; |
2754 png_bytep dp = sp; | 1868 png_bytep dp = sp; |
2755 png_byte save; | 1869 png_byte save; |
2756 png_uint_32 i; | 1870 png_uint_32 i; |
2757 | 1871 |
2758 for (i = 0; i < row_width; i++) | 1872 for (i = 0; i < row_width; i++) |
2759 { | 1873 { |
2760 save = *(--sp); | 1874 save = *(--sp); |
2761 *(--dp) = *(--sp); | 1875 *(--dp) = *(--sp); |
2762 *(--dp) = *(--sp); | 1876 *(--dp) = *(--sp); |
2763 *(--dp) = *(--sp); | 1877 *(--dp) = *(--sp); |
2764 *(--dp) = save; | 1878 *(--dp) = save; |
2765 } | 1879 } |
2766 } | 1880 } |
2767 | |
2768 #ifdef PNG_READ_16BIT_SUPPORTED | |
2769 /* This converts from RRGGBBAA to AARRGGBB */ | 1881 /* This converts from RRGGBBAA to AARRGGBB */ |
2770 else | 1882 else |
2771 { | 1883 { |
2772 png_bytep sp = row + row_info->rowbytes; | 1884 png_bytep sp = row + row_info->rowbytes; |
2773 png_bytep dp = sp; | 1885 png_bytep dp = sp; |
2774 png_byte save[2]; | 1886 png_byte save[2]; |
2775 png_uint_32 i; | 1887 png_uint_32 i; |
2776 | 1888 |
2777 for (i = 0; i < row_width; i++) | 1889 for (i = 0; i < row_width; i++) |
2778 { | 1890 { |
2779 save[0] = *(--sp); | 1891 save[0] = *(--sp); |
2780 save[1] = *(--sp); | 1892 save[1] = *(--sp); |
2781 *(--dp) = *(--sp); | 1893 *(--dp) = *(--sp); |
2782 *(--dp) = *(--sp); | 1894 *(--dp) = *(--sp); |
2783 *(--dp) = *(--sp); | 1895 *(--dp) = *(--sp); |
2784 *(--dp) = *(--sp); | 1896 *(--dp) = *(--sp); |
2785 *(--dp) = *(--sp); | 1897 *(--dp) = *(--sp); |
2786 *(--dp) = *(--sp); | 1898 *(--dp) = *(--sp); |
2787 *(--dp) = save[0]; | 1899 *(--dp) = save[0]; |
2788 *(--dp) = save[1]; | 1900 *(--dp) = save[1]; |
2789 } | 1901 } |
2790 } | 1902 } |
2791 #endif | |
2792 } | 1903 } |
2793 | |
2794 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) | 1904 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) |
2795 { | 1905 { |
2796 /* This converts from GA to AG */ | 1906 /* This converts from GA to AG */ |
2797 if (row_info->bit_depth == 8) | 1907 if (row_info->bit_depth == 8) |
2798 { | 1908 { |
2799 png_bytep sp = row + row_info->rowbytes; | 1909 png_bytep sp = row + row_info->rowbytes; |
2800 png_bytep dp = sp; | 1910 png_bytep dp = sp; |
2801 png_byte save; | 1911 png_byte save; |
2802 png_uint_32 i; | 1912 png_uint_32 i; |
2803 | 1913 |
2804 for (i = 0; i < row_width; i++) | 1914 for (i = 0; i < row_width; i++) |
2805 { | 1915 { |
2806 save = *(--sp); | 1916 save = *(--sp); |
2807 *(--dp) = *(--sp); | 1917 *(--dp) = *(--sp); |
2808 *(--dp) = save; | 1918 *(--dp) = save; |
2809 } | 1919 } |
2810 } | 1920 } |
2811 | |
2812 #ifdef PNG_READ_16BIT_SUPPORTED | |
2813 /* This converts from GGAA to AAGG */ | 1921 /* This converts from GGAA to AAGG */ |
2814 else | 1922 else |
2815 { | 1923 { |
2816 png_bytep sp = row + row_info->rowbytes; | 1924 png_bytep sp = row + row_info->rowbytes; |
2817 png_bytep dp = sp; | 1925 png_bytep dp = sp; |
2818 png_byte save[2]; | 1926 png_byte save[2]; |
2819 png_uint_32 i; | 1927 png_uint_32 i; |
2820 | 1928 |
2821 for (i = 0; i < row_width; i++) | 1929 for (i = 0; i < row_width; i++) |
2822 { | 1930 { |
2823 save[0] = *(--sp); | 1931 save[0] = *(--sp); |
2824 save[1] = *(--sp); | 1932 save[1] = *(--sp); |
2825 *(--dp) = *(--sp); | 1933 *(--dp) = *(--sp); |
2826 *(--dp) = *(--sp); | 1934 *(--dp) = *(--sp); |
2827 *(--dp) = save[0]; | 1935 *(--dp) = save[0]; |
2828 *(--dp) = save[1]; | 1936 *(--dp) = save[1]; |
2829 } | 1937 } |
2830 } | 1938 } |
2831 #endif | |
2832 } | 1939 } |
2833 } | 1940 } |
2834 } | 1941 } |
2835 #endif | 1942 #endif |
2836 | 1943 |
2837 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED | 1944 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED |
2838 void /* PRIVATE */ | 1945 void /* PRIVATE */ |
2839 png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) | 1946 png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) |
2840 { | 1947 { |
2841 png_uint_32 row_width; | |
2842 png_debug(1, "in png_do_read_invert_alpha"); | 1948 png_debug(1, "in png_do_read_invert_alpha"); |
2843 | 1949 |
2844 row_width = row_info->width; | 1950 #ifdef PNG_USELESS_TESTS_SUPPORTED |
2845 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) | 1951 if (row != NULL && row_info != NULL) |
| 1952 #endif |
2846 { | 1953 { |
2847 if (row_info->bit_depth == 8) | 1954 png_uint_32 row_width = row_info->width; |
| 1955 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) |
2848 { | 1956 { |
2849 /* This inverts the alpha channel in RGBA */ | 1957 /* This inverts the alpha channel in RGBA */ |
2850 png_bytep sp = row + row_info->rowbytes; | 1958 if (row_info->bit_depth == 8) |
2851 png_bytep dp = sp; | 1959 { |
2852 png_uint_32 i; | 1960 png_bytep sp = row + row_info->rowbytes; |
| 1961 png_bytep dp = sp; |
| 1962 png_uint_32 i; |
2853 | 1963 |
2854 for (i = 0; i < row_width; i++) | 1964 for (i = 0; i < row_width; i++) |
| 1965 { |
| 1966 *(--dp) = (png_byte)(255 - *(--sp)); |
| 1967 |
| 1968 /* This does nothing: |
| 1969 *(--dp) = *(--sp); |
| 1970 *(--dp) = *(--sp); |
| 1971 *(--dp) = *(--sp); |
| 1972 We can replace it with: |
| 1973 */ |
| 1974 sp-=3; |
| 1975 dp=sp; |
| 1976 } |
| 1977 } |
| 1978 /* This inverts the alpha channel in RRGGBBAA */ |
| 1979 else |
2855 { | 1980 { |
2856 *(--dp) = (png_byte)(255 - *(--sp)); | 1981 png_bytep sp = row + row_info->rowbytes; |
| 1982 png_bytep dp = sp; |
| 1983 png_uint_32 i; |
2857 | 1984 |
2858 /* This does nothing: | 1985 for (i = 0; i < row_width; i++) |
2859 *(--dp) = *(--sp); | 1986 { |
2860 *(--dp) = *(--sp); | 1987 *(--dp) = (png_byte)(255 - *(--sp)); |
2861 *(--dp) = *(--sp); | 1988 *(--dp) = (png_byte)(255 - *(--sp)); |
2862 We can replace it with: | 1989 |
| 1990 /* This does nothing: |
| 1991 *(--dp) = *(--sp); |
| 1992 *(--dp) = *(--sp); |
| 1993 *(--dp) = *(--sp); |
| 1994 *(--dp) = *(--sp); |
| 1995 *(--dp) = *(--sp); |
| 1996 *(--dp) = *(--sp); |
| 1997 We can replace it with: |
2863 */ | 1998 */ |
2864 sp-=3; | 1999 sp-=6; |
2865 dp=sp; | 2000 dp=sp; |
| 2001 } |
2866 } | 2002 } |
2867 } | 2003 } |
| 2004 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) |
| 2005 { |
| 2006 /* This inverts the alpha channel in GA */ |
| 2007 if (row_info->bit_depth == 8) |
| 2008 { |
| 2009 png_bytep sp = row + row_info->rowbytes; |
| 2010 png_bytep dp = sp; |
| 2011 png_uint_32 i; |
2868 | 2012 |
2869 #ifdef PNG_READ_16BIT_SUPPORTED | 2013 for (i = 0; i < row_width; i++) |
2870 /* This inverts the alpha channel in RRGGBBAA */ | 2014 { |
2871 else | 2015 *(--dp) = (png_byte)(255 - *(--sp)); |
2872 { | 2016 *(--dp) = *(--sp); |
2873 png_bytep sp = row + row_info->rowbytes; | 2017 } |
2874 png_bytep dp = sp; | 2018 } |
2875 png_uint_32 i; | 2019 /* This inverts the alpha channel in GGAA */ |
| 2020 else |
| 2021 { |
| 2022 png_bytep sp = row + row_info->rowbytes; |
| 2023 png_bytep dp = sp; |
| 2024 png_uint_32 i; |
2876 | 2025 |
2877 for (i = 0; i < row_width; i++) | 2026 for (i = 0; i < row_width; i++) |
2878 { | 2027 { |
2879 *(--dp) = (png_byte)(255 - *(--sp)); | 2028 *(--dp) = (png_byte)(255 - *(--sp)); |
2880 *(--dp) = (png_byte)(255 - *(--sp)); | 2029 *(--dp) = (png_byte)(255 - *(--sp)); |
2881 | 2030 /* |
2882 /* This does nothing: | 2031 *(--dp) = *(--sp); |
2883 *(--dp) = *(--sp); | 2032 *(--dp) = *(--sp); |
2884 *(--dp) = *(--sp); | |
2885 *(--dp) = *(--sp); | |
2886 *(--dp) = *(--sp); | |
2887 *(--dp) = *(--sp); | |
2888 *(--dp) = *(--sp); | |
2889 We can replace it with: | |
2890 */ | 2033 */ |
2891 sp-=6; | 2034 sp-=2; |
2892 dp=sp; | 2035 dp=sp; |
| 2036 } |
2893 } | 2037 } |
2894 } | 2038 } |
2895 #endif | |
2896 } | |
2897 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) | |
2898 { | |
2899 if (row_info->bit_depth == 8) | |
2900 { | |
2901 /* This inverts the alpha channel in GA */ | |
2902 png_bytep sp = row + row_info->rowbytes; | |
2903 png_bytep dp = sp; | |
2904 png_uint_32 i; | |
2905 | |
2906 for (i = 0; i < row_width; i++) | |
2907 { | |
2908 *(--dp) = (png_byte)(255 - *(--sp)); | |
2909 *(--dp) = *(--sp); | |
2910 } | |
2911 } | |
2912 | |
2913 #ifdef PNG_READ_16BIT_SUPPORTED | |
2914 else | |
2915 { | |
2916 /* This inverts the alpha channel in GGAA */ | |
2917 png_bytep sp = row + row_info->rowbytes; | |
2918 png_bytep dp = sp; | |
2919 png_uint_32 i; | |
2920 | |
2921 for (i = 0; i < row_width; i++) | |
2922 { | |
2923 *(--dp) = (png_byte)(255 - *(--sp)); | |
2924 *(--dp) = (png_byte)(255 - *(--sp)); | |
2925 /* | |
2926 *(--dp) = *(--sp); | |
2927 *(--dp) = *(--sp); | |
2928 */ | |
2929 sp-=2; | |
2930 dp=sp; | |
2931 } | |
2932 } | |
2933 #endif | |
2934 } | 2039 } |
2935 } | 2040 } |
2936 #endif | 2041 #endif |
2937 | 2042 |
2938 #ifdef PNG_READ_FILLER_SUPPORTED | 2043 #ifdef PNG_READ_FILLER_SUPPORTED |
2939 /* Add filler channel if we have RGB color */ | 2044 /* Add filler channel if we have RGB color */ |
2940 void /* PRIVATE */ | 2045 void /* PRIVATE */ |
2941 png_do_read_filler(png_row_infop row_info, png_bytep row, | 2046 png_do_read_filler(png_row_infop row_info, png_bytep row, |
2942 png_uint_32 filler, png_uint_32 flags) | 2047 png_uint_32 filler, png_uint_32 flags) |
2943 { | 2048 { |
2944 png_uint_32 i; | 2049 png_uint_32 i; |
2945 png_uint_32 row_width = row_info->width; | 2050 png_uint_32 row_width = row_info->width; |
2946 | 2051 |
2947 #ifdef PNG_READ_16BIT_SUPPORTED | |
2948 png_byte hi_filler = (png_byte)((filler>>8) & 0xff); | 2052 png_byte hi_filler = (png_byte)((filler>>8) & 0xff); |
2949 #endif | |
2950 png_byte lo_filler = (png_byte)(filler & 0xff); | 2053 png_byte lo_filler = (png_byte)(filler & 0xff); |
2951 | 2054 |
2952 png_debug(1, "in png_do_read_filler"); | 2055 png_debug(1, "in png_do_read_filler"); |
2953 | 2056 |
2954 if ( | 2057 if ( |
| 2058 #ifdef PNG_USELESS_TESTS_SUPPORTED |
| 2059 row != NULL && row_info != NULL && |
| 2060 #endif |
2955 row_info->color_type == PNG_COLOR_TYPE_GRAY) | 2061 row_info->color_type == PNG_COLOR_TYPE_GRAY) |
2956 { | 2062 { |
2957 if (row_info->bit_depth == 8) | 2063 if (row_info->bit_depth == 8) |
2958 { | 2064 { |
| 2065 /* This changes the data from G to GX */ |
2959 if (flags & PNG_FLAG_FILLER_AFTER) | 2066 if (flags & PNG_FLAG_FILLER_AFTER) |
2960 { | 2067 { |
2961 /* This changes the data from G to GX */ | |
2962 png_bytep sp = row + (png_size_t)row_width; | 2068 png_bytep sp = row + (png_size_t)row_width; |
2963 png_bytep dp = sp + (png_size_t)row_width; | 2069 png_bytep dp = sp + (png_size_t)row_width; |
2964 for (i = 1; i < row_width; i++) | 2070 for (i = 1; i < row_width; i++) |
2965 { | 2071 { |
2966 *(--dp) = lo_filler; | 2072 *(--dp) = lo_filler; |
2967 *(--dp) = *(--sp); | 2073 *(--dp) = *(--sp); |
2968 } | 2074 } |
2969 *(--dp) = lo_filler; | 2075 *(--dp) = lo_filler; |
2970 row_info->channels = 2; | 2076 row_info->channels = 2; |
2971 row_info->pixel_depth = 16; | 2077 row_info->pixel_depth = 16; |
2972 row_info->rowbytes = row_width * 2; | 2078 row_info->rowbytes = row_width * 2; |
2973 } | 2079 } |
2974 | 2080 /* This changes the data from G to XG */ |
2975 else | 2081 else |
2976 { | 2082 { |
2977 /* This changes the data from G to XG */ | |
2978 png_bytep sp = row + (png_size_t)row_width; | 2083 png_bytep sp = row + (png_size_t)row_width; |
2979 png_bytep dp = sp + (png_size_t)row_width; | 2084 png_bytep dp = sp + (png_size_t)row_width; |
2980 for (i = 0; i < row_width; i++) | 2085 for (i = 0; i < row_width; i++) |
2981 { | 2086 { |
2982 *(--dp) = *(--sp); | 2087 *(--dp) = *(--sp); |
2983 *(--dp) = lo_filler; | 2088 *(--dp) = lo_filler; |
2984 } | 2089 } |
2985 row_info->channels = 2; | 2090 row_info->channels = 2; |
2986 row_info->pixel_depth = 16; | 2091 row_info->pixel_depth = 16; |
2987 row_info->rowbytes = row_width * 2; | 2092 row_info->rowbytes = row_width * 2; |
2988 } | 2093 } |
2989 } | 2094 } |
2990 | |
2991 #ifdef PNG_READ_16BIT_SUPPORTED | |
2992 else if (row_info->bit_depth == 16) | 2095 else if (row_info->bit_depth == 16) |
2993 { | 2096 { |
| 2097 /* This changes the data from GG to GGXX */ |
2994 if (flags & PNG_FLAG_FILLER_AFTER) | 2098 if (flags & PNG_FLAG_FILLER_AFTER) |
2995 { | 2099 { |
2996 /* This changes the data from GG to GGXX */ | |
2997 png_bytep sp = row + (png_size_t)row_width * 2; | 2100 png_bytep sp = row + (png_size_t)row_width * 2; |
2998 png_bytep dp = sp + (png_size_t)row_width * 2; | 2101 png_bytep dp = sp + (png_size_t)row_width * 2; |
2999 for (i = 1; i < row_width; i++) | 2102 for (i = 1; i < row_width; i++) |
3000 { | 2103 { |
3001 *(--dp) = hi_filler; | 2104 *(--dp) = hi_filler; |
3002 *(--dp) = lo_filler; | 2105 *(--dp) = lo_filler; |
3003 *(--dp) = *(--sp); | 2106 *(--dp) = *(--sp); |
3004 *(--dp) = *(--sp); | 2107 *(--dp) = *(--sp); |
3005 } | 2108 } |
3006 *(--dp) = hi_filler; | 2109 *(--dp) = hi_filler; |
3007 *(--dp) = lo_filler; | 2110 *(--dp) = lo_filler; |
3008 row_info->channels = 2; | 2111 row_info->channels = 2; |
3009 row_info->pixel_depth = 32; | 2112 row_info->pixel_depth = 32; |
3010 row_info->rowbytes = row_width * 4; | 2113 row_info->rowbytes = row_width * 4; |
3011 } | 2114 } |
3012 | 2115 /* This changes the data from GG to XXGG */ |
3013 else | 2116 else |
3014 { | 2117 { |
3015 /* This changes the data from GG to XXGG */ | |
3016 png_bytep sp = row + (png_size_t)row_width * 2; | 2118 png_bytep sp = row + (png_size_t)row_width * 2; |
3017 png_bytep dp = sp + (png_size_t)row_width * 2; | 2119 png_bytep dp = sp + (png_size_t)row_width * 2; |
3018 for (i = 0; i < row_width; i++) | 2120 for (i = 0; i < row_width; i++) |
3019 { | 2121 { |
3020 *(--dp) = *(--sp); | 2122 *(--dp) = *(--sp); |
3021 *(--dp) = *(--sp); | 2123 *(--dp) = *(--sp); |
3022 *(--dp) = hi_filler; | 2124 *(--dp) = hi_filler; |
3023 *(--dp) = lo_filler; | 2125 *(--dp) = lo_filler; |
3024 } | 2126 } |
3025 row_info->channels = 2; | 2127 row_info->channels = 2; |
3026 row_info->pixel_depth = 32; | 2128 row_info->pixel_depth = 32; |
3027 row_info->rowbytes = row_width * 4; | 2129 row_info->rowbytes = row_width * 4; |
3028 } | 2130 } |
3029 } | 2131 } |
3030 #endif | |
3031 } /* COLOR_TYPE == GRAY */ | 2132 } /* COLOR_TYPE == GRAY */ |
3032 else if (row_info->color_type == PNG_COLOR_TYPE_RGB) | 2133 else if (row_info->color_type == PNG_COLOR_TYPE_RGB) |
3033 { | 2134 { |
3034 if (row_info->bit_depth == 8) | 2135 if (row_info->bit_depth == 8) |
3035 { | 2136 { |
| 2137 /* This changes the data from RGB to RGBX */ |
3036 if (flags & PNG_FLAG_FILLER_AFTER) | 2138 if (flags & PNG_FLAG_FILLER_AFTER) |
3037 { | 2139 { |
3038 /* This changes the data from RGB to RGBX */ | |
3039 png_bytep sp = row + (png_size_t)row_width * 3; | 2140 png_bytep sp = row + (png_size_t)row_width * 3; |
3040 png_bytep dp = sp + (png_size_t)row_width; | 2141 png_bytep dp = sp + (png_size_t)row_width; |
3041 for (i = 1; i < row_width; i++) | 2142 for (i = 1; i < row_width; i++) |
3042 { | 2143 { |
3043 *(--dp) = lo_filler; | 2144 *(--dp) = lo_filler; |
3044 *(--dp) = *(--sp); | 2145 *(--dp) = *(--sp); |
3045 *(--dp) = *(--sp); | 2146 *(--dp) = *(--sp); |
3046 *(--dp) = *(--sp); | 2147 *(--dp) = *(--sp); |
3047 } | 2148 } |
3048 *(--dp) = lo_filler; | 2149 *(--dp) = lo_filler; |
3049 row_info->channels = 4; | 2150 row_info->channels = 4; |
3050 row_info->pixel_depth = 32; | 2151 row_info->pixel_depth = 32; |
3051 row_info->rowbytes = row_width * 4; | 2152 row_info->rowbytes = row_width * 4; |
3052 } | 2153 } |
3053 | 2154 /* This changes the data from RGB to XRGB */ |
3054 else | 2155 else |
3055 { | 2156 { |
3056 /* This changes the data from RGB to XRGB */ | |
3057 png_bytep sp = row + (png_size_t)row_width * 3; | 2157 png_bytep sp = row + (png_size_t)row_width * 3; |
3058 png_bytep dp = sp + (png_size_t)row_width; | 2158 png_bytep dp = sp + (png_size_t)row_width; |
3059 for (i = 0; i < row_width; i++) | 2159 for (i = 0; i < row_width; i++) |
3060 { | 2160 { |
3061 *(--dp) = *(--sp); | 2161 *(--dp) = *(--sp); |
3062 *(--dp) = *(--sp); | 2162 *(--dp) = *(--sp); |
3063 *(--dp) = *(--sp); | 2163 *(--dp) = *(--sp); |
3064 *(--dp) = lo_filler; | 2164 *(--dp) = lo_filler; |
3065 } | 2165 } |
3066 row_info->channels = 4; | 2166 row_info->channels = 4; |
3067 row_info->pixel_depth = 32; | 2167 row_info->pixel_depth = 32; |
3068 row_info->rowbytes = row_width * 4; | 2168 row_info->rowbytes = row_width * 4; |
3069 } | 2169 } |
3070 } | 2170 } |
3071 | |
3072 #ifdef PNG_READ_16BIT_SUPPORTED | |
3073 else if (row_info->bit_depth == 16) | 2171 else if (row_info->bit_depth == 16) |
3074 { | 2172 { |
| 2173 /* This changes the data from RRGGBB to RRGGBBXX */ |
3075 if (flags & PNG_FLAG_FILLER_AFTER) | 2174 if (flags & PNG_FLAG_FILLER_AFTER) |
3076 { | 2175 { |
3077 /* This changes the data from RRGGBB to RRGGBBXX */ | |
3078 png_bytep sp = row + (png_size_t)row_width * 6; | 2176 png_bytep sp = row + (png_size_t)row_width * 6; |
3079 png_bytep dp = sp + (png_size_t)row_width * 2; | 2177 png_bytep dp = sp + (png_size_t)row_width * 2; |
3080 for (i = 1; i < row_width; i++) | 2178 for (i = 1; i < row_width; i++) |
3081 { | 2179 { |
3082 *(--dp) = hi_filler; | 2180 *(--dp) = hi_filler; |
3083 *(--dp) = lo_filler; | 2181 *(--dp) = lo_filler; |
3084 *(--dp) = *(--sp); | 2182 *(--dp) = *(--sp); |
3085 *(--dp) = *(--sp); | 2183 *(--dp) = *(--sp); |
3086 *(--dp) = *(--sp); | 2184 *(--dp) = *(--sp); |
3087 *(--dp) = *(--sp); | 2185 *(--dp) = *(--sp); |
3088 *(--dp) = *(--sp); | 2186 *(--dp) = *(--sp); |
3089 *(--dp) = *(--sp); | 2187 *(--dp) = *(--sp); |
3090 } | 2188 } |
3091 *(--dp) = hi_filler; | 2189 *(--dp) = hi_filler; |
3092 *(--dp) = lo_filler; | 2190 *(--dp) = lo_filler; |
3093 row_info->channels = 4; | 2191 row_info->channels = 4; |
3094 row_info->pixel_depth = 64; | 2192 row_info->pixel_depth = 64; |
3095 row_info->rowbytes = row_width * 8; | 2193 row_info->rowbytes = row_width * 8; |
3096 } | 2194 } |
3097 | 2195 /* This changes the data from RRGGBB to XXRRGGBB */ |
3098 else | 2196 else |
3099 { | 2197 { |
3100 /* This changes the data from RRGGBB to XXRRGGBB */ | |
3101 png_bytep sp = row + (png_size_t)row_width * 6; | 2198 png_bytep sp = row + (png_size_t)row_width * 6; |
3102 png_bytep dp = sp + (png_size_t)row_width * 2; | 2199 png_bytep dp = sp + (png_size_t)row_width * 2; |
3103 for (i = 0; i < row_width; i++) | 2200 for (i = 0; i < row_width; i++) |
3104 { | 2201 { |
3105 *(--dp) = *(--sp); | 2202 *(--dp) = *(--sp); |
3106 *(--dp) = *(--sp); | 2203 *(--dp) = *(--sp); |
3107 *(--dp) = *(--sp); | 2204 *(--dp) = *(--sp); |
3108 *(--dp) = *(--sp); | 2205 *(--dp) = *(--sp); |
3109 *(--dp) = *(--sp); | 2206 *(--dp) = *(--sp); |
3110 *(--dp) = *(--sp); | 2207 *(--dp) = *(--sp); |
3111 *(--dp) = hi_filler; | 2208 *(--dp) = hi_filler; |
3112 *(--dp) = lo_filler; | 2209 *(--dp) = lo_filler; |
3113 } | 2210 } |
3114 | |
3115 row_info->channels = 4; | 2211 row_info->channels = 4; |
3116 row_info->pixel_depth = 64; | 2212 row_info->pixel_depth = 64; |
3117 row_info->rowbytes = row_width * 8; | 2213 row_info->rowbytes = row_width * 8; |
3118 } | 2214 } |
3119 } | 2215 } |
3120 #endif | |
3121 } /* COLOR_TYPE == RGB */ | 2216 } /* COLOR_TYPE == RGB */ |
3122 } | 2217 } |
3123 #endif | 2218 #endif |
3124 | 2219 |
3125 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED | 2220 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED |
3126 /* Expand grayscale files to RGB, with or without alpha */ | 2221 /* Expand grayscale files to RGB, with or without alpha */ |
3127 void /* PRIVATE */ | 2222 void /* PRIVATE */ |
3128 png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) | 2223 png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) |
3129 { | 2224 { |
3130 png_uint_32 i; | 2225 png_uint_32 i; |
3131 png_uint_32 row_width = row_info->width; | 2226 png_uint_32 row_width = row_info->width; |
3132 | 2227 |
3133 png_debug(1, "in png_do_gray_to_rgb"); | 2228 png_debug(1, "in png_do_gray_to_rgb"); |
3134 | 2229 |
3135 if (row_info->bit_depth >= 8 && | 2230 if (row_info->bit_depth >= 8 && |
3136 !(row_info->color_type & PNG_COLOR_MASK_COLOR)) | 2231 #ifdef PNG_USELESS_TESTS_SUPPORTED |
| 2232 row != NULL && row_info != NULL && |
| 2233 #endif |
| 2234 !(row_info->color_type & PNG_COLOR_MASK_COLOR)) |
3137 { | 2235 { |
3138 if (row_info->color_type == PNG_COLOR_TYPE_GRAY) | 2236 if (row_info->color_type == PNG_COLOR_TYPE_GRAY) |
3139 { | 2237 { |
3140 if (row_info->bit_depth == 8) | 2238 if (row_info->bit_depth == 8) |
3141 { | 2239 { |
3142 /* This changes G to RGB */ | |
3143 png_bytep sp = row + (png_size_t)row_width - 1; | 2240 png_bytep sp = row + (png_size_t)row_width - 1; |
3144 png_bytep dp = sp + (png_size_t)row_width * 2; | 2241 png_bytep dp = sp + (png_size_t)row_width * 2; |
3145 for (i = 0; i < row_width; i++) | 2242 for (i = 0; i < row_width; i++) |
3146 { | 2243 { |
3147 *(dp--) = *sp; | 2244 *(dp--) = *sp; |
3148 *(dp--) = *sp; | 2245 *(dp--) = *sp; |
3149 *(dp--) = *(sp--); | 2246 *(dp--) = *(sp--); |
3150 } | 2247 } |
3151 } | 2248 } |
3152 | |
3153 else | 2249 else |
3154 { | 2250 { |
3155 /* This changes GG to RRGGBB */ | |
3156 png_bytep sp = row + (png_size_t)row_width * 2 - 1; | 2251 png_bytep sp = row + (png_size_t)row_width * 2 - 1; |
3157 png_bytep dp = sp + (png_size_t)row_width * 4; | 2252 png_bytep dp = sp + (png_size_t)row_width * 4; |
3158 for (i = 0; i < row_width; i++) | 2253 for (i = 0; i < row_width; i++) |
3159 { | 2254 { |
3160 *(dp--) = *sp; | 2255 *(dp--) = *sp; |
3161 *(dp--) = *(sp - 1); | 2256 *(dp--) = *(sp - 1); |
3162 *(dp--) = *sp; | 2257 *(dp--) = *sp; |
3163 *(dp--) = *(sp - 1); | 2258 *(dp--) = *(sp - 1); |
3164 *(dp--) = *(sp--); | 2259 *(dp--) = *(sp--); |
3165 *(dp--) = *(sp--); | 2260 *(dp--) = *(sp--); |
3166 } | 2261 } |
3167 } | 2262 } |
3168 } | 2263 } |
3169 | |
3170 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) | 2264 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) |
3171 { | 2265 { |
3172 if (row_info->bit_depth == 8) | 2266 if (row_info->bit_depth == 8) |
3173 { | 2267 { |
3174 /* This changes GA to RGBA */ | |
3175 png_bytep sp = row + (png_size_t)row_width * 2 - 1; | 2268 png_bytep sp = row + (png_size_t)row_width * 2 - 1; |
3176 png_bytep dp = sp + (png_size_t)row_width * 2; | 2269 png_bytep dp = sp + (png_size_t)row_width * 2; |
3177 for (i = 0; i < row_width; i++) | 2270 for (i = 0; i < row_width; i++) |
3178 { | 2271 { |
3179 *(dp--) = *(sp--); | 2272 *(dp--) = *(sp--); |
3180 *(dp--) = *sp; | 2273 *(dp--) = *sp; |
3181 *(dp--) = *sp; | 2274 *(dp--) = *sp; |
3182 *(dp--) = *(sp--); | 2275 *(dp--) = *(sp--); |
3183 } | 2276 } |
3184 } | 2277 } |
3185 | |
3186 else | 2278 else |
3187 { | 2279 { |
3188 /* This changes GGAA to RRGGBBAA */ | |
3189 png_bytep sp = row + (png_size_t)row_width * 4 - 1; | 2280 png_bytep sp = row + (png_size_t)row_width * 4 - 1; |
3190 png_bytep dp = sp + (png_size_t)row_width * 4; | 2281 png_bytep dp = sp + (png_size_t)row_width * 4; |
3191 for (i = 0; i < row_width; i++) | 2282 for (i = 0; i < row_width; i++) |
3192 { | 2283 { |
3193 *(dp--) = *(sp--); | 2284 *(dp--) = *(sp--); |
3194 *(dp--) = *(sp--); | 2285 *(dp--) = *(sp--); |
3195 *(dp--) = *sp; | 2286 *(dp--) = *sp; |
3196 *(dp--) = *(sp - 1); | 2287 *(dp--) = *(sp - 1); |
3197 *(dp--) = *sp; | 2288 *(dp--) = *sp; |
3198 *(dp--) = *(sp - 1); | 2289 *(dp--) = *(sp - 1); |
3199 *(dp--) = *(sp--); | 2290 *(dp--) = *(sp--); |
3200 *(dp--) = *(sp--); | 2291 *(dp--) = *(sp--); |
3201 } | 2292 } |
3202 } | 2293 } |
3203 } | 2294 } |
3204 row_info->channels = (png_byte)(row_info->channels + 2); | 2295 row_info->channels += (png_byte)2; |
3205 row_info->color_type |= PNG_COLOR_MASK_COLOR; | 2296 row_info->color_type |= PNG_COLOR_MASK_COLOR; |
3206 row_info->pixel_depth = (png_byte)(row_info->channels * | 2297 row_info->pixel_depth = (png_byte)(row_info->channels * |
3207 row_info->bit_depth); | 2298 row_info->bit_depth); |
3208 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); | 2299 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); |
3209 } | 2300 } |
3210 } | 2301 } |
3211 #endif | 2302 #endif |
3212 | 2303 |
3213 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED | 2304 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED |
3214 /* Reduce RGB files to grayscale, with or without alpha | 2305 /* Reduce RGB files to grayscale, with or without alpha |
3215 * using the equation given in Poynton's ColorFAQ of 1998-01-04 at | 2306 * using the equation given in Poynton's ColorFAQ at |
3216 * <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008 but | 2307 * <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008) |
3217 * versions dated 1998 through November 2002 have been archived at | 2308 * New link: |
3218 * http://web.archive.org/web/20000816232553/http://www.inforamp.net/ | 2309 * <http://www.poynton.com/notes/colour_and_gamma/> |
3219 * ~poynton/notes/colour_and_gamma/ColorFAQ.txt ) | |
3220 * Charles Poynton poynton at poynton.com | 2310 * Charles Poynton poynton at poynton.com |
3221 * | 2311 * |
3222 * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B | 2312 * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B |
3223 * | 2313 * |
| 2314 * We approximate this with |
| 2315 * |
| 2316 * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B |
| 2317 * |
3224 * which can be expressed with integers as | 2318 * which can be expressed with integers as |
3225 * | 2319 * |
3226 * Y = (6969 * R + 23434 * G + 2365 * B)/32768 | 2320 * Y = (6969 * R + 23434 * G + 2365 * B)/32768 |
3227 * | 2321 * |
3228 * Poynton's current link (as of January 2003 through July 2011): | 2322 * The calculation is to be done in a linear colorspace. |
3229 * <http://www.poynton.com/notes/colour_and_gamma/> | 2323 * |
3230 * has changed the numbers slightly: | 2324 * Other integer coefficents can be used via png_set_rgb_to_gray(). |
3231 * | |
3232 * Y = 0.2126*R + 0.7152*G + 0.0722*B | |
3233 * | |
3234 * which can be expressed with integers as | |
3235 * | |
3236 * Y = (6966 * R + 23436 * G + 2366 * B)/32768 | |
3237 * | |
3238 * Historically, however, libpng uses numbers derived from the ITU-R Rec 709 | |
3239 * end point chromaticities and the D65 white point. Depending on the | |
3240 * precision used for the D65 white point this produces a variety of different | |
3241 * numbers, however if the four decimal place value used in ITU-R Rec 709 is | |
3242 * used (0.3127,0.3290) the Y calculation would be: | |
3243 * | |
3244 * Y = (6968 * R + 23435 * G + 2366 * B)/32768 | |
3245 * | |
3246 * While this is correct the rounding results in an overflow for white, because | |
3247 * the sum of the rounded coefficients is 32769, not 32768. Consequently | |
3248 * libpng uses, instead, the closest non-overflowing approximation: | |
3249 * | |
3250 * Y = (6968 * R + 23434 * G + 2366 * B)/32768 | |
3251 * | |
3252 * Starting with libpng-1.5.5, if the image being converted has a cHRM chunk | |
3253 * (including an sRGB chunk) then the chromaticities are used to calculate the | |
3254 * coefficients. See the chunk handling in pngrutil.c for more information. | |
3255 * | |
3256 * In all cases the calculation is to be done in a linear colorspace. If no | |
3257 * gamma information is available to correct the encoding of the original RGB | |
3258 * values this results in an implicit assumption that the original PNG RGB | |
3259 * values were linear. | |
3260 * | |
3261 * Other integer coefficents can be used via png_set_rgb_to_gray(). Because | |
3262 * the API takes just red and green coefficients the blue coefficient is | |
3263 * calculated to make the sum 32768. This will result in different rounding | |
3264 * to that used above. | |
3265 */ | 2325 */ |
3266 int /* PRIVATE */ | 2326 int /* PRIVATE */ |
3267 png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row) | 2327 png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) |
3268 | 2328 |
3269 { | 2329 { |
| 2330 png_uint_32 i; |
| 2331 |
| 2332 png_uint_32 row_width = row_info->width; |
3270 int rgb_error = 0; | 2333 int rgb_error = 0; |
3271 | 2334 |
3272 png_debug(1, "in png_do_rgb_to_gray"); | 2335 png_debug(1, "in png_do_rgb_to_gray"); |
3273 | 2336 |
3274 if (!(row_info->color_type & PNG_COLOR_MASK_PALETTE) && | 2337 if ( |
3275 (row_info->color_type & PNG_COLOR_MASK_COLOR)) | 2338 #ifdef PNG_USELESS_TESTS_SUPPORTED |
| 2339 row != NULL && row_info != NULL && |
| 2340 #endif |
| 2341 (row_info->color_type & PNG_COLOR_MASK_COLOR)) |
3276 { | 2342 { |
3277 PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; | 2343 png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; |
3278 PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; | 2344 png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; |
3279 PNG_CONST png_uint_32 bc = 32768 - rc - gc; | 2345 png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff; |
3280 PNG_CONST png_uint_32 row_width = row_info->width; | 2346 |
3281 PNG_CONST int have_alpha = | 2347 if (row_info->color_type == PNG_COLOR_TYPE_RGB) |
3282 (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0; | |
3283 | |
3284 if (row_info->bit_depth == 8) | |
3285 { | 2348 { |
3286 #ifdef PNG_READ_GAMMA_SUPPORTED | 2349 if (row_info->bit_depth == 8) |
3287 /* Notice that gamma to/from 1 are not necessarily inverses (if | 2350 { |
3288 * there is an overall gamma correction). Prior to 1.5.5 this code | 2351 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) |
3289 * checked the linearized values for equality; this doesn't match | 2352 if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) |
3290 * the documentation, the original values must be checked. | 2353 { |
3291 */ | 2354 png_bytep sp = row; |
3292 if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) | 2355 png_bytep dp = row; |
3293 { | 2356 |
3294 png_bytep sp = row; | 2357 for (i = 0; i < row_width; i++) |
3295 png_bytep dp = row; | 2358 { |
3296 png_uint_32 i; | 2359 png_byte red = png_ptr->gamma_to_1[*(sp++)]; |
3297 | 2360 png_byte green = png_ptr->gamma_to_1[*(sp++)]; |
3298 for (i = 0; i < row_width; i++) | 2361 png_byte blue = png_ptr->gamma_to_1[*(sp++)]; |
3299 { | 2362 if (red != green || red != blue) |
3300 png_byte red = *(sp++); | 2363 { |
3301 png_byte green = *(sp++); | 2364 rgb_error |= 1; |
3302 png_byte blue = *(sp++); | 2365 *(dp++) = png_ptr->gamma_from_1[ |
3303 | 2366 (rc*red + gc*green + bc*blue)>>15]; |
3304 if (red != green || red != blue) | 2367 } |
3305 { | 2368 else |
3306 red = png_ptr->gamma_to_1[red]; | 2369 *(dp++) = *(sp - 1); |
3307 green = png_ptr->gamma_to_1[green]; | 2370 } |
3308 blue = png_ptr->gamma_to_1[blue]; | 2371 } |
3309 | 2372 else |
3310 rgb_error |= 1; | 2373 #endif |
3311 *(dp++) = png_ptr->gamma_from_1[ | 2374 { |
3312 (rc*red + gc*green + bc*blue + 16384)>>15]; | 2375 png_bytep sp = row; |
3313 } | 2376 png_bytep dp = row; |
3314 | 2377 for (i = 0; i < row_width; i++) |
3315 else | 2378 { |
3316 { | 2379 png_byte red = *(sp++); |
3317 /* If there is no overall correction the table will not be | 2380 png_byte green = *(sp++); |
3318 * set. | 2381 png_byte blue = *(sp++); |
3319 */ | 2382 if (red != green || red != blue) |
3320 if (png_ptr->gamma_table != NULL) | 2383 { |
3321 red = png_ptr->gamma_table[red]; | 2384 rgb_error |= 1; |
3322 | 2385 *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); |
3323 *(dp++) = red; | 2386 } |
3324 } | 2387 else |
3325 | 2388 *(dp++) = *(sp - 1); |
3326 if (have_alpha) | 2389 } |
| 2390 } |
| 2391 } |
| 2392 |
| 2393 else /* RGB bit_depth == 16 */ |
| 2394 { |
| 2395 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) |
| 2396 if (png_ptr->gamma_16_to_1 != NULL && |
| 2397 png_ptr->gamma_16_from_1 != NULL) |
| 2398 { |
| 2399 png_bytep sp = row; |
| 2400 png_bytep dp = row; |
| 2401 for (i = 0; i < row_width; i++) |
| 2402 { |
| 2403 png_uint_16 red, green, blue, w; |
| 2404 |
| 2405 red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; |
| 2406 green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; |
| 2407 blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; |
| 2408 |
| 2409 if (red == green && red == blue) |
| 2410 w = red; |
| 2411 else |
| 2412 { |
| 2413 png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >> |
| 2414 png_ptr->gamma_shift][red>>8]; |
| 2415 png_uint_16 green_1 = |
| 2416 png_ptr->gamma_16_to_1[(green&0xff) >> |
| 2417 png_ptr->gamma_shift][green>>8]; |
| 2418 png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >> |
| 2419 png_ptr->gamma_shift][blue>>8]; |
| 2420 png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 |
| 2421 + bc*blue_1)>>15); |
| 2422 w = png_ptr->gamma_16_from_1[(gray16&0xff) >> |
| 2423 png_ptr->gamma_shift][gray16 >> 8]; |
| 2424 rgb_error |= 1; |
| 2425 } |
| 2426 |
| 2427 *(dp++) = (png_byte)((w>>8) & 0xff); |
| 2428 *(dp++) = (png_byte)(w & 0xff); |
| 2429 } |
| 2430 } |
| 2431 else |
| 2432 #endif |
| 2433 { |
| 2434 png_bytep sp = row; |
| 2435 png_bytep dp = row; |
| 2436 for (i = 0; i < row_width; i++) |
| 2437 { |
| 2438 png_uint_16 red, green, blue, gray16; |
| 2439 |
| 2440 red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; |
| 2441 green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; |
| 2442 blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; |
| 2443 |
| 2444 if (red != green || red != blue) |
| 2445 rgb_error |= 1; |
| 2446 gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15); |
| 2447 *(dp++) = (png_byte)((gray16>>8) & 0xff); |
| 2448 *(dp++) = (png_byte)(gray16 & 0xff); |
| 2449 } |
| 2450 } |
| 2451 } |
| 2452 } |
| 2453 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) |
| 2454 { |
| 2455 if (row_info->bit_depth == 8) |
| 2456 { |
| 2457 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) |
| 2458 if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) |
| 2459 { |
| 2460 png_bytep sp = row; |
| 2461 png_bytep dp = row; |
| 2462 for (i = 0; i < row_width; i++) |
| 2463 { |
| 2464 png_byte red = png_ptr->gamma_to_1[*(sp++)]; |
| 2465 png_byte green = png_ptr->gamma_to_1[*(sp++)]; |
| 2466 png_byte blue = png_ptr->gamma_to_1[*(sp++)]; |
| 2467 if (red != green || red != blue) |
| 2468 rgb_error |= 1; |
| 2469 *(dp++) = png_ptr->gamma_from_1 |
| 2470 [(rc*red + gc*green + bc*blue)>>15]; |
| 2471 *(dp++) = *(sp++); /* alpha */ |
| 2472 } |
| 2473 } |
| 2474 else |
| 2475 #endif |
| 2476 { |
| 2477 png_bytep sp = row; |
| 2478 png_bytep dp = row; |
| 2479 for (i = 0; i < row_width; i++) |
| 2480 { |
| 2481 png_byte red = *(sp++); |
| 2482 png_byte green = *(sp++); |
| 2483 png_byte blue = *(sp++); |
| 2484 if (red != green || red != blue) |
| 2485 rgb_error |= 1; |
| 2486 *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); |
| 2487 *(dp++) = *(sp++); /* alpha */ |
| 2488 } |
| 2489 } |
| 2490 } |
| 2491 else /* RGBA bit_depth == 16 */ |
| 2492 { |
| 2493 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) |
| 2494 if (png_ptr->gamma_16_to_1 != NULL && |
| 2495 png_ptr->gamma_16_from_1 != NULL) |
| 2496 { |
| 2497 png_bytep sp = row; |
| 2498 png_bytep dp = row; |
| 2499 for (i = 0; i < row_width; i++) |
| 2500 { |
| 2501 png_uint_16 red, green, blue, w; |
| 2502 |
| 2503 red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; |
| 2504 green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; |
| 2505 blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; |
| 2506 |
| 2507 if (red == green && red == blue) |
| 2508 w = red; |
| 2509 else |
| 2510 { |
| 2511 png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >> |
| 2512 png_ptr->gamma_shift][red>>8]; |
| 2513 png_uint_16 green_1 = |
| 2514 png_ptr->gamma_16_to_1[(green&0xff) >> |
| 2515 png_ptr->gamma_shift][green>>8]; |
| 2516 png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >> |
| 2517 png_ptr->gamma_shift][blue>>8]; |
| 2518 png_uint_16 gray16 = (png_uint_16)((rc * red_1 |
| 2519 + gc * green_1 + bc * blue_1)>>15); |
| 2520 w = png_ptr->gamma_16_from_1[(gray16&0xff) >> |
| 2521 png_ptr->gamma_shift][gray16 >> 8]; |
| 2522 rgb_error |= 1; |
| 2523 } |
| 2524 |
| 2525 *(dp++) = (png_byte)((w>>8) & 0xff); |
| 2526 *(dp++) = (png_byte)(w & 0xff); |
| 2527 *(dp++) = *(sp++); /* alpha */ |
3327 *(dp++) = *(sp++); | 2528 *(dp++) = *(sp++); |
3328 } | 2529 } |
3329 } | 2530 } |
3330 else | 2531 else |
3331 #endif | 2532 #endif |
3332 { | 2533 { |
3333 png_bytep sp = row; | 2534 png_bytep sp = row; |
3334 png_bytep dp = row; | 2535 png_bytep dp = row; |
3335 png_uint_32 i; | 2536 for (i = 0; i < row_width; i++) |
3336 | 2537 { |
3337 for (i = 0; i < row_width; i++) | 2538 png_uint_16 red, green, blue, gray16; |
3338 { | 2539 red = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2; |
3339 png_byte red = *(sp++); | 2540 green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2; |
3340 png_byte green = *(sp++); | 2541 blue = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2; |
3341 png_byte blue = *(sp++); | 2542 if (red != green || red != blue) |
3342 | 2543 rgb_error |= 1; |
3343 if (red != green || red != blue) | 2544 gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15); |
3344 { | 2545 *(dp++) = (png_byte)((gray16>>8) & 0xff); |
3345 rgb_error |= 1; | 2546 *(dp++) = (png_byte)(gray16 & 0xff); |
3346 /* NOTE: this is the historical approach which simply | 2547 *(dp++) = *(sp++); /* alpha */ |
3347 * truncates the results. | |
3348 */ | |
3349 *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); | |
3350 } | |
3351 | |
3352 else | |
3353 *(dp++) = red; | |
3354 | |
3355 if (have_alpha) | |
3356 *(dp++) = *(sp++); | 2548 *(dp++) = *(sp++); |
| 2549 } |
3357 } | 2550 } |
3358 } | 2551 } |
3359 } | 2552 } |
3360 | 2553 row_info->channels -= (png_byte)2; |
3361 else /* RGB bit_depth == 16 */ | 2554 row_info->color_type &= ~PNG_COLOR_MASK_COLOR; |
3362 { | |
3363 #ifdef PNG_READ_GAMMA_SUPPORTED | |
3364 if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL) | |
3365 { | |
3366 png_bytep sp = row; | |
3367 png_bytep dp = row; | |
3368 png_uint_32 i; | |
3369 | |
3370 for (i = 0; i < row_width; i++) | |
3371 { | |
3372 png_uint_16 red, green, blue, w; | |
3373 | |
3374 red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; | |
3375 green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; | |
3376 blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; | |
3377 | |
3378 if (red == green && red == blue) | |
3379 { | |
3380 if (png_ptr->gamma_16_table != NULL) | |
3381 w = png_ptr->gamma_16_table[(red&0xff) | |
3382 >> png_ptr->gamma_shift][red>>8]; | |
3383 | |
3384 else | |
3385 w = red; | |
3386 } | |
3387 | |
3388 else | |
3389 { | |
3390 png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) | |
3391 >> png_ptr->gamma_shift][red>>8]; | |
3392 png_uint_16 green_1 = | |
3393 png_ptr->gamma_16_to_1[(green&0xff) >> | |
3394 png_ptr->gamma_shift][green>>8]; | |
3395 png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) | |
3396 >> png_ptr->gamma_shift][blue>>8]; | |
3397 png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 | |
3398 + bc*blue_1 + 16384)>>15); | |
3399 w = png_ptr->gamma_16_from_1[(gray16&0xff) >> | |
3400 png_ptr->gamma_shift][gray16 >> 8]; | |
3401 rgb_error |= 1; | |
3402 } | |
3403 | |
3404 *(dp++) = (png_byte)((w>>8) & 0xff); | |
3405 *(dp++) = (png_byte)(w & 0xff); | |
3406 | |
3407 if (have_alpha) | |
3408 { | |
3409 *(dp++) = *(sp++); | |
3410 *(dp++) = *(sp++); | |
3411 } | |
3412 } | |
3413 } | |
3414 else | |
3415 #endif | |
3416 { | |
3417 png_bytep sp = row; | |
3418 png_bytep dp = row; | |
3419 png_uint_32 i; | |
3420 | |
3421 for (i = 0; i < row_width; i++) | |
3422 { | |
3423 png_uint_16 red, green, blue, gray16; | |
3424 | |
3425 red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; | |
3426 green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; | |
3427 blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; | |
3428 | |
3429 if (red != green || red != blue) | |
3430 rgb_error |= 1; | |
3431 | |
3432 /* From 1.5.5 in the 16 bit case do the accurate conversion even | |
3433 * in the 'fast' case - this is because this is where the code | |
3434 * ends up when handling linear 16 bit data. | |
3435 */ | |
3436 gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >> | |
3437 15); | |
3438 *(dp++) = (png_byte)((gray16>>8) & 0xff); | |
3439 *(dp++) = (png_byte)(gray16 & 0xff); | |
3440 | |
3441 if (have_alpha) | |
3442 { | |
3443 *(dp++) = *(sp++); | |
3444 *(dp++) = *(sp++); | |
3445 } | |
3446 } | |
3447 } | |
3448 } | |
3449 | |
3450 row_info->channels = (png_byte)(row_info->channels - 2); | |
3451 row_info->color_type = (png_byte)(row_info->color_type & | |
3452 ~PNG_COLOR_MASK_COLOR); | |
3453 row_info->pixel_depth = (png_byte)(row_info->channels * | 2555 row_info->pixel_depth = (png_byte)(row_info->channels * |
3454 row_info->bit_depth); | 2556 row_info->bit_depth); |
3455 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); | 2557 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); |
3456 } | 2558 } |
3457 return rgb_error; | 2559 return rgb_error; |
3458 } | 2560 } |
3459 #endif | 2561 #endif |
3460 #endif /* PNG_READ_TRANSFORMS_SUPPORTED */ | 2562 |
3461 | |
3462 #ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED | |
3463 /* Build a grayscale palette. Palette is assumed to be 1 << bit_depth | 2563 /* Build a grayscale palette. Palette is assumed to be 1 << bit_depth |
3464 * large of png_color. This lets grayscale images be treated as | 2564 * large of png_color. This lets grayscale images be treated as |
3465 * paletted. Most useful for gamma correction and simplification | 2565 * paletted. Most useful for gamma correction and simplification |
3466 * of code. This API is not used internally. | 2566 * of code. |
3467 */ | 2567 */ |
3468 void PNGAPI | 2568 void PNGAPI |
3469 png_build_grayscale_palette(int bit_depth, png_colorp palette) | 2569 png_build_grayscale_palette(int bit_depth, png_colorp palette) |
3470 { | 2570 { |
3471 int num_palette; | 2571 int num_palette; |
3472 int color_inc; | 2572 int color_inc; |
3473 int i; | 2573 int i; |
3474 int v; | 2574 int v; |
3475 | 2575 |
3476 png_debug(1, "in png_do_build_grayscale_palette"); | 2576 png_debug(1, "in png_do_build_grayscale_palette"); |
(...skipping 29 matching lines...) Expand all Loading... |
3506 break; | 2606 break; |
3507 } | 2607 } |
3508 | 2608 |
3509 for (i = 0, v = 0; i < num_palette; i++, v += color_inc) | 2609 for (i = 0, v = 0; i < num_palette; i++, v += color_inc) |
3510 { | 2610 { |
3511 palette[i].red = (png_byte)v; | 2611 palette[i].red = (png_byte)v; |
3512 palette[i].green = (png_byte)v; | 2612 palette[i].green = (png_byte)v; |
3513 palette[i].blue = (png_byte)v; | 2613 palette[i].blue = (png_byte)v; |
3514 } | 2614 } |
3515 } | 2615 } |
3516 #endif | 2616 |
3517 | 2617 /* This function is currently unused. Do we really need it? */ |
3518 | 2618 #if defined(PNG_READ_DITHER_SUPPORTED) && \ |
3519 #ifdef PNG_READ_TRANSFORMS_SUPPORTED | 2619 defined(PNG_CORRECT_PALETTE_SUPPORTED) |
3520 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ | 2620 void /* PRIVATE */ |
3521 defined(PNG_READ_ALPHA_MODE_SUPPORTED) | 2621 png_correct_palette(png_structp png_ptr, png_colorp palette, |
| 2622 int num_palette) |
| 2623 { |
| 2624 png_debug(1, "in png_correct_palette"); |
| 2625 |
| 2626 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ |
| 2627 defined(PNG_READ_GAMMA_SUPPORTED) && \ |
| 2628 defined(PNG_FLOATING_POINT_SUPPORTED) |
| 2629 if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND)) |
| 2630 { |
| 2631 png_color back, back_1; |
| 2632 |
| 2633 if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE) |
| 2634 { |
| 2635 back.red = png_ptr->gamma_table[png_ptr->background.red]; |
| 2636 back.green = png_ptr->gamma_table[png_ptr->background.green]; |
| 2637 back.blue = png_ptr->gamma_table[png_ptr->background.blue]; |
| 2638 |
| 2639 back_1.red = png_ptr->gamma_to_1[png_ptr->background.red]; |
| 2640 back_1.green = png_ptr->gamma_to_1[png_ptr->background.green]; |
| 2641 back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue]; |
| 2642 } |
| 2643 else |
| 2644 { |
| 2645 double g; |
| 2646 |
| 2647 g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma); |
| 2648 |
| 2649 if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN |
| 2650 || fabs(g - 1.0) < PNG_GAMMA_THRESHOLD) |
| 2651 { |
| 2652 back.red = png_ptr->background.red; |
| 2653 back.green = png_ptr->background.green; |
| 2654 back.blue = png_ptr->background.blue; |
| 2655 } |
| 2656 else |
| 2657 { |
| 2658 back.red = |
| 2659 (png_byte)(pow((double)png_ptr->background.red/255, g) * |
| 2660 255.0 + 0.5); |
| 2661 back.green = |
| 2662 (png_byte)(pow((double)png_ptr->background.green/255, g) * |
| 2663 255.0 + 0.5); |
| 2664 back.blue = |
| 2665 (png_byte)(pow((double)png_ptr->background.blue/255, g) * |
| 2666 255.0 + 0.5); |
| 2667 } |
| 2668 |
| 2669 g = 1.0 / png_ptr->background_gamma; |
| 2670 |
| 2671 back_1.red = |
| 2672 (png_byte)(pow((double)png_ptr->background.red/255, g) * |
| 2673 255.0 + 0.5); |
| 2674 back_1.green = |
| 2675 (png_byte)(pow((double)png_ptr->background.green/255, g) * |
| 2676 255.0 + 0.5); |
| 2677 back_1.blue = |
| 2678 (png_byte)(pow((double)png_ptr->background.blue/255, g) * |
| 2679 255.0 + 0.5); |
| 2680 } |
| 2681 |
| 2682 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
| 2683 { |
| 2684 png_uint_32 i; |
| 2685 |
| 2686 for (i = 0; i < (png_uint_32)num_palette; i++) |
| 2687 { |
| 2688 if (i < png_ptr->num_trans && png_ptr->trans[i] == 0) |
| 2689 { |
| 2690 palette[i] = back; |
| 2691 } |
| 2692 else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff) |
| 2693 { |
| 2694 png_byte v, w; |
| 2695 |
| 2696 v = png_ptr->gamma_to_1[png_ptr->palette[i].red]; |
| 2697 png_composite(w, v, png_ptr->trans[i], back_1.red); |
| 2698 palette[i].red = png_ptr->gamma_from_1[w]; |
| 2699 |
| 2700 v = png_ptr->gamma_to_1[png_ptr->palette[i].green]; |
| 2701 png_composite(w, v, png_ptr->trans[i], back_1.green); |
| 2702 palette[i].green = png_ptr->gamma_from_1[w]; |
| 2703 |
| 2704 v = png_ptr->gamma_to_1[png_ptr->palette[i].blue]; |
| 2705 png_composite(w, v, png_ptr->trans[i], back_1.blue); |
| 2706 palette[i].blue = png_ptr->gamma_from_1[w]; |
| 2707 } |
| 2708 else |
| 2709 { |
| 2710 palette[i].red = png_ptr->gamma_table[palette[i].red]; |
| 2711 palette[i].green = png_ptr->gamma_table[palette[i].green]; |
| 2712 palette[i].blue = png_ptr->gamma_table[palette[i].blue]; |
| 2713 } |
| 2714 } |
| 2715 } |
| 2716 else |
| 2717 { |
| 2718 int i; |
| 2719 |
| 2720 for (i = 0; i < num_palette; i++) |
| 2721 { |
| 2722 if (palette[i].red == (png_byte)png_ptr->trans_values.gray) |
| 2723 { |
| 2724 palette[i] = back; |
| 2725 } |
| 2726 else |
| 2727 { |
| 2728 palette[i].red = png_ptr->gamma_table[palette[i].red]; |
| 2729 palette[i].green = png_ptr->gamma_table[palette[i].green]; |
| 2730 palette[i].blue = png_ptr->gamma_table[palette[i].blue]; |
| 2731 } |
| 2732 } |
| 2733 } |
| 2734 } |
| 2735 else |
| 2736 #endif |
| 2737 #ifdef PNG_READ_GAMMA_SUPPORTED |
| 2738 if (png_ptr->transformations & PNG_GAMMA) |
| 2739 { |
| 2740 int i; |
| 2741 |
| 2742 for (i = 0; i < num_palette; i++) |
| 2743 { |
| 2744 palette[i].red = png_ptr->gamma_table[palette[i].red]; |
| 2745 palette[i].green = png_ptr->gamma_table[palette[i].green]; |
| 2746 palette[i].blue = png_ptr->gamma_table[palette[i].blue]; |
| 2747 } |
| 2748 } |
| 2749 #ifdef PNG_READ_BACKGROUND_SUPPORTED |
| 2750 else |
| 2751 #endif |
| 2752 #endif |
| 2753 #ifdef PNG_READ_BACKGROUND_SUPPORTED |
| 2754 if (png_ptr->transformations & PNG_BACKGROUND) |
| 2755 { |
| 2756 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
| 2757 { |
| 2758 png_color back; |
| 2759 |
| 2760 back.red = (png_byte)png_ptr->background.red; |
| 2761 back.green = (png_byte)png_ptr->background.green; |
| 2762 back.blue = (png_byte)png_ptr->background.blue; |
| 2763 |
| 2764 for (i = 0; i < (int)png_ptr->num_trans; i++) |
| 2765 { |
| 2766 if (png_ptr->trans[i] == 0) |
| 2767 { |
| 2768 palette[i].red = back.red; |
| 2769 palette[i].green = back.green; |
| 2770 palette[i].blue = back.blue; |
| 2771 } |
| 2772 else if (png_ptr->trans[i] != 0xff) |
| 2773 { |
| 2774 png_composite(palette[i].red, png_ptr->palette[i].red, |
| 2775 png_ptr->trans[i], back.red); |
| 2776 png_composite(palette[i].green, png_ptr->palette[i].green, |
| 2777 png_ptr->trans[i], back.green); |
| 2778 png_composite(palette[i].blue, png_ptr->palette[i].blue, |
| 2779 png_ptr->trans[i], back.blue); |
| 2780 } |
| 2781 } |
| 2782 } |
| 2783 else /* Assume grayscale palette (what else could it be?) */ |
| 2784 { |
| 2785 int i; |
| 2786 |
| 2787 for (i = 0; i < num_palette; i++) |
| 2788 { |
| 2789 if (i == (png_byte)png_ptr->trans_values.gray) |
| 2790 { |
| 2791 palette[i].red = (png_byte)png_ptr->background.red; |
| 2792 palette[i].green = (png_byte)png_ptr->background.green; |
| 2793 palette[i].blue = (png_byte)png_ptr->background.blue; |
| 2794 } |
| 2795 } |
| 2796 } |
| 2797 } |
| 2798 #endif |
| 2799 } |
| 2800 #endif |
| 2801 |
| 2802 #ifdef PNG_READ_BACKGROUND_SUPPORTED |
3522 /* Replace any alpha or transparency with the supplied background color. | 2803 /* Replace any alpha or transparency with the supplied background color. |
3523 * "background" is already in the screen gamma, while "background_1" is | 2804 * "background" is already in the screen gamma, while "background_1" is |
3524 * at a gamma of 1.0. Paletted files have already been taken care of. | 2805 * at a gamma of 1.0. Paletted files have already been taken care of. |
3525 */ | 2806 */ |
3526 void /* PRIVATE */ | 2807 void /* PRIVATE */ |
3527 png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) | 2808 png_do_background(png_row_infop row_info, png_bytep row, |
| 2809 png_color_16p trans_values, png_color_16p background |
| 2810 #ifdef PNG_READ_GAMMA_SUPPORTED |
| 2811 , png_color_16p background_1, |
| 2812 png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1, |
| 2813 png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1, |
| 2814 png_uint_16pp gamma_16_to_1, int gamma_shift |
| 2815 #endif |
| 2816 ) |
3528 { | 2817 { |
3529 #ifdef PNG_READ_GAMMA_SUPPORTED | 2818 png_bytep sp, dp; |
3530 png_const_bytep gamma_table = png_ptr->gamma_table; | |
3531 png_const_bytep gamma_from_1 = png_ptr->gamma_from_1; | |
3532 png_const_bytep gamma_to_1 = png_ptr->gamma_to_1; | |
3533 png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table; | |
3534 png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1; | |
3535 png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1; | |
3536 int gamma_shift = png_ptr->gamma_shift; | |
3537 int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; | |
3538 #endif | |
3539 | |
3540 png_bytep sp; | |
3541 png_uint_32 i; | 2819 png_uint_32 i; |
3542 png_uint_32 row_width = row_info->width; | 2820 png_uint_32 row_width=row_info->width; |
3543 int shift; | 2821 int shift; |
3544 | 2822 |
3545 png_debug(1, "in png_do_compose"); | 2823 png_debug(1, "in png_do_background"); |
3546 | 2824 |
| 2825 if (background != NULL && |
| 2826 #ifdef PNG_USELESS_TESTS_SUPPORTED |
| 2827 row != NULL && row_info != NULL && |
| 2828 #endif |
| 2829 (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) || |
| 2830 (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values))) |
3547 { | 2831 { |
3548 switch (row_info->color_type) | 2832 switch (row_info->color_type) |
3549 { | 2833 { |
3550 case PNG_COLOR_TYPE_GRAY: | 2834 case PNG_COLOR_TYPE_GRAY: |
3551 { | 2835 { |
3552 switch (row_info->bit_depth) | 2836 switch (row_info->bit_depth) |
3553 { | 2837 { |
3554 case 1: | 2838 case 1: |
3555 { | 2839 { |
3556 sp = row; | 2840 sp = row; |
3557 shift = 7; | 2841 shift = 7; |
3558 for (i = 0; i < row_width; i++) | 2842 for (i = 0; i < row_width; i++) |
3559 { | 2843 { |
3560 if ((png_uint_16)((*sp >> shift) & 0x01) | 2844 if ((png_uint_16)((*sp >> shift) & 0x01) |
3561 == png_ptr->trans_color.gray) | 2845 == trans_values->gray) |
3562 { | 2846 { |
3563 unsigned int tmp = *sp & (0x7f7f >> (7 - shift)); | 2847 *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); |
3564 tmp |= png_ptr->background.gray << shift; | 2848 *sp |= (png_byte)(background->gray << shift); |
3565 *sp = (png_byte)(tmp & 0xff); | |
3566 } | 2849 } |
3567 | |
3568 if (!shift) | 2850 if (!shift) |
3569 { | 2851 { |
3570 shift = 7; | 2852 shift = 7; |
3571 sp++; | 2853 sp++; |
3572 } | 2854 } |
3573 | |
3574 else | 2855 else |
3575 shift--; | 2856 shift--; |
3576 } | 2857 } |
3577 break; | 2858 break; |
3578 } | 2859 } |
3579 | 2860 |
3580 case 2: | 2861 case 2: |
3581 { | 2862 { |
3582 #ifdef PNG_READ_GAMMA_SUPPORTED | 2863 #ifdef PNG_READ_GAMMA_SUPPORTED |
3583 if (gamma_table != NULL) | 2864 if (gamma_table != NULL) |
3584 { | 2865 { |
3585 sp = row; | 2866 sp = row; |
3586 shift = 6; | 2867 shift = 6; |
3587 for (i = 0; i < row_width; i++) | 2868 for (i = 0; i < row_width; i++) |
3588 { | 2869 { |
3589 if ((png_uint_16)((*sp >> shift) & 0x03) | 2870 if ((png_uint_16)((*sp >> shift) & 0x03) |
3590 == png_ptr->trans_color.gray) | 2871 == trans_values->gray) |
3591 { | 2872 { |
3592 unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); | 2873 *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); |
3593 tmp |= png_ptr->background.gray << shift; | 2874 *sp |= (png_byte)(background->gray << shift); |
3594 *sp = (png_byte)(tmp & 0xff); | |
3595 } | 2875 } |
3596 | |
3597 else | 2876 else |
3598 { | 2877 { |
3599 unsigned int p = (*sp >> shift) & 0x03; | 2878 png_byte p = (png_byte)((*sp >> shift) & 0x03); |
3600 unsigned int g = (gamma_table [p | (p << 2) | | 2879 png_byte g = (png_byte)((gamma_table [p | (p << 2) | |
3601 (p << 4) | (p << 6)] >> 6) & 0x03; | 2880 (p << 4) | (p << 6)] >> 6) & 0x03); |
3602 unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); | 2881 *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); |
3603 tmp |= g << shift; | 2882 *sp |= (png_byte)(g << shift); |
3604 *sp = (png_byte)(tmp & 0xff); | |
3605 } | 2883 } |
3606 | |
3607 if (!shift) | 2884 if (!shift) |
3608 { | 2885 { |
3609 shift = 6; | 2886 shift = 6; |
3610 sp++; | 2887 sp++; |
3611 } | 2888 } |
3612 | |
3613 else | 2889 else |
3614 shift -= 2; | 2890 shift -= 2; |
3615 } | 2891 } |
3616 } | 2892 } |
3617 | |
3618 else | 2893 else |
3619 #endif | 2894 #endif |
3620 { | 2895 { |
3621 sp = row; | 2896 sp = row; |
3622 shift = 6; | 2897 shift = 6; |
3623 for (i = 0; i < row_width; i++) | 2898 for (i = 0; i < row_width; i++) |
3624 { | 2899 { |
3625 if ((png_uint_16)((*sp >> shift) & 0x03) | 2900 if ((png_uint_16)((*sp >> shift) & 0x03) |
3626 == png_ptr->trans_color.gray) | 2901 == trans_values->gray) |
3627 { | 2902 { |
3628 unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); | 2903 *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); |
3629 tmp |= png_ptr->background.gray << shift; | 2904 *sp |= (png_byte)(background->gray << shift); |
3630 *sp = (png_byte)(tmp & 0xff); | |
3631 } | 2905 } |
3632 | |
3633 if (!shift) | 2906 if (!shift) |
3634 { | 2907 { |
3635 shift = 6; | 2908 shift = 6; |
3636 sp++; | 2909 sp++; |
3637 } | 2910 } |
3638 | |
3639 else | 2911 else |
3640 shift -= 2; | 2912 shift -= 2; |
3641 } | 2913 } |
3642 } | 2914 } |
3643 break; | 2915 break; |
3644 } | 2916 } |
3645 | 2917 |
3646 case 4: | 2918 case 4: |
3647 { | 2919 { |
3648 #ifdef PNG_READ_GAMMA_SUPPORTED | 2920 #ifdef PNG_READ_GAMMA_SUPPORTED |
3649 if (gamma_table != NULL) | 2921 if (gamma_table != NULL) |
3650 { | 2922 { |
3651 sp = row; | 2923 sp = row; |
3652 shift = 4; | 2924 shift = 4; |
3653 for (i = 0; i < row_width; i++) | 2925 for (i = 0; i < row_width; i++) |
3654 { | 2926 { |
3655 if ((png_uint_16)((*sp >> shift) & 0x0f) | 2927 if ((png_uint_16)((*sp >> shift) & 0x0f) |
3656 == png_ptr->trans_color.gray) | 2928 == trans_values->gray) |
3657 { | 2929 { |
3658 unsigned int tmp = *sp & (0xf0f >> (4 - shift)); | 2930 *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); |
3659 tmp |= png_ptr->background.gray << shift; | 2931 *sp |= (png_byte)(background->gray << shift); |
3660 *sp = (png_byte)(tmp & 0xff); | |
3661 } | 2932 } |
3662 | |
3663 else | 2933 else |
3664 { | 2934 { |
3665 unsigned int p = (*sp >> shift) & 0x0f; | 2935 png_byte p = (png_byte)((*sp >> shift) & 0x0f); |
3666 unsigned int g = (gamma_table[p | (p << 4)] >> 4) & | 2936 png_byte g = (png_byte)((gamma_table[p | |
3667 0x0f; | 2937 (p << 4)] >> 4) & 0x0f); |
3668 unsigned int tmp = *sp & (0xf0f >> (4 - shift)); | 2938 *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); |
3669 tmp |= g << shift; | 2939 *sp |= (png_byte)(g << shift); |
3670 *sp = (png_byte)(tmp & 0xff); | |
3671 } | 2940 } |
3672 | |
3673 if (!shift) | 2941 if (!shift) |
3674 { | 2942 { |
3675 shift = 4; | 2943 shift = 4; |
3676 sp++; | 2944 sp++; |
3677 } | 2945 } |
3678 | |
3679 else | 2946 else |
3680 shift -= 4; | 2947 shift -= 4; |
3681 } | 2948 } |
3682 } | 2949 } |
3683 | |
3684 else | 2950 else |
3685 #endif | 2951 #endif |
3686 { | 2952 { |
3687 sp = row; | 2953 sp = row; |
3688 shift = 4; | 2954 shift = 4; |
3689 for (i = 0; i < row_width; i++) | 2955 for (i = 0; i < row_width; i++) |
3690 { | 2956 { |
3691 if ((png_uint_16)((*sp >> shift) & 0x0f) | 2957 if ((png_uint_16)((*sp >> shift) & 0x0f) |
3692 == png_ptr->trans_color.gray) | 2958 == trans_values->gray) |
3693 { | 2959 { |
3694 unsigned int tmp = *sp & (0xf0f >> (4 - shift)); | 2960 *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); |
3695 tmp |= png_ptr->background.gray << shift; | 2961 *sp |= (png_byte)(background->gray << shift); |
3696 *sp = (png_byte)(tmp & 0xff); | |
3697 } | 2962 } |
3698 | |
3699 if (!shift) | 2963 if (!shift) |
3700 { | 2964 { |
3701 shift = 4; | 2965 shift = 4; |
3702 sp++; | 2966 sp++; |
3703 } | 2967 } |
3704 | |
3705 else | 2968 else |
3706 shift -= 4; | 2969 shift -= 4; |
3707 } | 2970 } |
3708 } | 2971 } |
3709 break; | 2972 break; |
3710 } | 2973 } |
3711 | 2974 |
3712 case 8: | 2975 case 8: |
3713 { | 2976 { |
3714 #ifdef PNG_READ_GAMMA_SUPPORTED | 2977 #ifdef PNG_READ_GAMMA_SUPPORTED |
3715 if (gamma_table != NULL) | 2978 if (gamma_table != NULL) |
3716 { | 2979 { |
3717 sp = row; | 2980 sp = row; |
3718 for (i = 0; i < row_width; i++, sp++) | 2981 for (i = 0; i < row_width; i++, sp++) |
3719 { | 2982 { |
3720 if (*sp == png_ptr->trans_color.gray) | 2983 if (*sp == trans_values->gray) |
3721 *sp = (png_byte)png_ptr->background.gray; | 2984 { |
3722 | 2985 *sp = (png_byte)background->gray; |
| 2986 } |
3723 else | 2987 else |
| 2988 { |
3724 *sp = gamma_table[*sp]; | 2989 *sp = gamma_table[*sp]; |
| 2990 } |
3725 } | 2991 } |
3726 } | 2992 } |
3727 else | 2993 else |
3728 #endif | 2994 #endif |
3729 { | 2995 { |
3730 sp = row; | 2996 sp = row; |
3731 for (i = 0; i < row_width; i++, sp++) | 2997 for (i = 0; i < row_width; i++, sp++) |
3732 { | 2998 { |
3733 if (*sp == png_ptr->trans_color.gray) | 2999 if (*sp == trans_values->gray) |
3734 *sp = (png_byte)png_ptr->background.gray; | 3000 { |
| 3001 *sp = (png_byte)background->gray; |
| 3002 } |
3735 } | 3003 } |
3736 } | 3004 } |
3737 break; | 3005 break; |
3738 } | 3006 } |
3739 | 3007 |
3740 case 16: | 3008 case 16: |
3741 { | 3009 { |
3742 #ifdef PNG_READ_GAMMA_SUPPORTED | 3010 #ifdef PNG_READ_GAMMA_SUPPORTED |
3743 if (gamma_16 != NULL) | 3011 if (gamma_16 != NULL) |
3744 { | 3012 { |
3745 sp = row; | 3013 sp = row; |
3746 for (i = 0; i < row_width; i++, sp += 2) | 3014 for (i = 0; i < row_width; i++, sp += 2) |
3747 { | 3015 { |
3748 png_uint_16 v; | 3016 png_uint_16 v; |
3749 | 3017 |
3750 v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); | 3018 v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); |
3751 | 3019 if (v == trans_values->gray) |
3752 if (v == png_ptr->trans_color.gray) | |
3753 { | 3020 { |
3754 /* Background is already in screen gamma */ | 3021 /* Background is already in screen gamma */ |
3755 *sp = (png_byte)((png_ptr->background.gray >> 8) | 3022 *sp = (png_byte)((background->gray >> 8) & 0xff); |
3756 & 0xff); | 3023 *(sp + 1) = (png_byte)(background->gray & 0xff); |
3757 *(sp + 1) = (png_byte)(png_ptr->background.gray | |
3758 & 0xff); | |
3759 } | 3024 } |
3760 | |
3761 else | 3025 else |
3762 { | 3026 { |
3763 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; | 3027 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; |
3764 *sp = (png_byte)((v >> 8) & 0xff); | 3028 *sp = (png_byte)((v >> 8) & 0xff); |
3765 *(sp + 1) = (png_byte)(v & 0xff); | 3029 *(sp + 1) = (png_byte)(v & 0xff); |
3766 } | 3030 } |
3767 } | 3031 } |
3768 } | 3032 } |
3769 else | 3033 else |
3770 #endif | 3034 #endif |
3771 { | 3035 { |
3772 sp = row; | 3036 sp = row; |
3773 for (i = 0; i < row_width; i++, sp += 2) | 3037 for (i = 0; i < row_width; i++, sp += 2) |
3774 { | 3038 { |
3775 png_uint_16 v; | 3039 png_uint_16 v; |
3776 | 3040 |
3777 v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); | 3041 v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); |
3778 | 3042 if (v == trans_values->gray) |
3779 if (v == png_ptr->trans_color.gray) | |
3780 { | 3043 { |
3781 *sp = (png_byte)((png_ptr->background.gray >> 8) | 3044 *sp = (png_byte)((background->gray >> 8) & 0xff); |
3782 & 0xff); | 3045 *(sp + 1) = (png_byte)(background->gray & 0xff); |
3783 *(sp + 1) = (png_byte)(png_ptr->background.gray | |
3784 & 0xff); | |
3785 } | 3046 } |
3786 } | 3047 } |
3787 } | 3048 } |
3788 break; | 3049 break; |
3789 } | 3050 } |
3790 | |
3791 default: | |
3792 break; | |
3793 } | 3051 } |
3794 break; | 3052 break; |
3795 } | 3053 } |
3796 | 3054 |
3797 case PNG_COLOR_TYPE_RGB: | 3055 case PNG_COLOR_TYPE_RGB: |
3798 { | 3056 { |
3799 if (row_info->bit_depth == 8) | 3057 if (row_info->bit_depth == 8) |
3800 { | 3058 { |
3801 #ifdef PNG_READ_GAMMA_SUPPORTED | 3059 #ifdef PNG_READ_GAMMA_SUPPORTED |
3802 if (gamma_table != NULL) | 3060 if (gamma_table != NULL) |
3803 { | 3061 { |
3804 sp = row; | 3062 sp = row; |
3805 for (i = 0; i < row_width; i++, sp += 3) | 3063 for (i = 0; i < row_width; i++, sp += 3) |
3806 { | 3064 { |
3807 if (*sp == png_ptr->trans_color.red && | 3065 if (*sp == trans_values->red && |
3808 *(sp + 1) == png_ptr->trans_color.green && | 3066 *(sp + 1) == trans_values->green && |
3809 *(sp + 2) == png_ptr->trans_color.blue) | 3067 *(sp + 2) == trans_values->blue) |
3810 { | 3068 { |
3811 *sp = (png_byte)png_ptr->background.red; | 3069 *sp = (png_byte)background->red; |
3812 *(sp + 1) = (png_byte)png_ptr->background.green; | 3070 *(sp + 1) = (png_byte)background->green; |
3813 *(sp + 2) = (png_byte)png_ptr->background.blue; | 3071 *(sp + 2) = (png_byte)background->blue; |
3814 } | 3072 } |
3815 | |
3816 else | 3073 else |
3817 { | 3074 { |
3818 *sp = gamma_table[*sp]; | 3075 *sp = gamma_table[*sp]; |
3819 *(sp + 1) = gamma_table[*(sp + 1)]; | 3076 *(sp + 1) = gamma_table[*(sp + 1)]; |
3820 *(sp + 2) = gamma_table[*(sp + 2)]; | 3077 *(sp + 2) = gamma_table[*(sp + 2)]; |
3821 } | 3078 } |
3822 } | 3079 } |
3823 } | 3080 } |
3824 else | 3081 else |
3825 #endif | 3082 #endif |
3826 { | 3083 { |
3827 sp = row; | 3084 sp = row; |
3828 for (i = 0; i < row_width; i++, sp += 3) | 3085 for (i = 0; i < row_width; i++, sp += 3) |
3829 { | 3086 { |
3830 if (*sp == png_ptr->trans_color.red && | 3087 if (*sp == trans_values->red && |
3831 *(sp + 1) == png_ptr->trans_color.green && | 3088 *(sp + 1) == trans_values->green && |
3832 *(sp + 2) == png_ptr->trans_color.blue) | 3089 *(sp + 2) == trans_values->blue) |
3833 { | 3090 { |
3834 *sp = (png_byte)png_ptr->background.red; | 3091 *sp = (png_byte)background->red; |
3835 *(sp + 1) = (png_byte)png_ptr->background.green; | 3092 *(sp + 1) = (png_byte)background->green; |
3836 *(sp + 2) = (png_byte)png_ptr->background.blue; | 3093 *(sp + 2) = (png_byte)background->blue; |
3837 } | 3094 } |
3838 } | 3095 } |
3839 } | 3096 } |
3840 } | 3097 } |
3841 else /* if (row_info->bit_depth == 16) */ | 3098 else /* if (row_info->bit_depth == 16) */ |
3842 { | 3099 { |
3843 #ifdef PNG_READ_GAMMA_SUPPORTED | 3100 #ifdef PNG_READ_GAMMA_SUPPORTED |
3844 if (gamma_16 != NULL) | 3101 if (gamma_16 != NULL) |
3845 { | 3102 { |
3846 sp = row; | 3103 sp = row; |
3847 for (i = 0; i < row_width; i++, sp += 6) | 3104 for (i = 0; i < row_width; i++, sp += 6) |
3848 { | 3105 { |
3849 png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); | 3106 png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); |
3850 | 3107 png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); |
3851 png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) | 3108 png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5)); |
3852 + *(sp + 3)); | 3109 if (r == trans_values->red && g == trans_values->green && |
3853 | 3110 b == trans_values->blue) |
3854 png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) | |
3855 + *(sp + 5)); | |
3856 | |
3857 if (r == png_ptr->trans_color.red && | |
3858 g == png_ptr->trans_color.green && | |
3859 b == png_ptr->trans_color.blue) | |
3860 { | 3111 { |
3861 /* Background is already in screen gamma */ | 3112 /* Background is already in screen gamma */ |
3862 *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); | 3113 *sp = (png_byte)((background->red >> 8) & 0xff); |
3863 *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); | 3114 *(sp + 1) = (png_byte)(background->red & 0xff); |
3864 *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) | 3115 *(sp + 2) = (png_byte)((background->green >> 8) & 0xff); |
3865 & 0xff); | 3116 *(sp + 3) = (png_byte)(background->green & 0xff); |
3866 *(sp + 3) = (png_byte)(png_ptr->background.green | 3117 *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff); |
3867 & 0xff); | 3118 *(sp + 5) = (png_byte)(background->blue & 0xff); |
3868 *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) | |
3869 & 0xff); | |
3870 *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); | |
3871 } | 3119 } |
3872 | |
3873 else | 3120 else |
3874 { | 3121 { |
3875 png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; | 3122 png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; |
3876 *sp = (png_byte)((v >> 8) & 0xff); | 3123 *sp = (png_byte)((v >> 8) & 0xff); |
3877 *(sp + 1) = (png_byte)(v & 0xff); | 3124 *(sp + 1) = (png_byte)(v & 0xff); |
3878 | |
3879 v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; | 3125 v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; |
3880 *(sp + 2) = (png_byte)((v >> 8) & 0xff); | 3126 *(sp + 2) = (png_byte)((v >> 8) & 0xff); |
3881 *(sp + 3) = (png_byte)(v & 0xff); | 3127 *(sp + 3) = (png_byte)(v & 0xff); |
3882 | |
3883 v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; | 3128 v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; |
3884 *(sp + 4) = (png_byte)((v >> 8) & 0xff); | 3129 *(sp + 4) = (png_byte)((v >> 8) & 0xff); |
3885 *(sp + 5) = (png_byte)(v & 0xff); | 3130 *(sp + 5) = (png_byte)(v & 0xff); |
3886 } | 3131 } |
3887 } | 3132 } |
3888 } | 3133 } |
3889 | |
3890 else | 3134 else |
3891 #endif | 3135 #endif |
3892 { | 3136 { |
3893 sp = row; | 3137 sp = row; |
3894 for (i = 0; i < row_width; i++, sp += 6) | 3138 for (i = 0; i < row_width; i++, sp += 6) |
3895 { | 3139 { |
3896 png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); | 3140 png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1)); |
| 3141 png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); |
| 3142 png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5)); |
3897 | 3143 |
3898 png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) | 3144 if (r == trans_values->red && g == trans_values->green && |
3899 + *(sp + 3)); | 3145 b == trans_values->blue) |
3900 | |
3901 png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) | |
3902 + *(sp + 5)); | |
3903 | |
3904 if (r == png_ptr->trans_color.red && | |
3905 g == png_ptr->trans_color.green && | |
3906 b == png_ptr->trans_color.blue) | |
3907 { | 3146 { |
3908 *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); | 3147 *sp = (png_byte)((background->red >> 8) & 0xff); |
3909 *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); | 3148 *(sp + 1) = (png_byte)(background->red & 0xff); |
3910 *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) | 3149 *(sp + 2) = (png_byte)((background->green >> 8) & 0xff); |
3911 & 0xff); | 3150 *(sp + 3) = (png_byte)(background->green & 0xff); |
3912 *(sp + 3) = (png_byte)(png_ptr->background.green | 3151 *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff); |
3913 & 0xff); | 3152 *(sp + 5) = (png_byte)(background->blue & 0xff); |
3914 *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) | |
3915 & 0xff); | |
3916 *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); | |
3917 } | 3153 } |
3918 } | 3154 } |
3919 } | 3155 } |
3920 } | 3156 } |
3921 break; | 3157 break; |
3922 } | 3158 } |
3923 | 3159 |
3924 case PNG_COLOR_TYPE_GRAY_ALPHA: | 3160 case PNG_COLOR_TYPE_GRAY_ALPHA: |
3925 { | 3161 { |
3926 if (row_info->bit_depth == 8) | 3162 if (row_info->bit_depth == 8) |
3927 { | 3163 { |
3928 #ifdef PNG_READ_GAMMA_SUPPORTED | 3164 #ifdef PNG_READ_GAMMA_SUPPORTED |
3929 if (gamma_to_1 != NULL && gamma_from_1 != NULL && | 3165 if (gamma_to_1 != NULL && gamma_from_1 != NULL && |
3930 gamma_table != NULL) | 3166 gamma_table != NULL) |
3931 { | 3167 { |
3932 sp = row; | 3168 sp = row; |
3933 for (i = 0; i < row_width; i++, sp += 2) | 3169 dp = row; |
| 3170 for (i = 0; i < row_width; i++, sp += 2, dp++) |
3934 { | 3171 { |
3935 png_uint_16 a = *(sp + 1); | 3172 png_uint_16 a = *(sp + 1); |
3936 | 3173 |
3937 if (a == 0xff) | 3174 if (a == 0xff) |
3938 *sp = gamma_table[*sp]; | 3175 { |
3939 | 3176 *dp = gamma_table[*sp]; |
| 3177 } |
3940 else if (a == 0) | 3178 else if (a == 0) |
3941 { | 3179 { |
3942 /* Background is already in screen gamma */ | 3180 /* Background is already in screen gamma */ |
3943 *sp = (png_byte)png_ptr->background.gray; | 3181 *dp = (png_byte)background->gray; |
3944 } | 3182 } |
3945 | |
3946 else | 3183 else |
3947 { | 3184 { |
3948 png_byte v, w; | 3185 png_byte v, w; |
3949 | 3186 |
3950 v = gamma_to_1[*sp]; | 3187 v = gamma_to_1[*sp]; |
3951 png_composite(w, v, a, png_ptr->background_1.gray); | 3188 png_composite(w, v, a, background_1->gray); |
3952 if (!optimize) | 3189 *dp = gamma_from_1[w]; |
3953 w = gamma_from_1[w]; | |
3954 *sp = w; | |
3955 } | 3190 } |
3956 } | 3191 } |
3957 } | 3192 } |
3958 else | 3193 else |
3959 #endif | 3194 #endif |
3960 { | 3195 { |
3961 sp = row; | 3196 sp = row; |
3962 for (i = 0; i < row_width; i++, sp += 2) | 3197 dp = row; |
| 3198 for (i = 0; i < row_width; i++, sp += 2, dp++) |
3963 { | 3199 { |
3964 png_byte a = *(sp + 1); | 3200 png_byte a = *(sp + 1); |
3965 | 3201 |
3966 if (a == 0) | 3202 if (a == 0xff) |
3967 *sp = (png_byte)png_ptr->background.gray; | 3203 { |
3968 | 3204 *dp = *sp; |
3969 else if (a < 0xff) | 3205 } |
3970 png_composite(*sp, *sp, a, png_ptr->background.gray); | 3206 #ifdef PNG_READ_GAMMA_SUPPORTED |
| 3207 else if (a == 0) |
| 3208 { |
| 3209 *dp = (png_byte)background->gray; |
| 3210 } |
| 3211 else |
| 3212 { |
| 3213 png_composite(*dp, *sp, a, background_1->gray); |
| 3214 } |
| 3215 #else |
| 3216 *dp = (png_byte)background->gray; |
| 3217 #endif |
3971 } | 3218 } |
3972 } | 3219 } |
3973 } | 3220 } |
3974 else /* if (png_ptr->bit_depth == 16) */ | 3221 else /* if (png_ptr->bit_depth == 16) */ |
3975 { | 3222 { |
3976 #ifdef PNG_READ_GAMMA_SUPPORTED | 3223 #ifdef PNG_READ_GAMMA_SUPPORTED |
3977 if (gamma_16 != NULL && gamma_16_from_1 != NULL && | 3224 if (gamma_16 != NULL && gamma_16_from_1 != NULL && |
3978 gamma_16_to_1 != NULL) | 3225 gamma_16_to_1 != NULL) |
3979 { | 3226 { |
3980 sp = row; | 3227 sp = row; |
3981 for (i = 0; i < row_width; i++, sp += 4) | 3228 dp = row; |
| 3229 for (i = 0; i < row_width; i++, sp += 4, dp += 2) |
3982 { | 3230 { |
3983 png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) | 3231 png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); |
3984 + *(sp + 3)); | |
3985 | 3232 |
3986 if (a == (png_uint_16)0xffff) | 3233 if (a == (png_uint_16)0xffff) |
3987 { | 3234 { |
3988 png_uint_16 v; | 3235 png_uint_16 v; |
3989 | 3236 |
3990 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; | 3237 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; |
3991 *sp = (png_byte)((v >> 8) & 0xff); | 3238 *dp = (png_byte)((v >> 8) & 0xff); |
3992 *(sp + 1) = (png_byte)(v & 0xff); | 3239 *(dp + 1) = (png_byte)(v & 0xff); |
3993 } | 3240 } |
3994 | 3241 #ifdef PNG_READ_GAMMA_SUPPORTED |
3995 else if (a == 0) | 3242 else if (a == 0) |
| 3243 #else |
| 3244 else |
| 3245 #endif |
3996 { | 3246 { |
3997 /* Background is already in screen gamma */ | 3247 /* Background is already in screen gamma */ |
3998 *sp = (png_byte)((png_ptr->background.gray >> 8) | 3248 *dp = (png_byte)((background->gray >> 8) & 0xff); |
3999 & 0xff); | 3249 *(dp + 1) = (png_byte)(background->gray & 0xff); |
4000 *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); | |
4001 } | 3250 } |
4002 | 3251 #ifdef PNG_READ_GAMMA_SUPPORTED |
4003 else | 3252 else |
4004 { | 3253 { |
4005 png_uint_16 g, v, w; | 3254 png_uint_16 g, v, w; |
4006 | 3255 |
4007 g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; | 3256 g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; |
4008 png_composite_16(v, g, a, png_ptr->background_1.gray); | 3257 png_composite_16(v, g, a, background_1->gray); |
4009 if (optimize) | 3258 w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8]; |
4010 w = v; | 3259 *dp = (png_byte)((w >> 8) & 0xff); |
4011 else | 3260 *(dp + 1) = (png_byte)(w & 0xff); |
4012 w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8]; | |
4013 *sp = (png_byte)((w >> 8) & 0xff); | |
4014 *(sp + 1) = (png_byte)(w & 0xff); | |
4015 } | 3261 } |
| 3262 #endif |
4016 } | 3263 } |
4017 } | 3264 } |
4018 else | 3265 else |
4019 #endif | 3266 #endif |
4020 { | 3267 { |
4021 sp = row; | 3268 sp = row; |
4022 for (i = 0; i < row_width; i++, sp += 4) | 3269 dp = row; |
| 3270 for (i = 0; i < row_width; i++, sp += 4, dp += 2) |
4023 { | 3271 { |
4024 png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) | 3272 png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); |
4025 + *(sp + 3)); | 3273 if (a == (png_uint_16)0xffff) |
4026 | |
4027 if (a == 0) | |
4028 { | 3274 { |
4029 *sp = (png_byte)((png_ptr->background.gray >> 8) | 3275 png_memcpy(dp, sp, 2); |
4030 & 0xff); | |
4031 *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); | |
4032 } | 3276 } |
4033 | 3277 #ifdef PNG_READ_GAMMA_SUPPORTED |
4034 else if (a < 0xffff) | 3278 else if (a == 0) |
| 3279 #else |
| 3280 else |
| 3281 #endif |
| 3282 { |
| 3283 *dp = (png_byte)((background->gray >> 8) & 0xff); |
| 3284 *(dp + 1) = (png_byte)(background->gray & 0xff); |
| 3285 } |
| 3286 #ifdef PNG_READ_GAMMA_SUPPORTED |
| 3287 else |
4035 { | 3288 { |
4036 png_uint_16 g, v; | 3289 png_uint_16 g, v; |
4037 | 3290 |
4038 g = (png_uint_16)(((*sp) << 8) + *(sp + 1)); | 3291 g = (png_uint_16)(((*sp) << 8) + *(sp + 1)); |
4039 png_composite_16(v, g, a, png_ptr->background.gray); | 3292 png_composite_16(v, g, a, background_1->gray); |
4040 *sp = (png_byte)((v >> 8) & 0xff); | 3293 *dp = (png_byte)((v >> 8) & 0xff); |
4041 *(sp + 1) = (png_byte)(v & 0xff); | 3294 *(dp + 1) = (png_byte)(v & 0xff); |
4042 } | 3295 } |
| 3296 #endif |
4043 } | 3297 } |
4044 } | 3298 } |
4045 } | 3299 } |
4046 break; | 3300 break; |
4047 } | 3301 } |
4048 | 3302 |
4049 case PNG_COLOR_TYPE_RGB_ALPHA: | 3303 case PNG_COLOR_TYPE_RGB_ALPHA: |
4050 { | 3304 { |
4051 if (row_info->bit_depth == 8) | 3305 if (row_info->bit_depth == 8) |
4052 { | 3306 { |
4053 #ifdef PNG_READ_GAMMA_SUPPORTED | 3307 #ifdef PNG_READ_GAMMA_SUPPORTED |
4054 if (gamma_to_1 != NULL && gamma_from_1 != NULL && | 3308 if (gamma_to_1 != NULL && gamma_from_1 != NULL && |
4055 gamma_table != NULL) | 3309 gamma_table != NULL) |
4056 { | 3310 { |
4057 sp = row; | 3311 sp = row; |
4058 for (i = 0; i < row_width; i++, sp += 4) | 3312 dp = row; |
| 3313 for (i = 0; i < row_width; i++, sp += 4, dp += 3) |
4059 { | 3314 { |
4060 png_byte a = *(sp + 3); | 3315 png_byte a = *(sp + 3); |
4061 | 3316 |
4062 if (a == 0xff) | 3317 if (a == 0xff) |
4063 { | 3318 { |
4064 *sp = gamma_table[*sp]; | 3319 *dp = gamma_table[*sp]; |
4065 *(sp + 1) = gamma_table[*(sp + 1)]; | 3320 *(dp + 1) = gamma_table[*(sp + 1)]; |
4066 *(sp + 2) = gamma_table[*(sp + 2)]; | 3321 *(dp + 2) = gamma_table[*(sp + 2)]; |
4067 } | 3322 } |
4068 | |
4069 else if (a == 0) | 3323 else if (a == 0) |
4070 { | 3324 { |
4071 /* Background is already in screen gamma */ | 3325 /* Background is already in screen gamma */ |
4072 *sp = (png_byte)png_ptr->background.red; | 3326 *dp = (png_byte)background->red; |
4073 *(sp + 1) = (png_byte)png_ptr->background.green; | 3327 *(dp + 1) = (png_byte)background->green; |
4074 *(sp + 2) = (png_byte)png_ptr->background.blue; | 3328 *(dp + 2) = (png_byte)background->blue; |
4075 } | 3329 } |
4076 | |
4077 else | 3330 else |
4078 { | 3331 { |
4079 png_byte v, w; | 3332 png_byte v, w; |
4080 | 3333 |
4081 v = gamma_to_1[*sp]; | 3334 v = gamma_to_1[*sp]; |
4082 png_composite(w, v, a, png_ptr->background_1.red); | 3335 png_composite(w, v, a, background_1->red); |
4083 if (!optimize) w = gamma_from_1[w]; | 3336 *dp = gamma_from_1[w]; |
4084 *sp = w; | |
4085 | |
4086 v = gamma_to_1[*(sp + 1)]; | 3337 v = gamma_to_1[*(sp + 1)]; |
4087 png_composite(w, v, a, png_ptr->background_1.green); | 3338 png_composite(w, v, a, background_1->green); |
4088 if (!optimize) w = gamma_from_1[w]; | 3339 *(dp + 1) = gamma_from_1[w]; |
4089 *(sp + 1) = w; | |
4090 | |
4091 v = gamma_to_1[*(sp + 2)]; | 3340 v = gamma_to_1[*(sp + 2)]; |
4092 png_composite(w, v, a, png_ptr->background_1.blue); | 3341 png_composite(w, v, a, background_1->blue); |
4093 if (!optimize) w = gamma_from_1[w]; | 3342 *(dp + 2) = gamma_from_1[w]; |
4094 *(sp + 2) = w; | |
4095 } | 3343 } |
4096 } | 3344 } |
4097 } | 3345 } |
4098 else | 3346 else |
4099 #endif | 3347 #endif |
4100 { | 3348 { |
4101 sp = row; | 3349 sp = row; |
4102 for (i = 0; i < row_width; i++, sp += 4) | 3350 dp = row; |
| 3351 for (i = 0; i < row_width; i++, sp += 4, dp += 3) |
4103 { | 3352 { |
4104 png_byte a = *(sp + 3); | 3353 png_byte a = *(sp + 3); |
4105 | 3354 |
4106 if (a == 0) | 3355 if (a == 0xff) |
4107 { | 3356 { |
4108 *sp = (png_byte)png_ptr->background.red; | 3357 *dp = *sp; |
4109 *(sp + 1) = (png_byte)png_ptr->background.green; | 3358 *(dp + 1) = *(sp + 1); |
4110 *(sp + 2) = (png_byte)png_ptr->background.blue; | 3359 *(dp + 2) = *(sp + 2); |
4111 } | 3360 } |
4112 | 3361 else if (a == 0) |
4113 else if (a < 0xff) | |
4114 { | 3362 { |
4115 png_composite(*sp, *sp, a, png_ptr->background.red); | 3363 *dp = (png_byte)background->red; |
4116 | 3364 *(dp + 1) = (png_byte)background->green; |
4117 png_composite(*(sp + 1), *(sp + 1), a, | 3365 *(dp + 2) = (png_byte)background->blue; |
4118 png_ptr->background.green); | 3366 } |
4119 | 3367 else |
4120 png_composite(*(sp + 2), *(sp + 2), a, | 3368 { |
4121 png_ptr->background.blue); | 3369 png_composite(*dp, *sp, a, background->red); |
| 3370 png_composite(*(dp + 1), *(sp + 1), a, |
| 3371 background->green); |
| 3372 png_composite(*(dp + 2), *(sp + 2), a, |
| 3373 background->blue); |
4122 } | 3374 } |
4123 } | 3375 } |
4124 } | 3376 } |
4125 } | 3377 } |
4126 else /* if (row_info->bit_depth == 16) */ | 3378 else /* if (row_info->bit_depth == 16) */ |
4127 { | 3379 { |
4128 #ifdef PNG_READ_GAMMA_SUPPORTED | 3380 #ifdef PNG_READ_GAMMA_SUPPORTED |
4129 if (gamma_16 != NULL && gamma_16_from_1 != NULL && | 3381 if (gamma_16 != NULL && gamma_16_from_1 != NULL && |
4130 gamma_16_to_1 != NULL) | 3382 gamma_16_to_1 != NULL) |
4131 { | 3383 { |
4132 sp = row; | 3384 sp = row; |
4133 for (i = 0; i < row_width; i++, sp += 8) | 3385 dp = row; |
| 3386 for (i = 0; i < row_width; i++, sp += 8, dp += 6) |
4134 { | 3387 { |
4135 png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) | 3388 png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) |
4136 << 8) + (png_uint_16)(*(sp + 7))); | 3389 << 8) + (png_uint_16)(*(sp + 7))); |
4137 | |
4138 if (a == (png_uint_16)0xffff) | 3390 if (a == (png_uint_16)0xffff) |
4139 { | 3391 { |
4140 png_uint_16 v; | 3392 png_uint_16 v; |
4141 | 3393 |
4142 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; | 3394 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; |
4143 *sp = (png_byte)((v >> 8) & 0xff); | 3395 *dp = (png_byte)((v >> 8) & 0xff); |
4144 *(sp + 1) = (png_byte)(v & 0xff); | 3396 *(dp + 1) = (png_byte)(v & 0xff); |
4145 | |
4146 v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; | 3397 v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; |
4147 *(sp + 2) = (png_byte)((v >> 8) & 0xff); | 3398 *(dp + 2) = (png_byte)((v >> 8) & 0xff); |
4148 *(sp + 3) = (png_byte)(v & 0xff); | 3399 *(dp + 3) = (png_byte)(v & 0xff); |
4149 | |
4150 v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; | 3400 v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; |
4151 *(sp + 4) = (png_byte)((v >> 8) & 0xff); | 3401 *(dp + 4) = (png_byte)((v >> 8) & 0xff); |
4152 *(sp + 5) = (png_byte)(v & 0xff); | 3402 *(dp + 5) = (png_byte)(v & 0xff); |
4153 } | 3403 } |
4154 | |
4155 else if (a == 0) | 3404 else if (a == 0) |
4156 { | 3405 { |
4157 /* Background is already in screen gamma */ | 3406 /* Background is already in screen gamma */ |
4158 *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); | 3407 *dp = (png_byte)((background->red >> 8) & 0xff); |
4159 *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); | 3408 *(dp + 1) = (png_byte)(background->red & 0xff); |
4160 *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) | 3409 *(dp + 2) = (png_byte)((background->green >> 8) & 0xff); |
4161 & 0xff); | 3410 *(dp + 3) = (png_byte)(background->green & 0xff); |
4162 *(sp + 3) = (png_byte)(png_ptr->background.green | 3411 *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff); |
4163 & 0xff); | 3412 *(dp + 5) = (png_byte)(background->blue & 0xff); |
4164 *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) | |
4165 & 0xff); | |
4166 *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); | |
4167 } | 3413 } |
4168 | |
4169 else | 3414 else |
4170 { | 3415 { |
4171 png_uint_16 v, w; | 3416 png_uint_16 v, w, x; |
4172 | 3417 |
4173 v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; | 3418 v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; |
4174 png_composite_16(w, v, a, png_ptr->background_1.red); | 3419 png_composite_16(w, v, a, background_1->red); |
4175 if (!optimize) | 3420 x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; |
4176 w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> | 3421 *dp = (png_byte)((x >> 8) & 0xff); |
4177 8]; | 3422 *(dp + 1) = (png_byte)(x & 0xff); |
4178 *sp = (png_byte)((w >> 8) & 0xff); | |
4179 *(sp + 1) = (png_byte)(w & 0xff); | |
4180 | |
4181 v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; | 3423 v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; |
4182 png_composite_16(w, v, a, png_ptr->background_1.green); | 3424 png_composite_16(w, v, a, background_1->green); |
4183 if (!optimize) | 3425 x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; |
4184 w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> | 3426 *(dp + 2) = (png_byte)((x >> 8) & 0xff); |
4185 8]; | 3427 *(dp + 3) = (png_byte)(x & 0xff); |
4186 | |
4187 *(sp + 2) = (png_byte)((w >> 8) & 0xff); | |
4188 *(sp + 3) = (png_byte)(w & 0xff); | |
4189 | |
4190 v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; | 3428 v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; |
4191 png_composite_16(w, v, a, png_ptr->background_1.blue); | 3429 png_composite_16(w, v, a, background_1->blue); |
4192 if (!optimize) | 3430 x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8]; |
4193 w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> | 3431 *(dp + 4) = (png_byte)((x >> 8) & 0xff); |
4194 8]; | 3432 *(dp + 5) = (png_byte)(x & 0xff); |
4195 | |
4196 *(sp + 4) = (png_byte)((w >> 8) & 0xff); | |
4197 *(sp + 5) = (png_byte)(w & 0xff); | |
4198 } | 3433 } |
4199 } | 3434 } |
4200 } | 3435 } |
4201 | |
4202 else | 3436 else |
4203 #endif | 3437 #endif |
4204 { | 3438 { |
4205 sp = row; | 3439 sp = row; |
4206 for (i = 0; i < row_width; i++, sp += 8) | 3440 dp = row; |
| 3441 for (i = 0; i < row_width; i++, sp += 8, dp += 6) |
4207 { | 3442 { |
4208 png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) | 3443 png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) |
4209 << 8) + (png_uint_16)(*(sp + 7))); | 3444 << 8) + (png_uint_16)(*(sp + 7))); |
4210 | 3445 if (a == (png_uint_16)0xffff) |
4211 if (a == 0) | |
4212 { | 3446 { |
4213 *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); | 3447 png_memcpy(dp, sp, 6); |
4214 *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); | |
4215 *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) | |
4216 & 0xff); | |
4217 *(sp + 3) = (png_byte)(png_ptr->background.green | |
4218 & 0xff); | |
4219 *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) | |
4220 & 0xff); | |
4221 *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); | |
4222 } | 3448 } |
4223 | 3449 else if (a == 0) |
4224 else if (a < 0xffff) | 3450 { |
| 3451 *dp = (png_byte)((background->red >> 8) & 0xff); |
| 3452 *(dp + 1) = (png_byte)(background->red & 0xff); |
| 3453 *(dp + 2) = (png_byte)((background->green >> 8) & 0xff); |
| 3454 *(dp + 3) = (png_byte)(background->green & 0xff); |
| 3455 *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff); |
| 3456 *(dp + 5) = (png_byte)(background->blue & 0xff); |
| 3457 } |
| 3458 else |
4225 { | 3459 { |
4226 png_uint_16 v; | 3460 png_uint_16 v; |
4227 | 3461 |
4228 png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); | 3462 png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); |
4229 png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) | 3463 png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) |
4230 + *(sp + 3)); | 3464 + *(sp + 3)); |
4231 png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) | 3465 png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) |
4232 + *(sp + 5)); | 3466 + *(sp + 5)); |
4233 | 3467 |
4234 png_composite_16(v, r, a, png_ptr->background.red); | 3468 png_composite_16(v, r, a, background->red); |
4235 *sp = (png_byte)((v >> 8) & 0xff); | 3469 *dp = (png_byte)((v >> 8) & 0xff); |
4236 *(sp + 1) = (png_byte)(v & 0xff); | 3470 *(dp + 1) = (png_byte)(v & 0xff); |
4237 | 3471 png_composite_16(v, g, a, background->green); |
4238 png_composite_16(v, g, a, png_ptr->background.green); | 3472 *(dp + 2) = (png_byte)((v >> 8) & 0xff); |
4239 *(sp + 2) = (png_byte)((v >> 8) & 0xff); | 3473 *(dp + 3) = (png_byte)(v & 0xff); |
4240 *(sp + 3) = (png_byte)(v & 0xff); | 3474 png_composite_16(v, b, a, background->blue); |
4241 | 3475 *(dp + 4) = (png_byte)((v >> 8) & 0xff); |
4242 png_composite_16(v, b, a, png_ptr->background.blue); | 3476 *(dp + 5) = (png_byte)(v & 0xff); |
4243 *(sp + 4) = (png_byte)((v >> 8) & 0xff); | |
4244 *(sp + 5) = (png_byte)(v & 0xff); | |
4245 } | 3477 } |
4246 } | 3478 } |
4247 } | 3479 } |
4248 } | 3480 } |
4249 break; | 3481 break; |
4250 } | 3482 } |
| 3483 } |
4251 | 3484 |
4252 default: | 3485 if (row_info->color_type & PNG_COLOR_MASK_ALPHA) |
4253 break; | 3486 { |
| 3487 row_info->color_type &= ~PNG_COLOR_MASK_ALPHA; |
| 3488 row_info->channels--; |
| 3489 row_info->pixel_depth = (png_byte)(row_info->channels * |
| 3490 row_info->bit_depth); |
| 3491 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); |
4254 } | 3492 } |
4255 } | 3493 } |
4256 } | 3494 } |
4257 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_READ_ALPHA_MODE_SUPPORTED */ | 3495 #endif |
4258 | 3496 |
4259 #ifdef PNG_READ_GAMMA_SUPPORTED | 3497 #ifdef PNG_READ_GAMMA_SUPPORTED |
4260 /* Gamma correct the image, avoiding the alpha channel. Make sure | 3498 /* Gamma correct the image, avoiding the alpha channel. Make sure |
4261 * you do this after you deal with the transparency issue on grayscale | 3499 * you do this after you deal with the transparency issue on grayscale |
4262 * or RGB images. If your bit depth is 8, use gamma_table, if it | 3500 * or RGB images. If your bit depth is 8, use gamma_table, if it |
4263 * is 16, use gamma_16_table and gamma_shift. Build these with | 3501 * is 16, use gamma_16_table and gamma_shift. Build these with |
4264 * build_gamma_table(). | 3502 * build_gamma_table(). |
4265 */ | 3503 */ |
4266 void /* PRIVATE */ | 3504 void /* PRIVATE */ |
4267 png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr) | 3505 png_do_gamma(png_row_infop row_info, png_bytep row, |
| 3506 png_bytep gamma_table, png_uint_16pp gamma_16_table, |
| 3507 int gamma_shift) |
4268 { | 3508 { |
4269 png_const_bytep gamma_table = png_ptr->gamma_table; | |
4270 png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table; | |
4271 int gamma_shift = png_ptr->gamma_shift; | |
4272 | |
4273 png_bytep sp; | 3509 png_bytep sp; |
4274 png_uint_32 i; | 3510 png_uint_32 i; |
4275 png_uint_32 row_width=row_info->width; | 3511 png_uint_32 row_width=row_info->width; |
4276 | 3512 |
4277 png_debug(1, "in png_do_gamma"); | 3513 png_debug(1, "in png_do_gamma"); |
4278 | 3514 |
4279 if (((row_info->bit_depth <= 8 && gamma_table != NULL) || | 3515 if ( |
4280 (row_info->bit_depth == 16 && gamma_16_table != NULL))) | 3516 #ifdef PNG_USELESS_TESTS_SUPPORTED |
| 3517 row != NULL && row_info != NULL && |
| 3518 #endif |
| 3519 ((row_info->bit_depth <= 8 && gamma_table != NULL) || |
| 3520 (row_info->bit_depth == 16 && gamma_16_table != NULL))) |
4281 { | 3521 { |
4282 switch (row_info->color_type) | 3522 switch (row_info->color_type) |
4283 { | 3523 { |
4284 case PNG_COLOR_TYPE_RGB: | 3524 case PNG_COLOR_TYPE_RGB: |
4285 { | 3525 { |
4286 if (row_info->bit_depth == 8) | 3526 if (row_info->bit_depth == 8) |
4287 { | 3527 { |
4288 sp = row; | 3528 sp = row; |
4289 for (i = 0; i < row_width; i++) | 3529 for (i = 0; i < row_width; i++) |
4290 { | 3530 { |
4291 *sp = gamma_table[*sp]; | 3531 *sp = gamma_table[*sp]; |
4292 sp++; | 3532 sp++; |
4293 *sp = gamma_table[*sp]; | 3533 *sp = gamma_table[*sp]; |
4294 sp++; | 3534 sp++; |
4295 *sp = gamma_table[*sp]; | 3535 *sp = gamma_table[*sp]; |
4296 sp++; | 3536 sp++; |
4297 } | 3537 } |
4298 } | 3538 } |
4299 | |
4300 else /* if (row_info->bit_depth == 16) */ | 3539 else /* if (row_info->bit_depth == 16) */ |
4301 { | 3540 { |
4302 sp = row; | 3541 sp = row; |
4303 for (i = 0; i < row_width; i++) | 3542 for (i = 0; i < row_width; i++) |
4304 { | 3543 { |
4305 png_uint_16 v; | 3544 png_uint_16 v; |
4306 | 3545 |
4307 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; | 3546 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; |
4308 *sp = (png_byte)((v >> 8) & 0xff); | 3547 *sp = (png_byte)((v >> 8) & 0xff); |
4309 *(sp + 1) = (png_byte)(v & 0xff); | 3548 *(sp + 1) = (png_byte)(v & 0xff); |
4310 sp += 2; | 3549 sp += 2; |
4311 | |
4312 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; | 3550 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; |
4313 *sp = (png_byte)((v >> 8) & 0xff); | 3551 *sp = (png_byte)((v >> 8) & 0xff); |
4314 *(sp + 1) = (png_byte)(v & 0xff); | 3552 *(sp + 1) = (png_byte)(v & 0xff); |
4315 sp += 2; | 3553 sp += 2; |
4316 | |
4317 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; | 3554 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; |
4318 *sp = (png_byte)((v >> 8) & 0xff); | 3555 *sp = (png_byte)((v >> 8) & 0xff); |
4319 *(sp + 1) = (png_byte)(v & 0xff); | 3556 *(sp + 1) = (png_byte)(v & 0xff); |
4320 sp += 2; | 3557 sp += 2; |
4321 } | 3558 } |
4322 } | 3559 } |
4323 break; | 3560 break; |
4324 } | 3561 } |
4325 | 3562 |
4326 case PNG_COLOR_TYPE_RGB_ALPHA: | 3563 case PNG_COLOR_TYPE_RGB_ALPHA: |
4327 { | 3564 { |
4328 if (row_info->bit_depth == 8) | 3565 if (row_info->bit_depth == 8) |
4329 { | 3566 { |
4330 sp = row; | 3567 sp = row; |
4331 for (i = 0; i < row_width; i++) | 3568 for (i = 0; i < row_width; i++) |
4332 { | 3569 { |
4333 *sp = gamma_table[*sp]; | 3570 *sp = gamma_table[*sp]; |
4334 sp++; | 3571 sp++; |
4335 | |
4336 *sp = gamma_table[*sp]; | 3572 *sp = gamma_table[*sp]; |
4337 sp++; | 3573 sp++; |
4338 | |
4339 *sp = gamma_table[*sp]; | 3574 *sp = gamma_table[*sp]; |
4340 sp++; | 3575 sp++; |
4341 | |
4342 sp++; | 3576 sp++; |
4343 } | 3577 } |
4344 } | 3578 } |
4345 | |
4346 else /* if (row_info->bit_depth == 16) */ | 3579 else /* if (row_info->bit_depth == 16) */ |
4347 { | 3580 { |
4348 sp = row; | 3581 sp = row; |
4349 for (i = 0; i < row_width; i++) | 3582 for (i = 0; i < row_width; i++) |
4350 { | 3583 { |
4351 png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; | 3584 png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; |
4352 *sp = (png_byte)((v >> 8) & 0xff); | 3585 *sp = (png_byte)((v >> 8) & 0xff); |
4353 *(sp + 1) = (png_byte)(v & 0xff); | 3586 *(sp + 1) = (png_byte)(v & 0xff); |
4354 sp += 2; | 3587 sp += 2; |
4355 | |
4356 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; | 3588 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; |
4357 *sp = (png_byte)((v >> 8) & 0xff); | 3589 *sp = (png_byte)((v >> 8) & 0xff); |
4358 *(sp + 1) = (png_byte)(v & 0xff); | 3590 *(sp + 1) = (png_byte)(v & 0xff); |
4359 sp += 2; | 3591 sp += 2; |
4360 | |
4361 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; | 3592 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; |
4362 *sp = (png_byte)((v >> 8) & 0xff); | 3593 *sp = (png_byte)((v >> 8) & 0xff); |
4363 *(sp + 1) = (png_byte)(v & 0xff); | 3594 *(sp + 1) = (png_byte)(v & 0xff); |
4364 sp += 4; | 3595 sp += 4; |
4365 } | 3596 } |
4366 } | 3597 } |
4367 break; | 3598 break; |
4368 } | 3599 } |
4369 | 3600 |
4370 case PNG_COLOR_TYPE_GRAY_ALPHA: | 3601 case PNG_COLOR_TYPE_GRAY_ALPHA: |
4371 { | 3602 { |
4372 if (row_info->bit_depth == 8) | 3603 if (row_info->bit_depth == 8) |
4373 { | 3604 { |
4374 sp = row; | 3605 sp = row; |
4375 for (i = 0; i < row_width; i++) | 3606 for (i = 0; i < row_width; i++) |
4376 { | 3607 { |
4377 *sp = gamma_table[*sp]; | 3608 *sp = gamma_table[*sp]; |
4378 sp += 2; | 3609 sp += 2; |
4379 } | 3610 } |
4380 } | 3611 } |
4381 | |
4382 else /* if (row_info->bit_depth == 16) */ | 3612 else /* if (row_info->bit_depth == 16) */ |
4383 { | 3613 { |
4384 sp = row; | 3614 sp = row; |
4385 for (i = 0; i < row_width; i++) | 3615 for (i = 0; i < row_width; i++) |
4386 { | 3616 { |
4387 png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; | 3617 png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; |
4388 *sp = (png_byte)((v >> 8) & 0xff); | 3618 *sp = (png_byte)((v >> 8) & 0xff); |
4389 *(sp + 1) = (png_byte)(v & 0xff); | 3619 *(sp + 1) = (png_byte)(v & 0xff); |
4390 sp += 4; | 3620 sp += 4; |
4391 } | 3621 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4444 for (i = 0; i < row_width; i++) | 3674 for (i = 0; i < row_width; i++) |
4445 { | 3675 { |
4446 png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; | 3676 png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; |
4447 *sp = (png_byte)((v >> 8) & 0xff); | 3677 *sp = (png_byte)((v >> 8) & 0xff); |
4448 *(sp + 1) = (png_byte)(v & 0xff); | 3678 *(sp + 1) = (png_byte)(v & 0xff); |
4449 sp += 2; | 3679 sp += 2; |
4450 } | 3680 } |
4451 } | 3681 } |
4452 break; | 3682 break; |
4453 } | 3683 } |
4454 | |
4455 default: | |
4456 break; | |
4457 } | 3684 } |
4458 } | 3685 } |
4459 } | 3686 } |
4460 #endif | 3687 #endif |
4461 | 3688 |
4462 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED | |
4463 /* Encode the alpha channel to the output gamma (the input channel is always | |
4464 * linear.) Called only with color types that have an alpha channel. Needs the | |
4465 * from_1 tables. | |
4466 */ | |
4467 void /* PRIVATE */ | |
4468 png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr) | |
4469 { | |
4470 png_uint_32 row_width = row_info->width; | |
4471 | |
4472 png_debug(1, "in png_do_encode_alpha"); | |
4473 | |
4474 if (row_info->color_type & PNG_COLOR_MASK_ALPHA) | |
4475 { | |
4476 if (row_info->bit_depth == 8) | |
4477 { | |
4478 PNG_CONST png_bytep table = png_ptr->gamma_from_1; | |
4479 | |
4480 if (table != NULL) | |
4481 { | |
4482 PNG_CONST int step = | |
4483 (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2; | |
4484 | |
4485 /* The alpha channel is the last component: */ | |
4486 row += step - 1; | |
4487 | |
4488 for (; row_width > 0; --row_width, row += step) | |
4489 *row = table[*row]; | |
4490 | |
4491 return; | |
4492 } | |
4493 } | |
4494 | |
4495 else if (row_info->bit_depth == 16) | |
4496 { | |
4497 PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1; | |
4498 PNG_CONST int gamma_shift = png_ptr->gamma_shift; | |
4499 | |
4500 if (table != NULL) | |
4501 { | |
4502 PNG_CONST int step = | |
4503 (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4; | |
4504 | |
4505 /* The alpha channel is the last component: */ | |
4506 row += step - 2; | |
4507 | |
4508 for (; row_width > 0; --row_width, row += step) | |
4509 { | |
4510 png_uint_16 v; | |
4511 | |
4512 v = table[*(row + 1) >> gamma_shift][*row]; | |
4513 *row = (png_byte)((v >> 8) & 0xff); | |
4514 *(row + 1) = (png_byte)(v & 0xff); | |
4515 } | |
4516 | |
4517 return; | |
4518 } | |
4519 } | |
4520 } | |
4521 | |
4522 /* Only get to here if called with a weird row_info; no harm has been done, | |
4523 * so just issue a warning. | |
4524 */ | |
4525 png_warning(png_ptr, "png_do_encode_alpha: unexpected call"); | |
4526 } | |
4527 #endif | |
4528 | |
4529 #ifdef PNG_READ_EXPAND_SUPPORTED | 3689 #ifdef PNG_READ_EXPAND_SUPPORTED |
4530 /* Expands a palette row to an RGB or RGBA row depending | 3690 /* Expands a palette row to an RGB or RGBA row depending |
4531 * upon whether you supply trans and num_trans. | 3691 * upon whether you supply trans and num_trans. |
4532 */ | 3692 */ |
4533 void /* PRIVATE */ | 3693 void /* PRIVATE */ |
4534 png_do_expand_palette(png_row_infop row_info, png_bytep row, | 3694 png_do_expand_palette(png_row_infop row_info, png_bytep row, |
4535 png_const_colorp palette, png_const_bytep trans_alpha, int num_trans) | 3695 png_colorp palette, png_bytep trans, int num_trans) |
4536 { | 3696 { |
4537 int shift, value; | 3697 int shift, value; |
4538 png_bytep sp, dp; | 3698 png_bytep sp, dp; |
4539 png_uint_32 i; | 3699 png_uint_32 i; |
4540 png_uint_32 row_width=row_info->width; | 3700 png_uint_32 row_width=row_info->width; |
4541 | 3701 |
4542 png_debug(1, "in png_do_expand_palette"); | 3702 png_debug(1, "in png_do_expand_palette"); |
4543 | 3703 |
4544 if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) | 3704 if ( |
| 3705 #ifdef PNG_USELESS_TESTS_SUPPORTED |
| 3706 row != NULL && row_info != NULL && |
| 3707 #endif |
| 3708 row_info->color_type == PNG_COLOR_TYPE_PALETTE) |
4545 { | 3709 { |
4546 if (row_info->bit_depth < 8) | 3710 if (row_info->bit_depth < 8) |
4547 { | 3711 { |
4548 switch (row_info->bit_depth) | 3712 switch (row_info->bit_depth) |
4549 { | 3713 { |
4550 case 1: | 3714 case 1: |
4551 { | 3715 { |
4552 sp = row + (png_size_t)((row_width - 1) >> 3); | 3716 sp = row + (png_size_t)((row_width - 1) >> 3); |
4553 dp = row + (png_size_t)row_width - 1; | 3717 dp = row + (png_size_t)row_width - 1; |
4554 shift = 7 - (int)((row_width + 7) & 0x07); | 3718 shift = 7 - (int)((row_width + 7) & 0x07); |
4555 for (i = 0; i < row_width; i++) | 3719 for (i = 0; i < row_width; i++) |
4556 { | 3720 { |
4557 if ((*sp >> shift) & 0x01) | 3721 if ((*sp >> shift) & 0x01) |
4558 *dp = 1; | 3722 *dp = 1; |
4559 | |
4560 else | 3723 else |
4561 *dp = 0; | 3724 *dp = 0; |
4562 | |
4563 if (shift == 7) | 3725 if (shift == 7) |
4564 { | 3726 { |
4565 shift = 0; | 3727 shift = 0; |
4566 sp--; | 3728 sp--; |
4567 } | 3729 } |
4568 | |
4569 else | 3730 else |
4570 shift++; | 3731 shift++; |
4571 | 3732 |
4572 dp--; | 3733 dp--; |
4573 } | 3734 } |
4574 break; | 3735 break; |
4575 } | 3736 } |
4576 | 3737 |
4577 case 2: | 3738 case 2: |
4578 { | 3739 { |
4579 sp = row + (png_size_t)((row_width - 1) >> 2); | 3740 sp = row + (png_size_t)((row_width - 1) >> 2); |
4580 dp = row + (png_size_t)row_width - 1; | 3741 dp = row + (png_size_t)row_width - 1; |
4581 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); | 3742 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); |
4582 for (i = 0; i < row_width; i++) | 3743 for (i = 0; i < row_width; i++) |
4583 { | 3744 { |
4584 value = (*sp >> shift) & 0x03; | 3745 value = (*sp >> shift) & 0x03; |
4585 *dp = (png_byte)value; | 3746 *dp = (png_byte)value; |
4586 if (shift == 6) | 3747 if (shift == 6) |
4587 { | 3748 { |
4588 shift = 0; | 3749 shift = 0; |
4589 sp--; | 3750 sp--; |
4590 } | 3751 } |
4591 | |
4592 else | 3752 else |
4593 shift += 2; | 3753 shift += 2; |
4594 | 3754 |
4595 dp--; | 3755 dp--; |
4596 } | 3756 } |
4597 break; | 3757 break; |
4598 } | 3758 } |
4599 | 3759 |
4600 case 4: | 3760 case 4: |
4601 { | 3761 { |
4602 sp = row + (png_size_t)((row_width - 1) >> 1); | 3762 sp = row + (png_size_t)((row_width - 1) >> 1); |
4603 dp = row + (png_size_t)row_width - 1; | 3763 dp = row + (png_size_t)row_width - 1; |
4604 shift = (int)((row_width & 0x01) << 2); | 3764 shift = (int)((row_width & 0x01) << 2); |
4605 for (i = 0; i < row_width; i++) | 3765 for (i = 0; i < row_width; i++) |
4606 { | 3766 { |
4607 value = (*sp >> shift) & 0x0f; | 3767 value = (*sp >> shift) & 0x0f; |
4608 *dp = (png_byte)value; | 3768 *dp = (png_byte)value; |
4609 if (shift == 4) | 3769 if (shift == 4) |
4610 { | 3770 { |
4611 shift = 0; | 3771 shift = 0; |
4612 sp--; | 3772 sp--; |
4613 } | 3773 } |
4614 | |
4615 else | 3774 else |
4616 shift += 4; | 3775 shift += 4; |
4617 | 3776 |
4618 dp--; | 3777 dp--; |
4619 } | 3778 } |
4620 break; | 3779 break; |
4621 } | 3780 } |
4622 | |
4623 default: | |
4624 break; | |
4625 } | 3781 } |
4626 row_info->bit_depth = 8; | 3782 row_info->bit_depth = 8; |
4627 row_info->pixel_depth = 8; | 3783 row_info->pixel_depth = 8; |
4628 row_info->rowbytes = row_width; | 3784 row_info->rowbytes = row_width; |
4629 } | 3785 } |
4630 | 3786 switch (row_info->bit_depth) |
4631 if (row_info->bit_depth == 8) | |
4632 { | 3787 { |
| 3788 case 8: |
4633 { | 3789 { |
4634 if (num_trans > 0) | 3790 if (trans != NULL) |
4635 { | 3791 { |
4636 sp = row + (png_size_t)row_width - 1; | 3792 sp = row + (png_size_t)row_width - 1; |
4637 dp = row + (png_size_t)(row_width << 2) - 1; | 3793 dp = row + (png_size_t)(row_width << 2) - 1; |
4638 | 3794 |
4639 for (i = 0; i < row_width; i++) | 3795 for (i = 0; i < row_width; i++) |
4640 { | 3796 { |
4641 if ((int)(*sp) >= num_trans) | 3797 if ((int)(*sp) >= num_trans) |
4642 *dp-- = 0xff; | 3798 *dp-- = 0xff; |
4643 | |
4644 else | 3799 else |
4645 *dp-- = trans_alpha[*sp]; | 3800 *dp-- = trans[*sp]; |
4646 | |
4647 *dp-- = palette[*sp].blue; | 3801 *dp-- = palette[*sp].blue; |
4648 *dp-- = palette[*sp].green; | 3802 *dp-- = palette[*sp].green; |
4649 *dp-- = palette[*sp].red; | 3803 *dp-- = palette[*sp].red; |
4650 sp--; | 3804 sp--; |
4651 } | 3805 } |
4652 row_info->bit_depth = 8; | 3806 row_info->bit_depth = 8; |
4653 row_info->pixel_depth = 32; | 3807 row_info->pixel_depth = 32; |
4654 row_info->rowbytes = row_width * 4; | 3808 row_info->rowbytes = row_width * 4; |
4655 row_info->color_type = 6; | 3809 row_info->color_type = 6; |
4656 row_info->channels = 4; | 3810 row_info->channels = 4; |
4657 } | 3811 } |
4658 | |
4659 else | 3812 else |
4660 { | 3813 { |
4661 sp = row + (png_size_t)row_width - 1; | 3814 sp = row + (png_size_t)row_width - 1; |
4662 dp = row + (png_size_t)(row_width * 3) - 1; | 3815 dp = row + (png_size_t)(row_width * 3) - 1; |
4663 | 3816 |
4664 for (i = 0; i < row_width; i++) | 3817 for (i = 0; i < row_width; i++) |
4665 { | 3818 { |
4666 *dp-- = palette[*sp].blue; | 3819 *dp-- = palette[*sp].blue; |
4667 *dp-- = palette[*sp].green; | 3820 *dp-- = palette[*sp].green; |
4668 *dp-- = palette[*sp].red; | 3821 *dp-- = palette[*sp].red; |
4669 sp--; | 3822 sp--; |
4670 } | 3823 } |
4671 | 3824 |
4672 row_info->bit_depth = 8; | 3825 row_info->bit_depth = 8; |
4673 row_info->pixel_depth = 24; | 3826 row_info->pixel_depth = 24; |
4674 row_info->rowbytes = row_width * 3; | 3827 row_info->rowbytes = row_width * 3; |
4675 row_info->color_type = 2; | 3828 row_info->color_type = 2; |
4676 row_info->channels = 3; | 3829 row_info->channels = 3; |
4677 } | 3830 } |
| 3831 break; |
4678 } | 3832 } |
4679 } | 3833 } |
4680 } | 3834 } |
4681 } | 3835 } |
4682 | 3836 |
4683 /* If the bit depth < 8, it is expanded to 8. Also, if the already | 3837 /* If the bit depth < 8, it is expanded to 8. Also, if the already |
4684 * expanded transparency value is supplied, an alpha channel is built. | 3838 * expanded transparency value is supplied, an alpha channel is built. |
4685 */ | 3839 */ |
4686 void /* PRIVATE */ | 3840 void /* PRIVATE */ |
4687 png_do_expand(png_row_infop row_info, png_bytep row, | 3841 png_do_expand(png_row_infop row_info, png_bytep row, |
4688 png_const_color_16p trans_color) | 3842 png_color_16p trans_value) |
4689 { | 3843 { |
4690 int shift, value; | 3844 int shift, value; |
4691 png_bytep sp, dp; | 3845 png_bytep sp, dp; |
4692 png_uint_32 i; | 3846 png_uint_32 i; |
4693 png_uint_32 row_width=row_info->width; | 3847 png_uint_32 row_width=row_info->width; |
4694 | 3848 |
4695 png_debug(1, "in png_do_expand"); | 3849 png_debug(1, "in png_do_expand"); |
4696 | 3850 |
| 3851 #ifdef PNG_USELESS_TESTS_SUPPORTED |
| 3852 if (row != NULL && row_info != NULL) |
| 3853 #endif |
4697 { | 3854 { |
4698 if (row_info->color_type == PNG_COLOR_TYPE_GRAY) | 3855 if (row_info->color_type == PNG_COLOR_TYPE_GRAY) |
4699 { | 3856 { |
4700 unsigned int gray = trans_color ? trans_color->gray : 0; | 3857 png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0); |
4701 | 3858 |
4702 if (row_info->bit_depth < 8) | 3859 if (row_info->bit_depth < 8) |
4703 { | 3860 { |
4704 switch (row_info->bit_depth) | 3861 switch (row_info->bit_depth) |
4705 { | 3862 { |
4706 case 1: | 3863 case 1: |
4707 { | 3864 { |
4708 gray = (gray & 0x01) * 0xff; | 3865 gray = (png_uint_16)((gray&0x01)*0xff); |
4709 sp = row + (png_size_t)((row_width - 1) >> 3); | 3866 sp = row + (png_size_t)((row_width - 1) >> 3); |
4710 dp = row + (png_size_t)row_width - 1; | 3867 dp = row + (png_size_t)row_width - 1; |
4711 shift = 7 - (int)((row_width + 7) & 0x07); | 3868 shift = 7 - (int)((row_width + 7) & 0x07); |
4712 for (i = 0; i < row_width; i++) | 3869 for (i = 0; i < row_width; i++) |
4713 { | 3870 { |
4714 if ((*sp >> shift) & 0x01) | 3871 if ((*sp >> shift) & 0x01) |
4715 *dp = 0xff; | 3872 *dp = 0xff; |
4716 | |
4717 else | 3873 else |
4718 *dp = 0; | 3874 *dp = 0; |
4719 | |
4720 if (shift == 7) | 3875 if (shift == 7) |
4721 { | 3876 { |
4722 shift = 0; | 3877 shift = 0; |
4723 sp--; | 3878 sp--; |
4724 } | 3879 } |
4725 | |
4726 else | 3880 else |
4727 shift++; | 3881 shift++; |
4728 | 3882 |
4729 dp--; | 3883 dp--; |
4730 } | 3884 } |
4731 break; | 3885 break; |
4732 } | 3886 } |
4733 | 3887 |
4734 case 2: | 3888 case 2: |
4735 { | 3889 { |
4736 gray = (gray & 0x03) * 0x55; | 3890 gray = (png_uint_16)((gray&0x03)*0x55); |
4737 sp = row + (png_size_t)((row_width - 1) >> 2); | 3891 sp = row + (png_size_t)((row_width - 1) >> 2); |
4738 dp = row + (png_size_t)row_width - 1; | 3892 dp = row + (png_size_t)row_width - 1; |
4739 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); | 3893 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); |
4740 for (i = 0; i < row_width; i++) | 3894 for (i = 0; i < row_width; i++) |
4741 { | 3895 { |
4742 value = (*sp >> shift) & 0x03; | 3896 value = (*sp >> shift) & 0x03; |
4743 *dp = (png_byte)(value | (value << 2) | (value << 4) | | 3897 *dp = (png_byte)(value | (value << 2) | (value << 4) | |
4744 (value << 6)); | 3898 (value << 6)); |
4745 if (shift == 6) | 3899 if (shift == 6) |
4746 { | 3900 { |
4747 shift = 0; | 3901 shift = 0; |
4748 sp--; | 3902 sp--; |
4749 } | 3903 } |
4750 | |
4751 else | 3904 else |
4752 shift += 2; | 3905 shift += 2; |
4753 | 3906 |
4754 dp--; | 3907 dp--; |
4755 } | 3908 } |
4756 break; | 3909 break; |
4757 } | 3910 } |
4758 | 3911 |
4759 case 4: | 3912 case 4: |
4760 { | 3913 { |
4761 gray = (gray & 0x0f) * 0x11; | 3914 gray = (png_uint_16)((gray&0x0f)*0x11); |
4762 sp = row + (png_size_t)((row_width - 1) >> 1); | 3915 sp = row + (png_size_t)((row_width - 1) >> 1); |
4763 dp = row + (png_size_t)row_width - 1; | 3916 dp = row + (png_size_t)row_width - 1; |
4764 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); | 3917 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); |
4765 for (i = 0; i < row_width; i++) | 3918 for (i = 0; i < row_width; i++) |
4766 { | 3919 { |
4767 value = (*sp >> shift) & 0x0f; | 3920 value = (*sp >> shift) & 0x0f; |
4768 *dp = (png_byte)(value | (value << 4)); | 3921 *dp = (png_byte)(value | (value << 4)); |
4769 if (shift == 4) | 3922 if (shift == 4) |
4770 { | 3923 { |
4771 shift = 0; | 3924 shift = 0; |
4772 sp--; | 3925 sp--; |
4773 } | 3926 } |
4774 | |
4775 else | 3927 else |
4776 shift = 4; | 3928 shift = 4; |
4777 | 3929 |
4778 dp--; | 3930 dp--; |
4779 } | 3931 } |
4780 break; | 3932 break; |
4781 } | 3933 } |
4782 | |
4783 default: | |
4784 break; | |
4785 } | 3934 } |
4786 | 3935 |
4787 row_info->bit_depth = 8; | 3936 row_info->bit_depth = 8; |
4788 row_info->pixel_depth = 8; | 3937 row_info->pixel_depth = 8; |
4789 row_info->rowbytes = row_width; | 3938 row_info->rowbytes = row_width; |
4790 } | 3939 } |
4791 | 3940 |
4792 if (trans_color != NULL) | 3941 if (trans_value != NULL) |
4793 { | 3942 { |
4794 if (row_info->bit_depth == 8) | 3943 if (row_info->bit_depth == 8) |
4795 { | 3944 { |
4796 gray = gray & 0xff; | 3945 gray = gray & 0xff; |
4797 sp = row + (png_size_t)row_width - 1; | 3946 sp = row + (png_size_t)row_width - 1; |
4798 dp = row + (png_size_t)(row_width << 1) - 1; | 3947 dp = row + (png_size_t)(row_width << 1) - 1; |
4799 | |
4800 for (i = 0; i < row_width; i++) | 3948 for (i = 0; i < row_width; i++) |
4801 { | 3949 { |
4802 if (*sp == gray) | 3950 if (*sp == gray) |
4803 *dp-- = 0; | 3951 *dp-- = 0; |
4804 | |
4805 else | 3952 else |
4806 *dp-- = 0xff; | 3953 *dp-- = 0xff; |
4807 | |
4808 *dp-- = *sp--; | 3954 *dp-- = *sp--; |
4809 } | 3955 } |
4810 } | 3956 } |
4811 | 3957 |
4812 else if (row_info->bit_depth == 16) | 3958 else if (row_info->bit_depth == 16) |
4813 { | 3959 { |
4814 unsigned int gray_high = (gray >> 8) & 0xff; | 3960 png_byte gray_high = (gray >> 8) & 0xff; |
4815 unsigned int gray_low = gray & 0xff; | 3961 png_byte gray_low = gray & 0xff; |
4816 sp = row + row_info->rowbytes - 1; | 3962 sp = row + row_info->rowbytes - 1; |
4817 dp = row + (row_info->rowbytes << 1) - 1; | 3963 dp = row + (row_info->rowbytes << 1) - 1; |
4818 for (i = 0; i < row_width; i++) | 3964 for (i = 0; i < row_width; i++) |
4819 { | 3965 { |
4820 if (*(sp - 1) == gray_high && *(sp) == gray_low) | 3966 if (*(sp - 1) == gray_high && *(sp) == gray_low) |
4821 { | 3967 { |
4822 *dp-- = 0; | 3968 *dp-- = 0; |
4823 *dp-- = 0; | 3969 *dp-- = 0; |
4824 } | 3970 } |
4825 | |
4826 else | 3971 else |
4827 { | 3972 { |
4828 *dp-- = 0xff; | 3973 *dp-- = 0xff; |
4829 *dp-- = 0xff; | 3974 *dp-- = 0xff; |
4830 } | 3975 } |
4831 | |
4832 *dp-- = *sp--; | 3976 *dp-- = *sp--; |
4833 *dp-- = *sp--; | 3977 *dp-- = *sp--; |
4834 } | 3978 } |
4835 } | 3979 } |
4836 | 3980 |
4837 row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA; | 3981 row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA; |
4838 row_info->channels = 2; | 3982 row_info->channels = 2; |
4839 row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1); | 3983 row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1); |
4840 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, | 3984 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, |
4841 row_width); | 3985 row_width); |
4842 } | 3986 } |
4843 } | 3987 } |
4844 else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_color) | 3988 else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value) |
4845 { | 3989 { |
4846 if (row_info->bit_depth == 8) | 3990 if (row_info->bit_depth == 8) |
4847 { | 3991 { |
4848 png_byte red = (png_byte)(trans_color->red & 0xff); | 3992 png_byte red = trans_value->red & 0xff; |
4849 png_byte green = (png_byte)(trans_color->green & 0xff); | 3993 png_byte green = trans_value->green & 0xff; |
4850 png_byte blue = (png_byte)(trans_color->blue & 0xff); | 3994 png_byte blue = trans_value->blue & 0xff; |
4851 sp = row + (png_size_t)row_info->rowbytes - 1; | 3995 sp = row + (png_size_t)row_info->rowbytes - 1; |
4852 dp = row + (png_size_t)(row_width << 2) - 1; | 3996 dp = row + (png_size_t)(row_width << 2) - 1; |
4853 for (i = 0; i < row_width; i++) | 3997 for (i = 0; i < row_width; i++) |
4854 { | 3998 { |
4855 if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue) | 3999 if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue) |
4856 *dp-- = 0; | 4000 *dp-- = 0; |
4857 | |
4858 else | 4001 else |
4859 *dp-- = 0xff; | 4002 *dp-- = 0xff; |
4860 | |
4861 *dp-- = *sp--; | 4003 *dp-- = *sp--; |
4862 *dp-- = *sp--; | 4004 *dp-- = *sp--; |
4863 *dp-- = *sp--; | 4005 *dp-- = *sp--; |
4864 } | 4006 } |
4865 } | 4007 } |
4866 else if (row_info->bit_depth == 16) | 4008 else if (row_info->bit_depth == 16) |
4867 { | 4009 { |
4868 png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff); | 4010 png_byte red_high = (trans_value->red >> 8) & 0xff; |
4869 png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff); | 4011 png_byte green_high = (trans_value->green >> 8) & 0xff; |
4870 png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff); | 4012 png_byte blue_high = (trans_value->blue >> 8) & 0xff; |
4871 png_byte red_low = (png_byte)(trans_color->red & 0xff); | 4013 png_byte red_low = trans_value->red & 0xff; |
4872 png_byte green_low = (png_byte)(trans_color->green & 0xff); | 4014 png_byte green_low = trans_value->green & 0xff; |
4873 png_byte blue_low = (png_byte)(trans_color->blue & 0xff); | 4015 png_byte blue_low = trans_value->blue & 0xff; |
4874 sp = row + row_info->rowbytes - 1; | 4016 sp = row + row_info->rowbytes - 1; |
4875 dp = row + (png_size_t)(row_width << 3) - 1; | 4017 dp = row + (png_size_t)(row_width << 3) - 1; |
4876 for (i = 0; i < row_width; i++) | 4018 for (i = 0; i < row_width; i++) |
4877 { | 4019 { |
4878 if (*(sp - 5) == red_high && | 4020 if (*(sp - 5) == red_high && |
4879 *(sp - 4) == red_low && | 4021 *(sp - 4) == red_low && |
4880 *(sp - 3) == green_high && | 4022 *(sp - 3) == green_high && |
4881 *(sp - 2) == green_low && | 4023 *(sp - 2) == green_low && |
4882 *(sp - 1) == blue_high && | 4024 *(sp - 1) == blue_high && |
4883 *(sp ) == blue_low) | 4025 *(sp ) == blue_low) |
4884 { | 4026 { |
4885 *dp-- = 0; | 4027 *dp-- = 0; |
4886 *dp-- = 0; | 4028 *dp-- = 0; |
4887 } | 4029 } |
4888 | |
4889 else | 4030 else |
4890 { | 4031 { |
4891 *dp-- = 0xff; | 4032 *dp-- = 0xff; |
4892 *dp-- = 0xff; | 4033 *dp-- = 0xff; |
4893 } | 4034 } |
4894 | |
4895 *dp-- = *sp--; | 4035 *dp-- = *sp--; |
4896 *dp-- = *sp--; | 4036 *dp-- = *sp--; |
4897 *dp-- = *sp--; | 4037 *dp-- = *sp--; |
4898 *dp-- = *sp--; | 4038 *dp-- = *sp--; |
4899 *dp-- = *sp--; | 4039 *dp-- = *sp--; |
4900 *dp-- = *sp--; | 4040 *dp-- = *sp--; |
4901 } | 4041 } |
4902 } | 4042 } |
4903 row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA; | 4043 row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA; |
4904 row_info->channels = 4; | 4044 row_info->channels = 4; |
4905 row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2); | 4045 row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2); |
4906 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); | 4046 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); |
4907 } | 4047 } |
4908 } | 4048 } |
4909 } | 4049 } |
4910 #endif | 4050 #endif |
4911 | 4051 |
4912 #ifdef PNG_READ_EXPAND_16_SUPPORTED | 4052 #ifdef PNG_READ_DITHER_SUPPORTED |
4913 /* If the bit depth is 8 and the color type is not a palette type expand the | |
4914 * whole row to 16 bits. Has no effect otherwise. | |
4915 */ | |
4916 void /* PRIVATE */ | 4053 void /* PRIVATE */ |
4917 png_do_expand_16(png_row_infop row_info, png_bytep row) | 4054 png_do_dither(png_row_infop row_info, png_bytep row, |
4918 { | 4055 png_bytep palette_lookup, png_bytep dither_lookup) |
4919 if (row_info->bit_depth == 8 && | |
4920 row_info->color_type != PNG_COLOR_TYPE_PALETTE) | |
4921 { | |
4922 /* The row have a sequence of bytes containing [0..255] and we need | |
4923 * to turn it into another row containing [0..65535], to do this we | |
4924 * calculate: | |
4925 * | |
4926 * (input / 255) * 65535 | |
4927 * | |
4928 * Which happens to be exactly input * 257 and this can be achieved | |
4929 * simply by byte replication in place (copying backwards). | |
4930 */ | |
4931 png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */ | |
4932 png_byte *dp = sp + row_info->rowbytes; /* destination, end + 1 */ | |
4933 while (dp > sp) | |
4934 dp[-2] = dp[-1] = *--sp, dp -= 2; | |
4935 | |
4936 row_info->rowbytes *= 2; | |
4937 row_info->bit_depth = 16; | |
4938 row_info->pixel_depth = (png_byte)(row_info->channels * 16); | |
4939 } | |
4940 } | |
4941 #endif | |
4942 | |
4943 #ifdef PNG_READ_QUANTIZE_SUPPORTED | |
4944 void /* PRIVATE */ | |
4945 png_do_quantize(png_row_infop row_info, png_bytep row, | |
4946 png_const_bytep palette_lookup, png_const_bytep quantize_lookup) | |
4947 { | 4056 { |
4948 png_bytep sp, dp; | 4057 png_bytep sp, dp; |
4949 png_uint_32 i; | 4058 png_uint_32 i; |
4950 png_uint_32 row_width=row_info->width; | 4059 png_uint_32 row_width=row_info->width; |
4951 | 4060 |
4952 png_debug(1, "in png_do_quantize"); | 4061 png_debug(1, "in png_do_dither"); |
4953 | 4062 |
4954 if (row_info->bit_depth == 8) | 4063 #ifdef PNG_USELESS_TESTS_SUPPORTED |
| 4064 if (row != NULL && row_info != NULL) |
| 4065 #endif |
4955 { | 4066 { |
4956 if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup) | 4067 if (row_info->color_type == PNG_COLOR_TYPE_RGB && |
| 4068 palette_lookup && row_info->bit_depth == 8) |
4957 { | 4069 { |
4958 int r, g, b, p; | 4070 int r, g, b, p; |
4959 sp = row; | 4071 sp = row; |
4960 dp = row; | 4072 dp = row; |
4961 for (i = 0; i < row_width; i++) | 4073 for (i = 0; i < row_width; i++) |
4962 { | 4074 { |
4963 r = *sp++; | 4075 r = *sp++; |
4964 g = *sp++; | 4076 g = *sp++; |
4965 b = *sp++; | 4077 b = *sp++; |
4966 | 4078 |
4967 /* This looks real messy, but the compiler will reduce | 4079 /* This looks real messy, but the compiler will reduce |
4968 * it down to a reasonable formula. For example, with | 4080 * it down to a reasonable formula. For example, with |
4969 * 5 bits per color, we get: | 4081 * 5 bits per color, we get: |
4970 * p = (((r >> 3) & 0x1f) << 10) | | 4082 * p = (((r >> 3) & 0x1f) << 10) | |
4971 * (((g >> 3) & 0x1f) << 5) | | 4083 * (((g >> 3) & 0x1f) << 5) | |
4972 * ((b >> 3) & 0x1f); | 4084 * ((b >> 3) & 0x1f); |
4973 */ | 4085 */ |
4974 p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) & | 4086 p = (((r >> (8 - PNG_DITHER_RED_BITS)) & |
4975 ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << | 4087 ((1 << PNG_DITHER_RED_BITS) - 1)) << |
4976 (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | | 4088 (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) | |
4977 (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & | 4089 (((g >> (8 - PNG_DITHER_GREEN_BITS)) & |
4978 ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << | 4090 ((1 << PNG_DITHER_GREEN_BITS) - 1)) << |
4979 (PNG_QUANTIZE_BLUE_BITS)) | | 4091 (PNG_DITHER_BLUE_BITS)) | |
4980 ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & | 4092 ((b >> (8 - PNG_DITHER_BLUE_BITS)) & |
4981 ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); | 4093 ((1 << PNG_DITHER_BLUE_BITS) - 1)); |
4982 | 4094 |
4983 *dp++ = palette_lookup[p]; | 4095 *dp++ = palette_lookup[p]; |
4984 } | 4096 } |
4985 | |
4986 row_info->color_type = PNG_COLOR_TYPE_PALETTE; | 4097 row_info->color_type = PNG_COLOR_TYPE_PALETTE; |
4987 row_info->channels = 1; | 4098 row_info->channels = 1; |
4988 row_info->pixel_depth = row_info->bit_depth; | 4099 row_info->pixel_depth = row_info->bit_depth; |
4989 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); | 4100 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); |
4990 } | 4101 } |
4991 | |
4992 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA && | 4102 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA && |
4993 palette_lookup != NULL) | 4103 palette_lookup != NULL && row_info->bit_depth == 8) |
4994 { | 4104 { |
4995 int r, g, b, p; | 4105 int r, g, b, p; |
4996 sp = row; | 4106 sp = row; |
4997 dp = row; | 4107 dp = row; |
4998 for (i = 0; i < row_width; i++) | 4108 for (i = 0; i < row_width; i++) |
4999 { | 4109 { |
5000 r = *sp++; | 4110 r = *sp++; |
5001 g = *sp++; | 4111 g = *sp++; |
5002 b = *sp++; | 4112 b = *sp++; |
5003 sp++; | 4113 sp++; |
5004 | 4114 |
5005 p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) & | 4115 p = (((r >> (8 - PNG_DITHER_RED_BITS)) & |
5006 ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << | 4116 ((1 << PNG_DITHER_RED_BITS) - 1)) << |
5007 (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | | 4117 (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) | |
5008 (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & | 4118 (((g >> (8 - PNG_DITHER_GREEN_BITS)) & |
5009 ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << | 4119 ((1 << PNG_DITHER_GREEN_BITS) - 1)) << |
5010 (PNG_QUANTIZE_BLUE_BITS)) | | 4120 (PNG_DITHER_BLUE_BITS)) | |
5011 ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & | 4121 ((b >> (8 - PNG_DITHER_BLUE_BITS)) & |
5012 ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); | 4122 ((1 << PNG_DITHER_BLUE_BITS) - 1)); |
5013 | 4123 |
5014 *dp++ = palette_lookup[p]; | 4124 *dp++ = palette_lookup[p]; |
5015 } | 4125 } |
5016 | |
5017 row_info->color_type = PNG_COLOR_TYPE_PALETTE; | 4126 row_info->color_type = PNG_COLOR_TYPE_PALETTE; |
5018 row_info->channels = 1; | 4127 row_info->channels = 1; |
5019 row_info->pixel_depth = row_info->bit_depth; | 4128 row_info->pixel_depth = row_info->bit_depth; |
5020 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); | 4129 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); |
5021 } | 4130 } |
5022 | |
5023 else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && | 4131 else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && |
5024 quantize_lookup) | 4132 dither_lookup && row_info->bit_depth == 8) |
5025 { | 4133 { |
5026 sp = row; | 4134 sp = row; |
5027 | |
5028 for (i = 0; i < row_width; i++, sp++) | 4135 for (i = 0; i < row_width; i++, sp++) |
5029 { | 4136 { |
5030 *sp = quantize_lookup[*sp]; | 4137 *sp = dither_lookup[*sp]; |
5031 } | 4138 } |
5032 } | 4139 } |
5033 } | 4140 } |
5034 } | 4141 } |
5035 #endif /* PNG_READ_QUANTIZE_SUPPORTED */ | 4142 #endif |
5036 #endif /* PNG_READ_TRANSFORMS_SUPPORTED */ | 4143 |
| 4144 #ifdef PNG_FLOATING_POINT_SUPPORTED |
| 4145 #ifdef PNG_READ_GAMMA_SUPPORTED |
| 4146 static PNG_CONST int png_gamma_shift[] = |
| 4147 {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00}; |
| 4148 |
| 4149 /* We build the 8- or 16-bit gamma tables here. Note that for 16-bit |
| 4150 * tables, we don't make a full table if we are reducing to 8-bit in |
| 4151 * the future. Note also how the gamma_16 tables are segmented so that |
| 4152 * we don't need to allocate > 64K chunks for a full 16-bit table. |
| 4153 * |
| 4154 * See the PNG extensions document for an integer algorithm for creating |
| 4155 * the gamma tables. Maybe we will implement that here someday. |
| 4156 * |
| 4157 * We should only reach this point if |
| 4158 * |
| 4159 * the file_gamma is known (i.e., the gAMA or sRGB chunk is present, |
| 4160 * or the application has provided a file_gamma) |
| 4161 * |
| 4162 * AND |
| 4163 * { |
| 4164 * the screen_gamma is known |
| 4165 * OR |
| 4166 * |
| 4167 * RGB_to_gray transformation is being performed |
| 4168 * } |
| 4169 * |
| 4170 * AND |
| 4171 * { |
| 4172 * the screen_gamma is different from the reciprocal of the |
| 4173 * file_gamma by more than the specified threshold |
| 4174 * |
| 4175 * OR |
| 4176 * |
| 4177 * a background color has been specified and the file_gamma |
| 4178 * and screen_gamma are not 1.0, within the specified threshold. |
| 4179 * } |
| 4180 */ |
| 4181 |
| 4182 void /* PRIVATE */ |
| 4183 png_build_gamma_table(png_structp png_ptr) |
| 4184 { |
| 4185 png_debug(1, "in png_build_gamma_table"); |
| 4186 |
| 4187 if (png_ptr->bit_depth <= 8) |
| 4188 { |
| 4189 int i; |
| 4190 double g; |
| 4191 |
| 4192 if (png_ptr->screen_gamma > .000001) |
| 4193 g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); |
| 4194 |
| 4195 else |
| 4196 g = 1.0; |
| 4197 |
| 4198 png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr, |
| 4199 (png_uint_32)256); |
| 4200 |
| 4201 for (i = 0; i < 256; i++) |
| 4202 { |
| 4203 png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0, |
| 4204 g) * 255.0 + .5); |
| 4205 } |
| 4206 |
| 4207 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ |
| 4208 defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) |
| 4209 if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY)) |
| 4210 { |
| 4211 |
| 4212 g = 1.0 / (png_ptr->gamma); |
| 4213 |
| 4214 png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr, |
| 4215 (png_uint_32)256); |
| 4216 |
| 4217 for (i = 0; i < 256; i++) |
| 4218 { |
| 4219 png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0, |
| 4220 g) * 255.0 + .5); |
| 4221 } |
| 4222 |
| 4223 |
| 4224 png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr, |
| 4225 (png_uint_32)256); |
| 4226 |
| 4227 if (png_ptr->screen_gamma > 0.000001) |
| 4228 g = 1.0 / png_ptr->screen_gamma; |
| 4229 |
| 4230 else |
| 4231 g = png_ptr->gamma; /* Probably doing rgb_to_gray */ |
| 4232 |
| 4233 for (i = 0; i < 256; i++) |
| 4234 { |
| 4235 png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0, |
| 4236 g) * 255.0 + .5); |
| 4237 |
| 4238 } |
| 4239 } |
| 4240 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */ |
| 4241 } |
| 4242 else |
| 4243 { |
| 4244 double g; |
| 4245 int i, j, shift, num; |
| 4246 int sig_bit; |
| 4247 png_uint_32 ig; |
| 4248 |
| 4249 if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) |
| 4250 { |
| 4251 sig_bit = (int)png_ptr->sig_bit.red; |
| 4252 |
| 4253 if ((int)png_ptr->sig_bit.green > sig_bit) |
| 4254 sig_bit = png_ptr->sig_bit.green; |
| 4255 |
| 4256 if ((int)png_ptr->sig_bit.blue > sig_bit) |
| 4257 sig_bit = png_ptr->sig_bit.blue; |
| 4258 } |
| 4259 else |
| 4260 { |
| 4261 sig_bit = (int)png_ptr->sig_bit.gray; |
| 4262 } |
| 4263 |
| 4264 if (sig_bit > 0) |
| 4265 shift = 16 - sig_bit; |
| 4266 |
| 4267 else |
| 4268 shift = 0; |
| 4269 |
| 4270 if (png_ptr->transformations & PNG_16_TO_8) |
| 4271 { |
| 4272 if (shift < (16 - PNG_MAX_GAMMA_8)) |
| 4273 shift = (16 - PNG_MAX_GAMMA_8); |
| 4274 } |
| 4275 |
| 4276 if (shift > 8) |
| 4277 shift = 8; |
| 4278 |
| 4279 if (shift < 0) |
| 4280 shift = 0; |
| 4281 |
| 4282 png_ptr->gamma_shift = (png_byte)shift; |
| 4283 |
| 4284 num = (1 << (8 - shift)); |
| 4285 |
| 4286 if (png_ptr->screen_gamma > .000001) |
| 4287 g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); |
| 4288 else |
| 4289 g = 1.0; |
| 4290 |
| 4291 png_ptr->gamma_16_table = (png_uint_16pp)png_calloc(png_ptr, |
| 4292 (png_uint_32)(num * png_sizeof(png_uint_16p))); |
| 4293 |
| 4294 if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND)) |
| 4295 { |
| 4296 double fin, fout; |
| 4297 png_uint_32 last, max; |
| 4298 |
| 4299 for (i = 0; i < num; i++) |
| 4300 { |
| 4301 png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr, |
| 4302 (png_uint_32)(256 * png_sizeof(png_uint_16))); |
| 4303 } |
| 4304 |
| 4305 g = 1.0 / g; |
| 4306 last = 0; |
| 4307 for (i = 0; i < 256; i++) |
| 4308 { |
| 4309 fout = ((double)i + 0.5) / 256.0; |
| 4310 fin = pow(fout, g); |
| 4311 max = (png_uint_32)(fin * (double)((png_uint_32)num << 8)); |
| 4312 while (last <= max) |
| 4313 { |
| 4314 png_ptr->gamma_16_table[(int)(last & (0xff >> shift))] |
| 4315 [(int)(last >> (8 - shift))] = (png_uint_16)( |
| 4316 (png_uint_16)i | ((png_uint_16)i << 8)); |
| 4317 last++; |
| 4318 } |
| 4319 } |
| 4320 while (last < ((png_uint_32)num << 8)) |
| 4321 { |
| 4322 png_ptr->gamma_16_table[(int)(last & (0xff >> shift))] |
| 4323 [(int)(last >> (8 - shift))] = (png_uint_16)65535L; |
| 4324 last++; |
| 4325 } |
| 4326 } |
| 4327 else |
| 4328 { |
| 4329 for (i = 0; i < num; i++) |
| 4330 { |
| 4331 png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr, |
| 4332 (png_uint_32)(256 * png_sizeof(png_uint_16))); |
| 4333 |
| 4334 ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4); |
| 4335 |
| 4336 for (j = 0; j < 256; j++) |
| 4337 { |
| 4338 png_ptr->gamma_16_table[i][j] = |
| 4339 (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) / |
| 4340 65535.0, g) * 65535.0 + .5); |
| 4341 } |
| 4342 } |
| 4343 } |
| 4344 |
| 4345 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ |
| 4346 defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) |
| 4347 if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY)) |
| 4348 { |
| 4349 |
| 4350 g = 1.0 / (png_ptr->gamma); |
| 4351 |
| 4352 png_ptr->gamma_16_to_1 = (png_uint_16pp)png_calloc(png_ptr, |
| 4353 (png_uint_32)(num * png_sizeof(png_uint_16p ))); |
| 4354 |
| 4355 for (i = 0; i < num; i++) |
| 4356 { |
| 4357 png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr, |
| 4358 (png_uint_32)(256 * png_sizeof(png_uint_16))); |
| 4359 |
| 4360 ig = (((png_uint_32)i * |
| 4361 (png_uint_32)png_gamma_shift[shift]) >> 4); |
| 4362 for (j = 0; j < 256; j++) |
| 4363 { |
| 4364 png_ptr->gamma_16_to_1[i][j] = |
| 4365 (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) / |
| 4366 65535.0, g) * 65535.0 + .5); |
| 4367 } |
| 4368 } |
| 4369 |
| 4370 if (png_ptr->screen_gamma > 0.000001) |
| 4371 g = 1.0 / png_ptr->screen_gamma; |
| 4372 |
| 4373 else |
| 4374 g = png_ptr->gamma; /* Probably doing rgb_to_gray */ |
| 4375 |
| 4376 png_ptr->gamma_16_from_1 = (png_uint_16pp)png_calloc(png_ptr, |
| 4377 (png_uint_32)(num * png_sizeof(png_uint_16p))); |
| 4378 |
| 4379 for (i = 0; i < num; i++) |
| 4380 { |
| 4381 png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr, |
| 4382 (png_uint_32)(256 * png_sizeof(png_uint_16))); |
| 4383 |
| 4384 ig = (((png_uint_32)i * |
| 4385 (png_uint_32)png_gamma_shift[shift]) >> 4); |
| 4386 |
| 4387 for (j = 0; j < 256; j++) |
| 4388 { |
| 4389 png_ptr->gamma_16_from_1[i][j] = |
| 4390 (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) / |
| 4391 65535.0, g) * 65535.0 + .5); |
| 4392 } |
| 4393 } |
| 4394 } |
| 4395 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */ |
| 4396 } |
| 4397 } |
| 4398 #endif |
| 4399 /* To do: install integer version of png_build_gamma_table here */ |
| 4400 #endif |
5037 | 4401 |
5038 #ifdef PNG_MNG_FEATURES_SUPPORTED | 4402 #ifdef PNG_MNG_FEATURES_SUPPORTED |
5039 /* Undoes intrapixel differencing */ | 4403 /* Undoes intrapixel differencing */ |
5040 void /* PRIVATE */ | 4404 void /* PRIVATE */ |
5041 png_do_read_intrapixel(png_row_infop row_info, png_bytep row) | 4405 png_do_read_intrapixel(png_row_infop row_info, png_bytep row) |
5042 { | 4406 { |
5043 png_debug(1, "in png_do_read_intrapixel"); | 4407 png_debug(1, "in png_do_read_intrapixel"); |
5044 | 4408 |
5045 if ( | 4409 if ( |
| 4410 #ifdef PNG_USELESS_TESTS_SUPPORTED |
| 4411 row != NULL && row_info != NULL && |
| 4412 #endif |
5046 (row_info->color_type & PNG_COLOR_MASK_COLOR)) | 4413 (row_info->color_type & PNG_COLOR_MASK_COLOR)) |
5047 { | 4414 { |
5048 int bytes_per_pixel; | 4415 int bytes_per_pixel; |
5049 png_uint_32 row_width = row_info->width; | 4416 png_uint_32 row_width = row_info->width; |
5050 | |
5051 if (row_info->bit_depth == 8) | 4417 if (row_info->bit_depth == 8) |
5052 { | 4418 { |
5053 png_bytep rp; | 4419 png_bytep rp; |
5054 png_uint_32 i; | 4420 png_uint_32 i; |
5055 | 4421 |
5056 if (row_info->color_type == PNG_COLOR_TYPE_RGB) | 4422 if (row_info->color_type == PNG_COLOR_TYPE_RGB) |
5057 bytes_per_pixel = 3; | 4423 bytes_per_pixel = 3; |
5058 | 4424 |
5059 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) | 4425 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) |
5060 bytes_per_pixel = 4; | 4426 bytes_per_pixel = 4; |
5061 | 4427 |
5062 else | 4428 else |
5063 return; | 4429 return; |
5064 | 4430 |
5065 for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) | 4431 for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) |
5066 { | 4432 { |
5067 *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff); | 4433 *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff); |
5068 *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff); | 4434 *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff); |
5069 } | 4435 } |
5070 } | 4436 } |
5071 else if (row_info->bit_depth == 16) | 4437 else if (row_info->bit_depth == 16) |
5072 { | 4438 { |
5073 png_bytep rp; | 4439 png_bytep rp; |
5074 png_uint_32 i; | 4440 png_uint_32 i; |
5075 | 4441 |
5076 if (row_info->color_type == PNG_COLOR_TYPE_RGB) | 4442 if (row_info->color_type == PNG_COLOR_TYPE_RGB) |
5077 bytes_per_pixel = 6; | 4443 bytes_per_pixel = 6; |
5078 | 4444 |
5079 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) | 4445 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) |
5080 bytes_per_pixel = 8; | 4446 bytes_per_pixel = 8; |
5081 | 4447 |
5082 else | 4448 else |
5083 return; | 4449 return; |
5084 | 4450 |
5085 for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) | 4451 for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) |
5086 { | 4452 { |
5087 png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); | 4453 png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); |
5088 png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); | 4454 png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); |
5089 png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); | 4455 png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); |
5090 png_uint_32 red = (s0 + s1 + 65536) & 0xffff; | 4456 png_uint_32 red = (png_uint_32)((s0 + s1 + 65536L) & 0xffffL); |
5091 png_uint_32 blue = (s2 + s1 + 65536) & 0xffff; | 4457 png_uint_32 blue = (png_uint_32)((s2 + s1 + 65536L) & 0xffffL); |
5092 *(rp ) = (png_byte)((red >> 8) & 0xff); | 4458 *(rp ) = (png_byte)((red >> 8) & 0xff); |
5093 *(rp + 1) = (png_byte)(red & 0xff); | 4459 *(rp+1) = (png_byte)(red & 0xff); |
5094 *(rp + 4) = (png_byte)((blue >> 8) & 0xff); | 4460 *(rp+4) = (png_byte)((blue >> 8) & 0xff); |
5095 *(rp + 5) = (png_byte)(blue & 0xff); | 4461 *(rp+5) = (png_byte)(blue & 0xff); |
5096 } | 4462 } |
5097 } | 4463 } |
5098 } | 4464 } |
5099 } | 4465 } |
5100 #endif /* PNG_MNG_FEATURES_SUPPORTED */ | 4466 #endif /* PNG_MNG_FEATURES_SUPPORTED */ |
5101 #endif /* PNG_READ_SUPPORTED */ | 4467 #endif /* PNG_READ_SUPPORTED */ |
OLD | NEW |