1 |
1 |
2 /* pngtrans.c - transforms the data in a row (used by both readers and writers) |
2 /* pngtrans.c - transforms the data in a row (used by both readers and writers) |
3 * |
3 * |
4 * Last changed in libpng 1.2.36 [May 14, 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 |
11 * and license in png.h |
11 * and license in png.h |
12 */ |
12 */ |
13 |
13 |
14 #define PNG_INTERNAL |
14 #define PNG_NO_PEDANTIC_WARNINGS |
15 #include "png.h" |
15 #include "png.h" |
16 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) |
16 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) |
|
17 #include "pngpriv.h" |
17 |
18 |
18 #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) |
19 #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) |
19 /* Turn on BGR-to-RGB mapping */ |
20 /* Turn on BGR-to-RGB mapping */ |
20 void PNGAPI |
21 void PNGAPI |
21 png_set_bgr(png_structp png_ptr) |
22 png_set_bgr(png_structp png_ptr) |
22 { |
23 { |
23 png_debug(1, "in png_set_bgr"); |
24 png_debug(1, "in png_set_bgr"); |
|
25 |
24 if (png_ptr == NULL) |
26 if (png_ptr == NULL) |
25 return; |
27 return; |
26 png_ptr->transformations |= PNG_BGR; |
28 png_ptr->transformations |= PNG_BGR; |
27 } |
29 } |
28 #endif |
30 #endif |
31 /* Turn on 16 bit byte swapping */ |
33 /* Turn on 16 bit byte swapping */ |
32 void PNGAPI |
34 void PNGAPI |
33 png_set_swap(png_structp png_ptr) |
35 png_set_swap(png_structp png_ptr) |
34 { |
36 { |
35 png_debug(1, "in png_set_swap"); |
37 png_debug(1, "in png_set_swap"); |
|
38 |
36 if (png_ptr == NULL) |
39 if (png_ptr == NULL) |
37 return; |
40 return; |
38 if (png_ptr->bit_depth == 16) |
41 if (png_ptr->bit_depth == 16) |
39 png_ptr->transformations |= PNG_SWAP_BYTES; |
42 png_ptr->transformations |= PNG_SWAP_BYTES; |
40 } |
43 } |
44 /* Turn on pixel packing */ |
47 /* Turn on pixel packing */ |
45 void PNGAPI |
48 void PNGAPI |
46 png_set_packing(png_structp png_ptr) |
49 png_set_packing(png_structp png_ptr) |
47 { |
50 { |
48 png_debug(1, "in png_set_packing"); |
51 png_debug(1, "in png_set_packing"); |
|
52 |
49 if (png_ptr == NULL) |
53 if (png_ptr == NULL) |
50 return; |
54 return; |
51 if (png_ptr->bit_depth < 8) |
55 if (png_ptr->bit_depth < 8) |
52 { |
56 { |
53 png_ptr->transformations |= PNG_PACK; |
57 png_ptr->transformations |= PNG_PACK; |
60 /* Turn on packed pixel swapping */ |
64 /* Turn on packed pixel swapping */ |
61 void PNGAPI |
65 void PNGAPI |
62 png_set_packswap(png_structp png_ptr) |
66 png_set_packswap(png_structp png_ptr) |
63 { |
67 { |
64 png_debug(1, "in png_set_packswap"); |
68 png_debug(1, "in png_set_packswap"); |
|
69 |
65 if (png_ptr == NULL) |
70 if (png_ptr == NULL) |
66 return; |
71 return; |
67 if (png_ptr->bit_depth < 8) |
72 if (png_ptr->bit_depth < 8) |
68 png_ptr->transformations |= PNG_PACKSWAP; |
73 png_ptr->transformations |= PNG_PACKSWAP; |
69 } |
74 } |
72 #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) |
77 #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) |
73 void PNGAPI |
78 void PNGAPI |
74 png_set_shift(png_structp png_ptr, png_color_8p true_bits) |
79 png_set_shift(png_structp png_ptr, png_color_8p true_bits) |
75 { |
80 { |
76 png_debug(1, "in png_set_shift"); |
81 png_debug(1, "in png_set_shift"); |
|
82 |
77 if (png_ptr == NULL) |
83 if (png_ptr == NULL) |
78 return; |
84 return; |
79 png_ptr->transformations |= PNG_SHIFT; |
85 png_ptr->transformations |= PNG_SHIFT; |
80 png_ptr->shift = *true_bits; |
86 png_ptr->shift = *true_bits; |
81 } |
87 } |
85 defined(PNG_WRITE_INTERLACING_SUPPORTED) |
91 defined(PNG_WRITE_INTERLACING_SUPPORTED) |
86 int PNGAPI |
92 int PNGAPI |
87 png_set_interlace_handling(png_structp png_ptr) |
93 png_set_interlace_handling(png_structp png_ptr) |
88 { |
94 { |
89 png_debug(1, "in png_set_interlace handling"); |
95 png_debug(1, "in png_set_interlace handling"); |
|
96 |
90 if (png_ptr && png_ptr->interlaced) |
97 if (png_ptr && png_ptr->interlaced) |
91 { |
98 { |
92 png_ptr->transformations |= PNG_INTERLACE; |
99 png_ptr->transformations |= PNG_INTERLACE; |
93 return (7); |
100 return (7); |
94 } |
101 } |
105 */ |
112 */ |
106 void PNGAPI |
113 void PNGAPI |
107 png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc) |
114 png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc) |
108 { |
115 { |
109 png_debug(1, "in png_set_filler"); |
116 png_debug(1, "in png_set_filler"); |
|
117 |
110 if (png_ptr == NULL) |
118 if (png_ptr == NULL) |
111 return; |
119 return; |
112 png_ptr->transformations |= PNG_FILLER; |
120 png_ptr->transformations |= PNG_FILLER; |
113 png_ptr->filler = (png_byte)filler; |
121 png_ptr->filler = (png_uint_16)filler; |
114 if (filler_loc == PNG_FILLER_AFTER) |
122 if (filler_loc == PNG_FILLER_AFTER) |
115 png_ptr->flags |= PNG_FLAG_FILLER_AFTER; |
123 png_ptr->flags |= PNG_FLAG_FILLER_AFTER; |
116 else |
124 else |
117 png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER; |
125 png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER; |
118 |
126 |
133 { |
141 { |
134 png_ptr->usr_channels = 2; |
142 png_ptr->usr_channels = 2; |
135 } |
143 } |
136 } |
144 } |
137 |
145 |
138 #if !defined(PNG_1_0_X) |
|
139 /* Added to libpng-1.2.7 */ |
146 /* Added to libpng-1.2.7 */ |
140 void PNGAPI |
147 void PNGAPI |
141 png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc) |
148 png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc) |
142 { |
149 { |
143 png_debug(1, "in png_set_add_alpha"); |
150 png_debug(1, "in png_set_add_alpha"); |
|
151 |
144 if (png_ptr == NULL) |
152 if (png_ptr == NULL) |
145 return; |
153 return; |
146 png_set_filler(png_ptr, filler, filler_loc); |
154 png_set_filler(png_ptr, filler, filler_loc); |
147 png_ptr->transformations |= PNG_ADD_ALPHA; |
155 png_ptr->transformations |= PNG_ADD_ALPHA; |
148 } |
156 } |
149 #endif |
|
150 |
157 |
151 #endif |
158 #endif |
152 |
159 |
153 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ |
160 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ |
154 defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) |
161 defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) |
155 void PNGAPI |
162 void PNGAPI |
156 png_set_swap_alpha(png_structp png_ptr) |
163 png_set_swap_alpha(png_structp png_ptr) |
157 { |
164 { |
158 png_debug(1, "in png_set_swap_alpha"); |
165 png_debug(1, "in png_set_swap_alpha"); |
|
166 |
159 if (png_ptr == NULL) |
167 if (png_ptr == NULL) |
160 return; |
168 return; |
161 png_ptr->transformations |= PNG_SWAP_ALPHA; |
169 png_ptr->transformations |= PNG_SWAP_ALPHA; |
162 } |
170 } |
163 #endif |
171 #endif |
177 #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) |
186 #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) |
178 void PNGAPI |
187 void PNGAPI |
179 png_set_invert_mono(png_structp png_ptr) |
188 png_set_invert_mono(png_structp png_ptr) |
180 { |
189 { |
181 png_debug(1, "in png_set_invert_mono"); |
190 png_debug(1, "in png_set_invert_mono"); |
|
191 |
182 if (png_ptr == NULL) |
192 if (png_ptr == NULL) |
183 return; |
193 return; |
184 png_ptr->transformations |= PNG_INVERT_MONO; |
194 png_ptr->transformations |= PNG_INVERT_MONO; |
185 } |
195 } |
186 |
196 |
187 /* Invert monochrome grayscale data */ |
197 /* Invert monochrome grayscale data */ |
188 void /* PRIVATE */ |
198 void /* PRIVATE */ |
189 png_do_invert(png_row_infop row_info, png_bytep row) |
199 png_do_invert(png_row_infop row_info, png_bytep row) |
190 { |
200 { |
191 png_debug(1, "in png_do_invert"); |
201 png_debug(1, "in png_do_invert"); |
|
202 |
192 /* This test removed from libpng version 1.0.13 and 1.2.0: |
203 /* This test removed from libpng version 1.0.13 and 1.2.0: |
193 * if (row_info->bit_depth == 1 && |
204 * if (row_info->bit_depth == 1 && |
194 */ |
205 */ |
195 #if defined(PNG_USELESS_TESTS_SUPPORTED) |
|
196 if (row == NULL || row_info == NULL) |
|
197 return; |
|
198 #endif |
|
199 if (row_info->color_type == PNG_COLOR_TYPE_GRAY) |
206 if (row_info->color_type == PNG_COLOR_TYPE_GRAY) |
200 { |
207 { |
201 png_bytep rp = row; |
208 png_bytep rp = row; |
202 png_uint_32 i; |
209 png_uint_32 i; |
203 png_uint_32 istop = row_info->rowbytes; |
210 png_uint_32 istop = row_info->rowbytes; |
242 /* Swaps byte order on 16 bit depth images */ |
249 /* Swaps byte order on 16 bit depth images */ |
243 void /* PRIVATE */ |
250 void /* PRIVATE */ |
244 png_do_swap(png_row_infop row_info, png_bytep row) |
251 png_do_swap(png_row_infop row_info, png_bytep row) |
245 { |
252 { |
246 png_debug(1, "in png_do_swap"); |
253 png_debug(1, "in png_do_swap"); |
|
254 |
247 if ( |
255 if ( |
248 #if defined(PNG_USELESS_TESTS_SUPPORTED) |
|
249 row != NULL && row_info != NULL && |
|
250 #endif |
|
251 row_info->bit_depth == 16) |
256 row_info->bit_depth == 16) |
252 { |
257 { |
253 png_bytep rp = row; |
258 png_bytep rp = row; |
254 png_uint_32 i; |
259 png_uint_32 i; |
255 png_uint_32 istop= row_info->width * row_info->channels; |
260 png_uint_32 istop= row_info->width * row_info->channels; |
373 /* Swaps pixel packing order within bytes */ |
378 /* Swaps pixel packing order within bytes */ |
374 void /* PRIVATE */ |
379 void /* PRIVATE */ |
375 png_do_packswap(png_row_infop row_info, png_bytep row) |
380 png_do_packswap(png_row_infop row_info, png_bytep row) |
376 { |
381 { |
377 png_debug(1, "in png_do_packswap"); |
382 png_debug(1, "in png_do_packswap"); |
|
383 |
378 if ( |
384 if ( |
379 #if defined(PNG_USELESS_TESTS_SUPPORTED) |
|
380 row != NULL && row_info != NULL && |
|
381 #endif |
|
382 row_info->bit_depth < 8) |
385 row_info->bit_depth < 8) |
383 { |
386 { |
384 png_bytep rp, end, table; |
387 png_bytep rp, end, table; |
385 |
388 |
386 end = row + row_info->rowbytes; |
389 end = row + row_info->rowbytes; |
405 /* Remove filler or alpha byte(s) */ |
408 /* Remove filler or alpha byte(s) */ |
406 void /* PRIVATE */ |
409 void /* PRIVATE */ |
407 png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags) |
410 png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags) |
408 { |
411 { |
409 png_debug(1, "in png_do_strip_filler"); |
412 png_debug(1, "in png_do_strip_filler"); |
410 #if defined(PNG_USELESS_TESTS_SUPPORTED) |
413 |
411 if (row != NULL && row_info != NULL) |
|
412 #endif |
|
413 { |
414 { |
414 png_bytep sp=row; |
415 png_bytep sp=row; |
415 png_bytep dp=row; |
416 png_bytep dp=row; |
416 png_uint_32 row_width=row_info->width; |
417 png_uint_32 row_width=row_info->width; |
417 png_uint_32 i; |
418 png_uint_32 i; |
563 /* Swaps red and blue bytes within a pixel */ |
564 /* Swaps red and blue bytes within a pixel */ |
564 void /* PRIVATE */ |
565 void /* PRIVATE */ |
565 png_do_bgr(png_row_infop row_info, png_bytep row) |
566 png_do_bgr(png_row_infop row_info, png_bytep row) |
566 { |
567 { |
567 png_debug(1, "in png_do_bgr"); |
568 png_debug(1, "in png_do_bgr"); |
|
569 |
568 if ( |
570 if ( |
569 #if defined(PNG_USELESS_TESTS_SUPPORTED) |
|
570 row != NULL && row_info != NULL && |
|
571 #endif |
|
572 (row_info->color_type & PNG_COLOR_MASK_COLOR)) |
571 (row_info->color_type & PNG_COLOR_MASK_COLOR)) |
573 { |
572 { |
574 png_uint_32 row_width = row_info->width; |
573 png_uint_32 row_width = row_info->width; |
575 if (row_info->bit_depth == 8) |
574 if (row_info->bit_depth == 8) |
576 { |
575 { |
635 } |
634 } |
636 } |
635 } |
637 #endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */ |
636 #endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */ |
638 |
637 |
639 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ |
638 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ |
640 defined(PNG_LEGACY_SUPPORTED) || \ |
|
641 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) |
639 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) |
642 void PNGAPI |
640 void PNGAPI |
643 png_set_user_transform_info(png_structp png_ptr, png_voidp |
641 png_set_user_transform_info(png_structp png_ptr, png_voidp |
644 user_transform_ptr, int user_transform_depth, int user_transform_channels) |
642 user_transform_ptr, int user_transform_depth, int user_transform_channels) |
645 { |
643 { |
646 png_debug(1, "in png_set_user_transform_info"); |
644 png_debug(1, "in png_set_user_transform_info"); |
647 if (png_ptr == NULL) |
645 |
648 return; |
646 if (png_ptr == NULL) |
649 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) |
647 return; |
|
648 #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED |
650 png_ptr->user_transform_ptr = user_transform_ptr; |
649 png_ptr->user_transform_ptr = user_transform_ptr; |
651 png_ptr->user_transform_depth = (png_byte)user_transform_depth; |
650 png_ptr->user_transform_depth = (png_byte)user_transform_depth; |
652 png_ptr->user_transform_channels = (png_byte)user_transform_channels; |
651 png_ptr->user_transform_channels = (png_byte)user_transform_channels; |
653 #else |
652 #else |
654 if (user_transform_ptr || user_transform_depth || user_transform_channels) |
653 if (user_transform_ptr || user_transform_depth || user_transform_channels) |