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