blob: c6b4ff0d71a8fbba73e77bb345cd6dcda5629b92 [file] [log] [blame]
Guy Schalnat0d580581995-07-20 02:43:20 -05001
Andreas Dilger47a0c421997-05-16 02:46:07 -05002/* pngtrans.c - transforms the data in a row (used by both readers and writers)
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06003 *
Glenn Randers-Pehrson8f8fb6a1998-03-09 23:02:06 -06004 * libpng 1.0.0a
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-Pehrson8f8fb6a1998-03-09 23:02:06 -06009 * March 9, 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
Guy Schalnat51f0eb41995-09-26 05:22:39 -050015#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
Guy Schalnat0d580581995-07-20 02:43:20 -050016/* turn on bgr to rgb mapping */
17void
Guy Schalnat6d764711995-12-19 03:22:19 -060018png_set_bgr(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_set_bgr\n");
Guy Schalnat0d580581995-07-20 02:43:20 -050021 png_ptr->transformations |= PNG_BGR;
22}
Guy Schalnat51f0eb41995-09-26 05:22:39 -050023#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050024
Guy Schalnat51f0eb41995-09-26 05:22:39 -050025#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
Guy Schalnat0d580581995-07-20 02:43:20 -050026/* turn on 16 bit byte swapping */
27void
Guy Schalnat6d764711995-12-19 03:22:19 -060028png_set_swap(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -050029{
Andreas Dilger47a0c421997-05-16 02:46:07 -050030 png_debug(1, "in png_set_swap\n");
Guy Schalnat0d580581995-07-20 02:43:20 -050031 if (png_ptr->bit_depth == 16)
32 png_ptr->transformations |= PNG_SWAP_BYTES;
33}
Guy Schalnat51f0eb41995-09-26 05:22:39 -050034#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050035
Guy Schalnat51f0eb41995-09-26 05:22:39 -050036#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
Guy Schalnat0d580581995-07-20 02:43:20 -050037/* turn on pixel packing */
38void
Guy Schalnat6d764711995-12-19 03:22:19 -060039png_set_packing(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -050040{
Andreas Dilger47a0c421997-05-16 02:46:07 -050041 png_debug(1, "in png_set_packing\n");
Guy Schalnat0d580581995-07-20 02:43:20 -050042 if (png_ptr->bit_depth < 8)
43 {
44 png_ptr->transformations |= PNG_PACK;
45 png_ptr->usr_bit_depth = 8;
46 }
47}
Guy Schalnat51f0eb41995-09-26 05:22:39 -050048#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050049
Andreas Dilger47a0c421997-05-16 02:46:07 -050050#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
51/* turn on packed pixel swapping */
52void
53png_set_packswap(png_structp png_ptr)
54{
55 png_debug(1, "in png_set_packswap\n");
56 if (png_ptr->bit_depth < 8)
57 png_ptr->transformations |= PNG_PACKSWAP;
58}
59#endif
60
Guy Schalnat51f0eb41995-09-26 05:22:39 -050061#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
Guy Schalnat0d580581995-07-20 02:43:20 -050062void
Guy Schalnat6d764711995-12-19 03:22:19 -060063png_set_shift(png_structp png_ptr, png_color_8p true_bits)
Guy Schalnat0d580581995-07-20 02:43:20 -050064{
Andreas Dilger47a0c421997-05-16 02:46:07 -050065 png_debug(1, "in png_set_shift\n");
Guy Schalnat0d580581995-07-20 02:43:20 -050066 png_ptr->transformations |= PNG_SHIFT;
67 png_ptr->shift = *true_bits;
68}
Guy Schalnat51f0eb41995-09-26 05:22:39 -050069#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050070
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -060071#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
72 defined(PNG_WRITE_INTERLACING_SUPPORTED)
Guy Schalnat0d580581995-07-20 02:43:20 -050073int
Guy Schalnat6d764711995-12-19 03:22:19 -060074png_set_interlace_handling(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -050075{
Andreas Dilger47a0c421997-05-16 02:46:07 -050076 png_debug(1, "in png_set_interlace handling\n");
Guy Schalnat0d580581995-07-20 02:43:20 -050077 if (png_ptr->interlaced)
78 {
79 png_ptr->transformations |= PNG_INTERLACE;
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -060080 return (7);
Guy Schalnat0d580581995-07-20 02:43:20 -050081 }
82
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -060083 return (1);
Guy Schalnat0d580581995-07-20 02:43:20 -050084}
Guy Schalnat51f0eb41995-09-26 05:22:39 -050085#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050086
Guy Schalnat51f0eb41995-09-26 05:22:39 -050087#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -050088/* Add a filler byte on read, or remove a filler or alpha byte on write.
89 * The filler type has changed in v0.95 to allow future 2-byte fillers
90 * for 48-bit input data, as well as avoiding problems with some compilers
91 * which don't like bytes as parameters.
92 */
Guy Schalnat0d580581995-07-20 02:43:20 -050093void
Andreas Dilger47a0c421997-05-16 02:46:07 -050094png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
Guy Schalnat0d580581995-07-20 02:43:20 -050095{
Andreas Dilger47a0c421997-05-16 02:46:07 -050096 png_debug(1, "in png_set_filler\n");
Guy Schalnat51f0eb41995-09-26 05:22:39 -050097 png_ptr->transformations |= PNG_FILLER;
Andreas Dilger47a0c421997-05-16 02:46:07 -050098 png_ptr->filler = (png_byte)filler;
Guy Schalnate5a37791996-06-05 15:50:50 -050099 if (filler_loc == PNG_FILLER_AFTER)
100 png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
101 else
102 png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
103
Andreas Dilger47a0c421997-05-16 02:46:07 -0500104 /* This should probably go in the "do_filler" routine */
105 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB && png_ptr->bit_depth == 8)
106 {
Guy Schalnat0d580581995-07-20 02:43:20 -0500107 png_ptr->usr_channels = 4;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500108 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500109}
Andreas Dilger47a0c421997-05-16 02:46:07 -0500110#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500111
Andreas Dilger47a0c421997-05-16 02:46:07 -0500112#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
113 defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500114void
Andreas Dilger47a0c421997-05-16 02:46:07 -0500115png_set_swap_alpha(png_structp png_ptr)
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500116{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500117 png_debug(1, "in png_set_swap_alpha\n");
118 png_ptr->transformations |= PNG_SWAP_ALPHA;
Guy Schalnat0d580581995-07-20 02:43:20 -0500119}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500120#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500121
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600122#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
123 defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
124void
125png_set_invert_alpha(png_structp png_ptr)
126{
127 png_debug(1, "in png_set_invert_alpha\n");
128 png_ptr->transformations |= PNG_INVERT_ALPHA;
129}
130#endif
131
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500132#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
Guy Schalnat0d580581995-07-20 02:43:20 -0500133void
Guy Schalnat6d764711995-12-19 03:22:19 -0600134png_set_invert_mono(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -0500135{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500136 png_debug(1, "in png_set_invert_mono\n");
Guy Schalnat0d580581995-07-20 02:43:20 -0500137 png_ptr->transformations |= PNG_INVERT_MONO;
138}
139
140/* invert monocrome grayscale data */
141void
Guy Schalnat6d764711995-12-19 03:22:19 -0600142png_do_invert(png_row_infop row_info, png_bytep row)
Guy Schalnat0d580581995-07-20 02:43:20 -0500143{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500144 png_debug(1, "in png_do_invert\n");
145 if (row_info->bit_depth == 1 &&
146#if defined(PNG_USELESS_TESTS_SUPPORTED)
147 row != NULL && row_info != NULL &&
148#endif
149 row_info->color_type == PNG_COLOR_TYPE_GRAY)
Guy Schalnat0d580581995-07-20 02:43:20 -0500150 {
Guy Schalnat6d764711995-12-19 03:22:19 -0600151 png_bytep rp;
Guy Schalnat0d580581995-07-20 02:43:20 -0500152 png_uint_32 i;
153
Andreas Dilger47a0c421997-05-16 02:46:07 -0500154 for (i = 0, rp = row; i < row_info->rowbytes; i++, rp++)
Guy Schalnat0d580581995-07-20 02:43:20 -0500155 {
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600156 *rp = (png_byte)(~(*rp));
Guy Schalnat0d580581995-07-20 02:43:20 -0500157 }
158 }
159}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500160#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500161
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500162#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
Guy Schalnat0d580581995-07-20 02:43:20 -0500163/* swaps byte order on 16 bit depth images */
164void
Guy Schalnat6d764711995-12-19 03:22:19 -0600165png_do_swap(png_row_infop row_info, png_bytep row)
Guy Schalnat0d580581995-07-20 02:43:20 -0500166{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500167 png_debug(1, "in png_do_swap\n");
168 if (
169#if defined(PNG_USELESS_TESTS_SUPPORTED)
170 row != NULL && row_info != NULL &&
171#endif
172 row_info->bit_depth == 16)
Guy Schalnat0d580581995-07-20 02:43:20 -0500173 {
Guy Schalnat6d764711995-12-19 03:22:19 -0600174 png_bytep rp;
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500175 png_byte t;
Guy Schalnat0d580581995-07-20 02:43:20 -0500176 png_uint_32 i;
177
178 for (i = 0, rp = row;
179 i < row_info->width * row_info->channels;
180 i++, rp += 2)
181 {
182 t = *rp;
183 *rp = *(rp + 1);
184 *(rp + 1) = t;
185 }
186 }
187}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500188#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500189
Andreas Dilger47a0c421997-05-16 02:46:07 -0500190#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
191static png_byte onebppswaptable[256] = {
192 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
193 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
194 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
195 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
196 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
197 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
198 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
199 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
200 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
201 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
202 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
203 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
204 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
205 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
206 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
207 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
208 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
209 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
210 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
211 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
212 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
213 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
214 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
215 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
216 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
217 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
218 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
219 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
220 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
221 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
222 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
223 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
224};
225
226static png_byte twobppswaptable[256] = {
227 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
228 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
229 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
230 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
231 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
232 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
233 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
234 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
235 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
236 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
237 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
238 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
239 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
240 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
241 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
242 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
243 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
244 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
245 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
246 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
247 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
248 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
249 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
250 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
251 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
252 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
253 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
254 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
255 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
256 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
257 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
258 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
259};
260
261static png_byte fourbppswaptable[256] = {
262 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
263 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
264 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
265 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
266 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
267 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
268 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
269 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
270 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
271 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
272 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
273 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
274 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
275 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
276 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
277 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
278 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
279 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
280 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
281 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
282 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
283 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
284 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
285 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
286 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
287 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
288 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
289 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
290 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
291 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
292 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
293 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
294};
295
296/* swaps pixel packing order within bytes */
Guy Schalnat0d580581995-07-20 02:43:20 -0500297void
Andreas Dilger47a0c421997-05-16 02:46:07 -0500298png_do_packswap(png_row_infop row_info, png_bytep row)
Guy Schalnat0d580581995-07-20 02:43:20 -0500299{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500300 png_debug(1, "in png_do_packswap\n");
301 if (
302#if defined(PNG_USELESS_TESTS_SUPPORTED)
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600303 row != NULL && row_info != NULL &&
Andreas Dilger47a0c421997-05-16 02:46:07 -0500304#endif
305 row_info->bit_depth < 8)
Guy Schalnat0d580581995-07-20 02:43:20 -0500306 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500307 png_bytep rp, end, table;
Guy Schalnat0d580581995-07-20 02:43:20 -0500308
Andreas Dilger47a0c421997-05-16 02:46:07 -0500309 end = row + row_info->rowbytes;
310
311 if (row_info->bit_depth == 1)
312 table = onebppswaptable;
313 else if (row_info->bit_depth == 2)
314 table = twobppswaptable;
315 else if (row_info->bit_depth == 4)
316 table = fourbppswaptable;
317 else
318 return;
319
320 for (rp = row; rp < end; rp++)
321 *rp = table[*rp];
322 }
323}
324#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
325
326#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
327 defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
328/* remove filler or alpha byte(s) */
329void
330png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
331{
332 png_debug(1, "in png_do_strip_filler\n");
333#if defined(PNG_USELESS_TESTS_SUPPORTED)
334 if (row != NULL && row_info != NULL)
335#endif
336 {
337/*
338 if (row_info->color_type == PNG_COLOR_TYPE_RGB ||
339 row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
340*/
341 if (row_info->channels == 4)
342 {
343 if (row_info->bit_depth == 8)
Guy Schalnat0d580581995-07-20 02:43:20 -0500344 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500345 /* This converts from RGBX or RGBA to RGB */
346 if (flags & PNG_FLAG_FILLER_AFTER)
347 {
348 png_bytep sp, dp;
349 png_uint_32 i;
350
351 for (i = 1, sp = row + 4, dp = row + 3; i < row_info->width; i++)
352 {
353 *dp++ = *sp++;
354 *dp++ = *sp++;
355 *dp++ = *sp++;
356 sp++;
357 }
358 }
359 /* This converts from XRGB or ARGB to RGB */
360 else
361 {
362 png_bytep sp, dp;
363 png_uint_32 i;
364
365 for (i = 0, sp = row, dp = row; i < row_info->width; i++)
366 {
367 sp++;
368 *dp++ = *sp++;
369 *dp++ = *sp++;
370 *dp++ = *sp++;
371 }
372 }
373 row_info->pixel_depth = 24;
374 row_info->rowbytes = row_info->width * 3;
Guy Schalnat0d580581995-07-20 02:43:20 -0500375 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500376 else /* if (row_info->bit_depth == 16) */
377 {
378 if (flags & PNG_FLAG_FILLER_AFTER)
379 {
380 png_bytep sp, dp;
381 png_uint_32 i;
382
383 /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
384 for (i = 1, sp = row + 8, dp = row + 6; i < row_info->width; i++)
385 {
386 /* This could be (although memcpy is probably slower):
387 png_memcpy(dp, sp, 6);
388 sp += 8;
389 dp += 6;
390 */
391 *dp++ = *sp++;
392 *dp++ = *sp++;
393 *dp++ = *sp++;
394 *dp++ = *sp++;
395 *dp++ = *sp++;
396 *dp++ = *sp++;
397 sp += 2;
398 }
399 }
400 else
401 {
402 png_bytep sp, dp;
403 png_uint_32 i;
404
405 /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
406 for (i = 0, sp = row + 2, dp = row; i < row_info->width; i++)
407 {
408 /* This could be (although memcpy is probably slower):
409 png_memcpy(dp, sp, 6);
410 sp += 8;
411 dp += 6;
412 */
413 *dp++ = *sp++;
414 *dp++ = *sp++;
415 *dp++ = *sp++;
416 *dp++ = *sp++;
417 *dp++ = *sp++;
418 *dp++ = *sp++;
419 }
420 }
421 row_info->pixel_depth = 48;
422 row_info->rowbytes = row_info->width * 6;
423 }
424 row_info->channels = 3;
Guy Schalnat0d580581995-07-20 02:43:20 -0500425 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500426/*
427 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY ||
428 row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
429*/
430 else if (row_info->channels == 2)
Guy Schalnat0d580581995-07-20 02:43:20 -0500431 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500432 if (row_info->bit_depth == 8)
Guy Schalnat0d580581995-07-20 02:43:20 -0500433 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500434 /* This converts from GX or GA to G */
435 if (flags & PNG_FLAG_FILLER_AFTER)
436 {
437 png_bytep sp, dp;
438 png_uint_32 i;
Guy Schalnat0d580581995-07-20 02:43:20 -0500439
Andreas Dilger47a0c421997-05-16 02:46:07 -0500440 for (i = 1, sp = row + 2, dp = row + 1; i < row_info->width; i++)
441 {
442 *dp++ = *sp++;
443 sp++;
444 }
445 }
446 /* This converts from XG or AG to G */
447 else
448 {
449 png_bytep sp, dp;
450 png_uint_32 i;
Guy Schalnat0d580581995-07-20 02:43:20 -0500451
Andreas Dilger47a0c421997-05-16 02:46:07 -0500452 for (i = 0, sp = row, dp = row; i < row_info->width; i++)
453 {
454 sp++;
455 *dp++ = *sp++;
456 }
457 }
458 row_info->pixel_depth = 8;
459 row_info->rowbytes = row_info->width;
Guy Schalnat0d580581995-07-20 02:43:20 -0500460 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500461 else /* if (row_info->bit_depth == 16) */
462 {
463 if (flags & PNG_FLAG_FILLER_AFTER)
464 {
465 png_bytep sp, dp;
466 png_uint_32 i;
467
468 /* This converts from GGXX or GGAA to GG */
469 for (i = 1, sp = row + 4, dp = row + 2; i < row_info->width; i++)
470 {
471 *dp++ = *sp++;
472 *dp++ = *sp++;
473 sp += 2;
474 }
475 }
476 else
477 {
478 png_bytep sp, dp;
479 png_uint_32 i;
480
481 /* This converts from XXGG or AAGG to GG */
482 for (i = 0, sp = row, dp = row; i < row_info->width; i++)
483 {
484 sp += 2;
485 *dp++ = *sp++;
486 *dp++ = *sp++;
487 }
488 }
489 row_info->pixel_depth = 16;
490 row_info->rowbytes = row_info->width * 2;
491 }
492 row_info->channels = 1;
Guy Schalnat0d580581995-07-20 02:43:20 -0500493 }
494 }
495}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500496#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500497
Andreas Dilger47a0c421997-05-16 02:46:07 -0500498#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
499/* swaps red and blue bytes within a pixel */
500void
501png_do_bgr(png_row_infop row_info, png_bytep row)
502{
503 png_debug(1, "in png_do_bgr\n");
504 if (
505#if defined(PNG_USELESS_TESTS_SUPPORTED)
506 row != NULL && row_info != NULL &&
507#endif
508 (row_info->color_type & PNG_COLOR_MASK_COLOR))
509 {
510 if (row_info->bit_depth == 8)
511 {
512 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
513 {
514 png_bytep rp;
515 png_byte save;
516 png_uint_32 i;
517
518 for (i = 0, rp = row; i < row_info->width; i++, rp += 3)
519 {
520 save = *rp;
521 *rp = *(rp + 2);
522 *(rp + 2) = save;
523 }
524 }
525 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
526 {
527 png_bytep rp;
528 png_byte save;
529 png_uint_32 i;
530
531 for (i = 0, rp = row; i < row_info->width; i++, rp += 4)
532 {
533 save = *rp;
534 *rp = *(rp + 2);
535 *(rp + 2) = save;
536 }
537 }
538 }
539 else if (row_info->bit_depth == 16)
540 {
541 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
542 {
543 png_bytep rp;
544 png_byte save[2];
545 png_uint_32 i;
546
547 for (i = 0, rp = row; i < row_info->width; i++, rp += 6)
548 {
549 save[0] = *rp;
550 save[1] = *(rp + 1);
551 *rp = *(rp + 4);
552 *(rp + 1) = *(rp + 5);
553 *(rp + 4) = save[0];
554 *(rp + 5) = save[1];
555 }
556 }
557 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
558 {
559 png_bytep rp;
560 png_byte save[2];
561 png_uint_32 i;
562
563 for (i = 0, rp = row; i < row_info->width; i++, rp += 8)
564 {
565 save[0] = *rp;
566 save[1] = *(rp + 1);
567 *rp = *(rp + 4);
568 *(rp + 1) = *(rp + 5);
569 *(rp + 4) = save[0];
570 *(rp + 5) = save[1];
571 }
572 }
573 }
574 }
575}
576#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
577