2
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
4
* libpng 1.2.5 - October 3, 2002
5
* For conditions of distribution and use, see copyright notice in png.h
6
* Copyright (c) 1998-2002 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
/* This test removed from libpng version 1.0.13 and 1.2.0:
157
* if (row_info->bit_depth == 1 &&
159
#if defined(PNG_USELESS_TESTS_SUPPORTED)
160
if (row == NULL || row_info == NULL)
163
if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
167
png_uint_32 istop = row_info->rowbytes;
169
for (i = 0; i < istop; i++)
171
*rp = (png_byte)(~(*rp));
175
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
176
row_info->bit_depth == 8)
180
png_uint_32 istop = row_info->rowbytes;
182
for (i = 0; i < istop; i+=2)
184
*rp = (png_byte)(~(*rp));
188
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
189
row_info->bit_depth == 16)
193
png_uint_32 istop = row_info->rowbytes;
195
for (i = 0; i < istop; i+=4)
197
*rp = (png_byte)(~(*rp));
198
*(rp+1) = (png_byte)(~(*(rp+1)));
205
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
206
/* swaps byte order on 16 bit depth images */
208
png_do_swap(png_row_infop row_info, png_bytep row)
210
png_debug(1, "in png_do_swap\n");
212
#if defined(PNG_USELESS_TESTS_SUPPORTED)
213
row != NULL && row_info != NULL &&
215
row_info->bit_depth == 16)
219
png_uint_32 istop= row_info->width * row_info->channels;
221
for (i = 0; i < istop; i++, rp += 2)
231
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
232
static png_byte onebppswaptable[256] = {
233
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
234
0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
235
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
236
0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
237
0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
238
0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
239
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
240
0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
241
0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
242
0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
243
0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
244
0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
245
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
246
0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
247
0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
248
0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
249
0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
250
0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
251
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
252
0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
253
0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
254
0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
255
0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
256
0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
257
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
258
0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
259
0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
260
0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
261
0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
262
0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
263
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
264
0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
267
static png_byte twobppswaptable[256] = {
268
0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
269
0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
270
0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
271
0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
272
0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
273
0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
274
0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
275
0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
276
0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
277
0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
278
0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
279
0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
280
0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
281
0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
282
0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
283
0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
284
0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
285
0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
286
0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
287
0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
288
0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
289
0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
290
0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
291
0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
292
0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
293
0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
294
0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
295
0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
296
0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
297
0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
298
0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
299
0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
302
static png_byte fourbppswaptable[256] = {
303
0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
304
0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
305
0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
306
0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
307
0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
308
0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
309
0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
310
0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
311
0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
312
0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
313
0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
314
0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
315
0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
316
0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
317
0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
318
0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
319
0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
320
0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
321
0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
322
0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
323
0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
324
0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
325
0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
326
0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
327
0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
328
0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
329
0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
330
0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
331
0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
332
0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
333
0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
334
0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
337
/* swaps pixel packing order within bytes */
339
png_do_packswap(png_row_infop row_info, png_bytep row)
341
png_debug(1, "in png_do_packswap\n");
343
#if defined(PNG_USELESS_TESTS_SUPPORTED)
344
row != NULL && row_info != NULL &&
346
row_info->bit_depth < 8)
348
png_bytep rp, end, table;
350
end = row + row_info->rowbytes;
352
if (row_info->bit_depth == 1)
353
table = onebppswaptable;
354
else if (row_info->bit_depth == 2)
355
table = twobppswaptable;
356
else if (row_info->bit_depth == 4)
357
table = fourbppswaptable;
361
for (rp = row; rp < end; rp++)
365
#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
367
#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
368
defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
369
/* remove filler or alpha byte(s) */
371
png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
373
png_debug(1, "in png_do_strip_filler\n");
374
#if defined(PNG_USELESS_TESTS_SUPPORTED)
375
if (row != NULL && row_info != NULL)
379
if (row_info->color_type == PNG_COLOR_TYPE_RGB ||
380
row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
384
png_uint_32 row_width=row_info->width;
387
if (row_info->channels == 4)
389
if (row_info->bit_depth == 8)
391
/* This converts from RGBX or RGBA to RGB */
392
if (flags & PNG_FLAG_FILLER_AFTER)
395
for (i = 1; i < row_width; i++)
403
/* This converts from XRGB or ARGB to RGB */
406
for (i = 0; i < row_width; i++)
414
row_info->pixel_depth = 24;
415
row_info->rowbytes = row_width * 3;
417
else /* if (row_info->bit_depth == 16) */
419
if (flags & PNG_FLAG_FILLER_AFTER)
421
/* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
423
for (i = 1; i < row_width; i++)
425
/* This could be (although png_memcpy is probably slower):
426
png_memcpy(dp, sp, 6);
442
/* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
443
for (i = 0; i < row_width; i++)
445
/* This could be (although png_memcpy is probably slower):
446
png_memcpy(dp, sp, 6);
460
row_info->pixel_depth = 48;
461
row_info->rowbytes = row_width * 6;
463
row_info->channels = 3;
464
row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
467
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY ||
468
row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
470
else if (row_info->channels == 2)
472
if (row_info->bit_depth == 8)
474
/* This converts from GX or GA to G */
475
if (flags & PNG_FLAG_FILLER_AFTER)
477
for (i = 0; i < row_width; i++)
483
/* This converts from XG or AG to G */
486
for (i = 0; i < row_width; i++)
492
row_info->pixel_depth = 8;
493
row_info->rowbytes = row_width;
495
else /* if (row_info->bit_depth == 16) */
497
if (flags & PNG_FLAG_FILLER_AFTER)
499
/* This converts from GGXX or GGAA to GG */
501
for (i = 1; i < row_width; i++)
510
/* This converts from XXGG or AAGG to GG */
511
for (i = 0; i < row_width; i++)
518
row_info->pixel_depth = 16;
519
row_info->rowbytes = row_width * 2;
521
row_info->channels = 1;
522
row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
528
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
529
/* swaps red and blue bytes within a pixel */
531
png_do_bgr(png_row_infop row_info, png_bytep row)
533
png_debug(1, "in png_do_bgr\n");
535
#if defined(PNG_USELESS_TESTS_SUPPORTED)
536
row != NULL && row_info != NULL &&
538
(row_info->color_type & PNG_COLOR_MASK_COLOR))
540
png_uint_32 row_width = row_info->width;
541
if (row_info->bit_depth == 8)
543
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
548
for (i = 0, rp = row; i < row_width; i++, rp += 3)
555
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
560
for (i = 0, rp = row; i < row_width; i++, rp += 4)
568
else if (row_info->bit_depth == 16)
570
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
575
for (i = 0, rp = row; i < row_width; i++, rp += 6)
581
*(rp + 1) = *(rp + 5);
585
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
590
for (i = 0, rp = row; i < row_width; i++, rp += 8)
596
*(rp + 1) = *(rp + 5);
603
#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
605
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
606
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
607
defined(PNG_LEGACY_SUPPORTED)
609
png_set_user_transform_info(png_structp png_ptr, png_voidp
610
user_transform_ptr, int user_transform_depth, int user_transform_channels)
612
png_debug(1, "in png_set_user_transform_info\n");
613
#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
614
png_ptr->user_transform_ptr = user_transform_ptr;
615
png_ptr->user_transform_depth = (png_byte)user_transform_depth;
616
png_ptr->user_transform_channels = (png_byte)user_transform_channels;
618
if(user_transform_ptr || user_transform_depth || user_transform_channels)
620
"This version of libpng does not support user transform info");
625
/* This function returns a pointer to the user_transform_ptr associated with
626
* the user transform functions. The application should free any memory
627
* associated with this pointer before png_write_destroy and png_read_destroy
631
png_get_user_transform_ptr(png_structp png_ptr)
633
#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
634
return ((png_voidp)png_ptr->user_transform_ptr);