blob: 548abbf414d0b01722993d377dab039b944cb830 [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-Pehrsonbdbade92009-11-12 06:22:16 -06004 * Last changed in libpng 1.4.0 [November 12, 2009]
Glenn Randers-Pehrson79134c62009-02-14 10:32:18 -06005 * Copyright (c) 1998-2009 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
Guy Schalnat0d580581995-07-20 02:43:20 -050014#include "png.h"
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -050015#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -050016#include "pngpriv.h"
Guy Schalnat0d580581995-07-20 02:43:20 -050017
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;
Guy Schalnat0d580581995-07-20 02:43:20 -050027 png_ptr->transformations |= PNG_BGR;
28}
Guy Schalnat51f0eb41995-09-26 05:22:39 -050029#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050030
Guy Schalnat51f0eb41995-09-26 05:22:39 -050031#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -050032/* Turn on 16 bit byte swapping */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050033void PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -060034png_set_swap(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -050035{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -050036 png_debug(1, "in png_set_swap");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -050037
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050038 if (png_ptr == NULL)
39 return;
Guy Schalnat0d580581995-07-20 02:43:20 -050040 if (png_ptr->bit_depth == 16)
41 png_ptr->transformations |= PNG_SWAP_BYTES;
42}
Guy Schalnat51f0eb41995-09-26 05:22:39 -050043#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050044
Guy Schalnat51f0eb41995-09-26 05:22:39 -050045#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -050046/* Turn on pixel packing */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050047void PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -060048png_set_packing(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -050049{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -050050 png_debug(1, "in png_set_packing");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -050051
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050052 if (png_ptr == NULL)
53 return;
Guy Schalnat0d580581995-07-20 02:43:20 -050054 if (png_ptr->bit_depth < 8)
55 {
56 png_ptr->transformations |= PNG_PACK;
57 png_ptr->usr_bit_depth = 8;
58 }
59}
Guy Schalnat51f0eb41995-09-26 05:22:39 -050060#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050061
Andreas Dilger47a0c421997-05-16 02:46:07 -050062#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -050063/* Turn on packed pixel swapping */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050064void PNGAPI
Andreas Dilger47a0c421997-05-16 02:46:07 -050065png_set_packswap(png_structp png_ptr)
66{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -050067 png_debug(1, "in png_set_packswap");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -050068
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050069 if (png_ptr == NULL)
70 return;
Andreas Dilger47a0c421997-05-16 02:46:07 -050071 if (png_ptr->bit_depth < 8)
72 png_ptr->transformations |= PNG_PACKSWAP;
73}
74#endif
75
Guy Schalnat51f0eb41995-09-26 05:22:39 -050076#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050077void PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -060078png_set_shift(png_structp png_ptr, png_color_8p true_bits)
Guy Schalnat0d580581995-07-20 02:43:20 -050079{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -050080 png_debug(1, "in png_set_shift");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -050081
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050082 if (png_ptr == NULL)
83 return;
Guy Schalnat0d580581995-07-20 02:43:20 -050084 png_ptr->transformations |= PNG_SHIFT;
85 png_ptr->shift = *true_bits;
86}
Guy Schalnat51f0eb41995-09-26 05:22:39 -050087#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050088
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -060089#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
90 defined(PNG_WRITE_INTERLACING_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050091int PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -060092png_set_interlace_handling(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -050093{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -050094 png_debug(1, "in png_set_interlace handling");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -050095
Glenn Randers-Pehrson6b12c082006-11-14 10:53:30 -060096 if (png_ptr && png_ptr->interlaced)
Guy Schalnat0d580581995-07-20 02:43:20 -050097 {
98 png_ptr->transformations |= PNG_INTERLACE;
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -060099 return (7);
Guy Schalnat0d580581995-07-20 02:43:20 -0500100 }
101
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600102 return (1);
Guy Schalnat0d580581995-07-20 02:43:20 -0500103}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500104#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500105
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500106#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500107/* Add a filler byte on read, or remove a filler or alpha byte on write.
108 * The filler type has changed in v0.95 to allow future 2-byte fillers
Glenn Randers-Pehrson8686fff1998-05-21 09:27:50 -0500109 * for 48-bit input data, as well as to avoid problems with some compilers
110 * that don't like bytes as parameters.
Andreas Dilger47a0c421997-05-16 02:46:07 -0500111 */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500112void PNGAPI
Andreas Dilger47a0c421997-05-16 02:46:07 -0500113png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
Guy Schalnat0d580581995-07-20 02:43:20 -0500114{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500115 png_debug(1, "in png_set_filler");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500116
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500117 if (png_ptr == NULL)
118 return;
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500119 png_ptr->transformations |= PNG_FILLER;
Glenn Randers-Pehrson36ac0b52009-09-15 19:12:08 -0500120 png_ptr->filler = (png_uint_16)filler;
Guy Schalnate5a37791996-06-05 15:50:50 -0500121 if (filler_loc == PNG_FILLER_AFTER)
122 png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
123 else
124 png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600125
Glenn Randers-Pehrson5b779162004-09-04 13:25:08 -0500126 /* This should probably go in the "do_read_filler" routine.
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600127 * I attempted to do that in libpng-1.0.1a but that caused problems
128 * so I restored it in libpng-1.0.2a
129 */
130
131 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
132 {
133 png_ptr->usr_channels = 4;
134 }
135
136 /* Also I added this in libpng-1.0.2a (what happens when we expand
137 * a less-than-8-bit grayscale to GA? */
138
139 if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
140 {
141 png_ptr->usr_channels = 2;
142 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500143}
Glenn Randers-Pehrson67864af2004-08-28 23:30:07 -0500144
Glenn Randers-Pehrson67864af2004-08-28 23:30:07 -0500145/* Added to libpng-1.2.7 */
146void PNGAPI
147png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
148{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500149 png_debug(1, "in png_set_add_alpha");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500150
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500151 if (png_ptr == NULL)
152 return;
Glenn Randers-Pehrson67864af2004-08-28 23:30:07 -0500153 png_set_filler(png_ptr, filler, filler_loc);
154 png_ptr->transformations |= PNG_ADD_ALPHA;
155}
Glenn Randers-Pehrson67864af2004-08-28 23:30:07 -0500156
Andreas Dilger47a0c421997-05-16 02:46:07 -0500157#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500158
Andreas Dilger47a0c421997-05-16 02:46:07 -0500159#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
160 defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500161void PNGAPI
Andreas Dilger47a0c421997-05-16 02:46:07 -0500162png_set_swap_alpha(png_structp png_ptr)
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500163{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500164 png_debug(1, "in png_set_swap_alpha");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500165
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500166 if (png_ptr == NULL)
167 return;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500168 png_ptr->transformations |= PNG_SWAP_ALPHA;
Guy Schalnat0d580581995-07-20 02:43:20 -0500169}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500170#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500171
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600172#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
173 defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500174void PNGAPI
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600175png_set_invert_alpha(png_structp png_ptr)
176{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500177 png_debug(1, "in png_set_invert_alpha");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500178
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500179 if (png_ptr == NULL)
180 return;
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600181 png_ptr->transformations |= PNG_INVERT_ALPHA;
182}
183#endif
184
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500185#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500186void PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -0600187png_set_invert_mono(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -0500188{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500189 png_debug(1, "in png_set_invert_mono");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500190
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500191 if (png_ptr == NULL)
192 return;
Guy Schalnat0d580581995-07-20 02:43:20 -0500193 png_ptr->transformations |= PNG_INVERT_MONO;
194}
195
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -0500196/* Invert monochrome grayscale data */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500197void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -0600198png_do_invert(png_row_infop row_info, png_bytep row)
Guy Schalnat0d580581995-07-20 02:43:20 -0500199{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500200 png_debug(1, "in png_do_invert");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500201
Glenn Randers-Pehrson1ea0ff32001-08-07 22:25:59 -0500202 /* This test removed from libpng version 1.0.13 and 1.2.0:
203 * if (row_info->bit_depth == 1 &&
204 */
Glenn Randers-Pehrson1ea0ff32001-08-07 22:25:59 -0500205 if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
Guy Schalnat0d580581995-07-20 02:43:20 -0500206 {
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500207 png_bytep rp = row;
Guy Schalnat0d580581995-07-20 02:43:20 -0500208 png_uint_32 i;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500209 png_uint_32 istop = row_info->rowbytes;
Guy Schalnat0d580581995-07-20 02:43:20 -0500210
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500211 for (i = 0; i < istop; i++)
Guy Schalnat0d580581995-07-20 02:43:20 -0500212 {
Glenn Randers-Pehrson8686fff1998-05-21 09:27:50 -0500213 *rp = (png_byte)(~(*rp));
214 rp++;
Guy Schalnat0d580581995-07-20 02:43:20 -0500215 }
216 }
Glenn Randers-Pehrson1ea0ff32001-08-07 22:25:59 -0500217 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
218 row_info->bit_depth == 8)
219 {
220 png_bytep rp = row;
221 png_uint_32 i;
222 png_uint_32 istop = row_info->rowbytes;
223
224 for (i = 0; i < istop; i+=2)
225 {
226 *rp = (png_byte)(~(*rp));
227 rp+=2;
228 }
229 }
230 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
231 row_info->bit_depth == 16)
232 {
233 png_bytep rp = row;
234 png_uint_32 i;
235 png_uint_32 istop = row_info->rowbytes;
236
237 for (i = 0; i < istop; i+=4)
238 {
239 *rp = (png_byte)(~(*rp));
240 *(rp+1) = (png_byte)(~(*(rp+1)));
241 rp+=4;
242 }
243 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500244}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500245#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500246
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500247#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -0500248/* Swaps byte order on 16 bit depth images */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500249void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -0600250png_do_swap(png_row_infop row_info, png_bytep row)
Guy Schalnat0d580581995-07-20 02:43:20 -0500251{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500252 png_debug(1, "in png_do_swap");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500253
Andreas Dilger47a0c421997-05-16 02:46:07 -0500254 if (
Andreas Dilger47a0c421997-05-16 02:46:07 -0500255 row_info->bit_depth == 16)
Guy Schalnat0d580581995-07-20 02:43:20 -0500256 {
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500257 png_bytep rp = row;
Guy Schalnat0d580581995-07-20 02:43:20 -0500258 png_uint_32 i;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500259 png_uint_32 istop= row_info->width * row_info->channels;
Guy Schalnat0d580581995-07-20 02:43:20 -0500260
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500261 for (i = 0; i < istop; i++, rp += 2)
Guy Schalnat0d580581995-07-20 02:43:20 -0500262 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500263 png_byte t = *rp;
Guy Schalnat0d580581995-07-20 02:43:20 -0500264 *rp = *(rp + 1);
265 *(rp + 1) = t;
266 }
267 }
268}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500269#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500270
Andreas Dilger47a0c421997-05-16 02:46:07 -0500271#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
Glenn Randers-Pehrsonc3d51c12006-03-02 07:23:18 -0600272static PNG_CONST png_byte onebppswaptable[256] = {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500273 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
274 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
275 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
276 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
277 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
278 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
279 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
280 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
281 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
282 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
283 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
284 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
285 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
286 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
287 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
288 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
289 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
290 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
291 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
292 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
293 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
294 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
295 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
296 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
297 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
298 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
299 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
300 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
301 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
302 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
303 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
304 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
305};
306
Glenn Randers-Pehrsonc3d51c12006-03-02 07:23:18 -0600307static PNG_CONST png_byte twobppswaptable[256] = {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500308 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
309 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
310 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
311 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
312 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
313 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
314 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
315 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
316 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
317 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
318 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
319 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
320 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
321 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
322 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
323 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
324 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
325 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
326 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
327 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
328 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
329 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
330 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
331 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
332 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
333 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
334 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
335 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
336 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
337 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
338 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
339 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
340};
341
Glenn Randers-Pehrsonc3d51c12006-03-02 07:23:18 -0600342static PNG_CONST png_byte fourbppswaptable[256] = {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500343 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
344 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
345 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
346 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
347 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
348 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
349 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
350 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
351 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
352 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
353 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
354 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
355 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
356 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
357 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
358 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
359 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
360 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
361 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
362 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
363 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
364 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
365 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
366 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
367 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
368 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
369 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
370 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
371 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
372 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
373 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
374 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
375};
376
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500377/* Swaps pixel packing order within bytes */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500378void /* PRIVATE */
Andreas Dilger47a0c421997-05-16 02:46:07 -0500379png_do_packswap(png_row_infop row_info, png_bytep row)
Guy Schalnat0d580581995-07-20 02:43:20 -0500380{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500381 png_debug(1, "in png_do_packswap");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500382
Andreas Dilger47a0c421997-05-16 02:46:07 -0500383 if (
Andreas Dilger47a0c421997-05-16 02:46:07 -0500384 row_info->bit_depth < 8)
Guy Schalnat0d580581995-07-20 02:43:20 -0500385 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500386 png_bytep rp, end, table;
Guy Schalnat0d580581995-07-20 02:43:20 -0500387
Andreas Dilger47a0c421997-05-16 02:46:07 -0500388 end = row + row_info->rowbytes;
389
390 if (row_info->bit_depth == 1)
Glenn Randers-Pehrsonc3d51c12006-03-02 07:23:18 -0600391 table = (png_bytep)onebppswaptable;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500392 else if (row_info->bit_depth == 2)
Glenn Randers-Pehrsonc3d51c12006-03-02 07:23:18 -0600393 table = (png_bytep)twobppswaptable;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500394 else if (row_info->bit_depth == 4)
Glenn Randers-Pehrsonc3d51c12006-03-02 07:23:18 -0600395 table = (png_bytep)fourbppswaptable;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500396 else
397 return;
398
399 for (rp = row; rp < end; rp++)
400 *rp = table[*rp];
401 }
402}
403#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
404
405#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
406 defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500407/* Remove filler or alpha byte(s) */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500408void /* PRIVATE */
Glenn Randers-Pehrson40936072004-11-20 11:18:40 -0600409png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500410{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500411 png_debug(1, "in png_do_strip_filler");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500412
Andreas Dilger47a0c421997-05-16 02:46:07 -0500413 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500414 png_bytep sp=row;
415 png_bytep dp=row;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500416 png_uint_32 row_width=row_info->width;
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500417 png_uint_32 i;
418
Glenn Randers-Pehrson16e11662004-11-01 14:13:40 -0600419 if ((row_info->color_type == PNG_COLOR_TYPE_RGB ||
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500420 (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
421 (flags & PNG_FLAG_STRIP_ALPHA))) &&
422 row_info->channels == 4)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500423 {
424 if (row_info->bit_depth == 8)
Guy Schalnat0d580581995-07-20 02:43:20 -0500425 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500426 /* This converts from RGBX or RGBA to RGB */
427 if (flags & PNG_FLAG_FILLER_AFTER)
428 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500429 dp+=3; sp+=4;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500430 for (i = 1; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500431 {
432 *dp++ = *sp++;
433 *dp++ = *sp++;
434 *dp++ = *sp++;
435 sp++;
436 }
437 }
438 /* This converts from XRGB or ARGB to RGB */
439 else
440 {
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500441 for (i = 0; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500442 {
443 sp++;
444 *dp++ = *sp++;
445 *dp++ = *sp++;
446 *dp++ = *sp++;
447 }
448 }
449 row_info->pixel_depth = 24;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500450 row_info->rowbytes = row_width * 3;
Guy Schalnat0d580581995-07-20 02:43:20 -0500451 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500452 else /* if (row_info->bit_depth == 16) */
453 {
454 if (flags & PNG_FLAG_FILLER_AFTER)
455 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500456 /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500457 sp += 8; dp += 6;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500458 for (i = 1; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500459 {
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500460 /* This could be (although png_memcpy is probably slower):
Andreas Dilger47a0c421997-05-16 02:46:07 -0500461 png_memcpy(dp, sp, 6);
462 sp += 8;
463 dp += 6;
464 */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500465
Andreas Dilger47a0c421997-05-16 02:46:07 -0500466 *dp++ = *sp++;
467 *dp++ = *sp++;
468 *dp++ = *sp++;
469 *dp++ = *sp++;
470 *dp++ = *sp++;
471 *dp++ = *sp++;
472 sp += 2;
473 }
474 }
475 else
476 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500477 /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500478 for (i = 0; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500479 {
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500480 /* This could be (although png_memcpy is probably slower):
Andreas Dilger47a0c421997-05-16 02:46:07 -0500481 png_memcpy(dp, sp, 6);
482 sp += 8;
483 dp += 6;
484 */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500485
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500486 sp+=2;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500487 *dp++ = *sp++;
488 *dp++ = *sp++;
489 *dp++ = *sp++;
490 *dp++ = *sp++;
491 *dp++ = *sp++;
492 *dp++ = *sp++;
493 }
494 }
495 row_info->pixel_depth = 48;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500496 row_info->rowbytes = row_width * 6;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500497 }
498 row_info->channels = 3;
Guy Schalnat0d580581995-07-20 02:43:20 -0500499 }
Glenn Randers-Pehrson94d93622004-11-01 22:38:54 -0600500 else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY ||
Glenn Randers-Pehrson16e11662004-11-01 14:13:40 -0600501 (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
Glenn Randers-Pehrson40936072004-11-20 11:18:40 -0600502 (flags & PNG_FLAG_STRIP_ALPHA))) &&
Glenn Randers-Pehrson5b779162004-09-04 13:25:08 -0500503 row_info->channels == 2)
Guy Schalnat0d580581995-07-20 02:43:20 -0500504 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500505 if (row_info->bit_depth == 8)
Guy Schalnat0d580581995-07-20 02:43:20 -0500506 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500507 /* This converts from GX or GA to G */
508 if (flags & PNG_FLAG_FILLER_AFTER)
509 {
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500510 for (i = 0; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500511 {
512 *dp++ = *sp++;
513 sp++;
514 }
515 }
516 /* This converts from XG or AG to G */
517 else
518 {
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500519 for (i = 0; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500520 {
521 sp++;
522 *dp++ = *sp++;
523 }
524 }
525 row_info->pixel_depth = 8;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500526 row_info->rowbytes = row_width;
Guy Schalnat0d580581995-07-20 02:43:20 -0500527 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500528 else /* if (row_info->bit_depth == 16) */
529 {
530 if (flags & PNG_FLAG_FILLER_AFTER)
531 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500532 /* This converts from GGXX or GGAA to GG */
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500533 sp += 4; dp += 2;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500534 for (i = 1; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500535 {
536 *dp++ = *sp++;
537 *dp++ = *sp++;
538 sp += 2;
539 }
540 }
541 else
542 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500543 /* This converts from XXGG or AAGG to GG */
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500544 for (i = 0; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500545 {
546 sp += 2;
547 *dp++ = *sp++;
548 *dp++ = *sp++;
549 }
550 }
551 row_info->pixel_depth = 16;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500552 row_info->rowbytes = row_width * 2;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500553 }
554 row_info->channels = 1;
Guy Schalnat0d580581995-07-20 02:43:20 -0500555 }
Glenn Randers-Pehrson40936072004-11-20 11:18:40 -0600556 if (flags & PNG_FLAG_STRIP_ALPHA)
Glenn Randers-Pehrson94d93622004-11-01 22:38:54 -0600557 row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
Guy Schalnat0d580581995-07-20 02:43:20 -0500558 }
559}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500560#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500561
Andreas Dilger47a0c421997-05-16 02:46:07 -0500562#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500563/* Swaps red and blue bytes within a pixel */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500564void /* PRIVATE */
Andreas Dilger47a0c421997-05-16 02:46:07 -0500565png_do_bgr(png_row_infop row_info, png_bytep row)
566{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500567 png_debug(1, "in png_do_bgr");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500568
Andreas Dilger47a0c421997-05-16 02:46:07 -0500569 if (
Andreas Dilger47a0c421997-05-16 02:46:07 -0500570 (row_info->color_type & PNG_COLOR_MASK_COLOR))
571 {
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500572 png_uint_32 row_width = row_info->width;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500573 if (row_info->bit_depth == 8)
574 {
575 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
576 {
577 png_bytep rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500578 png_uint_32 i;
579
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500580 for (i = 0, rp = row; i < row_width; i++, rp += 3)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500581 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500582 png_byte save = *rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500583 *rp = *(rp + 2);
584 *(rp + 2) = save;
585 }
586 }
587 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
588 {
589 png_bytep rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500590 png_uint_32 i;
591
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500592 for (i = 0, rp = row; i < row_width; i++, rp += 4)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500593 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500594 png_byte save = *rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500595 *rp = *(rp + 2);
596 *(rp + 2) = save;
597 }
598 }
599 }
600 else if (row_info->bit_depth == 16)
601 {
602 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
603 {
604 png_bytep rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500605 png_uint_32 i;
606
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500607 for (i = 0, rp = row; i < row_width; i++, rp += 6)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500608 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500609 png_byte save = *rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500610 *rp = *(rp + 4);
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500611 *(rp + 4) = save;
612 save = *(rp + 1);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500613 *(rp + 1) = *(rp + 5);
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500614 *(rp + 5) = save;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500615 }
616 }
617 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
618 {
619 png_bytep rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500620 png_uint_32 i;
621
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500622 for (i = 0, rp = row; i < row_width; i++, rp += 8)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500623 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500624 png_byte save = *rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500625 *rp = *(rp + 4);
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500626 *(rp + 4) = save;
627 save = *(rp + 1);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500628 *(rp + 1) = *(rp + 5);
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500629 *(rp + 5) = save;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500630 }
631 }
632 }
633 }
634}
635#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
636
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500637#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
Glenn Randers-Pehrson33188ac2009-06-16 14:12:35 -0500638 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500639void PNGAPI
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500640png_set_user_transform_info(png_structp png_ptr, png_voidp
641 user_transform_ptr, int user_transform_depth, int user_transform_channels)
642{
Glenn Randers-Pehrson51650b82008-08-05 07:44:42 -0500643 png_debug(1, "in png_set_user_transform_info");
Glenn Randers-Pehrsonda009802009-08-15 13:25:47 -0500644
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500645 if (png_ptr == NULL)
646 return;
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500647#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500648 png_ptr->user_transform_ptr = user_transform_ptr;
Glenn Randers-Pehrsonab1e5831999-10-06 04:57:42 -0500649 png_ptr->user_transform_depth = (png_byte)user_transform_depth;
650 png_ptr->user_transform_channels = (png_byte)user_transform_channels;
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -0500651#else
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500652 if (user_transform_ptr || user_transform_depth || user_transform_channels)
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -0500653 png_warning(png_ptr,
654 "This version of libpng does not support user transform info");
655#endif
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500656}
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -0500657#endif
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500658
659/* This function returns a pointer to the user_transform_ptr associated with
660 * the user transform functions. The application should free any memory
661 * associated with this pointer before png_write_destroy and png_read_destroy
662 * are called.
663 */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500664png_voidp PNGAPI
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500665png_get_user_transform_ptr(png_structp png_ptr)
666{
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500667 if (png_ptr == NULL)
668 return (NULL);
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500669#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500670 return ((png_voidp)png_ptr->user_transform_ptr);
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500671#else
Glenn Randers-Pehrson6b12c082006-11-14 10:53:30 -0600672 return (NULL);
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500673#endif
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -0500674}
Glenn Randers-Pehrson9c3ab682006-02-20 22:09:05 -0600675#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */