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