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