blob: 6f08c4969df4d3a5319c940320a98c61c2daa16f [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-Pehrson289500a2010-06-28 20:14:31 -05004 * Last changed in libpng 1.5.0 [June 29, 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-Pehrsonbeb572e2006-08-19 13:59:24 -050014#include "pngpriv.h"
Guy Schalnat0d580581995-07-20 02:43:20 -050015
Glenn Randers-Pehrsonc3cd22b2010-03-08 21:10:25 -060016#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
17
Guy Schalnat51f0eb41995-09-26 05:22:39 -050018#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050019/* Turn on BGR-to-RGB mapping */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050020void PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -060021png_set_bgr(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -050022{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -050023 png_debug(1, "in png_set_bgr");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -050024
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050025 if (png_ptr == NULL)
26 return;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -050027
Guy Schalnat0d580581995-07-20 02:43:20 -050028 png_ptr->transformations |= PNG_BGR;
29}
Guy Schalnat51f0eb41995-09-26 05:22:39 -050030#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050031
Guy Schalnat51f0eb41995-09-26 05:22:39 -050032#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -050033/* Turn on 16 bit byte swapping */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050034void PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -060035png_set_swap(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -050036{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -050037 png_debug(1, "in png_set_swap");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -050038
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050039 if (png_ptr == NULL)
40 return;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -050041
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;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -050056
Guy Schalnat0d580581995-07-20 02:43:20 -050057 if (png_ptr->bit_depth < 8)
58 {
59 png_ptr->transformations |= PNG_PACK;
60 png_ptr->usr_bit_depth = 8;
61 }
62}
Guy Schalnat51f0eb41995-09-26 05:22:39 -050063#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050064
Andreas Dilger47a0c421997-05-16 02:46:07 -050065#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -050066/* Turn on packed pixel swapping */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050067void PNGAPI
Andreas Dilger47a0c421997-05-16 02:46:07 -050068png_set_packswap(png_structp png_ptr)
69{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -050070 png_debug(1, "in png_set_packswap");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -050071
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050072 if (png_ptr == NULL)
73 return;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -050074
Andreas Dilger47a0c421997-05-16 02:46:07 -050075 if (png_ptr->bit_depth < 8)
76 png_ptr->transformations |= PNG_PACKSWAP;
77}
78#endif
79
Guy Schalnat51f0eb41995-09-26 05:22:39 -050080#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050081void PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -060082png_set_shift(png_structp png_ptr, png_color_8p true_bits)
Guy Schalnat0d580581995-07-20 02:43:20 -050083{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -050084 png_debug(1, "in png_set_shift");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -050085
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050086 if (png_ptr == NULL)
87 return;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -050088
Guy Schalnat0d580581995-07-20 02:43:20 -050089 png_ptr->transformations |= PNG_SHIFT;
90 png_ptr->shift = *true_bits;
91}
Guy Schalnat51f0eb41995-09-26 05:22:39 -050092#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050093
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -060094#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
95 defined(PNG_WRITE_INTERLACING_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050096int PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -060097png_set_interlace_handling(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -050098{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -050099 png_debug(1, "in png_set_interlace handling");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500100
Glenn Randers-Pehrson6b12c082006-11-14 10:53:30 -0600101 if (png_ptr && png_ptr->interlaced)
Guy Schalnat0d580581995-07-20 02:43:20 -0500102 {
103 png_ptr->transformations |= PNG_INTERLACE;
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600104 return (7);
Guy Schalnat0d580581995-07-20 02:43:20 -0500105 }
106
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600107 return (1);
Guy Schalnat0d580581995-07-20 02:43:20 -0500108}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500109#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500110
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500111#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500112/* Add a filler byte on read, or remove a filler or alpha byte on write.
113 * The filler type has changed in v0.95 to allow future 2-byte fillers
Glenn Randers-Pehrson8686fff1998-05-21 09:27:50 -0500114 * for 48-bit input data, as well as to avoid problems with some compilers
115 * that don't like bytes as parameters.
Andreas Dilger47a0c421997-05-16 02:46:07 -0500116 */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500117void PNGAPI
Andreas Dilger47a0c421997-05-16 02:46:07 -0500118png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
Guy Schalnat0d580581995-07-20 02:43:20 -0500119{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500120 png_debug(1, "in png_set_filler");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500121
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500122 if (png_ptr == NULL)
123 return;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500124
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500125 png_ptr->transformations |= PNG_FILLER;
Glenn Randers-Pehrson36ac0b52009-09-15 19:12:08 -0500126 png_ptr->filler = (png_uint_16)filler;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500127
Guy Schalnate5a37791996-06-05 15:50:50 -0500128 if (filler_loc == PNG_FILLER_AFTER)
129 png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500130
Guy Schalnate5a37791996-06-05 15:50:50 -0500131 else
132 png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600133
Glenn Randers-Pehrson5b779162004-09-04 13:25:08 -0500134 /* This should probably go in the "do_read_filler" routine.
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600135 * I attempted to do that in libpng-1.0.1a but that caused problems
136 * so I restored it in libpng-1.0.2a
137 */
138
139 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
140 {
141 png_ptr->usr_channels = 4;
142 }
143
144 /* Also I added this in libpng-1.0.2a (what happens when we expand
Glenn Randers-Pehrson45624d62010-03-03 11:40:43 -0600145 * a less-than-8-bit grayscale to GA?) */
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600146
147 if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
148 {
149 png_ptr->usr_channels = 2;
150 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500151}
Glenn Randers-Pehrson67864af2004-08-28 23:30:07 -0500152
Glenn Randers-Pehrson67864af2004-08-28 23:30:07 -0500153/* Added to libpng-1.2.7 */
154void PNGAPI
155png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
156{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500157 png_debug(1, "in png_set_add_alpha");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500158
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500159 if (png_ptr == NULL)
160 return;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500161
Glenn Randers-Pehrson67864af2004-08-28 23:30:07 -0500162 png_set_filler(png_ptr, filler, filler_loc);
163 png_ptr->transformations |= PNG_ADD_ALPHA;
164}
Glenn Randers-Pehrson67864af2004-08-28 23:30:07 -0500165
Andreas Dilger47a0c421997-05-16 02:46:07 -0500166#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500167
Andreas Dilger47a0c421997-05-16 02:46:07 -0500168#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
169 defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500170void PNGAPI
Andreas Dilger47a0c421997-05-16 02:46:07 -0500171png_set_swap_alpha(png_structp png_ptr)
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500172{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500173 png_debug(1, "in png_set_swap_alpha");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500174
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500175 if (png_ptr == NULL)
176 return;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500177
Andreas Dilger47a0c421997-05-16 02:46:07 -0500178 png_ptr->transformations |= PNG_SWAP_ALPHA;
Guy Schalnat0d580581995-07-20 02:43:20 -0500179}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500180#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500181
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600182#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
183 defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500184void PNGAPI
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600185png_set_invert_alpha(png_structp png_ptr)
186{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500187 png_debug(1, "in png_set_invert_alpha");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500188
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500189 if (png_ptr == NULL)
190 return;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500191
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600192 png_ptr->transformations |= PNG_INVERT_ALPHA;
193}
194#endif
195
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500196#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500197void PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -0600198png_set_invert_mono(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -0500199{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500200 png_debug(1, "in png_set_invert_mono");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500201
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500202 if (png_ptr == NULL)
203 return;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500204
Guy Schalnat0d580581995-07-20 02:43:20 -0500205 png_ptr->transformations |= PNG_INVERT_MONO;
206}
207
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -0500208/* Invert monochrome grayscale data */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500209void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -0600210png_do_invert(png_row_infop row_info, png_bytep row)
Guy Schalnat0d580581995-07-20 02:43:20 -0500211{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500212 png_debug(1, "in png_do_invert");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500213
Glenn Randers-Pehrson1ea0ff32001-08-07 22:25:59 -0500214 /* This test removed from libpng version 1.0.13 and 1.2.0:
215 * if (row_info->bit_depth == 1 &&
216 */
Glenn Randers-Pehrson1ea0ff32001-08-07 22:25:59 -0500217 if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
Guy Schalnat0d580581995-07-20 02:43:20 -0500218 {
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500219 png_bytep rp = row;
Guy Schalnat0d580581995-07-20 02:43:20 -0500220 png_uint_32 i;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500221 png_uint_32 istop = row_info->rowbytes;
Guy Schalnat0d580581995-07-20 02:43:20 -0500222
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500223 for (i = 0; i < istop; i++)
Guy Schalnat0d580581995-07-20 02:43:20 -0500224 {
Glenn Randers-Pehrson8686fff1998-05-21 09:27:50 -0500225 *rp = (png_byte)(~(*rp));
226 rp++;
Guy Schalnat0d580581995-07-20 02:43:20 -0500227 }
228 }
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500229
Glenn Randers-Pehrson1ea0ff32001-08-07 22:25:59 -0500230 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
231 row_info->bit_depth == 8)
232 {
233 png_bytep rp = row;
234 png_uint_32 i;
235 png_uint_32 istop = row_info->rowbytes;
236
Glenn Randers-Pehrson45624d62010-03-03 11:40:43 -0600237 for (i = 0; i < istop; i += 2)
Glenn Randers-Pehrson1ea0ff32001-08-07 22:25:59 -0500238 {
239 *rp = (png_byte)(~(*rp));
Glenn Randers-Pehrson45624d62010-03-03 11:40:43 -0600240 rp += 2;
Glenn Randers-Pehrson1ea0ff32001-08-07 22:25:59 -0500241 }
242 }
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500243
Glenn Randers-Pehrson1ea0ff32001-08-07 22:25:59 -0500244 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
245 row_info->bit_depth == 16)
246 {
247 png_bytep rp = row;
248 png_uint_32 i;
249 png_uint_32 istop = row_info->rowbytes;
250
Glenn Randers-Pehrson45624d62010-03-03 11:40:43 -0600251 for (i = 0; i < istop; i += 4)
Glenn Randers-Pehrson1ea0ff32001-08-07 22:25:59 -0500252 {
253 *rp = (png_byte)(~(*rp));
Glenn Randers-Pehrson45624d62010-03-03 11:40:43 -0600254 *(rp + 1) = (png_byte)(~(*(rp + 1)));
255 rp += 4;
Glenn Randers-Pehrson1ea0ff32001-08-07 22:25:59 -0500256 }
257 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500258}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500259#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500260
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500261#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -0500262/* Swaps byte order on 16 bit depth images */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500263void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -0600264png_do_swap(png_row_infop row_info, png_bytep row)
Guy Schalnat0d580581995-07-20 02:43:20 -0500265{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500266 png_debug(1, "in png_do_swap");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500267
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500268 if (row_info->bit_depth == 16)
Guy Schalnat0d580581995-07-20 02:43:20 -0500269 {
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500270 png_bytep rp = row;
Guy Schalnat0d580581995-07-20 02:43:20 -0500271 png_uint_32 i;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500272 png_uint_32 istop= row_info->width * row_info->channels;
Guy Schalnat0d580581995-07-20 02:43:20 -0500273
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500274 for (i = 0; i < istop; i++, rp += 2)
Guy Schalnat0d580581995-07-20 02:43:20 -0500275 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500276 png_byte t = *rp;
Guy Schalnat0d580581995-07-20 02:43:20 -0500277 *rp = *(rp + 1);
278 *(rp + 1) = t;
279 }
280 }
281}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500282#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500283
Andreas Dilger47a0c421997-05-16 02:46:07 -0500284#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
Glenn Randers-Pehrsonc3d51c12006-03-02 07:23:18 -0600285static PNG_CONST png_byte onebppswaptable[256] = {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500286 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
287 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
288 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
289 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
290 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
291 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
292 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
293 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
294 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
295 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
296 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
297 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
298 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
299 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
300 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
301 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
302 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
303 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
304 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
305 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
306 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
307 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
308 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
309 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
310 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
311 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
312 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
313 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
314 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
315 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
316 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
317 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
318};
319
Glenn Randers-Pehrsonc3d51c12006-03-02 07:23:18 -0600320static PNG_CONST png_byte twobppswaptable[256] = {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500321 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
322 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
323 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
324 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
325 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
326 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
327 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
328 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
329 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
330 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
331 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
332 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
333 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
334 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
335 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
336 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
337 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
338 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
339 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
340 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
341 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
342 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
343 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
344 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
345 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
346 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
347 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
348 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
349 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
350 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
351 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
352 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
353};
354
Glenn Randers-Pehrsonc3d51c12006-03-02 07:23:18 -0600355static PNG_CONST png_byte fourbppswaptable[256] = {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500356 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
357 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
358 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
359 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
360 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
361 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
362 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
363 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
364 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
365 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
366 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
367 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
368 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
369 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
370 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
371 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
372 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
373 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
374 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
375 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
376 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
377 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
378 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
379 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
380 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
381 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
382 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
383 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
384 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
385 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
386 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
387 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
388};
389
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500390/* Swaps pixel packing order within bytes */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500391void /* PRIVATE */
Andreas Dilger47a0c421997-05-16 02:46:07 -0500392png_do_packswap(png_row_infop row_info, png_bytep row)
Guy Schalnat0d580581995-07-20 02:43:20 -0500393{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500394 png_debug(1, "in png_do_packswap");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500395
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500396 if (row_info->bit_depth < 8)
Guy Schalnat0d580581995-07-20 02:43:20 -0500397 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500398 png_bytep rp, end, table;
Guy Schalnat0d580581995-07-20 02:43:20 -0500399
Andreas Dilger47a0c421997-05-16 02:46:07 -0500400 end = row + row_info->rowbytes;
401
402 if (row_info->bit_depth == 1)
Glenn Randers-Pehrsonc3d51c12006-03-02 07:23:18 -0600403 table = (png_bytep)onebppswaptable;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500404
Andreas Dilger47a0c421997-05-16 02:46:07 -0500405 else if (row_info->bit_depth == 2)
Glenn Randers-Pehrsonc3d51c12006-03-02 07:23:18 -0600406 table = (png_bytep)twobppswaptable;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500407
Andreas Dilger47a0c421997-05-16 02:46:07 -0500408 else if (row_info->bit_depth == 4)
Glenn Randers-Pehrsonc3d51c12006-03-02 07:23:18 -0600409 table = (png_bytep)fourbppswaptable;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500410
Andreas Dilger47a0c421997-05-16 02:46:07 -0500411 else
412 return;
413
414 for (rp = row; rp < end; rp++)
415 *rp = table[*rp];
416 }
417}
418#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
419
420#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
421 defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500422/* Remove filler or alpha byte(s) */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500423void /* PRIVATE */
Glenn Randers-Pehrson40936072004-11-20 11:18:40 -0600424png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500425{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500426 png_debug(1, "in png_do_strip_filler");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500427
Andreas Dilger47a0c421997-05-16 02:46:07 -0500428 {
Glenn Randers-Pehrson45624d62010-03-03 11:40:43 -0600429 png_bytep sp = row;
430 png_bytep dp = row;
431 png_uint_32 row_width = row_info->width;
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500432 png_uint_32 i;
433
Glenn Randers-Pehrson16e11662004-11-01 14:13:40 -0600434 if ((row_info->color_type == PNG_COLOR_TYPE_RGB ||
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500435 (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
436 (flags & PNG_FLAG_STRIP_ALPHA))) &&
437 row_info->channels == 4)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500438 {
439 if (row_info->bit_depth == 8)
Guy Schalnat0d580581995-07-20 02:43:20 -0500440 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500441 /* This converts from RGBX or RGBA to RGB */
442 if (flags & PNG_FLAG_FILLER_AFTER)
443 {
Glenn Randers-Pehrson45624d62010-03-03 11:40:43 -0600444 dp += 3; sp += 4;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500445 for (i = 1; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500446 {
447 *dp++ = *sp++;
448 *dp++ = *sp++;
449 *dp++ = *sp++;
450 sp++;
451 }
452 }
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500453
Andreas Dilger47a0c421997-05-16 02:46:07 -0500454 /* This converts from XRGB or ARGB to RGB */
455 else
456 {
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500457 for (i = 0; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500458 {
459 sp++;
460 *dp++ = *sp++;
461 *dp++ = *sp++;
462 *dp++ = *sp++;
463 }
464 }
465 row_info->pixel_depth = 24;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500466 row_info->rowbytes = row_width * 3;
Guy Schalnat0d580581995-07-20 02:43:20 -0500467 }
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500468
Andreas Dilger47a0c421997-05-16 02:46:07 -0500469 else /* if (row_info->bit_depth == 16) */
470 {
471 if (flags & PNG_FLAG_FILLER_AFTER)
472 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500473 /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500474 sp += 8; dp += 6;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500475 for (i = 1; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500476 {
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500477 /* This could be (although png_memcpy is probably slower):
Andreas Dilger47a0c421997-05-16 02:46:07 -0500478 png_memcpy(dp, sp, 6);
479 sp += 8;
480 dp += 6;
481 */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500482
Andreas Dilger47a0c421997-05-16 02:46:07 -0500483 *dp++ = *sp++;
484 *dp++ = *sp++;
485 *dp++ = *sp++;
486 *dp++ = *sp++;
487 *dp++ = *sp++;
488 *dp++ = *sp++;
489 sp += 2;
490 }
491 }
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500492
Andreas Dilger47a0c421997-05-16 02:46:07 -0500493 else
494 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500495 /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500496 for (i = 0; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500497 {
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500498 /* This could be (although png_memcpy is probably slower):
Andreas Dilger47a0c421997-05-16 02:46:07 -0500499 png_memcpy(dp, sp, 6);
500 sp += 8;
501 dp += 6;
502 */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500503
Glenn Randers-Pehrson45624d62010-03-03 11:40:43 -0600504 sp += 2;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500505 *dp++ = *sp++;
506 *dp++ = *sp++;
507 *dp++ = *sp++;
508 *dp++ = *sp++;
509 *dp++ = *sp++;
510 *dp++ = *sp++;
511 }
512 }
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500513
Andreas Dilger47a0c421997-05-16 02:46:07 -0500514 row_info->pixel_depth = 48;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500515 row_info->rowbytes = row_width * 6;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500516 }
517 row_info->channels = 3;
Guy Schalnat0d580581995-07-20 02:43:20 -0500518 }
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500519
Glenn Randers-Pehrson94d93622004-11-01 22:38:54 -0600520 else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY ||
Glenn Randers-Pehrson16e11662004-11-01 14:13:40 -0600521 (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
Glenn Randers-Pehrson40936072004-11-20 11:18:40 -0600522 (flags & PNG_FLAG_STRIP_ALPHA))) &&
Glenn Randers-Pehrson5b779162004-09-04 13:25:08 -0500523 row_info->channels == 2)
Guy Schalnat0d580581995-07-20 02:43:20 -0500524 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500525 if (row_info->bit_depth == 8)
Guy Schalnat0d580581995-07-20 02:43:20 -0500526 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500527 if (flags & PNG_FLAG_FILLER_AFTER)
528 {
Glenn Randers-Pehrson45624d62010-03-03 11:40:43 -0600529 /* This converts from GX or GA to G */
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500530 for (i = 0; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500531 {
532 *dp++ = *sp++;
533 sp++;
534 }
535 }
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500536
Andreas Dilger47a0c421997-05-16 02:46:07 -0500537 else
538 {
Glenn Randers-Pehrson45624d62010-03-03 11:40:43 -0600539 /* This converts from XG or AG to G */
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500540 for (i = 0; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500541 {
542 sp++;
543 *dp++ = *sp++;
544 }
545 }
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500546
Andreas Dilger47a0c421997-05-16 02:46:07 -0500547 row_info->pixel_depth = 8;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500548 row_info->rowbytes = row_width;
Guy Schalnat0d580581995-07-20 02:43:20 -0500549 }
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500550
Andreas Dilger47a0c421997-05-16 02:46:07 -0500551 else /* if (row_info->bit_depth == 16) */
552 {
553 if (flags & PNG_FLAG_FILLER_AFTER)
554 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500555 /* This converts from GGXX or GGAA to GG */
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500556 sp += 4; dp += 2;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500557 for (i = 1; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500558 {
559 *dp++ = *sp++;
560 *dp++ = *sp++;
561 sp += 2;
562 }
563 }
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500564
Andreas Dilger47a0c421997-05-16 02:46:07 -0500565 else
566 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500567 /* This converts from XXGG or AAGG to GG */
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500568 for (i = 0; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500569 {
570 sp += 2;
571 *dp++ = *sp++;
572 *dp++ = *sp++;
573 }
574 }
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500575
Andreas Dilger47a0c421997-05-16 02:46:07 -0500576 row_info->pixel_depth = 16;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500577 row_info->rowbytes = row_width * 2;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500578 }
579 row_info->channels = 1;
Guy Schalnat0d580581995-07-20 02:43:20 -0500580 }
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500581
Glenn Randers-Pehrson40936072004-11-20 11:18:40 -0600582 if (flags & PNG_FLAG_STRIP_ALPHA)
Glenn Randers-Pehrson94d93622004-11-01 22:38:54 -0600583 row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
Guy Schalnat0d580581995-07-20 02:43:20 -0500584 }
585}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500586#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500587
Andreas Dilger47a0c421997-05-16 02:46:07 -0500588#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500589/* Swaps red and blue bytes within a pixel */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500590void /* PRIVATE */
Andreas Dilger47a0c421997-05-16 02:46:07 -0500591png_do_bgr(png_row_infop row_info, png_bytep row)
592{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500593 png_debug(1, "in png_do_bgr");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500594
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500595 if ((row_info->color_type & PNG_COLOR_MASK_COLOR))
Andreas Dilger47a0c421997-05-16 02:46:07 -0500596 {
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500597 png_uint_32 row_width = row_info->width;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500598 if (row_info->bit_depth == 8)
599 {
600 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
601 {
602 png_bytep rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500603 png_uint_32 i;
604
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500605 for (i = 0, rp = row; i < row_width; i++, rp += 3)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500606 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500607 png_byte save = *rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500608 *rp = *(rp + 2);
609 *(rp + 2) = save;
610 }
611 }
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500612
Andreas Dilger47a0c421997-05-16 02:46:07 -0500613 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
614 {
615 png_bytep rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500616 png_uint_32 i;
617
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500618 for (i = 0, rp = row; i < row_width; i++, rp += 4)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500619 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500620 png_byte save = *rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500621 *rp = *(rp + 2);
622 *(rp + 2) = save;
623 }
624 }
625 }
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500626
Andreas Dilger47a0c421997-05-16 02:46:07 -0500627 else if (row_info->bit_depth == 16)
628 {
629 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
630 {
631 png_bytep rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500632 png_uint_32 i;
633
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500634 for (i = 0, rp = row; i < row_width; i++, rp += 6)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500635 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500636 png_byte save = *rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500637 *rp = *(rp + 4);
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500638 *(rp + 4) = save;
639 save = *(rp + 1);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500640 *(rp + 1) = *(rp + 5);
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500641 *(rp + 5) = save;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500642 }
643 }
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500644
Andreas Dilger47a0c421997-05-16 02:46:07 -0500645 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
646 {
647 png_bytep rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500648 png_uint_32 i;
649
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500650 for (i = 0, rp = row; i < row_width; i++, rp += 8)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500651 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500652 png_byte save = *rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500653 *rp = *(rp + 4);
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500654 *(rp + 4) = save;
655 save = *(rp + 1);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500656 *(rp + 1) = *(rp + 5);
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500657 *(rp + 5) = save;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500658 }
659 }
660 }
661 }
662}
663#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
664
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500665#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
Glenn Randers-Pehrson33188ac2009-06-16 14:12:35 -0500666 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500667void PNGAPI
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500668png_set_user_transform_info(png_structp png_ptr, png_voidp
669 user_transform_ptr, int user_transform_depth, int user_transform_channels)
670{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500671 png_debug(1, "in png_set_user_transform_info");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500672
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500673 if (png_ptr == NULL)
674 return;
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500675#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500676 png_ptr->user_transform_ptr = user_transform_ptr;
Glenn Randers-Pehrsonab1e5831999-10-06 04:57:42 -0500677 png_ptr->user_transform_depth = (png_byte)user_transform_depth;
678 png_ptr->user_transform_channels = (png_byte)user_transform_channels;
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -0500679#else
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500680 if (user_transform_ptr || user_transform_depth || user_transform_channels)
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -0500681 png_warning(png_ptr,
682 "This version of libpng does not support user transform info");
683#endif
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500684}
685
686/* This function returns a pointer to the user_transform_ptr associated with
687 * the user transform functions. The application should free any memory
688 * associated with this pointer before png_write_destroy and png_read_destroy
689 * are called.
690 */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500691png_voidp PNGAPI
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500692png_get_user_transform_ptr(png_structp png_ptr)
693{
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500694 if (png_ptr == NULL)
695 return (NULL);
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500696
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500697#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500698 return ((png_voidp)png_ptr->user_transform_ptr);
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500699#else
Glenn Randers-Pehrson6b12c082006-11-14 10:53:30 -0600700 return (NULL);
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500701#endif
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -0500702}
Glenn Randers-Pehrsoncf2fd3b2010-04-28 21:25:18 -0500703#endif /* PNG_READ_USER_TRANSFORM_SUPPORTED ||
704 PNG_WRITE_USER_TRANSFORM_SUPPORTED */
Glenn Randers-Pehrson9c3ab682006-02-20 22:09:05 -0600705#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */