blob: bb0d3c23d7b6a99451d6c263b69c612debfd56a2 [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-Pehrson65a22372010-03-03 05:38:29 -06004 * Last changed in libpng 1.5.0 [March 3, 2010]
Glenn Randers-Pehrsone69b55d2010-01-01 10:29:06 -06005 * Copyright (c) 1998-2010 Glenn Randers-Pehrson
Glenn Randers-Pehrsond4366722000-06-04 14:29:29 -05006 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
Glenn Randers-Pehrson3e61d792009-06-24 09:31:28 -05008 *
Glenn Randers-Pehrsonbfbf8652009-06-26 21:46:52 -05009 * This code is released under the libpng license.
Glenn Randers-Pehrsonc332bbc2009-06-25 13:43:50 -050010 * For conditions of distribution and use, see the disclaimer
Glenn Randers-Pehrson037023b2009-06-24 10:27:36 -050011 * and license in png.h
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -060012 */
Guy Schalnat0d580581995-07-20 02:43:20 -050013
Glenn Randers-Pehrsonf9795312010-02-09 01:16:48 -060014#define PNG_EXPOSE_INTERNAL_STRUCTURES
Glenn Randers-Pehrson03f9b022009-12-04 08:40:41 -060015#define PNG_NO_PEDANTIC_WARNINGS
Guy Schalnat0d580581995-07-20 02:43:20 -050016#include "png.h"
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -050017#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -050018#include "pngpriv.h"
Guy Schalnat0d580581995-07-20 02:43:20 -050019
Guy Schalnat51f0eb41995-09-26 05:22:39 -050020#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050021/* Turn on BGR-to-RGB mapping */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050022void PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -060023png_set_bgr(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -050024{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -050025 png_debug(1, "in png_set_bgr");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -050026
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050027 if (png_ptr == NULL)
28 return;
Guy Schalnat0d580581995-07-20 02:43:20 -050029 png_ptr->transformations |= PNG_BGR;
30}
Guy Schalnat51f0eb41995-09-26 05:22:39 -050031#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050032
Guy Schalnat51f0eb41995-09-26 05:22:39 -050033#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -050034/* Turn on 16 bit byte swapping */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050035void PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -060036png_set_swap(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -050037{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -050038 png_debug(1, "in png_set_swap");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -050039
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050040 if (png_ptr == NULL)
41 return;
Guy Schalnat0d580581995-07-20 02:43:20 -050042 if (png_ptr->bit_depth == 16)
43 png_ptr->transformations |= PNG_SWAP_BYTES;
44}
Guy Schalnat51f0eb41995-09-26 05:22:39 -050045#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050046
Guy Schalnat51f0eb41995-09-26 05:22:39 -050047#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -050048/* Turn on pixel packing */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050049void PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -060050png_set_packing(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -050051{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -050052 png_debug(1, "in png_set_packing");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -050053
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050054 if (png_ptr == NULL)
55 return;
Guy Schalnat0d580581995-07-20 02:43:20 -050056 if (png_ptr->bit_depth < 8)
57 {
58 png_ptr->transformations |= PNG_PACK;
59 png_ptr->usr_bit_depth = 8;
60 }
61}
Guy Schalnat51f0eb41995-09-26 05:22:39 -050062#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050063
Andreas Dilger47a0c421997-05-16 02:46:07 -050064#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -050065/* Turn on packed pixel swapping */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050066void PNGAPI
Andreas Dilger47a0c421997-05-16 02:46:07 -050067png_set_packswap(png_structp png_ptr)
68{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -050069 png_debug(1, "in png_set_packswap");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -050070
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050071 if (png_ptr == NULL)
72 return;
Andreas Dilger47a0c421997-05-16 02:46:07 -050073 if (png_ptr->bit_depth < 8)
74 png_ptr->transformations |= PNG_PACKSWAP;
75}
76#endif
77
Guy Schalnat51f0eb41995-09-26 05:22:39 -050078#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050079void PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -060080png_set_shift(png_structp png_ptr, png_color_8p true_bits)
Guy Schalnat0d580581995-07-20 02:43:20 -050081{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -050082 png_debug(1, "in png_set_shift");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -050083
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050084 if (png_ptr == NULL)
85 return;
Guy Schalnat0d580581995-07-20 02:43:20 -050086 png_ptr->transformations |= PNG_SHIFT;
87 png_ptr->shift = *true_bits;
88}
Guy Schalnat51f0eb41995-09-26 05:22:39 -050089#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050090
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -060091#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
92 defined(PNG_WRITE_INTERLACING_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050093int PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -060094png_set_interlace_handling(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -050095{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -050096 png_debug(1, "in png_set_interlace handling");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -050097
Glenn Randers-Pehrson6b12c082006-11-14 10:53:30 -060098 if (png_ptr && png_ptr->interlaced)
Guy Schalnat0d580581995-07-20 02:43:20 -050099 {
100 png_ptr->transformations |= PNG_INTERLACE;
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600101 return (7);
Guy Schalnat0d580581995-07-20 02:43:20 -0500102 }
103
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600104 return (1);
Guy Schalnat0d580581995-07-20 02:43:20 -0500105}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500106#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500107
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500108#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500109/* Add a filler byte on read, or remove a filler or alpha byte on write.
110 * The filler type has changed in v0.95 to allow future 2-byte fillers
Glenn Randers-Pehrson8686fff1998-05-21 09:27:50 -0500111 * for 48-bit input data, as well as to avoid problems with some compilers
112 * that don't like bytes as parameters.
Andreas Dilger47a0c421997-05-16 02:46:07 -0500113 */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500114void PNGAPI
Andreas Dilger47a0c421997-05-16 02:46:07 -0500115png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
Guy Schalnat0d580581995-07-20 02:43:20 -0500116{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500117 png_debug(1, "in png_set_filler");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500118
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500119 if (png_ptr == NULL)
120 return;
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500121 png_ptr->transformations |= PNG_FILLER;
Glenn Randers-Pehrson36ac0b52009-09-15 19:12:08 -0500122 png_ptr->filler = (png_uint_16)filler;
Guy Schalnate5a37791996-06-05 15:50:50 -0500123 if (filler_loc == PNG_FILLER_AFTER)
124 png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
125 else
126 png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600127
Glenn Randers-Pehrson5b779162004-09-04 13:25:08 -0500128 /* This should probably go in the "do_read_filler" routine.
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600129 * I attempted to do that in libpng-1.0.1a but that caused problems
130 * so I restored it in libpng-1.0.2a
131 */
132
133 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
134 {
135 png_ptr->usr_channels = 4;
136 }
137
138 /* Also I added this in libpng-1.0.2a (what happens when we expand
Glenn Randers-Pehrson45624d62010-03-03 11:40:43 -0600139 * a less-than-8-bit grayscale to GA?) */
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600140
141 if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
142 {
143 png_ptr->usr_channels = 2;
144 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500145}
Glenn Randers-Pehrson67864af2004-08-28 23:30:07 -0500146
Glenn Randers-Pehrson67864af2004-08-28 23:30:07 -0500147/* Added to libpng-1.2.7 */
148void PNGAPI
149png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
150{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500151 png_debug(1, "in png_set_add_alpha");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500152
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500153 if (png_ptr == NULL)
154 return;
Glenn Randers-Pehrson67864af2004-08-28 23:30:07 -0500155 png_set_filler(png_ptr, filler, filler_loc);
156 png_ptr->transformations |= PNG_ADD_ALPHA;
157}
Glenn Randers-Pehrson67864af2004-08-28 23:30:07 -0500158
Andreas Dilger47a0c421997-05-16 02:46:07 -0500159#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500160
Andreas Dilger47a0c421997-05-16 02:46:07 -0500161#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
162 defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500163void PNGAPI
Andreas Dilger47a0c421997-05-16 02:46:07 -0500164png_set_swap_alpha(png_structp png_ptr)
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500165{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500166 png_debug(1, "in png_set_swap_alpha");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500167
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500168 if (png_ptr == NULL)
169 return;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500170 png_ptr->transformations |= PNG_SWAP_ALPHA;
Guy Schalnat0d580581995-07-20 02:43:20 -0500171}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500172#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500173
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600174#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
175 defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500176void PNGAPI
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600177png_set_invert_alpha(png_structp png_ptr)
178{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500179 png_debug(1, "in png_set_invert_alpha");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500180
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500181 if (png_ptr == NULL)
182 return;
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600183 png_ptr->transformations |= PNG_INVERT_ALPHA;
184}
185#endif
186
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500187#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500188void PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -0600189png_set_invert_mono(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -0500190{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500191 png_debug(1, "in png_set_invert_mono");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500192
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500193 if (png_ptr == NULL)
194 return;
Guy Schalnat0d580581995-07-20 02:43:20 -0500195 png_ptr->transformations |= PNG_INVERT_MONO;
196}
197
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -0500198/* Invert monochrome grayscale data */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500199void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -0600200png_do_invert(png_row_infop row_info, png_bytep row)
Guy Schalnat0d580581995-07-20 02:43:20 -0500201{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500202 png_debug(1, "in png_do_invert");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500203
Glenn Randers-Pehrson1ea0ff32001-08-07 22:25:59 -0500204 /* This test removed from libpng version 1.0.13 and 1.2.0:
205 * if (row_info->bit_depth == 1 &&
206 */
Glenn Randers-Pehrson1ea0ff32001-08-07 22:25:59 -0500207 if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
Guy Schalnat0d580581995-07-20 02:43:20 -0500208 {
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500209 png_bytep rp = row;
Guy Schalnat0d580581995-07-20 02:43:20 -0500210 png_uint_32 i;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500211 png_uint_32 istop = row_info->rowbytes;
Guy Schalnat0d580581995-07-20 02:43:20 -0500212
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500213 for (i = 0; i < istop; i++)
Guy Schalnat0d580581995-07-20 02:43:20 -0500214 {
Glenn Randers-Pehrson8686fff1998-05-21 09:27:50 -0500215 *rp = (png_byte)(~(*rp));
216 rp++;
Guy Schalnat0d580581995-07-20 02:43:20 -0500217 }
218 }
Glenn Randers-Pehrson1ea0ff32001-08-07 22:25:59 -0500219 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
220 row_info->bit_depth == 8)
221 {
222 png_bytep rp = row;
223 png_uint_32 i;
224 png_uint_32 istop = row_info->rowbytes;
225
Glenn Randers-Pehrson45624d62010-03-03 11:40:43 -0600226 for (i = 0; i < istop; i += 2)
Glenn Randers-Pehrson1ea0ff32001-08-07 22:25:59 -0500227 {
228 *rp = (png_byte)(~(*rp));
Glenn Randers-Pehrson45624d62010-03-03 11:40:43 -0600229 rp += 2;
Glenn Randers-Pehrson1ea0ff32001-08-07 22:25:59 -0500230 }
231 }
232 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
233 row_info->bit_depth == 16)
234 {
235 png_bytep rp = row;
236 png_uint_32 i;
237 png_uint_32 istop = row_info->rowbytes;
238
Glenn Randers-Pehrson45624d62010-03-03 11:40:43 -0600239 for (i = 0; i < istop; i += 4)
Glenn Randers-Pehrson1ea0ff32001-08-07 22:25:59 -0500240 {
241 *rp = (png_byte)(~(*rp));
Glenn Randers-Pehrson45624d62010-03-03 11:40:43 -0600242 *(rp + 1) = (png_byte)(~(*(rp + 1)));
243 rp += 4;
Glenn Randers-Pehrson1ea0ff32001-08-07 22:25:59 -0500244 }
245 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500246}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500247#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500248
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500249#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -0500250/* Swaps byte order on 16 bit depth images */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500251void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -0600252png_do_swap(png_row_infop row_info, png_bytep row)
Guy Schalnat0d580581995-07-20 02:43:20 -0500253{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500254 png_debug(1, "in png_do_swap");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500255
Andreas Dilger47a0c421997-05-16 02:46:07 -0500256 if (
Andreas Dilger47a0c421997-05-16 02:46:07 -0500257 row_info->bit_depth == 16)
Guy Schalnat0d580581995-07-20 02:43:20 -0500258 {
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500259 png_bytep rp = row;
Guy Schalnat0d580581995-07-20 02:43:20 -0500260 png_uint_32 i;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500261 png_uint_32 istop= row_info->width * row_info->channels;
Guy Schalnat0d580581995-07-20 02:43:20 -0500262
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500263 for (i = 0; i < istop; i++, rp += 2)
Guy Schalnat0d580581995-07-20 02:43:20 -0500264 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500265 png_byte t = *rp;
Guy Schalnat0d580581995-07-20 02:43:20 -0500266 *rp = *(rp + 1);
267 *(rp + 1) = t;
268 }
269 }
270}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500271#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500272
Andreas Dilger47a0c421997-05-16 02:46:07 -0500273#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
Glenn Randers-Pehrsonc3d51c12006-03-02 07:23:18 -0600274static PNG_CONST png_byte onebppswaptable[256] = {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500275 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
276 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
277 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
278 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
279 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
280 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
281 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
282 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
283 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
284 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
285 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
286 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
287 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
288 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
289 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
290 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
291 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
292 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
293 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
294 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
295 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
296 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
297 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
298 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
299 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
300 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
301 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
302 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
303 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
304 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
305 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
306 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
307};
308
Glenn Randers-Pehrsonc3d51c12006-03-02 07:23:18 -0600309static PNG_CONST png_byte twobppswaptable[256] = {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500310 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
311 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
312 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
313 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
314 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
315 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
316 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
317 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
318 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
319 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
320 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
321 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
322 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
323 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
324 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
325 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
326 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
327 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
328 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
329 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
330 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
331 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
332 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
333 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
334 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
335 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
336 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
337 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
338 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
339 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
340 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
341 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
342};
343
Glenn Randers-Pehrsonc3d51c12006-03-02 07:23:18 -0600344static PNG_CONST png_byte fourbppswaptable[256] = {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500345 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
346 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
347 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
348 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
349 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
350 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
351 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
352 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
353 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
354 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
355 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
356 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
357 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
358 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
359 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
360 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
361 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
362 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
363 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
364 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
365 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
366 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
367 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
368 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
369 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
370 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
371 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
372 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
373 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
374 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
375 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
376 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
377};
378
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500379/* Swaps pixel packing order within bytes */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500380void /* PRIVATE */
Andreas Dilger47a0c421997-05-16 02:46:07 -0500381png_do_packswap(png_row_infop row_info, png_bytep row)
Guy Schalnat0d580581995-07-20 02:43:20 -0500382{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500383 png_debug(1, "in png_do_packswap");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500384
Andreas Dilger47a0c421997-05-16 02:46:07 -0500385 if (
Andreas Dilger47a0c421997-05-16 02:46:07 -0500386 row_info->bit_depth < 8)
Guy Schalnat0d580581995-07-20 02:43:20 -0500387 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500388 png_bytep rp, end, table;
Guy Schalnat0d580581995-07-20 02:43:20 -0500389
Andreas Dilger47a0c421997-05-16 02:46:07 -0500390 end = row + row_info->rowbytes;
391
392 if (row_info->bit_depth == 1)
Glenn Randers-Pehrsonc3d51c12006-03-02 07:23:18 -0600393 table = (png_bytep)onebppswaptable;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500394 else if (row_info->bit_depth == 2)
Glenn Randers-Pehrsonc3d51c12006-03-02 07:23:18 -0600395 table = (png_bytep)twobppswaptable;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500396 else if (row_info->bit_depth == 4)
Glenn Randers-Pehrsonc3d51c12006-03-02 07:23:18 -0600397 table = (png_bytep)fourbppswaptable;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500398 else
399 return;
400
401 for (rp = row; rp < end; rp++)
402 *rp = table[*rp];
403 }
404}
405#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
406
407#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
408 defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500409/* Remove filler or alpha byte(s) */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500410void /* PRIVATE */
Glenn Randers-Pehrson40936072004-11-20 11:18:40 -0600411png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500412{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500413 png_debug(1, "in png_do_strip_filler");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500414
Andreas Dilger47a0c421997-05-16 02:46:07 -0500415 {
Glenn Randers-Pehrson45624d62010-03-03 11:40:43 -0600416 png_bytep sp = row;
417 png_bytep dp = row;
418 png_uint_32 row_width = row_info->width;
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500419 png_uint_32 i;
420
Glenn Randers-Pehrson16e11662004-11-01 14:13:40 -0600421 if ((row_info->color_type == PNG_COLOR_TYPE_RGB ||
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500422 (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
423 (flags & PNG_FLAG_STRIP_ALPHA))) &&
424 row_info->channels == 4)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500425 {
426 if (row_info->bit_depth == 8)
Guy Schalnat0d580581995-07-20 02:43:20 -0500427 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500428 /* This converts from RGBX or RGBA to RGB */
429 if (flags & PNG_FLAG_FILLER_AFTER)
430 {
Glenn Randers-Pehrson45624d62010-03-03 11:40:43 -0600431 dp += 3; sp += 4;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500432 for (i = 1; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500433 {
434 *dp++ = *sp++;
435 *dp++ = *sp++;
436 *dp++ = *sp++;
437 sp++;
438 }
439 }
440 /* This converts from XRGB or ARGB to RGB */
441 else
442 {
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500443 for (i = 0; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500444 {
445 sp++;
446 *dp++ = *sp++;
447 *dp++ = *sp++;
448 *dp++ = *sp++;
449 }
450 }
451 row_info->pixel_depth = 24;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500452 row_info->rowbytes = row_width * 3;
Guy Schalnat0d580581995-07-20 02:43:20 -0500453 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500454 else /* if (row_info->bit_depth == 16) */
455 {
456 if (flags & PNG_FLAG_FILLER_AFTER)
457 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500458 /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500459 sp += 8; dp += 6;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500460 for (i = 1; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500461 {
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500462 /* This could be (although png_memcpy is probably slower):
Andreas Dilger47a0c421997-05-16 02:46:07 -0500463 png_memcpy(dp, sp, 6);
464 sp += 8;
465 dp += 6;
466 */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500467
Andreas Dilger47a0c421997-05-16 02:46:07 -0500468 *dp++ = *sp++;
469 *dp++ = *sp++;
470 *dp++ = *sp++;
471 *dp++ = *sp++;
472 *dp++ = *sp++;
473 *dp++ = *sp++;
474 sp += 2;
475 }
476 }
477 else
478 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500479 /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500480 for (i = 0; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500481 {
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500482 /* This could be (although png_memcpy is probably slower):
Andreas Dilger47a0c421997-05-16 02:46:07 -0500483 png_memcpy(dp, sp, 6);
484 sp += 8;
485 dp += 6;
486 */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500487
Glenn Randers-Pehrson45624d62010-03-03 11:40:43 -0600488 sp += 2;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500489 *dp++ = *sp++;
490 *dp++ = *sp++;
491 *dp++ = *sp++;
492 *dp++ = *sp++;
493 *dp++ = *sp++;
494 *dp++ = *sp++;
495 }
496 }
497 row_info->pixel_depth = 48;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500498 row_info->rowbytes = row_width * 6;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500499 }
500 row_info->channels = 3;
Guy Schalnat0d580581995-07-20 02:43:20 -0500501 }
Glenn Randers-Pehrson94d93622004-11-01 22:38:54 -0600502 else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY ||
Glenn Randers-Pehrson16e11662004-11-01 14:13:40 -0600503 (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
Glenn Randers-Pehrson40936072004-11-20 11:18:40 -0600504 (flags & PNG_FLAG_STRIP_ALPHA))) &&
Glenn Randers-Pehrson5b779162004-09-04 13:25:08 -0500505 row_info->channels == 2)
Guy Schalnat0d580581995-07-20 02:43:20 -0500506 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500507 if (row_info->bit_depth == 8)
Guy Schalnat0d580581995-07-20 02:43:20 -0500508 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500509 if (flags & PNG_FLAG_FILLER_AFTER)
510 {
Glenn Randers-Pehrson45624d62010-03-03 11:40:43 -0600511 /* This converts from GX or GA to G */
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500512 for (i = 0; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500513 {
514 *dp++ = *sp++;
515 sp++;
516 }
517 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500518 else
519 {
Glenn Randers-Pehrson45624d62010-03-03 11:40:43 -0600520 /* This converts from XG or AG to G */
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500521 for (i = 0; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500522 {
523 sp++;
524 *dp++ = *sp++;
525 }
526 }
527 row_info->pixel_depth = 8;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500528 row_info->rowbytes = row_width;
Guy Schalnat0d580581995-07-20 02:43:20 -0500529 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500530 else /* if (row_info->bit_depth == 16) */
531 {
532 if (flags & PNG_FLAG_FILLER_AFTER)
533 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500534 /* This converts from GGXX or GGAA to GG */
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500535 sp += 4; dp += 2;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500536 for (i = 1; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500537 {
538 *dp++ = *sp++;
539 *dp++ = *sp++;
540 sp += 2;
541 }
542 }
543 else
544 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500545 /* This converts from XXGG or AAGG to GG */
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500546 for (i = 0; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500547 {
548 sp += 2;
549 *dp++ = *sp++;
550 *dp++ = *sp++;
551 }
552 }
553 row_info->pixel_depth = 16;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500554 row_info->rowbytes = row_width * 2;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500555 }
556 row_info->channels = 1;
Guy Schalnat0d580581995-07-20 02:43:20 -0500557 }
Glenn Randers-Pehrson40936072004-11-20 11:18:40 -0600558 if (flags & PNG_FLAG_STRIP_ALPHA)
Glenn Randers-Pehrson94d93622004-11-01 22:38:54 -0600559 row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
Guy Schalnat0d580581995-07-20 02:43:20 -0500560 }
561}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500562#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500563
Andreas Dilger47a0c421997-05-16 02:46:07 -0500564#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500565/* Swaps red and blue bytes within a pixel */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500566void /* PRIVATE */
Andreas Dilger47a0c421997-05-16 02:46:07 -0500567png_do_bgr(png_row_infop row_info, png_bytep row)
568{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500569 png_debug(1, "in png_do_bgr");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500570
Andreas Dilger47a0c421997-05-16 02:46:07 -0500571 if (
Andreas Dilger47a0c421997-05-16 02:46:07 -0500572 (row_info->color_type & PNG_COLOR_MASK_COLOR))
573 {
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500574 png_uint_32 row_width = row_info->width;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500575 if (row_info->bit_depth == 8)
576 {
577 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
578 {
579 png_bytep rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500580 png_uint_32 i;
581
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500582 for (i = 0, rp = row; i < row_width; i++, rp += 3)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500583 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500584 png_byte save = *rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500585 *rp = *(rp + 2);
586 *(rp + 2) = save;
587 }
588 }
589 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
590 {
591 png_bytep rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500592 png_uint_32 i;
593
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500594 for (i = 0, rp = row; i < row_width; i++, rp += 4)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500595 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500596 png_byte save = *rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500597 *rp = *(rp + 2);
598 *(rp + 2) = save;
599 }
600 }
601 }
602 else if (row_info->bit_depth == 16)
603 {
604 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
605 {
606 png_bytep rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500607 png_uint_32 i;
608
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500609 for (i = 0, rp = row; i < row_width; i++, rp += 6)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500610 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500611 png_byte save = *rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500612 *rp = *(rp + 4);
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500613 *(rp + 4) = save;
614 save = *(rp + 1);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500615 *(rp + 1) = *(rp + 5);
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500616 *(rp + 5) = save;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500617 }
618 }
619 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
620 {
621 png_bytep rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500622 png_uint_32 i;
623
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500624 for (i = 0, rp = row; i < row_width; i++, rp += 8)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500625 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500626 png_byte save = *rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500627 *rp = *(rp + 4);
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500628 *(rp + 4) = save;
629 save = *(rp + 1);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500630 *(rp + 1) = *(rp + 5);
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500631 *(rp + 5) = save;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500632 }
633 }
634 }
635 }
636}
637#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
638
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500639#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
Glenn Randers-Pehrson33188ac2009-06-16 14:12:35 -0500640 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500641void PNGAPI
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500642png_set_user_transform_info(png_structp png_ptr, png_voidp
643 user_transform_ptr, int user_transform_depth, int user_transform_channels)
644{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500645 png_debug(1, "in png_set_user_transform_info");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500646
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500647 if (png_ptr == NULL)
648 return;
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500649#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500650 png_ptr->user_transform_ptr = user_transform_ptr;
Glenn Randers-Pehrsonab1e5831999-10-06 04:57:42 -0500651 png_ptr->user_transform_depth = (png_byte)user_transform_depth;
652 png_ptr->user_transform_channels = (png_byte)user_transform_channels;
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -0500653#else
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500654 if (user_transform_ptr || user_transform_depth || user_transform_channels)
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -0500655 png_warning(png_ptr,
656 "This version of libpng does not support user transform info");
657#endif
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500658}
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -0500659#endif
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500660
661/* This function returns a pointer to the user_transform_ptr associated with
662 * the user transform functions. The application should free any memory
663 * associated with this pointer before png_write_destroy and png_read_destroy
664 * are called.
665 */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500666png_voidp PNGAPI
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500667png_get_user_transform_ptr(png_structp png_ptr)
668{
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500669 if (png_ptr == NULL)
670 return (NULL);
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500671#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500672 return ((png_voidp)png_ptr->user_transform_ptr);
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500673#else
Glenn Randers-Pehrson6b12c082006-11-14 10:53:30 -0600674 return (NULL);
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500675#endif
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -0500676}
Glenn Randers-Pehrson9c3ab682006-02-20 22:09:05 -0600677#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */