2
/* pngrtran.c - transforms the data in a row for PNG readers
4
* libpng 1.0.8 - July 24, 2000
5
* For conditions of distribution and use, see copyright notice in png.h
6
* Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson
7
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
10
* This file contains functions optionally called by an application
11
* in order to tell libpng how to handle data when reading a PNG.
12
* Transformations that are used in both reading and writing are
19
/* Set the action on getting a CRC error for an ancillary or critical chunk. */
21
png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
23
png_debug(1, "in png_set_crc_action\n");
24
/* Tell libpng how we react to CRC errors in critical chunks */
27
case PNG_CRC_NO_CHANGE: /* leave setting as is */
29
case PNG_CRC_WARN_USE: /* warn/use data */
30
png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
31
png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
33
case PNG_CRC_QUIET_USE: /* quiet/use data */
34
png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
35
png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
36
PNG_FLAG_CRC_CRITICAL_IGNORE;
38
case PNG_CRC_WARN_DISCARD: /* not a valid action for critical data */
39
png_warning(png_ptr, "Can't discard critical data on CRC error.");
40
case PNG_CRC_ERROR_QUIT: /* error/quit */
43
png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
49
case PNG_CRC_NO_CHANGE: /* leave setting as is */
51
case PNG_CRC_WARN_USE: /* warn/use data */
52
png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
53
png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
55
case PNG_CRC_QUIET_USE: /* quiet/use data */
56
png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
57
png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
58
PNG_FLAG_CRC_ANCILLARY_NOWARN;
60
case PNG_CRC_ERROR_QUIT: /* error/quit */
61
png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
62
png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
64
case PNG_CRC_WARN_DISCARD: /* warn/discard data */
67
png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
72
#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
73
defined(PNG_FLOATING_POINT_SUPPORTED)
74
/* handle alpha and tRNS via a background color */
76
png_set_background(png_structp png_ptr,
77
png_color_16p background_color, int background_gamma_code,
78
int need_expand, double background_gamma)
80
png_debug(1, "in png_set_background\n");
81
if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
83
png_warning(png_ptr, "Application must supply a known background gamma");
87
png_ptr->transformations |= PNG_BACKGROUND;
88
png_memcpy(&(png_ptr->background), background_color, sizeof(png_color_16));
89
png_ptr->background_gamma = (float)background_gamma;
90
png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
91
png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
93
/* Note: if need_expand is set and color_type is either RGB or RGB_ALPHA
94
* (in which case need_expand is superfluous anyway), the background color
95
* might actually be gray yet not be flagged as such. This is not a problem
96
* for the current code, which uses PNG_BACKGROUND_IS_GRAY only to
97
* decide when to do the png_do_gray_to_rgb() transformation.
99
if ((need_expand && !(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) ||
100
(!need_expand && background_color->red == background_color->green &&
101
background_color->red == background_color->blue))
102
png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
106
#if defined(PNG_READ_16_TO_8_SUPPORTED)
107
/* strip 16 bit depth files to 8 bit depth */
109
png_set_strip_16(png_structp png_ptr)
111
png_debug(1, "in png_set_strip_16\n");
112
png_ptr->transformations |= PNG_16_TO_8;
116
#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
118
png_set_strip_alpha(png_structp png_ptr)
120
png_debug(1, "in png_set_strip_alpha\n");
121
png_ptr->transformations |= PNG_STRIP_ALPHA;
125
#if defined(PNG_READ_DITHER_SUPPORTED)
126
/* Dither file to 8 bit. Supply a palette, the current number
127
* of elements in the palette, the maximum number of elements
128
* allowed, and a histogram if possible. If the current number
129
* of colors is greater then the maximum number, the palette will be
130
* modified to fit in the maximum number. "full_dither" indicates
131
* whether we need a dithering cube set up for RGB images, or if we
132
* simply are reducing the number of colors in a paletted image.
135
typedef struct png_dsort_struct
137
struct png_dsort_struct FAR * next;
141
typedef png_dsort FAR * png_dsortp;
142
typedef png_dsort FAR * FAR * png_dsortpp;
145
png_set_dither(png_structp png_ptr, png_colorp palette,
146
int num_palette, int maximum_colors, png_uint_16p histogram,
149
png_debug(1, "in png_set_dither\n");
150
png_ptr->transformations |= PNG_DITHER;
156
png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
157
(png_uint_32)(num_palette * sizeof (png_byte)));
158
for (i = 0; i < num_palette; i++)
159
png_ptr->dither_index[i] = (png_byte)i;
162
if (num_palette > maximum_colors)
164
if (histogram != NULL)
166
/* This is easy enough, just throw out the least used colors.
167
Perhaps not the best solution, but good enough. */
172
/* initialize an array to sort colors */
173
sort = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_palette
174
* sizeof (png_byte)));
176
/* initialize the sort array */
177
for (i = 0; i < num_palette; i++)
178
sort[i] = (png_byte)i;
180
/* Find the least used palette entries by starting a
181
bubble sort, and running it until we have sorted
182
out enough colors. Note that we don't care about
183
sorting all the colors, just finding which are
186
for (i = num_palette - 1; i >= maximum_colors; i--)
188
int done; /* to stop early if the list is pre-sorted */
192
for (j = 0; j < i; j++)
194
if (histogram[sort[j]] < histogram[sort[j + 1]])
199
sort[j] = sort[j + 1];
208
/* swap the palette around, and set up a table, if necessary */
213
/* put all the useful colors within the max, but don't
215
for (i = 0; i < maximum_colors; i++)
217
if ((int)sort[i] >= maximum_colors)
221
while ((int)sort[j] >= maximum_colors);
222
palette[i] = palette[j];
230
/* move all the used colors inside the max limit, and
231
develop a translation table */
232
for (i = 0; i < maximum_colors; i++)
234
/* only move the colors we need to */
235
if ((int)sort[i] >= maximum_colors)
241
while ((int)sort[j] >= maximum_colors);
243
tmp_color = palette[j];
244
palette[j] = palette[i];
245
palette[i] = tmp_color;
246
/* indicate where the color went */
247
png_ptr->dither_index[j] = (png_byte)i;
248
png_ptr->dither_index[i] = (png_byte)j;
252
/* find closest color for those colors we are not using */
253
for (i = 0; i < num_palette; i++)
255
if ((int)png_ptr->dither_index[i] >= maximum_colors)
257
int min_d, k, min_k, d_index;
259
/* find the closest color to one we threw out */
260
d_index = png_ptr->dither_index[i];
261
min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
262
for (k = 1, min_k = 0; k < maximum_colors; k++)
266
d = PNG_COLOR_DIST(palette[d_index], palette[k]);
274
/* point to closest color */
275
png_ptr->dither_index[i] = (png_byte)min_k;
279
png_free(png_ptr, sort);
283
/* This is much harder to do simply (and quickly). Perhaps
284
we need to go through a median cut routine, but those
285
don't always behave themselves with only a few colors
286
as input. So we will just find the closest two colors,
287
and throw out one of them (chosen somewhat randomly).
288
[We don't understand this at all, so if someone wants to
289
work on improving it, be our guest - AED, GRP]
295
png_bytep index_to_palette;
296
/* where the original index currently is in the palette */
297
png_bytep palette_to_index;
298
/* which original index points to this palette color */
300
/* initialize palette index arrays */
301
index_to_palette = (png_bytep)png_malloc(png_ptr,
302
(png_uint_32)(num_palette * sizeof (png_byte)));
303
palette_to_index = (png_bytep)png_malloc(png_ptr,
304
(png_uint_32)(num_palette * sizeof (png_byte)));
306
/* initialize the sort array */
307
for (i = 0; i < num_palette; i++)
309
index_to_palette[i] = (png_byte)i;
310
palette_to_index[i] = (png_byte)i;
313
hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 *
314
sizeof (png_dsortp)));
315
for (i = 0; i < 769; i++)
317
/* png_memset(hash, 0, 769 * sizeof (png_dsortp)); */
319
num_new_palette = num_palette;
321
/* initial wild guess at how far apart the farthest pixel
322
pair we will be eliminating will be. Larger
323
numbers mean more areas will be allocated, Smaller
324
numbers run the risk of not saving enough data, and
325
having to do this all over again.
327
I have not done extensive checking on this number.
331
while (num_new_palette > maximum_colors)
333
for (i = 0; i < num_new_palette - 1; i++)
337
for (j = i + 1; j < num_new_palette; j++)
341
d = PNG_COLOR_DIST(palette[i], palette[j]);
347
t = (png_dsortp)png_malloc(png_ptr, (png_uint_32)(sizeof
350
t->left = (png_byte)i;
351
t->right = (png_byte)j;
357
for (i = 0; i <= max_d; i++)
363
for (p = hash[i]; p; p = p->next)
365
if ((int)index_to_palette[p->left] < num_new_palette &&
366
(int)index_to_palette[p->right] < num_new_palette)
370
if (num_new_palette & 0x01)
382
palette[index_to_palette[j]] = palette[num_new_palette];
387
for (k = 0; k < num_palette; k++)
389
if (png_ptr->dither_index[k] ==
391
png_ptr->dither_index[k] =
392
index_to_palette[next_j];
393
if ((int)png_ptr->dither_index[k] ==
395
png_ptr->dither_index[k] =
400
index_to_palette[palette_to_index[num_new_palette]] =
402
palette_to_index[index_to_palette[j]] =
403
palette_to_index[num_new_palette];
405
index_to_palette[j] = (png_byte)num_new_palette;
406
palette_to_index[num_new_palette] = (png_byte)j;
408
if (num_new_palette <= maximum_colors)
411
if (num_new_palette <= maximum_colors)
416
for (i = 0; i < 769; i++)
420
png_dsortp p = hash[i];
426
png_free(png_ptr, p);
434
png_free(png_ptr, hash);
435
png_free(png_ptr, palette_to_index);
436
png_free(png_ptr, index_to_palette);
438
num_palette = maximum_colors;
440
if (png_ptr->palette == NULL)
442
png_ptr->palette = palette;
444
png_ptr->num_palette = (png_uint_16)num_palette;
450
int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
451
PNG_DITHER_BLUE_BITS;
452
int num_red = (1 << PNG_DITHER_RED_BITS);
453
int num_green = (1 << PNG_DITHER_GREEN_BITS);
454
int num_blue = (1 << PNG_DITHER_BLUE_BITS);
455
png_size_t num_entries = ((png_size_t)1 << total_bits);
457
png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr,
458
(png_uint_32)(num_entries * sizeof (png_byte)));
460
png_memset(png_ptr->palette_lookup, 0, num_entries * sizeof (png_byte));
462
distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
465
png_memset(distance, 0xff, num_entries * sizeof(png_byte));
467
for (i = 0; i < num_palette; i++)
470
int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
471
int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
472
int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
474
for (ir = 0; ir < num_red; ir++)
476
int dr = abs(ir - r);
477
int index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS));
479
for (ig = 0; ig < num_green; ig++)
481
int dg = abs(ig - g);
483
int dm = ((dr > dg) ? dr : dg);
484
int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
486
for (ib = 0; ib < num_blue; ib++)
488
int d_index = index_g | ib;
489
int db = abs(ib - b);
490
int dmax = ((dm > db) ? dm : db);
491
int d = dmax + dt + db;
493
if (d < (int)distance[d_index])
495
distance[d_index] = (png_byte)d;
496
png_ptr->palette_lookup[d_index] = (png_byte)i;
503
png_free(png_ptr, distance);
508
#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
509
/* Transform the image from the file_gamma to the screen_gamma. We
510
* only do transformations on images where the file_gamma and screen_gamma
511
* are not close reciprocals, otherwise it slows things down slightly, and
512
* also needlessly introduces small errors.
515
png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
517
png_debug(1, "in png_set_gamma\n");
518
if (fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD)
519
png_ptr->transformations |= PNG_GAMMA;
520
png_ptr->gamma = (float)file_gamma;
521
png_ptr->screen_gamma = (float)scrn_gamma;
525
#if defined(PNG_READ_EXPAND_SUPPORTED)
526
/* Expand paletted images to RGB, expand grayscale images of
527
* less than 8-bit depth to 8-bit depth, and expand tRNS chunks
531
png_set_expand(png_structp png_ptr)
533
png_debug(1, "in png_set_expand\n");
534
png_ptr->transformations |= PNG_EXPAND;
537
/* GRR 19990627: the following three functions currently are identical
538
* to png_set_expand(). However, it is entirely reasonable that someone
539
* might wish to expand an indexed image to RGB but *not* expand a single,
540
* fully transparent palette entry to a full alpha channel--perhaps instead
541
* convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
542
* the transparent color with a particular RGB value, or drop tRNS entirely.
543
* IOW, a future version of the library may make the transformations flag
544
* a bit more fine-grained, with separate bits for each of these three
547
* More to the point, these functions make it obvious what libpng will be
548
* doing, whereas "expand" can (and does) mean any number of things.
551
/* Expand paletted images to RGB. */
553
png_set_palette_to_rgb(png_structp png_ptr)
555
png_debug(1, "in png_set_expand\n");
556
png_ptr->transformations |= PNG_EXPAND;
559
/* Expand grayscale images of less than 8-bit depth to 8 bits. */
561
png_set_gray_1_2_4_to_8(png_structp png_ptr)
563
png_debug(1, "in png_set_expand\n");
564
png_ptr->transformations |= PNG_EXPAND;
567
/* Expand tRNS chunks to alpha channels. */
569
png_set_tRNS_to_alpha(png_structp png_ptr)
571
png_debug(1, "in png_set_expand\n");
572
png_ptr->transformations |= PNG_EXPAND;
574
#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
576
#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
578
png_set_gray_to_rgb(png_structp png_ptr)
580
png_debug(1, "in png_set_gray_to_rgb\n");
581
png_ptr->transformations |= PNG_GRAY_TO_RGB;
585
#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
586
#if defined(PNG_FLOATING_POINT_SUPPORTED)
587
/* Convert a RGB image to a grayscale of the same width. This allows us,
588
* for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
592
png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
595
int red_fixed = (int)((float)red*100000.0 + 0.5);
596
int green_fixed = (int)((float)green*100000.0 + 0.5);
597
png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed);
602
png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
603
png_fixed_point red, png_fixed_point green)
605
png_debug(1, "in png_set_rgb_to_gray\n");
608
case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY;
610
case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
612
case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
614
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
615
#if defined(PNG_READ_EXPAND_SUPPORTED)
616
png_ptr->transformations |= PNG_EXPAND;
619
png_warning(png_ptr, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
620
png_ptr->transformations &= ~PNG_RGB_TO_GRAY;
624
png_uint_16 red_int, green_int;
625
if(red < 0 || green < 0)
627
red_int = 6968; /* .212671 * 32768 + .5 */
628
green_int = 23434; /* .715160 * 32768 + .5 */
630
else if(red + green < 100000L)
632
red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L);
633
green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
637
png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
641
png_ptr->rgb_to_gray_red_coeff = red_int;
642
png_ptr->rgb_to_gray_green_coeff = green_int;
643
png_ptr->rgb_to_gray_blue_coeff = (png_uint_16)(32768-red_int-green_int);
648
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
649
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
650
defined(PNG_LEGACY_SUPPORTED)
652
png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
653
read_user_transform_fn)
655
png_debug(1, "in png_set_read_user_transform_fn\n");
656
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
657
png_ptr->transformations |= PNG_USER_TRANSFORM;
658
png_ptr->read_user_transform_fn = read_user_transform_fn;
660
#ifdef PNG_LEGACY_SUPPORTED
661
if(read_user_transform_fn)
663
"This version of libpng does not support user transforms");
668
/* Initialize everything needed for the read. This includes modifying
672
png_init_read_transformations(png_structp png_ptr)
674
png_debug(1, "in png_init_read_transformations\n");
675
#if defined(PNG_USELESS_TESTS_SUPPORTED)
679
#if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
680
|| defined(PNG_READ_GAMMA_SUPPORTED)
681
int color_type = png_ptr->color_type;
684
#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
685
if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
686
(png_ptr->transformations & PNG_EXPAND))
688
if (!(color_type & PNG_COLOR_MASK_COLOR)) /* i.e., GRAY or GRAY_ALPHA */
690
/* expand background chunk. */
691
switch (png_ptr->bit_depth)
694
png_ptr->background.gray *= (png_uint_16)0xff;
695
png_ptr->background.red = png_ptr->background.green =
696
png_ptr->background.blue = png_ptr->background.gray;
699
png_ptr->background.gray *= (png_uint_16)0x55;
700
png_ptr->background.red = png_ptr->background.green =
701
png_ptr->background.blue = png_ptr->background.gray;
704
png_ptr->background.gray *= (png_uint_16)0x11;
705
png_ptr->background.red = png_ptr->background.green =
706
png_ptr->background.blue = png_ptr->background.gray;
710
png_ptr->background.red = png_ptr->background.green =
711
png_ptr->background.blue = png_ptr->background.gray;
715
else if (color_type == PNG_COLOR_TYPE_PALETTE)
717
png_ptr->background.red =
718
png_ptr->palette[png_ptr->background.index].red;
719
png_ptr->background.green =
720
png_ptr->palette[png_ptr->background.index].green;
721
png_ptr->background.blue =
722
png_ptr->palette[png_ptr->background.index].blue;
724
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
725
if (png_ptr->transformations & PNG_INVERT_ALPHA)
727
#if defined(PNG_READ_EXPAND_SUPPORTED)
728
if (!(png_ptr->transformations & PNG_EXPAND))
731
/* invert the alpha channel (in tRNS) unless the pixels are
732
going to be expanded, in which case leave it for later */
734
istop=(int)png_ptr->num_trans;
735
for (i=0; i<istop; i++)
736
png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]);
745
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
746
png_ptr->background_1 = png_ptr->background;
748
#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
749
if (png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY))
751
png_build_gamma_table(png_ptr);
752
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
753
if (png_ptr->transformations & PNG_BACKGROUND)
755
if (color_type == PNG_COLOR_TYPE_PALETTE)
757
png_color back, back_1;
758
png_colorp palette = png_ptr->palette;
759
int num_palette = png_ptr->num_palette;
761
if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
763
back.red = png_ptr->gamma_table[png_ptr->background.red];
764
back.green = png_ptr->gamma_table[png_ptr->background.green];
765
back.blue = png_ptr->gamma_table[png_ptr->background.blue];
767
back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
768
back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
769
back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
775
switch (png_ptr->background_gamma_type)
777
case PNG_BACKGROUND_GAMMA_SCREEN:
778
g = (png_ptr->screen_gamma);
781
case PNG_BACKGROUND_GAMMA_FILE:
782
g = 1.0 / (png_ptr->gamma);
783
gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
785
case PNG_BACKGROUND_GAMMA_UNIQUE:
786
g = 1.0 / (png_ptr->background_gamma);
787
gs = 1.0 / (png_ptr->background_gamma *
788
png_ptr->screen_gamma);
791
g = 1.0; /* back_1 */
795
if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD)
797
back.red = (png_byte)png_ptr->background.red;
798
back.green = (png_byte)png_ptr->background.green;
799
back.blue = (png_byte)png_ptr->background.blue;
803
back.red = (png_byte)(pow(
804
(double)png_ptr->background.red/255, gs) * 255.0 + .5);
805
back.green = (png_byte)(pow(
806
(double)png_ptr->background.green/255, gs) * 255.0 + .5);
807
back.blue = (png_byte)(pow(
808
(double)png_ptr->background.blue/255, gs) * 255.0 + .5);
811
back_1.red = (png_byte)(pow(
812
(double)png_ptr->background.red/255, g) * 255.0 + .5);
813
back_1.green = (png_byte)(pow(
814
(double)png_ptr->background.green/255, g) * 255.0 + .5);
815
back_1.blue = (png_byte)(pow(
816
(double)png_ptr->background.blue/255, g) * 255.0 + .5);
818
for (i = 0; i < num_palette; i++)
820
if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
822
if (png_ptr->trans[i] == 0)
826
else /* if (png_ptr->trans[i] != 0xff) */
830
v = png_ptr->gamma_to_1[palette[i].red];
831
png_composite(w, v, png_ptr->trans[i], back_1.red);
832
palette[i].red = png_ptr->gamma_from_1[w];
834
v = png_ptr->gamma_to_1[palette[i].green];
835
png_composite(w, v, png_ptr->trans[i], back_1.green);
836
palette[i].green = png_ptr->gamma_from_1[w];
838
v = png_ptr->gamma_to_1[palette[i].blue];
839
png_composite(w, v, png_ptr->trans[i], back_1.blue);
840
palette[i].blue = png_ptr->gamma_from_1[w];
845
palette[i].red = png_ptr->gamma_table[palette[i].red];
846
palette[i].green = png_ptr->gamma_table[palette[i].green];
847
palette[i].blue = png_ptr->gamma_table[palette[i].blue];
851
/* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN)*/
853
/* color_type != PNG_COLOR_TYPE_PALETTE */
855
double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
859
switch (png_ptr->background_gamma_type)
861
case PNG_BACKGROUND_GAMMA_SCREEN:
862
g = (png_ptr->screen_gamma);
865
case PNG_BACKGROUND_GAMMA_FILE:
866
g = 1.0 / (png_ptr->gamma);
867
gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
869
case PNG_BACKGROUND_GAMMA_UNIQUE:
870
g = 1.0 / (png_ptr->background_gamma);
871
gs = 1.0 / (png_ptr->background_gamma *
872
png_ptr->screen_gamma);
876
if (color_type & PNG_COLOR_MASK_COLOR)
879
png_ptr->background_1.red = (png_uint_16)(pow(
880
(double)png_ptr->background.red / m, g) * m + .5);
881
png_ptr->background_1.green = (png_uint_16)(pow(
882
(double)png_ptr->background.green / m, g) * m + .5);
883
png_ptr->background_1.blue = (png_uint_16)(pow(
884
(double)png_ptr->background.blue / m, g) * m + .5);
885
png_ptr->background.red = (png_uint_16)(pow(
886
(double)png_ptr->background.red / m, gs) * m + .5);
887
png_ptr->background.green = (png_uint_16)(pow(
888
(double)png_ptr->background.green / m, gs) * m + .5);
889
png_ptr->background.blue = (png_uint_16)(pow(
890
(double)png_ptr->background.blue / m, gs) * m + .5);
894
/* GRAY or GRAY ALPHA */
895
png_ptr->background_1.gray = (png_uint_16)(pow(
896
(double)png_ptr->background.gray / m, g) * m + .5);
897
png_ptr->background.gray = (png_uint_16)(pow(
898
(double)png_ptr->background.gray / m, gs) * m + .5);
903
/* transformation does not include PNG_BACKGROUND */
905
if (color_type == PNG_COLOR_TYPE_PALETTE)
907
png_colorp palette = png_ptr->palette;
908
int num_palette = png_ptr->num_palette;
911
for (i = 0; i < num_palette; i++)
913
palette[i].red = png_ptr->gamma_table[palette[i].red];
914
palette[i].green = png_ptr->gamma_table[palette[i].green];
915
palette[i].blue = png_ptr->gamma_table[palette[i].blue];
919
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
923
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
924
/* No GAMMA transformation */
925
if ((png_ptr->transformations & PNG_BACKGROUND) &&
926
(color_type == PNG_COLOR_TYPE_PALETTE))
929
int istop = (int)png_ptr->num_trans;
931
png_colorp palette = png_ptr->palette;
933
back.red = (png_byte)png_ptr->background.red;
934
back.green = (png_byte)png_ptr->background.green;
935
back.blue = (png_byte)png_ptr->background.blue;
937
for (i = 0; i < istop; i++)
939
if (png_ptr->trans[i] == 0)
943
else if (png_ptr->trans[i] != 0xff)
945
/* The png_composite() macro is defined in png.h */
946
png_composite(palette[i].red, palette[i].red,
947
png_ptr->trans[i], back.red);
948
png_composite(palette[i].green, palette[i].green,
949
png_ptr->trans[i], back.green);
950
png_composite(palette[i].blue, palette[i].blue,
951
png_ptr->trans[i], back.blue);
957
#if defined(PNG_READ_SHIFT_SUPPORTED)
958
if ((png_ptr->transformations & PNG_SHIFT) &&
959
(color_type == PNG_COLOR_TYPE_PALETTE))
962
png_uint_16 istop = png_ptr->num_palette;
963
int sr = 8 - png_ptr->sig_bit.red;
964
int sg = 8 - png_ptr->sig_bit.green;
965
int sb = 8 - png_ptr->sig_bit.blue;
967
if (sr < 0 || sr > 8)
969
if (sg < 0 || sg > 8)
971
if (sb < 0 || sb > 8)
973
for (i = 0; i < istop; i++)
975
png_ptr->palette[i].red >>= sr;
976
png_ptr->palette[i].green >>= sg;
977
png_ptr->palette[i].blue >>= sb;
982
#if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
983
&& !defined(PNG_READ_BACKGROUND_SUPPORTED)
989
/* Modify the info structure to reflect the transformations. The
990
* info should be updated so a PNG file could be written with it,
991
* assuming the transformations result in valid PNG data.
994
png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
996
png_debug(1, "in png_read_transform_info\n");
997
#if defined(PNG_READ_EXPAND_SUPPORTED)
998
if (png_ptr->transformations & PNG_EXPAND)
1000
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1002
if (png_ptr->num_trans)
1003
info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
1005
info_ptr->color_type = PNG_COLOR_TYPE_RGB;
1006
info_ptr->bit_depth = 8;
1007
info_ptr->num_trans = 0;
1011
if (png_ptr->num_trans)
1012
info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
1013
if (info_ptr->bit_depth < 8)
1014
info_ptr->bit_depth = 8;
1015
info_ptr->num_trans = 0;
1020
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
1021
if (png_ptr->transformations & PNG_BACKGROUND)
1023
info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
1024
info_ptr->num_trans = 0;
1025
info_ptr->background = png_ptr->background;
1029
#if defined(PNG_READ_GAMMA_SUPPORTED)
1030
if (png_ptr->transformations & PNG_GAMMA)
1032
#ifdef PNG_FLOATING_POINT_SUPPORTED
1033
info_ptr->gamma = png_ptr->gamma;
1035
#ifdef PNG_FIXED_POINT_SUPPORTED
1036
info_ptr->int_gamma = png_ptr->int_gamma;
1041
#if defined(PNG_READ_16_TO_8_SUPPORTED)
1042
if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16))
1043
info_ptr->bit_depth = 8;
1046
#if defined(PNG_READ_DITHER_SUPPORTED)
1047
if (png_ptr->transformations & PNG_DITHER)
1049
if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
1050
(info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
1051
png_ptr->palette_lookup && info_ptr->bit_depth == 8)
1053
info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
1058
#if defined(PNG_READ_PACK_SUPPORTED)
1059
if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
1060
info_ptr->bit_depth = 8;
1063
#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1064
if (png_ptr->transformations & PNG_GRAY_TO_RGB)
1065
info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
1068
#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1069
if (png_ptr->transformations & PNG_RGB_TO_GRAY)
1070
info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR;
1073
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1074
info_ptr->channels = 1;
1075
else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
1076
info_ptr->channels = 3;
1078
info_ptr->channels = 1;
1080
#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1081
if (png_ptr->transformations & PNG_STRIP_ALPHA)
1082
info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
1085
if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
1086
info_ptr->channels++;
1088
#if defined(PNG_READ_FILLER_SUPPORTED)
1089
/* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
1090
if ((png_ptr->transformations & PNG_FILLER) &&
1091
((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
1092
(info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
1093
info_ptr->channels++;
1096
#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
1097
defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1098
if(png_ptr->transformations & PNG_USER_TRANSFORM)
1100
if(info_ptr->bit_depth < png_ptr->user_transform_depth)
1101
info_ptr->bit_depth = png_ptr->user_transform_depth;
1102
if(info_ptr->channels < png_ptr->user_transform_channels)
1103
info_ptr->channels = png_ptr->user_transform_channels;
1107
info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
1108
info_ptr->bit_depth);
1109
info_ptr->rowbytes = ((info_ptr->width * info_ptr->pixel_depth + 7) >> 3);
1111
#if !defined(PNG_READ_EXPAND_SUPPORTED)
1117
/* Transform the row. The order of transformations is significant,
1118
* and is very touchy. If you add a transformation, take care to
1119
* decide how it fits in with the other transformations here.
1122
png_do_read_transformations(png_structp png_ptr)
1124
png_debug(1, "in png_do_read_transformations\n");
1125
#if !defined(PNG_USELESS_TESTS_SUPPORTED)
1126
if (png_ptr->row_buf == NULL)
1128
#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
1131
sprintf(msg, "NULL row buffer for row %ld, pass %d", png_ptr->row_number,
1133
png_error(png_ptr, msg);
1135
png_error(png_ptr, "NULL row buffer");
1140
#if defined(PNG_READ_EXPAND_SUPPORTED)
1141
if (png_ptr->transformations & PNG_EXPAND)
1143
if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
1145
png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
1146
png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
1150
if (png_ptr->num_trans)
1151
png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
1152
&(png_ptr->trans_values));
1154
png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
1160
#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1161
if (png_ptr->transformations & PNG_STRIP_ALPHA)
1162
png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
1163
PNG_FLAG_FILLER_AFTER);
1166
#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1167
if (png_ptr->transformations & PNG_RGB_TO_GRAY)
1170
png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1);
1173
png_ptr->rgb_to_gray_status=1;
1174
if(png_ptr->transformations == PNG_RGB_TO_GRAY_WARN)
1175
png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
1176
if(png_ptr->transformations == PNG_RGB_TO_GRAY_ERR)
1177
png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
1183
From Andreas Dilger e-mail to png-implement, 26 March 1998:
1185
In most cases, the "simple transparency" should be done prior to doing
1186
gray-to-RGB, or you will have to test 3x as many bytes to check if a
1187
pixel is transparent. You would also need to make sure that the
1188
transparency information is upgraded to RGB.
1190
To summarize, the current flow is:
1191
- Gray + simple transparency -> compare 1 or 2 gray bytes and composite
1192
with background "in place" if transparent,
1193
convert to RGB if necessary
1194
- Gray + alpha -> composite with gray background and remove alpha bytes,
1195
convert to RGB if necessary
1197
To support RGB backgrounds for gray images we need:
1198
- Gray + simple transparency -> convert to RGB + simple transparency, compare
1199
3 or 6 bytes and composite with background
1200
"in place" if transparent (3x compare/pixel
1201
compared to doing composite with gray bkgrnd)
1202
- Gray + alpha -> convert to RGB + alpha, composite with background and
1203
remove alpha bytes (3x float operations/pixel
1204
compared with composite on gray background)
1206
Greg's change will do this. The reason it wasn't done before is for
1207
performance, as this increases the per-pixel operations. If we would check
1208
in advance if the background was gray or RGB, and position the gray-to-RGB
1209
transform appropriately, then it would save a lot of work/time.
1212
#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1213
/* if gray -> RGB, do so now only if background is non-gray; else do later
1214
* for performance reasons */
1215
if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
1216
!(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
1217
png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
1220
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
1221
if ((png_ptr->transformations & PNG_BACKGROUND) &&
1222
((png_ptr->num_trans != 0 ) ||
1223
(png_ptr->color_type & PNG_COLOR_MASK_ALPHA)))
1224
png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
1225
&(png_ptr->trans_values), &(png_ptr->background),
1226
&(png_ptr->background_1),
1227
png_ptr->gamma_table, png_ptr->gamma_from_1,
1228
png_ptr->gamma_to_1, png_ptr->gamma_16_table,
1229
png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
1230
png_ptr->gamma_shift);
1233
#if defined(PNG_READ_GAMMA_SUPPORTED)
1234
if ((png_ptr->transformations & PNG_GAMMA) &&
1235
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
1236
!((png_ptr->transformations & PNG_BACKGROUND) &&
1237
((png_ptr->num_trans != 0) ||
1238
(png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
1240
(png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
1241
png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
1242
png_ptr->gamma_table, png_ptr->gamma_16_table,
1243
png_ptr->gamma_shift);
1246
#if defined(PNG_READ_16_TO_8_SUPPORTED)
1247
if (png_ptr->transformations & PNG_16_TO_8)
1248
png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
1251
#if defined(PNG_READ_DITHER_SUPPORTED)
1252
if (png_ptr->transformations & PNG_DITHER)
1254
png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1,
1255
png_ptr->palette_lookup, png_ptr->dither_index);
1256
if(png_ptr->row_info.rowbytes == (png_uint_32)0)
1257
png_error(png_ptr, "png_do_dither returned rowbytes=0");
1261
#if defined(PNG_READ_INVERT_SUPPORTED)
1262
if (png_ptr->transformations & PNG_INVERT_MONO)
1263
png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
1266
#if defined(PNG_READ_SHIFT_SUPPORTED)
1267
if (png_ptr->transformations & PNG_SHIFT)
1268
png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
1272
#if defined(PNG_READ_PACK_SUPPORTED)
1273
if (png_ptr->transformations & PNG_PACK)
1274
png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
1277
#if defined(PNG_READ_BGR_SUPPORTED)
1278
if (png_ptr->transformations & PNG_BGR)
1279
png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
1282
#if defined(PNG_READ_PACKSWAP_SUPPORTED)
1283
if (png_ptr->transformations & PNG_PACKSWAP)
1284
png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
1287
#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1288
/* if gray -> RGB, do so now only if we did not do so above */
1289
if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
1290
(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
1291
png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
1294
#if defined(PNG_READ_FILLER_SUPPORTED)
1295
if (png_ptr->transformations & PNG_FILLER)
1296
png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
1297
(png_uint_32)png_ptr->filler, png_ptr->flags);
1300
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1301
if (png_ptr->transformations & PNG_INVERT_ALPHA)
1302
png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
1305
#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1306
if (png_ptr->transformations & PNG_SWAP_ALPHA)
1307
png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
1310
#if defined(PNG_READ_SWAP_SUPPORTED)
1311
if (png_ptr->transformations & PNG_SWAP_BYTES)
1312
png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
1315
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1316
if (png_ptr->transformations & PNG_USER_TRANSFORM)
1318
if(png_ptr->read_user_transform_fn != NULL)
1319
(*(png_ptr->read_user_transform_fn)) /* user read transform function */
1320
(png_ptr, /* png_ptr */
1321
&(png_ptr->row_info), /* row_info: */
1322
/* png_uint_32 width; width of row */
1323
/* png_uint_32 rowbytes; number of bytes in row */
1324
/* png_byte color_type; color type of pixels */
1325
/* png_byte bit_depth; bit depth of samples */
1326
/* png_byte channels; number of channels (1-4) */
1327
/* png_byte pixel_depth; bits per pixel (depth*channels) */
1328
png_ptr->row_buf + 1); /* start of pixel data for row */
1329
#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
1330
if(png_ptr->user_transform_depth)
1331
png_ptr->row_info.bit_depth = png_ptr->user_transform_depth;
1332
if(png_ptr->user_transform_channels)
1333
png_ptr->row_info.channels = png_ptr->user_transform_channels;
1335
png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
1336
png_ptr->row_info.channels);
1337
png_ptr->row_info.rowbytes = (png_ptr->row_info.width *
1338
png_ptr->row_info.pixel_depth+7)>>3;
1344
#if defined(PNG_READ_PACK_SUPPORTED)
1345
/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
1346
* without changing the actual values. Thus, if you had a row with
1347
* a bit depth of 1, you would end up with bytes that only contained
1348
* the numbers 0 or 1. If you would rather they contain 0 and 255, use
1349
* png_do_shift() after this.
1352
png_do_unpack(png_row_infop row_info, png_bytep row)
1354
png_debug(1, "in png_do_unpack\n");
1355
#if defined(PNG_USELESS_TESTS_SUPPORTED)
1356
if (row != NULL && row_info != NULL && row_info->bit_depth < 8)
1358
if (row_info->bit_depth < 8)
1362
png_uint_32 row_width=row_info->width;
1364
switch (row_info->bit_depth)
1368
png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
1369
png_bytep dp = row + (png_size_t)row_width - 1;
1370
png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
1371
for (i = 0; i < row_width; i++)
1373
*dp = (png_byte)((*sp >> shift) & 0x01);
1389
png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
1390
png_bytep dp = row + (png_size_t)row_width - 1;
1391
png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
1392
for (i = 0; i < row_width; i++)
1394
*dp = (png_byte)((*sp >> shift) & 0x03);
1409
png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
1410
png_bytep dp = row + (png_size_t)row_width - 1;
1411
png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
1412
for (i = 0; i < row_width; i++)
1414
*dp = (png_byte)((*sp >> shift) & 0x0f);
1428
row_info->bit_depth = 8;
1429
row_info->pixel_depth = (png_byte)(8 * row_info->channels);
1430
row_info->rowbytes = row_width * row_info->channels;
1435
#if defined(PNG_READ_SHIFT_SUPPORTED)
1436
/* Reverse the effects of png_do_shift. This routine merely shifts the
1437
* pixels back to their significant bits values. Thus, if you have
1438
* a row of bit depth 8, but only 5 are significant, this will shift
1439
* the values back to 0 through 31.
1442
png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
1444
png_debug(1, "in png_do_unshift\n");
1446
#if defined(PNG_USELESS_TESTS_SUPPORTED)
1447
row != NULL && row_info != NULL && sig_bits != NULL &&
1449
row_info->color_type != PNG_COLOR_TYPE_PALETTE)
1454
png_uint_16 value = 0;
1455
png_uint_32 row_width = row_info->width;
1457
if (row_info->color_type & PNG_COLOR_MASK_COLOR)
1459
shift[channels++] = row_info->bit_depth - sig_bits->red;
1460
shift[channels++] = row_info->bit_depth - sig_bits->green;
1461
shift[channels++] = row_info->bit_depth - sig_bits->blue;
1465
shift[channels++] = row_info->bit_depth - sig_bits->gray;
1467
if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
1469
shift[channels++] = row_info->bit_depth - sig_bits->alpha;
1472
for (c = 0; c < channels; c++)
1483
switch (row_info->bit_depth)
1489
png_uint_32 istop = row_info->rowbytes;
1491
for (bp = row, i = 0; i < istop; i++)
1502
png_uint_32 istop = row_info->rowbytes;
1503
png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) |
1504
(png_byte)((int)0xf >> shift[0]));
1506
for (i = 0; i < istop; i++)
1517
png_uint_32 istop = row_width * channels;
1519
for (i = 0; i < istop; i++)
1521
*bp++ >>= shift[i%channels];
1529
png_uint_32 istop = channels * row_width;
1531
for (i = 0; i < istop; i++)
1533
value = (png_uint_16)((*bp << 8) + *(bp + 1));
1534
value >>= shift[i%channels];
1535
*bp++ = (png_byte)(value >> 8);
1536
*bp++ = (png_byte)(value & 0xff);
1545
#if defined(PNG_READ_16_TO_8_SUPPORTED)
1546
/* chop rows of bit depth 16 down to 8 */
1548
png_do_chop(png_row_infop row_info, png_bytep row)
1550
png_debug(1, "in png_do_chop\n");
1551
#if defined(PNG_USELESS_TESTS_SUPPORTED)
1552
if (row != NULL && row_info != NULL && row_info->bit_depth == 16)
1554
if (row_info->bit_depth == 16)
1560
png_uint_32 istop = row_info->width * row_info->channels;
1562
for (i = 0; i<istop; i++, sp += 2, dp++)
1564
#if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
1565
/* This does a more accurate scaling of the 16-bit color
1566
* value, rather than a simple low-byte truncation.
1568
* What the ideal calculation should be:
1569
* *dp = (((((png_uint_32)(*sp) << 8) |
1570
* (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L;
1572
* GRR: no, I think this is what it really should be:
1573
* *dp = (((((png_uint_32)(*sp) << 8) |
1574
* (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L;
1576
* GRR: here's the exact calculation with shifts:
1577
* temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L;
1578
* *dp = (temp - (temp >> 8)) >> 8;
1580
* Approximate calculation with shift/add instead of multiply/divide:
1581
* *dp = ((((png_uint_32)(*sp) << 8) |
1582
* (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
1584
* What we actually do to avoid extra shifting and conversion:
1587
*dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0);
1589
/* Simply discard the low order byte */
1593
row_info->bit_depth = 8;
1594
row_info->pixel_depth = (png_byte)(8 * row_info->channels);
1595
row_info->rowbytes = row_info->width * row_info->channels;
1600
#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1602
png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
1604
png_debug(1, "in png_do_read_swap_alpha\n");
1605
#if defined(PNG_USELESS_TESTS_SUPPORTED)
1606
if (row != NULL && row_info != NULL)
1609
png_uint_32 row_width = row_info->width;
1610
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
1612
/* This converts from RGBA to ARGB */
1613
if (row_info->bit_depth == 8)
1615
png_bytep sp = row + row_info->rowbytes;
1620
for (i = 0; i < row_width; i++)
1629
/* This converts from RRGGBBAA to AARRGGBB */
1632
png_bytep sp = row + row_info->rowbytes;
1637
for (i = 0; i < row_width; i++)
1652
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1654
/* This converts from GA to AG */
1655
if (row_info->bit_depth == 8)
1657
png_bytep sp = row + row_info->rowbytes;
1662
for (i = 0; i < row_width; i++)
1669
/* This converts from GGAA to AAGG */
1672
png_bytep sp = row + row_info->rowbytes;
1677
for (i = 0; i < row_width; i++)
1692
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1694
png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
1696
png_debug(1, "in png_do_read_invert_alpha\n");
1697
#if defined(PNG_USELESS_TESTS_SUPPORTED)
1698
if (row != NULL && row_info != NULL)
1701
png_uint_32 row_width = row_info->width;
1702
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
1704
/* This inverts the alpha channel in RGBA */
1705
if (row_info->bit_depth == 8)
1707
png_bytep sp = row + row_info->rowbytes;
1711
for (i = 0; i < row_width; i++)
1713
*(--dp) = (png_byte)(255 - *(--sp));
1715
/* This does nothing:
1719
We can replace it with:
1725
/* This inverts the alpha channel in RRGGBBAA */
1728
png_bytep sp = row + row_info->rowbytes;
1732
for (i = 0; i < row_width; i++)
1734
*(--dp) = (png_byte)(255 - *(--sp));
1735
*(--dp) = (png_byte)(255 - *(--sp));
1737
/* This does nothing:
1744
We can replace it with:
1751
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1753
/* This inverts the alpha channel in GA */
1754
if (row_info->bit_depth == 8)
1756
png_bytep sp = row + row_info->rowbytes;
1760
for (i = 0; i < row_width; i++)
1762
*(--dp) = (png_byte)(255 - *(--sp));
1766
/* This inverts the alpha channel in GGAA */
1769
png_bytep sp = row + row_info->rowbytes;
1773
for (i = 0; i < row_width; i++)
1775
*(--dp) = (png_byte)(255 - *(--sp));
1776
*(--dp) = (png_byte)(255 - *(--sp));
1790
#if defined(PNG_READ_FILLER_SUPPORTED)
1791
/* Add filler channel if we have RGB color */
1793
png_do_read_filler(png_row_infop row_info, png_bytep row,
1794
png_uint_32 filler, png_uint_32 flags)
1797
png_uint_32 row_width = row_info->width;
1799
png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
1800
png_byte lo_filler = (png_byte)(filler & 0xff);
1802
png_debug(1, "in png_do_read_filler\n");
1804
#if defined(PNG_USELESS_TESTS_SUPPORTED)
1805
row != NULL && row_info != NULL &&
1807
row_info->color_type == PNG_COLOR_TYPE_GRAY)
1809
if(row_info->bit_depth == 8)
1811
/* This changes the data from G to GX */
1812
if (flags & PNG_FLAG_FILLER_AFTER)
1814
png_bytep sp = row + (png_size_t)row_width;
1815
png_bytep dp = sp + (png_size_t)row_width;
1816
for (i = 1; i < row_width; i++)
1818
*(--dp) = lo_filler;
1821
*(--dp) = lo_filler;
1822
row_info->channels = 2;
1823
row_info->pixel_depth = 16;
1824
row_info->rowbytes = row_width * 2;
1826
/* This changes the data from G to XG */
1829
png_bytep sp = row + (png_size_t)row_width;
1830
png_bytep dp = sp + (png_size_t)row_width;
1831
for (i = 0; i < row_width; i++)
1834
*(--dp) = lo_filler;
1836
row_info->channels = 2;
1837
row_info->pixel_depth = 16;
1838
row_info->rowbytes = row_width * 2;
1841
else if(row_info->bit_depth == 16)
1843
/* This changes the data from GG to GGXX */
1844
if (flags & PNG_FLAG_FILLER_AFTER)
1846
png_bytep sp = row + (png_size_t)row_width;
1847
png_bytep dp = sp + (png_size_t)row_width;
1848
for (i = 1; i < row_width; i++)
1850
*(--dp) = hi_filler;
1851
*(--dp) = lo_filler;
1855
*(--dp) = hi_filler;
1856
*(--dp) = lo_filler;
1857
row_info->channels = 2;
1858
row_info->pixel_depth = 32;
1859
row_info->rowbytes = row_width * 4;
1861
/* This changes the data from GG to XXGG */
1864
png_bytep sp = row + (png_size_t)row_width;
1865
png_bytep dp = sp + (png_size_t)row_width;
1866
for (i = 0; i < row_width; i++)
1870
*(--dp) = hi_filler;
1871
*(--dp) = lo_filler;
1873
row_info->channels = 2;
1874
row_info->pixel_depth = 32;
1875
row_info->rowbytes = row_width * 4;
1878
} /* COLOR_TYPE == GRAY */
1879
else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
1881
if(row_info->bit_depth == 8)
1883
/* This changes the data from RGB to RGBX */
1884
if (flags & PNG_FLAG_FILLER_AFTER)
1886
png_bytep sp = row + (png_size_t)row_width * 3;
1887
png_bytep dp = sp + (png_size_t)row_width;
1888
for (i = 1; i < row_width; i++)
1890
*(--dp) = lo_filler;
1895
*(--dp) = lo_filler;
1896
row_info->channels = 4;
1897
row_info->pixel_depth = 32;
1898
row_info->rowbytes = row_width * 4;
1900
/* This changes the data from RGB to XRGB */
1903
png_bytep sp = row + (png_size_t)row_width * 3;
1904
png_bytep dp = sp + (png_size_t)row_width;
1905
for (i = 0; i < row_width; i++)
1910
*(--dp) = lo_filler;
1912
row_info->channels = 4;
1913
row_info->pixel_depth = 32;
1914
row_info->rowbytes = row_width * 4;
1917
else if(row_info->bit_depth == 16)
1919
/* This changes the data from RRGGBB to RRGGBBXX */
1920
if (flags & PNG_FLAG_FILLER_AFTER)
1922
png_bytep sp = row + (png_size_t)row_width * 3;
1923
png_bytep dp = sp + (png_size_t)row_width;
1924
for (i = 1; i < row_width; i++)
1926
*(--dp) = hi_filler;
1927
*(--dp) = lo_filler;
1935
*(--dp) = hi_filler;
1936
*(--dp) = lo_filler;
1937
row_info->channels = 4;
1938
row_info->pixel_depth = 64;
1939
row_info->rowbytes = row_width * 8;
1941
/* This changes the data from RRGGBB to XXRRGGBB */
1944
png_bytep sp = row + (png_size_t)row_width * 3;
1945
png_bytep dp = sp + (png_size_t)row_width;
1946
for (i = 0; i < row_width; i++)
1954
*(--dp) = hi_filler;
1955
*(--dp) = lo_filler;
1957
row_info->channels = 4;
1958
row_info->pixel_depth = 64;
1959
row_info->rowbytes = row_width * 8;
1962
} /* COLOR_TYPE == RGB */
1966
#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1967
/* expand grayscale files to RGB, with or without alpha */
1969
png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
1972
png_uint_32 row_width = row_info->width;
1974
png_debug(1, "in png_do_gray_to_rgb\n");
1975
if (row_info->bit_depth >= 8 &&
1976
#if defined(PNG_USELESS_TESTS_SUPPORTED)
1977
row != NULL && row_info != NULL &&
1979
!(row_info->color_type & PNG_COLOR_MASK_COLOR))
1981
if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
1983
if (row_info->bit_depth == 8)
1985
png_bytep sp = row + (png_size_t)row_width - 1;
1986
png_bytep dp = sp + (png_size_t)row_width * 2;
1987
for (i = 0; i < row_width; i++)
1996
png_bytep sp = row + (png_size_t)row_width * 2 - 1;
1997
png_bytep dp = sp + (png_size_t)row_width * 4;
1998
for (i = 0; i < row_width; i++)
2001
*(dp--) = *(sp - 1);
2003
*(dp--) = *(sp - 1);
2009
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2011
if (row_info->bit_depth == 8)
2013
png_bytep sp = row + (png_size_t)row_width * 2 - 1;
2014
png_bytep dp = sp + (png_size_t)row_width * 2;
2015
for (i = 0; i < row_width; i++)
2025
png_bytep sp = row + (png_size_t)row_width * 4 - 1;
2026
png_bytep dp = sp + (png_size_t)row_width * 4;
2027
for (i = 0; i < row_width; i++)
2032
*(dp--) = *(sp - 1);
2034
*(dp--) = *(sp - 1);
2040
row_info->channels += (png_byte)2;
2041
row_info->color_type |= PNG_COLOR_MASK_COLOR;
2042
row_info->pixel_depth = (png_byte)(row_info->channels *
2043
row_info->bit_depth);
2044
row_info->rowbytes = ((row_width *
2045
row_info->pixel_depth + 7) >> 3);
2050
#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
2051
/* reduce RGB files to grayscale, with or without alpha
2052
* using the equation given in Poynton's ColorFAQ at
2053
* <http://www.inforamp.net/~poynton/>
2054
* Copyright (c) 1998-01-04 Charles Poynton poynton@inforamp.net
2056
* Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
2058
* We approximate this with
2060
* Y = 0.21268 * R + 0.7151 * G + 0.07217 * B
2062
* which can be expressed with integers as
2064
* Y = (6969 * R + 23434 * G + 2365 * B)/32768
2066
* The calculation is to be done in a linear colorspace.
2068
* Other integer coefficents can be used via png_set_rgb_to_gray().
2071
png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
2076
png_uint_32 row_width = row_info->width;
2079
png_debug(1, "in png_do_rgb_to_gray\n");
2081
#if defined(PNG_USELESS_TESTS_SUPPORTED)
2082
row != NULL && row_info != NULL &&
2084
(row_info->color_type & PNG_COLOR_MASK_COLOR))
2086
png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
2087
png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
2088
png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff;
2090
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
2092
if (row_info->bit_depth == 8)
2094
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2095
if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
2100
for (i = 0; i < row_width; i++)
2102
png_byte red = png_ptr->gamma_to_1[*(sp++)];
2103
png_byte green = png_ptr->gamma_to_1[*(sp++)];
2104
png_byte blue = png_ptr->gamma_to_1[*(sp++)];
2105
if(red != green || red != blue)
2108
*(dp++) = png_ptr->gamma_from_1[
2109
(rc*red+gc*green+bc*blue)>>15];
2120
for (i = 0; i < row_width; i++)
2122
png_byte red = *(sp++);
2123
png_byte green = *(sp++);
2124
png_byte blue = *(sp++);
2125
if(red != green || red != blue)
2128
*(dp++) = (png_byte)((rc*red+gc*green+bc*blue)>>15);
2136
else /* RGB bit_depth == 16 */
2138
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2139
if (png_ptr->gamma_16_to_1 != NULL &&
2140
png_ptr->gamma_16_from_1 != NULL)
2144
for (i = 0; i < row_width; i++)
2146
png_uint_16 red, green, blue, w;
2148
red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2149
green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2150
blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2152
if(red == green && red == blue)
2156
png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >>
2157
png_ptr->gamma_shift][red>>8];
2158
png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
2159
png_ptr->gamma_shift][green>>8];
2160
png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
2161
png_ptr->gamma_shift][blue>>8];
2162
png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1
2164
w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
2165
png_ptr->gamma_shift][gray16 >> 8];
2169
*(dp++) = (png_byte)((w>>8) & 0xff);
2170
*(dp++) = (png_byte)(w & 0xff);
2178
for (i = 0; i < row_width; i++)
2180
png_uint_16 red, green, blue, gray16;
2182
red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2183
green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2184
blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2186
if(red != green || red != blue)
2188
gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
2189
*(dp++) = (png_byte)((gray16>>8) & 0xff);
2190
*(dp++) = (png_byte)(gray16 & 0xff);
2195
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
2197
if (row_info->bit_depth == 8)
2199
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2200
if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
2204
for (i = 0; i < row_width; i++)
2206
png_byte red = png_ptr->gamma_to_1[*(sp++)];
2207
png_byte green = png_ptr->gamma_to_1[*(sp++)];
2208
png_byte blue = png_ptr->gamma_to_1[*(sp++)];
2209
if(red != green || red != blue)
2211
*(dp++) = png_ptr->gamma_from_1
2212
[(rc*red + gc*green + bc*blue)>>15];
2213
*(dp++) = *(sp++); /* alpha */
2221
for (i = 0; i < row_width; i++)
2223
png_byte red = *(sp++);
2224
png_byte green = *(sp++);
2225
png_byte blue = *(sp++);
2226
if(red != green || red != blue)
2228
*(dp++) = (png_byte)((gc*red + gc*green + bc*blue)>>8);
2229
*(dp++) = *(sp++); /* alpha */
2233
else /* RGBA bit_depth == 16 */
2235
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2236
if (png_ptr->gamma_16_to_1 != NULL &&
2237
png_ptr->gamma_16_from_1 != NULL)
2241
for (i = 0; i < row_width; i++)
2243
png_uint_16 red, green, blue, w;
2245
red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2246
green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2247
blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2249
if(red == green && red == blue)
2253
png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >>
2254
png_ptr->gamma_shift][red>>8];
2255
png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
2256
png_ptr->gamma_shift][green>>8];
2257
png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
2258
png_ptr->gamma_shift][blue>>8];
2259
png_uint_16 gray16 = (png_uint_16)((rc * red_1
2260
+ gc * green_1 + bc * blue_1)>>15);
2261
w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
2262
png_ptr->gamma_shift][gray16 >> 8];
2266
*(dp++) = (png_byte)((w>>8) & 0xff);
2267
*(dp++) = (png_byte)(w & 0xff);
2268
*(dp++) = *(sp++); /* alpha */
2277
for (i = 0; i < row_width; i++)
2279
png_uint_16 red, green, blue, gray16;
2280
red = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
2281
green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
2282
blue = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
2283
if(red != green || red != blue)
2285
gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
2286
*(dp++) = (png_byte)((gray16>>8) & 0xff);
2287
*(dp++) = (png_byte)(gray16 & 0xff);
2288
*(dp++) = *(sp++); /* alpha */
2294
row_info->channels -= (png_byte)2;
2295
row_info->color_type &= ~PNG_COLOR_MASK_COLOR;
2296
row_info->pixel_depth = (png_byte)(row_info->channels *
2297
row_info->bit_depth);
2298
row_info->rowbytes = ((row_width *
2299
row_info->pixel_depth + 7) >> 3);
2305
/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
2306
* large of png_color. This lets grayscale images be treated as
2307
* paletted. Most useful for gamma correction and simplification
2311
png_build_grayscale_palette(int bit_depth, png_colorp palette)
2318
png_debug(1, "in png_do_build_grayscale_palette\n");
2319
if (palette == NULL)
2346
for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
2348
palette[i].red = (png_byte)v;
2349
palette[i].green = (png_byte)v;
2350
palette[i].blue = (png_byte)v;
2354
/* This function is currently unused. Do we really need it? */
2355
#if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
2357
png_correct_palette(png_structp png_ptr, png_colorp palette,
2360
png_debug(1, "in png_correct_palette\n");
2361
#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
2362
defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
2363
if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND))
2365
png_color back, back_1;
2367
if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
2369
back.red = png_ptr->gamma_table[png_ptr->background.red];
2370
back.green = png_ptr->gamma_table[png_ptr->background.green];
2371
back.blue = png_ptr->gamma_table[png_ptr->background.blue];
2373
back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
2374
back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
2375
back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
2381
g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma);
2383
if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN ||
2384
fabs(g - 1.0) < PNG_GAMMA_THRESHOLD)
2386
back.red = png_ptr->background.red;
2387
back.green = png_ptr->background.green;
2388
back.blue = png_ptr->background.blue;
2393
(png_byte)(pow((double)png_ptr->background.red/255, g) *
2396
(png_byte)(pow((double)png_ptr->background.green/255, g) *
2399
(png_byte)(pow((double)png_ptr->background.blue/255, g) *
2403
g = 1.0 / png_ptr->background_gamma;
2406
(png_byte)(pow((double)png_ptr->background.red/255, g) *
2409
(png_byte)(pow((double)png_ptr->background.green/255, g) *
2412
(png_byte)(pow((double)png_ptr->background.blue/255, g) *
2416
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
2420
for (i = 0; i < (png_uint_32)num_palette; i++)
2422
if (i < png_ptr->num_trans && png_ptr->trans[i] == 0)
2426
else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff)
2430
v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
2431
png_composite(w, v, png_ptr->trans[i], back_1.red);
2432
palette[i].red = png_ptr->gamma_from_1[w];
2434
v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
2435
png_composite(w, v, png_ptr->trans[i], back_1.green);
2436
palette[i].green = png_ptr->gamma_from_1[w];
2438
v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
2439
png_composite(w, v, png_ptr->trans[i], back_1.blue);
2440
palette[i].blue = png_ptr->gamma_from_1[w];
2444
palette[i].red = png_ptr->gamma_table[palette[i].red];
2445
palette[i].green = png_ptr->gamma_table[palette[i].green];
2446
palette[i].blue = png_ptr->gamma_table[palette[i].blue];
2454
for (i = 0; i < num_palette; i++)
2456
if (palette[i].red == (png_byte)png_ptr->trans_values.gray)
2462
palette[i].red = png_ptr->gamma_table[palette[i].red];
2463
palette[i].green = png_ptr->gamma_table[palette[i].green];
2464
palette[i].blue = png_ptr->gamma_table[palette[i].blue];
2471
#if defined(PNG_READ_GAMMA_SUPPORTED)
2472
if (png_ptr->transformations & PNG_GAMMA)
2476
for (i = 0; i < num_palette; i++)
2478
palette[i].red = png_ptr->gamma_table[palette[i].red];
2479
palette[i].green = png_ptr->gamma_table[palette[i].green];
2480
palette[i].blue = png_ptr->gamma_table[palette[i].blue];
2483
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
2487
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
2488
if (png_ptr->transformations & PNG_BACKGROUND)
2490
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
2494
back.red = (png_byte)png_ptr->background.red;
2495
back.green = (png_byte)png_ptr->background.green;
2496
back.blue = (png_byte)png_ptr->background.blue;
2498
for (i = 0; i < (int)png_ptr->num_trans; i++)
2500
if (png_ptr->trans[i] == 0)
2502
palette[i].red = back.red;
2503
palette[i].green = back.green;
2504
palette[i].blue = back.blue;
2506
else if (png_ptr->trans[i] != 0xff)
2508
png_composite(palette[i].red, png_ptr->palette[i].red,
2509
png_ptr->trans[i], back.red);
2510
png_composite(palette[i].green, png_ptr->palette[i].green,
2511
png_ptr->trans[i], back.green);
2512
png_composite(palette[i].blue, png_ptr->palette[i].blue,
2513
png_ptr->trans[i], back.blue);
2517
else /* assume grayscale palette (what else could it be?) */
2521
for (i = 0; i < num_palette; i++)
2523
if (i == (png_byte)png_ptr->trans_values.gray)
2525
palette[i].red = (png_byte)png_ptr->background.red;
2526
palette[i].green = (png_byte)png_ptr->background.green;
2527
palette[i].blue = (png_byte)png_ptr->background.blue;
2536
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
2537
/* Replace any alpha or transparency with the supplied background color.
2538
* "background" is already in the screen gamma, while "background_1" is
2539
* at a gamma of 1.0. Paletted files have already been taken care of.
2542
png_do_background(png_row_infop row_info, png_bytep row,
2543
png_color_16p trans_values, png_color_16p background,
2544
png_color_16p background_1,
2545
png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
2546
png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
2547
png_uint_16pp gamma_16_to_1, int gamma_shift)
2551
png_uint_32 row_width=row_info->width;
2554
png_debug(1, "in png_do_background\n");
2555
if (background != NULL &&
2556
#if defined(PNG_USELESS_TESTS_SUPPORTED)
2557
row != NULL && row_info != NULL &&
2559
(!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
2560
(row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values)))
2562
switch (row_info->color_type)
2564
case PNG_COLOR_TYPE_GRAY:
2566
switch (row_info->bit_depth)
2572
for (i = 0; i < row_width; i++)
2574
if ((png_uint_16)((*sp >> shift) & 0x01)
2575
== trans_values->gray)
2577
*sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
2578
*sp |= (png_byte)(background->gray << shift);
2592
#if defined(PNG_READ_GAMMA_SUPPORTED)
2593
if (gamma_table != NULL)
2597
for (i = 0; i < row_width; i++)
2599
if ((png_uint_16)((*sp >> shift) & 0x03)
2600
== trans_values->gray)
2602
*sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2603
*sp |= (png_byte)(background->gray << shift);
2607
png_byte p = (png_byte)((*sp >> shift) & 0x03);
2608
png_byte g = (png_byte)((gamma_table [p | (p << 2) |
2609
(p << 4) | (p << 6)] >> 6) & 0x03);
2610
*sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2611
*sp |= (png_byte)(g << shift);
2627
for (i = 0; i < row_width; i++)
2629
if ((png_uint_16)((*sp >> shift) & 0x03)
2630
== trans_values->gray)
2632
*sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2633
*sp |= (png_byte)(background->gray << shift);
2648
#if defined(PNG_READ_GAMMA_SUPPORTED)
2649
if (gamma_table != NULL)
2653
for (i = 0; i < row_width; i++)
2655
if ((png_uint_16)((*sp >> shift) & 0x0f)
2656
== trans_values->gray)
2658
*sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2659
*sp |= (png_byte)(background->gray << shift);
2663
png_byte p = (png_byte)((*sp >> shift) & 0x0f);
2664
png_byte g = (png_byte)((gamma_table[p |
2665
(p << 4)] >> 4) & 0x0f);
2666
*sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2667
*sp |= (png_byte)(g << shift);
2683
for (i = 0; i < row_width; i++)
2685
if ((png_uint_16)((*sp >> shift) & 0x0f)
2686
== trans_values->gray)
2688
*sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2689
*sp |= (png_byte)(background->gray << shift);
2704
#if defined(PNG_READ_GAMMA_SUPPORTED)
2705
if (gamma_table != NULL)
2708
for (i = 0; i < row_width; i++, sp++)
2710
if (*sp == trans_values->gray)
2712
*sp = (png_byte)background->gray;
2716
*sp = gamma_table[*sp];
2724
for (i = 0; i < row_width; i++, sp++)
2726
if (*sp == trans_values->gray)
2728
*sp = (png_byte)background->gray;
2736
#if defined(PNG_READ_GAMMA_SUPPORTED)
2737
if (gamma_16 != NULL)
2740
for (i = 0; i < row_width; i++, sp += 2)
2744
v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
2745
if (v == trans_values->gray)
2747
/* background is already in screen gamma */
2748
*sp = (png_byte)((background->gray >> 8) & 0xff);
2749
*(sp + 1) = (png_byte)(background->gray & 0xff);
2753
v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
2754
*sp = (png_byte)((v >> 8) & 0xff);
2755
*(sp + 1) = (png_byte)(v & 0xff);
2763
for (i = 0; i < row_width; i++, sp += 2)
2767
v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
2768
if (v == trans_values->gray)
2770
*sp = (png_byte)((background->gray >> 8) & 0xff);
2771
*(sp + 1) = (png_byte)(background->gray & 0xff);
2780
case PNG_COLOR_TYPE_RGB:
2782
if (row_info->bit_depth == 8)
2784
#if defined(PNG_READ_GAMMA_SUPPORTED)
2785
if (gamma_table != NULL)
2788
for (i = 0; i < row_width; i++, sp += 3)
2790
if (*sp == trans_values->red &&
2791
*(sp + 1) == trans_values->green &&
2792
*(sp + 2) == trans_values->blue)
2794
*sp = (png_byte)background->red;
2795
*(sp + 1) = (png_byte)background->green;
2796
*(sp + 2) = (png_byte)background->blue;
2800
*sp = gamma_table[*sp];
2801
*(sp + 1) = gamma_table[*(sp + 1)];
2802
*(sp + 2) = gamma_table[*(sp + 2)];
2810
for (i = 0; i < row_width; i++, sp += 3)
2812
if (*sp == trans_values->red &&
2813
*(sp + 1) == trans_values->green &&
2814
*(sp + 2) == trans_values->blue)
2816
*sp = (png_byte)background->red;
2817
*(sp + 1) = (png_byte)background->green;
2818
*(sp + 2) = (png_byte)background->blue;
2823
else /* if (row_info->bit_depth == 16) */
2825
#if defined(PNG_READ_GAMMA_SUPPORTED)
2826
if (gamma_16 != NULL)
2829
for (i = 0; i < row_width; i++, sp += 6)
2831
png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
2832
png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
2833
png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
2834
if (r == trans_values->red && g == trans_values->green &&
2835
b == trans_values->blue)
2837
/* background is already in screen gamma */
2838
*sp = (png_byte)((background->red >> 8) & 0xff);
2839
*(sp + 1) = (png_byte)(background->red & 0xff);
2840
*(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
2841
*(sp + 3) = (png_byte)(background->green & 0xff);
2842
*(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
2843
*(sp + 5) = (png_byte)(background->blue & 0xff);
2847
png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
2848
*sp = (png_byte)((v >> 8) & 0xff);
2849
*(sp + 1) = (png_byte)(v & 0xff);
2850
v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
2851
*(sp + 2) = (png_byte)((v >> 8) & 0xff);
2852
*(sp + 3) = (png_byte)(v & 0xff);
2853
v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
2854
*(sp + 4) = (png_byte)((v >> 8) & 0xff);
2855
*(sp + 5) = (png_byte)(v & 0xff);
2863
for (i = 0; i < row_width; i++, sp += 6)
2865
png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1));
2866
png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
2867
png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
2869
if (r == trans_values->red && g == trans_values->green &&
2870
b == trans_values->blue)
2872
*sp = (png_byte)((background->red >> 8) & 0xff);
2873
*(sp + 1) = (png_byte)(background->red & 0xff);
2874
*(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
2875
*(sp + 3) = (png_byte)(background->green & 0xff);
2876
*(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
2877
*(sp + 5) = (png_byte)(background->blue & 0xff);
2884
case PNG_COLOR_TYPE_GRAY_ALPHA:
2886
if (row_info->bit_depth == 8)
2888
#if defined(PNG_READ_GAMMA_SUPPORTED)
2889
if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
2890
gamma_table != NULL)
2894
for (i = 0; i < row_width; i++, sp += 2, dp++)
2896
png_uint_16 a = *(sp + 1);
2900
*dp = gamma_table[*sp];
2904
/* background is already in screen gamma */
2905
*dp = (png_byte)background->gray;
2911
v = gamma_to_1[*sp];
2912
png_composite(w, v, a, background_1->gray);
2913
*dp = gamma_from_1[w];
2922
for (i = 0; i < row_width; i++, sp += 2, dp++)
2924
png_byte a = *(sp + 1);
2932
*dp = (png_byte)background->gray;
2936
png_composite(*dp, *sp, a, background_1->gray);
2941
else /* if (png_ptr->bit_depth == 16) */
2943
#if defined(PNG_READ_GAMMA_SUPPORTED)
2944
if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
2945
gamma_16_to_1 != NULL)
2949
for (i = 0; i < row_width; i++, sp += 4, dp += 2)
2951
png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
2953
if (a == (png_uint_16)0xffff)
2957
v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
2958
*dp = (png_byte)((v >> 8) & 0xff);
2959
*(dp + 1) = (png_byte)(v & 0xff);
2963
/* background is already in screen gamma */
2964
*dp = (png_byte)((background->gray >> 8) & 0xff);
2965
*(dp + 1) = (png_byte)(background->gray & 0xff);
2969
png_uint_16 g, v, w;
2971
g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
2972
png_composite_16(v, g, a, background_1->gray);
2973
w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
2974
*dp = (png_byte)((w >> 8) & 0xff);
2975
*(dp + 1) = (png_byte)(w & 0xff);
2984
for (i = 0; i < row_width; i++, sp += 4, dp += 2)
2986
png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
2987
if (a == (png_uint_16)0xffff)
2989
png_memcpy(dp, sp, 2);
2993
*dp = (png_byte)((background->gray >> 8) & 0xff);
2994
*(dp + 1) = (png_byte)(background->gray & 0xff);
3000
g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3001
png_composite_16(v, g, a, background_1->gray);
3002
*dp = (png_byte)((v >> 8) & 0xff);
3003
*(dp + 1) = (png_byte)(v & 0xff);
3010
case PNG_COLOR_TYPE_RGB_ALPHA:
3012
if (row_info->bit_depth == 8)
3014
#if defined(PNG_READ_GAMMA_SUPPORTED)
3015
if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
3016
gamma_table != NULL)
3020
for (i = 0; i < row_width; i++, sp += 4, dp += 3)
3022
png_byte a = *(sp + 3);
3026
*dp = gamma_table[*sp];
3027
*(dp + 1) = gamma_table[*(sp + 1)];
3028
*(dp + 2) = gamma_table[*(sp + 2)];
3032
/* background is already in screen gamma */
3033
*dp = (png_byte)background->red;
3034
*(dp + 1) = (png_byte)background->green;
3035
*(dp + 2) = (png_byte)background->blue;
3041
v = gamma_to_1[*sp];
3042
png_composite(w, v, a, background_1->red);
3043
*dp = gamma_from_1[w];
3044
v = gamma_to_1[*(sp + 1)];
3045
png_composite(w, v, a, background_1->green);
3046
*(dp + 1) = gamma_from_1[w];
3047
v = gamma_to_1[*(sp + 2)];
3048
png_composite(w, v, a, background_1->blue);
3049
*(dp + 2) = gamma_from_1[w];
3058
for (i = 0; i < row_width; i++, sp += 4, dp += 3)
3060
png_byte a = *(sp + 3);
3065
*(dp + 1) = *(sp + 1);
3066
*(dp + 2) = *(sp + 2);
3070
*dp = (png_byte)background->red;
3071
*(dp + 1) = (png_byte)background->green;
3072
*(dp + 2) = (png_byte)background->blue;
3076
png_composite(*dp, *sp, a, background->red);
3077
png_composite(*(dp + 1), *(sp + 1), a,
3079
png_composite(*(dp + 2), *(sp + 2), a,
3085
else /* if (row_info->bit_depth == 16) */
3087
#if defined(PNG_READ_GAMMA_SUPPORTED)
3088
if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
3089
gamma_16_to_1 != NULL)
3093
for (i = 0; i < row_width; i++, sp += 8, dp += 6)
3095
png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
3096
<< 8) + (png_uint_16)(*(sp + 7)));
3097
if (a == (png_uint_16)0xffff)
3101
v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3102
*dp = (png_byte)((v >> 8) & 0xff);
3103
*(dp + 1) = (png_byte)(v & 0xff);
3104
v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
3105
*(dp + 2) = (png_byte)((v >> 8) & 0xff);
3106
*(dp + 3) = (png_byte)(v & 0xff);
3107
v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
3108
*(dp + 4) = (png_byte)((v >> 8) & 0xff);
3109
*(dp + 5) = (png_byte)(v & 0xff);
3113
/* background is already in screen gamma */
3114
*dp = (png_byte)((background->red >> 8) & 0xff);
3115
*(dp + 1) = (png_byte)(background->red & 0xff);
3116
*(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
3117
*(dp + 3) = (png_byte)(background->green & 0xff);
3118
*(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
3119
*(dp + 5) = (png_byte)(background->blue & 0xff);
3123
png_uint_16 v, w, x;
3125
v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
3126
png_composite_16(w, v, a, background->red);
3127
x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
3128
*dp = (png_byte)((x >> 8) & 0xff);
3129
*(dp + 1) = (png_byte)(x & 0xff);
3130
v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
3131
png_composite_16(w, v, a, background->green);
3132
x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
3133
*(dp + 2) = (png_byte)((x >> 8) & 0xff);
3134
*(dp + 3) = (png_byte)(x & 0xff);
3135
v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
3136
png_composite_16(w, v, a, background->blue);
3137
x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8];
3138
*(dp + 4) = (png_byte)((x >> 8) & 0xff);
3139
*(dp + 5) = (png_byte)(x & 0xff);
3148
for (i = 0; i < row_width; i++, sp += 8, dp += 6)
3150
png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
3151
<< 8) + (png_uint_16)(*(sp + 7)));
3152
if (a == (png_uint_16)0xffff)
3154
png_memcpy(dp, sp, 6);
3158
*dp = (png_byte)((background->red >> 8) & 0xff);
3159
*(dp + 1) = (png_byte)(background->red & 0xff);
3160
*(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
3161
*(dp + 3) = (png_byte)(background->green & 0xff);
3162
*(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
3163
*(dp + 5) = (png_byte)(background->blue & 0xff);
3169
png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3170
png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
3172
png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
3175
png_composite_16(v, r, a, background->red);
3176
*dp = (png_byte)((v >> 8) & 0xff);
3177
*(dp + 1) = (png_byte)(v & 0xff);
3178
png_composite_16(v, g, a, background->green);
3179
*(dp + 2) = (png_byte)((v >> 8) & 0xff);
3180
*(dp + 3) = (png_byte)(v & 0xff);
3181
png_composite_16(v, b, a, background->blue);
3182
*(dp + 4) = (png_byte)((v >> 8) & 0xff);
3183
*(dp + 5) = (png_byte)(v & 0xff);
3192
if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
3194
row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
3195
row_info->channels--;
3196
row_info->pixel_depth = (png_byte)(row_info->channels *
3197
row_info->bit_depth);
3198
row_info->rowbytes = ((row_width *
3199
row_info->pixel_depth + 7) >> 3);
3205
#if defined(PNG_READ_GAMMA_SUPPORTED)
3206
/* Gamma correct the image, avoiding the alpha channel. Make sure
3207
* you do this after you deal with the transparency issue on grayscale
3208
* or RGB images. If your bit depth is 8, use gamma_table, if it
3209
* is 16, use gamma_16_table and gamma_shift. Build these with
3210
* build_gamma_table().
3213
png_do_gamma(png_row_infop row_info, png_bytep row,
3214
png_bytep gamma_table, png_uint_16pp gamma_16_table,
3219
png_uint_32 row_width=row_info->width;
3221
png_debug(1, "in png_do_gamma\n");
3223
#if defined(PNG_USELESS_TESTS_SUPPORTED)
3224
row != NULL && row_info != NULL &&
3226
((row_info->bit_depth <= 8 && gamma_table != NULL) ||
3227
(row_info->bit_depth == 16 && gamma_16_table != NULL)))
3229
switch (row_info->color_type)
3231
case PNG_COLOR_TYPE_RGB:
3233
if (row_info->bit_depth == 8)
3236
for (i = 0; i < row_width; i++)
3238
*sp = gamma_table[*sp];
3240
*sp = gamma_table[*sp];
3242
*sp = gamma_table[*sp];
3246
else /* if (row_info->bit_depth == 16) */
3249
for (i = 0; i < row_width; i++)
3253
v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3254
*sp = (png_byte)((v >> 8) & 0xff);
3255
*(sp + 1) = (png_byte)(v & 0xff);
3257
v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3258
*sp = (png_byte)((v >> 8) & 0xff);
3259
*(sp + 1) = (png_byte)(v & 0xff);
3261
v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3262
*sp = (png_byte)((v >> 8) & 0xff);
3263
*(sp + 1) = (png_byte)(v & 0xff);
3269
case PNG_COLOR_TYPE_RGB_ALPHA:
3271
if (row_info->bit_depth == 8)
3274
for (i = 0; i < row_width; i++)
3276
*sp = gamma_table[*sp];
3278
*sp = gamma_table[*sp];
3280
*sp = gamma_table[*sp];
3285
else /* if (row_info->bit_depth == 16) */
3288
for (i = 0; i < row_width; i++)
3290
png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3291
*sp = (png_byte)((v >> 8) & 0xff);
3292
*(sp + 1) = (png_byte)(v & 0xff);
3294
v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3295
*sp = (png_byte)((v >> 8) & 0xff);
3296
*(sp + 1) = (png_byte)(v & 0xff);
3298
v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3299
*sp = (png_byte)((v >> 8) & 0xff);
3300
*(sp + 1) = (png_byte)(v & 0xff);
3306
case PNG_COLOR_TYPE_GRAY_ALPHA:
3308
if (row_info->bit_depth == 8)
3311
for (i = 0; i < row_width; i++)
3313
*sp = gamma_table[*sp];
3317
else /* if (row_info->bit_depth == 16) */
3320
for (i = 0; i < row_width; i++)
3322
png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3323
*sp = (png_byte)((v >> 8) & 0xff);
3324
*(sp + 1) = (png_byte)(v & 0xff);
3330
case PNG_COLOR_TYPE_GRAY:
3332
if (row_info->bit_depth == 2)
3335
for (i = 0; i < row_width; i += 4)
3343
((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)|
3344
((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
3345
((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
3346
((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
3350
if (row_info->bit_depth == 4)
3353
for (i = 0; i < row_width; i += 2)
3355
int msb = *sp & 0xf0;
3356
int lsb = *sp & 0x0f;
3358
*sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
3359
| (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
3363
else if (row_info->bit_depth == 8)
3366
for (i = 0; i < row_width; i++)
3368
*sp = gamma_table[*sp];
3372
else if (row_info->bit_depth == 16)
3375
for (i = 0; i < row_width; i++)
3377
png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3378
*sp = (png_byte)((v >> 8) & 0xff);
3379
*(sp + 1) = (png_byte)(v & 0xff);
3390
#if defined(PNG_READ_EXPAND_SUPPORTED)
3391
/* Expands a palette row to an RGB or RGBA row depending
3392
* upon whether you supply trans and num_trans.
3395
png_do_expand_palette(png_row_infop row_info, png_bytep row,
3396
png_colorp palette, png_bytep trans, int num_trans)
3401
png_uint_32 row_width=row_info->width;
3403
png_debug(1, "in png_do_expand_palette\n");
3405
#if defined(PNG_USELESS_TESTS_SUPPORTED)
3406
row != NULL && row_info != NULL &&
3408
row_info->color_type == PNG_COLOR_TYPE_PALETTE)
3410
if (row_info->bit_depth < 8)
3412
switch (row_info->bit_depth)
3416
sp = row + (png_size_t)((row_width - 1) >> 3);
3417
dp = row + (png_size_t)row_width - 1;
3418
shift = 7 - (int)((row_width + 7) & 0x07);
3419
for (i = 0; i < row_width; i++)
3421
if ((*sp >> shift) & 0x01)
3439
sp = row + (png_size_t)((row_width - 1) >> 2);
3440
dp = row + (png_size_t)row_width - 1;
3441
shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
3442
for (i = 0; i < row_width; i++)
3444
value = (*sp >> shift) & 0x03;
3445
*dp = (png_byte)value;
3460
sp = row + (png_size_t)((row_width - 1) >> 1);
3461
dp = row + (png_size_t)row_width - 1;
3462
shift = (int)((row_width & 0x01) << 2);
3463
for (i = 0; i < row_width; i++)
3465
value = (*sp >> shift) & 0x0f;
3466
*dp = (png_byte)value;
3480
row_info->bit_depth = 8;
3481
row_info->pixel_depth = 8;
3482
row_info->rowbytes = row_width;
3484
switch (row_info->bit_depth)
3490
sp = row + (png_size_t)row_width - 1;
3491
dp = row + (png_size_t)(row_width << 2) - 1;
3493
for (i = 0; i < row_width; i++)
3495
if ((int)(*sp) >= num_trans)
3499
*dp-- = palette[*sp].blue;
3500
*dp-- = palette[*sp].green;
3501
*dp-- = palette[*sp].red;
3504
row_info->bit_depth = 8;
3505
row_info->pixel_depth = 32;
3506
row_info->rowbytes = row_width * 4;
3507
row_info->color_type = 6;
3508
row_info->channels = 4;
3512
sp = row + (png_size_t)row_width - 1;
3513
dp = row + (png_size_t)(row_width * 3) - 1;
3515
for (i = 0; i < row_width; i++)
3517
*dp-- = palette[*sp].blue;
3518
*dp-- = palette[*sp].green;
3519
*dp-- = palette[*sp].red;
3522
row_info->bit_depth = 8;
3523
row_info->pixel_depth = 24;
3524
row_info->rowbytes = row_width * 3;
3525
row_info->color_type = 2;
3526
row_info->channels = 3;
3534
/* If the bit depth < 8, it is expanded to 8. Also, if the
3535
* transparency value is supplied, an alpha channel is built.
3538
png_do_expand(png_row_infop row_info, png_bytep row,
3539
png_color_16p trans_value)
3544
png_uint_32 row_width=row_info->width;
3546
png_debug(1, "in png_do_expand\n");
3547
#if defined(PNG_USELESS_TESTS_SUPPORTED)
3548
if (row != NULL && row_info != NULL)
3551
if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
3553
png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0);
3555
if (row_info->bit_depth < 8)
3557
switch (row_info->bit_depth)
3561
gray = (png_uint_16)(gray*0xff);
3562
sp = row + (png_size_t)((row_width - 1) >> 3);
3563
dp = row + (png_size_t)row_width - 1;
3564
shift = 7 - (int)((row_width + 7) & 0x07);
3565
for (i = 0; i < row_width; i++)
3567
if ((*sp >> shift) & 0x01)
3585
gray = (png_uint_16)(gray*0x55);
3586
sp = row + (png_size_t)((row_width - 1) >> 2);
3587
dp = row + (png_size_t)row_width - 1;
3588
shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
3589
for (i = 0; i < row_width; i++)
3591
value = (*sp >> shift) & 0x03;
3592
*dp = (png_byte)(value | (value << 2) | (value << 4) |
3608
gray = (png_uint_16)(gray*0x11);
3609
sp = row + (png_size_t)((row_width - 1) >> 1);
3610
dp = row + (png_size_t)row_width - 1;
3611
shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
3612
for (i = 0; i < row_width; i++)
3614
value = (*sp >> shift) & 0x0f;
3615
*dp = (png_byte)(value | (value << 4));
3629
row_info->bit_depth = 8;
3630
row_info->pixel_depth = 8;
3631
row_info->rowbytes = row_width;
3634
if (trans_value != NULL)
3636
if (row_info->bit_depth == 8)
3638
sp = row + (png_size_t)row_width - 1;
3639
dp = row + (png_size_t)(row_width << 1) - 1;
3640
for (i = 0; i < row_width; i++)
3649
else if (row_info->bit_depth == 16)
3651
sp = row + row_info->rowbytes - 1;
3652
dp = row + (row_info->rowbytes << 1) - 1;
3653
for (i = 0; i < row_width; i++)
3655
if (((png_uint_16)*(sp) |
3656
((png_uint_16)*(sp - 1) << 8)) == gray)
3670
row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
3671
row_info->channels = 2;
3672
row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
3673
row_info->rowbytes =
3674
((row_width * row_info->pixel_depth) >> 3);
3677
else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
3679
if (row_info->bit_depth == 8)
3681
sp = row + (png_size_t)row_info->rowbytes - 1;
3682
dp = row + (png_size_t)(row_width << 2) - 1;
3683
for (i = 0; i < row_width; i++)
3685
if (*(sp - 2) == trans_value->red &&
3686
*(sp - 1) == trans_value->green &&
3687
*(sp - 0) == trans_value->blue)
3696
else if (row_info->bit_depth == 16)
3698
sp = row + row_info->rowbytes - 1;
3699
dp = row + (png_size_t)(row_width << 3) - 1;
3700
for (i = 0; i < row_width; i++)
3702
if ((((png_uint_16)*(sp - 4) |
3703
((png_uint_16)*(sp - 5) << 8)) == trans_value->red) &&
3704
(((png_uint_16)*(sp - 2) |
3705
((png_uint_16)*(sp - 3) << 8)) == trans_value->green) &&
3706
(((png_uint_16)*(sp - 0) |
3707
((png_uint_16)*(sp - 1) << 8)) == trans_value->blue))
3725
row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
3726
row_info->channels = 4;
3727
row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
3728
row_info->rowbytes =
3729
((row_width * row_info->pixel_depth) >> 3);
3735
#if defined(PNG_READ_DITHER_SUPPORTED)
3737
png_do_dither(png_row_infop row_info, png_bytep row,
3738
png_bytep palette_lookup, png_bytep dither_lookup)
3742
png_uint_32 row_width=row_info->width;
3744
png_debug(1, "in png_do_dither\n");
3745
#if defined(PNG_USELESS_TESTS_SUPPORTED)
3746
if (row != NULL && row_info != NULL)
3749
if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
3750
palette_lookup && row_info->bit_depth == 8)
3755
for (i = 0; i < row_width; i++)
3761
/* this looks real messy, but the compiler will reduce
3762
it down to a reasonable formula. For example, with
3763
5 bits per color, we get:
3764
p = (((r >> 3) & 0x1f) << 10) |
3765
(((g >> 3) & 0x1f) << 5) |
3768
p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
3769
((1 << PNG_DITHER_RED_BITS) - 1)) <<
3770
(PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
3771
(((g >> (8 - PNG_DITHER_GREEN_BITS)) &
3772
((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
3773
(PNG_DITHER_BLUE_BITS)) |
3774
((b >> (8 - PNG_DITHER_BLUE_BITS)) &
3775
((1 << PNG_DITHER_BLUE_BITS) - 1));
3777
*dp++ = palette_lookup[p];
3779
row_info->color_type = PNG_COLOR_TYPE_PALETTE;
3780
row_info->channels = 1;
3781
row_info->pixel_depth = row_info->bit_depth;
3782
row_info->rowbytes =
3783
((row_width * row_info->pixel_depth + 7) >> 3);
3785
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
3786
palette_lookup != NULL && row_info->bit_depth == 8)
3791
for (i = 0; i < row_width; i++)
3798
p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
3799
((1 << PNG_DITHER_RED_BITS) - 1)) <<
3800
(PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
3801
(((g >> (8 - PNG_DITHER_GREEN_BITS)) &
3802
((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
3803
(PNG_DITHER_BLUE_BITS)) |
3804
((b >> (8 - PNG_DITHER_BLUE_BITS)) &
3805
((1 << PNG_DITHER_BLUE_BITS) - 1));
3807
*dp++ = palette_lookup[p];
3809
row_info->color_type = PNG_COLOR_TYPE_PALETTE;
3810
row_info->channels = 1;
3811
row_info->pixel_depth = row_info->bit_depth;
3812
row_info->rowbytes =
3813
((row_width * row_info->pixel_depth + 7) >> 3);
3815
else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
3816
dither_lookup && row_info->bit_depth == 8)
3819
for (i = 0; i < row_width; i++, sp++)
3821
*sp = dither_lookup[*sp];
3828
#ifdef PNG_FLOATING_POINT_SUPPORTED
3829
#if defined(PNG_READ_GAMMA_SUPPORTED)
3830
static int png_gamma_shift[] =
3831
{0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0};
3833
/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit
3834
* tables, we don't make a full table if we are reducing to 8-bit in
3835
* the future. Note also how the gamma_16 tables are segmented so that
3836
* we don't need to allocate > 64K chunks for a full 16-bit table.
3839
png_build_gamma_table(png_structp png_ptr)
3841
png_debug(1, "in png_build_gamma_table\n");
3842
if(png_ptr->gamma != 0.0)
3844
if (png_ptr->bit_depth <= 8)
3849
if (png_ptr->screen_gamma > .000001)
3850
g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
3854
png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
3857
for (i = 0; i < 256; i++)
3859
png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
3863
#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
3864
defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
3865
if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY))
3868
g = 1.0 / (png_ptr->gamma);
3870
png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
3873
for (i = 0; i < 256; i++)
3875
png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
3880
png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
3883
if(png_ptr->screen_gamma > 0.000001)
3884
g = 1.0 / png_ptr->screen_gamma;
3886
g = png_ptr->gamma; /* probably doing rgb_to_gray */
3888
for (i = 0; i < 256; i++)
3890
png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
3895
#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
3900
int i, j, shift, num;
3904
if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
3906
sig_bit = (int)png_ptr->sig_bit.red;
3907
if ((int)png_ptr->sig_bit.green > sig_bit)
3908
sig_bit = png_ptr->sig_bit.green;
3909
if ((int)png_ptr->sig_bit.blue > sig_bit)
3910
sig_bit = png_ptr->sig_bit.blue;
3914
sig_bit = (int)png_ptr->sig_bit.gray;
3918
shift = 16 - sig_bit;
3922
if (png_ptr->transformations & PNG_16_TO_8)
3924
if (shift < (16 - PNG_MAX_GAMMA_8))
3925
shift = (16 - PNG_MAX_GAMMA_8);
3933
png_ptr->gamma_shift = (png_byte)shift;
3935
num = (1 << (8 - shift));
3937
if (png_ptr->screen_gamma > .000001)
3938
g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
3942
png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr,
3943
(png_uint_32)(num * sizeof (png_uint_16p)));
3945
if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND))
3948
png_uint_32 last, max;
3950
for (i = 0; i < num; i++)
3952
png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
3953
(png_uint_32)(256 * sizeof (png_uint_16)));
3958
for (i = 0; i < 256; i++)
3960
fout = ((double)i + 0.5) / 256.0;
3962
max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
3965
png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
3966
[(int)(last >> (8 - shift))] = (png_uint_16)(
3967
(png_uint_16)i | ((png_uint_16)i << 8));
3971
while (last < ((png_uint_32)num << 8))
3973
png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
3974
[(int)(last >> (8 - shift))] = (png_uint_16)65535L;
3980
for (i = 0; i < num; i++)
3982
png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
3983
(png_uint_32)(256 * sizeof (png_uint_16)));
3985
ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4);
3986
for (j = 0; j < 256; j++)
3988
png_ptr->gamma_16_table[i][j] =
3989
(png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
3990
65535.0, g) * 65535.0 + .5);
3995
#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
3996
defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
3997
if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY))
4000
g = 1.0 / (png_ptr->gamma);
4002
png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr,
4003
(png_uint_32)(num * sizeof (png_uint_16p )));
4005
for (i = 0; i < num; i++)
4007
png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
4008
(png_uint_32)(256 * sizeof (png_uint_16)));
4010
ig = (((png_uint_32)i *
4011
(png_uint_32)png_gamma_shift[shift]) >> 4);
4012
for (j = 0; j < 256; j++)
4014
png_ptr->gamma_16_to_1[i][j] =
4015
(png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
4016
65535.0, g) * 65535.0 + .5);
4020
if(png_ptr->screen_gamma > 0.000001)
4021
g = 1.0 / png_ptr->screen_gamma;
4023
g = png_ptr->gamma; /* probably doing rgb_to_gray */
4025
png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr,
4026
(png_uint_32)(num * sizeof (png_uint_16p)));
4028
for (i = 0; i < num; i++)
4030
png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
4031
(png_uint_32)(256 * sizeof (png_uint_16)));
4033
ig = (((png_uint_32)i *
4034
(png_uint_32)png_gamma_shift[shift]) >> 4);
4035
for (j = 0; j < 256; j++)
4037
png_ptr->gamma_16_from_1[i][j] =
4038
(png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
4039
65535.0, g) * 65535.0 + .5);
4043
#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
4048
/* To do: install integer version of png_build_gamma_table here */