blob: d85e01536e43c040f0b1f928684e245d2678659c [file] [log] [blame]
Guy Schalnat0d580581995-07-20 02:43:20 -05001
Andreas Dilger47a0c421997-05-16 02:46:07 -05002/* pngwtran.c - transforms the data in a row for PNG writers
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06003 *
Glenn Randers-Pehrsonf9f2fe01998-03-15 18:20:23 -06004 * libpng 1.0.1
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06005 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
7 * Copyright (c) 1996, 1997 Andreas Dilger
Glenn Randers-Pehrson2687fcc1998-01-07 20:54:20 -06008 * Copyright (c) 1998, Glenn Randers-Pehrson
Glenn Randers-Pehrsonf9f2fe01998-03-15 18:20:23 -06009 * March 15, 1998
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -060010 */
Guy Schalnat0d580581995-07-20 02:43:20 -050011
12#define PNG_INTERNAL
13#include "png.h"
14
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -060015/* Transform the data according to the users wishes. The order of
16 * transformations is significant.
17 */
Guy Schalnat0d580581995-07-20 02:43:20 -050018void
Guy Schalnat6d764711995-12-19 03:22:19 -060019png_do_write_transformations(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -050020{
Andreas Dilger47a0c421997-05-16 02:46:07 -050021 png_debug(1, "in png_do_write_transformations\n");
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -060022
23#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
24 if (png_ptr->transformations & PNG_USER_TRANSFORM)
25 if(png_ptr->write_user_transform_fn != NULL)
26 (*(png_ptr->write_user_transform_fn)) /* user write transform function */
27 (png_ptr, /* png_ptr */
28 &(png_ptr->row_info), /* row_info: */
29 /* png_uint_32 width; width of row */
30 /* png_uint_32 rowbytes; number of bytes in row */
31 /* png_byte color_type; color type of pixels */
32 /* png_byte bit_depth; bit depth of samples */
33 /* png_byte channels; number of channels (1-4) */
34 /* png_byte pixel_depth; bits per pixel (depth*channels) */
35 png_ptr->row_buf + 1); /* start of pixel data for row */
36#endif
Guy Schalnat51f0eb41995-09-26 05:22:39 -050037#if defined(PNG_WRITE_FILLER_SUPPORTED)
Guy Schalnat6d764711995-12-19 03:22:19 -060038 if (png_ptr->transformations & PNG_FILLER)
Andreas Dilger47a0c421997-05-16 02:46:07 -050039 png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
Guy Schalnate5a37791996-06-05 15:50:50 -050040 png_ptr->flags);
Guy Schalnat51f0eb41995-09-26 05:22:39 -050041#endif
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -060042#if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
43 if (png_ptr->transformations & PNG_PACKSWAP)
44 png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
45#endif
Guy Schalnat51f0eb41995-09-26 05:22:39 -050046#if defined(PNG_WRITE_PACK_SUPPORTED)
Guy Schalnat0d580581995-07-20 02:43:20 -050047 if (png_ptr->transformations & PNG_PACK)
48 png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
Andreas Dilger47a0c421997-05-16 02:46:07 -050049 (png_uint_32)png_ptr->bit_depth);
Guy Schalnat51f0eb41995-09-26 05:22:39 -050050#endif
51#if defined(PNG_WRITE_SHIFT_SUPPORTED)
Guy Schalnat0d580581995-07-20 02:43:20 -050052 if (png_ptr->transformations & PNG_SHIFT)
53 png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
54 &(png_ptr->shift));
Guy Schalnat51f0eb41995-09-26 05:22:39 -050055#endif
56#if defined(PNG_WRITE_SWAP_SUPPORTED)
Guy Schalnat0d580581995-07-20 02:43:20 -050057 if (png_ptr->transformations & PNG_SWAP_BYTES)
58 png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
Guy Schalnat51f0eb41995-09-26 05:22:39 -050059#endif
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -060060#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
61 if (png_ptr->transformations & PNG_INVERT_ALPHA)
62 png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
63#endif
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -060064#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
65 if (png_ptr->transformations & PNG_SWAP_ALPHA)
66 png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
67#endif
Guy Schalnat51f0eb41995-09-26 05:22:39 -050068#if defined(PNG_WRITE_BGR_SUPPORTED)
Guy Schalnat0d580581995-07-20 02:43:20 -050069 if (png_ptr->transformations & PNG_BGR)
70 png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
Guy Schalnat51f0eb41995-09-26 05:22:39 -050071#endif
72#if defined(PNG_WRITE_INVERT_SUPPORTED)
Guy Schalnat0d580581995-07-20 02:43:20 -050073 if (png_ptr->transformations & PNG_INVERT_MONO)
74 png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
Guy Schalnat51f0eb41995-09-26 05:22:39 -050075#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050076}
77
Guy Schalnat51f0eb41995-09-26 05:22:39 -050078#if defined(PNG_WRITE_PACK_SUPPORTED)
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -060079/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
80 * row_info bit depth should be 8 (one pixel per byte). The channels
81 * should be 1 (this only happens on grayscale and paletted images).
82 */
Guy Schalnat0d580581995-07-20 02:43:20 -050083void
Andreas Dilger47a0c421997-05-16 02:46:07 -050084png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
Guy Schalnat0d580581995-07-20 02:43:20 -050085{
Andreas Dilger47a0c421997-05-16 02:46:07 -050086 png_debug(1, "in png_do_pack\n");
87 if (row_info->bit_depth == 8 &&
88#if defined(PNG_USELESS_TESTS_SUPPORTED)
89 row != NULL && row_info != NULL &&
90#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050091 row_info->channels == 1)
92 {
Andreas Dilger47a0c421997-05-16 02:46:07 -050093 switch ((int)bit_depth)
Guy Schalnat0d580581995-07-20 02:43:20 -050094 {
95 case 1:
96 {
Andreas Dilger47a0c421997-05-16 02:46:07 -050097 png_bytep sp, dp;
98 int mask, v;
99 png_uint_32 i;
Guy Schalnat0d580581995-07-20 02:43:20 -0500100
101 sp = row;
102 dp = row;
103 mask = 0x80;
104 v = 0;
105 for (i = 0; i < row_info->width; i++)
106 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500107 if (*sp != 0)
Guy Schalnat0d580581995-07-20 02:43:20 -0500108 v |= mask;
109 sp++;
110 if (mask > 1)
111 mask >>= 1;
112 else
113 {
114 mask = 0x80;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600115 *dp = (png_byte)v;
116 dp++;
Guy Schalnat0d580581995-07-20 02:43:20 -0500117 v = 0;
118 }
119 }
120 if (mask != 0x80)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600121 *dp = (png_byte)v;
Guy Schalnat0d580581995-07-20 02:43:20 -0500122 break;
123 }
124 case 2:
125 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500126 png_bytep sp, dp;
127 int shift, v;
128 png_uint_32 i;
Guy Schalnat0d580581995-07-20 02:43:20 -0500129
130 sp = row;
131 dp = row;
132 shift = 6;
133 v = 0;
134 for (i = 0; i < row_info->width; i++)
135 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500136 png_byte value;
137
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600138 value = (png_byte)(*sp & 0x3);
Guy Schalnat0d580581995-07-20 02:43:20 -0500139 v |= (value << shift);
140 if (shift == 0)
141 {
142 shift = 6;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600143 *dp = (png_byte)v;
Guy Schalnat0d580581995-07-20 02:43:20 -0500144 dp++;
145 v = 0;
146 }
147 else
148 shift -= 2;
149 sp++;
150 }
151 if (shift != 6)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600152 *dp = (png_byte)v;
Guy Schalnat0d580581995-07-20 02:43:20 -0500153 break;
154 }
155 case 4:
156 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500157 png_bytep sp, dp;
158 int shift, v;
159 png_uint_32 i;
Guy Schalnat0d580581995-07-20 02:43:20 -0500160
161 sp = row;
162 dp = row;
163 shift = 4;
164 v = 0;
165 for (i = 0; i < row_info->width; i++)
166 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500167 png_byte value;
168
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600169 value = (png_byte)(*sp & 0xf);
Guy Schalnat0d580581995-07-20 02:43:20 -0500170 v |= (value << shift);
171
172 if (shift == 0)
173 {
174 shift = 4;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600175 *dp = (png_byte)v;
Guy Schalnat0d580581995-07-20 02:43:20 -0500176 dp++;
177 v = 0;
178 }
179 else
180 shift -= 4;
181
182 sp++;
183 }
184 if (shift != 4)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600185 *dp = (png_byte)v;
Guy Schalnat0d580581995-07-20 02:43:20 -0500186 break;
187 }
188 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500189 row_info->bit_depth = (png_byte)bit_depth;
190 row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
Guy Schalnat0d580581995-07-20 02:43:20 -0500191 row_info->rowbytes =
192 ((row_info->width * row_info->pixel_depth + 7) >> 3);
193 }
194}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500195#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500196
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500197#if defined(PNG_WRITE_SHIFT_SUPPORTED)
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600198/* Shift pixel values to take advantage of whole range. Pass the
199 * true number of bits in bit_depth. The row should be packed
200 * according to row_info->bit_depth. Thus, if you had a row of
201 * bit depth 4, but the pixels only had values from 0 to 7, you
202 * would pass 3 as bit_depth, and this routine would translate the
203 * data to 0 to 15.
204 */
Guy Schalnat0d580581995-07-20 02:43:20 -0500205void
Guy Schalnat6d764711995-12-19 03:22:19 -0600206png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
Guy Schalnat0d580581995-07-20 02:43:20 -0500207{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500208 png_debug(1, "in png_do_shift\n");
209#if defined(PNG_USELESS_TESTS_SUPPORTED)
210 if (row != NULL && row_info != NULL &&
211#else
212 if (
213#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500214 row_info->color_type != PNG_COLOR_TYPE_PALETTE)
215 {
216 int shift_start[4], shift_dec[4];
Andreas Dilger47a0c421997-05-16 02:46:07 -0500217 png_uint_32 channels;
Guy Schalnat0d580581995-07-20 02:43:20 -0500218
219 channels = 0;
220 if (row_info->color_type & PNG_COLOR_MASK_COLOR)
221 {
222 shift_start[channels] = row_info->bit_depth - bit_depth->red;
223 shift_dec[channels] = bit_depth->red;
224 channels++;
225 shift_start[channels] = row_info->bit_depth - bit_depth->green;
226 shift_dec[channels] = bit_depth->green;
227 channels++;
228 shift_start[channels] = row_info->bit_depth - bit_depth->blue;
229 shift_dec[channels] = bit_depth->blue;
230 channels++;
231 }
232 else
233 {
234 shift_start[channels] = row_info->bit_depth - bit_depth->gray;
235 shift_dec[channels] = bit_depth->gray;
236 channels++;
237 }
238 if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
239 {
240 shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
241 shift_dec[channels] = bit_depth->alpha;
242 channels++;
243 }
244
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -0600245 /* with low row depths, could only be grayscale, so one channel */
Guy Schalnat0d580581995-07-20 02:43:20 -0500246 if (row_info->bit_depth < 8)
247 {
Guy Schalnat6d764711995-12-19 03:22:19 -0600248 png_bytep bp;
Guy Schalnat0d580581995-07-20 02:43:20 -0500249 png_uint_32 i;
Guy Schalnat0d580581995-07-20 02:43:20 -0500250 png_byte mask;
251
252 if (bit_depth->gray == 1 && row_info->bit_depth == 2)
253 mask = 0x55;
254 else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
255 mask = 0x11;
256 else
257 mask = 0xff;
258
259 for (bp = row, i = 0; i < row_info->rowbytes; i++, bp++)
260 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500261 png_uint_16 v;
262 int j;
Guy Schalnat0d580581995-07-20 02:43:20 -0500263
264 v = *bp;
265 *bp = 0;
266 for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
267 {
268 if (j > 0)
269 *bp |= (png_byte)((v << j) & 0xff);
270 else
271 *bp |= (png_byte)((v >> (-j)) & mask);
272 }
273 }
274 }
275 else if (row_info->bit_depth == 8)
276 {
Guy Schalnat6d764711995-12-19 03:22:19 -0600277 png_bytep bp;
Guy Schalnat0d580581995-07-20 02:43:20 -0500278 png_uint_32 i;
Guy Schalnat0d580581995-07-20 02:43:20 -0500279
280 for (bp = row, i = 0; i < row_info->width; i++)
281 {
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600282 png_uint_32 c;
Guy Schalnat0d580581995-07-20 02:43:20 -0500283
284 for (c = 0; c < channels; c++, bp++)
285 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500286 png_uint_16 v;
287 int j;
Guy Schalnat0d580581995-07-20 02:43:20 -0500288
289 v = *bp;
290 *bp = 0;
291 for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
292 {
293 if (j > 0)
294 *bp |= (png_byte)((v << j) & 0xff);
295 else
296 *bp |= (png_byte)((v >> (-j)) & 0xff);
297 }
298 }
299 }
300 }
301 else
302 {
Guy Schalnat6d764711995-12-19 03:22:19 -0600303 png_bytep bp;
Guy Schalnat0d580581995-07-20 02:43:20 -0500304 png_uint_32 i;
Guy Schalnat0d580581995-07-20 02:43:20 -0500305
Andreas Dilger47a0c421997-05-16 02:46:07 -0500306 for (bp = row, i = 0; i < row_info->width * row_info->channels; i++)
Guy Schalnat0d580581995-07-20 02:43:20 -0500307 {
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600308 png_uint_32 c;
Guy Schalnat0d580581995-07-20 02:43:20 -0500309
310 for (c = 0; c < channels; c++, bp += 2)
311 {
312 png_uint_16 value, v;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500313 int j;
Guy Schalnat0d580581995-07-20 02:43:20 -0500314
Andreas Dilger47a0c421997-05-16 02:46:07 -0500315 v = ((png_uint_16)(*bp) << 8) + *(bp + 1);
Guy Schalnat0d580581995-07-20 02:43:20 -0500316 value = 0;
317 for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
318 {
319 if (j > 0)
320 value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
321 else
322 value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
323 }
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600324 *bp = (png_byte)(value >> 8);
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600325 *(bp + 1) = (png_byte)(value & 0xff);
Guy Schalnat0d580581995-07-20 02:43:20 -0500326 }
327 }
328 }
329 }
330}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500331#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500332
Andreas Dilger47a0c421997-05-16 02:46:07 -0500333#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
Guy Schalnat0d580581995-07-20 02:43:20 -0500334void
Andreas Dilger47a0c421997-05-16 02:46:07 -0500335png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
Guy Schalnat0d580581995-07-20 02:43:20 -0500336{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500337 png_debug(1, "in png_do_write_swap_alpha\n");
338#if defined(PNG_USELESS_TESTS_SUPPORTED)
339 if (row != NULL && row_info != NULL)
340#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500341 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500342 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
Guy Schalnat0d580581995-07-20 02:43:20 -0500343 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500344 /* This converts from ARGB to RGBA */
345 if (row_info->bit_depth == 8)
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500346 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500347 png_bytep sp, dp;
348 png_byte save;
349 png_uint_32 i;
350
351 for (i = 0, sp = dp = row; i < row_info->width; i++)
352 {
353 save = *(sp++);
354 *(dp++) = *(sp++);
355 *(dp++) = *(sp++);
356 *(dp++) = *(sp++);
357 *(dp++) = save;
358 }
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500359 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500360 /* This converts from AARRGGBB to RRGGBBAA */
361 else
362 {
363 png_bytep sp, dp;
364 png_byte save[2];
365 png_uint_32 i;
366
367 for (i = 0, sp = dp = row; i < row_info->width; i++)
368 {
369 save[0] = *(sp++);
370 save[1] = *(sp++);
371 *(dp++) = *(sp++);
372 *(dp++) = *(sp++);
373 *(dp++) = *(sp++);
374 *(dp++) = *(sp++);
375 *(dp++) = *(sp++);
376 *(dp++) = *(sp++);
377 *(dp++) = save[0];
378 *(dp++) = save[1];
379 }
380 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500381 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500382 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500383 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500384 /* This converts from AG to GA */
385 if (row_info->bit_depth == 8)
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500386 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500387 png_bytep sp, dp;
388 png_byte save;
389 png_uint_32 i;
390
391 for (i = 0, sp = dp = row; i < row_info->width; i++)
392 {
393 save = *(sp++);
394 *(dp++) = *(sp++);
395 *(dp++) = save;
396 }
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500397 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500398 /* This converts from AAGG to GGAA */
399 else
400 {
401 png_bytep sp, dp;
402 png_byte save[2];
403 png_uint_32 i;
404
405 for (i = 0, sp = dp = row; i < row_info->width; i++)
406 {
407 save[0] = *(sp++);
408 save[1] = *(sp++);
409 *(dp++) = *(sp++);
410 *(dp++) = *(sp++);
411 *(dp++) = save[0];
412 *(dp++) = save[1];
413 }
414 }
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500415 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500416 }
417}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500418#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500419
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600420#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
421void
422png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
423{
424 png_debug(1, "in png_do_write_invert_alpha\n");
425#if defined(PNG_USELESS_TESTS_SUPPORTED)
426 if (row != NULL && row_info != NULL)
427#endif
428 {
429 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
430 {
431 /* This inverts the alpha channel in RGBA */
432 if (row_info->bit_depth == 8)
433 {
434 png_bytep sp, dp;
435 png_uint_32 i;
436
437 for (i = 0, sp = dp = row; i < row_info->width; i++)
438 {
439 *(dp++) = *(sp++);
440 *(dp++) = *(sp++);
441 *(dp++) = *(sp++);
442 *(dp++) = 255 - *(sp++);
443 }
444 }
445 /* This inverts the alpha channel in RRGGBBAA */
446 else
447 {
448 png_bytep sp, dp;
449 png_uint_32 i;
450
451 for (i = 0, sp = dp = row; i < row_info->width; i++)
452 {
453 *(dp++) = *(sp++);
454 *(dp++) = *(sp++);
455 *(dp++) = *(sp++);
456 *(dp++) = *(sp++);
457 *(dp++) = *(sp++);
458 *(dp++) = *(sp++);
459 *(dp++) = 255 - *(sp++);
460 *(dp++) = 255 - *(sp++);
461 }
462 }
463 }
464 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
465 {
466 /* This inverts the alpha channel in GA */
467 if (row_info->bit_depth == 8)
468 {
469 png_bytep sp, dp;
470 png_uint_32 i;
471
472 for (i = 0, sp = dp = row; i < row_info->width; i++)
473 {
474 *(dp++) = *(sp++);
475 *(dp++) = 255 - *(sp++);
476 }
477 }
478 /* This inverts the alpha channel in GGAA */
479 else
480 {
481 png_bytep sp, dp;
482 png_uint_32 i;
483
484 for (i = 0, sp = dp = row; i < row_info->width; i++)
485 {
486 *(dp++) = *(sp++);
487 *(dp++) = *(sp++);
488 *(dp++) = 255 - *(sp++);
489 *(dp++) = 255 - *(sp++);
490 }
491 }
492 }
493 }
494}
495#endif