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