Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
96 giacomo 1
 
2
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
3
 *
4
 * libpng 1.2.5 - October 3, 2002
5
 * For conditions of distribution and use, see copyright notice in png.h
6
 * Copyright (c) 1998-2002 Glenn Randers-Pehrson
7
 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8
 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
9
 */
10
 
11
#define PNG_INTERNAL
12
#include "png.h"
13
 
14
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
15
/* turn on BGR-to-RGB mapping */
16
void PNGAPI
17
png_set_bgr(png_structp png_ptr)
18
{
19
   png_debug(1, "in png_set_bgr\n");
20
   png_ptr->transformations |= PNG_BGR;
21
}
22
#endif
23
 
24
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
25
/* turn on 16 bit byte swapping */
26
void PNGAPI
27
png_set_swap(png_structp png_ptr)
28
{
29
   png_debug(1, "in png_set_swap\n");
30
   if (png_ptr->bit_depth == 16)
31
      png_ptr->transformations |= PNG_SWAP_BYTES;
32
}
33
#endif
34
 
35
#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
36
/* turn on pixel packing */
37
void PNGAPI
38
png_set_packing(png_structp png_ptr)
39
{
40
   png_debug(1, "in png_set_packing\n");
41
   if (png_ptr->bit_depth < 8)
42
   {
43
      png_ptr->transformations |= PNG_PACK;
44
      png_ptr->usr_bit_depth = 8;
45
   }
46
}
47
#endif
48
 
49
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
50
/* turn on packed pixel swapping */
51
void PNGAPI
52
png_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
 
60
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
61
void PNGAPI
62
png_set_shift(png_structp png_ptr, png_color_8p true_bits)
63
{
64
   png_debug(1, "in png_set_shift\n");
65
   png_ptr->transformations |= PNG_SHIFT;
66
   png_ptr->shift = *true_bits;
67
}
68
#endif
69
 
70
#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
71
    defined(PNG_WRITE_INTERLACING_SUPPORTED)
72
int PNGAPI
73
png_set_interlace_handling(png_structp png_ptr)
74
{
75
   png_debug(1, "in png_set_interlace handling\n");
76
   if (png_ptr->interlaced)
77
   {
78
      png_ptr->transformations |= PNG_INTERLACE;
79
      return (7);
80
   }
81
 
82
   return (1);
83
}
84
#endif
85
 
86
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
87
/* 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
89
 * for 48-bit input data, as well as to avoid problems with some compilers
90
 * that don't like bytes as parameters.
91
 */
92
void PNGAPI
93
png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
94
{
95
   png_debug(1, "in png_set_filler\n");
96
   png_ptr->transformations |= PNG_FILLER;
97
   png_ptr->filler = (png_byte)filler;
98
   if (filler_loc == PNG_FILLER_AFTER)
99
      png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
100
   else
101
      png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
102
 
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
   }
120
}
121
#endif
122
 
123
#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
124
    defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
125
void PNGAPI
126
png_set_swap_alpha(png_structp png_ptr)
127
{
128
   png_debug(1, "in png_set_swap_alpha\n");
129
   png_ptr->transformations |= PNG_SWAP_ALPHA;
130
}
131
#endif
132
 
133
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
134
    defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
135
void PNGAPI
136
png_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
 
143
#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
144
void PNGAPI
145
png_set_invert_mono(png_structp png_ptr)
146
{
147
   png_debug(1, "in png_set_invert_mono\n");
148
   png_ptr->transformations |= PNG_INVERT_MONO;
149
}
150
 
151
/* invert monochrome grayscale data */
152
void /* PRIVATE */
153
png_do_invert(png_row_infop row_info, png_bytep row)
154
{
155
   png_debug(1, "in png_do_invert\n");
156
  /* This test removed from libpng version 1.0.13 and 1.2.0:
157
   *   if (row_info->bit_depth == 1 &&
158
   */
159
#if defined(PNG_USELESS_TESTS_SUPPORTED)
160
   if (row == NULL || row_info == NULL)
161
     return;
162
#endif
163
   if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
164
   {
165
      png_bytep rp = row;
166
      png_uint_32 i;
167
      png_uint_32 istop = row_info->rowbytes;
168
 
169
      for (i = 0; i < istop; i++)
170
      {
171
         *rp = (png_byte)(~(*rp));
172
         rp++;
173
      }
174
   }
175
   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
176
      row_info->bit_depth == 8)
177
   {
178
      png_bytep rp = row;
179
      png_uint_32 i;
180
      png_uint_32 istop = row_info->rowbytes;
181
 
182
      for (i = 0; i < istop; i+=2)
183
      {
184
         *rp = (png_byte)(~(*rp));
185
         rp+=2;
186
      }
187
   }
188
   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
189
      row_info->bit_depth == 16)
190
   {
191
      png_bytep rp = row;
192
      png_uint_32 i;
193
      png_uint_32 istop = row_info->rowbytes;
194
 
195
      for (i = 0; i < istop; i+=4)
196
      {
197
         *rp = (png_byte)(~(*rp));
198
         *(rp+1) = (png_byte)(~(*(rp+1)));
199
         rp+=4;
200
      }
201
   }
202
}
203
#endif
204
 
205
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
206
/* swaps byte order on 16 bit depth images */
207
void /* PRIVATE */
208
png_do_swap(png_row_infop row_info, png_bytep row)
209
{
210
   png_debug(1, "in png_do_swap\n");
211
   if (
212
#if defined(PNG_USELESS_TESTS_SUPPORTED)
213
       row != NULL && row_info != NULL &&
214
#endif
215
       row_info->bit_depth == 16)
216
   {
217
      png_bytep rp = row;
218
      png_uint_32 i;
219
      png_uint_32 istop= row_info->width * row_info->channels;
220
 
221
      for (i = 0; i < istop; i++, rp += 2)
222
      {
223
         png_byte t = *rp;
224
         *rp = *(rp + 1);
225
         *(rp + 1) = t;
226
      }
227
   }
228
}
229
#endif
230
 
231
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
232
static png_byte onebppswaptable[256] = {
233
   0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
234
   0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
235
   0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
236
   0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
237
   0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
238
   0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
239
   0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
240
   0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
241
   0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
242
   0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
243
   0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
244
   0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
245
   0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
246
   0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
247
   0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
248
   0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
249
   0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
250
   0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
251
   0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
252
   0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
253
   0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
254
   0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
255
   0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
256
   0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
257
   0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
258
   0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
259
   0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
260
   0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
261
   0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
262
   0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
263
   0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
264
   0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
265
};
266
 
267
static png_byte twobppswaptable[256] = {
268
   0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
269
   0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
270
   0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
271
   0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
272
   0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
273
   0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
274
   0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
275
   0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
276
   0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
277
   0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
278
   0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
279
   0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
280
   0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
281
   0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
282
   0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
283
   0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
284
   0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
285
   0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
286
   0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
287
   0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
288
   0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
289
   0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
290
   0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
291
   0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
292
   0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
293
   0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
294
   0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
295
   0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
296
   0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
297
   0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
298
   0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
299
   0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
300
};
301
 
302
static png_byte fourbppswaptable[256] = {
303
   0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
304
   0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
305
   0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
306
   0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
307
   0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
308
   0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
309
   0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
310
   0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
311
   0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
312
   0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
313
   0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
314
   0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
315
   0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
316
   0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
317
   0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
318
   0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
319
   0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
320
   0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
321
   0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
322
   0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
323
   0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
324
   0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
325
   0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
326
   0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
327
   0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
328
   0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
329
   0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
330
   0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
331
   0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
332
   0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
333
   0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
334
   0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
335
};
336
 
337
/* swaps pixel packing order within bytes */
338
void /* PRIVATE */
339
png_do_packswap(png_row_infop row_info, png_bytep row)
340
{
341
   png_debug(1, "in png_do_packswap\n");
342
   if (
343
#if defined(PNG_USELESS_TESTS_SUPPORTED)
344
       row != NULL && row_info != NULL &&
345
#endif
346
       row_info->bit_depth < 8)
347
   {
348
      png_bytep rp, end, table;
349
 
350
      end = row + row_info->rowbytes;
351
 
352
      if (row_info->bit_depth == 1)
353
         table = onebppswaptable;
354
      else if (row_info->bit_depth == 2)
355
         table = twobppswaptable;
356
      else if (row_info->bit_depth == 4)
357
         table = fourbppswaptable;
358
      else
359
         return;
360
 
361
      for (rp = row; rp < end; rp++)
362
         *rp = table[*rp];
363
   }
364
}
365
#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
366
 
367
#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
368
    defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
369
/* remove filler or alpha byte(s) */
370
void /* PRIVATE */
371
png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
372
{
373
   png_debug(1, "in png_do_strip_filler\n");
374
#if defined(PNG_USELESS_TESTS_SUPPORTED)
375
   if (row != NULL && row_info != NULL)
376
#endif
377
   {
378
/*
379
      if (row_info->color_type == PNG_COLOR_TYPE_RGB ||
380
          row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
381
*/
382
      png_bytep sp=row;
383
      png_bytep dp=row;
384
      png_uint_32 row_width=row_info->width;
385
      png_uint_32 i;
386
 
387
      if (row_info->channels == 4)
388
      {
389
         if (row_info->bit_depth == 8)
390
         {
391
            /* This converts from RGBX or RGBA to RGB */
392
            if (flags & PNG_FLAG_FILLER_AFTER)
393
            {
394
               dp+=3; sp+=4;
395
               for (i = 1; i < row_width; i++)
396
               {
397
                  *dp++ = *sp++;
398
                  *dp++ = *sp++;
399
                  *dp++ = *sp++;
400
                  sp++;
401
               }
402
            }
403
            /* This converts from XRGB or ARGB to RGB */
404
            else
405
            {
406
               for (i = 0; i < row_width; i++)
407
               {
408
                  sp++;
409
                  *dp++ = *sp++;
410
                  *dp++ = *sp++;
411
                  *dp++ = *sp++;
412
               }
413
            }
414
            row_info->pixel_depth = 24;
415
            row_info->rowbytes = row_width * 3;
416
         }
417
         else /* if (row_info->bit_depth == 16) */
418
         {
419
            if (flags & PNG_FLAG_FILLER_AFTER)
420
            {
421
               /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
422
               sp += 8; dp += 6;
423
               for (i = 1; i < row_width; i++)
424
               {
425
                  /* This could be (although png_memcpy is probably slower):
426
                  png_memcpy(dp, sp, 6);
427
                  sp += 8;
428
                  dp += 6;
429
                  */
430
 
431
                  *dp++ = *sp++;
432
                  *dp++ = *sp++;
433
                  *dp++ = *sp++;
434
                  *dp++ = *sp++;
435
                  *dp++ = *sp++;
436
                  *dp++ = *sp++;
437
                  sp += 2;
438
               }
439
            }
440
            else
441
            {
442
               /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
443
               for (i = 0; i < row_width; i++)
444
               {
445
                  /* This could be (although png_memcpy is probably slower):
446
                  png_memcpy(dp, sp, 6);
447
                  sp += 8;
448
                  dp += 6;
449
                  */
450
 
451
                  sp+=2;
452
                  *dp++ = *sp++;
453
                  *dp++ = *sp++;
454
                  *dp++ = *sp++;
455
                  *dp++ = *sp++;
456
                  *dp++ = *sp++;
457
                  *dp++ = *sp++;
458
               }
459
            }
460
            row_info->pixel_depth = 48;
461
            row_info->rowbytes = row_width * 6;
462
         }
463
         row_info->channels = 3;
464
         row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
465
      }
466
/*
467
      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY ||
468
               row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
469
*/
470
      else if (row_info->channels == 2)
471
      {
472
         if (row_info->bit_depth == 8)
473
         {
474
            /* This converts from GX or GA to G */
475
            if (flags & PNG_FLAG_FILLER_AFTER)
476
            {
477
               for (i = 0; i < row_width; i++)
478
               {
479
                  *dp++ = *sp++;
480
                  sp++;
481
               }
482
            }
483
            /* This converts from XG or AG to G */
484
            else
485
            {
486
               for (i = 0; i < row_width; i++)
487
               {
488
                  sp++;
489
                  *dp++ = *sp++;
490
               }
491
            }
492
            row_info->pixel_depth = 8;
493
            row_info->rowbytes = row_width;
494
         }
495
         else /* if (row_info->bit_depth == 16) */
496
         {
497
            if (flags & PNG_FLAG_FILLER_AFTER)
498
            {
499
               /* This converts from GGXX or GGAA to GG */
500
               sp += 4; dp += 2;
501
               for (i = 1; i < row_width; i++)
502
               {
503
                  *dp++ = *sp++;
504
                  *dp++ = *sp++;
505
                  sp += 2;
506
               }
507
            }
508
            else
509
            {
510
               /* This converts from XXGG or AAGG to GG */
511
               for (i = 0; i < row_width; i++)
512
               {
513
                  sp += 2;
514
                  *dp++ = *sp++;
515
                  *dp++ = *sp++;
516
               }
517
            }
518
            row_info->pixel_depth = 16;
519
            row_info->rowbytes = row_width * 2;
520
         }
521
         row_info->channels = 1;
522
         row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
523
      }
524
   }
525
}
526
#endif
527
 
