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