2
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
4
* libpng 1.0.8 - July 24, 2000
5
* For conditions of distribution and use, see copyright notice in png.h
6
* Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson
7
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
14
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
15
/* turn on BGR-to-RGB mapping */
17
png_set_bgr(png_structp png_ptr)
19
png_debug(1, "in png_set_bgr\n");
20
png_ptr->transformations |= PNG_BGR;
24
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
25
/* turn on 16 bit byte swapping */
27
png_set_swap(png_structp png_ptr)
29
png_debug(1, "in png_set_swap\n");
30
if (png_ptr->bit_depth == 16)
31
png_ptr->transformations |= PNG_SWAP_BYTES;
35
#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
36
/* turn on pixel packing */
38
png_set_packing(png_structp png_ptr)
40
png_debug(1, "in png_set_packing\n");
41
if (png_ptr->bit_depth < 8)
43
png_ptr->transformations |= PNG_PACK;
44
png_ptr->usr_bit_depth = 8;
49
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
50
/* turn on packed pixel swapping */
52
png_set_packswap(png_structp png_ptr)
54
png_debug(1, "in png_set_packswap\n");
55
if (png_ptr->bit_depth < 8)
56
png_ptr->transformations |= PNG_PACKSWAP;
60
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
62
png_set_shift(png_structp png_ptr, png_color_8p true_bits)
64
png_debug(1, "in png_set_shift\n");
65
png_ptr->transformations |= PNG_SHIFT;
66
png_ptr->shift = *true_bits;
70
#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
71
defined(PNG_WRITE_INTERLACING_SUPPORTED)
73
png_set_interlace_handling(png_structp png_ptr)
75
png_debug(1, "in png_set_interlace handling\n");
76
if (png_ptr->interlaced)
78
png_ptr->transformations |= PNG_INTERLACE;
86
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
87
/* Add a filler byte on read, or remove a filler or alpha byte on write.
88
* The filler type has changed in v0.95 to allow future 2-byte fillers
89
* for 48-bit input data, as well as to avoid problems with some compilers
90
* that don't like bytes as parameters.
93
png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
95
png_debug(1, "in png_set_filler\n");
96
png_ptr->transformations |= PNG_FILLER;
97
png_ptr->filler = (png_byte)filler;
98
if (filler_loc == PNG_FILLER_AFTER)
99
png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
101
png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
103
/* This should probably go in the "do_filler" routine.
104
* I attempted to do that in libpng-1.0.1a but that caused problems
105
* so I restored it in libpng-1.0.2a
108
if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
110
png_ptr->usr_channels = 4;
113
/* Also I added this in libpng-1.0.2a (what happens when we expand
114
* a less-than-8-bit grayscale to GA? */
116
if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
118
png_ptr->usr_channels = 2;
123
#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
124
defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
126
png_set_swap_alpha(png_structp png_ptr)
128
png_debug(1, "in png_set_swap_alpha\n");
129
png_ptr->transformations |= PNG_SWAP_ALPHA;
133
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
134
defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
136
png_set_invert_alpha(png_structp png_ptr)
138
png_debug(1, "in png_set_invert_alpha\n");
139
png_ptr->transformations |= PNG_INVERT_ALPHA;
143
#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
145
png_set_invert_mono(png_structp png_ptr)
147
png_debug(1, "in png_set_invert_mono\n");
148
png_ptr->transformations |= PNG_INVERT_MONO;
151
/* invert monochrome grayscale data */
153
png_do_invert(png_row_infop row_info, png_bytep row)
155
png_debug(1, "in png_do_invert\n");
156
if (row_info->bit_depth == 1 &&
157
#if defined(PNG_USELESS_TESTS_SUPPORTED)
158
row != NULL && row_info != NULL &&
160
row_info->color_type == PNG_COLOR_TYPE_GRAY)
164
png_uint_32 istop = row_info->rowbytes;
166
for (i = 0; i < istop; i++)
168
*rp = (png_byte)(~(*rp));
175
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
176
/* swaps byte order on 16 bit depth images */
178
png_do_swap(png_row_infop row_info, png_bytep row)
180
png_debug(1, "in png_do_swap\n");
182
#if defined(PNG_USELESS_TESTS_SUPPORTED)
183
row != NULL && row_info != NULL &&
185
row_info->bit_depth == 16)
189
png_uint_32 istop= row_info->width * row_info->channels;
191
for (i = 0; i < istop; i++, rp += 2)
201
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
202
static png_byte onebppswaptable[256] = {
203
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
204
0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
205
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
206
0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
207
0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
208
0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
209
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
210
0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
211
0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
212
0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
213
0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
214
0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
215
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
216
0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
217
0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
218
0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
219
0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
220
0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
221
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
222
0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
223
0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
224
0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
225
0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
226
0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
227
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
228
0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
229
0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
230
0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
231
0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
232
0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
233
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
234
0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
237
static png_byte twobppswaptable[256] = {
238
0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
239
0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
240
0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
241
0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
242
0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
243
0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
244
0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
245
0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
246
0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
247
0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
248
0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
249
0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
250
0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
251
0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
252
0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
253
0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
254
0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
255
0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
256
0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
257
0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
258
0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
259
0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
260
0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
261
0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
262
0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
263
0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
264
0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
265
0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
266
0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
267
0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
268
0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
269
0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
272
static png_byte fourbppswaptable[256] = {
273
0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
274
0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
275
0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
276
0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
277
0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
278
0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
279
0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
280
0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
281
0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
282
0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
283
0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
284
0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
285
0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
286
0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
287
0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
288
0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
289
0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
290
0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
291
0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
292
0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
293
0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
294
0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
295
0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
296
0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
297
0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
298
0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
299
0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
300
0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
301
0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
302
0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
303
0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
304
0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
307
/* swaps pixel packing order within bytes */
309
png_do_packswap(png_row_infop row_info, png_bytep row)
311
png_debug(1, "in png_do_packswap\n");
313
#if defined(PNG_USELESS_TESTS_SUPPORTED)
314
row != NULL && row_info != NULL &&
316
row_info->bit_depth < 8)
318
png_bytep rp, end, table;
320
end = row + row_info->rowbytes;
322
if (row_info->bit_depth == 1)
323
table = onebppswaptable;
324
else if (row_info->bit_depth == 2)
325
table = twobppswaptable;
326
else if (row_info->bit_depth == 4)
327
table = fourbppswaptable;
331
for (rp = row; rp < end; rp++)
335
#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
337
#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
338
defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
339
/* remove filler or alpha byte(s) */
341
png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
343
png_debug(1, "in png_do_strip_filler\n");
344
#if defined(PNG_USELESS_TESTS_SUPPORTED)
345
if (row != NULL && row_info != NULL)
349
if (row_info->color_type == PNG_COLOR_TYPE_RGB ||
350
row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
354
png_uint_32 row_width=row_info->width;
357
if (row_info->channels == 4)
359
if (row_info->bit_depth == 8)
361
/* This converts from RGBX or RGBA to RGB */
362
if (flags & PNG_FLAG_FILLER_AFTER)
365
for (i = 1; i < row_width; i++)
373
/* This converts from XRGB or ARGB to RGB */
376
for (i = 0; i < row_width; i++)
384
row_info->pixel_depth = 24;
385
row_info->rowbytes = row_width * 3;
387
else /* if (row_info->bit_depth == 16) */
389
if (flags & PNG_FLAG_FILLER_AFTER)
391
/* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
393
for (i = 1; i < row_width; i++)
395
/* This could be (although memcpy is probably slower):
396
png_memcpy(dp, sp, 6);
411
/* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
412
for (i = 0; i < row_width; i++)
414
/* This could be (although memcpy is probably slower):
415
png_memcpy(dp, sp, 6);
428
row_info->pixel_depth = 48;
429
row_info->rowbytes = row_width * 6;
431
row_info->channels = 3;
432
row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
435
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY ||
436
row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
438
else if (row_info->channels == 2)
440
if (row_info->bit_depth == 8)
442
/* This converts from GX or GA to G */
443
if (flags & PNG_FLAG_FILLER_AFTER)
445
for (i = 0; i < row_width; i++)
451
/* This converts from XG or AG to G */
454
for (i = 0; i < row_width; i++)
460
row_info->pixel_depth = 8;
461
row_info->rowbytes = row_width;
463
else /* if (row_info->bit_depth == 16) */
465
if (flags & PNG_FLAG_FILLER_AFTER)
467
/* This converts from GGXX or GGAA to GG */
469
for (i = 1; i < row_width; i++)
478
/* This converts from XXGG or AAGG to GG */
479
for (i = 0; i < row_width; i++)
486
row_info->pixel_depth = 16;
487
row_info->rowbytes = row_width * 2;
489
row_info->channels = 1;
490
row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
496
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
497
/* swaps red and blue bytes within a pixel */
499
png_do_bgr(png_row_infop row_info, png_bytep row)
501
png_debug(1, "in png_do_bgr\n");
503
#if defined(PNG_USELESS_TESTS_SUPPORTED)
504
row != NULL && row_info != NULL &&
506
(row_info->color_type & PNG_COLOR_MASK_COLOR))
508
png_uint_32 row_width = row_info->width;
509
if (row_info->bit_depth == 8)
511
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
516
for (i = 0, rp = row; i < row_width; i++, rp += 3)
523
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
528
for (i = 0, rp = row; i < row_width; i++, rp += 4)
536
else if (row_info->bit_depth == 16)
538
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
543
for (i = 0, rp = row; i < row_width; i++, rp += 6)
549
*(rp + 1) = *(rp + 5);
553
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
558
for (i = 0, rp = row; i < row_width; i++, rp += 8)
564
*(rp + 1) = *(rp + 5);
571
#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
573
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
574
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
575
defined(PNG_LEGACY_SUPPORTED)
577
png_set_user_transform_info(png_structp png_ptr, png_voidp
578
user_transform_ptr, int user_transform_depth, int user_transform_channels)
580
png_debug(1, "in png_set_user_transform_info\n");
581
#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
582
png_ptr->user_transform_ptr = user_transform_ptr;
583
png_ptr->user_transform_depth = (png_byte)user_transform_depth;
584
png_ptr->user_transform_channels = (png_byte)user_transform_channels;
586
if(user_transform_ptr || user_transform_depth || user_transform_channels)
588
"This version of libpng does not support user transform info");
593
/* This function returns a pointer to the user_transform_ptr associated with
594
* the user transform functions. The application should free any memory
595
* associated with this pointer before png_write_destroy and png_read_destroy
599
png_get_user_transform_ptr(png_structp png_ptr)
601
#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
602
return ((png_voidp)png_ptr->user_transform_ptr);