blob: 12f6f237f9ab9a293157ae4b1eb5edbc3bb07382 [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-Pehrson3097f612001-05-07 14:52:45 -05004 * libpng 1.2.0beta2 - May 7, 2001
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06005 * For conditions of distribution and use, see copyright notice in png.h
Glenn Randers-Pehrsonbe9de0f2001-01-22 08:52:16 -06006 * Copyright (c) 1998-2001 Glenn Randers-Pehrson
Glenn Randers-Pehrsond4366722000-06-04 14:29:29 -05007 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06009 */
Guy Schalnat0d580581995-07-20 02:43:20 -050010
11#define PNG_INTERNAL
12#include "png.h"
13
Guy Schalnat51f0eb41995-09-26 05:22:39 -050014#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
Glenn Randers-Pehrson352ca6b1999-09-18 15:49:20 -050015/* turn on BGR-to-RGB mapping */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050016void PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -060017png_set_bgr(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -050018{
Andreas Dilger47a0c421997-05-16 02:46:07 -050019 png_debug(1, "in png_set_bgr\n");
Guy Schalnat0d580581995-07-20 02:43:20 -050020 png_ptr->transformations |= PNG_BGR;
21}
Guy Schalnat51f0eb41995-09-26 05:22:39 -050022#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050023
Guy Schalnat51f0eb41995-09-26 05:22:39 -050024#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
Guy Schalnat0d580581995-07-20 02:43:20 -050025/* turn on 16 bit byte swapping */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050026void PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -060027png_set_swap(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -050028{
Andreas Dilger47a0c421997-05-16 02:46:07 -050029 png_debug(1, "in png_set_swap\n");
Guy Schalnat0d580581995-07-20 02:43:20 -050030 if (png_ptr->bit_depth == 16)
31 png_ptr->transformations |= PNG_SWAP_BYTES;
32}
Guy Schalnat51f0eb41995-09-26 05:22:39 -050033#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050034
Guy Schalnat51f0eb41995-09-26 05:22:39 -050035#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
Guy Schalnat0d580581995-07-20 02:43:20 -050036/* turn on pixel packing */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050037void PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -060038png_set_packing(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -050039{
Andreas Dilger47a0c421997-05-16 02:46:07 -050040 png_debug(1, "in png_set_packing\n");
Guy Schalnat0d580581995-07-20 02:43:20 -050041 if (png_ptr->bit_depth < 8)
42 {
43 png_ptr->transformations |= PNG_PACK;
44 png_ptr->usr_bit_depth = 8;
45 }
46}
Guy Schalnat51f0eb41995-09-26 05:22:39 -050047#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050048
Andreas Dilger47a0c421997-05-16 02:46:07 -050049#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
50/* turn on packed pixel swapping */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050051void PNGAPI
Andreas Dilger47a0c421997-05-16 02:46:07 -050052png_set_packswap(png_structp png_ptr)
53{
54 png_debug(1, "in png_set_packswap\n");
55 if (png_ptr->bit_depth < 8)
56 png_ptr->transformations |= PNG_PACKSWAP;
57}
58#endif
59
Guy Schalnat51f0eb41995-09-26 05:22:39 -050060#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050061void PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -060062png_set_shift(png_structp png_ptr, png_color_8p true_bits)
Guy Schalnat0d580581995-07-20 02:43:20 -050063{
Andreas Dilger47a0c421997-05-16 02:46:07 -050064 png_debug(1, "in png_set_shift\n");
Guy Schalnat0d580581995-07-20 02:43:20 -050065 png_ptr->transformations |= PNG_SHIFT;
66 png_ptr->shift = *true_bits;
67}
Guy Schalnat51f0eb41995-09-26 05:22:39 -050068#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050069
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -060070#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
71 defined(PNG_WRITE_INTERLACING_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050072int PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -060073png_set_interlace_handling(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -050074{
Andreas Dilger47a0c421997-05-16 02:46:07 -050075 png_debug(1, "in png_set_interlace handling\n");
Guy Schalnat0d580581995-07-20 02:43:20 -050076 if (png_ptr->interlaced)
77 {
78 png_ptr->transformations |= PNG_INTERLACE;
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -060079 return (7);
Guy Schalnat0d580581995-07-20 02:43:20 -050080 }
81
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -060082 return (1);
Guy Schalnat0d580581995-07-20 02:43:20 -050083}
Guy Schalnat51f0eb41995-09-26 05:22:39 -050084#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050085
Guy Schalnat51f0eb41995-09-26 05:22:39 -050086#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -050087/* Add a filler byte on read, or remove a filler or alpha byte on write.
88 * The filler type has changed in v0.95 to allow future 2-byte fillers
Glenn Randers-Pehrson8686fff1998-05-21 09:27:50 -050089 * for 48-bit input data, as well as to avoid problems with some compilers
90 * that don't like bytes as parameters.
Andreas Dilger47a0c421997-05-16 02:46:07 -050091 */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050092void PNGAPI
Andreas Dilger47a0c421997-05-16 02:46:07 -050093png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
Guy Schalnat0d580581995-07-20 02:43:20 -050094{
Andreas Dilger47a0c421997-05-16 02:46:07 -050095 png_debug(1, "in png_set_filler\n");
Guy Schalnat51f0eb41995-09-26 05:22:39 -050096 png_ptr->transformations |= PNG_FILLER;
Andreas Dilger47a0c421997-05-16 02:46:07 -050097 png_ptr->filler = (png_byte)filler;
Guy Schalnate5a37791996-06-05 15:50:50 -050098 if (filler_loc == PNG_FILLER_AFTER)
99 png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
100 else
101 png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600102
103 /* This should probably go in the "do_filler" routine.
104 * I attempted to do that in libpng-1.0.1a but that caused problems
105 * so I restored it in libpng-1.0.2a
106 */
107
108 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
109 {
110 png_ptr->usr_channels = 4;
111 }
112
113 /* Also I added this in libpng-1.0.2a (what happens when we expand
114 * a less-than-8-bit grayscale to GA? */
115
116 if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
117 {
118 png_ptr->usr_channels = 2;
119 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500120}
Andreas Dilger47a0c421997-05-16 02:46:07 -0500121#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500122
Andreas Dilger47a0c421997-05-16 02:46:07 -0500123#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
124 defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500125void PNGAPI
Andreas Dilger47a0c421997-05-16 02:46:07 -0500126png_set_swap_alpha(png_structp png_ptr)
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500127{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500128 png_debug(1, "in png_set_swap_alpha\n");
129 png_ptr->transformations |= PNG_SWAP_ALPHA;
Guy Schalnat0d580581995-07-20 02:43:20 -0500130}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500131#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500132
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600133#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
134 defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500135void PNGAPI
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600136png_set_invert_alpha(png_structp png_ptr)
137{
138 png_debug(1, "in png_set_invert_alpha\n");
139 png_ptr->transformations |= PNG_INVERT_ALPHA;
140}
141#endif
142
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500143#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500144void PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -0600145png_set_invert_mono(png_structp png_ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -0500146{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500147 png_debug(1, "in png_set_invert_mono\n");
Guy Schalnat0d580581995-07-20 02:43:20 -0500148 png_ptr->transformations |= PNG_INVERT_MONO;
149}
150
Glenn Randers-Pehrson345bc271998-06-14 14:43:31 -0500151/* invert monochrome grayscale data */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500152void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -0600153png_do_invert(png_row_infop row_info, png_bytep row)
Guy Schalnat0d580581995-07-20 02:43:20 -0500154{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500155 png_debug(1, "in png_do_invert\n");
156 if (row_info->bit_depth == 1 &&
157#if defined(PNG_USELESS_TESTS_SUPPORTED)
158 row != NULL && row_info != NULL &&
159#endif
160 row_info->color_type == PNG_COLOR_TYPE_GRAY)
Guy Schalnat0d580581995-07-20 02:43:20 -0500161 {
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500162 png_bytep rp = row;
Guy Schalnat0d580581995-07-20 02:43:20 -0500163 png_uint_32 i;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500164 png_uint_32 istop = row_info->rowbytes;
Guy Schalnat0d580581995-07-20 02:43:20 -0500165
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500166 for (i = 0; i < istop; i++)
Guy Schalnat0d580581995-07-20 02:43:20 -0500167 {
Glenn Randers-Pehrson8686fff1998-05-21 09:27:50 -0500168 *rp = (png_byte)(~(*rp));
169 rp++;
Guy Schalnat0d580581995-07-20 02:43:20 -0500170 }
171 }
172}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500173#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500174
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500175#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
Guy Schalnat0d580581995-07-20 02:43:20 -0500176/* swaps byte order on 16 bit depth images */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500177void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -0600178png_do_swap(png_row_infop row_info, png_bytep row)
Guy Schalnat0d580581995-07-20 02:43:20 -0500179{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500180 png_debug(1, "in png_do_swap\n");
181 if (
182#if defined(PNG_USELESS_TESTS_SUPPORTED)
183 row != NULL && row_info != NULL &&
184#endif
185 row_info->bit_depth == 16)
Guy Schalnat0d580581995-07-20 02:43:20 -0500186 {
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500187 png_bytep rp = row;
Guy Schalnat0d580581995-07-20 02:43:20 -0500188 png_uint_32 i;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500189 png_uint_32 istop= row_info->width * row_info->channels;
Guy Schalnat0d580581995-07-20 02:43:20 -0500190
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500191 for (i = 0; i < istop; i++, rp += 2)
Guy Schalnat0d580581995-07-20 02:43:20 -0500192 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500193 png_byte t = *rp;
Guy Schalnat0d580581995-07-20 02:43:20 -0500194 *rp = *(rp + 1);
195 *(rp + 1) = t;
196 }
197 }
198}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500199#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500200
Andreas Dilger47a0c421997-05-16 02:46:07 -0500201#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
202static png_byte onebppswaptable[256] = {
203 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
204 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
205 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
206 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
207 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
208 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
209 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
210 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
211 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
212 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
213 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
214 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
215 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
216 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
217 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
218 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
219 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
220 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
221 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
222 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
223 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
224 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
225 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
226 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
227 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
228 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
229 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
230 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
231 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
232 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
233 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
234 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
235};
236
237static png_byte twobppswaptable[256] = {
238 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
239 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
240 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
241 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
242 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
243 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
244 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
245 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
246 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
247 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
248 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
249 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
250 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
251 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
252 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
253 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
254 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
255 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
256 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
257 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
258 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
259 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
260 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
261 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
262 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
263 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
264 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
265 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
266 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
267 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
268 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
269 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
270};
271
272static png_byte fourbppswaptable[256] = {
273 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
274 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
275 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
276 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
277 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
278 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
279 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
280 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
281 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
282 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
283 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
284 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
285 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
286 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
287 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
288 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
289 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
290 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
291 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
292 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
293 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
294 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
295 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
296 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
297 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
298 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
299 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
300 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
301 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
302 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
303 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
304 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
305};
306
307/* swaps pixel packing order within bytes */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500308void /* PRIVATE */
Andreas Dilger47a0c421997-05-16 02:46:07 -0500309png_do_packswap(png_row_infop row_info, png_bytep row)
Guy Schalnat0d580581995-07-20 02:43:20 -0500310{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500311 png_debug(1, "in png_do_packswap\n");
312 if (
313#if defined(PNG_USELESS_TESTS_SUPPORTED)
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600314 row != NULL && row_info != NULL &&
Andreas Dilger47a0c421997-05-16 02:46:07 -0500315#endif
316 row_info->bit_depth < 8)
Guy Schalnat0d580581995-07-20 02:43:20 -0500317 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500318 png_bytep rp, end, table;
Guy Schalnat0d580581995-07-20 02:43:20 -0500319
Andreas Dilger47a0c421997-05-16 02:46:07 -0500320 end = row + row_info->rowbytes;
321
322 if (row_info->bit_depth == 1)
323 table = onebppswaptable;
324 else if (row_info->bit_depth == 2)
325 table = twobppswaptable;
326 else if (row_info->bit_depth == 4)
327 table = fourbppswaptable;
328 else
329 return;
330
331 for (rp = row; rp < end; rp++)
332 *rp = table[*rp];
333 }
334}
335#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
336
337#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
338 defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
339/* remove filler or alpha byte(s) */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500340void /* PRIVATE */
Andreas Dilger47a0c421997-05-16 02:46:07 -0500341png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
342{
343 png_debug(1, "in png_do_strip_filler\n");
344#if defined(PNG_USELESS_TESTS_SUPPORTED)
345 if (row != NULL && row_info != NULL)
346#endif
347 {
348/*
349 if (row_info->color_type == PNG_COLOR_TYPE_RGB ||
350 row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
351*/
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500352 png_bytep sp=row;
353 png_bytep dp=row;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500354 png_uint_32 row_width=row_info->width;
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500355 png_uint_32 i;
356
Andreas Dilger47a0c421997-05-16 02:46:07 -0500357 if (row_info->channels == 4)
358 {
359 if (row_info->bit_depth == 8)
Guy Schalnat0d580581995-07-20 02:43:20 -0500360 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500361 /* This converts from RGBX or RGBA to RGB */
362 if (flags & PNG_FLAG_FILLER_AFTER)
363 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500364 dp+=3; sp+=4;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500365 for (i = 1; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500366 {
367 *dp++ = *sp++;
368 *dp++ = *sp++;
369 *dp++ = *sp++;
370 sp++;
371 }
372 }
373 /* This converts from XRGB or ARGB to RGB */
374 else
375 {
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500376 for (i = 0; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500377 {
378 sp++;
379 *dp++ = *sp++;
380 *dp++ = *sp++;
381 *dp++ = *sp++;
382 }
383 }
384 row_info->pixel_depth = 24;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500385 row_info->rowbytes = row_width * 3;
Guy Schalnat0d580581995-07-20 02:43:20 -0500386 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500387 else /* if (row_info->bit_depth == 16) */
388 {
389 if (flags & PNG_FLAG_FILLER_AFTER)
390 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500391 /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500392 sp += 8; dp += 6;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500393 for (i = 1; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500394 {
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500395 /* This could be (although png_memcpy is probably slower):
Andreas Dilger47a0c421997-05-16 02:46:07 -0500396 png_memcpy(dp, sp, 6);
397 sp += 8;
398 dp += 6;
399 */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500400
Andreas Dilger47a0c421997-05-16 02:46:07 -0500401 *dp++ = *sp++;
402 *dp++ = *sp++;
403 *dp++ = *sp++;
404 *dp++ = *sp++;
405 *dp++ = *sp++;
406 *dp++ = *sp++;
407 sp += 2;
408 }
409 }
410 else
411 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500412 /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500413 for (i = 0; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500414 {
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500415 /* This could be (although png_memcpy is probably slower):
Andreas Dilger47a0c421997-05-16 02:46:07 -0500416 png_memcpy(dp, sp, 6);
417 sp += 8;
418 dp += 6;
419 */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500420
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500421 sp+=2;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500422 *dp++ = *sp++;
423 *dp++ = *sp++;
424 *dp++ = *sp++;
425 *dp++ = *sp++;
426 *dp++ = *sp++;
427 *dp++ = *sp++;
428 }
429 }
430 row_info->pixel_depth = 48;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500431 row_info->rowbytes = row_width * 6;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500432 }
433 row_info->channels = 3;
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500434 row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
Guy Schalnat0d580581995-07-20 02:43:20 -0500435 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500436/*
437 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY ||
438 row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
439*/
440 else if (row_info->channels == 2)
Guy Schalnat0d580581995-07-20 02:43:20 -0500441 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500442 if (row_info->bit_depth == 8)
Guy Schalnat0d580581995-07-20 02:43:20 -0500443 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500444 /* This converts from GX or GA to G */
445 if (flags & PNG_FLAG_FILLER_AFTER)
446 {
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500447 for (i = 0; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500448 {
449 *dp++ = *sp++;
450 sp++;
451 }
452 }
453 /* This converts from XG or AG to G */
454 else
455 {
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500456 for (i = 0; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500457 {
458 sp++;
459 *dp++ = *sp++;
460 }
461 }
462 row_info->pixel_depth = 8;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500463 row_info->rowbytes = row_width;
Guy Schalnat0d580581995-07-20 02:43:20 -0500464 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500465 else /* if (row_info->bit_depth == 16) */
466 {
467 if (flags & PNG_FLAG_FILLER_AFTER)
468 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500469 /* This converts from GGXX or GGAA to GG */
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500470 sp += 4; dp += 2;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500471 for (i = 1; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500472 {
473 *dp++ = *sp++;
474 *dp++ = *sp++;
475 sp += 2;
476 }
477 }
478 else
479 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500480 /* This converts from XXGG or AAGG to GG */
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500481 for (i = 0; i < row_width; i++)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500482 {
483 sp += 2;
484 *dp++ = *sp++;
485 *dp++ = *sp++;
486 }
487 }
488 row_info->pixel_depth = 16;
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500489 row_info->rowbytes = row_width * 2;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500490 }
491 row_info->channels = 1;
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500492 row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
Guy Schalnat0d580581995-07-20 02:43:20 -0500493 }
494 }
495}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500496#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500497
Andreas Dilger47a0c421997-05-16 02:46:07 -0500498#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
499/* swaps red and blue bytes within a pixel */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500500void /* PRIVATE */
Andreas Dilger47a0c421997-05-16 02:46:07 -0500501png_do_bgr(png_row_infop row_info, png_bytep row)
502{
503 png_debug(1, "in png_do_bgr\n");
504 if (
505#if defined(PNG_USELESS_TESTS_SUPPORTED)
506 row != NULL && row_info != NULL &&
507#endif
508 (row_info->color_type & PNG_COLOR_MASK_COLOR))
509 {
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500510 png_uint_32 row_width = row_info->width;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500511 if (row_info->bit_depth == 8)
512 {
513 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
514 {
515 png_bytep rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500516 png_uint_32 i;
517
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500518 for (i = 0, rp = row; i < row_width; i++, rp += 3)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500519 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500520 png_byte save = *rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500521 *rp = *(rp + 2);
522 *(rp + 2) = save;
523 }
524 }
525 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
526 {
527 png_bytep rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500528 png_uint_32 i;
529
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500530 for (i = 0, rp = row; i < row_width; i++, rp += 4)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500531 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500532 png_byte save = *rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500533 *rp = *(rp + 2);
534 *(rp + 2) = save;
535 }
536 }
537 }
538 else if (row_info->bit_depth == 16)
539 {
540 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
541 {
542 png_bytep rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500543 png_uint_32 i;
544
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500545 for (i = 0, rp = row; i < row_width; i++, rp += 6)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500546 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500547 png_byte save = *rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500548 *rp = *(rp + 4);
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500549 *(rp + 4) = save;
550 save = *(rp + 1);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500551 *(rp + 1) = *(rp + 5);
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500552 *(rp + 5) = save;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500553 }
554 }
555 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
556 {
557 png_bytep rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500558 png_uint_32 i;
559
Glenn Randers-Pehrson1d963611998-05-02 12:52:25 -0500560 for (i = 0, rp = row; i < row_width; i++, rp += 8)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500561 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500562 png_byte save = *rp;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500563 *rp = *(rp + 4);
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500564 *(rp + 4) = save;
565 save = *(rp + 1);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500566 *(rp + 1) = *(rp + 5);
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500567 *(rp + 5) = save;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500568 }
569 }
570 }
571 }
572}
573#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
574
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500575#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -0500576 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
577 defined(PNG_LEGACY_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500578void PNGAPI
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500579png_set_user_transform_info(png_structp png_ptr, png_voidp
580 user_transform_ptr, int user_transform_depth, int user_transform_channels)
581{
582 png_debug(1, "in png_set_user_transform_info\n");
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -0500583#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500584 png_ptr->user_transform_ptr = user_transform_ptr;
Glenn Randers-Pehrsonab1e5831999-10-06 04:57:42 -0500585 png_ptr->user_transform_depth = (png_byte)user_transform_depth;
586 png_ptr->user_transform_channels = (png_byte)user_transform_channels;
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -0500587#else
588 if(user_transform_ptr || user_transform_depth || user_transform_channels)
589 png_warning(png_ptr,
590 "This version of libpng does not support user transform info");
591#endif
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500592}
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -0500593#endif
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500594
595/* This function returns a pointer to the user_transform_ptr associated with
596 * the user transform functions. The application should free any memory
597 * associated with this pointer before png_write_destroy and png_read_destroy
598 * are called.
599 */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500600png_voidp PNGAPI
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500601png_get_user_transform_ptr(png_structp png_ptr)
602{
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -0500603#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500604 return ((png_voidp)png_ptr->user_transform_ptr);
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -0500605#else
606 if(png_ptr)
607 return (NULL);
608 return (NULL);
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500609#endif
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -0500610}
Glenn Randers-Pehrson2ad31ae2000-12-15 08:54:42 -0600611