CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/ext/libpng17/pngtrans.c
Views: 1401
1
2
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
3
*
4
* Last changed in libpng 1.7.0 [(PENDING RELEASE)]
5
* Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
6
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8
*
9
* This code is released under the libpng license.
10
* For conditions of distribution and use, see the disclaimer
11
* and license in png.h
12
*/
13
#include "pngpriv.h"
14
#define PNG_SRC_FILE PNG_SRC_FILE_pngtrans
15
16
#ifdef _XOPEN_SOURCE
17
# include <unistd.h>
18
#endif /* for swab */
19
20
/* Memory format enquiries */
21
#ifdef PNG_GAMMA_SUPPORTED
22
static png_fixed_point
23
memory_gamma(png_const_structrp png_ptr)
24
{
25
# ifdef PNG_READ_GAMMA_SUPPORTED
26
# ifdef PNG_TRANSFORM_MECH_SUPPORTED
27
if (png_ptr->read_struct)
28
return png_ptr->row_gamma;
29
# endif /* TRANSFORM_MECH */
30
# endif /* READ_GAMMA */
31
32
/* Else either no READ_GAMMA support or this is a write struct; in both
33
* cases there are no gamma transforms. In the write case the set of the
34
* gamma in the info may not have been copied to the png_struct.
35
*/
36
# if defined(PNG_GAMMA_SUPPORTED) && defined(PNG_READ_SUPPORTED)
37
if ((png_ptr->colorspace.flags &
38
(PNG_COLORSPACE_INVALID|PNG_COLORSPACE_HAVE_GAMMA)) ==
39
PNG_COLORSPACE_HAVE_GAMMA)
40
return png_ptr->colorspace.gamma;
41
# else /* !(GAMMA && READ) */
42
PNG_UNUSED(png_ptr)
43
# endif /* !(GAMMA && READ) */
44
45
/* '0' means the value is not know: */
46
return 0;
47
}
48
#endif /* GAMMA */
49
50
unsigned int PNGAPI
51
png_memory_format(png_structrp png_ptr)
52
{
53
/* The in-memory format as a bitmask of PNG_FORMAT_FLAG_ values. All the
54
* flags listed below are used. If PNG_FORMAT_FLAG_INVALID is set the
55
* following caveats apply to the interpretation of PNG_FORMAT_FLAG_LINEAR:
56
*
57
* The gamma may differ from the sRGB (!LINEAR) or 1.0 (LINEAR). Call
58
* png_memory_gamma to find the correct value.
59
*
60
* The channel depth may differ from 8 (!LINEAR) or 16 (LINEAR). Call
61
* png_memory_channel_depth to find the correct value.
62
*
63
* It is only valid to call these APIS *after* either png_read_update_info
64
* or png_start_read_image on read or after the first row of an image has
65
* been written on write.
66
*/
67
if (png_ptr != NULL)
68
{
69
# ifdef PNG_TRANSFORM_MECH_SUPPORTED
70
unsigned int format = png_ptr->row_format;
71
# else /* !TRANSFORM_MECH */
72
unsigned int format = PNG_FORMAT_FROM_COLOR_TYPE(png_ptr->color_type);
73
# endif /* !TRANSFORM_MECH */
74
75
if (png_ptr->read_struct) /* else no way to find the gamma! */
76
{
77
# ifdef PNG_GAMMA_SUPPORTED
78
# ifdef PNG_TRANSFORM_MECH_SUPPORTED
79
unsigned int bit_depth = png_ptr->row_bit_depth;
80
# else /* !TRANSFORM_MECH */
81
unsigned int bit_depth = png_ptr->bit_depth;
82
# endif /* !TRANSFORM_MECH */
83
84
/* Now work out whether this is a valid simplified API format. */
85
switch (bit_depth)
86
{
87
case 8U:
88
{
89
png_fixed_point gamma = memory_gamma(png_ptr);
90
91
if (!PNG_GAMMA_IS_sRGB(gamma))
92
format |= PNG_FORMAT_FLAG_INVALID;
93
}
94
break;
95
96
case 16:
97
if (memory_gamma(png_ptr) == PNG_GAMMA_LINEAR)
98
{
99
static const union
100
{
101
png_uint_16 u16;
102
png_byte u8[2];
103
} sex = { 1U };
104
105
format |= PNG_FORMAT_FLAG_LINEAR;
106
107
/* But the memory layout of the 16-bit quantities must also
108
* match; we need swapped data on LSB platforms.
109
*/
110
if (sex.u8[0] == ((format & PNG_FORMAT_FLAG_SWAPPED) != 0))
111
break; /* ok */
112
}
113
114
/* FALL THROUGH*/
115
default: /* bit depth not supported for simplified API */
116
format |= PNG_FORMAT_FLAG_INVALID;
117
break;
118
}
119
# else /* !GAMMA */
120
/* We have no way of knowing if the gamma value matches that
121
* expected by the simplified API so mark the format as invalid:
122
*/
123
format |= PNG_FORMAT_FLAG_INVALID;
124
# endif
125
} /* read_struct */
126
127
return format;
128
}
129
130
return 0;
131
}
132
133
unsigned int PNGAPI png_memory_channel_depth(png_structrp png_ptr)
134
{
135
/* The actual depth of each channel in the image. */
136
if (png_ptr != NULL)
137
{
138
# ifdef PNG_TRANSFORM_MECH_SUPPORTED
139
return png_ptr->row_bit_depth;
140
# else
141
return png_ptr->bit_depth;
142
# endif
143
}
144
145
return 0;
146
}
147
148
#ifdef PNG_GAMMA_SUPPORTED
149
png_fixed_point PNGAPI
150
png_memory_gamma(png_structrp png_ptr)
151
{
152
/* The actual gamma of the image data, scaled by 100,000. This is the
153
* encoding gamma, e.g. 1/2.2 for sRGB. If the gamma is unknown this will
154
* return 0.
155
*
156
* On write this invariably returns 0; libpng does not change the gamma of
157
* the data on write.
158
*
159
* Note that this is not always the exact inverse of the 'screen gamma'
160
* passed to png_set_gamma; internal optimizations remove attempts to make
161
* small changes to the gamma value. This function returns the actual
162
* output value.
163
*/
164
return (png_ptr != NULL) ? memory_gamma(png_ptr) : 0;
165
}
166
#endif /* GAMMA */
167
168
/* These are general purpose APIs that deal with the row buffer format in both
169
* the read and write case. The png_struct::row_* members describe the
170
* in-memory format of the image data based on the transformations requested by
171
* the application.
172
*/
173
#ifdef PNG_TRANSFORM_MECH_SUPPORTED
174
png_voidp /* PRIVATE */
175
png_transform_cast_check(png_const_structp png_ptr, unsigned int src_line,
176
png_transformp tr, size_t size)
177
{
178
/* Given a pointer to a transform, 'tr' validate that the underlying derived
179
* class has size 'size' using the tr->size field and return the same
180
* pointer. If there is a size mismatch the function does an affirm using
181
* the given line number.
182
*/
183
if (tr->size != size)
184
png_affirm(png_ptr, param_deb("transform upcast") src_line);
185
186
return tr;
187
}
188
189
void /* PRIAVE */
190
png_transform_free(png_const_structrp png_ptr, png_transformp *list)
191
{
192
if (*list != NULL)
193
{
194
png_transform_free(png_ptr, &(*list)-> next);
195
if ((*list)->free != NULL)
196
(*list)->free(png_ptr, *list);
197
png_free(png_ptr, *list);
198
*list = NULL;
199
}
200
}
201
202
/* Utility to initialize a png_transform_control for read or write. */
203
void /* PRIVATE */
204
png_init_transform_control(png_transform_controlp tc, png_structp png_ptr)
205
{
206
png_byte bd; /* bit depth of the row */
207
png_byte cd; /* bit depth of color information */
208
209
memset(tc, 0, sizeof *tc);
210
tc->png_ptr = png_ptr; /* ALIAS */
211
tc->sp = tc->dp = NULL;
212
tc->width = 0;
213
214
# ifdef PNG_READ_GAMMA_SUPPORTED
215
/* The file gamma is set by png_set_gamma, as well as being read from the
216
* input PNG gAMA chunk, if present, we don't have a png_info so can't get
217
* the set_gAMA value but this doesn't matter because on read the gamma
218
* value is in png_struct::colorspace and on write it isn't used.
219
*/
220
if ((png_ptr->colorspace.flags &
221
(PNG_COLORSPACE_INVALID|PNG_COLORSPACE_HAVE_GAMMA)) ==
222
PNG_COLORSPACE_HAVE_GAMMA)
223
{
224
tc->gamma = png_ptr->colorspace.gamma;
225
debug(tc->gamma > 0);
226
}
227
228
else
229
{
230
/* There is no input gamma, so there should be no overall gamma
231
* correction going on. This test works because the various things
232
* that set an output gamma also default the input gamma.
233
*/
234
debug(png_ptr->row_gamma == 0);
235
}
236
# endif
237
238
/* Validate bit depth and color type here */
239
cd = bd = png_ptr->bit_depth;
240
241
switch (png_ptr->color_type)
242
{
243
case PNG_COLOR_TYPE_GRAY:
244
affirm(bd == 1U || bd == 2U || bd == 4U || bd == 8U || bd == 16U);
245
tc->format = 0U;
246
break;
247
248
case PNG_COLOR_TYPE_PALETTE:
249
affirm(bd == 1U || bd == 2U || bd == 4U || bd == 8U);
250
tc->format = PNG_FORMAT_FLAG_COLORMAP | PNG_FORMAT_FLAG_COLOR;
251
cd = 8U;
252
break;
253
254
case PNG_COLOR_TYPE_GRAY_ALPHA:
255
affirm(bd == 8U || bd == 16U);
256
tc->format = PNG_FORMAT_FLAG_ALPHA;
257
break;
258
259
case PNG_COLOR_TYPE_RGB:
260
affirm(bd == 8U || bd == 16U);
261
tc->format = PNG_FORMAT_FLAG_COLOR;
262
break;
263
264
case PNG_COLOR_TYPE_RGB_ALPHA:
265
affirm(bd == 8U || bd == 16U);
266
tc->format = PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_ALPHA;
267
break;
268
269
default:
270
impossible("PNG color type");
271
}
272
273
tc->bit_depth = bd;
274
tc->range = 0;
275
276
/* Preset the sBIT data to full precision/handled. */
277
tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = tc->sBIT_A = cd;
278
# ifdef PNG_READ_sBIT_SUPPORTED
279
{
280
int handled = 1;
281
282
if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
283
{
284
png_byte c = png_ptr->sig_bit.red;
285
if (c > 0 && c < cd)
286
{
287
tc->sBIT_R = c;
288
handled = 0;
289
}
290
291
c = png_ptr->sig_bit.green;
292
if (c > 0 && c < cd)
293
{
294
tc->sBIT_G = c;
295
handled = 0;
296
}
297
298
c = png_ptr->sig_bit.blue;
299
if (c > 0 && c < cd)
300
{
301
tc->sBIT_B = c;
302
handled = 0;
303
}
304
}
305
306
else /* grayscale */
307
{
308
png_byte c = png_ptr->sig_bit.gray;
309
if (c > 0 && c < cd)
310
{
311
tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = c;
312
handled = 0;
313
}
314
}
315
316
/* The palette-mapped format doesn't store alpha information, an
317
* omission in the spec that is difficult to fix. Notice that
318
* 'handled' is not cleared below, this is because the alpha channel is
319
* always linear, so the sBIT_A value can always be treated as a
320
* precision value.
321
*/
322
if ((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
323
{
324
png_byte c = png_ptr->sig_bit.alpha;
325
if (c > 0 && c < cd)
326
tc->sBIT_A = c;
327
}
328
329
/* If 'handled' did not get cleared there is no sBIT information. */
330
if (handled)
331
tc->invalid_info = PNG_INFO_sBIT;
332
}
333
# else /* !READ_sBIT */
334
/* No sBIT information */
335
tc->invalid_info = PNG_INFO_sBIT;
336
# endif /* !READ_sBIT */
337
}
338
339
png_transformp /*PRIVATE*/
340
png_add_transform(png_structrp png_ptr, size_t size, png_transform_fn fn,
341
unsigned int order)
342
{
343
/* Add a transform. This is a minimal implementation; the order is just
344
* controlled by 'order', the result is a point to the new transform, or
345
* to an existing one if one was already in the list.
346
*/
347
png_transformp *p = &png_ptr->transform_list;
348
349
while (*p != NULL && (*p)->order < order)
350
p = &(*p)->next;
351
352
if (size == 0)
353
size = sizeof (png_transform);
354
355
else
356
affirm(size >= sizeof (png_transform));
357
358
if (*p == NULL || (*p)->order > order)
359
{
360
png_transformp t;
361
362
t = png_voidcast(png_transformp, png_malloc(png_ptr, size));
363
memset(t, 0, size); /* zeros out the extra data too */
364
/* *p comes after the new entry, t: */
365
t->next = *p;
366
t->fn = fn;
367
t->free = NULL;
368
t->order = order;
369
t->size = 0xFFFFU & size;
370
*p = t;
371
return t;
372
}
373
374
else /* (*p)->order matches order, return *p */
375
{
376
affirm((*p)->fn == fn && (*p)->order == order && (*p)->size == size);
377
return *p;
378
}
379
}
380
381
png_transformp /* PRIVATE */
382
png_push_transform(png_structrp png_ptr, size_t size, png_transform_fn fn,
383
png_transformp *transform, png_transform_controlp tc)
384
{
385
png_transformp tr = *transform;
386
unsigned int order = tr->order;
387
388
/* Basic loop detection: */
389
affirm(fn != NULL && tr->fn != fn);
390
391
/* Move the following transforms up: */
392
{
393
unsigned int old_order = order;
394
395
do
396
{
397
tr->order = ++old_order;
398
tr = tr->next;
399
}
400
while (tr != NULL && tr->order == old_order);
401
402
affirm(tr == NULL || tr->order > old_order);
403
}
404
405
*transform = png_add_transform(png_ptr, size, fn, order);
406
407
if (tc != NULL)
408
fn(transform, tc);
409
410
return *transform;
411
}
412
413
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
414
static png_transformp
415
png_find_transform(png_const_structrp png_ptr, unsigned int order)
416
/* Find a transform with the given order, or return NULL. Currently only
417
* used here.
418
*/
419
{
420
png_transformp p = png_ptr->transform_list;
421
422
for (;;)
423
{
424
if (p == NULL || p->order > order)
425
return NULL;
426
427
if (p->order == order)
428
return p;
429
430
p = p->next;
431
}
432
}
433
#endif /* USER_TRANSFORM_PTR */
434
435
static void
436
remove_transform(png_const_structp png_ptr, png_transformp *transform)
437
/* Remove a transform on a running list */
438
{
439
png_transformp tp = *transform;
440
png_transformp next = tp->next;
441
442
*transform = next;
443
tp->next = NULL;
444
png_transform_free(png_ptr, &tp);
445
}
446
447
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
448
void /* PRIVATE */
449
png_remove_transform(png_const_structp png_ptr, png_transformp *transform)
450
{
451
remove_transform(png_ptr, transform);
452
}
453
#endif /* READ_TRANSFORMS */
454
455
static unsigned int
456
run_transform_list_forwards(png_transform_controlp tc, png_transformp *start,
457
png_transformp end/*NULL for whole list*/)
458
/* Called from the init code and below, the caller must initialize 'tc' */
459
{
460
png_const_structp png_ptr = tc->png_ptr;
461
unsigned int max_depth = PNG_TC_PIXEL_DEPTH(*tc);
462
463
/* Caller guarantees that *start is non-NULL */
464
debug(*start != NULL);
465
466
do
467
{
468
if ((*start)->fn != NULL)
469
(*start)->fn(start, tc);
470
471
if ((*start)->fn == NULL) /* delete this transform */
472
remove_transform(png_ptr, start);
473
474
else
475
{
476
/* Handle the initialization of the maximum pixel depth. */
477
unsigned int tc_depth = PNG_TC_PIXEL_DEPTH(*tc);
478
479
if (tc_depth > max_depth)
480
max_depth = tc_depth;
481
482
/* Advance to the next transform. */
483
start = &(*start)->next;
484
}
485
}
486
while (*start != NULL && *start != end);
487
488
/* This only goes wrong if 'end' was non-NULL and not in the list: */
489
debug(*start == end);
490
491
return max_depth;
492
}
493
494
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
495
unsigned int /* PRIVATE */
496
png_run_this_transform_list_forwards(png_transform_controlp tc,
497
png_transformp *start, png_transformp end)
498
{
499
return run_transform_list_forwards(tc, start, end);
500
}
501
#endif /* READ_TRANSFORMS */
502
503
#ifdef PNG_READ_SUPPORTED
504
unsigned int /* PRIVATE */
505
png_run_transform_list_forwards(png_structp png_ptr, png_transform_controlp tc)
506
{
507
if (png_ptr->transform_list != NULL)
508
return run_transform_list_forwards(tc, &png_ptr->transform_list, NULL);
509
510
else
511
return PNG_PIXEL_DEPTH(*png_ptr);
512
}
513
#endif /* READ */
514
515
#ifdef PNG_WRITE_SUPPORTED /* only used from pngwrite.c */
516
static unsigned int
517
run_transform_list_backwards(png_transform_controlp tc, png_transformp *list)
518
{
519
png_const_structp png_ptr = tc->png_ptr;
520
unsigned int max_depth = 0;
521
522
if ((*list)->next != NULL)
523
max_depth = run_transform_list_backwards(tc, &(*list)->next);
524
525
/* Note that the above might change (*list)->next, but it can't change
526
* *list itself.
527
*/
528
if ((*list)->fn != NULL)
529
(*list)->fn(list, tc);
530
531
/* If that set 'fn' to NULL this transform must be removed; this is how
532
* (*list)->next gets changed in our caller:
533
*/
534
if ((*list)->fn == NULL)
535
remove_transform(png_ptr, list);
536
537
else
538
{
539
unsigned int depth = PNG_TC_PIXEL_DEPTH(*tc);
540
541
if (depth > max_depth)
542
max_depth = depth;
543
}
544
545
return max_depth;
546
}
547
548
void /* PRIVATE */
549
png_run_transform_list_backwards(png_structp png_ptr, png_transform_controlp tc)
550
{
551
if (png_ptr->transform_list != NULL)
552
{
553
/* This doesn't take account of the base PNG depth, but that shouldn't
554
* matter, it's just a check:
555
*/
556
unsigned int max_depth =
557
run_transform_list_backwards(tc, &png_ptr->transform_list);
558
559
/* Better late than never (if this fires a memory overwrite has happened):
560
*/
561
affirm(max_depth <= png_ptr->row_max_pixel_depth);
562
}
563
}
564
#endif /* WRITE */
565
566
static unsigned int
567
init_transform_mech(png_structrp png_ptr, png_transform_control *tc, int start)
568
/* Called each time to run the transform list once during initialization. */
569
{
570
png_init_transform_control(tc, png_ptr);
571
tc->init = start ? PNG_TC_INIT_FORMAT : PNG_TC_INIT_FINAL;
572
# ifdef PNG_READ_TRANSFORMS_SUPPORTED
573
if (png_ptr->read_struct)
574
return png_read_init_transform_mech(png_ptr, tc);
575
else
576
# endif
577
return run_transform_list_forwards(tc, &png_ptr->transform_list, NULL);
578
}
579
#endif /* TRANSFORM_MECH */
580
581
#ifdef PNG_PALETTE_MAX_SUPPORTED
582
static int
583
set_palette_max(png_structrp png_ptr, png_transformp tr, unsigned int max,
584
unsigned int format_max)
585
/* Called whenever a new maximum pixel value is found */
586
{
587
/* One of these must be true: */
588
# ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
589
if (max >= (tr->args & 0x1FFU) && !png_ptr->palette_index_check_issued)
590
{
591
/* In 1.7 only issue the error/warning by default; the 'check' API is
592
* used to enable/disable the check. Assume that if the app enabled it
593
* then the app will be checking the result with get_palette_max in
594
* read. In write an error results unless the check is disabled.
595
*/
596
if (png_ptr->palette_index_check == PNG_PALETTE_CHECK_DEFAULT
597
# ifdef PNG_WRITE_SUPPORTED
598
|| (!png_ptr->read_struct &&
599
png_ptr->palette_index_check != PNG_PALETTE_CHECK_OFF)
600
# endif /* WRITE */
601
)
602
{
603
# ifdef PNG_READ_SUPPORTED
604
# ifdef PNG_WRITE_SUPPORTED
605
if (png_ptr->read_struct)
606
# endif /* WRITE */
607
png_chunk_benign_error(png_ptr, "palette index too large");
608
# ifdef PNG_WRITE_SUPPORTED
609
else
610
# endif
611
# endif /* READ */
612
# ifdef PNG_WRITE_SUPPORTED
613
png_error(png_ptr, "palette index too large");
614
# endif /* WRITE */
615
}
616
617
png_ptr->palette_index_check_issued = 1;
618
}
619
# endif /* CHECK_FOR_INVALID_INDEX */
620
# ifdef PNG_GET_PALETTE_MAX_SUPPORTED
621
png_ptr->palette_index_max = png_check_byte(png_ptr, max);
622
# endif
623
624
if (max == format_max)
625
{
626
tr->fn = NULL; /* no point continuing once the max has been seen */
627
return 1; /* stop */
628
}
629
630
return 0; /* keep going */
631
}
632
633
static void
634
palette_max_1bpp(png_transformp *tr, png_transform_controlp tc)
635
{
636
png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
637
png_uint_32 width = tc->width;
638
639
while (width >= 8)
640
{
641
if (*sp++) break;
642
width -= 8;
643
}
644
645
if (width < 8)
646
{
647
if (width == 0 ||
648
(*sp & (((1U<<width)-1U) << (8-width))) == 0)
649
return; /* no '1' pixels */
650
}
651
652
/* If the code reaches this point there is a set pixel */
653
(void)set_palette_max(tc->png_ptr, *tr, 1U, 1U);
654
}
655
656
static void
657
palette_max_2bpp(png_transformp *tr, png_transform_controlp tc)
658
{
659
png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
660
png_uint_32 width = tc->width;
661
const png_uint_32 args = (*tr)->args;
662
unsigned int max = args >> 24; /* saved maximum */
663
664
while (width > 0)
665
{
666
png_uint_32 input = 0U, test;
667
unsigned int new_max;
668
669
/* This just skips 0 bytes: */
670
while (width > 0)
671
{
672
unsigned int next = *sp++;
673
674
/* There may be partial pixels at the end, just remove the absent
675
* pixels with a right shift:
676
*/
677
if (width >= 4)
678
width -= 4;
679
else
680
next >>= (4U-width) * 2U, width = 0;
681
682
if (next)
683
{
684
input = (input << 8) | next;
685
if ((input & 0xFF000000U) != 0)
686
break;
687
}
688
}
689
690
test = input & 0xAAAAAAAAU;
691
692
if (test != 0)
693
{
694
if ((input & (test >> 1)) != 0)
695
new_max = 3U; /* both bits set in at least one pixel */
696
697
else if (max < 2U)
698
new_max = 2U;
699
700
else
701
continue; /* no change to max */
702
}
703
704
else /* test is 0 */ if (input != 0 && max == 0)
705
new_max = 1U;
706
707
else /* input is 0, or max is at least 1 */
708
continue;
709
710
/* new_max is greater than max: */
711
if (set_palette_max(tc->png_ptr, *tr, new_max, 3U))
712
return;
713
714
/* Record new_max: */
715
max = new_max;
716
}
717
718
/* End of input, check the next line. */
719
(*tr)->args = (max << 24) + (args & 0xFFFFFFU);
720
}
721
722
static void
723
palette_max_4bpp(png_transformp *tr, png_transform_controlp tc)
724
{
725
png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
726
png_uint_32 width = tc->width;
727
const png_uint_32 args = (*tr)->args;
728
unsigned int max = args >> 24; /* saved maximum */
729
730
while (width > 0)
731
{
732
unsigned int input = *sp++;
733
734
if (width >= 2)
735
width -= 2;
736
else
737
input >>= 1, width = 0;
738
739
if ((input & 0xFU) > max)
740
max = input & 0xFU;
741
742
if (((input >> 4) & 0xFU) > max)
743
max = (input >> 4) & 0xFU;
744
}
745
746
if (max > (args >> 24))
747
{
748
if (set_palette_max(tc->png_ptr, *tr, max, 15U))
749
return;
750
751
(*tr)->args = (max << 24) + (args & 0xFFFFFFU);
752
}
753
}
754
755
static void
756
palette_max_8bpp(png_transformp *tr, png_transform_controlp tc)
757
{
758
png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
759
png_uint_32 width = tc->width;
760
const png_uint_32 args = (*tr)->args;
761
unsigned int max = args >> 24; /* saved maximum */
762
763
while (width > 0)
764
{
765
unsigned int input = *sp++;
766
767
if (input > max)
768
max = input;
769
770
--width;
771
}
772
773
if (max > (args >> 24))
774
{
775
if (set_palette_max(tc->png_ptr, *tr, max, 255U))
776
return;
777
778
(*tr)->args = (max << 24) + (args & 0xFFFFFFU);
779
}
780
}
781
782
static void
783
palette_max_init(png_transformp *tr, png_transform_controlp tc)
784
{
785
# define png_ptr (tc->png_ptr)
786
affirm((tc->format & PNG_FORMAT_FLAG_COLORMAP) != 0);
787
debug(tc->init);
788
789
if (tc->init == PNG_TC_INIT_FINAL)
790
{
791
/* Record the palette depth to check here along with the running total
792
* in the top 8 bits (initially 0, which is always valid).
793
*/
794
(*tr)->args = png_ptr->num_palette;
795
796
switch (tc->bit_depth)
797
{
798
case 1: (*tr)->fn = palette_max_1bpp; break;
799
case 2: (*tr)->fn = palette_max_2bpp; break;
800
case 4: (*tr)->fn = palette_max_4bpp; break;
801
case 8: (*tr)->fn = palette_max_8bpp; break;
802
default:impossible("palette bit depth");
803
}
804
805
png_ptr->palette_index_have_max = 1U;
806
}
807
# undef png_ptr
808
}
809
#endif /* PALETTE_MAX */
810
811
#ifdef PNG_GET_PALETTE_MAX_SUPPORTED
812
int PNGAPI
813
png_get_palette_max(png_const_structrp png_ptr, png_const_inforp info_ptr)
814
{
815
if (png_ptr != NULL && png_ptr->palette_index_have_max)
816
return png_ptr->palette_index_max;
817
818
/* This indicates to the caller that the information is not available: */
819
return -1;
820
PNG_UNUSED(info_ptr)
821
}
822
#endif /* GET_PALETTE_MAX */
823
824
void /* PRIVATE */
825
png_init_row_info(png_structrp png_ptr)
826
{
827
/* PNG pixels never exceed 64 bits in depth: */
828
const png_byte png_depth =
829
png_check_bits(png_ptr, PNG_PIXEL_DEPTH(*png_ptr), 7U);
830
831
# ifdef PNG_TRANSFORM_MECH_SUPPORTED
832
/* The palette index check stuff is *on* automatically. To handle this
833
* add it here, if it is supported.
834
*/
835
# ifdef PNG_PALETTE_MAX_SUPPORTED
836
/* The logic here is a little complex because of the plethora of
837
* #defines controlling this stuff.
838
*/
839
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE/* fast escape */ && (
840
# if defined (PNG_READ_GET_PALETTE_MAX_SUPPORTED) ||\
841
defined (PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED)
842
(png_ptr->read_struct
843
# ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
844
&& (png_ptr->palette_index_check == PNG_PALETTE_CHECK_ON ||
845
(png_ptr->palette_index_check == PNG_PALETTE_CHECK_DEFAULT
846
&& png_ptr->num_palette < (1U << png_ptr->bit_depth)))
847
# endif /* READ_CHECK_FOR_INVALID_INDEX */
848
)
849
# else /* no READ support */
850
0
851
# endif /* READ checks */
852
||
853
# if defined (PNG_WRITE_GET_PALETTE_MAX_SUPPORTED) ||\
854
defined (PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
855
(!png_ptr->read_struct
856
# ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
857
&& (png_ptr->palette_index_check == PNG_PALETTE_CHECK_ON ||
858
(png_ptr->palette_index_check == PNG_PALETTE_CHECK_DEFAULT
859
&& png_ptr->num_palette < (1U << png_ptr->bit_depth)))
860
# endif /* WRITE_CHECK_FOR_INVALID_INDEX */
861
)
862
# else /* no WRITE support */
863
0
864
# endif /* WRITE checks */
865
))
866
png_add_transform(png_ptr, 0/*size*/, palette_max_init,
867
PNG_TR_CHECK_PALETTE);
868
# endif
869
870
/* Application transforms may change the format of the data or, when
871
* producing interlaced images, the number of pixels in a line. This code
872
* determines the maximum pixel depth required and allows transformations
873
* a chance to initialize themselves.
874
*/
875
if (png_ptr->transform_list != NULL)
876
{
877
png_transform_control tc;
878
879
(void)init_transform_mech(png_ptr, &tc, 1/*start*/);
880
881
png_ptr->row_format = png_check_bits(png_ptr, tc.format, PNG_RF_BITS);
882
affirm(tc.bit_depth <= 32);
883
png_ptr->row_bit_depth = png_check_bits(png_ptr, tc.bit_depth, 6);
884
png_ptr->row_range = png_check_bits(png_ptr, tc.range, 3);
885
# ifdef PNG_READ_GAMMA_SUPPORTED
886
png_ptr->row_gamma = tc.gamma;
887
# endif /* READ_GAMMA */
888
889
/* The above may have cancelled all the transforms in the list. */
890
if (png_ptr->transform_list != NULL)
891
{
892
/* Run the transform list again, also forward, and accumulate the
893
* maximum pixel depth. At this point the transforms can swap
894
* out their initialization code.
895
*/
896
unsigned int max_depth =
897
init_transform_mech(png_ptr, &tc, 0/*final*/);
898
899
/* init_transform_mech is expected to take the input depth into
900
* account:
901
*/
902
debug(max_depth >= png_depth);
903
if (max_depth < png_depth)
904
max_depth = png_depth;
905
affirm(max_depth <= (png_ptr->read_struct ? 128U : 64U));
906
907
# ifdef PNG_READ_TRANSFORMS_SUPPORTED
908
/* Set this now because it only gets resolved finally at this
909
* point.
910
*/
911
png_ptr->invalid_info = tc.invalid_info;
912
# endif /* READ_TRANSFORMS */
913
914
/* And check the transform fields: */
915
affirm(png_ptr->row_format == tc.format &&
916
png_ptr->row_range == tc.range &&
917
png_ptr->row_bit_depth == tc.bit_depth);
918
# ifdef PNG_READ_GAMMA_SUPPORTED
919
affirm(png_ptr->row_gamma == tc.gamma);
920
# endif /* READ_GAMMA */
921
922
png_ptr->row_max_pixel_depth =
923
png_check_bits(png_ptr, max_depth, 8U);
924
925
/* On 'read' input_depth is the PNG pixel depth and output_depth is
926
* the depth of the pixels passed to the application, but on 'write'
927
* the transform list is reversed so output_depth is the PNG depth
928
* and input_depth the application depth.
929
*/
930
{
931
const png_byte app_depth =
932
png_check_bits(png_ptr, PNG_TC_PIXEL_DEPTH(tc), 8U);
933
934
affirm(app_depth <= max_depth);
935
936
if (png_ptr->read_struct)
937
{
938
png_ptr->row_input_pixel_depth = png_depth;
939
png_ptr->row_output_pixel_depth = app_depth;
940
}
941
942
else
943
{
944
png_ptr->row_input_pixel_depth = app_depth;
945
png_ptr->row_output_pixel_depth = png_depth;
946
}
947
948
return; /* to skip the default settings below */
949
}
950
}
951
}
952
953
else /* png_ptr->transform_list == NULL */
954
{
955
png_ptr->row_format = png_check_bits(png_ptr,
956
PNG_FORMAT_FROM_COLOR_TYPE(png_ptr->color_type), PNG_RF_BITS);
957
png_ptr->row_bit_depth = png_check_bits(png_ptr, png_ptr->bit_depth,
958
6);
959
png_ptr->row_range = 0;
960
# ifdef PNG_READ_GAMMA_SUPPORTED
961
if ((png_ptr->colorspace.flags &
962
(PNG_COLORSPACE_INVALID|PNG_COLORSPACE_HAVE_GAMMA)) ==
963
PNG_COLORSPACE_HAVE_GAMMA)
964
png_ptr->row_gamma = png_ptr->colorspace.gamma;
965
# endif /* READ_GAMMA */
966
# ifdef PNG_READ_TRANSFORMS_SUPPORTED
967
png_ptr->invalid_info = 0U;
968
# endif /* READ_TRANSFORMS */
969
}
970
# endif /* TRANSFORM_MECH */
971
972
/* We get here if there are no transforms therefore no change to the pixel
973
* bit depths.
974
*/
975
png_ptr->row_output_pixel_depth = png_ptr->row_max_pixel_depth =
976
png_ptr->row_input_pixel_depth = png_depth;
977
}
978
979
#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
980
defined(PNG_WRITE_INTERLACING_SUPPORTED)
981
int PNGAPI
982
png_set_interlace_handling(png_structrp png_ptr)
983
{
984
png_debug(1, "in png_set_interlace handling");
985
986
if (png_ptr != 0)
987
{
988
if (png_ptr->read_struct)
989
{
990
# ifdef PNG_READ_INTERLACING_SUPPORTED
991
if (png_ptr->interlaced)
992
{
993
png_ptr->do_interlace = 1;
994
return PNG_INTERLACE_ADAM7_PASSES;
995
}
996
997
return 1;
998
# else /* !READ_INTERLACING */
999
png_app_error(png_ptr, "no de-interlace support");
1000
/* return 0 below */
1001
# endif /* !READ_INTERLACING */
1002
}
1003
1004
else /* write */
1005
{
1006
# ifdef PNG_WRITE_INTERLACING_SUPPORTED
1007
if (png_ptr->interlaced)
1008
{
1009
png_ptr->do_interlace = 1;
1010
return PNG_INTERLACE_ADAM7_PASSES;
1011
}
1012
1013
return 1;
1014
# else /* !WRITE_INTERLACING */
1015
png_app_error(png_ptr, "no interlace support");
1016
/* return 0 below */
1017
# endif /* !WRITE_INTERLACING */
1018
}
1019
}
1020
1021
/* API CHANGE: 1.7.0: returns 0 if called with a NULL png_ptr */
1022
return 0;
1023
}
1024
#endif /* READ_INTERLACING || WRITE_INTERLACING */
1025
1026
#ifdef PNG_MNG_READ_FEATURES_SUPPORTED
1027
/* Undoes intrapixel differencing, this is called immediately after the PNG
1028
* filter has been undone.
1029
*/
1030
static void
1031
png_do_read_intrapixel_RGB8(png_transformp *tr, png_transform_controlp tc)
1032
{
1033
png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
1034
png_bytep dp = png_voidcast(png_bytep, tc->dp);
1035
png_uint_32 width = tc->width;
1036
1037
tc->sp = dp;
1038
1039
/* TAKE CARE: dp and sp may be the same, in which case the assignments to *dp
1040
* are overwriting sp[]
1041
*/
1042
do
1043
{
1044
*dp++ = PNG_BYTE(sp[0] + sp[1]); /* red+green */
1045
*dp++ = *++sp; /* green */
1046
*dp++ = PNG_BYTE(sp[0] + sp[1]); /* green+blue */
1047
sp += 2;
1048
}
1049
while (--width > 0);
1050
1051
# define png_ptr (tc->png_ptr)
1052
UNTESTED
1053
# undef png_ptr
1054
PNG_UNUSED(tr)
1055
}
1056
1057
static void
1058
png_do_read_intrapixel_RGBA8(png_transformp *tr, png_transform_controlp tc)
1059
{
1060
png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
1061
png_bytep dp = png_voidcast(png_bytep, tc->dp);
1062
png_uint_32 width = tc->width;
1063
1064
tc->sp = dp;
1065
1066
do
1067
{
1068
*dp++ = PNG_BYTE(sp[0] + sp[1]); /* red+green */
1069
*dp++ = *++sp; /* green */
1070
*dp++ = PNG_BYTE(sp[0] + sp[1]); /* green+blue */
1071
sp += 2;
1072
*dp++ = *sp++; /* alpha */
1073
}
1074
while (--width > 0);
1075
1076
# define png_ptr (tc->png_ptr)
1077
UNTESTED
1078
# undef png_ptr
1079
PNG_UNUSED(tr)
1080
}
1081
1082
static void
1083
png_do_read_intrapixel_RGB16(png_transformp *tr, png_transform_controlp tc)
1084
{
1085
png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
1086
png_bytep dp = png_voidcast(png_bytep, tc->dp);
1087
png_uint_32 width = tc->width;
1088
1089
tc->sp = dp;
1090
1091
/* The input consists of 16-bit values and, by examination of the code
1092
* (please, someone, check; I didn't read the spec) the differencing is done
1093
* against the 16-bit green value.
1094
*/
1095
do
1096
{
1097
unsigned int red = png_get_uint_16(sp + 0);
1098
unsigned int green = png_get_uint_16(sp + 2);
1099
unsigned int blue = png_get_uint_16(sp + 4);
1100
sp += 6;
1101
1102
red += green;
1103
blue += green;
1104
1105
*dp++ = PNG_BYTE(red >> 8);
1106
*dp++ = PNG_BYTE(red);
1107
*dp++ = PNG_BYTE(green >> 8);
1108
*dp++ = PNG_BYTE(green);
1109
*dp++ = PNG_BYTE(blue >> 8);
1110
*dp++ = PNG_BYTE(blue);
1111
}
1112
while (--width > 0);
1113
1114
# define png_ptr (tc->png_ptr)
1115
UNTESTED
1116
# undef png_ptr
1117
PNG_UNUSED(tr)
1118
}
1119
1120
static void
1121
png_do_read_intrapixel_RGBA16(png_transformp *tr, png_transform_controlp tc)
1122
{
1123
png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
1124
png_bytep dp = png_voidcast(png_bytep, tc->dp);
1125
png_uint_32 width = tc->width;
1126
1127
tc->sp = dp;
1128
1129
/* As above but copy the alpha over too. */
1130
do
1131
{
1132
unsigned int red = png_get_uint_16(sp + 0);
1133
unsigned int green = png_get_uint_16(sp + 2);
1134
unsigned int blue = png_get_uint_16(sp + 4);
1135
sp += 6;
1136
1137
red += green;
1138
blue += green;
1139
1140
*dp++ = PNG_BYTE(red >> 8);
1141
*dp++ = PNG_BYTE(red);
1142
*dp++ = PNG_BYTE(green >> 8);
1143
*dp++ = PNG_BYTE(green);
1144
*dp++ = PNG_BYTE(blue >> 8);
1145
*dp++ = PNG_BYTE(blue);
1146
*dp++ = *sp++;
1147
*dp++ = *sp++; /* alpha */
1148
}
1149
while (--width > 0);
1150
1151
# define png_ptr (tc->png_ptr)
1152
UNTESTED
1153
# undef png_ptr
1154
PNG_UNUSED(tr)
1155
}
1156
1157
static void
1158
png_init_read_intrapixel(png_transformp *tr, png_transform_controlp tc)
1159
{
1160
/* Double check the permitted MNG features in case the app turned the feature
1161
* on then off again. Also make sure the color type is acceptable; it must
1162
* be RGB or RGBA.
1163
*/
1164
png_const_structp png_ptr = tc->png_ptr;
1165
1166
if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
1167
(png_ptr->filter_method == PNG_INTRAPIXEL_DIFFERENCING) &&
1168
(tc->format & (PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_COLORMAP)) ==
1169
PNG_FORMAT_FLAG_COLOR)
1170
{
1171
if (tc->init == PNG_TC_INIT_FINAL) switch (PNG_TC_PIXEL_DEPTH(*tc))
1172
{
1173
case 24: (*tr)->fn = png_do_read_intrapixel_RGB8; break;
1174
case 32: (*tr)->fn = png_do_read_intrapixel_RGBA8; break;
1175
case 48: (*tr)->fn = png_do_read_intrapixel_RGB16; break;
1176
case 64: (*tr)->fn = png_do_read_intrapixel_RGBA16; break;
1177
default: impossible("bit depth");
1178
}
1179
}
1180
1181
else
1182
(*tr)->fn = NULL;
1183
}
1184
#endif /* MNG_READ_FEATURES_SUPPORTED */
1185
1186
#ifdef PNG_MNG_WRITE_FEATURES_SUPPORTED
1187
/* This is just the forward direction of the above:
1188
*
1189
* red := red - green
1190
* blue:= blue- green
1191
*
1192
* Alpha is not changed.
1193
*/
1194
static void
1195
png_do_write_intrapixel_RGB8(png_transformp *tr, png_transform_controlp tc)
1196
{
1197
png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
1198
png_bytep dp = png_voidcast(png_bytep, tc->dp);
1199
png_uint_32 width = tc->width;
1200
1201
tc->sp = dp;
1202
1203
/* TAKE CARE: dp and sp may be the same, in which case the assignments to *dp
1204
* are overwriting sp[]
1205
*/
1206
do
1207
{
1208
*dp++ = PNG_BYTE(sp[0] - sp[1]); /* red-green */
1209
*dp++ = *++sp; /* green */
1210
*dp++ = PNG_BYTE(sp[0] - sp[1]); /* green-blue */
1211
sp += 2;
1212
}
1213
while (--width > 0);
1214
1215
# define png_ptr (tc->png_ptr)
1216
UNTESTED
1217
# undef png_ptr
1218
PNG_UNUSED(tr)
1219
}
1220
1221
static void
1222
png_do_write_intrapixel_RGBA8(png_transformp *tr, png_transform_controlp tc)
1223
{
1224
png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
1225
png_bytep dp = png_voidcast(png_bytep, tc->dp);
1226
png_uint_32 width = tc->width;
1227
1228
tc->sp = dp;
1229
1230
do
1231
{
1232
*dp++ = PNG_BYTE(sp[0] - sp[1]); /* red-green */
1233
*dp++ = *++sp; /* green */
1234
*dp++ = PNG_BYTE(sp[0] - sp[1]); /* green-blue */
1235
sp += 2;
1236
*dp++ = *sp++; /* alpha */
1237
}
1238
while (--width > 0);
1239
1240
# define png_ptr (tc->png_ptr)
1241
UNTESTED
1242
# undef png_ptr
1243
PNG_UNUSED(tr)
1244
}
1245
1246
static void
1247
png_do_write_intrapixel_RGB16(png_transformp *tr, png_transform_controlp tc)
1248
{
1249
png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
1250
png_bytep dp = png_voidcast(png_bytep, tc->dp);
1251
png_uint_32 width = tc->width;
1252
1253
tc->sp = dp;
1254
1255
do
1256
{
1257
unsigned int red = png_get_uint_16(sp + 0);
1258
unsigned int green = png_get_uint_16(sp + 2);
1259
unsigned int blue = png_get_uint_16(sp + 4);
1260
sp += 6;
1261
1262
red -= green;
1263
blue -= green;
1264
1265
*dp++ = PNG_BYTE(red >> 8);
1266
*dp++ = PNG_BYTE(red);
1267
*dp++ = PNG_BYTE(green >> 8);
1268
*dp++ = PNG_BYTE(green);
1269
*dp++ = PNG_BYTE(blue >> 8);
1270
*dp++ = PNG_BYTE(blue);
1271
}
1272
while (--width > 0);
1273
1274
# define png_ptr (tc->png_ptr)
1275
UNTESTED
1276
# undef png_ptr
1277
PNG_UNUSED(tr)
1278
}
1279
1280
static void
1281
png_do_write_intrapixel_RGBA16(png_transformp *tr, png_transform_controlp tc)
1282
{
1283
png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
1284
png_bytep dp = png_voidcast(png_bytep, tc->dp);
1285
png_uint_32 width = tc->width;
1286
1287
tc->sp = dp;
1288
1289
/* As above but copy the alpha over too. */
1290
do
1291
{
1292
unsigned int red = png_get_uint_16(sp + 0);
1293
unsigned int green = png_get_uint_16(sp + 2);
1294
unsigned int blue = png_get_uint_16(sp + 4);
1295
sp += 6;
1296
1297
red -= green;
1298
blue -= green;
1299
1300
*dp++ = PNG_BYTE(red >> 8);
1301
*dp++ = PNG_BYTE(red);
1302
*dp++ = PNG_BYTE(green >> 8);
1303
*dp++ = PNG_BYTE(green);
1304
*dp++ = PNG_BYTE(blue >> 8);
1305
*dp++ = PNG_BYTE(blue);
1306
*dp++ = *sp++;
1307
*dp++ = *sp++; /* alpha */
1308
}
1309
while (--width > 0);
1310
1311
# define png_ptr (tc->png_ptr)
1312
UNTESTED
1313
# undef png_ptr
1314
PNG_UNUSED(tr)
1315
}
1316
1317
static void
1318
png_init_write_intrapixel(png_transformp *tr, png_transform_controlp tc)
1319
{
1320
/* Write filter_method 64 (intrapixel differencing) only if:
1321
*
1322
* 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED, and;
1323
* 2. Libpng did not write a PNG signature (this filter_method is only
1324
* used in PNG datastreams that are embedded in MNG datastreams),
1325
* and;
1326
* 3. The application called png_permit_mng_features with a mask that
1327
* included PNG_FLAG_MNG_FILTER_64, and;
1328
* 4. The filter_method is 64, and;
1329
* 5. The color_type is RGB or RGBA
1330
*/
1331
png_const_structp png_ptr = tc->png_ptr;
1332
1333
if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
1334
(png_ptr->filter_method == PNG_INTRAPIXEL_DIFFERENCING) &&
1335
(tc->format & (PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_COLORMAP)) ==
1336
PNG_FORMAT_FLAG_COLOR)
1337
{
1338
if (tc->init == PNG_TC_INIT_FINAL) switch (PNG_TC_PIXEL_DEPTH(*tc))
1339
{
1340
case 24: (*tr)->fn = png_do_write_intrapixel_RGB8; break;
1341
case 32: (*tr)->fn = png_do_write_intrapixel_RGBA8; break;
1342
case 48: (*tr)->fn = png_do_write_intrapixel_RGB16; break;
1343
case 64: (*tr)->fn = png_do_write_intrapixel_RGBA16; break;
1344
default: impossible("bit depth");
1345
}
1346
}
1347
1348
else
1349
(*tr)->fn = NULL;
1350
}
1351
#endif /* MNG_WRITE_FEATURES */
1352
1353
#ifdef PNG_MNG_FEATURES_SUPPORTED
1354
png_uint_32 PNGAPI
1355
png_permit_mng_features(png_structrp png_ptr, png_uint_32 mng_features)
1356
{
1357
if (png_ptr != NULL)
1358
{
1359
# ifdef PNG_MNG_READ_FEATURES_SUPPORTED
1360
if ((mng_features & PNG_FLAG_MNG_FILTER_64) != 0)
1361
png_add_transform(png_ptr, 0/*size*/, png_init_read_intrapixel,
1362
PNG_TR_MNG_INTRAPIXEL);
1363
# else /* !MNG_READ_FEATURES */
1364
if (png_ptr->read_struct)
1365
{
1366
png_app_error(png_ptr, "MNG not supported on read");
1367
return;
1368
}
1369
# endif /* !MNG_READ_FEATURES */
1370
1371
# ifdef PNG_MNG_WRITE_FEATURES_SUPPORTED
1372
if ((mng_features & PNG_FLAG_MNG_FILTER_64) != 0)
1373
png_add_transform(png_ptr, 0/*size*/, png_init_write_intrapixel,
1374
PNG_TR_MNG_INTRAPIXEL);
1375
# else /* !MNG_WRITE_FEATURES */
1376
if (!png_ptr->read_struct)
1377
{
1378
png_app_error(png_ptr, "MNG not supported on write");
1379
return;
1380
}
1381
# endif /* !MNG_WRITE_FEATURES */
1382
1383
return png_ptr->mng_features_permitted =
1384
mng_features & PNG_ALL_MNG_FEATURES;
1385
}
1386
1387
return 0;
1388
}
1389
#endif /* MNG_FEATURES */
1390
1391
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) ||\
1392
defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) ||\
1393
defined(PNG_READ_SWAP_ALPHA_SUPPORTED) ||\
1394
defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) ||\
1395
defined(PNG_READ_FILLER_SUPPORTED) ||\
1396
defined(PNG_WRITE_FILLER_SUPPORTED) ||\
1397
defined(PNG_READ_STRIP_ALPHA_SUPPORTED) ||\
1398
defined(PNG_READ_STRIP_16_TO_8_SUPPORTED) ||\
1399
defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) ||\
1400
defined(PNG_READ_EXPAND_16_SUPPORTED) ||\
1401
defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1402
/* This is a generic transform which manipulates the bytes in an input row. The
1403
* manipulations supported are:
1404
*
1405
* Channel addition (alpha or filler)
1406
* Channel removal (alpha or filler)
1407
* Channel swaps - RGB to BGR, alpha/filler from last to first and vice versa
1408
*
1409
* The output is described in blocks of output pixel size 4-bit codes encoded
1410
* as follows:
1411
*
1412
* 0 Advance the source pointer by the source pixel size, start the
1413
* code list again. This code doesn't actually exist; it is simply
1414
* the result of emptying the code list.
1415
* 1..3 An error (ignored; treated like 0)
1416
* 4..7 Put filler[code-4] into the output
1417
* 8..15 Put source byte[code-8] in the output
1418
*
1419
* The codes are held in a png_uint_32 parameter. transform->args is used by
1420
* the init routine to work out the required codes. The format change is a mask
1421
* which is XORed with the tc format. Note that the init routine works out
1422
* whether to work from the beginning or end of the row and the codes are always
1423
* stored LSB first in the order needed.
1424
*/
1425
typedef struct
1426
{
1427
png_transform tr;
1428
png_uint_32 codes; /* As above */
1429
unsigned int format; /* format after transform */
1430
unsigned int bit_depth; /* bit depth after transform */
1431
png_byte filler[4]; /* Filler or alpha bytes, LSB first (see below) */
1432
} png_transform_byte_op;
1433
1434
static void
1435
png_do_byte_ops_up(png_transformp *transform, png_transform_controlp tc)
1436
/* Row width is unchanged or decreasing */
1437
{
1438
# define png_ptr (tc->png_ptr)
1439
png_transform_byte_op *tr =
1440
png_transform_cast(png_transform_byte_op, *transform);
1441
png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
1442
const unsigned int sp_advance = PNG_TC_PIXEL_DEPTH(*tc) >> 3;
1443
const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc);
1444
png_bytep dp = png_voidcast(png_bytep, tc->dp);
1445
1446
debug(tc->bit_depth == 8 || tc->bit_depth == 16);
1447
debug((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0);
1448
1449
tc->sp = tc->dp;
1450
tc->format = tr->format;
1451
tc->bit_depth = tr->bit_depth;
1452
1453
/* 'output' is a 32-byte buffer that is used to delay writes for 16 bytes,
1454
* avoiding overwrite when source and destination buffers are the same.
1455
* 'hwm' is either 32 or 16, initially '32', when the byte counter 'i'
1456
* reaches 'hwm' the last-but-one 16 bytes are written; the bytes
1457
* [hwm..hwm+15] modulo 32. hwm is then swapped to hwm+16 mod 32 and i
1458
* continues to advance. i is always below hwm.
1459
*
1460
* At the end the whole remaining buffer from hwm to i is written.
1461
*/
1462
{
1463
const png_uint_32 codes = tr->codes;
1464
png_uint_32 code = codes;
1465
unsigned int i, hwm; /* buffer index and high-water-mark */
1466
png_byte output[32];
1467
1468
hwm = 32;
1469
1470
for (i=0;;)
1471
{
1472
unsigned int next_code = code & 0xf;
1473
1474
if (next_code >= 8)
1475
output[i++] = sp[next_code-8];
1476
1477
else if (next_code >= 4)
1478
output[i++] = tr->filler[next_code - 4];
1479
1480
else /* end code */
1481
{
1482
sp += sp_advance;
1483
1484
if (sp >= ep)
1485
break; /* i may be == hwm at this point. */
1486
1487
code = codes;
1488
continue; /* no ouput produced, skip the check */
1489
}
1490
1491
code >>= 4; /* find the next code */
1492
1493
if (i == hwm)
1494
{
1495
hwm &= 0x10U; /* 0 or 16 */
1496
memcpy(dp, output + hwm, 16);
1497
dp += 16;
1498
i = hwm; /* reset i if hwm was 32 */
1499
/* hwm is only ever 16 or 32: */
1500
hwm += 16;
1501
}
1502
}
1503
1504
/* Write from hwm to (i-1), the delay means there is always something to
1505
* write.
1506
*/
1507
hwm &= 0x10U;
1508
if (hwm == 16)
1509
{
1510
debug(i <= 16);
1511
memcpy(dp, output + hwm, 16);
1512
dp += 16;
1513
}
1514
1515
if (i > 0)
1516
memcpy(dp, output, i);
1517
1518
# ifndef PNG_RELEASE_BUILD
1519
dp += i;
1520
/* The macro expansion exceeded the limit on ANSI strings, so split it:
1521
*/
1522
dp -= PNG_TC_ROWBYTES(*tc);
1523
debug(dp == tc->dp);
1524
# endif
1525
}
1526
1527
debug(sp == ep);
1528
# undef png_ptr
1529
}
1530
1531
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
1532
static void
1533
png_do_byte_ops_down(png_transformp *transform, png_transform_controlp tc)
1534
/* Row width is increasing */
1535
{
1536
# define png_ptr (tc->png_ptr)
1537
png_transform_byte_op *tr =
1538
png_transform_cast(png_transform_byte_op, *transform);
1539
const png_const_bytep ep = png_voidcast(png_const_bytep, tc->sp);
1540
const unsigned int sp_advance = PNG_TC_PIXEL_DEPTH(*tc) >> 3;
1541
png_const_bytep sp = ep + PNG_TC_ROWBYTES(*tc);
1542
png_bytep dp = png_voidcast(png_bytep, tc->dp);
1543
png_alloc_size_t dest_rowbytes;
1544
1545
debug(tc->bit_depth == 8U || tc->bit_depth == 16U);
1546
debug((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0U);
1547
1548
tc->sp = tc->dp;
1549
tc->format = tr->format;
1550
tc->bit_depth = tr->bit_depth;
1551
dest_rowbytes = PNG_TC_ROWBYTES(*tc);
1552
dp += dest_rowbytes;
1553
1554
/* In this case the 32-byte buffer is written downwards with a writes delayed
1555
* by 16 bytes as before. 'hwm' is lower than i; 0 or 16.
1556
*/
1557
{
1558
const png_uint_32 codes = tr->codes;
1559
png_uint_32 code = codes;
1560
unsigned int size, hwm, i;
1561
png_byte output[32] = { 0 };
1562
1563
/* This catches an empty codes array, which would cause all the input to
1564
* be skipped and, potentially, a garbage output[] to be written (once) to
1565
* *dp.
1566
*/
1567
affirm((codes & 0xFU) >= 4U);
1568
1569
/* Align the writes to a 16-byte multiple from the start of the
1570
* destination buffer:
1571
*/
1572
size = dest_rowbytes & 0xFU;
1573
if (size == 0U) size = 16U;
1574
i = size+16U;
1575
sp -= sp_advance; /* Move 1 pixel back */
1576
hwm = 0U;
1577
1578
for (;;)
1579
{
1580
unsigned int next_code = code & 0xFU;
1581
1582
if (next_code >= 8U)
1583
output[--i] = sp[next_code-8U];
1584
1585
else if (next_code >= 4U)
1586
output[--i] = tr->filler[next_code - 4U];
1587
1588
else /* end code */
1589
{
1590
sp -= sp_advance;
1591
1592
if (sp < ep)
1593
break;
1594
1595
code = codes;
1596
continue; /* no ouput produced, skip the check */
1597
}
1598
1599
code >>= 4; /* find the next code */
1600
1601
if (i == hwm)
1602
{
1603
/* A partial copy comes at the beginning to align the copies to a
1604
* 16-byte boundary. The bytes to be written are the bytes
1605
* i+16..(hwm-1) except that the partial buffer may reduce this.
1606
*/
1607
dp -= size;
1608
hwm ^= 0x10U; /* == i+16 mod 32 */
1609
memcpy(dp, output + hwm, size);
1610
size = 16U;
1611
if (i == 0U) i = 32U;
1612
}
1613
}
1614
1615
/* The loop above only exits with an exit code, so 'i' has been checked
1616
* against 'hwm' before and, because of the alignment, i will always be
1617
* either 16 or 32:
1618
*/
1619
debug((i == 16U || i == 32U) & (((i & 0x10U)^0x10U) == hwm));
1620
debug(sp+sp_advance == ep);
1621
1622
/* At the end the bytes i..(hwm-1) need to be written, with the proviso
1623
* that 'size' will be less than 16 for short rows. If 'size' is still a
1624
* short value then the range to be written is output[i..16+(size-1)],
1625
* otherwise (size == 16) either this is the first write and a full 32
1626
* bytes will be written (hwm == 0, i == 32) or 16 bytes need to be
1627
* written.
1628
*/
1629
if (size < 16U)
1630
{
1631
debug(i == 16U);
1632
dp -= size;
1633
memcpy(dp, output + i, size);
1634
}
1635
1636
else /* size == 16 */
1637
{
1638
debug(size == 16U);
1639
1640
/* Write i..(hwm-1); 16 or 32 bytes, however if 32 bytes are written
1641
* they are contiguous and i==0.
1642
*
1643
* hwm is 0 or 16, i is 16 or 32, swap 0 and 32:
1644
*/
1645
if (hwm == 0U) hwm = 32U;
1646
if (i == 32U) i = 0U;
1647
affirm(i < hwm);
1648
debug(hwm == i+16U || (i == 0U && hwm == 32U));
1649
1650
hwm -= i;
1651
dp -= hwm;
1652
memcpy(dp, output+i, hwm);
1653
}
1654
}
1655
1656
debug(dp == png_upcast(png_bytep, tc->dp));
1657
1658
# undef png_ptr
1659
}
1660
#endif /* READ_TRANSFORMS */
1661
1662
/* 16 bit byte swapping */
1663
static void
1664
png_do_bswap(png_transformp *transform, png_transform_controlp tc)
1665
{
1666
# define png_ptr (tc->png_ptr)
1667
png_transform_byte_op *tr =
1668
png_transform_cast(png_transform_byte_op, *transform);
1669
png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
1670
png_bytep dp = png_voidcast(png_bytep, tc->dp);
1671
const png_alloc_size_t rowbytes = PNG_TC_ROWBYTES(*tc);
1672
1673
tc->format = tr->format;
1674
tc->bit_depth = tr->bit_depth;
1675
tc->sp = dp;
1676
1677
# ifdef _XOPEN_SOURCE
1678
/* byte swapping often has incredibly fast implementations because of the
1679
* importance in handling ethernet traffic. X/Open defines swab() for
1680
* this purpose and it is widely supported and normally incredibly fast:
1681
*/
1682
debug((rowbytes & 1) == 0);
1683
swab(sp, dp, rowbytes);
1684
# else /* !_XOPEN_SOURCE */
1685
{
1686
const png_const_bytep ep = sp + rowbytes - 1;
1687
1688
while (sp < ep)
1689
{
1690
png_byte b0 = *sp++;
1691
*dp++ = *sp++;
1692
*dp++ = b0;
1693
}
1694
1695
debug(sp == ep+1); /* even number of bytes */
1696
}
1697
# endif
1698
1699
PNG_UNUSED(transform)
1700
# undef png_ptr
1701
}
1702
1703
/* The following flags, store in tr->args, are set by the relevant PNGAPI
1704
* png_set calls then resolved below.
1705
*/
1706
#define PNG_BO_STRIP_ALPHA 0x0001U /* Remove an alpha channel (read only) */
1707
#define PNG_BO_CHOP_16_TO_8 0x0002U /* Chop 16-bit to 8-bit channels */
1708
#define PNG_BO_GRAY_TO_RGB 0x0004U /* G <-> RGB; replicate channels */
1709
/* QUANTIZE happens here */
1710
#define PNG_BO_EXPAND_16 0x0008U /* Expand 8-bit channels to 16-bit */
1711
#define PNG_BO_BGR 0x0010U /* RGB <-> BGR */
1712
#define PNG_BO_FILLER 0x0020U /* Add a filler/alpha */
1713
#define PNG_BO_SWAP_ALPHA 0x0040U /* xA <-> Ax; alpha swap */
1714
#define PNG_BO_SWAP_16 0x0080U /* 16-bit channel byte swapping */
1715
1716
/* The following are additional flags to qualify the transforms: */
1717
#define PNG_BO_FILLER_ALPHA 0x4000U /* The filler is an alpha value */
1718
#define PNG_BO_FILLER_FIRST 0x8000U /* The filler comes first */
1719
1720
static void
1721
png_init_byte_ops(png_transformp *transform, png_transform_controlp tc)
1722
{
1723
/* In the absence of png_set_quantize none of the above operations apply to a
1724
* palette row except indirectly; they may apply if the palette was expanded,
1725
* but this happens earlier in the pipeline.
1726
*
1727
* In the presence of png_set_quantize the rules are considerably more
1728
* complex. In libpng 1.6.0 the following operations occur before
1729
* png_do_quantize:
1730
*
1731
* PNG_BO_GRAY_TO_RGB (png_do_gray_to_rgb, but only sometimes)
1732
* PNG_BO_STRIP_ALPHA (png_do_strip_channel; removes alpha)
1733
* encode_alpha
1734
* scale_16_to_8
1735
* PNG_BO_CHOP_16_TO_8 (png_do_chop)
1736
*
1737
* The following occur afterward:
1738
*
1739
* PNG_BO_EXPAND_16 (png_do_expand_16)
1740
* PNG_BO_GRAY_TO_RGB (png_do_gray_to_rgb, normally)
1741
* PNG_BO_BGR (png_do_bgr)
1742
* PNG_BO_FILLER (png_do_read_filler)
1743
* PNG_BO_SWAP_ALPHA (png_do_read_swap_alpha)
1744
* PNG_BO_SWAP_16 (png_do_swap; 16-bit byte swap)
1745
*
1746
* The gray to RGB operation needs to occur early for GA or gray+tRNS images
1747
* where the pixels are being composed on a non-gray value. For the moment
1748
* we assume that if this is necessary the following 'init' code will see RGB
1749
* at this point.
1750
*
1751
* The quantize operation operates only if:
1752
*
1753
* 1) tc->bit_depth is 8
1754
* 2) The color type exactly matches that required by the parameters to
1755
* png_set_quantize; it can be RGB, RGBA or palette, but
1756
* png_set_quantize (not the init routine) determines this.
1757
*
1758
* To avoid needing to know this here the two stage initialization is used
1759
* with two transforms, one pre-quantization the other post. In the first
1760
* stage the correct row format and depth is set up. In the second stage the
1761
* pre-quantization transform looks for a post-quantization transform
1762
* immediately following and, if it exists, transfers its flags to that.
1763
*/
1764
png_structp png_ptr = tc->png_ptr;
1765
png_transform_byte_op *tr =
1766
png_transform_cast(png_transform_byte_op, *transform);
1767
png_uint_32 args = tr->tr.args;
1768
const unsigned int png_format = tc->format;
1769
unsigned int format = png_format; /* memory format */
1770
const unsigned int png_bit_depth = tc->bit_depth;
1771
unsigned int bit_depth = png_bit_depth; /* memory bit depth */
1772
1773
debug(tc->init);
1774
1775
/* Channel swaps do not occur on COLORMAP format data at present because the
1776
* COLORMAP is limited to 1 byte per pixel (so there is nothing to
1777
* manipulate). Likewise for low bit depth gray, however the code below may
1778
* widen 8-bit gray to RGB.
1779
*/
1780
if ((png_format & PNG_FORMAT_FLAG_COLORMAP) != 0U || png_bit_depth < 8U)
1781
{
1782
tr->tr.fn = NULL;
1783
return;
1784
}
1785
1786
/* This will normally happen in TC_INIT_FORMAT, but if there is a
1787
* png_do_quantize operation which doesn't apply (this is unlikely) it will
1788
* happen in TC_INIT_FINAL.
1789
*/
1790
if (tr->tr.next != NULL && tr->tr.next->order == PNG_TR_CHANNEL_POSTQ)
1791
{
1792
debug(tr->tr.order == PNG_TR_CHANNEL_PREQ);
1793
1794
/* So we can merge this transform into the next one, note that because the
1795
* PNG_BO_FILLER operation is POSTQ we don't need to copy anything other
1796
* than the flags.
1797
*/
1798
debug((args & tr->tr.next->args) == 0U);
1799
tr->tr.next->args |= args;
1800
tr->tr.fn = NULL;
1801
return;
1802
}
1803
1804
/* Else compact the flags for this transform - this is done in both
1805
* TC_INIT_FORMAT and TC_INIT_FINAL because it is safer that way; the copy
1806
* above shouldn't actually affect the results but might result in TO8 and
1807
* TO16 cancelling each other because they are in separate transforms before
1808
* the merge above.
1809
*
1810
* QUIET API CHANGE:
1811
* For compatiblity with earlier versions of libpng these tests need to
1812
* occur in the same order as the earlier transforms; 'TO8' combined with
1813
* 'TO16' did actually do something to 16-bit data, however now it just
1814
* preserves the original bit depth.
1815
*/
1816
if ((args & PNG_BO_STRIP_ALPHA) != 0U)
1817
{
1818
if ((format & PNG_FORMAT_FLAG_ALPHA) != 0U)
1819
format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA);
1820
1821
else
1822
args &= PNG_BIC_MASK(PNG_BO_STRIP_ALPHA);
1823
}
1824
1825
if ((args & PNG_BO_CHOP_16_TO_8) != 0U)
1826
{
1827
/* This is the quiet API CHANGE; in fact it isn't necessary, but it
1828
* seems likely that requesting both operations is a mistake:
1829
*/
1830
if ((args & PNG_BO_EXPAND_16) != 0U)
1831
args &= PNG_BIC_MASK(PNG_BO_CHOP_16_TO_8|PNG_BO_EXPAND_16);
1832
1833
else if (bit_depth == 16U)
1834
{
1835
bit_depth = 8U;
1836
1837
/* This also makes the tRNS chunk unusable: */
1838
tc->invalid_info |= PNG_INFO_tRNS+PNG_INFO_hIST+PNG_INFO_pCAL;
1839
/* These need further processing: PNG_INFO_sBIT, PNG_INFO_bKGD */
1840
}
1841
1842
else
1843
args &= PNG_BIC_MASK(PNG_BO_CHOP_16_TO_8);
1844
}
1845
1846
/* QUANTIZE happens here */
1847
1848
if ((args & PNG_BO_EXPAND_16) != 0U)
1849
{
1850
/* This only does the 8 to 16-bit part of the expansion by multiply by
1851
* 65535/255 (257) using byte replication. The cases of low bit depth
1852
* gray being expanded to 16-bit have to be handled separately.
1853
*/
1854
if (bit_depth == 8U)
1855
bit_depth = 16U;
1856
1857
else
1858
args &= PNG_BIC_MASK(PNG_BO_EXPAND_16);
1859
}
1860
1861
if ((args & PNG_BO_GRAY_TO_RGB) != 0U)
1862
{
1863
if ((format & PNG_FORMAT_FLAG_COLOR) == 0U)
1864
format |= PNG_FORMAT_FLAG_COLOR;
1865
1866
else
1867
args &= PNG_BIC_MASK(PNG_BO_GRAY_TO_RGB);
1868
}
1869
1870
if ((args & PNG_BO_BGR) != 0U)
1871
{
1872
/* This does not happen on colormaps: */
1873
if ((format & PNG_FORMAT_FLAG_COLOR) != 0U && !tc->palette)
1874
format |= PNG_FORMAT_FLAG_BGR;
1875
1876
else
1877
args &= PNG_BIC_MASK(PNG_BO_BGR);
1878
}
1879
1880
if ((args & PNG_BO_FILLER) != 0U)
1881
{
1882
if ((format & PNG_FORMAT_FLAG_ALPHA) == 0U)
1883
{
1884
format |= PNG_FORMAT_FLAG_ALPHA;
1885
tc->channel_add = 1U;
1886
/* And SWAP_ALPHA did not occur, because prior to 1.7.0 the filler op
1887
* did not set ALPHA in the color type, so use SWAP_ALPHA to handle the
1888
* before/after filler location.
1889
*
1890
* NOTE: this occurs twice, once in TC_START and once in TC_FINAL, but
1891
* that is ok, the operations are idempotent.
1892
*
1893
* For colormaps (tc->palette set) the filler will just end up setting
1894
* all the tRNS entries and PNG_BO_SWAP_ALPHA will be cancelled below.
1895
*/
1896
if ((args & PNG_BO_FILLER_FIRST) != 0U)
1897
args |= PNG_BO_SWAP_ALPHA;
1898
1899
else
1900
args &= PNG_BIC_MASK(PNG_BO_SWAP_ALPHA);
1901
1902
if (!(args & PNG_BO_FILLER_ALPHA)) /* filler is not alpha */
1903
format |= PNG_FORMAT_FLAG_AFILLER;
1904
}
1905
1906
else
1907
args &= PNG_BIC_MASK(PNG_BO_FILLER);
1908
}
1909
1910
if ((args & PNG_BO_SWAP_ALPHA) != 0U)
1911
{
1912
/* This does not happen on color maps: */
1913
if ((format & PNG_FORMAT_FLAG_ALPHA) != 0U && !tc->palette)
1914
format |= PNG_FORMAT_FLAG_AFIRST;
1915
1916
else
1917
args &= PNG_BIC_MASK(PNG_BO_SWAP_ALPHA);
1918
}
1919
1920
if ((args & PNG_BO_SWAP_16) != 0U)
1921
{
1922
if (bit_depth == 16U)
1923
format |= PNG_FORMAT_FLAG_SWAPPED;
1924
1925
else
1926
args &= PNG_BIC_MASK(PNG_BO_SWAP_16);
1927
}
1928
1929
if (args != 0U)
1930
{
1931
/* At the end (TC_INIT_FINAL) work out the mapping array using the codes
1932
* defined above and store the format and bit depth changes (as changes,
1933
* so they will work either forward or backward). The filler array must
1934
* be set up by the png_set API.
1935
*/
1936
if (tc->init == PNG_TC_INIT_FINAL)
1937
{
1938
const unsigned int png_pixel_size = PNG_TC_PIXEL_DEPTH(*tc) >> 3;
1939
1940
tc->format = format;
1941
tc->bit_depth = bit_depth;
1942
1943
{
1944
const unsigned int memory_pixel_size = PNG_TC_PIXEL_DEPTH(*tc) >> 3;
1945
unsigned int code_size, src_size;
1946
int go_down;
1947
png_byte codes[8];
1948
1949
/* The codes array maps the PNG format into the memory format
1950
* assuming the mapping works upwards in the address space.
1951
* Initially ignore the bit depth and just work on the first four
1952
* bytes.
1953
*/
1954
codes[0] = 8U;
1955
codes[1] = 9U;
1956
codes[2] = 10U;
1957
codes[3] = 11U;
1958
codes[7] = codes[6] = codes[5] = codes[4] = 0U/*error*/;
1959
1960
/* PNG_BO_STRIP_ALPHA: handled by memory_pixel_size */
1961
/* PNG_BO_CHOP_16_TO_8: handled below */
1962
/* PNG_BO_EXPAND_16: handled below */
1963
1964
if ((args & PNG_BO_GRAY_TO_RGB) != 0U)
1965
{
1966
codes[3] = 9U; /* alpha, if present */
1967
codes[2] = codes[1] = 8U;
1968
1969
# ifdef PNG_READ_tRNS_SUPPORTED
1970
/* Gray to RGB, so copy the tRNS G value into r,g,b: */
1971
if (png_ptr->num_trans == 1U)
1972
png_ptr->trans_color.blue =
1973
png_ptr->trans_color.green =
1974
png_ptr->trans_color.red =
1975
png_ptr->trans_color.gray;
1976
# endif /* READ_tRNS */
1977
}
1978
1979
/* 'BGR' and gray-to-RGB are mutually exclusive; with gray-to-RGB
1980
* codes[0] == codes[2] == 8
1981
*/
1982
else if ((args & PNG_BO_BGR) != 0U)
1983
{
1984
codes[0] = 10U;
1985
codes[2] = 8U;
1986
}
1987
1988
if ((args & PNG_BO_FILLER) != 0U)
1989
{
1990
/* The filler alway goes after; for a 'before' filler the code
1991
* above turns on SWAP_ALPHA too. The gray-to-RGB transform has
1992
* happened already, so the location of the filler channel is
1993
* given by 'format':
1994
*/
1995
if ((format & PNG_FORMAT_FLAG_COLOR) != 0U)
1996
codes[3] = 4U; /* low byte of filler */
1997
1998
else
1999
codes[1] = 4U;
2000
}
2001
2002
if ((args & PNG_BO_SWAP_ALPHA) != 0U)
2003
{
2004
if ((format & PNG_FORMAT_FLAG_COLOR) != 0U)
2005
{
2006
/* BGR may have swapped the early codes. gray-to-RGB may have
2007
* set them all to '8':
2008
*/
2009
png_byte acode = codes[3];
2010
codes[3] = codes[2];
2011
codes[2] = codes[1];
2012
codes[1] = codes[0];
2013
codes[0] = acode;
2014
}
2015
2016
else /* GA format */
2017
codes[0] = codes[1], codes[1] = 8U;
2018
}
2019
2020
/* PNG_BO_SWAP_16: 16-bit only, handled below */
2021
2022
/* Now the 16-bit dependent stuff. */
2023
if ((args & PNG_BO_CHOP_16_TO_8) != 0U)
2024
{
2025
/* 16-bit input, 8-bit output, happens before FILLER so the
2026
* filler must be an 8-bit value. Apart from a filler code (4 in
2027
* this case) the code must be adjusted from byte 'x' to byte
2028
* '2x' to select the MSB of each 16-bit channel.
2029
*
2030
* We must use PNG_FORMAT_CHANNELS here because the memory pixel
2031
* size might (in the future) include a TO16 operation.
2032
*/
2033
unsigned int i = PNG_FORMAT_CHANNELS(format);
2034
2035
while (i > 0U)
2036
{
2037
unsigned int code = codes[--i];
2038
2039
if (code > 8U) /* 8, 4 need not change */
2040
codes[i] = PNG_BYTE(8U+2U*(code-8U));
2041
}
2042
}
2043
2044
if ((args & PNG_BO_EXPAND_16) != 0U)
2045
{
2046
/* Don't expect this with CHOP, but it will work, setting the low
2047
* 8-bits of each 16-bit value to the high bits.
2048
*/
2049
unsigned int i = PNG_FORMAT_CHANNELS(format);
2050
2051
while (i > 0U)
2052
{
2053
png_byte code = codes[--i];
2054
2055
/* BSWAP is after FILLER, however the data passed in is a
2056
* machine native png_uint_16. We don't know until this init
2057
* routine whether the data is an 8 or 16-bit value because we
2058
* don't know the full set of transforms the app will apply
2059
* when the png_set_filler API is called.
2060
*
2061
* This means that the data in tr->filler[] needs to have the
2062
* low bits in a known place, so the code here puts the low 8
2063
* bits in filler[0], code 4. Hence the following:
2064
*/
2065
if (code == 4U)
2066
codes[2U*i/*MSB*/] = 5U, codes[2U*i+1U/*LSB*/] = 4U;
2067
2068
else
2069
codes[2U*i] = codes[2U*i+1U] = code;
2070
}
2071
2072
# ifdef PNG_READ_tRNS_SUPPORTED
2073
/* We're just duplicating bytes, so the tRNS chunk can be
2074
* maintained if present. If the tRNS is for a colormap this
2075
* produces garbage in trans_color, but it isn't used.
2076
*/
2077
if (png_ptr->num_trans == 1U)
2078
{
2079
# define TO16(x) x = PNG_UINT_16((x & 0xFFU) * 0x101U)
2080
TO16(png_ptr->trans_color.gray);
2081
TO16(png_ptr->trans_color.red);
2082
TO16(png_ptr->trans_color.green);
2083
TO16(png_ptr->trans_color.blue);
2084
# undef TO16
2085
}
2086
# endif /* READ_tRNS */
2087
}
2088
2089
else if (bit_depth == 16U)
2090
{
2091
/* 16-bit input and output. */
2092
unsigned int i = PNG_FORMAT_CHANNELS(format);
2093
2094
while (i > 0U)
2095
{
2096
unsigned int code = codes[--i];
2097
2098
if (code == 4U) /* as above */
2099
codes[2U*i/*MSB*/] = 5U, codes[2U*i+1U/*LSB*/] = 4U;
2100
2101
else
2102
{
2103
codes[2U*i] = PNG_BYTE(8U+2U*(code-8U));
2104
codes[2U*i+1U] = PNG_BYTE(8U+2U*(code-8U)+1U);
2105
}
2106
}
2107
}
2108
2109
if ((args & PNG_BO_SWAP_16) != 0U)
2110
{
2111
/* bswap the memory bytes. */
2112
unsigned int i;
2113
png_byte bswap_codes[sizeof codes];
2114
2115
debug((memory_pixel_size & 1U) == 0U);
2116
2117
for (i=0U; i<sizeof codes; ++i)
2118
bswap_codes[i] = codes[i ^ 1U];
2119
2120
memcpy(codes, bswap_codes, sizeof codes);
2121
}
2122
2123
# ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
2124
/* Handle the 'write' case; the codes[] array must be inverted,
2125
* it lists the PNG pixel for each memory pixel, we need it to
2126
* list the memory pixel for each PNG pixel.
2127
*/
2128
if (!png_ptr->read_struct)
2129
{
2130
/* There are no write transforms that add data to the PNG
2131
* file; the 'filler' transform removes a channel, but that is
2132
* the limit of the changes.
2133
*/
2134
unsigned int i = 0U;
2135
png_byte write_codes[8U];
2136
2137
memset(write_codes, 0, sizeof write_codes);
2138
2139
while (i<memory_pixel_size)
2140
{
2141
unsigned int code = codes[i];
2142
2143
if (code >= 8U) /* 8+index of PNG byte */
2144
write_codes[code-8U] = PNG_BYTE(8U+i);
2145
/* else this is a filler byte to be removed */
2146
else
2147
debug(code == 4U || code == 5U);
2148
2149
++i;
2150
}
2151
2152
code_size = png_pixel_size;
2153
src_size = memory_pixel_size;
2154
tr->format = png_format;
2155
tr->bit_depth = png_bit_depth;
2156
2157
/* The PNG size should always be <= to the memory size, the
2158
* source pointer will be the memory, the destination the PNG
2159
* format, so it should always be possible to do the upwards
2160
* copy.
2161
*/
2162
go_down = png_pixel_size > memory_pixel_size;
2163
affirm(!go_down);
2164
memcpy(codes, write_codes, sizeof codes);
2165
}
2166
2167
else
2168
# endif /* WRITE_TRANSFORMS */
2169
{
2170
code_size = memory_pixel_size;
2171
src_size = png_pixel_size;
2172
tr->format = format;
2173
tr->bit_depth = bit_depth;
2174
go_down = png_pixel_size < memory_pixel_size;
2175
}
2176
2177
/* Record this for debugging: */
2178
tr->tr.args = args;
2179
2180
/* For the same-pixel-size case check for a bswap; this is available
2181
* in heavily optimized forms and is a common operation (50% of the
2182
* time) with 16-bit PNG data, particularly given the handling in
2183
* the simplified API.
2184
*/
2185
if (!go_down)
2186
{
2187
if (memory_pixel_size == png_pixel_size)
2188
{
2189
int the_same = 1;
2190
int swapped = (memory_pixel_size & 1) == 0; /* even count */
2191
unsigned int i;
2192
2193
for (i=0U; i<memory_pixel_size; ++i)
2194
{
2195
if (codes[i] != 8U+i)
2196
{
2197
the_same = 0;
2198
if (codes[i] != 8U+(i^1U))
2199
swapped = 0;
2200
if (!swapped)
2201
break;
2202
}
2203
2204
else /* byte is copied, so it can't be swapped! */
2205
{
2206
swapped = 0;
2207
if (!the_same)
2208
break;
2209
}
2210
}
2211
2212
/* Use the 'bswap' routine if possible. */
2213
if (swapped)
2214
{
2215
tr->tr.fn = png_do_bswap;
2216
return;
2217
}
2218
2219
else if (the_same)
2220
impossible("not reached");
2221
}
2222
2223
tr->tr.fn = png_do_byte_ops_up;
2224
2225
/* Construct the code, forwards: */
2226
{
2227
unsigned int i = code_size;
2228
png_uint_32 code = 0U;
2229
2230
while (i > 0U)
2231
{
2232
unsigned int next = codes[--i];
2233
2234
code <<= 4U;
2235
2236
if ((next >= 8U && next < 8U+src_size) ||
2237
next == 4U || next == 5U)
2238
code += next;
2239
2240
else
2241
impossible("invalid code (up)");
2242
}
2243
2244
tr->codes = code;
2245
}
2246
}
2247
2248
else /* go_down */
2249
# ifdef PNG_READ_TRANSFORMS_SUPPORTED
2250
{
2251
tr->tr.fn = png_do_byte_ops_down;
2252
2253
/* Construct the code, backwards: */
2254
{
2255
unsigned int i = 0U;
2256
png_uint_32 code = 0U;
2257
2258
while (i < code_size)
2259
{
2260
unsigned int next = codes[i++];
2261
2262
code <<= 4;
2263
2264
if ((next >= 8U && next < 8U+src_size) ||
2265
next == 4U || next == 5U)
2266
code += next;
2267
2268
else
2269
impossible("invalid code (down)");
2270
}
2271
2272
tr->codes = code;
2273
}
2274
}
2275
# else /* !READ_TRANSFORMS */
2276
impossible("not reached"); /* because of the affirm above */
2277
# endif /* !READ_TRANSFORMS */
2278
}
2279
}
2280
2281
else /* TC_INIT_FORMAT: just store modified 'args' */
2282
{
2283
tc->format = format;
2284
tc->bit_depth = bit_depth;
2285
tr->tr.args = args;
2286
}
2287
}
2288
2289
else /* the transform is not applicable */
2290
tr->tr.fn = NULL;
2291
}
2292
#endif /* SWAP poo */
2293
2294
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
2295
static void
2296
png_init_rgb_to_gray_byte_ops(png_transformp *transform,
2297
png_transform_controlp tc)
2298
{
2299
/* This just delay initializes the function; all the transform initialization
2300
* has been done below.
2301
*/
2302
(*transform)->fn = png_do_byte_ops_up;
2303
2304
/* If this happens on a row do the transform immediately: */
2305
if (!tc->init)
2306
png_do_byte_ops_up(transform, tc);
2307
2308
else
2309
{
2310
/* This doing the init - update the row information here */
2311
# define png_ptr (tc->png_ptr)
2312
png_transform_byte_op *tr =
2313
png_transform_cast(png_transform_byte_op, *transform);
2314
2315
debug(tc->bit_depth == 8U || tc->bit_depth == 16U);
2316
debug((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0U &&
2317
(tc->format & PNG_FORMAT_FLAG_COLOR) != 0U);
2318
2319
tc->format = tr->format;
2320
tc->bit_depth = tr->bit_depth;
2321
# undef png_ptr
2322
}
2323
}
2324
2325
void /* PRIVATE */
2326
png_add_rgb_to_gray_byte_ops(png_structrp png_ptr, png_transform_controlp tc,
2327
unsigned int index, unsigned int order)
2328
/* Add a byte_ops transform to convert RGB or RGBA data to 'gray' by
2329
* selecting just the given change [index] The transform added is added at
2330
* 'order'.
2331
*/
2332
{
2333
png_transform_byte_op *tr = png_transform_cast(png_transform_byte_op,
2334
png_add_transform(png_ptr, sizeof (png_transform_byte_op),
2335
png_init_rgb_to_gray_byte_ops, order));
2336
2337
affirm((tc->format & (PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_COLORMAP)) ==
2338
PNG_FORMAT_FLAG_COLOR &&
2339
index <= 2 && tc->init == PNG_TC_INIT_FINAL);
2340
2341
tr->format = tc->format & PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR);
2342
tr->bit_depth = tc->bit_depth;
2343
2344
/* For 1 byte channel [index] plus, maybe, alpha: */
2345
if (tc->bit_depth == 8)
2346
tr->codes = 8U + index +
2347
((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0 ? (8U+3U) << 4 : 0U);
2348
2349
else
2350
{
2351
affirm(tc->bit_depth == 16);
2352
2353
/* As above, but two bytes; [2*index] and [2*index+1] */
2354
index *= 2U;
2355
tr->codes = (8U + index) + ((9U + index) << 4) +
2356
((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0 ?
2357
((8U+6U) + ((9U+6U) << 4)) << 8 : 0U);
2358
}
2359
}
2360
#endif /* READ_RGB_TO_GRAY */
2361
2362
#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) &&\
2363
defined(PNG_READ_BACKGROUND_SUPPORTED)
2364
void /* PRIVATE */
2365
png_push_gray_to_rgb_byte_ops(png_transformp *transform,
2366
png_transform_controlp tc)
2367
/* This is an init-time utility to add appropriate byte ops to expand a
2368
* grayscale PNG data set to RGB.
2369
*/
2370
{
2371
# define png_ptr (tc->png_ptr)
2372
png_transformp tr = png_push_transform(png_ptr,
2373
sizeof (png_transform_byte_op), png_init_byte_ops, transform, NULL);
2374
2375
tr->args = PNG_BO_GRAY_TO_RGB;
2376
debug(tr == *transform);
2377
png_init_byte_ops(transform, tc);
2378
# undef png_ptr
2379
}
2380
#endif /* GRAY_TO_RGB && READ_BACKGROUND */
2381
2382
#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
2383
void /* PRIVATE */
2384
png_add_strip_alpha_byte_ops(png_structrp png_ptr)
2385
{
2386
png_add_transform(png_ptr, sizeof (png_transform_byte_op), png_init_byte_ops,
2387
PNG_TR_CHANNEL_PREQ)->args |= PNG_BO_STRIP_ALPHA;
2388
}
2389
#endif /* READ_STRIP_ALPHA */
2390
2391
#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
2392
/* Chop 16-bit depth files to 8-bit depth */
2393
void PNGAPI
2394
png_set_strip_16(png_structrp png_ptr)
2395
{
2396
if (png_ptr != NULL)
2397
png_add_transform(png_ptr, sizeof (png_transform_byte_op),
2398
png_init_byte_ops, PNG_TR_CHANNEL_PREQ)->args |=
2399
PNG_BO_CHOP_16_TO_8;
2400
}
2401
#endif /* READ_STRIP_16_TO_8 */
2402
2403
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
2404
void PNGAPI
2405
png_set_gray_to_rgb(png_structrp png_ptr)
2406
{
2407
if (png_ptr != NULL)
2408
{
2409
png_set_expand_gray_1_2_4_to_8(png_ptr);
2410
png_add_transform(png_ptr, sizeof (png_transform_byte_op),
2411
png_init_byte_ops, PNG_TR_CHANNEL_PREQ)->args |=
2412
PNG_BO_GRAY_TO_RGB;
2413
}
2414
}
2415
#endif /* READ_GRAY_TO_RGB */
2416
2417
/* QUANTIZE */
2418
2419
#ifdef PNG_READ_EXPAND_16_SUPPORTED
2420
/* Expand to 16-bit channels. PNG_BO_EXPAND_16 also expands the tRNS chunk if
2421
* it is present, but it requires low bit depth grayscale expanded first. This
2422
* must also force palette to RGB.
2423
*/
2424
void PNGAPI
2425
png_set_expand_16(png_structrp png_ptr)
2426
{
2427
if (png_ptr != NULL)
2428
{
2429
png_set_expand_gray_1_2_4_to_8(png_ptr);
2430
png_set_palette_to_rgb(png_ptr);
2431
png_add_transform(png_ptr, sizeof (png_transform_byte_op),
2432
png_init_byte_ops, PNG_TR_CHANNEL_POSTQ)->args |=
2433
PNG_BO_EXPAND_16;
2434
}
2435
}
2436
#endif /* READ_EXPAND_16 */
2437
2438
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
2439
void PNGAPI
2440
png_set_bgr(png_structrp png_ptr)
2441
{
2442
if (png_ptr != NULL)
2443
{
2444
# ifndef PNG_READ_BGR_SUPPORTED
2445
if (png_ptr->read_struct)
2446
{
2447
png_app_error(png_ptr, "png_set_bgr not supported on read");
2448
return;
2449
}
2450
# endif
2451
# ifndef PNG_WRITE_BGR_SUPPORTED
2452
if (!png_ptr->read_struct)
2453
{
2454
png_app_error(png_ptr, "png_set_bgr not supported on write");
2455
return;
2456
}
2457
# endif
2458
2459
png_add_transform(png_ptr, sizeof (png_transform_byte_op),
2460
png_init_byte_ops, PNG_TR_CHANNEL_POSTQ)->args |=
2461
PNG_BO_BGR;
2462
}
2463
}
2464
#endif /* BGR */
2465
2466
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
2467
/* This includes png_set_filler and png_set_add_alpha. The only difference
2468
* between the two is that the latter resulted in PNG_COLOR_MASK_ALPHA being
2469
* added to the info_ptr color type, if png_read_update_info was called whereas
2470
* the former did not.
2471
*
2472
* Regardless of whether the added channel resulted in the change to the
2473
* png_info color type, the SWAP_ALPHA transform was not performed, even though
2474
* it apparently occured after the add, because PNG_COLOR_MASK_ALPHA was never
2475
* set in the 1.6 'row_info'.
2476
*
2477
* Consequently 'SWAP_ALPHA' and 'FILLER' were independent; one or the other
2478
* would occur depending on the color type (not the number of channels) prior to
2479
* the two transforms.
2480
*
2481
* Prior to 1.7.0 the app could obtain information about the memory format by
2482
* calling png_read_update_info followed by png_get_color_type and
2483
* png_get_channels. The first would return PNG_COLOR_TYPE..._ALPHA if
2484
* png_set_add_alpha was performed and the base type if png_set_filler was
2485
* performed, however in both cases png_get_channels would return the extra
2486
* channel; 2 or 4.
2487
*
2488
* The app could also insert a user transform callback and view the color type
2489
* in the old "row_info" structure, however this resulted in an inconsistent
2490
* color type because png_set_alpha did not add COLOR_MASK_ALPHA to the color
2491
* type.
2492
*
2493
* Hence API CHANGE: 1.7.0, row transform callbacks now see the same color type
2494
* as reported by png_get_color_type after png_read_update_info.
2495
*/
2496
/* Add a filler byte on read, or remove a filler or alpha byte on write.
2497
* The filler type has changed in v0.95 to allow future 2-byte fillers
2498
* for 48-bit input data, as well as to avoid problems with some compilers
2499
* that don't like bytes as parameters.
2500
*/
2501
static void
2502
set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc, int alpha)
2503
{
2504
if (png_ptr != NULL)
2505
{
2506
if (filler_loc != PNG_FILLER_BEFORE && filler_loc != PNG_FILLER_AFTER)
2507
{
2508
png_app_error(png_ptr, "png_set_filler: invalid filler location");
2509
return;
2510
}
2511
2512
# ifndef PNG_READ_SWAP_SUPPORTED
2513
if (png_ptr->read_struct)
2514
{
2515
png_app_error(png_ptr, "png_set_filler not supported on read");
2516
return;
2517
}
2518
# endif
2519
# ifndef PNG_WRITE_SWAP_SUPPORTED
2520
if (!png_ptr->read_struct)
2521
{
2522
png_app_error(png_ptr, "png_set_filler not supported on write");
2523
return;
2524
}
2525
# endif
2526
2527
{
2528
png_transform_byte_op *tr =
2529
png_transform_cast(png_transform_byte_op,
2530
png_add_transform(png_ptr, sizeof (png_transform_byte_op),
2531
png_init_byte_ops, PNG_TR_CHANNEL_POSTQ));
2532
png_uint_32 args = PNG_BO_FILLER;
2533
2534
if (filler_loc == PNG_FILLER_BEFORE)
2535
args |= PNG_BO_FILLER_FIRST;
2536
2537
if (alpha)
2538
args |= PNG_BO_FILLER_ALPHA;
2539
2540
tr->tr.args |= args;
2541
2542
/* The filler must be stored LSByte first: */
2543
tr->filler[0] = PNG_BYTE(filler >> 0);
2544
tr->filler[1] = PNG_BYTE(filler >> 8);
2545
tr->filler[2] = PNG_BYTE(filler >> 16);
2546
tr->filler[3] = PNG_BYTE(filler >> 24);
2547
}
2548
}
2549
}
2550
2551
void PNGAPI
2552
png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
2553
{
2554
set_filler(png_ptr, filler, filler_loc, 0/*!alpha*/);
2555
}
2556
2557
/* Added to libpng-1.2.7 */
2558
void PNGAPI
2559
png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
2560
{
2561
set_filler(png_ptr, filler, filler_loc, 1/*alpha*/);
2562
}
2563
#endif /* FILLER */
2564
2565
#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
2566
defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
2567
void PNGAPI
2568
png_set_swap_alpha(png_structrp png_ptr)
2569
{
2570
if (png_ptr != NULL)
2571
{
2572
# ifndef PNG_READ_SWAP_SUPPORTED
2573
if (png_ptr->read_struct)
2574
{
2575
png_app_error(png_ptr, "png_set_swap_alpha not supported on read");
2576
return;
2577
}
2578
# endif
2579
# ifndef PNG_WRITE_SWAP_SUPPORTED
2580
if (!png_ptr->read_struct)
2581
{
2582
png_app_error(png_ptr, "png_set_swap_alpha not supported on write");
2583
return;
2584
}
2585
# endif
2586
2587
png_add_transform(png_ptr, sizeof (png_transform_byte_op),
2588
png_init_byte_ops, PNG_TR_CHANNEL_POSTQ)->args |=
2589
PNG_BO_SWAP_ALPHA;
2590
}
2591
}
2592
#endif /* SWAP_ALPHA */
2593
2594
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
2595
void PNGAPI
2596
png_set_swap(png_structrp png_ptr)
2597
{
2598
if (png_ptr != NULL)
2599
{
2600
# ifndef PNG_READ_SWAP_SUPPORTED
2601
if (png_ptr->read_struct)
2602
{
2603
png_app_error(png_ptr, "png_set_swap not supported on read");
2604
return;
2605
}
2606
# endif
2607
# ifndef PNG_WRITE_SWAP_SUPPORTED
2608
if (!png_ptr->read_struct)
2609
{
2610
png_app_error(png_ptr, "png_set_swap not supported on write");
2611
return;
2612
}
2613
# endif
2614
2615
png_add_transform(png_ptr, sizeof (png_transform_byte_op),
2616
png_init_byte_ops, PNG_TR_CHANNEL_POSTQ)->args |=
2617
PNG_BO_SWAP_16;
2618
}
2619
}
2620
#endif /* SWAP */
2621
2622
#if defined(PNG_READ_PACKSWAP_SUPPORTED) ||\
2623
defined(PNG_WRITE_PACKSWAP_SUPPORTED) ||\
2624
defined(PNG_READ_INVERT_ALPHA_SUPPORTED) ||\
2625
defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) ||\
2626
defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
2627
static png_alloc_size_t
2628
row_align(png_transform_controlp tc)
2629
/* Utiltity to align the source row (sp) in a transform control; it does this
2630
* by simply copying it to dp if it is not already aligned. As a convenience
2631
* the utility returns the number of bytes in the row.
2632
*/
2633
{
2634
png_const_structp png_ptr = tc->png_ptr;
2635
png_const_voidp sp = tc->sp;
2636
png_voidp dp = tc->dp;
2637
png_alloc_size_t rowbytes = PNG_TC_ROWBYTES(*tc);
2638
2639
/* For alignment; if png_alignof is not supported by the compiler this will
2640
* always do an initial memcpy if the source and destination are not the
2641
* same. We can only get here for write; the read case always uses locally
2642
* allocated buffers, only write reads from the application data directly.
2643
*/
2644
# ifdef png_alignof
2645
debug(png_isaligned(dp, png_uint_32));
2646
# endif
2647
if (sp != dp && !png_ptr->read_struct && !png_isaligned(sp, png_uint_32))
2648
{
2649
UNTESTED
2650
memcpy(dp, sp, rowbytes);
2651
tc->sp = dp;
2652
}
2653
2654
return rowbytes;
2655
}
2656
#endif /* Stuff that needs row_align */
2657
2658
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) ||\
2659
defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) ||\
2660
defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
2661
/* Bit-ops; invert bytes. This works for mono inverts too because even the low
2662
* bit depths can be handled as bytes (since there can be no intervening
2663
* channels).
2664
*/
2665
#define PNG_B_INVERT_MONO 1U
2666
#define PNG_B_INVERT_RGB 2U /* not set, used below */
2667
#define PNG_B_INVERT_ALPHA 4U
2668
2669
typedef struct
2670
{
2671
png_transform tr;
2672
unsigned int step0; /* initial advance on sp and dp */
2673
unsigned int step; /* advance after start */
2674
png_uint_32 mask; /* XOR mask */
2675
} png_transform_bit_op;
2676
2677
static void
2678
png_do_invert_all(png_transformp *transform, png_transform_controlp tc)
2679
{
2680
const png_const_structp png_ptr = tc->png_ptr;
2681
/* Invert the whole row, quickly */
2682
const png_const_voidp dp_end = png_upcast(png_bytep, tc->dp) + row_align(tc);
2683
png_uint_32p dp = png_voidcast(png_uint_32p, tc->dp);
2684
png_const_uint_32p sp = png_voidcast(png_const_uint_32p, tc->sp);
2685
2686
tc->sp = dp;
2687
2688
if (png_ptr->read_struct)
2689
{
2690
tc->format |= PNG_FORMAT_FLAG_RANGE;
2691
tc->range++;
2692
}
2693
2694
else if (--(tc->range) == 0)
2695
tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_RANGE);
2696
2697
while (png_upcast(void*,dp) < dp_end)
2698
*dp++ = ~*sp++;
2699
2700
PNG_UNUSED(transform)
2701
}
2702
2703
static void
2704
png_do_invert_channel(png_transformp *transform, png_transform_controlp tc)
2705
{
2706
const png_const_structp png_ptr = tc->png_ptr;
2707
/* Invert just one channel in the row. */
2708
const png_transform_bit_op * const tr =
2709
png_transform_cast(png_transform_bit_op, *transform);
2710
const png_uint_32 mask = tr->mask;
2711
const unsigned int step = tr->step;
2712
const unsigned int step0 = tr->step0;
2713
const png_const_voidp dp_end = png_upcast(png_bytep, tc->dp) + row_align(tc);
2714
png_uint_32p dp = png_voidcast(png_uint_32p, tc->dp);
2715
png_const_uint_32p sp = png_voidcast(png_const_uint_32p, tc->sp);
2716
2717
tc->sp = dp;
2718
2719
if (png_ptr->read_struct)
2720
{
2721
tc->format |= PNG_FORMAT_FLAG_RANGE;
2722
tc->range++;
2723
}
2724
2725
else if (--(tc->range) == 0)
2726
tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_RANGE);
2727
2728
if (sp == dp || step == 1)
2729
{
2730
sp += step0;
2731
dp += step0;
2732
2733
while (png_upcast(void*,dp) < dp_end)
2734
*dp = *sp ^ mask, dp += step, sp += step;
2735
}
2736
2737
else /* step == 2, copy required */
2738
{
2739
if (step0) /* must be 1 */
2740
*dp++ = *sp++;
2741
2742
while (png_upcast(void*,dp) < dp_end)
2743
{
2744
*dp++ = *sp++ ^ mask;
2745
if (!(png_upcast(void*,dp) < dp_end))
2746
break;
2747
*dp++ = *sp++;
2748
}
2749
}
2750
2751
PNG_UNUSED(transform)
2752
}
2753
2754
static void
2755
png_init_invert(png_transformp *transform, png_transform_controlp tc)
2756
{
2757
# define png_ptr (tc->png_ptr)
2758
png_transform_bit_op *tr =
2759
png_transform_cast(png_transform_bit_op, *transform);
2760
png_uint_32 invert = tr->tr.args;
2761
png_uint_32 present; /* channels present */
2762
2763
if ((tc->format & PNG_FORMAT_FLAG_COLORMAP) != 0)
2764
present = 0;
2765
2766
else /* not color mapped */
2767
{
2768
if ((tc->format & PNG_FORMAT_FLAG_COLOR) != 0)
2769
present = PNG_B_INVERT_RGB;
2770
else
2771
present = PNG_B_INVERT_MONO;
2772
2773
if ((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0)
2774
present |= PNG_B_INVERT_ALPHA;
2775
}
2776
2777
/* Cannot invert things that aren't there: */
2778
invert &= present;
2779
2780
/* If nothing can be inverted is present the transform is not applicable: */
2781
if (invert == 0)
2782
(*transform)->fn = NULL;
2783
2784
else
2785
{
2786
tc->format |= PNG_FORMAT_FLAG_RANGE;
2787
tc->range++;
2788
2789
if (tc->init == PNG_TC_INIT_FINAL)
2790
{
2791
/* If everything that is present is to be inverted just invert the
2792
* whole row:
2793
*/
2794
if (invert == present)
2795
(*transform)->fn = png_do_invert_all;
2796
2797
else
2798
{
2799
/* One thing is to be inverted, G or A: */
2800
unsigned int channels = PNG_TC_CHANNELS(*tc);
2801
unsigned int channel =
2802
(tc->format & PNG_FORMAT_FLAG_AFIRST) != 0 ? 0 : channels-1;
2803
2804
affirm(channels == 2 || channels == 4);
2805
2806
if (invert != PNG_B_INVERT_ALPHA)
2807
{
2808
debug(invert == PNG_B_INVERT_MONO && channels == 2 &&
2809
present == PNG_B_INVERT_MONO+PNG_B_INVERT_ALPHA);
2810
channel = (channels-1) - channel;
2811
}
2812
2813
affirm(tc->bit_depth == 8 || tc->bit_depth == 16);
2814
2815
/* So channels[channel] is to be inverted, make a mask: */
2816
{
2817
union
2818
{
2819
png_byte bytes[8];
2820
png_uint_32 words[2];
2821
} masks;
2822
2823
memset(&masks, 0, sizeof masks);
2824
2825
if (tc->bit_depth == 8)
2826
{
2827
/* channels is 2 or 4, channel < 4. */
2828
masks.bytes[channel+channels] = masks.bytes[channel] = 0xff;
2829
tr->step = 1;
2830
tr->mask = masks.words[0];
2831
tr->step0 = 0;
2832
}
2833
2834
else /* tc->bit_depth == 16 */
2835
{
2836
channel <<= 1; /* in bytes */
2837
masks.bytes[channel+1] = masks.bytes[channel] = 0xff;
2838
2839
if (channels == 2)
2840
{
2841
tr->step = 1;
2842
tr->mask = masks.words[0];
2843
tr->step0 = 0;
2844
}
2845
2846
else /* channels == 4 */
2847
{
2848
tr->step = 2;
2849
2850
if (masks.words[0] == 0)
2851
{
2852
tr->mask = masks.words[1];
2853
tr->step0 = 1;
2854
}
2855
2856
else
2857
{
2858
tr->mask = masks.words[0];
2859
tr->step0 = 0;
2860
}
2861
}
2862
}
2863
}
2864
2865
(*transform)->fn = png_do_invert_channel;
2866
}
2867
}
2868
}
2869
# undef png_ptr
2870
}
2871
2872
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) ||\
2873
defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
2874
void PNGAPI
2875
png_set_invert_alpha(png_structrp png_ptr)
2876
{
2877
if (png_ptr != NULL)
2878
{
2879
png_add_transform(png_ptr, sizeof (png_transform_bit_op),
2880
png_init_invert, PNG_TR_INVERT)->args |= PNG_B_INVERT_ALPHA;
2881
# ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
2882
/* This is necessary to avoid palette processing on write; the only
2883
* transform that applies to colormapped images is the tRNS chunk
2884
* invert.
2885
*/
2886
png_ptr->write_invert_alpha = 1U;
2887
# endif
2888
}
2889
}
2890
#endif /* INVERT_ALPHA */
2891
2892
#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
2893
void PNGAPI
2894
png_set_invert_mono(png_structrp png_ptr)
2895
{
2896
if (png_ptr != NULL)
2897
png_add_transform(png_ptr, sizeof (png_transform_bit_op),
2898
png_init_invert, PNG_TR_INVERT)->args |= PNG_B_INVERT_MONO;
2899
}
2900
#endif /* INVERT */
2901
#endif /* INVERT_ALPHA || INVERT */
2902
2903
/*
2904
* WARNING
2905
* WARNING
2906
* WARNING
2907
* WARNING
2908
* WARNING The transforms below are temporary; they can and will be
2909
* WARNING heavily optimized before release.
2910
* WARNING
2911
* WARNING
2912
* WARNING
2913
*/
2914
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
2915
typedef struct
2916
{
2917
png_transform tr;
2918
png_color_8 true_bits;
2919
} png_transform_shift;
2920
2921
/* Shift pixel values to take advantage of whole range. Pass the
2922
* true number of bits in bit_depth. The row should be packed
2923
* according to tc->bit_depth. Thus, if you had a row of
2924
* bit depth 4, but the pixels only had values from 0 to 7, you
2925
* would pass 3 as bit_depth, and this routine would translate the
2926
* data to 0 to 15.
2927
*
2928
* NOTE: this is horrible complexity for no value. Once people suggested they
2929
* were selling 16-bit displays with 5:6:5 bits spread R:G:B but so far as I
2930
* could determine these displays produced intermediate grey (uncolored) colors,
2931
* which is impossible with a true 5:6:5, so most likely 5:6:5 was marketing.
2932
*/
2933
static unsigned int
2934
set_shifts(unsigned int format, unsigned int bit_depth,
2935
png_const_color_8p true_bits, int *shift_start, int *shift_dec)
2936
{
2937
unsigned int channels = 0;
2938
2939
if ((format & (PNG_FORMAT_FLAG_ALPHA+PNG_FORMAT_FLAG_AFIRST)) ==
2940
(PNG_FORMAT_FLAG_ALPHA+PNG_FORMAT_FLAG_AFIRST))
2941
++channels; /* filled in below */
2942
2943
if ((format & PNG_FORMAT_FLAG_COLOR) != 0)
2944
{
2945
unsigned int offset = /* 0 or 2 as appropriate for red */
2946
((format & PNG_FORMAT_FLAG_BGR) != 0) << 1;
2947
2948
shift_start[channels+offset] = bit_depth - true_bits->red;
2949
if (shift_dec != NULL) shift_dec[channels+offset] = true_bits->red;
2950
2951
shift_start[channels+1] = bit_depth - true_bits->green;
2952
if (shift_dec != NULL) shift_dec[channels+1] = true_bits->green;
2953
2954
offset ^= 2; /* for blue */
2955
shift_start[channels+offset] = bit_depth - true_bits->blue;
2956
if (shift_dec != NULL) shift_dec[channels+offset] = true_bits->blue;
2957
2958
channels += 3;
2959
}
2960
2961
else /* no color: gray */
2962
{
2963
shift_start[channels] = bit_depth - true_bits->gray;
2964
if (shift_dec != NULL) shift_dec[channels] = true_bits->gray;
2965
++channels;
2966
}
2967
2968
if ((format & PNG_FORMAT_FLAG_ALPHA) != 0)
2969
{
2970
const unsigned int offset =
2971
(format & PNG_FORMAT_FLAG_AFIRST) != 0 ? 0 : channels++;
2972
2973
shift_start[offset] = bit_depth - true_bits->alpha;
2974
if (shift_dec != NULL) shift_dec[offset] = true_bits->alpha;
2975
}
2976
2977
return channels;
2978
}
2979
2980
#ifdef PNG_WRITE_SHIFT_SUPPORTED
2981
static void
2982
png_do_shift(png_transformp *transform, png_transform_controlp tc)
2983
{
2984
# define png_ptr (tc->png_ptr)
2985
png_transform_shift *tr =
2986
png_transform_cast(png_transform_shift, *transform);
2987
png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
2988
png_bytep dp = png_voidcast(png_bytep, tc->dp);
2989
png_const_bytep dp_end = dp + PNG_TC_ROWBYTES(*tc);
2990
2991
png_debug(1, "in png_do_shift");
2992
2993
if (--(tc->range) == 0)
2994
tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_RANGE);
2995
2996
tc->sp = dp;
2997
2998
{
2999
int shift_start[4], shift_dec[4];
3000
unsigned int channels = set_shifts(tc->format, tc->bit_depth,
3001
&tr->true_bits, shift_start, shift_dec);
3002
3003
debug(PNG_TC_CHANNELS(*tc) == channels);
3004
3005
/* With low res depths, could only be grayscale, so one channel */
3006
if (tc->bit_depth < 8)
3007
{
3008
unsigned int mask;
3009
3010
UNTESTED
3011
affirm(channels == 1);
3012
/* This doesn't matter but we expect to run before packswap: */
3013
debug(!(tc->format & PNG_FORMAT_FLAG_SWAPPED));
3014
3015
if (tr->true_bits.gray == 1 && tc->bit_depth == 2)
3016
mask = 0x55;
3017
3018
else if (tc->bit_depth == 4 && tr->true_bits.gray == 3)
3019
mask = 0x11;
3020
3021
else
3022
mask = 0xff;
3023
3024
while (dp < dp_end)
3025
{
3026
int j;
3027
unsigned int v, out;
3028
3029
v = *sp++;
3030
out = 0;
3031
3032
for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
3033
{
3034
if (j > 0)
3035
out |= v << j;
3036
3037
else
3038
out |= (v >> (-j)) & mask;
3039
}
3040
3041
*dp++ = png_check_byte(png_ptr, out);
3042
}
3043
}
3044
3045
else if (tc->bit_depth == 8)
3046
{
3047
unsigned int c = 0;
3048
3049
UNTESTED
3050
while (dp < dp_end)
3051
{
3052
3053
int j;
3054
unsigned int v, out;
3055
3056
v = *sp++;
3057
out = 0;
3058
3059
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
3060
{
3061
if (j > 0)
3062
out |= v << j;
3063
3064
else
3065
out |= v >> (-j);
3066
}
3067
3068
*dp++ = png_check_byte(png_ptr, out);
3069
if (++c == channels) c = 0;
3070
}
3071
}
3072
3073
else /* tc->bit_depth == 16 */
3074
{
3075
unsigned int c = 0, s0, s1;
3076
3077
UNTESTED
3078
if ((tc->format & PNG_FORMAT_FLAG_SWAPPED) != 0)
3079
s0 = 0, s1 = 8; /* LSB */
3080
3081
else
3082
s0 = 8, s1 = 0; /* MSB */
3083
3084
while (dp < dp_end)
3085
{
3086
int j;
3087
unsigned int value, v;
3088
3089
v = *sp++ << s0;
3090
v += *sp++ << s1;
3091
value = 0;
3092
3093
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
3094
{
3095
if (j > 0)
3096
value |= v << j;
3097
3098
else
3099
value |= v >> (-j);
3100
}
3101
3102
*dp++ = PNG_BYTE(value >> s0);
3103
*dp++ = PNG_BYTE(value >> s1);
3104
}
3105
}
3106
}
3107
# undef png_ptr
3108
}
3109
#endif /* WRITE_SHIFT */
3110
3111
#ifdef PNG_READ_SHIFT_SUPPORTED
3112
/* Reverse the effects of png_do_shift. This routine merely shifts the
3113
* pixels back to their significant bits values. Thus, if you have
3114
* a row of bit depth 8, but only 5 are significant, this will shift
3115
* the values back to 0 through 31.
3116
*/
3117
static void
3118
png_do_unshift(png_transformp *transform, png_transform_controlp tc)
3119
{
3120
# define png_ptr (tc->png_ptr)
3121
png_transform_shift *tr =
3122
png_transform_cast(png_transform_shift, *transform);
3123
png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
3124
png_bytep dp = png_voidcast(png_bytep, tc->dp);
3125
png_const_bytep dp_end = dp + PNG_TC_ROWBYTES(*tc);
3126
3127
png_debug(1, "in png_do_unshift");
3128
3129
tc->range++;
3130
tc->format |= PNG_FORMAT_FLAG_RANGE;
3131
3132
{
3133
int shift[4];
3134
unsigned int channels = set_shifts(tc->format, tc->bit_depth,
3135
&tr->true_bits, shift, NULL);
3136
3137
debug(PNG_TC_CHANNELS(*tc) == channels);
3138
3139
{
3140
unsigned int c, have_shift;
3141
3142
for (c = have_shift = 0; c < channels; ++c)
3143
{
3144
/* A shift of more than the bit depth is an error condition but it
3145
* gets ignored here.
3146
*/
3147
if (shift[c] <= 0 || (unsigned)/*SAFE*/shift[c] >= tc->bit_depth)
3148
shift[c] = 0;
3149
3150
else
3151
have_shift = 1;
3152
}
3153
3154
if (have_shift == 0)
3155
return;
3156
}
3157
3158
/* The code below will copy sp to dp, so: */
3159
tc->sp = dp;
3160
3161
switch (tc->bit_depth)
3162
{
3163
default:
3164
/* Must be 1bpp gray: should not be here! */
3165
impossible("unshift bit depth");
3166
/* NOTREACHED */
3167
break;
3168
3169
case 2:
3170
/* Must be 2bpp gray */
3171
debug(channels == 1 && shift[0] == 1);
3172
debug(!(tc->format & PNG_FORMAT_FLAG_SWAPPED));
3173
3174
while (dp < dp_end)
3175
*dp++ = (*sp++ >> 1) & 0x55;
3176
break;
3177
3178
case 4:
3179
/* Must be 4bpp gray */
3180
debug(channels == 1);
3181
debug(!(tc->format & PNG_FORMAT_FLAG_SWAPPED));
3182
{
3183
unsigned int gray_shift = shift[0];
3184
unsigned int mask = 0xf >> gray_shift; /* <= 4 bits */
3185
3186
mask |= mask << 4; /* <= 8 bits */
3187
3188
while (dp < dp_end)
3189
*dp++ = (png_byte)/*SAFE*/((*sp++ >> gray_shift) & mask);
3190
}
3191
break;
3192
3193
case 8:
3194
/* Single byte components, G, GA, RGB, RGBA */
3195
{
3196
unsigned int channel = 0;
3197
3198
while (dp < dp_end)
3199
{
3200
*dp++ = (png_byte)/*SAFE*/(*sp++ >> shift[channel]);
3201
if (++channel >= channels)
3202
channel = 0;
3203
}
3204
}
3205
break;
3206
3207
case 16:
3208
/* Double byte components, G, GA, RGB, RGBA */
3209
{
3210
unsigned int channel = 0;
3211
unsigned int s0, s1;
3212
3213
if ((tc->format & PNG_FORMAT_FLAG_SWAPPED) != 0)
3214
s0 = 0, s1 = 8; /* LSB */
3215
3216
else
3217
s0 = 8, s1 = 0; /* MSB */
3218
3219
while (dp < dp_end)
3220
{
3221
unsigned int value = *sp++ << s0;
3222
3223
value += *sp++ << s1; /* <= 16 bits */
3224
3225
value >>= shift[channel];
3226
if (++channel >= channels) channel = 0;
3227
*dp++ = PNG_BYTE(value >> s0);
3228
*dp++ = PNG_BYTE(value >> s1);
3229
}
3230
}
3231
break;
3232
}
3233
}
3234
3235
# undef png_ptr
3236
}
3237
#endif /* READ_SHIFT */
3238
3239
static void
3240
init_shift(png_transformp *transform, png_transform_controlp tc)
3241
{
3242
png_const_structp png_ptr = tc->png_ptr;
3243
3244
/* These shifts apply to the component value, not the pixel index, so skip
3245
* palette data. In addition there is no *write* shift for palette entries;
3246
* only a read one, so skip the write/palette case too.
3247
*/
3248
if ((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0 &&
3249
(png_ptr->read_struct || !tc->palette))
3250
{
3251
/* The only change to the format is to mark the data as having a non-PNG
3252
* range.
3253
*/
3254
tc->range++;
3255
tc->format |= PNG_FORMAT_FLAG_RANGE;
3256
3257
if (tc->init == PNG_TC_INIT_FINAL)
3258
{
3259
# ifdef PNG_READ_SHIFT_SUPPORTED
3260
if (png_ptr->read_struct)
3261
{
3262
(*transform)->fn = png_do_unshift;
3263
return;
3264
}
3265
# endif
3266
# ifdef PNG_WRITE_SHIFT_SUPPORTED
3267
if (png_ptr->read_struct)
3268
{
3269
(*transform)->fn = png_do_shift;
3270
return;
3271
}
3272
# endif
3273
}
3274
}
3275
3276
else /* transform not applicable */
3277
(*transform)->fn = NULL;
3278
}
3279
3280
void PNGAPI
3281
png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits)
3282
{
3283
if (png_ptr != NULL && true_bits != NULL)
3284
{
3285
# ifndef PNG_READ_SHIFT_SUPPORTED
3286
if (png_ptr->read_struct)
3287
{
3288
png_app_error(png_ptr, "png_set_shift not supported on read");
3289
return;
3290
}
3291
# endif
3292
# ifndef PNG_WRITE_SHIFT_SUPPORTED
3293
if (!png_ptr->read_struct)
3294
{
3295
png_app_error(png_ptr, "png_set_shift not supported on write");
3296
return;
3297
}
3298
# endif
3299
3300
{
3301
png_transform_shift *trs = png_transform_cast(png_transform_shift,
3302
png_add_transform(png_ptr, sizeof (png_transform_shift),
3303
init_shift, PNG_TR_SHIFT));
3304
trs->true_bits = *true_bits;
3305
}
3306
}
3307
}
3308
#endif /* SHIFT */
3309
3310
#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
3311
/* Turn on pixel packing */
3312
void PNGAPI
3313
png_set_packing(png_structrp png_ptr)
3314
{
3315
/* The transforms aren't symmetric, so even though there is one API there are
3316
* two internal init functions, one for read, the other write:
3317
*/
3318
if (png_ptr != NULL)
3319
{
3320
if (png_ptr->read_struct)
3321
{
3322
# ifdef PNG_READ_PACK_SUPPORTED
3323
png_add_transform(png_ptr, 0/*size*/, png_init_read_pack,
3324
PNG_TR_PACK);
3325
# else
3326
png_app_error(png_ptr, "png_set_packing not supported on read");
3327
# endif
3328
}
3329
3330
else
3331
{
3332
# ifdef PNG_WRITE_PACK_SUPPORTED
3333
png_add_transform(png_ptr, 0/*size*/, png_init_write_pack,
3334
PNG_TR_PACK);
3335
# else
3336
png_app_error(png_ptr, "png_set_packing not supported on write");
3337
# endif
3338
}
3339
}
3340
}
3341
#endif /* PACK */
3342
3343
#if defined(PNG_READ_PACKSWAP_SUPPORTED) ||\
3344
defined(PNG_WRITE_PACKSWAP_SUPPORTED)
3345
/* Turn on pixel-swapping within a byte, this is symmetric - doing the swap
3346
* twice produces the original value, so only one implementation is required for
3347
* either read or write.
3348
*
3349
* Used to be refered to as "packswap", but pixel-swap seems more
3350
* self-documenting.
3351
*/
3352
static void
3353
png_do_swap_1bit(png_transformp *transform, png_transform_controlp tc)
3354
{
3355
png_alloc_size_t rowbytes = row_align(tc); /* may change tc->sp */
3356
png_const_uint_32p sp = png_voidcast(png_const_uint_32p, tc->sp);
3357
png_uint_32p dp = png_voidcast(png_uint_32p, tc->dp);
3358
3359
tc->sp = dp;
3360
tc->format ^= PNG_FORMAT_FLAG_SWAPPED;
3361
3362
for (;;)
3363
{
3364
png_uint_32 s = *sp++;
3365
s = ((s >> 1) & 0x55555555) | ((s & 0x55555555) << 1);
3366
s = ((s >> 2) & 0x33333333) | ((s & 0x33333333) << 2);
3367
s = ((s >> 4) & 0x0f0f0f0f) | ((s & 0x0f0f0f0f) << 4);
3368
*dp++ = s;
3369
if (rowbytes <= 4) break;
3370
rowbytes -= 4;
3371
}
3372
3373
PNG_UNUSED(transform)
3374
}
3375
3376
static void
3377
png_do_swap_2bit(png_transformp *transform, png_transform_controlp tc)
3378
{
3379
png_alloc_size_t rowbytes = row_align(tc); /* may change tc->sp */
3380
png_const_uint_32p sp = png_voidcast(png_const_uint_32p, tc->sp);
3381
png_uint_32p dp = png_voidcast(png_uint_32p, tc->dp);
3382
3383
tc->sp = dp;
3384
tc->format ^= PNG_FORMAT_FLAG_SWAPPED;
3385
3386
for (;;)
3387
{
3388
png_uint_32 s = *sp++;
3389
s = ((s >> 2) & 0x33333333) | ((s & 0x33333333) << 2);
3390
s = ((s >> 4) & 0x0f0f0f0f) | ((s & 0x0f0f0f0f) << 4);
3391
*dp++ = s;
3392
if (rowbytes <= 4) break;
3393
rowbytes -= 4;
3394
}
3395
3396
PNG_UNUSED(transform)
3397
}
3398
3399
static void
3400
png_do_swap_4bit(png_transformp *transform, png_transform_controlp tc)
3401
{
3402
png_alloc_size_t rowbytes = row_align(tc); /* may change tc->sp */
3403
png_const_uint_32p sp = png_voidcast(png_const_uint_32p, tc->sp);
3404
png_uint_32p dp = png_voidcast(png_uint_32p, tc->dp);
3405
3406
tc->sp = dp;
3407
tc->format ^= PNG_FORMAT_FLAG_SWAPPED;
3408
3409
for (;;)
3410
{
3411
png_uint_32 s = *sp++;
3412
s = ((s >> 4) & 0x0f0f0f0f) | ((s & 0x0f0f0f0f) << 4);
3413
*dp++ = s;
3414
if (rowbytes <= 4) break;
3415
rowbytes -= 4;
3416
}
3417
3418
PNG_UNUSED(transform)
3419
}
3420
3421
static void
3422
init_packswap(png_transformp *transform, png_transform_controlp tc)
3423
{
3424
png_transform_fn fn;
3425
3426
# define png_ptr tc->png_ptr
3427
debug(tc->init);
3428
# undef png_ptr
3429
3430
switch (tc->bit_depth)
3431
{
3432
case 1: fn = png_do_swap_1bit; break;
3433
case 2: fn = png_do_swap_2bit; break;
3434
case 4: fn = png_do_swap_4bit; break;
3435
3436
default: /* transform not applicable */
3437
(*transform)->fn = NULL;
3438
return;
3439
}
3440
3441
tc->format ^= PNG_FORMAT_FLAG_SWAPPED;
3442
if (tc->init == PNG_TC_INIT_FINAL)
3443
(*transform)->fn = fn;
3444
}
3445
3446
void PNGAPI
3447
png_set_packswap(png_structrp png_ptr)
3448
{
3449
if (png_ptr != NULL)
3450
{
3451
# ifndef PNG_READ_PACKSWAP_SUPPORTED
3452
if (png_ptr->read_struct)
3453
{
3454
png_app_error(png_ptr, "png_set_packswap not supported on read");
3455
return;
3456
}
3457
# endif
3458
# ifndef PNG_WRITE_PACKSWAP_SUPPORTED
3459
if (!png_ptr->read_struct)
3460
{
3461
png_app_error(png_ptr, "png_set_packswap not supported on write");
3462
return;
3463
}
3464
# endif
3465
3466
png_add_transform(png_ptr, 0/*size*/, init_packswap, PNG_TR_PIXEL_SWAP);
3467
}
3468
}
3469
#endif /* PACKSWAP */
3470
3471
/* User transform handling */
3472
#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
3473
png_uint_32 PNGAPI
3474
png_get_current_row_number(png_const_structrp png_ptr)
3475
{
3476
/* See the comments in png.h - this is the sub-image row when reading an
3477
* interlaced image.
3478
*/
3479
if (png_ptr != NULL)
3480
{
3481
/* In the read case png_struct::row_number is the row in the final image,
3482
* not the pass, this will return the previous row number if the row isn't
3483
* in the pass:
3484
*/
3485
if (png_ptr->read_struct)
3486
return PNG_PASS_ROWS(png_ptr->row_number+1, png_ptr->pass)-1U;
3487
3488
else
3489
return png_ptr->row_number;
3490
}
3491
3492
return PNG_UINT_32_MAX; /* help the app not to fail silently */
3493
}
3494
3495
png_byte PNGAPI
3496
png_get_current_pass_number(png_const_structrp png_ptr)
3497
{
3498
if (png_ptr != NULL)
3499
return png_ptr->pass;
3500
return 8; /* invalid */
3501
}
3502
#endif /* USER_TRANSFORM_INFO */
3503
3504
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) ||\
3505
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
3506
typedef struct
3507
{
3508
png_transform tr;
3509
png_user_transform_ptr user_fn;
3510
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
3511
png_voidp user_ptr;
3512
#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
3513
unsigned int user_depth;
3514
unsigned int user_channels;
3515
#endif
3516
#endif
3517
} png_user_transform, *png_user_transformp;
3518
3519
typedef const png_user_transform *png_const_user_transformp;
3520
3521
static png_user_transformp
3522
get_user_transform(png_structrp png_ptr)
3523
{
3524
/* Note that in an added transform the whole transform is memset to 0, so we
3525
* don't need to initialize anything.
3526
*/
3527
return png_transform_cast(png_user_transform, png_add_transform(png_ptr,
3528
sizeof (png_user_transform), NULL/*function*/, PNG_TR_USER));
3529
}
3530
#endif /* READ_USER_TRANSFORM || WRITE_USER_TRANSFORM */
3531
3532
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
3533
png_voidp PNGAPI
3534
png_get_user_transform_ptr(png_const_structrp png_ptr)
3535
{
3536
if (png_ptr != NULL)
3537
{
3538
png_transformp tr = png_find_transform(png_ptr, PNG_TR_USER);
3539
3540
if (tr != NULL)
3541
{
3542
png_user_transformp tru = png_transform_cast(png_user_transform, tr);
3543
return tru->user_ptr;
3544
}
3545
}
3546
3547
return NULL;
3548
}
3549
#endif /* USER_TRANSFORM_PTR */
3550
3551
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
3552
void PNGAPI
3553
png_set_user_transform_info(png_structrp png_ptr, png_voidp ptr, int depth,
3554
int channels)
3555
{
3556
if (png_ptr != NULL)
3557
{
3558
/* NOTE: this function only sets the user transform pointer on write, i.e.
3559
* the depth and channels arguments are ignored.
3560
*/
3561
png_user_transformp tr = get_user_transform(png_ptr);
3562
3563
tr->user_ptr = ptr;
3564
3565
# ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
3566
if (png_ptr->read_struct)
3567
{
3568
if (png_ptr->row_bit_depth == 0)
3569
{
3570
if (depth > 0 && depth <= 32 && channels > 0 && channels <= 4 &&
3571
(-depth & depth) == depth /* power of 2 */)
3572
{
3573
tr->user_depth = png_check_bits(png_ptr, depth, 6);
3574
tr->user_channels = png_check_bits(png_ptr, channels, 3);
3575
}
3576
3577
else
3578
png_app_error(png_ptr, "unsupported bit-depth or channels");
3579
}
3580
else
3581
png_app_error(png_ptr,
3582
"cannot change user info after image start");
3583
}
3584
# else /* !READ_USER_TRANSFORM */
3585
PNG_UNUSED(depth)
3586
PNG_UNUSED(channels)
3587
# endif /* !READ_USER_TRANSFORM */
3588
}
3589
}
3590
#endif /* USER_TRANSFORM_PTR */
3591
3592
#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
3593
static void
3594
png_do_read_user_transform(png_transformp *trIn, png_transform_controlp tc)
3595
{
3596
# define png_ptr (tc->png_ptr)
3597
png_user_transformp tr = png_transform_cast(png_user_transform, *trIn);
3598
3599
if (!tc->init && tr->user_fn != NULL)
3600
{
3601
png_row_info row_info;
3602
3603
row_info.width = tc->width;
3604
row_info.rowbytes = PNG_TC_ROWBYTES(*tc);
3605
row_info.color_type = png_check_byte(png_ptr,
3606
PNG_COLOR_TYPE_FROM_FORMAT(tc->format));
3607
row_info.bit_depth = png_check_byte(png_ptr, tc->bit_depth);
3608
row_info.channels = png_check_byte(png_ptr,
3609
PNG_FORMAT_CHANNELS(tc->format));
3610
row_info.bit_depth = png_check_byte(png_ptr,
3611
PNG_TC_PIXEL_DEPTH(*tc));
3612
3613
/* TODO: fix this API, but for the moment we have to copy the row data to
3614
* the working buffer. This is an unnecessary perf overhead when a user
3615
* transform is used to read information without a transform or when it is
3616
* used on write.
3617
*/
3618
if (tc->sp != tc->dp)
3619
{
3620
memcpy(tc->dp, tc->sp, PNG_TC_ROWBYTES(*tc));
3621
tc->sp = tc->dp;
3622
}
3623
3624
tr->user_fn(png_ptr, &row_info, png_voidcast(png_bytep, tc->dp));
3625
}
3626
3627
# ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
3628
if (tr->user_depth > 0)
3629
{
3630
/* The read transform can modify the bit depth and number of
3631
* channels; the interface doesn't permit anything else to be
3632
* changed. If the information isn't set the user callback has to
3633
* produce pixels with the correct pixel depth (otherwise the
3634
* de-interlace won't work) but there really is no other constraint.
3635
*/
3636
tc->bit_depth = tr->user_depth;
3637
3638
/* The API is very restricted in functionality; the user_channels
3639
* can be changed, but the color_type can't, so the format is simply
3640
* fixed up to match the channels.
3641
*/
3642
if (tr->user_channels != PNG_FORMAT_CHANNELS(tc->format))
3643
switch (tr->user_channels)
3644
{
3645
case 1:
3646
tc->format &=
3647
PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_ALPHA);
3648
break;
3649
3650
case 2: /* has to be GA */
3651
tc->format &=
3652
PNG_BIC_MASK(PNG_FORMAT_FLAG_COLORMAP+PNG_FORMAT_FLAG_COLOR);
3653
tc->format |= PNG_FORMAT_FLAG_ALPHA;
3654
break;
3655
3656
case 3: /* has to be RGB */
3657
tc->format &=
3658
PNG_BIC_MASK(PNG_FORMAT_FLAG_COLORMAP|PNG_FORMAT_FLAG_ALPHA);
3659
tc->format |= PNG_FORMAT_FLAG_COLOR;
3660
break;
3661
3662
case 4: /* has to be RGBA */
3663
tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_COLORMAP);
3664
tc->format |= (PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_ALPHA);
3665
break;
3666
3667
default: /* checked before */
3668
impossible("user channels");
3669
}
3670
3671
debug(PNG_FORMAT_CHANNELS(tc->format) == tr->user_channels);
3672
}
3673
# endif /* USER_TRANSFORM_PTR */
3674
# undef png_ptr
3675
}
3676
3677
void PNGAPI
3678
png_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr
3679
read_user_transform_fn)
3680
{
3681
/* There is no 'init' function, just the callback above to handle the
3682
* transform.
3683
*/
3684
if (png_ptr != NULL)
3685
{
3686
if (png_ptr->read_struct)
3687
{
3688
png_user_transformp tr = get_user_transform(png_ptr);
3689
3690
tr->user_fn = read_user_transform_fn;
3691
tr->tr.fn = png_do_read_user_transform;
3692
}
3693
3694
else
3695
png_app_error(png_ptr, "cannot set a read transform on write");
3696
}
3697
}
3698
#endif /* READ_USER_TRANSFORM */
3699
3700
#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
3701
static void
3702
png_do_write_user_transform(png_transformp *trIn, png_transform_controlp tc)
3703
{
3704
# define png_ptr (tc->png_ptr)
3705
/* The write side is pretty simple; call the call-back, it will make the row
3706
* data right.
3707
*
3708
* BUG: we need to copy the input row (it would be a non-quiet API change
3709
* otherwise) and we don't know how big it is because the information passed
3710
* to png_set_user_transform_info never was used on write, but that's fine
3711
* because the write code never did get this right, so presumably all the
3712
* apps have worked round it...
3713
*/
3714
if (!tc->init)
3715
{
3716
png_user_transformp tr = png_transform_cast(png_user_transform, *trIn);
3717
png_row_info row_info;
3718
3719
if (tc->sp != tc->dp) /* no interlace */
3720
{
3721
memcpy(tc->dp, tc->sp, PNG_TC_ROWBYTES(*tc));
3722
tc->sp = tc->dp;
3723
}
3724
3725
row_info.width = tc->width;
3726
row_info.rowbytes = PNG_TC_ROWBYTES(*tc);
3727
row_info.color_type = png_check_byte(png_ptr,
3728
PNG_COLOR_TYPE_FROM_FORMAT(tc->format));
3729
row_info.bit_depth = png_check_byte(png_ptr, tc->bit_depth);
3730
row_info.channels = png_check_byte(png_ptr,
3731
PNG_FORMAT_CHANNELS(tc->format));
3732
row_info.bit_depth = png_check_byte(png_ptr,
3733
PNG_TC_PIXEL_DEPTH(*tc));
3734
3735
/* The user function promises to give us this format: */
3736
tr->user_fn(png_ptr, &row_info, png_voidcast(png_bytep, tc->dp));
3737
}
3738
# undef png_ptr
3739
}
3740
3741
void PNGAPI
3742
png_set_write_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr
3743
write_user_transform_fn)
3744
{
3745
3746
if (png_ptr != NULL)
3747
{
3748
if (!png_ptr->read_struct)
3749
{
3750
png_user_transformp tr = get_user_transform(png_ptr);
3751
3752
tr->user_fn = write_user_transform_fn;
3753
tr->tr.fn = png_do_write_user_transform;
3754
}
3755
3756
else
3757
png_app_error(png_ptr, "cannot set a write transform on read");
3758
}
3759
}
3760
#endif /* WRITE_USER_TRANSFORM */
3761
3762