OLD | NEW |
1 | 1 |
2 /* pngwtran.c - transforms the data in a row for PNG writers | 2 /* pngwtran.c - transforms the data in a row for PNG writers |
3 * | 3 * |
4 * Last changed in libpng 1.2.43 [February 25, 2010] | 4 * Last changed in libpng 1.6.18 [July 23, 2015] |
5 * Copyright (c) 1998-2002,2004,2006-2010 Glenn Randers-Pehrson | 5 * Copyright (c) 1998-2002,2004,2006-2015 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 #include "pngpriv.h" |
15 #define PNG_NO_PEDANTIC_WARNINGS | 15 |
16 #include "png.h" | |
17 #ifdef PNG_WRITE_SUPPORTED | 16 #ifdef PNG_WRITE_SUPPORTED |
18 | 17 #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED |
19 /* Transform the data according to the user's wishes. The order of | |
20 * transformations is significant. | |
21 */ | |
22 void /* PRIVATE */ | |
23 png_do_write_transformations(png_structp png_ptr) | |
24 { | |
25 png_debug(1, "in png_do_write_transformations"); | |
26 | |
27 if (png_ptr == NULL) | |
28 return; | |
29 | |
30 #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED | |
31 if (png_ptr->transformations & PNG_USER_TRANSFORM) | |
32 if (png_ptr->write_user_transform_fn != NULL) | |
33 (*(png_ptr->write_user_transform_fn)) /* User write transform | |
34 function */ | |
35 (png_ptr, /* png_ptr */ | |
36 &(png_ptr->row_info), /* row_info: */ | |
37 /* png_uint_32 width; width of row */ | |
38 /* png_uint_32 rowbytes; number of bytes in row */ | |
39 /* png_byte color_type; color type of pixels */ | |
40 /* png_byte bit_depth; bit depth of samples */ | |
41 /* png_byte channels; number of channels (1-4) */ | |
42 /* png_byte pixel_depth; bits per pixel (depth*channels) */ | |
43 png_ptr->row_buf + 1); /* start of pixel data for row */ | |
44 #endif | |
45 #ifdef PNG_WRITE_FILLER_SUPPORTED | |
46 if (png_ptr->transformations & PNG_FILLER) | |
47 png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, | |
48 png_ptr->flags); | |
49 #endif | |
50 #ifdef PNG_WRITE_PACKSWAP_SUPPORTED | |
51 if (png_ptr->transformations & PNG_PACKSWAP) | |
52 png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); | |
53 #endif | |
54 #ifdef PNG_WRITE_PACK_SUPPORTED | |
55 if (png_ptr->transformations & PNG_PACK) | |
56 png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1, | |
57 (png_uint_32)png_ptr->bit_depth); | |
58 #endif | |
59 #ifdef PNG_WRITE_SWAP_SUPPORTED | |
60 if (png_ptr->transformations & PNG_SWAP_BYTES) | |
61 png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); | |
62 #endif | |
63 #ifdef PNG_WRITE_SHIFT_SUPPORTED | |
64 if (png_ptr->transformations & PNG_SHIFT) | |
65 png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1, | |
66 &(png_ptr->shift)); | |
67 #endif | |
68 #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED | |
69 if (png_ptr->transformations & PNG_SWAP_ALPHA) | |
70 png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); | |
71 #endif | |
72 #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED | |
73 if (png_ptr->transformations & PNG_INVERT_ALPHA) | |
74 png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); | |
75 #endif | |
76 #ifdef PNG_WRITE_BGR_SUPPORTED | |
77 if (png_ptr->transformations & PNG_BGR) | |
78 png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); | |
79 #endif | |
80 #ifdef PNG_WRITE_INVERT_SUPPORTED | |
81 if (png_ptr->transformations & PNG_INVERT_MONO) | |
82 png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); | |
83 #endif | |
84 } | |
85 | 18 |
86 #ifdef PNG_WRITE_PACK_SUPPORTED | 19 #ifdef PNG_WRITE_PACK_SUPPORTED |
87 /* Pack pixels into bytes. Pass the true bit depth in bit_depth. The | 20 /* Pack pixels into bytes. Pass the true bit depth in bit_depth. The |
88 * row_info bit depth should be 8 (one pixel per byte). The channels | 21 * row_info bit depth should be 8 (one pixel per byte). The channels |
89 * should be 1 (this only happens on grayscale and paletted images). | 22 * should be 1 (this only happens on grayscale and paletted images). |
90 */ | 23 */ |
91 void /* PRIVATE */ | 24 static void |
92 png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) | 25 png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) |
93 { | 26 { |
94 png_debug(1, "in png_do_pack"); | 27 png_debug(1, "in png_do_pack"); |
95 | 28 |
96 if (row_info->bit_depth == 8 && | 29 if (row_info->bit_depth == 8 && |
97 #ifdef PNG_USELESS_TESTS_SUPPORTED | |
98 row != NULL && row_info != NULL && | |
99 #endif | |
100 row_info->channels == 1) | 30 row_info->channels == 1) |
101 { | 31 { |
102 switch ((int)bit_depth) | 32 switch ((int)bit_depth) |
103 { | 33 { |
104 case 1: | 34 case 1: |
105 { | 35 { |
106 png_bytep sp, dp; | 36 png_bytep sp, dp; |
107 int mask, v; | 37 int mask, v; |
108 png_uint_32 i; | 38 png_uint_32 i; |
109 png_uint_32 row_width = row_info->width; | 39 png_uint_32 row_width = row_info->width; |
110 | 40 |
111 sp = row; | 41 sp = row; |
112 dp = row; | 42 dp = row; |
113 mask = 0x80; | 43 mask = 0x80; |
114 v = 0; | 44 v = 0; |
115 | 45 |
116 for (i = 0; i < row_width; i++) | 46 for (i = 0; i < row_width; i++) |
117 { | 47 { |
118 if (*sp != 0) | 48 if (*sp != 0) |
119 v |= mask; | 49 v |= mask; |
| 50 |
120 sp++; | 51 sp++; |
| 52 |
121 if (mask > 1) | 53 if (mask > 1) |
122 mask >>= 1; | 54 mask >>= 1; |
| 55 |
123 else | 56 else |
124 { | 57 { |
125 mask = 0x80; | 58 mask = 0x80; |
126 *dp = (png_byte)v; | 59 *dp = (png_byte)v; |
127 dp++; | 60 dp++; |
128 v = 0; | 61 v = 0; |
129 } | 62 } |
130 } | 63 } |
| 64 |
131 if (mask != 0x80) | 65 if (mask != 0x80) |
132 *dp = (png_byte)v; | 66 *dp = (png_byte)v; |
| 67 |
133 break; | 68 break; |
134 } | 69 } |
| 70 |
135 case 2: | 71 case 2: |
136 { | 72 { |
137 png_bytep sp, dp; | 73 png_bytep sp, dp; |
138 int shift, v; | 74 unsigned int shift; |
| 75 int v; |
139 png_uint_32 i; | 76 png_uint_32 i; |
140 png_uint_32 row_width = row_info->width; | 77 png_uint_32 row_width = row_info->width; |
141 | 78 |
142 sp = row; | 79 sp = row; |
143 dp = row; | 80 dp = row; |
144 shift = 6; | 81 shift = 6; |
145 v = 0; | 82 v = 0; |
| 83 |
146 for (i = 0; i < row_width; i++) | 84 for (i = 0; i < row_width; i++) |
147 { | 85 { |
148 png_byte value; | 86 png_byte value; |
149 | 87 |
150 value = (png_byte)(*sp & 0x03); | 88 value = (png_byte)(*sp & 0x03); |
151 v |= (value << shift); | 89 v |= (value << shift); |
| 90 |
152 if (shift == 0) | 91 if (shift == 0) |
153 { | 92 { |
154 shift = 6; | 93 shift = 6; |
155 *dp = (png_byte)v; | 94 *dp = (png_byte)v; |
156 dp++; | 95 dp++; |
157 v = 0; | 96 v = 0; |
158 } | 97 } |
| 98 |
159 else | 99 else |
160 shift -= 2; | 100 shift -= 2; |
| 101 |
161 sp++; | 102 sp++; |
162 } | 103 } |
| 104 |
163 if (shift != 6) | 105 if (shift != 6) |
164 *dp = (png_byte)v; | 106 *dp = (png_byte)v; |
| 107 |
165 break; | 108 break; |
166 } | 109 } |
| 110 |
167 case 4: | 111 case 4: |
168 { | 112 { |
169 png_bytep sp, dp; | 113 png_bytep sp, dp; |
170 int shift, v; | 114 unsigned int shift; |
| 115 int v; |
171 png_uint_32 i; | 116 png_uint_32 i; |
172 png_uint_32 row_width = row_info->width; | 117 png_uint_32 row_width = row_info->width; |
173 | 118 |
174 sp = row; | 119 sp = row; |
175 dp = row; | 120 dp = row; |
176 shift = 4; | 121 shift = 4; |
177 v = 0; | 122 v = 0; |
| 123 |
178 for (i = 0; i < row_width; i++) | 124 for (i = 0; i < row_width; i++) |
179 { | 125 { |
180 png_byte value; | 126 png_byte value; |
181 | 127 |
182 value = (png_byte)(*sp & 0x0f); | 128 value = (png_byte)(*sp & 0x0f); |
183 v |= (value << shift); | 129 v |= (value << shift); |
184 | 130 |
185 if (shift == 0) | 131 if (shift == 0) |
186 { | 132 { |
187 shift = 4; | 133 shift = 4; |
188 *dp = (png_byte)v; | 134 *dp = (png_byte)v; |
189 dp++; | 135 dp++; |
190 v = 0; | 136 v = 0; |
191 } | 137 } |
| 138 |
192 else | 139 else |
193 shift -= 4; | 140 shift -= 4; |
194 | 141 |
195 sp++; | 142 sp++; |
196 } | 143 } |
| 144 |
197 if (shift != 4) | 145 if (shift != 4) |
198 *dp = (png_byte)v; | 146 *dp = (png_byte)v; |
| 147 |
199 break; | 148 break; |
200 } | 149 } |
| 150 |
| 151 default: |
| 152 break; |
201 } | 153 } |
| 154 |
202 row_info->bit_depth = (png_byte)bit_depth; | 155 row_info->bit_depth = (png_byte)bit_depth; |
203 row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels); | 156 row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels); |
204 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, | 157 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, |
205 row_info->width); | 158 row_info->width); |
206 } | 159 } |
207 } | 160 } |
208 #endif | 161 #endif |
209 | 162 |
210 #ifdef PNG_WRITE_SHIFT_SUPPORTED | 163 #ifdef PNG_WRITE_SHIFT_SUPPORTED |
211 /* Shift pixel values to take advantage of whole range. Pass the | 164 /* Shift pixel values to take advantage of whole range. Pass the |
212 * true number of bits in bit_depth. The row should be packed | 165 * true number of bits in bit_depth. The row should be packed |
213 * according to row_info->bit_depth. Thus, if you had a row of | 166 * according to row_info->bit_depth. Thus, if you had a row of |
214 * bit depth 4, but the pixels only had values from 0 to 7, you | 167 * bit depth 4, but the pixels only had values from 0 to 7, you |
215 * would pass 3 as bit_depth, and this routine would translate the | 168 * would pass 3 as bit_depth, and this routine would translate the |
216 * data to 0 to 15. | 169 * data to 0 to 15. |
217 */ | 170 */ |
218 void /* PRIVATE */ | 171 static void |
219 png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth) | 172 png_do_shift(png_row_infop row_info, png_bytep row, |
| 173 png_const_color_8p bit_depth) |
220 { | 174 { |
221 png_debug(1, "in png_do_shift"); | 175 png_debug(1, "in png_do_shift"); |
222 | 176 |
223 #ifdef PNG_USELESS_TESTS_SUPPORTED | 177 if (row_info->color_type != PNG_COLOR_TYPE_PALETTE) |
224 if (row != NULL && row_info != NULL && | |
225 #else | |
226 if ( | |
227 #endif | |
228 row_info->color_type != PNG_COLOR_TYPE_PALETTE) | |
229 { | 178 { |
230 int shift_start[4], shift_dec[4]; | 179 int shift_start[4], shift_dec[4]; |
231 int channels = 0; | 180 int channels = 0; |
232 | 181 |
233 if (row_info->color_type & PNG_COLOR_MASK_COLOR) | 182 if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) |
234 { | 183 { |
235 shift_start[channels] = row_info->bit_depth - bit_depth->red; | 184 shift_start[channels] = row_info->bit_depth - bit_depth->red; |
236 shift_dec[channels] = bit_depth->red; | 185 shift_dec[channels] = bit_depth->red; |
237 channels++; | 186 channels++; |
| 187 |
238 shift_start[channels] = row_info->bit_depth - bit_depth->green; | 188 shift_start[channels] = row_info->bit_depth - bit_depth->green; |
239 shift_dec[channels] = bit_depth->green; | 189 shift_dec[channels] = bit_depth->green; |
240 channels++; | 190 channels++; |
| 191 |
241 shift_start[channels] = row_info->bit_depth - bit_depth->blue; | 192 shift_start[channels] = row_info->bit_depth - bit_depth->blue; |
242 shift_dec[channels] = bit_depth->blue; | 193 shift_dec[channels] = bit_depth->blue; |
243 channels++; | 194 channels++; |
244 } | 195 } |
| 196 |
245 else | 197 else |
246 { | 198 { |
247 shift_start[channels] = row_info->bit_depth - bit_depth->gray; | 199 shift_start[channels] = row_info->bit_depth - bit_depth->gray; |
248 shift_dec[channels] = bit_depth->gray; | 200 shift_dec[channels] = bit_depth->gray; |
249 channels++; | 201 channels++; |
250 } | 202 } |
251 if (row_info->color_type & PNG_COLOR_MASK_ALPHA) | 203 |
| 204 if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) |
252 { | 205 { |
253 shift_start[channels] = row_info->bit_depth - bit_depth->alpha; | 206 shift_start[channels] = row_info->bit_depth - bit_depth->alpha; |
254 shift_dec[channels] = bit_depth->alpha; | 207 shift_dec[channels] = bit_depth->alpha; |
255 channels++; | 208 channels++; |
256 } | 209 } |
257 | 210 |
258 /* With low row depths, could only be grayscale, so one channel */ | 211 /* With low row depths, could only be grayscale, so one channel */ |
259 if (row_info->bit_depth < 8) | 212 if (row_info->bit_depth < 8) |
260 { | 213 { |
261 png_bytep bp = row; | 214 png_bytep bp = row; |
262 png_uint_32 i; | 215 png_size_t i; |
263 png_byte mask; | 216 unsigned int mask; |
264 png_uint_32 row_bytes = row_info->rowbytes; | 217 png_size_t row_bytes = row_info->rowbytes; |
265 | 218 |
266 if (bit_depth->gray == 1 && row_info->bit_depth == 2) | 219 if (bit_depth->gray == 1 && row_info->bit_depth == 2) |
267 mask = 0x55; | 220 mask = 0x55; |
| 221 |
268 else if (row_info->bit_depth == 4 && bit_depth->gray == 3) | 222 else if (row_info->bit_depth == 4 && bit_depth->gray == 3) |
269 mask = 0x11; | 223 mask = 0x11; |
| 224 |
270 else | 225 else |
271 mask = 0xff; | 226 mask = 0xff; |
272 | 227 |
273 for (i = 0; i < row_bytes; i++, bp++) | 228 for (i = 0; i < row_bytes; i++, bp++) |
274 { | 229 { |
275 png_uint_16 v; | |
276 int j; | 230 int j; |
| 231 unsigned int v, out; |
277 | 232 |
278 v = *bp; | 233 v = *bp; |
279 *bp = 0; | 234 out = 0; |
| 235 |
280 for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0]) | 236 for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0]) |
281 { | 237 { |
282 if (j > 0) | 238 if (j > 0) |
283 *bp |= (png_byte)((v << j) & 0xff); | 239 out |= v << j; |
| 240 |
284 else | 241 else |
285 *bp |= (png_byte)((v >> (-j)) & mask); | 242 out |= (v >> (-j)) & mask; |
286 } | 243 } |
| 244 |
| 245 *bp = (png_byte)(out & 0xff); |
287 } | 246 } |
288 } | 247 } |
| 248 |
289 else if (row_info->bit_depth == 8) | 249 else if (row_info->bit_depth == 8) |
290 { | 250 { |
291 png_bytep bp = row; | 251 png_bytep bp = row; |
292 png_uint_32 i; | 252 png_uint_32 i; |
293 png_uint_32 istop = channels * row_info->width; | 253 png_uint_32 istop = channels * row_info->width; |
294 | 254 |
295 for (i = 0; i < istop; i++, bp++) | 255 for (i = 0; i < istop; i++, bp++) |
296 { | 256 { |
297 | 257 |
298 png_uint_16 v; | 258 const unsigned int c = i%channels; |
299 int j; | 259 int j; |
300 int c = (int)(i%channels); | 260 unsigned int v, out; |
301 | 261 |
302 v = *bp; | 262 v = *bp; |
303 *bp = 0; | 263 out = 0; |
| 264 |
304 for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) | 265 for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) |
305 { | 266 { |
306 if (j > 0) | 267 if (j > 0) |
307 *bp |= (png_byte)((v << j) & 0xff); | 268 out |= v << j; |
| 269 |
308 else | 270 else |
309 *bp |= (png_byte)((v >> (-j)) & 0xff); | 271 out |= v >> (-j); |
310 } | 272 } |
| 273 |
| 274 *bp = (png_byte)(out & 0xff); |
311 } | 275 } |
312 } | 276 } |
| 277 |
313 else | 278 else |
314 { | 279 { |
315 png_bytep bp; | 280 png_bytep bp; |
316 png_uint_32 i; | 281 png_uint_32 i; |
317 png_uint_32 istop = channels * row_info->width; | 282 png_uint_32 istop = channels * row_info->width; |
318 | 283 |
319 for (bp = row, i = 0; i < istop; i++) | 284 for (bp = row, i = 0; i < istop; i++) |
320 { | 285 { |
321 int c = (int)(i%channels); | 286 const unsigned int c = i%channels; |
322 png_uint_16 value, v; | |
323 int j; | 287 int j; |
| 288 unsigned int value, v; |
324 | 289 |
325 v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1)); | 290 v = png_get_uint_16(bp); |
326 value = 0; | 291 value = 0; |
| 292 |
327 for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) | 293 for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) |
328 { | 294 { |
329 if (j > 0) | 295 if (j > 0) |
330 value |= (png_uint_16)((v << j) & (png_uint_16)0xffff); | 296 value |= v << j; |
| 297 |
331 else | 298 else |
332 value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff); | 299 value |= v >> (-j); |
333 } | 300 } |
334 *bp++ = (png_byte)(value >> 8); | 301 *bp++ = (png_byte)((value >> 8) & 0xff); |
335 *bp++ = (png_byte)(value & 0xff); | 302 *bp++ = (png_byte)(value & 0xff); |
336 } | 303 } |
337 } | 304 } |
338 } | 305 } |
339 } | 306 } |
340 #endif | 307 #endif |
341 | 308 |
342 #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED | 309 #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED |
343 void /* PRIVATE */ | 310 static void |
344 png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) | 311 png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) |
345 { | 312 { |
346 png_debug(1, "in png_do_write_swap_alpha"); | 313 png_debug(1, "in png_do_write_swap_alpha"); |
347 | 314 |
348 #ifdef PNG_USELESS_TESTS_SUPPORTED | |
349 if (row != NULL && row_info != NULL) | |
350 #endif | |
351 { | 315 { |
352 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) | 316 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) |
353 { | 317 { |
354 /* This converts from ARGB to RGBA */ | |
355 if (row_info->bit_depth == 8) | 318 if (row_info->bit_depth == 8) |
356 { | 319 { |
| 320 /* This converts from ARGB to RGBA */ |
357 png_bytep sp, dp; | 321 png_bytep sp, dp; |
358 png_uint_32 i; | 322 png_uint_32 i; |
359 png_uint_32 row_width = row_info->width; | 323 png_uint_32 row_width = row_info->width; |
| 324 |
360 for (i = 0, sp = dp = row; i < row_width; i++) | 325 for (i = 0, sp = dp = row; i < row_width; i++) |
361 { | 326 { |
362 png_byte save = *(sp++); | 327 png_byte save = *(sp++); |
363 *(dp++) = *(sp++); | 328 *(dp++) = *(sp++); |
364 *(dp++) = *(sp++); | 329 *(dp++) = *(sp++); |
365 *(dp++) = *(sp++); | 330 *(dp++) = *(sp++); |
366 *(dp++) = save; | 331 *(dp++) = save; |
367 } | 332 } |
368 } | 333 } |
369 /* This converts from AARRGGBB to RRGGBBAA */ | 334 |
| 335 #ifdef PNG_WRITE_16BIT_SUPPORTED |
370 else | 336 else |
371 { | 337 { |
| 338 /* This converts from AARRGGBB to RRGGBBAA */ |
372 png_bytep sp, dp; | 339 png_bytep sp, dp; |
373 png_uint_32 i; | 340 png_uint_32 i; |
374 png_uint_32 row_width = row_info->width; | 341 png_uint_32 row_width = row_info->width; |
375 | 342 |
376 for (i = 0, sp = dp = row; i < row_width; i++) | 343 for (i = 0, sp = dp = row; i < row_width; i++) |
377 { | 344 { |
378 png_byte save[2]; | 345 png_byte save[2]; |
379 save[0] = *(sp++); | 346 save[0] = *(sp++); |
380 save[1] = *(sp++); | 347 save[1] = *(sp++); |
381 *(dp++) = *(sp++); | 348 *(dp++) = *(sp++); |
382 *(dp++) = *(sp++); | 349 *(dp++) = *(sp++); |
383 *(dp++) = *(sp++); | 350 *(dp++) = *(sp++); |
384 *(dp++) = *(sp++); | 351 *(dp++) = *(sp++); |
385 *(dp++) = *(sp++); | 352 *(dp++) = *(sp++); |
386 *(dp++) = *(sp++); | 353 *(dp++) = *(sp++); |
387 *(dp++) = save[0]; | 354 *(dp++) = save[0]; |
388 *(dp++) = save[1]; | 355 *(dp++) = save[1]; |
389 } | 356 } |
390 } | 357 } |
| 358 #endif /* WRITE_16BIT */ |
391 } | 359 } |
| 360 |
392 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) | 361 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) |
393 { | 362 { |
394 /* This converts from AG to GA */ | |
395 if (row_info->bit_depth == 8) | 363 if (row_info->bit_depth == 8) |
396 { | 364 { |
| 365 /* This converts from AG to GA */ |
397 png_bytep sp, dp; | 366 png_bytep sp, dp; |
398 png_uint_32 i; | 367 png_uint_32 i; |
399 png_uint_32 row_width = row_info->width; | 368 png_uint_32 row_width = row_info->width; |
400 | 369 |
401 for (i = 0, sp = dp = row; i < row_width; i++) | 370 for (i = 0, sp = dp = row; i < row_width; i++) |
402 { | 371 { |
403 png_byte save = *(sp++); | 372 png_byte save = *(sp++); |
404 *(dp++) = *(sp++); | 373 *(dp++) = *(sp++); |
405 *(dp++) = save; | 374 *(dp++) = save; |
406 } | 375 } |
407 } | 376 } |
408 /* This converts from AAGG to GGAA */ | 377 |
| 378 #ifdef PNG_WRITE_16BIT_SUPPORTED |
409 else | 379 else |
410 { | 380 { |
| 381 /* This converts from AAGG to GGAA */ |
411 png_bytep sp, dp; | 382 png_bytep sp, dp; |
412 png_uint_32 i; | 383 png_uint_32 i; |
413 png_uint_32 row_width = row_info->width; | 384 png_uint_32 row_width = row_info->width; |
414 | 385 |
415 for (i = 0, sp = dp = row; i < row_width; i++) | 386 for (i = 0, sp = dp = row; i < row_width; i++) |
416 { | 387 { |
417 png_byte save[2]; | 388 png_byte save[2]; |
418 save[0] = *(sp++); | 389 save[0] = *(sp++); |
419 save[1] = *(sp++); | 390 save[1] = *(sp++); |
420 *(dp++) = *(sp++); | 391 *(dp++) = *(sp++); |
421 *(dp++) = *(sp++); | 392 *(dp++) = *(sp++); |
422 *(dp++) = save[0]; | 393 *(dp++) = save[0]; |
423 *(dp++) = save[1]; | 394 *(dp++) = save[1]; |
424 } | 395 } |
425 } | 396 } |
| 397 #endif /* WRITE_16BIT */ |
426 } | 398 } |
427 } | 399 } |
428 } | 400 } |
429 #endif | 401 #endif |
430 | 402 |
431 #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED | 403 #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED |
432 void /* PRIVATE */ | 404 static void |
433 png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) | 405 png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) |
434 { | 406 { |
435 png_debug(1, "in png_do_write_invert_alpha"); | 407 png_debug(1, "in png_do_write_invert_alpha"); |
436 | 408 |
437 #ifdef PNG_USELESS_TESTS_SUPPORTED | |
438 if (row != NULL && row_info != NULL) | |
439 #endif | |
440 { | 409 { |
441 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) | 410 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) |
442 { | 411 { |
443 /* This inverts the alpha channel in RGBA */ | |
444 if (row_info->bit_depth == 8) | 412 if (row_info->bit_depth == 8) |
445 { | 413 { |
| 414 /* This inverts the alpha channel in RGBA */ |
446 png_bytep sp, dp; | 415 png_bytep sp, dp; |
447 png_uint_32 i; | 416 png_uint_32 i; |
448 png_uint_32 row_width = row_info->width; | 417 png_uint_32 row_width = row_info->width; |
| 418 |
449 for (i = 0, sp = dp = row; i < row_width; i++) | 419 for (i = 0, sp = dp = row; i < row_width; i++) |
450 { | 420 { |
451 /* Does nothing | 421 /* Does nothing |
452 *(dp++) = *(sp++); | 422 *(dp++) = *(sp++); |
453 *(dp++) = *(sp++); | 423 *(dp++) = *(sp++); |
454 *(dp++) = *(sp++); | 424 *(dp++) = *(sp++); |
455 */ | 425 */ |
456 sp+=3; dp = sp; | 426 sp+=3; dp = sp; |
457 *(dp++) = (png_byte)(255 - *(sp++)); | 427 *dp = (png_byte)(255 - *(sp++)); |
458 } | 428 } |
459 } | 429 } |
460 /* This inverts the alpha channel in RRGGBBAA */ | 430 |
| 431 #ifdef PNG_WRITE_16BIT_SUPPORTED |
461 else | 432 else |
462 { | 433 { |
| 434 /* This inverts the alpha channel in RRGGBBAA */ |
463 png_bytep sp, dp; | 435 png_bytep sp, dp; |
464 png_uint_32 i; | 436 png_uint_32 i; |
465 png_uint_32 row_width = row_info->width; | 437 png_uint_32 row_width = row_info->width; |
466 | 438 |
467 for (i = 0, sp = dp = row; i < row_width; i++) | 439 for (i = 0, sp = dp = row; i < row_width; i++) |
468 { | 440 { |
469 /* Does nothing | 441 /* Does nothing |
470 *(dp++) = *(sp++); | 442 *(dp++) = *(sp++); |
471 *(dp++) = *(sp++); | 443 *(dp++) = *(sp++); |
472 *(dp++) = *(sp++); | 444 *(dp++) = *(sp++); |
473 *(dp++) = *(sp++); | 445 *(dp++) = *(sp++); |
474 *(dp++) = *(sp++); | 446 *(dp++) = *(sp++); |
475 *(dp++) = *(sp++); | 447 *(dp++) = *(sp++); |
476 */ | 448 */ |
477 sp+=6; dp = sp; | 449 sp+=6; dp = sp; |
478 *(dp++) = (png_byte)(255 - *(sp++)); | 450 *(dp++) = (png_byte)(255 - *(sp++)); |
479 *(dp++) = (png_byte)(255 - *(sp++)); | 451 *dp = (png_byte)(255 - *(sp++)); |
480 } | 452 } |
481 } | 453 } |
| 454 #endif /* WRITE_16BIT */ |
482 } | 455 } |
| 456 |
483 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) | 457 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) |
484 { | 458 { |
485 /* This inverts the alpha channel in GA */ | |
486 if (row_info->bit_depth == 8) | 459 if (row_info->bit_depth == 8) |
487 { | 460 { |
| 461 /* This inverts the alpha channel in GA */ |
488 png_bytep sp, dp; | 462 png_bytep sp, dp; |
489 png_uint_32 i; | 463 png_uint_32 i; |
490 png_uint_32 row_width = row_info->width; | 464 png_uint_32 row_width = row_info->width; |
491 | 465 |
492 for (i = 0, sp = dp = row; i < row_width; i++) | 466 for (i = 0, sp = dp = row; i < row_width; i++) |
493 { | 467 { |
494 *(dp++) = *(sp++); | 468 *(dp++) = *(sp++); |
495 *(dp++) = (png_byte)(255 - *(sp++)); | 469 *(dp++) = (png_byte)(255 - *(sp++)); |
496 } | 470 } |
497 } | 471 } |
498 /* This inverts the alpha channel in GGAA */ | 472 |
| 473 #ifdef PNG_WRITE_16BIT_SUPPORTED |
499 else | 474 else |
500 { | 475 { |
| 476 /* This inverts the alpha channel in GGAA */ |
501 png_bytep sp, dp; | 477 png_bytep sp, dp; |
502 png_uint_32 i; | 478 png_uint_32 i; |
503 png_uint_32 row_width = row_info->width; | 479 png_uint_32 row_width = row_info->width; |
504 | 480 |
505 for (i = 0, sp = dp = row; i < row_width; i++) | 481 for (i = 0, sp = dp = row; i < row_width; i++) |
506 { | 482 { |
507 /* Does nothing | 483 /* Does nothing |
508 *(dp++) = *(sp++); | 484 *(dp++) = *(sp++); |
509 *(dp++) = *(sp++); | 485 *(dp++) = *(sp++); |
510 */ | 486 */ |
511 sp+=2; dp = sp; | 487 sp+=2; dp = sp; |
512 *(dp++) = (png_byte)(255 - *(sp++)); | 488 *(dp++) = (png_byte)(255 - *(sp++)); |
513 *(dp++) = (png_byte)(255 - *(sp++)); | 489 *dp = (png_byte)(255 - *(sp++)); |
514 } | 490 } |
515 } | 491 } |
| 492 #endif /* WRITE_16BIT */ |
516 } | 493 } |
517 } | 494 } |
518 } | 495 } |
519 #endif | 496 #endif |
520 | 497 |
521 #ifdef PNG_MNG_FEATURES_SUPPORTED | 498 /* Transform the data according to the user's wishes. The order of |
522 /* Undoes intrapixel differencing */ | 499 * transformations is significant. |
| 500 */ |
523 void /* PRIVATE */ | 501 void /* PRIVATE */ |
524 png_do_write_intrapixel(png_row_infop row_info, png_bytep row) | 502 png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info) |
525 { | 503 { |
526 png_debug(1, "in png_do_write_intrapixel"); | 504 png_debug(1, "in png_do_write_transformations"); |
527 | 505 |
528 if ( | 506 if (png_ptr == NULL) |
529 #ifdef PNG_USELESS_TESTS_SUPPORTED | 507 return; |
530 row != NULL && row_info != NULL && | 508 |
| 509 #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED |
| 510 if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) |
| 511 if (png_ptr->write_user_transform_fn != NULL) |
| 512 (*(png_ptr->write_user_transform_fn)) /* User write transform |
| 513 function */ |
| 514 (png_ptr, /* png_ptr */ |
| 515 row_info, /* row_info: */ |
| 516 /* png_uint_32 width; width of row */ |
| 517 /* png_size_t rowbytes; number of bytes in row */ |
| 518 /* png_byte color_type; color type of pixels */ |
| 519 /* png_byte bit_depth; bit depth of samples */ |
| 520 /* png_byte channels; number of channels (1-4) */ |
| 521 /* png_byte pixel_depth; bits per pixel (depth*channels) */ |
| 522 png_ptr->row_buf + 1); /* start of pixel data for row */ |
531 #endif | 523 #endif |
532 (row_info->color_type & PNG_COLOR_MASK_COLOR)) | |
533 { | |
534 int bytes_per_pixel; | |
535 png_uint_32 row_width = row_info->width; | |
536 if (row_info->bit_depth == 8) | |
537 { | |
538 png_bytep rp; | |
539 png_uint_32 i; | |
540 | 524 |
541 if (row_info->color_type == PNG_COLOR_TYPE_RGB) | 525 #ifdef PNG_WRITE_FILLER_SUPPORTED |
542 bytes_per_pixel = 3; | 526 if ((png_ptr->transformations & PNG_FILLER) != 0) |
543 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) | 527 png_do_strip_channel(row_info, png_ptr->row_buf + 1, |
544 bytes_per_pixel = 4; | 528 !(png_ptr->flags & PNG_FLAG_FILLER_AFTER)); |
545 else | 529 #endif |
546 return; | |
547 | 530 |
548 for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) | 531 #ifdef PNG_WRITE_PACKSWAP_SUPPORTED |
549 { | 532 if ((png_ptr->transformations & PNG_PACKSWAP) != 0) |
550 *(rp) = (png_byte)((*rp - *(rp+1))&0xff); | 533 png_do_packswap(row_info, png_ptr->row_buf + 1); |
551 *(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff); | 534 #endif |
552 } | |
553 } | |
554 else if (row_info->bit_depth == 16) | |
555 { | |
556 png_bytep rp; | |
557 png_uint_32 i; | |
558 | 535 |
559 if (row_info->color_type == PNG_COLOR_TYPE_RGB) | 536 #ifdef PNG_WRITE_PACK_SUPPORTED |
560 bytes_per_pixel = 6; | 537 if ((png_ptr->transformations & PNG_PACK) != 0) |
561 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) | 538 png_do_pack(row_info, png_ptr->row_buf + 1, |
562 bytes_per_pixel = 8; | 539 (png_uint_32)png_ptr->bit_depth); |
563 else | 540 #endif |
564 return; | |
565 | 541 |
566 for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) | 542 #ifdef PNG_WRITE_SWAP_SUPPORTED |
567 { | 543 # ifdef PNG_16BIT_SUPPORTED |
568 png_uint_32 s0 = (*(rp ) << 8) | *(rp+1); | 544 if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) |
569 png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3); | 545 png_do_swap(row_info, png_ptr->row_buf + 1); |
570 png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5); | 546 # endif |
571 png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL); | 547 #endif |
572 png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL); | 548 |
573 *(rp ) = (png_byte)((red >> 8) & 0xff); | 549 #ifdef PNG_WRITE_SHIFT_SUPPORTED |
574 *(rp+1) = (png_byte)(red & 0xff); | 550 if ((png_ptr->transformations & PNG_SHIFT) != 0) |
575 *(rp+4) = (png_byte)((blue >> 8) & 0xff); | 551 png_do_shift(row_info, png_ptr->row_buf + 1, |
576 *(rp+5) = (png_byte)(blue & 0xff); | 552 &(png_ptr->shift)); |
577 } | 553 #endif |
578 } | 554 |
579 } | 555 #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED |
| 556 if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0) |
| 557 png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1); |
| 558 #endif |
| 559 |
| 560 #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED |
| 561 if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) |
| 562 png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1); |
| 563 #endif |
| 564 |
| 565 #ifdef PNG_WRITE_BGR_SUPPORTED |
| 566 if ((png_ptr->transformations & PNG_BGR) != 0) |
| 567 png_do_bgr(row_info, png_ptr->row_buf + 1); |
| 568 #endif |
| 569 |
| 570 #ifdef PNG_WRITE_INVERT_SUPPORTED |
| 571 if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) |
| 572 png_do_invert(row_info, png_ptr->row_buf + 1); |
| 573 #endif |
580 } | 574 } |
581 #endif /* PNG_MNG_FEATURES_SUPPORTED */ | 575 #endif /* WRITE_TRANSFORMS */ |
582 #endif /* PNG_WRITE_SUPPORTED */ | 576 #endif /* WRITE */ |
OLD | NEW |