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