2 /* pngrtran.c - transforms the data in a row for PNG readers
4 * libpng 1.0.3 - January 14, 1999
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
7 * Copyright (c) 1996, 1997 Andreas Dilger
8 * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
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 #if defined(_MSC_VER) && !defined(__MWERKS__)
20 #define __VISUALC__ _MSC_VER
24 #pragma warning(disable:4135)
28 /* Set the action on getting a CRC error for an ancillary or critical chunk. */
30 png_set_crc_action(png_structp png_ptr
, int crit_action
, int ancil_action
)
32 png_debug(1, "in png_set_crc_action\n");
33 /* Tell libpng how we react to CRC errors in critical chunks */
36 case PNG_CRC_NO_CHANGE
: /* leave setting as is */
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
;
42 case PNG_CRC_QUIET_USE
: /* quiet/use data */
43 png_ptr
->flags
&= ~PNG_FLAG_CRC_CRITICAL_MASK
;
44 png_ptr
->flags
|= PNG_FLAG_CRC_CRITICAL_USE
|
45 PNG_FLAG_CRC_CRITICAL_IGNORE
;
47 case PNG_CRC_WARN_DISCARD
: /* not a valid action for critical data */
48 png_warning(png_ptr
, "Can't discard critical data on CRC error.");
49 case PNG_CRC_ERROR_QUIT
: /* error/quit */
52 png_ptr
->flags
&= ~PNG_FLAG_CRC_CRITICAL_MASK
;
58 case PNG_CRC_NO_CHANGE
: /* leave setting as is */
60 case PNG_CRC_WARN_USE
: /* warn/use data */
61 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
62 png_ptr
->flags
|= PNG_FLAG_CRC_ANCILLARY_USE
;
64 case PNG_CRC_QUIET_USE
: /* quiet/use data */
65 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
66 png_ptr
->flags
|= PNG_FLAG_CRC_ANCILLARY_USE
|
67 PNG_FLAG_CRC_ANCILLARY_NOWARN
;
69 case PNG_CRC_ERROR_QUIT
: /* error/quit */
70 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
71 png_ptr
->flags
|= PNG_FLAG_CRC_ANCILLARY_NOWARN
;
73 case PNG_CRC_WARN_DISCARD
: /* warn/discard data */
76 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
81 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
82 /* handle alpha and tRNS via a background color */
84 png_set_background(png_structp png_ptr
,
85 png_color_16p background_color
, int background_gamma_code
,
86 int need_expand
, double background_gamma
)
88 png_debug(1, "in png_set_background\n");
89 if (background_gamma_code
== PNG_BACKGROUND_GAMMA_UNKNOWN
)
91 png_warning(png_ptr
, "Application must supply a known background gamma");
95 png_ptr
->transformations
|= PNG_BACKGROUND
;
96 png_memcpy(&(png_ptr
->background
), background_color
, sizeof(png_color_16
));
97 png_ptr
->background_gamma
= (float)background_gamma
;
98 png_ptr
->background_gamma_type
= (png_byte
)(background_gamma_code
);
99 png_ptr
->transformations
|= (need_expand
? PNG_BACKGROUND_EXPAND
: 0);
101 /* Note: if need_expand is set and color_type is either RGB or RGB_ALPHA
102 * (in which case need_expand is superfluous anyway), the background color
103 * might actually be gray yet not be flagged as such. This is not a problem
104 * for the current code, which uses PNG_FLAG_BACKGROUND_IS_GRAY only to
105 * decide when to do the png_do_gray_to_rgb() transformation.
107 if ((need_expand
&& !(png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)) ||
108 (!need_expand
&& background_color
->red
== background_color
->green
&&
109 background_color
->red
== background_color
->blue
))
110 png_ptr
->flags
|= PNG_FLAG_BACKGROUND_IS_GRAY
;
114 #if defined(PNG_READ_16_TO_8_SUPPORTED)
115 /* strip 16 bit depth files to 8 bit depth */
117 png_set_strip_16(png_structp png_ptr
)
119 png_debug(1, "in png_set_strip_16\n");
120 png_ptr
->transformations
|= PNG_16_TO_8
;
124 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
126 png_set_strip_alpha(png_structp png_ptr
)
128 png_debug(1, "in png_set_strip_alpha\n");
129 png_ptr
->transformations
|= PNG_STRIP_ALPHA
;
133 #if defined(PNG_READ_DITHER_SUPPORTED)
134 /* Dither file to 8 bit. Supply a palette, the current number
135 * of elements in the palette, the maximum number of elements
136 * allowed, and a histogram if possible. If the current number
137 * of colors is greater then the maximum number, the palette will be
138 * modified to fit in the maximum number. "full_dither" indicates
139 * whether we need a dithering cube set up for RGB images, or if we
140 * simply are reducing the number of colors in a paletted image.
143 typedef struct png_dsort_struct
145 struct png_dsort_struct FAR
* next
;
149 typedef png_dsort FAR
* png_dsortp
;
150 typedef png_dsort FAR
* FAR
* png_dsortpp
;
153 png_set_dither(png_structp png_ptr
, png_colorp palette
,
154 int num_palette
, int maximum_colors
, png_uint_16p histogram
,
157 png_debug(1, "in png_set_dither\n");
158 png_ptr
->transformations
|= PNG_DITHER
;
164 png_ptr
->dither_index
= (png_bytep
)png_malloc(png_ptr
,
165 (png_uint_32
)(num_palette
* sizeof (png_byte
)));
166 for (i
= 0; i
< num_palette
; i
++)
167 png_ptr
->dither_index
[i
] = (png_byte
)i
;
170 if (num_palette
> maximum_colors
)
172 if (histogram
!= NULL
)
174 /* This is easy enough, just throw out the least used colors.
175 Perhaps not the best solution, but good enough. */
180 /* initialize an array to sort colors */
181 sort
= (png_bytep
)png_malloc(png_ptr
, (png_uint_32
)(num_palette
182 * sizeof (png_byte
)));
184 /* initialize the sort array */
185 for (i
= 0; i
< num_palette
; i
++)
186 sort
[i
] = (png_byte
)i
;
188 /* Find the least used palette entries by starting a
189 bubble sort, and running it until we have sorted
190 out enough colors. Note that we don't care about
191 sorting all the colors, just finding which are
194 for (i
= num_palette
- 1; i
>= maximum_colors
; i
--)
196 int done
; /* to stop early if the list is pre-sorted */
200 for (j
= 0; j
< i
; j
++)
202 if (histogram
[sort
[j
]] < histogram
[sort
[j
+ 1]])
207 sort
[j
] = sort
[j
+ 1];
216 /* swap the palette around, and set up a table, if necessary */
221 /* put all the useful colors within the max, but don't
223 for (i
= 0; i
< maximum_colors
; i
++)
225 if ((int)sort
[i
] >= maximum_colors
)
229 while ((int)sort
[j
] >= maximum_colors
);
230 palette
[i
] = palette
[j
];
238 /* move all the used colors inside the max limit, and
239 develop a translation table */
240 for (i
= 0; i
< maximum_colors
; i
++)
242 /* only move the colors we need to */
243 if ((int)sort
[i
] >= maximum_colors
)
249 while ((int)sort
[j
] >= maximum_colors
);
251 tmp_color
= palette
[j
];
252 palette
[j
] = palette
[i
];
253 palette
[i
] = tmp_color
;
254 /* indicate where the color went */
255 png_ptr
->dither_index
[j
] = (png_byte
)i
;
256 png_ptr
->dither_index
[i
] = (png_byte
)j
;
260 /* find closest color for those colors we are not using */
261 for (i
= 0; i
< num_palette
; i
++)
263 if ((int)png_ptr
->dither_index
[i
] >= maximum_colors
)
265 int min_d
, k
, min_k
, d_index
;
267 /* find the closest color to one we threw out */
268 d_index
= png_ptr
->dither_index
[i
];
269 min_d
= PNG_COLOR_DIST(palette
[d_index
], palette
[0]);
270 for (k
= 1, min_k
= 0; k
< maximum_colors
; k
++)
274 d
= PNG_COLOR_DIST(palette
[d_index
], palette
[k
]);
282 /* point to closest color */
283 png_ptr
->dither_index
[i
] = (png_byte
)min_k
;
287 png_free(png_ptr
, sort
);
291 /* This is much harder to do simply (and quickly). Perhaps
292 we need to go through a median cut routine, but those
293 don't always behave themselves with only a few colors
294 as input. So we will just find the closest two colors,
295 and throw out one of them (chosen somewhat randomly).
296 [We don't understand this at all, so if someone wants to
297 work on improving it, be our guest - AED, GRP]
303 png_bytep index_to_palette
;
304 /* where the original index currently is in the palette */
305 png_bytep palette_to_index
;
306 /* which original index points to this palette color */
308 /* initialize palette index arrays */
309 index_to_palette
= (png_bytep
)png_malloc(png_ptr
,
310 (png_uint_32
)(num_palette
* sizeof (png_byte
)));
311 palette_to_index
= (png_bytep
)png_malloc(png_ptr
,
312 (png_uint_32
)(num_palette
* sizeof (png_byte
)));
314 /* initialize the sort array */
315 for (i
= 0; i
< num_palette
; i
++)
317 index_to_palette
[i
] = (png_byte
)i
;
318 palette_to_index
[i
] = (png_byte
)i
;
321 hash
= (png_dsortpp
)png_malloc(png_ptr
, (png_uint_32
)(769 *
322 sizeof (png_dsortp
)));
323 for (i
= 0; i
< 769; i
++)
325 /* png_memset(hash, 0, 769 * sizeof (png_dsortp)); */
327 num_new_palette
= num_palette
;
329 /* initial wild guess at how far apart the farthest pixel
330 pair we will be eliminating will be. Larger
331 numbers mean more areas will be allocated, Smaller
332 numbers run the risk of not saving enough data, and
333 having to do this all over again.
335 I have not done extensive checking on this number.
339 while (num_new_palette
> maximum_colors
)
341 for (i
= 0; i
< num_new_palette
- 1; i
++)
345 for (j
= i
+ 1; j
< num_new_palette
; j
++)
349 d
= PNG_COLOR_DIST(palette
[i
], palette
[j
]);
355 t
= (png_dsortp
)png_malloc(png_ptr
, (png_uint_32
)(sizeof
358 t
->left
= (png_byte
)i
;
359 t
->right
= (png_byte
)j
;
365 for (i
= 0; i
<= max_d
; i
++)
371 for (p
= hash
[i
]; p
; p
= p
->next
)
373 if ((int)index_to_palette
[p
->left
] < num_new_palette
&&
374 (int)index_to_palette
[p
->right
] < num_new_palette
)
378 if (num_new_palette
& 1)
390 palette
[index_to_palette
[j
]] = palette
[num_new_palette
];
395 for (k
= 0; k
< num_palette
; k
++)
397 if (png_ptr
->dither_index
[k
] ==
399 png_ptr
->dither_index
[k
] =
400 index_to_palette
[next_j
];
401 if ((int)png_ptr
->dither_index
[k
] ==
403 png_ptr
->dither_index
[k
] =
408 index_to_palette
[palette_to_index
[num_new_palette
]] =
410 palette_to_index
[index_to_palette
[j
]] =
411 palette_to_index
[num_new_palette
];
413 index_to_palette
[j
] = (png_byte
)num_new_palette
;
414 palette_to_index
[num_new_palette
] = (png_byte
)j
;
416 if (num_new_palette
<= maximum_colors
)
419 if (num_new_palette
<= maximum_colors
)
424 for (i
= 0; i
< 769; i
++)
428 png_dsortp p
= hash
[i
];
434 png_free(png_ptr
, p
);
442 png_free(png_ptr
, hash
);
443 png_free(png_ptr
, palette_to_index
);
444 png_free(png_ptr
, index_to_palette
);
446 num_palette
= maximum_colors
;
448 if (png_ptr
->palette
== NULL
)
450 png_ptr
->palette
= palette
;
452 png_ptr
->num_palette
= (png_uint_16
)num_palette
;
458 int total_bits
= PNG_DITHER_RED_BITS
+ PNG_DITHER_GREEN_BITS
+
459 PNG_DITHER_BLUE_BITS
;
460 int num_red
= (1 << PNG_DITHER_RED_BITS
);
461 int num_green
= (1 << PNG_DITHER_GREEN_BITS
);
462 int num_blue
= (1 << PNG_DITHER_BLUE_BITS
);
463 png_size_t num_entries
= ((png_size_t
)1 << total_bits
);
465 png_ptr
->palette_lookup
= (png_bytep
)png_malloc(png_ptr
,
466 (png_uint_32
)(num_entries
* sizeof (png_byte
)));
468 png_memset(png_ptr
->palette_lookup
, 0, num_entries
* sizeof (png_byte
));
470 distance
= (png_bytep
)png_malloc(png_ptr
, (png_uint_32
)(num_entries
*
473 png_memset(distance
, 0xff, num_entries
* sizeof(png_byte
));
475 for (i
= 0; i
< num_palette
; i
++)
478 int r
= (palette
[i
].red
>> (8 - PNG_DITHER_RED_BITS
));
479 int g
= (palette
[i
].green
>> (8 - PNG_DITHER_GREEN_BITS
));
480 int b
= (palette
[i
].blue
>> (8 - PNG_DITHER_BLUE_BITS
));
482 for (ir
= 0; ir
< num_red
; ir
++)
484 int dr
= abs(ir
- r
);
485 int index_r
= (ir
<< (PNG_DITHER_BLUE_BITS
+ PNG_DITHER_GREEN_BITS
));
487 for (ig
= 0; ig
< num_green
; ig
++)
489 int dg
= abs(ig
- g
);
491 int dm
= ((dr
> dg
) ? dr
: dg
);
492 int index_g
= index_r
| (ig
<< PNG_DITHER_BLUE_BITS
);
494 for (ib
= 0; ib
< num_blue
; ib
++)
496 int d_index
= index_g
| ib
;
497 int db
= abs(ib
- b
);
498 int dmax
= ((dm
> db
) ? dm
: db
);
499 int d
= dmax
+ dt
+ db
;
501 if (d
< (int)distance
[d_index
])
503 distance
[d_index
] = (png_byte
)d
;
504 png_ptr
->palette_lookup
[d_index
] = (png_byte
)i
;
511 png_free(png_ptr
, distance
);
516 #if defined(PNG_READ_GAMMA_SUPPORTED)
517 /* Transform the image from the file_gamma to the screen_gamma. We
518 * only do transformations on images where the file_gamma and screen_gamma
519 * are not close reciprocals, otherwise it slows things down slightly, and
520 * also needlessly introduces small errors.
523 png_set_gamma(png_structp png_ptr
, double scrn_gamma
, double file_gamma
)
525 png_debug(1, "in png_set_gamma\n");
526 if (fabs(scrn_gamma
* file_gamma
- 1.0) > PNG_GAMMA_THRESHOLD
)
527 png_ptr
->transformations
|= PNG_GAMMA
;
528 png_ptr
->gamma
= (float)file_gamma
;
529 png_ptr
->screen_gamma
= (float)scrn_gamma
;
533 #if defined(PNG_READ_EXPAND_SUPPORTED)
534 /* Expand paletted images to rgb, expand grayscale images of
535 * less than 8 bit depth to 8 bit depth, and expand tRNS chunks
539 png_set_expand(png_structp png_ptr
)
541 png_debug(1, "in png_set_expand\n");
542 png_ptr
->transformations
|= PNG_EXPAND
;
546 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
548 png_set_gray_to_rgb(png_structp png_ptr
)
550 png_debug(1, "in png_set_gray_to_rgb\n");
551 png_ptr
->transformations
|= PNG_GRAY_TO_RGB
;
555 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
556 /* Convert a RGB image to a grayscale of the same width. This allows us,
557 * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
560 png_set_rgb_to_gray(png_structp png_ptr
, int error_action
, float red
,
563 png_debug(1, "in png_set_rgb_to_gray\n");
566 case 1: png_ptr
->transformations
|= PNG_RGB_TO_GRAY
;
568 case 2: png_ptr
->transformations
|= PNG_RGB_TO_GRAY_WARN
;
570 case 3: png_ptr
->transformations
|= PNG_RGB_TO_GRAY_ERR
;
572 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
573 #if defined(PNG_READ_EXPAND_SUPPORTED)
574 png_ptr
->transformations
|= PNG_EXPAND
;
577 png_warning(png_ptr
, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
578 png_ptr
->transformations
&= ~PNG_RGB_TO_GRAY
;
582 png_byte red_byte
= (png_byte
)(red
*255.0 + 0.5);
583 png_byte green_byte
= (png_byte
)(green
*255.0 + 0.5);
584 if(red
< 0.0 || green
< 0.0)
589 else if(red_byte
+ green_byte
> 255)
591 png_warning(png_ptr
, "ignoring out of range rgb_to_gray coefficients");
595 png_ptr
->rgb_to_gray_red_coeff
= red_byte
;
596 png_ptr
->rgb_to_gray_green_coeff
= green_byte
;
597 png_ptr
->rgb_to_gray_blue_coeff
= 255 - red_byte
- green_byte
;
602 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
604 png_set_read_user_transform_fn(png_structp png_ptr
, png_user_transform_ptr
605 read_user_transform_fn
)
607 png_debug(1, "in png_set_read_user_transform_fn\n");
608 png_ptr
->transformations
|= PNG_USER_TRANSFORM
;
609 png_ptr
->read_user_transform_fn
= read_user_transform_fn
;
613 /* Initialize everything needed for the read. This includes modifying
617 png_init_read_transformations(png_structp png_ptr
)
619 png_debug(1, "in png_init_read_transformations\n");
620 #if defined(PNG_USELESS_TESTS_SUPPORTED)
624 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
625 || defined(PNG_READ_GAMMA_SUPPORTED)
626 int color_type
= png_ptr
->color_type
;
629 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
630 if (png_ptr
->transformations
& PNG_BACKGROUND_EXPAND
)
632 if (!(color_type
& PNG_COLOR_MASK_COLOR
)) /* i.e., GRAY or GRAY_ALPHA */
634 /* expand background chunk. */
635 switch (png_ptr
->bit_depth
)
638 png_ptr
->background
.gray
*= (png_uint_16
)0xff;
639 png_ptr
->background
.red
= png_ptr
->background
.green
=
640 png_ptr
->background
.blue
= png_ptr
->background
.gray
;
643 png_ptr
->background
.gray
*= (png_uint_16
)0x55;
644 png_ptr
->background
.red
= png_ptr
->background
.green
=
645 png_ptr
->background
.blue
= png_ptr
->background
.gray
;
648 png_ptr
->background
.gray
*= (png_uint_16
)0x11;
649 png_ptr
->background
.red
= png_ptr
->background
.green
=
650 png_ptr
->background
.blue
= png_ptr
->background
.gray
;
654 png_ptr
->background
.red
= png_ptr
->background
.green
=
655 png_ptr
->background
.blue
= png_ptr
->background
.gray
;
659 else if (color_type
== PNG_COLOR_TYPE_PALETTE
)
661 png_ptr
->background
.red
=
662 png_ptr
->palette
[png_ptr
->background
.index
].red
;
663 png_ptr
->background
.green
=
664 png_ptr
->palette
[png_ptr
->background
.index
].green
;
665 png_ptr
->background
.blue
=
666 png_ptr
->palette
[png_ptr
->background
.index
].blue
;
668 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
669 if (png_ptr
->transformations
& PNG_INVERT_ALPHA
)
671 #if defined(PNG_READ_EXPAND_SUPPORTED)
672 if (!(png_ptr
->transformations
& PNG_EXPAND
))
675 /* invert the alpha channel (in tRNS) unless the pixels are
676 going to be expanded, in which case leave it for later */
678 istop
=(int)png_ptr
->num_trans
;
679 for (i
=0; i
<istop
; i
++)
680 png_ptr
->trans
[i
] = 255 - png_ptr
->trans
[i
];
689 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
690 png_ptr
->background_1
= png_ptr
->background
;
692 #if defined(PNG_READ_GAMMA_SUPPORTED)
693 if (png_ptr
->transformations
& (PNG_GAMMA
| PNG_RGB_TO_GRAY
))
695 png_build_gamma_table(png_ptr
);
696 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
697 if (png_ptr
->transformations
& PNG_BACKGROUND
)
699 if (color_type
== PNG_COLOR_TYPE_PALETTE
)
701 png_color back
, back_1
;
702 png_colorp palette
= png_ptr
->palette
;
703 int num_palette
= png_ptr
->num_palette
;
706 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_FILE
)
708 back
.red
= png_ptr
->gamma_table
[png_ptr
->background
.red
];
709 back
.green
= png_ptr
->gamma_table
[png_ptr
->background
.green
];
710 back
.blue
= png_ptr
->gamma_table
[png_ptr
->background
.blue
];
712 back_1
.red
= png_ptr
->gamma_to_1
[png_ptr
->background
.red
];
713 back_1
.green
= png_ptr
->gamma_to_1
[png_ptr
->background
.green
];
714 back_1
.blue
= png_ptr
->gamma_to_1
[png_ptr
->background
.blue
];
720 switch (png_ptr
->background_gamma_type
)
722 case PNG_BACKGROUND_GAMMA_SCREEN
:
723 g
= (png_ptr
->screen_gamma
);
726 case PNG_BACKGROUND_GAMMA_FILE
:
727 g
= 1.0 / (png_ptr
->gamma
);
728 gs
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
730 case PNG_BACKGROUND_GAMMA_UNIQUE
:
731 g
= 1.0 / (png_ptr
->background_gamma
);
732 gs
= 1.0 / (png_ptr
->background_gamma
*
733 png_ptr
->screen_gamma
);
736 g
= 1.0; /* back_1 */
740 if ( fabs(gs
- 1.0) < PNG_GAMMA_THRESHOLD
)
742 back
.red
= (png_byte
)png_ptr
->background
.red
;
743 back
.green
= (png_byte
)png_ptr
->background
.green
;
744 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
748 back
.red
= (png_byte
)(pow(
749 (double)png_ptr
->background
.red
/255, gs
) * 255.0 + .5);
750 back
.green
= (png_byte
)(pow(
751 (double)png_ptr
->background
.green
/255, gs
) * 255.0 + .5);
752 back
.blue
= (png_byte
)(pow(
753 (double)png_ptr
->background
.blue
/255, gs
) * 255.0 + .5);
756 back_1
.red
= (png_byte
)(pow(
757 (double)png_ptr
->background
.red
/255, g
) * 255.0 + .5);
758 back_1
.green
= (png_byte
)(pow(
759 (double)png_ptr
->background
.green
/255, g
) * 255.0 + .5);
760 back_1
.blue
= (png_byte
)(pow(
761 (double)png_ptr
->background
.blue
/255, g
) * 255.0 + .5);
764 for (i
= 0; i
< num_palette
; i
++)
766 if (i
< (int)png_ptr
->num_trans
&& png_ptr
->trans
[i
] != 0xff)
768 if (png_ptr
->trans
[i
] == 0)
772 else /* if (png_ptr->trans[i] != 0xff) */
776 v
= png_ptr
->gamma_to_1
[palette
[i
].red
];
777 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.red
);
778 palette
[i
].red
= png_ptr
->gamma_from_1
[w
];
780 v
= png_ptr
->gamma_to_1
[palette
[i
].green
];
781 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.green
);
782 palette
[i
].green
= png_ptr
->gamma_from_1
[w
];
784 v
= png_ptr
->gamma_to_1
[palette
[i
].blue
];
785 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.blue
);
786 palette
[i
].blue
= png_ptr
->gamma_from_1
[w
];
791 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
792 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
793 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
797 /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN)*/
799 /* color_type != PNG_COLOR_TYPE_PALETTE */
801 double m
= (double)(((png_uint_32
)1 << png_ptr
->bit_depth
) - 1);
805 switch (png_ptr
->background_gamma_type
)
807 case PNG_BACKGROUND_GAMMA_SCREEN
:
808 g
= (png_ptr
->screen_gamma
);
811 case PNG_BACKGROUND_GAMMA_FILE
:
812 g
= 1.0 / (png_ptr
->gamma
);
813 gs
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
815 case PNG_BACKGROUND_GAMMA_UNIQUE
:
816 g
= 1.0 / (png_ptr
->background_gamma
);
817 gs
= 1.0 / (png_ptr
->background_gamma
*
818 png_ptr
->screen_gamma
);
822 if (color_type
& PNG_COLOR_MASK_COLOR
)
825 png_ptr
->background_1
.red
= (png_uint_16
)(pow(
826 (double)png_ptr
->background
.red
/ m
, g
) * m
+ .5);
827 png_ptr
->background_1
.green
= (png_uint_16
)(pow(
828 (double)png_ptr
->background
.green
/ m
, g
) * m
+ .5);
829 png_ptr
->background_1
.blue
= (png_uint_16
)(pow(
830 (double)png_ptr
->background
.blue
/ m
, g
) * m
+ .5);
831 png_ptr
->background
.red
= (png_uint_16
)(pow(
832 (double)png_ptr
->background
.red
/ m
, gs
) * m
+ .5);
833 png_ptr
->background
.green
= (png_uint_16
)(pow(
834 (double)png_ptr
->background
.green
/ m
, gs
) * m
+ .5);
835 png_ptr
->background
.blue
= (png_uint_16
)(pow(
836 (double)png_ptr
->background
.blue
/ m
, gs
) * m
+ .5);
840 /* GRAY or GRAY ALPHA */
841 png_ptr
->background_1
.gray
= (png_uint_16
)(pow(
842 (double)png_ptr
->background
.gray
/ m
, g
) * m
+ .5);
843 png_ptr
->background
.gray
= (png_uint_16
)(pow(
844 (double)png_ptr
->background
.gray
/ m
, gs
) * m
+ .5);
849 /* transformation does not include PNG_BACKGROUND */
851 if (color_type
== PNG_COLOR_TYPE_PALETTE
)
853 png_colorp palette
= png_ptr
->palette
;
854 int num_palette
= png_ptr
->num_palette
;
857 for (i
= 0; i
< num_palette
; i
++)
859 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
860 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
861 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
865 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
869 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
870 /* No GAMMA transformation */
871 if (png_ptr
->transformations
& PNG_BACKGROUND
&&
872 color_type
== PNG_COLOR_TYPE_PALETTE
)
875 int istop
= (int)png_ptr
->num_trans
;
877 png_colorp palette
= png_ptr
->palette
;
879 back
.red
= (png_byte
)png_ptr
->background
.red
;
880 back
.green
= (png_byte
)png_ptr
->background
.green
;
881 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
883 for (i
= 0; i
< istop
; i
++)
885 if (png_ptr
->trans
[i
] == 0)
889 else if (png_ptr
->trans
[i
] != 0xff)
891 /* The png_composite() macro is defined in png.h */
892 png_composite(palette
[i
].red
, palette
[i
].red
,
893 png_ptr
->trans
[i
], back
.red
);
894 png_composite(palette
[i
].green
, palette
[i
].green
,
895 png_ptr
->trans
[i
], back
.green
);
896 png_composite(palette
[i
].blue
, palette
[i
].blue
,
897 png_ptr
->trans
[i
], back
.blue
);
903 #if defined(PNG_READ_SHIFT_SUPPORTED)
904 if ((png_ptr
->transformations
& PNG_SHIFT
) &&
905 color_type
== PNG_COLOR_TYPE_PALETTE
)
908 png_uint_16 istop
= png_ptr
->num_palette
;
909 int sr
= 8 - png_ptr
->sig_bit
.red
;
910 int sg
= 8 - png_ptr
->sig_bit
.green
;
911 int sb
= 8 - png_ptr
->sig_bit
.blue
;
913 if (sr
< 0 || sr
> 8)
915 if (sg
< 0 || sg
> 8)
917 if (sb
< 0 || sb
> 8)
919 for (i
= 0; i
< istop
; i
++)
921 png_ptr
->palette
[i
].red
>>= sr
;
922 png_ptr
->palette
[i
].green
>>= sg
;
923 png_ptr
->palette
[i
].blue
>>= sb
;
930 /* Modify the info structure to reflect the transformations. The
931 * info should be updated so a PNG file could be written with it,
932 * assuming the transformations result in valid PNG data.
935 png_read_transform_info(png_structp png_ptr
, png_infop info_ptr
)
937 png_debug(1, "in png_read_transform_info\n");
938 #if defined(PNG_READ_EXPAND_SUPPORTED)
939 if (png_ptr
->transformations
& PNG_EXPAND
)
941 if (info_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
943 if (png_ptr
->num_trans
)
944 info_ptr
->color_type
= PNG_COLOR_TYPE_RGB_ALPHA
;
946 info_ptr
->color_type
= PNG_COLOR_TYPE_RGB
;
947 info_ptr
->bit_depth
= 8;
948 info_ptr
->num_trans
= 0;
952 if (png_ptr
->num_trans
)
953 info_ptr
->color_type
|= PNG_COLOR_MASK_ALPHA
;
954 if (info_ptr
->bit_depth
< 8)
955 info_ptr
->bit_depth
= 8;
956 info_ptr
->num_trans
= 0;
961 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
962 if (png_ptr
->transformations
& PNG_BACKGROUND
)
964 info_ptr
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
965 info_ptr
->num_trans
= 0;
966 info_ptr
->background
= png_ptr
->background
;
970 #if defined(PNG_READ_GAMMA_SUPPORTED)
971 if (png_ptr
->transformations
& PNG_GAMMA
)
972 info_ptr
->gamma
= png_ptr
->gamma
;
975 #if defined(PNG_READ_16_TO_8_SUPPORTED)
976 if ((png_ptr
->transformations
& PNG_16_TO_8
) && info_ptr
->bit_depth
== 16)
977 info_ptr
->bit_depth
= 8;
980 #if defined(PNG_READ_DITHER_SUPPORTED)
981 if (png_ptr
->transformations
& PNG_DITHER
)
983 if (((info_ptr
->color_type
== PNG_COLOR_TYPE_RGB
) ||
984 (info_ptr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)) &&
985 png_ptr
->palette_lookup
&& info_ptr
->bit_depth
== 8)
987 info_ptr
->color_type
= PNG_COLOR_TYPE_PALETTE
;
992 #if defined(PNG_READ_PACK_SUPPORTED)
993 if ((png_ptr
->transformations
& PNG_PACK
) && info_ptr
->bit_depth
< 8)
994 info_ptr
->bit_depth
= 8;
997 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
998 if (png_ptr
->transformations
& PNG_GRAY_TO_RGB
)
999 info_ptr
->color_type
|= PNG_COLOR_MASK_COLOR
;
1002 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1003 if (png_ptr
->transformations
& PNG_RGB_TO_GRAY
)
1004 info_ptr
->color_type
&= ~PNG_COLOR_MASK_COLOR
;
1007 if (info_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1008 info_ptr
->channels
= 1;
1009 else if (info_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
1010 info_ptr
->channels
= 3;
1012 info_ptr
->channels
= 1;
1014 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1015 if (png_ptr
->transformations
& PNG_STRIP_ALPHA
)
1016 info_ptr
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
1019 if (info_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
)
1020 info_ptr
->channels
++;
1022 #if defined(PNG_READ_FILLER_SUPPORTED)
1023 /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
1024 if (png_ptr
->transformations
& PNG_FILLER
&&
1025 (info_ptr
->color_type
== PNG_COLOR_TYPE_RGB
||
1026 info_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
))
1027 ++info_ptr
->channels
;
1030 info_ptr
->pixel_depth
= (png_byte
)(info_ptr
->channels
*
1031 info_ptr
->bit_depth
);
1032 info_ptr
->rowbytes
= ((info_ptr
->width
* info_ptr
->pixel_depth
+ 7) >> 3);
1035 /* Transform the row. The order of transformations is significant,
1036 * and is very touchy. If you add a transformation, take care to
1037 * decide how it fits in with the other transformations here.
1040 png_do_read_transformations(png_structp png_ptr
)
1042 png_debug(1, "in png_do_read_transformations\n");
1043 #if !defined(PNG_USELESS_TESTS_SUPPORTED)
1044 if (png_ptr
->row_buf
== NULL
)
1046 #if !defined(PNG_NO_STDIO)
1049 sprintf(msg
, "NULL row buffer for row %ld, pass %d", png_ptr
->row_number
,
1051 png_error(png_ptr
, msg
);
1053 png_error(png_ptr
, "NULL row buffer");
1058 #if defined(PNG_READ_EXPAND_SUPPORTED)
1059 if (png_ptr
->transformations
& PNG_EXPAND
)
1061 if (png_ptr
->row_info
.color_type
== PNG_COLOR_TYPE_PALETTE
)
1063 png_do_expand_palette(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1064 png_ptr
->palette
, png_ptr
->trans
, png_ptr
->num_trans
);
1068 if (png_ptr
->num_trans
)
1069 png_do_expand(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1070 &(png_ptr
->trans_values
));
1072 png_do_expand(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1078 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1079 if (png_ptr
->transformations
& PNG_STRIP_ALPHA
)
1080 png_do_strip_filler(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1081 PNG_FLAG_FILLER_AFTER
);
1084 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1085 if (png_ptr
->transformations
& PNG_RGB_TO_GRAY
)
1088 png_do_rgb_to_gray(png_ptr
, &(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1091 png_ptr
->rgb_to_gray_status
=1;
1092 if(png_ptr
->transformations
== PNG_RGB_TO_GRAY_WARN
)
1093 png_warning(png_ptr
, "png_do_rgb_to_gray found nongray pixel");
1094 if(png_ptr
->transformations
== PNG_RGB_TO_GRAY_ERR
)
1095 png_error(png_ptr
, "png_do_rgb_to_gray found nongray pixel");
1101 From Andreas Dilger e-mail to png-implement, 26 March 1998:
1103 In most cases, the "simple transparency" should be done prior to doing
1104 gray-to-RGB, or you will have to test 3x as many bytes to check if a
1105 pixel is transparent. You would also need to make sure that the
1106 transparency information is upgraded to RGB.
1108 To summarize, the current flow is:
1109 - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
1110 with background "in place" if transparent,
1111 convert to RGB if necessary
1112 - Gray + alpha -> composite with gray background and remove alpha bytes,
1113 convert to RGB if necessary
1115 To support RGB backgrounds for gray images we need:
1116 - Gray + simple transparency -> convert to RGB + simple transparency, compare
1117 3 or 6 bytes and composite with background
1118 "in place" if transparent (3x compare/pixel
1119 compared to doing composite with gray bkgrnd)
1120 - Gray + alpha -> convert to RGB + alpha, composite with background and
1121 remove alpha bytes (3x float operations/pixel
1122 compared with composite on gray background)
1124 Greg's change will do this. The reason it wasn't done before is for
1125 performance, as this increases the per-pixel operations. If we would check
1126 in advance if the background was gray or RGB, and position the gray-to-RGB
1127 transform appropriately, then it would save a lot of work/time.
1130 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1131 /* if gray -> RGB, do so now only if background is non-gray; else do later
1132 * for performance reasons */
1133 if (png_ptr
->transformations
& PNG_GRAY_TO_RGB
&&
1134 !(png_ptr
->flags
& PNG_FLAG_BACKGROUND_IS_GRAY
))
1135 png_do_gray_to_rgb(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1138 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1139 if ((png_ptr
->transformations
& PNG_BACKGROUND
) &&
1140 ((png_ptr
->num_trans
!= 0 ) ||
1141 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
)))
1142 png_do_background(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1143 &(png_ptr
->trans_values
), &(png_ptr
->background
),
1144 &(png_ptr
->background_1
),
1145 png_ptr
->gamma_table
, png_ptr
->gamma_from_1
,
1146 png_ptr
->gamma_to_1
, png_ptr
->gamma_16_table
,
1147 png_ptr
->gamma_16_from_1
, png_ptr
->gamma_16_to_1
,
1148 png_ptr
->gamma_shift
);
1151 #if defined(PNG_READ_GAMMA_SUPPORTED)
1152 if ((png_ptr
->transformations
& PNG_GAMMA
) &&
1153 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1154 !((png_ptr
->transformations
& PNG_BACKGROUND
) &&
1155 ((png_ptr
->num_trans
!= 0) ||
1156 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
))) &&
1158 (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
))
1159 png_do_gamma(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1160 png_ptr
->gamma_table
, png_ptr
->gamma_16_table
,
1161 png_ptr
->gamma_shift
);
1164 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1165 if (png_ptr
->transformations
& PNG_16_TO_8
)
1166 png_do_chop(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1169 #if defined(PNG_READ_DITHER_SUPPORTED)
1170 if (png_ptr
->transformations
& PNG_DITHER
)
1172 png_do_dither((png_row_infop
)&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1173 png_ptr
->palette_lookup
, png_ptr
->dither_index
);
1174 if(png_ptr
->row_info
.rowbytes
== (png_uint_32
)0)
1175 png_error(png_ptr
, "png_do_dither returned rowbytes=0");
1179 #if defined(PNG_READ_INVERT_SUPPORTED)
1180 if (png_ptr
->transformations
& PNG_INVERT_MONO
)
1181 png_do_invert(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1184 #if defined(PNG_READ_SHIFT_SUPPORTED)
1185 if (png_ptr
->transformations
& PNG_SHIFT
)
1186 png_do_unshift(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1190 #if defined(PNG_READ_PACK_SUPPORTED)
1191 if (png_ptr
->transformations
& PNG_PACK
)
1192 png_do_unpack(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1195 #if defined(PNG_READ_BGR_SUPPORTED)
1196 if (png_ptr
->transformations
& PNG_BGR
)
1197 png_do_bgr(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1200 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1201 if (png_ptr
->transformations
& PNG_PACKSWAP
)
1202 png_do_packswap(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1205 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1206 /* if gray -> RGB, do so now only if we did not do so above */
1207 if (png_ptr
->transformations
& PNG_GRAY_TO_RGB
&&
1208 png_ptr
->flags
& PNG_FLAG_BACKGROUND_IS_GRAY
)
1209 png_do_gray_to_rgb(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1212 #if defined(PNG_READ_FILLER_SUPPORTED)
1213 if (png_ptr
->transformations
& PNG_FILLER
)
1214 png_do_read_filler(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1215 (png_uint_32
)png_ptr
->filler
, png_ptr
->flags
);
1218 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1219 if (png_ptr
->transformations
& PNG_INVERT_ALPHA
)
1220 png_do_read_invert_alpha(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1223 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1224 if (png_ptr
->transformations
& PNG_SWAP_ALPHA
)
1225 png_do_read_swap_alpha(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1228 #if defined(PNG_READ_SWAP_SUPPORTED)
1229 if (png_ptr
->transformations
& PNG_SWAP_BYTES
)
1230 png_do_swap(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1233 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1234 if (png_ptr
->transformations
& PNG_USER_TRANSFORM
)
1235 if(png_ptr
->read_user_transform_fn
!= NULL
)
1236 (*(png_ptr
->read_user_transform_fn
)) /* user read transform function */
1237 (png_ptr
, /* png_ptr */
1238 &(png_ptr
->row_info
), /* row_info: */
1239 /* png_uint_32 width; width of row */
1240 /* png_uint_32 rowbytes; number of bytes in row */
1241 /* png_byte color_type; color type of pixels */
1242 /* png_byte bit_depth; bit depth of samples */
1243 /* png_byte channels; number of channels (1-4) */
1244 /* png_byte pixel_depth; bits per pixel (depth*channels) */
1245 png_ptr
->row_buf
+ 1); /* start of pixel data for row */
1250 #if defined(PNG_READ_PACK_SUPPORTED)
1251 /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
1252 * without changing the actual values. Thus, if you had a row with
1253 * a bit depth of 1, you would end up with bytes that only contained
1254 * the numbers 0 or 1. If you would rather they contain 0 and 255, use
1255 * png_do_shift() after this.
1258 png_do_unpack(png_row_infop row_info
, png_bytep row
)
1260 png_debug(1, "in png_do_unpack\n");
1261 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1262 if (row
!= NULL
&& row_info
!= NULL
&& row_info
->bit_depth
< 8)
1264 if (row_info
->bit_depth
< 8)
1268 png_uint_32 row_width
=row_info
->width
;
1270 switch (row_info
->bit_depth
)
1274 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
1275 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1276 png_uint_32 shift
= 7 - (int)((row_width
+ 7) & 7);
1277 for (i
= 0; i
< row_width
; i
++)
1279 *dp
= (png_byte
)((*sp
>> shift
) & 0x1);
1295 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
1296 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1297 png_uint_32 shift
= (int)((3 - ((row_width
+ 3) & 3)) << 1);
1298 for (i
= 0; i
< row_width
; i
++)
1300 *dp
= (png_byte
)((*sp
>> shift
) & 0x3);
1315 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
1316 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1317 png_uint_32 shift
= (int)((1 - ((row_width
+ 1) & 1)) << 2);
1318 for (i
= 0; i
< row_width
; i
++)
1320 *dp
= (png_byte
)((*sp
>> shift
) & 0xf);
1334 row_info
->bit_depth
= 8;
1335 row_info
->pixel_depth
= (png_byte
)(8 * row_info
->channels
);
1336 row_info
->rowbytes
= row_width
* row_info
->channels
;
1341 #if defined(PNG_READ_SHIFT_SUPPORTED)
1342 /* Reverse the effects of png_do_shift. This routine merely shifts the
1343 * pixels back to their significant bits values. Thus, if you have
1344 * a row of bit depth 8, but only 5 are significant, this will shift
1345 * the values back to 0 through 31.
1348 png_do_unshift(png_row_infop row_info
, png_bytep row
, png_color_8p sig_bits
)
1350 png_debug(1, "in png_do_unshift\n");
1352 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1353 row
!= NULL
&& row_info
!= NULL
&& sig_bits
!= NULL
&&
1355 row_info
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
1360 png_uint_16 value
= 0;
1361 png_uint_32 row_width
= row_info
->width
;
1363 if (row_info
->color_type
& PNG_COLOR_MASK_COLOR
)
1365 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->red
;
1366 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->green
;
1367 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->blue
;
1371 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->gray
;
1373 if (row_info
->color_type
& PNG_COLOR_MASK_ALPHA
)
1375 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->alpha
;
1378 for (c
= 0; c
< channels
; c
++)
1389 switch (row_info
->bit_depth
)
1395 png_uint_32 istop
= row_info
->rowbytes
;
1397 for (bp
= row
, i
= 0; i
< istop
; i
++)
1408 png_uint_32 istop
= row_info
->rowbytes
;
1409 png_byte mask
= (png_byte
)(((int)0xf0 >> shift
[0]) & (int)0xf0) |
1410 (png_byte
)((int)0xf >> shift
[0]);
1412 for (i
= 0; i
< istop
; i
++)
1423 png_uint_32 istop
= row_width
* channels
;
1425 for (i
= 0; i
< istop
; i
++)
1427 *bp
++ >>= shift
[i%channels
];
1435 png_uint_32 istop
= channels
* row_width
;
1437 for (i
= 0; i
< istop
; i
++)
1439 value
= (png_uint_16
)((*bp
<< 8) + *(bp
+ 1));
1440 value
>>= shift
[i%channels
];
1441 *bp
++ = (png_byte
)(value
>> 8);
1442 *bp
++ = (png_byte
)(value
& 0xff);
1451 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1452 /* chop rows of bit depth 16 down to 8 */
1454 png_do_chop(png_row_infop row_info
, png_bytep row
)
1456 png_debug(1, "in png_do_chop\n");
1457 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1458 if (row
!= NULL
&& row_info
!= NULL
&& row_info
->bit_depth
== 16)
1460 if (row_info
->bit_depth
== 16)
1466 png_uint_32 istop
= row_info
->width
* row_info
->channels
;
1468 for (i
= 0; i
<istop
; i
++, sp
+= 2, dp
++)
1470 #if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
1471 /* This does a more accurate scaling of the 16-bit color
1472 * value, rather than a simple low-byte truncation.
1474 * What the ideal calculation should be:
1475 * *dp = (((((png_uint_32)(*sp) << 8) |
1476 * (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L;
1478 * GRR: no, I think this is what it really should be:
1479 * *dp = (((((png_uint_32)(*sp) << 8) |
1480 * (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L;
1482 * GRR: here's the exact calculation with shifts:
1483 * temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L;
1484 * *dp = (temp - (temp >> 8)) >> 8;
1486 * Approximate calculation with shift/add instead of multiply/divide:
1487 * *dp = ((((png_uint_32)(*sp) << 8) |
1488 * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
1490 * What we actually do to avoid extra shifting and conversion:
1493 *dp
= *sp
+ ((((int)(*(sp
+ 1)) - *sp
) > 128) ? 1 : 0);
1495 /* Simply discard the low order byte */
1499 row_info
->bit_depth
= 8;
1500 row_info
->pixel_depth
= (png_byte
)(8 * row_info
->channels
);
1501 row_info
->rowbytes
= row_info
->width
* row_info
->channels
;
1506 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1508 png_do_read_swap_alpha(png_row_infop row_info
, png_bytep row
)
1510 png_debug(1, "in png_do_read_swap_alpha\n");
1511 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1512 if (row
!= NULL
&& row_info
!= NULL
)
1515 png_uint_32 row_width
= row_info
->width
;
1516 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
1518 /* This converts from RGBA to ARGB */
1519 if (row_info
->bit_depth
== 8)
1521 png_bytep sp
= row
+ row_info
->rowbytes
;
1526 for (i
= 0; i
< row_width
; i
++)
1535 /* This converts from RRGGBBAA to AARRGGBB */
1538 png_bytep sp
= row
+ row_info
->rowbytes
;
1543 for (i
= 0; i
< row_width
; i
++)
1558 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
1560 /* This converts from GA to AG */
1561 if (row_info
->bit_depth
== 8)
1563 png_bytep sp
= row
+ row_info
->rowbytes
;
1568 for (i
= 0; i
< row_width
; i
++)
1575 /* This converts from GGAA to AAGG */
1578 png_bytep sp
= row
+ row_info
->rowbytes
;
1583 for (i
= 0; i
< row_width
; i
++)
1598 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1600 png_do_read_invert_alpha(png_row_infop row_info
, png_bytep row
)
1602 png_debug(1, "in png_do_read_invert_alpha\n");
1603 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1604 if (row
!= NULL
&& row_info
!= NULL
)
1607 png_uint_32 row_width
= row_info
->width
;
1608 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
1610 /* This inverts the alpha channel in RGBA */
1611 if (row_info
->bit_depth
== 8)
1613 png_bytep sp
= row
+ row_info
->rowbytes
;
1617 for (i
= 0; i
< row_width
; i
++)
1619 *(--dp
) = 255 - *(--sp
);
1625 /* This inverts the alpha channel in RRGGBBAA */
1628 png_bytep sp
= row
+ row_info
->rowbytes
;
1632 for (i
= 0; i
< row_width
; i
++)
1634 *(--dp
) = 255 - *(--sp
);
1635 *(--dp
) = 255 - *(--sp
);
1645 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
1647 /* This inverts the alpha channel in GA */
1648 if (row_info
->bit_depth
== 8)
1650 png_bytep sp
= row
+ row_info
->rowbytes
;
1654 for (i
= 0; i
< row_width
; i
++)
1656 *(--dp
) = 255 - *(--sp
);
1660 /* This inverts the alpha channel in GGAA */
1663 png_bytep sp
= row
+ row_info
->rowbytes
;
1667 for (i
= 0; i
< row_width
; i
++)
1669 *(--dp
) = 255 - *(--sp
);
1670 *(--dp
) = 255 - *(--sp
);
1680 #if defined(PNG_READ_FILLER_SUPPORTED)
1681 /* Add filler channel if we have RGB color */
1683 png_do_read_filler(png_row_infop row_info
, png_bytep row
,
1684 png_uint_32 filler
, png_uint_32 flags
)
1687 png_uint_32 row_width
= row_info
->width
;
1689 png_byte hi_filler
= (png_byte
)((filler
>>8) & 0xff);
1690 png_byte lo_filler
= (png_byte
)(filler
& 0xff);
1692 png_debug(1, "in png_do_read_filler\n");
1694 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1695 row
!= NULL
&& row_info
!= NULL
&&
1697 row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
1699 if(row_info
->bit_depth
== 8)
1701 /* This changes the data from G to GX */
1702 if (flags
& PNG_FLAG_FILLER_AFTER
)
1704 png_bytep sp
= row
+ (png_size_t
)row_width
;
1705 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1706 for (i
= 1; i
< row_width
; i
++)
1708 *(--dp
) = lo_filler
;
1711 *(--dp
) = lo_filler
;
1712 row_info
->channels
= 2;
1713 row_info
->pixel_depth
= 16;
1714 row_info
->rowbytes
= row_width
* 2;
1716 /* This changes the data from G to XG */
1719 png_bytep sp
= row
+ (png_size_t
)row_width
;
1720 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1721 for (i
= 0; i
< row_width
; i
++)
1724 *(--dp
) = lo_filler
;
1726 row_info
->channels
= 2;
1727 row_info
->pixel_depth
= 16;
1728 row_info
->rowbytes
= row_width
* 2;
1731 else if(row_info
->bit_depth
== 16)
1733 /* This changes the data from GG to GGXX */
1734 if (flags
& PNG_FLAG_FILLER_AFTER
)
1736 png_bytep sp
= row
+ (png_size_t
)row_width
;
1737 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1738 for (i
= 1; i
< row_width
; i
++)
1740 *(--dp
) = hi_filler
;
1741 *(--dp
) = lo_filler
;
1745 *(--dp
) = hi_filler
;
1746 *(--dp
) = lo_filler
;
1747 row_info
->channels
= 2;
1748 row_info
->pixel_depth
= 32;
1749 row_info
->rowbytes
= row_width
* 2;
1751 /* This changes the data from GG to XXGG */
1754 png_bytep sp
= row
+ (png_size_t
)row_width
;
1755 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1756 for (i
= 0; i
< row_width
; i
++)
1760 *(--dp
) = hi_filler
;
1761 *(--dp
) = lo_filler
;
1763 row_info
->channels
= 2;
1764 row_info
->pixel_depth
= 16;
1765 row_info
->rowbytes
= row_width
* 2;
1768 } /* COLOR_TYPE == GRAY */
1769 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
1771 if(row_info
->bit_depth
== 8)
1773 /* This changes the data from RGB to RGBX */
1774 if (flags
& PNG_FLAG_FILLER_AFTER
)
1776 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
1777 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1778 for (i
= 1; i
< row_width
; i
++)
1780 *(--dp
) = lo_filler
;
1785 *(--dp
) = lo_filler
;
1786 row_info
->channels
= 4;
1787 row_info
->pixel_depth
= 32;
1788 row_info
->rowbytes
= row_width
* 4;
1790 /* This changes the data from RGB to XRGB */
1793 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
1794 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1795 for (i
= 0; i
< row_width
; i
++)
1800 *(--dp
) = lo_filler
;
1802 row_info
->channels
= 4;
1803 row_info
->pixel_depth
= 32;
1804 row_info
->rowbytes
= row_width
* 4;
1807 else if(row_info
->bit_depth
== 16)
1809 /* This changes the data from RRGGBB to RRGGBBXX */
1810 if (flags
& PNG_FLAG_FILLER_AFTER
)
1812 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
1813 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1814 for (i
= 1; i
< row_width
; i
++)
1816 *(--dp
) = hi_filler
;
1817 *(--dp
) = lo_filler
;
1825 *(--dp
) = hi_filler
;
1826 *(--dp
) = lo_filler
;
1827 row_info
->channels
= 4;
1828 row_info
->pixel_depth
= 64;
1829 row_info
->rowbytes
= row_width
* 4;
1831 /* This changes the data from RRGGBB to XXRRGGBB */
1834 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
1835 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1836 for (i
= 0; i
< row_width
; i
++)
1844 *(--dp
) = hi_filler
;
1845 *(--dp
) = lo_filler
;
1847 row_info
->channels
= 4;
1848 row_info
->pixel_depth
= 64;
1849 row_info
->rowbytes
= row_width
* 4;
1852 } /* COLOR_TYPE == RGB */
1856 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1857 /* expand grayscale files to RGB, with or without alpha */
1859 png_do_gray_to_rgb(png_row_infop row_info
, png_bytep row
)
1862 png_uint_32 row_width
= row_info
->width
;
1864 png_debug(1, "in png_do_gray_to_rgb\n");
1865 if (row_info
->bit_depth
>= 8 &&
1866 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1867 row
!= NULL
&& row_info
!= NULL
&&
1869 !(row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
1871 if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
1873 if (row_info
->bit_depth
== 8)
1875 png_bytep sp
= row
+ (png_size_t
)row_width
- 1;
1876 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
1877 for (i
= 0; i
< row_width
; i
++)
1887 png_bytep sp
= row
+ (png_size_t
)row_width
* 2 - 1;
1888 png_bytep dp
= sp
+ (png_size_t
)row_width
* 4;
1889 for (i
= 0; i
< row_width
; i
++)
1892 *(dp
--) = *(sp
- 1);
1894 *(dp
--) = *(sp
- 1);
1896 *(dp
--) = *(sp
- 1);
1902 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
1904 if (row_info
->bit_depth
== 8)
1906 png_bytep sp
= row
+ (png_size_t
)row_width
* 2 - 1;
1907 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
1908 for (i
= 0; i
< row_width
; i
++)
1919 png_bytep sp
= row
+ (png_size_t
)row_width
* 4 - 1;
1920 png_bytep dp
= sp
+ (png_size_t
)row_width
* 4;
1921 for (i
= 0; i
< row_width
; i
++)
1926 *(dp
--) = *(sp
- 1);
1928 *(dp
--) = *(sp
- 1);
1930 *(dp
--) = *(sp
- 1);
1936 row_info
->channels
+= (png_byte
)2;
1937 row_info
->color_type
|= PNG_COLOR_MASK_COLOR
;
1938 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
1939 row_info
->bit_depth
);
1940 row_info
->rowbytes
= ((row_width
*
1941 row_info
->pixel_depth
+ 7) >> 3);
1946 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1947 /* reduce RGB files to grayscale, with or without alpha
1948 * using the equation given in Poynton's ColorFAQ at
1949 * <http://www.inforamp.net/~poynton/>
1950 * Copyright (c) 1998-01-04 Charles Poynton poynton@inforamp.net
1952 * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
1954 * We approximate this with
1956 * Y = 0.211 * R + 0.715 * G + 0.074 * B
1958 * which can be expressed with integers as
1960 * Y = (54 * R + 183 * G + 19 * B)/256
1962 * The calculation is to be done in a linear colorspace.
1964 * Other integer coefficents can be used via png_set_rgb_to_gray().
1967 png_do_rgb_to_gray(png_structp png_ptr
, png_row_infop row_info
, png_bytep row
)
1972 png_uint_32 row_width
= row_info
->width
;
1975 png_debug(1, "in png_do_rgb_to_gray\n");
1977 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1978 row
!= NULL
&& row_info
!= NULL
&&
1980 (row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
1982 png_byte rc
= png_ptr
->rgb_to_gray_red_coeff
;
1983 png_byte gc
= png_ptr
->rgb_to_gray_green_coeff
;
1984 png_byte bc
= png_ptr
->rgb_to_gray_blue_coeff
;
1986 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
1988 if (row_info
->bit_depth
== 8)
1990 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
1991 if (png_ptr
->gamma_from_1
!= NULL
&& png_ptr
->gamma_to_1
!= NULL
)
1996 for (i
= 0; i
< row_width
; i
++)
1998 png_byte red
= png_ptr
->gamma_to_1
[*(sp
++)];
1999 png_byte green
= png_ptr
->gamma_to_1
[*(sp
++)];
2000 png_byte blue
= png_ptr
->gamma_to_1
[*(sp
++)];
2001 if(red
!= green
|| red
!= blue
)
2004 *(dp
++) = png_ptr
->gamma_from_1
[
2005 (rc
*red
+gc
*green
+bc
*blue
)>>8];
2016 for (i
= 0; i
< row_width
; i
++)
2018 png_byte red
= *(sp
++);
2019 png_byte green
= *(sp
++);
2020 png_byte blue
= *(sp
++);
2021 if(red
!= green
|| red
!= blue
)
2024 *(dp
++) = (rc
*red
+gc
*green
+bc
*blue
)>>8;
2032 else /* RGB bit_depth == 16 */
2034 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2035 if (png_ptr
->gamma_16_to_1
!= NULL
&&
2036 png_ptr
->gamma_16_from_1
!= NULL
)
2040 for (i
= 0; i
< row_width
; i
++)
2042 png_uint_16 red
, green
, blue
, w
;
2044 red
= ((*(sp
))<<8) | *(sp
+1); sp
+=2;
2045 green
= ((*(sp
))<<8) | *(sp
+1); sp
+=2;
2046 blue
= ((*(sp
))<<8) | *(sp
+1); sp
+=2;
2048 if(red
== green
&& red
== blue
)
2052 png_uint_16 red_1
= png_ptr
->gamma_16_to_1
[(red
&0xff) >>
2053 png_ptr
->gamma_shift
][red
>>8];
2054 png_uint_16 green_1
= png_ptr
->gamma_16_to_1
[(green
&0xff) >>
2055 png_ptr
->gamma_shift
][green
>>8];
2056 png_uint_16 blue_1
= png_ptr
->gamma_16_to_1
[(blue
&0xff) >>
2057 png_ptr
->gamma_shift
][blue
>>8];
2058 png_uint_16 gray16
= (rc
* red_1
+ gc
* green_1
2060 w
= png_ptr
->gamma_16_from_1
[(gray16
&0xff) >>
2061 png_ptr
->gamma_shift
][gray16
>> 8];
2065 *(dp
++) = (w
>>8) & 0xff;
2074 for (i
= 0; i
< row_width
; i
++)
2076 png_uint_16 red
, green
, blue
, gray16
;
2078 red
= ((*(sp
))<<8) | *(sp
+1); sp
+=2;
2079 green
= ((*(sp
))<<8) | *(sp
+1); sp
+=2;
2080 blue
= ((*(sp
))<<8) | *(sp
+1); sp
+=2;
2082 if(red
!= green
|| red
!= blue
)
2084 gray16
= (rc
* red
+ gc
* green
+ bc
* blue
)>>8;
2085 *(dp
++) = (gray16
>>8) & 0xff;
2086 *(dp
++) = gray16
& 0xff;
2091 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
2093 if (row_info
->bit_depth
== 8)
2095 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2096 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
)
2107 *(dp
++) = png_ptr
->gamma_from_1
2108 [(rc
*red
+ gc
*green
+ bc
*blue
)>>8];
2109 *(dp
++) = *(sp
++); /* alpha */
2117 for (i
= 0; i
< row_width
; i
++)
2119 png_byte red
= *(sp
++);
2120 png_byte green
= *(sp
++);
2121 png_byte blue
= *(sp
++);
2122 if(red
!= green
|| red
!= blue
)
2124 *(dp
++) = (gc
*red
+ gc
*green
+ bc
*blue
)>>8;
2125 *(dp
++) = *(sp
++); /* alpha */
2129 else /* RGBA bit_depth == 16 */
2131 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2132 if (png_ptr
->gamma_16_to_1
!= NULL
&&
2133 png_ptr
->gamma_16_from_1
!= NULL
)
2137 for (i
= 0; i
< row_width
; i
++)
2139 png_uint_16 red
, green
, blue
, w
;
2141 red
= ((*(sp
))<<8) | *(sp
+1); sp
+=2;
2142 green
= ((*(sp
))<<8) | *(sp
+1); sp
+=2;
2143 blue
= ((*(sp
))<<8) | *(sp
+1); sp
+=2;
2145 if(red
== green
&& red
== blue
)
2149 png_uint_16 red_1
= png_ptr
->gamma_16_to_1
[(red
&0xff) >>
2150 png_ptr
->gamma_shift
][red
>>8];
2151 png_uint_16 green_1
= png_ptr
->gamma_16_to_1
[(green
&0xff) >>
2152 png_ptr
->gamma_shift
][green
>>8];
2153 png_uint_16 blue_1
= png_ptr
->gamma_16_to_1
[(blue
&0xff) >>
2154 png_ptr
->gamma_shift
][blue
>>8];
2155 png_uint_16 gray16
= (rc
* red_1
+ gc
* green_1
2157 w
= png_ptr
->gamma_16_from_1
[(gray16
&0xff) >>
2158 png_ptr
->gamma_shift
][gray16
>> 8];
2162 *(dp
++) = (w
>>8) & 0xff;
2164 *(dp
++) = *(sp
++); /* alpha */
2173 for (i
= 0; i
< row_width
; i
++)
2175 png_uint_16 red
, green
, blue
, gray16
;
2176 red
= (*(sp
)<<8) | *(sp
+1); sp
+=2;
2177 green
= (*(sp
)<<8) | *(sp
+1); sp
+=2;
2178 blue
= (*(sp
)<<8) | *(sp
+1); sp
+=2;
2179 if(red
!= green
|| red
!= blue
)
2181 gray16
= (rc
* red
+ gc
* green
+ bc
* blue
)>>8;
2182 *(dp
++) = (gray16
>>8) & 0xff;
2183 *(dp
++) = gray16
& 0xff;
2184 *(dp
++) = *(sp
++); /* alpha */
2190 row_info
->channels
-= (png_byte
)2;
2191 row_info
->color_type
&= ~PNG_COLOR_MASK_COLOR
;
2192 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
2193 row_info
->bit_depth
);
2194 row_info
->rowbytes
= ((row_width
*
2195 row_info
->pixel_depth
+ 7) >> 3);
2201 /* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
2202 * large of png_color. This lets grayscale images be treated as
2203 * paletted. Most useful for gamma correction and simplification
2207 png_build_grayscale_palette(int bit_depth
, png_colorp palette
)
2214 png_debug(1, "in png_do_build_grayscale_palette\n");
2215 if (palette
== NULL
)
2242 for (i
= 0, v
= 0; i
< num_palette
; i
++, v
+= color_inc
)
2244 palette
[i
].red
= (png_byte
)v
;
2245 palette
[i
].green
= (png_byte
)v
;
2246 palette
[i
].blue
= (png_byte
)v
;
2250 /* This function is currently unused. Do we really need it? */
2251 #if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
2253 png_correct_palette(png_structp png_ptr
, png_colorp palette
,
2256 png_debug(1, "in png_correct_palette\n");
2257 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
2258 if (png_ptr
->transformations
& (PNG_GAMMA
| PNG_BACKGROUND
))
2260 png_color back
, back_1
;
2262 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_FILE
)
2264 back
.red
= png_ptr
->gamma_table
[png_ptr
->background
.red
];
2265 back
.green
= png_ptr
->gamma_table
[png_ptr
->background
.green
];
2266 back
.blue
= png_ptr
->gamma_table
[png_ptr
->background
.blue
];
2268 back_1
.red
= png_ptr
->gamma_to_1
[png_ptr
->background
.red
];
2269 back_1
.green
= png_ptr
->gamma_to_1
[png_ptr
->background
.green
];
2270 back_1
.blue
= png_ptr
->gamma_to_1
[png_ptr
->background
.blue
];
2276 g
= 1.0 / (png_ptr
->background_gamma
* png_ptr
->screen_gamma
);
2278 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_SCREEN
||
2279 fabs(g
- 1.0) < PNG_GAMMA_THRESHOLD
)
2281 back
.red
= png_ptr
->background
.red
;
2282 back
.green
= png_ptr
->background
.green
;
2283 back
.blue
= png_ptr
->background
.blue
;
2288 (png_byte
)(pow((double)png_ptr
->background
.red
/255, g
) *
2291 (png_byte
)(pow((double)png_ptr
->background
.green
/255, g
) *
2294 (png_byte
)(pow((double)png_ptr
->background
.blue
/255, g
) *
2298 g
= 1.0 / png_ptr
->background_gamma
;
2301 (png_byte
)(pow((double)png_ptr
->background
.red
/255, g
) *
2304 (png_byte
)(pow((double)png_ptr
->background
.green
/255, g
) *
2307 (png_byte
)(pow((double)png_ptr
->background
.blue
/255, g
) *
2311 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
2315 for (i
= 0; i
< (png_uint_32
)num_palette
; i
++)
2317 if (i
< png_ptr
->num_trans
&& png_ptr
->trans
[i
] == 0)
2321 else if (i
< png_ptr
->num_trans
&& png_ptr
->trans
[i
] != 0xff)
2325 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].red
];
2326 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.red
);
2327 palette
[i
].red
= png_ptr
->gamma_from_1
[w
];
2329 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].green
];
2330 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.green
);
2331 palette
[i
].green
= png_ptr
->gamma_from_1
[w
];
2333 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].blue
];
2334 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.blue
);
2335 palette
[i
].blue
= png_ptr
->gamma_from_1
[w
];
2339 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2340 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2341 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2349 for (i
= 0; i
< num_palette
; i
++)
2351 if (palette
[i
].red
== (png_byte
)png_ptr
->trans_values
.gray
)
2357 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2358 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2359 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2366 #if defined(PNG_READ_GAMMA_SUPPORTED)
2367 if (png_ptr
->transformations
& PNG_GAMMA
)
2371 for (i
= 0; i
< num_palette
; i
++)
2373 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2374 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2375 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2378 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2382 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2383 if (png_ptr
->transformations
& PNG_BACKGROUND
)
2385 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
2389 back
.red
= (png_byte
)png_ptr
->background
.red
;
2390 back
.green
= (png_byte
)png_ptr
->background
.green
;
2391 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
2393 for (i
= 0; i
< (int)png_ptr
->num_trans
; i
++)
2395 if (png_ptr
->trans
[i
] == 0)
2397 palette
[i
].red
= back
.red
;
2398 palette
[i
].green
= back
.green
;
2399 palette
[i
].blue
= back
.blue
;
2401 else if (png_ptr
->trans
[i
] != 0xff)
2403 png_composite(palette
[i
].red
, png_ptr
->palette
[i
].red
,
2404 png_ptr
->trans
[i
], back
.red
);
2405 png_composite(palette
[i
].green
, png_ptr
->palette
[i
].green
,
2406 png_ptr
->trans
[i
], back
.green
);
2407 png_composite(palette
[i
].blue
, png_ptr
->palette
[i
].blue
,
2408 png_ptr
->trans
[i
], back
.blue
);
2412 else /* assume grayscale palette (what else could it be?) */
2416 for (i
= 0; i
< num_palette
; i
++)
2418 if (i
== (png_byte
)png_ptr
->trans_values
.gray
)
2420 palette
[i
].red
= (png_byte
)png_ptr
->background
.red
;
2421 palette
[i
].green
= (png_byte
)png_ptr
->background
.green
;
2422 palette
[i
].blue
= (png_byte
)png_ptr
->background
.blue
;
2431 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2432 /* Replace any alpha or transparency with the supplied background color.
2433 * "background" is already in the screen gamma, while "background_1" is
2434 * at a gamma of 1.0. Paletted files have already been taken care of.
2437 png_do_background(png_row_infop row_info
, png_bytep row
,
2438 png_color_16p trans_values
, png_color_16p background
,
2439 png_color_16p background_1
,
2440 png_bytep gamma_table
, png_bytep gamma_from_1
, png_bytep gamma_to_1
,
2441 png_uint_16pp gamma_16
, png_uint_16pp gamma_16_from_1
,
2442 png_uint_16pp gamma_16_to_1
, int gamma_shift
)
2446 png_uint_32 row_width
=row_info
->width
;
2449 png_debug(1, "in png_do_background\n");
2450 if (background
!= NULL
&&
2451 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2452 row
!= NULL
&& row_info
!= NULL
&&
2454 (!(row_info
->color_type
& PNG_COLOR_MASK_ALPHA
) ||
2455 (row_info
->color_type
!= PNG_COLOR_TYPE_PALETTE
&& trans_values
)))
2457 switch (row_info
->color_type
)
2459 case PNG_COLOR_TYPE_GRAY
:
2461 switch (row_info
->bit_depth
)
2467 for (i
= 0; i
< row_width
; i
++)
2469 if ((png_uint_16
)((*sp
>> shift
) & 0x1)
2470 == trans_values
->gray
)
2472 *sp
&= (png_byte
)((0x7f7f >> (7 - shift
)) & 0xff);
2473 *sp
|= (png_byte
)(background
->gray
<< shift
);
2487 #if defined(PNG_READ_GAMMA_SUPPORTED)
2488 if (gamma_table
!= NULL
)
2492 for (i
= 0; i
< row_width
; i
++)
2494 if ((png_uint_16
)((*sp
>> shift
) & 0x3)
2495 == trans_values
->gray
)
2497 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2498 *sp
|= (png_byte
)(background
->gray
<< shift
);
2502 png_byte p
= (*sp
>> shift
) & 0x3;
2503 png_byte g
= (gamma_table
[p
| (p
<< 2) | (p
<< 4) |
2504 (p
<< 6)] >> 6) & 0x3;
2505 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2506 *sp
|= (png_byte
)(g
<< shift
);
2522 for (i
= 0; i
< row_width
; i
++)
2524 if ((png_uint_16
)((*sp
>> shift
) & 0x3)
2525 == trans_values
->gray
)
2527 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2528 *sp
|= (png_byte
)(background
->gray
<< shift
);
2543 #if defined(PNG_READ_GAMMA_SUPPORTED)
2544 if (gamma_table
!= NULL
)
2548 for (i
= 0; i
< row_width
; i
++)
2550 if ((png_uint_16
)((*sp
>> shift
) & 0xf)
2551 == trans_values
->gray
)
2553 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2554 *sp
|= (png_byte
)(background
->gray
<< shift
);
2558 png_byte p
= (*sp
>> shift
) & 0xf;
2559 png_byte g
= (gamma_table
[p
| (p
<< 4)] >> 4) & 0xf;
2560 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2561 *sp
|= (png_byte
)(g
<< shift
);
2577 for (i
= 0; i
< row_width
; i
++)
2579 if ((png_uint_16
)((*sp
>> shift
) & 0xf)
2580 == trans_values
->gray
)
2582 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2583 *sp
|= (png_byte
)(background
->gray
<< shift
);
2598 #if defined(PNG_READ_GAMMA_SUPPORTED)
2599 if (gamma_table
!= NULL
)
2602 for (i
= 0; i
< row_width
; i
++, sp
++)
2604 if (*sp
== trans_values
->gray
)
2606 *sp
= (png_byte
)background
->gray
;
2610 *sp
= gamma_table
[*sp
];
2618 for (i
= 0; i
< row_width
; i
++, sp
++)
2620 if (*sp
== trans_values
->gray
)
2622 *sp
= (png_byte
)background
->gray
;
2630 #if defined(PNG_READ_GAMMA_SUPPORTED)
2631 if (gamma_16
!= NULL
)
2634 for (i
= 0; i
< row_width
; i
++, sp
+= 2)
2638 v
= ((png_uint_16
)(*sp
) << 8) + *(sp
+ 1);
2639 if (v
== trans_values
->gray
)
2641 /* background is already in screen gamma */
2642 *sp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2643 *(sp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2647 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2648 *sp
= (png_byte
)((v
>> 8) & 0xff);
2649 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2657 for (i
= 0; i
< row_width
; i
++, sp
+= 2)
2661 v
= ((png_uint_16
)(*sp
) << 8) + *(sp
+ 1);
2662 if (v
== trans_values
->gray
)
2664 *sp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2665 *(sp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2674 case PNG_COLOR_TYPE_RGB
:
2676 if (row_info
->bit_depth
== 8)
2678 #if defined(PNG_READ_GAMMA_SUPPORTED)
2679 if (gamma_table
!= NULL
)
2682 for (i
= 0; i
< row_width
; i
++, sp
+= 3)
2684 if (*sp
== trans_values
->red
&&
2685 *(sp
+ 1) == trans_values
->green
&&
2686 *(sp
+ 2) == trans_values
->blue
)
2688 *sp
= (png_byte
)background
->red
;
2689 *(sp
+ 1) = (png_byte
)background
->green
;
2690 *(sp
+ 2) = (png_byte
)background
->blue
;
2694 *sp
= gamma_table
[*sp
];
2695 *(sp
+ 1) = gamma_table
[*(sp
+ 1)];
2696 *(sp
+ 2) = gamma_table
[*(sp
+ 2)];
2704 for (i
= 0; i
< row_width
; i
++, sp
+= 3)
2706 if (*sp
== trans_values
->red
&&
2707 *(sp
+ 1) == trans_values
->green
&&
2708 *(sp
+ 2) == trans_values
->blue
)
2710 *sp
= (png_byte
)background
->red
;
2711 *(sp
+ 1) = (png_byte
)background
->green
;
2712 *(sp
+ 2) = (png_byte
)background
->blue
;
2717 else /* if (row_info->bit_depth == 16) */
2719 #if defined(PNG_READ_GAMMA_SUPPORTED)
2720 if (gamma_16
!= NULL
)
2723 for (i
= 0; i
< row_width
; i
++, sp
+= 6)
2725 png_uint_16 r
= ((png_uint_16
)(*sp
) << 8) + *(sp
+ 1);
2726 png_uint_16 g
= ((png_uint_16
)(*(sp
+ 2)) << 8) + *(sp
+ 3);
2727 png_uint_16 b
= ((png_uint_16
)(*(sp
+ 4)) << 8) + *(sp
+ 5);
2728 if (r
== trans_values
->red
&& g
== trans_values
->green
&&
2729 b
== trans_values
->blue
)
2731 /* background is already in screen gamma */
2732 *sp
= (png_byte
)((background
->red
>> 8) & 0xff);
2733 *(sp
+ 1) = (png_byte
)(background
->red
& 0xff);
2734 *(sp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
2735 *(sp
+ 3) = (png_byte
)(background
->green
& 0xff);
2736 *(sp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
2737 *(sp
+ 5) = (png_byte
)(background
->blue
& 0xff);
2741 png_uint_16 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2742 *sp
= (png_byte
)((v
>> 8) & 0xff);
2743 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2744 v
= gamma_16
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
2745 *(sp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
2746 *(sp
+ 3) = (png_byte
)(v
& 0xff);
2747 v
= gamma_16
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
2748 *(sp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
2749 *(sp
+ 5) = (png_byte
)(v
& 0xff);
2757 for (i
= 0; i
< row_width
; i
++, sp
+= 6)
2759 png_uint_16 r
= ((png_uint_16
)(*sp
) << 8) + *(sp
+ 1);
2760 png_uint_16 g
= ((png_uint_16
)(*(sp
+ 2)) << 8) + *(sp
+ 3);
2761 png_uint_16 b
= ((png_uint_16
)(*(sp
+ 4)) << 8) + *(sp
+ 5);
2763 if (r
== trans_values
->red
&& g
== trans_values
->green
&&
2764 b
== trans_values
->blue
)
2766 *sp
= (png_byte
)((background
->red
>> 8) & 0xff);
2767 *(sp
+ 1) = (png_byte
)(background
->red
& 0xff);
2768 *(sp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
2769 *(sp
+ 3) = (png_byte
)(background
->green
& 0xff);
2770 *(sp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
2771 *(sp
+ 5) = (png_byte
)(background
->blue
& 0xff);
2778 case PNG_COLOR_TYPE_GRAY_ALPHA
:
2780 if (row_info
->bit_depth
== 8)
2782 #if defined(PNG_READ_GAMMA_SUPPORTED)
2783 if (gamma_to_1
!= NULL
&& gamma_from_1
!= NULL
&&
2784 gamma_table
!= NULL
)
2788 for (i
= 0; i
< row_width
; i
++, sp
+= 2, dp
++)
2790 png_uint_16 a
= *(sp
+ 1);
2794 *dp
= gamma_table
[*sp
];
2798 /* background is already in screen gamma */
2799 *dp
= (png_byte
)background
->gray
;
2805 v
= gamma_to_1
[*sp
];
2806 png_composite(w
, v
, a
, background_1
->gray
);
2807 *dp
= gamma_from_1
[w
];
2816 for (i
= 0; i
< row_width
; i
++, sp
+= 2, dp
++)
2818 png_byte a
= *(sp
+ 1);
2826 *dp
= (png_byte
)background
->gray
;
2830 png_composite(*dp
, *sp
, a
, background_1
->gray
);
2835 else /* if (png_ptr->bit_depth == 16) */
2837 #if defined(PNG_READ_GAMMA_SUPPORTED)
2838 if (gamma_16
!= NULL
&& gamma_16_from_1
!= NULL
&&
2839 gamma_16_to_1
!= NULL
)
2843 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 2)
2845 png_uint_16 a
= ((png_uint_16
)(*(sp
+ 2)) << 8) + *(sp
+ 3);
2847 if (a
== (png_uint_16
)0xffff)
2851 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2852 *dp
= (png_byte
)((v
>> 8) & 0xff);
2853 *(dp
+ 1) = (png_byte
)(v
& 0xff);
2857 /* background is already in screen gamma */
2858 *dp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2859 *(dp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2863 png_uint_16 g
, v
, w
;
2865 g
= gamma_16_to_1
[*(sp
+ 1) >> gamma_shift
][*sp
];
2866 png_composite_16(v
, g
, a
, background_1
->gray
);
2867 w
= gamma_16_from_1
[(v
&0xff) >> gamma_shift
][v
>> 8];
2868 *dp
= (png_byte
)((w
>> 8) & 0xff);
2869 *(dp
+ 1) = (png_byte
)(w
& 0xff);
2878 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 2)
2880 png_uint_16 a
= ((png_uint_16
)(*(sp
+ 2)) << 8) + *(sp
+ 3);
2881 if (a
== (png_uint_16
)0xffff)
2883 png_memcpy(dp
, sp
, 2);
2887 *dp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2888 *(dp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2894 g
= ((png_uint_16
)(*sp
) << 8) + *(sp
+ 1);
2895 png_composite_16(v
, g
, a
, background_1
->gray
);
2896 *dp
= (png_byte
)((v
>> 8) & 0xff);
2897 *(dp
+ 1) = (png_byte
)(v
& 0xff);
2904 case PNG_COLOR_TYPE_RGB_ALPHA
:
2906 if (row_info
->bit_depth
== 8)
2908 #if defined(PNG_READ_GAMMA_SUPPORTED)
2909 if (gamma_to_1
!= NULL
&& gamma_from_1
!= NULL
&&
2910 gamma_table
!= NULL
)
2914 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 3)
2916 png_byte a
= *(sp
+ 3);
2920 *dp
= gamma_table
[*sp
];
2921 *(dp
+ 1) = gamma_table
[*(sp
+ 1)];
2922 *(dp
+ 2) = gamma_table
[*(sp
+ 2)];
2926 /* background is already in screen gamma */
2927 *dp
= (png_byte
)background
->red
;
2928 *(dp
+ 1) = (png_byte
)background
->green
;
2929 *(dp
+ 2) = (png_byte
)background
->blue
;
2935 v
= gamma_to_1
[*sp
];
2936 png_composite(w
, v
, a
, background_1
->red
);
2937 *dp
= gamma_from_1
[w
];
2938 v
= gamma_to_1
[*(sp
+ 1)];
2939 png_composite(w
, v
, a
, background_1
->green
);
2940 *(dp
+ 1) = gamma_from_1
[w
];
2941 v
= gamma_to_1
[*(sp
+ 2)];
2942 png_composite(w
, v
, a
, background_1
->blue
);
2943 *(dp
+ 2) = gamma_from_1
[w
];
2952 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 3)
2954 png_byte a
= *(sp
+ 3);
2959 *(dp
+ 1) = *(sp
+ 1);
2960 *(dp
+ 2) = *(sp
+ 2);
2964 *dp
= (png_byte
)background
->red
;
2965 *(dp
+ 1) = (png_byte
)background
->green
;
2966 *(dp
+ 2) = (png_byte
)background
->blue
;
2970 png_composite(*dp
, *sp
, a
, background
->red
);
2971 png_composite(*(dp
+ 1), *(sp
+ 1), a
,
2973 png_composite(*(dp
+ 2), *(sp
+ 2), a
,
2979 else /* if (row_info->bit_depth == 16) */
2981 #if defined(PNG_READ_GAMMA_SUPPORTED)
2982 if (gamma_16
!= NULL
&& gamma_16_from_1
!= NULL
&&
2983 gamma_16_to_1
!= NULL
)
2987 for (i
= 0; i
< row_width
; i
++, sp
+= 8, dp
+= 6)
2989 png_uint_16 a
= (png_uint_16
)(((png_uint_16
)(*(sp
+ 6))
2990 << 8) + (png_uint_16
)(*(sp
+ 7)));
2991 if (a
== (png_uint_16
)0xffff)
2995 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2996 *dp
= (png_byte
)((v
>> 8) & 0xff);
2997 *(dp
+ 1) = (png_byte
)(v
& 0xff);
2998 v
= gamma_16
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
2999 *(dp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
3000 *(dp
+ 3) = (png_byte
)(v
& 0xff);
3001 v
= gamma_16
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
3002 *(dp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
3003 *(dp
+ 5) = (png_byte
)(v
& 0xff);
3007 /* background is already in screen gamma */
3008 *dp
= (png_byte
)((background
->red
>> 8) & 0xff);
3009 *(dp
+ 1) = (png_byte
)(background
->red
& 0xff);
3010 *(dp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
3011 *(dp
+ 3) = (png_byte
)(background
->green
& 0xff);
3012 *(dp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
3013 *(dp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3017 png_uint_16 v
, w
, x
;
3019 v
= gamma_16_to_1
[*(sp
+ 1) >> gamma_shift
][*sp
];
3020 png_composite_16(w
, v
, a
, background
->red
);
3021 x
= gamma_16_from_1
[((w
&0xff) >> gamma_shift
)][w
>> 8];
3022 *dp
= (png_byte
)((x
>> 8) & 0xff);
3023 *(dp
+ 1) = (png_byte
)(x
& 0xff);
3024 v
= gamma_16_to_1
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
3025 png_composite_16(w
, v
, a
, background
->green
);
3026 x
= gamma_16_from_1
[((w
&0xff) >> gamma_shift
)][w
>> 8];
3027 *(dp
+ 2) = (png_byte
)((x
>> 8) & 0xff);
3028 *(dp
+ 3) = (png_byte
)(x
& 0xff);
3029 v
= gamma_16_to_1
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
3030 png_composite_16(w
, v
, a
, background
->blue
);
3031 x
= gamma_16_from_1
[(w
& 0xff) >> gamma_shift
][w
>> 8];
3032 *(dp
+ 4) = (png_byte
)((x
>> 8) & 0xff);
3033 *(dp
+ 5) = (png_byte
)(x
& 0xff);
3042 for (i
= 0; i
< row_width
; i
++, sp
+= 8, dp
+= 6)
3044 png_uint_16 a
= (png_uint_16
)(((png_uint_16
)(*(sp
+ 6))
3045 << 8) + (png_uint_16
)(*(sp
+ 7)));
3046 if (a
== (png_uint_16
)0xffff)
3048 png_memcpy(dp
, sp
, 6);
3052 *dp
= (png_byte
)((background
->red
>> 8) & 0xff);
3053 *(dp
+ 1) = (png_byte
)(background
->red
& 0xff);
3054 *(dp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
3055 *(dp
+ 3) = (png_byte
)(background
->green
& 0xff);
3056 *(dp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
3057 *(dp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3063 png_uint_16 r
= ((png_uint_16
)(*sp
) << 8) + *(sp
+ 1);
3064 png_uint_16 g
= ((png_uint_16
)(*(sp
+ 2)) << 8)
3066 png_uint_16 b
= ((png_uint_16
)(*(sp
+ 4)) << 8)
3069 png_composite_16(v
, r
, a
, background
->red
);
3070 *dp
= (png_byte
)((v
>> 8) & 0xff);
3071 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3072 png_composite_16(v
, g
, a
, background
->green
);
3073 *(dp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
3074 *(dp
+ 3) = (png_byte
)(v
& 0xff);
3075 png_composite_16(v
, b
, a
, background
->blue
);
3076 *(dp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
3077 *(dp
+ 5) = (png_byte
)(v
& 0xff);
3086 if (row_info
->color_type
& PNG_COLOR_MASK_ALPHA
)
3088 row_info
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
3089 row_info
->channels
--;
3090 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
3091 row_info
->bit_depth
);
3092 row_info
->rowbytes
= ((row_width
*
3093 row_info
->pixel_depth
+ 7) >> 3);
3099 #if defined(PNG_READ_GAMMA_SUPPORTED)
3100 /* Gamma correct the image, avoiding the alpha channel. Make sure
3101 * you do this after you deal with the transparency issue on grayscale
3102 * or rgb images. If your bit depth is 8, use gamma_table, if it
3103 * is 16, use gamma_16_table and gamma_shift. Build these with
3104 * build_gamma_table().
3107 png_do_gamma(png_row_infop row_info
, png_bytep row
,
3108 png_bytep gamma_table
, png_uint_16pp gamma_16_table
,
3113 png_uint_32 row_width
=row_info
->width
;
3115 png_debug(1, "in png_do_gamma\n");
3117 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3118 row
!= NULL
&& row_info
!= NULL
&&
3120 ((row_info
->bit_depth
<= 8 && gamma_table
!= NULL
) ||
3121 (row_info
->bit_depth
== 16 && gamma_16_table
!= NULL
)))
3123 switch (row_info
->color_type
)
3125 case PNG_COLOR_TYPE_RGB
:
3127 if (row_info
->bit_depth
== 8)
3130 for (i
= 0; i
< row_width
; i
++)
3132 *sp
= gamma_table
[*sp
];
3134 *sp
= gamma_table
[*sp
];
3136 *sp
= gamma_table
[*sp
];
3140 else /* if (row_info->bit_depth == 16) */
3143 for (i
= 0; i
< row_width
; i
++)
3147 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3148 *sp
= (png_byte
)((v
>> 8) & 0xff);
3149 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3151 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3152 *sp
= (png_byte
)((v
>> 8) & 0xff);
3153 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3155 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3156 *sp
= (png_byte
)((v
>> 8) & 0xff);
3157 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3163 case PNG_COLOR_TYPE_RGB_ALPHA
:
3165 if (row_info
->bit_depth
== 8)
3168 for (i
= 0; i
< row_width
; i
++)
3170 *sp
= gamma_table
[*sp
];
3172 *sp
= gamma_table
[*sp
];
3174 *sp
= gamma_table
[*sp
];
3179 else /* if (row_info->bit_depth == 16) */
3182 for (i
= 0; i
< row_width
; i
++)
3184 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3185 *sp
= (png_byte
)((v
>> 8) & 0xff);
3186 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3188 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3189 *sp
= (png_byte
)((v
>> 8) & 0xff);
3190 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3192 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3193 *sp
= (png_byte
)((v
>> 8) & 0xff);
3194 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3200 case PNG_COLOR_TYPE_GRAY_ALPHA
:
3202 if (row_info
->bit_depth
== 8)
3205 for (i
= 0; i
< row_width
; i
++)
3207 *sp
= gamma_table
[*sp
];
3211 else /* if (row_info->bit_depth == 16) */
3214 for (i
= 0; i
< row_width
; i
++)
3216 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3217 *sp
= (png_byte
)((v
>> 8) & 0xff);
3218 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3224 case PNG_COLOR_TYPE_GRAY
:
3226 if (row_info
->bit_depth
== 2)
3229 for (i
= 0; i
< row_width
; i
+= 4)
3236 *sp
= ((((int)gamma_table
[a
|(a
>>2)|(a
>>4)|(a
>>6)]) ) & 0xc0)|
3237 ((((int)gamma_table
[(b
<<2)|b
|(b
>>2)|(b
>>4)])>>2) & 0x30)|
3238 ((((int)gamma_table
[(c
<<4)|(c
<<2)|c
|(c
>>2)])>>4) & 0x0c)|
3239 ((((int)gamma_table
[(d
<<6)|(d
<<4)|(d
<<2)|d
])>>6) );
3243 if (row_info
->bit_depth
== 4)
3246 for (i
= 0; i
< row_width
; i
+= 2)
3248 int msb
= *sp
& 0xf0;
3249 int lsb
= *sp
& 0x0f;
3251 *sp
= (((int)gamma_table
[msb
| (msb
>> 4)]) & 0xf0) |
3252 (((int)gamma_table
[(lsb
<< 4) | lsb
]) >> 4);
3256 else if (row_info
->bit_depth
== 8)
3259 for (i
= 0; i
< row_width
; i
++)
3261 *sp
= gamma_table
[*sp
];
3265 else if (row_info
->bit_depth
== 16)
3268 for (i
= 0; i
< row_width
; i
++)
3270 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3271 *sp
= (png_byte
)((v
>> 8) & 0xff);
3272 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3283 #if defined(PNG_READ_EXPAND_SUPPORTED)
3284 /* Expands a palette row to an rgb or rgba row depending
3285 * upon whether you supply trans and num_trans.
3288 png_do_expand_palette(png_row_infop row_info
, png_bytep row
,
3289 png_colorp palette
, png_bytep trans
, int num_trans
)
3294 png_uint_32 row_width
=row_info
->width
;
3296 png_debug(1, "in png_do_expand_palette\n");
3298 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3299 row
!= NULL
&& row_info
!= NULL
&&
3301 row_info
->color_type
== PNG_COLOR_TYPE_PALETTE
)
3303 if (row_info
->bit_depth
< 8)
3305 switch (row_info
->bit_depth
)
3309 sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
3310 dp
= row
+ (png_size_t
)row_width
- 1;
3311 shift
= 7 - (int)((row_width
+ 7) & 7);
3312 for (i
= 0; i
< row_width
; i
++)
3314 if ((*sp
>> shift
) & 0x1)
3332 sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
3333 dp
= row
+ (png_size_t
)row_width
- 1;
3334 shift
= (int)((3 - ((row_width
+ 3) & 3)) << 1);
3335 for (i
= 0; i
< row_width
; i
++)
3337 value
= (*sp
>> shift
) & 0x3;
3338 *dp
= (png_byte
)value
;
3353 sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
3354 dp
= row
+ (png_size_t
)row_width
- 1;
3355 shift
= (int)((row_width
& 1) << 2);
3356 for (i
= 0; i
< row_width
; i
++)
3358 value
= (*sp
>> shift
) & 0xf;
3359 *dp
= (png_byte
)value
;
3373 row_info
->bit_depth
= 8;
3374 row_info
->pixel_depth
= 8;
3375 row_info
->rowbytes
= row_width
;
3377 switch (row_info
->bit_depth
)
3383 sp
= row
+ (png_size_t
)row_width
- 1;
3384 dp
= row
+ (png_size_t
)(row_width
<< 2) - 1;
3386 for (i
= 0; i
< row_width
; i
++)
3388 if ((int)(*sp
) >= num_trans
)
3392 *dp
-- = palette
[*sp
].blue
;
3393 *dp
-- = palette
[*sp
].green
;
3394 *dp
-- = palette
[*sp
].red
;
3397 row_info
->bit_depth
= 8;
3398 row_info
->pixel_depth
= 32;
3399 row_info
->rowbytes
= row_width
* 4;
3400 row_info
->color_type
= 6;
3401 row_info
->channels
= 4;
3405 sp
= row
+ (png_size_t
)row_width
- 1;
3406 dp
= row
+ (png_size_t
)(row_width
* 3) - 1;
3408 for (i
= 0; i
< row_width
; i
++)
3410 *dp
-- = palette
[*sp
].blue
;
3411 *dp
-- = palette
[*sp
].green
;
3412 *dp
-- = palette
[*sp
].red
;
3415 row_info
->bit_depth
= 8;
3416 row_info
->pixel_depth
= 24;
3417 row_info
->rowbytes
= row_width
* 3;
3418 row_info
->color_type
= 2;
3419 row_info
->channels
= 3;
3427 /* If the bit depth < 8, it is expanded to 8. Also, if the
3428 * transparency value is supplied, an alpha channel is built.
3431 png_do_expand(png_row_infop row_info
, png_bytep row
,
3432 png_color_16p trans_value
)
3437 png_uint_32 row_width
=row_info
->width
;
3439 png_debug(1, "in png_do_expand\n");
3440 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3441 if (row
!= NULL
&& row_info
!= NULL
)
3444 if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
3446 png_uint_16 gray
= trans_value
? trans_value
->gray
: 0;
3448 if (row_info
->bit_depth
< 8)
3450 switch (row_info
->bit_depth
)
3455 sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
3456 dp
= row
+ (png_size_t
)row_width
- 1;
3457 shift
= 7 - (int)((row_width
+ 7) & 7);
3458 for (i
= 0; i
< row_width
; i
++)
3460 if ((*sp
>> shift
) & 0x1)
3479 sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
3480 dp
= row
+ (png_size_t
)row_width
- 1;
3481 shift
= (int)((3 - ((row_width
+ 3) & 3)) << 1);
3482 for (i
= 0; i
< row_width
; i
++)
3484 value
= (*sp
>> shift
) & 0x3;
3485 *dp
= (png_byte
)(value
| (value
<< 2) | (value
<< 4) |
3502 sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
3503 dp
= row
+ (png_size_t
)row_width
- 1;
3504 shift
= (int)((1 - ((row_width
+ 1) & 1)) << 2);
3505 for (i
= 0; i
< row_width
; i
++)
3507 value
= (*sp
>> shift
) & 0xf;
3508 *dp
= (png_byte
)(value
| (value
<< 4));
3522 row_info
->bit_depth
= 8;
3523 row_info
->pixel_depth
= 8;
3524 row_info
->rowbytes
= row_width
;
3527 if (trans_value
!= NULL
)
3529 if (row_info
->bit_depth
== 8)
3531 sp
= row
+ (png_size_t
)row_width
- 1;
3532 dp
= row
+ (png_size_t
)(row_width
<< 1) - 1;
3533 for (i
= 0; i
< row_width
; i
++)
3542 else if (row_info
->bit_depth
== 16)
3544 sp
= row
+ row_info
->rowbytes
- 1;
3545 dp
= row
+ (row_info
->rowbytes
<< 1) - 1;
3546 for (i
= 0; i
< row_width
; i
++)
3548 if (((png_uint_16
)*(sp
) |
3549 ((png_uint_16
)*(sp
- 1) << 8)) == gray
)
3563 row_info
->color_type
= PNG_COLOR_TYPE_GRAY_ALPHA
;
3564 row_info
->channels
= 2;
3565 row_info
->pixel_depth
= (png_byte
)(row_info
->bit_depth
<< 1);
3566 row_info
->rowbytes
=
3567 ((row_width
* row_info
->pixel_depth
) >> 3);
3570 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
&& trans_value
)
3572 if (row_info
->bit_depth
== 8)
3574 sp
= row
+ (png_size_t
)row_info
->rowbytes
- 1;
3575 dp
= row
+ (png_size_t
)(row_width
<< 2) - 1;
3576 for (i
= 0; i
< row_width
; i
++)
3578 if (*(sp
- 2) == trans_value
->red
&&
3579 *(sp
- 1) == trans_value
->green
&&
3580 *(sp
- 0) == trans_value
->blue
)
3589 else if (row_info
->bit_depth
== 16)
3591 sp
= row
+ row_info
->rowbytes
- 1;
3592 dp
= row
+ (png_size_t
)(row_width
<< 3) - 1;
3593 for (i
= 0; i
< row_width
; i
++)
3595 if ((((png_uint_16
)*(sp
- 4) |
3596 ((png_uint_16
)*(sp
- 5) << 8)) == trans_value
->red
) &&
3597 (((png_uint_16
)*(sp
- 2) |
3598 ((png_uint_16
)*(sp
- 3) << 8)) == trans_value
->green
) &&
3599 (((png_uint_16
)*(sp
- 0) |
3600 ((png_uint_16
)*(sp
- 1) << 8)) == trans_value
->blue
))
3618 row_info
->color_type
= PNG_COLOR_TYPE_RGB_ALPHA
;
3619 row_info
->channels
= 4;
3620 row_info
->pixel_depth
= (png_byte
)(row_info
->bit_depth
<< 2);
3621 row_info
->rowbytes
=
3622 ((row_width
* row_info
->pixel_depth
) >> 3);
3628 #if defined(PNG_READ_DITHER_SUPPORTED)
3630 png_do_dither(png_row_infop row_info
, png_bytep row
,
3631 png_bytep palette_lookup
, png_bytep dither_lookup
)
3635 png_uint_32 row_width
=row_info
->width
;
3637 png_debug(1, "in png_do_dither\n");
3638 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3639 if (row
!= NULL
&& row_info
!= NULL
)
3642 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
&&
3643 palette_lookup
&& row_info
->bit_depth
== 8)
3648 for (i
= 0; i
< row_width
; i
++)
3654 /* this looks real messy, but the compiler will reduce
3655 it down to a reasonable formula. For example, with
3656 5 bits per color, we get:
3657 p = (((r >> 3) & 0x1f) << 10) |
3658 (((g >> 3) & 0x1f) << 5) |
3661 p
= (((r
>> (8 - PNG_DITHER_RED_BITS
)) &
3662 ((1 << PNG_DITHER_RED_BITS
) - 1)) <<
3663 (PNG_DITHER_GREEN_BITS
+ PNG_DITHER_BLUE_BITS
)) |
3664 (((g
>> (8 - PNG_DITHER_GREEN_BITS
)) &
3665 ((1 << PNG_DITHER_GREEN_BITS
) - 1)) <<
3666 (PNG_DITHER_BLUE_BITS
)) |
3667 ((b
>> (8 - PNG_DITHER_BLUE_BITS
)) &
3668 ((1 << PNG_DITHER_BLUE_BITS
) - 1));
3670 *dp
++ = palette_lookup
[p
];
3672 row_info
->color_type
= PNG_COLOR_TYPE_PALETTE
;
3673 row_info
->channels
= 1;
3674 row_info
->pixel_depth
= row_info
->bit_depth
;
3675 row_info
->rowbytes
=
3676 ((row_width
* row_info
->pixel_depth
+ 7) >> 3);
3678 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
&&
3679 palette_lookup
!= NULL
&& row_info
->bit_depth
== 8)
3684 for (i
= 0; i
< row_width
; i
++)
3691 p
= (((r
>> (8 - PNG_DITHER_RED_BITS
)) &
3692 ((1 << PNG_DITHER_RED_BITS
) - 1)) <<
3693 (PNG_DITHER_GREEN_BITS
+ PNG_DITHER_BLUE_BITS
)) |
3694 (((g
>> (8 - PNG_DITHER_GREEN_BITS
)) &
3695 ((1 << PNG_DITHER_GREEN_BITS
) - 1)) <<
3696 (PNG_DITHER_BLUE_BITS
)) |
3697 ((b
>> (8 - PNG_DITHER_BLUE_BITS
)) &
3698 ((1 << PNG_DITHER_BLUE_BITS
) - 1));
3700 *dp
++ = palette_lookup
[p
];
3702 row_info
->color_type
= PNG_COLOR_TYPE_PALETTE
;
3703 row_info
->channels
= 1;
3704 row_info
->pixel_depth
= row_info
->bit_depth
;
3705 row_info
->rowbytes
=
3706 ((row_width
* row_info
->pixel_depth
+ 7) >> 3);
3708 else if (row_info
->color_type
== PNG_COLOR_TYPE_PALETTE
&&
3709 dither_lookup
&& row_info
->bit_depth
== 8)
3712 for (i
= 0; i
< row_width
; i
++, sp
++)
3714 *sp
= dither_lookup
[*sp
];
3721 #if defined(PNG_READ_GAMMA_SUPPORTED)
3722 static int png_gamma_shift
[] =
3723 {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0};
3725 /* We build the 8- or 16-bit gamma tables here. Note that for 16-bit
3726 * tables, we don't make a full table if we are reducing to 8-bit in
3727 * the future. Note also how the gamma_16 tables are segmented so that
3728 * we don't need to allocate > 64K chunks for a full 16-bit table.
3731 png_build_gamma_table(png_structp png_ptr
)
3733 png_debug(1, "in png_build_gamma_table\n");
3734 if(png_ptr
->gamma
!= 0.0)
3736 if (png_ptr
->bit_depth
<= 8)
3741 if (png_ptr
->screen_gamma
> .000001)
3742 g
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
3746 png_ptr
->gamma_table
= (png_bytep
)png_malloc(png_ptr
,
3749 for (i
= 0; i
< 256; i
++)
3751 png_ptr
->gamma_table
[i
] = (png_byte
)(pow((double)i
/ 255.0,
3755 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
3756 defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
3757 if (png_ptr
->transformations
& (PNG_BACKGROUND
| PNG_RGB_TO_GRAY
))
3760 g
= 1.0 / (png_ptr
->gamma
);
3762 png_ptr
->gamma_to_1
= (png_bytep
)png_malloc(png_ptr
,
3765 for (i
= 0; i
< 256; i
++)
3767 png_ptr
->gamma_to_1
[i
] = (png_byte
)(pow((double)i
/ 255.0,
3772 png_ptr
->gamma_from_1
= (png_bytep
)png_malloc(png_ptr
,
3775 if(png_ptr
->screen_gamma
> 0.000001)
3776 g
= 1.0 / png_ptr
->screen_gamma
;
3778 g
= png_ptr
->gamma
; /* probably doing rgb_to_gray */
3780 for (i
= 0; i
< 256; i
++)
3782 png_ptr
->gamma_from_1
[i
] = (png_byte
)(pow((double)i
/ 255.0,
3787 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
3792 int i
, j
, shift
, num
;
3796 if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
3798 sig_bit
= (int)png_ptr
->sig_bit
.red
;
3799 if ((int)png_ptr
->sig_bit
.green
> sig_bit
)
3800 sig_bit
= png_ptr
->sig_bit
.green
;
3801 if ((int)png_ptr
->sig_bit
.blue
> sig_bit
)
3802 sig_bit
= png_ptr
->sig_bit
.blue
;
3806 sig_bit
= (int)png_ptr
->sig_bit
.gray
;
3810 shift
= 16 - sig_bit
;
3814 if (png_ptr
->transformations
& PNG_16_TO_8
)
3816 if (shift
< (16 - PNG_MAX_GAMMA_8
))
3817 shift
= (16 - PNG_MAX_GAMMA_8
);
3825 png_ptr
->gamma_shift
= (png_byte
)shift
;
3827 num
= (1 << (8 - shift
));
3829 if (png_ptr
->screen_gamma
> .000001)
3830 g
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
3834 png_ptr
->gamma_16_table
= (png_uint_16pp
)png_malloc(png_ptr
,
3835 (png_uint_32
)(num
* sizeof (png_uint_16p
)));
3837 if (png_ptr
->transformations
& (PNG_16_TO_8
| PNG_BACKGROUND
))
3840 png_uint_32 last
, max
;
3842 for (i
= 0; i
< num
; i
++)
3844 png_ptr
->gamma_16_table
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
3845 (png_uint_32
)(256 * sizeof (png_uint_16
)));
3850 for (i
= 0; i
< 256; i
++)
3852 fout
= ((double)i
+ 0.5) / 256.0;
3854 max
= (png_uint_32
)(fin
* (double)((png_uint_32
)num
<< 8));
3857 png_ptr
->gamma_16_table
[(int)(last
& (0xff >> shift
))]
3858 [(int)(last
>> (8 - shift
))] = (png_uint_16
)(
3859 (png_uint_16
)i
| ((png_uint_16
)i
<< 8));
3863 while (last
< ((png_uint_32
)num
<< 8))
3865 png_ptr
->gamma_16_table
[(int)(last
& (0xff >> shift
))]
3866 [(int)(last
>> (8 - shift
))] = (png_uint_16
)65535L;
3872 for (i
= 0; i
< num
; i
++)
3874 png_ptr
->gamma_16_table
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
3875 (png_uint_32
)(256 * sizeof (png_uint_16
)));
3877 ig
= (((png_uint_32
)i
* (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
3878 for (j
= 0; j
< 256; j
++)
3880 png_ptr
->gamma_16_table
[i
][j
] =
3881 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
3882 65535.0, g
) * 65535.0 + .5);
3887 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
3888 defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
3889 if (png_ptr
->transformations
& (PNG_BACKGROUND
| PNG_RGB_TO_GRAY
))
3892 g
= 1.0 / (png_ptr
->gamma
);
3894 png_ptr
->gamma_16_to_1
= (png_uint_16pp
)png_malloc(png_ptr
,
3895 (png_uint_32
)(num
* sizeof (png_uint_16p
)));
3897 for (i
= 0; i
< num
; i
++)
3899 png_ptr
->gamma_16_to_1
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
3900 (png_uint_32
)(256 * sizeof (png_uint_16
)));
3902 ig
= (((png_uint_32
)i
*
3903 (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
3904 for (j
= 0; j
< 256; j
++)
3906 png_ptr
->gamma_16_to_1
[i
][j
] =
3907 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
3908 65535.0, g
) * 65535.0 + .5);
3912 if(png_ptr
->screen_gamma
> 0.000001)
3913 g
= 1.0 / png_ptr
->screen_gamma
;
3915 g
= png_ptr
->gamma
; /* probably doing rgb_to_gray */
3917 png_ptr
->gamma_16_from_1
= (png_uint_16pp
)png_malloc(png_ptr
,
3918 (png_uint_32
)(num
* sizeof (png_uint_16p
)));
3920 for (i
= 0; i
< num
; i
++)
3922 png_ptr
->gamma_16_from_1
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
3923 (png_uint_32
)(256 * sizeof (png_uint_16
)));
3925 ig
= (((png_uint_32
)i
*
3926 (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
3927 for (j
= 0; j
< 256; j
++)
3929 png_ptr
->gamma_16_from_1
[i
][j
] =
3930 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
3931 65535.0, g
) * 65535.0 + .5);
3935 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */