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 /* 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 /* handle alpha and tRNS via a background color */
75 png_set_background(png_structp png_ptr
,
76 png_color_16p background_color
, int background_gamma_code
,
77 int need_expand
, double background_gamma
)
79 png_debug(1, "in png_set_background\n");
80 if (background_gamma_code
== PNG_BACKGROUND_GAMMA_UNKNOWN
)
82 png_warning(png_ptr
, "Application must supply a known background gamma");
86 png_ptr
->transformations
|= PNG_BACKGROUND
;
87 png_memcpy(&(png_ptr
->background
), background_color
, sizeof(png_color_16
));
88 png_ptr
->background_gamma
= (float)background_gamma
;
89 png_ptr
->background_gamma_type
= (png_byte
)(background_gamma_code
);
90 png_ptr
->transformations
|= (need_expand
? PNG_BACKGROUND_EXPAND
: 0);
92 /* Note: if need_expand is set and color_type is either RGB or RGB_ALPHA
93 * (in which case need_expand is superfluous anyway), the background color
94 * might actually be gray yet not be flagged as such. This is not a problem
95 * for the current code, which uses PNG_FLAG_BACKGROUND_IS_GRAY only to
96 * decide when to do the png_do_gray_to_rgb() transformation.
98 if ((need_expand
&& !(png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)) ||
99 (!need_expand
&& background_color
->red
== background_color
->green
&&
100 background_color
->red
== background_color
->blue
))
101 png_ptr
->flags
|= PNG_FLAG_BACKGROUND_IS_GRAY
;
105 #if defined(PNG_READ_16_TO_8_SUPPORTED)
106 /* strip 16 bit depth files to 8 bit depth */
108 png_set_strip_16(png_structp png_ptr
)
110 png_debug(1, "in png_set_strip_16\n");
111 png_ptr
->transformations
|= PNG_16_TO_8
;
115 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
117 png_set_strip_alpha(png_structp png_ptr
)
119 png_debug(1, "in png_set_strip_alpha\n");
120 png_ptr
->transformations
|= PNG_STRIP_ALPHA
;
124 #if defined(PNG_READ_DITHER_SUPPORTED)
125 /* Dither file to 8 bit. Supply a palette, the current number
126 * of elements in the palette, the maximum number of elements
127 * allowed, and a histogram if possible. If the current number
128 * of colors is greater then the maximum number, the palette will be
129 * modified to fit in the maximum number. "full_dither" indicates
130 * whether we need a dithering cube set up for RGB images, or if we
131 * simply are reducing the number of colors in a paletted image.
134 typedef struct png_dsort_struct
136 struct png_dsort_struct FAR
* next
;
140 typedef png_dsort FAR
* png_dsortp
;
141 typedef png_dsort FAR
* FAR
* png_dsortpp
;
144 png_set_dither(png_structp png_ptr
, png_colorp palette
,
145 int num_palette
, int maximum_colors
, png_uint_16p histogram
,
148 png_debug(1, "in png_set_dither\n");
149 png_ptr
->transformations
|= PNG_DITHER
;
155 png_ptr
->dither_index
= (png_bytep
)png_malloc(png_ptr
,
156 (png_uint_32
)(num_palette
* sizeof (png_byte
)));
157 for (i
= 0; i
< num_palette
; i
++)
158 png_ptr
->dither_index
[i
] = (png_byte
)i
;
161 if (num_palette
> maximum_colors
)
163 if (histogram
!= NULL
)
165 /* This is easy enough, just throw out the least used colors.
166 Perhaps not the best solution, but good enough. */
171 /* initialize an array to sort colors */
172 sort
= (png_bytep
)png_malloc(png_ptr
, (png_uint_32
)(num_palette
173 * sizeof (png_byte
)));
175 /* initialize the sort array */
176 for (i
= 0; i
< num_palette
; i
++)
177 sort
[i
] = (png_byte
)i
;
179 /* Find the least used palette entries by starting a
180 bubble sort, and running it until we have sorted
181 out enough colors. Note that we don't care about
182 sorting all the colors, just finding which are
185 for (i
= num_palette
- 1; i
>= maximum_colors
; i
--)
187 int done
; /* to stop early if the list is pre-sorted */
191 for (j
= 0; j
< i
; j
++)
193 if (histogram
[sort
[j
]] < histogram
[sort
[j
+ 1]])
198 sort
[j
] = sort
[j
+ 1];
207 /* swap the palette around, and set up a table, if necessary */
212 /* put all the useful colors within the max, but don't
214 for (i
= 0; i
< maximum_colors
; i
++)
216 if ((int)sort
[i
] >= maximum_colors
)
220 while ((int)sort
[j
] >= maximum_colors
);
221 palette
[i
] = palette
[j
];
229 /* move all the used colors inside the max limit, and
230 develop a translation table */
231 for (i
= 0; i
< maximum_colors
; i
++)
233 /* only move the colors we need to */
234 if ((int)sort
[i
] >= maximum_colors
)
240 while ((int)sort
[j
] >= maximum_colors
);
242 tmp_color
= palette
[j
];
243 palette
[j
] = palette
[i
];
244 palette
[i
] = tmp_color
;
245 /* indicate where the color went */
246 png_ptr
->dither_index
[j
] = (png_byte
)i
;
247 png_ptr
->dither_index
[i
] = (png_byte
)j
;
251 /* find closest color for those colors we are not using */
252 for (i
= 0; i
< num_palette
; i
++)
254 if ((int)png_ptr
->dither_index
[i
] >= maximum_colors
)
256 int min_d
, k
, min_k
, d_index
;
258 /* find the closest color to one we threw out */
259 d_index
= png_ptr
->dither_index
[i
];
260 min_d
= PNG_COLOR_DIST(palette
[d_index
], palette
[0]);
261 for (k
= 1, min_k
= 0; k
< maximum_colors
; k
++)
265 d
= PNG_COLOR_DIST(palette
[d_index
], palette
[k
]);
273 /* point to closest color */
274 png_ptr
->dither_index
[i
] = (png_byte
)min_k
;
278 png_free(png_ptr
, sort
);
282 /* This is much harder to do simply (and quickly). Perhaps
283 we need to go through a median cut routine, but those
284 don't always behave themselves with only a few colors
285 as input. So we will just find the closest two colors,
286 and throw out one of them (chosen somewhat randomly).
287 [We don't understand this at all, so if someone wants to
288 work on improving it, be our guest - AED, GRP]
294 png_bytep index_to_palette
;
295 /* where the original index currently is in the palette */
296 png_bytep palette_to_index
;
297 /* which original index points to this palette color */
299 /* initialize palette index arrays */
300 index_to_palette
= (png_bytep
)png_malloc(png_ptr
,
301 (png_uint_32
)(num_palette
* sizeof (png_byte
)));
302 palette_to_index
= (png_bytep
)png_malloc(png_ptr
,
303 (png_uint_32
)(num_palette
* sizeof (png_byte
)));
305 /* initialize the sort array */
306 for (i
= 0; i
< num_palette
; i
++)
308 index_to_palette
[i
] = (png_byte
)i
;
309 palette_to_index
[i
] = (png_byte
)i
;
312 hash
= (png_dsortpp
)png_malloc(png_ptr
, (png_uint_32
)(769 *
313 sizeof (png_dsortp
)));
314 for (i
= 0; i
< 769; i
++)
316 /* png_memset(hash, 0, 769 * sizeof (png_dsortp)); */
318 num_new_palette
= num_palette
;
320 /* initial wild guess at how far apart the farthest pixel
321 pair we will be eliminating will be. Larger
322 numbers mean more areas will be allocated, Smaller
323 numbers run the risk of not saving enough data, and
324 having to do this all over again.
326 I have not done extensive checking on this number.
330 while (num_new_palette
> maximum_colors
)
332 for (i
= 0; i
< num_new_palette
- 1; i
++)
336 for (j
= i
+ 1; j
< num_new_palette
; j
++)
340 d
= PNG_COLOR_DIST(palette
[i
], palette
[j
]);
346 t
= (png_dsortp
)png_malloc(png_ptr
, (png_uint_32
)(sizeof
349 t
->left
= (png_byte
)i
;
350 t
->right
= (png_byte
)j
;
356 for (i
= 0; i
<= max_d
; i
++)
362 for (p
= hash
[i
]; p
; p
= p
->next
)
364 if ((int)index_to_palette
[p
->left
] < num_new_palette
&&
365 (int)index_to_palette
[p
->right
] < num_new_palette
)
369 if (num_new_palette
& 1)
381 palette
[index_to_palette
[j
]] = palette
[num_new_palette
];
386 for (k
= 0; k
< num_palette
; k
++)
388 if (png_ptr
->dither_index
[k
] ==
390 png_ptr
->dither_index
[k
] =
391 index_to_palette
[next_j
];
392 if ((int)png_ptr
->dither_index
[k
] ==
394 png_ptr
->dither_index
[k
] =
399 index_to_palette
[palette_to_index
[num_new_palette
]] =
401 palette_to_index
[index_to_palette
[j
]] =
402 palette_to_index
[num_new_palette
];
404 index_to_palette
[j
] = (png_byte
)num_new_palette
;
405 palette_to_index
[num_new_palette
] = (png_byte
)j
;
407 if (num_new_palette
<= maximum_colors
)
410 if (num_new_palette
<= maximum_colors
)
415 for (i
= 0; i
< 769; i
++)
419 png_dsortp p
= hash
[i
];
425 png_free(png_ptr
, p
);
433 png_free(png_ptr
, hash
);
434 png_free(png_ptr
, palette_to_index
);
435 png_free(png_ptr
, index_to_palette
);
437 num_palette
= maximum_colors
;
439 if (png_ptr
->palette
== NULL
)
441 png_ptr
->palette
= palette
;
443 png_ptr
->num_palette
= (png_uint_16
)num_palette
;
449 int total_bits
= PNG_DITHER_RED_BITS
+ PNG_DITHER_GREEN_BITS
+
450 PNG_DITHER_BLUE_BITS
;
451 int num_red
= (1 << PNG_DITHER_RED_BITS
);
452 int num_green
= (1 << PNG_DITHER_GREEN_BITS
);
453 int num_blue
= (1 << PNG_DITHER_BLUE_BITS
);
454 png_size_t num_entries
= ((png_size_t
)1 << total_bits
);
456 png_ptr
->palette_lookup
= (png_bytep
)png_malloc(png_ptr
,
457 (png_uint_32
)(num_entries
* sizeof (png_byte
)));
459 png_memset(png_ptr
->palette_lookup
, 0, num_entries
* sizeof (png_byte
));
461 distance
= (png_bytep
)png_malloc(png_ptr
, (png_uint_32
)(num_entries
*
464 png_memset(distance
, 0xff, num_entries
* sizeof(png_byte
));
466 for (i
= 0; i
< num_palette
; i
++)
469 int r
= (palette
[i
].red
>> (8 - PNG_DITHER_RED_BITS
));
470 int g
= (palette
[i
].green
>> (8 - PNG_DITHER_GREEN_BITS
));
471 int b
= (palette
[i
].blue
>> (8 - PNG_DITHER_BLUE_BITS
));
473 for (ir
= 0; ir
< num_red
; ir
++)
475 int dr
= abs(ir
- r
);
476 int index_r
= (ir
<< (PNG_DITHER_BLUE_BITS
+ PNG_DITHER_GREEN_BITS
));
478 for (ig
= 0; ig
< num_green
; ig
++)
480 int dg
= abs(ig
- g
);
482 int dm
= ((dr
> dg
) ? dr
: dg
);
483 int index_g
= index_r
| (ig
<< PNG_DITHER_BLUE_BITS
);
485 for (ib
= 0; ib
< num_blue
; ib
++)
487 int d_index
= index_g
| ib
;
488 int db
= abs(ib
- b
);
489 int dmax
= ((dm
> db
) ? dm
: db
);
490 int d
= dmax
+ dt
+ db
;
492 if (d
< (int)distance
[d_index
])
494 distance
[d_index
] = (png_byte
)d
;
495 png_ptr
->palette_lookup
[d_index
] = (png_byte
)i
;
502 png_free(png_ptr
, distance
);
507 #if defined(PNG_READ_GAMMA_SUPPORTED)
508 /* Transform the image from the file_gamma to the screen_gamma. We
509 * only do transformations on images where the file_gamma and screen_gamma
510 * are not close reciprocals, otherwise it slows things down slightly, and
511 * also needlessly introduces small errors.
514 png_set_gamma(png_structp png_ptr
, double scrn_gamma
, double file_gamma
)
516 png_debug(1, "in png_set_gamma\n");
517 if (fabs(scrn_gamma
* file_gamma
- 1.0) > PNG_GAMMA_THRESHOLD
)
518 png_ptr
->transformations
|= PNG_GAMMA
;
519 png_ptr
->gamma
= (float)file_gamma
;
520 png_ptr
->screen_gamma
= (float)scrn_gamma
;
524 #if defined(PNG_READ_EXPAND_SUPPORTED)
525 /* Expand paletted images to rgb, expand grayscale images of
526 * less than 8 bit depth to 8 bit depth, and expand tRNS chunks
530 png_set_expand(png_structp png_ptr
)
532 png_debug(1, "in png_set_expand\n");
533 png_ptr
->transformations
|= PNG_EXPAND
;
537 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
539 png_set_gray_to_rgb(png_structp png_ptr
)
541 png_debug(1, "in png_set_gray_to_rgb\n");
542 png_ptr
->transformations
|= PNG_GRAY_TO_RGB
;
546 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
547 /* Convert a RGB image to a grayscale of the same width. This allows us,
548 * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
551 png_set_rgb_to_gray(png_structp png_ptr
, int error_action
, float red
,
554 png_debug(1, "in png_set_rgb_to_gray\n");
557 case 1: png_ptr
->transformations
|= PNG_RGB_TO_GRAY
;
559 case 2: png_ptr
->transformations
|= PNG_RGB_TO_GRAY_WARN
;
561 case 3: png_ptr
->transformations
|= PNG_RGB_TO_GRAY_ERR
;
563 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
564 #if defined(PNG_READ_EXPAND_SUPPORTED)
565 png_ptr
->transformations
|= PNG_EXPAND
;
568 png_warning(png_ptr
, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
569 png_ptr
->transformations
&= ~PNG_RGB_TO_GRAY
;
573 png_byte red_byte
= (png_byte
)(red
*255.0 + 0.5);
574 png_byte green_byte
= (png_byte
)(green
*255.0 + 0.5);
575 if(red
< 0.0 || green
< 0.0)
580 else if(red_byte
+ green_byte
> 255)
582 png_warning(png_ptr
, "ignoring out of range rgb_to_gray coefficients");
586 png_ptr
->rgb_to_gray_red_coeff
= red_byte
;
587 png_ptr
->rgb_to_gray_green_coeff
= green_byte
;
588 png_ptr
->rgb_to_gray_blue_coeff
= 255 - red_byte
- green_byte
;
593 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
595 png_set_read_user_transform_fn(png_structp png_ptr
, png_user_transform_ptr
596 read_user_transform_fn
)
598 png_debug(1, "in png_set_read_user_transform_fn\n");
599 png_ptr
->transformations
|= PNG_USER_TRANSFORM
;
600 png_ptr
->read_user_transform_fn
= read_user_transform_fn
;
604 /* Initialize everything needed for the read. This includes modifying
608 png_init_read_transformations(png_structp png_ptr
)
610 png_debug(1, "in png_init_read_transformations\n");
611 #if defined(PNG_USELESS_TESTS_SUPPORTED)
615 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
616 || defined(PNG_READ_GAMMA_SUPPORTED)
617 int color_type
= png_ptr
->color_type
;
620 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
621 if (png_ptr
->transformations
& PNG_BACKGROUND_EXPAND
)
623 if (!(color_type
& PNG_COLOR_MASK_COLOR
)) /* i.e., GRAY or GRAY_ALPHA */
625 /* expand background chunk. */
626 switch (png_ptr
->bit_depth
)
629 png_ptr
->background
.gray
*= (png_uint_16
)0xff;
630 png_ptr
->background
.red
= png_ptr
->background
.green
=
631 png_ptr
->background
.blue
= png_ptr
->background
.gray
;
634 png_ptr
->background
.gray
*= (png_uint_16
)0x55;
635 png_ptr
->background
.red
= png_ptr
->background
.green
=
636 png_ptr
->background
.blue
= png_ptr
->background
.gray
;
639 png_ptr
->background
.gray
*= (png_uint_16
)0x11;
640 png_ptr
->background
.red
= png_ptr
->background
.green
=
641 png_ptr
->background
.blue
= png_ptr
->background
.gray
;
645 png_ptr
->background
.red
= png_ptr
->background
.green
=
646 png_ptr
->background
.blue
= png_ptr
->background
.gray
;
650 else if (color_type
== PNG_COLOR_TYPE_PALETTE
)
652 png_ptr
->background
.red
=
653 png_ptr
->palette
[png_ptr
->background
.index
].red
;
654 png_ptr
->background
.green
=
655 png_ptr
->palette
[png_ptr
->background
.index
].green
;
656 png_ptr
->background
.blue
=
657 png_ptr
->palette
[png_ptr
->background
.index
].blue
;
659 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
660 if (png_ptr
->transformations
& PNG_INVERT_ALPHA
)
662 #if defined(PNG_READ_EXPAND_SUPPORTED)
663 if (!(png_ptr
->transformations
& PNG_EXPAND
))
666 /* invert the alpha channel (in tRNS) unless the pixels are
667 going to be expanded, in which case leave it for later */
669 istop
=(int)png_ptr
->num_trans
;
670 for (i
=0; i
<istop
; i
++)
671 png_ptr
->trans
[i
] = 255 - png_ptr
->trans
[i
];
680 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
681 png_ptr
->background_1
= png_ptr
->background
;
683 #if defined(PNG_READ_GAMMA_SUPPORTED)
684 if (png_ptr
->transformations
& (PNG_GAMMA
| PNG_RGB_TO_GRAY
))
686 png_build_gamma_table(png_ptr
);
687 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
688 if (png_ptr
->transformations
& PNG_BACKGROUND
)
690 if (color_type
== PNG_COLOR_TYPE_PALETTE
)
692 png_color back
, back_1
;
693 png_colorp palette
= png_ptr
->palette
;
694 int num_palette
= png_ptr
->num_palette
;
697 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_FILE
)
699 back
.red
= png_ptr
->gamma_table
[png_ptr
->background
.red
];
700 back
.green
= png_ptr
->gamma_table
[png_ptr
->background
.green
];
701 back
.blue
= png_ptr
->gamma_table
[png_ptr
->background
.blue
];
703 back_1
.red
= png_ptr
->gamma_to_1
[png_ptr
->background
.red
];
704 back_1
.green
= png_ptr
->gamma_to_1
[png_ptr
->background
.green
];
705 back_1
.blue
= png_ptr
->gamma_to_1
[png_ptr
->background
.blue
];
711 switch (png_ptr
->background_gamma_type
)
713 case PNG_BACKGROUND_GAMMA_SCREEN
:
714 g
= (png_ptr
->screen_gamma
);
717 case PNG_BACKGROUND_GAMMA_FILE
:
718 g
= 1.0 / (png_ptr
->gamma
);
719 gs
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
721 case PNG_BACKGROUND_GAMMA_UNIQUE
:
722 g
= 1.0 / (png_ptr
->background_gamma
);
723 gs
= 1.0 / (png_ptr
->background_gamma
*
724 png_ptr
->screen_gamma
);
727 g
= 1.0; /* back_1 */
731 if ( fabs(gs
- 1.0) < PNG_GAMMA_THRESHOLD
)
733 back
.red
= (png_byte
)png_ptr
->background
.red
;
734 back
.green
= (png_byte
)png_ptr
->background
.green
;
735 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
739 back
.red
= (png_byte
)(pow(
740 (double)png_ptr
->background
.red
/255, gs
) * 255.0 + .5);
741 back
.green
= (png_byte
)(pow(
742 (double)png_ptr
->background
.green
/255, gs
) * 255.0 + .5);
743 back
.blue
= (png_byte
)(pow(
744 (double)png_ptr
->background
.blue
/255, gs
) * 255.0 + .5);
747 back_1
.red
= (png_byte
)(pow(
748 (double)png_ptr
->background
.red
/255, g
) * 255.0 + .5);
749 back_1
.green
= (png_byte
)(pow(
750 (double)png_ptr
->background
.green
/255, g
) * 255.0 + .5);
751 back_1
.blue
= (png_byte
)(pow(
752 (double)png_ptr
->background
.blue
/255, g
) * 255.0 + .5);
755 for (i
= 0; i
< num_palette
; i
++)
757 if (i
< (int)png_ptr
->num_trans
&& png_ptr
->trans
[i
] != 0xff)
759 if (png_ptr
->trans
[i
] == 0)
763 else /* if (png_ptr->trans[i] != 0xff) */
767 v
= png_ptr
->gamma_to_1
[palette
[i
].red
];
768 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.red
);
769 palette
[i
].red
= png_ptr
->gamma_from_1
[w
];
771 v
= png_ptr
->gamma_to_1
[palette
[i
].green
];
772 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.green
);
773 palette
[i
].green
= png_ptr
->gamma_from_1
[w
];
775 v
= png_ptr
->gamma_to_1
[palette
[i
].blue
];
776 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.blue
);
777 palette
[i
].blue
= png_ptr
->gamma_from_1
[w
];
782 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
783 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
784 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
788 /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN)*/
790 /* color_type != PNG_COLOR_TYPE_PALETTE */
792 double m
= (double)(((png_uint_32
)1 << png_ptr
->bit_depth
) - 1);
796 switch (png_ptr
->background_gamma_type
)
798 case PNG_BACKGROUND_GAMMA_SCREEN
:
799 g
= (png_ptr
->screen_gamma
);
802 case PNG_BACKGROUND_GAMMA_FILE
:
803 g
= 1.0 / (png_ptr
->gamma
);
804 gs
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
806 case PNG_BACKGROUND_GAMMA_UNIQUE
:
807 g
= 1.0 / (png_ptr
->background_gamma
);
808 gs
= 1.0 / (png_ptr
->background_gamma
*
809 png_ptr
->screen_gamma
);
813 if (color_type
& PNG_COLOR_MASK_COLOR
)
816 png_ptr
->background_1
.red
= (png_uint_16
)(pow(
817 (double)png_ptr
->background
.red
/ m
, g
) * m
+ .5);
818 png_ptr
->background_1
.green
= (png_uint_16
)(pow(
819 (double)png_ptr
->background
.green
/ m
, g
) * m
+ .5);
820 png_ptr
->background_1
.blue
= (png_uint_16
)(pow(
821 (double)png_ptr
->background
.blue
/ m
, g
) * m
+ .5);
822 png_ptr
->background
.red
= (png_uint_16
)(pow(
823 (double)png_ptr
->background
.red
/ m
, gs
) * m
+ .5);
824 png_ptr
->background
.green
= (png_uint_16
)(pow(
825 (double)png_ptr
->background
.green
/ m
, gs
) * m
+ .5);
826 png_ptr
->background
.blue
= (png_uint_16
)(pow(
827 (double)png_ptr
->background
.blue
/ m
, gs
) * m
+ .5);
831 /* GRAY or GRAY ALPHA */
832 png_ptr
->background_1
.gray
= (png_uint_16
)(pow(
833 (double)png_ptr
->background
.gray
/ m
, g
) * m
+ .5);
834 png_ptr
->background
.gray
= (png_uint_16
)(pow(
835 (double)png_ptr
->background
.gray
/ m
, gs
) * m
+ .5);
840 /* transformation does not include PNG_BACKGROUND */
842 if (color_type
== PNG_COLOR_TYPE_PALETTE
)
844 png_colorp palette
= png_ptr
->palette
;
845 int num_palette
= png_ptr
->num_palette
;
848 for (i
= 0; i
< num_palette
; i
++)
850 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
851 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
852 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
856 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
860 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
861 /* No GAMMA transformation */
862 if (png_ptr
->transformations
& PNG_BACKGROUND
&&
863 color_type
== PNG_COLOR_TYPE_PALETTE
)
866 int istop
= (int)png_ptr
->num_trans
;
868 png_colorp palette
= png_ptr
->palette
;
870 back
.red
= (png_byte
)png_ptr
->background
.red
;
871 back
.green
= (png_byte
)png_ptr
->background
.green
;
872 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
874 for (i
= 0; i
< istop
; i
++)
876 if (png_ptr
->trans
[i
] == 0)
880 else if (png_ptr
->trans
[i
] != 0xff)
882 /* The png_composite() macro is defined in png.h */
883 png_composite(palette
[i
].red
, palette
[i
].red
,
884 png_ptr
->trans
[i
], back
.red
);
885 png_composite(palette
[i
].green
, palette
[i
].green
,
886 png_ptr
->trans
[i
], back
.green
);
887 png_composite(palette
[i
].blue
, palette
[i
].blue
,
888 png_ptr
->trans
[i
], back
.blue
);
894 #if defined(PNG_READ_SHIFT_SUPPORTED)
895 if ((png_ptr
->transformations
& PNG_SHIFT
) &&
896 color_type
== PNG_COLOR_TYPE_PALETTE
)
899 png_uint_16 istop
= png_ptr
->num_palette
;
900 int sr
= 8 - png_ptr
->sig_bit
.red
;
901 int sg
= 8 - png_ptr
->sig_bit
.green
;
902 int sb
= 8 - png_ptr
->sig_bit
.blue
;
904 if (sr
< 0 || sr
> 8)
906 if (sg
< 0 || sg
> 8)
908 if (sb
< 0 || sb
> 8)
910 for (i
= 0; i
< istop
; i
++)
912 png_ptr
->palette
[i
].red
>>= sr
;
913 png_ptr
->palette
[i
].green
>>= sg
;
914 png_ptr
->palette
[i
].blue
>>= sb
;
921 /* Modify the info structure to reflect the transformations. The
922 * info should be updated so a PNG file could be written with it,
923 * assuming the transformations result in valid PNG data.
926 png_read_transform_info(png_structp png_ptr
, png_infop info_ptr
)
928 png_debug(1, "in png_read_transform_info\n");
929 #if defined(PNG_READ_EXPAND_SUPPORTED)
930 if (png_ptr
->transformations
& PNG_EXPAND
)
932 if (info_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
934 if (png_ptr
->num_trans
)
935 info_ptr
->color_type
= PNG_COLOR_TYPE_RGB_ALPHA
;
937 info_ptr
->color_type
= PNG_COLOR_TYPE_RGB
;
938 info_ptr
->bit_depth
= 8;
939 info_ptr
->num_trans
= 0;
943 if (png_ptr
->num_trans
)
944 info_ptr
->color_type
|= PNG_COLOR_MASK_ALPHA
;
945 if (info_ptr
->bit_depth
< 8)
946 info_ptr
->bit_depth
= 8;
947 info_ptr
->num_trans
= 0;
952 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
953 if (png_ptr
->transformations
& PNG_BACKGROUND
)
955 info_ptr
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
956 info_ptr
->num_trans
= 0;
957 info_ptr
->background
= png_ptr
->background
;
961 #if defined(PNG_READ_GAMMA_SUPPORTED)
962 if (png_ptr
->transformations
& PNG_GAMMA
)
963 info_ptr
->gamma
= png_ptr
->gamma
;
966 #if defined(PNG_READ_16_TO_8_SUPPORTED)
967 if ((png_ptr
->transformations
& PNG_16_TO_8
) && info_ptr
->bit_depth
== 16)
968 info_ptr
->bit_depth
= 8;
971 #if defined(PNG_READ_DITHER_SUPPORTED)
972 if (png_ptr
->transformations
& PNG_DITHER
)
974 if (((info_ptr
->color_type
== PNG_COLOR_TYPE_RGB
) ||
975 (info_ptr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)) &&
976 png_ptr
->palette_lookup
&& info_ptr
->bit_depth
== 8)
978 info_ptr
->color_type
= PNG_COLOR_TYPE_PALETTE
;
983 #if defined(PNG_READ_PACK_SUPPORTED)
984 if ((png_ptr
->transformations
& PNG_PACK
) && info_ptr
->bit_depth
< 8)
985 info_ptr
->bit_depth
= 8;
988 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
989 if (png_ptr
->transformations
& PNG_GRAY_TO_RGB
)
990 info_ptr
->color_type
|= PNG_COLOR_MASK_COLOR
;
993 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
994 if (png_ptr
->transformations
& PNG_RGB_TO_GRAY
)
995 info_ptr
->color_type
&= ~PNG_COLOR_MASK_COLOR
;
998 if (info_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
999 info_ptr
->channels
= 1;
1000 else if (info_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
1001 info_ptr
->channels
= 3;
1003 info_ptr
->channels
= 1;
1005 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1006 if (png_ptr
->transformations
& PNG_STRIP_ALPHA
)
1007 info_ptr
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
1010 if (info_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
)
1011 info_ptr
->channels
++;
1013 #if defined(PNG_READ_FILLER_SUPPORTED)
1014 /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
1015 if (png_ptr
->transformations
& PNG_FILLER
&&
1016 (info_ptr
->color_type
== PNG_COLOR_TYPE_RGB
||
1017 info_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
))
1018 ++info_ptr
->channels
;
1021 info_ptr
->pixel_depth
= (png_byte
)(info_ptr
->channels
*
1022 info_ptr
->bit_depth
);
1023 info_ptr
->rowbytes
= ((info_ptr
->width
* info_ptr
->pixel_depth
+ 7) >> 3);
1026 /* Transform the row. The order of transformations is significant,
1027 * and is very touchy. If you add a transformation, take care to
1028 * decide how it fits in with the other transformations here.
1031 png_do_read_transformations(png_structp png_ptr
)
1033 png_debug(1, "in png_do_read_transformations\n");
1034 #if !defined(PNG_USELESS_TESTS_SUPPORTED)
1035 if (png_ptr
->row_buf
== NULL
)
1037 #if !defined(PNG_NO_STDIO)
1040 sprintf(msg
, "NULL row buffer for row %ld, pass %d", png_ptr
->row_number
,
1042 png_error(png_ptr
, msg
);
1044 png_error(png_ptr
, "NULL row buffer");
1049 #if defined(PNG_READ_EXPAND_SUPPORTED)
1050 if (png_ptr
->transformations
& PNG_EXPAND
)
1052 if (png_ptr
->row_info
.color_type
== PNG_COLOR_TYPE_PALETTE
)
1054 png_do_expand_palette(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1055 png_ptr
->palette
, png_ptr
->trans
, png_ptr
->num_trans
);
1059 if (png_ptr
->num_trans
)
1060 png_do_expand(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1061 &(png_ptr
->trans_values
));
1063 png_do_expand(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1069 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1070 if (png_ptr
->transformations
& PNG_STRIP_ALPHA
)
1071 png_do_strip_filler(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1072 PNG_FLAG_FILLER_AFTER
);
1075 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1076 if (png_ptr
->transformations
& PNG_RGB_TO_GRAY
)
1079 png_do_rgb_to_gray(png_ptr
, &(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1082 png_ptr
->rgb_to_gray_status
=1;
1083 if(png_ptr
->transformations
== PNG_RGB_TO_GRAY_WARN
)
1084 png_warning(png_ptr
, "png_do_rgb_to_gray found nongray pixel");
1085 if(png_ptr
->transformations
== PNG_RGB_TO_GRAY_ERR
)
1086 png_error(png_ptr
, "png_do_rgb_to_gray found nongray pixel");
1092 From Andreas Dilger e-mail to png-implement, 26 March 1998:
1094 In most cases, the "simple transparency" should be done prior to doing
1095 gray-to-RGB, or you will have to test 3x as many bytes to check if a
1096 pixel is transparent. You would also need to make sure that the
1097 transparency information is upgraded to RGB.
1099 To summarize, the current flow is:
1100 - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
1101 with background "in place" if transparent,
1102 convert to RGB if necessary
1103 - Gray + alpha -> composite with gray background and remove alpha bytes,
1104 convert to RGB if necessary
1106 To support RGB backgrounds for gray images we need:
1107 - Gray + simple transparency -> convert to RGB + simple transparency, compare
1108 3 or 6 bytes and composite with background
1109 "in place" if transparent (3x compare/pixel
1110 compared to doing composite with gray bkgrnd)
1111 - Gray + alpha -> convert to RGB + alpha, composite with background and
1112 remove alpha bytes (3x float operations/pixel
1113 compared with composite on gray background)
1115 Greg's change will do this. The reason it wasn't done before is for
1116 performance, as this increases the per-pixel operations. If we would check
1117 in advance if the background was gray or RGB, and position the gray-to-RGB
1118 transform appropriately, then it would save a lot of work/time.
1121 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1122 /* if gray -> RGB, do so now only if background is non-gray; else do later
1123 * for performance reasons */
1124 if (png_ptr
->transformations
& PNG_GRAY_TO_RGB
&&
1125 !(png_ptr
->flags
& PNG_FLAG_BACKGROUND_IS_GRAY
))
1126 png_do_gray_to_rgb(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1129 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1130 if ((png_ptr
->transformations
& PNG_BACKGROUND
) &&
1131 ((png_ptr
->num_trans
!= 0 ) ||
1132 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
)))
1133 png_do_background(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1134 &(png_ptr
->trans_values
), &(png_ptr
->background
),
1135 &(png_ptr
->background_1
),
1136 png_ptr
->gamma_table
, png_ptr
->gamma_from_1
,
1137 png_ptr
->gamma_to_1
, png_ptr
->gamma_16_table
,
1138 png_ptr
->gamma_16_from_1
, png_ptr
->gamma_16_to_1
,
1139 png_ptr
->gamma_shift
);
1142 #if defined(PNG_READ_GAMMA_SUPPORTED)
1143 if ((png_ptr
->transformations
& PNG_GAMMA
) &&
1144 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1145 !((png_ptr
->transformations
& PNG_BACKGROUND
) &&
1146 ((png_ptr
->num_trans
!= 0) ||
1147 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
))) &&
1149 (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
))
1150 png_do_gamma(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1151 png_ptr
->gamma_table
, png_ptr
->gamma_16_table
,
1152 png_ptr
->gamma_shift
);
1155 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1156 if (png_ptr
->transformations
& PNG_16_TO_8
)
1157 png_do_chop(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1160 #if defined(PNG_READ_DITHER_SUPPORTED)
1161 if (png_ptr
->transformations
& PNG_DITHER
)
1163 png_do_dither((png_row_infop
)&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1164 png_ptr
->palette_lookup
, png_ptr
->dither_index
);
1165 if(png_ptr
->row_info
.rowbytes
== (png_uint_32
)0)
1166 png_error(png_ptr
, "png_do_dither returned rowbytes=0");
1170 #if defined(PNG_READ_INVERT_SUPPORTED)
1171 if (png_ptr
->transformations
& PNG_INVERT_MONO
)
1172 png_do_invert(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1175 #if defined(PNG_READ_SHIFT_SUPPORTED)
1176 if (png_ptr
->transformations
& PNG_SHIFT
)
1177 png_do_unshift(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1181 #if defined(PNG_READ_PACK_SUPPORTED)
1182 if (png_ptr
->transformations
& PNG_PACK
)
1183 png_do_unpack(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1186 #if defined(PNG_READ_BGR_SUPPORTED)
1187 if (png_ptr
->transformations
& PNG_BGR
)
1188 png_do_bgr(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1191 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1192 if (png_ptr
->transformations
& PNG_PACKSWAP
)
1193 png_do_packswap(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1196 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1197 /* if gray -> RGB, do so now only if we did not do so above */
1198 if (png_ptr
->transformations
& PNG_GRAY_TO_RGB
&&
1199 png_ptr
->flags
& PNG_FLAG_BACKGROUND_IS_GRAY
)
1200 png_do_gray_to_rgb(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1203 #if defined(PNG_READ_FILLER_SUPPORTED)
1204 if (png_ptr
->transformations
& PNG_FILLER
)
1205 png_do_read_filler(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1206 (png_uint_32
)png_ptr
->filler
, png_ptr
->flags
);
1209 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1210 if (png_ptr
->transformations
& PNG_INVERT_ALPHA
)
1211 png_do_read_invert_alpha(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1214 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1215 if (png_ptr
->transformations
& PNG_SWAP_ALPHA
)
1216 png_do_read_swap_alpha(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1219 #if defined(PNG_READ_SWAP_SUPPORTED)
1220 if (png_ptr
->transformations
& PNG_SWAP_BYTES
)
1221 png_do_swap(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1224 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1225 if (png_ptr
->transformations
& PNG_USER_TRANSFORM
)
1226 if(png_ptr
->read_user_transform_fn
!= NULL
)
1227 (*(png_ptr
->read_user_transform_fn
)) /* user read transform function */
1228 (png_ptr
, /* png_ptr */
1229 &(png_ptr
->row_info
), /* row_info: */
1230 /* png_uint_32 width; width of row */
1231 /* png_uint_32 rowbytes; number of bytes in row */
1232 /* png_byte color_type; color type of pixels */
1233 /* png_byte bit_depth; bit depth of samples */
1234 /* png_byte channels; number of channels (1-4) */
1235 /* png_byte pixel_depth; bits per pixel (depth*channels) */
1236 png_ptr
->row_buf
+ 1); /* start of pixel data for row */
1241 #if defined(PNG_READ_PACK_SUPPORTED)
1242 /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
1243 * without changing the actual values. Thus, if you had a row with
1244 * a bit depth of 1, you would end up with bytes that only contained
1245 * the numbers 0 or 1. If you would rather they contain 0 and 255, use
1246 * png_do_shift() after this.
1249 png_do_unpack(png_row_infop row_info
, png_bytep row
)
1251 png_debug(1, "in png_do_unpack\n");
1252 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1253 if (row
!= NULL
&& row_info
!= NULL
&& row_info
->bit_depth
< 8)
1255 if (row_info
->bit_depth
< 8)
1259 png_uint_32 row_width
=row_info
->width
;
1261 switch (row_info
->bit_depth
)
1265 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
1266 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1267 png_uint_32 shift
= 7 - (int)((row_width
+ 7) & 7);
1268 for (i
= 0; i
< row_width
; i
++)
1270 *dp
= (png_byte
)((*sp
>> shift
) & 0x1);
1286 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
1287 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1288 png_uint_32 shift
= (int)((3 - ((row_width
+ 3) & 3)) << 1);
1289 for (i
= 0; i
< row_width
; i
++)
1291 *dp
= (png_byte
)((*sp
>> shift
) & 0x3);
1306 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
1307 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1308 png_uint_32 shift
= (int)((1 - ((row_width
+ 1) & 1)) << 2);
1309 for (i
= 0; i
< row_width
; i
++)
1311 *dp
= (png_byte
)((*sp
>> shift
) & 0xf);
1325 row_info
->bit_depth
= 8;
1326 row_info
->pixel_depth
= (png_byte
)(8 * row_info
->channels
);
1327 row_info
->rowbytes
= row_width
* row_info
->channels
;
1332 #if defined(PNG_READ_SHIFT_SUPPORTED)
1333 /* Reverse the effects of png_do_shift. This routine merely shifts the
1334 * pixels back to their significant bits values. Thus, if you have
1335 * a row of bit depth 8, but only 5 are significant, this will shift
1336 * the values back to 0 through 31.
1339 png_do_unshift(png_row_infop row_info
, png_bytep row
, png_color_8p sig_bits
)
1341 png_debug(1, "in png_do_unshift\n");
1343 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1344 row
!= NULL
&& row_info
!= NULL
&& sig_bits
!= NULL
&&
1346 row_info
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
1351 png_uint_16 value
= 0;
1352 png_uint_32 row_width
= row_info
->width
;
1354 if (row_info
->color_type
& PNG_COLOR_MASK_COLOR
)
1356 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->red
;
1357 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->green
;
1358 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->blue
;
1362 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->gray
;
1364 if (row_info
->color_type
& PNG_COLOR_MASK_ALPHA
)
1366 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->alpha
;
1369 for (c
= 0; c
< channels
; c
++)
1380 switch (row_info
->bit_depth
)
1386 png_uint_32 istop
= row_info
->rowbytes
;
1388 for (bp
= row
, i
= 0; i
< istop
; i
++)
1399 png_uint_32 istop
= row_info
->rowbytes
;
1400 png_byte mask
= (png_byte
)(((int)0xf0 >> shift
[0]) & (int)0xf0) |
1401 (png_byte
)((int)0xf >> shift
[0]);
1403 for (i
= 0; i
< istop
; i
++)
1414 png_uint_32 istop
= row_width
* channels
;
1416 for (i
= 0; i
< istop
; i
++)
1418 *bp
++ >>= shift
[i%channels
];
1426 png_uint_32 istop
= channels
* row_width
;
1428 for (i
= 0; i
< istop
; i
++)
1430 value
= (png_uint_16
)((*bp
<< 8) + *(bp
+ 1));
1431 value
>>= shift
[i%channels
];
1432 *bp
++ = (png_byte
)(value
>> 8);
1433 *bp
++ = (png_byte
)(value
& 0xff);
1442 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1443 /* chop rows of bit depth 16 down to 8 */
1445 png_do_chop(png_row_infop row_info
, png_bytep row
)
1447 png_debug(1, "in png_do_chop\n");
1448 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1449 if (row
!= NULL
&& row_info
!= NULL
&& row_info
->bit_depth
== 16)
1451 if (row_info
->bit_depth
== 16)
1457 png_uint_32 istop
= row_info
->width
* row_info
->channels
;
1459 for (i
= 0; i
<istop
; i
++, sp
+= 2, dp
++)
1461 #if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
1462 /* This does a more accurate scaling of the 16-bit color
1463 * value, rather than a simple low-byte truncation.
1465 * What the ideal calculation should be:
1466 * *dp = (((((png_uint_32)(*sp) << 8) |
1467 * (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L;
1469 * GRR: no, I think this is what it really should be:
1470 * *dp = (((((png_uint_32)(*sp) << 8) |
1471 * (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L;
1473 * GRR: here's the exact calculation with shifts:
1474 * temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L;
1475 * *dp = (temp - (temp >> 8)) >> 8;
1477 * Approximate calculation with shift/add instead of multiply/divide:
1478 * *dp = ((((png_uint_32)(*sp) << 8) |
1479 * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
1481 * What we actually do to avoid extra shifting and conversion:
1484 *dp
= *sp
+ ((((int)(*(sp
+ 1)) - *sp
) > 128) ? 1 : 0);
1486 /* Simply discard the low order byte */
1490 row_info
->bit_depth
= 8;
1491 row_info
->pixel_depth
= (png_byte
)(8 * row_info
->channels
);
1492 row_info
->rowbytes
= row_info
->width
* row_info
->channels
;
1497 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1499 png_do_read_swap_alpha(png_row_infop row_info
, png_bytep row
)
1501 png_debug(1, "in png_do_read_swap_alpha\n");
1502 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1503 if (row
!= NULL
&& row_info
!= NULL
)
1506 png_uint_32 row_width
= row_info
->width
;
1507 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
1509 /* This converts from RGBA to ARGB */
1510 if (row_info
->bit_depth
== 8)
1512 png_bytep sp
= row
+ row_info
->rowbytes
;
1517 for (i
= 0; i
< row_width
; i
++)
1526 /* This converts from RRGGBBAA to AARRGGBB */
1529 png_bytep sp
= row
+ row_info
->rowbytes
;
1534 for (i
= 0; i
< row_width
; i
++)
1549 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
1551 /* This converts from GA to AG */
1552 if (row_info
->bit_depth
== 8)
1554 png_bytep sp
= row
+ row_info
->rowbytes
;
1559 for (i
= 0; i
< row_width
; i
++)
1566 /* This converts from GGAA to AAGG */
1569 png_bytep sp
= row
+ row_info
->rowbytes
;
1574 for (i
= 0; i
< row_width
; i
++)
1589 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1591 png_do_read_invert_alpha(png_row_infop row_info
, png_bytep row
)
1593 png_debug(1, "in png_do_read_invert_alpha\n");
1594 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1595 if (row
!= NULL
&& row_info
!= NULL
)
1598 png_uint_32 row_width
= row_info
->width
;
1599 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
1601 /* This inverts the alpha channel in RGBA */
1602 if (row_info
->bit_depth
== 8)
1604 png_bytep sp
= row
+ row_info
->rowbytes
;
1608 for (i
= 0; i
< row_width
; i
++)
1610 *(--dp
) = 255 - *(--sp
);
1616 /* This inverts the alpha channel in RRGGBBAA */
1619 png_bytep sp
= row
+ row_info
->rowbytes
;
1623 for (i
= 0; i
< row_width
; i
++)
1625 *(--dp
) = 255 - *(--sp
);
1626 *(--dp
) = 255 - *(--sp
);
1636 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
1638 /* This inverts the alpha channel in GA */
1639 if (row_info
->bit_depth
== 8)
1641 png_bytep sp
= row
+ row_info
->rowbytes
;
1645 for (i
= 0; i
< row_width
; i
++)
1647 *(--dp
) = 255 - *(--sp
);
1651 /* This inverts the alpha channel in GGAA */
1654 png_bytep sp
= row
+ row_info
->rowbytes
;
1658 for (i
= 0; i
< row_width
; i
++)
1660 *(--dp
) = 255 - *(--sp
);
1661 *(--dp
) = 255 - *(--sp
);
1671 #if defined(PNG_READ_FILLER_SUPPORTED)
1672 /* Add filler channel if we have RGB color */
1674 png_do_read_filler(png_row_infop row_info
, png_bytep row
,
1675 png_uint_32 filler
, png_uint_32 flags
)
1678 png_uint_32 row_width
= row_info
->width
;
1680 png_byte hi_filler
= (png_byte
)((filler
>>8) & 0xff);
1681 png_byte lo_filler
= (png_byte
)(filler
& 0xff);
1683 png_debug(1, "in png_do_read_filler\n");
1685 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1686 row
!= NULL
&& row_info
!= NULL
&&
1688 row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
1690 if(row_info
->bit_depth
== 8)
1692 /* This changes the data from G to GX */
1693 if (flags
& PNG_FLAG_FILLER_AFTER
)
1695 png_bytep sp
= row
+ (png_size_t
)row_width
;
1696 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1697 for (i
= 1; i
< row_width
; i
++)
1699 *(--dp
) = lo_filler
;
1702 *(--dp
) = lo_filler
;
1703 row_info
->channels
= 2;
1704 row_info
->pixel_depth
= 16;
1705 row_info
->rowbytes
= row_width
* 2;
1707 /* This changes the data from G to XG */
1710 png_bytep sp
= row
+ (png_size_t
)row_width
;
1711 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1712 for (i
= 0; i
< row_width
; i
++)
1715 *(--dp
) = lo_filler
;
1717 row_info
->channels
= 2;
1718 row_info
->pixel_depth
= 16;
1719 row_info
->rowbytes
= row_width
* 2;
1722 else if(row_info
->bit_depth
== 16)
1724 /* This changes the data from GG to GGXX */
1725 if (flags
& PNG_FLAG_FILLER_AFTER
)
1727 png_bytep sp
= row
+ (png_size_t
)row_width
;
1728 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1729 for (i
= 1; i
< row_width
; i
++)
1731 *(--dp
) = hi_filler
;
1732 *(--dp
) = lo_filler
;
1736 *(--dp
) = hi_filler
;
1737 *(--dp
) = lo_filler
;
1738 row_info
->channels
= 2;
1739 row_info
->pixel_depth
= 32;
1740 row_info
->rowbytes
= row_width
* 2;
1742 /* This changes the data from GG to XXGG */
1745 png_bytep sp
= row
+ (png_size_t
)row_width
;
1746 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1747 for (i
= 0; i
< row_width
; i
++)
1751 *(--dp
) = hi_filler
;
1752 *(--dp
) = lo_filler
;
1754 row_info
->channels
= 2;
1755 row_info
->pixel_depth
= 16;
1756 row_info
->rowbytes
= row_width
* 2;
1759 } /* COLOR_TYPE == GRAY */
1760 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
1762 if(row_info
->bit_depth
== 8)
1764 /* This changes the data from RGB to RGBX */
1765 if (flags
& PNG_FLAG_FILLER_AFTER
)
1767 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
1768 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1769 for (i
= 1; i
< row_width
; i
++)
1771 *(--dp
) = lo_filler
;
1776 *(--dp
) = lo_filler
;
1777 row_info
->channels
= 4;
1778 row_info
->pixel_depth
= 32;
1779 row_info
->rowbytes
= row_width
* 4;
1781 /* This changes the data from RGB to XRGB */
1784 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
1785 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1786 for (i
= 0; i
< row_width
; i
++)
1791 *(--dp
) = lo_filler
;
1793 row_info
->channels
= 4;
1794 row_info
->pixel_depth
= 32;
1795 row_info
->rowbytes
= row_width
* 4;
1798 else if(row_info
->bit_depth
== 16)
1800 /* This changes the data from RRGGBB to RRGGBBXX */
1801 if (flags
& PNG_FLAG_FILLER_AFTER
)
1803 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
1804 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1805 for (i
= 1; i
< row_width
; i
++)
1807 *(--dp
) = hi_filler
;
1808 *(--dp
) = lo_filler
;
1816 *(--dp
) = hi_filler
;
1817 *(--dp
) = lo_filler
;
1818 row_info
->channels
= 4;
1819 row_info
->pixel_depth
= 64;
1820 row_info
->rowbytes
= row_width
* 4;
1822 /* This changes the data from RRGGBB to XXRRGGBB */
1825 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
1826 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1827 for (i
= 0; i
< row_width
; i
++)
1835 *(--dp
) = hi_filler
;
1836 *(--dp
) = lo_filler
;
1838 row_info
->channels
= 4;
1839 row_info
->pixel_depth
= 64;
1840 row_info
->rowbytes
= row_width
* 4;
1843 } /* COLOR_TYPE == RGB */
1847 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1848 /* expand grayscale files to RGB, with or without alpha */
1850 png_do_gray_to_rgb(png_row_infop row_info
, png_bytep row
)
1853 png_uint_32 row_width
= row_info
->width
;
1855 png_debug(1, "in png_do_gray_to_rgb\n");
1856 if (row_info
->bit_depth
>= 8 &&
1857 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1858 row
!= NULL
&& row_info
!= NULL
&&
1860 !(row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
1862 if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
1864 if (row_info
->bit_depth
== 8)
1866 png_bytep sp
= row
+ (png_size_t
)row_width
- 1;
1867 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
1868 for (i
= 0; i
< row_width
; i
++)
1878 png_bytep sp
= row
+ (png_size_t
)row_width
* 2 - 1;
1879 png_bytep dp
= sp
+ (png_size_t
)row_width
* 4;
1880 for (i
= 0; i
< row_width
; i
++)
1883 *(dp
--) = *(sp
- 1);
1885 *(dp
--) = *(sp
- 1);
1887 *(dp
--) = *(sp
- 1);
1893 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
1895 if (row_info
->bit_depth
== 8)
1897 png_bytep sp
= row
+ (png_size_t
)row_width
* 2 - 1;
1898 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
1899 for (i
= 0; i
< row_width
; i
++)
1910 png_bytep sp
= row
+ (png_size_t
)row_width
* 4 - 1;
1911 png_bytep dp
= sp
+ (png_size_t
)row_width
* 4;
1912 for (i
= 0; i
< row_width
; i
++)
1917 *(dp
--) = *(sp
- 1);
1919 *(dp
--) = *(sp
- 1);
1921 *(dp
--) = *(sp
- 1);
1927 row_info
->channels
+= (png_byte
)2;
1928 row_info
->color_type
|= PNG_COLOR_MASK_COLOR
;
1929 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
1930 row_info
->bit_depth
);
1931 row_info
->rowbytes
= ((row_width
*
1932 row_info
->pixel_depth
+ 7) >> 3);
1937 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1938 /* reduce RGB files to grayscale, with or without alpha
1939 * using the equation given in Poynton's ColorFAQ at
1940 * <http://www.inforamp.net/~poynton/>
1941 * Copyright (c) 1998-01-04 Charles Poynton poynton@inforamp.net
1943 * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
1945 * We approximate this with
1947 * Y = 0.211 * R + 0.715 * G + 0.074 * B
1949 * which can be expressed with integers as
1951 * Y = (54 * R + 183 * G + 19 * B)/256
1953 * The calculation is to be done in a linear colorspace.
1955 * Other integer coefficents can be used via png_set_rgb_to_gray().
1958 png_do_rgb_to_gray(png_structp png_ptr
, png_row_infop row_info
, png_bytep row
)
1963 png_uint_32 row_width
= row_info
->width
;
1966 png_debug(1, "in png_do_rgb_to_gray\n");
1968 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1969 row
!= NULL
&& row_info
!= NULL
&&
1971 (row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
1973 png_byte rc
= png_ptr
->rgb_to_gray_red_coeff
;
1974 png_byte gc
= png_ptr
->rgb_to_gray_green_coeff
;
1975 png_byte bc
= png_ptr
->rgb_to_gray_blue_coeff
;
1977 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
1979 if (row_info
->bit_depth
== 8)
1981 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
1982 if (png_ptr
->gamma_from_1
!= NULL
&& png_ptr
->gamma_to_1
!= NULL
)
1987 for (i
= 0; i
< row_width
; i
++)
1989 png_byte red
= png_ptr
->gamma_to_1
[*(sp
++)];
1990 png_byte green
= png_ptr
->gamma_to_1
[*(sp
++)];
1991 png_byte blue
= png_ptr
->gamma_to_1
[*(sp
++)];
1992 if(red
!= green
|| red
!= blue
)
1995 *(dp
++) = png_ptr
->gamma_from_1
[
1996 (rc
*red
+gc
*green
+bc
*blue
)>>8];
2007 for (i
= 0; i
< row_width
; i
++)
2009 png_byte red
= *(sp
++);
2010 png_byte green
= *(sp
++);
2011 png_byte blue
= *(sp
++);
2012 if(red
!= green
|| red
!= blue
)
2015 *(dp
++) = (rc
*red
+gc
*green
+bc
*blue
)>>8;
2023 else /* RGB bit_depth == 16 */
2025 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2026 if (png_ptr
->gamma_16_to_1
!= NULL
&&
2027 png_ptr
->gamma_16_from_1
!= NULL
)
2031 for (i
= 0; i
< row_width
; i
++)
2033 png_uint_16 red
, green
, blue
, w
;
2035 red
= ((*(sp
))<<8) | *(sp
+1); sp
+=2;
2036 green
= ((*(sp
))<<8) | *(sp
+1); sp
+=2;
2037 blue
= ((*(sp
))<<8) | *(sp
+1); sp
+=2;
2039 if(red
== green
&& red
== blue
)
2043 png_uint_16 red_1
= png_ptr
->gamma_16_to_1
[(red
&0xff) >>
2044 png_ptr
->gamma_shift
][red
>>8];
2045 png_uint_16 green_1
= png_ptr
->gamma_16_to_1
[(green
&0xff) >>
2046 png_ptr
->gamma_shift
][green
>>8];
2047 png_uint_16 blue_1
= png_ptr
->gamma_16_to_1
[(blue
&0xff) >>
2048 png_ptr
->gamma_shift
][blue
>>8];
2049 png_uint_16 gray16
= (rc
* red_1
+ gc
* green_1
2051 w
= png_ptr
->gamma_16_from_1
[(gray16
&0xff) >>
2052 png_ptr
->gamma_shift
][gray16
>> 8];
2056 *(dp
++) = (w
>>8) & 0xff;
2065 for (i
= 0; i
< row_width
; i
++)
2067 png_uint_16 red
, green
, blue
, gray16
;
2069 red
= ((*(sp
))<<8) | *(sp
+1); sp
+=2;
2070 green
= ((*(sp
))<<8) | *(sp
+1); sp
+=2;
2071 blue
= ((*(sp
))<<8) | *(sp
+1); sp
+=2;
2073 if(red
!= green
|| red
!= blue
)
2075 gray16
= (rc
* red
+ gc
* green
+ bc
* blue
)>>8;
2076 *(dp
++) = (gray16
>>8) & 0xff;
2077 *(dp
++) = gray16
& 0xff;
2082 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
2084 if (row_info
->bit_depth
== 8)
2086 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2087 if (png_ptr
->gamma_from_1
!= NULL
&& png_ptr
->gamma_to_1
!= NULL
)
2091 for (i
= 0; i
< row_width
; i
++)
2093 png_byte red
= png_ptr
->gamma_to_1
[*(sp
++)];
2094 png_byte green
= png_ptr
->gamma_to_1
[*(sp
++)];
2095 png_byte blue
= png_ptr
->gamma_to_1
[*(sp
++)];
2096 if(red
!= green
|| red
!= blue
)
2098 *(dp
++) = png_ptr
->gamma_from_1
2099 [(rc
*red
+ gc
*green
+ bc
*blue
)>>8];
2100 *(dp
++) = *(sp
++); /* alpha */
2108 for (i
= 0; i
< row_width
; i
++)
2110 png_byte red
= *(sp
++);
2111 png_byte green
= *(sp
++);
2112 png_byte blue
= *(sp
++);
2113 if(red
!= green
|| red
!= blue
)
2115 *(dp
++) = (gc
*red
+ gc
*green
+ bc
*blue
)>>8;
2116 *(dp
++) = *(sp
++); /* alpha */
2120 else /* RGBA bit_depth == 16 */
2122 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2123 if (png_ptr
->gamma_16_to_1
!= NULL
&&
2124 png_ptr
->gamma_16_from_1
!= NULL
)
2128 for (i
= 0; i
< row_width
; i
++)
2130 png_uint_16 red
, green
, blue
, w
;
2132 red
= ((*(sp
))<<8) | *(sp
+1); sp
+=2;
2133 green
= ((*(sp
))<<8) | *(sp
+1); sp
+=2;
2134 blue
= ((*(sp
))<<8) | *(sp
+1); sp
+=2;
2136 if(red
== green
&& red
== blue
)
2140 png_uint_16 red_1
= png_ptr
->gamma_16_to_1
[(red
&0xff) >>
2141 png_ptr
->gamma_shift
][red
>>8];
2142 png_uint_16 green_1
= png_ptr
->gamma_16_to_1
[(green
&0xff) >>
2143 png_ptr
->gamma_shift
][green
>>8];
2144 png_uint_16 blue_1
= png_ptr
->gamma_16_to_1
[(blue
&0xff) >>
2145 png_ptr
->gamma_shift
][blue
>>8];
2146 png_uint_16 gray16
= (rc
* red_1
+ gc
* green_1
2148 w
= png_ptr
->gamma_16_from_1
[(gray16
&0xff) >>
2149 png_ptr
->gamma_shift
][gray16
>> 8];
2153 *(dp
++) = (w
>>8) & 0xff;
2155 *(dp
++) = *(sp
++); /* alpha */
2164 for (i
= 0; i
< row_width
; i
++)
2166 png_uint_16 red
, green
, blue
, gray16
;
2167 red
= (*(sp
)<<8) | *(sp
+1); sp
+=2;
2168 green
= (*(sp
)<<8) | *(sp
+1); sp
+=2;
2169 blue
= (*(sp
)<<8) | *(sp
+1); sp
+=2;
2170 if(red
!= green
|| red
!= blue
)
2172 gray16
= (rc
* red
+ gc
* green
+ bc
* blue
)>>8;
2173 *(dp
++) = (gray16
>>8) & 0xff;
2174 *(dp
++) = gray16
& 0xff;
2175 *(dp
++) = *(sp
++); /* alpha */
2181 row_info
->channels
-= (png_byte
)2;
2182 row_info
->color_type
&= ~PNG_COLOR_MASK_COLOR
;
2183 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
2184 row_info
->bit_depth
);
2185 row_info
->rowbytes
= ((row_width
*
2186 row_info
->pixel_depth
+ 7) >> 3);
2192 /* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
2193 * large of png_color. This lets grayscale images be treated as
2194 * paletted. Most useful for gamma correction and simplification
2198 png_build_grayscale_palette(int bit_depth
, png_colorp palette
)
2205 png_debug(1, "in png_do_build_grayscale_palette\n");
2206 if (palette
== NULL
)
2233 for (i
= 0, v
= 0; i
< num_palette
; i
++, v
+= color_inc
)
2235 palette
[i
].red
= (png_byte
)v
;
2236 palette
[i
].green
= (png_byte
)v
;
2237 palette
[i
].blue
= (png_byte
)v
;
2241 /* This function is currently unused. Do we really need it? */
2242 #if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
2244 png_correct_palette(png_structp png_ptr
, png_colorp palette
,
2247 png_debug(1, "in png_correct_palette\n");
2248 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
2249 if (png_ptr
->transformations
& (PNG_GAMMA
| PNG_BACKGROUND
))
2251 png_color back
, back_1
;
2253 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_FILE
)
2255 back
.red
= png_ptr
->gamma_table
[png_ptr
->background
.red
];
2256 back
.green
= png_ptr
->gamma_table
[png_ptr
->background
.green
];
2257 back
.blue
= png_ptr
->gamma_table
[png_ptr
->background
.blue
];
2259 back_1
.red
= png_ptr
->gamma_to_1
[png_ptr
->background
.red
];
2260 back_1
.green
= png_ptr
->gamma_to_1
[png_ptr
->background
.green
];
2261 back_1
.blue
= png_ptr
->gamma_to_1
[png_ptr
->background
.blue
];
2267 g
= 1.0 / (png_ptr
->background_gamma
* png_ptr
->screen_gamma
);
2269 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_SCREEN
||
2270 fabs(g
- 1.0) < PNG_GAMMA_THRESHOLD
)
2272 back
.red
= png_ptr
->background
.red
;
2273 back
.green
= png_ptr
->background
.green
;
2274 back
.blue
= png_ptr
->background
.blue
;
2279 (png_byte
)(pow((double)png_ptr
->background
.red
/255, g
) *
2282 (png_byte
)(pow((double)png_ptr
->background
.green
/255, g
) *
2285 (png_byte
)(pow((double)png_ptr
->background
.blue
/255, g
) *
2289 g
= 1.0 / png_ptr
->background_gamma
;
2292 (png_byte
)(pow((double)png_ptr
->background
.red
/255, g
) *
2295 (png_byte
)(pow((double)png_ptr
->background
.green
/255, g
) *
2298 (png_byte
)(pow((double)png_ptr
->background
.blue
/255, g
) *
2302 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
2306 for (i
= 0; i
< (png_uint_32
)num_palette
; i
++)
2308 if (i
< png_ptr
->num_trans
&& png_ptr
->trans
[i
] == 0)
2312 else if (i
< png_ptr
->num_trans
&& png_ptr
->trans
[i
] != 0xff)
2316 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].red
];
2317 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.red
);
2318 palette
[i
].red
= png_ptr
->gamma_from_1
[w
];
2320 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].green
];
2321 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.green
);
2322 palette
[i
].green
= png_ptr
->gamma_from_1
[w
];
2324 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].blue
];
2325 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.blue
);
2326 palette
[i
].blue
= png_ptr
->gamma_from_1
[w
];
2330 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2331 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2332 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2340 for (i
= 0; i
< num_palette
; i
++)
2342 if (palette
[i
].red
== (png_byte
)png_ptr
->trans_values
.gray
)
2348 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2349 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2350 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2357 #if defined(PNG_READ_GAMMA_SUPPORTED)
2358 if (png_ptr
->transformations
& PNG_GAMMA
)
2362 for (i
= 0; i
< num_palette
; i
++)
2364 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2365 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2366 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2369 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2373 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2374 if (png_ptr
->transformations
& PNG_BACKGROUND
)
2376 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
2380 back
.red
= (png_byte
)png_ptr
->background
.red
;
2381 back
.green
= (png_byte
)png_ptr
->background
.green
;
2382 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
2384 for (i
= 0; i
< (int)png_ptr
->num_trans
; i
++)
2386 if (png_ptr
->trans
[i
] == 0)
2388 palette
[i
].red
= back
.red
;
2389 palette
[i
].green
= back
.green
;
2390 palette
[i
].blue
= back
.blue
;
2392 else if (png_ptr
->trans
[i
] != 0xff)
2394 png_composite(palette
[i
].red
, png_ptr
->palette
[i
].red
,
2395 png_ptr
->trans
[i
], back
.red
);
2396 png_composite(palette
[i
].green
, png_ptr
->palette
[i
].green
,
2397 png_ptr
->trans
[i
], back
.green
);
2398 png_composite(palette
[i
].blue
, png_ptr
->palette
[i
].blue
,
2399 png_ptr
->trans
[i
], back
.blue
);
2403 else /* assume grayscale palette (what else could it be?) */
2407 for (i
= 0; i
< num_palette
; i
++)
2409 if (i
== (png_byte
)png_ptr
->trans_values
.gray
)
2411 palette
[i
].red
= (png_byte
)png_ptr
->background
.red
;
2412 palette
[i
].green
= (png_byte
)png_ptr
->background
.green
;
2413 palette
[i
].blue
= (png_byte
)png_ptr
->background
.blue
;
2422 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2423 /* Replace any alpha or transparency with the supplied background color.
2424 * "background" is already in the screen gamma, while "background_1" is
2425 * at a gamma of 1.0. Paletted files have already been taken care of.
2428 png_do_background(png_row_infop row_info
, png_bytep row
,
2429 png_color_16p trans_values
, png_color_16p background
,
2430 png_color_16p background_1
,
2431 png_bytep gamma_table
, png_bytep gamma_from_1
, png_bytep gamma_to_1
,
2432 png_uint_16pp gamma_16
, png_uint_16pp gamma_16_from_1
,
2433 png_uint_16pp gamma_16_to_1
, int gamma_shift
)
2437 png_uint_32 row_width
=row_info
->width
;
2440 png_debug(1, "in png_do_background\n");
2441 if (background
!= NULL
&&
2442 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2443 row
!= NULL
&& row_info
!= NULL
&&
2445 (!(row_info
->color_type
& PNG_COLOR_MASK_ALPHA
) ||
2446 (row_info
->color_type
!= PNG_COLOR_TYPE_PALETTE
&& trans_values
)))
2448 switch (row_info
->color_type
)
2450 case PNG_COLOR_TYPE_GRAY
:
2452 switch (row_info
->bit_depth
)
2458 for (i
= 0; i
< row_width
; i
++)
2460 if ((png_uint_16
)((*sp
>> shift
) & 0x1)
2461 == trans_values
->gray
)
2463 *sp
&= (png_byte
)((0x7f7f >> (7 - shift
)) & 0xff);
2464 *sp
|= (png_byte
)(background
->gray
<< shift
);
2478 #if defined(PNG_READ_GAMMA_SUPPORTED)
2479 if (gamma_table
!= NULL
)
2483 for (i
= 0; i
< row_width
; i
++)
2485 if ((png_uint_16
)((*sp
>> shift
) & 0x3)
2486 == trans_values
->gray
)
2488 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2489 *sp
|= (png_byte
)(background
->gray
<< shift
);
2493 png_byte p
= (*sp
>> shift
) & 0x3;
2494 png_byte g
= (gamma_table
[p
| (p
<< 2) | (p
<< 4) |
2495 (p
<< 6)] >> 6) & 0x3;
2496 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2497 *sp
|= (png_byte
)(g
<< shift
);
2513 for (i
= 0; i
< row_width
; i
++)
2515 if ((png_uint_16
)((*sp
>> shift
) & 0x3)
2516 == trans_values
->gray
)
2518 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2519 *sp
|= (png_byte
)(background
->gray
<< shift
);
2534 #if defined(PNG_READ_GAMMA_SUPPORTED)
2535 if (gamma_table
!= NULL
)
2539 for (i
= 0; i
< row_width
; i
++)
2541 if ((png_uint_16
)((*sp
>> shift
) & 0xf)
2542 == trans_values
->gray
)
2544 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2545 *sp
|= (png_byte
)(background
->gray
<< shift
);
2549 png_byte p
= (*sp
>> shift
) & 0xf;
2550 png_byte g
= (gamma_table
[p
| (p
<< 4)] >> 4) & 0xf;
2551 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2552 *sp
|= (png_byte
)(g
<< shift
);
2568 for (i
= 0; i
< row_width
; i
++)
2570 if ((png_uint_16
)((*sp
>> shift
) & 0xf)
2571 == trans_values
->gray
)
2573 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2574 *sp
|= (png_byte
)(background
->gray
<< shift
);
2589 #if defined(PNG_READ_GAMMA_SUPPORTED)
2590 if (gamma_table
!= NULL
)
2593 for (i
= 0; i
< row_width
; i
++, sp
++)
2595 if (*sp
== trans_values
->gray
)
2597 *sp
= (png_byte
)background
->gray
;
2601 *sp
= gamma_table
[*sp
];
2609 for (i
= 0; i
< row_width
; i
++, sp
++)
2611 if (*sp
== trans_values
->gray
)
2613 *sp
= (png_byte
)background
->gray
;
2621 #if defined(PNG_READ_GAMMA_SUPPORTED)
2622 if (gamma_16
!= NULL
)
2625 for (i
= 0; i
< row_width
; i
++, sp
+= 2)
2629 v
= ((png_uint_16
)(*sp
) << 8) + *(sp
+ 1);
2630 if (v
== trans_values
->gray
)
2632 /* background is already in screen gamma */
2633 *sp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2634 *(sp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2638 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2639 *sp
= (png_byte
)((v
>> 8) & 0xff);
2640 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2648 for (i
= 0; i
< row_width
; i
++, sp
+= 2)
2652 v
= ((png_uint_16
)(*sp
) << 8) + *(sp
+ 1);
2653 if (v
== trans_values
->gray
)
2655 *sp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2656 *(sp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2665 case PNG_COLOR_TYPE_RGB
:
2667 if (row_info
->bit_depth
== 8)
2669 #if defined(PNG_READ_GAMMA_SUPPORTED)
2670 if (gamma_table
!= NULL
)
2673 for (i
= 0; i
< row_width
; i
++, sp
+= 3)
2675 if (*sp
== trans_values
->red
&&
2676 *(sp
+ 1) == trans_values
->green
&&
2677 *(sp
+ 2) == trans_values
->blue
)
2679 *sp
= (png_byte
)background
->red
;
2680 *(sp
+ 1) = (png_byte
)background
->green
;
2681 *(sp
+ 2) = (png_byte
)background
->blue
;
2685 *sp
= gamma_table
[*sp
];
2686 *(sp
+ 1) = gamma_table
[*(sp
+ 1)];
2687 *(sp
+ 2) = gamma_table
[*(sp
+ 2)];
2695 for (i
= 0; i
< row_width
; i
++, sp
+= 3)
2697 if (*sp
== trans_values
->red
&&
2698 *(sp
+ 1) == trans_values
->green
&&
2699 *(sp
+ 2) == trans_values
->blue
)
2701 *sp
= (png_byte
)background
->red
;
2702 *(sp
+ 1) = (png_byte
)background
->green
;
2703 *(sp
+ 2) = (png_byte
)background
->blue
;
2708 else /* if (row_info->bit_depth == 16) */
2710 #if defined(PNG_READ_GAMMA_SUPPORTED)
2711 if (gamma_16
!= NULL
)
2714 for (i
= 0; i
< row_width
; i
++, sp
+= 6)
2716 png_uint_16 r
= ((png_uint_16
)(*sp
) << 8) + *(sp
+ 1);
2717 png_uint_16 g
= ((png_uint_16
)(*(sp
+ 2)) << 8) + *(sp
+ 3);
2718 png_uint_16 b
= ((png_uint_16
)(*(sp
+ 4)) << 8) + *(sp
+ 5);
2719 if (r
== trans_values
->red
&& g
== trans_values
->green
&&
2720 b
== trans_values
->blue
)
2722 /* background is already in screen gamma */
2723 *sp
= (png_byte
)((background
->red
>> 8) & 0xff);
2724 *(sp
+ 1) = (png_byte
)(background
->red
& 0xff);
2725 *(sp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
2726 *(sp
+ 3) = (png_byte
)(background
->green
& 0xff);
2727 *(sp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
2728 *(sp
+ 5) = (png_byte
)(background
->blue
& 0xff);
2732 png_uint_16 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2733 *sp
= (png_byte
)((v
>> 8) & 0xff);
2734 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2735 v
= gamma_16
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
2736 *(sp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
2737 *(sp
+ 3) = (png_byte
)(v
& 0xff);
2738 v
= gamma_16
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
2739 *(sp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
2740 *(sp
+ 5) = (png_byte
)(v
& 0xff);
2748 for (i
= 0; i
< row_width
; i
++, sp
+= 6)
2750 png_uint_16 r
= ((png_uint_16
)(*sp
) << 8) + *(sp
+ 1);
2751 png_uint_16 g
= ((png_uint_16
)(*(sp
+ 2)) << 8) + *(sp
+ 3);
2752 png_uint_16 b
= ((png_uint_16
)(*(sp
+ 4)) << 8) + *(sp
+ 5);
2754 if (r
== trans_values
->red
&& g
== trans_values
->green
&&
2755 b
== trans_values
->blue
)
2757 *sp
= (png_byte
)((background
->red
>> 8) & 0xff);
2758 *(sp
+ 1) = (png_byte
)(background
->red
& 0xff);
2759 *(sp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
2760 *(sp
+ 3) = (png_byte
)(background
->green
& 0xff);
2761 *(sp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
2762 *(sp
+ 5) = (png_byte
)(background
->blue
& 0xff);
2769 case PNG_COLOR_TYPE_GRAY_ALPHA
:
2771 if (row_info
->bit_depth
== 8)
2773 #if defined(PNG_READ_GAMMA_SUPPORTED)
2774 if (gamma_to_1
!= NULL
&& gamma_from_1
!= NULL
&&
2775 gamma_table
!= NULL
)
2779 for (i
= 0; i
< row_width
; i
++, sp
+= 2, dp
++)
2781 png_uint_16 a
= *(sp
+ 1);
2785 *dp
= gamma_table
[*sp
];
2789 /* background is already in screen gamma */
2790 *dp
= (png_byte
)background
->gray
;
2796 v
= gamma_to_1
[*sp
];
2797 png_composite(w
, v
, a
, background_1
->gray
);
2798 *dp
= gamma_from_1
[w
];
2807 for (i
= 0; i
< row_width
; i
++, sp
+= 2, dp
++)
2809 png_byte a
= *(sp
+ 1);
2817 *dp
= (png_byte
)background
->gray
;
2821 png_composite(*dp
, *sp
, a
, background_1
->gray
);
2826 else /* if (png_ptr->bit_depth == 16) */
2828 #if defined(PNG_READ_GAMMA_SUPPORTED)
2829 if (gamma_16
!= NULL
&& gamma_16_from_1
!= NULL
&&
2830 gamma_16_to_1
!= NULL
)
2834 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 2)
2836 png_uint_16 a
= ((png_uint_16
)(*(sp
+ 2)) << 8) + *(sp
+ 3);
2838 if (a
== (png_uint_16
)0xffff)
2842 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2843 *dp
= (png_byte
)((v
>> 8) & 0xff);
2844 *(dp
+ 1) = (png_byte
)(v
& 0xff);
2848 /* background is already in screen gamma */
2849 *dp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2850 *(dp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2854 png_uint_16 g
, v
, w
;
2856 g
= gamma_16_to_1
[*(sp
+ 1) >> gamma_shift
][*sp
];
2857 png_composite_16(v
, g
, a
, background_1
->gray
);
2858 w
= gamma_16_from_1
[(v
&0xff) >> gamma_shift
][v
>> 8];
2859 *dp
= (png_byte
)((w
>> 8) & 0xff);
2860 *(dp
+ 1) = (png_byte
)(w
& 0xff);
2869 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 2)
2871 png_uint_16 a
= ((png_uint_16
)(*(sp
+ 2)) << 8) + *(sp
+ 3);
2872 if (a
== (png_uint_16
)0xffff)
2874 png_memcpy(dp
, sp
, 2);
2878 *dp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2879 *(dp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2885 g
= ((png_uint_16
)(*sp
) << 8) + *(sp
+ 1);
2886 png_composite_16(v
, g
, a
, background_1
->gray
);
2887 *dp
= (png_byte
)((v
>> 8) & 0xff);
2888 *(dp
+ 1) = (png_byte
)(v
& 0xff);
2895 case PNG_COLOR_TYPE_RGB_ALPHA
:
2897 if (row_info
->bit_depth
== 8)
2899 #if defined(PNG_READ_GAMMA_SUPPORTED)
2900 if (gamma_to_1
!= NULL
&& gamma_from_1
!= NULL
&&
2901 gamma_table
!= NULL
)
2905 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 3)
2907 png_byte a
= *(sp
+ 3);
2911 *dp
= gamma_table
[*sp
];
2912 *(dp
+ 1) = gamma_table
[*(sp
+ 1)];
2913 *(dp
+ 2) = gamma_table
[*(sp
+ 2)];
2917 /* background is already in screen gamma */
2918 *dp
= (png_byte
)background
->red
;
2919 *(dp
+ 1) = (png_byte
)background
->green
;
2920 *(dp
+ 2) = (png_byte
)background
->blue
;
2926 v
= gamma_to_1
[*sp
];
2927 png_composite(w
, v
, a
, background_1
->red
);
2928 *dp
= gamma_from_1
[w
];
2929 v
= gamma_to_1
[*(sp
+ 1)];
2930 png_composite(w
, v
, a
, background_1
->green
);
2931 *(dp
+ 1) = gamma_from_1
[w
];
2932 v
= gamma_to_1
[*(sp
+ 2)];
2933 png_composite(w
, v
, a
, background_1
->blue
);
2934 *(dp
+ 2) = gamma_from_1
[w
];
2943 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 3)
2945 png_byte a
= *(sp
+ 3);
2950 *(dp
+ 1) = *(sp
+ 1);
2951 *(dp
+ 2) = *(sp
+ 2);
2955 *dp
= (png_byte
)background
->red
;
2956 *(dp
+ 1) = (png_byte
)background
->green
;
2957 *(dp
+ 2) = (png_byte
)background
->blue
;
2961 png_composite(*dp
, *sp
, a
, background
->red
);
2962 png_composite(*(dp
+ 1), *(sp
+ 1), a
,
2964 png_composite(*(dp
+ 2), *(sp
+ 2), a
,
2970 else /* if (row_info->bit_depth == 16) */
2972 #if defined(PNG_READ_GAMMA_SUPPORTED)
2973 if (gamma_16
!= NULL
&& gamma_16_from_1
!= NULL
&&
2974 gamma_16_to_1
!= NULL
)
2978 for (i
= 0; i
< row_width
; i
++, sp
+= 8, dp
+= 6)
2980 png_uint_16 a
= (png_uint_16
)(((png_uint_16
)(*(sp
+ 6))
2981 << 8) + (png_uint_16
)(*(sp
+ 7)));
2982 if (a
== (png_uint_16
)0xffff)
2986 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2987 *dp
= (png_byte
)((v
>> 8) & 0xff);
2988 *(dp
+ 1) = (png_byte
)(v
& 0xff);
2989 v
= gamma_16
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
2990 *(dp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
2991 *(dp
+ 3) = (png_byte
)(v
& 0xff);
2992 v
= gamma_16
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
2993 *(dp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
2994 *(dp
+ 5) = (png_byte
)(v
& 0xff);
2998 /* background is already in screen gamma */
2999 *dp
= (png_byte
)((background
->red
>> 8) & 0xff);
3000 *(dp
+ 1) = (png_byte
)(background
->red
& 0xff);
3001 *(dp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
3002 *(dp
+ 3) = (png_byte
)(background
->green
& 0xff);
3003 *(dp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
3004 *(dp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3008 png_uint_16 v
, w
, x
;
3010 v
= gamma_16_to_1
[*(sp
+ 1) >> gamma_shift
][*sp
];
3011 png_composite_16(w
, v
, a
, background
->red
);
3012 x
= gamma_16_from_1
[((w
&0xff) >> gamma_shift
)][w
>> 8];
3013 *dp
= (png_byte
)((x
>> 8) & 0xff);
3014 *(dp
+ 1) = (png_byte
)(x
& 0xff);
3015 v
= gamma_16_to_1
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
3016 png_composite_16(w
, v
, a
, background
->green
);
3017 x
= gamma_16_from_1
[((w
&0xff) >> gamma_shift
)][w
>> 8];
3018 *(dp
+ 2) = (png_byte
)((x
>> 8) & 0xff);
3019 *(dp
+ 3) = (png_byte
)(x
& 0xff);
3020 v
= gamma_16_to_1
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
3021 png_composite_16(w
, v
, a
, background
->blue
);
3022 x
= gamma_16_from_1
[(w
& 0xff) >> gamma_shift
][w
>> 8];
3023 *(dp
+ 4) = (png_byte
)((x
>> 8) & 0xff);
3024 *(dp
+ 5) = (png_byte
)(x
& 0xff);
3033 for (i
= 0; i
< row_width
; i
++, sp
+= 8, dp
+= 6)
3035 png_uint_16 a
= (png_uint_16
)(((png_uint_16
)(*(sp
+ 6))
3036 << 8) + (png_uint_16
)(*(sp
+ 7)));
3037 if (a
== (png_uint_16
)0xffff)
3039 png_memcpy(dp
, sp
, 6);
3043 *dp
= (png_byte
)((background
->red
>> 8) & 0xff);
3044 *(dp
+ 1) = (png_byte
)(background
->red
& 0xff);
3045 *(dp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
3046 *(dp
+ 3) = (png_byte
)(background
->green
& 0xff);
3047 *(dp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
3048 *(dp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3054 png_uint_16 r
= ((png_uint_16
)(*sp
) << 8) + *(sp
+ 1);
3055 png_uint_16 g
= ((png_uint_16
)(*(sp
+ 2)) << 8)
3057 png_uint_16 b
= ((png_uint_16
)(*(sp
+ 4)) << 8)
3060 png_composite_16(v
, r
, a
, background
->red
);
3061 *dp
= (png_byte
)((v
>> 8) & 0xff);
3062 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3063 png_composite_16(v
, g
, a
, background
->green
);
3064 *(dp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
3065 *(dp
+ 3) = (png_byte
)(v
& 0xff);
3066 png_composite_16(v
, b
, a
, background
->blue
);
3067 *(dp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
3068 *(dp
+ 5) = (png_byte
)(v
& 0xff);
3077 if (row_info
->color_type
& PNG_COLOR_MASK_ALPHA
)
3079 row_info
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
3080 row_info
->channels
--;
3081 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
3082 row_info
->bit_depth
);
3083 row_info
->rowbytes
= ((row_width
*
3084 row_info
->pixel_depth
+ 7) >> 3);
3090 #if defined(PNG_READ_GAMMA_SUPPORTED)
3091 /* Gamma correct the image, avoiding the alpha channel. Make sure
3092 * you do this after you deal with the transparency issue on grayscale
3093 * or rgb images. If your bit depth is 8, use gamma_table, if it
3094 * is 16, use gamma_16_table and gamma_shift. Build these with
3095 * build_gamma_table().
3098 png_do_gamma(png_row_infop row_info
, png_bytep row
,
3099 png_bytep gamma_table
, png_uint_16pp gamma_16_table
,
3104 png_uint_32 row_width
=row_info
->width
;
3106 png_debug(1, "in png_do_gamma\n");
3108 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3109 row
!= NULL
&& row_info
!= NULL
&&
3111 ((row_info
->bit_depth
<= 8 && gamma_table
!= NULL
) ||
3112 (row_info
->bit_depth
== 16 && gamma_16_table
!= NULL
)))
3114 switch (row_info
->color_type
)
3116 case PNG_COLOR_TYPE_RGB
:
3118 if (row_info
->bit_depth
== 8)
3121 for (i
= 0; i
< row_width
; i
++)
3123 *sp
= gamma_table
[*sp
];
3125 *sp
= gamma_table
[*sp
];
3127 *sp
= gamma_table
[*sp
];
3131 else /* if (row_info->bit_depth == 16) */
3134 for (i
= 0; i
< row_width
; i
++)
3138 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3139 *sp
= (png_byte
)((v
>> 8) & 0xff);
3140 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3142 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3143 *sp
= (png_byte
)((v
>> 8) & 0xff);
3144 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3146 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3147 *sp
= (png_byte
)((v
>> 8) & 0xff);
3148 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3154 case PNG_COLOR_TYPE_RGB_ALPHA
:
3156 if (row_info
->bit_depth
== 8)
3159 for (i
= 0; i
< row_width
; i
++)
3161 *sp
= gamma_table
[*sp
];
3163 *sp
= gamma_table
[*sp
];
3165 *sp
= gamma_table
[*sp
];
3170 else /* if (row_info->bit_depth == 16) */
3173 for (i
= 0; i
< row_width
; i
++)
3175 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3176 *sp
= (png_byte
)((v
>> 8) & 0xff);
3177 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3179 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3180 *sp
= (png_byte
)((v
>> 8) & 0xff);
3181 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3183 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3184 *sp
= (png_byte
)((v
>> 8) & 0xff);
3185 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3191 case PNG_COLOR_TYPE_GRAY_ALPHA
:
3193 if (row_info
->bit_depth
== 8)
3196 for (i
= 0; i
< row_width
; i
++)
3198 *sp
= gamma_table
[*sp
];
3202 else /* if (row_info->bit_depth == 16) */
3205 for (i
= 0; i
< row_width
; i
++)
3207 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3208 *sp
= (png_byte
)((v
>> 8) & 0xff);
3209 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3215 case PNG_COLOR_TYPE_GRAY
:
3217 if (row_info
->bit_depth
== 2)
3220 for (i
= 0; i
< row_width
; i
+= 4)
3227 *sp
= ((((int)gamma_table
[a
|(a
>>2)|(a
>>4)|(a
>>6)]) ) & 0xc0)|
3228 ((((int)gamma_table
[(b
<<2)|b
|(b
>>2)|(b
>>4)])>>2) & 0x30)|
3229 ((((int)gamma_table
[(c
<<4)|(c
<<2)|c
|(c
>>2)])>>4) & 0x0c)|
3230 ((((int)gamma_table
[(d
<<6)|(d
<<4)|(d
<<2)|d
])>>6) );
3234 if (row_info
->bit_depth
== 4)
3237 for (i
= 0; i
< row_width
; i
+= 2)
3239 int msb
= *sp
& 0xf0;
3240 int lsb
= *sp
& 0x0f;
3242 *sp
= (((int)gamma_table
[msb
| (msb
>> 4)]) & 0xf0) |
3243 (((int)gamma_table
[(lsb
<< 4) | lsb
]) >> 4);
3247 else if (row_info
->bit_depth
== 8)
3250 for (i
= 0; i
< row_width
; i
++)
3252 *sp
= gamma_table
[*sp
];
3256 else if (row_info
->bit_depth
== 16)
3259 for (i
= 0; i
< row_width
; i
++)
3261 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3262 *sp
= (png_byte
)((v
>> 8) & 0xff);
3263 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3274 #if defined(PNG_READ_EXPAND_SUPPORTED)
3275 /* Expands a palette row to an rgb or rgba row depending
3276 * upon whether you supply trans and num_trans.
3279 png_do_expand_palette(png_row_infop row_info
, png_bytep row
,
3280 png_colorp palette
, png_bytep trans
, int num_trans
)
3285 png_uint_32 row_width
=row_info
->width
;
3287 png_debug(1, "in png_do_expand_palette\n");
3289 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3290 row
!= NULL
&& row_info
!= NULL
&&
3292 row_info
->color_type
== PNG_COLOR_TYPE_PALETTE
)
3294 if (row_info
->bit_depth
< 8)
3296 switch (row_info
->bit_depth
)
3300 sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
3301 dp
= row
+ (png_size_t
)row_width
- 1;
3302 shift
= 7 - (int)((row_width
+ 7) & 7);
3303 for (i
= 0; i
< row_width
; i
++)
3305 if ((*sp
>> shift
) & 0x1)
3323 sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
3324 dp
= row
+ (png_size_t
)row_width
- 1;
3325 shift
= (int)((3 - ((row_width
+ 3) & 3)) << 1);
3326 for (i
= 0; i
< row_width
; i
++)
3328 value
= (*sp
>> shift
) & 0x3;
3329 *dp
= (png_byte
)value
;
3344 sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
3345 dp
= row
+ (png_size_t
)row_width
- 1;
3346 shift
= (int)((row_width
& 1) << 2);
3347 for (i
= 0; i
< row_width
; i
++)
3349 value
= (*sp
>> shift
) & 0xf;
3350 *dp
= (png_byte
)value
;
3364 row_info
->bit_depth
= 8;
3365 row_info
->pixel_depth
= 8;
3366 row_info
->rowbytes
= row_width
;
3368 switch (row_info
->bit_depth
)
3374 sp
= row
+ (png_size_t
)row_width
- 1;
3375 dp
= row
+ (png_size_t
)(row_width
<< 2) - 1;
3377 for (i
= 0; i
< row_width
; i
++)
3379 if ((int)(*sp
) >= num_trans
)
3383 *dp
-- = palette
[*sp
].blue
;
3384 *dp
-- = palette
[*sp
].green
;
3385 *dp
-- = palette
[*sp
].red
;
3388 row_info
->bit_depth
= 8;
3389 row_info
->pixel_depth
= 32;
3390 row_info
->rowbytes
= row_width
* 4;
3391 row_info
->color_type
= 6;
3392 row_info
->channels
= 4;
3396 sp
= row
+ (png_size_t
)row_width
- 1;
3397 dp
= row
+ (png_size_t
)(row_width
* 3) - 1;
3399 for (i
= 0; i
< row_width
; i
++)
3401 *dp
-- = palette
[*sp
].blue
;
3402 *dp
-- = palette
[*sp
].green
;
3403 *dp
-- = palette
[*sp
].red
;
3406 row_info
->bit_depth
= 8;
3407 row_info
->pixel_depth
= 24;
3408 row_info
->rowbytes
= row_width
* 3;
3409 row_info
->color_type
= 2;
3410 row_info
->channels
= 3;
3418 /* If the bit depth < 8, it is expanded to 8. Also, if the
3419 * transparency value is supplied, an alpha channel is built.
3422 png_do_expand(png_row_infop row_info
, png_bytep row
,
3423 png_color_16p trans_value
)
3428 png_uint_32 row_width
=row_info
->width
;
3430 png_debug(1, "in png_do_expand\n");
3431 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3432 if (row
!= NULL
&& row_info
!= NULL
)
3435 if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
3437 png_uint_16 gray
= trans_value
? trans_value
->gray
: 0;
3439 if (row_info
->bit_depth
< 8)
3441 switch (row_info
->bit_depth
)
3446 sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
3447 dp
= row
+ (png_size_t
)row_width
- 1;
3448 shift
= 7 - (int)((row_width
+ 7) & 7);
3449 for (i
= 0; i
< row_width
; i
++)
3451 if ((*sp
>> shift
) & 0x1)
3470 sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
3471 dp
= row
+ (png_size_t
)row_width
- 1;
3472 shift
= (int)((3 - ((row_width
+ 3) & 3)) << 1);
3473 for (i
= 0; i
< row_width
; i
++)
3475 value
= (*sp
>> shift
) & 0x3;
3476 *dp
= (png_byte
)(value
| (value
<< 2) | (value
<< 4) |
3493 sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
3494 dp
= row
+ (png_size_t
)row_width
- 1;
3495 shift
= (int)((1 - ((row_width
+ 1) & 1)) << 2);
3496 for (i
= 0; i
< row_width
; i
++)
3498 value
= (*sp
>> shift
) & 0xf;
3499 *dp
= (png_byte
)(value
| (value
<< 4));
3513 row_info
->bit_depth
= 8;
3514 row_info
->pixel_depth
= 8;
3515 row_info
->rowbytes
= row_width
;
3518 if (trans_value
!= NULL
)
3520 if (row_info
->bit_depth
== 8)
3522 sp
= row
+ (png_size_t
)row_width
- 1;
3523 dp
= row
+ (png_size_t
)(row_width
<< 1) - 1;
3524 for (i
= 0; i
< row_width
; i
++)
3533 else if (row_info
->bit_depth
== 16)
3535 sp
= row
+ row_info
->rowbytes
- 1;
3536 dp
= row
+ (row_info
->rowbytes
<< 1) - 1;
3537 for (i
= 0; i
< row_width
; i
++)
3539 if (((png_uint_16
)*(sp
) |
3540 ((png_uint_16
)*(sp
- 1) << 8)) == gray
)
3554 row_info
->color_type
= PNG_COLOR_TYPE_GRAY_ALPHA
;
3555 row_info
->channels
= 2;
3556 row_info
->pixel_depth
= (png_byte
)(row_info
->bit_depth
<< 1);
3557 row_info
->rowbytes
=
3558 ((row_width
* row_info
->pixel_depth
) >> 3);
3561 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
&& trans_value
)
3563 if (row_info
->bit_depth
== 8)
3565 sp
= row
+ (png_size_t
)row_info
->rowbytes
- 1;
3566 dp
= row
+ (png_size_t
)(row_width
<< 2) - 1;
3567 for (i
= 0; i
< row_width
; i
++)
3569 if (*(sp
- 2) == trans_value
->red
&&
3570 *(sp
- 1) == trans_value
->green
&&
3571 *(sp
- 0) == trans_value
->blue
)
3580 else if (row_info
->bit_depth
== 16)
3582 sp
= row
+ row_info
->rowbytes
- 1;
3583 dp
= row
+ (png_size_t
)(row_width
<< 3) - 1;
3584 for (i
= 0; i
< row_width
; i
++)
3586 if ((((png_uint_16
)*(sp
- 4) |
3587 ((png_uint_16
)*(sp
- 5) << 8)) == trans_value
->red
) &&
3588 (((png_uint_16
)*(sp
- 2) |
3589 ((png_uint_16
)*(sp
- 3) << 8)) == trans_value
->green
) &&
3590 (((png_uint_16
)*(sp
- 0) |
3591 ((png_uint_16
)*(sp
- 1) << 8)) == trans_value
->blue
))
3609 row_info
->color_type
= PNG_COLOR_TYPE_RGB_ALPHA
;
3610 row_info
->channels
= 4;
3611 row_info
->pixel_depth
= (png_byte
)(row_info
->bit_depth
<< 2);
3612 row_info
->rowbytes
=
3613 ((row_width
* row_info
->pixel_depth
) >> 3);
3619 #if defined(PNG_READ_DITHER_SUPPORTED)
3621 png_do_dither(png_row_infop row_info
, png_bytep row
,
3622 png_bytep palette_lookup
, png_bytep dither_lookup
)
3626 png_uint_32 row_width
=row_info
->width
;
3628 png_debug(1, "in png_do_dither\n");
3629 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3630 if (row
!= NULL
&& row_info
!= NULL
)
3633 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
&&
3634 palette_lookup
&& row_info
->bit_depth
== 8)
3639 for (i
= 0; i
< row_width
; i
++)
3645 /* this looks real messy, but the compiler will reduce
3646 it down to a reasonable formula. For example, with
3647 5 bits per color, we get:
3648 p = (((r >> 3) & 0x1f) << 10) |
3649 (((g >> 3) & 0x1f) << 5) |
3652 p
= (((r
>> (8 - PNG_DITHER_RED_BITS
)) &
3653 ((1 << PNG_DITHER_RED_BITS
) - 1)) <<
3654 (PNG_DITHER_GREEN_BITS
+ PNG_DITHER_BLUE_BITS
)) |
3655 (((g
>> (8 - PNG_DITHER_GREEN_BITS
)) &
3656 ((1 << PNG_DITHER_GREEN_BITS
) - 1)) <<
3657 (PNG_DITHER_BLUE_BITS
)) |
3658 ((b
>> (8 - PNG_DITHER_BLUE_BITS
)) &
3659 ((1 << PNG_DITHER_BLUE_BITS
) - 1));
3661 *dp
++ = palette_lookup
[p
];
3663 row_info
->color_type
= PNG_COLOR_TYPE_PALETTE
;
3664 row_info
->channels
= 1;
3665 row_info
->pixel_depth
= row_info
->bit_depth
;
3666 row_info
->rowbytes
=
3667 ((row_width
* row_info
->pixel_depth
+ 7) >> 3);
3669 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
&&
3670 palette_lookup
!= NULL
&& row_info
->bit_depth
== 8)
3675 for (i
= 0; i
< row_width
; i
++)
3682 p
= (((r
>> (8 - PNG_DITHER_RED_BITS
)) &
3683 ((1 << PNG_DITHER_RED_BITS
) - 1)) <<
3684 (PNG_DITHER_GREEN_BITS
+ PNG_DITHER_BLUE_BITS
)) |
3685 (((g
>> (8 - PNG_DITHER_GREEN_BITS
)) &
3686 ((1 << PNG_DITHER_GREEN_BITS
) - 1)) <<
3687 (PNG_DITHER_BLUE_BITS
)) |
3688 ((b
>> (8 - PNG_DITHER_BLUE_BITS
)) &
3689 ((1 << PNG_DITHER_BLUE_BITS
) - 1));
3691 *dp
++ = palette_lookup
[p
];
3693 row_info
->color_type
= PNG_COLOR_TYPE_PALETTE
;
3694 row_info
->channels
= 1;
3695 row_info
->pixel_depth
= row_info
->bit_depth
;
3696 row_info
->rowbytes
=
3697 ((row_width
* row_info
->pixel_depth
+ 7) >> 3);
3699 else if (row_info
->color_type
== PNG_COLOR_TYPE_PALETTE
&&
3700 dither_lookup
&& row_info
->bit_depth
== 8)
3703 for (i
= 0; i
< row_width
; i
++, sp
++)
3705 *sp
= dither_lookup
[*sp
];
3712 #if defined(PNG_READ_GAMMA_SUPPORTED)
3713 static int png_gamma_shift
[] =
3714 {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0};
3716 /* We build the 8- or 16-bit gamma tables here. Note that for 16-bit
3717 * tables, we don't make a full table if we are reducing to 8-bit in
3718 * the future. Note also how the gamma_16 tables are segmented so that
3719 * we don't need to allocate > 64K chunks for a full 16-bit table.
3722 png_build_gamma_table(png_structp png_ptr
)
3724 png_debug(1, "in png_build_gamma_table\n");
3725 if(png_ptr
->gamma
!= 0.0)
3727 if (png_ptr
->bit_depth
<= 8)
3732 if (png_ptr
->screen_gamma
> .000001)
3733 g
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
3737 png_ptr
->gamma_table
= (png_bytep
)png_malloc(png_ptr
,
3740 for (i
= 0; i
< 256; i
++)
3742 png_ptr
->gamma_table
[i
] = (png_byte
)(pow((double)i
/ 255.0,
3746 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
3747 defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
3748 if (png_ptr
->transformations
& (PNG_BACKGROUND
| PNG_RGB_TO_GRAY
))
3751 g
= 1.0 / (png_ptr
->gamma
);
3753 png_ptr
->gamma_to_1
= (png_bytep
)png_malloc(png_ptr
,
3756 for (i
= 0; i
< 256; i
++)
3758 png_ptr
->gamma_to_1
[i
] = (png_byte
)(pow((double)i
/ 255.0,
3763 png_ptr
->gamma_from_1
= (png_bytep
)png_malloc(png_ptr
,
3766 if(png_ptr
->screen_gamma
> 0.000001)
3767 g
= 1.0 / png_ptr
->screen_gamma
;
3769 g
= png_ptr
->gamma
; /* probably doing rgb_to_gray */
3771 for (i
= 0; i
< 256; i
++)
3773 png_ptr
->gamma_from_1
[i
] = (png_byte
)(pow((double)i
/ 255.0,
3778 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
3783 int i
, j
, shift
, num
;
3787 if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
3789 sig_bit
= (int)png_ptr
->sig_bit
.red
;
3790 if ((int)png_ptr
->sig_bit
.green
> sig_bit
)
3791 sig_bit
= png_ptr
->sig_bit
.green
;
3792 if ((int)png_ptr
->sig_bit
.blue
> sig_bit
)
3793 sig_bit
= png_ptr
->sig_bit
.blue
;
3797 sig_bit
= (int)png_ptr
->sig_bit
.gray
;
3801 shift
= 16 - sig_bit
;
3805 if (png_ptr
->transformations
& PNG_16_TO_8
)
3807 if (shift
< (16 - PNG_MAX_GAMMA_8
))
3808 shift
= (16 - PNG_MAX_GAMMA_8
);
3816 png_ptr
->gamma_shift
= (png_byte
)shift
;
3818 num
= (1 << (8 - shift
));
3820 if (png_ptr
->screen_gamma
> .000001)
3821 g
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
3825 png_ptr
->gamma_16_table
= (png_uint_16pp
)png_malloc(png_ptr
,
3826 (png_uint_32
)(num
* sizeof (png_uint_16p
)));
3828 if (png_ptr
->transformations
& (PNG_16_TO_8
| PNG_BACKGROUND
))
3831 png_uint_32 last
, max
;
3833 for (i
= 0; i
< num
; i
++)
3835 png_ptr
->gamma_16_table
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
3836 (png_uint_32
)(256 * sizeof (png_uint_16
)));
3841 for (i
= 0; i
< 256; i
++)
3843 fout
= ((double)i
+ 0.5) / 256.0;
3845 max
= (png_uint_32
)(fin
* (double)((png_uint_32
)num
<< 8));
3848 png_ptr
->gamma_16_table
[(int)(last
& (0xff >> shift
))]
3849 [(int)(last
>> (8 - shift
))] = (png_uint_16
)(
3850 (png_uint_16
)i
| ((png_uint_16
)i
<< 8));
3854 while (last
< ((png_uint_32
)num
<< 8))
3856 png_ptr
->gamma_16_table
[(int)(last
& (0xff >> shift
))]
3857 [(int)(last
>> (8 - shift
))] = (png_uint_16
)65535L;
3863 for (i
= 0; i
< num
; i
++)
3865 png_ptr
->gamma_16_table
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
3866 (png_uint_32
)(256 * sizeof (png_uint_16
)));
3868 ig
= (((png_uint_32
)i
* (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
3869 for (j
= 0; j
< 256; j
++)
3871 png_ptr
->gamma_16_table
[i
][j
] =
3872 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
3873 65535.0, g
) * 65535.0 + .5);
3878 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
3879 defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
3880 if (png_ptr
->transformations
& (PNG_BACKGROUND
| PNG_RGB_TO_GRAY
))
3883 g
= 1.0 / (png_ptr
->gamma
);
3885 png_ptr
->gamma_16_to_1
= (png_uint_16pp
)png_malloc(png_ptr
,
3886 (png_uint_32
)(num
* sizeof (png_uint_16p
)));
3888 for (i
= 0; i
< num
; i
++)
3890 png_ptr
->gamma_16_to_1
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
3891 (png_uint_32
)(256 * sizeof (png_uint_16
)));
3893 ig
= (((png_uint_32
)i
*
3894 (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
3895 for (j
= 0; j
< 256; j
++)
3897 png_ptr
->gamma_16_to_1
[i
][j
] =
3898 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
3899 65535.0, g
) * 65535.0 + .5);
3903 if(png_ptr
->screen_gamma
> 0.000001)
3904 g
= 1.0 / png_ptr
->screen_gamma
;
3906 g
= png_ptr
->gamma
; /* probably doing rgb_to_gray */
3908 png_ptr
->gamma_16_from_1
= (png_uint_16pp
)png_malloc(png_ptr
,
3909 (png_uint_32
)(num
* sizeof (png_uint_16p
)));
3911 for (i
= 0; i
< num
; i
++)
3913 png_ptr
->gamma_16_from_1
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
3914 (png_uint_32
)(256 * sizeof (png_uint_16
)));
3916 ig
= (((png_uint_32
)i
*
3917 (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
3918 for (j
= 0; j
< 256; j
++)
3920 png_ptr
->gamma_16_from_1
[i
][j
] =
3921 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
3922 65535.0, g
) * 65535.0 + .5);
3926 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */