Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/native/libsplashscreen/libpng/pngtrans.c
41155 views
1
/*
2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3
*
4
* This code is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License version 2 only, as
6
* published by the Free Software Foundation. Oracle designates this
7
* particular file as subject to the "Classpath" exception as provided
8
* by Oracle in the LICENSE file that accompanied this code.
9
*
10
* This code is distributed in the hope that it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* version 2 for more details (a copy is included in the LICENSE file that
14
* accompanied this code).
15
*
16
* You should have received a copy of the GNU General Public License version
17
* 2 along with this work; if not, write to the Free Software Foundation,
18
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
*
20
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21
* or visit www.oracle.com if you need additional information or have any
22
* questions.
23
*/
24
25
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
26
*
27
* This file is available under and governed by the GNU General Public
28
* License version 2 only, as published by the Free Software Foundation.
29
* However, the following notice accompanied the original version of this
30
* file and, per its terms, should not be removed:
31
*
32
* Copyright (c) 2018 Cosmin Truta
33
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
34
* Copyright (c) 1996-1997 Andreas Dilger
35
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
36
*
37
* This code is released under the libpng license.
38
* For conditions of distribution and use, see the disclaimer
39
* and license in png.h
40
*/
41
42
#include "pngpriv.h"
43
44
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
45
46
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
47
/* Turn on BGR-to-RGB mapping */
48
void PNGAPI
49
png_set_bgr(png_structrp png_ptr)
50
{
51
png_debug(1, "in png_set_bgr");
52
53
if (png_ptr == NULL)
54
return;
55
56
png_ptr->transformations |= PNG_BGR;
57
}
58
#endif
59
60
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
61
/* Turn on 16-bit byte swapping */
62
void PNGAPI
63
png_set_swap(png_structrp png_ptr)
64
{
65
png_debug(1, "in png_set_swap");
66
67
if (png_ptr == NULL)
68
return;
69
70
if (png_ptr->bit_depth == 16)
71
png_ptr->transformations |= PNG_SWAP_BYTES;
72
}
73
#endif
74
75
#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
76
/* Turn on pixel packing */
77
void PNGAPI
78
png_set_packing(png_structrp png_ptr)
79
{
80
png_debug(1, "in png_set_packing");
81
82
if (png_ptr == NULL)
83
return;
84
85
if (png_ptr->bit_depth < 8)
86
{
87
png_ptr->transformations |= PNG_PACK;
88
# ifdef PNG_WRITE_SUPPORTED
89
png_ptr->usr_bit_depth = 8;
90
# endif
91
}
92
}
93
#endif
94
95
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
96
/* Turn on packed pixel swapping */
97
void PNGAPI
98
png_set_packswap(png_structrp png_ptr)
99
{
100
png_debug(1, "in png_set_packswap");
101
102
if (png_ptr == NULL)
103
return;
104
105
if (png_ptr->bit_depth < 8)
106
png_ptr->transformations |= PNG_PACKSWAP;
107
}
108
#endif
109
110
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
111
void PNGAPI
112
png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits)
113
{
114
png_debug(1, "in png_set_shift");
115
116
if (png_ptr == NULL)
117
return;
118
119
png_ptr->transformations |= PNG_SHIFT;
120
png_ptr->shift = *true_bits;
121
}
122
#endif
123
124
#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
125
defined(PNG_WRITE_INTERLACING_SUPPORTED)
126
int PNGAPI
127
png_set_interlace_handling(png_structrp png_ptr)
128
{
129
png_debug(1, "in png_set_interlace handling");
130
131
if (png_ptr != 0 && png_ptr->interlaced != 0)
132
{
133
png_ptr->transformations |= PNG_INTERLACE;
134
return (7);
135
}
136
137
return (1);
138
}
139
#endif
140
141
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
142
/* Add a filler byte on read, or remove a filler or alpha byte on write.
143
* The filler type has changed in v0.95 to allow future 2-byte fillers
144
* for 48-bit input data, as well as to avoid problems with some compilers
145
* that don't like bytes as parameters.
146
*/
147
void PNGAPI
148
png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
149
{
150
png_debug(1, "in png_set_filler");
151
152
if (png_ptr == NULL)
153
return;
154
155
/* In libpng 1.6 it is possible to determine whether this is a read or write
156
* operation and therefore to do more checking here for a valid call.
157
*/
158
if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
159
{
160
# ifdef PNG_READ_FILLER_SUPPORTED
161
/* On read png_set_filler is always valid, regardless of the base PNG
162
* format, because other transformations can give a format where the
163
* filler code can execute (basically an 8 or 16-bit component RGB or G
164
* format.)
165
*
166
* NOTE: usr_channels is not used by the read code! (This has led to
167
* confusion in the past.) The filler is only used in the read code.
168
*/
169
png_ptr->filler = (png_uint_16)filler;
170
# else
171
png_app_error(png_ptr, "png_set_filler not supported on read");
172
PNG_UNUSED(filler) /* not used in the write case */
173
return;
174
# endif
175
}
176
177
else /* write */
178
{
179
# ifdef PNG_WRITE_FILLER_SUPPORTED
180
/* On write the usr_channels parameter must be set correctly at the
181
* start to record the number of channels in the app-supplied data.
182
*/
183
switch (png_ptr->color_type)
184
{
185
case PNG_COLOR_TYPE_RGB:
186
png_ptr->usr_channels = 4;
187
break;
188
189
case PNG_COLOR_TYPE_GRAY:
190
if (png_ptr->bit_depth >= 8)
191
{
192
png_ptr->usr_channels = 2;
193
break;
194
}
195
196
else
197
{
198
/* There simply isn't any code in libpng to strip out bits
199
* from bytes when the components are less than a byte in
200
* size!
201
*/
202
png_app_error(png_ptr,
203
"png_set_filler is invalid for"
204
" low bit depth gray output");
205
return;
206
}
207
208
default:
209
png_app_error(png_ptr,
210
"png_set_filler: inappropriate color type");
211
return;
212
}
213
# else
214
png_app_error(png_ptr, "png_set_filler not supported on write");
215
return;
216
# endif
217
}
218
219
/* Here on success - libpng supports the operation, set the transformation
220
* and the flag to say where the filler channel is.
221
*/
222
png_ptr->transformations |= PNG_FILLER;
223
224
if (filler_loc == PNG_FILLER_AFTER)
225
png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
226
227
else
228
png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
229
}
230
231
/* Added to libpng-1.2.7 */
232
void PNGAPI
233
png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
234
{
235
png_debug(1, "in png_set_add_alpha");
236
237
if (png_ptr == NULL)
238
return;
239
240
png_set_filler(png_ptr, filler, filler_loc);
241
/* The above may fail to do anything. */
242
if ((png_ptr->transformations & PNG_FILLER) != 0)
243
png_ptr->transformations |= PNG_ADD_ALPHA;
244
}
245
246
#endif
247
248
#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
249
defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
250
void PNGAPI
251
png_set_swap_alpha(png_structrp png_ptr)
252
{
253
png_debug(1, "in png_set_swap_alpha");
254
255
if (png_ptr == NULL)
256
return;
257
258
png_ptr->transformations |= PNG_SWAP_ALPHA;
259
}
260
#endif
261
262
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
263
defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
264
void PNGAPI
265
png_set_invert_alpha(png_structrp png_ptr)
266
{
267
png_debug(1, "in png_set_invert_alpha");
268
269
if (png_ptr == NULL)
270
return;
271
272
png_ptr->transformations |= PNG_INVERT_ALPHA;
273
}
274
#endif
275
276
#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
277
void PNGAPI
278
png_set_invert_mono(png_structrp png_ptr)
279
{
280
png_debug(1, "in png_set_invert_mono");
281
282
if (png_ptr == NULL)
283
return;
284
285
png_ptr->transformations |= PNG_INVERT_MONO;
286
}
287
288
/* Invert monochrome grayscale data */
289
void /* PRIVATE */
290
png_do_invert(png_row_infop row_info, png_bytep row)
291
{
292
png_debug(1, "in png_do_invert");
293
294
/* This test removed from libpng version 1.0.13 and 1.2.0:
295
* if (row_info->bit_depth == 1 &&
296
*/
297
if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
298
{
299
png_bytep rp = row;
300
size_t i;
301
size_t istop = row_info->rowbytes;
302
303
for (i = 0; i < istop; i++)
304
{
305
*rp = (png_byte)(~(*rp));
306
rp++;
307
}
308
}
309
310
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
311
row_info->bit_depth == 8)
312
{
313
png_bytep rp = row;
314
size_t i;
315
size_t istop = row_info->rowbytes;
316
317
for (i = 0; i < istop; i += 2)
318
{
319
*rp = (png_byte)(~(*rp));
320
rp += 2;
321
}
322
}
323
324
#ifdef PNG_16BIT_SUPPORTED
325
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
326
row_info->bit_depth == 16)
327
{
328
png_bytep rp = row;
329
size_t i;
330
size_t istop = row_info->rowbytes;
331
332
for (i = 0; i < istop; i += 4)
333
{
334
*rp = (png_byte)(~(*rp));
335
*(rp + 1) = (png_byte)(~(*(rp + 1)));
336
rp += 4;
337
}
338
}
339
#endif
340
}
341
#endif
342
343
#ifdef PNG_16BIT_SUPPORTED
344
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
345
/* Swaps byte order on 16-bit depth images */
346
void /* PRIVATE */
347
png_do_swap(png_row_infop row_info, png_bytep row)
348
{
349
png_debug(1, "in png_do_swap");
350
351
if (row_info->bit_depth == 16)
352
{
353
png_bytep rp = row;
354
png_uint_32 i;
355
png_uint_32 istop= row_info->width * row_info->channels;
356
357
for (i = 0; i < istop; i++, rp += 2)
358
{
359
#ifdef PNG_BUILTIN_BSWAP16_SUPPORTED
360
/* Feature added to libpng-1.6.11 for testing purposes, not
361
* enabled by default.
362
*/
363
*(png_uint_16*)rp = __builtin_bswap16(*(png_uint_16*)rp);
364
#else
365
png_byte t = *rp;
366
*rp = *(rp + 1);
367
*(rp + 1) = t;
368
#endif
369
}
370
}
371
}
372
#endif
373
#endif
374
375
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
376
static const png_byte onebppswaptable[256] = {
377
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
378
0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
379
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
380
0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
381
0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
382
0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
383
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
384
0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
385
0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
386
0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
387
0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
388
0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
389
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
390
0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
391
0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
392
0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
393
0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
394
0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
395
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
396
0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
397
0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
398
0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
399
0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
400
0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
401
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
402
0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
403
0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
404
0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
405
0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
406
0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
407
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
408
0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
409
};
410
411
static const png_byte twobppswaptable[256] = {
412
0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
413
0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
414
0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
415
0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
416
0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
417
0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
418
0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
419
0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
420
0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
421
0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
422
0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
423
0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
424
0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
425
0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
426
0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
427
0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
428
0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
429
0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
430
0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
431
0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
432
0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
433
0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
434
0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
435
0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
436
0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
437
0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
438
0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
439
0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
440
0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
441
0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
442
0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
443
0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
444
};
445
446
static const png_byte fourbppswaptable[256] = {
447
0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
448
0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
449
0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
450
0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
451
0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
452
0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
453
0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
454
0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
455
0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
456
0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
457
0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
458
0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
459
0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
460
0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
461
0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
462
0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
463
0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
464
0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
465
0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
466
0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
467
0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
468
0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
469
0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
470
0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
471
0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
472
0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
473
0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
474
0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
475
0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
476
0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
477
0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
478
0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
479
};
480
481
/* Swaps pixel packing order within bytes */
482
void /* PRIVATE */
483
png_do_packswap(png_row_infop row_info, png_bytep row)
484
{
485
png_debug(1, "in png_do_packswap");
486
487
if (row_info->bit_depth < 8)
488
{
489
png_bytep rp;
490
png_const_bytep end, table;
491
492
end = row + row_info->rowbytes;
493
494
if (row_info->bit_depth == 1)
495
table = onebppswaptable;
496
497
else if (row_info->bit_depth == 2)
498
table = twobppswaptable;
499
500
else if (row_info->bit_depth == 4)
501
table = fourbppswaptable;
502
503
else
504
return;
505
506
for (rp = row; rp < end; rp++)
507
*rp = table[*rp];
508
}
509
}
510
#endif /* PACKSWAP || WRITE_PACKSWAP */
511
512
#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
513
defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
514
/* Remove a channel - this used to be 'png_do_strip_filler' but it used a
515
* somewhat weird combination of flags to determine what to do. All the calls
516
* to png_do_strip_filler are changed in 1.5.2 to call this instead with the
517
* correct arguments.
518
*
519
* The routine isn't general - the channel must be the channel at the start or
520
* end (not in the middle) of each pixel.
521
*/
522
void /* PRIVATE */
523
png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
524
{
525
png_bytep sp = row; /* source pointer */
526
png_bytep dp = row; /* destination pointer */
527
png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */
528
529
/* At the start sp will point to the first byte to copy and dp to where
530
* it is copied to. ep always points just beyond the end of the row, so
531
* the loop simply copies (channels-1) channels until sp reaches ep.
532
*
533
* at_start: 0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc.
534
* nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc.
535
*/
536
537
/* GA, GX, XG cases */
538
if (row_info->channels == 2)
539
{
540
if (row_info->bit_depth == 8)
541
{
542
if (at_start != 0) /* Skip initial filler */
543
++sp;
544
else /* Skip initial channel and, for sp, the filler */
545
{
546
sp += 2; ++dp;
547
}
548
549
/* For a 1 pixel wide image there is nothing to do */
550
while (sp < ep)
551
{
552
*dp++ = *sp; sp += 2;
553
}
554
555
row_info->pixel_depth = 8;
556
}
557
558
else if (row_info->bit_depth == 16)
559
{
560
if (at_start != 0) /* Skip initial filler */
561
sp += 2;
562
else /* Skip initial channel and, for sp, the filler */
563
{
564
sp += 4; dp += 2;
565
}
566
567
while (sp < ep)
568
{
569
*dp++ = *sp++; *dp++ = *sp; sp += 3;
570
}
571
572
row_info->pixel_depth = 16;
573
}
574
575
else
576
return; /* bad bit depth */
577
578
row_info->channels = 1;
579
580
/* Finally fix the color type if it records an alpha channel */
581
if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
582
row_info->color_type = PNG_COLOR_TYPE_GRAY;
583
}
584
585
/* RGBA, RGBX, XRGB cases */
586
else if (row_info->channels == 4)
587
{
588
if (row_info->bit_depth == 8)
589
{
590
if (at_start != 0) /* Skip initial filler */
591
++sp;
592
else /* Skip initial channels and, for sp, the filler */
593
{
594
sp += 4; dp += 3;
595
}
596
597
/* Note that the loop adds 3 to dp and 4 to sp each time. */
598
while (sp < ep)
599
{
600
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp; sp += 2;
601
}
602
603
row_info->pixel_depth = 24;
604
}
605
606
else if (row_info->bit_depth == 16)
607
{
608
if (at_start != 0) /* Skip initial filler */
609
sp += 2;
610
else /* Skip initial channels and, for sp, the filler */
611
{
612
sp += 8; dp += 6;
613
}
614
615
while (sp < ep)
616
{
617
/* Copy 6 bytes, skip 2 */
618
*dp++ = *sp++; *dp++ = *sp++;
619
*dp++ = *sp++; *dp++ = *sp++;
620
*dp++ = *sp++; *dp++ = *sp; sp += 3;
621
}
622
623
row_info->pixel_depth = 48;
624
}
625
626
else
627
return; /* bad bit depth */
628
629
row_info->channels = 3;
630
631
/* Finally fix the color type if it records an alpha channel */
632
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
633
row_info->color_type = PNG_COLOR_TYPE_RGB;
634
}
635
636
else
637
return; /* The filler channel has gone already */
638
639
/* Fix the rowbytes value. */
640
row_info->rowbytes = (size_t)(dp-row);
641
}
642
#endif
643
644
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
645
/* Swaps red and blue bytes within a pixel */
646
void /* PRIVATE */
647
png_do_bgr(png_row_infop row_info, png_bytep row)
648
{
649
png_debug(1, "in png_do_bgr");
650
651
if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
652
{
653
png_uint_32 row_width = row_info->width;
654
if (row_info->bit_depth == 8)
655
{
656
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
657
{
658
png_bytep rp;
659
png_uint_32 i;
660
661
for (i = 0, rp = row; i < row_width; i++, rp += 3)
662
{
663
png_byte save = *rp;
664
*rp = *(rp + 2);
665
*(rp + 2) = save;
666
}
667
}
668
669
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
670
{
671
png_bytep rp;
672
png_uint_32 i;
673
674
for (i = 0, rp = row; i < row_width; i++, rp += 4)
675
{
676
png_byte save = *rp;
677
*rp = *(rp + 2);
678
*(rp + 2) = save;
679
}
680
}
681
}
682
683
#ifdef PNG_16BIT_SUPPORTED
684
else if (row_info->bit_depth == 16)
685
{
686
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
687
{
688
png_bytep rp;
689
png_uint_32 i;
690
691
for (i = 0, rp = row; i < row_width; i++, rp += 6)
692
{
693
png_byte save = *rp;
694
*rp = *(rp + 4);
695
*(rp + 4) = save;
696
save = *(rp + 1);
697
*(rp + 1) = *(rp + 5);
698
*(rp + 5) = save;
699
}
700
}
701
702
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
703
{
704
png_bytep rp;
705
png_uint_32 i;
706
707
for (i = 0, rp = row; i < row_width; i++, rp += 8)
708
{
709
png_byte save = *rp;
710
*rp = *(rp + 4);
711
*(rp + 4) = save;
712
save = *(rp + 1);
713
*(rp + 1) = *(rp + 5);
714
*(rp + 5) = save;
715
}
716
}
717
}
718
#endif
719
}
720
}
721
#endif /* READ_BGR || WRITE_BGR */
722
723
#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
724
defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
725
/* Added at libpng-1.5.10 */
726
void /* PRIVATE */
727
png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
728
{
729
if (png_ptr->num_palette < (1 << row_info->bit_depth) &&
730
png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */
731
{
732
/* Calculations moved outside switch in an attempt to stop different
733
* compiler warnings. 'padding' is in *bits* within the last byte, it is
734
* an 'int' because pixel_depth becomes an 'int' in the expression below,
735
* and this calculation is used because it avoids warnings that other
736
* forms produced on either GCC or MSVC.
737
*/
738
int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width);
739
png_bytep rp = png_ptr->row_buf + row_info->rowbytes - 1;
740
741
switch (row_info->bit_depth)
742
{
743
case 1:
744
{
745
/* in this case, all bytes must be 0 so we don't need
746
* to unpack the pixels except for the rightmost one.
747
*/
748
for (; rp > png_ptr->row_buf; rp--)
749
{
750
if ((*rp >> padding) != 0)
751
png_ptr->num_palette_max = 1;
752
padding = 0;
753
}
754
755
break;
756
}
757
758
case 2:
759
{
760
for (; rp > png_ptr->row_buf; rp--)
761
{
762
int i = ((*rp >> padding) & 0x03);
763
764
if (i > png_ptr->num_palette_max)
765
png_ptr->num_palette_max = i;
766
767
i = (((*rp >> padding) >> 2) & 0x03);
768
769
if (i > png_ptr->num_palette_max)
770
png_ptr->num_palette_max = i;
771
772
i = (((*rp >> padding) >> 4) & 0x03);
773
774
if (i > png_ptr->num_palette_max)
775
png_ptr->num_palette_max = i;
776
777
i = (((*rp >> padding) >> 6) & 0x03);
778
779
if (i > png_ptr->num_palette_max)
780
png_ptr->num_palette_max = i;
781
782
padding = 0;
783
}
784
785
break;
786
}
787
788
case 4:
789
{
790
for (; rp > png_ptr->row_buf; rp--)
791
{
792
int i = ((*rp >> padding) & 0x0f);
793
794
if (i > png_ptr->num_palette_max)
795
png_ptr->num_palette_max = i;
796
797
i = (((*rp >> padding) >> 4) & 0x0f);
798
799
if (i > png_ptr->num_palette_max)
800
png_ptr->num_palette_max = i;
801
802
padding = 0;
803
}
804
805
break;
806
}
807
808
case 8:
809
{
810
for (; rp > png_ptr->row_buf; rp--)
811
{
812
if (*rp > png_ptr->num_palette_max)
813
png_ptr->num_palette_max = (int) *rp;
814
}
815
816
break;
817
}
818
819
default:
820
break;
821
}
822
}
823
}
824
#endif /* CHECK_FOR_INVALID_INDEX */
825
826
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
827
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
828
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
829
void PNGAPI
830
png_set_user_transform_info(png_structrp png_ptr, png_voidp
831
user_transform_ptr, int user_transform_depth, int user_transform_channels)
832
{
833
png_debug(1, "in png_set_user_transform_info");
834
835
if (png_ptr == NULL)
836
return;
837
838
#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
839
if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
840
(png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
841
{
842
png_app_error(png_ptr,
843
"info change after png_start_read_image or png_read_update_info");
844
return;
845
}
846
#endif
847
848
png_ptr->user_transform_ptr = user_transform_ptr;
849
png_ptr->user_transform_depth = (png_byte)user_transform_depth;
850
png_ptr->user_transform_channels = (png_byte)user_transform_channels;
851
}
852
#endif
853
854
/* This function returns a pointer to the user_transform_ptr associated with
855
* the user transform functions. The application should free any memory
856
* associated with this pointer before png_write_destroy and png_read_destroy
857
* are called.
858
*/
859
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
860
png_voidp PNGAPI
861
png_get_user_transform_ptr(png_const_structrp png_ptr)
862
{
863
if (png_ptr == NULL)
864
return (NULL);
865
866
return png_ptr->user_transform_ptr;
867
}
868
#endif
869
870
#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
871
png_uint_32 PNGAPI
872
png_get_current_row_number(png_const_structrp png_ptr)
873
{
874
/* See the comments in png.h - this is the sub-image row when reading an
875
* interlaced image.
876
*/
877
if (png_ptr != NULL)
878
return png_ptr->row_number;
879
880
return PNG_UINT_32_MAX; /* help the app not to fail silently */
881
}
882
883
png_byte PNGAPI
884
png_get_current_pass_number(png_const_structrp png_ptr)
885
{
886
if (png_ptr != NULL)
887
return png_ptr->pass;
888
return 8; /* invalid */
889
}
890
#endif /* USER_TRANSFORM_INFO */
891
#endif /* READ_USER_TRANSFORM || WRITE_USER_TRANSFORM */
892
#endif /* READ || WRITE */
893
894