blob: addb61c8096f36a4e800449a9db7fadf42842b1a [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-Pehrson860ab2b1999-10-14 07:43:10 -05004 * libpng 1.0.5 - October 15, 1999
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-Pehrsonc9442291999-01-06 21:50:16 -06008 * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06009 */
Guy Schalnat0d580581995-07-20 02:43:20 -050010
11#define PNG_INTERNAL
12#include "png.h"
13
Glenn Randers-Pehrson345bc271998-06-14 14:43:31 -050014/* Transform the data according to the user's wishes. The order of
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -060015 * transformations is significant.
16 */
Guy Schalnat0d580581995-07-20 02:43:20 -050017void
Guy Schalnat6d764711995-12-19 03:22:19 -060018png_do_write_transformations(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -050019{
Andreas Dilger47a0c421997-05-16 02:46:07 -050020 png_debug(1, "in png_do_write_transformations\n");
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -060021
22#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
23 if (png_ptr->transformations & PNG_USER_TRANSFORM)
24 if(png_ptr->write_user_transform_fn != NULL)
25 (*(png_ptr->write_user_transform_fn)) /* user write transform function */
26 (png_ptr, /* png_ptr */
27 &(png_ptr->row_info), /* row_info: */
28 /* png_uint_32 width; width of row */
29 /* png_uint_32 rowbytes; number of bytes in row */
30 /* png_byte color_type; color type of pixels */
31 /* png_byte bit_depth; bit depth of samples */
32 /* png_byte channels; number of channels (1-4) */
33 /* png_byte pixel_depth; bits per pixel (depth*channels) */
34 png_ptr->row_buf + 1); /* start of pixel data for row */
35#endif
Guy Schalnat51f0eb41995-09-26 05:22:39 -050036#if defined(PNG_WRITE_FILLER_SUPPORTED)
Guy Schalnat6d764711995-12-19 03:22:19 -060037 if (png_ptr->transformations & PNG_FILLER)
Andreas Dilger47a0c421997-05-16 02:46:07 -050038 png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
Guy Schalnate5a37791996-06-05 15:50:50 -050039 png_ptr->flags);
Guy Schalnat51f0eb41995-09-26 05:22:39 -050040#endif
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -060041#if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
42 if (png_ptr->transformations & PNG_PACKSWAP)
43 png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
44#endif
Guy Schalnat51f0eb41995-09-26 05:22:39 -050045#if defined(PNG_WRITE_PACK_SUPPORTED)
Guy Schalnat0d580581995-07-20 02:43:20 -050046 if (png_ptr->transformations & PNG_PACK)
47 png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
Andreas Dilger47a0c421997-05-16 02:46:07 -050048 (png_uint_32)png_ptr->bit_depth);
Guy Schalnat51f0eb41995-09-26 05:22:39 -050049#endif
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -060050#if defined(PNG_WRITE_SWAP_SUPPORTED)
51 if (png_ptr->transformations & PNG_SWAP_BYTES)
52 png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
53#endif
Guy Schalnat51f0eb41995-09-26 05:22:39 -050054#if defined(PNG_WRITE_SHIFT_SUPPORTED)
Guy Schalnat0d580581995-07-20 02:43:20 -050055 if (png_ptr->transformations & PNG_SHIFT)
56 png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
57 &(png_ptr->shift));
Guy Schalnat51f0eb41995-09-26 05:22:39 -050058#endif
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -060059#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
60 if (png_ptr->transformations & PNG_INVERT_ALPHA)
61 png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
62#endif
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -060063#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
64 if (png_ptr->transformations & PNG_SWAP_ALPHA)
65 png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
66#endif
Guy Schalnat51f0eb41995-09-26 05:22:39 -050067#if defined(PNG_WRITE_BGR_SUPPORTED)
Guy Schalnat0d580581995-07-20 02:43:20 -050068 if (png_ptr->transformations & PNG_BGR)
69 png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
Guy Schalnat51f0eb41995-09-26 05:22:39 -050070#endif
71#if defined(PNG_WRITE_INVERT_SUPPORTED)
Guy Schalnat0d580581995-07-20 02:43:20 -050072 if (png_ptr->transformations & PNG_INVERT_MONO)
73 png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
Guy Schalnat51f0eb41995-09-26 05:22:39 -050074#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050075}
76
Guy Schalnat51f0eb41995-09-26 05:22:39 -050077#if defined(PNG_WRITE_PACK_SUPPORTED)
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -060078/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
79 * row_info bit depth should be 8 (one pixel per byte). The channels
80 * should be 1 (this only happens on grayscale and paletted images).
81 */
Guy Schalnat0d580581995-07-20 02:43:20 -050082void
Andreas Dilger47a0c421997-05-16 02:46:07 -050083png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
Guy Schalnat0d580581995-07-20 02:43:20 -050084{
Andreas Dilger47a0c421997-05-16 02:46:07 -050085 png_debug(1, "in png_do_pack\n");
86 if (row_info->bit_depth == 8 &&
87#if defined(PNG_USELESS_TESTS_SUPPORTED)
88 row != NULL && row_info != NULL &&
89#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050090 row_info->channels == 1)
91 {
Andreas Dilger47a0c421997-05-16 02:46:07 -050092 switch ((int)bit_depth)
Guy Schalnat0d580581995-07-20 02:43:20 -050093 {
94 case 1:
95 {
Andreas Dilger47a0c421997-05-16 02:46:07 -050096 png_bytep sp, dp;
97 int mask, v;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -050098 png_uint_32 i;
99 png_uint_32 row_width = row_info->width;
Guy Schalnat0d580581995-07-20 02:43:20 -0500100
101 sp = row;
102 dp = row;
103 mask = 0x80;
104 v = 0;
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600105
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500106 for (i = 0; i < row_width; i++)
Guy Schalnat0d580581995-07-20 02:43:20 -0500107 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500108 if (*sp != 0)
Guy Schalnat0d580581995-07-20 02:43:20 -0500109 v |= mask;
110 sp++;
111 if (mask > 1)
112 mask >>= 1;
113 else
114 {
115 mask = 0x80;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600116 *dp = (png_byte)v;
117 dp++;
Guy Schalnat0d580581995-07-20 02:43:20 -0500118 v = 0;
119 }
120 }
121 if (mask != 0x80)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600122 *dp = (png_byte)v;
Guy Schalnat0d580581995-07-20 02:43:20 -0500123 break;
124 }
125 case 2:
126 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500127 png_bytep sp, dp;
128 int shift, v;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500129 png_uint_32 i;
130 png_uint_32 row_width = row_info->width;
Guy Schalnat0d580581995-07-20 02:43:20 -0500131
132 sp = row;
133 dp = row;
134 shift = 6;
135 v = 0;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500136 for (i = 0; i < row_width; i++)
Guy Schalnat0d580581995-07-20 02:43:20 -0500137 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500138 png_byte value;
139
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600140 value = (png_byte)(*sp & 0x3);
Guy Schalnat0d580581995-07-20 02:43:20 -0500141 v |= (value << shift);
142 if (shift == 0)
143 {
144 shift = 6;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600145 *dp = (png_byte)v;
Guy Schalnat0d580581995-07-20 02:43:20 -0500146 dp++;
147 v = 0;
148 }
149 else
150 shift -= 2;
151 sp++;
152 }
153 if (shift != 6)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600154 *dp = (png_byte)v;
Guy Schalnat0d580581995-07-20 02:43:20 -0500155 break;
156 }
157 case 4:
158 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500159 png_bytep sp, dp;
160 int shift, v;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500161 png_uint_32 i;
162 png_uint_32 row_width = row_info->width;
Guy Schalnat0d580581995-07-20 02:43:20 -0500163
164 sp = row;
165 dp = row;
166 shift = 4;
167 v = 0;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500168 for (i = 0; i < row_width; i++)
Guy Schalnat0d580581995-07-20 02:43:20 -0500169 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500170 png_byte value;
171
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600172 value = (png_byte)(*sp & 0xf);
Guy Schalnat0d580581995-07-20 02:43:20 -0500173 v |= (value << shift);
174
175 if (shift == 0)
176 {
177 shift = 4;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600178 *dp = (png_byte)v;
Guy Schalnat0d580581995-07-20 02:43:20 -0500179 dp++;
180 v = 0;
181 }
182 else
183 shift -= 4;
184
185 sp++;
186 }
187 if (shift != 4)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600188 *dp = (png_byte)v;
Guy Schalnat0d580581995-07-20 02:43:20 -0500189 break;
190 }
191 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500192 row_info->bit_depth = (png_byte)bit_depth;
193 row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
Guy Schalnat0d580581995-07-20 02:43:20 -0500194 row_info->rowbytes =
195 ((row_info->width * row_info->pixel_depth + 7) >> 3);
196 }
197}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500198#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500199
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500200#if defined(PNG_WRITE_SHIFT_SUPPORTED)
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600201/* Shift pixel values to take advantage of whole range. Pass the
202 * true number of bits in bit_depth. The row should be packed
203 * according to row_info->bit_depth. Thus, if you had a row of
204 * bit depth 4, but the pixels only had values from 0 to 7, you
205 * would pass 3 as bit_depth, and this routine would translate the
206 * data to 0 to 15.
207 */
Guy Schalnat0d580581995-07-20 02:43:20 -0500208void
Guy Schalnat6d764711995-12-19 03:22:19 -0600209png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
Guy Schalnat0d580581995-07-20 02:43:20 -0500210{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500211 png_debug(1, "in png_do_shift\n");
212#if defined(PNG_USELESS_TESTS_SUPPORTED)
213 if (row != NULL && row_info != NULL &&
214#else
215 if (
216#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500217 row_info->color_type != PNG_COLOR_TYPE_PALETTE)
218 {
219 int shift_start[4], shift_dec[4];
Glenn Randers-Pehrsond0dce401998-05-09 10:02:29 -0500220 int channels = 0;
Guy Schalnat0d580581995-07-20 02:43:20 -0500221
Guy Schalnat0d580581995-07-20 02:43:20 -0500222 if (row_info->color_type & PNG_COLOR_MASK_COLOR)
223 {
224 shift_start[channels] = row_info->bit_depth - bit_depth->red;
225 shift_dec[channels] = bit_depth->red;
226 channels++;
227 shift_start[channels] = row_info->bit_depth - bit_depth->green;
228 shift_dec[channels] = bit_depth->green;
229 channels++;
230 shift_start[channels] = row_info->bit_depth - bit_depth->blue;
231 shift_dec[channels] = bit_depth->blue;
232 channels++;
233 }
234 else
235 {
236 shift_start[channels] = row_info->bit_depth - bit_depth->gray;
237 shift_dec[channels] = bit_depth->gray;
238 channels++;
239 }
240 if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
241 {
242 shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
243 shift_dec[channels] = bit_depth->alpha;
244 channels++;
245 }
246
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -0600247 /* with low row depths, could only be grayscale, so one channel */
Guy Schalnat0d580581995-07-20 02:43:20 -0500248 if (row_info->bit_depth < 8)
249 {
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500250 png_bytep bp = row;
251 png_uint_32 i;
Guy Schalnat0d580581995-07-20 02:43:20 -0500252 png_byte mask;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500253 png_uint_32 row_bytes = row_info->rowbytes;
Guy Schalnat0d580581995-07-20 02:43:20 -0500254
255 if (bit_depth->gray == 1 && row_info->bit_depth == 2)
256 mask = 0x55;
257 else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
258 mask = 0x11;
259 else
260 mask = 0xff;
261
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500262 for (i = 0; i < row_bytes; i++, bp++)
Guy Schalnat0d580581995-07-20 02:43:20 -0500263 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500264 png_uint_16 v;
265 int j;
Guy Schalnat0d580581995-07-20 02:43:20 -0500266
267 v = *bp;
268 *bp = 0;
269 for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
270 {
271 if (j > 0)
272 *bp |= (png_byte)((v << j) & 0xff);
273 else
274 *bp |= (png_byte)((v >> (-j)) & mask);
275 }
276 }
277 }
278 else if (row_info->bit_depth == 8)
279 {
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500280 png_bytep bp = row;
281 png_uint_32 i;
Glenn Randers-Pehrsond0dce401998-05-09 10:02:29 -0500282 png_uint_32 istop = channels * row_info->width;
Guy Schalnat0d580581995-07-20 02:43:20 -0500283
Glenn Randers-Pehrsond0dce401998-05-09 10:02:29 -0500284 for (i = 0; i < istop; i++, bp++)
Guy Schalnat0d580581995-07-20 02:43:20 -0500285 {
Guy Schalnat0d580581995-07-20 02:43:20 -0500286
Glenn Randers-Pehrsond0dce401998-05-09 10:02:29 -0500287 png_uint_16 v;
288 int j;
289 int c = (int)(i%channels);
290
291 v = *bp;
292 *bp = 0;
293 for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
Guy Schalnat0d580581995-07-20 02:43:20 -0500294 {
Glenn Randers-Pehrsond0dce401998-05-09 10:02:29 -0500295 if (j > 0)
296 *bp |= (png_byte)((v << j) & 0xff);
297 else
298 *bp |= (png_byte)((v >> (-j)) & 0xff);
Guy Schalnat0d580581995-07-20 02:43:20 -0500299 }
300 }
301 }
302 else
303 {
Guy Schalnat6d764711995-12-19 03:22:19 -0600304 png_bytep bp;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500305 png_uint_32 i;
Glenn Randers-Pehrsond0dce401998-05-09 10:02:29 -0500306 png_uint_32 istop = channels * row_info->width;
Guy Schalnat0d580581995-07-20 02:43:20 -0500307
Glenn Randers-Pehrsond0dce401998-05-09 10:02:29 -0500308 for (bp = row, i = 0; i < istop; i++)
Guy Schalnat0d580581995-07-20 02:43:20 -0500309 {
Glenn Randers-Pehrsond0dce401998-05-09 10:02:29 -0500310 int c = (int)(i%channels);
311 png_uint_16 value, v;
312 int j;
Guy Schalnat0d580581995-07-20 02:43:20 -0500313
Glenn Randers-Pehrson860ab2b1999-10-14 07:43:10 -0500314 v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
Glenn Randers-Pehrsond0dce401998-05-09 10:02:29 -0500315 value = 0;
316 for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
Guy Schalnat0d580581995-07-20 02:43:20 -0500317 {
Glenn Randers-Pehrsond0dce401998-05-09 10:02:29 -0500318 if (j > 0)
319 value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
320 else
321 value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
Guy Schalnat0d580581995-07-20 02:43:20 -0500322 }
Glenn Randers-Pehrsond0dce401998-05-09 10:02:29 -0500323 *bp++ = (png_byte)(value >> 8);
324 *bp++ = (png_byte)(value & 0xff);
Guy Schalnat0d580581995-07-20 02:43:20 -0500325 }
326 }
327 }
328}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500329#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500330
Andreas Dilger47a0c421997-05-16 02:46:07 -0500331#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
Guy Schalnat0d580581995-07-20 02:43:20 -0500332void
Andreas Dilger47a0c421997-05-16 02:46:07 -0500333png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
Guy Schalnat0d580581995-07-20 02:43:20 -0500334{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500335 png_debug(1, "in png_do_write_swap_alpha\n");
336#if defined(PNG_USELESS_TESTS_SUPPORTED)
337 if (row != NULL && row_info != NULL)
338#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500339 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500340 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
Guy Schalnat0d580581995-07-20 02:43:20 -0500341 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500342 /* This converts from ARGB to RGBA */
343 if (row_info->bit_depth == 8)
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500344 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500345 png_bytep sp, dp;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500346 png_uint_32 i;
347 png_uint_32 row_width = row_info->width;
348 for (i = 0, sp = dp = row; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500349 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500350 png_byte save = *(sp++);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500351 *(dp++) = *(sp++);
352 *(dp++) = *(sp++);
353 *(dp++) = *(sp++);
354 *(dp++) = save;
355 }
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500356 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500357 /* This converts from AARRGGBB to RRGGBBAA */
358 else
359 {
360 png_bytep sp, dp;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500361 png_uint_32 i;
362 png_uint_32 row_width = row_info->width;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500363
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500364 for (i = 0, sp = dp = row; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500365 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500366 png_byte save[2];
Andreas Dilger47a0c421997-05-16 02:46:07 -0500367 save[0] = *(sp++);
368 save[1] = *(sp++);
369 *(dp++) = *(sp++);
370 *(dp++) = *(sp++);
371 *(dp++) = *(sp++);
372 *(dp++) = *(sp++);
373 *(dp++) = *(sp++);
374 *(dp++) = *(sp++);
375 *(dp++) = save[0];
376 *(dp++) = save[1];
377 }
378 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500379 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500380 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500381 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500382 /* This converts from AG to GA */
383 if (row_info->bit_depth == 8)
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500384 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500385 png_bytep sp, dp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500386 png_uint_32 i;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500387 png_uint_32 row_width = row_info->width;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500388
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500389 for (i = 0, sp = dp = row; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500390 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500391 png_byte save = *(sp++);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500392 *(dp++) = *(sp++);
393 *(dp++) = save;
394 }
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500395 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500396 /* This converts from AAGG to GGAA */
397 else
398 {
399 png_bytep sp, dp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500400 png_uint_32 i;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500401 png_uint_32 row_width = row_info->width;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500402
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500403 for (i = 0, sp = dp = row; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500404 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500405 png_byte save[2];
Andreas Dilger47a0c421997-05-16 02:46:07 -0500406 save[0] = *(sp++);
407 save[1] = *(sp++);
408 *(dp++) = *(sp++);
409 *(dp++) = *(sp++);
410 *(dp++) = save[0];
411 *(dp++) = save[1];
412 }
413 }
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500414 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500415 }
416}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500417#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500418
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600419#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
420void
421png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
422{
423 png_debug(1, "in png_do_write_invert_alpha\n");
424#if defined(PNG_USELESS_TESTS_SUPPORTED)
425 if (row != NULL && row_info != NULL)
426#endif
427 {
428 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
429 {
430 /* This inverts the alpha channel in RGBA */
431 if (row_info->bit_depth == 8)
432 {
433 png_bytep sp, dp;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500434 png_uint_32 i;
435 png_uint_32 row_width = row_info->width;
436 for (i = 0, sp = dp = row; i < row_width; i++)
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600437 {
438 *(dp++) = *(sp++);
439 *(dp++) = *(sp++);
440 *(dp++) = *(sp++);
Glenn Randers-Pehrson860ab2b1999-10-14 07:43:10 -0500441 *(dp++) = (png_byte)(255 - *(sp++));
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600442 }
443 }
444 /* This inverts the alpha channel in RRGGBBAA */
445 else
446 {
447 png_bytep sp, dp;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500448 png_uint_32 i;
449 png_uint_32 row_width = row_info->width;
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600450
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500451 for (i = 0, sp = dp = row; i < row_width; i++)
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600452 {
453 *(dp++) = *(sp++);
454 *(dp++) = *(sp++);
455 *(dp++) = *(sp++);
456 *(dp++) = *(sp++);
457 *(dp++) = *(sp++);
458 *(dp++) = *(sp++);
Glenn Randers-Pehrson860ab2b1999-10-14 07:43:10 -0500459 *(dp++) = (png_byte)(255 - *(sp++));
460 *(dp++) = (png_byte)(255 - *(sp++));
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600461 }
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;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500470 png_uint_32 i;
471 png_uint_32 row_width = row_info->width;
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600472
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500473 for (i = 0, sp = dp = row; i < row_width; i++)
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600474 {
475 *(dp++) = *(sp++);
Glenn Randers-Pehrson860ab2b1999-10-14 07:43:10 -0500476 *(dp++) = (png_byte)(255 - *(sp++));
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600477 }
478 }
479 /* This inverts the alpha channel in GGAA */
480 else
481 {
482 png_bytep sp, dp;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500483 png_uint_32 i;
484 png_uint_32 row_width = row_info->width;
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600485
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500486 for (i = 0, sp = dp = row; i < row_width; i++)
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600487 {
488 *(dp++) = *(sp++);
489 *(dp++) = *(sp++);
Glenn Randers-Pehrson860ab2b1999-10-14 07:43:10 -0500490 *(dp++) = (png_byte)(255 - *(sp++));
491 *(dp++) = (png_byte)(255 - *(sp++));
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600492 }
493 }
494 }
495 }
496}
497#endif