2
/* pngwtran.c - transforms the data in a row for PNG writers
4
* libpng version 1.2.7 - September 12, 2004
5
* For conditions of distribution and use, see copyright notice in png.h
6
* Copyright (c) 1998-2004 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.)
13
#ifdef PNG_WRITE_SUPPORTED
15
/* Transform the data according to the user's wishes. The order of
16
* transformations is significant.
19
png_do_write_transformations(png_structp png_ptr)
21
png_debug(1, "in png_do_write_transformations\n");
26
#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
27
if (png_ptr->transformations & PNG_USER_TRANSFORM)
28
if(png_ptr->write_user_transform_fn != NULL)
29
(*(png_ptr->write_user_transform_fn)) /* user write transform function */
30
(png_ptr, /* png_ptr */
31
&(png_ptr->row_info), /* row_info: */
32
/* png_uint_32 width; width of row */
33
/* png_uint_32 rowbytes; number of bytes in row */
34
/* png_byte color_type; color type of pixels */
35
/* png_byte bit_depth; bit depth of samples */
36
/* png_byte channels; number of channels (1-4) */
37
/* png_byte pixel_depth; bits per pixel (depth*channels) */
38
png_ptr->row_buf + 1); /* start of pixel data for row */
40
#if defined(PNG_WRITE_FILLER_SUPPORTED)
41
if (png_ptr->transformations & PNG_FILLER)
42
png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
45
#if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
46
if (png_ptr->transformations & PNG_PACKSWAP)
47
png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
49
#if defined(PNG_WRITE_PACK_SUPPORTED)
50
if (png_ptr->transformations & PNG_PACK)
51
png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
52
(png_uint_32)png_ptr->bit_depth);
54
#if defined(PNG_WRITE_SWAP_SUPPORTED)
55
if (png_ptr->transformations & PNG_SWAP_BYTES)
56
png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
58
#if defined(PNG_WRITE_SHIFT_SUPPORTED)
59
if (png_ptr->transformations & PNG_SHIFT)
60
png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
63
#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
64
if (png_ptr->transformations & PNG_INVERT_ALPHA)
65
png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
67
#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
68
if (png_ptr->transformations & PNG_SWAP_ALPHA)
69
png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
71
#if defined(PNG_WRITE_BGR_SUPPORTED)
72
if (png_ptr->transformations & PNG_BGR)
73
png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
75
#if defined(PNG_WRITE_INVERT_SUPPORTED)
76
if (png_ptr->transformations & PNG_INVERT_MONO)
77
png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
81
#if defined(PNG_WRITE_PACK_SUPPORTED)
82
/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
83
* row_info bit depth should be 8 (one pixel per byte). The channels
84
* should be 1 (this only happens on grayscale and paletted images).
87
png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
89
png_debug(1, "in png_do_pack\n");
90
if (row_info->bit_depth == 8 &&
91
#if defined(PNG_USELESS_TESTS_SUPPORTED)
92
row != NULL && row_info != NULL &&
94
row_info->channels == 1)
96
switch ((int)bit_depth)
103
png_uint_32 row_width = row_info->width;
110
for (i = 0; i < row_width; i++)
134
png_uint_32 row_width = row_info->width;
140
for (i = 0; i < row_width; i++)
144
value = (png_byte)(*sp & 0x03);
145
v |= (value << shift);
166
png_uint_32 row_width = row_info->width;
172
for (i = 0; i < row_width; i++)
176
value = (png_byte)(*sp & 0x0f);
177
v |= (value << shift);
196
row_info->bit_depth = (png_byte)bit_depth;
197
row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
198
row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
204
#if defined(PNG_WRITE_SHIFT_SUPPORTED)
205
/* Shift pixel values to take advantage of whole range. Pass the
206
* true number of bits in bit_depth. The row should be packed
207
* according to row_info->bit_depth. Thus, if you had a row of
208
* bit depth 4, but the pixels only had values from 0 to 7, you
209
* would pass 3 as bit_depth, and this routine would translate the
213
png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
215
png_debug(1, "in png_do_shift\n");
216
#if defined(PNG_USELESS_TESTS_SUPPORTED)
217
if (row != NULL && row_info != NULL &&
221
row_info->color_type != PNG_COLOR_TYPE_PALETTE)
223
int shift_start[4], shift_dec[4];
226
if (row_info->color_type & PNG_COLOR_MASK_COLOR)
228
shift_start[channels] = row_info->bit_depth - bit_depth->red;
229
shift_dec[channels] = bit_depth->red;
231
shift_start[channels] = row_info->bit_depth - bit_depth->green;
232
shift_dec[channels] = bit_depth->green;
234
shift_start[channels] = row_info->bit_depth - bit_depth->blue;
235
shift_dec[channels] = bit_depth->blue;
240
shift_start[channels] = row_info->bit_depth - bit_depth->gray;
241
shift_dec[channels] = bit_depth->gray;
244
if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
246
shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
247
shift_dec[channels] = bit_depth->alpha;
251
/* with low row depths, could only be grayscale, so one channel */
252
if (row_info->bit_depth < 8)
257
png_uint_32 row_bytes = row_info->rowbytes;
259
if (bit_depth->gray == 1 && row_info->bit_depth == 2)
261
else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
266
for (i = 0; i < row_bytes; i++, bp++)
273
for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
276
*bp |= (png_byte)((v << j) & 0xff);
278
*bp |= (png_byte)((v >> (-j)) & mask);
282
else if (row_info->bit_depth == 8)
286
png_uint_32 istop = channels * row_info->width;
288
for (i = 0; i < istop; i++, bp++)
293
int c = (int)(i%channels);
297
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
300
*bp |= (png_byte)((v << j) & 0xff);
302
*bp |= (png_byte)((v >> (-j)) & 0xff);
310
png_uint_32 istop = channels * row_info->width;
312
for (bp = row, i = 0; i < istop; i++)
314
int c = (int)(i%channels);
315
png_uint_16 value, v;
318
v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
320
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
323
value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
325
value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
327
*bp++ = (png_byte)(value >> 8);
328
*bp++ = (png_byte)(value & 0xff);
335
#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
337
png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
339
png_debug(1, "in png_do_write_swap_alpha\n");
340
#if defined(PNG_USELESS_TESTS_SUPPORTED)
341
if (row != NULL && row_info != NULL)
344
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
346
/* This converts from ARGB to RGBA */
347
if (row_info->bit_depth == 8)
351
png_uint_32 row_width = row_info->width;
352
for (i = 0, sp = dp = row; i < row_width; i++)
354
png_byte save = *(sp++);
361
/* This converts from AARRGGBB to RRGGBBAA */
366
png_uint_32 row_width = row_info->width;
368
for (i = 0, sp = dp = row; i < row_width; i++)
384
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
386
/* This converts from AG to GA */
387
if (row_info->bit_depth == 8)
391
png_uint_32 row_width = row_info->width;
393
for (i = 0, sp = dp = row; i < row_width; i++)
395
png_byte save = *(sp++);
400
/* This converts from AAGG to GGAA */
405
png_uint_32 row_width = row_info->width;
407
for (i = 0, sp = dp = row; i < row_width; i++)
423
#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
425
png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
427
png_debug(1, "in png_do_write_invert_alpha\n");
428
#if defined(PNG_USELESS_TESTS_SUPPORTED)
429
if (row != NULL && row_info != NULL)
432
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
434
/* This inverts the alpha channel in RGBA */
435
if (row_info->bit_depth == 8)
439
png_uint_32 row_width = row_info->width;
440
for (i = 0, sp = dp = row; i < row_width; i++)
445
*(dp++) = (png_byte)(255 - *(sp++));
448
/* This inverts the alpha channel in RRGGBBAA */
453
png_uint_32 row_width = row_info->width;
455
for (i = 0, sp = dp = row; i < row_width; i++)
463
*(dp++) = (png_byte)(255 - *(sp++));
464
*(dp++) = (png_byte)(255 - *(sp++));
468
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
470
/* This inverts the alpha channel in GA */
471
if (row_info->bit_depth == 8)
475
png_uint_32 row_width = row_info->width;
477
for (i = 0, sp = dp = row; i < row_width; i++)
480
*(dp++) = (png_byte)(255 - *(sp++));
483
/* This inverts the alpha channel in GGAA */
488
png_uint_32 row_width = row_info->width;
490
for (i = 0, sp = dp = row; i < row_width; i++)
494
*(dp++) = (png_byte)(255 - *(sp++));
495
*(dp++) = (png_byte)(255 - *(sp++));
503
#if defined(PNG_MNG_FEATURES_SUPPORTED)
504
/* undoes intrapixel differencing */
506
png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
508
png_debug(1, "in png_do_write_intrapixel\n");
510
#if defined(PNG_USELESS_TESTS_SUPPORTED)
511
row != NULL && row_info != NULL &&
513
(row_info->color_type & PNG_COLOR_MASK_COLOR))
516
png_uint_32 row_width = row_info->width;
517
if (row_info->bit_depth == 8)
522
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
524
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
529
for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
531
*(rp) = (png_byte)((*rp - *(rp+1))&0xff);
532
*(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff);
535
else if (row_info->bit_depth == 16)
540
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
542
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
547
for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
549
png_uint_32 s0 = (*(rp ) << 8) | *(rp+1);
550
png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3);
551
png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5);
552
png_uint_32 red = (png_uint_32)((s0-s1) & 0xffffL);
553
png_uint_32 blue = (png_uint_32)((s2-s1) & 0xffffL);
554
*(rp ) = (png_byte)((red >> 8) & 0xff);
555
*(rp+1) = (png_byte)(red & 0xff);
556
*(rp+4) = (png_byte)((blue >> 8) & 0xff);
557
*(rp+5) = (png_byte)(blue & 0xff);
562
#endif /* PNG_MNG_FEATURES_SUPPORTED */
563
#endif /* PNG_WRITE_SUPPORTED */