2 /* pngrtran.c - transforms the data in a row for PNG readers
4 * Last changed in libpng 1.2.37 [June 4, 2009]
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1998-2009 Glenn Randers-Pehrson
7 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
10 * This file contains functions optionally called by an application
11 * in order to tell libpng how to handle data when reading a PNG.
12 * Transformations that are used in both reading and writing are
18 #if defined(PNG_READ_SUPPORTED)
20 /* Set the action on getting a CRC error for an ancillary or critical chunk. */
22 png_set_crc_action(png_structp png_ptr
, int crit_action
, int ancil_action
)
24 png_debug(1, "in png_set_crc_action");
25 /* Tell libpng how we react to CRC errors in critical chunks */
30 case PNG_CRC_NO_CHANGE
: /* Leave setting as is */
33 case PNG_CRC_WARN_USE
: /* Warn/use data */
34 png_ptr
->flags
&= ~PNG_FLAG_CRC_CRITICAL_MASK
;
35 png_ptr
->flags
|= PNG_FLAG_CRC_CRITICAL_USE
;
38 case PNG_CRC_QUIET_USE
: /* Quiet/use data */
39 png_ptr
->flags
&= ~PNG_FLAG_CRC_CRITICAL_MASK
;
40 png_ptr
->flags
|= PNG_FLAG_CRC_CRITICAL_USE
|
41 PNG_FLAG_CRC_CRITICAL_IGNORE
;
44 case PNG_CRC_WARN_DISCARD
: /* Not a valid action for critical data */
46 "Can't discard critical data on CRC error.");
47 case PNG_CRC_ERROR_QUIT
: /* Error/quit */
51 png_ptr
->flags
&= ~PNG_FLAG_CRC_CRITICAL_MASK
;
57 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
;
65 case PNG_CRC_QUIET_USE
: /* Quiet/use data */
66 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
67 png_ptr
->flags
|= PNG_FLAG_CRC_ANCILLARY_USE
|
68 PNG_FLAG_CRC_ANCILLARY_NOWARN
;
71 case PNG_CRC_ERROR_QUIT
: /* Error/quit */
72 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
73 png_ptr
->flags
|= PNG_FLAG_CRC_ANCILLARY_NOWARN
;
76 case PNG_CRC_WARN_DISCARD
: /* Warn/discard data */
80 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
85 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
86 defined(PNG_FLOATING_POINT_SUPPORTED)
87 /* Handle alpha and tRNS via a background color */
89 png_set_background(png_structp png_ptr
,
90 png_color_16p background_color
, int background_gamma_code
,
91 int need_expand
, double background_gamma
)
93 png_debug(1, "in png_set_background");
96 if (background_gamma_code
== PNG_BACKGROUND_GAMMA_UNKNOWN
)
98 png_warning(png_ptr
, "Application must supply a known background gamma");
102 png_ptr
->transformations
|= PNG_BACKGROUND
;
103 png_memcpy(&(png_ptr
->background
), background_color
,
104 png_sizeof(png_color_16
));
105 png_ptr
->background_gamma
= (float)background_gamma
;
106 png_ptr
->background_gamma_type
= (png_byte
)(background_gamma_code
);
107 png_ptr
->transformations
|= (need_expand
? PNG_BACKGROUND_EXPAND
: 0);
111 #if defined(PNG_READ_16_TO_8_SUPPORTED)
112 /* Strip 16 bit depth files to 8 bit depth */
114 png_set_strip_16(png_structp png_ptr
)
116 png_debug(1, "in png_set_strip_16");
119 png_ptr
->transformations
|= PNG_16_TO_8
;
123 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
125 png_set_strip_alpha(png_structp png_ptr
)
127 png_debug(1, "in png_set_strip_alpha");
130 png_ptr
->flags
|= PNG_FLAG_STRIP_ALPHA
;
134 #if defined(PNG_READ_DITHER_SUPPORTED)
135 /* Dither file to 8 bit. Supply a palette, the current number
136 * of elements in the palette, the maximum number of elements
137 * allowed, and a histogram if possible. If the current number
138 * of colors is greater then the maximum number, the palette will be
139 * modified to fit in the maximum number. "full_dither" indicates
140 * whether we need a dithering cube set up for RGB images, or if we
141 * simply are reducing the number of colors in a paletted image.
144 typedef struct png_dsort_struct
146 struct png_dsort_struct FAR
* next
;
150 typedef png_dsort FAR
* png_dsortp
;
151 typedef png_dsort FAR
* FAR
* png_dsortpp
;
154 png_set_dither(png_structp png_ptr
, png_colorp palette
,
155 int num_palette
, int maximum_colors
, png_uint_16p histogram
,
158 png_debug(1, "in png_set_dither");
161 png_ptr
->transformations
|= PNG_DITHER
;
167 png_ptr
->dither_index
= (png_bytep
)png_malloc(png_ptr
,
168 (png_uint_32
)(num_palette
* png_sizeof(png_byte
)));
169 for (i
= 0; i
< num_palette
; i
++)
170 png_ptr
->dither_index
[i
] = (png_byte
)i
;
173 if (num_palette
> maximum_colors
)
175 if (histogram
!= NULL
)
177 /* This is easy enough, just throw out the least used colors.
178 * Perhaps not the best solution, but good enough.
183 /* Initialize an array to sort colors */
184 png_ptr
->dither_sort
= (png_bytep
)png_malloc(png_ptr
,
185 (png_uint_32
)(num_palette
* png_sizeof(png_byte
)));
187 /* Initialize the dither_sort array */
188 for (i
= 0; i
< num_palette
; i
++)
189 png_ptr
->dither_sort
[i
] = (png_byte
)i
;
191 /* Find the least used palette entries by starting a
192 * bubble sort, and running it until we have sorted
193 * out enough colors. Note that we don't care about
194 * sorting all the colors, just finding which are
198 for (i
= num_palette
- 1; i
>= maximum_colors
; i
--)
200 int done
; /* To stop early if the list is pre-sorted */
204 for (j
= 0; j
< i
; j
++)
206 if (histogram
[png_ptr
->dither_sort
[j
]]
207 < histogram
[png_ptr
->dither_sort
[j
+ 1]])
211 t
= png_ptr
->dither_sort
[j
];
212 png_ptr
->dither_sort
[j
] = png_ptr
->dither_sort
[j
+ 1];
213 png_ptr
->dither_sort
[j
+ 1] = t
;
221 /* Swap the palette around, and set up a table, if necessary */
226 /* Put all the useful colors within the max, but don't
229 for (i
= 0; i
< maximum_colors
; i
++)
231 if ((int)png_ptr
->dither_sort
[i
] >= maximum_colors
)
235 while ((int)png_ptr
->dither_sort
[j
] >= maximum_colors
);
236 palette
[i
] = palette
[j
];
244 /* Move all the used colors inside the max limit, and
245 * develop a translation table.
247 for (i
= 0; i
< maximum_colors
; i
++)
249 /* Only move the colors we need to */
250 if ((int)png_ptr
->dither_sort
[i
] >= maximum_colors
)
256 while ((int)png_ptr
->dither_sort
[j
] >= maximum_colors
);
258 tmp_color
= palette
[j
];
259 palette
[j
] = palette
[i
];
260 palette
[i
] = tmp_color
;
261 /* Indicate where the color went */
262 png_ptr
->dither_index
[j
] = (png_byte
)i
;
263 png_ptr
->dither_index
[i
] = (png_byte
)j
;
267 /* Find closest color for those colors we are not using */
268 for (i
= 0; i
< num_palette
; i
++)
270 if ((int)png_ptr
->dither_index
[i
] >= maximum_colors
)
272 int min_d
, k
, min_k
, d_index
;
274 /* Find the closest color to one we threw out */
275 d_index
= png_ptr
->dither_index
[i
];
276 min_d
= PNG_COLOR_DIST(palette
[d_index
], palette
[0]);
277 for (k
= 1, min_k
= 0; k
< maximum_colors
; k
++)
281 d
= PNG_COLOR_DIST(palette
[d_index
], palette
[k
]);
289 /* Point to closest color */
290 png_ptr
->dither_index
[i
] = (png_byte
)min_k
;
294 png_free(png_ptr
, png_ptr
->dither_sort
);
295 png_ptr
->dither_sort
= NULL
;
299 /* This is much harder to do simply (and quickly). Perhaps
300 * we need to go through a median cut routine, but those
301 * don't always behave themselves with only a few colors
302 * as input. So we will just find the closest two colors,
303 * and throw out one of them (chosen somewhat randomly).
304 * [We don't understand this at all, so if someone wants to
305 * work on improving it, be our guest - AED, GRP]
315 /* Initialize palette index arrays */
316 png_ptr
->index_to_palette
= (png_bytep
)png_malloc(png_ptr
,
317 (png_uint_32
)(num_palette
* png_sizeof(png_byte
)));
318 png_ptr
->palette_to_index
= (png_bytep
)png_malloc(png_ptr
,
319 (png_uint_32
)(num_palette
* png_sizeof(png_byte
)));
321 /* Initialize the sort array */
322 for (i
= 0; i
< num_palette
; i
++)
324 png_ptr
->index_to_palette
[i
] = (png_byte
)i
;
325 png_ptr
->palette_to_index
[i
] = (png_byte
)i
;
328 hash
= (png_dsortpp
)png_malloc(png_ptr
, (png_uint_32
)(769 *
329 png_sizeof(png_dsortp
)));
330 png_memset(hash
, 0, 769 * png_sizeof(png_dsortp
));
332 num_new_palette
= num_palette
;
334 /* Initial wild guess at how far apart the farthest pixel
335 * pair we will be eliminating will be. Larger
336 * numbers mean more areas will be allocated, Smaller
337 * numbers run the risk of not saving enough data, and
338 * having to do this all over again.
340 * I have not done extensive checking on this number.
344 while (num_new_palette
> maximum_colors
)
346 for (i
= 0; i
< num_new_palette
- 1; i
++)
350 for (j
= i
+ 1; j
< num_new_palette
; j
++)
354 d
= PNG_COLOR_DIST(palette
[i
], palette
[j
]);
359 t
= (png_dsortp
)png_malloc_warn(png_ptr
,
360 (png_uint_32
)(png_sizeof(png_dsort
)));
364 t
->left
= (png_byte
)i
;
365 t
->right
= (png_byte
)j
;
374 for (i
= 0; i
<= max_d
; i
++)
380 for (p
= hash
[i
]; p
; p
= p
->next
)
382 if ((int)png_ptr
->index_to_palette
[p
->left
]
384 (int)png_ptr
->index_to_palette
[p
->right
]
389 if (num_new_palette
& 0x01)
401 palette
[png_ptr
->index_to_palette
[j
]]
402 = palette
[num_new_palette
];
407 for (k
= 0; k
< num_palette
; k
++)
409 if (png_ptr
->dither_index
[k
] ==
410 png_ptr
->index_to_palette
[j
])
411 png_ptr
->dither_index
[k
] =
412 png_ptr
->index_to_palette
[next_j
];
413 if ((int)png_ptr
->dither_index
[k
] ==
415 png_ptr
->dither_index
[k
] =
416 png_ptr
->index_to_palette
[j
];
420 png_ptr
->index_to_palette
[png_ptr
->palette_to_index
421 [num_new_palette
]] = png_ptr
->index_to_palette
[j
];
422 png_ptr
->palette_to_index
[png_ptr
->index_to_palette
[j
]]
423 = png_ptr
->palette_to_index
[num_new_palette
];
425 png_ptr
->index_to_palette
[j
] = (png_byte
)num_new_palette
;
426 png_ptr
->palette_to_index
[num_new_palette
] = (png_byte
)j
;
428 if (num_new_palette
<= maximum_colors
)
431 if (num_new_palette
<= maximum_colors
)
436 for (i
= 0; i
< 769; i
++)
440 png_dsortp p
= hash
[i
];
444 png_free(png_ptr
, p
);
452 png_free(png_ptr
, hash
);
453 png_free(png_ptr
, png_ptr
->palette_to_index
);
454 png_free(png_ptr
, png_ptr
->index_to_palette
);
455 png_ptr
->palette_to_index
= NULL
;
456 png_ptr
->index_to_palette
= NULL
;
458 num_palette
= maximum_colors
;
460 if (png_ptr
->palette
== NULL
)
462 png_ptr
->palette
= palette
;
464 png_ptr
->num_palette
= (png_uint_16
)num_palette
;
470 int total_bits
= PNG_DITHER_RED_BITS
+ PNG_DITHER_GREEN_BITS
+
471 PNG_DITHER_BLUE_BITS
;
472 int num_red
= (1 << PNG_DITHER_RED_BITS
);
473 int num_green
= (1 << PNG_DITHER_GREEN_BITS
);
474 int num_blue
= (1 << PNG_DITHER_BLUE_BITS
);
475 png_size_t num_entries
= ((png_size_t
)1 << total_bits
);
476 png_ptr
->palette_lookup
= (png_bytep
)png_malloc(png_ptr
,
477 (png_uint_32
)(num_entries
* png_sizeof(png_byte
)));
478 png_memset(png_ptr
->palette_lookup
, 0, num_entries
*
479 png_sizeof(png_byte
));
481 distance
= (png_bytep
)png_malloc(png_ptr
, (png_uint_32
)(num_entries
*
482 png_sizeof(png_byte
)));
484 png_memset(distance
, 0xff, num_entries
* png_sizeof(png_byte
));
486 for (i
= 0; i
< num_palette
; i
++)
489 int r
= (palette
[i
].red
>> (8 - PNG_DITHER_RED_BITS
));
490 int g
= (palette
[i
].green
>> (8 - PNG_DITHER_GREEN_BITS
));
491 int b
= (palette
[i
].blue
>> (8 - PNG_DITHER_BLUE_BITS
));
493 for (ir
= 0; ir
< num_red
; ir
++)
495 /* int dr = abs(ir - r); */
496 int dr
= ((ir
> r
) ? ir
- r
: r
- ir
);
497 int index_r
= (ir
<< (PNG_DITHER_BLUE_BITS
+ PNG_DITHER_GREEN_BITS
));
499 for (ig
= 0; ig
< num_green
; ig
++)
501 /* int dg = abs(ig - g); */
502 int dg
= ((ig
> g
) ? ig
- g
: g
- ig
);
504 int dm
= ((dr
> dg
) ? dr
: dg
);
505 int index_g
= index_r
| (ig
<< PNG_DITHER_BLUE_BITS
);
507 for (ib
= 0; ib
< num_blue
; ib
++)
509 int d_index
= index_g
| ib
;
510 /* int db = abs(ib - b); */
511 int db
= ((ib
> b
) ? ib
- b
: b
- ib
);
512 int dmax
= ((dm
> db
) ? dm
: db
);
513 int d
= dmax
+ dt
+ db
;
515 if (d
< (int)distance
[d_index
])
517 distance
[d_index
] = (png_byte
)d
;
518 png_ptr
->palette_lookup
[d_index
] = (png_byte
)i
;
525 png_free(png_ptr
, distance
);
530 #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
531 /* Transform the image from the file_gamma to the screen_gamma. We
532 * only do transformations on images where the file_gamma and screen_gamma
533 * are not close reciprocals, otherwise it slows things down slightly, and
534 * also needlessly introduces small errors.
536 * We will turn off gamma transformation later if no semitransparent entries
537 * are present in the tRNS array for palette images. We can't do it here
538 * because we don't necessarily have the tRNS chunk yet.
541 png_set_gamma(png_structp png_ptr
, double scrn_gamma
, double file_gamma
)
543 png_debug(1, "in png_set_gamma");
546 if ((fabs(scrn_gamma
* file_gamma
- 1.0) > PNG_GAMMA_THRESHOLD
) ||
547 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
) ||
548 (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
))
549 png_ptr
->transformations
|= PNG_GAMMA
;
550 png_ptr
->gamma
= (float)file_gamma
;
551 png_ptr
->screen_gamma
= (float)scrn_gamma
;
555 #if defined(PNG_READ_EXPAND_SUPPORTED)
556 /* Expand paletted images to RGB, expand grayscale images of
557 * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
561 png_set_expand(png_structp png_ptr
)
563 png_debug(1, "in png_set_expand");
566 png_ptr
->transformations
|= (PNG_EXPAND
| PNG_EXPAND_tRNS
);
567 png_ptr
->flags
&= ~PNG_FLAG_ROW_INIT
;
570 /* GRR 19990627: the following three functions currently are identical
571 * to png_set_expand(). However, it is entirely reasonable that someone
572 * might wish to expand an indexed image to RGB but *not* expand a single,
573 * fully transparent palette entry to a full alpha channel--perhaps instead
574 * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
575 * the transparent color with a particular RGB value, or drop tRNS entirely.
576 * IOW, a future version of the library may make the transformations flag
577 * a bit more fine-grained, with separate bits for each of these three
580 * More to the point, these functions make it obvious what libpng will be
581 * doing, whereas "expand" can (and does) mean any number of things.
583 * GRP 20060307: In libpng-1.4.0, png_set_gray_1_2_4_to_8() was modified
584 * to expand only the sample depth but not to expand the tRNS to alpha.
587 /* Expand paletted images to RGB. */
589 png_set_palette_to_rgb(png_structp png_ptr
)
591 png_debug(1, "in png_set_palette_to_rgb");
594 png_ptr
->transformations
|= (PNG_EXPAND
| PNG_EXPAND_tRNS
);
595 png_ptr
->flags
&= ~PNG_FLAG_ROW_INIT
;
598 #if !defined(PNG_1_0_X)
599 /* Expand grayscale images of less than 8-bit depth to 8 bits. */
601 png_set_expand_gray_1_2_4_to_8(png_structp png_ptr
)
603 png_debug(1, "in png_set_expand_gray_1_2_4_to_8");
606 png_ptr
->transformations
|= PNG_EXPAND
;
607 png_ptr
->flags
&= ~PNG_FLAG_ROW_INIT
;
611 #if defined(PNG_1_0_X) || defined(PNG_1_2_X)
612 /* Expand grayscale images of less than 8-bit depth to 8 bits. */
613 /* Deprecated as of libpng-1.2.9 */
615 png_set_gray_1_2_4_to_8(png_structp png_ptr
)
617 png_debug(1, "in png_set_gray_1_2_4_to_8");
620 png_ptr
->transformations
|= (PNG_EXPAND
| PNG_EXPAND_tRNS
);
625 /* Expand tRNS chunks to alpha channels. */
627 png_set_tRNS_to_alpha(png_structp png_ptr
)
629 png_debug(1, "in png_set_tRNS_to_alpha");
630 png_ptr
->transformations
|= (PNG_EXPAND
| PNG_EXPAND_tRNS
);
631 png_ptr
->flags
&= ~PNG_FLAG_ROW_INIT
;
633 #endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
635 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
637 png_set_gray_to_rgb(png_structp png_ptr
)
639 png_debug(1, "in png_set_gray_to_rgb");
640 png_ptr
->transformations
|= PNG_GRAY_TO_RGB
;
641 png_ptr
->flags
&= ~PNG_FLAG_ROW_INIT
;
645 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
646 #if defined(PNG_FLOATING_POINT_SUPPORTED)
647 /* Convert a RGB image to a grayscale of the same width. This allows us,
648 * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
652 png_set_rgb_to_gray(png_structp png_ptr
, int error_action
, double red
,
655 int red_fixed
= (int)((float)red
*100000.0 + 0.5);
656 int green_fixed
= (int)((float)green
*100000.0 + 0.5);
659 png_set_rgb_to_gray_fixed(png_ptr
, error_action
, red_fixed
, green_fixed
);
664 png_set_rgb_to_gray_fixed(png_structp png_ptr
, int error_action
,
665 png_fixed_point red
, png_fixed_point green
)
667 png_debug(1, "in png_set_rgb_to_gray");
672 case 1: png_ptr
->transformations
|= PNG_RGB_TO_GRAY
;
675 case 2: png_ptr
->transformations
|= PNG_RGB_TO_GRAY_WARN
;
678 case 3: png_ptr
->transformations
|= PNG_RGB_TO_GRAY_ERR
;
680 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
681 #if defined(PNG_READ_EXPAND_SUPPORTED)
682 png_ptr
->transformations
|= PNG_EXPAND
;
686 "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
687 png_ptr
->transformations
&= ~PNG_RGB_TO_GRAY
;
691 png_uint_16 red_int
, green_int
;
692 if (red
< 0 || green
< 0)
694 red_int
= 6968; /* .212671 * 32768 + .5 */
695 green_int
= 23434; /* .715160 * 32768 + .5 */
697 else if (red
+ green
< 100000L)
699 red_int
= (png_uint_16
)(((png_uint_32
)red
*32768L)/100000L);
700 green_int
= (png_uint_16
)(((png_uint_32
)green
*32768L)/100000L);
704 png_warning(png_ptr
, "ignoring out of range rgb_to_gray coefficients");
708 png_ptr
->rgb_to_gray_red_coeff
= red_int
;
709 png_ptr
->rgb_to_gray_green_coeff
= green_int
;
710 png_ptr
->rgb_to_gray_blue_coeff
=
711 (png_uint_16
)(32768 - red_int
- green_int
);
716 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
717 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
718 defined(PNG_LEGACY_SUPPORTED)
720 png_set_read_user_transform_fn(png_structp png_ptr
, png_user_transform_ptr
721 read_user_transform_fn
)
723 png_debug(1, "in png_set_read_user_transform_fn");
726 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
727 png_ptr
->transformations
|= PNG_USER_TRANSFORM
;
728 png_ptr
->read_user_transform_fn
= read_user_transform_fn
;
730 #ifdef PNG_LEGACY_SUPPORTED
731 if (read_user_transform_fn
)
733 "This version of libpng does not support user transforms");
738 /* Initialize everything needed for the read. This includes modifying
742 png_init_read_transformations(png_structp png_ptr
)
744 png_debug(1, "in png_init_read_transformations");
745 #if defined(PNG_USELESS_TESTS_SUPPORTED)
749 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
750 || defined(PNG_READ_GAMMA_SUPPORTED)
751 int color_type
= png_ptr
->color_type
;
754 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
756 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
757 /* Detect gray background and attempt to enable optimization
758 * for gray --> RGB case
760 * Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
761 * RGB_ALPHA (in which case need_expand is superfluous anyway), the
762 * background color might actually be gray yet not be flagged as such.
763 * This is not a problem for the current code, which uses
764 * PNG_BACKGROUND_IS_GRAY only to decide when to do the
765 * png_do_gray_to_rgb() transformation.
767 if ((png_ptr
->transformations
& PNG_BACKGROUND_EXPAND
) &&
768 !(color_type
& PNG_COLOR_MASK_COLOR
))
770 png_ptr
->mode
|= PNG_BACKGROUND_IS_GRAY
;
771 } else if ((png_ptr
->transformations
& PNG_BACKGROUND
) &&
772 !(png_ptr
->transformations
& PNG_BACKGROUND_EXPAND
) &&
773 (png_ptr
->transformations
& PNG_GRAY_TO_RGB
) &&
774 png_ptr
->background
.red
== png_ptr
->background
.green
&&
775 png_ptr
->background
.red
== png_ptr
->background
.blue
)
777 png_ptr
->mode
|= PNG_BACKGROUND_IS_GRAY
;
778 png_ptr
->background
.gray
= png_ptr
->background
.red
;
782 if ((png_ptr
->transformations
& PNG_BACKGROUND_EXPAND
) &&
783 (png_ptr
->transformations
& PNG_EXPAND
))
785 if (!(color_type
& PNG_COLOR_MASK_COLOR
)) /* i.e., GRAY or GRAY_ALPHA */
787 /* Expand background and tRNS chunks */
788 switch (png_ptr
->bit_depth
)
791 png_ptr
->background
.gray
*= (png_uint_16
)0xff;
792 png_ptr
->background
.red
= png_ptr
->background
.green
793 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
794 if (!(png_ptr
->transformations
& PNG_EXPAND_tRNS
))
796 png_ptr
->trans_values
.gray
*= (png_uint_16
)0xff;
797 png_ptr
->trans_values
.red
= png_ptr
->trans_values
.green
798 = png_ptr
->trans_values
.blue
= png_ptr
->trans_values
.gray
;
803 png_ptr
->background
.gray
*= (png_uint_16
)0x55;
804 png_ptr
->background
.red
= png_ptr
->background
.green
805 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
806 if (!(png_ptr
->transformations
& PNG_EXPAND_tRNS
))
808 png_ptr
->trans_values
.gray
*= (png_uint_16
)0x55;
809 png_ptr
->trans_values
.red
= png_ptr
->trans_values
.green
810 = png_ptr
->trans_values
.blue
= png_ptr
->trans_values
.gray
;
815 png_ptr
->background
.gray
*= (png_uint_16
)0x11;
816 png_ptr
->background
.red
= png_ptr
->background
.green
817 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
818 if (!(png_ptr
->transformations
& PNG_EXPAND_tRNS
))
820 png_ptr
->trans_values
.gray
*= (png_uint_16
)0x11;
821 png_ptr
->trans_values
.red
= png_ptr
->trans_values
.green
822 = png_ptr
->trans_values
.blue
= png_ptr
->trans_values
.gray
;
829 png_ptr
->background
.red
= png_ptr
->background
.green
830 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
834 else if (color_type
== PNG_COLOR_TYPE_PALETTE
)
836 png_ptr
->background
.red
=
837 png_ptr
->palette
[png_ptr
->background
.index
].red
;
838 png_ptr
->background
.green
=
839 png_ptr
->palette
[png_ptr
->background
.index
].green
;
840 png_ptr
->background
.blue
=
841 png_ptr
->palette
[png_ptr
->background
.index
].blue
;
843 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
844 if (png_ptr
->transformations
& PNG_INVERT_ALPHA
)
846 #if defined(PNG_READ_EXPAND_SUPPORTED)
847 if (!(png_ptr
->transformations
& PNG_EXPAND_tRNS
))
850 /* Invert the alpha channel (in tRNS) unless the pixels are
851 * going to be expanded, in which case leave it for later
854 istop
=(int)png_ptr
->num_trans
;
855 for (i
=0; i
<istop
; i
++)
856 png_ptr
->trans
[i
] = (png_byte
)(255 - png_ptr
->trans
[i
]);
865 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
866 png_ptr
->background_1
= png_ptr
->background
;
868 #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
870 if ((color_type
== PNG_COLOR_TYPE_PALETTE
&& png_ptr
->num_trans
!= 0)
871 && (fabs(png_ptr
->screen_gamma
* png_ptr
->gamma
- 1.0)
872 < PNG_GAMMA_THRESHOLD
))
876 for (i
=0; i
<png_ptr
->num_trans
; i
++)
878 if (png_ptr
->trans
[i
] != 0 && png_ptr
->trans
[i
] != 0xff)
879 k
=1; /* Partial transparency is present */
882 png_ptr
->transformations
&= ~PNG_GAMMA
;
885 if ((png_ptr
->transformations
& (PNG_GAMMA
| PNG_RGB_TO_GRAY
)) &&
886 png_ptr
->gamma
!= 0.0)
888 png_build_gamma_table(png_ptr
);
889 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
890 if (png_ptr
->transformations
& PNG_BACKGROUND
)
892 if (color_type
== PNG_COLOR_TYPE_PALETTE
)
894 /* Could skip if no transparency */
895 png_color back
, back_1
;
896 png_colorp palette
= png_ptr
->palette
;
897 int num_palette
= png_ptr
->num_palette
;
899 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_FILE
)
901 back
.red
= png_ptr
->gamma_table
[png_ptr
->background
.red
];
902 back
.green
= png_ptr
->gamma_table
[png_ptr
->background
.green
];
903 back
.blue
= png_ptr
->gamma_table
[png_ptr
->background
.blue
];
905 back_1
.red
= png_ptr
->gamma_to_1
[png_ptr
->background
.red
];
906 back_1
.green
= png_ptr
->gamma_to_1
[png_ptr
->background
.green
];
907 back_1
.blue
= png_ptr
->gamma_to_1
[png_ptr
->background
.blue
];
913 switch (png_ptr
->background_gamma_type
)
915 case PNG_BACKGROUND_GAMMA_SCREEN
:
916 g
= (png_ptr
->screen_gamma
);
920 case PNG_BACKGROUND_GAMMA_FILE
:
921 g
= 1.0 / (png_ptr
->gamma
);
922 gs
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
925 case PNG_BACKGROUND_GAMMA_UNIQUE
:
926 g
= 1.0 / (png_ptr
->background_gamma
);
927 gs
= 1.0 / (png_ptr
->background_gamma
*
928 png_ptr
->screen_gamma
);
931 g
= 1.0; /* back_1 */
935 if ( fabs(gs
- 1.0) < PNG_GAMMA_THRESHOLD
)
937 back
.red
= (png_byte
)png_ptr
->background
.red
;
938 back
.green
= (png_byte
)png_ptr
->background
.green
;
939 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
943 back
.red
= (png_byte
)(pow(
944 (double)png_ptr
->background
.red
/255, gs
) * 255.0 + .5);
945 back
.green
= (png_byte
)(pow(
946 (double)png_ptr
->background
.green
/255, gs
) * 255.0 + .5);
947 back
.blue
= (png_byte
)(pow(
948 (double)png_ptr
->background
.blue
/255, gs
) * 255.0 + .5);
951 back_1
.red
= (png_byte
)(pow(
952 (double)png_ptr
->background
.red
/255, g
) * 255.0 + .5);
953 back_1
.green
= (png_byte
)(pow(
954 (double)png_ptr
->background
.green
/255, g
) * 255.0 + .5);
955 back_1
.blue
= (png_byte
)(pow(
956 (double)png_ptr
->background
.blue
/255, g
) * 255.0 + .5);
958 for (i
= 0; i
< num_palette
; i
++)
960 if (i
< (int)png_ptr
->num_trans
&& png_ptr
->trans
[i
] != 0xff)
962 if (png_ptr
->trans
[i
] == 0)
966 else /* if (png_ptr->trans[i] != 0xff) */
970 v
= png_ptr
->gamma_to_1
[palette
[i
].red
];
971 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.red
);
972 palette
[i
].red
= png_ptr
->gamma_from_1
[w
];
974 v
= png_ptr
->gamma_to_1
[palette
[i
].green
];
975 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.green
);
976 palette
[i
].green
= png_ptr
->gamma_from_1
[w
];
978 v
= png_ptr
->gamma_to_1
[palette
[i
].blue
];
979 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.blue
);
980 palette
[i
].blue
= png_ptr
->gamma_from_1
[w
];
985 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
986 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
987 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
990 /* Prevent the transformations being done again, and make sure
991 * that the now spurious alpha channel is stripped - the code
992 * has just reduced background composition and gamma correction
993 * to a simple alpha channel strip.
995 png_ptr
->transformations
&= ~PNG_BACKGROUND
;
996 png_ptr
->transformations
&= ~PNG_GAMMA
;
997 png_ptr
->transformations
|= PNG_STRIP_ALPHA
;
999 /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
1001 /* color_type != PNG_COLOR_TYPE_PALETTE */
1003 double m
= (double)(((png_uint_32
)1 << png_ptr
->bit_depth
) - 1);
1007 switch (png_ptr
->background_gamma_type
)
1009 case PNG_BACKGROUND_GAMMA_SCREEN
:
1010 g
= (png_ptr
->screen_gamma
);
1014 case PNG_BACKGROUND_GAMMA_FILE
:
1015 g
= 1.0 / (png_ptr
->gamma
);
1016 gs
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
1019 case PNG_BACKGROUND_GAMMA_UNIQUE
:
1020 g
= 1.0 / (png_ptr
->background_gamma
);
1021 gs
= 1.0 / (png_ptr
->background_gamma
*
1022 png_ptr
->screen_gamma
);
1026 png_ptr
->background_1
.gray
= (png_uint_16
)(pow(
1027 (double)png_ptr
->background
.gray
/ m
, g
) * m
+ .5);
1028 png_ptr
->background
.gray
= (png_uint_16
)(pow(
1029 (double)png_ptr
->background
.gray
/ m
, gs
) * m
+ .5);
1031 if ((png_ptr
->background
.red
!= png_ptr
->background
.green
) ||
1032 (png_ptr
->background
.red
!= png_ptr
->background
.blue
) ||
1033 (png_ptr
->background
.red
!= png_ptr
->background
.gray
))
1035 /* RGB or RGBA with color background */
1036 png_ptr
->background_1
.red
= (png_uint_16
)(pow(
1037 (double)png_ptr
->background
.red
/ m
, g
) * m
+ .5);
1038 png_ptr
->background_1
.green
= (png_uint_16
)(pow(
1039 (double)png_ptr
->background
.green
/ m
, g
) * m
+ .5);
1040 png_ptr
->background_1
.blue
= (png_uint_16
)(pow(
1041 (double)png_ptr
->background
.blue
/ m
, g
) * m
+ .5);
1042 png_ptr
->background
.red
= (png_uint_16
)(pow(
1043 (double)png_ptr
->background
.red
/ m
, gs
) * m
+ .5);
1044 png_ptr
->background
.green
= (png_uint_16
)(pow(
1045 (double)png_ptr
->background
.green
/ m
, gs
) * m
+ .5);
1046 png_ptr
->background
.blue
= (png_uint_16
)(pow(
1047 (double)png_ptr
->background
.blue
/ m
, gs
) * m
+ .5);
1051 /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
1052 png_ptr
->background_1
.red
= png_ptr
->background_1
.green
1053 = png_ptr
->background_1
.blue
= png_ptr
->background_1
.gray
;
1054 png_ptr
->background
.red
= png_ptr
->background
.green
1055 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
1060 /* Transformation does not include PNG_BACKGROUND */
1061 #endif /* PNG_READ_BACKGROUND_SUPPORTED */
1062 if (color_type
== PNG_COLOR_TYPE_PALETTE
)
1064 png_colorp palette
= png_ptr
->palette
;
1065 int num_palette
= png_ptr
->num_palette
;
1068 for (i
= 0; i
< num_palette
; i
++)
1070 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
1071 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
1072 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
1075 /* Done the gamma correction. */
1076 png_ptr
->transformations
&= ~PNG_GAMMA
;
1079 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1082 #endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */
1083 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1084 /* No GAMMA transformation */
1085 if ((png_ptr
->transformations
& PNG_BACKGROUND
) &&
1086 (color_type
== PNG_COLOR_TYPE_PALETTE
))
1089 int istop
= (int)png_ptr
->num_trans
;
1091 png_colorp palette
= png_ptr
->palette
;
1093 back
.red
= (png_byte
)png_ptr
->background
.red
;
1094 back
.green
= (png_byte
)png_ptr
->background
.green
;
1095 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
1097 for (i
= 0; i
< istop
; i
++)
1099 if (png_ptr
->trans
[i
] == 0)
1103 else if (png_ptr
->trans
[i
] != 0xff)
1105 /* The png_composite() macro is defined in png.h */
1106 png_composite(palette
[i
].red
, palette
[i
].red
,
1107 png_ptr
->trans
[i
], back
.red
);
1108 png_composite(palette
[i
].green
, palette
[i
].green
,
1109 png_ptr
->trans
[i
], back
.green
);
1110 png_composite(palette
[i
].blue
, palette
[i
].blue
,
1111 png_ptr
->trans
[i
], back
.blue
);
1115 /* Handled alpha, still need to strip the channel. */
1116 png_ptr
->transformations
&= ~PNG_BACKGROUND
;
1117 png_ptr
->transformations
|= PNG_STRIP_ALPHA
;
1119 #endif /* PNG_READ_BACKGROUND_SUPPORTED */
1121 #if defined(PNG_READ_SHIFT_SUPPORTED)
1122 if ((png_ptr
->transformations
& PNG_SHIFT
) &&
1123 (color_type
== PNG_COLOR_TYPE_PALETTE
))
1126 png_uint_16 istop
= png_ptr
->num_palette
;
1127 int sr
= 8 - png_ptr
->sig_bit
.red
;
1128 int sg
= 8 - png_ptr
->sig_bit
.green
;
1129 int sb
= 8 - png_ptr
->sig_bit
.blue
;
1131 if (sr
< 0 || sr
> 8)
1133 if (sg
< 0 || sg
> 8)
1135 if (sb
< 0 || sb
> 8)
1137 for (i
= 0; i
< istop
; i
++)
1139 png_ptr
->palette
[i
].red
>>= sr
;
1140 png_ptr
->palette
[i
].green
>>= sg
;
1141 png_ptr
->palette
[i
].blue
>>= sb
;
1144 #endif /* PNG_READ_SHIFT_SUPPORTED */
1146 #if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
1147 && !defined(PNG_READ_BACKGROUND_SUPPORTED)
1153 /* Modify the info structure to reflect the transformations. The
1154 * info should be updated so a PNG file could be written with it,
1155 * assuming the transformations result in valid PNG data.
1158 png_read_transform_info(png_structp png_ptr
, png_infop info_ptr
)
1160 png_debug(1, "in png_read_transform_info");
1161 #if defined(PNG_READ_EXPAND_SUPPORTED)
1162 if (png_ptr
->transformations
& PNG_EXPAND
)
1164 if (info_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1166 if (png_ptr
->num_trans
&&
1167 (png_ptr
->transformations
& PNG_EXPAND_tRNS
))
1168 info_ptr
->color_type
= PNG_COLOR_TYPE_RGB_ALPHA
;
1170 info_ptr
->color_type
= PNG_COLOR_TYPE_RGB
;
1171 info_ptr
->bit_depth
= 8;
1172 info_ptr
->num_trans
= 0;
1176 if (png_ptr
->num_trans
)
1178 if (png_ptr
->transformations
& PNG_EXPAND_tRNS
)
1179 info_ptr
->color_type
|= PNG_COLOR_MASK_ALPHA
;
1180 #if 0 /* Removed from libpng-1.2.27 */
1182 info_ptr
->color_type
|= PNG_COLOR_MASK_COLOR
;
1185 if (info_ptr
->bit_depth
< 8)
1186 info_ptr
->bit_depth
= 8;
1187 info_ptr
->num_trans
= 0;
1192 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1193 if (png_ptr
->transformations
& PNG_BACKGROUND
)
1195 info_ptr
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
1196 info_ptr
->num_trans
= 0;
1197 info_ptr
->background
= png_ptr
->background
;
1201 #if defined(PNG_READ_GAMMA_SUPPORTED)
1202 if (png_ptr
->transformations
& PNG_GAMMA
)
1204 #ifdef PNG_FLOATING_POINT_SUPPORTED
1205 info_ptr
->gamma
= png_ptr
->gamma
;
1207 #ifdef PNG_FIXED_POINT_SUPPORTED
1208 info_ptr
->int_gamma
= png_ptr
->int_gamma
;
1213 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1214 if ((png_ptr
->transformations
& PNG_16_TO_8
) && (info_ptr
->bit_depth
== 16))
1215 info_ptr
->bit_depth
= 8;
1218 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1219 if (png_ptr
->transformations
& PNG_GRAY_TO_RGB
)
1220 info_ptr
->color_type
|= PNG_COLOR_MASK_COLOR
;
1223 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1224 if (png_ptr
->transformations
& PNG_RGB_TO_GRAY
)
1225 info_ptr
->color_type
&= ~PNG_COLOR_MASK_COLOR
;
1228 #if defined(PNG_READ_DITHER_SUPPORTED)
1229 if (png_ptr
->transformations
& PNG_DITHER
)
1231 if (((info_ptr
->color_type
== PNG_COLOR_TYPE_RGB
) ||
1232 (info_ptr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)) &&
1233 png_ptr
->palette_lookup
&& info_ptr
->bit_depth
== 8)
1235 info_ptr
->color_type
= PNG_COLOR_TYPE_PALETTE
;
1240 #if defined(PNG_READ_PACK_SUPPORTED)
1241 if ((png_ptr
->transformations
& PNG_PACK
) && (info_ptr
->bit_depth
< 8))
1242 info_ptr
->bit_depth
= 8;
1245 if (info_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1246 info_ptr
->channels
= 1;
1247 else if (info_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
1248 info_ptr
->channels
= 3;
1250 info_ptr
->channels
= 1;
1252 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1253 if (png_ptr
->flags
& PNG_FLAG_STRIP_ALPHA
)
1254 info_ptr
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
1257 if (info_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
)
1258 info_ptr
->channels
++;
1260 #if defined(PNG_READ_FILLER_SUPPORTED)
1261 /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
1262 if ((png_ptr
->transformations
& PNG_FILLER
) &&
1263 ((info_ptr
->color_type
== PNG_COLOR_TYPE_RGB
) ||
1264 (info_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)))
1266 info_ptr
->channels
++;
1267 /* If adding a true alpha channel not just filler */
1268 #if !defined(PNG_1_0_X)
1269 if (png_ptr
->transformations
& PNG_ADD_ALPHA
)
1270 info_ptr
->color_type
|= PNG_COLOR_MASK_ALPHA
;
1275 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
1276 defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1277 if (png_ptr
->transformations
& PNG_USER_TRANSFORM
)
1279 if (info_ptr
->bit_depth
< png_ptr
->user_transform_depth
)
1280 info_ptr
->bit_depth
= png_ptr
->user_transform_depth
;
1281 if (info_ptr
->channels
< png_ptr
->user_transform_channels
)
1282 info_ptr
->channels
= png_ptr
->user_transform_channels
;
1286 info_ptr
->pixel_depth
= (png_byte
)(info_ptr
->channels
*
1287 info_ptr
->bit_depth
);
1289 info_ptr
->rowbytes
= PNG_ROWBYTES(info_ptr
->pixel_depth
, info_ptr
->width
);
1291 #if !defined(PNG_READ_EXPAND_SUPPORTED)
1297 /* Transform the row. The order of transformations is significant,
1298 * and is very touchy. If you add a transformation, take care to
1299 * decide how it fits in with the other transformations here.
1302 png_do_read_transformations(png_structp png_ptr
)
1304 png_debug(1, "in png_do_read_transformations");
1305 if (png_ptr
->row_buf
== NULL
)
1307 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
1310 png_snprintf2(msg
, 50,
1311 "NULL row buffer for row %ld, pass %d", (long)png_ptr
->row_number
,
1313 png_error(png_ptr
, msg
);
1315 png_error(png_ptr
, "NULL row buffer");
1318 #ifdef PNG_WARN_UNINITIALIZED_ROW
1319 if (!(png_ptr
->flags
& PNG_FLAG_ROW_INIT
))
1320 /* Application has failed to call either png_read_start_image()
1321 * or png_read_update_info() after setting transforms that expand
1322 * pixels. This check added to libpng-1.2.19
1324 #if (PNG_WARN_UNINITIALIZED_ROW==1)
1325 png_error(png_ptr
, "Uninitialized row");
1327 png_warning(png_ptr
, "Uninitialized row");
1331 #if defined(PNG_READ_EXPAND_SUPPORTED)
1332 if (png_ptr
->transformations
& PNG_EXPAND
)
1334 if (png_ptr
->row_info
.color_type
== PNG_COLOR_TYPE_PALETTE
)
1336 png_do_expand_palette(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1337 png_ptr
->palette
, png_ptr
->trans
, png_ptr
->num_trans
);
1341 if (png_ptr
->num_trans
&&
1342 (png_ptr
->transformations
& PNG_EXPAND_tRNS
))
1343 png_do_expand(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1344 &(png_ptr
->trans_values
));
1346 png_do_expand(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1352 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1353 if (png_ptr
->flags
& PNG_FLAG_STRIP_ALPHA
)
1354 png_do_strip_filler(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1355 PNG_FLAG_FILLER_AFTER
| (png_ptr
->flags
& PNG_FLAG_STRIP_ALPHA
));
1358 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1359 if (png_ptr
->transformations
& PNG_RGB_TO_GRAY
)
1362 png_do_rgb_to_gray(png_ptr
, &(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1365 png_ptr
->rgb_to_gray_status
=1;
1366 if ((png_ptr
->transformations
& PNG_RGB_TO_GRAY
) ==
1367 PNG_RGB_TO_GRAY_WARN
)
1368 png_warning(png_ptr
, "png_do_rgb_to_gray found nongray pixel");
1369 if ((png_ptr
->transformations
& PNG_RGB_TO_GRAY
) ==
1370 PNG_RGB_TO_GRAY_ERR
)
1371 png_error(png_ptr
, "png_do_rgb_to_gray found nongray pixel");
1376 /* From Andreas Dilger e-mail to png-implement, 26 March 1998:
1378 * In most cases, the "simple transparency" should be done prior to doing
1379 * gray-to-RGB, or you will have to test 3x as many bytes to check if a
1380 * pixel is transparent. You would also need to make sure that the
1381 * transparency information is upgraded to RGB.
1383 * To summarize, the current flow is:
1384 * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
1385 * with background "in place" if transparent,
1386 * convert to RGB if necessary
1387 * - Gray + alpha -> composite with gray background and remove alpha bytes,
1388 * convert to RGB if necessary
1390 * To support RGB backgrounds for gray images we need:
1391 * - Gray + simple transparency -> convert to RGB + simple transparency,
1392 * compare 3 or 6 bytes and composite with
1393 * background "in place" if transparent
1394 * (3x compare/pixel compared to doing
1395 * composite with gray bkgrnd)
1396 * - Gray + alpha -> convert to RGB + alpha, composite with background and
1397 * remove alpha bytes (3x float
1398 * operations/pixel compared with composite
1399 * on gray background)
1401 * Greg's change will do this. The reason it wasn't done before is for
1402 * performance, as this increases the per-pixel operations. If we would check
1403 * in advance if the background was gray or RGB, and position the gray-to-RGB
1404 * transform appropriately, then it would save a lot of work/time.
1407 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1408 /* If gray -> RGB, do so now only if background is non-gray; else do later
1409 * for performance reasons
1411 if ((png_ptr
->transformations
& PNG_GRAY_TO_RGB
) &&
1412 !(png_ptr
->mode
& PNG_BACKGROUND_IS_GRAY
))
1413 png_do_gray_to_rgb(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1416 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1417 if ((png_ptr
->transformations
& PNG_BACKGROUND
) &&
1418 ((png_ptr
->num_trans
!= 0 ) ||
1419 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
)))
1420 png_do_background(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1421 &(png_ptr
->trans_values
), &(png_ptr
->background
)
1422 #if defined(PNG_READ_GAMMA_SUPPORTED)
1423 , &(png_ptr
->background_1
),
1424 png_ptr
->gamma_table
, png_ptr
->gamma_from_1
,
1425 png_ptr
->gamma_to_1
, png_ptr
->gamma_16_table
,
1426 png_ptr
->gamma_16_from_1
, png_ptr
->gamma_16_to_1
,
1427 png_ptr
->gamma_shift
1432 #if defined(PNG_READ_GAMMA_SUPPORTED)
1433 if ((png_ptr
->transformations
& PNG_GAMMA
) &&
1434 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1435 !((png_ptr
->transformations
& PNG_BACKGROUND
) &&
1436 ((png_ptr
->num_trans
!= 0) ||
1437 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
))) &&
1439 (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
))
1440 png_do_gamma(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1441 png_ptr
->gamma_table
, png_ptr
->gamma_16_table
,
1442 png_ptr
->gamma_shift
);
1445 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1446 if (png_ptr
->transformations
& PNG_16_TO_8
)
1447 png_do_chop(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1450 #if defined(PNG_READ_DITHER_SUPPORTED)
1451 if (png_ptr
->transformations
& PNG_DITHER
)
1453 png_do_dither((png_row_infop
)&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1454 png_ptr
->palette_lookup
, png_ptr
->dither_index
);
1455 if (png_ptr
->row_info
.rowbytes
== (png_uint_32
)0)
1456 png_error(png_ptr
, "png_do_dither returned rowbytes=0");
1460 #if defined(PNG_READ_INVERT_SUPPORTED)
1461 if (png_ptr
->transformations
& PNG_INVERT_MONO
)
1462 png_do_invert(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1465 #if defined(PNG_READ_SHIFT_SUPPORTED)
1466 if (png_ptr
->transformations
& PNG_SHIFT
)
1467 png_do_unshift(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1471 #if defined(PNG_READ_PACK_SUPPORTED)
1472 if (png_ptr
->transformations
& PNG_PACK
)
1473 png_do_unpack(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1476 #if defined(PNG_READ_BGR_SUPPORTED)
1477 if (png_ptr
->transformations
& PNG_BGR
)
1478 png_do_bgr(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1481 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1482 if (png_ptr
->transformations
& PNG_PACKSWAP
)
1483 png_do_packswap(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1486 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1487 /* If gray -> RGB, do so now only if we did not do so above */
1488 if ((png_ptr
->transformations
& PNG_GRAY_TO_RGB
) &&
1489 (png_ptr
->mode
& PNG_BACKGROUND_IS_GRAY
))
1490 png_do_gray_to_rgb(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1493 #if defined(PNG_READ_FILLER_SUPPORTED)
1494 if (png_ptr
->transformations
& PNG_FILLER
)
1495 png_do_read_filler(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1496 (png_uint_32
)png_ptr
->filler
, png_ptr
->flags
);
1499 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1500 if (png_ptr
->transformations
& PNG_INVERT_ALPHA
)
1501 png_do_read_invert_alpha(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1504 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1505 if (png_ptr
->transformations
& PNG_SWAP_ALPHA
)
1506 png_do_read_swap_alpha(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1509 #if defined(PNG_READ_SWAP_SUPPORTED)
1510 if (png_ptr
->transformations
& PNG_SWAP_BYTES
)
1511 png_do_swap(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1514 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1515 if (png_ptr
->transformations
& PNG_USER_TRANSFORM
)
1517 if (png_ptr
->read_user_transform_fn
!= NULL
)
1518 (*(png_ptr
->read_user_transform_fn
)) /* User read transform function */
1519 (png_ptr
, /* png_ptr */
1520 &(png_ptr
->row_info
), /* row_info: */
1521 /* png_uint_32 width; width of row */
1522 /* png_uint_32 rowbytes; number of bytes in row */
1523 /* png_byte color_type; color type of pixels */
1524 /* png_byte bit_depth; bit depth of samples */
1525 /* png_byte channels; number of channels (1-4) */
1526 /* png_byte pixel_depth; bits per pixel (depth*channels) */
1527 png_ptr
->row_buf
+ 1); /* start of pixel data for row */
1528 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
1529 if (png_ptr
->user_transform_depth
)
1530 png_ptr
->row_info
.bit_depth
= png_ptr
->user_transform_depth
;
1531 if (png_ptr
->user_transform_channels
)
1532 png_ptr
->row_info
.channels
= png_ptr
->user_transform_channels
;
1534 png_ptr
->row_info
.pixel_depth
= (png_byte
)(png_ptr
->row_info
.bit_depth
*
1535 png_ptr
->row_info
.channels
);
1536 png_ptr
->row_info
.rowbytes
= PNG_ROWBYTES(png_ptr
->row_info
.pixel_depth
,
1537 png_ptr
->row_info
.width
);
1543 #if defined(PNG_READ_PACK_SUPPORTED)
1544 /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
1545 * without changing the actual values. Thus, if you had a row with
1546 * a bit depth of 1, you would end up with bytes that only contained
1547 * the numbers 0 or 1. If you would rather they contain 0 and 255, use
1548 * png_do_shift() after this.
1551 png_do_unpack(png_row_infop row_info
, png_bytep row
)
1553 png_debug(1, "in png_do_unpack");
1554 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1555 if (row
!= NULL
&& row_info
!= NULL
&& row_info
->bit_depth
< 8)
1557 if (row_info
->bit_depth
< 8)
1561 png_uint_32 row_width
=row_info
->width
;
1563 switch (row_info
->bit_depth
)
1567 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
1568 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1569 png_uint_32 shift
= 7 - (int)((row_width
+ 7) & 0x07);
1570 for (i
= 0; i
< row_width
; i
++)
1572 *dp
= (png_byte
)((*sp
>> shift
) & 0x01);
1589 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
1590 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1591 png_uint_32 shift
= (int)((3 - ((row_width
+ 3) & 0x03)) << 1);
1592 for (i
= 0; i
< row_width
; i
++)
1594 *dp
= (png_byte
)((*sp
>> shift
) & 0x03);
1610 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
1611 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1612 png_uint_32 shift
= (int)((1 - ((row_width
+ 1) & 0x01)) << 2);
1613 for (i
= 0; i
< row_width
; i
++)
1615 *dp
= (png_byte
)((*sp
>> shift
) & 0x0f);
1629 row_info
->bit_depth
= 8;
1630 row_info
->pixel_depth
= (png_byte
)(8 * row_info
->channels
);
1631 row_info
->rowbytes
= row_width
* row_info
->channels
;
1636 #if defined(PNG_READ_SHIFT_SUPPORTED)
1637 /* Reverse the effects of png_do_shift. This routine merely shifts the
1638 * pixels back to their significant bits values. Thus, if you have
1639 * a row of bit depth 8, but only 5 are significant, this will shift
1640 * the values back to 0 through 31.
1643 png_do_unshift(png_row_infop row_info
, png_bytep row
, png_color_8p sig_bits
)
1645 png_debug(1, "in png_do_unshift");
1647 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1648 row
!= NULL
&& row_info
!= NULL
&& sig_bits
!= NULL
&&
1650 row_info
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
1655 png_uint_16 value
= 0;
1656 png_uint_32 row_width
= row_info
->width
;
1658 if (row_info
->color_type
& PNG_COLOR_MASK_COLOR
)
1660 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->red
;
1661 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->green
;
1662 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->blue
;
1666 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->gray
;
1668 if (row_info
->color_type
& PNG_COLOR_MASK_ALPHA
)
1670 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->alpha
;
1673 for (c
= 0; c
< channels
; c
++)
1684 switch (row_info
->bit_depth
)
1690 png_uint_32 istop
= row_info
->rowbytes
;
1692 for (bp
= row
, i
= 0; i
< istop
; i
++)
1704 png_uint_32 istop
= row_info
->rowbytes
;
1705 png_byte mask
= (png_byte
)((((int)0xf0 >> shift
[0]) & (int)0xf0) |
1706 (png_byte
)((int)0xf >> shift
[0]));
1708 for (i
= 0; i
< istop
; i
++)
1720 png_uint_32 istop
= row_width
* channels
;
1722 for (i
= 0; i
< istop
; i
++)
1724 *bp
++ >>= shift
[i
%channels
];
1733 png_uint_32 istop
= channels
* row_width
;
1735 for (i
= 0; i
< istop
; i
++)
1737 value
= (png_uint_16
)((*bp
<< 8) + *(bp
+ 1));
1738 value
>>= shift
[i
%channels
];
1739 *bp
++ = (png_byte
)(value
>> 8);
1740 *bp
++ = (png_byte
)(value
& 0xff);
1749 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1750 /* Chop rows of bit depth 16 down to 8 */
1752 png_do_chop(png_row_infop row_info
, png_bytep row
)
1754 png_debug(1, "in png_do_chop");
1755 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1756 if (row
!= NULL
&& row_info
!= NULL
&& row_info
->bit_depth
== 16)
1758 if (row_info
->bit_depth
== 16)
1764 png_uint_32 istop
= row_info
->width
* row_info
->channels
;
1766 for (i
= 0; i
<istop
; i
++, sp
+= 2, dp
++)
1768 #if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
1769 /* This does a more accurate scaling of the 16-bit color
1770 * value, rather than a simple low-byte truncation.
1772 * What the ideal calculation should be:
1773 * *dp = (((((png_uint_32)(*sp) << 8) |
1774 * (png_uint_32)(*(sp + 1))) * 255 + 127)
1775 * / (png_uint_32)65535L;
1777 * GRR: no, I think this is what it really should be:
1778 * *dp = (((((png_uint_32)(*sp) << 8) |
1779 * (png_uint_32)(*(sp + 1))) + 128L)
1780 * / (png_uint_32)257L;
1782 * GRR: here's the exact calculation with shifts:
1783 * temp = (((png_uint_32)(*sp) << 8) |
1784 * (png_uint_32)(*(sp + 1))) + 128L;
1785 * *dp = (temp - (temp >> 8)) >> 8;
1787 * Approximate calculation with shift/add instead of multiply/divide:
1788 * *dp = ((((png_uint_32)(*sp) << 8) |
1789 * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
1791 * What we actually do to avoid extra shifting and conversion:
1794 *dp
= *sp
+ ((((int)(*(sp
+ 1)) - *sp
) > 128) ? 1 : 0);
1796 /* Simply discard the low order byte */
1800 row_info
->bit_depth
= 8;
1801 row_info
->pixel_depth
= (png_byte
)(8 * row_info
->channels
);
1802 row_info
->rowbytes
= row_info
->width
* row_info
->channels
;
1807 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1809 png_do_read_swap_alpha(png_row_infop row_info
, png_bytep row
)
1811 png_debug(1, "in png_do_read_swap_alpha");
1812 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1813 if (row
!= NULL
&& row_info
!= NULL
)
1816 png_uint_32 row_width
= row_info
->width
;
1817 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
1819 /* This converts from RGBA to ARGB */
1820 if (row_info
->bit_depth
== 8)
1822 png_bytep sp
= row
+ row_info
->rowbytes
;
1827 for (i
= 0; i
< row_width
; i
++)
1836 /* This converts from RRGGBBAA to AARRGGBB */
1839 png_bytep sp
= row
+ row_info
->rowbytes
;
1844 for (i
= 0; i
< row_width
; i
++)
1859 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
1861 /* This converts from GA to AG */
1862 if (row_info
->bit_depth
== 8)
1864 png_bytep sp
= row
+ row_info
->rowbytes
;
1869 for (i
= 0; i
< row_width
; i
++)
1876 /* This converts from GGAA to AAGG */
1879 png_bytep sp
= row
+ row_info
->rowbytes
;
1884 for (i
= 0; i
< row_width
; i
++)
1899 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1901 png_do_read_invert_alpha(png_row_infop row_info
, png_bytep row
)
1903 png_debug(1, "in png_do_read_invert_alpha");
1904 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1905 if (row
!= NULL
&& row_info
!= NULL
)
1908 png_uint_32 row_width
= row_info
->width
;
1909 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
1911 /* This inverts the alpha channel in RGBA */
1912 if (row_info
->bit_depth
== 8)
1914 png_bytep sp
= row
+ row_info
->rowbytes
;
1918 for (i
= 0; i
< row_width
; i
++)
1920 *(--dp
) = (png_byte
)(255 - *(--sp
));
1922 /* This does nothing:
1926 We can replace it with:
1932 /* This inverts the alpha channel in RRGGBBAA */
1935 png_bytep sp
= row
+ row_info
->rowbytes
;
1939 for (i
= 0; i
< row_width
; i
++)
1941 *(--dp
) = (png_byte
)(255 - *(--sp
));
1942 *(--dp
) = (png_byte
)(255 - *(--sp
));
1944 /* This does nothing:
1951 We can replace it with:
1958 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
1960 /* This inverts the alpha channel in GA */
1961 if (row_info
->bit_depth
== 8)
1963 png_bytep sp
= row
+ row_info
->rowbytes
;
1967 for (i
= 0; i
< row_width
; i
++)
1969 *(--dp
) = (png_byte
)(255 - *(--sp
));
1973 /* This inverts the alpha channel in GGAA */
1976 png_bytep sp
= row
+ row_info
->rowbytes
;
1980 for (i
= 0; i
< row_width
; i
++)
1982 *(--dp
) = (png_byte
)(255 - *(--sp
));
1983 *(--dp
) = (png_byte
)(255 - *(--sp
));
1997 #if defined(PNG_READ_FILLER_SUPPORTED)
1998 /* Add filler channel if we have RGB color */
2000 png_do_read_filler(png_row_infop row_info
, png_bytep row
,
2001 png_uint_32 filler
, png_uint_32 flags
)
2004 png_uint_32 row_width
= row_info
->width
;
2006 png_byte hi_filler
= (png_byte
)((filler
>>8) & 0xff);
2007 png_byte lo_filler
= (png_byte
)(filler
& 0xff);
2009 png_debug(1, "in png_do_read_filler");
2011 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2012 row
!= NULL
&& row_info
!= NULL
&&
2014 row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
2016 if (row_info
->bit_depth
== 8)
2018 /* This changes the data from G to GX */
2019 if (flags
& PNG_FLAG_FILLER_AFTER
)
2021 png_bytep sp
= row
+ (png_size_t
)row_width
;
2022 png_bytep dp
= sp
+ (png_size_t
)row_width
;
2023 for (i
= 1; i
< row_width
; i
++)
2025 *(--dp
) = lo_filler
;
2028 *(--dp
) = lo_filler
;
2029 row_info
->channels
= 2;
2030 row_info
->pixel_depth
= 16;
2031 row_info
->rowbytes
= row_width
* 2;
2033 /* This changes the data from G to XG */
2036 png_bytep sp
= row
+ (png_size_t
)row_width
;
2037 png_bytep dp
= sp
+ (png_size_t
)row_width
;
2038 for (i
= 0; i
< row_width
; i
++)
2041 *(--dp
) = lo_filler
;
2043 row_info
->channels
= 2;
2044 row_info
->pixel_depth
= 16;
2045 row_info
->rowbytes
= row_width
* 2;
2048 else if (row_info
->bit_depth
== 16)
2050 /* This changes the data from GG to GGXX */
2051 if (flags
& PNG_FLAG_FILLER_AFTER
)
2053 png_bytep sp
= row
+ (png_size_t
)row_width
* 2;
2054 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2055 for (i
= 1; i
< row_width
; i
++)
2057 *(--dp
) = hi_filler
;
2058 *(--dp
) = lo_filler
;
2062 *(--dp
) = hi_filler
;
2063 *(--dp
) = lo_filler
;
2064 row_info
->channels
= 2;
2065 row_info
->pixel_depth
= 32;
2066 row_info
->rowbytes
= row_width
* 4;
2068 /* This changes the data from GG to XXGG */
2071 png_bytep sp
= row
+ (png_size_t
)row_width
* 2;
2072 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2073 for (i
= 0; i
< row_width
; i
++)
2077 *(--dp
) = hi_filler
;
2078 *(--dp
) = lo_filler
;
2080 row_info
->channels
= 2;
2081 row_info
->pixel_depth
= 32;
2082 row_info
->rowbytes
= row_width
* 4;
2085 } /* COLOR_TYPE == GRAY */
2086 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
2088 if (row_info
->bit_depth
== 8)
2090 /* This changes the data from RGB to RGBX */
2091 if (flags
& PNG_FLAG_FILLER_AFTER
)
2093 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
2094 png_bytep dp
= sp
+ (png_size_t
)row_width
;
2095 for (i
= 1; i
< row_width
; i
++)
2097 *(--dp
) = lo_filler
;
2102 *(--dp
) = lo_filler
;
2103 row_info
->channels
= 4;
2104 row_info
->pixel_depth
= 32;
2105 row_info
->rowbytes
= row_width
* 4;
2107 /* This changes the data from RGB to XRGB */
2110 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
2111 png_bytep dp
= sp
+ (png_size_t
)row_width
;
2112 for (i
= 0; i
< row_width
; i
++)
2117 *(--dp
) = lo_filler
;
2119 row_info
->channels
= 4;
2120 row_info
->pixel_depth
= 32;
2121 row_info
->rowbytes
= row_width
* 4;
2124 else if (row_info
->bit_depth
== 16)
2126 /* This changes the data from RRGGBB to RRGGBBXX */
2127 if (flags
& PNG_FLAG_FILLER_AFTER
)
2129 png_bytep sp
= row
+ (png_size_t
)row_width
* 6;
2130 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2131 for (i
= 1; i
< row_width
; i
++)
2133 *(--dp
) = hi_filler
;
2134 *(--dp
) = lo_filler
;
2142 *(--dp
) = hi_filler
;
2143 *(--dp
) = lo_filler
;
2144 row_info
->channels
= 4;
2145 row_info
->pixel_depth
= 64;
2146 row_info
->rowbytes
= row_width
* 8;
2148 /* This changes the data from RRGGBB to XXRRGGBB */
2151 png_bytep sp
= row
+ (png_size_t
)row_width
* 6;
2152 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2153 for (i
= 0; i
< row_width
; i
++)
2161 *(--dp
) = hi_filler
;
2162 *(--dp
) = lo_filler
;
2164 row_info
->channels
= 4;
2165 row_info
->pixel_depth
= 64;
2166 row_info
->rowbytes
= row_width
* 8;
2169 } /* COLOR_TYPE == RGB */
2173 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
2174 /* Expand grayscale files to RGB, with or without alpha */
2176 png_do_gray_to_rgb(png_row_infop row_info
, png_bytep row
)
2179 png_uint_32 row_width
= row_info
->width
;
2181 png_debug(1, "in png_do_gray_to_rgb");
2182 if (row_info
->bit_depth
>= 8 &&
2183 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2184 row
!= NULL
&& row_info
!= NULL
&&
2186 !(row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
2188 if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
2190 if (row_info
->bit_depth
== 8)
2192 png_bytep sp
= row
+ (png_size_t
)row_width
- 1;
2193 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2194 for (i
= 0; i
< row_width
; i
++)
2203 png_bytep sp
= row
+ (png_size_t
)row_width
* 2 - 1;
2204 png_bytep dp
= sp
+ (png_size_t
)row_width
* 4;
2205 for (i
= 0; i
< row_width
; i
++)
2208 *(dp
--) = *(sp
- 1);
2210 *(dp
--) = *(sp
- 1);
2216 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
2218 if (row_info
->bit_depth
== 8)
2220 png_bytep sp
= row
+ (png_size_t
)row_width
* 2 - 1;
2221 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2222 for (i
= 0; i
< row_width
; i
++)
2232 png_bytep sp
= row
+ (png_size_t
)row_width
* 4 - 1;
2233 png_bytep dp
= sp
+ (png_size_t
)row_width
* 4;
2234 for (i
= 0; i
< row_width
; i
++)
2239 *(dp
--) = *(sp
- 1);
2241 *(dp
--) = *(sp
- 1);
2247 row_info
->channels
+= (png_byte
)2;
2248 row_info
->color_type
|= PNG_COLOR_MASK_COLOR
;
2249 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
2250 row_info
->bit_depth
);
2251 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
, row_width
);
2256 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
2257 /* Reduce RGB files to grayscale, with or without alpha
2258 * using the equation given in Poynton's ColorFAQ at
2259 * <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008)
2261 * <http://www.poynton.com/notes/colour_and_gamma/>
2262 * Charles Poynton poynton at poynton.com
2264 * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
2266 * We approximate this with
2268 * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B
2270 * which can be expressed with integers as
2272 * Y = (6969 * R + 23434 * G + 2365 * B)/32768
2274 * The calculation is to be done in a linear colorspace.
2276 * Other integer coefficents can be used via png_set_rgb_to_gray().
2279 png_do_rgb_to_gray(png_structp png_ptr
, png_row_infop row_info
, png_bytep row
)
2284 png_uint_32 row_width
= row_info
->width
;
2287 png_debug(1, "in png_do_rgb_to_gray");
2289 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2290 row
!= NULL
&& row_info
!= NULL
&&
2292 (row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
2294 png_uint_32 rc
= png_ptr
->rgb_to_gray_red_coeff
;
2295 png_uint_32 gc
= png_ptr
->rgb_to_gray_green_coeff
;
2296 png_uint_32 bc
= png_ptr
->rgb_to_gray_blue_coeff
;
2298 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
2300 if (row_info
->bit_depth
== 8)
2302 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2303 if (png_ptr
->gamma_from_1
!= NULL
&& png_ptr
->gamma_to_1
!= NULL
)
2308 for (i
= 0; i
< row_width
; i
++)
2310 png_byte red
= png_ptr
->gamma_to_1
[*(sp
++)];
2311 png_byte green
= png_ptr
->gamma_to_1
[*(sp
++)];
2312 png_byte blue
= png_ptr
->gamma_to_1
[*(sp
++)];
2313 if (red
!= green
|| red
!= blue
)
2316 *(dp
++) = png_ptr
->gamma_from_1
[
2317 (rc
*red
+ gc
*green
+ bc
*blue
)>>15];
2320 *(dp
++) = *(sp
- 1);
2328 for (i
= 0; i
< row_width
; i
++)
2330 png_byte red
= *(sp
++);
2331 png_byte green
= *(sp
++);
2332 png_byte blue
= *(sp
++);
2333 if (red
!= green
|| red
!= blue
)
2336 *(dp
++) = (png_byte
)((rc
*red
+ gc
*green
+ bc
*blue
)>>15);
2339 *(dp
++) = *(sp
- 1);
2344 else /* RGB bit_depth == 16 */
2346 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2347 if (png_ptr
->gamma_16_to_1
!= NULL
&&
2348 png_ptr
->gamma_16_from_1
!= NULL
)
2352 for (i
= 0; i
< row_width
; i
++)
2354 png_uint_16 red
, green
, blue
, w
;
2356 red
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2357 green
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2358 blue
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2360 if (red
== green
&& red
== blue
)
2364 png_uint_16 red_1
= png_ptr
->gamma_16_to_1
[(red
&0xff) >>
2365 png_ptr
->gamma_shift
][red
>>8];
2366 png_uint_16 green_1
= png_ptr
->gamma_16_to_1
[(green
&0xff) >>
2367 png_ptr
->gamma_shift
][green
>>8];
2368 png_uint_16 blue_1
= png_ptr
->gamma_16_to_1
[(blue
&0xff) >>
2369 png_ptr
->gamma_shift
][blue
>>8];
2370 png_uint_16 gray16
= (png_uint_16
)((rc
*red_1
+ gc
*green_1
2372 w
= png_ptr
->gamma_16_from_1
[(gray16
&0xff) >>
2373 png_ptr
->gamma_shift
][gray16
>> 8];
2377 *(dp
++) = (png_byte
)((w
>>8) & 0xff);
2378 *(dp
++) = (png_byte
)(w
& 0xff);
2386 for (i
= 0; i
< row_width
; i
++)
2388 png_uint_16 red
, green
, blue
, gray16
;
2390 red
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2391 green
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2392 blue
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2394 if (red
!= green
|| red
!= blue
)
2396 gray16
= (png_uint_16
)((rc
*red
+ gc
*green
+ bc
*blue
)>>15);
2397 *(dp
++) = (png_byte
)((gray16
>>8) & 0xff);
2398 *(dp
++) = (png_byte
)(gray16
& 0xff);
2403 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
2405 if (row_info
->bit_depth
== 8)
2407 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2408 if (png_ptr
->gamma_from_1
!= NULL
&& png_ptr
->gamma_to_1
!= NULL
)
2412 for (i
= 0; i
< row_width
; i
++)
2414 png_byte red
= png_ptr
->gamma_to_1
[*(sp
++)];
2415 png_byte green
= png_ptr
->gamma_to_1
[*(sp
++)];
2416 png_byte blue
= png_ptr
->gamma_to_1
[*(sp
++)];
2417 if (red
!= green
|| red
!= blue
)
2419 *(dp
++) = png_ptr
->gamma_from_1
2420 [(rc
*red
+ gc
*green
+ bc
*blue
)>>15];
2421 *(dp
++) = *(sp
++); /* alpha */
2429 for (i
= 0; i
< row_width
; i
++)
2431 png_byte red
= *(sp
++);
2432 png_byte green
= *(sp
++);
2433 png_byte blue
= *(sp
++);
2434 if (red
!= green
|| red
!= blue
)
2436 *(dp
++) = (png_byte
)((rc
*red
+ gc
*green
+ bc
*blue
)>>15);
2437 *(dp
++) = *(sp
++); /* alpha */
2441 else /* RGBA bit_depth == 16 */
2443 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2444 if (png_ptr
->gamma_16_to_1
!= NULL
&&
2445 png_ptr
->gamma_16_from_1
!= NULL
)
2449 for (i
= 0; i
< row_width
; i
++)
2451 png_uint_16 red
, green
, blue
, w
;
2453 red
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2454 green
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2455 blue
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2457 if (red
== green
&& red
== blue
)
2461 png_uint_16 red_1
= png_ptr
->gamma_16_to_1
[(red
&0xff) >>
2462 png_ptr
->gamma_shift
][red
>>8];
2463 png_uint_16 green_1
= png_ptr
->gamma_16_to_1
[(green
&0xff) >>
2464 png_ptr
->gamma_shift
][green
>>8];
2465 png_uint_16 blue_1
= png_ptr
->gamma_16_to_1
[(blue
&0xff) >>
2466 png_ptr
->gamma_shift
][blue
>>8];
2467 png_uint_16 gray16
= (png_uint_16
)((rc
* red_1
2468 + gc
* green_1
+ bc
* blue_1
)>>15);
2469 w
= png_ptr
->gamma_16_from_1
[(gray16
&0xff) >>
2470 png_ptr
->gamma_shift
][gray16
>> 8];
2474 *(dp
++) = (png_byte
)((w
>>8) & 0xff);
2475 *(dp
++) = (png_byte
)(w
& 0xff);
2476 *(dp
++) = *(sp
++); /* alpha */
2485 for (i
= 0; i
< row_width
; i
++)
2487 png_uint_16 red
, green
, blue
, gray16
;
2488 red
= (png_uint_16
)((*(sp
)<<8) | *(sp
+1)); sp
+=2;
2489 green
= (png_uint_16
)((*(sp
)<<8) | *(sp
+1)); sp
+=2;
2490 blue
= (png_uint_16
)((*(sp
)<<8) | *(sp
+1)); sp
+=2;
2491 if (red
!= green
|| red
!= blue
)
2493 gray16
= (png_uint_16
)((rc
*red
+ gc
*green
+ bc
*blue
)>>15);
2494 *(dp
++) = (png_byte
)((gray16
>>8) & 0xff);
2495 *(dp
++) = (png_byte
)(gray16
& 0xff);
2496 *(dp
++) = *(sp
++); /* alpha */
2502 row_info
->channels
-= (png_byte
)2;
2503 row_info
->color_type
&= ~PNG_COLOR_MASK_COLOR
;
2504 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
2505 row_info
->bit_depth
);
2506 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
, row_width
);
2512 /* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
2513 * large of png_color. This lets grayscale images be treated as
2514 * paletted. Most useful for gamma correction and simplification
2518 png_build_grayscale_palette(int bit_depth
, png_colorp palette
)
2525 png_debug(1, "in png_do_build_grayscale_palette");
2526 if (palette
== NULL
)
2557 for (i
= 0, v
= 0; i
< num_palette
; i
++, v
+= color_inc
)
2559 palette
[i
].red
= (png_byte
)v
;
2560 palette
[i
].green
= (png_byte
)v
;
2561 palette
[i
].blue
= (png_byte
)v
;
2565 /* This function is currently unused. Do we really need it? */
2566 #if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
2568 png_correct_palette(png_structp png_ptr
, png_colorp palette
,
2571 png_debug(1, "in png_correct_palette");
2572 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
2573 defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
2574 if (png_ptr
->transformations
& (PNG_GAMMA
| PNG_BACKGROUND
))
2576 png_color back
, back_1
;
2578 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_FILE
)
2580 back
.red
= png_ptr
->gamma_table
[png_ptr
->background
.red
];
2581 back
.green
= png_ptr
->gamma_table
[png_ptr
->background
.green
];
2582 back
.blue
= png_ptr
->gamma_table
[png_ptr
->background
.blue
];
2584 back_1
.red
= png_ptr
->gamma_to_1
[png_ptr
->background
.red
];
2585 back_1
.green
= png_ptr
->gamma_to_1
[png_ptr
->background
.green
];
2586 back_1
.blue
= png_ptr
->gamma_to_1
[png_ptr
->background
.blue
];
2592 g
= 1.0 / (png_ptr
->background_gamma
* png_ptr
->screen_gamma
);
2594 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_SCREEN
||
2595 fabs(g
- 1.0) < PNG_GAMMA_THRESHOLD
)
2597 back
.red
= png_ptr
->background
.red
;
2598 back
.green
= png_ptr
->background
.green
;
2599 back
.blue
= png_ptr
->background
.blue
;
2604 (png_byte
)(pow((double)png_ptr
->background
.red
/255, g
) *
2607 (png_byte
)(pow((double)png_ptr
->background
.green
/255, g
) *
2610 (png_byte
)(pow((double)png_ptr
->background
.blue
/255, g
) *
2614 g
= 1.0 / png_ptr
->background_gamma
;
2617 (png_byte
)(pow((double)png_ptr
->background
.red
/255, g
) *
2620 (png_byte
)(pow((double)png_ptr
->background
.green
/255, g
) *
2623 (png_byte
)(pow((double)png_ptr
->background
.blue
/255, g
) *
2627 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
2631 for (i
= 0; i
< (png_uint_32
)num_palette
; i
++)
2633 if (i
< png_ptr
->num_trans
&& png_ptr
->trans
[i
] == 0)
2637 else if (i
< png_ptr
->num_trans
&& png_ptr
->trans
[i
] != 0xff)
2641 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].red
];
2642 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.red
);
2643 palette
[i
].red
= png_ptr
->gamma_from_1
[w
];
2645 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].green
];
2646 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.green
);
2647 palette
[i
].green
= png_ptr
->gamma_from_1
[w
];
2649 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].blue
];
2650 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.blue
);
2651 palette
[i
].blue
= png_ptr
->gamma_from_1
[w
];
2655 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2656 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2657 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2665 for (i
= 0; i
< num_palette
; i
++)
2667 if (palette
[i
].red
== (png_byte
)png_ptr
->trans_values
.gray
)
2673 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2674 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2675 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2682 #if defined(PNG_READ_GAMMA_SUPPORTED)
2683 if (png_ptr
->transformations
& PNG_GAMMA
)
2687 for (i
= 0; i
< num_palette
; i
++)
2689 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2690 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2691 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2694 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2698 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2699 if (png_ptr
->transformations
& PNG_BACKGROUND
)
2701 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
2705 back
.red
= (png_byte
)png_ptr
->background
.red
;
2706 back
.green
= (png_byte
)png_ptr
->background
.green
;
2707 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
2709 for (i
= 0; i
< (int)png_ptr
->num_trans
; i
++)
2711 if (png_ptr
->trans
[i
] == 0)
2713 palette
[i
].red
= back
.red
;
2714 palette
[i
].green
= back
.green
;
2715 palette
[i
].blue
= back
.blue
;
2717 else if (png_ptr
->trans
[i
] != 0xff)
2719 png_composite(palette
[i
].red
, png_ptr
->palette
[i
].red
,
2720 png_ptr
->trans
[i
], back
.red
);
2721 png_composite(palette
[i
].green
, png_ptr
->palette
[i
].green
,
2722 png_ptr
->trans
[i
], back
.green
);
2723 png_composite(palette
[i
].blue
, png_ptr
->palette
[i
].blue
,
2724 png_ptr
->trans
[i
], back
.blue
);
2728 else /* Assume grayscale palette (what else could it be?) */
2732 for (i
= 0; i
< num_palette
; i
++)
2734 if (i
== (png_byte
)png_ptr
->trans_values
.gray
)
2736 palette
[i
].red
= (png_byte
)png_ptr
->background
.red
;
2737 palette
[i
].green
= (png_byte
)png_ptr
->background
.green
;
2738 palette
[i
].blue
= (png_byte
)png_ptr
->background
.blue
;
2747 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2748 /* Replace any alpha or transparency with the supplied background color.
2749 * "background" is already in the screen gamma, while "background_1" is
2750 * at a gamma of 1.0. Paletted files have already been taken care of.
2753 png_do_background(png_row_infop row_info
, png_bytep row
,
2754 png_color_16p trans_values
, png_color_16p background
2755 #if defined(PNG_READ_GAMMA_SUPPORTED)
2756 , png_color_16p background_1
,
2757 png_bytep gamma_table
, png_bytep gamma_from_1
, png_bytep gamma_to_1
,
2758 png_uint_16pp gamma_16
, png_uint_16pp gamma_16_from_1
,
2759 png_uint_16pp gamma_16_to_1
, int gamma_shift
2765 png_uint_32 row_width
=row_info
->width
;
2768 png_debug(1, "in png_do_background");
2769 if (background
!= NULL
&&
2770 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2771 row
!= NULL
&& row_info
!= NULL
&&
2773 (!(row_info
->color_type
& PNG_COLOR_MASK_ALPHA
) ||
2774 (row_info
->color_type
!= PNG_COLOR_TYPE_PALETTE
&& trans_values
)))
2776 switch (row_info
->color_type
)
2778 case PNG_COLOR_TYPE_GRAY
:
2780 switch (row_info
->bit_depth
)
2786 for (i
= 0; i
< row_width
; i
++)
2788 if ((png_uint_16
)((*sp
>> shift
) & 0x01)
2789 == trans_values
->gray
)
2791 *sp
&= (png_byte
)((0x7f7f >> (7 - shift
)) & 0xff);
2792 *sp
|= (png_byte
)(background
->gray
<< shift
);
2807 #if defined(PNG_READ_GAMMA_SUPPORTED)
2808 if (gamma_table
!= NULL
)
2812 for (i
= 0; i
< row_width
; i
++)
2814 if ((png_uint_16
)((*sp
>> shift
) & 0x03)
2815 == trans_values
->gray
)
2817 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2818 *sp
|= (png_byte
)(background
->gray
<< shift
);
2822 png_byte p
= (png_byte
)((*sp
>> shift
) & 0x03);
2823 png_byte g
= (png_byte
)((gamma_table
[p
| (p
<< 2) |
2824 (p
<< 4) | (p
<< 6)] >> 6) & 0x03);
2825 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2826 *sp
|= (png_byte
)(g
<< shift
);
2842 for (i
= 0; i
< row_width
; i
++)
2844 if ((png_uint_16
)((*sp
>> shift
) & 0x03)
2845 == trans_values
->gray
)
2847 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2848 *sp
|= (png_byte
)(background
->gray
<< shift
);
2864 #if defined(PNG_READ_GAMMA_SUPPORTED)
2865 if (gamma_table
!= NULL
)
2869 for (i
= 0; i
< row_width
; i
++)
2871 if ((png_uint_16
)((*sp
>> shift
) & 0x0f)
2872 == trans_values
->gray
)
2874 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2875 *sp
|= (png_byte
)(background
->gray
<< shift
);
2879 png_byte p
= (png_byte
)((*sp
>> shift
) & 0x0f);
2880 png_byte g
= (png_byte
)((gamma_table
[p
|
2881 (p
<< 4)] >> 4) & 0x0f);
2882 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2883 *sp
|= (png_byte
)(g
<< shift
);
2899 for (i
= 0; i
< row_width
; i
++)
2901 if ((png_uint_16
)((*sp
>> shift
) & 0x0f)
2902 == trans_values
->gray
)
2904 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2905 *sp
|= (png_byte
)(background
->gray
<< shift
);
2921 #if defined(PNG_READ_GAMMA_SUPPORTED)
2922 if (gamma_table
!= NULL
)
2925 for (i
= 0; i
< row_width
; i
++, sp
++)
2927 if (*sp
== trans_values
->gray
)
2929 *sp
= (png_byte
)background
->gray
;
2933 *sp
= gamma_table
[*sp
];
2941 for (i
= 0; i
< row_width
; i
++, sp
++)
2943 if (*sp
== trans_values
->gray
)
2945 *sp
= (png_byte
)background
->gray
;
2954 #if defined(PNG_READ_GAMMA_SUPPORTED)
2955 if (gamma_16
!= NULL
)
2958 for (i
= 0; i
< row_width
; i
++, sp
+= 2)
2962 v
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
2963 if (v
== trans_values
->gray
)
2965 /* Background is already in screen gamma */
2966 *sp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2967 *(sp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2971 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2972 *sp
= (png_byte
)((v
>> 8) & 0xff);
2973 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2981 for (i
= 0; i
< row_width
; i
++, sp
+= 2)
2985 v
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
2986 if (v
== trans_values
->gray
)
2988 *sp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2989 *(sp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2999 case PNG_COLOR_TYPE_RGB
:
3001 if (row_info
->bit_depth
== 8)
3003 #if defined(PNG_READ_GAMMA_SUPPORTED)
3004 if (gamma_table
!= NULL
)
3007 for (i
= 0; i
< row_width
; i
++, sp
+= 3)
3009 if (*sp
== trans_values
->red
&&
3010 *(sp
+ 1) == trans_values
->green
&&
3011 *(sp
+ 2) == trans_values
->blue
)
3013 *sp
= (png_byte
)background
->red
;
3014 *(sp
+ 1) = (png_byte
)background
->green
;
3015 *(sp
+ 2) = (png_byte
)background
->blue
;
3019 *sp
= gamma_table
[*sp
];
3020 *(sp
+ 1) = gamma_table
[*(sp
+ 1)];
3021 *(sp
+ 2) = gamma_table
[*(sp
+ 2)];
3029 for (i
= 0; i
< row_width
; i
++, sp
+= 3)
3031 if (*sp
== trans_values
->red
&&
3032 *(sp
+ 1) == trans_values
->green
&&
3033 *(sp
+ 2) == trans_values
->blue
)
3035 *sp
= (png_byte
)background
->red
;
3036 *(sp
+ 1) = (png_byte
)background
->green
;
3037 *(sp
+ 2) = (png_byte
)background
->blue
;
3042 else /* if (row_info->bit_depth == 16) */
3044 #if defined(PNG_READ_GAMMA_SUPPORTED)
3045 if (gamma_16
!= NULL
)
3048 for (i
= 0; i
< row_width
; i
++, sp
+= 6)
3050 png_uint_16 r
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
3051 png_uint_16 g
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
3052 png_uint_16 b
= (png_uint_16
)(((*(sp
+4)) << 8) + *(sp
+5));
3053 if (r
== trans_values
->red
&& g
== trans_values
->green
&&
3054 b
== trans_values
->blue
)
3056 /* Background is already in screen gamma */
3057 *sp
= (png_byte
)((background
->red
>> 8) & 0xff);
3058 *(sp
+ 1) = (png_byte
)(background
->red
& 0xff);
3059 *(sp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
3060 *(sp
+ 3) = (png_byte
)(background
->green
& 0xff);
3061 *(sp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
3062 *(sp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3066 png_uint_16 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
3067 *sp
= (png_byte
)((v
>> 8) & 0xff);
3068 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3069 v
= gamma_16
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
3070 *(sp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
3071 *(sp
+ 3) = (png_byte
)(v
& 0xff);
3072 v
= gamma_16
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
3073 *(sp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
3074 *(sp
+ 5) = (png_byte
)(v
& 0xff);
3082 for (i
= 0; i
< row_width
; i
++, sp
+= 6)
3084 png_uint_16 r
= (png_uint_16
)(((*sp
) << 8) + *(sp
+1));
3085 png_uint_16 g
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
3086 png_uint_16 b
= (png_uint_16
)(((*(sp
+4)) << 8) + *(sp
+5));
3088 if (r
== trans_values
->red
&& g
== trans_values
->green
&&
3089 b
== trans_values
->blue
)
3091 *sp
= (png_byte
)((background
->red
>> 8) & 0xff);
3092 *(sp
+ 1) = (png_byte
)(background
->red
& 0xff);
3093 *(sp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
3094 *(sp
+ 3) = (png_byte
)(background
->green
& 0xff);
3095 *(sp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
3096 *(sp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3104 case PNG_COLOR_TYPE_GRAY_ALPHA
:
3106 if (row_info
->bit_depth
== 8)
3108 #if defined(PNG_READ_GAMMA_SUPPORTED)
3109 if (gamma_to_1
!= NULL
&& gamma_from_1
!= NULL
&&
3110 gamma_table
!= NULL
)
3114 for (i
= 0; i
< row_width
; i
++, sp
+= 2, dp
++)
3116 png_uint_16 a
= *(sp
+ 1);
3120 *dp
= gamma_table
[*sp
];
3124 /* Background is already in screen gamma */
3125 *dp
= (png_byte
)background
->gray
;
3131 v
= gamma_to_1
[*sp
];
3132 png_composite(w
, v
, a
, background_1
->gray
);
3133 *dp
= gamma_from_1
[w
];
3142 for (i
= 0; i
< row_width
; i
++, sp
+= 2, dp
++)
3144 png_byte a
= *(sp
+ 1);
3150 #if defined(PNG_READ_GAMMA_SUPPORTED)
3153 *dp
= (png_byte
)background
->gray
;
3157 png_composite(*dp
, *sp
, a
, background_1
->gray
);
3160 *dp
= (png_byte
)background
->gray
;
3165 else /* if (png_ptr->bit_depth == 16) */
3167 #if defined(PNG_READ_GAMMA_SUPPORTED)
3168 if (gamma_16
!= NULL
&& gamma_16_from_1
!= NULL
&&
3169 gamma_16_to_1
!= NULL
)
3173 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 2)
3175 png_uint_16 a
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
3177 if (a
== (png_uint_16
)0xffff)
3181 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
3182 *dp
= (png_byte
)((v
>> 8) & 0xff);
3183 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3185 #if defined(PNG_READ_GAMMA_SUPPORTED)
3191 /* Background is already in screen gamma */
3192 *dp
= (png_byte
)((background
->gray
>> 8) & 0xff);
3193 *(dp
+ 1) = (png_byte
)(background
->gray
& 0xff);
3195 #if defined(PNG_READ_GAMMA_SUPPORTED)
3198 png_uint_16 g
, v
, w
;
3200 g
= gamma_16_to_1
[*(sp
+ 1) >> gamma_shift
][*sp
];
3201 png_composite_16(v
, g
, a
, background_1
->gray
);
3202 w
= gamma_16_from_1
[(v
&0xff) >> gamma_shift
][v
>> 8];
3203 *dp
= (png_byte
)((w
>> 8) & 0xff);
3204 *(dp
+ 1) = (png_byte
)(w
& 0xff);
3214 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 2)
3216 png_uint_16 a
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
3217 if (a
== (png_uint_16
)0xffff)
3219 png_memcpy(dp
, sp
, 2);
3221 #if defined(PNG_READ_GAMMA_SUPPORTED)
3227 *dp
= (png_byte
)((background
->gray
>> 8) & 0xff);
3228 *(dp
+ 1) = (png_byte
)(background
->gray
& 0xff);
3230 #if defined(PNG_READ_GAMMA_SUPPORTED)
3235 g
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
3236 png_composite_16(v
, g
, a
, background_1
->gray
);
3237 *dp
= (png_byte
)((v
>> 8) & 0xff);
3238 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3247 case PNG_COLOR_TYPE_RGB_ALPHA
:
3249 if (row_info
->bit_depth
== 8)
3251 #if defined(PNG_READ_GAMMA_SUPPORTED)
3252 if (gamma_to_1
!= NULL
&& gamma_from_1
!= NULL
&&
3253 gamma_table
!= NULL
)
3257 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 3)
3259 png_byte a
= *(sp
+ 3);
3263 *dp
= gamma_table
[*sp
];
3264 *(dp
+ 1) = gamma_table
[*(sp
+ 1)];
3265 *(dp
+ 2) = gamma_table
[*(sp
+ 2)];
3269 /* Background is already in screen gamma */
3270 *dp
= (png_byte
)background
->red
;
3271 *(dp
+ 1) = (png_byte
)background
->green
;
3272 *(dp
+ 2) = (png_byte
)background
->blue
;
3278 v
= gamma_to_1
[*sp
];
3279 png_composite(w
, v
, a
, background_1
->red
);
3280 *dp
= gamma_from_1
[w
];
3281 v
= gamma_to_1
[*(sp
+ 1)];
3282 png_composite(w
, v
, a
, background_1
->green
);
3283 *(dp
+ 1) = gamma_from_1
[w
];
3284 v
= gamma_to_1
[*(sp
+ 2)];
3285 png_composite(w
, v
, a
, background_1
->blue
);
3286 *(dp
+ 2) = gamma_from_1
[w
];
3295 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 3)
3297 png_byte a
= *(sp
+ 3);
3302 *(dp
+ 1) = *(sp
+ 1);
3303 *(dp
+ 2) = *(sp
+ 2);
3307 *dp
= (png_byte
)background
->red
;
3308 *(dp
+ 1) = (png_byte
)background
->green
;
3309 *(dp
+ 2) = (png_byte
)background
->blue
;
3313 png_composite(*dp
, *sp
, a
, background
->red
);
3314 png_composite(*(dp
+ 1), *(sp
+ 1), a
,
3316 png_composite(*(dp
+ 2), *(sp
+ 2), a
,
3322 else /* if (row_info->bit_depth == 16) */
3324 #if defined(PNG_READ_GAMMA_SUPPORTED)
3325 if (gamma_16
!= NULL
&& gamma_16_from_1
!= NULL
&&
3326 gamma_16_to_1
!= NULL
)
3330 for (i
= 0; i
< row_width
; i
++, sp
+= 8, dp
+= 6)
3332 png_uint_16 a
= (png_uint_16
)(((png_uint_16
)(*(sp
+ 6))
3333 << 8) + (png_uint_16
)(*(sp
+ 7)));
3334 if (a
== (png_uint_16
)0xffff)
3338 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
3339 *dp
= (png_byte
)((v
>> 8) & 0xff);
3340 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3341 v
= gamma_16
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
3342 *(dp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
3343 *(dp
+ 3) = (png_byte
)(v
& 0xff);
3344 v
= gamma_16
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
3345 *(dp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
3346 *(dp
+ 5) = (png_byte
)(v
& 0xff);
3350 /* Background is already in screen gamma */
3351 *dp
= (png_byte
)((background
->red
>> 8) & 0xff);
3352 *(dp
+ 1) = (png_byte
)(background
->red
& 0xff);
3353 *(dp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
3354 *(dp
+ 3) = (png_byte
)(background
->green
& 0xff);
3355 *(dp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
3356 *(dp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3360 png_uint_16 v
, w
, x
;
3362 v
= gamma_16_to_1
[*(sp
+ 1) >> gamma_shift
][*sp
];
3363 png_composite_16(w
, v
, a
, background_1
->red
);
3364 x
= gamma_16_from_1
[((w
&0xff) >> gamma_shift
)][w
>> 8];
3365 *dp
= (png_byte
)((x
>> 8) & 0xff);
3366 *(dp
+ 1) = (png_byte
)(x
& 0xff);
3367 v
= gamma_16_to_1
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
3368 png_composite_16(w
, v
, a
, background_1
->green
);
3369 x
= gamma_16_from_1
[((w
&0xff) >> gamma_shift
)][w
>> 8];
3370 *(dp
+ 2) = (png_byte
)((x
>> 8) & 0xff);
3371 *(dp
+ 3) = (png_byte
)(x
& 0xff);
3372 v
= gamma_16_to_1
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
3373 png_composite_16(w
, v
, a
, background_1
->blue
);
3374 x
= gamma_16_from_1
[(w
& 0xff) >> gamma_shift
][w
>> 8];
3375 *(dp
+ 4) = (png_byte
)((x
>> 8) & 0xff);
3376 *(dp
+ 5) = (png_byte
)(x
& 0xff);
3385 for (i
= 0; i
< row_width
; i
++, sp
+= 8, dp
+= 6)
3387 png_uint_16 a
= (png_uint_16
)(((png_uint_16
)(*(sp
+ 6))
3388 << 8) + (png_uint_16
)(*(sp
+ 7)));
3389 if (a
== (png_uint_16
)0xffff)
3391 png_memcpy(dp
, sp
, 6);
3395 *dp
= (png_byte
)((background
->red
>> 8) & 0xff);
3396 *(dp
+ 1) = (png_byte
)(background
->red
& 0xff);
3397 *(dp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
3398 *(dp
+ 3) = (png_byte
)(background
->green
& 0xff);
3399 *(dp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
3400 *(dp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3406 png_uint_16 r
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
3407 png_uint_16 g
= (png_uint_16
)(((*(sp
+ 2)) << 8)
3409 png_uint_16 b
= (png_uint_16
)(((*(sp
+ 4)) << 8)
3412 png_composite_16(v
, r
, a
, background
->red
);
3413 *dp
= (png_byte
)((v
>> 8) & 0xff);
3414 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3415 png_composite_16(v
, g
, a
, background
->green
);
3416 *(dp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
3417 *(dp
+ 3) = (png_byte
)(v
& 0xff);
3418 png_composite_16(v
, b
, a
, background
->blue
);
3419 *(dp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
3420 *(dp
+ 5) = (png_byte
)(v
& 0xff);
3429 if (row_info
->color_type
& PNG_COLOR_MASK_ALPHA
)
3431 row_info
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
3432 row_info
->channels
--;
3433 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
3434 row_info
->bit_depth
);
3435 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
, row_width
);
3441 #if defined(PNG_READ_GAMMA_SUPPORTED)
3442 /* Gamma correct the image, avoiding the alpha channel. Make sure
3443 * you do this after you deal with the transparency issue on grayscale
3444 * or RGB images. If your bit depth is 8, use gamma_table, if it
3445 * is 16, use gamma_16_table and gamma_shift. Build these with
3446 * build_gamma_table().
3449 png_do_gamma(png_row_infop row_info
, png_bytep row
,
3450 png_bytep gamma_table
, png_uint_16pp gamma_16_table
,
3455 png_uint_32 row_width
=row_info
->width
;
3457 png_debug(1, "in png_do_gamma");
3459 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3460 row
!= NULL
&& row_info
!= NULL
&&
3462 ((row_info
->bit_depth
<= 8 && gamma_table
!= NULL
) ||
3463 (row_info
->bit_depth
== 16 && gamma_16_table
!= NULL
)))
3465 switch (row_info
->color_type
)
3467 case PNG_COLOR_TYPE_RGB
:
3469 if (row_info
->bit_depth
== 8)
3472 for (i
= 0; i
< row_width
; i
++)
3474 *sp
= gamma_table
[*sp
];
3476 *sp
= gamma_table
[*sp
];
3478 *sp
= gamma_table
[*sp
];
3482 else /* if (row_info->bit_depth == 16) */
3485 for (i
= 0; i
< row_width
; i
++)
3489 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3490 *sp
= (png_byte
)((v
>> 8) & 0xff);
3491 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3493 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3494 *sp
= (png_byte
)((v
>> 8) & 0xff);
3495 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3497 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3498 *sp
= (png_byte
)((v
>> 8) & 0xff);
3499 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3506 case PNG_COLOR_TYPE_RGB_ALPHA
:
3508 if (row_info
->bit_depth
== 8)
3511 for (i
= 0; i
< row_width
; i
++)
3513 *sp
= gamma_table
[*sp
];
3515 *sp
= gamma_table
[*sp
];
3517 *sp
= gamma_table
[*sp
];
3522 else /* if (row_info->bit_depth == 16) */
3525 for (i
= 0; i
< row_width
; i
++)
3527 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3528 *sp
= (png_byte
)((v
>> 8) & 0xff);
3529 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3531 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3532 *sp
= (png_byte
)((v
>> 8) & 0xff);
3533 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3535 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3536 *sp
= (png_byte
)((v
>> 8) & 0xff);
3537 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3544 case PNG_COLOR_TYPE_GRAY_ALPHA
:
3546 if (row_info
->bit_depth
== 8)
3549 for (i
= 0; i
< row_width
; i
++)
3551 *sp
= gamma_table
[*sp
];
3555 else /* if (row_info->bit_depth == 16) */
3558 for (i
= 0; i
< row_width
; i
++)
3560 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3561 *sp
= (png_byte
)((v
>> 8) & 0xff);
3562 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3569 case PNG_COLOR_TYPE_GRAY
:
3571 if (row_info
->bit_depth
== 2)
3574 for (i
= 0; i
< row_width
; i
+= 4)
3582 ((((int)gamma_table
[a
|(a
>>2)|(a
>>4)|(a
>>6)]) ) & 0xc0)|
3583 ((((int)gamma_table
[(b
<<2)|b
|(b
>>2)|(b
>>4)])>>2) & 0x30)|
3584 ((((int)gamma_table
[(c
<<4)|(c
<<2)|c
|(c
>>2)])>>4) & 0x0c)|
3585 ((((int)gamma_table
[(d
<<6)|(d
<<4)|(d
<<2)|d
])>>6) ));
3590 if (row_info
->bit_depth
== 4)
3593 for (i
= 0; i
< row_width
; i
+= 2)
3595 int msb
= *sp
& 0xf0;
3596 int lsb
= *sp
& 0x0f;
3598 *sp
= (png_byte
)((((int)gamma_table
[msb
| (msb
>> 4)]) & 0xf0)
3599 | (((int)gamma_table
[(lsb
<< 4) | lsb
]) >> 4));
3604 else if (row_info
->bit_depth
== 8)
3607 for (i
= 0; i
< row_width
; i
++)
3609 *sp
= gamma_table
[*sp
];
3614 else if (row_info
->bit_depth
== 16)
3617 for (i
= 0; i
< row_width
; i
++)
3619 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3620 *sp
= (png_byte
)((v
>> 8) & 0xff);
3621 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3632 #if defined(PNG_READ_EXPAND_SUPPORTED)
3633 /* Expands a palette row to an RGB or RGBA row depending
3634 * upon whether you supply trans and num_trans.
3637 png_do_expand_palette(png_row_infop row_info
, png_bytep row
,
3638 png_colorp palette
, png_bytep trans
, int num_trans
)
3643 png_uint_32 row_width
=row_info
->width
;
3645 png_debug(1, "in png_do_expand_palette");
3647 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3648 row
!= NULL
&& row_info
!= NULL
&&
3650 row_info
->color_type
== PNG_COLOR_TYPE_PALETTE
)
3652 if (row_info
->bit_depth
< 8)
3654 switch (row_info
->bit_depth
)
3658 sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
3659 dp
= row
+ (png_size_t
)row_width
- 1;
3660 shift
= 7 - (int)((row_width
+ 7) & 0x07);
3661 for (i
= 0; i
< row_width
; i
++)
3663 if ((*sp
>> shift
) & 0x01)
3682 sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
3683 dp
= row
+ (png_size_t
)row_width
- 1;
3684 shift
= (int)((3 - ((row_width
+ 3) & 0x03)) << 1);
3685 for (i
= 0; i
< row_width
; i
++)
3687 value
= (*sp
>> shift
) & 0x03;
3688 *dp
= (png_byte
)value
;
3704 sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
3705 dp
= row
+ (png_size_t
)row_width
- 1;
3706 shift
= (int)((row_width
& 0x01) << 2);
3707 for (i
= 0; i
< row_width
; i
++)
3709 value
= (*sp
>> shift
) & 0x0f;
3710 *dp
= (png_byte
)value
;
3724 row_info
->bit_depth
= 8;
3725 row_info
->pixel_depth
= 8;
3726 row_info
->rowbytes
= row_width
;
3728 switch (row_info
->bit_depth
)
3734 sp
= row
+ (png_size_t
)row_width
- 1;
3735 dp
= row
+ (png_size_t
)(row_width
<< 2) - 1;
3737 for (i
= 0; i
< row_width
; i
++)
3739 if ((int)(*sp
) >= num_trans
)
3743 *dp
-- = palette
[*sp
].blue
;
3744 *dp
-- = palette
[*sp
].green
;
3745 *dp
-- = palette
[*sp
].red
;
3748 row_info
->bit_depth
= 8;
3749 row_info
->pixel_depth
= 32;
3750 row_info
->rowbytes
= row_width
* 4;
3751 row_info
->color_type
= 6;
3752 row_info
->channels
= 4;
3756 sp
= row
+ (png_size_t
)row_width
- 1;
3757 dp
= row
+ (png_size_t
)(row_width
* 3) - 1;
3759 for (i
= 0; i
< row_width
; i
++)
3761 *dp
-- = palette
[*sp
].blue
;
3762 *dp
-- = palette
[*sp
].green
;
3763 *dp
-- = palette
[*sp
].red
;
3767 row_info
->bit_depth
= 8;
3768 row_info
->pixel_depth
= 24;
3769 row_info
->rowbytes
= row_width
* 3;
3770 row_info
->color_type
= 2;
3771 row_info
->channels
= 3;
3779 /* If the bit depth < 8, it is expanded to 8. Also, if the already
3780 * expanded transparency value is supplied, an alpha channel is built.
3783 png_do_expand(png_row_infop row_info
, png_bytep row
,
3784 png_color_16p trans_value
)
3789 png_uint_32 row_width
=row_info
->width
;
3791 png_debug(1, "in png_do_expand");
3792 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3793 if (row
!= NULL
&& row_info
!= NULL
)
3796 if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
3798 png_uint_16 gray
= (png_uint_16
)(trans_value
? trans_value
->gray
: 0);
3800 if (row_info
->bit_depth
< 8)
3802 switch (row_info
->bit_depth
)
3806 gray
= (png_uint_16
)((gray
&0x01)*0xff);
3807 sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
3808 dp
= row
+ (png_size_t
)row_width
- 1;
3809 shift
= 7 - (int)((row_width
+ 7) & 0x07);
3810 for (i
= 0; i
< row_width
; i
++)
3812 if ((*sp
>> shift
) & 0x01)
3831 gray
= (png_uint_16
)((gray
&0x03)*0x55);
3832 sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
3833 dp
= row
+ (png_size_t
)row_width
- 1;
3834 shift
= (int)((3 - ((row_width
+ 3) & 0x03)) << 1);
3835 for (i
= 0; i
< row_width
; i
++)
3837 value
= (*sp
>> shift
) & 0x03;
3838 *dp
= (png_byte
)(value
| (value
<< 2) | (value
<< 4) |
3855 gray
= (png_uint_16
)((gray
&0x0f)*0x11);
3856 sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
3857 dp
= row
+ (png_size_t
)row_width
- 1;
3858 shift
= (int)((1 - ((row_width
+ 1) & 0x01)) << 2);
3859 for (i
= 0; i
< row_width
; i
++)
3861 value
= (*sp
>> shift
) & 0x0f;
3862 *dp
= (png_byte
)(value
| (value
<< 4));
3877 row_info
->bit_depth
= 8;
3878 row_info
->pixel_depth
= 8;
3879 row_info
->rowbytes
= row_width
;
3882 if (trans_value
!= NULL
)
3884 if (row_info
->bit_depth
== 8)
3887 sp
= row
+ (png_size_t
)row_width
- 1;
3888 dp
= row
+ (png_size_t
)(row_width
<< 1) - 1;
3889 for (i
= 0; i
< row_width
; i
++)
3899 else if (row_info
->bit_depth
== 16)
3901 png_byte gray_high
= (gray
>> 8) & 0xff;
3902 png_byte gray_low
= gray
& 0xff;
3903 sp
= row
+ row_info
->rowbytes
- 1;
3904 dp
= row
+ (row_info
->rowbytes
<< 1) - 1;
3905 for (i
= 0; i
< row_width
; i
++)
3907 if (*(sp
- 1) == gray_high
&& *(sp
) == gray_low
)
3922 row_info
->color_type
= PNG_COLOR_TYPE_GRAY_ALPHA
;
3923 row_info
->channels
= 2;
3924 row_info
->pixel_depth
= (png_byte
)(row_info
->bit_depth
<< 1);
3925 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
,
3929 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
&& trans_value
)
3931 if (row_info
->bit_depth
== 8)
3933 png_byte red
= trans_value
->red
& 0xff;
3934 png_byte green
= trans_value
->green
& 0xff;
3935 png_byte blue
= trans_value
->blue
& 0xff;
3936 sp
= row
+ (png_size_t
)row_info
->rowbytes
- 1;
3937 dp
= row
+ (png_size_t
)(row_width
<< 2) - 1;
3938 for (i
= 0; i
< row_width
; i
++)
3940 if (*(sp
- 2) == red
&& *(sp
- 1) == green
&& *(sp
) == blue
)
3949 else if (row_info
->bit_depth
== 16)
3951 png_byte red_high
= (trans_value
->red
>> 8) & 0xff;
3952 png_byte green_high
= (trans_value
->green
>> 8) & 0xff;
3953 png_byte blue_high
= (trans_value
->blue
>> 8) & 0xff;
3954 png_byte red_low
= trans_value
->red
& 0xff;
3955 png_byte green_low
= trans_value
->green
& 0xff;
3956 png_byte blue_low
= trans_value
->blue
& 0xff;
3957 sp
= row
+ row_info
->rowbytes
- 1;
3958 dp
= row
+ (png_size_t
)(row_width
<< 3) - 1;
3959 for (i
= 0; i
< row_width
; i
++)
3961 if (*(sp
- 5) == red_high
&&
3962 *(sp
- 4) == red_low
&&
3963 *(sp
- 3) == green_high
&&
3964 *(sp
- 2) == green_low
&&
3965 *(sp
- 1) == blue_high
&&
3984 row_info
->color_type
= PNG_COLOR_TYPE_RGB_ALPHA
;
3985 row_info
->channels
= 4;
3986 row_info
->pixel_depth
= (png_byte
)(row_info
->bit_depth
<< 2);
3987 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
, row_width
);
3993 #if defined(PNG_READ_DITHER_SUPPORTED)
3995 png_do_dither(png_row_infop row_info
, png_bytep row
,
3996 png_bytep palette_lookup
, png_bytep dither_lookup
)
4000 png_uint_32 row_width
=row_info
->width
;
4002 png_debug(1, "in png_do_dither");
4003 #if defined(PNG_USELESS_TESTS_SUPPORTED)
4004 if (row
!= NULL
&& row_info
!= NULL
)
4007 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
&&
4008 palette_lookup
&& row_info
->bit_depth
== 8)
4013 for (i
= 0; i
< row_width
; i
++)
4019 /* This looks real messy, but the compiler will reduce
4020 * it down to a reasonable formula. For example, with
4021 * 5 bits per color, we get:
4022 * p = (((r >> 3) & 0x1f) << 10) |
4023 * (((g >> 3) & 0x1f) << 5) |
4024 * ((b >> 3) & 0x1f);
4026 p
= (((r
>> (8 - PNG_DITHER_RED_BITS
)) &
4027 ((1 << PNG_DITHER_RED_BITS
) - 1)) <<
4028 (PNG_DITHER_GREEN_BITS
+ PNG_DITHER_BLUE_BITS
)) |
4029 (((g
>> (8 - PNG_DITHER_GREEN_BITS
)) &
4030 ((1 << PNG_DITHER_GREEN_BITS
) - 1)) <<
4031 (PNG_DITHER_BLUE_BITS
)) |
4032 ((b
>> (8 - PNG_DITHER_BLUE_BITS
)) &
4033 ((1 << PNG_DITHER_BLUE_BITS
) - 1));
4035 *dp
++ = palette_lookup
[p
];
4037 row_info
->color_type
= PNG_COLOR_TYPE_PALETTE
;
4038 row_info
->channels
= 1;
4039 row_info
->pixel_depth
= row_info
->bit_depth
;
4040 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
, row_width
);
4042 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
&&
4043 palette_lookup
!= NULL
&& row_info
->bit_depth
== 8)
4048 for (i
= 0; i
< row_width
; i
++)
4055 p
= (((r
>> (8 - PNG_DITHER_RED_BITS
)) &
4056 ((1 << PNG_DITHER_RED_BITS
) - 1)) <<
4057 (PNG_DITHER_GREEN_BITS
+ PNG_DITHER_BLUE_BITS
)) |
4058 (((g
>> (8 - PNG_DITHER_GREEN_BITS
)) &
4059 ((1 << PNG_DITHER_GREEN_BITS
) - 1)) <<
4060 (PNG_DITHER_BLUE_BITS
)) |
4061 ((b
>> (8 - PNG_DITHER_BLUE_BITS
)) &
4062 ((1 << PNG_DITHER_BLUE_BITS
) - 1));
4064 *dp
++ = palette_lookup
[p
];
4066 row_info
->color_type
= PNG_COLOR_TYPE_PALETTE
;
4067 row_info
->channels
= 1;
4068 row_info
->pixel_depth
= row_info
->bit_depth
;
4069 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
, row_width
);
4071 else if (row_info
->color_type
== PNG_COLOR_TYPE_PALETTE
&&
4072 dither_lookup
&& row_info
->bit_depth
== 8)
4075 for (i
= 0; i
< row_width
; i
++, sp
++)
4077 *sp
= dither_lookup
[*sp
];
4084 #ifdef PNG_FLOATING_POINT_SUPPORTED
4085 #if defined(PNG_READ_GAMMA_SUPPORTED)
4086 static PNG_CONST
int png_gamma_shift
[] =
4087 {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00};
4089 /* We build the 8- or 16-bit gamma tables here. Note that for 16-bit
4090 * tables, we don't make a full table if we are reducing to 8-bit in
4091 * the future. Note also how the gamma_16 tables are segmented so that
4092 * we don't need to allocate > 64K chunks for a full 16-bit table.
4095 png_build_gamma_table(png_structp png_ptr
)
4097 png_debug(1, "in png_build_gamma_table");
4099 if (png_ptr
->bit_depth
<= 8)
4104 if (png_ptr
->screen_gamma
> .000001)
4105 g
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
4110 png_ptr
->gamma_table
= (png_bytep
)png_malloc(png_ptr
,
4113 for (i
= 0; i
< 256; i
++)
4115 png_ptr
->gamma_table
[i
] = (png_byte
)(pow((double)i
/ 255.0,
4119 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
4120 defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
4121 if (png_ptr
->transformations
& ((PNG_BACKGROUND
) | PNG_RGB_TO_GRAY
))
4124 g
= 1.0 / (png_ptr
->gamma
);
4126 png_ptr
->gamma_to_1
= (png_bytep
)png_malloc(png_ptr
,
4129 for (i
= 0; i
< 256; i
++)
4131 png_ptr
->gamma_to_1
[i
] = (png_byte
)(pow((double)i
/ 255.0,
4136 png_ptr
->gamma_from_1
= (png_bytep
)png_malloc(png_ptr
,
4139 if (png_ptr
->screen_gamma
> 0.000001)
4140 g
= 1.0 / png_ptr
->screen_gamma
;
4143 g
= png_ptr
->gamma
; /* Probably doing rgb_to_gray */
4145 for (i
= 0; i
< 256; i
++)
4147 png_ptr
->gamma_from_1
[i
] = (png_byte
)(pow((double)i
/ 255.0,
4152 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
4157 int i
, j
, shift
, num
;
4161 if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
4163 sig_bit
= (int)png_ptr
->sig_bit
.red
;
4165 if ((int)png_ptr
->sig_bit
.green
> sig_bit
)
4166 sig_bit
= png_ptr
->sig_bit
.green
;
4168 if ((int)png_ptr
->sig_bit
.blue
> sig_bit
)
4169 sig_bit
= png_ptr
->sig_bit
.blue
;
4173 sig_bit
= (int)png_ptr
->sig_bit
.gray
;
4177 shift
= 16 - sig_bit
;
4182 if (png_ptr
->transformations
& PNG_16_TO_8
)
4184 if (shift
< (16 - PNG_MAX_GAMMA_8
))
4185 shift
= (16 - PNG_MAX_GAMMA_8
);
4194 png_ptr
->gamma_shift
= (png_byte
)shift
;
4196 num
= (1 << (8 - shift
));
4198 if (png_ptr
->screen_gamma
> .000001)
4199 g
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
4203 png_ptr
->gamma_16_table
= (png_uint_16pp
)png_malloc(png_ptr
,
4204 (png_uint_32
)(num
* png_sizeof(png_uint_16p
)));
4205 png_memset(png_ptr
->gamma_16_table
, 0, num
* png_sizeof(png_uint_16p
));
4207 if (png_ptr
->transformations
& (PNG_16_TO_8
| PNG_BACKGROUND
))
4210 png_uint_32 last
, max
;
4212 for (i
= 0; i
< num
; i
++)
4214 png_ptr
->gamma_16_table
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
4215 (png_uint_32
)(256 * png_sizeof(png_uint_16
)));
4220 for (i
= 0; i
< 256; i
++)
4222 fout
= ((double)i
+ 0.5) / 256.0;
4224 max
= (png_uint_32
)(fin
* (double)((png_uint_32
)num
<< 8));
4227 png_ptr
->gamma_16_table
[(int)(last
& (0xff >> shift
))]
4228 [(int)(last
>> (8 - shift
))] = (png_uint_16
)(
4229 (png_uint_16
)i
| ((png_uint_16
)i
<< 8));
4233 while (last
< ((png_uint_32
)num
<< 8))
4235 png_ptr
->gamma_16_table
[(int)(last
& (0xff >> shift
))]
4236 [(int)(last
>> (8 - shift
))] = (png_uint_16
)65535L;
4242 for (i
= 0; i
< num
; i
++)
4244 png_ptr
->gamma_16_table
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
4245 (png_uint_32
)(256 * png_sizeof(png_uint_16
)));
4247 ig
= (((png_uint_32
)i
* (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
4249 for (j
= 0; j
< 256; j
++)
4251 png_ptr
->gamma_16_table
[i
][j
] =
4252 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
4253 65535.0, g
) * 65535.0 + .5);
4258 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
4259 defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
4260 if (png_ptr
->transformations
& (PNG_BACKGROUND
| PNG_RGB_TO_GRAY
))
4263 g
= 1.0 / (png_ptr
->gamma
);
4265 png_ptr
->gamma_16_to_1
= (png_uint_16pp
)png_malloc(png_ptr
,
4266 (png_uint_32
)(num
* png_sizeof(png_uint_16p
)));
4267 png_memset(png_ptr
->gamma_16_to_1
, 0, num
* png_sizeof(png_uint_16p
));
4269 for (i
= 0; i
< num
; i
++)
4271 png_ptr
->gamma_16_to_1
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
4272 (png_uint_32
)(256 * png_sizeof(png_uint_16
)));
4274 ig
= (((png_uint_32
)i
*
4275 (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
4276 for (j
= 0; j
< 256; j
++)
4278 png_ptr
->gamma_16_to_1
[i
][j
] =
4279 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
4280 65535.0, g
) * 65535.0 + .5);
4284 if (png_ptr
->screen_gamma
> 0.000001)
4285 g
= 1.0 / png_ptr
->screen_gamma
;
4288 g
= png_ptr
->gamma
; /* Probably doing rgb_to_gray */
4290 png_ptr
->gamma_16_from_1
= (png_uint_16pp
)png_malloc(png_ptr
,
4291 (png_uint_32
)(num
* png_sizeof(png_uint_16p
)));
4292 png_memset(png_ptr
->gamma_16_from_1
, 0,
4293 num
* png_sizeof(png_uint_16p
));
4295 for (i
= 0; i
< num
; i
++)
4297 png_ptr
->gamma_16_from_1
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
4298 (png_uint_32
)(256 * png_sizeof(png_uint_16
)));
4300 ig
= (((png_uint_32
)i
*
4301 (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
4303 for (j
= 0; j
< 256; j
++)
4305 png_ptr
->gamma_16_from_1
[i
][j
] =
4306 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
4307 65535.0, g
) * 65535.0 + .5);
4311 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
4315 /* To do: install integer version of png_build_gamma_table here */
4318 #if defined(PNG_MNG_FEATURES_SUPPORTED)
4319 /* Undoes intrapixel differencing */
4321 png_do_read_intrapixel(png_row_infop row_info
, png_bytep row
)
4323 png_debug(1, "in png_do_read_intrapixel");
4325 #if defined(PNG_USELESS_TESTS_SUPPORTED)
4326 row
!= NULL
&& row_info
!= NULL
&&
4328 (row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
4330 int bytes_per_pixel
;
4331 png_uint_32 row_width
= row_info
->width
;
4332 if (row_info
->bit_depth
== 8)
4337 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
4338 bytes_per_pixel
= 3;
4340 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
4341 bytes_per_pixel
= 4;
4346 for (i
= 0, rp
= row
; i
< row_width
; i
++, rp
+= bytes_per_pixel
)
4348 *(rp
) = (png_byte
)((256 + *rp
+ *(rp
+1))&0xff);
4349 *(rp
+2) = (png_byte
)((256 + *(rp
+2) + *(rp
+1))&0xff);
4352 else if (row_info
->bit_depth
== 16)
4357 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
4358 bytes_per_pixel
= 6;
4360 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
4361 bytes_per_pixel
= 8;
4366 for (i
= 0, rp
= row
; i
< row_width
; i
++, rp
+= bytes_per_pixel
)
4368 png_uint_32 s0
= (*(rp
) << 8) | *(rp
+ 1);
4369 png_uint_32 s1
= (*(rp
+ 2) << 8) | *(rp
+ 3);
4370 png_uint_32 s2
= (*(rp
+ 4) << 8) | *(rp
+ 5);
4371 png_uint_32 red
= (png_uint_32
)((s0
+ s1
+ 65536L) & 0xffffL
);
4372 png_uint_32 blue
= (png_uint_32
)((s2
+ s1
+ 65536L) & 0xffffL
);
4373 *(rp
) = (png_byte
)((red
>> 8) & 0xff);
4374 *(rp
+1) = (png_byte
)(red
& 0xff);
4375 *(rp
+4) = (png_byte
)((blue
>> 8) & 0xff);
4376 *(rp
+5) = (png_byte
)(blue
& 0xff);
4381 #endif /* PNG_MNG_FEATURES_SUPPORTED */
4382 #endif /* PNG_READ_SUPPORTED */