Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/3rdparty/libpng/pngrtran.c
16337 views
1
2
/* pngrtran.c - transforms the data in a row for PNG readers
3
*
4
* Last changed in libpng 1.6.33 [September 28, 2017]
5
* Copyright (c) 1998-2002,2004,2006-2017 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
* This file contains functions optionally called by an application
14
* in order to tell libpng how to handle data when reading a PNG.
15
* Transformations that are used in both reading and writing are
16
* in pngtrans.c.
17
*/
18
19
#include "pngpriv.h"
20
21
#ifdef PNG_READ_SUPPORTED
22
23
/* Set the action on getting a CRC error for an ancillary or critical chunk. */
24
void PNGAPI
25
png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action)
26
{
27
png_debug(1, "in png_set_crc_action");
28
29
if (png_ptr == NULL)
30
return;
31
32
/* Tell libpng how we react to CRC errors in critical chunks */
33
switch (crit_action)
34
{
35
case PNG_CRC_NO_CHANGE: /* Leave setting as is */
36
break;
37
38
case PNG_CRC_WARN_USE: /* Warn/use data */
39
png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
40
png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
41
break;
42
43
case PNG_CRC_QUIET_USE: /* Quiet/use data */
44
png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
45
png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
46
PNG_FLAG_CRC_CRITICAL_IGNORE;
47
break;
48
49
case PNG_CRC_WARN_DISCARD: /* Not a valid action for critical data */
50
png_warning(png_ptr,
51
"Can't discard critical data on CRC error");
52
/* FALLTHROUGH */
53
case PNG_CRC_ERROR_QUIT: /* Error/quit */
54
55
case PNG_CRC_DEFAULT:
56
default:
57
png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
58
break;
59
}
60
61
/* Tell libpng how we react to CRC errors in ancillary chunks */
62
switch (ancil_action)
63
{
64
case PNG_CRC_NO_CHANGE: /* Leave setting as is */
65
break;
66
67
case PNG_CRC_WARN_USE: /* Warn/use data */
68
png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
69
png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
70
break;
71
72
case PNG_CRC_QUIET_USE: /* Quiet/use data */
73
png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
74
png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
75
PNG_FLAG_CRC_ANCILLARY_NOWARN;
76
break;
77
78
case PNG_CRC_ERROR_QUIT: /* Error/quit */
79
png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
80
png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
81
break;
82
83
case PNG_CRC_WARN_DISCARD: /* Warn/discard data */
84
85
case PNG_CRC_DEFAULT:
86
default:
87
png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
88
break;
89
}
90
}
91
92
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
93
/* Is it OK to set a transformation now? Only if png_start_read_image or
94
* png_read_update_info have not been called. It is not necessary for the IHDR
95
* to have been read in all cases; the need_IHDR parameter allows for this
96
* check too.
97
*/
98
static int
99
png_rtran_ok(png_structrp png_ptr, int need_IHDR)
100
{
101
if (png_ptr != NULL)
102
{
103
if ((png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
104
png_app_error(png_ptr,
105
"invalid after png_start_read_image or png_read_update_info");
106
107
else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0)
108
png_app_error(png_ptr, "invalid before the PNG header has been read");
109
110
else
111
{
112
/* Turn on failure to initialize correctly for all transforms. */
113
png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED;
114
115
return 1; /* Ok */
116
}
117
}
118
119
return 0; /* no png_error possible! */
120
}
121
#endif
122
123
#ifdef PNG_READ_BACKGROUND_SUPPORTED
124
/* Handle alpha and tRNS via a background color */
125
void PNGFAPI
126
png_set_background_fixed(png_structrp png_ptr,
127
png_const_color_16p background_color, int background_gamma_code,
128
int need_expand, png_fixed_point background_gamma)
129
{
130
png_debug(1, "in png_set_background_fixed");
131
132
if (png_rtran_ok(png_ptr, 0) == 0 || background_color == NULL)
133
return;
134
135
if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
136
{
137
png_warning(png_ptr, "Application must supply a known background gamma");
138
return;
139
}
140
141
png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA;
142
png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
143
png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
144
145
png_ptr->background = *background_color;
146
png_ptr->background_gamma = background_gamma;
147
png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
148
if (need_expand != 0)
149
png_ptr->transformations |= PNG_BACKGROUND_EXPAND;
150
else
151
png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
152
}
153
154
# ifdef PNG_FLOATING_POINT_SUPPORTED
155
void PNGAPI
156
png_set_background(png_structrp png_ptr,
157
png_const_color_16p background_color, int background_gamma_code,
158
int need_expand, double background_gamma)
159
{
160
png_set_background_fixed(png_ptr, background_color, background_gamma_code,
161
need_expand, png_fixed(png_ptr, background_gamma, "png_set_background"));
162
}
163
# endif /* FLOATING_POINT */
164
#endif /* READ_BACKGROUND */
165
166
/* Scale 16-bit depth files to 8-bit depth. If both of these are set then the
167
* one that pngrtran does first (scale) happens. This is necessary to allow the
168
* TRANSFORM and API behavior to be somewhat consistent, and it's simpler.
169
*/
170
#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
171
void PNGAPI
172
png_set_scale_16(png_structrp png_ptr)
173
{
174
png_debug(1, "in png_set_scale_16");
175
176
if (png_rtran_ok(png_ptr, 0) == 0)
177
return;
178
179
png_ptr->transformations |= PNG_SCALE_16_TO_8;
180
}
181
#endif
182
183
#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
184
/* Chop 16-bit depth files to 8-bit depth */
185
void PNGAPI
186
png_set_strip_16(png_structrp png_ptr)
187
{
188
png_debug(1, "in png_set_strip_16");
189
190
if (png_rtran_ok(png_ptr, 0) == 0)
191
return;
192
193
png_ptr->transformations |= PNG_16_TO_8;
194
}
195
#endif
196
197
#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
198
void PNGAPI
199
png_set_strip_alpha(png_structrp png_ptr)
200
{
201
png_debug(1, "in png_set_strip_alpha");
202
203
if (png_rtran_ok(png_ptr, 0) == 0)
204
return;
205
206
png_ptr->transformations |= PNG_STRIP_ALPHA;
207
}
208
#endif
209
210
#if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED)
211
static png_fixed_point
212
translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma,
213
int is_screen)
214
{
215
/* Check for flag values. The main reason for having the old Mac value as a
216
* flag is that it is pretty near impossible to work out what the correct
217
* value is from Apple documentation - a working Mac system is needed to
218
* discover the value!
219
*/
220
if (output_gamma == PNG_DEFAULT_sRGB ||
221
output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB)
222
{
223
/* If there is no sRGB support this just sets the gamma to the standard
224
* sRGB value. (This is a side effect of using this function!)
225
*/
226
# ifdef PNG_READ_sRGB_SUPPORTED
227
png_ptr->flags |= PNG_FLAG_ASSUME_sRGB;
228
# else
229
PNG_UNUSED(png_ptr)
230
# endif
231
if (is_screen != 0)
232
output_gamma = PNG_GAMMA_sRGB;
233
else
234
output_gamma = PNG_GAMMA_sRGB_INVERSE;
235
}
236
237
else if (output_gamma == PNG_GAMMA_MAC_18 ||
238
output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18)
239
{
240
if (is_screen != 0)
241
output_gamma = PNG_GAMMA_MAC_OLD;
242
else
243
output_gamma = PNG_GAMMA_MAC_INVERSE;
244
}
245
246
return output_gamma;
247
}
248
249
# ifdef PNG_FLOATING_POINT_SUPPORTED
250
static png_fixed_point
251
convert_gamma_value(png_structrp png_ptr, double output_gamma)
252
{
253
/* The following silently ignores cases where fixed point (times 100,000)
254
* gamma values are passed to the floating point API. This is safe and it
255
* means the fixed point constants work just fine with the floating point
256
* API. The alternative would just lead to undetected errors and spurious
257
* bug reports. Negative values fail inside the _fixed API unless they
258
* correspond to the flag values.
259
*/
260
if (output_gamma > 0 && output_gamma < 128)
261
output_gamma *= PNG_FP_1;
262
263
/* This preserves -1 and -2 exactly: */
264
output_gamma = floor(output_gamma + .5);
265
266
if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN)
267
png_fixed_error(png_ptr, "gamma value");
268
269
return (png_fixed_point)output_gamma;
270
}
271
# endif
272
#endif /* READ_ALPHA_MODE || READ_GAMMA */
273
274
#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
275
void PNGFAPI
276
png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
277
png_fixed_point output_gamma)
278
{
279
int compose = 0;
280
png_fixed_point file_gamma;
281
282
png_debug(1, "in png_set_alpha_mode");
283
284
if (png_rtran_ok(png_ptr, 0) == 0)
285
return;
286
287
output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/);
288
289
/* Validate the value to ensure it is in a reasonable range. The value
290
* is expected to be 1 or greater, but this range test allows for some
291
* viewing correction values. The intent is to weed out users of this API
292
* who use the inverse of the gamma value accidentally! Since some of these
293
* values are reasonable this may have to be changed:
294
*
295
* 1.6.x: changed from 0.07..3 to 0.01..100 (to accomodate the optimal 16-bit
296
* gamma of 36, and its reciprocal.)
297
*/
298
if (output_gamma < 1000 || output_gamma > 10000000)
299
png_error(png_ptr, "output gamma out of expected range");
300
301
/* The default file gamma is the inverse of the output gamma; the output
302
* gamma may be changed below so get the file value first:
303
*/
304
file_gamma = png_reciprocal(output_gamma);
305
306
/* There are really 8 possibilities here, composed of any combination
307
* of:
308
*
309
* premultiply the color channels
310
* do not encode non-opaque pixels
311
* encode the alpha as well as the color channels
312
*
313
* The differences disappear if the input/output ('screen') gamma is 1.0,
314
* because then the encoding is a no-op and there is only the choice of
315
* premultiplying the color channels or not.
316
*
317
* png_set_alpha_mode and png_set_background interact because both use
318
* png_compose to do the work. Calling both is only useful when
319
* png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along
320
* with a default gamma value. Otherwise PNG_COMPOSE must not be set.
321
*/
322
switch (mode)
323
{
324
case PNG_ALPHA_PNG: /* default: png standard */
325
/* No compose, but it may be set by png_set_background! */
326
png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
327
png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
328
break;
329
330
case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */
331
compose = 1;
332
png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
333
png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
334
/* The output is linear: */
335
output_gamma = PNG_FP_1;
336
break;
337
338
case PNG_ALPHA_OPTIMIZED: /* associated, non-opaque pixels linear */
339
compose = 1;
340
png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
341
png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA;
342
/* output_gamma records the encoding of opaque pixels! */
343
break;
344
345
case PNG_ALPHA_BROKEN: /* associated, non-linear, alpha encoded */
346
compose = 1;
347
png_ptr->transformations |= PNG_ENCODE_ALPHA;
348
png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
349
break;
350
351
default:
352
png_error(png_ptr, "invalid alpha mode");
353
}
354
355
/* Only set the default gamma if the file gamma has not been set (this has
356
* the side effect that the gamma in a second call to png_set_alpha_mode will
357
* be ignored.)
358
*/
359
if (png_ptr->colorspace.gamma == 0)
360
{
361
png_ptr->colorspace.gamma = file_gamma;
362
png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
363
}
364
365
/* But always set the output gamma: */
366
png_ptr->screen_gamma = output_gamma;
367
368
/* Finally, if pre-multiplying, set the background fields to achieve the
369
* desired result.
370
*/
371
if (compose != 0)
372
{
373
/* And obtain alpha pre-multiplication by composing on black: */
374
memset(&png_ptr->background, 0, (sizeof png_ptr->background));
375
png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */
376
png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE;
377
png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
378
379
if ((png_ptr->transformations & PNG_COMPOSE) != 0)
380
png_error(png_ptr,
381
"conflicting calls to set alpha mode and background");
382
383
png_ptr->transformations |= PNG_COMPOSE;
384
}
385
}
386
387
# ifdef PNG_FLOATING_POINT_SUPPORTED
388
void PNGAPI
389
png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma)
390
{
391
png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr,
392
output_gamma));
393
}
394
# endif
395
#endif
396
397
#ifdef PNG_READ_QUANTIZE_SUPPORTED
398
/* Dither file to 8-bit. Supply a palette, the current number
399
* of elements in the palette, the maximum number of elements
400
* allowed, and a histogram if possible. If the current number
401
* of colors is greater than the maximum number, the palette will be
402
* modified to fit in the maximum number. "full_quantize" indicates
403
* whether we need a quantizing cube set up for RGB images, or if we
404
* simply are reducing the number of colors in a paletted image.
405
*/
406
407
typedef struct png_dsort_struct
408
{
409
struct png_dsort_struct * next;
410
png_byte left;
411
png_byte right;
412
} png_dsort;
413
typedef png_dsort * png_dsortp;
414
typedef png_dsort * * png_dsortpp;
415
416
void PNGAPI
417
png_set_quantize(png_structrp png_ptr, png_colorp palette,
418
int num_palette, int maximum_colors, png_const_uint_16p histogram,
419
int full_quantize)
420
{
421
png_debug(1, "in png_set_quantize");
422
423
if (png_rtran_ok(png_ptr, 0) == 0)
424
return;
425
426
png_ptr->transformations |= PNG_QUANTIZE;
427
428
if (full_quantize == 0)
429
{
430
int i;
431
432
png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,
433
(png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte))));
434
for (i = 0; i < num_palette; i++)
435
png_ptr->quantize_index[i] = (png_byte)i;
436
}
437
438
if (num_palette > maximum_colors)
439
{
440
if (histogram != NULL)
441
{
442
/* This is easy enough, just throw out the least used colors.
443
* Perhaps not the best solution, but good enough.
444
*/
445
446
int i;
447
448
/* Initialize an array to sort colors */
449
png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,
450
(png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte))));
451
452
/* Initialize the quantize_sort array */
453
for (i = 0; i < num_palette; i++)
454
png_ptr->quantize_sort[i] = (png_byte)i;
455
456
/* Find the least used palette entries by starting a
457
* bubble sort, and running it until we have sorted
458
* out enough colors. Note that we don't care about
459
* sorting all the colors, just finding which are
460
* least used.
461
*/
462
463
for (i = num_palette - 1; i >= maximum_colors; i--)
464
{
465
int done; /* To stop early if the list is pre-sorted */
466
int j;
467
468
done = 1;
469
for (j = 0; j < i; j++)
470
{
471
if (histogram[png_ptr->quantize_sort[j]]
472
< histogram[png_ptr->quantize_sort[j + 1]])
473
{
474
png_byte t;
475
476
t = png_ptr->quantize_sort[j];
477
png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1];
478
png_ptr->quantize_sort[j + 1] = t;
479
done = 0;
480
}
481
}
482
483
if (done != 0)
484
break;
485
}
486
487
/* Swap the palette around, and set up a table, if necessary */
488
if (full_quantize != 0)
489
{
490
int j = num_palette;
491
492
/* Put all the useful colors within the max, but don't
493
* move the others.
494
*/
495
for (i = 0; i < maximum_colors; i++)
496
{
497
if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
498
{
499
do
500
j--;
501
while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
502
503
palette[i] = palette[j];
504
}
505
}
506
}
507
else
508
{
509
int j = num_palette;
510
511
/* Move all the used colors inside the max limit, and
512
* develop a translation table.
513
*/
514
for (i = 0; i < maximum_colors; i++)
515
{
516
/* Only move the colors we need to */
517
if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
518
{
519
png_color tmp_color;
520
521
do
522
j--;
523
while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
524
525
tmp_color = palette[j];
526
palette[j] = palette[i];
527
palette[i] = tmp_color;
528
/* Indicate where the color went */
529
png_ptr->quantize_index[j] = (png_byte)i;
530
png_ptr->quantize_index[i] = (png_byte)j;
531
}
532
}
533
534
/* Find closest color for those colors we are not using */
535
for (i = 0; i < num_palette; i++)
536
{
537
if ((int)png_ptr->quantize_index[i] >= maximum_colors)
538
{
539
int min_d, k, min_k, d_index;
540
541
/* Find the closest color to one we threw out */
542
d_index = png_ptr->quantize_index[i];
543
min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
544
for (k = 1, min_k = 0; k < maximum_colors; k++)
545
{
546
int d;
547
548
d = PNG_COLOR_DIST(palette[d_index], palette[k]);
549
550
if (d < min_d)
551
{
552
min_d = d;
553
min_k = k;
554
}
555
}
556
/* Point to closest color */
557
png_ptr->quantize_index[i] = (png_byte)min_k;
558
}
559
}
560
}
561
png_free(png_ptr, png_ptr->quantize_sort);
562
png_ptr->quantize_sort = NULL;
563
}
564
else
565
{
566
/* This is much harder to do simply (and quickly). Perhaps
567
* we need to go through a median cut routine, but those
568
* don't always behave themselves with only a few colors
569
* as input. So we will just find the closest two colors,
570
* and throw out one of them (chosen somewhat randomly).
571
* [We don't understand this at all, so if someone wants to
572
* work on improving it, be our guest - AED, GRP]
573
*/
574
int i;
575
int max_d;
576
int num_new_palette;
577
png_dsortp t;
578
png_dsortpp hash;
579
580
t = NULL;
581
582
/* Initialize palette index arrays */
583
png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
584
(png_alloc_size_t)((png_uint_32)num_palette *
585
(sizeof (png_byte))));
586
png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
587
(png_alloc_size_t)((png_uint_32)num_palette *
588
(sizeof (png_byte))));
589
590
/* Initialize the sort array */
591
for (i = 0; i < num_palette; i++)
592
{
593
png_ptr->index_to_palette[i] = (png_byte)i;
594
png_ptr->palette_to_index[i] = (png_byte)i;
595
}
596
597
hash = (png_dsortpp)png_calloc(png_ptr, (png_alloc_size_t)(769 *
598
(sizeof (png_dsortp))));
599
600
num_new_palette = num_palette;
601
602
/* Initial wild guess at how far apart the farthest pixel
603
* pair we will be eliminating will be. Larger
604
* numbers mean more areas will be allocated, Smaller
605
* numbers run the risk of not saving enough data, and
606
* having to do this all over again.
607
*
608
* I have not done extensive checking on this number.
609
*/
610
max_d = 96;
611
612
while (num_new_palette > maximum_colors)
613
{
614
for (i = 0; i < num_new_palette - 1; i++)
615
{
616
int j;
617
618
for (j = i + 1; j < num_new_palette; j++)
619
{
620
int d;
621
622
d = PNG_COLOR_DIST(palette[i], palette[j]);
623
624
if (d <= max_d)
625
{
626
627
t = (png_dsortp)png_malloc_warn(png_ptr,
628
(png_alloc_size_t)(sizeof (png_dsort)));
629
630
if (t == NULL)
631
break;
632
633
t->next = hash[d];
634
t->left = (png_byte)i;
635
t->right = (png_byte)j;
636
hash[d] = t;
637
}
638
}
639
if (t == NULL)
640
break;
641
}
642
643
if (t != NULL)
644
for (i = 0; i <= max_d; i++)
645
{
646
if (hash[i] != NULL)
647
{
648
png_dsortp p;
649
650
for (p = hash[i]; p; p = p->next)
651
{
652
if ((int)png_ptr->index_to_palette[p->left]
653
< num_new_palette &&
654
(int)png_ptr->index_to_palette[p->right]
655
< num_new_palette)
656
{
657
int j, next_j;
658
659
if (num_new_palette & 0x01)
660
{
661
j = p->left;
662
next_j = p->right;
663
}
664
else
665
{
666
j = p->right;
667
next_j = p->left;
668
}
669
670
num_new_palette--;
671
palette[png_ptr->index_to_palette[j]]
672
= palette[num_new_palette];
673
if (full_quantize == 0)
674
{
675
int k;
676
677
for (k = 0; k < num_palette; k++)
678
{
679
if (png_ptr->quantize_index[k] ==
680
png_ptr->index_to_palette[j])
681
png_ptr->quantize_index[k] =
682
png_ptr->index_to_palette[next_j];
683
684
if ((int)png_ptr->quantize_index[k] ==
685
num_new_palette)
686
png_ptr->quantize_index[k] =
687
png_ptr->index_to_palette[j];
688
}
689
}
690
691
png_ptr->index_to_palette[png_ptr->palette_to_index
692
[num_new_palette]] = png_ptr->index_to_palette[j];
693
694
png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
695
= png_ptr->palette_to_index[num_new_palette];
696
697
png_ptr->index_to_palette[j] =
698
(png_byte)num_new_palette;
699
700
png_ptr->palette_to_index[num_new_palette] =
701
(png_byte)j;
702
}
703
if (num_new_palette <= maximum_colors)
704
break;
705
}
706
if (num_new_palette <= maximum_colors)
707
break;
708
}
709
}
710
711
for (i = 0; i < 769; i++)
712
{
713
if (hash[i] != NULL)
714
{
715
png_dsortp p = hash[i];
716
while (p)
717
{
718
t = p->next;
719
png_free(png_ptr, p);
720
p = t;
721
}
722
}
723
hash[i] = 0;
724
}
725
max_d += 96;
726
}
727
png_free(png_ptr, hash);
728
png_free(png_ptr, png_ptr->palette_to_index);
729
png_free(png_ptr, png_ptr->index_to_palette);
730
png_ptr->palette_to_index = NULL;
731
png_ptr->index_to_palette = NULL;
732
}
733
num_palette = maximum_colors;
734
}
735
if (png_ptr->palette == NULL)
736
{
737
png_ptr->palette = palette;
738
}
739
png_ptr->num_palette = (png_uint_16)num_palette;
740
741
if (full_quantize != 0)
742
{
743
int i;
744
png_bytep distance;
745
int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS +
746
PNG_QUANTIZE_BLUE_BITS;
747
int num_red = (1 << PNG_QUANTIZE_RED_BITS);
748
int num_green = (1 << PNG_QUANTIZE_GREEN_BITS);
749
int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS);
750
png_size_t num_entries = ((png_size_t)1 << total_bits);
751
752
png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr,
753
(png_alloc_size_t)(num_entries * (sizeof (png_byte))));
754
755
distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)(num_entries *
756
(sizeof (png_byte))));
757
758
memset(distance, 0xff, num_entries * (sizeof (png_byte)));
759
760
for (i = 0; i < num_palette; i++)
761
{
762
int ir, ig, ib;
763
int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS));
764
int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS));
765
int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS));
766
767
for (ir = 0; ir < num_red; ir++)
768
{
769
/* int dr = abs(ir - r); */
770
int dr = ((ir > r) ? ir - r : r - ir);
771
int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS +
772
PNG_QUANTIZE_GREEN_BITS));
773
774
for (ig = 0; ig < num_green; ig++)
775
{
776
/* int dg = abs(ig - g); */
777
int dg = ((ig > g) ? ig - g : g - ig);
778
int dt = dr + dg;
779
int dm = ((dr > dg) ? dr : dg);
780
int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS);
781
782
for (ib = 0; ib < num_blue; ib++)
783
{
784
int d_index = index_g | ib;
785
/* int db = abs(ib - b); */
786
int db = ((ib > b) ? ib - b : b - ib);
787
int dmax = ((dm > db) ? dm : db);
788
int d = dmax + dt + db;
789
790
if (d < (int)distance[d_index])
791
{
792
distance[d_index] = (png_byte)d;
793
png_ptr->palette_lookup[d_index] = (png_byte)i;
794
}
795
}
796
}
797
}
798
}
799
800
png_free(png_ptr, distance);
801
}
802
}
803
#endif /* READ_QUANTIZE */
804
805
#ifdef PNG_READ_GAMMA_SUPPORTED
806
void PNGFAPI
807
png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma,
808
png_fixed_point file_gamma)
809
{
810
png_debug(1, "in png_set_gamma_fixed");
811
812
if (png_rtran_ok(png_ptr, 0) == 0)
813
return;
814
815
/* New in libpng-1.5.4 - reserve particular negative values as flags. */
816
scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/);
817
file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/);
818
819
/* Checking the gamma values for being >0 was added in 1.5.4 along with the
820
* premultiplied alpha support; this actually hides an undocumented feature
821
* of the previous implementation which allowed gamma processing to be
822
* disabled in background handling. There is no evidence (so far) that this
823
* was being used; however, png_set_background itself accepted and must still
824
* accept '0' for the gamma value it takes, because it isn't always used.
825
*
826
* Since this is an API change (albeit a very minor one that removes an
827
* undocumented API feature) the following checks were only enabled in
828
* libpng-1.6.0.
829
*/
830
if (file_gamma <= 0)
831
png_error(png_ptr, "invalid file gamma in png_set_gamma");
832
833
if (scrn_gamma <= 0)
834
png_error(png_ptr, "invalid screen gamma in png_set_gamma");
835
836
/* Set the gamma values unconditionally - this overrides the value in the PNG
837
* file if a gAMA chunk was present. png_set_alpha_mode provides a
838
* different, easier, way to default the file gamma.
839
*/
840
png_ptr->colorspace.gamma = file_gamma;
841
png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
842
png_ptr->screen_gamma = scrn_gamma;
843
}
844
845
# ifdef PNG_FLOATING_POINT_SUPPORTED
846
void PNGAPI
847
png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma)
848
{
849
png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma),
850
convert_gamma_value(png_ptr, file_gamma));
851
}
852
# endif /* FLOATING_POINT */
853
#endif /* READ_GAMMA */
854
855
#ifdef PNG_READ_EXPAND_SUPPORTED
856
/* Expand paletted images to RGB, expand grayscale images of
857
* less than 8-bit depth to 8-bit depth, and expand tRNS chunks
858
* to alpha channels.
859
*/
860
void PNGAPI
861
png_set_expand(png_structrp png_ptr)
862
{
863
png_debug(1, "in png_set_expand");
864
865
if (png_rtran_ok(png_ptr, 0) == 0)
866
return;
867
868
png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
869
}
870
871
/* GRR 19990627: the following three functions currently are identical
872
* to png_set_expand(). However, it is entirely reasonable that someone
873
* might wish to expand an indexed image to RGB but *not* expand a single,
874
* fully transparent palette entry to a full alpha channel--perhaps instead
875
* convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
876
* the transparent color with a particular RGB value, or drop tRNS entirely.
877
* IOW, a future version of the library may make the transformations flag
878
* a bit more fine-grained, with separate bits for each of these three
879
* functions.
880
*
881
* More to the point, these functions make it obvious what libpng will be
882
* doing, whereas "expand" can (and does) mean any number of things.
883
*
884
* GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified
885
* to expand only the sample depth but not to expand the tRNS to alpha
886
* and its name was changed to png_set_expand_gray_1_2_4_to_8().
887
*/
888
889
/* Expand paletted images to RGB. */
890
void PNGAPI
891
png_set_palette_to_rgb(png_structrp png_ptr)
892
{
893
png_debug(1, "in png_set_palette_to_rgb");
894
895
if (png_rtran_ok(png_ptr, 0) == 0)
896
return;
897
898
png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
899
}
900
901
/* Expand grayscale images of less than 8-bit depth to 8 bits. */
902
void PNGAPI
903
png_set_expand_gray_1_2_4_to_8(png_structrp png_ptr)
904
{
905
png_debug(1, "in png_set_expand_gray_1_2_4_to_8");
906
907
if (png_rtran_ok(png_ptr, 0) == 0)
908
return;
909
910
png_ptr->transformations |= PNG_EXPAND;
911
}
912
913
/* Expand tRNS chunks to alpha channels. */
914
void PNGAPI
915
png_set_tRNS_to_alpha(png_structrp png_ptr)
916
{
917
png_debug(1, "in png_set_tRNS_to_alpha");
918
919
if (png_rtran_ok(png_ptr, 0) == 0)
920
return;
921
922
png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
923
}
924
#endif /* READ_EXPAND */
925
926
#ifdef PNG_READ_EXPAND_16_SUPPORTED
927
/* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise
928
* it may not work correctly.)
929
*/
930
void PNGAPI
931
png_set_expand_16(png_structrp png_ptr)
932
{
933
png_debug(1, "in png_set_expand_16");
934
935
if (png_rtran_ok(png_ptr, 0) == 0)
936
return;
937
938
png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS);
939
}
940
#endif
941
942
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
943
void PNGAPI
944
png_set_gray_to_rgb(png_structrp png_ptr)
945
{
946
png_debug(1, "in png_set_gray_to_rgb");
947
948
if (png_rtran_ok(png_ptr, 0) == 0)
949
return;
950
951
/* Because rgb must be 8 bits or more: */
952
png_set_expand_gray_1_2_4_to_8(png_ptr);
953
png_ptr->transformations |= PNG_GRAY_TO_RGB;
954
}
955
#endif
956
957
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
958
void PNGFAPI
959
png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
960
png_fixed_point red, png_fixed_point green)
961
{
962
png_debug(1, "in png_set_rgb_to_gray");
963
964
/* Need the IHDR here because of the check on color_type below. */
965
/* TODO: fix this */
966
if (png_rtran_ok(png_ptr, 1) == 0)
967
return;
968
969
switch (error_action)
970
{
971
case PNG_ERROR_ACTION_NONE:
972
png_ptr->transformations |= PNG_RGB_TO_GRAY;
973
break;
974
975
case PNG_ERROR_ACTION_WARN:
976
png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
977
break;
978
979
case PNG_ERROR_ACTION_ERROR:
980
png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
981
break;
982
983
default:
984
png_error(png_ptr, "invalid error action to rgb_to_gray");
985
}
986
987
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
988
#ifdef PNG_READ_EXPAND_SUPPORTED
989
png_ptr->transformations |= PNG_EXPAND;
990
#else
991
{
992
/* Make this an error in 1.6 because otherwise the application may assume
993
* that it just worked and get a memory overwrite.
994
*/
995
png_error(png_ptr,
996
"Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");
997
998
/* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */
999
}
1000
#endif
1001
{
1002
if (red >= 0 && green >= 0 && red + green <= PNG_FP_1)
1003
{
1004
png_uint_16 red_int, green_int;
1005
1006
/* NOTE: this calculation does not round, but this behavior is retained
1007
* for consistency; the inaccuracy is very small. The code here always
1008
* overwrites the coefficients, regardless of whether they have been
1009
* defaulted or set already.
1010
*/
1011
red_int = (png_uint_16)(((png_uint_32)red*32768)/100000);
1012
green_int = (png_uint_16)(((png_uint_32)green*32768)/100000);
1013
1014
png_ptr->rgb_to_gray_red_coeff = red_int;
1015
png_ptr->rgb_to_gray_green_coeff = green_int;
1016
png_ptr->rgb_to_gray_coefficients_set = 1;
1017
}
1018
1019
else
1020
{
1021
if (red >= 0 && green >= 0)
1022
png_app_warning(png_ptr,
1023
"ignoring out of range rgb_to_gray coefficients");
1024
1025
/* Use the defaults, from the cHRM chunk if set, else the historical
1026
* values which are close to the sRGB/HDTV/ITU-Rec 709 values. See
1027
* png_do_rgb_to_gray for more discussion of the values. In this case
1028
* the coefficients are not marked as 'set' and are not overwritten if
1029
* something has already provided a default.
1030
*/
1031
if (png_ptr->rgb_to_gray_red_coeff == 0 &&
1032
png_ptr->rgb_to_gray_green_coeff == 0)
1033
{
1034
png_ptr->rgb_to_gray_red_coeff = 6968;
1035
png_ptr->rgb_to_gray_green_coeff = 23434;
1036
/* png_ptr->rgb_to_gray_blue_coeff = 2366; */
1037
}
1038
}
1039
}
1040
}
1041
1042
#ifdef PNG_FLOATING_POINT_SUPPORTED
1043
/* Convert a RGB image to a grayscale of the same width. This allows us,
1044
* for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
1045
*/
1046
1047
void PNGAPI
1048
png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red,
1049
double green)
1050
{
1051
png_set_rgb_to_gray_fixed(png_ptr, error_action,
1052
png_fixed(png_ptr, red, "rgb to gray red coefficient"),
1053
png_fixed(png_ptr, green, "rgb to gray green coefficient"));
1054
}
1055
#endif /* FLOATING POINT */
1056
1057
#endif /* RGB_TO_GRAY */
1058
1059
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
1060
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
1061
void PNGAPI
1062
png_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr
1063
read_user_transform_fn)
1064
{
1065
png_debug(1, "in png_set_read_user_transform_fn");
1066
1067
#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
1068
png_ptr->transformations |= PNG_USER_TRANSFORM;
1069
png_ptr->read_user_transform_fn = read_user_transform_fn;
1070
#endif
1071
}
1072
#endif
1073
1074
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
1075
#ifdef PNG_READ_GAMMA_SUPPORTED
1076
/* In the case of gamma transformations only do transformations on images where
1077
* the [file] gamma and screen_gamma are not close reciprocals, otherwise it
1078
* slows things down slightly, and also needlessly introduces small errors.
1079
*/
1080
static int /* PRIVATE */
1081
png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma)
1082
{
1083
/* PNG_GAMMA_THRESHOLD is the threshold for performing gamma
1084
* correction as a difference of the overall transform from 1.0
1085
*
1086
* We want to compare the threshold with s*f - 1, if we get
1087
* overflow here it is because of wacky gamma values so we
1088
* turn on processing anyway.
1089
*/
1090
png_fixed_point gtest;
1091
return !png_muldiv(&gtest, screen_gamma, file_gamma, PNG_FP_1) ||
1092
png_gamma_significant(gtest);
1093
}
1094
#endif
1095
1096
/* Initialize everything needed for the read. This includes modifying
1097
* the palette.
1098
*/
1099
1100
/* For the moment 'png_init_palette_transformations' and
1101
* 'png_init_rgb_transformations' only do some flag canceling optimizations.
1102
* The intent is that these two routines should have palette or rgb operations
1103
* extracted from 'png_init_read_transformations'.
1104
*/
1105
static void /* PRIVATE */
1106
png_init_palette_transformations(png_structrp png_ptr)
1107
{
1108
/* Called to handle the (input) palette case. In png_do_read_transformations
1109
* the first step is to expand the palette if requested, so this code must
1110
* take care to only make changes that are invariant with respect to the
1111
* palette expansion, or only do them if there is no expansion.
1112
*
1113
* STRIP_ALPHA has already been handled in the caller (by setting num_trans
1114
* to 0.)
1115
*/
1116
int input_has_alpha = 0;
1117
int input_has_transparency = 0;
1118
1119
if (png_ptr->num_trans > 0)
1120
{
1121
int i;
1122
1123
/* Ignore if all the entries are opaque (unlikely!) */
1124
for (i=0; i<png_ptr->num_trans; ++i)
1125
{
1126
if (png_ptr->trans_alpha[i] == 255)
1127
continue;
1128
else if (png_ptr->trans_alpha[i] == 0)
1129
input_has_transparency = 1;
1130
else
1131
{
1132
input_has_transparency = 1;
1133
input_has_alpha = 1;
1134
break;
1135
}
1136
}
1137
}
1138
1139
/* If no alpha we can optimize. */
1140
if (input_has_alpha == 0)
1141
{
1142
/* Any alpha means background and associative alpha processing is
1143
* required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA
1144
* and ENCODE_ALPHA are irrelevant.
1145
*/
1146
png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
1147
png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1148
1149
if (input_has_transparency == 0)
1150
png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
1151
}
1152
1153
#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
1154
/* png_set_background handling - deals with the complexity of whether the
1155
* background color is in the file format or the screen format in the case
1156
* where an 'expand' will happen.
1157
*/
1158
1159
/* The following code cannot be entered in the alpha pre-multiplication case
1160
* because PNG_BACKGROUND_EXPAND is cancelled below.
1161
*/
1162
if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 &&
1163
(png_ptr->transformations & PNG_EXPAND) != 0)
1164
{
1165
{
1166
png_ptr->background.red =
1167
png_ptr->palette[png_ptr->background.index].red;
1168
png_ptr->background.green =
1169
png_ptr->palette[png_ptr->background.index].green;
1170
png_ptr->background.blue =
1171
png_ptr->palette[png_ptr->background.index].blue;
1172
1173
#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
1174
if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
1175
{
1176
if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0)
1177
{
1178
/* Invert the alpha channel (in tRNS) unless the pixels are
1179
* going to be expanded, in which case leave it for later
1180
*/
1181
int i, istop = png_ptr->num_trans;
1182
1183
for (i=0; i<istop; i++)
1184
png_ptr->trans_alpha[i] = (png_byte)(255 -
1185
png_ptr->trans_alpha[i]);
1186
}
1187
}
1188
#endif /* READ_INVERT_ALPHA */
1189
}
1190
} /* background expand and (therefore) no alpha association. */
1191
#endif /* READ_EXPAND && READ_BACKGROUND */
1192
}
1193
1194
static void /* PRIVATE */
1195
png_init_rgb_transformations(png_structrp png_ptr)
1196
{
1197
/* Added to libpng-1.5.4: check the color type to determine whether there
1198
* is any alpha or transparency in the image and simply cancel the
1199
* background and alpha mode stuff if there isn't.
1200
*/
1201
int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0;
1202
int input_has_transparency = png_ptr->num_trans > 0;
1203
1204
/* If no alpha we can optimize. */
1205
if (input_has_alpha == 0)
1206
{
1207
/* Any alpha means background and associative alpha processing is
1208
* required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA
1209
* and ENCODE_ALPHA are irrelevant.
1210
*/
1211
# ifdef PNG_READ_ALPHA_MODE_SUPPORTED
1212
png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
1213
png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1214
# endif
1215
1216
if (input_has_transparency == 0)
1217
png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
1218
}
1219
1220
#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
1221
/* png_set_background handling - deals with the complexity of whether the
1222
* background color is in the file format or the screen format in the case
1223
* where an 'expand' will happen.
1224
*/
1225
1226
/* The following code cannot be entered in the alpha pre-multiplication case
1227
* because PNG_BACKGROUND_EXPAND is cancelled below.
1228
*/
1229
if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 &&
1230
(png_ptr->transformations & PNG_EXPAND) != 0 &&
1231
(png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
1232
/* i.e., GRAY or GRAY_ALPHA */
1233
{
1234
{
1235
/* Expand background and tRNS chunks */
1236
int gray = png_ptr->background.gray;
1237
int trans_gray = png_ptr->trans_color.gray;
1238
1239
switch (png_ptr->bit_depth)
1240
{
1241
case 1:
1242
gray *= 0xff;
1243
trans_gray *= 0xff;
1244
break;
1245
1246
case 2:
1247
gray *= 0x55;
1248
trans_gray *= 0x55;
1249
break;
1250
1251
case 4:
1252
gray *= 0x11;
1253
trans_gray *= 0x11;
1254
break;
1255
1256
default:
1257
1258
case 8:
1259
/* FALLTHROUGH */ /* (Already 8 bits) */
1260
1261
case 16:
1262
/* Already a full 16 bits */
1263
break;
1264
}
1265
1266
png_ptr->background.red = png_ptr->background.green =
1267
png_ptr->background.blue = (png_uint_16)gray;
1268
1269
if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0)
1270
{
1271
png_ptr->trans_color.red = png_ptr->trans_color.green =
1272
png_ptr->trans_color.blue = (png_uint_16)trans_gray;
1273
}
1274
}
1275
} /* background expand and (therefore) no alpha association. */
1276
#endif /* READ_EXPAND && READ_BACKGROUND */
1277
}
1278
1279
void /* PRIVATE */
1280
png_init_read_transformations(png_structrp png_ptr)
1281
{
1282
png_debug(1, "in png_init_read_transformations");
1283
1284
/* This internal function is called from png_read_start_row in pngrutil.c
1285
* and it is called before the 'rowbytes' calculation is done, so the code
1286
* in here can change or update the transformations flags.
1287
*
1288
* First do updates that do not depend on the details of the PNG image data
1289
* being processed.
1290
*/
1291
1292
#ifdef PNG_READ_GAMMA_SUPPORTED
1293
/* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds
1294
* png_set_alpha_mode and this is another source for a default file gamma so
1295
* the test needs to be performed later - here. In addition prior to 1.5.4
1296
* the tests were repeated for the PALETTE color type here - this is no
1297
* longer necessary (and doesn't seem to have been necessary before.)
1298
*/
1299
{
1300
/* The following temporary indicates if overall gamma correction is
1301
* required.
1302
*/
1303
int gamma_correction = 0;
1304
1305
if (png_ptr->colorspace.gamma != 0) /* has been set */
1306
{
1307
if (png_ptr->screen_gamma != 0) /* screen set too */
1308
gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma,
1309
png_ptr->screen_gamma);
1310
1311
else
1312
/* Assume the output matches the input; a long time default behavior
1313
* of libpng, although the standard has nothing to say about this.
1314
*/
1315
png_ptr->screen_gamma = png_reciprocal(png_ptr->colorspace.gamma);
1316
}
1317
1318
else if (png_ptr->screen_gamma != 0)
1319
/* The converse - assume the file matches the screen, note that this
1320
* perhaps undesireable default can (from 1.5.4) be changed by calling
1321
* png_set_alpha_mode (even if the alpha handling mode isn't required
1322
* or isn't changed from the default.)
1323
*/
1324
png_ptr->colorspace.gamma = png_reciprocal(png_ptr->screen_gamma);
1325
1326
else /* neither are set */
1327
/* Just in case the following prevents any processing - file and screen
1328
* are both assumed to be linear and there is no way to introduce a
1329
* third gamma value other than png_set_background with 'UNIQUE', and,
1330
* prior to 1.5.4
1331
*/
1332
png_ptr->screen_gamma = png_ptr->colorspace.gamma = PNG_FP_1;
1333
1334
/* We have a gamma value now. */
1335
png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
1336
1337
/* Now turn the gamma transformation on or off as appropriate. Notice
1338
* that PNG_GAMMA just refers to the file->screen correction. Alpha
1339
* composition may independently cause gamma correction because it needs
1340
* linear data (e.g. if the file has a gAMA chunk but the screen gamma
1341
* hasn't been specified.) In any case this flag may get turned off in
1342
* the code immediately below if the transform can be handled outside the
1343
* row loop.
1344
*/
1345
if (gamma_correction != 0)
1346
png_ptr->transformations |= PNG_GAMMA;
1347
1348
else
1349
png_ptr->transformations &= ~PNG_GAMMA;
1350
}
1351
#endif
1352
1353
/* Certain transformations have the effect of preventing other
1354
* transformations that happen afterward in png_do_read_transformations;
1355
* resolve the interdependencies here. From the code of
1356
* png_do_read_transformations the order is:
1357
*
1358
* 1) PNG_EXPAND (including PNG_EXPAND_tRNS)
1359
* 2) PNG_STRIP_ALPHA (if no compose)
1360
* 3) PNG_RGB_TO_GRAY
1361
* 4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY
1362
* 5) PNG_COMPOSE
1363
* 6) PNG_GAMMA
1364
* 7) PNG_STRIP_ALPHA (if compose)
1365
* 8) PNG_ENCODE_ALPHA
1366
* 9) PNG_SCALE_16_TO_8
1367
* 10) PNG_16_TO_8
1368
* 11) PNG_QUANTIZE (converts to palette)
1369
* 12) PNG_EXPAND_16
1370
* 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY
1371
* 14) PNG_INVERT_MONO
1372
* 15) PNG_INVERT_ALPHA
1373
* 16) PNG_SHIFT
1374
* 17) PNG_PACK
1375
* 18) PNG_BGR
1376
* 19) PNG_PACKSWAP
1377
* 20) PNG_FILLER (includes PNG_ADD_ALPHA)
1378
* 21) PNG_SWAP_ALPHA
1379
* 22) PNG_SWAP_BYTES
1380
* 23) PNG_USER_TRANSFORM [must be last]
1381
*/
1382
#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
1383
if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
1384
(png_ptr->transformations & PNG_COMPOSE) == 0)
1385
{
1386
/* Stripping the alpha channel happens immediately after the 'expand'
1387
* transformations, before all other transformation, so it cancels out
1388
* the alpha handling. It has the side effect negating the effect of
1389
* PNG_EXPAND_tRNS too:
1390
*/
1391
png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA |
1392
PNG_EXPAND_tRNS);
1393
png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1394
1395
/* Kill the tRNS chunk itself too. Prior to 1.5.4 this did not happen
1396
* so transparency information would remain just so long as it wasn't
1397
* expanded. This produces unexpected API changes if the set of things
1398
* that do PNG_EXPAND_tRNS changes (perfectly possible given the
1399
* documentation - which says ask for what you want, accept what you
1400
* get.) This makes the behavior consistent from 1.5.4:
1401
*/
1402
png_ptr->num_trans = 0;
1403
}
1404
#endif /* STRIP_ALPHA supported, no COMPOSE */
1405
1406
#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
1407
/* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA
1408
* settings will have no effect.
1409
*/
1410
if (png_gamma_significant(png_ptr->screen_gamma) == 0)
1411
{
1412
png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
1413
png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1414
}
1415
#endif
1416
1417
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1418
/* Make sure the coefficients for the rgb to gray conversion are set
1419
* appropriately.
1420
*/
1421
if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
1422
png_colorspace_set_rgb_coefficients(png_ptr);
1423
#endif
1424
1425
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
1426
#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
1427
/* Detect gray background and attempt to enable optimization for
1428
* gray --> RGB case.
1429
*
1430
* Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
1431
* RGB_ALPHA (in which case need_expand is superfluous anyway), the
1432
* background color might actually be gray yet not be flagged as such.
1433
* This is not a problem for the current code, which uses
1434
* PNG_BACKGROUND_IS_GRAY only to decide when to do the
1435
* png_do_gray_to_rgb() transformation.
1436
*
1437
* TODO: this code needs to be revised to avoid the complexity and
1438
* interdependencies. The color type of the background should be recorded in
1439
* png_set_background, along with the bit depth, then the code has a record
1440
* of exactly what color space the background is currently in.
1441
*/
1442
if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0)
1443
{
1444
/* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if
1445
* the file was grayscale the background value is gray.
1446
*/
1447
if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
1448
png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
1449
}
1450
1451
else if ((png_ptr->transformations & PNG_COMPOSE) != 0)
1452
{
1453
/* PNG_COMPOSE: png_set_background was called with need_expand false,
1454
* so the color is in the color space of the output or png_set_alpha_mode
1455
* was called and the color is black. Ignore RGB_TO_GRAY because that
1456
* happens before GRAY_TO_RGB.
1457
*/
1458
if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)
1459
{
1460
if (png_ptr->background.red == png_ptr->background.green &&
1461
png_ptr->background.red == png_ptr->background.blue)
1462
{
1463
png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
1464
png_ptr->background.gray = png_ptr->background.red;
1465
}
1466
}
1467
}
1468
#endif /* READ_EXPAND && READ_BACKGROUND */
1469
#endif /* READ_GRAY_TO_RGB */
1470
1471
/* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations
1472
* can be performed directly on the palette, and some (such as rgb to gray)
1473
* can be optimized inside the palette. This is particularly true of the
1474
* composite (background and alpha) stuff, which can be pretty much all done
1475
* in the palette even if the result is expanded to RGB or gray afterward.
1476
*
1477
* NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and
1478
* earlier and the palette stuff is actually handled on the first row. This
1479
* leads to the reported bug that the palette returned by png_get_PLTE is not
1480
* updated.
1481
*/
1482
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1483
png_init_palette_transformations(png_ptr);
1484
1485
else
1486
png_init_rgb_transformations(png_ptr);
1487
1488
#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
1489
defined(PNG_READ_EXPAND_16_SUPPORTED)
1490
if ((png_ptr->transformations & PNG_EXPAND_16) != 0 &&
1491
(png_ptr->transformations & PNG_COMPOSE) != 0 &&
1492
(png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 &&
1493
png_ptr->bit_depth != 16)
1494
{
1495
/* TODO: fix this. Because the expand_16 operation is after the compose
1496
* handling the background color must be 8, not 16, bits deep, but the
1497
* application will supply a 16-bit value so reduce it here.
1498
*
1499
* The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at
1500
* present, so that case is ok (until do_expand_16 is moved.)
1501
*
1502
* NOTE: this discards the low 16 bits of the user supplied background
1503
* color, but until expand_16 works properly there is no choice!
1504
*/
1505
# define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x))
1506
CHOP(png_ptr->background.red);
1507
CHOP(png_ptr->background.green);
1508
CHOP(png_ptr->background.blue);
1509
CHOP(png_ptr->background.gray);
1510
# undef CHOP
1511
}
1512
#endif /* READ_BACKGROUND && READ_EXPAND_16 */
1513
1514
#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
1515
(defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \
1516
defined(PNG_READ_STRIP_16_TO_8_SUPPORTED))
1517
if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) != 0 &&
1518
(png_ptr->transformations & PNG_COMPOSE) != 0 &&
1519
(png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 &&
1520
png_ptr->bit_depth == 16)
1521
{
1522
/* On the other hand, if a 16-bit file is to be reduced to 8-bits per
1523
* component this will also happen after PNG_COMPOSE and so the background
1524
* color must be pre-expanded here.
1525
*
1526
* TODO: fix this too.
1527
*/
1528
png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257);
1529
png_ptr->background.green =
1530
(png_uint_16)(png_ptr->background.green * 257);
1531
png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257);
1532
png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257);
1533
}
1534
#endif
1535
1536
/* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the
1537
* background support (see the comments in scripts/pnglibconf.dfa), this
1538
* allows pre-multiplication of the alpha channel to be implemented as
1539
* compositing on black. This is probably sub-optimal and has been done in
1540
* 1.5.4 betas simply to enable external critique and testing (i.e. to
1541
* implement the new API quickly, without lots of internal changes.)
1542
*/
1543
1544
#ifdef PNG_READ_GAMMA_SUPPORTED
1545
# ifdef PNG_READ_BACKGROUND_SUPPORTED
1546
/* Includes ALPHA_MODE */
1547
png_ptr->background_1 = png_ptr->background;
1548
# endif
1549
1550
/* This needs to change - in the palette image case a whole set of tables are
1551
* built when it would be quicker to just calculate the correct value for
1552
* each palette entry directly. Also, the test is too tricky - why check
1553
* PNG_RGB_TO_GRAY if PNG_GAMMA is not set? The answer seems to be that
1554
* PNG_GAMMA is cancelled even if the gamma is known? The test excludes the
1555
* PNG_COMPOSE case, so apparently if there is no *overall* gamma correction
1556
* the gamma tables will not be built even if composition is required on a
1557
* gamma encoded value.
1558
*
1559
* In 1.5.4 this is addressed below by an additional check on the individual
1560
* file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the
1561
* tables.
1562
*/
1563
if ((png_ptr->transformations & PNG_GAMMA) != 0 ||
1564
((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0 &&
1565
(png_gamma_significant(png_ptr->colorspace.gamma) != 0 ||
1566
png_gamma_significant(png_ptr->screen_gamma) != 0)) ||
1567
((png_ptr->transformations & PNG_COMPOSE) != 0 &&
1568
(png_gamma_significant(png_ptr->colorspace.gamma) != 0 ||
1569
png_gamma_significant(png_ptr->screen_gamma) != 0
1570
# ifdef PNG_READ_BACKGROUND_SUPPORTED
1571
|| (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE &&
1572
png_gamma_significant(png_ptr->background_gamma) != 0)
1573
# endif
1574
)) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 &&
1575
png_gamma_significant(png_ptr->screen_gamma) != 0))
1576
{
1577
png_build_gamma_table(png_ptr, png_ptr->bit_depth);
1578
1579
#ifdef PNG_READ_BACKGROUND_SUPPORTED
1580
if ((png_ptr->transformations & PNG_COMPOSE) != 0)
1581
{
1582
/* Issue a warning about this combination: because RGB_TO_GRAY is
1583
* optimized to do the gamma transform if present yet do_background has
1584
* to do the same thing if both options are set a
1585
* double-gamma-correction happens. This is true in all versions of
1586
* libpng to date.
1587
*/
1588
if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
1589
png_warning(png_ptr,
1590
"libpng does not support gamma+background+rgb_to_gray");
1591
1592
if ((png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) != 0)
1593
{
1594
/* We don't get to here unless there is a tRNS chunk with non-opaque
1595
* entries - see the checking code at the start of this function.
1596
*/
1597
png_color back, back_1;
1598
png_colorp palette = png_ptr->palette;
1599
int num_palette = png_ptr->num_palette;
1600
int i;
1601
if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
1602
{
1603
1604
back.red = png_ptr->gamma_table[png_ptr->background.red];
1605
back.green = png_ptr->gamma_table[png_ptr->background.green];
1606
back.blue = png_ptr->gamma_table[png_ptr->background.blue];
1607
1608
back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
1609
back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
1610
back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
1611
}
1612
else
1613
{
1614
png_fixed_point g, gs;
1615
1616
switch (png_ptr->background_gamma_type)
1617
{
1618
case PNG_BACKGROUND_GAMMA_SCREEN:
1619
g = (png_ptr->screen_gamma);
1620
gs = PNG_FP_1;
1621
break;
1622
1623
case PNG_BACKGROUND_GAMMA_FILE:
1624
g = png_reciprocal(png_ptr->colorspace.gamma);
1625
gs = png_reciprocal2(png_ptr->colorspace.gamma,
1626
png_ptr->screen_gamma);
1627
break;
1628
1629
case PNG_BACKGROUND_GAMMA_UNIQUE:
1630
g = png_reciprocal(png_ptr->background_gamma);
1631
gs = png_reciprocal2(png_ptr->background_gamma,
1632
png_ptr->screen_gamma);
1633
break;
1634
default:
1635
g = PNG_FP_1; /* back_1 */
1636
gs = PNG_FP_1; /* back */
1637
break;
1638
}
1639
1640
if (png_gamma_significant(gs) != 0)
1641
{
1642
back.red = png_gamma_8bit_correct(png_ptr->background.red,
1643
gs);
1644
back.green = png_gamma_8bit_correct(png_ptr->background.green,
1645
gs);
1646
back.blue = png_gamma_8bit_correct(png_ptr->background.blue,
1647
gs);
1648
}
1649
1650
else
1651
{
1652
back.red = (png_byte)png_ptr->background.red;
1653
back.green = (png_byte)png_ptr->background.green;
1654
back.blue = (png_byte)png_ptr->background.blue;
1655
}
1656
1657
if (png_gamma_significant(g) != 0)
1658
{
1659
back_1.red = png_gamma_8bit_correct(png_ptr->background.red,
1660
g);
1661
back_1.green = png_gamma_8bit_correct(
1662
png_ptr->background.green, g);
1663
back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue,
1664
g);
1665
}
1666
1667
else
1668
{
1669
back_1.red = (png_byte)png_ptr->background.red;
1670
back_1.green = (png_byte)png_ptr->background.green;
1671
back_1.blue = (png_byte)png_ptr->background.blue;
1672
}
1673
}
1674
1675
for (i = 0; i < num_palette; i++)
1676
{
1677
if (i < (int)png_ptr->num_trans &&
1678
png_ptr->trans_alpha[i] != 0xff)
1679
{
1680
if (png_ptr->trans_alpha[i] == 0)
1681
{
1682
palette[i] = back;
1683
}
1684
else /* if (png_ptr->trans_alpha[i] != 0xff) */
1685
{
1686
png_byte v, w;
1687
1688
v = png_ptr->gamma_to_1[palette[i].red];
1689
png_composite(w, v, png_ptr->trans_alpha[i], back_1.red);
1690
palette[i].red = png_ptr->gamma_from_1[w];
1691
1692
v = png_ptr->gamma_to_1[palette[i].green];
1693
png_composite(w, v, png_ptr->trans_alpha[i], back_1.green);
1694
palette[i].green = png_ptr->gamma_from_1[w];
1695
1696
v = png_ptr->gamma_to_1[palette[i].blue];
1697
png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue);
1698
palette[i].blue = png_ptr->gamma_from_1[w];
1699
}
1700
}
1701
else
1702
{
1703
palette[i].red = png_ptr->gamma_table[palette[i].red];
1704
palette[i].green = png_ptr->gamma_table[palette[i].green];
1705
palette[i].blue = png_ptr->gamma_table[palette[i].blue];
1706
}
1707
}
1708
1709
/* Prevent the transformations being done again.
1710
*
1711
* NOTE: this is highly dubious; it removes the transformations in
1712
* place. This seems inconsistent with the general treatment of the
1713
* transformations elsewhere.
1714
*/
1715
png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA);
1716
} /* color_type == PNG_COLOR_TYPE_PALETTE */
1717
1718
/* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
1719
else /* color_type != PNG_COLOR_TYPE_PALETTE */
1720
{
1721
int gs_sig, g_sig;
1722
png_fixed_point g = PNG_FP_1; /* Correction to linear */
1723
png_fixed_point gs = PNG_FP_1; /* Correction to screen */
1724
1725
switch (png_ptr->background_gamma_type)
1726
{
1727
case PNG_BACKGROUND_GAMMA_SCREEN:
1728
g = png_ptr->screen_gamma;
1729
/* gs = PNG_FP_1; */
1730
break;
1731
1732
case PNG_BACKGROUND_GAMMA_FILE:
1733
g = png_reciprocal(png_ptr->colorspace.gamma);
1734
gs = png_reciprocal2(png_ptr->colorspace.gamma,
1735
png_ptr->screen_gamma);
1736
break;
1737
1738
case PNG_BACKGROUND_GAMMA_UNIQUE:
1739
g = png_reciprocal(png_ptr->background_gamma);
1740
gs = png_reciprocal2(png_ptr->background_gamma,
1741
png_ptr->screen_gamma);
1742
break;
1743
1744
default:
1745
png_error(png_ptr, "invalid background gamma type");
1746
}
1747
1748
g_sig = png_gamma_significant(g);
1749
gs_sig = png_gamma_significant(gs);
1750
1751
if (g_sig != 0)
1752
png_ptr->background_1.gray = png_gamma_correct(png_ptr,
1753
png_ptr->background.gray, g);
1754
1755
if (gs_sig != 0)
1756
png_ptr->background.gray = png_gamma_correct(png_ptr,
1757
png_ptr->background.gray, gs);
1758
1759
if ((png_ptr->background.red != png_ptr->background.green) ||
1760
(png_ptr->background.red != png_ptr->background.blue) ||
1761
(png_ptr->background.red != png_ptr->background.gray))
1762
{
1763
/* RGB or RGBA with color background */
1764
if (g_sig != 0)
1765
{
1766
png_ptr->background_1.red = png_gamma_correct(png_ptr,
1767
png_ptr->background.red, g);
1768
1769
png_ptr->background_1.green = png_gamma_correct(png_ptr,
1770
png_ptr->background.green, g);
1771
1772
png_ptr->background_1.blue = png_gamma_correct(png_ptr,
1773
png_ptr->background.blue, g);
1774
}
1775
1776
if (gs_sig != 0)
1777
{
1778
png_ptr->background.red = png_gamma_correct(png_ptr,
1779
png_ptr->background.red, gs);
1780
1781
png_ptr->background.green = png_gamma_correct(png_ptr,
1782
png_ptr->background.green, gs);
1783
1784
png_ptr->background.blue = png_gamma_correct(png_ptr,
1785
png_ptr->background.blue, gs);
1786
}
1787
}
1788
1789
else
1790
{
1791
/* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
1792
png_ptr->background_1.red = png_ptr->background_1.green
1793
= png_ptr->background_1.blue = png_ptr->background_1.gray;
1794
1795
png_ptr->background.red = png_ptr->background.green
1796
= png_ptr->background.blue = png_ptr->background.gray;
1797
}
1798
1799
/* The background is now in screen gamma: */
1800
png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN;
1801
} /* color_type != PNG_COLOR_TYPE_PALETTE */
1802
}/* png_ptr->transformations & PNG_BACKGROUND */
1803
1804
else
1805
/* Transformation does not include PNG_BACKGROUND */
1806
#endif /* READ_BACKGROUND */
1807
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE
1808
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1809
/* RGB_TO_GRAY needs to have non-gamma-corrected values! */
1810
&& ((png_ptr->transformations & PNG_EXPAND) == 0 ||
1811
(png_ptr->transformations & PNG_RGB_TO_GRAY) == 0)
1812
#endif
1813
)
1814
{
1815
png_colorp palette = png_ptr->palette;
1816
int num_palette = png_ptr->num_palette;
1817
int i;
1818
1819
/* NOTE: there are other transformations that should probably be in
1820
* here too.
1821
*/
1822
for (i = 0; i < num_palette; i++)
1823
{
1824
palette[i].red = png_ptr->gamma_table[palette[i].red];
1825
palette[i].green = png_ptr->gamma_table[palette[i].green];
1826
palette[i].blue = png_ptr->gamma_table[palette[i].blue];
1827
}
1828
1829
/* Done the gamma correction. */
1830
png_ptr->transformations &= ~PNG_GAMMA;
1831
} /* color_type == PALETTE && !PNG_BACKGROUND transformation */
1832
}
1833
#ifdef PNG_READ_BACKGROUND_SUPPORTED
1834
else
1835
#endif
1836
#endif /* READ_GAMMA */
1837
1838
#ifdef PNG_READ_BACKGROUND_SUPPORTED
1839
/* No GAMMA transformation (see the hanging else 4 lines above) */
1840
if ((png_ptr->transformations & PNG_COMPOSE) != 0 &&
1841
(png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
1842
{
1843
int i;
1844
int istop = (int)png_ptr->num_trans;
1845
png_color back;
1846
png_colorp palette = png_ptr->palette;
1847
1848
back.red = (png_byte)png_ptr->background.red;
1849
back.green = (png_byte)png_ptr->background.green;
1850
back.blue = (png_byte)png_ptr->background.blue;
1851
1852
for (i = 0; i < istop; i++)
1853
{
1854
if (png_ptr->trans_alpha[i] == 0)
1855
{
1856
palette[i] = back;
1857
}
1858
1859
else if (png_ptr->trans_alpha[i] != 0xff)
1860
{
1861
/* The png_composite() macro is defined in png.h */
1862
png_composite(palette[i].red, palette[i].red,
1863
png_ptr->trans_alpha[i], back.red);
1864
1865
png_composite(palette[i].green, palette[i].green,
1866
png_ptr->trans_alpha[i], back.green);
1867
1868
png_composite(palette[i].blue, palette[i].blue,
1869
png_ptr->trans_alpha[i], back.blue);
1870
}
1871
}
1872
1873
png_ptr->transformations &= ~PNG_COMPOSE;
1874
}
1875
#endif /* READ_BACKGROUND */
1876
1877
#ifdef PNG_READ_SHIFT_SUPPORTED
1878
if ((png_ptr->transformations & PNG_SHIFT) != 0 &&
1879
(png_ptr->transformations & PNG_EXPAND) == 0 &&
1880
(png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
1881
{
1882
int i;
1883
int istop = png_ptr->num_palette;
1884
int shift = 8 - png_ptr->sig_bit.red;
1885
1886
png_ptr->transformations &= ~PNG_SHIFT;
1887
1888
/* significant bits can be in the range 1 to 7 for a meaninful result, if
1889
* the number of significant bits is 0 then no shift is done (this is an
1890
* error condition which is silently ignored.)
1891
*/
1892
if (shift > 0 && shift < 8)
1893
for (i=0; i<istop; ++i)
1894
{
1895
int component = png_ptr->palette[i].red;
1896
1897
component >>= shift;
1898
png_ptr->palette[i].red = (png_byte)component;
1899
}
1900
1901
shift = 8 - png_ptr->sig_bit.green;
1902
if (shift > 0 && shift < 8)
1903
for (i=0; i<istop; ++i)
1904
{
1905
int component = png_ptr->palette[i].green;
1906
1907
component >>= shift;
1908
png_ptr->palette[i].green = (png_byte)component;
1909
}
1910
1911
shift = 8 - png_ptr->sig_bit.blue;
1912
if (shift > 0 && shift < 8)
1913
for (i=0; i<istop; ++i)
1914
{
1915
int component = png_ptr->palette[i].blue;
1916
1917
component >>= shift;
1918
png_ptr->palette[i].blue = (png_byte)component;
1919
}
1920
}
1921
#endif /* READ_SHIFT */
1922
}
1923
1924
/* Modify the info structure to reflect the transformations. The
1925
* info should be updated so a PNG file could be written with it,
1926
* assuming the transformations result in valid PNG data.
1927
*/
1928
void /* PRIVATE */
1929
png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)
1930
{
1931
png_debug(1, "in png_read_transform_info");
1932
1933
#ifdef PNG_READ_EXPAND_SUPPORTED
1934
if ((png_ptr->transformations & PNG_EXPAND) != 0)
1935
{
1936
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1937
{
1938
/* This check must match what actually happens in
1939
* png_do_expand_palette; if it ever checks the tRNS chunk to see if
1940
* it is all opaque we must do the same (at present it does not.)
1941
*/
1942
if (png_ptr->num_trans > 0)
1943
info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
1944
1945
else
1946
info_ptr->color_type = PNG_COLOR_TYPE_RGB;
1947
1948
info_ptr->bit_depth = 8;
1949
info_ptr->num_trans = 0;
1950
1951
if (png_ptr->palette == NULL)
1952
png_error (png_ptr, "Palette is NULL in indexed image");
1953
}
1954
else
1955
{
1956
if (png_ptr->num_trans != 0)
1957
{
1958
if ((png_ptr->transformations & PNG_EXPAND_tRNS) != 0)
1959
info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
1960
}
1961
if (info_ptr->bit_depth < 8)
1962
info_ptr->bit_depth = 8;
1963
1964
info_ptr->num_trans = 0;
1965
}
1966
}
1967
#endif
1968
1969
#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
1970
defined(PNG_READ_ALPHA_MODE_SUPPORTED)
1971
/* The following is almost certainly wrong unless the background value is in
1972
* the screen space!
1973
*/
1974
if ((png_ptr->transformations & PNG_COMPOSE) != 0)
1975
info_ptr->background = png_ptr->background;
1976
#endif
1977
1978
#ifdef PNG_READ_GAMMA_SUPPORTED
1979
/* The following used to be conditional on PNG_GAMMA (prior to 1.5.4),
1980
* however it seems that the code in png_init_read_transformations, which has
1981
* been called before this from png_read_update_info->png_read_start_row
1982
* sometimes does the gamma transform and cancels the flag.
1983
*
1984
* TODO: this looks wrong; the info_ptr should end up with a gamma equal to
1985
* the screen_gamma value. The following probably results in weirdness if
1986
* the info_ptr is used by the app after the rows have been read.
1987
*/
1988
info_ptr->colorspace.gamma = png_ptr->colorspace.gamma;
1989
#endif
1990
1991
if (info_ptr->bit_depth == 16)
1992
{
1993
# ifdef PNG_READ_16BIT_SUPPORTED
1994
# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
1995
if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0)
1996
info_ptr->bit_depth = 8;
1997
# endif
1998
1999
# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
2000
if ((png_ptr->transformations & PNG_16_TO_8) != 0)
2001
info_ptr->bit_depth = 8;
2002
# endif
2003
2004
# else
2005
/* No 16-bit support: force chopping 16-bit input down to 8, in this case
2006
* the app program can chose if both APIs are available by setting the
2007
* correct scaling to use.
2008
*/
2009
# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
2010
/* For compatibility with previous versions use the strip method by
2011
* default. This code works because if PNG_SCALE_16_TO_8 is already
2012
* set the code below will do that in preference to the chop.
2013
*/
2014
png_ptr->transformations |= PNG_16_TO_8;
2015
info_ptr->bit_depth = 8;
2016
# else
2017
2018
# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
2019
png_ptr->transformations |= PNG_SCALE_16_TO_8;
2020
info_ptr->bit_depth = 8;
2021
# else
2022
2023
CONFIGURATION ERROR: you must enable at least one 16 to 8 method
2024
# endif
2025
# endif
2026
#endif /* !READ_16BIT */
2027
}
2028
2029
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
2030
if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)
2031
info_ptr->color_type = (png_byte)(info_ptr->color_type |
2032
PNG_COLOR_MASK_COLOR);
2033
#endif
2034
2035
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
2036
if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
2037
info_ptr->color_type = (png_byte)(info_ptr->color_type &
2038
~PNG_COLOR_MASK_COLOR);
2039
#endif
2040
2041
#ifdef PNG_READ_QUANTIZE_SUPPORTED
2042
if ((png_ptr->transformations & PNG_QUANTIZE) != 0)
2043
{
2044
if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
2045
(info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
2046
png_ptr->palette_lookup != 0 && info_ptr->bit_depth == 8)
2047
{
2048
info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
2049
}
2050
}
2051
#endif
2052
2053
#ifdef PNG_READ_EXPAND_16_SUPPORTED
2054
if ((png_ptr->transformations & PNG_EXPAND_16) != 0 &&
2055
info_ptr->bit_depth == 8 &&
2056
info_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
2057
{
2058
info_ptr->bit_depth = 16;
2059
}
2060
#endif
2061
2062
#ifdef PNG_READ_PACK_SUPPORTED
2063
if ((png_ptr->transformations & PNG_PACK) != 0 &&
2064
(info_ptr->bit_depth < 8))
2065
info_ptr->bit_depth = 8;
2066
#endif
2067
2068
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
2069
info_ptr->channels = 1;
2070
2071
else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
2072
info_ptr->channels = 3;
2073
2074
else
2075
info_ptr->channels = 1;
2076
2077
#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
2078
if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0)
2079
{
2080
info_ptr->color_type = (png_byte)(info_ptr->color_type &
2081
~PNG_COLOR_MASK_ALPHA);
2082
info_ptr->num_trans = 0;
2083
}
2084
#endif
2085
2086
if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
2087
info_ptr->channels++;
2088
2089
#ifdef PNG_READ_FILLER_SUPPORTED
2090
/* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
2091
if ((png_ptr->transformations & PNG_FILLER) != 0 &&
2092
(info_ptr->color_type == PNG_COLOR_TYPE_RGB ||
2093
info_ptr->color_type == PNG_COLOR_TYPE_GRAY))
2094
{
2095
info_ptr->channels++;
2096
/* If adding a true alpha channel not just filler */
2097
if ((png_ptr->transformations & PNG_ADD_ALPHA) != 0)
2098
info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
2099
}
2100
#endif
2101
2102
#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
2103
defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
2104
if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
2105
{
2106
if (png_ptr->user_transform_depth != 0)
2107
info_ptr->bit_depth = png_ptr->user_transform_depth;
2108
2109
if (png_ptr->user_transform_channels != 0)
2110
info_ptr->channels = png_ptr->user_transform_channels;
2111
}
2112
#endif
2113
2114
info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
2115
info_ptr->bit_depth);
2116
2117
info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);
2118
2119
/* Adding in 1.5.4: cache the above value in png_struct so that we can later
2120
* check in png_rowbytes that the user buffer won't get overwritten. Note
2121
* that the field is not always set - if png_read_update_info isn't called
2122
* the application has to either not do any transforms or get the calculation
2123
* right itself.
2124
*/
2125
png_ptr->info_rowbytes = info_ptr->rowbytes;
2126
2127
#ifndef PNG_READ_EXPAND_SUPPORTED
2128
if (png_ptr != NULL)
2129
return;
2130
#endif
2131
}
2132
2133
#ifdef PNG_READ_PACK_SUPPORTED
2134
/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
2135
* without changing the actual values. Thus, if you had a row with
2136
* a bit depth of 1, you would end up with bytes that only contained
2137
* the numbers 0 or 1. If you would rather they contain 0 and 255, use
2138
* png_do_shift() after this.
2139
*/
2140
static void
2141
png_do_unpack(png_row_infop row_info, png_bytep row)
2142
{
2143
png_debug(1, "in png_do_unpack");
2144
2145
if (row_info->bit_depth < 8)
2146
{
2147
png_uint_32 i;
2148
png_uint_32 row_width=row_info->width;
2149
2150
switch (row_info->bit_depth)
2151
{
2152
case 1:
2153
{
2154
png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
2155
png_bytep dp = row + (png_size_t)row_width - 1;
2156
png_uint_32 shift = 7U - ((row_width + 7U) & 0x07);
2157
for (i = 0; i < row_width; i++)
2158
{
2159
*dp = (png_byte)((*sp >> shift) & 0x01);
2160
2161
if (shift == 7)
2162
{
2163
shift = 0;
2164
sp--;
2165
}
2166
2167
else
2168
shift++;
2169
2170
dp--;
2171
}
2172
break;
2173
}
2174
2175
case 2:
2176
{
2177
2178
png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
2179
png_bytep dp = row + (png_size_t)row_width - 1;
2180
png_uint_32 shift = ((3U - ((row_width + 3U) & 0x03)) << 1);
2181
for (i = 0; i < row_width; i++)
2182
{
2183
*dp = (png_byte)((*sp >> shift) & 0x03);
2184
2185
if (shift == 6)
2186
{
2187
shift = 0;
2188
sp--;
2189
}
2190
2191
else
2192
shift += 2;
2193
2194
dp--;
2195
}
2196
break;
2197
}
2198
2199
case 4:
2200
{
2201
png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
2202
png_bytep dp = row + (png_size_t)row_width - 1;
2203
png_uint_32 shift = ((1U - ((row_width + 1U) & 0x01)) << 2);
2204
for (i = 0; i < row_width; i++)
2205
{
2206
*dp = (png_byte)((*sp >> shift) & 0x0f);
2207
2208
if (shift == 4)
2209
{
2210
shift = 0;
2211
sp--;
2212
}
2213
2214
else
2215
shift = 4;
2216
2217
dp--;
2218
}
2219
break;
2220
}
2221
2222
default:
2223
break;
2224
}
2225
row_info->bit_depth = 8;
2226
row_info->pixel_depth = (png_byte)(8 * row_info->channels);
2227
row_info->rowbytes = row_width * row_info->channels;
2228
}
2229
}
2230
#endif
2231
2232
#ifdef PNG_READ_SHIFT_SUPPORTED
2233
/* Reverse the effects of png_do_shift. This routine merely shifts the
2234
* pixels back to their significant bits values. Thus, if you have
2235
* a row of bit depth 8, but only 5 are significant, this will shift
2236
* the values back to 0 through 31.
2237
*/
2238
static void
2239
png_do_unshift(png_row_infop row_info, png_bytep row,
2240
png_const_color_8p sig_bits)
2241
{
2242
int color_type;
2243
2244
png_debug(1, "in png_do_unshift");
2245
2246
/* The palette case has already been handled in the _init routine. */
2247
color_type = row_info->color_type;
2248
2249
if (color_type != PNG_COLOR_TYPE_PALETTE)
2250
{
2251
int shift[4];
2252
int channels = 0;
2253
int bit_depth = row_info->bit_depth;
2254
2255
if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
2256
{
2257
shift[channels++] = bit_depth - sig_bits->red;
2258
shift[channels++] = bit_depth - sig_bits->green;
2259
shift[channels++] = bit_depth - sig_bits->blue;
2260
}
2261
2262
else
2263
{
2264
shift[channels++] = bit_depth - sig_bits->gray;
2265
}
2266
2267
if ((color_type & PNG_COLOR_MASK_ALPHA) != 0)
2268
{
2269
shift[channels++] = bit_depth - sig_bits->alpha;
2270
}
2271
2272
{
2273
int c, have_shift;
2274
2275
for (c = have_shift = 0; c < channels; ++c)
2276
{
2277
/* A shift of more than the bit depth is an error condition but it
2278
* gets ignored here.
2279
*/
2280
if (shift[c] <= 0 || shift[c] >= bit_depth)
2281
shift[c] = 0;
2282
2283
else
2284
have_shift = 1;
2285
}
2286
2287
if (have_shift == 0)
2288
return;
2289
}
2290
2291
switch (bit_depth)
2292
{
2293
default:
2294
/* Must be 1bpp gray: should not be here! */
2295
/* NOTREACHED */
2296
break;
2297
2298
case 2:
2299
/* Must be 2bpp gray */
2300
/* assert(channels == 1 && shift[0] == 1) */
2301
{
2302
png_bytep bp = row;
2303
png_bytep bp_end = bp + row_info->rowbytes;
2304
2305
while (bp < bp_end)
2306
{
2307
int b = (*bp >> 1) & 0x55;
2308
*bp++ = (png_byte)b;
2309
}
2310
break;
2311
}
2312
2313
case 4:
2314
/* Must be 4bpp gray */
2315
/* assert(channels == 1) */
2316
{
2317
png_bytep bp = row;
2318
png_bytep bp_end = bp + row_info->rowbytes;
2319
int gray_shift = shift[0];
2320
int mask = 0xf >> gray_shift;
2321
2322
mask |= mask << 4;
2323
2324
while (bp < bp_end)
2325
{
2326
int b = (*bp >> gray_shift) & mask;
2327
*bp++ = (png_byte)b;
2328
}
2329
break;
2330
}
2331
2332
case 8:
2333
/* Single byte components, G, GA, RGB, RGBA */
2334
{
2335
png_bytep bp = row;
2336
png_bytep bp_end = bp + row_info->rowbytes;
2337
int channel = 0;
2338
2339
while (bp < bp_end)
2340
{
2341
int b = *bp >> shift[channel];
2342
if (++channel >= channels)
2343
channel = 0;
2344
*bp++ = (png_byte)b;
2345
}
2346
break;
2347
}
2348
2349
#ifdef PNG_READ_16BIT_SUPPORTED
2350
case 16:
2351
/* Double byte components, G, GA, RGB, RGBA */
2352
{
2353
png_bytep bp = row;
2354
png_bytep bp_end = bp + row_info->rowbytes;
2355
int channel = 0;
2356
2357
while (bp < bp_end)
2358
{
2359
int value = (bp[0] << 8) + bp[1];
2360
2361
value >>= shift[channel];
2362
if (++channel >= channels)
2363
channel = 0;
2364
*bp++ = (png_byte)(value >> 8);
2365
*bp++ = (png_byte)value;
2366
}
2367
break;
2368
}
2369
#endif
2370
}
2371
}
2372
}
2373
#endif
2374
2375
#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
2376
/* Scale rows of bit depth 16 down to 8 accurately */
2377
static void
2378
png_do_scale_16_to_8(png_row_infop row_info, png_bytep row)
2379
{
2380
png_debug(1, "in png_do_scale_16_to_8");
2381
2382
if (row_info->bit_depth == 16)
2383
{
2384
png_bytep sp = row; /* source */
2385
png_bytep dp = row; /* destination */
2386
png_bytep ep = sp + row_info->rowbytes; /* end+1 */
2387
2388
while (sp < ep)
2389
{
2390
/* The input is an array of 16-bit components, these must be scaled to
2391
* 8 bits each. For a 16-bit value V the required value (from the PNG
2392
* specification) is:
2393
*
2394
* (V * 255) / 65535
2395
*
2396
* This reduces to round(V / 257), or floor((V + 128.5)/257)
2397
*
2398
* Represent V as the two byte value vhi.vlo. Make a guess that the
2399
* result is the top byte of V, vhi, then the correction to this value
2400
* is:
2401
*
2402
* error = floor(((V-vhi.vhi) + 128.5) / 257)
2403
* = floor(((vlo-vhi) + 128.5) / 257)
2404
*
2405
* This can be approximated using integer arithmetic (and a signed
2406
* shift):
2407
*
2408
* error = (vlo-vhi+128) >> 8;
2409
*
2410
* The approximate differs from the exact answer only when (vlo-vhi) is
2411
* 128; it then gives a correction of +1 when the exact correction is
2412
* 0. This gives 128 errors. The exact answer (correct for all 16-bit
2413
* input values) is:
2414
*
2415
* error = (vlo-vhi+128)*65535 >> 24;
2416
*
2417
* An alternative arithmetic calculation which also gives no errors is:
2418
*
2419
* (V * 255 + 32895) >> 16
2420
*/
2421
2422
png_int_32 tmp = *sp++; /* must be signed! */
2423
tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24;
2424
*dp++ = (png_byte)tmp;
2425
}
2426
2427
row_info->bit_depth = 8;
2428
row_info->pixel_depth = (png_byte)(8 * row_info->channels);
2429
row_info->rowbytes = row_info->width * row_info->channels;
2430
}
2431
}
2432
#endif
2433
2434
#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
2435
static void
2436
/* Simply discard the low byte. This was the default behavior prior
2437
* to libpng-1.5.4.
2438
*/
2439
png_do_chop(png_row_infop row_info, png_bytep row)
2440
{
2441
png_debug(1, "in png_do_chop");
2442
2443
if (row_info->bit_depth == 16)
2444
{
2445
png_bytep sp = row; /* source */
2446
png_bytep dp = row; /* destination */
2447
png_bytep ep = sp + row_info->rowbytes; /* end+1 */
2448
2449
while (sp < ep)
2450
{
2451
*dp++ = *sp;
2452
sp += 2; /* skip low byte */
2453
}
2454
2455
row_info->bit_depth = 8;
2456
row_info->pixel_depth = (png_byte)(8 * row_info->channels);
2457
row_info->rowbytes = row_info->width * row_info->channels;
2458
}
2459
}
2460
#endif
2461
2462
#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
2463
static void
2464
png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
2465
{
2466
png_debug(1, "in png_do_read_swap_alpha");
2467
2468
{
2469
png_uint_32 row_width = row_info->width;
2470
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
2471
{
2472
/* This converts from RGBA to ARGB */
2473
if (row_info->bit_depth == 8)
2474
{
2475
png_bytep sp = row + row_info->rowbytes;
2476
png_bytep dp = sp;
2477
png_byte save;
2478
png_uint_32 i;
2479
2480
for (i = 0; i < row_width; i++)
2481
{
2482
save = *(--sp);
2483
*(--dp) = *(--sp);
2484
*(--dp) = *(--sp);
2485
*(--dp) = *(--sp);
2486
*(--dp) = save;
2487
}
2488
}
2489
2490
#ifdef PNG_READ_16BIT_SUPPORTED
2491
/* This converts from RRGGBBAA to AARRGGBB */
2492
else
2493
{
2494
png_bytep sp = row + row_info->rowbytes;
2495
png_bytep dp = sp;
2496
png_byte save[2];
2497
png_uint_32 i;
2498
2499
for (i = 0; i < row_width; i++)
2500
{
2501
save[0] = *(--sp);
2502
save[1] = *(--sp);
2503
*(--dp) = *(--sp);
2504
*(--dp) = *(--sp);
2505
*(--dp) = *(--sp);
2506
*(--dp) = *(--sp);
2507
*(--dp) = *(--sp);
2508
*(--dp) = *(--sp);
2509
*(--dp) = save[0];
2510
*(--dp) = save[1];
2511
}
2512
}
2513
#endif
2514
}
2515
2516
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2517
{
2518
/* This converts from GA to AG */
2519
if (row_info->bit_depth == 8)
2520
{
2521
png_bytep sp = row + row_info->rowbytes;
2522
png_bytep dp = sp;
2523
png_byte save;
2524
png_uint_32 i;
2525
2526
for (i = 0; i < row_width; i++)
2527
{
2528
save = *(--sp);
2529
*(--dp) = *(--sp);
2530
*(--dp) = save;
2531
}
2532
}
2533
2534
#ifdef PNG_READ_16BIT_SUPPORTED
2535
/* This converts from GGAA to AAGG */
2536
else
2537
{
2538
png_bytep sp = row + row_info->rowbytes;
2539
png_bytep dp = sp;
2540
png_byte save[2];
2541
png_uint_32 i;
2542
2543
for (i = 0; i < row_width; i++)
2544
{
2545
save[0] = *(--sp);
2546
save[1] = *(--sp);
2547
*(--dp) = *(--sp);
2548
*(--dp) = *(--sp);
2549
*(--dp) = save[0];
2550
*(--dp) = save[1];
2551
}
2552
}
2553
#endif
2554
}
2555
}
2556
}
2557
#endif
2558
2559
#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
2560
static void
2561
png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
2562
{
2563
png_uint_32 row_width;
2564
png_debug(1, "in png_do_read_invert_alpha");
2565
2566
row_width = row_info->width;
2567
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
2568
{
2569
if (row_info->bit_depth == 8)
2570
{
2571
/* This inverts the alpha channel in RGBA */
2572
png_bytep sp = row + row_info->rowbytes;
2573
png_bytep dp = sp;
2574
png_uint_32 i;
2575
2576
for (i = 0; i < row_width; i++)
2577
{
2578
*(--dp) = (png_byte)(255 - *(--sp));
2579
2580
/* This does nothing:
2581
*(--dp) = *(--sp);
2582
*(--dp) = *(--sp);
2583
*(--dp) = *(--sp);
2584
We can replace it with:
2585
*/
2586
sp-=3;
2587
dp=sp;
2588
}
2589
}
2590
2591
#ifdef PNG_READ_16BIT_SUPPORTED
2592
/* This inverts the alpha channel in RRGGBBAA */
2593
else
2594
{
2595
png_bytep sp = row + row_info->rowbytes;
2596
png_bytep dp = sp;
2597
png_uint_32 i;
2598
2599
for (i = 0; i < row_width; i++)
2600
{
2601
*(--dp) = (png_byte)(255 - *(--sp));
2602
*(--dp) = (png_byte)(255 - *(--sp));
2603
2604
/* This does nothing:
2605
*(--dp) = *(--sp);
2606
*(--dp) = *(--sp);
2607
*(--dp) = *(--sp);
2608
*(--dp) = *(--sp);
2609
*(--dp) = *(--sp);
2610
*(--dp) = *(--sp);
2611
We can replace it with:
2612
*/
2613
sp-=6;
2614
dp=sp;
2615
}
2616
}
2617
#endif
2618
}
2619
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2620
{
2621
if (row_info->bit_depth == 8)
2622
{
2623
/* This inverts the alpha channel in GA */
2624
png_bytep sp = row + row_info->rowbytes;
2625
png_bytep dp = sp;
2626
png_uint_32 i;
2627
2628
for (i = 0; i < row_width; i++)
2629
{
2630
*(--dp) = (png_byte)(255 - *(--sp));
2631
*(--dp) = *(--sp);
2632
}
2633
}
2634
2635
#ifdef PNG_READ_16BIT_SUPPORTED
2636
else
2637
{
2638
/* This inverts the alpha channel in GGAA */
2639
png_bytep sp = row + row_info->rowbytes;
2640
png_bytep dp = sp;
2641
png_uint_32 i;
2642
2643
for (i = 0; i < row_width; i++)
2644
{
2645
*(--dp) = (png_byte)(255 - *(--sp));
2646
*(--dp) = (png_byte)(255 - *(--sp));
2647
/*
2648
*(--dp) = *(--sp);
2649
*(--dp) = *(--sp);
2650
*/
2651
sp-=2;
2652
dp=sp;
2653
}
2654
}
2655
#endif
2656
}
2657
}
2658
#endif
2659
2660
#ifdef PNG_READ_FILLER_SUPPORTED
2661
/* Add filler channel if we have RGB color */
2662
static void
2663
png_do_read_filler(png_row_infop row_info, png_bytep row,
2664
png_uint_32 filler, png_uint_32 flags)
2665
{
2666
png_uint_32 i;
2667
png_uint_32 row_width = row_info->width;
2668
2669
#ifdef PNG_READ_16BIT_SUPPORTED
2670
png_byte hi_filler = (png_byte)(filler>>8);
2671
#endif
2672
png_byte lo_filler = (png_byte)filler;
2673
2674
png_debug(1, "in png_do_read_filler");
2675
2676
if (
2677
row_info->color_type == PNG_COLOR_TYPE_GRAY)
2678
{
2679
if (row_info->bit_depth == 8)
2680
{
2681
if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
2682
{
2683
/* This changes the data from G to GX */
2684
png_bytep sp = row + (png_size_t)row_width;
2685
png_bytep dp = sp + (png_size_t)row_width;
2686
for (i = 1; i < row_width; i++)
2687
{
2688
*(--dp) = lo_filler;
2689
*(--dp) = *(--sp);
2690
}
2691
*(--dp) = lo_filler;
2692
row_info->channels = 2;
2693
row_info->pixel_depth = 16;
2694
row_info->rowbytes = row_width * 2;
2695
}
2696
2697
else
2698
{
2699
/* This changes the data from G to XG */
2700
png_bytep sp = row + (png_size_t)row_width;
2701
png_bytep dp = sp + (png_size_t)row_width;
2702
for (i = 0; i < row_width; i++)
2703
{
2704
*(--dp) = *(--sp);
2705
*(--dp) = lo_filler;
2706
}
2707
row_info->channels = 2;
2708
row_info->pixel_depth = 16;
2709
row_info->rowbytes = row_width * 2;
2710
}
2711
}
2712
2713
#ifdef PNG_READ_16BIT_SUPPORTED
2714
else if (row_info->bit_depth == 16)
2715
{
2716
if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
2717
{
2718
/* This changes the data from GG to GGXX */
2719
png_bytep sp = row + (png_size_t)row_width * 2;
2720
png_bytep dp = sp + (png_size_t)row_width * 2;
2721
for (i = 1; i < row_width; i++)
2722
{
2723
*(--dp) = lo_filler;
2724
*(--dp) = hi_filler;
2725
*(--dp) = *(--sp);
2726
*(--dp) = *(--sp);
2727
}
2728
*(--dp) = lo_filler;
2729
*(--dp) = hi_filler;
2730
row_info->channels = 2;
2731
row_info->pixel_depth = 32;
2732
row_info->rowbytes = row_width * 4;
2733
}
2734
2735
else
2736
{
2737
/* This changes the data from GG to XXGG */
2738
png_bytep sp = row + (png_size_t)row_width * 2;
2739
png_bytep dp = sp + (png_size_t)row_width * 2;
2740
for (i = 0; i < row_width; i++)
2741
{
2742
*(--dp) = *(--sp);
2743
*(--dp) = *(--sp);
2744
*(--dp) = lo_filler;
2745
*(--dp) = hi_filler;
2746
}
2747
row_info->channels = 2;
2748
row_info->pixel_depth = 32;
2749
row_info->rowbytes = row_width * 4;
2750
}
2751
}
2752
#endif
2753
} /* COLOR_TYPE == GRAY */
2754
else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
2755
{
2756
if (row_info->bit_depth == 8)
2757
{
2758
if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
2759
{
2760
/* This changes the data from RGB to RGBX */
2761
png_bytep sp = row + (png_size_t)row_width * 3;
2762
png_bytep dp = sp + (png_size_t)row_width;
2763
for (i = 1; i < row_width; i++)
2764
{
2765
*(--dp) = lo_filler;
2766
*(--dp) = *(--sp);
2767
*(--dp) = *(--sp);
2768
*(--dp) = *(--sp);
2769
}
2770
*(--dp) = lo_filler;
2771
row_info->channels = 4;
2772
row_info->pixel_depth = 32;
2773
row_info->rowbytes = row_width * 4;
2774
}
2775
2776
else
2777
{
2778
/* This changes the data from RGB to XRGB */
2779
png_bytep sp = row + (png_size_t)row_width * 3;
2780
png_bytep dp = sp + (png_size_t)row_width;
2781
for (i = 0; i < row_width; i++)
2782
{
2783
*(--dp) = *(--sp);
2784
*(--dp) = *(--sp);
2785
*(--dp) = *(--sp);
2786
*(--dp) = lo_filler;
2787
}
2788
row_info->channels = 4;
2789
row_info->pixel_depth = 32;
2790
row_info->rowbytes = row_width * 4;
2791
}
2792
}
2793
2794
#ifdef PNG_READ_16BIT_SUPPORTED
2795
else if (row_info->bit_depth == 16)
2796
{
2797
if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
2798
{
2799
/* This changes the data from RRGGBB to RRGGBBXX */
2800
png_bytep sp = row + (png_size_t)row_width * 6;
2801
png_bytep dp = sp + (png_size_t)row_width * 2;
2802
for (i = 1; i < row_width; i++)
2803
{
2804
*(--dp) = lo_filler;
2805
*(--dp) = hi_filler;
2806
*(--dp) = *(--sp);
2807
*(--dp) = *(--sp);
2808
*(--dp) = *(--sp);
2809
*(--dp) = *(--sp);
2810
*(--dp) = *(--sp);
2811
*(--dp) = *(--sp);
2812
}
2813
*(--dp) = lo_filler;
2814
*(--dp) = hi_filler;
2815
row_info->channels = 4;
2816
row_info->pixel_depth = 64;
2817
row_info->rowbytes = row_width * 8;
2818
}
2819
2820
else
2821
{
2822
/* This changes the data from RRGGBB to XXRRGGBB */
2823
png_bytep sp = row + (png_size_t)row_width * 6;
2824
png_bytep dp = sp + (png_size_t)row_width * 2;
2825
for (i = 0; i < row_width; i++)
2826
{
2827
*(--dp) = *(--sp);
2828
*(--dp) = *(--sp);
2829
*(--dp) = *(--sp);
2830
*(--dp) = *(--sp);
2831
*(--dp) = *(--sp);
2832
*(--dp) = *(--sp);
2833
*(--dp) = lo_filler;
2834
*(--dp) = hi_filler;
2835
}
2836
2837
row_info->channels = 4;
2838
row_info->pixel_depth = 64;
2839
row_info->rowbytes = row_width * 8;
2840
}
2841
}
2842
#endif
2843
} /* COLOR_TYPE == RGB */
2844
}
2845
#endif
2846
2847
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
2848
/* Expand grayscale files to RGB, with or without alpha */
2849
static void
2850
png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
2851
{
2852
png_uint_32 i;
2853
png_uint_32 row_width = row_info->width;
2854
2855
png_debug(1, "in png_do_gray_to_rgb");
2856
2857
if (row_info->bit_depth >= 8 &&
2858
(row_info->color_type & PNG_COLOR_MASK_COLOR) == 0)
2859
{
2860
if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
2861
{
2862
if (row_info->bit_depth == 8)
2863
{
2864
/* This changes G to RGB */
2865
png_bytep sp = row + (png_size_t)row_width - 1;
2866
png_bytep dp = sp + (png_size_t)row_width * 2;
2867
for (i = 0; i < row_width; i++)
2868
{
2869
*(dp--) = *sp;
2870
*(dp--) = *sp;
2871
*(dp--) = *(sp--);
2872
}
2873
}
2874
2875
else
2876
{
2877
/* This changes GG to RRGGBB */
2878
png_bytep sp = row + (png_size_t)row_width * 2 - 1;
2879
png_bytep dp = sp + (png_size_t)row_width * 4;
2880
for (i = 0; i < row_width; i++)
2881
{
2882
*(dp--) = *sp;
2883
*(dp--) = *(sp - 1);
2884
*(dp--) = *sp;
2885
*(dp--) = *(sp - 1);
2886
*(dp--) = *(sp--);
2887
*(dp--) = *(sp--);
2888
}
2889
}
2890
}
2891
2892
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2893
{
2894
if (row_info->bit_depth == 8)
2895
{
2896
/* This changes GA to RGBA */
2897
png_bytep sp = row + (png_size_t)row_width * 2 - 1;
2898
png_bytep dp = sp + (png_size_t)row_width * 2;
2899
for (i = 0; i < row_width; i++)
2900
{
2901
*(dp--) = *(sp--);
2902
*(dp--) = *sp;
2903
*(dp--) = *sp;
2904
*(dp--) = *(sp--);
2905
}
2906
}
2907
2908
else
2909
{
2910
/* This changes GGAA to RRGGBBAA */
2911
png_bytep sp = row + (png_size_t)row_width * 4 - 1;
2912
png_bytep dp = sp + (png_size_t)row_width * 4;
2913
for (i = 0; i < row_width; i++)
2914
{
2915
*(dp--) = *(sp--);
2916
*(dp--) = *(sp--);
2917
*(dp--) = *sp;
2918
*(dp--) = *(sp - 1);
2919
*(dp--) = *sp;
2920
*(dp--) = *(sp - 1);
2921
*(dp--) = *(sp--);
2922
*(dp--) = *(sp--);
2923
}
2924
}
2925
}
2926
row_info->channels = (png_byte)(row_info->channels + 2);
2927
row_info->color_type |= PNG_COLOR_MASK_COLOR;
2928
row_info->pixel_depth = (png_byte)(row_info->channels *
2929
row_info->bit_depth);
2930
row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
2931
}
2932
}
2933
#endif
2934
2935
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
2936
/* Reduce RGB files to grayscale, with or without alpha
2937
* using the equation given in Poynton's ColorFAQ of 1998-01-04 at
2938
* <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008 but
2939
* versions dated 1998 through November 2002 have been archived at
2940
* https://web.archive.org/web/20000816232553/www.inforamp.net/
2941
* ~poynton/notes/colour_and_gamma/ColorFAQ.txt )
2942
* Charles Poynton poynton at poynton.com
2943
*
2944
* Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
2945
*
2946
* which can be expressed with integers as
2947
*
2948
* Y = (6969 * R + 23434 * G + 2365 * B)/32768
2949
*
2950
* Poynton's current link (as of January 2003 through July 2011):
2951
* <http://www.poynton.com/notes/colour_and_gamma/>
2952
* has changed the numbers slightly:
2953
*
2954
* Y = 0.2126*R + 0.7152*G + 0.0722*B
2955
*
2956
* which can be expressed with integers as
2957
*
2958
* Y = (6966 * R + 23436 * G + 2366 * B)/32768
2959
*
2960
* Historically, however, libpng uses numbers derived from the ITU-R Rec 709
2961
* end point chromaticities and the D65 white point. Depending on the
2962
* precision used for the D65 white point this produces a variety of different
2963
* numbers, however if the four decimal place value used in ITU-R Rec 709 is
2964
* used (0.3127,0.3290) the Y calculation would be:
2965
*
2966
* Y = (6968 * R + 23435 * G + 2366 * B)/32768
2967
*
2968
* While this is correct the rounding results in an overflow for white, because
2969
* the sum of the rounded coefficients is 32769, not 32768. Consequently
2970
* libpng uses, instead, the closest non-overflowing approximation:
2971
*
2972
* Y = (6968 * R + 23434 * G + 2366 * B)/32768
2973
*
2974
* Starting with libpng-1.5.5, if the image being converted has a cHRM chunk
2975
* (including an sRGB chunk) then the chromaticities are used to calculate the
2976
* coefficients. See the chunk handling in pngrutil.c for more information.
2977
*
2978
* In all cases the calculation is to be done in a linear colorspace. If no
2979
* gamma information is available to correct the encoding of the original RGB
2980
* values this results in an implicit assumption that the original PNG RGB
2981
* values were linear.
2982
*
2983
* Other integer coefficents can be used via png_set_rgb_to_gray(). Because
2984
* the API takes just red and green coefficients the blue coefficient is
2985
* calculated to make the sum 32768. This will result in different rounding
2986
* to that used above.
2987
*/
2988
static int
2989
png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
2990
2991
{
2992
int rgb_error = 0;
2993
2994
png_debug(1, "in png_do_rgb_to_gray");
2995
2996
if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 &&
2997
(row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
2998
{
2999
PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
3000
PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
3001
PNG_CONST png_uint_32 bc = 32768 - rc - gc;
3002
PNG_CONST png_uint_32 row_width = row_info->width;
3003
PNG_CONST int have_alpha =
3004
(row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0;
3005
3006
if (row_info->bit_depth == 8)
3007
{
3008
#ifdef PNG_READ_GAMMA_SUPPORTED
3009
/* Notice that gamma to/from 1 are not necessarily inverses (if
3010
* there is an overall gamma correction). Prior to 1.5.5 this code
3011
* checked the linearized values for equality; this doesn't match
3012
* the documentation, the original values must be checked.
3013
*/
3014
if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
3015
{
3016
png_bytep sp = row;
3017
png_bytep dp = row;
3018
png_uint_32 i;
3019
3020
for (i = 0; i < row_width; i++)
3021
{
3022
png_byte red = *(sp++);
3023
png_byte green = *(sp++);
3024
png_byte blue = *(sp++);
3025
3026
if (red != green || red != blue)
3027
{
3028
red = png_ptr->gamma_to_1[red];
3029
green = png_ptr->gamma_to_1[green];
3030
blue = png_ptr->gamma_to_1[blue];
3031
3032
rgb_error |= 1;
3033
*(dp++) = png_ptr->gamma_from_1[
3034
(rc*red + gc*green + bc*blue + 16384)>>15];
3035
}
3036
3037
else
3038
{
3039
/* If there is no overall correction the table will not be
3040
* set.
3041
*/
3042
if (png_ptr->gamma_table != NULL)
3043
red = png_ptr->gamma_table[red];
3044
3045
*(dp++) = red;
3046
}
3047
3048
if (have_alpha != 0)
3049
*(dp++) = *(sp++);
3050
}
3051
}
3052
else
3053
#endif
3054
{
3055
png_bytep sp = row;
3056
png_bytep dp = row;
3057
png_uint_32 i;
3058
3059
for (i = 0; i < row_width; i++)
3060
{
3061
png_byte red = *(sp++);
3062
png_byte green = *(sp++);
3063
png_byte blue = *(sp++);
3064
3065
if (red != green || red != blue)
3066
{
3067
rgb_error |= 1;
3068
/* NOTE: this is the historical approach which simply
3069
* truncates the results.
3070
*/
3071
*(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
3072
}
3073
3074
else
3075
*(dp++) = red;
3076
3077
if (have_alpha != 0)
3078
*(dp++) = *(sp++);
3079
}
3080
}
3081
}
3082
3083
else /* RGB bit_depth == 16 */
3084
{
3085
#ifdef PNG_READ_GAMMA_SUPPORTED
3086
if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL)
3087
{
3088
png_bytep sp = row;
3089
png_bytep dp = row;
3090
png_uint_32 i;
3091
3092
for (i = 0; i < row_width; i++)
3093
{
3094
png_uint_16 red, green, blue, w;
3095
png_byte hi,lo;
3096
3097
hi=*(sp)++; lo=*(sp)++; red = (png_uint_16)((hi << 8) | (lo));
3098
hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo));
3099
hi=*(sp)++; lo=*(sp)++; blue = (png_uint_16)((hi << 8) | (lo));
3100
3101
if (red == green && red == blue)
3102
{
3103
if (png_ptr->gamma_16_table != NULL)
3104
w = png_ptr->gamma_16_table[(red & 0xff)
3105
>> png_ptr->gamma_shift][red >> 8];
3106
3107
else
3108
w = red;
3109
}
3110
3111
else
3112
{
3113
png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red & 0xff)
3114
>> png_ptr->gamma_shift][red>>8];
3115
png_uint_16 green_1 =
3116
png_ptr->gamma_16_to_1[(green & 0xff) >>
3117
png_ptr->gamma_shift][green>>8];
3118
png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue & 0xff)
3119
>> png_ptr->gamma_shift][blue>>8];
3120
png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1
3121
+ bc*blue_1 + 16384)>>15);
3122
w = png_ptr->gamma_16_from_1[(gray16 & 0xff) >>
3123
png_ptr->gamma_shift][gray16 >> 8];
3124
rgb_error |= 1;
3125
}
3126
3127
*(dp++) = (png_byte)((w>>8) & 0xff);
3128
*(dp++) = (png_byte)(w & 0xff);
3129
3130
if (have_alpha != 0)
3131
{
3132
*(dp++) = *(sp++);
3133
*(dp++) = *(sp++);
3134
}
3135
}
3136
}
3137
else
3138
#endif
3139
{
3140
png_bytep sp = row;
3141
png_bytep dp = row;
3142
png_uint_32 i;
3143
3144
for (i = 0; i < row_width; i++)
3145
{
3146
png_uint_16 red, green, blue, gray16;
3147
png_byte hi,lo;
3148
3149
hi=*(sp)++; lo=*(sp)++; red = (png_uint_16)((hi << 8) | (lo));
3150
hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo));
3151
hi=*(sp)++; lo=*(sp)++; blue = (png_uint_16)((hi << 8) | (lo));
3152
3153
if (red != green || red != blue)
3154
rgb_error |= 1;
3155
3156
/* From 1.5.5 in the 16-bit case do the accurate conversion even
3157
* in the 'fast' case - this is because this is where the code
3158
* ends up when handling linear 16-bit data.
3159
*/
3160
gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >>
3161
15);
3162
*(dp++) = (png_byte)((gray16 >> 8) & 0xff);
3163
*(dp++) = (png_byte)(gray16 & 0xff);
3164
3165
if (have_alpha != 0)
3166
{
3167
*(dp++) = *(sp++);
3168
*(dp++) = *(sp++);
3169
}
3170
}
3171
}
3172
}
3173
3174
row_info->channels = (png_byte)(row_info->channels - 2);
3175
row_info->color_type = (png_byte)(row_info->color_type &
3176
~PNG_COLOR_MASK_COLOR);
3177
row_info->pixel_depth = (png_byte)(row_info->channels *
3178
row_info->bit_depth);
3179
row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
3180
}
3181
return rgb_error;
3182
}
3183
#endif
3184
3185
#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
3186
defined(PNG_READ_ALPHA_MODE_SUPPORTED)
3187
/* Replace any alpha or transparency with the supplied background color.
3188
* "background" is already in the screen gamma, while "background_1" is
3189
* at a gamma of 1.0. Paletted files have already been taken care of.
3190
*/
3191
static void
3192
png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
3193
{
3194
#ifdef PNG_READ_GAMMA_SUPPORTED
3195
png_const_bytep gamma_table = png_ptr->gamma_table;
3196
png_const_bytep gamma_from_1 = png_ptr->gamma_from_1;
3197
png_const_bytep gamma_to_1 = png_ptr->gamma_to_1;
3198
png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table;
3199
png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1;
3200
png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1;
3201
int gamma_shift = png_ptr->gamma_shift;
3202
int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0;
3203
#endif
3204
3205
png_bytep sp;
3206
png_uint_32 i;
3207
png_uint_32 row_width = row_info->width;
3208
int shift;
3209
3210
png_debug(1, "in png_do_compose");
3211
3212
{
3213
switch (row_info->color_type)
3214
{
3215
case PNG_COLOR_TYPE_GRAY:
3216
{
3217
switch (row_info->bit_depth)
3218
{
3219
case 1:
3220
{
3221
sp = row;
3222
shift = 7;
3223
for (i = 0; i < row_width; i++)
3224
{
3225
if ((png_uint_16)((*sp >> shift) & 0x01)
3226
== png_ptr->trans_color.gray)
3227
{
3228
unsigned int tmp = *sp & (0x7f7f >> (7 - shift));
3229
tmp |=
3230
(unsigned int)(png_ptr->background.gray << shift);
3231
*sp = (png_byte)(tmp & 0xff);
3232
}
3233
3234
if (shift == 0)
3235
{
3236
shift = 7;
3237
sp++;
3238
}
3239
3240
else
3241
shift--;
3242
}
3243
break;
3244
}
3245
3246
case 2:
3247
{
3248
#ifdef PNG_READ_GAMMA_SUPPORTED
3249
if (gamma_table != NULL)
3250
{
3251
sp = row;
3252
shift = 6;
3253
for (i = 0; i < row_width; i++)
3254
{
3255
if ((png_uint_16)((*sp >> shift) & 0x03)
3256
== png_ptr->trans_color.gray)
3257
{
3258
unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
3259
tmp |=
3260
(unsigned int)png_ptr->background.gray << shift;
3261
*sp = (png_byte)(tmp & 0xff);
3262
}
3263
3264
else
3265
{
3266
unsigned int p = (*sp >> shift) & 0x03;
3267
unsigned int g = (gamma_table [p | (p << 2) |
3268
(p << 4) | (p << 6)] >> 6) & 0x03;
3269
unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
3270
tmp |= (unsigned int)(g << shift);
3271
*sp = (png_byte)(tmp & 0xff);
3272
}
3273
3274
if (shift == 0)
3275
{
3276
shift = 6;
3277
sp++;
3278
}
3279
3280
else
3281
shift -= 2;
3282
}
3283
}
3284
3285
else
3286
#endif
3287
{
3288
sp = row;
3289
shift = 6;
3290
for (i = 0; i < row_width; i++)
3291
{
3292
if ((png_uint_16)((*sp >> shift) & 0x03)
3293
== png_ptr->trans_color.gray)
3294
{
3295
unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
3296
tmp |=
3297
(unsigned int)png_ptr->background.gray << shift;
3298
*sp = (png_byte)(tmp & 0xff);
3299
}
3300
3301
if (shift == 0)
3302
{
3303
shift = 6;
3304
sp++;
3305
}
3306
3307
else
3308
shift -= 2;
3309
}
3310
}
3311
break;
3312
}
3313
3314
case 4:
3315
{
3316
#ifdef PNG_READ_GAMMA_SUPPORTED
3317
if (gamma_table != NULL)
3318
{
3319
sp = row;
3320
shift = 4;
3321
for (i = 0; i < row_width; i++)
3322
{
3323
if ((png_uint_16)((*sp >> shift) & 0x0f)
3324
== png_ptr->trans_color.gray)
3325
{
3326
unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
3327
tmp |=
3328
(unsigned int)(png_ptr->background.gray << shift);
3329
*sp = (png_byte)(tmp & 0xff);
3330
}
3331
3332
else
3333
{
3334
unsigned int p = (*sp >> shift) & 0x0f;
3335
unsigned int g = (gamma_table[p | (p << 4)] >> 4) &
3336
0x0f;
3337
unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
3338
tmp |= (unsigned int)(g << shift);
3339
*sp = (png_byte)(tmp & 0xff);
3340
}
3341
3342
if (shift == 0)
3343
{
3344
shift = 4;
3345
sp++;
3346
}
3347
3348
else
3349
shift -= 4;
3350
}
3351
}
3352
3353
else
3354
#endif
3355
{
3356
sp = row;
3357
shift = 4;
3358
for (i = 0; i < row_width; i++)
3359
{
3360
if ((png_uint_16)((*sp >> shift) & 0x0f)
3361
== png_ptr->trans_color.gray)
3362
{
3363
unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
3364
tmp |=
3365
(unsigned int)(png_ptr->background.gray << shift);
3366
*sp = (png_byte)(tmp & 0xff);
3367
}
3368
3369
if (shift == 0)
3370
{
3371
shift = 4;
3372
sp++;
3373
}
3374
3375
else
3376
shift -= 4;
3377
}
3378
}
3379
break;
3380
}
3381
3382
case 8:
3383
{
3384
#ifdef PNG_READ_GAMMA_SUPPORTED
3385
if (gamma_table != NULL)
3386
{
3387
sp = row;
3388
for (i = 0; i < row_width; i++, sp++)
3389
{
3390
if (*sp == png_ptr->trans_color.gray)
3391
*sp = (png_byte)png_ptr->background.gray;
3392
3393
else
3394
*sp = gamma_table[*sp];
3395
}
3396
}
3397
else
3398
#endif
3399
{
3400
sp = row;
3401
for (i = 0; i < row_width; i++, sp++)
3402
{
3403
if (*sp == png_ptr->trans_color.gray)
3404
*sp = (png_byte)png_ptr->background.gray;
3405
}
3406
}
3407
break;
3408
}
3409
3410
case 16:
3411
{
3412
#ifdef PNG_READ_GAMMA_SUPPORTED
3413
if (gamma_16 != NULL)
3414
{
3415
sp = row;
3416
for (i = 0; i < row_width; i++, sp += 2)
3417
{
3418
png_uint_16 v;
3419
3420
v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3421
3422
if (v == png_ptr->trans_color.gray)
3423
{
3424
/* Background is already in screen gamma */
3425
*sp = (png_byte)((png_ptr->background.gray >> 8)
3426
& 0xff);
3427
*(sp + 1) = (png_byte)(png_ptr->background.gray
3428
& 0xff);
3429
}
3430
3431
else
3432
{
3433
v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3434
*sp = (png_byte)((v >> 8) & 0xff);
3435
*(sp + 1) = (png_byte)(v & 0xff);
3436
}
3437
}
3438
}
3439
else
3440
#endif
3441
{
3442
sp = row;
3443
for (i = 0; i < row_width; i++, sp += 2)
3444
{
3445
png_uint_16 v;
3446
3447
v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3448
3449
if (v == png_ptr->trans_color.gray)
3450
{
3451
*sp = (png_byte)((png_ptr->background.gray >> 8)
3452
& 0xff);
3453
*(sp + 1) = (png_byte)(png_ptr->background.gray
3454
& 0xff);
3455
}
3456
}
3457
}
3458
break;
3459
}
3460
3461
default:
3462
break;
3463
}
3464
break;
3465
}
3466
3467
case PNG_COLOR_TYPE_RGB:
3468
{
3469
if (row_info->bit_depth == 8)
3470
{
3471
#ifdef PNG_READ_GAMMA_SUPPORTED
3472
if (gamma_table != NULL)
3473
{
3474
sp = row;
3475
for (i = 0; i < row_width; i++, sp += 3)
3476
{
3477
if (*sp == png_ptr->trans_color.red &&
3478
*(sp + 1) == png_ptr->trans_color.green &&
3479
*(sp + 2) == png_ptr->trans_color.blue)
3480
{
3481
*sp = (png_byte)png_ptr->background.red;
3482
*(sp + 1) = (png_byte)png_ptr->background.green;
3483
*(sp + 2) = (png_byte)png_ptr->background.blue;
3484
}
3485
3486
else
3487
{
3488
*sp = gamma_table[*sp];
3489
*(sp + 1) = gamma_table[*(sp + 1)];
3490
*(sp + 2) = gamma_table[*(sp + 2)];
3491
}
3492
}
3493
}
3494
else
3495
#endif
3496
{
3497
sp = row;
3498
for (i = 0; i < row_width; i++, sp += 3)
3499
{
3500
if (*sp == png_ptr->trans_color.red &&
3501
*(sp + 1) == png_ptr->trans_color.green &&
3502
*(sp + 2) == png_ptr->trans_color.blue)
3503
{
3504
*sp = (png_byte)png_ptr->background.red;
3505
*(sp + 1) = (png_byte)png_ptr->background.green;
3506
*(sp + 2) = (png_byte)png_ptr->background.blue;
3507
}
3508
}
3509
}
3510
}
3511
else /* if (row_info->bit_depth == 16) */
3512
{
3513
#ifdef PNG_READ_GAMMA_SUPPORTED
3514
if (gamma_16 != NULL)
3515
{
3516
sp = row;
3517
for (i = 0; i < row_width; i++, sp += 6)
3518
{
3519
png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3520
3521
png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
3522
+ *(sp + 3));
3523
3524
png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
3525
+ *(sp + 5));
3526
3527
if (r == png_ptr->trans_color.red &&
3528
g == png_ptr->trans_color.green &&
3529
b == png_ptr->trans_color.blue)
3530
{
3531
/* Background is already in screen gamma */
3532
*sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
3533
*(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
3534
*(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
3535
& 0xff);
3536
*(sp + 3) = (png_byte)(png_ptr->background.green
3537
& 0xff);
3538
*(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
3539
& 0xff);
3540
*(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
3541
}
3542
3543
else
3544
{
3545
png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3546
*sp = (png_byte)((v >> 8) & 0xff);
3547
*(sp + 1) = (png_byte)(v & 0xff);
3548
3549
v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
3550
*(sp + 2) = (png_byte)((v >> 8) & 0xff);
3551
*(sp + 3) = (png_byte)(v & 0xff);
3552
3553
v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
3554
*(sp + 4) = (png_byte)((v >> 8) & 0xff);
3555
*(sp + 5) = (png_byte)(v & 0xff);
3556
}
3557
}
3558
}
3559
3560
else
3561
#endif
3562
{
3563
sp = row;
3564
for (i = 0; i < row_width; i++, sp += 6)
3565
{
3566
png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3567
3568
png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
3569
+ *(sp + 3));
3570
3571
png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
3572
+ *(sp + 5));
3573
3574
if (r == png_ptr->trans_color.red &&
3575
g == png_ptr->trans_color.green &&
3576
b == png_ptr->trans_color.blue)
3577
{
3578
*sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
3579
*(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
3580
*(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
3581
& 0xff);
3582
*(sp + 3) = (png_byte)(png_ptr->background.green
3583
& 0xff);
3584
*(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
3585
& 0xff);
3586
*(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
3587
}
3588
}
3589
}
3590
}
3591
break;
3592
}
3593
3594
case PNG_COLOR_TYPE_GRAY_ALPHA:
3595
{
3596
if (row_info->bit_depth == 8)
3597
{
3598
#ifdef PNG_READ_GAMMA_SUPPORTED
3599
if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
3600
gamma_table != NULL)
3601
{
3602
sp = row;
3603
for (i = 0; i < row_width; i++, sp += 2)
3604
{
3605
png_uint_16 a = *(sp + 1);
3606
3607
if (a == 0xff)
3608
*sp = gamma_table[*sp];
3609
3610
else if (a == 0)
3611
{
3612
/* Background is already in screen gamma */
3613
*sp = (png_byte)png_ptr->background.gray;
3614
}
3615
3616
else
3617
{
3618
png_byte v, w;
3619
3620
v = gamma_to_1[*sp];
3621
png_composite(w, v, a, png_ptr->background_1.gray);
3622
if (optimize == 0)
3623
w = gamma_from_1[w];
3624
*sp = w;
3625
}
3626
}
3627
}
3628
else
3629
#endif
3630
{
3631
sp = row;
3632
for (i = 0; i < row_width; i++, sp += 2)
3633
{
3634
png_byte a = *(sp + 1);
3635
3636
if (a == 0)
3637
*sp = (png_byte)png_ptr->background.gray;
3638
3639
else if (a < 0xff)
3640
png_composite(*sp, *sp, a, png_ptr->background.gray);
3641
}
3642
}
3643
}
3644
else /* if (png_ptr->bit_depth == 16) */
3645
{
3646
#ifdef PNG_READ_GAMMA_SUPPORTED
3647
if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
3648
gamma_16_to_1 != NULL)
3649
{
3650
sp = row;
3651
for (i = 0; i < row_width; i++, sp += 4)
3652
{
3653
png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
3654
+ *(sp + 3));
3655
3656
if (a == (png_uint_16)0xffff)
3657
{
3658
png_uint_16 v;
3659
3660
v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3661
*sp = (png_byte)((v >> 8) & 0xff);
3662
*(sp + 1) = (png_byte)(v & 0xff);
3663
}
3664
3665
else if (a == 0)
3666
{
3667
/* Background is already in screen gamma */
3668
*sp = (png_byte)((png_ptr->background.gray >> 8)
3669
& 0xff);
3670
*(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
3671
}
3672
3673
else
3674
{
3675
png_uint_16 g, v, w;
3676
3677
g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
3678
png_composite_16(v, g, a, png_ptr->background_1.gray);
3679
if (optimize != 0)
3680
w = v;
3681
else
3682
w = gamma_16_from_1[(v & 0xff) >>
3683
gamma_shift][v >> 8];
3684
*sp = (png_byte)((w >> 8) & 0xff);
3685
*(sp + 1) = (png_byte)(w & 0xff);
3686
}
3687
}
3688
}
3689
else
3690
#endif
3691
{
3692
sp = row;
3693
for (i = 0; i < row_width; i++, sp += 4)
3694
{
3695
png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
3696
+ *(sp + 3));
3697
3698
if (a == 0)
3699
{
3700
*sp = (png_byte)((png_ptr->background.gray >> 8)
3701
& 0xff);
3702
*(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
3703
}
3704
3705
else if (a < 0xffff)
3706
{
3707
png_uint_16 g, v;
3708
3709
g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3710
png_composite_16(v, g, a, png_ptr->background.gray);
3711
*sp = (png_byte)((v >> 8) & 0xff);
3712
*(sp + 1) = (png_byte)(v & 0xff);
3713
}
3714
}
3715
}
3716
}
3717
break;
3718
}
3719
3720
case PNG_COLOR_TYPE_RGB_ALPHA:
3721
{
3722
if (row_info->bit_depth == 8)
3723
{
3724
#ifdef PNG_READ_GAMMA_SUPPORTED
3725
if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
3726
gamma_table != NULL)
3727
{
3728
sp = row;
3729
for (i = 0; i < row_width; i++, sp += 4)
3730
{
3731
png_byte a = *(sp + 3);
3732
3733
if (a == 0xff)
3734
{
3735
*sp = gamma_table[*sp];
3736
*(sp + 1) = gamma_table[*(sp + 1)];
3737
*(sp + 2) = gamma_table[*(sp + 2)];
3738
}
3739
3740
else if (a == 0)
3741
{
3742
/* Background is already in screen gamma */
3743
*sp = (png_byte)png_ptr->background.red;
3744
*(sp + 1) = (png_byte)png_ptr->background.green;
3745
*(sp + 2) = (png_byte)png_ptr->background.blue;
3746
}
3747
3748
else
3749
{
3750
png_byte v, w;
3751
3752
v = gamma_to_1[*sp];
3753
png_composite(w, v, a, png_ptr->background_1.red);
3754
if (optimize == 0) w = gamma_from_1[w];
3755
*sp = w;
3756
3757
v = gamma_to_1[*(sp + 1)];
3758
png_composite(w, v, a, png_ptr->background_1.green);
3759
if (optimize == 0) w = gamma_from_1[w];
3760
*(sp + 1) = w;
3761
3762
v = gamma_to_1[*(sp + 2)];
3763
png_composite(w, v, a, png_ptr->background_1.blue);
3764
if (optimize == 0) w = gamma_from_1[w];
3765
*(sp + 2) = w;
3766
}
3767
}
3768
}
3769
else
3770
#endif
3771
{
3772
sp = row;
3773
for (i = 0; i < row_width; i++, sp += 4)
3774
{
3775
png_byte a = *(sp + 3);
3776
3777
if (a == 0)
3778
{
3779
*sp = (png_byte)png_ptr->background.red;
3780
*(sp + 1) = (png_byte)png_ptr->background.green;
3781
*(sp + 2) = (png_byte)png_ptr->background.blue;
3782
}
3783
3784
else if (a < 0xff)
3785
{
3786
png_composite(*sp, *sp, a, png_ptr->background.red);
3787
3788
png_composite(*(sp + 1), *(sp + 1), a,
3789
png_ptr->background.green);
3790
3791
png_composite(*(sp + 2), *(sp + 2), a,
3792
png_ptr->background.blue);
3793
}
3794
}
3795
}
3796
}
3797
else /* if (row_info->bit_depth == 16) */
3798
{
3799
#ifdef PNG_READ_GAMMA_SUPPORTED
3800
if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
3801
gamma_16_to_1 != NULL)
3802
{
3803
sp = row;
3804
for (i = 0; i < row_width; i++, sp += 8)
3805
{
3806
png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
3807
<< 8) + (png_uint_16)(*(sp + 7)));
3808
3809
if (a == (png_uint_16)0xffff)
3810
{
3811
png_uint_16 v;
3812
3813
v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3814
*sp = (png_byte)((v >> 8) & 0xff);
3815
*(sp + 1) = (png_byte)(v & 0xff);
3816
3817
v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
3818
*(sp + 2) = (png_byte)((v >> 8) & 0xff);
3819
*(sp + 3) = (png_byte)(v & 0xff);
3820
3821
v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
3822
*(sp + 4) = (png_byte)((v >> 8) & 0xff);
3823
*(sp + 5) = (png_byte)(v & 0xff);
3824
}
3825
3826
else if (a == 0)
3827
{
3828
/* Background is already in screen gamma */
3829
*sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
3830
*(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
3831
*(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
3832
& 0xff);
3833
*(sp + 3) = (png_byte)(png_ptr->background.green
3834
& 0xff);
3835
*(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
3836
& 0xff);
3837
*(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
3838
}
3839
3840
else
3841
{
3842
png_uint_16 v, w;
3843
3844
v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
3845
png_composite_16(w, v, a, png_ptr->background_1.red);
3846
if (optimize == 0)
3847
w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
3848
8];
3849
*sp = (png_byte)((w >> 8) & 0xff);
3850
*(sp + 1) = (png_byte)(w & 0xff);
3851
3852
v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
3853
png_composite_16(w, v, a, png_ptr->background_1.green);
3854
if (optimize == 0)
3855
w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
3856
8];
3857
3858
*(sp + 2) = (png_byte)((w >> 8) & 0xff);
3859
*(sp + 3) = (png_byte)(w & 0xff);
3860
3861
v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
3862
png_composite_16(w, v, a, png_ptr->background_1.blue);
3863
if (optimize == 0)
3864
w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
3865
8];
3866
3867
*(sp + 4) = (png_byte)((w >> 8) & 0xff);
3868
*(sp + 5) = (png_byte)(w & 0xff);
3869
}
3870
}
3871
}
3872
3873
else
3874
#endif
3875
{
3876
sp = row;
3877
for (i = 0; i < row_width; i++, sp += 8)
3878
{
3879
png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
3880
<< 8) + (png_uint_16)(*(sp + 7)));
3881
3882
if (a == 0)
3883
{
3884
*sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
3885
*(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
3886
*(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
3887
& 0xff);
3888
*(sp + 3) = (png_byte)(png_ptr->background.green
3889
& 0xff);
3890
*(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
3891
& 0xff);
3892
*(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
3893
}
3894
3895
else if (a < 0xffff)
3896
{
3897
png_uint_16 v;
3898
3899
png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3900
png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
3901
+ *(sp + 3));
3902
png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
3903
+ *(sp + 5));
3904
3905
png_composite_16(v, r, a, png_ptr->background.red);
3906
*sp = (png_byte)((v >> 8) & 0xff);
3907
*(sp + 1) = (png_byte)(v & 0xff);
3908
3909
png_composite_16(v, g, a, png_ptr->background.green);
3910
*(sp + 2) = (png_byte)((v >> 8) & 0xff);
3911
*(sp + 3) = (png_byte)(v & 0xff);
3912
3913
png_composite_16(v, b, a, png_ptr->background.blue);
3914
*(sp + 4) = (png_byte)((v >> 8) & 0xff);
3915
*(sp + 5) = (png_byte)(v & 0xff);
3916
}
3917
}
3918
}
3919
}
3920
break;
3921
}
3922
3923
default:
3924
break;
3925
}
3926
}
3927
}
3928
#endif /* READ_BACKGROUND || READ_ALPHA_MODE */
3929
3930
#ifdef PNG_READ_GAMMA_SUPPORTED
3931
/* Gamma correct the image, avoiding the alpha channel. Make sure
3932
* you do this after you deal with the transparency issue on grayscale
3933
* or RGB images. If your bit depth is 8, use gamma_table, if it
3934
* is 16, use gamma_16_table and gamma_shift. Build these with
3935
* build_gamma_table().
3936
*/
3937
static void
3938
png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
3939
{
3940
png_const_bytep gamma_table = png_ptr->gamma_table;
3941
png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table;
3942
int gamma_shift = png_ptr->gamma_shift;
3943
3944
png_bytep sp;
3945
png_uint_32 i;
3946
png_uint_32 row_width=row_info->width;
3947
3948
png_debug(1, "in png_do_gamma");
3949
3950
if (((row_info->bit_depth <= 8 && gamma_table != NULL) ||
3951
(row_info->bit_depth == 16 && gamma_16_table != NULL)))
3952
{
3953
switch (row_info->color_type)
3954
{
3955
case PNG_COLOR_TYPE_RGB:
3956
{
3957
if (row_info->bit_depth == 8)
3958
{
3959
sp = row;
3960
for (i = 0; i < row_width; i++)
3961
{
3962
*sp = gamma_table[*sp];
3963
sp++;
3964
*sp = gamma_table[*sp];
3965
sp++;
3966
*sp = gamma_table[*sp];
3967
sp++;
3968
}
3969
}
3970
3971
else /* if (row_info->bit_depth == 16) */
3972
{
3973
sp = row;
3974
for (i = 0; i < row_width; i++)
3975
{
3976
png_uint_16 v;
3977
3978
v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3979
*sp = (png_byte)((v >> 8) & 0xff);
3980
*(sp + 1) = (png_byte)(v & 0xff);
3981
sp += 2;
3982
3983
v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3984
*sp = (png_byte)((v >> 8) & 0xff);
3985
*(sp + 1) = (png_byte)(v & 0xff);
3986
sp += 2;
3987
3988
v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3989
*sp = (png_byte)((v >> 8) & 0xff);
3990
*(sp + 1) = (png_byte)(v & 0xff);
3991
sp += 2;
3992
}
3993
}
3994
break;
3995
}
3996
3997
case PNG_COLOR_TYPE_RGB_ALPHA:
3998
{
3999
if (row_info->bit_depth == 8)
4000
{
4001
sp = row;
4002
for (i = 0; i < row_width; i++)
4003
{
4004
*sp = gamma_table[*sp];
4005
sp++;
4006
4007
*sp = gamma_table[*sp];
4008
sp++;
4009
4010
*sp = gamma_table[*sp];
4011
sp++;
4012
4013
sp++;
4014
}
4015
}
4016
4017
else /* if (row_info->bit_depth == 16) */
4018
{
4019
sp = row;
4020
for (i = 0; i < row_width; i++)
4021
{
4022
png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4023
*sp = (png_byte)((v >> 8) & 0xff);
4024
*(sp + 1) = (png_byte)(v & 0xff);
4025
sp += 2;
4026
4027
v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4028
*sp = (png_byte)((v >> 8) & 0xff);
4029
*(sp + 1) = (png_byte)(v & 0xff);
4030
sp += 2;
4031
4032
v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4033
*sp = (png_byte)((v >> 8) & 0xff);
4034
*(sp + 1) = (png_byte)(v & 0xff);
4035
sp += 4;
4036
}
4037
}
4038
break;
4039
}
4040
4041
case PNG_COLOR_TYPE_GRAY_ALPHA:
4042
{
4043
if (row_info->bit_depth == 8)
4044
{
4045
sp = row;
4046
for (i = 0; i < row_width; i++)
4047
{
4048
*sp = gamma_table[*sp];
4049
sp += 2;
4050
}
4051
}
4052
4053
else /* if (row_info->bit_depth == 16) */
4054
{
4055
sp = row;
4056
for (i = 0; i < row_width; i++)
4057
{
4058
png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4059
*sp = (png_byte)((v >> 8) & 0xff);
4060
*(sp + 1) = (png_byte)(v & 0xff);
4061
sp += 4;
4062
}
4063
}
4064
break;
4065
}
4066
4067
case PNG_COLOR_TYPE_GRAY:
4068
{
4069
if (row_info->bit_depth == 2)
4070
{
4071
sp = row;
4072
for (i = 0; i < row_width; i += 4)
4073
{
4074
int a = *sp & 0xc0;
4075
int b = *sp & 0x30;
4076
int c = *sp & 0x0c;
4077
int d = *sp & 0x03;
4078
4079
*sp = (png_byte)(
4080
((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)|
4081
((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
4082
((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
4083
((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
4084
sp++;
4085
}
4086
}
4087
4088
if (row_info->bit_depth == 4)
4089
{
4090
sp = row;
4091
for (i = 0; i < row_width; i += 2)
4092
{
4093
int msb = *sp & 0xf0;
4094
int lsb = *sp & 0x0f;
4095
4096
*sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
4097
| (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
4098
sp++;
4099
}
4100
}
4101
4102
else if (row_info->bit_depth == 8)
4103
{
4104
sp = row;
4105
for (i = 0; i < row_width; i++)
4106
{
4107
*sp = gamma_table[*sp];
4108
sp++;
4109
}
4110
}
4111
4112
else if (row_info->bit_depth == 16)
4113
{
4114
sp = row;
4115
for (i = 0; i < row_width; i++)
4116
{
4117
png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4118
*sp = (png_byte)((v >> 8) & 0xff);
4119
*(sp + 1) = (png_byte)(v & 0xff);
4120
sp += 2;
4121
}
4122
}
4123
break;
4124
}
4125
4126
default:
4127
break;
4128
}
4129
}
4130
}
4131
#endif
4132
4133
#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
4134
/* Encode the alpha channel to the output gamma (the input channel is always
4135
* linear.) Called only with color types that have an alpha channel. Needs the
4136
* from_1 tables.
4137
*/
4138
static void
4139
png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
4140
{
4141
png_uint_32 row_width = row_info->width;
4142
4143
png_debug(1, "in png_do_encode_alpha");
4144
4145
if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
4146
{
4147
if (row_info->bit_depth == 8)
4148
{
4149
PNG_CONST png_bytep table = png_ptr->gamma_from_1;
4150
4151
if (table != NULL)
4152
{
4153
PNG_CONST int step =
4154
(row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2;
4155
4156
/* The alpha channel is the last component: */
4157
row += step - 1;
4158
4159
for (; row_width > 0; --row_width, row += step)
4160
*row = table[*row];
4161
4162
return;
4163
}
4164
}
4165
4166
else if (row_info->bit_depth == 16)
4167
{
4168
PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1;
4169
PNG_CONST int gamma_shift = png_ptr->gamma_shift;
4170
4171
if (table != NULL)
4172
{
4173
PNG_CONST int step =
4174
(row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4;
4175
4176
/* The alpha channel is the last component: */
4177
row += step - 2;
4178
4179
for (; row_width > 0; --row_width, row += step)
4180
{
4181
png_uint_16 v;
4182
4183
v = table[*(row + 1) >> gamma_shift][*row];
4184
*row = (png_byte)((v >> 8) & 0xff);
4185
*(row + 1) = (png_byte)(v & 0xff);
4186
}
4187
4188
return;
4189
}
4190
}
4191
}
4192
4193
/* Only get to here if called with a weird row_info; no harm has been done,
4194
* so just issue a warning.
4195
*/
4196
png_warning(png_ptr, "png_do_encode_alpha: unexpected call");
4197
}
4198
#endif
4199
4200
#ifdef PNG_READ_EXPAND_SUPPORTED
4201
/* Expands a palette row to an RGB or RGBA row depending
4202
* upon whether you supply trans and num_trans.
4203
*/
4204
static void
4205
png_do_expand_palette(png_row_infop row_info, png_bytep row,
4206
png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)
4207
{
4208
int shift, value;
4209
png_bytep sp, dp;
4210
png_uint_32 i;
4211
png_uint_32 row_width=row_info->width;
4212
4213
png_debug(1, "in png_do_expand_palette");
4214
4215
if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
4216
{
4217
if (row_info->bit_depth < 8)
4218
{
4219
switch (row_info->bit_depth)
4220
{
4221
case 1:
4222
{
4223
sp = row + (png_size_t)((row_width - 1) >> 3);
4224
dp = row + (png_size_t)row_width - 1;
4225
shift = 7 - (int)((row_width + 7) & 0x07);
4226
for (i = 0; i < row_width; i++)
4227
{
4228
if ((*sp >> shift) & 0x01)
4229
*dp = 1;
4230
4231
else
4232
*dp = 0;
4233
4234
if (shift == 7)
4235
{
4236
shift = 0;
4237
sp--;
4238
}
4239
4240
else
4241
shift++;
4242
4243
dp--;
4244
}
4245
break;
4246
}
4247
4248
case 2:
4249
{
4250
sp = row + (png_size_t)((row_width - 1) >> 2);
4251
dp = row + (png_size_t)row_width - 1;
4252
shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
4253
for (i = 0; i < row_width; i++)
4254
{
4255
value = (*sp >> shift) & 0x03;
4256
*dp = (png_byte)value;
4257
if (shift == 6)
4258
{
4259
shift = 0;
4260
sp--;
4261
}
4262
4263
else
4264
shift += 2;
4265
4266
dp--;
4267
}
4268
break;
4269
}
4270
4271
case 4:
4272
{
4273
sp = row + (png_size_t)((row_width - 1) >> 1);
4274
dp = row + (png_size_t)row_width - 1;
4275
shift = (int)((row_width & 0x01) << 2);
4276
for (i = 0; i < row_width; i++)
4277
{
4278
value = (*sp >> shift) & 0x0f;
4279
*dp = (png_byte)value;
4280
if (shift == 4)
4281
{
4282
shift = 0;
4283
sp--;
4284
}
4285
4286
else
4287
shift += 4;
4288
4289
dp--;
4290
}
4291
break;
4292
}
4293
4294
default:
4295
break;
4296
}
4297
row_info->bit_depth = 8;
4298
row_info->pixel_depth = 8;
4299
row_info->rowbytes = row_width;
4300
}
4301
4302
if (row_info->bit_depth == 8)
4303
{
4304
{
4305
if (num_trans > 0)
4306
{
4307
sp = row + (png_size_t)row_width - 1;
4308
dp = row + ((png_size_t)row_width << 2) - 1;
4309
4310
for (i = 0; i < row_width; i++)
4311
{
4312
if ((int)(*sp) >= num_trans)
4313
*dp-- = 0xff;
4314
4315
else
4316
*dp-- = trans_alpha[*sp];
4317
4318
*dp-- = palette[*sp].blue;
4319
*dp-- = palette[*sp].green;
4320
*dp-- = palette[*sp].red;
4321
sp--;
4322
}
4323
row_info->bit_depth = 8;
4324
row_info->pixel_depth = 32;
4325
row_info->rowbytes = row_width * 4;
4326
row_info->color_type = 6;
4327
row_info->channels = 4;
4328
}
4329
4330
else
4331
{
4332
sp = row + (png_size_t)row_width - 1;
4333
dp = row + (png_size_t)(row_width * 3) - 1;
4334
4335
for (i = 0; i < row_width; i++)
4336
{
4337
*dp-- = palette[*sp].blue;
4338
*dp-- = palette[*sp].green;
4339
*dp-- = palette[*sp].red;
4340
sp--;
4341
}
4342
4343
row_info->bit_depth = 8;
4344
row_info->pixel_depth = 24;
4345
row_info->rowbytes = row_width * 3;
4346
row_info->color_type = 2;
4347
row_info->channels = 3;
4348
}
4349
}
4350
}
4351
}
4352
}
4353
4354
/* If the bit depth < 8, it is expanded to 8. Also, if the already
4355
* expanded transparency value is supplied, an alpha channel is built.
4356
*/
4357
static void
4358
png_do_expand(png_row_infop row_info, png_bytep row,
4359
png_const_color_16p trans_color)
4360
{
4361
int shift, value;
4362
png_bytep sp, dp;
4363
png_uint_32 i;
4364
png_uint_32 row_width=row_info->width;
4365
4366
png_debug(1, "in png_do_expand");
4367
4368
{
4369
if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
4370
{
4371
unsigned int gray = trans_color != NULL ? trans_color->gray : 0;
4372
4373
if (row_info->bit_depth < 8)
4374
{
4375
switch (row_info->bit_depth)
4376
{
4377
case 1:
4378
{
4379
gray = (gray & 0x01) * 0xff;
4380
sp = row + (png_size_t)((row_width - 1) >> 3);
4381
dp = row + (png_size_t)row_width - 1;
4382
shift = 7 - (int)((row_width + 7) & 0x07);
4383
for (i = 0; i < row_width; i++)
4384
{
4385
if ((*sp >> shift) & 0x01)
4386
*dp = 0xff;
4387
4388
else
4389
*dp = 0;
4390
4391
if (shift == 7)
4392
{
4393
shift = 0;
4394
sp--;
4395
}
4396
4397
else
4398
shift++;
4399
4400
dp--;
4401
}
4402
break;
4403
}
4404
4405
case 2:
4406
{
4407
gray = (gray & 0x03) * 0x55;
4408
sp = row + (png_size_t)((row_width - 1) >> 2);
4409
dp = row + (png_size_t)row_width - 1;
4410
shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
4411
for (i = 0; i < row_width; i++)
4412
{
4413
value = (*sp >> shift) & 0x03;
4414
*dp = (png_byte)(value | (value << 2) | (value << 4) |
4415
(value << 6));
4416
if (shift == 6)
4417
{
4418
shift = 0;
4419
sp--;
4420
}
4421
4422
else
4423
shift += 2;
4424
4425
dp--;
4426
}
4427
break;
4428
}
4429
4430
case 4:
4431
{
4432
gray = (gray & 0x0f) * 0x11;
4433
sp = row + (png_size_t)((row_width - 1) >> 1);
4434
dp = row + (png_size_t)row_width - 1;
4435
shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
4436
for (i = 0; i < row_width; i++)
4437
{
4438
value = (*sp >> shift) & 0x0f;
4439
*dp = (png_byte)(value | (value << 4));
4440
if (shift == 4)
4441
{
4442
shift = 0;
4443
sp--;
4444
}
4445
4446
else
4447
shift = 4;
4448
4449
dp--;
4450
}
4451
break;
4452
}
4453
4454
default:
4455
break;
4456
}
4457
4458
row_info->bit_depth = 8;
4459
row_info->pixel_depth = 8;
4460
row_info->rowbytes = row_width;
4461
}
4462
4463
if (trans_color != NULL)
4464
{
4465
if (row_info->bit_depth == 8)
4466
{
4467
gray = gray & 0xff;
4468
sp = row + (png_size_t)row_width - 1;
4469
dp = row + ((png_size_t)row_width << 1) - 1;
4470
4471
for (i = 0; i < row_width; i++)
4472
{
4473
if ((*sp & 0xffU) == gray)
4474
*dp-- = 0;
4475
4476
else
4477
*dp-- = 0xff;
4478
4479
*dp-- = *sp--;
4480
}
4481
}
4482
4483
else if (row_info->bit_depth == 16)
4484
{
4485
unsigned int gray_high = (gray >> 8) & 0xff;
4486
unsigned int gray_low = gray & 0xff;
4487
sp = row + row_info->rowbytes - 1;
4488
dp = row + (row_info->rowbytes << 1) - 1;
4489
for (i = 0; i < row_width; i++)
4490
{
4491
if ((*(sp - 1) & 0xffU) == gray_high &&
4492
(*(sp) & 0xffU) == gray_low)
4493
{
4494
*dp-- = 0;
4495
*dp-- = 0;
4496
}
4497
4498
else
4499
{
4500
*dp-- = 0xff;
4501
*dp-- = 0xff;
4502
}
4503
4504
*dp-- = *sp--;
4505
*dp-- = *sp--;
4506
}
4507
}
4508
4509
row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
4510
row_info->channels = 2;
4511
row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
4512
row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
4513
row_width);
4514
}
4515
}
4516
else if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
4517
trans_color != NULL)
4518
{
4519
if (row_info->bit_depth == 8)
4520
{
4521
png_byte red = (png_byte)(trans_color->red & 0xff);
4522
png_byte green = (png_byte)(trans_color->green & 0xff);
4523
png_byte blue = (png_byte)(trans_color->blue & 0xff);
4524
sp = row + (png_size_t)row_info->rowbytes - 1;
4525
dp = row + ((png_size_t)row_width << 2) - 1;
4526
for (i = 0; i < row_width; i++)
4527
{
4528
if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
4529
*dp-- = 0;
4530
4531
else
4532
*dp-- = 0xff;
4533
4534
*dp-- = *sp--;
4535
*dp-- = *sp--;
4536
*dp-- = *sp--;
4537
}
4538
}
4539
else if (row_info->bit_depth == 16)
4540
{
4541
png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff);
4542
png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff);
4543
png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff);
4544
png_byte red_low = (png_byte)(trans_color->red & 0xff);
4545
png_byte green_low = (png_byte)(trans_color->green & 0xff);
4546
png_byte blue_low = (png_byte)(trans_color->blue & 0xff);
4547
sp = row + row_info->rowbytes - 1;
4548
dp = row + ((png_size_t)row_width << 3) - 1;
4549
for (i = 0; i < row_width; i++)
4550
{
4551
if (*(sp - 5) == red_high &&
4552
*(sp - 4) == red_low &&
4553
*(sp - 3) == green_high &&
4554
*(sp - 2) == green_low &&
4555
*(sp - 1) == blue_high &&
4556
*(sp ) == blue_low)
4557
{
4558
*dp-- = 0;
4559
*dp-- = 0;
4560
}
4561
4562
else
4563
{
4564
*dp-- = 0xff;
4565
*dp-- = 0xff;
4566
}
4567
4568
*dp-- = *sp--;
4569
*dp-- = *sp--;
4570
*dp-- = *sp--;
4571
*dp-- = *sp--;
4572
*dp-- = *sp--;
4573
*dp-- = *sp--;
4574
}
4575
}
4576
row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
4577
row_info->channels = 4;
4578
row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
4579
row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
4580
}
4581
}
4582
}
4583
#endif
4584
4585
#ifdef PNG_READ_EXPAND_16_SUPPORTED
4586
/* If the bit depth is 8 and the color type is not a palette type expand the
4587
* whole row to 16 bits. Has no effect otherwise.
4588
*/
4589
static void
4590
png_do_expand_16(png_row_infop row_info, png_bytep row)
4591
{
4592
if (row_info->bit_depth == 8 &&
4593
row_info->color_type != PNG_COLOR_TYPE_PALETTE)
4594
{
4595
/* The row have a sequence of bytes containing [0..255] and we need
4596
* to turn it into another row containing [0..65535], to do this we
4597
* calculate:
4598
*
4599
* (input / 255) * 65535
4600
*
4601
* Which happens to be exactly input * 257 and this can be achieved
4602
* simply by byte replication in place (copying backwards).
4603
*/
4604
png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */
4605
png_byte *dp = sp + row_info->rowbytes; /* destination, end + 1 */
4606
while (dp > sp)
4607
{
4608
dp[-2] = dp[-1] = *--sp; dp -= 2;
4609
}
4610
4611
row_info->rowbytes *= 2;
4612
row_info->bit_depth = 16;
4613
row_info->pixel_depth = (png_byte)(row_info->channels * 16);
4614
}
4615
}
4616
#endif
4617
4618
#ifdef PNG_READ_QUANTIZE_SUPPORTED
4619
static void
4620
png_do_quantize(png_row_infop row_info, png_bytep row,
4621
png_const_bytep palette_lookup, png_const_bytep quantize_lookup)
4622
{
4623
png_bytep sp, dp;
4624
png_uint_32 i;
4625
png_uint_32 row_width=row_info->width;
4626
4627
png_debug(1, "in png_do_quantize");
4628
4629
if (row_info->bit_depth == 8)
4630
{
4631
if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup)
4632
{
4633
int r, g, b, p;
4634
sp = row;
4635
dp = row;
4636
for (i = 0; i < row_width; i++)
4637
{
4638
r = *sp++;
4639
g = *sp++;
4640
b = *sp++;
4641
4642
/* This looks real messy, but the compiler will reduce
4643
* it down to a reasonable formula. For example, with
4644
* 5 bits per color, we get:
4645
* p = (((r >> 3) & 0x1f) << 10) |
4646
* (((g >> 3) & 0x1f) << 5) |
4647
* ((b >> 3) & 0x1f);
4648
*/
4649
p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
4650
((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
4651
(PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
4652
(((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
4653
((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
4654
(PNG_QUANTIZE_BLUE_BITS)) |
4655
((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
4656
((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
4657
4658
*dp++ = palette_lookup[p];
4659
}
4660
4661
row_info->color_type = PNG_COLOR_TYPE_PALETTE;
4662
row_info->channels = 1;
4663
row_info->pixel_depth = row_info->bit_depth;
4664
row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
4665
}
4666
4667
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
4668
palette_lookup != NULL)
4669
{
4670
int r, g, b, p;
4671
sp = row;
4672
dp = row;
4673
for (i = 0; i < row_width; i++)
4674
{
4675
r = *sp++;
4676
g = *sp++;
4677
b = *sp++;
4678
sp++;
4679
4680
p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
4681
((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
4682
(PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
4683
(((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
4684
((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
4685
(PNG_QUANTIZE_BLUE_BITS)) |
4686
((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
4687
((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
4688
4689
*dp++ = palette_lookup[p];
4690
}
4691
4692
row_info->color_type = PNG_COLOR_TYPE_PALETTE;
4693
row_info->channels = 1;
4694
row_info->pixel_depth = row_info->bit_depth;
4695
row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
4696
}
4697
4698
else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
4699
quantize_lookup)
4700
{
4701
sp = row;
4702
4703
for (i = 0; i < row_width; i++, sp++)
4704
{
4705
*sp = quantize_lookup[*sp];
4706
}
4707
}
4708
}
4709
}
4710
#endif /* READ_QUANTIZE */
4711
4712
/* Transform the row. The order of transformations is significant,
4713
* and is very touchy. If you add a transformation, take care to
4714
* decide how it fits in with the other transformations here.
4715
*/
4716
void /* PRIVATE */
4717
png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
4718
{
4719
png_debug(1, "in png_do_read_transformations");
4720
4721
if (png_ptr->row_buf == NULL)
4722
{
4723
/* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this
4724
* error is incredibly rare and incredibly easy to debug without this
4725
* information.
4726
*/
4727
png_error(png_ptr, "NULL row buffer");
4728
}
4729
4730
/* The following is debugging; prior to 1.5.4 the code was never compiled in;
4731
* in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro
4732
* PNG_WARN_UNINITIALIZED_ROW removed. In 1.6 the new flag is set only for
4733
* all transformations, however in practice the ROW_INIT always gets done on
4734
* demand, if necessary.
4735
*/
4736
if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 &&
4737
(png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
4738
{
4739
/* Application has failed to call either png_read_start_image() or
4740
* png_read_update_info() after setting transforms that expand pixels.
4741
* This check added to libpng-1.2.19 (but not enabled until 1.5.4).
4742
*/
4743
png_error(png_ptr, "Uninitialized row");
4744
}
4745
4746
#ifdef PNG_READ_EXPAND_SUPPORTED
4747
if ((png_ptr->transformations & PNG_EXPAND) != 0)
4748
{
4749
if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
4750
{
4751
png_do_expand_palette(row_info, png_ptr->row_buf + 1,
4752
png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
4753
}
4754
4755
else
4756
{
4757
if (png_ptr->num_trans != 0 &&
4758
(png_ptr->transformations & PNG_EXPAND_tRNS) != 0)
4759
png_do_expand(row_info, png_ptr->row_buf + 1,
4760
&(png_ptr->trans_color));
4761
4762
else
4763
png_do_expand(row_info, png_ptr->row_buf + 1,
4764
NULL);
4765
}
4766
}
4767
#endif
4768
4769
#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
4770
if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
4771
(png_ptr->transformations & PNG_COMPOSE) == 0 &&
4772
(row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
4773
row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
4774
png_do_strip_channel(row_info, png_ptr->row_buf + 1,
4775
0 /* at_start == false, because SWAP_ALPHA happens later */);
4776
#endif
4777
4778
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
4779
if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
4780
{
4781
int rgb_error =
4782
png_do_rgb_to_gray(png_ptr, row_info,
4783
png_ptr->row_buf + 1);
4784
4785
if (rgb_error != 0)
4786
{
4787
png_ptr->rgb_to_gray_status=1;
4788
if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
4789
PNG_RGB_TO_GRAY_WARN)
4790
png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
4791
4792
if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
4793
PNG_RGB_TO_GRAY_ERR)
4794
png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
4795
}
4796
}
4797
#endif
4798
4799
/* From Andreas Dilger e-mail to png-implement, 26 March 1998:
4800
*
4801
* In most cases, the "simple transparency" should be done prior to doing
4802
* gray-to-RGB, or you will have to test 3x as many bytes to check if a
4803
* pixel is transparent. You would also need to make sure that the
4804
* transparency information is upgraded to RGB.
4805
*
4806
* To summarize, the current flow is:
4807
* - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
4808
* with background "in place" if transparent,
4809
* convert to RGB if necessary
4810
* - Gray + alpha -> composite with gray background and remove alpha bytes,
4811
* convert to RGB if necessary
4812
*
4813
* To support RGB backgrounds for gray images we need:
4814
* - Gray + simple transparency -> convert to RGB + simple transparency,
4815
* compare 3 or 6 bytes and composite with
4816
* background "in place" if transparent
4817
* (3x compare/pixel compared to doing
4818
* composite with gray bkgrnd)
4819
* - Gray + alpha -> convert to RGB + alpha, composite with background and
4820
* remove alpha bytes (3x float
4821
* operations/pixel compared with composite
4822
* on gray background)
4823
*
4824
* Greg's change will do this. The reason it wasn't done before is for
4825
* performance, as this increases the per-pixel operations. If we would check
4826
* in advance if the background was gray or RGB, and position the gray-to-RGB
4827
* transform appropriately, then it would save a lot of work/time.
4828
*/
4829
4830
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
4831
/* If gray -> RGB, do so now only if background is non-gray; else do later
4832
* for performance reasons
4833
*/
4834
if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 &&
4835
(png_ptr->mode & PNG_BACKGROUND_IS_GRAY) == 0)
4836
png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
4837
#endif
4838
4839
#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
4840
defined(PNG_READ_ALPHA_MODE_SUPPORTED)
4841
if ((png_ptr->transformations & PNG_COMPOSE) != 0)
4842
png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr);
4843
#endif
4844
4845
#ifdef PNG_READ_GAMMA_SUPPORTED
4846
if ((png_ptr->transformations & PNG_GAMMA) != 0 &&
4847
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
4848
/* Because RGB_TO_GRAY does the gamma transform. */
4849
(png_ptr->transformations & PNG_RGB_TO_GRAY) == 0 &&
4850
#endif
4851
#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
4852
defined(PNG_READ_ALPHA_MODE_SUPPORTED)
4853
/* Because PNG_COMPOSE does the gamma transform if there is something to
4854
* do (if there is an alpha channel or transparency.)
4855
*/
4856
!((png_ptr->transformations & PNG_COMPOSE) != 0 &&
4857
((png_ptr->num_trans != 0) ||
4858
(png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)) &&
4859
#endif
4860
/* Because png_init_read_transformations transforms the palette, unless
4861
* RGB_TO_GRAY will do the transform.
4862
*/
4863
(png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
4864
png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr);
4865
#endif
4866
4867
#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
4868
if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
4869
(png_ptr->transformations & PNG_COMPOSE) != 0 &&
4870
(row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
4871
row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
4872
png_do_strip_channel(row_info, png_ptr->row_buf + 1,
4873
0 /* at_start == false, because SWAP_ALPHA happens later */);
4874
#endif
4875
4876
#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
4877
if ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 &&
4878
(row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
4879
png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr);
4880
#endif
4881
4882
#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
4883
if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0)
4884
png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1);
4885
#endif
4886
4887
#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
4888
/* There is no harm in doing both of these because only one has any effect,
4889
* by putting the 'scale' option first if the app asks for scale (either by
4890
* calling the API or in a TRANSFORM flag) this is what happens.
4891
*/
4892
if ((png_ptr->transformations & PNG_16_TO_8) != 0)
4893
png_do_chop(row_info, png_ptr->row_buf + 1);
4894
#endif
4895
4896
#ifdef PNG_READ_QUANTIZE_SUPPORTED
4897
if ((png_ptr->transformations & PNG_QUANTIZE) != 0)
4898
{
4899
png_do_quantize(row_info, png_ptr->row_buf + 1,
4900
png_ptr->palette_lookup, png_ptr->quantize_index);
4901
4902
if (row_info->rowbytes == 0)
4903
png_error(png_ptr, "png_do_quantize returned rowbytes=0");
4904
}
4905
#endif /* READ_QUANTIZE */
4906
4907
#ifdef PNG_READ_EXPAND_16_SUPPORTED
4908
/* Do the expansion now, after all the arithmetic has been done. Notice
4909
* that previous transformations can handle the PNG_EXPAND_16 flag if this
4910
* is efficient (particularly true in the case of gamma correction, where
4911
* better accuracy results faster!)
4912
*/
4913
if ((png_ptr->transformations & PNG_EXPAND_16) != 0)
4914
png_do_expand_16(row_info, png_ptr->row_buf + 1);
4915
#endif
4916
4917
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
4918
/* NOTE: moved here in 1.5.4 (from much later in this list.) */
4919
if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 &&
4920
(png_ptr->mode & PNG_BACKGROUND_IS_GRAY) != 0)
4921
png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
4922
#endif
4923
4924
#ifdef PNG_READ_INVERT_SUPPORTED
4925
if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
4926
png_do_invert(row_info, png_ptr->row_buf + 1);
4927
#endif
4928
4929
#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
4930
if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
4931
png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1);
4932
#endif
4933
4934
#ifdef PNG_READ_SHIFT_SUPPORTED
4935
if ((png_ptr->transformations & PNG_SHIFT) != 0)
4936
png_do_unshift(row_info, png_ptr->row_buf + 1,
4937
&(png_ptr->shift));
4938
#endif
4939
4940
#ifdef PNG_READ_PACK_SUPPORTED
4941
if ((png_ptr->transformations & PNG_PACK) != 0)
4942
png_do_unpack(row_info, png_ptr->row_buf + 1);
4943
#endif
4944
4945
#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
4946
/* Added at libpng-1.5.10 */
4947
if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
4948
png_ptr->num_palette_max >= 0)
4949
png_do_check_palette_indexes(png_ptr, row_info);
4950
#endif
4951
4952
#ifdef PNG_READ_BGR_SUPPORTED
4953
if ((png_ptr->transformations & PNG_BGR) != 0)
4954
png_do_bgr(row_info, png_ptr->row_buf + 1);
4955
#endif
4956
4957
#ifdef PNG_READ_PACKSWAP_SUPPORTED
4958
if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
4959
png_do_packswap(row_info, png_ptr->row_buf + 1);
4960
#endif
4961
4962
#ifdef PNG_READ_FILLER_SUPPORTED
4963
if ((png_ptr->transformations & PNG_FILLER) != 0)
4964
png_do_read_filler(row_info, png_ptr->row_buf + 1,
4965
(png_uint_32)png_ptr->filler, png_ptr->flags);
4966
#endif
4967
4968
#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
4969
if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0)
4970
png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1);
4971
#endif
4972
4973
#ifdef PNG_READ_16BIT_SUPPORTED
4974
#ifdef PNG_READ_SWAP_SUPPORTED
4975
if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
4976
png_do_swap(row_info, png_ptr->row_buf + 1);
4977
#endif
4978
#endif
4979
4980
#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
4981
if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
4982
{
4983
if (png_ptr->read_user_transform_fn != NULL)
4984
(*(png_ptr->read_user_transform_fn)) /* User read transform function */
4985
(png_ptr, /* png_ptr */
4986
row_info, /* row_info: */
4987
/* png_uint_32 width; width of row */
4988
/* png_size_t rowbytes; number of bytes in row */
4989
/* png_byte color_type; color type of pixels */
4990
/* png_byte bit_depth; bit depth of samples */
4991
/* png_byte channels; number of channels (1-4) */
4992
/* png_byte pixel_depth; bits per pixel (depth*channels) */
4993
png_ptr->row_buf + 1); /* start of pixel data for row */
4994
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
4995
if (png_ptr->user_transform_depth != 0)
4996
row_info->bit_depth = png_ptr->user_transform_depth;
4997
4998
if (png_ptr->user_transform_channels != 0)
4999
row_info->channels = png_ptr->user_transform_channels;
5000
#endif
5001
row_info->pixel_depth = (png_byte)(row_info->bit_depth *
5002
row_info->channels);
5003
5004
row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width);
5005
}
5006
#endif
5007
}
5008
5009
#endif /* READ_TRANSFORMS */
5010
#endif /* READ */
5011
5012