528
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
529
/* swaps red and blue bytes within a pixel */
530
void /* PRIVATE */
531
png_do_bgr(png_row_infop row_info, png_bytep row)
532
{
533
   png_debug(1, "in png_do_bgr\n");
534
   if (
535
#if defined(PNG_USELESS_TESTS_SUPPORTED)
536
       row != NULL && row_info != NULL &&
537
#endif
538
       (row_info->color_type & PNG_COLOR_MASK_COLOR))
539
   {
540
      png_uint_32 row_width = row_info->width;
541
      if (row_info->bit_depth == 8)
542
      {
543
         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
544
         {
545
            png_bytep rp;
546
            png_uint_32 i;
547
 
548
            for (i = 0, rp = row; i < row_width; i++, rp += 3)
549
            {
550
               png_byte save = *rp;
551
               *rp = *(rp + 2);
552
               *(rp + 2) = save;
553
            }
554
         }
555
         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
556
         {
557
            png_bytep rp;
558
            png_uint_32 i;
559
 
560
            for (i = 0, rp = row; i < row_width; i++, rp += 4)
561
            {
562
               png_byte save = *rp;
563
               *rp = *(rp + 2);
564
               *(rp + 2) = save;
565
            }
566
         }
567
      }
568
      else if (row_info->bit_depth == 16)
569
      {
570
         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
571
         {
572
            png_bytep rp;
573
            png_uint_32 i;
574
 
575
            for (i = 0, rp = row; i < row_width; i++, rp += 6)
576
            {
577
               png_byte save = *rp;
578
               *rp = *(rp + 4);
579
               *(rp + 4) = save;
580
               save = *(rp + 1);
581
               *(rp + 1) = *(rp + 5);
582
               *(rp + 5) = save;
583
            }
584
         }
585
         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
586
         {
587
            png_bytep rp;
588
            png_uint_32 i;
589
 
590
            for (i = 0, rp = row; i < row_width; i++, rp += 8)
591
            {
592
               png_byte save = *rp;
593
               *rp = *(rp + 4);
594
               *(rp + 4) = save;
595
               save = *(rp + 1);
596
               *(rp + 1) = *(rp + 5);
597
               *(rp + 5) = save;
598
            }
599
         }
600
      }
601
   }
602
}
603
#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
604
 
605
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
606
    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
607
    defined(PNG_LEGACY_SUPPORTED)
608
void PNGAPI
609
png_set_user_transform_info(png_structp png_ptr, png_voidp
610
   user_transform_ptr, int user_transform_depth, int user_transform_channels)
611
{
612
   png_debug(1, "in png_set_user_transform_info\n");
613
#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
614
   png_ptr->user_transform_ptr = user_transform_ptr;
615
   png_ptr->user_transform_depth = (png_byte)user_transform_depth;
616
   png_ptr->user_transform_channels = (png_byte)user_transform_channels;
617
#else
618
   if(user_transform_ptr || user_transform_depth || user_transform_channels)
619
      png_warning(png_ptr,
620
        "This version of libpng does not support user transform info");
621
#endif
622
}
623
#endif
624
 
625
/* This function returns a pointer to the user_transform_ptr associated with
626
 * the user transform functions.  The application should free any memory
627
 * associated with this pointer before png_write_destroy and png_read_destroy
628
 * are called.
629
 */
630
png_voidp PNGAPI
631
png_get_user_transform_ptr(png_structp png_ptr)
632
{
633
#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
634
   return ((png_voidp)png_ptr->user_transform_ptr);
635
#else
636
   if(png_ptr)
637
     return (NULL);
638
   return (NULL);
639
#endif
640
}