changeset 30 | 5dc02b23752f |
parent 0 | 1918ee327afb |
29:b72c6db6890b | 30:5dc02b23752f |
---|---|
1 |
1 |
2 /* pngrtran.c - transforms the data in a row for PNG readers |
2 /* pngrtran.c - transforms the data in a row for PNG readers |
3 * |
3 * |
4 * Last changed in libpng 1.2.38 [July 16, 2009] |
4 * Last changed in libpng 1.4.0 [January 3, 2010] |
5 * Copyright (c) 1998-2009 Glenn Randers-Pehrson |
5 * Copyright (c) 1998-2010 Glenn Randers-Pehrson |
6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) |
6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) |
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) |
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) |
8 * |
8 * |
9 * This code is released under the libpng license. |
9 * This code is released under the libpng license. |
10 * For conditions of distribution and use, see the disclaimer |
10 * For conditions of distribution and use, see the disclaimer |
14 * in order to tell libpng how to handle data when reading a PNG. |
14 * in order to tell libpng how to handle data when reading a PNG. |
15 * Transformations that are used in both reading and writing are |
15 * Transformations that are used in both reading and writing are |
16 * in pngtrans.c. |
16 * in pngtrans.c. |
17 */ |
17 */ |
18 |
18 |
19 #define PNG_INTERNAL |
19 #define PNG_NO_PEDANTIC_WARNINGS |
20 #include "png.h" |
20 #include "png.h" |
21 #if defined(PNG_READ_SUPPORTED) |
21 #ifdef PNG_READ_SUPPORTED |
22 #include "pngpriv.h" |
|
22 |
23 |
23 /* Set the action on getting a CRC error for an ancillary or critical chunk. */ |
24 /* Set the action on getting a CRC error for an ancillary or critical chunk. */ |
24 void PNGAPI |
25 void PNGAPI |
25 png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action) |
26 png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action) |
26 { |
27 { |
27 png_debug(1, "in png_set_crc_action"); |
28 png_debug(1, "in png_set_crc_action"); |
28 /* Tell libpng how we react to CRC errors in critical chunks */ |
29 |
29 if (png_ptr == NULL) |
30 if (png_ptr == NULL) |
30 return; |
31 return; |
32 |
|
33 /* Tell libpng how we react to CRC errors in critical chunks */ |
|
31 switch (crit_action) |
34 switch (crit_action) |
32 { |
35 { |
33 case PNG_CRC_NO_CHANGE: /* Leave setting as is */ |
36 case PNG_CRC_NO_CHANGE: /* Leave setting as is */ |
34 break; |
37 break; |
35 |
38 |
44 PNG_FLAG_CRC_CRITICAL_IGNORE; |
47 PNG_FLAG_CRC_CRITICAL_IGNORE; |
45 break; |
48 break; |
46 |
49 |
47 case PNG_CRC_WARN_DISCARD: /* Not a valid action for critical data */ |
50 case PNG_CRC_WARN_DISCARD: /* Not a valid action for critical data */ |
48 png_warning(png_ptr, |
51 png_warning(png_ptr, |
49 "Can't discard critical data on CRC error."); |
52 "Can't discard critical data on CRC error"); |
50 case PNG_CRC_ERROR_QUIT: /* Error/quit */ |
53 case PNG_CRC_ERROR_QUIT: /* Error/quit */ |
51 |
54 |
52 case PNG_CRC_DEFAULT: |
55 case PNG_CRC_DEFAULT: |
53 default: |
56 default: |
54 png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; |
57 png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; |
55 break; |
58 break; |
56 } |
59 } |
57 |
60 |
61 /* Tell libpng how we react to CRC errors in ancillary chunks */ |
|
58 switch (ancil_action) |
62 switch (ancil_action) |
59 { |
63 { |
60 case PNG_CRC_NO_CHANGE: /* Leave setting as is */ |
64 case PNG_CRC_NO_CHANGE: /* Leave setting as is */ |
61 break; |
65 break; |
62 |
66 |
92 png_set_background(png_structp png_ptr, |
96 png_set_background(png_structp png_ptr, |
93 png_color_16p background_color, int background_gamma_code, |
97 png_color_16p background_color, int background_gamma_code, |
94 int need_expand, double background_gamma) |
98 int need_expand, double background_gamma) |
95 { |
99 { |
96 png_debug(1, "in png_set_background"); |
100 png_debug(1, "in png_set_background"); |
101 |
|
97 if (png_ptr == NULL) |
102 if (png_ptr == NULL) |
98 return; |
103 return; |
99 if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) |
104 if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) |
100 { |
105 { |
101 png_warning(png_ptr, "Application must supply a known background gamma"); |
106 png_warning(png_ptr, "Application must supply a known background gamma"); |
109 png_ptr->background_gamma_type = (png_byte)(background_gamma_code); |
114 png_ptr->background_gamma_type = (png_byte)(background_gamma_code); |
110 png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0); |
115 png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0); |
111 } |
116 } |
112 #endif |
117 #endif |
113 |
118 |
114 #if defined(PNG_READ_16_TO_8_SUPPORTED) |
119 #ifdef PNG_READ_16_TO_8_SUPPORTED |
115 /* Strip 16 bit depth files to 8 bit depth */ |
120 /* Strip 16 bit depth files to 8 bit depth */ |
116 void PNGAPI |
121 void PNGAPI |
117 png_set_strip_16(png_structp png_ptr) |
122 png_set_strip_16(png_structp png_ptr) |
118 { |
123 { |
119 png_debug(1, "in png_set_strip_16"); |
124 png_debug(1, "in png_set_strip_16"); |
125 |
|
120 if (png_ptr == NULL) |
126 if (png_ptr == NULL) |
121 return; |
127 return; |
122 png_ptr->transformations |= PNG_16_TO_8; |
128 png_ptr->transformations |= PNG_16_TO_8; |
123 } |
129 } |
124 #endif |
130 #endif |
125 |
131 |
126 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) |
132 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED |
127 void PNGAPI |
133 void PNGAPI |
128 png_set_strip_alpha(png_structp png_ptr) |
134 png_set_strip_alpha(png_structp png_ptr) |
129 { |
135 { |
130 png_debug(1, "in png_set_strip_alpha"); |
136 png_debug(1, "in png_set_strip_alpha"); |
137 |
|
131 if (png_ptr == NULL) |
138 if (png_ptr == NULL) |
132 return; |
139 return; |
133 png_ptr->flags |= PNG_FLAG_STRIP_ALPHA; |
140 png_ptr->flags |= PNG_FLAG_STRIP_ALPHA; |
134 } |
141 } |
135 #endif |
142 #endif |
136 |
143 |
137 #if defined(PNG_READ_DITHER_SUPPORTED) |
144 #ifdef PNG_READ_DITHER_SUPPORTED |
138 /* Dither file to 8 bit. Supply a palette, the current number |
145 /* Dither file to 8 bit. Supply a palette, the current number |
139 * of elements in the palette, the maximum number of elements |
146 * of elements in the palette, the maximum number of elements |
140 * allowed, and a histogram if possible. If the current number |
147 * allowed, and a histogram if possible. If the current number |
141 * of colors is greater then the maximum number, the palette will be |
148 * of colors is greater then the maximum number, the palette will be |
142 * modified to fit in the maximum number. "full_dither" indicates |
149 * modified to fit in the maximum number. "full_dither" indicates |
157 png_set_dither(png_structp png_ptr, png_colorp palette, |
164 png_set_dither(png_structp png_ptr, png_colorp palette, |
158 int num_palette, int maximum_colors, png_uint_16p histogram, |
165 int num_palette, int maximum_colors, png_uint_16p histogram, |
159 int full_dither) |
166 int full_dither) |
160 { |
167 { |
161 png_debug(1, "in png_set_dither"); |
168 png_debug(1, "in png_set_dither"); |
169 |
|
162 if (png_ptr == NULL) |
170 if (png_ptr == NULL) |
163 return; |
171 return; |
164 png_ptr->transformations |= PNG_DITHER; |
172 png_ptr->transformations |= PNG_DITHER; |
165 |
173 |
166 if (!full_dither) |
174 if (!full_dither) |
326 { |
334 { |
327 png_ptr->index_to_palette[i] = (png_byte)i; |
335 png_ptr->index_to_palette[i] = (png_byte)i; |
328 png_ptr->palette_to_index[i] = (png_byte)i; |
336 png_ptr->palette_to_index[i] = (png_byte)i; |
329 } |
337 } |
330 |
338 |
331 hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 * |
339 hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 * |
332 png_sizeof(png_dsortp))); |
340 png_sizeof(png_dsortp))); |
333 png_memset(hash, 0, 769 * png_sizeof(png_dsortp)); |
|
334 |
341 |
335 num_new_palette = num_palette; |
342 num_new_palette = num_palette; |
336 |
343 |
337 /* Initial wild guess at how far apart the farthest pixel |
344 /* Initial wild guess at how far apart the farthest pixel |
338 * pair we will be eliminating will be. Larger |
345 * pair we will be eliminating will be. Larger |
474 PNG_DITHER_BLUE_BITS; |
481 PNG_DITHER_BLUE_BITS; |
475 int num_red = (1 << PNG_DITHER_RED_BITS); |
482 int num_red = (1 << PNG_DITHER_RED_BITS); |
476 int num_green = (1 << PNG_DITHER_GREEN_BITS); |
483 int num_green = (1 << PNG_DITHER_GREEN_BITS); |
477 int num_blue = (1 << PNG_DITHER_BLUE_BITS); |
484 int num_blue = (1 << PNG_DITHER_BLUE_BITS); |
478 png_size_t num_entries = ((png_size_t)1 << total_bits); |
485 png_size_t num_entries = ((png_size_t)1 << total_bits); |
479 png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr, |
486 |
487 png_ptr->palette_lookup = (png_bytep )png_calloc(png_ptr, |
|
480 (png_uint_32)(num_entries * png_sizeof(png_byte))); |
488 (png_uint_32)(num_entries * png_sizeof(png_byte))); |
481 png_memset(png_ptr->palette_lookup, 0, num_entries * |
|
482 png_sizeof(png_byte)); |
|
483 |
489 |
484 distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * |
490 distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * |
485 png_sizeof(png_byte))); |
491 png_sizeof(png_byte))); |
486 |
|
487 png_memset(distance, 0xff, num_entries * png_sizeof(png_byte)); |
492 png_memset(distance, 0xff, num_entries * png_sizeof(png_byte)); |
488 |
493 |
489 for (i = 0; i < num_palette; i++) |
494 for (i = 0; i < num_palette; i++) |
490 { |
495 { |
491 int ir, ig, ib; |
496 int ir, ig, ib; |
542 */ |
547 */ |
543 void PNGAPI |
548 void PNGAPI |
544 png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma) |
549 png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma) |
545 { |
550 { |
546 png_debug(1, "in png_set_gamma"); |
551 png_debug(1, "in png_set_gamma"); |
552 |
|
547 if (png_ptr == NULL) |
553 if (png_ptr == NULL) |
548 return; |
554 return; |
555 |
|
549 if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) || |
556 if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) || |
550 (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) || |
557 (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) || |
551 (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) |
558 (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) |
552 png_ptr->transformations |= PNG_GAMMA; |
559 png_ptr->transformations |= PNG_GAMMA; |
553 png_ptr->gamma = (float)file_gamma; |
560 png_ptr->gamma = (float)file_gamma; |
554 png_ptr->screen_gamma = (float)scrn_gamma; |
561 png_ptr->screen_gamma = (float)scrn_gamma; |
555 } |
562 } |
556 #endif |
563 #endif |
557 |
564 |
558 #if defined(PNG_READ_EXPAND_SUPPORTED) |
565 #ifdef PNG_READ_EXPAND_SUPPORTED |
559 /* Expand paletted images to RGB, expand grayscale images of |
566 /* Expand paletted images to RGB, expand grayscale images of |
560 * less than 8-bit depth to 8-bit depth, and expand tRNS chunks |
567 * less than 8-bit depth to 8-bit depth, and expand tRNS chunks |
561 * to alpha channels. |
568 * to alpha channels. |
562 */ |
569 */ |
563 void PNGAPI |
570 void PNGAPI |
564 png_set_expand(png_structp png_ptr) |
571 png_set_expand(png_structp png_ptr) |
565 { |
572 { |
566 png_debug(1, "in png_set_expand"); |
573 png_debug(1, "in png_set_expand"); |
574 |
|
567 if (png_ptr == NULL) |
575 if (png_ptr == NULL) |
568 return; |
576 return; |
577 |
|
569 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); |
578 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); |
570 png_ptr->flags &= ~PNG_FLAG_ROW_INIT; |
579 png_ptr->flags &= ~PNG_FLAG_ROW_INIT; |
571 } |
580 } |
572 |
581 |
573 /* GRR 19990627: the following three functions currently are identical |
582 /* GRR 19990627: the following three functions currently are identical |
581 * functions. |
590 * functions. |
582 * |
591 * |
583 * More to the point, these functions make it obvious what libpng will be |
592 * More to the point, these functions make it obvious what libpng will be |
584 * doing, whereas "expand" can (and does) mean any number of things. |
593 * doing, whereas "expand" can (and does) mean any number of things. |
585 * |
594 * |
586 * GRP 20060307: In libpng-1.4.0, png_set_gray_1_2_4_to_8() was modified |
595 * GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified |
587 * to expand only the sample depth but not to expand the tRNS to alpha. |
596 * to expand only the sample depth but not to expand the tRNS to alpha |
597 * and its name was changed to png_set_expand_gray_1_2_4_to_8(). |
|
588 */ |
598 */ |
589 |
599 |
590 /* Expand paletted images to RGB. */ |
600 /* Expand paletted images to RGB. */ |
591 void PNGAPI |
601 void PNGAPI |
592 png_set_palette_to_rgb(png_structp png_ptr) |
602 png_set_palette_to_rgb(png_structp png_ptr) |
593 { |
603 { |
594 png_debug(1, "in png_set_palette_to_rgb"); |
604 png_debug(1, "in png_set_palette_to_rgb"); |
605 |
|
595 if (png_ptr == NULL) |
606 if (png_ptr == NULL) |
596 return; |
607 return; |
608 |
|
597 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); |
609 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); |
598 png_ptr->flags &= ~PNG_FLAG_ROW_INIT; |
610 png_ptr->flags &= ~PNG_FLAG_ROW_INIT; |
599 } |
611 } |
600 |
612 |
601 #if !defined(PNG_1_0_X) |
|
602 /* Expand grayscale images of less than 8-bit depth to 8 bits. */ |
613 /* Expand grayscale images of less than 8-bit depth to 8 bits. */ |
603 void PNGAPI |
614 void PNGAPI |
604 png_set_expand_gray_1_2_4_to_8(png_structp png_ptr) |
615 png_set_expand_gray_1_2_4_to_8(png_structp png_ptr) |
605 { |
616 { |
606 png_debug(1, "in png_set_expand_gray_1_2_4_to_8"); |
617 png_debug(1, "in png_set_expand_gray_1_2_4_to_8"); |
618 |
|
607 if (png_ptr == NULL) |
619 if (png_ptr == NULL) |
608 return; |
620 return; |
621 |
|
609 png_ptr->transformations |= PNG_EXPAND; |
622 png_ptr->transformations |= PNG_EXPAND; |
610 png_ptr->flags &= ~PNG_FLAG_ROW_INIT; |
623 png_ptr->flags &= ~PNG_FLAG_ROW_INIT; |
611 } |
624 } |
612 #endif |
625 |
613 |
|
614 #if defined(PNG_1_0_X) || defined(PNG_1_2_X) |
|
615 /* Expand grayscale images of less than 8-bit depth to 8 bits. */ |
|
616 /* Deprecated as of libpng-1.2.9 */ |
|
617 void PNGAPI |
|
618 png_set_gray_1_2_4_to_8(png_structp png_ptr) |
|
619 { |
|
620 png_debug(1, "in png_set_gray_1_2_4_to_8"); |
|
621 if (png_ptr == NULL) |
|
622 return; |
|
623 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); |
|
624 } |
|
625 #endif |
|
626 |
626 |
627 |
627 |
628 /* Expand tRNS chunks to alpha channels. */ |
628 /* Expand tRNS chunks to alpha channels. */ |
629 void PNGAPI |
629 void PNGAPI |
630 png_set_tRNS_to_alpha(png_structp png_ptr) |
630 png_set_tRNS_to_alpha(png_structp png_ptr) |
631 { |
631 { |
632 png_debug(1, "in png_set_tRNS_to_alpha"); |
632 png_debug(1, "in png_set_tRNS_to_alpha"); |
633 |
|
633 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); |
634 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); |
634 png_ptr->flags &= ~PNG_FLAG_ROW_INIT; |
635 png_ptr->flags &= ~PNG_FLAG_ROW_INIT; |
635 } |
636 } |
636 #endif /* defined(PNG_READ_EXPAND_SUPPORTED) */ |
637 #endif /* defined(PNG_READ_EXPAND_SUPPORTED) */ |
637 |
638 |
638 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) |
639 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED |
639 void PNGAPI |
640 void PNGAPI |
640 png_set_gray_to_rgb(png_structp png_ptr) |
641 png_set_gray_to_rgb(png_structp png_ptr) |
641 { |
642 { |
642 png_debug(1, "in png_set_gray_to_rgb"); |
643 png_debug(1, "in png_set_gray_to_rgb"); |
644 |
|
643 png_ptr->transformations |= PNG_GRAY_TO_RGB; |
645 png_ptr->transformations |= PNG_GRAY_TO_RGB; |
644 png_ptr->flags &= ~PNG_FLAG_ROW_INIT; |
646 png_ptr->flags &= ~PNG_FLAG_ROW_INIT; |
645 } |
647 } |
646 #endif |
648 #endif |
647 |
649 |
648 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) |
650 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED |
649 #if defined(PNG_FLOATING_POINT_SUPPORTED) |
651 #ifdef PNG_FLOATING_POINT_SUPPORTED |
650 /* Convert a RGB image to a grayscale of the same width. This allows us, |
652 /* Convert a RGB image to a grayscale of the same width. This allows us, |
651 * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image. |
653 * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image. |
652 */ |
654 */ |
653 |
655 |
654 void PNGAPI |
656 void PNGAPI |
666 void PNGAPI |
668 void PNGAPI |
667 png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, |
669 png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, |
668 png_fixed_point red, png_fixed_point green) |
670 png_fixed_point red, png_fixed_point green) |
669 { |
671 { |
670 png_debug(1, "in png_set_rgb_to_gray"); |
672 png_debug(1, "in png_set_rgb_to_gray"); |
673 |
|
671 if (png_ptr == NULL) |
674 if (png_ptr == NULL) |
672 return; |
675 return; |
676 |
|
673 switch(error_action) |
677 switch(error_action) |
674 { |
678 { |
675 case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY; |
679 case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY; |
676 break; |
680 break; |
677 |
681 |
679 break; |
683 break; |
680 |
684 |
681 case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; |
685 case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; |
682 } |
686 } |
683 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
687 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
684 #if defined(PNG_READ_EXPAND_SUPPORTED) |
688 #ifdef PNG_READ_EXPAND_SUPPORTED |
685 png_ptr->transformations |= PNG_EXPAND; |
689 png_ptr->transformations |= PNG_EXPAND; |
686 #else |
690 #else |
687 { |
691 { |
688 png_warning(png_ptr, |
692 png_warning(png_ptr, |
689 "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED."); |
693 "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED"); |
690 png_ptr->transformations &= ~PNG_RGB_TO_GRAY; |
694 png_ptr->transformations &= ~PNG_RGB_TO_GRAY; |
691 } |
695 } |
692 #endif |
696 #endif |
693 { |
697 { |
694 png_uint_16 red_int, green_int; |
698 png_uint_16 red_int, green_int; |
715 } |
719 } |
716 } |
720 } |
717 #endif |
721 #endif |
718 |
722 |
719 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ |
723 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ |
720 defined(PNG_LEGACY_SUPPORTED) || \ |
|
721 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) |
724 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) |
722 void PNGAPI |
725 void PNGAPI |
723 png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr |
726 png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr |
724 read_user_transform_fn) |
727 read_user_transform_fn) |
725 { |
728 { |
726 png_debug(1, "in png_set_read_user_transform_fn"); |
729 png_debug(1, "in png_set_read_user_transform_fn"); |
730 |
|
727 if (png_ptr == NULL) |
731 if (png_ptr == NULL) |
728 return; |
732 return; |
729 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) |
733 |
734 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED |
|
730 png_ptr->transformations |= PNG_USER_TRANSFORM; |
735 png_ptr->transformations |= PNG_USER_TRANSFORM; |
731 png_ptr->read_user_transform_fn = read_user_transform_fn; |
736 png_ptr->read_user_transform_fn = read_user_transform_fn; |
732 #endif |
|
733 #ifdef PNG_LEGACY_SUPPORTED |
|
734 if (read_user_transform_fn) |
|
735 png_warning(png_ptr, |
|
736 "This version of libpng does not support user transforms"); |
|
737 #endif |
737 #endif |
738 } |
738 } |
739 #endif |
739 #endif |
740 |
740 |
741 /* Initialize everything needed for the read. This includes modifying |
741 /* Initialize everything needed for the read. This includes modifying |
743 */ |
743 */ |
744 void /* PRIVATE */ |
744 void /* PRIVATE */ |
745 png_init_read_transformations(png_structp png_ptr) |
745 png_init_read_transformations(png_structp png_ptr) |
746 { |
746 { |
747 png_debug(1, "in png_init_read_transformations"); |
747 png_debug(1, "in png_init_read_transformations"); |
748 #if defined(PNG_USELESS_TESTS_SUPPORTED) |
748 |
749 if (png_ptr != NULL) |
|
750 #endif |
|
751 { |
749 { |
752 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \ |
750 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \ |
753 || defined(PNG_READ_GAMMA_SUPPORTED) |
751 || defined(PNG_READ_GAMMA_SUPPORTED) |
754 int color_type = png_ptr->color_type; |
752 int color_type = png_ptr->color_type; |
755 #endif |
753 #endif |
756 |
754 |
757 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) |
755 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) |
758 |
756 |
759 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) |
757 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED |
760 /* Detect gray background and attempt to enable optimization |
758 /* Detect gray background and attempt to enable optimization |
761 * for gray --> RGB case |
759 * for gray --> RGB case |
762 * |
760 * |
763 * Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or |
761 * Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or |
764 * RGB_ALPHA (in which case need_expand is superfluous anyway), the |
762 * RGB_ALPHA (in which case need_expand is superfluous anyway), the |
794 png_ptr->background.gray *= (png_uint_16)0xff; |
792 png_ptr->background.gray *= (png_uint_16)0xff; |
795 png_ptr->background.red = png_ptr->background.green |
793 png_ptr->background.red = png_ptr->background.green |
796 = png_ptr->background.blue = png_ptr->background.gray; |
794 = png_ptr->background.blue = png_ptr->background.gray; |
797 if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) |
795 if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) |
798 { |
796 { |
799 png_ptr->trans_values.gray *= (png_uint_16)0xff; |
797 png_ptr->trans_color.gray *= (png_uint_16)0xff; |
800 png_ptr->trans_values.red = png_ptr->trans_values.green |
798 png_ptr->trans_color.red = png_ptr->trans_color.green |
801 = png_ptr->trans_values.blue = png_ptr->trans_values.gray; |
799 = png_ptr->trans_color.blue = png_ptr->trans_color.gray; |
802 } |
800 } |
803 break; |
801 break; |
804 |
802 |
805 case 2: |
803 case 2: |
806 png_ptr->background.gray *= (png_uint_16)0x55; |
804 png_ptr->background.gray *= (png_uint_16)0x55; |
807 png_ptr->background.red = png_ptr->background.green |
805 png_ptr->background.red = png_ptr->background.green |
808 = png_ptr->background.blue = png_ptr->background.gray; |
806 = png_ptr->background.blue = png_ptr->background.gray; |
809 if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) |
807 if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) |
810 { |
808 { |
811 png_ptr->trans_values.gray *= (png_uint_16)0x55; |
809 png_ptr->trans_color.gray *= (png_uint_16)0x55; |
812 png_ptr->trans_values.red = png_ptr->trans_values.green |
810 png_ptr->trans_color.red = png_ptr->trans_color.green |
813 = png_ptr->trans_values.blue = png_ptr->trans_values.gray; |
811 = png_ptr->trans_color.blue = png_ptr->trans_color.gray; |
814 } |
812 } |
815 break; |
813 break; |
816 |
814 |
817 case 4: |
815 case 4: |
818 png_ptr->background.gray *= (png_uint_16)0x11; |
816 png_ptr->background.gray *= (png_uint_16)0x11; |
819 png_ptr->background.red = png_ptr->background.green |
817 png_ptr->background.red = png_ptr->background.green |
820 = png_ptr->background.blue = png_ptr->background.gray; |
818 = png_ptr->background.blue = png_ptr->background.gray; |
821 if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) |
819 if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) |
822 { |
820 { |
823 png_ptr->trans_values.gray *= (png_uint_16)0x11; |
821 png_ptr->trans_color.gray *= (png_uint_16)0x11; |
824 png_ptr->trans_values.red = png_ptr->trans_values.green |
822 png_ptr->trans_color.red = png_ptr->trans_color.green |
825 = png_ptr->trans_values.blue = png_ptr->trans_values.gray; |
823 = png_ptr->trans_color.blue = png_ptr->trans_color.gray; |
826 } |
824 } |
827 break; |
825 break; |
828 |
826 |
829 case 8: |
827 case 8: |
830 |
828 |
841 png_ptr->background.green = |
839 png_ptr->background.green = |
842 png_ptr->palette[png_ptr->background.index].green; |
840 png_ptr->palette[png_ptr->background.index].green; |
843 png_ptr->background.blue = |
841 png_ptr->background.blue = |
844 png_ptr->palette[png_ptr->background.index].blue; |
842 png_ptr->palette[png_ptr->background.index].blue; |
845 |
843 |
846 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) |
844 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED |
847 if (png_ptr->transformations & PNG_INVERT_ALPHA) |
845 if (png_ptr->transformations & PNG_INVERT_ALPHA) |
848 { |
846 { |
849 #if defined(PNG_READ_EXPAND_SUPPORTED) |
847 #ifdef PNG_READ_EXPAND_SUPPORTED |
850 if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) |
848 if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) |
851 #endif |
849 #endif |
852 { |
850 { |
853 /* Invert the alpha channel (in tRNS) unless the pixels are |
851 /* Invert the alpha channel (in tRNS) unless the pixels are |
854 * going to be expanded, in which case leave it for later |
852 * going to be expanded, in which case leave it for later |
855 */ |
853 */ |
856 int i, istop; |
854 int i, istop; |
857 istop=(int)png_ptr->num_trans; |
855 istop=(int)png_ptr->num_trans; |
858 for (i=0; i<istop; i++) |
856 for (i=0; i<istop; i++) |
859 png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]); |
857 png_ptr->trans_alpha[i] = (png_byte)(255 - png_ptr->trans_alpha[i]); |
860 } |
858 } |
861 } |
859 } |
862 #endif |
860 #endif |
863 |
861 |
864 } |
862 } |
876 { |
874 { |
877 int i, k; |
875 int i, k; |
878 k=0; |
876 k=0; |
879 for (i=0; i<png_ptr->num_trans; i++) |
877 for (i=0; i<png_ptr->num_trans; i++) |
880 { |
878 { |
881 if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff) |
879 if (png_ptr->trans_alpha[i] != 0 && png_ptr->trans_alpha[i] != 0xff) |
882 k=1; /* Partial transparency is present */ |
880 k=1; /* Partial transparency is present */ |
883 } |
881 } |
884 if (k == 0) |
882 if (k == 0) |
885 png_ptr->transformations &= ~PNG_GAMMA; |
883 png_ptr->transformations &= ~PNG_GAMMA; |
886 } |
884 } |
887 |
885 |
888 if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) && |
886 if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) && |
889 png_ptr->gamma != 0.0) |
887 png_ptr->gamma != 0.0) |
890 { |
888 { |
891 png_build_gamma_table(png_ptr); |
889 png_build_gamma_table(png_ptr, png_ptr->bit_depth); |
892 #if defined(PNG_READ_BACKGROUND_SUPPORTED) |
890 |
891 #ifdef PNG_READ_BACKGROUND_SUPPORTED |
|
893 if (png_ptr->transformations & PNG_BACKGROUND) |
892 if (png_ptr->transformations & PNG_BACKGROUND) |
894 { |
893 { |
895 if (color_type == PNG_COLOR_TYPE_PALETTE) |
894 if (color_type == PNG_COLOR_TYPE_PALETTE) |
896 { |
895 { |
897 /* Could skip if no transparency */ |
896 /* Could skip if no transparency */ |
942 back.blue = (png_byte)png_ptr->background.blue; |
941 back.blue = (png_byte)png_ptr->background.blue; |
943 } |
942 } |
944 else |
943 else |
945 { |
944 { |
946 back.red = (png_byte)(pow( |
945 back.red = (png_byte)(pow( |
947 (double)png_ptr->background.red/255, gs) * 255.0 + .5); |
946 (double)png_ptr->background.red/255.0, gs) * 255.0 + .5); |
948 back.green = (png_byte)(pow( |
947 back.green = (png_byte)(pow( |
949 (double)png_ptr->background.green/255, gs) * 255.0 + .5); |
948 (double)png_ptr->background.green/255.0, gs) * 255.0 + .5); |
950 back.blue = (png_byte)(pow( |
949 back.blue = (png_byte)(pow( |
951 (double)png_ptr->background.blue/255, gs) * 255.0 + .5); |
950 (double)png_ptr->background.blue/255.0, gs) * 255.0 + .5); |
952 } |
951 } |
953 |
952 |
954 back_1.red = (png_byte)(pow( |
953 back_1.red = (png_byte)(pow( |
955 (double)png_ptr->background.red/255, g) * 255.0 + .5); |
954 (double)png_ptr->background.red/255.0, g) * 255.0 + .5); |
956 back_1.green = (png_byte)(pow( |
955 back_1.green = (png_byte)(pow( |
957 (double)png_ptr->background.green/255, g) * 255.0 + .5); |
956 (double)png_ptr->background.green/255.0, g) * 255.0 + .5); |
958 back_1.blue = (png_byte)(pow( |
957 back_1.blue = (png_byte)(pow( |
959 (double)png_ptr->background.blue/255, g) * 255.0 + .5); |
958 (double)png_ptr->background.blue/255.0, g) * 255.0 + .5); |
960 } |
959 } |
961 for (i = 0; i < num_palette; i++) |
960 for (i = 0; i < num_palette; i++) |
962 { |
961 { |
963 if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff) |
962 if (i < (int)png_ptr->num_trans && png_ptr->trans_alpha[i] != 0xff) |
964 { |
963 { |
965 if (png_ptr->trans[i] == 0) |
964 if (png_ptr->trans_alpha[i] == 0) |
966 { |
965 { |
967 palette[i] = back; |
966 palette[i] = back; |
968 } |
967 } |
969 else /* if (png_ptr->trans[i] != 0xff) */ |
968 else /* if (png_ptr->trans_alpha[i] != 0xff) */ |
970 { |
969 { |
971 png_byte v, w; |
970 png_byte v, w; |
972 |
971 |
973 v = png_ptr->gamma_to_1[palette[i].red]; |
972 v = png_ptr->gamma_to_1[palette[i].red]; |
974 png_composite(w, v, png_ptr->trans[i], back_1.red); |
973 png_composite(w, v, png_ptr->trans_alpha[i], back_1.red); |
975 palette[i].red = png_ptr->gamma_from_1[w]; |
974 palette[i].red = png_ptr->gamma_from_1[w]; |
976 |
975 |
977 v = png_ptr->gamma_to_1[palette[i].green]; |
976 v = png_ptr->gamma_to_1[palette[i].green]; |
978 png_composite(w, v, png_ptr->trans[i], back_1.green); |
977 png_composite(w, v, png_ptr->trans_alpha[i], back_1.green); |
979 palette[i].green = png_ptr->gamma_from_1[w]; |
978 palette[i].green = png_ptr->gamma_from_1[w]; |
980 |
979 |
981 v = png_ptr->gamma_to_1[palette[i].blue]; |
980 v = png_ptr->gamma_to_1[palette[i].blue]; |
982 png_composite(w, v, png_ptr->trans[i], back_1.blue); |
981 png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue); |
983 palette[i].blue = png_ptr->gamma_from_1[w]; |
982 palette[i].blue = png_ptr->gamma_from_1[w]; |
984 } |
983 } |
985 } |
984 } |
986 else |
985 else |
987 { |
986 { |
988 palette[i].red = png_ptr->gamma_table[palette[i].red]; |
987 palette[i].red = png_ptr->gamma_table[palette[i].red]; |
989 palette[i].green = png_ptr->gamma_table[palette[i].green]; |
988 palette[i].green = png_ptr->gamma_table[palette[i].green]; |
990 palette[i].blue = png_ptr->gamma_table[palette[i].blue]; |
989 palette[i].blue = png_ptr->gamma_table[palette[i].blue]; |
991 } |
990 } |
992 } |
991 } |
993 /* Prevent the transformations being done again, and make sure |
992 /* Prevent the transformations being done again, and make sure |
994 * that the now spurious alpha channel is stripped - the code |
993 * that the now spurious alpha channel is stripped - the code |
995 * has just reduced background composition and gamma correction |
994 * has just reduced background composition and gamma correction |
996 * to a simple alpha channel strip. |
995 * to a simple alpha channel strip. |
997 */ |
996 */ |
998 png_ptr->transformations &= ~PNG_BACKGROUND; |
997 png_ptr->transformations &= ~PNG_BACKGROUND; |
999 png_ptr->transformations &= ~PNG_GAMMA; |
998 png_ptr->transformations &= ~PNG_GAMMA; |
1000 png_ptr->transformations |= PNG_STRIP_ALPHA; |
999 png_ptr->transformations |= PNG_STRIP_ALPHA; |
1001 } |
1000 } |
1002 /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ |
1001 /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ |
1003 else |
1002 else |
1004 /* color_type != PNG_COLOR_TYPE_PALETTE */ |
1003 /* color_type != PNG_COLOR_TYPE_PALETTE */ |
1005 { |
1004 { |
1073 palette[i].red = png_ptr->gamma_table[palette[i].red]; |
1072 palette[i].red = png_ptr->gamma_table[palette[i].red]; |
1074 palette[i].green = png_ptr->gamma_table[palette[i].green]; |
1073 palette[i].green = png_ptr->gamma_table[palette[i].green]; |
1075 palette[i].blue = png_ptr->gamma_table[palette[i].blue]; |
1074 palette[i].blue = png_ptr->gamma_table[palette[i].blue]; |
1076 } |
1075 } |
1077 |
1076 |
1078 /* Done the gamma correction. */ |
1077 /* Done the gamma correction. */ |
1079 png_ptr->transformations &= ~PNG_GAMMA; |
1078 png_ptr->transformations &= ~PNG_GAMMA; |
1080 } |
1079 } |
1081 } |
1080 } |
1082 #if defined(PNG_READ_BACKGROUND_SUPPORTED) |
1081 #ifdef PNG_READ_BACKGROUND_SUPPORTED |
1083 else |
1082 else |
1084 #endif |
1083 #endif |
1085 #endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */ |
1084 #endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */ |
1086 #if defined(PNG_READ_BACKGROUND_SUPPORTED) |
1085 #ifdef PNG_READ_BACKGROUND_SUPPORTED |
1087 /* No GAMMA transformation */ |
1086 /* No GAMMA transformation */ |
1088 if ((png_ptr->transformations & PNG_BACKGROUND) && |
1087 if ((png_ptr->transformations & PNG_BACKGROUND) && |
1089 (color_type == PNG_COLOR_TYPE_PALETTE)) |
1088 (color_type == PNG_COLOR_TYPE_PALETTE)) |
1090 { |
1089 { |
1091 int i; |
1090 int i; |
1097 back.green = (png_byte)png_ptr->background.green; |
1096 back.green = (png_byte)png_ptr->background.green; |
1098 back.blue = (png_byte)png_ptr->background.blue; |
1097 back.blue = (png_byte)png_ptr->background.blue; |
1099 |
1098 |
1100 for (i = 0; i < istop; i++) |
1099 for (i = 0; i < istop; i++) |
1101 { |
1100 { |
1102 if (png_ptr->trans[i] == 0) |
1101 if (png_ptr->trans_alpha[i] == 0) |
1103 { |
1102 { |
1104 palette[i] = back; |
1103 palette[i] = back; |
1105 } |
1104 } |
1106 else if (png_ptr->trans[i] != 0xff) |
1105 else if (png_ptr->trans_alpha[i] != 0xff) |
1107 { |
1106 { |
1108 /* The png_composite() macro is defined in png.h */ |
1107 /* The png_composite() macro is defined in png.h */ |
1109 png_composite(palette[i].red, palette[i].red, |
1108 png_composite(palette[i].red, palette[i].red, |
1110 png_ptr->trans[i], back.red); |
1109 png_ptr->trans_alpha[i], back.red); |
1111 png_composite(palette[i].green, palette[i].green, |
1110 png_composite(palette[i].green, palette[i].green, |
1112 png_ptr->trans[i], back.green); |
1111 png_ptr->trans_alpha[i], back.green); |
1113 png_composite(palette[i].blue, palette[i].blue, |
1112 png_composite(palette[i].blue, palette[i].blue, |
1114 png_ptr->trans[i], back.blue); |
1113 png_ptr->trans_alpha[i], back.blue); |
1115 } |
1114 } |
1116 } |
1115 } |
1117 |
1116 |
1118 /* Handled alpha, still need to strip the channel. */ |
1117 /* Handled alpha, still need to strip the channel. */ |
1119 png_ptr->transformations &= ~PNG_BACKGROUND; |
1118 png_ptr->transformations &= ~PNG_BACKGROUND; |
1120 png_ptr->transformations |= PNG_STRIP_ALPHA; |
1119 png_ptr->transformations |= PNG_STRIP_ALPHA; |
1121 } |
1120 } |
1122 #endif /* PNG_READ_BACKGROUND_SUPPORTED */ |
1121 #endif /* PNG_READ_BACKGROUND_SUPPORTED */ |
1123 |
1122 |
1124 #if defined(PNG_READ_SHIFT_SUPPORTED) |
1123 #ifdef PNG_READ_SHIFT_SUPPORTED |
1125 if ((png_ptr->transformations & PNG_SHIFT) && |
1124 if ((png_ptr->transformations & PNG_SHIFT) && |
1126 (color_type == PNG_COLOR_TYPE_PALETTE)) |
1125 (color_type == PNG_COLOR_TYPE_PALETTE)) |
1127 { |
1126 { |
1128 png_uint_16 i; |
1127 png_uint_16 i; |
1129 png_uint_16 istop = png_ptr->num_palette; |
1128 png_uint_16 istop = png_ptr->num_palette; |
1159 */ |
1158 */ |
1160 void /* PRIVATE */ |
1159 void /* PRIVATE */ |
1161 png_read_transform_info(png_structp png_ptr, png_infop info_ptr) |
1160 png_read_transform_info(png_structp png_ptr, png_infop info_ptr) |
1162 { |
1161 { |
1163 png_debug(1, "in png_read_transform_info"); |
1162 png_debug(1, "in png_read_transform_info"); |
1164 #if defined(PNG_READ_EXPAND_SUPPORTED) |
1163 |
1164 #ifdef PNG_READ_EXPAND_SUPPORTED |
|
1165 if (png_ptr->transformations & PNG_EXPAND) |
1165 if (png_ptr->transformations & PNG_EXPAND) |
1166 { |
1166 { |
1167 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
1167 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
1168 { |
1168 { |
1169 if (png_ptr->num_trans && |
1169 if (png_ptr->num_trans && |
1186 info_ptr->num_trans = 0; |
1186 info_ptr->num_trans = 0; |
1187 } |
1187 } |
1188 } |
1188 } |
1189 #endif |
1189 #endif |
1190 |
1190 |
1191 #if defined(PNG_READ_BACKGROUND_SUPPORTED) |
1191 #ifdef PNG_READ_BACKGROUND_SUPPORTED |
1192 if (png_ptr->transformations & PNG_BACKGROUND) |
1192 if (png_ptr->transformations & PNG_BACKGROUND) |
1193 { |
1193 { |
1194 info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; |
1194 info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; |
1195 info_ptr->num_trans = 0; |
1195 info_ptr->num_trans = 0; |
1196 info_ptr->background = png_ptr->background; |
1196 info_ptr->background = png_ptr->background; |
1197 } |
1197 } |
1198 #endif |
1198 #endif |
1199 |
1199 |
1200 #if defined(PNG_READ_GAMMA_SUPPORTED) |
1200 #ifdef PNG_READ_GAMMA_SUPPORTED |
1201 if (png_ptr->transformations & PNG_GAMMA) |
1201 if (png_ptr->transformations & PNG_GAMMA) |
1202 { |
1202 { |
1203 #ifdef PNG_FLOATING_POINT_SUPPORTED |
1203 #ifdef PNG_FLOATING_POINT_SUPPORTED |
1204 info_ptr->gamma = png_ptr->gamma; |
1204 info_ptr->gamma = png_ptr->gamma; |
1205 #endif |
1205 #endif |
1207 info_ptr->int_gamma = png_ptr->int_gamma; |
1207 info_ptr->int_gamma = png_ptr->int_gamma; |
1208 #endif |
1208 #endif |
1209 } |
1209 } |
1210 #endif |
1210 #endif |
1211 |
1211 |
1212 #if defined(PNG_READ_16_TO_8_SUPPORTED) |
1212 #ifdef PNG_READ_16_TO_8_SUPPORTED |
1213 if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16)) |
1213 if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16)) |
1214 info_ptr->bit_depth = 8; |
1214 info_ptr->bit_depth = 8; |
1215 #endif |
1215 #endif |
1216 |
1216 |
1217 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) |
1217 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED |
1218 if (png_ptr->transformations & PNG_GRAY_TO_RGB) |
1218 if (png_ptr->transformations & PNG_GRAY_TO_RGB) |
1219 info_ptr->color_type |= PNG_COLOR_MASK_COLOR; |
1219 info_ptr->color_type |= PNG_COLOR_MASK_COLOR; |
1220 #endif |
1220 #endif |
1221 |
1221 |
1222 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) |
1222 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED |
1223 if (png_ptr->transformations & PNG_RGB_TO_GRAY) |
1223 if (png_ptr->transformations & PNG_RGB_TO_GRAY) |
1224 info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR; |
1224 info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR; |
1225 #endif |
1225 #endif |
1226 |
1226 |
1227 #if defined(PNG_READ_DITHER_SUPPORTED) |
1227 #ifdef PNG_READ_DITHER_SUPPORTED |
1228 if (png_ptr->transformations & PNG_DITHER) |
1228 if (png_ptr->transformations & PNG_DITHER) |
1229 { |
1229 { |
1230 if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || |
1230 if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || |
1231 (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && |
1231 (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && |
1232 png_ptr->palette_lookup && info_ptr->bit_depth == 8) |
1232 png_ptr->palette_lookup && info_ptr->bit_depth == 8) |
1234 info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; |
1234 info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; |
1235 } |
1235 } |
1236 } |
1236 } |
1237 #endif |
1237 #endif |
1238 |
1238 |
1239 #if defined(PNG_READ_PACK_SUPPORTED) |
1239 #ifdef PNG_READ_PACK_SUPPORTED |
1240 if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8)) |
1240 if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8)) |
1241 info_ptr->bit_depth = 8; |
1241 info_ptr->bit_depth = 8; |
1242 #endif |
1242 #endif |
1243 |
1243 |
1244 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
1244 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
1246 else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) |
1246 else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) |
1247 info_ptr->channels = 3; |
1247 info_ptr->channels = 3; |
1248 else |
1248 else |
1249 info_ptr->channels = 1; |
1249 info_ptr->channels = 1; |
1250 |
1250 |
1251 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) |
1251 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED |
1252 if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA) |
1252 if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA) |
1253 info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; |
1253 info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; |
1254 #endif |
1254 #endif |
1255 |
1255 |
1256 if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) |
1256 if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) |
1257 info_ptr->channels++; |
1257 info_ptr->channels++; |
1258 |
1258 |
1259 #if defined(PNG_READ_FILLER_SUPPORTED) |
1259 #ifdef PNG_READ_FILLER_SUPPORTED |
1260 /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */ |
1260 /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */ |
1261 if ((png_ptr->transformations & PNG_FILLER) && |
1261 if ((png_ptr->transformations & PNG_FILLER) && |
1262 ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || |
1262 ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || |
1263 (info_ptr->color_type == PNG_COLOR_TYPE_GRAY))) |
1263 (info_ptr->color_type == PNG_COLOR_TYPE_GRAY))) |
1264 { |
1264 { |
1265 info_ptr->channels++; |
1265 info_ptr->channels++; |
1266 /* If adding a true alpha channel not just filler */ |
1266 /* If adding a true alpha channel not just filler */ |
1267 #if !defined(PNG_1_0_X) |
|
1268 if (png_ptr->transformations & PNG_ADD_ALPHA) |
1267 if (png_ptr->transformations & PNG_ADD_ALPHA) |
1269 info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; |
1268 info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; |
1270 #endif |
|
1271 } |
1269 } |
1272 #endif |
1270 #endif |
1273 |
1271 |
1274 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \ |
1272 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \ |
1275 defined(PNG_READ_USER_TRANSFORM_SUPPORTED) |
1273 defined(PNG_READ_USER_TRANSFORM_SUPPORTED) |
1285 info_ptr->pixel_depth = (png_byte)(info_ptr->channels * |
1283 info_ptr->pixel_depth = (png_byte)(info_ptr->channels * |
1286 info_ptr->bit_depth); |
1284 info_ptr->bit_depth); |
1287 |
1285 |
1288 info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width); |
1286 info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width); |
1289 |
1287 |
1290 #if !defined(PNG_READ_EXPAND_SUPPORTED) |
1288 #ifndef PNG_READ_EXPAND_SUPPORTED |
1291 if (png_ptr) |
1289 if (png_ptr) |
1292 return; |
1290 return; |
1293 #endif |
1291 #endif |
1294 } |
1292 } |
1295 |
1293 |
1299 */ |
1297 */ |
1300 void /* PRIVATE */ |
1298 void /* PRIVATE */ |
1301 png_do_read_transformations(png_structp png_ptr) |
1299 png_do_read_transformations(png_structp png_ptr) |
1302 { |
1300 { |
1303 png_debug(1, "in png_do_read_transformations"); |
1301 png_debug(1, "in png_do_read_transformations"); |
1302 |
|
1304 if (png_ptr->row_buf == NULL) |
1303 if (png_ptr->row_buf == NULL) |
1305 { |
1304 { |
1306 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) |
1305 #ifdef PNG_STDIO_SUPPORTED |
1307 char msg[50]; |
1306 char msg[50]; |
1308 |
1307 |
1309 png_snprintf2(msg, 50, |
1308 png_snprintf2(msg, 50, |
1310 "NULL row buffer for row %ld, pass %d", (long)png_ptr->row_number, |
1309 "NULL row buffer for row %ld, pass %d", (long)png_ptr->row_number, |
1311 png_ptr->pass); |
1310 png_ptr->pass); |
1325 #else |
1324 #else |
1326 png_warning(png_ptr, "Uninitialized row"); |
1325 png_warning(png_ptr, "Uninitialized row"); |
1327 #endif |
1326 #endif |
1328 #endif |
1327 #endif |
1329 |
1328 |
1330 #if defined(PNG_READ_EXPAND_SUPPORTED) |
1329 #ifdef PNG_READ_EXPAND_SUPPORTED |
1331 if (png_ptr->transformations & PNG_EXPAND) |
1330 if (png_ptr->transformations & PNG_EXPAND) |
1332 { |
1331 { |
1333 if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE) |
1332 if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE) |
1334 { |
1333 { |
1335 png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1, |
1334 png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1, |
1336 png_ptr->palette, png_ptr->trans, png_ptr->num_trans); |
1335 png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); |
1337 } |
1336 } |
1338 else |
1337 else |
1339 { |
1338 { |
1340 if (png_ptr->num_trans && |
1339 if (png_ptr->num_trans && |
1341 (png_ptr->transformations & PNG_EXPAND_tRNS)) |
1340 (png_ptr->transformations & PNG_EXPAND_tRNS)) |
1342 png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, |
1341 png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, |
1343 &(png_ptr->trans_values)); |
1342 &(png_ptr->trans_color)); |
1344 else |
1343 else |
1345 png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, |
1344 png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, |
1346 NULL); |
1345 NULL); |
1347 } |
1346 } |
1348 } |
1347 } |
1349 #endif |
1348 #endif |
1350 |
1349 |
1351 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) |
1350 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED |
1352 if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA) |
1351 if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA) |
1353 png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, |
1352 png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, |
1354 PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)); |
1353 PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)); |
1355 #endif |
1354 #endif |
1356 |
1355 |
1357 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) |
1356 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED |
1358 if (png_ptr->transformations & PNG_RGB_TO_GRAY) |
1357 if (png_ptr->transformations & PNG_RGB_TO_GRAY) |
1359 { |
1358 { |
1360 int rgb_error = |
1359 int rgb_error = |
1361 png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1); |
1360 png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1); |
1362 if (rgb_error) |
1361 if (rgb_error) |
1401 * performance, as this increases the per-pixel operations. If we would check |
1400 * performance, as this increases the per-pixel operations. If we would check |
1402 * in advance if the background was gray or RGB, and position the gray-to-RGB |
1401 * in advance if the background was gray or RGB, and position the gray-to-RGB |
1403 * transform appropriately, then it would save a lot of work/time. |
1402 * transform appropriately, then it would save a lot of work/time. |
1404 */ |
1403 */ |
1405 |
1404 |
1406 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) |
1405 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED |
1407 /* If gray -> RGB, do so now only if background is non-gray; else do later |
1406 /* If gray -> RGB, do so now only if background is non-gray; else do later |
1408 * for performance reasons |
1407 * for performance reasons |
1409 */ |
1408 */ |
1410 if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && |
1409 if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && |
1411 !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) |
1410 !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) |
1412 png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); |
1411 png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); |
1413 #endif |
1412 #endif |
1414 |
1413 |
1415 #if defined(PNG_READ_BACKGROUND_SUPPORTED) |
1414 #ifdef PNG_READ_BACKGROUND_SUPPORTED |
1416 if ((png_ptr->transformations & PNG_BACKGROUND) && |
1415 if ((png_ptr->transformations & PNG_BACKGROUND) && |
1417 ((png_ptr->num_trans != 0 ) || |
1416 ((png_ptr->num_trans != 0 ) || |
1418 (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) |
1417 (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) |
1419 png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1, |
1418 png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1, |
1420 &(png_ptr->trans_values), &(png_ptr->background) |
1419 &(png_ptr->trans_color), &(png_ptr->background) |
1421 #if defined(PNG_READ_GAMMA_SUPPORTED) |
1420 #ifdef PNG_READ_GAMMA_SUPPORTED |
1422 , &(png_ptr->background_1), |
1421 , &(png_ptr->background_1), |
1423 png_ptr->gamma_table, png_ptr->gamma_from_1, |
1422 png_ptr->gamma_table, png_ptr->gamma_from_1, |
1424 png_ptr->gamma_to_1, png_ptr->gamma_16_table, |
1423 png_ptr->gamma_to_1, png_ptr->gamma_16_table, |
1425 png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1, |
1424 png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1, |
1426 png_ptr->gamma_shift |
1425 png_ptr->gamma_shift |
1427 #endif |
1426 #endif |
1428 ); |
1427 ); |
1429 #endif |
1428 #endif |
1430 |
1429 |
1431 #if defined(PNG_READ_GAMMA_SUPPORTED) |
1430 #ifdef PNG_READ_GAMMA_SUPPORTED |
1432 if ((png_ptr->transformations & PNG_GAMMA) && |
1431 if ((png_ptr->transformations & PNG_GAMMA) && |
1433 #if defined(PNG_READ_BACKGROUND_SUPPORTED) |
1432 #ifdef PNG_READ_BACKGROUND_SUPPORTED |
1434 !((png_ptr->transformations & PNG_BACKGROUND) && |
1433 !((png_ptr->transformations & PNG_BACKGROUND) && |
1435 ((png_ptr->num_trans != 0) || |
1434 ((png_ptr->num_trans != 0) || |
1436 (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) && |
1435 (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) && |
1437 #endif |
1436 #endif |
1438 (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) |
1437 (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) |
1439 png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1, |
1438 png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1, |
1440 png_ptr->gamma_table, png_ptr->gamma_16_table, |
1439 png_ptr->gamma_table, png_ptr->gamma_16_table, |
1441 png_ptr->gamma_shift); |
1440 png_ptr->gamma_shift); |
1442 #endif |
1441 #endif |
1443 |
1442 |
1444 #if defined(PNG_READ_16_TO_8_SUPPORTED) |
1443 #ifdef PNG_READ_16_TO_8_SUPPORTED |
1445 if (png_ptr->transformations & PNG_16_TO_8) |
1444 if (png_ptr->transformations & PNG_16_TO_8) |
1446 png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1); |
1445 png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1); |
1447 #endif |
1446 #endif |
1448 |
1447 |
1449 #if defined(PNG_READ_DITHER_SUPPORTED) |
1448 #ifdef PNG_READ_DITHER_SUPPORTED |
1450 if (png_ptr->transformations & PNG_DITHER) |
1449 if (png_ptr->transformations & PNG_DITHER) |
1451 { |
1450 { |
1452 png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1, |
1451 png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1, |
1453 png_ptr->palette_lookup, png_ptr->dither_index); |
1452 png_ptr->palette_lookup, png_ptr->dither_index); |
1454 if (png_ptr->row_info.rowbytes == (png_uint_32)0) |
1453 if (png_ptr->row_info.rowbytes == (png_uint_32)0) |
1455 png_error(png_ptr, "png_do_dither returned rowbytes=0"); |
1454 png_error(png_ptr, "png_do_dither returned rowbytes=0"); |
1456 } |
1455 } |
1457 #endif |
1456 #endif |
1458 |
1457 |
1459 #if defined(PNG_READ_INVERT_SUPPORTED) |
1458 #ifdef PNG_READ_INVERT_SUPPORTED |
1460 if (png_ptr->transformations & PNG_INVERT_MONO) |
1459 if (png_ptr->transformations & PNG_INVERT_MONO) |
1461 png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); |
1460 png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); |
1462 #endif |
1461 #endif |
1463 |
1462 |
1464 #if defined(PNG_READ_SHIFT_SUPPORTED) |
1463 #ifdef PNG_READ_SHIFT_SUPPORTED |
1465 if (png_ptr->transformations & PNG_SHIFT) |
1464 if (png_ptr->transformations & PNG_SHIFT) |
1466 png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1, |
1465 png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1, |
1467 &(png_ptr->shift)); |
1466 &(png_ptr->shift)); |
1468 #endif |
1467 #endif |
1469 |
1468 |
1470 #if defined(PNG_READ_PACK_SUPPORTED) |
1469 #ifdef PNG_READ_PACK_SUPPORTED |
1471 if (png_ptr->transformations & PNG_PACK) |
1470 if (png_ptr->transformations & PNG_PACK) |
1472 png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1); |
1471 png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1); |
1473 #endif |
1472 #endif |
1474 |
1473 |
1475 #if defined(PNG_READ_BGR_SUPPORTED) |
1474 #ifdef PNG_READ_BGR_SUPPORTED |
1476 if (png_ptr->transformations & PNG_BGR) |
1475 if (png_ptr->transformations & PNG_BGR) |
1477 png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); |
1476 png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); |
1478 #endif |
1477 #endif |
1479 |
1478 |
1480 #if defined(PNG_READ_PACKSWAP_SUPPORTED) |
1479 #ifdef PNG_READ_PACKSWAP_SUPPORTED |
1481 if (png_ptr->transformations & PNG_PACKSWAP) |
1480 if (png_ptr->transformations & PNG_PACKSWAP) |
1482 png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); |
1481 png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); |
1483 #endif |
1482 #endif |
1484 |
1483 |
1485 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) |
1484 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED |
1486 /* If gray -> RGB, do so now only if we did not do so above */ |
1485 /* If gray -> RGB, do so now only if we did not do so above */ |
1487 if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && |
1486 if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && |
1488 (png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) |
1487 (png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) |
1489 png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); |
1488 png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); |
1490 #endif |
1489 #endif |
1491 |
1490 |
1492 #if defined(PNG_READ_FILLER_SUPPORTED) |
1491 #ifdef PNG_READ_FILLER_SUPPORTED |
1493 if (png_ptr->transformations & PNG_FILLER) |
1492 if (png_ptr->transformations & PNG_FILLER) |
1494 png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, |
1493 png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, |
1495 (png_uint_32)png_ptr->filler, png_ptr->flags); |
1494 (png_uint_32)png_ptr->filler, png_ptr->flags); |
1496 #endif |
1495 #endif |
1497 |
1496 |
1498 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) |
1497 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED |
1499 if (png_ptr->transformations & PNG_INVERT_ALPHA) |
1498 if (png_ptr->transformations & PNG_INVERT_ALPHA) |
1500 png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); |
1499 png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); |
1501 #endif |
1500 #endif |
1502 |
1501 |
1503 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) |
1502 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED |
1504 if (png_ptr->transformations & PNG_SWAP_ALPHA) |
1503 if (png_ptr->transformations & PNG_SWAP_ALPHA) |
1505 png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); |
1504 png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); |
1506 #endif |
1505 #endif |
1507 |
1506 |
1508 #if defined(PNG_READ_SWAP_SUPPORTED) |
1507 #ifdef PNG_READ_SWAP_SUPPORTED |
1509 if (png_ptr->transformations & PNG_SWAP_BYTES) |
1508 if (png_ptr->transformations & PNG_SWAP_BYTES) |
1510 png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); |
1509 png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); |
1511 #endif |
1510 #endif |
1512 |
1511 |
1513 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) |
1512 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED |
1514 if (png_ptr->transformations & PNG_USER_TRANSFORM) |
1513 if (png_ptr->transformations & PNG_USER_TRANSFORM) |
1515 { |
1514 { |
1516 if (png_ptr->read_user_transform_fn != NULL) |
1515 if (png_ptr->read_user_transform_fn != NULL) |
1517 (*(png_ptr->read_user_transform_fn)) /* User read transform function */ |
1516 (*(png_ptr->read_user_transform_fn)) /* User read transform function */ |
1518 (png_ptr, /* png_ptr */ |
1517 (png_ptr, /* png_ptr */ |
1522 /* png_byte color_type; color type of pixels */ |
1521 /* png_byte color_type; color type of pixels */ |
1523 /* png_byte bit_depth; bit depth of samples */ |
1522 /* png_byte bit_depth; bit depth of samples */ |
1524 /* png_byte channels; number of channels (1-4) */ |
1523 /* png_byte channels; number of channels (1-4) */ |
1525 /* png_byte pixel_depth; bits per pixel (depth*channels) */ |
1524 /* png_byte pixel_depth; bits per pixel (depth*channels) */ |
1526 png_ptr->row_buf + 1); /* start of pixel data for row */ |
1525 png_ptr->row_buf + 1); /* start of pixel data for row */ |
1527 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) |
1526 #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED |
1528 if (png_ptr->user_transform_depth) |
1527 if (png_ptr->user_transform_depth) |
1529 png_ptr->row_info.bit_depth = png_ptr->user_transform_depth; |
1528 png_ptr->row_info.bit_depth = png_ptr->user_transform_depth; |
1530 if (png_ptr->user_transform_channels) |
1529 if (png_ptr->user_transform_channels) |
1531 png_ptr->row_info.channels = png_ptr->user_transform_channels; |
1530 png_ptr->row_info.channels = png_ptr->user_transform_channels; |
1532 #endif |
1531 #endif |
1537 } |
1536 } |
1538 #endif |
1537 #endif |
1539 |
1538 |
1540 } |
1539 } |
1541 |
1540 |
1542 #if defined(PNG_READ_PACK_SUPPORTED) |
1541 #ifdef PNG_READ_PACK_SUPPORTED |
1543 /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, |
1542 /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, |
1544 * without changing the actual values. Thus, if you had a row with |
1543 * without changing the actual values. Thus, if you had a row with |
1545 * a bit depth of 1, you would end up with bytes that only contained |
1544 * a bit depth of 1, you would end up with bytes that only contained |
1546 * the numbers 0 or 1. If you would rather they contain 0 and 255, use |
1545 * the numbers 0 or 1. If you would rather they contain 0 and 255, use |
1547 * png_do_shift() after this. |
1546 * png_do_shift() after this. |
1548 */ |
1547 */ |
1549 void /* PRIVATE */ |
1548 void /* PRIVATE */ |
1550 png_do_unpack(png_row_infop row_info, png_bytep row) |
1549 png_do_unpack(png_row_infop row_info, png_bytep row) |
1551 { |
1550 { |
1552 png_debug(1, "in png_do_unpack"); |
1551 png_debug(1, "in png_do_unpack"); |
1553 #if defined(PNG_USELESS_TESTS_SUPPORTED) |
1552 |
1554 if (row != NULL && row_info != NULL && row_info->bit_depth < 8) |
|
1555 #else |
|
1556 if (row_info->bit_depth < 8) |
1553 if (row_info->bit_depth < 8) |
1557 #endif |
|
1558 { |
1554 { |
1559 png_uint_32 i; |
1555 png_uint_32 i; |
1560 png_uint_32 row_width=row_info->width; |
1556 png_uint_32 row_width=row_info->width; |
1561 |
1557 |
1562 switch (row_info->bit_depth) |
1558 switch (row_info->bit_depth) |
1630 row_info->rowbytes = row_width * row_info->channels; |
1626 row_info->rowbytes = row_width * row_info->channels; |
1631 } |
1627 } |
1632 } |
1628 } |
1633 #endif |
1629 #endif |
1634 |
1630 |
1635 #if defined(PNG_READ_SHIFT_SUPPORTED) |
1631 #ifdef PNG_READ_SHIFT_SUPPORTED |
1636 /* Reverse the effects of png_do_shift. This routine merely shifts the |
1632 /* Reverse the effects of png_do_shift. This routine merely shifts the |
1637 * pixels back to their significant bits values. Thus, if you have |
1633 * pixels back to their significant bits values. Thus, if you have |
1638 * a row of bit depth 8, but only 5 are significant, this will shift |
1634 * a row of bit depth 8, but only 5 are significant, this will shift |
1639 * the values back to 0 through 31. |
1635 * the values back to 0 through 31. |
1640 */ |
1636 */ |
1641 void /* PRIVATE */ |
1637 void /* PRIVATE */ |
1642 png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits) |
1638 png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits) |
1643 { |
1639 { |
1644 png_debug(1, "in png_do_unshift"); |
1640 png_debug(1, "in png_do_unshift"); |
1641 |
|
1645 if ( |
1642 if ( |
1646 #if defined(PNG_USELESS_TESTS_SUPPORTED) |
|
1647 row != NULL && row_info != NULL && sig_bits != NULL && |
|
1648 #endif |
|
1649 row_info->color_type != PNG_COLOR_TYPE_PALETTE) |
1643 row_info->color_type != PNG_COLOR_TYPE_PALETTE) |
1650 { |
1644 { |
1651 int shift[4]; |
1645 int shift[4]; |
1652 int channels = 0; |
1646 int channels = 0; |
1653 int c; |
1647 int c; |
1743 } |
1737 } |
1744 } |
1738 } |
1745 } |
1739 } |
1746 #endif |
1740 #endif |
1747 |
1741 |
1748 #if defined(PNG_READ_16_TO_8_SUPPORTED) |
1742 #ifdef PNG_READ_16_TO_8_SUPPORTED |
1749 /* Chop rows of bit depth 16 down to 8 */ |
1743 /* Chop rows of bit depth 16 down to 8 */ |
1750 void /* PRIVATE */ |
1744 void /* PRIVATE */ |
1751 png_do_chop(png_row_infop row_info, png_bytep row) |
1745 png_do_chop(png_row_infop row_info, png_bytep row) |
1752 { |
1746 { |
1753 png_debug(1, "in png_do_chop"); |
1747 png_debug(1, "in png_do_chop"); |
1754 #if defined(PNG_USELESS_TESTS_SUPPORTED) |
1748 |
1755 if (row != NULL && row_info != NULL && row_info->bit_depth == 16) |
|
1756 #else |
|
1757 if (row_info->bit_depth == 16) |
1749 if (row_info->bit_depth == 16) |
1758 #endif |
|
1759 { |
1750 { |
1760 png_bytep sp = row; |
1751 png_bytep sp = row; |
1761 png_bytep dp = row; |
1752 png_bytep dp = row; |
1762 png_uint_32 i; |
1753 png_uint_32 i; |
1763 png_uint_32 istop = row_info->width * row_info->channels; |
1754 png_uint_32 istop = row_info->width * row_info->channels; |
1764 |
1755 |
1765 for (i = 0; i<istop; i++, sp += 2, dp++) |
1756 for (i = 0; i<istop; i++, sp += 2, dp++) |
1766 { |
1757 { |
1767 #if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED) |
1758 #ifdef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED |
1768 /* This does a more accurate scaling of the 16-bit color |
1759 /* This does a more accurate scaling of the 16-bit color |
1769 * value, rather than a simple low-byte truncation. |
1760 * value, rather than a simple low-byte truncation. |
1770 * |
1761 * |
1771 * What the ideal calculation should be: |
1762 * What the ideal calculation should be: |
1772 * *dp = (((((png_uint_32)(*sp) << 8) | |
1763 * *dp = (((((png_uint_32)(*sp) << 8) | |
1801 row_info->rowbytes = row_info->width * row_info->channels; |
1792 row_info->rowbytes = row_info->width * row_info->channels; |
1802 } |
1793 } |
1803 } |
1794 } |
1804 #endif |
1795 #endif |
1805 |
1796 |
1806 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) |
1797 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED |
1807 void /* PRIVATE */ |
1798 void /* PRIVATE */ |
1808 png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) |
1799 png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) |
1809 { |
1800 { |
1810 png_debug(1, "in png_do_read_swap_alpha"); |
1801 png_debug(1, "in png_do_read_swap_alpha"); |
1811 #if defined(PNG_USELESS_TESTS_SUPPORTED) |
1802 |
1812 if (row != NULL && row_info != NULL) |
|
1813 #endif |
|
1814 { |
1803 { |
1815 png_uint_32 row_width = row_info->width; |
1804 png_uint_32 row_width = row_info->width; |
1816 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) |
1805 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) |
1817 { |
1806 { |
1818 /* This converts from RGBA to ARGB */ |
1807 /* This converts from RGBA to ARGB */ |
1893 } |
1882 } |
1894 } |
1883 } |
1895 } |
1884 } |
1896 #endif |
1885 #endif |
1897 |
1886 |
1898 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) |
1887 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED |
1899 void /* PRIVATE */ |
1888 void /* PRIVATE */ |
1900 png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) |
1889 png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) |
1901 { |
1890 { |
1902 png_debug(1, "in png_do_read_invert_alpha"); |
1891 png_debug(1, "in png_do_read_invert_alpha"); |
1903 #if defined(PNG_USELESS_TESTS_SUPPORTED) |
1892 |
1904 if (row != NULL && row_info != NULL) |
|
1905 #endif |
|
1906 { |
1893 { |
1907 png_uint_32 row_width = row_info->width; |
1894 png_uint_32 row_width = row_info->width; |
1908 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) |
1895 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) |
1909 { |
1896 { |
1910 /* This inverts the alpha channel in RGBA */ |
1897 /* This inverts the alpha channel in RGBA */ |
1991 } |
1978 } |
1992 } |
1979 } |
1993 } |
1980 } |
1994 #endif |
1981 #endif |
1995 |
1982 |
1996 #if defined(PNG_READ_FILLER_SUPPORTED) |
1983 #ifdef PNG_READ_FILLER_SUPPORTED |
1997 /* Add filler channel if we have RGB color */ |
1984 /* Add filler channel if we have RGB color */ |
1998 void /* PRIVATE */ |
1985 void /* PRIVATE */ |
1999 png_do_read_filler(png_row_infop row_info, png_bytep row, |
1986 png_do_read_filler(png_row_infop row_info, png_bytep row, |
2000 png_uint_32 filler, png_uint_32 flags) |
1987 png_uint_32 filler, png_uint_32 flags) |
2001 { |
1988 { |
2004 |
1991 |
2005 png_byte hi_filler = (png_byte)((filler>>8) & 0xff); |
1992 png_byte hi_filler = (png_byte)((filler>>8) & 0xff); |
2006 png_byte lo_filler = (png_byte)(filler & 0xff); |
1993 png_byte lo_filler = (png_byte)(filler & 0xff); |
2007 |
1994 |
2008 png_debug(1, "in png_do_read_filler"); |
1995 png_debug(1, "in png_do_read_filler"); |
1996 |
|
2009 if ( |
1997 if ( |
2010 #if defined(PNG_USELESS_TESTS_SUPPORTED) |
|
2011 row != NULL && row_info != NULL && |
|
2012 #endif |
|
2013 row_info->color_type == PNG_COLOR_TYPE_GRAY) |
1998 row_info->color_type == PNG_COLOR_TYPE_GRAY) |
2014 { |
1999 { |
2015 if (row_info->bit_depth == 8) |
2000 if (row_info->bit_depth == 8) |
2016 { |
2001 { |
2017 /* This changes the data from G to GX */ |
2002 /* This changes the data from G to GX */ |
2167 } |
2152 } |
2168 } /* COLOR_TYPE == RGB */ |
2153 } /* COLOR_TYPE == RGB */ |
2169 } |
2154 } |
2170 #endif |
2155 #endif |
2171 |
2156 |
2172 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) |
2157 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED |
2173 /* Expand grayscale files to RGB, with or without alpha */ |
2158 /* Expand grayscale files to RGB, with or without alpha */ |
2174 void /* PRIVATE */ |
2159 void /* PRIVATE */ |
2175 png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) |
2160 png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) |
2176 { |
2161 { |
2177 png_uint_32 i; |
2162 png_uint_32 i; |
2178 png_uint_32 row_width = row_info->width; |
2163 png_uint_32 row_width = row_info->width; |
2179 |
2164 |
2180 png_debug(1, "in png_do_gray_to_rgb"); |
2165 png_debug(1, "in png_do_gray_to_rgb"); |
2166 |
|
2181 if (row_info->bit_depth >= 8 && |
2167 if (row_info->bit_depth >= 8 && |
2182 #if defined(PNG_USELESS_TESTS_SUPPORTED) |
|
2183 row != NULL && row_info != NULL && |
|
2184 #endif |
|
2185 !(row_info->color_type & PNG_COLOR_MASK_COLOR)) |
2168 !(row_info->color_type & PNG_COLOR_MASK_COLOR)) |
2186 { |
2169 { |
2187 if (row_info->color_type == PNG_COLOR_TYPE_GRAY) |
2170 if (row_info->color_type == PNG_COLOR_TYPE_GRAY) |
2188 { |
2171 { |
2189 if (row_info->bit_depth == 8) |
2172 if (row_info->bit_depth == 8) |
2250 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); |
2233 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); |
2251 } |
2234 } |
2252 } |
2235 } |
2253 #endif |
2236 #endif |
2254 |
2237 |
2255 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) |
2238 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED |
2256 /* Reduce RGB files to grayscale, with or without alpha |
2239 /* Reduce RGB files to grayscale, with or without alpha |
2257 * using the equation given in Poynton's ColorFAQ at |
2240 * using the equation given in Poynton's ColorFAQ at |
2258 * <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008) |
2241 * <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008) |
2259 * New link: |
2242 * New link: |
2260 * <http://www.poynton.com/notes/colour_and_gamma/> |
2243 * <http://www.poynton.com/notes/colour_and_gamma/> |
2282 |
2265 |
2283 png_uint_32 row_width = row_info->width; |
2266 png_uint_32 row_width = row_info->width; |
2284 int rgb_error = 0; |
2267 int rgb_error = 0; |
2285 |
2268 |
2286 png_debug(1, "in png_do_rgb_to_gray"); |
2269 png_debug(1, "in png_do_rgb_to_gray"); |
2270 |
|
2287 if ( |
2271 if ( |
2288 #if defined(PNG_USELESS_TESTS_SUPPORTED) |
|
2289 row != NULL && row_info != NULL && |
|
2290 #endif |
|
2291 (row_info->color_type & PNG_COLOR_MASK_COLOR)) |
2272 (row_info->color_type & PNG_COLOR_MASK_COLOR)) |
2292 { |
2273 { |
2293 png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; |
2274 png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; |
2294 png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; |
2275 png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; |
2295 png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff; |
2276 png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff; |
2520 int color_inc; |
2501 int color_inc; |
2521 int i; |
2502 int i; |
2522 int v; |
2503 int v; |
2523 |
2504 |
2524 png_debug(1, "in png_do_build_grayscale_palette"); |
2505 png_debug(1, "in png_do_build_grayscale_palette"); |
2506 |
|
2525 if (palette == NULL) |
2507 if (palette == NULL) |
2526 return; |
2508 return; |
2527 |
2509 |
2528 switch (bit_depth) |
2510 switch (bit_depth) |
2529 { |
2511 { |
2559 palette[i].green = (png_byte)v; |
2541 palette[i].green = (png_byte)v; |
2560 palette[i].blue = (png_byte)v; |
2542 palette[i].blue = (png_byte)v; |
2561 } |
2543 } |
2562 } |
2544 } |
2563 |
2545 |
2564 /* This function is currently unused. Do we really need it? */ |
2546 |
2565 #if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED) |
2547 #ifdef PNG_READ_BACKGROUND_SUPPORTED |
2566 void /* PRIVATE */ |
|
2567 png_correct_palette(png_structp png_ptr, png_colorp palette, |
|
2568 int num_palette) |
|
2569 { |
|
2570 png_debug(1, "in png_correct_palette"); |
|
2571 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ |
|
2572 defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) |
|
2573 if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND)) |
|
2574 { |
|
2575 png_color back, back_1; |
|
2576 |
|
2577 if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE) |
|
2578 { |
|
2579 back.red = png_ptr->gamma_table[png_ptr->background.red]; |
|
2580 back.green = png_ptr->gamma_table[png_ptr->background.green]; |
|
2581 back.blue = png_ptr->gamma_table[png_ptr->background.blue]; |
|
2582 |
|
2583 back_1.red = png_ptr->gamma_to_1[png_ptr->background.red]; |
|
2584 back_1.green = png_ptr->gamma_to_1[png_ptr->background.green]; |
|
2585 back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue]; |
|
2586 } |
|
2587 else |
|
2588 { |
|
2589 double g; |
|
2590 |
|
2591 g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma); |
|
2592 |
|
2593 if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN || |
|
2594 fabs(g - 1.0) < PNG_GAMMA_THRESHOLD) |
|
2595 { |
|
2596 back.red = png_ptr->background.red; |
|
2597 back.green = png_ptr->background.green; |
|
2598 back.blue = png_ptr->background.blue; |
|
2599 } |
|
2600 else |
|
2601 { |
|
2602 back.red = |
|
2603 (png_byte)(pow((double)png_ptr->background.red/255, g) * |
|
2604 255.0 + 0.5); |
|
2605 back.green = |
|
2606 (png_byte)(pow((double)png_ptr->background.green/255, g) * |
|
2607 255.0 + 0.5); |
|
2608 back.blue = |
|
2609 (png_byte)(pow((double)png_ptr->background.blue/255, g) * |
|
2610 255.0 + 0.5); |
|
2611 } |
|
2612 |
|
2613 g = 1.0 / png_ptr->background_gamma; |
|
2614 |
|
2615 back_1.red = |
|
2616 (png_byte)(pow((double)png_ptr->background.red/255, g) * |
|
2617 255.0 + 0.5); |
|
2618 back_1.green = |
|
2619 (png_byte)(pow((double)png_ptr->background.green/255, g) * |
|
2620 255.0 + 0.5); |
|
2621 back_1.blue = |
|
2622 (png_byte)(pow((double)png_ptr->background.blue/255, g) * |
|
2623 255.0 + 0.5); |
|
2624 } |
|
2625 |
|
2626 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
|
2627 { |
|
2628 png_uint_32 i; |
|
2629 |
|
2630 for (i = 0; i < (png_uint_32)num_palette; i++) |
|
2631 { |
|
2632 if (i < png_ptr->num_trans && png_ptr->trans[i] == 0) |
|
2633 { |
|
2634 palette[i] = back; |
|
2635 } |
|
2636 else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff) |
|
2637 { |
|
2638 png_byte v, w; |
|
2639 |
|
2640 v = png_ptr->gamma_to_1[png_ptr->palette[i].red]; |
|
2641 png_composite(w, v, png_ptr->trans[i], back_1.red); |
|
2642 palette[i].red = png_ptr->gamma_from_1[w]; |
|
2643 |
|
2644 v = png_ptr->gamma_to_1[png_ptr->palette[i].green]; |
|
2645 png_composite(w, v, png_ptr->trans[i], back_1.green); |
|
2646 palette[i].green = png_ptr->gamma_from_1[w]; |
|
2647 |
|
2648 v = png_ptr->gamma_to_1[png_ptr->palette[i].blue]; |
|
2649 png_composite(w, v, png_ptr->trans[i], back_1.blue); |
|
2650 palette[i].blue = png_ptr->gamma_from_1[w]; |
|
2651 } |
|
2652 else |
|
2653 { |
|
2654 palette[i].red = png_ptr->gamma_table[palette[i].red]; |
|
2655 palette[i].green = png_ptr->gamma_table[palette[i].green]; |
|
2656 palette[i].blue = png_ptr->gamma_table[palette[i].blue]; |
|
2657 } |
|
2658 } |
|
2659 } |
|
2660 else |
|
2661 { |
|
2662 int i; |
|
2663 |
|
2664 for (i = 0; i < num_palette; i++) |
|
2665 { |
|
2666 if (palette[i].red == (png_byte)png_ptr->trans_values.gray) |
|
2667 { |
|
2668 palette[i] = back; |
|
2669 } |
|
2670 else |
|
2671 { |
|
2672 palette[i].red = png_ptr->gamma_table[palette[i].red]; |
|
2673 palette[i].green = png_ptr->gamma_table[palette[i].green]; |
|
2674 palette[i].blue = png_ptr->gamma_table[palette[i].blue]; |
|
2675 } |
|
2676 } |
|
2677 } |
|
2678 } |
|
2679 else |
|
2680 #endif |
|
2681 #if defined(PNG_READ_GAMMA_SUPPORTED) |
|
2682 if (png_ptr->transformations & PNG_GAMMA) |
|
2683 { |
|
2684 int i; |
|
2685 |
|
2686 for (i = 0; i < num_palette; i++) |
|
2687 { |
|
2688 palette[i].red = png_ptr->gamma_table[palette[i].red]; |
|
2689 palette[i].green = png_ptr->gamma_table[palette[i].green]; |
|
2690 palette[i].blue = png_ptr->gamma_table[palette[i].blue]; |
|
2691 } |
|
2692 } |
|
2693 #if defined(PNG_READ_BACKGROUND_SUPPORTED) |
|
2694 else |
|
2695 #endif |
|
2696 #endif |
|
2697 #if defined(PNG_READ_BACKGROUND_SUPPORTED) |
|
2698 if (png_ptr->transformations & PNG_BACKGROUND) |
|
2699 { |
|
2700 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
|
2701 { |
|
2702 png_color back; |
|
2703 |
|
2704 back.red = (png_byte)png_ptr->background.red; |
|
2705 back.green = (png_byte)png_ptr->background.green; |
|
2706 back.blue = (png_byte)png_ptr->background.blue; |
|
2707 |
|
2708 for (i = 0; i < (int)png_ptr->num_trans; i++) |
|
2709 { |
|
2710 if (png_ptr->trans[i] == 0) |
|
2711 { |
|
2712 palette[i].red = back.red; |
|
2713 palette[i].green = back.green; |
|
2714 palette[i].blue = back.blue; |
|
2715 } |
|
2716 else if (png_ptr->trans[i] != 0xff) |
|
2717 { |
|
2718 png_composite(palette[i].red, png_ptr->palette[i].red, |
|
2719 png_ptr->trans[i], back.red); |
|
2720 png_composite(palette[i].green, png_ptr->palette[i].green, |
|
2721 png_ptr->trans[i], back.green); |
|
2722 png_composite(palette[i].blue, png_ptr->palette[i].blue, |
|
2723 png_ptr->trans[i], back.blue); |
|
2724 } |
|
2725 } |
|
2726 } |
|
2727 else /* Assume grayscale palette (what else could it be?) */ |
|
2728 { |
|
2729 int i; |
|
2730 |
|
2731 for (i = 0; i < num_palette; i++) |
|
2732 { |
|
2733 if (i == (png_byte)png_ptr->trans_values.gray) |
|
2734 { |
|
2735 palette[i].red = (png_byte)png_ptr->background.red; |
|
2736 palette[i].green = (png_byte)png_ptr->background.green; |
|
2737 palette[i].blue = (png_byte)png_ptr->background.blue; |
|
2738 } |
|
2739 } |
|
2740 } |
|
2741 } |
|
2742 #endif |
|
2743 } |
|
2744 #endif |
|
2745 |
|
2746 #if defined(PNG_READ_BACKGROUND_SUPPORTED) |
|
2747 /* Replace any alpha or transparency with the supplied background color. |
2548 /* Replace any alpha or transparency with the supplied background color. |
2748 * "background" is already in the screen gamma, while "background_1" is |
2549 * "background" is already in the screen gamma, while "background_1" is |
2749 * at a gamma of 1.0. Paletted files have already been taken care of. |
2550 * at a gamma of 1.0. Paletted files have already been taken care of. |
2750 */ |
2551 */ |
2751 void /* PRIVATE */ |
2552 void /* PRIVATE */ |
2752 png_do_background(png_row_infop row_info, png_bytep row, |
2553 png_do_background(png_row_infop row_info, png_bytep row, |
2753 png_color_16p trans_values, png_color_16p background |
2554 png_color_16p trans_color, png_color_16p background |
2754 #if defined(PNG_READ_GAMMA_SUPPORTED) |
2555 #ifdef PNG_READ_GAMMA_SUPPORTED |
2755 , png_color_16p background_1, |
2556 , png_color_16p background_1, |
2756 png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1, |
2557 png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1, |
2757 png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1, |
2558 png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1, |
2758 png_uint_16pp gamma_16_to_1, int gamma_shift |
2559 png_uint_16pp gamma_16_to_1, int gamma_shift |
2759 #endif |
2560 #endif |
2763 png_uint_32 i; |
2564 png_uint_32 i; |
2764 png_uint_32 row_width=row_info->width; |
2565 png_uint_32 row_width=row_info->width; |
2765 int shift; |
2566 int shift; |
2766 |
2567 |
2767 png_debug(1, "in png_do_background"); |
2568 png_debug(1, "in png_do_background"); |
2569 |
|
2768 if (background != NULL && |
2570 if (background != NULL && |
2769 #if defined(PNG_USELESS_TESTS_SUPPORTED) |
|
2770 row != NULL && row_info != NULL && |
|
2771 #endif |
|
2772 (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) || |
2571 (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) || |
2773 (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values))) |
2572 (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_color))) |
2774 { |
2573 { |
2775 switch (row_info->color_type) |
2574 switch (row_info->color_type) |
2776 { |
2575 { |
2777 case PNG_COLOR_TYPE_GRAY: |
2576 case PNG_COLOR_TYPE_GRAY: |
2778 { |
2577 { |
2783 sp = row; |
2582 sp = row; |
2784 shift = 7; |
2583 shift = 7; |
2785 for (i = 0; i < row_width; i++) |
2584 for (i = 0; i < row_width; i++) |
2786 { |
2585 { |
2787 if ((png_uint_16)((*sp >> shift) & 0x01) |
2586 if ((png_uint_16)((*sp >> shift) & 0x01) |
2788 == trans_values->gray) |
2587 == trans_color->gray) |
2789 { |
2588 { |
2790 *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); |
2589 *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); |
2791 *sp |= (png_byte)(background->gray << shift); |
2590 *sp |= (png_byte)(background->gray << shift); |
2792 } |
2591 } |
2793 if (!shift) |
2592 if (!shift) |
2801 break; |
2600 break; |
2802 } |
2601 } |
2803 |
2602 |
2804 case 2: |
2603 case 2: |
2805 { |
2604 { |
2806 #if defined(PNG_READ_GAMMA_SUPPORTED) |
2605 #ifdef PNG_READ_GAMMA_SUPPORTED |
2807 if (gamma_table != NULL) |
2606 if (gamma_table != NULL) |
2808 { |
2607 { |
2809 sp = row; |
2608 sp = row; |
2810 shift = 6; |
2609 shift = 6; |
2811 for (i = 0; i < row_width; i++) |
2610 for (i = 0; i < row_width; i++) |
2812 { |
2611 { |
2813 if ((png_uint_16)((*sp >> shift) & 0x03) |
2612 if ((png_uint_16)((*sp >> shift) & 0x03) |
2814 == trans_values->gray) |
2613 == trans_color->gray) |
2815 { |
2614 { |
2816 *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); |
2615 *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); |
2817 *sp |= (png_byte)(background->gray << shift); |
2616 *sp |= (png_byte)(background->gray << shift); |
2818 } |
2617 } |
2819 else |
2618 else |
2839 sp = row; |
2638 sp = row; |
2840 shift = 6; |
2639 shift = 6; |
2841 for (i = 0; i < row_width; i++) |
2640 for (i = 0; i < row_width; i++) |
2842 { |
2641 { |
2843 if ((png_uint_16)((*sp >> shift) & 0x03) |
2642 if ((png_uint_16)((*sp >> shift) & 0x03) |
2844 == trans_values->gray) |
2643 == trans_color->gray) |
2845 { |
2644 { |
2846 *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); |
2645 *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); |
2847 *sp |= (png_byte)(background->gray << shift); |
2646 *sp |= (png_byte)(background->gray << shift); |
2848 } |
2647 } |
2849 if (!shift) |
2648 if (!shift) |
2858 break; |
2657 break; |
2859 } |
2658 } |
2860 |
2659 |
2861 case 4: |
2660 case 4: |
2862 { |
2661 { |
2863 #if defined(PNG_READ_GAMMA_SUPPORTED) |
2662 #ifdef PNG_READ_GAMMA_SUPPORTED |
2864 if (gamma_table != NULL) |
2663 if (gamma_table != NULL) |
2865 { |
2664 { |
2866 sp = row; |
2665 sp = row; |
2867 shift = 4; |
2666 shift = 4; |
2868 for (i = 0; i < row_width; i++) |
2667 for (i = 0; i < row_width; i++) |
2869 { |
2668 { |
2870 if ((png_uint_16)((*sp >> shift) & 0x0f) |
2669 if ((png_uint_16)((*sp >> shift) & 0x0f) |
2871 == trans_values->gray) |
2670 == trans_color->gray) |
2872 { |
2671 { |
2873 *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); |
2672 *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); |
2874 *sp |= (png_byte)(background->gray << shift); |
2673 *sp |= (png_byte)(background->gray << shift); |
2875 } |
2674 } |
2876 else |
2675 else |
2896 sp = row; |
2695 sp = row; |
2897 shift = 4; |
2696 shift = 4; |
2898 for (i = 0; i < row_width; i++) |
2697 for (i = 0; i < row_width; i++) |
2899 { |
2698 { |
2900 if ((png_uint_16)((*sp >> shift) & 0x0f) |
2699 if ((png_uint_16)((*sp >> shift) & 0x0f) |
2901 == trans_values->gray) |
2700 == trans_color->gray) |
2902 { |
2701 { |
2903 *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); |
2702 *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); |
2904 *sp |= (png_byte)(background->gray << shift); |
2703 *sp |= (png_byte)(background->gray << shift); |
2905 } |
2704 } |
2906 if (!shift) |
2705 if (!shift) |
2915 break; |
2714 break; |
2916 } |
2715 } |
2917 |
2716 |
2918 case 8: |
2717 case 8: |
2919 { |
2718 { |
2920 #if defined(PNG_READ_GAMMA_SUPPORTED) |
2719 #ifdef PNG_READ_GAMMA_SUPPORTED |
2921 if (gamma_table != NULL) |
2720 if (gamma_table != NULL) |
2922 { |
2721 { |
2923 sp = row; |
2722 sp = row; |
2924 for (i = 0; i < row_width; i++, sp++) |
2723 for (i = 0; i < row_width; i++, sp++) |
2925 { |
2724 { |
2926 if (*sp == trans_values->gray) |
2725 if (*sp == trans_color->gray) |
2927 { |
2726 { |
2928 *sp = (png_byte)background->gray; |
2727 *sp = (png_byte)background->gray; |
2929 } |
2728 } |
2930 else |
2729 else |
2931 { |
2730 { |
2937 #endif |
2736 #endif |
2938 { |
2737 { |
2939 sp = row; |
2738 sp = row; |
2940 for (i = 0; i < row_width; i++, sp++) |
2739 for (i = 0; i < row_width; i++, sp++) |
2941 { |
2740 { |
2942 if (*sp == trans_values->gray) |
2741 if (*sp == trans_color->gray) |
2943 { |
2742 { |
2944 *sp = (png_byte)background->gray; |
2743 *sp = (png_byte)background->gray; |
2945 } |
2744 } |
2946 } |
2745 } |
2947 } |
2746 } |
2948 break; |
2747 break; |
2949 } |
2748 } |
2950 |
2749 |
2951 case 16: |
2750 case 16: |
2952 { |
2751 { |
2953 #if defined(PNG_READ_GAMMA_SUPPORTED) |
2752 #ifdef PNG_READ_GAMMA_SUPPORTED |
2954 if (gamma_16 != NULL) |
2753 if (gamma_16 != NULL) |
2955 { |
2754 { |
2956 sp = row; |
2755 sp = row; |
2957 for (i = 0; i < row_width; i++, sp += 2) |
2756 for (i = 0; i < row_width; i++, sp += 2) |
2958 { |
2757 { |
2959 png_uint_16 v; |
2758 png_uint_16 v; |
2960 |
2759 |
2961 v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); |
2760 v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); |
2962 if (v == trans_values->gray) |
2761 if (v == trans_color->gray) |
2963 { |
2762 { |
2964 /* Background is already in screen gamma */ |
2763 /* Background is already in screen gamma */ |
2965 *sp = (png_byte)((background->gray >> 8) & 0xff); |
2764 *sp = (png_byte)((background->gray >> 8) & 0xff); |
2966 *(sp + 1) = (png_byte)(background->gray & 0xff); |
2765 *(sp + 1) = (png_byte)(background->gray & 0xff); |
2967 } |
2766 } |
2980 for (i = 0; i < row_width; i++, sp += 2) |
2779 for (i = 0; i < row_width; i++, sp += 2) |
2981 { |
2780 { |
2982 png_uint_16 v; |
2781 png_uint_16 v; |
2983 |
2782 |
2984 v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); |
2783 v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); |
2985 if (v == trans_values->gray) |
2784 if (v == trans_color->gray) |
2986 { |
2785 { |
2987 *sp = (png_byte)((background->gray >> 8) & 0xff); |
2786 *sp = (png_byte)((background->gray >> 8) & 0xff); |
2988 *(sp + 1) = (png_byte)(background->gray & 0xff); |
2787 *(sp + 1) = (png_byte)(background->gray & 0xff); |
2989 } |
2788 } |
2990 } |
2789 } |
2997 |
2796 |
2998 case PNG_COLOR_TYPE_RGB: |
2797 case PNG_COLOR_TYPE_RGB: |
2999 { |
2798 { |
3000 if (row_info->bit_depth == 8) |
2799 if (row_info->bit_depth == 8) |
3001 { |
2800 { |
3002 #if defined(PNG_READ_GAMMA_SUPPORTED) |
2801 #ifdef PNG_READ_GAMMA_SUPPORTED |
3003 if (gamma_table != NULL) |
2802 if (gamma_table != NULL) |
3004 { |
2803 { |
3005 sp = row; |
2804 sp = row; |
3006 for (i = 0; i < row_width; i++, sp += 3) |
2805 for (i = 0; i < row_width; i++, sp += 3) |
3007 { |
2806 { |
3008 if (*sp == trans_values->red && |
2807 if (*sp == trans_color->red && |
3009 *(sp + 1) == trans_values->green && |
2808 *(sp + 1) == trans_color->green && |
3010 *(sp + 2) == trans_values->blue) |
2809 *(sp + 2) == trans_color->blue) |
3011 { |
2810 { |
3012 *sp = (png_byte)background->red; |
2811 *sp = (png_byte)background->red; |
3013 *(sp + 1) = (png_byte)background->green; |
2812 *(sp + 1) = (png_byte)background->green; |
3014 *(sp + 2) = (png_byte)background->blue; |
2813 *(sp + 2) = (png_byte)background->blue; |
3015 } |
2814 } |
3025 #endif |
2824 #endif |
3026 { |
2825 { |
3027 sp = row; |
2826 sp = row; |
3028 for (i = 0; i < row_width; i++, sp += 3) |
2827 for (i = 0; i < row_width; i++, sp += 3) |
3029 { |
2828 { |
3030 if (*sp == trans_values->red && |
2829 if (*sp == trans_color->red && |
3031 *(sp + 1) == trans_values->green && |
2830 *(sp + 1) == trans_color->green && |
3032 *(sp + 2) == trans_values->blue) |
2831 *(sp + 2) == trans_color->blue) |
3033 { |
2832 { |
3034 *sp = (png_byte)background->red; |
2833 *sp = (png_byte)background->red; |
3035 *(sp + 1) = (png_byte)background->green; |
2834 *(sp + 1) = (png_byte)background->green; |
3036 *(sp + 2) = (png_byte)background->blue; |
2835 *(sp + 2) = (png_byte)background->blue; |
3037 } |
2836 } |
3038 } |
2837 } |
3039 } |
2838 } |
3040 } |
2839 } |
3041 else /* if (row_info->bit_depth == 16) */ |
2840 else /* if (row_info->bit_depth == 16) */ |
3042 { |
2841 { |
3043 #if defined(PNG_READ_GAMMA_SUPPORTED) |
2842 #ifdef PNG_READ_GAMMA_SUPPORTED |
3044 if (gamma_16 != NULL) |
2843 if (gamma_16 != NULL) |
3045 { |
2844 { |
3046 sp = row; |
2845 sp = row; |
3047 for (i = 0; i < row_width; i++, sp += 6) |
2846 for (i = 0; i < row_width; i++, sp += 6) |
3048 { |
2847 { |
3049 png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); |
2848 png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); |
3050 png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); |
2849 png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); |
3051 png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5)); |
2850 png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5)); |
3052 if (r == trans_values->red && g == trans_values->green && |
2851 if (r == trans_color->red && g == trans_color->green && |
3053 b == trans_values->blue) |
2852 b == trans_color->blue) |
3054 { |
2853 { |
3055 /* Background is already in screen gamma */ |
2854 /* Background is already in screen gamma */ |
3056 *sp = (png_byte)((background->red >> 8) & 0xff); |
2855 *sp = (png_byte)((background->red >> 8) & 0xff); |
3057 *(sp + 1) = (png_byte)(background->red & 0xff); |
2856 *(sp + 1) = (png_byte)(background->red & 0xff); |
3058 *(sp + 2) = (png_byte)((background->green >> 8) & 0xff); |
2857 *(sp + 2) = (png_byte)((background->green >> 8) & 0xff); |
3082 { |
2881 { |
3083 png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1)); |
2882 png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1)); |
3084 png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); |
2883 png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); |
3085 png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5)); |
2884 png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5)); |
3086 |
2885 |
3087 if (r == trans_values->red && g == trans_values->green && |
2886 if (r == trans_color->red && g == trans_color->green && |
3088 b == trans_values->blue) |
2887 b == trans_color->blue) |
3089 { |
2888 { |
3090 *sp = (png_byte)((background->red >> 8) & 0xff); |
2889 *sp = (png_byte)((background->red >> 8) & 0xff); |
3091 *(sp + 1) = (png_byte)(background->red & 0xff); |
2890 *(sp + 1) = (png_byte)(background->red & 0xff); |
3092 *(sp + 2) = (png_byte)((background->green >> 8) & 0xff); |
2891 *(sp + 2) = (png_byte)((background->green >> 8) & 0xff); |
3093 *(sp + 3) = (png_byte)(background->green & 0xff); |
2892 *(sp + 3) = (png_byte)(background->green & 0xff); |
3102 |
2901 |
3103 case PNG_COLOR_TYPE_GRAY_ALPHA: |
2902 case PNG_COLOR_TYPE_GRAY_ALPHA: |
3104 { |
2903 { |
3105 if (row_info->bit_depth == 8) |
2904 if (row_info->bit_depth == 8) |
3106 { |
2905 { |
3107 #if defined(PNG_READ_GAMMA_SUPPORTED) |
2906 #ifdef PNG_READ_GAMMA_SUPPORTED |
3108 if (gamma_to_1 != NULL && gamma_from_1 != NULL && |
2907 if (gamma_to_1 != NULL && gamma_from_1 != NULL && |
3109 gamma_table != NULL) |
2908 gamma_table != NULL) |
3110 { |
2909 { |
3111 sp = row; |
2910 sp = row; |
3112 dp = row; |
2911 dp = row; |
3144 |
2943 |
3145 if (a == 0xff) |
2944 if (a == 0xff) |
3146 { |
2945 { |
3147 *dp = *sp; |
2946 *dp = *sp; |
3148 } |
2947 } |
3149 #if defined(PNG_READ_GAMMA_SUPPORTED) |
2948 #ifdef PNG_READ_GAMMA_SUPPORTED |
3150 else if (a == 0) |
2949 else if (a == 0) |
3151 { |
2950 { |
3152 *dp = (png_byte)background->gray; |
2951 *dp = (png_byte)background->gray; |
3153 } |
2952 } |
3154 else |
2953 else |
3161 } |
2960 } |
3162 } |
2961 } |
3163 } |
2962 } |
3164 else /* if (png_ptr->bit_depth == 16) */ |
2963 else /* if (png_ptr->bit_depth == 16) */ |
3165 { |
2964 { |
3166 #if defined(PNG_READ_GAMMA_SUPPORTED) |
2965 #ifdef PNG_READ_GAMMA_SUPPORTED |
3167 if (gamma_16 != NULL && gamma_16_from_1 != NULL && |
2966 if (gamma_16 != NULL && gamma_16_from_1 != NULL && |
3168 gamma_16_to_1 != NULL) |
2967 gamma_16_to_1 != NULL) |
3169 { |
2968 { |
3170 sp = row; |
2969 sp = row; |
3171 dp = row; |
2970 dp = row; |
3179 |
2978 |
3180 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; |
2979 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; |
3181 *dp = (png_byte)((v >> 8) & 0xff); |
2980 *dp = (png_byte)((v >> 8) & 0xff); |
3182 *(dp + 1) = (png_byte)(v & 0xff); |
2981 *(dp + 1) = (png_byte)(v & 0xff); |
3183 } |
2982 } |
3184 #if defined(PNG_READ_GAMMA_SUPPORTED) |
2983 #ifdef PNG_READ_GAMMA_SUPPORTED |
3185 else if (a == 0) |
2984 else if (a == 0) |
3186 #else |
2985 #else |
3187 else |
2986 else |
3188 #endif |
2987 #endif |
3189 { |
2988 { |
3190 /* Background is already in screen gamma */ |
2989 /* Background is already in screen gamma */ |
3191 *dp = (png_byte)((background->gray >> 8) & 0xff); |
2990 *dp = (png_byte)((background->gray >> 8) & 0xff); |
3192 *(dp + 1) = (png_byte)(background->gray & 0xff); |
2991 *(dp + 1) = (png_byte)(background->gray & 0xff); |
3193 } |
2992 } |
3194 #if defined(PNG_READ_GAMMA_SUPPORTED) |
2993 #ifdef PNG_READ_GAMMA_SUPPORTED |
3195 else |
2994 else |
3196 { |
2995 { |
3197 png_uint_16 g, v, w; |
2996 png_uint_16 g, v, w; |
3198 |
2997 |
3199 g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; |
2998 g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; |
3215 png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); |
3014 png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); |
3216 if (a == (png_uint_16)0xffff) |
3015 if (a == (png_uint_16)0xffff) |
3217 { |
3016 { |
3218 png_memcpy(dp, sp, 2); |
3017 png_memcpy(dp, sp, 2); |
3219 } |
3018 } |
3220 #if defined(PNG_READ_GAMMA_SUPPORTED) |
3019 #ifdef PNG_READ_GAMMA_SUPPORTED |
3221 else if (a == 0) |
3020 else if (a == 0) |
3222 #else |
3021 #else |
3223 else |
3022 else |
3224 #endif |
3023 #endif |
3225 { |
3024 { |
3226 *dp = (png_byte)((background->gray >> 8) & 0xff); |
3025 *dp = (png_byte)((background->gray >> 8) & 0xff); |
3227 *(dp + 1) = (png_byte)(background->gray & 0xff); |
3026 *(dp + 1) = (png_byte)(background->gray & 0xff); |
3228 } |
3027 } |
3229 #if defined(PNG_READ_GAMMA_SUPPORTED) |
3028 #ifdef PNG_READ_GAMMA_SUPPORTED |
3230 else |
3029 else |
3231 { |
3030 { |
3232 png_uint_16 g, v; |
3031 png_uint_16 g, v; |
3233 |
3032 |
3234 g = (png_uint_16)(((*sp) << 8) + *(sp + 1)); |
3033 g = (png_uint_16)(((*sp) << 8) + *(sp + 1)); |
3245 |
3044 |
3246 case PNG_COLOR_TYPE_RGB_ALPHA: |
3045 case PNG_COLOR_TYPE_RGB_ALPHA: |
3247 { |
3046 { |
3248 if (row_info->bit_depth == 8) |
3047 if (row_info->bit_depth == 8) |
3249 { |
3048 { |
3250 #if defined(PNG_READ_GAMMA_SUPPORTED) |
3049 #ifdef PNG_READ_GAMMA_SUPPORTED |
3251 if (gamma_to_1 != NULL && gamma_from_1 != NULL && |
3050 if (gamma_to_1 != NULL && gamma_from_1 != NULL && |
3252 gamma_table != NULL) |
3051 gamma_table != NULL) |
3253 { |
3052 { |
3254 sp = row; |
3053 sp = row; |
3255 dp = row; |
3054 dp = row; |
3318 } |
3117 } |
3319 } |
3118 } |
3320 } |
3119 } |
3321 else /* if (row_info->bit_depth == 16) */ |
3120 else /* if (row_info->bit_depth == 16) */ |
3322 { |
3121 { |
3323 #if defined(PNG_READ_GAMMA_SUPPORTED) |
3122 #ifdef PNG_READ_GAMMA_SUPPORTED |
3324 if (gamma_16 != NULL && gamma_16_from_1 != NULL && |
3123 if (gamma_16 != NULL && gamma_16_from_1 != NULL && |
3325 gamma_16_to_1 != NULL) |
3124 gamma_16_to_1 != NULL) |
3326 { |
3125 { |
3327 sp = row; |
3126 sp = row; |
3328 dp = row; |
3127 dp = row; |
3435 } |
3234 } |
3436 } |
3235 } |
3437 } |
3236 } |
3438 #endif |
3237 #endif |
3439 |
3238 |
3440 #if defined(PNG_READ_GAMMA_SUPPORTED) |
3239 #ifdef PNG_READ_GAMMA_SUPPORTED |
3441 /* Gamma correct the image, avoiding the alpha channel. Make sure |
3240 /* Gamma correct the image, avoiding the alpha channel. Make sure |
3442 * you do this after you deal with the transparency issue on grayscale |
3241 * you do this after you deal with the transparency issue on grayscale |
3443 * or RGB images. If your bit depth is 8, use gamma_table, if it |
3242 * or RGB images. If your bit depth is 8, use gamma_table, if it |
3444 * is 16, use gamma_16_table and gamma_shift. Build these with |
3243 * is 16, use gamma_16_table and gamma_shift. Build these with |
3445 * build_gamma_table(). |
3244 * build_gamma_table(). |
3452 png_bytep sp; |
3251 png_bytep sp; |
3453 png_uint_32 i; |
3252 png_uint_32 i; |
3454 png_uint_32 row_width=row_info->width; |
3253 png_uint_32 row_width=row_info->width; |
3455 |
3254 |
3456 png_debug(1, "in png_do_gamma"); |
3255 png_debug(1, "in png_do_gamma"); |
3256 |
|
3457 if ( |
3257 if ( |
3458 #if defined(PNG_USELESS_TESTS_SUPPORTED) |
|
3459 row != NULL && row_info != NULL && |
|
3460 #endif |
|
3461 ((row_info->bit_depth <= 8 && gamma_table != NULL) || |
3258 ((row_info->bit_depth <= 8 && gamma_table != NULL) || |
3462 (row_info->bit_depth == 16 && gamma_16_table != NULL))) |
3259 (row_info->bit_depth == 16 && gamma_16_table != NULL))) |
3463 { |
3260 { |
3464 switch (row_info->color_type) |
3261 switch (row_info->color_type) |
3465 { |
3262 { |
3626 } |
3423 } |
3627 } |
3424 } |
3628 } |
3425 } |
3629 #endif |
3426 #endif |
3630 |
3427 |
3631 #if defined(PNG_READ_EXPAND_SUPPORTED) |
3428 #ifdef PNG_READ_EXPAND_SUPPORTED |
3632 /* Expands a palette row to an RGB or RGBA row depending |
3429 /* Expands a palette row to an RGB or RGBA row depending |
3633 * upon whether you supply trans and num_trans. |
3430 * upon whether you supply trans and num_trans. |
3634 */ |
3431 */ |
3635 void /* PRIVATE */ |
3432 void /* PRIVATE */ |
3636 png_do_expand_palette(png_row_infop row_info, png_bytep row, |
3433 png_do_expand_palette(png_row_infop row_info, png_bytep row, |
3637 png_colorp palette, png_bytep trans, int num_trans) |
3434 png_colorp palette, png_bytep trans_alpha, int num_trans) |
3638 { |
3435 { |
3639 int shift, value; |
3436 int shift, value; |
3640 png_bytep sp, dp; |
3437 png_bytep sp, dp; |
3641 png_uint_32 i; |
3438 png_uint_32 i; |
3642 png_uint_32 row_width=row_info->width; |
3439 png_uint_32 row_width=row_info->width; |
3643 |
3440 |
3644 png_debug(1, "in png_do_expand_palette"); |
3441 png_debug(1, "in png_do_expand_palette"); |
3442 |
|
3645 if ( |
3443 if ( |
3646 #if defined(PNG_USELESS_TESTS_SUPPORTED) |
|
3647 row != NULL && row_info != NULL && |
|
3648 #endif |
|
3649 row_info->color_type == PNG_COLOR_TYPE_PALETTE) |
3444 row_info->color_type == PNG_COLOR_TYPE_PALETTE) |
3650 { |
3445 { |
3651 if (row_info->bit_depth < 8) |
3446 if (row_info->bit_depth < 8) |
3652 { |
3447 { |
3653 switch (row_info->bit_depth) |
3448 switch (row_info->bit_depth) |
3726 } |
3521 } |
3727 switch (row_info->bit_depth) |
3522 switch (row_info->bit_depth) |
3728 { |
3523 { |
3729 case 8: |
3524 case 8: |
3730 { |
3525 { |
3731 if (trans != NULL) |
3526 if (trans_alpha != NULL) |
3732 { |
3527 { |
3733 sp = row + (png_size_t)row_width - 1; |
3528 sp = row + (png_size_t)row_width - 1; |
3734 dp = row + (png_size_t)(row_width << 2) - 1; |
3529 dp = row + (png_size_t)(row_width << 2) - 1; |
3735 |
3530 |
3736 for (i = 0; i < row_width; i++) |
3531 for (i = 0; i < row_width; i++) |
3737 { |
3532 { |
3738 if ((int)(*sp) >= num_trans) |
3533 if ((int)(*sp) >= num_trans) |
3739 *dp-- = 0xff; |
3534 *dp-- = 0xff; |
3740 else |
3535 else |
3741 *dp-- = trans[*sp]; |
3536 *dp-- = trans_alpha[*sp]; |
3742 *dp-- = palette[*sp].blue; |
3537 *dp-- = palette[*sp].blue; |
3743 *dp-- = palette[*sp].green; |
3538 *dp-- = palette[*sp].green; |
3744 *dp-- = palette[*sp].red; |
3539 *dp-- = palette[*sp].red; |
3745 sp--; |
3540 sp--; |
3746 } |
3541 } |
3786 png_bytep sp, dp; |
3581 png_bytep sp, dp; |
3787 png_uint_32 i; |
3582 png_uint_32 i; |
3788 png_uint_32 row_width=row_info->width; |
3583 png_uint_32 row_width=row_info->width; |
3789 |
3584 |
3790 png_debug(1, "in png_do_expand"); |
3585 png_debug(1, "in png_do_expand"); |
3791 #if defined(PNG_USELESS_TESTS_SUPPORTED) |
3586 |
3792 if (row != NULL && row_info != NULL) |
|
3793 #endif |
|
3794 { |
3587 { |
3795 if (row_info->color_type == PNG_COLOR_TYPE_GRAY) |
3588 if (row_info->color_type == PNG_COLOR_TYPE_GRAY) |
3796 { |
3589 { |
3797 png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0); |
3590 png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0); |
3798 |
3591 |
3987 } |
3780 } |
3988 } |
3781 } |
3989 } |
3782 } |
3990 #endif |
3783 #endif |
3991 |
3784 |
3992 #if defined(PNG_READ_DITHER_SUPPORTED) |
3785 #ifdef PNG_READ_DITHER_SUPPORTED |
3993 void /* PRIVATE */ |
3786 void /* PRIVATE */ |
3994 png_do_dither(png_row_infop row_info, png_bytep row, |
3787 png_do_dither(png_row_infop row_info, png_bytep row, |
3995 png_bytep palette_lookup, png_bytep dither_lookup) |
3788 png_bytep palette_lookup, png_bytep dither_lookup) |
3996 { |
3789 { |
3997 png_bytep sp, dp; |
3790 png_bytep sp, dp; |
3998 png_uint_32 i; |
3791 png_uint_32 i; |
3999 png_uint_32 row_width=row_info->width; |
3792 png_uint_32 row_width=row_info->width; |
4000 |
3793 |
4001 png_debug(1, "in png_do_dither"); |
3794 png_debug(1, "in png_do_dither"); |
4002 #if defined(PNG_USELESS_TESTS_SUPPORTED) |
3795 |
4003 if (row != NULL && row_info != NULL) |
|
4004 #endif |
|
4005 { |
3796 { |
4006 if (row_info->color_type == PNG_COLOR_TYPE_RGB && |
3797 if (row_info->color_type == PNG_COLOR_TYPE_RGB && |
4007 palette_lookup && row_info->bit_depth == 8) |
3798 palette_lookup && row_info->bit_depth == 8) |
4008 { |
3799 { |
4009 int r, g, b, p; |
3800 int r, g, b, p; |
4079 } |
3870 } |
4080 } |
3871 } |
4081 #endif |
3872 #endif |
4082 |
3873 |
4083 #ifdef PNG_FLOATING_POINT_SUPPORTED |
3874 #ifdef PNG_FLOATING_POINT_SUPPORTED |
4084 #if defined(PNG_READ_GAMMA_SUPPORTED) |
3875 #ifdef PNG_READ_GAMMA_SUPPORTED |
4085 static PNG_CONST int png_gamma_shift[] = |
3876 static PNG_CONST int png_gamma_shift[] = |
4086 {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00}; |
3877 {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00}; |
4087 |
3878 |
4088 /* We build the 8- or 16-bit gamma tables here. Note that for 16-bit |
3879 /* We build the 8- or 16-bit gamma tables here. Note that for 16-bit |
4089 * tables, we don't make a full table if we are reducing to 8-bit in |
3880 * tables, we don't make a full table if we are reducing to 8-bit in |
4090 * the future. Note also how the gamma_16 tables are segmented so that |
3881 * the future. Note also how the gamma_16 tables are segmented so that |
4091 * we don't need to allocate > 64K chunks for a full 16-bit table. |
3882 * we don't need to allocate > 64K chunks for a full 16-bit table. |
3883 * |
|
3884 * See the PNG extensions document for an integer algorithm for creating |
|
3885 * the gamma tables. Maybe we will implement that here someday. |
|
3886 * |
|
3887 * We should only reach this point if |
|
3888 * |
|
3889 * the file_gamma is known (i.e., the gAMA or sRGB chunk is present, |
|
3890 * or the application has provided a file_gamma) |
|
3891 * |
|
3892 * AND |
|
3893 * { |
|
3894 * the screen_gamma is known |
|
3895 * |
|
3896 * OR |
|
3897 * |
|
3898 * RGB_to_gray transformation is being performed |
|
3899 * } |
|
3900 * |
|
3901 * AND |
|
3902 * { |
|
3903 * the screen_gamma is different from the reciprocal of the |
|
3904 * file_gamma by more than the specified threshold |
|
3905 * |
|
3906 * OR |
|
3907 * |
|
3908 * a background color has been specified and the file_gamma |
|
3909 * and screen_gamma are not 1.0, within the specified threshold. |
|
3910 * } |
|
4092 */ |
3911 */ |
3912 |
|
4093 void /* PRIVATE */ |
3913 void /* PRIVATE */ |
4094 png_build_gamma_table(png_structp png_ptr) |
3914 png_build_gamma_table(png_structp png_ptr, png_byte bit_depth) |
4095 { |
3915 { |
4096 png_debug(1, "in png_build_gamma_table"); |
3916 png_debug(1, "in png_build_gamma_table"); |
4097 |
3917 |
4098 if (png_ptr->bit_depth <= 8) |
3918 if (bit_depth <= 8) |
4099 { |
3919 { |
4100 int i; |
3920 int i; |
4101 double g; |
3921 double g; |
4102 |
3922 |
4103 if (png_ptr->screen_gamma > .000001) |
3923 if (png_ptr->screen_gamma > .000001) |
4197 if (png_ptr->screen_gamma > .000001) |
4017 if (png_ptr->screen_gamma > .000001) |
4198 g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); |
4018 g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); |
4199 else |
4019 else |
4200 g = 1.0; |
4020 g = 1.0; |
4201 |
4021 |
4202 png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr, |
4022 png_ptr->gamma_16_table = (png_uint_16pp)png_calloc(png_ptr, |
4203 (png_uint_32)(num * png_sizeof(png_uint_16p))); |
4023 (png_uint_32)(num * png_sizeof(png_uint_16p))); |
4204 png_memset(png_ptr->gamma_16_table, 0, num * png_sizeof(png_uint_16p)); |
|
4205 |
4024 |
4206 if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND)) |
4025 if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND)) |
4207 { |
4026 { |
4208 double fin, fout; |
4027 double fin, fout; |
4209 png_uint_32 last, max; |
4028 png_uint_32 last, max; |
4259 if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY)) |
4078 if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY)) |
4260 { |
4079 { |
4261 |
4080 |
4262 g = 1.0 / (png_ptr->gamma); |
4081 g = 1.0 / (png_ptr->gamma); |
4263 |
4082 |
4264 png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr, |
4083 png_ptr->gamma_16_to_1 = (png_uint_16pp)png_calloc(png_ptr, |
4265 (png_uint_32)(num * png_sizeof(png_uint_16p ))); |
4084 (png_uint_32)(num * png_sizeof(png_uint_16p ))); |
4266 png_memset(png_ptr->gamma_16_to_1, 0, num * png_sizeof(png_uint_16p)); |
|
4267 |
4085 |
4268 for (i = 0; i < num; i++) |
4086 for (i = 0; i < num; i++) |
4269 { |
4087 { |
4270 png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr, |
4088 png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr, |
4271 (png_uint_32)(256 * png_sizeof(png_uint_16))); |
4089 (png_uint_32)(256 * png_sizeof(png_uint_16))); |
4284 g = 1.0 / png_ptr->screen_gamma; |
4102 g = 1.0 / png_ptr->screen_gamma; |
4285 |
4103 |
4286 else |
4104 else |
4287 g = png_ptr->gamma; /* Probably doing rgb_to_gray */ |
4105 g = png_ptr->gamma; /* Probably doing rgb_to_gray */ |
4288 |
4106 |
4289 png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr, |
4107 png_ptr->gamma_16_from_1 = (png_uint_16pp)png_calloc(png_ptr, |
4290 (png_uint_32)(num * png_sizeof(png_uint_16p))); |
4108 (png_uint_32)(num * png_sizeof(png_uint_16p))); |
4291 png_memset(png_ptr->gamma_16_from_1, 0, |
|
4292 num * png_sizeof(png_uint_16p)); |
|
4293 |
4109 |
4294 for (i = 0; i < num; i++) |
4110 for (i = 0; i < num; i++) |
4295 { |
4111 { |
4296 png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr, |
4112 png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr, |
4297 (png_uint_32)(256 * png_sizeof(png_uint_16))); |
4113 (png_uint_32)(256 * png_sizeof(png_uint_16))); |
4312 } |
4128 } |
4313 #endif |
4129 #endif |
4314 /* To do: install integer version of png_build_gamma_table here */ |
4130 /* To do: install integer version of png_build_gamma_table here */ |
4315 #endif |
4131 #endif |
4316 |
4132 |
4317 #if defined(PNG_MNG_FEATURES_SUPPORTED) |
4133 #ifdef PNG_MNG_FEATURES_SUPPORTED |
4318 /* Undoes intrapixel differencing */ |
4134 /* Undoes intrapixel differencing */ |
4319 void /* PRIVATE */ |
4135 void /* PRIVATE */ |
4320 png_do_read_intrapixel(png_row_infop row_info, png_bytep row) |
4136 png_do_read_intrapixel(png_row_infop row_info, png_bytep row) |
4321 { |
4137 { |
4322 png_debug(1, "in png_do_read_intrapixel"); |
4138 png_debug(1, "in png_do_read_intrapixel"); |
4139 |
|
4323 if ( |
4140 if ( |
4324 #if defined(PNG_USELESS_TESTS_SUPPORTED) |
|
4325 row != NULL && row_info != NULL && |
|
4326 #endif |
|
4327 (row_info->color_type & PNG_COLOR_MASK_COLOR)) |
4141 (row_info->color_type & PNG_COLOR_MASK_COLOR)) |
4328 { |
4142 { |
4329 int bytes_per_pixel; |
4143 int bytes_per_pixel; |
4330 png_uint_32 row_width = row_info->width; |
4144 png_uint_32 row_width = row_info->width; |
4331 if (row_info->bit_depth == 8) |
4145 if (row_info->bit_depth == 8) |