2 /* pngrtran.c - transforms the data in a row for PNG readers
4 * Last changed in libpng 1.5.1 [February 3, 2011]
5 * Copyright (c) 1998-2011 Glenn Randers-Pehrson
6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
9 * This code is released under the libpng license.
10 * For conditions of distribution and use, see the disclaimer
11 * and license in png.h
13 * This file contains functions optionally called by an application
14 * in order to tell libpng how to handle data when reading a PNG.
15 * Transformations that are used in both reading and writing are
21 #ifdef PNG_READ_SUPPORTED
23 /* Set the action on getting a CRC error for an ancillary or critical chunk. */
25 png_set_crc_action(png_structp png_ptr
, int crit_action
, int ancil_action
)
27 png_debug(1, "in png_set_crc_action");
32 /* Tell libpng how we react to CRC errors in critical chunks */
35 case PNG_CRC_NO_CHANGE
: /* Leave setting as is */
38 case PNG_CRC_WARN_USE
: /* Warn/use data */
39 png_ptr
->flags
&= ~PNG_FLAG_CRC_CRITICAL_MASK
;
40 png_ptr
->flags
|= PNG_FLAG_CRC_CRITICAL_USE
;
43 case PNG_CRC_QUIET_USE
: /* Quiet/use data */
44 png_ptr
->flags
&= ~PNG_FLAG_CRC_CRITICAL_MASK
;
45 png_ptr
->flags
|= PNG_FLAG_CRC_CRITICAL_USE
|
46 PNG_FLAG_CRC_CRITICAL_IGNORE
;
49 case PNG_CRC_WARN_DISCARD
: /* Not a valid action for critical data */
51 "Can't discard critical data on CRC error");
52 case PNG_CRC_ERROR_QUIT
: /* Error/quit */
56 png_ptr
->flags
&= ~PNG_FLAG_CRC_CRITICAL_MASK
;
60 /* Tell libpng how we react to CRC errors in ancillary chunks */
63 case PNG_CRC_NO_CHANGE
: /* Leave setting as is */
66 case PNG_CRC_WARN_USE
: /* Warn/use data */
67 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
68 png_ptr
->flags
|= PNG_FLAG_CRC_ANCILLARY_USE
;
71 case PNG_CRC_QUIET_USE
: /* Quiet/use data */
72 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
73 png_ptr
->flags
|= PNG_FLAG_CRC_ANCILLARY_USE
|
74 PNG_FLAG_CRC_ANCILLARY_NOWARN
;
77 case PNG_CRC_ERROR_QUIT
: /* Error/quit */
78 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
79 png_ptr
->flags
|= PNG_FLAG_CRC_ANCILLARY_NOWARN
;
82 case PNG_CRC_WARN_DISCARD
: /* Warn/discard data */
86 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
91 #ifdef PNG_READ_BACKGROUND_SUPPORTED
92 /* Handle alpha and tRNS via a background color */
94 png_set_background_fixed(png_structp png_ptr
,
95 png_const_color_16p background_color
, int background_gamma_code
,
96 int need_expand
, png_fixed_point background_gamma
)
98 png_debug(1, "in png_set_background_fixed");
103 if (background_gamma_code
== PNG_BACKGROUND_GAMMA_UNKNOWN
)
105 png_warning(png_ptr
, "Application must supply a known background gamma");
109 png_ptr
->transformations
|= PNG_BACKGROUND
;
110 png_memcpy(&(png_ptr
->background
), background_color
,
111 png_sizeof(png_color_16
));
112 png_ptr
->background_gamma
= background_gamma
;
113 png_ptr
->background_gamma_type
= (png_byte
)(background_gamma_code
);
114 png_ptr
->transformations
|= (need_expand
? PNG_BACKGROUND_EXPAND
: 0);
117 # ifdef PNG_FLOATING_POINT_SUPPORTED
119 png_set_background(png_structp png_ptr
,
120 png_const_color_16p background_color
, int background_gamma_code
,
121 int need_expand
, double background_gamma
)
123 png_set_background_fixed(png_ptr
, background_color
, background_gamma_code
,
124 need_expand
, png_fixed(png_ptr
, background_gamma
, "png_set_background"));
126 # endif /* FLOATING_POINT */
127 #endif /* READ_BACKGROUND */
129 #ifdef PNG_READ_16_TO_8_SUPPORTED
130 /* Strip 16 bit depth files to 8 bit depth */
132 png_set_strip_16(png_structp png_ptr
)
134 png_debug(1, "in png_set_strip_16");
139 png_ptr
->transformations
|= PNG_16_TO_8
;
143 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
145 png_set_strip_alpha(png_structp png_ptr
)
147 png_debug(1, "in png_set_strip_alpha");
152 png_ptr
->flags
|= PNG_FLAG_STRIP_ALPHA
;
156 #ifdef PNG_READ_QUANTIZE_SUPPORTED
157 /* Dither file to 8 bit. Supply a palette, the current number
158 * of elements in the palette, the maximum number of elements
159 * allowed, and a histogram if possible. If the current number
160 * of colors is greater then the maximum number, the palette will be
161 * modified to fit in the maximum number. "full_quantize" indicates
162 * whether we need a quantizing cube set up for RGB images, or if we
163 * simply are reducing the number of colors in a paletted image.
166 typedef struct png_dsort_struct
168 struct png_dsort_struct FAR
* next
;
172 typedef png_dsort FAR
* png_dsortp
;
173 typedef png_dsort FAR
* FAR
* png_dsortpp
;
176 png_set_quantize(png_structp png_ptr
, png_colorp palette
,
177 int num_palette
, int maximum_colors
, png_const_uint_16p histogram
,
180 png_debug(1, "in png_set_quantize");
185 png_ptr
->transformations
|= PNG_QUANTIZE
;
191 png_ptr
->quantize_index
= (png_bytep
)png_malloc(png_ptr
,
192 (png_uint_32
)(num_palette
* png_sizeof(png_byte
)));
193 for (i
= 0; i
< num_palette
; i
++)
194 png_ptr
->quantize_index
[i
] = (png_byte
)i
;
197 if (num_palette
> maximum_colors
)
199 if (histogram
!= NULL
)
201 /* This is easy enough, just throw out the least used colors.
202 * Perhaps not the best solution, but good enough.
207 /* Initialize an array to sort colors */
208 png_ptr
->quantize_sort
= (png_bytep
)png_malloc(png_ptr
,
209 (png_uint_32
)(num_palette
* png_sizeof(png_byte
)));
211 /* Initialize the quantize_sort array */
212 for (i
= 0; i
< num_palette
; i
++)
213 png_ptr
->quantize_sort
[i
] = (png_byte
)i
;
215 /* Find the least used palette entries by starting a
216 * bubble sort, and running it until we have sorted
217 * out enough colors. Note that we don't care about
218 * sorting all the colors, just finding which are
222 for (i
= num_palette
- 1; i
>= maximum_colors
; i
--)
224 int done
; /* To stop early if the list is pre-sorted */
228 for (j
= 0; j
< i
; j
++)
230 if (histogram
[png_ptr
->quantize_sort
[j
]]
231 < histogram
[png_ptr
->quantize_sort
[j
+ 1]])
235 t
= png_ptr
->quantize_sort
[j
];
236 png_ptr
->quantize_sort
[j
] = png_ptr
->quantize_sort
[j
+ 1];
237 png_ptr
->quantize_sort
[j
+ 1] = t
;
246 /* Swap the palette around, and set up a table, if necessary */
251 /* Put all the useful colors within the max, but don't
254 for (i
= 0; i
< maximum_colors
; i
++)
256 if ((int)png_ptr
->quantize_sort
[i
] >= maximum_colors
)
260 while ((int)png_ptr
->quantize_sort
[j
] >= maximum_colors
);
262 palette
[i
] = palette
[j
];
270 /* Move all the used colors inside the max limit, and
271 * develop a translation table.
273 for (i
= 0; i
< maximum_colors
; i
++)
275 /* Only move the colors we need to */
276 if ((int)png_ptr
->quantize_sort
[i
] >= maximum_colors
)
282 while ((int)png_ptr
->quantize_sort
[j
] >= maximum_colors
);
284 tmp_color
= palette
[j
];
285 palette
[j
] = palette
[i
];
286 palette
[i
] = tmp_color
;
287 /* Indicate where the color went */
288 png_ptr
->quantize_index
[j
] = (png_byte
)i
;
289 png_ptr
->quantize_index
[i
] = (png_byte
)j
;
293 /* Find closest color for those colors we are not using */
294 for (i
= 0; i
< num_palette
; i
++)
296 if ((int)png_ptr
->quantize_index
[i
] >= maximum_colors
)
298 int min_d
, k
, min_k
, d_index
;
300 /* Find the closest color to one we threw out */
301 d_index
= png_ptr
->quantize_index
[i
];
302 min_d
= PNG_COLOR_DIST(palette
[d_index
], palette
[0]);
303 for (k
= 1, min_k
= 0; k
< maximum_colors
; k
++)
307 d
= PNG_COLOR_DIST(palette
[d_index
], palette
[k
]);
315 /* Point to closest color */
316 png_ptr
->quantize_index
[i
] = (png_byte
)min_k
;
320 png_free(png_ptr
, png_ptr
->quantize_sort
);
321 png_ptr
->quantize_sort
= NULL
;
325 /* This is much harder to do simply (and quickly). Perhaps
326 * we need to go through a median cut routine, but those
327 * don't always behave themselves with only a few colors
328 * as input. So we will just find the closest two colors,
329 * and throw out one of them (chosen somewhat randomly).
330 * [We don't understand this at all, so if someone wants to
331 * work on improving it, be our guest - AED, GRP]
341 /* Initialize palette index arrays */
342 png_ptr
->index_to_palette
= (png_bytep
)png_malloc(png_ptr
,
343 (png_uint_32
)(num_palette
* png_sizeof(png_byte
)));
344 png_ptr
->palette_to_index
= (png_bytep
)png_malloc(png_ptr
,
345 (png_uint_32
)(num_palette
* png_sizeof(png_byte
)));
347 /* Initialize the sort array */
348 for (i
= 0; i
< num_palette
; i
++)
350 png_ptr
->index_to_palette
[i
] = (png_byte
)i
;
351 png_ptr
->palette_to_index
[i
] = (png_byte
)i
;
354 hash
= (png_dsortpp
)png_calloc(png_ptr
, (png_uint_32
)(769 *
355 png_sizeof(png_dsortp
)));
357 num_new_palette
= num_palette
;
359 /* Initial wild guess at how far apart the farthest pixel
360 * pair we will be eliminating will be. Larger
361 * numbers mean more areas will be allocated, Smaller
362 * numbers run the risk of not saving enough data, and
363 * having to do this all over again.
365 * I have not done extensive checking on this number.
369 while (num_new_palette
> maximum_colors
)
371 for (i
= 0; i
< num_new_palette
- 1; i
++)
375 for (j
= i
+ 1; j
< num_new_palette
; j
++)
379 d
= PNG_COLOR_DIST(palette
[i
], palette
[j
]);
384 t
= (png_dsortp
)png_malloc_warn(png_ptr
,
385 (png_uint_32
)(png_sizeof(png_dsort
)));
391 t
->left
= (png_byte
)i
;
392 t
->right
= (png_byte
)j
;
401 for (i
= 0; i
<= max_d
; i
++)
407 for (p
= hash
[i
]; p
; p
= p
->next
)
409 if ((int)png_ptr
->index_to_palette
[p
->left
]
411 (int)png_ptr
->index_to_palette
[p
->right
]
416 if (num_new_palette
& 0x01)
428 palette
[png_ptr
->index_to_palette
[j
]]
429 = palette
[num_new_palette
];
434 for (k
= 0; k
< num_palette
; k
++)
436 if (png_ptr
->quantize_index
[k
] ==
437 png_ptr
->index_to_palette
[j
])
438 png_ptr
->quantize_index
[k
] =
439 png_ptr
->index_to_palette
[next_j
];
441 if ((int)png_ptr
->quantize_index
[k
] ==
443 png_ptr
->quantize_index
[k
] =
444 png_ptr
->index_to_palette
[j
];
448 png_ptr
->index_to_palette
[png_ptr
->palette_to_index
449 [num_new_palette
]] = png_ptr
->index_to_palette
[j
];
451 png_ptr
->palette_to_index
[png_ptr
->index_to_palette
[j
]]
452 = png_ptr
->palette_to_index
[num_new_palette
];
454 png_ptr
->index_to_palette
[j
] =
455 (png_byte
)num_new_palette
;
457 png_ptr
->palette_to_index
[num_new_palette
] =
460 if (num_new_palette
<= maximum_colors
)
463 if (num_new_palette
<= maximum_colors
)
468 for (i
= 0; i
< 769; i
++)
472 png_dsortp p
= hash
[i
];
476 png_free(png_ptr
, p
);
484 png_free(png_ptr
, hash
);
485 png_free(png_ptr
, png_ptr
->palette_to_index
);
486 png_free(png_ptr
, png_ptr
->index_to_palette
);
487 png_ptr
->palette_to_index
= NULL
;
488 png_ptr
->index_to_palette
= NULL
;
490 num_palette
= maximum_colors
;
492 if (png_ptr
->palette
== NULL
)
494 png_ptr
->palette
= palette
;
496 png_ptr
->num_palette
= (png_uint_16
)num_palette
;
502 int total_bits
= PNG_QUANTIZE_RED_BITS
+ PNG_QUANTIZE_GREEN_BITS
+
503 PNG_QUANTIZE_BLUE_BITS
;
504 int num_red
= (1 << PNG_QUANTIZE_RED_BITS
);
505 int num_green
= (1 << PNG_QUANTIZE_GREEN_BITS
);
506 int num_blue
= (1 << PNG_QUANTIZE_BLUE_BITS
);
507 png_size_t num_entries
= ((png_size_t
)1 << total_bits
);
509 png_ptr
->palette_lookup
= (png_bytep
)png_calloc(png_ptr
,
510 (png_uint_32
)(num_entries
* png_sizeof(png_byte
)));
512 distance
= (png_bytep
)png_malloc(png_ptr
, (png_uint_32
)(num_entries
*
513 png_sizeof(png_byte
)));
515 png_memset(distance
, 0xff, num_entries
* png_sizeof(png_byte
));
517 for (i
= 0; i
< num_palette
; i
++)
520 int r
= (palette
[i
].red
>> (8 - PNG_QUANTIZE_RED_BITS
));
521 int g
= (palette
[i
].green
>> (8 - PNG_QUANTIZE_GREEN_BITS
));
522 int b
= (palette
[i
].blue
>> (8 - PNG_QUANTIZE_BLUE_BITS
));
524 for (ir
= 0; ir
< num_red
; ir
++)
526 /* int dr = abs(ir - r); */
527 int dr
= ((ir
> r
) ? ir
- r
: r
- ir
);
528 int index_r
= (ir
<< (PNG_QUANTIZE_BLUE_BITS
+
529 PNG_QUANTIZE_GREEN_BITS
));
531 for (ig
= 0; ig
< num_green
; ig
++)
533 /* int dg = abs(ig - g); */
534 int dg
= ((ig
> g
) ? ig
- g
: g
- ig
);
536 int dm
= ((dr
> dg
) ? dr
: dg
);
537 int index_g
= index_r
| (ig
<< PNG_QUANTIZE_BLUE_BITS
);
539 for (ib
= 0; ib
< num_blue
; ib
++)
541 int d_index
= index_g
| ib
;
542 /* int db = abs(ib - b); */
543 int db
= ((ib
> b
) ? ib
- b
: b
- ib
);
544 int dmax
= ((dm
> db
) ? dm
: db
);
545 int d
= dmax
+ dt
+ db
;
547 if (d
< (int)distance
[d_index
])
549 distance
[d_index
] = (png_byte
)d
;
550 png_ptr
->palette_lookup
[d_index
] = (png_byte
)i
;
557 png_free(png_ptr
, distance
);
560 #endif /* PNG_READ_QUANTIZE_SUPPORTED */
562 #ifdef PNG_READ_GAMMA_SUPPORTED
563 /* Transform the image from the file_gamma to the screen_gamma. We
564 * only do transformations on images where the file_gamma and screen_gamma
565 * are not close reciprocals, otherwise it slows things down slightly, and
566 * also needlessly introduces small errors.
568 * We will turn off gamma transformation later if no semitransparent entries
569 * are present in the tRNS array for palette images. We can't do it here
570 * because we don't necessarily have the tRNS chunk yet.
572 static int /* PRIVATE */
573 png_gamma_threshold(png_fixed_point scrn_gamma
, png_fixed_point file_gamma
)
575 /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma
576 * correction as a difference of the overall transform from 1.0
578 * We want to compare the threshold with s*f - 1, if we get
579 * overflow here it is because of wacky gamma values so we
580 * turn on processing anyway.
582 png_fixed_point gtest
;
583 return !png_muldiv(>est
, scrn_gamma
, file_gamma
, PNG_FP_1
) ||
584 png_gamma_significant(gtest
);
588 png_set_gamma_fixed(png_structp png_ptr
, png_fixed_point scrn_gamma
,
589 png_fixed_point file_gamma
)
591 png_debug(1, "in png_set_gamma_fixed");
596 if ((png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
) ||
597 (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
) ||
598 png_gamma_threshold(scrn_gamma
, file_gamma
))
599 png_ptr
->transformations
|= PNG_GAMMA
;
600 png_ptr
->gamma
= file_gamma
;
601 png_ptr
->screen_gamma
= scrn_gamma
;
604 # ifdef PNG_FLOATING_POINT_SUPPORTED
606 png_set_gamma(png_structp png_ptr
, double scrn_gamma
, double file_gamma
)
608 png_set_gamma_fixed(png_ptr
,
609 png_fixed(png_ptr
, scrn_gamma
, "png_set_gamma screen gamma"),
610 png_fixed(png_ptr
, file_gamma
, "png_set_gamma file gamma"));
612 # endif /* FLOATING_POINT_SUPPORTED */
613 #endif /* READ_GAMMA */
615 #ifdef PNG_READ_EXPAND_SUPPORTED
616 /* Expand paletted images to RGB, expand grayscale images of
617 * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
621 png_set_expand(png_structp png_ptr
)
623 png_debug(1, "in png_set_expand");
628 png_ptr
->transformations
|= (PNG_EXPAND
| PNG_EXPAND_tRNS
);
629 png_ptr
->flags
&= ~PNG_FLAG_ROW_INIT
;
632 /* GRR 19990627: the following three functions currently are identical
633 * to png_set_expand(). However, it is entirely reasonable that someone
634 * might wish to expand an indexed image to RGB but *not* expand a single,
635 * fully transparent palette entry to a full alpha channel--perhaps instead
636 * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
637 * the transparent color with a particular RGB value, or drop tRNS entirely.
638 * IOW, a future version of the library may make the transformations flag
639 * a bit more fine-grained, with separate bits for each of these three
642 * More to the point, these functions make it obvious what libpng will be
643 * doing, whereas "expand" can (and does) mean any number of things.
645 * GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified
646 * to expand only the sample depth but not to expand the tRNS to alpha
647 * and its name was changed to png_set_expand_gray_1_2_4_to_8().
650 /* Expand paletted images to RGB. */
652 png_set_palette_to_rgb(png_structp png_ptr
)
654 png_debug(1, "in png_set_palette_to_rgb");
659 png_ptr
->transformations
|= (PNG_EXPAND
| PNG_EXPAND_tRNS
);
660 png_ptr
->flags
&= ~PNG_FLAG_ROW_INIT
;
663 /* Expand grayscale images of less than 8-bit depth to 8 bits. */
665 png_set_expand_gray_1_2_4_to_8(png_structp png_ptr
)
667 png_debug(1, "in png_set_expand_gray_1_2_4_to_8");
672 png_ptr
->transformations
|= PNG_EXPAND
;
673 png_ptr
->flags
&= ~PNG_FLAG_ROW_INIT
;
678 /* Expand tRNS chunks to alpha channels. */
680 png_set_tRNS_to_alpha(png_structp png_ptr
)
682 png_debug(1, "in png_set_tRNS_to_alpha");
684 png_ptr
->transformations
|= (PNG_EXPAND
| PNG_EXPAND_tRNS
);
685 png_ptr
->flags
&= ~PNG_FLAG_ROW_INIT
;
687 #endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
689 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
691 png_set_gray_to_rgb(png_structp png_ptr
)
693 png_debug(1, "in png_set_gray_to_rgb");
697 /* Because rgb must be 8 bits or more: */
698 png_set_expand_gray_1_2_4_to_8(png_ptr
);
699 png_ptr
->transformations
|= PNG_GRAY_TO_RGB
;
700 png_ptr
->flags
&= ~PNG_FLAG_ROW_INIT
;
705 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
707 png_set_rgb_to_gray_fixed(png_structp png_ptr
, int error_action
,
708 png_fixed_point red
, png_fixed_point green
)
710 png_debug(1, "in png_set_rgb_to_gray");
718 png_ptr
->transformations
|= PNG_RGB_TO_GRAY
;
722 png_ptr
->transformations
|= PNG_RGB_TO_GRAY_WARN
;
726 png_ptr
->transformations
|= PNG_RGB_TO_GRAY_ERR
;
730 png_error(png_ptr
, "invalid error action to rgb_to_gray");
733 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
734 #ifdef PNG_READ_EXPAND_SUPPORTED
735 png_ptr
->transformations
|= PNG_EXPAND
;
739 "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");
741 png_ptr
->transformations
&= ~PNG_RGB_TO_GRAY
;
745 png_uint_16 red_int
, green_int
;
746 if (red
< 0 || green
< 0)
748 red_int
= 6968; /* .212671 * 32768 + .5 */
749 green_int
= 23434; /* .715160 * 32768 + .5 */
752 else if (red
+ green
< 100000L)
754 red_int
= (png_uint_16
)(((png_uint_32
)red
*32768L)/100000L);
755 green_int
= (png_uint_16
)(((png_uint_32
)green
*32768L)/100000L);
760 png_warning(png_ptr
, "ignoring out of range rgb_to_gray coefficients");
765 png_ptr
->rgb_to_gray_red_coeff
= red_int
;
766 png_ptr
->rgb_to_gray_green_coeff
= green_int
;
767 png_ptr
->rgb_to_gray_blue_coeff
=
768 (png_uint_16
)(32768 - red_int
- green_int
);
772 #ifdef PNG_FLOATING_POINT_SUPPORTED
773 /* Convert a RGB image to a grayscale of the same width. This allows us,
774 * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
778 png_set_rgb_to_gray(png_structp png_ptr
, int error_action
, double red
,
784 png_set_rgb_to_gray_fixed(png_ptr
, error_action
,
785 png_fixed(png_ptr
, red
, "rgb to gray red coefficient"),
786 png_fixed(png_ptr
, green
, "rgb to gray green coefficient"));
788 #endif /* FLOATING POINT */
792 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
793 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
795 png_set_read_user_transform_fn(png_structp png_ptr
, png_user_transform_ptr
796 read_user_transform_fn
)
798 png_debug(1, "in png_set_read_user_transform_fn");
803 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
804 png_ptr
->transformations
|= PNG_USER_TRANSFORM
;
805 png_ptr
->read_user_transform_fn
= read_user_transform_fn
;
810 /* Initialize everything needed for the read. This includes modifying
814 png_init_read_transformations(png_structp png_ptr
)
816 png_debug(1, "in png_init_read_transformations");
819 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
820 defined(PNG_READ_SHIFT_SUPPORTED) || \
821 defined(PNG_READ_GAMMA_SUPPORTED)
822 int color_type
= png_ptr
->color_type
;
825 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
827 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
828 /* Detect gray background and attempt to enable optimization
829 * for gray --> RGB case
831 * Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
832 * RGB_ALPHA (in which case need_expand is superfluous anyway), the
833 * background color might actually be gray yet not be flagged as such.
834 * This is not a problem for the current code, which uses
835 * PNG_BACKGROUND_IS_GRAY only to decide when to do the
836 * png_do_gray_to_rgb() transformation.
838 if ((png_ptr
->transformations
& PNG_BACKGROUND_EXPAND
) &&
839 !(color_type
& PNG_COLOR_MASK_COLOR
))
841 png_ptr
->mode
|= PNG_BACKGROUND_IS_GRAY
;
844 else if ((png_ptr
->transformations
& PNG_BACKGROUND
) &&
845 !(png_ptr
->transformations
& PNG_BACKGROUND_EXPAND
) &&
846 (png_ptr
->transformations
& PNG_GRAY_TO_RGB
) &&
847 png_ptr
->background
.red
== png_ptr
->background
.green
&&
848 png_ptr
->background
.red
== png_ptr
->background
.blue
)
850 png_ptr
->mode
|= PNG_BACKGROUND_IS_GRAY
;
851 png_ptr
->background
.gray
= png_ptr
->background
.red
;
855 if ((png_ptr
->transformations
& PNG_BACKGROUND_EXPAND
) &&
856 (png_ptr
->transformations
& PNG_EXPAND
))
858 if (!(color_type
& PNG_COLOR_MASK_COLOR
)) /* i.e., GRAY or GRAY_ALPHA */
860 /* Expand background and tRNS chunks */
861 switch (png_ptr
->bit_depth
)
864 png_ptr
->background
.gray
*= (png_uint_16
)0xff;
865 png_ptr
->background
.red
= png_ptr
->background
.green
866 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
867 if (!(png_ptr
->transformations
& PNG_EXPAND_tRNS
))
869 png_ptr
->trans_color
.gray
*= (png_uint_16
)0xff;
870 png_ptr
->trans_color
.red
= png_ptr
->trans_color
.green
871 = png_ptr
->trans_color
.blue
= png_ptr
->trans_color
.gray
;
876 png_ptr
->background
.gray
*= (png_uint_16
)0x55;
877 png_ptr
->background
.red
= png_ptr
->background
.green
878 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
879 if (!(png_ptr
->transformations
& PNG_EXPAND_tRNS
))
881 png_ptr
->trans_color
.gray
*= (png_uint_16
)0x55;
882 png_ptr
->trans_color
.red
= png_ptr
->trans_color
.green
883 = png_ptr
->trans_color
.blue
= png_ptr
->trans_color
.gray
;
888 png_ptr
->background
.gray
*= (png_uint_16
)0x11;
889 png_ptr
->background
.red
= png_ptr
->background
.green
890 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
891 if (!(png_ptr
->transformations
& PNG_EXPAND_tRNS
))
893 png_ptr
->trans_color
.gray
*= (png_uint_16
)0x11;
894 png_ptr
->trans_color
.red
= png_ptr
->trans_color
.green
895 = png_ptr
->trans_color
.blue
= png_ptr
->trans_color
.gray
;
904 png_ptr
->background
.red
= png_ptr
->background
.green
905 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
909 else if (color_type
== PNG_COLOR_TYPE_PALETTE
)
911 png_ptr
->background
.red
=
912 png_ptr
->palette
[png_ptr
->background
.index
].red
;
913 png_ptr
->background
.green
=
914 png_ptr
->palette
[png_ptr
->background
.index
].green
;
915 png_ptr
->background
.blue
=
916 png_ptr
->palette
[png_ptr
->background
.index
].blue
;
918 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
919 if (png_ptr
->transformations
& PNG_INVERT_ALPHA
)
921 #ifdef PNG_READ_EXPAND_SUPPORTED
922 if (!(png_ptr
->transformations
& PNG_EXPAND_tRNS
))
925 /* Invert the alpha channel (in tRNS) unless the pixels are
926 * going to be expanded, in which case leave it for later
929 istop
=(int)png_ptr
->num_trans
;
930 for (i
=0; i
<istop
; i
++)
931 png_ptr
->trans_alpha
[i
] = (png_byte
)(255 -
932 png_ptr
->trans_alpha
[i
]);
941 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
942 png_ptr
->background_1
= png_ptr
->background
;
944 #ifdef PNG_READ_GAMMA_SUPPORTED
946 if ((color_type
== PNG_COLOR_TYPE_PALETTE
&& png_ptr
->num_trans
!= 0)
947 && png_gamma_threshold(png_ptr
->screen_gamma
, png_ptr
->gamma
))
951 for (i
=0; i
<png_ptr
->num_trans
; i
++)
953 if (png_ptr
->trans_alpha
[i
] != 0 && png_ptr
->trans_alpha
[i
] != 0xff)
954 k
=1; /* Partial transparency is present */
957 png_ptr
->transformations
&= ~PNG_GAMMA
;
960 if ((png_ptr
->transformations
& (PNG_GAMMA
| PNG_RGB_TO_GRAY
)) &&
963 png_build_gamma_table(png_ptr
, png_ptr
->bit_depth
);
965 #ifdef PNG_READ_BACKGROUND_SUPPORTED
966 if (png_ptr
->transformations
& PNG_BACKGROUND
)
968 if (color_type
== PNG_COLOR_TYPE_PALETTE
)
970 /* Could skip if no transparency */
971 png_color back
, back_1
;
972 png_colorp palette
= png_ptr
->palette
;
973 int num_palette
= png_ptr
->num_palette
;
975 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_FILE
)
978 back
.red
= png_ptr
->gamma_table
[png_ptr
->background
.red
];
979 back
.green
= png_ptr
->gamma_table
[png_ptr
->background
.green
];
980 back
.blue
= png_ptr
->gamma_table
[png_ptr
->background
.blue
];
982 back_1
.red
= png_ptr
->gamma_to_1
[png_ptr
->background
.red
];
983 back_1
.green
= png_ptr
->gamma_to_1
[png_ptr
->background
.green
];
984 back_1
.blue
= png_ptr
->gamma_to_1
[png_ptr
->background
.blue
];
988 png_fixed_point g
, gs
;
990 switch (png_ptr
->background_gamma_type
)
992 case PNG_BACKGROUND_GAMMA_SCREEN
:
993 g
= (png_ptr
->screen_gamma
);
997 case PNG_BACKGROUND_GAMMA_FILE
:
998 g
= png_reciprocal(png_ptr
->gamma
);
999 gs
= png_reciprocal2(png_ptr
->gamma
,
1000 png_ptr
->screen_gamma
);
1003 case PNG_BACKGROUND_GAMMA_UNIQUE
:
1004 g
= png_reciprocal(png_ptr
->background_gamma
);
1005 gs
= png_reciprocal2(png_ptr
->background_gamma
,
1006 png_ptr
->screen_gamma
);
1009 g
= PNG_FP_1
; /* back_1 */
1010 gs
= PNG_FP_1
; /* back */
1014 if (png_gamma_significant(gs
))
1016 back
.red
= (png_byte
)png_ptr
->background
.red
;
1017 back
.green
= (png_byte
)png_ptr
->background
.green
;
1018 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
1023 back
.red
= png_gamma_8bit_correct(png_ptr
->background
.red
,
1025 back
.green
= png_gamma_8bit_correct(png_ptr
->background
.green
,
1027 back
.blue
= png_gamma_8bit_correct(png_ptr
->background
.blue
,
1030 back_1
.red
= png_gamma_8bit_correct(png_ptr
->background
.red
, g
);
1031 back_1
.green
= png_gamma_8bit_correct(png_ptr
->background
.green
,
1033 back_1
.blue
= png_gamma_8bit_correct(png_ptr
->background
.blue
,
1036 for (i
= 0; i
< num_palette
; i
++)
1038 if (i
< (int)png_ptr
->num_trans
&&
1039 png_ptr
->trans_alpha
[i
] != 0xff)
1041 if (png_ptr
->trans_alpha
[i
] == 0)
1045 else /* if (png_ptr->trans_alpha[i] != 0xff) */
1049 v
= png_ptr
->gamma_to_1
[palette
[i
].red
];
1050 png_composite(w
, v
, png_ptr
->trans_alpha
[i
], back_1
.red
);
1051 palette
[i
].red
= png_ptr
->gamma_from_1
[w
];
1053 v
= png_ptr
->gamma_to_1
[palette
[i
].green
];
1054 png_composite(w
, v
, png_ptr
->trans_alpha
[i
], back_1
.green
);
1055 palette
[i
].green
= png_ptr
->gamma_from_1
[w
];
1057 v
= png_ptr
->gamma_to_1
[palette
[i
].blue
];
1058 png_composite(w
, v
, png_ptr
->trans_alpha
[i
], back_1
.blue
);
1059 palette
[i
].blue
= png_ptr
->gamma_from_1
[w
];
1064 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
1065 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
1066 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
1069 /* Prevent the transformations being done again, and make sure
1070 * that the now spurious alpha channel is stripped - the code
1071 * has just reduced background composition and gamma correction
1072 * to a simple alpha channel strip.
1074 png_ptr
->transformations
&= ~PNG_BACKGROUND
;
1075 png_ptr
->transformations
&= ~PNG_GAMMA
;
1076 png_ptr
->flags
|= PNG_FLAG_STRIP_ALPHA
;
1079 /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
1081 /* color_type != PNG_COLOR_TYPE_PALETTE */
1083 png_fixed_point g
= PNG_FP_1
;
1084 png_fixed_point gs
= PNG_FP_1
;
1086 switch (png_ptr
->background_gamma_type
)
1088 case PNG_BACKGROUND_GAMMA_SCREEN
:
1089 g
= png_ptr
->screen_gamma
;
1090 /* gs = PNG_FP_1; */
1093 case PNG_BACKGROUND_GAMMA_FILE
:
1094 g
= png_reciprocal(png_ptr
->gamma
);
1095 gs
= png_reciprocal2(png_ptr
->gamma
, png_ptr
->screen_gamma
);
1098 case PNG_BACKGROUND_GAMMA_UNIQUE
:
1099 g
= png_reciprocal(png_ptr
->background_gamma
);
1100 gs
= png_reciprocal2(png_ptr
->background_gamma
,
1101 png_ptr
->screen_gamma
);
1105 png_error(png_ptr
, "invalid background gamma type");
1108 png_ptr
->background_1
.gray
= png_gamma_correct(png_ptr
,
1109 png_ptr
->background
.gray
, g
);
1111 png_ptr
->background
.gray
= png_gamma_correct(png_ptr
,
1112 png_ptr
->background
.gray
, gs
);
1114 if ((png_ptr
->background
.red
!= png_ptr
->background
.green
) ||
1115 (png_ptr
->background
.red
!= png_ptr
->background
.blue
) ||
1116 (png_ptr
->background
.red
!= png_ptr
->background
.gray
))
1118 /* RGB or RGBA with color background */
1119 png_ptr
->background_1
.red
= png_gamma_correct(png_ptr
,
1120 png_ptr
->background
.red
, g
);
1122 png_ptr
->background_1
.green
= png_gamma_correct(png_ptr
,
1123 png_ptr
->background
.green
, g
);
1125 png_ptr
->background_1
.blue
= png_gamma_correct(png_ptr
,
1126 png_ptr
->background
.blue
, g
);
1128 png_ptr
->background
.red
= png_gamma_correct(png_ptr
,
1129 png_ptr
->background
.red
, gs
);
1131 png_ptr
->background
.green
= png_gamma_correct(png_ptr
,
1132 png_ptr
->background
.green
, gs
);
1134 png_ptr
->background
.blue
= png_gamma_correct(png_ptr
,
1135 png_ptr
->background
.blue
, gs
);
1140 /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
1141 png_ptr
->background_1
.red
= png_ptr
->background_1
.green
1142 = png_ptr
->background_1
.blue
= png_ptr
->background_1
.gray
;
1144 png_ptr
->background
.red
= png_ptr
->background
.green
1145 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
1150 /* Transformation does not include PNG_BACKGROUND */
1151 #endif /* PNG_READ_BACKGROUND_SUPPORTED */
1152 if (color_type
== PNG_COLOR_TYPE_PALETTE
)
1154 png_colorp palette
= png_ptr
->palette
;
1155 int num_palette
= png_ptr
->num_palette
;
1158 for (i
= 0; i
< num_palette
; i
++)
1160 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
1161 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
1162 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
1165 /* Done the gamma correction. */
1166 png_ptr
->transformations
&= ~PNG_GAMMA
;
1169 #ifdef PNG_READ_BACKGROUND_SUPPORTED
1172 #endif /* PNG_READ_GAMMA_SUPPORTED */
1173 #ifdef PNG_READ_BACKGROUND_SUPPORTED
1174 /* No GAMMA transformation */
1175 if ((png_ptr
->transformations
& PNG_BACKGROUND
) &&
1176 (color_type
== PNG_COLOR_TYPE_PALETTE
))
1179 int istop
= (int)png_ptr
->num_trans
;
1181 png_colorp palette
= png_ptr
->palette
;
1183 back
.red
= (png_byte
)png_ptr
->background
.red
;
1184 back
.green
= (png_byte
)png_ptr
->background
.green
;
1185 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
1187 for (i
= 0; i
< istop
; i
++)
1189 if (png_ptr
->trans_alpha
[i
] == 0)
1194 else if (png_ptr
->trans_alpha
[i
] != 0xff)
1196 /* The png_composite() macro is defined in png.h */
1197 png_composite(palette
[i
].red
, palette
[i
].red
,
1198 png_ptr
->trans_alpha
[i
], back
.red
);
1200 png_composite(palette
[i
].green
, palette
[i
].green
,
1201 png_ptr
->trans_alpha
[i
], back
.green
);
1203 png_composite(palette
[i
].blue
, palette
[i
].blue
,
1204 png_ptr
->trans_alpha
[i
], back
.blue
);
1208 /* Handled alpha, still need to strip the channel. */
1209 png_ptr
->transformations
&= ~PNG_BACKGROUND
;
1210 png_ptr
->flags
|= PNG_FLAG_STRIP_ALPHA
;
1212 #endif /* PNG_READ_BACKGROUND_SUPPORTED */
1214 #ifdef PNG_READ_SHIFT_SUPPORTED
1215 if ((png_ptr
->transformations
& PNG_SHIFT
) &&
1216 (color_type
== PNG_COLOR_TYPE_PALETTE
))
1219 png_uint_16 istop
= png_ptr
->num_palette
;
1220 int sr
= 8 - png_ptr
->sig_bit
.red
;
1221 int sg
= 8 - png_ptr
->sig_bit
.green
;
1222 int sb
= 8 - png_ptr
->sig_bit
.blue
;
1224 if (sr
< 0 || sr
> 8)
1227 if (sg
< 0 || sg
> 8)
1230 if (sb
< 0 || sb
> 8)
1233 for (i
= 0; i
< istop
; i
++)
1235 png_ptr
->palette
[i
].red
>>= sr
;
1236 png_ptr
->palette
[i
].green
>>= sg
;
1237 png_ptr
->palette
[i
].blue
>>= sb
;
1240 #endif /* PNG_READ_SHIFT_SUPPORTED */
1242 #if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
1243 && !defined(PNG_READ_BACKGROUND_SUPPORTED)
1249 /* Modify the info structure to reflect the transformations. The
1250 * info should be updated so a PNG file could be written with it,
1251 * assuming the transformations result in valid PNG data.
1254 png_read_transform_info(png_structp png_ptr
, png_infop info_ptr
)
1256 png_debug(1, "in png_read_transform_info");
1258 #ifdef PNG_READ_EXPAND_SUPPORTED
1259 if (png_ptr
->transformations
& PNG_EXPAND
)
1261 if (info_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1263 if (png_ptr
->num_trans
&&
1264 (png_ptr
->transformations
& PNG_EXPAND_tRNS
))
1265 info_ptr
->color_type
= PNG_COLOR_TYPE_RGB_ALPHA
;
1268 info_ptr
->color_type
= PNG_COLOR_TYPE_RGB
;
1270 info_ptr
->bit_depth
= 8;
1271 info_ptr
->num_trans
= 0;
1275 if (png_ptr
->num_trans
)
1277 if (png_ptr
->transformations
& PNG_EXPAND_tRNS
)
1278 info_ptr
->color_type
|= PNG_COLOR_MASK_ALPHA
;
1280 if (info_ptr
->bit_depth
< 8)
1281 info_ptr
->bit_depth
= 8;
1283 info_ptr
->num_trans
= 0;
1288 #ifdef PNG_READ_BACKGROUND_SUPPORTED
1289 if (png_ptr
->transformations
& PNG_BACKGROUND
)
1291 info_ptr
->color_type
= (png_byte
)(info_ptr
->color_type
&
1292 ~PNG_COLOR_MASK_ALPHA
);
1293 info_ptr
->num_trans
= 0;
1294 info_ptr
->background
= png_ptr
->background
;
1298 #ifdef PNG_READ_GAMMA_SUPPORTED
1299 if (png_ptr
->transformations
& PNG_GAMMA
)
1301 info_ptr
->gamma
= png_ptr
->gamma
;
1305 #ifdef PNG_READ_16_TO_8_SUPPORTED
1306 #ifdef PNG_READ_16BIT_SUPPORTED
1307 if ((png_ptr
->transformations
& PNG_16_TO_8
) && (info_ptr
->bit_depth
== 16))
1308 info_ptr
->bit_depth
= 8;
1310 /* Force chopping 16-bit input down to 8 */
1311 if (info_ptr
->bit_depth
== 16)
1313 png_ptr
->transformations
|=PNG_16_TO_8
;
1314 info_ptr
->bit_depth
= 8;
1319 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
1320 if (png_ptr
->transformations
& PNG_GRAY_TO_RGB
)
1321 info_ptr
->color_type
|= PNG_COLOR_MASK_COLOR
;
1324 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1325 if (png_ptr
->transformations
& PNG_RGB_TO_GRAY
)
1326 info_ptr
->color_type
&= ~PNG_COLOR_MASK_COLOR
;
1329 #ifdef PNG_READ_QUANTIZE_SUPPORTED
1330 if (png_ptr
->transformations
& PNG_QUANTIZE
)
1332 if (((info_ptr
->color_type
== PNG_COLOR_TYPE_RGB
) ||
1333 (info_ptr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)) &&
1334 png_ptr
->palette_lookup
&& info_ptr
->bit_depth
== 8)
1336 info_ptr
->color_type
= PNG_COLOR_TYPE_PALETTE
;
1341 #ifdef PNG_READ_PACK_SUPPORTED
1342 if ((png_ptr
->transformations
& PNG_PACK
) && (info_ptr
->bit_depth
< 8))
1343 info_ptr
->bit_depth
= 8;
1346 if (info_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1347 info_ptr
->channels
= 1;
1349 else if (info_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
1350 info_ptr
->channels
= 3;
1353 info_ptr
->channels
= 1;
1355 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
1356 if (png_ptr
->flags
& PNG_FLAG_STRIP_ALPHA
)
1357 info_ptr
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
1360 if (info_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
)
1361 info_ptr
->channels
++;
1363 #ifdef PNG_READ_FILLER_SUPPORTED
1364 /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
1365 if ((png_ptr
->transformations
& PNG_FILLER
) &&
1366 ((info_ptr
->color_type
== PNG_COLOR_TYPE_RGB
) ||
1367 (info_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)))
1369 info_ptr
->channels
++;
1370 /* If adding a true alpha channel not just filler */
1371 if (png_ptr
->transformations
& PNG_ADD_ALPHA
)
1372 info_ptr
->color_type
|= PNG_COLOR_MASK_ALPHA
;
1376 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
1377 defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1378 if (png_ptr
->transformations
& PNG_USER_TRANSFORM
)
1380 if (info_ptr
->bit_depth
< png_ptr
->user_transform_depth
)
1381 info_ptr
->bit_depth
= png_ptr
->user_transform_depth
;
1383 if (info_ptr
->channels
< png_ptr
->user_transform_channels
)
1384 info_ptr
->channels
= png_ptr
->user_transform_channels
;
1388 info_ptr
->pixel_depth
= (png_byte
)(info_ptr
->channels
*
1389 info_ptr
->bit_depth
);
1391 info_ptr
->rowbytes
= PNG_ROWBYTES(info_ptr
->pixel_depth
, info_ptr
->width
);
1393 #ifndef PNG_READ_EXPAND_SUPPORTED
1399 /* Transform the row. The order of transformations is significant,
1400 * and is very touchy. If you add a transformation, take care to
1401 * decide how it fits in with the other transformations here.
1404 png_do_read_transformations(png_structp png_ptr
)
1406 png_debug(1, "in png_do_read_transformations");
1408 if (png_ptr
->row_buf
== NULL
)
1410 #ifdef PNG_CONSOLE_IO_SUPPORTED
1413 png_snprintf2(msg
, 50,
1414 "NULL row buffer for row %ld, pass %d", (long)png_ptr
->row_number
,
1416 png_error(png_ptr
, msg
);
1418 png_error(png_ptr
, "NULL row buffer");
1421 #ifdef PNG_WARN_UNINITIALIZED_ROW
1422 if (!(png_ptr
->flags
& PNG_FLAG_ROW_INIT
))
1423 /* Application has failed to call either png_read_start_image()
1424 * or png_read_update_info() after setting transforms that expand
1425 * pixels. This check added to libpng-1.2.19
1427 #if (PNG_WARN_UNINITIALIZED_ROW==1)
1428 png_error(png_ptr
, "Uninitialized row");
1430 png_warning(png_ptr
, "Uninitialized row");
1434 #ifdef PNG_READ_EXPAND_SUPPORTED
1435 if (png_ptr
->transformations
& PNG_EXPAND
)
1437 if (png_ptr
->row_info
.color_type
== PNG_COLOR_TYPE_PALETTE
)
1439 png_do_expand_palette(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1440 png_ptr
->palette
, png_ptr
->trans_alpha
, png_ptr
->num_trans
);
1444 if (png_ptr
->num_trans
&&
1445 (png_ptr
->transformations
& PNG_EXPAND_tRNS
))
1446 png_do_expand(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1447 &(png_ptr
->trans_color
));
1450 png_do_expand(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1456 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
1457 if (png_ptr
->flags
& PNG_FLAG_STRIP_ALPHA
)
1458 png_do_strip_filler(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1459 PNG_FLAG_FILLER_AFTER
| (png_ptr
->flags
& PNG_FLAG_STRIP_ALPHA
));
1462 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1463 if (png_ptr
->transformations
& PNG_RGB_TO_GRAY
)
1466 png_do_rgb_to_gray(png_ptr
, &(png_ptr
->row_info
),
1467 png_ptr
->row_buf
+ 1);
1471 png_ptr
->rgb_to_gray_status
=1;
1472 if ((png_ptr
->transformations
& PNG_RGB_TO_GRAY
) ==
1473 PNG_RGB_TO_GRAY_WARN
)
1474 png_warning(png_ptr
, "png_do_rgb_to_gray found nongray pixel");
1476 if ((png_ptr
->transformations
& PNG_RGB_TO_GRAY
) ==
1477 PNG_RGB_TO_GRAY_ERR
)
1478 png_error(png_ptr
, "png_do_rgb_to_gray found nongray pixel");
1483 /* From Andreas Dilger e-mail to png-implement, 26 March 1998:
1485 * In most cases, the "simple transparency" should be done prior to doing
1486 * gray-to-RGB, or you will have to test 3x as many bytes to check if a
1487 * pixel is transparent. You would also need to make sure that the
1488 * transparency information is upgraded to RGB.
1490 * To summarize, the current flow is:
1491 * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
1492 * with background "in place" if transparent,
1493 * convert to RGB if necessary
1494 * - Gray + alpha -> composite with gray background and remove alpha bytes,
1495 * convert to RGB if necessary
1497 * To support RGB backgrounds for gray images we need:
1498 * - Gray + simple transparency -> convert to RGB + simple transparency,
1499 * compare 3 or 6 bytes and composite with
1500 * background "in place" if transparent
1501 * (3x compare/pixel compared to doing
1502 * composite with gray bkgrnd)
1503 * - Gray + alpha -> convert to RGB + alpha, composite with background and
1504 * remove alpha bytes (3x float
1505 * operations/pixel compared with composite
1506 * on gray background)
1508 * Greg's change will do this. The reason it wasn't done before is for
1509 * performance, as this increases the per-pixel operations. If we would check
1510 * in advance if the background was gray or RGB, and position the gray-to-RGB
1511 * transform appropriately, then it would save a lot of work/time.
1514 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
1515 /* If gray -> RGB, do so now only if background is non-gray; else do later
1516 * for performance reasons
1518 if ((png_ptr
->transformations
& PNG_GRAY_TO_RGB
) &&
1519 !(png_ptr
->mode
& PNG_BACKGROUND_IS_GRAY
))
1520 png_do_gray_to_rgb(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1523 #ifdef PNG_READ_BACKGROUND_SUPPORTED
1524 if ((png_ptr
->transformations
& PNG_BACKGROUND
) &&
1525 ((png_ptr
->num_trans
!= 0) ||
1526 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
)))
1527 png_do_background(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1528 &(png_ptr
->trans_color
), &(png_ptr
->background
)
1529 #ifdef PNG_READ_GAMMA_SUPPORTED
1530 , &(png_ptr
->background_1
),
1531 png_ptr
->gamma_table
, png_ptr
->gamma_from_1
,
1532 png_ptr
->gamma_to_1
, png_ptr
->gamma_16_table
,
1533 png_ptr
->gamma_16_from_1
, png_ptr
->gamma_16_to_1
,
1534 png_ptr
->gamma_shift
1539 #ifdef PNG_READ_GAMMA_SUPPORTED
1540 if ((png_ptr
->transformations
& PNG_GAMMA
) &&
1541 #ifdef PNG_READ_BACKGROUND_SUPPORTED
1542 !((png_ptr
->transformations
& PNG_BACKGROUND
) &&
1543 ((png_ptr
->num_trans
!= 0) ||
1544 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
))) &&
1546 (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
))
1547 png_do_gamma(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1548 png_ptr
->gamma_table
, png_ptr
->gamma_16_table
,
1549 png_ptr
->gamma_shift
);
1552 #ifdef PNG_READ_16_TO_8_SUPPORTED
1553 if (png_ptr
->transformations
& PNG_16_TO_8
)
1554 png_do_chop(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1557 #ifdef PNG_READ_QUANTIZE_SUPPORTED
1558 if (png_ptr
->transformations
& PNG_QUANTIZE
)
1560 png_do_quantize(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1561 png_ptr
->palette_lookup
, png_ptr
->quantize_index
);
1563 if (png_ptr
->row_info
.rowbytes
== 0)
1564 png_error(png_ptr
, "png_do_quantize returned rowbytes=0");
1566 #endif /* PNG_READ_QUANTIZE_SUPPORTED */
1568 #ifdef PNG_READ_INVERT_SUPPORTED
1569 if (png_ptr
->transformations
& PNG_INVERT_MONO
)
1570 png_do_invert(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1573 #ifdef PNG_READ_SHIFT_SUPPORTED
1574 if (png_ptr
->transformations
& PNG_SHIFT
)
1575 png_do_unshift(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1579 #ifdef PNG_READ_PACK_SUPPORTED
1580 if (png_ptr
->transformations
& PNG_PACK
)
1581 png_do_unpack(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1584 #ifdef PNG_READ_BGR_SUPPORTED
1585 if (png_ptr
->transformations
& PNG_BGR
)
1586 png_do_bgr(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1589 #ifdef PNG_READ_PACKSWAP_SUPPORTED
1590 if (png_ptr
->transformations
& PNG_PACKSWAP
)
1591 png_do_packswap(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1594 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
1595 /* If gray -> RGB, do so now only if we did not do so above */
1596 if ((png_ptr
->transformations
& PNG_GRAY_TO_RGB
) &&
1597 (png_ptr
->mode
& PNG_BACKGROUND_IS_GRAY
))
1598 png_do_gray_to_rgb(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1601 #ifdef PNG_READ_FILLER_SUPPORTED
1602 if (png_ptr
->transformations
& PNG_FILLER
)
1603 png_do_read_filler(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1604 (png_uint_32
)png_ptr
->filler
, png_ptr
->flags
);
1607 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
1608 if (png_ptr
->transformations
& PNG_INVERT_ALPHA
)
1609 png_do_read_invert_alpha(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1612 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
1613 if (png_ptr
->transformations
& PNG_SWAP_ALPHA
)
1614 png_do_read_swap_alpha(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1617 #ifdef PNG_READ_16BIT_SUPPORTED
1618 #ifdef PNG_READ_SWAP_SUPPORTED
1619 if (png_ptr
->transformations
& PNG_SWAP_BYTES
)
1620 png_do_swap(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1624 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
1625 if (png_ptr
->transformations
& PNG_USER_TRANSFORM
)
1627 if (png_ptr
->read_user_transform_fn
!= NULL
)
1628 (*(png_ptr
->read_user_transform_fn
)) /* User read transform function */
1629 (png_ptr
, /* png_ptr */
1630 &(png_ptr
->row_info
), /* row_info: */
1631 /* png_uint_32 width; width of row */
1632 /* png_size_t rowbytes; number of bytes in row */
1633 /* png_byte color_type; color type of pixels */
1634 /* png_byte bit_depth; bit depth of samples */
1635 /* png_byte channels; number of channels (1-4) */
1636 /* png_byte pixel_depth; bits per pixel (depth*channels) */
1637 png_ptr
->row_buf
+ 1); /* start of pixel data for row */
1638 #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
1639 if (png_ptr
->user_transform_depth
)
1640 png_ptr
->row_info
.bit_depth
= png_ptr
->user_transform_depth
;
1642 if (png_ptr
->user_transform_channels
)
1643 png_ptr
->row_info
.channels
= png_ptr
->user_transform_channels
;
1645 png_ptr
->row_info
.pixel_depth
= (png_byte
)(png_ptr
->row_info
.bit_depth
*
1646 png_ptr
->row_info
.channels
);
1648 png_ptr
->row_info
.rowbytes
= PNG_ROWBYTES(png_ptr
->row_info
.pixel_depth
,
1649 png_ptr
->row_info
.width
);
1655 #ifdef PNG_READ_PACK_SUPPORTED
1656 /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
1657 * without changing the actual values. Thus, if you had a row with
1658 * a bit depth of 1, you would end up with bytes that only contained
1659 * the numbers 0 or 1. If you would rather they contain 0 and 255, use
1660 * png_do_shift() after this.
1663 png_do_unpack(png_row_infop row_info
, png_bytep row
)
1665 png_debug(1, "in png_do_unpack");
1667 if (row_info
->bit_depth
< 8)
1670 png_uint_32 row_width
=row_info
->width
;
1672 switch (row_info
->bit_depth
)
1676 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
1677 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1678 png_uint_32 shift
= 7 - (int)((row_width
+ 7) & 0x07);
1679 for (i
= 0; i
< row_width
; i
++)
1681 *dp
= (png_byte
)((*sp
>> shift
) & 0x01);
1700 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
1701 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1702 png_uint_32 shift
= (int)((3 - ((row_width
+ 3) & 0x03)) << 1);
1703 for (i
= 0; i
< row_width
; i
++)
1705 *dp
= (png_byte
)((*sp
>> shift
) & 0x03);
1723 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
1724 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1725 png_uint_32 shift
= (int)((1 - ((row_width
+ 1) & 0x01)) << 2);
1726 for (i
= 0; i
< row_width
; i
++)
1728 *dp
= (png_byte
)((*sp
>> shift
) & 0x0f);
1747 row_info
->bit_depth
= 8;
1748 row_info
->pixel_depth
= (png_byte
)(8 * row_info
->channels
);
1749 row_info
->rowbytes
= row_width
* row_info
->channels
;
1754 #ifdef PNG_READ_SHIFT_SUPPORTED
1755 /* Reverse the effects of png_do_shift. This routine merely shifts the
1756 * pixels back to their significant bits values. Thus, if you have
1757 * a row of bit depth 8, but only 5 are significant, this will shift
1758 * the values back to 0 through 31.
1761 png_do_unshift(png_row_infop row_info
, png_bytep row
,
1762 png_const_color_8p sig_bits
)
1764 png_debug(1, "in png_do_unshift");
1767 row_info
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
1772 png_uint_16 value
= 0;
1773 png_uint_32 row_width
= row_info
->width
;
1775 if (row_info
->color_type
& PNG_COLOR_MASK_COLOR
)
1777 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->red
;
1778 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->green
;
1779 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->blue
;
1784 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->gray
;
1787 if (row_info
->color_type
& PNG_COLOR_MASK_ALPHA
)
1789 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->alpha
;
1792 for (c
= 0; c
< channels
; c
++)
1804 switch (row_info
->bit_depth
)
1813 png_size_t istop
= row_info
->rowbytes
;
1815 for (bp
= row
, i
= 0; i
< istop
; i
++)
1827 png_size_t istop
= row_info
->rowbytes
;
1828 png_byte mask
= (png_byte
)((((int)0xf0 >> shift
[0]) & (int)0xf0) |
1829 (png_byte
)((int)0xf >> shift
[0]));
1831 for (i
= 0; i
< istop
; i
++)
1843 png_uint_32 istop
= row_width
* channels
;
1845 for (i
= 0; i
< istop
; i
++)
1847 *bp
++ >>= shift
[i
%channels
];
1852 #ifdef PNG_READ_16BIT_SUPPORTED
1857 png_uint_32 istop
= channels
* row_width
;
1859 for (i
= 0; i
< istop
; i
++)
1861 value
= (png_uint_16
)((*bp
<< 8) + *(bp
+ 1));
1862 value
>>= shift
[i
%channels
];
1863 *bp
++ = (png_byte
)(value
>> 8);
1864 *bp
++ = (png_byte
)(value
& 0xff);
1874 #ifdef PNG_READ_16_TO_8_SUPPORTED
1875 /* Chop rows of bit depth 16 down to 8 */
1877 png_do_chop(png_row_infop row_info
, png_bytep row
)
1879 png_debug(1, "in png_do_chop");
1881 if (row_info
->bit_depth
== 16)
1886 png_uint_32 istop
= row_info
->width
* row_info
->channels
;
1888 for (i
= 0; i
<istop
; i
++, sp
+= 2, dp
++)
1890 #ifdef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
1891 /* This does a more accurate scaling of the 16-bit color
1892 * value, rather than a simple low-byte truncation.
1894 * What the ideal calculation should be:
1895 * *dp = (((((png_uint_32)(*sp) << 8) |
1896 * (png_uint_32)(*(sp + 1))) * 255 + 127)
1897 * / (png_uint_32)65535L;
1899 * GRR: no, I think this is what it really should be:
1900 * *dp = (((((png_uint_32)(*sp) << 8) |
1901 * (png_uint_32)(*(sp + 1))) + 128L)
1902 * / (png_uint_32)257L;
1904 * GRR: here's the exact calculation with shifts:
1905 * temp = (((png_uint_32)(*sp) << 8) |
1906 * (png_uint_32)(*(sp + 1))) + 128L;
1907 * *dp = (temp - (temp >> 8)) >> 8;
1909 * Approximate calculation with shift/add instead of multiply/divide:
1910 * *dp = ((((png_uint_32)(*sp) << 8) |
1911 * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
1913 * What we actually do to avoid extra shifting and conversion:
1916 *dp
= *sp
+ ((((int)(*(sp
+ 1)) - *sp
) > 128) ? 1 : 0);
1918 /* Simply discard the low order byte */
1922 row_info
->bit_depth
= 8;
1923 row_info
->pixel_depth
= (png_byte
)(8 * row_info
->channels
);
1924 row_info
->rowbytes
= row_info
->width
* row_info
->channels
;
1929 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
1931 png_do_read_swap_alpha(png_row_infop row_info
, png_bytep row
)
1933 png_debug(1, "in png_do_read_swap_alpha");
1936 png_uint_32 row_width
= row_info
->width
;
1937 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
1939 /* This converts from RGBA to ARGB */
1940 if (row_info
->bit_depth
== 8)
1942 png_bytep sp
= row
+ row_info
->rowbytes
;
1947 for (i
= 0; i
< row_width
; i
++)
1957 #ifdef PNG_READ_16BIT_SUPPORTED
1958 /* This converts from RRGGBBAA to AARRGGBB */
1961 png_bytep sp
= row
+ row_info
->rowbytes
;
1966 for (i
= 0; i
< row_width
; i
++)
1983 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
1985 /* This converts from GA to AG */
1986 if (row_info
->bit_depth
== 8)
1988 png_bytep sp
= row
+ row_info
->rowbytes
;
1993 for (i
= 0; i
< row_width
; i
++)
2001 #ifdef PNG_READ_16BIT_SUPPORTED
2002 /* This converts from GGAA to AAGG */
2005 png_bytep sp
= row
+ row_info
->rowbytes
;
2010 for (i
= 0; i
< row_width
; i
++)
2026 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
2028 png_do_read_invert_alpha(png_row_infop row_info
, png_bytep row
)
2030 png_uint_32 row_width
;
2031 png_debug(1, "in png_do_read_invert_alpha");
2033 row_width
= row_info
->width
;
2034 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
2036 if (row_info
->bit_depth
== 8)
2038 /* This inverts the alpha channel in RGBA */
2039 png_bytep sp
= row
+ row_info
->rowbytes
;
2043 for (i
= 0; i
< row_width
; i
++)
2045 *(--dp
) = (png_byte
)(255 - *(--sp
));
2047 /* This does nothing:
2051 We can replace it with:
2058 #ifdef PNG_READ_16BIT_SUPPORTED
2059 /* This inverts the alpha channel in RRGGBBAA */
2062 png_bytep sp
= row
+ row_info
->rowbytes
;
2066 for (i
= 0; i
< row_width
; i
++)
2068 *(--dp
) = (png_byte
)(255 - *(--sp
));
2069 *(--dp
) = (png_byte
)(255 - *(--sp
));
2071 /* This does nothing:
2078 We can replace it with:
2086 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
2088 if (row_info
->bit_depth
== 8)
2090 /* This inverts the alpha channel in GA */
2091 png_bytep sp
= row
+ row_info
->rowbytes
;
2095 for (i
= 0; i
< row_width
; i
++)
2097 *(--dp
) = (png_byte
)(255 - *(--sp
));
2102 #ifdef PNG_READ_16BIT_SUPPORTED
2105 /* This inverts the alpha channel in GGAA */
2106 png_bytep sp
= row
+ row_info
->rowbytes
;
2110 for (i
= 0; i
< row_width
; i
++)
2112 *(--dp
) = (png_byte
)(255 - *(--sp
));
2113 *(--dp
) = (png_byte
)(255 - *(--sp
));
2127 #ifdef PNG_READ_FILLER_SUPPORTED
2128 /* Add filler channel if we have RGB color */
2130 png_do_read_filler(png_row_infop row_info
, png_bytep row
,
2131 png_uint_32 filler
, png_uint_32 flags
)
2134 png_uint_32 row_width
= row_info
->width
;
2136 #ifdef PNG_READ_16BIT_SUPPORTED
2137 png_byte hi_filler
= (png_byte
)((filler
>>8) & 0xff);
2139 png_byte lo_filler
= (png_byte
)(filler
& 0xff);
2141 png_debug(1, "in png_do_read_filler");
2144 row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
2146 if (row_info
->bit_depth
== 8)
2148 if (flags
& PNG_FLAG_FILLER_AFTER
)
2150 /* This changes the data from G to GX */
2151 png_bytep sp
= row
+ (png_size_t
)row_width
;
2152 png_bytep dp
= sp
+ (png_size_t
)row_width
;
2153 for (i
= 1; i
< row_width
; i
++)
2155 *(--dp
) = lo_filler
;
2158 *(--dp
) = lo_filler
;
2159 row_info
->channels
= 2;
2160 row_info
->pixel_depth
= 16;
2161 row_info
->rowbytes
= row_width
* 2;
2166 /* This changes the data from G to XG */
2167 png_bytep sp
= row
+ (png_size_t
)row_width
;
2168 png_bytep dp
= sp
+ (png_size_t
)row_width
;
2169 for (i
= 0; i
< row_width
; i
++)
2172 *(--dp
) = lo_filler
;
2174 row_info
->channels
= 2;
2175 row_info
->pixel_depth
= 16;
2176 row_info
->rowbytes
= row_width
* 2;
2180 #ifdef PNG_READ_16BIT_SUPPORTED
2181 else if (row_info
->bit_depth
== 16)
2183 if (flags
& PNG_FLAG_FILLER_AFTER
)
2185 /* This changes the data from GG to GGXX */
2186 png_bytep sp
= row
+ (png_size_t
)row_width
* 2;
2187 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2188 for (i
= 1; i
< row_width
; i
++)
2190 *(--dp
) = hi_filler
;
2191 *(--dp
) = lo_filler
;
2195 *(--dp
) = hi_filler
;
2196 *(--dp
) = lo_filler
;
2197 row_info
->channels
= 2;
2198 row_info
->pixel_depth
= 32;
2199 row_info
->rowbytes
= row_width
* 4;
2204 /* This changes the data from GG to XXGG */
2205 png_bytep sp
= row
+ (png_size_t
)row_width
* 2;
2206 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2207 for (i
= 0; i
< row_width
; i
++)
2211 *(--dp
) = hi_filler
;
2212 *(--dp
) = lo_filler
;
2214 row_info
->channels
= 2;
2215 row_info
->pixel_depth
= 32;
2216 row_info
->rowbytes
= row_width
* 4;
2220 } /* COLOR_TYPE == GRAY */
2221 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
2223 if (row_info
->bit_depth
== 8)
2225 if (flags
& PNG_FLAG_FILLER_AFTER
)
2227 /* This changes the data from RGB to RGBX */
2228 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
2229 png_bytep dp
= sp
+ (png_size_t
)row_width
;
2230 for (i
= 1; i
< row_width
; i
++)
2232 *(--dp
) = lo_filler
;
2237 *(--dp
) = lo_filler
;
2238 row_info
->channels
= 4;
2239 row_info
->pixel_depth
= 32;
2240 row_info
->rowbytes
= row_width
* 4;
2245 /* This changes the data from RGB to XRGB */
2246 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
2247 png_bytep dp
= sp
+ (png_size_t
)row_width
;
2248 for (i
= 0; i
< row_width
; i
++)
2253 *(--dp
) = lo_filler
;
2255 row_info
->channels
= 4;
2256 row_info
->pixel_depth
= 32;
2257 row_info
->rowbytes
= row_width
* 4;
2261 #ifdef PNG_READ_16BIT_SUPPORTED
2262 else if (row_info
->bit_depth
== 16)
2264 if (flags
& PNG_FLAG_FILLER_AFTER
)
2266 /* This changes the data from RRGGBB to RRGGBBXX */
2267 png_bytep sp
= row
+ (png_size_t
)row_width
* 6;
2268 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2269 for (i
= 1; i
< row_width
; i
++)
2271 *(--dp
) = hi_filler
;
2272 *(--dp
) = lo_filler
;
2280 *(--dp
) = hi_filler
;
2281 *(--dp
) = lo_filler
;
2282 row_info
->channels
= 4;
2283 row_info
->pixel_depth
= 64;
2284 row_info
->rowbytes
= row_width
* 8;
2289 /* This changes the data from RRGGBB to XXRRGGBB */
2290 png_bytep sp
= row
+ (png_size_t
)row_width
* 6;
2291 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2292 for (i
= 0; i
< row_width
; i
++)
2300 *(--dp
) = hi_filler
;
2301 *(--dp
) = lo_filler
;
2304 row_info
->channels
= 4;
2305 row_info
->pixel_depth
= 64;
2306 row_info
->rowbytes
= row_width
* 8;
2310 } /* COLOR_TYPE == RGB */
2314 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
2315 /* Expand grayscale files to RGB, with or without alpha */
2317 png_do_gray_to_rgb(png_row_infop row_info
, png_bytep row
)
2320 png_uint_32 row_width
= row_info
->width
;
2322 png_debug(1, "in png_do_gray_to_rgb");
2324 if (row_info
->bit_depth
>= 8 &&
2325 !(row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
2327 if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
2329 if (row_info
->bit_depth
== 8)
2331 /* This changes G to RGB */
2332 png_bytep sp
= row
+ (png_size_t
)row_width
- 1;
2333 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2334 for (i
= 0; i
< row_width
; i
++)
2344 /* This changes GG to RRGGBB */
2345 png_bytep sp
= row
+ (png_size_t
)row_width
* 2 - 1;
2346 png_bytep dp
= sp
+ (png_size_t
)row_width
* 4;
2347 for (i
= 0; i
< row_width
; i
++)
2350 *(dp
--) = *(sp
- 1);
2352 *(dp
--) = *(sp
- 1);
2359 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
2361 if (row_info
->bit_depth
== 8)
2363 /* This changes GA to RGBA */
2364 png_bytep sp
= row
+ (png_size_t
)row_width
* 2 - 1;
2365 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2366 for (i
= 0; i
< row_width
; i
++)
2377 /* This changes GGAA to RRGGBBAA */
2378 png_bytep sp
= row
+ (png_size_t
)row_width
* 4 - 1;
2379 png_bytep dp
= sp
+ (png_size_t
)row_width
* 4;
2380 for (i
= 0; i
< row_width
; i
++)
2385 *(dp
--) = *(sp
- 1);
2387 *(dp
--) = *(sp
- 1);
2393 row_info
->channels
+= (png_byte
)2;
2394 row_info
->color_type
|= PNG_COLOR_MASK_COLOR
;
2395 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
2396 row_info
->bit_depth
);
2397 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
, row_width
);
2402 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
2403 /* Reduce RGB files to grayscale, with or without alpha
2404 * using the equation given in Poynton's ColorFAQ at
2405 * <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008)
2407 * <http://www.poynton.com/notes/colour_and_gamma/>
2408 * Charles Poynton poynton at poynton.com
2410 * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
2412 * We approximate this with
2414 * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B
2416 * which can be expressed with integers as
2418 * Y = (6969 * R + 23434 * G + 2365 * B)/32768
2420 * The calculation is to be done in a linear colorspace.
2422 * Other integer coefficents can be used via png_set_rgb_to_gray().
2425 png_do_rgb_to_gray(png_structp png_ptr
, png_row_infop row_info
, png_bytep row
)
2430 png_uint_32 row_width
= row_info
->width
;
2433 png_debug(1, "in png_do_rgb_to_gray");
2435 if (!(row_info
->color_type
& PNG_COLOR_MASK_PALETTE
) &&
2436 (row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
2438 png_uint_32 rc
= png_ptr
->rgb_to_gray_red_coeff
;
2439 png_uint_32 gc
= png_ptr
->rgb_to_gray_green_coeff
;
2440 png_uint_32 bc
= png_ptr
->rgb_to_gray_blue_coeff
;
2442 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
2444 if (row_info
->bit_depth
== 8)
2446 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2447 if (png_ptr
->gamma_from_1
!= NULL
&& png_ptr
->gamma_to_1
!= NULL
)
2452 for (i
= 0; i
< row_width
; i
++)
2454 png_byte red
= png_ptr
->gamma_to_1
[*(sp
++)];
2455 png_byte green
= png_ptr
->gamma_to_1
[*(sp
++)];
2456 png_byte blue
= png_ptr
->gamma_to_1
[*(sp
++)];
2458 if (red
!= green
|| red
!= blue
)
2461 *(dp
++) = png_ptr
->gamma_from_1
[
2462 (rc
*red
+ gc
*green
+ bc
*blue
)>>15];
2466 *(dp
++) = *(sp
- 1);
2474 for (i
= 0; i
< row_width
; i
++)
2476 png_byte red
= *(sp
++);
2477 png_byte green
= *(sp
++);
2478 png_byte blue
= *(sp
++);
2480 if (red
!= green
|| red
!= blue
)
2483 *(dp
++) = (png_byte
)((rc
*red
+ gc
*green
+ bc
*blue
)>>15);
2487 *(dp
++) = *(sp
- 1);
2492 else /* RGB bit_depth == 16 */
2494 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2495 if (png_ptr
->gamma_16_to_1
!= NULL
&&
2496 png_ptr
->gamma_16_from_1
!= NULL
)
2500 for (i
= 0; i
< row_width
; i
++)
2502 png_uint_16 red
, green
, blue
, w
;
2504 red
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+ 1)); sp
+= 2;
2505 green
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+ 1)); sp
+= 2;
2506 blue
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+ 1)); sp
+= 2;
2508 if (red
== green
&& red
== blue
)
2513 png_uint_16 red_1
= png_ptr
->gamma_16_to_1
[(red
&0xff)
2514 >> png_ptr
->gamma_shift
][red
>>8];
2515 png_uint_16 green_1
=
2516 png_ptr
->gamma_16_to_1
[(green
&0xff) >>
2517 png_ptr
->gamma_shift
][green
>>8];
2518 png_uint_16 blue_1
= png_ptr
->gamma_16_to_1
[(blue
&0xff)
2519 >> png_ptr
->gamma_shift
][blue
>>8];
2520 png_uint_16 gray16
= (png_uint_16
)((rc
*red_1
+ gc
*green_1
2522 w
= png_ptr
->gamma_16_from_1
[(gray16
&0xff) >>
2523 png_ptr
->gamma_shift
][gray16
>> 8];
2527 *(dp
++) = (png_byte
)((w
>>8) & 0xff);
2528 *(dp
++) = (png_byte
)(w
& 0xff);
2536 for (i
= 0; i
< row_width
; i
++)
2538 png_uint_16 red
, green
, blue
, gray16
;
2540 red
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+ 1)); sp
+= 2;
2541 green
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+ 1)); sp
+= 2;
2542 blue
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+ 1)); sp
+= 2;
2544 if (red
!= green
|| red
!= blue
)
2547 gray16
= (png_uint_16
)((rc
*red
+ gc
*green
+ bc
*blue
)>>15);
2548 *(dp
++) = (png_byte
)((gray16
>>8) & 0xff);
2549 *(dp
++) = (png_byte
)(gray16
& 0xff);
2554 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
2556 if (row_info
->bit_depth
== 8)
2558 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2559 if (png_ptr
->gamma_from_1
!= NULL
&& png_ptr
->gamma_to_1
!= NULL
)
2563 for (i
= 0; i
< row_width
; i
++)
2565 png_byte red
= png_ptr
->gamma_to_1
[*(sp
++)];
2566 png_byte green
= png_ptr
->gamma_to_1
[*(sp
++)];
2567 png_byte blue
= png_ptr
->gamma_to_1
[*(sp
++)];
2569 if (red
!= green
|| red
!= blue
)
2572 *(dp
++) = png_ptr
->gamma_from_1
2573 [(rc
*red
+ gc
*green
+ bc
*blue
)>>15];
2575 *(dp
++) = *(sp
++); /* alpha */
2583 for (i
= 0; i
< row_width
; i
++)
2585 png_byte red
= *(sp
++);
2586 png_byte green
= *(sp
++);
2587 png_byte blue
= *(sp
++);
2588 if (red
!= green
|| red
!= blue
)
2591 *(dp
++) = (png_byte
)((rc
*red
+ gc
*green
+ bc
*blue
)>>15);
2592 *(dp
++) = *(sp
++); /* alpha */
2596 else /* RGBA bit_depth == 16 */
2598 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2599 if (png_ptr
->gamma_16_to_1
!= NULL
&&
2600 png_ptr
->gamma_16_from_1
!= NULL
)
2604 for (i
= 0; i
< row_width
; i
++)
2606 png_uint_16 red
, green
, blue
, w
;
2608 red
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+ 1)); sp
+= 2;
2609 green
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+ 1)); sp
+= 2;
2610 blue
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+ 1)); sp
+= 2;
2612 if (red
== green
&& red
== blue
)
2617 png_uint_16 red_1
= png_ptr
->gamma_16_to_1
[(red
&0xff) >>
2618 png_ptr
->gamma_shift
][red
>>8];
2620 png_uint_16 green_1
=
2621 png_ptr
->gamma_16_to_1
[(green
&0xff) >>
2622 png_ptr
->gamma_shift
][green
>>8];
2624 png_uint_16 blue_1
= png_ptr
->gamma_16_to_1
[(blue
&0xff) >>
2625 png_ptr
->gamma_shift
][blue
>>8];
2627 png_uint_16 gray16
= (png_uint_16
)((rc
* red_1
2628 + gc
* green_1
+ bc
* blue_1
)>>15);
2630 w
= png_ptr
->gamma_16_from_1
[(gray16
&0xff) >>
2631 png_ptr
->gamma_shift
][gray16
>> 8];
2636 *(dp
++) = (png_byte
)((w
>>8) & 0xff);
2637 *(dp
++) = (png_byte
)(w
& 0xff);
2638 *(dp
++) = *(sp
++); /* alpha */
2647 for (i
= 0; i
< row_width
; i
++)
2649 png_uint_16 red
, green
, blue
, gray16
;
2650 red
= (png_uint_16
)((*(sp
)<<8) | *(sp
+ 1)); sp
+= 2;
2651 green
= (png_uint_16
)((*(sp
)<<8) | *(sp
+ 1)); sp
+= 2;
2652 blue
= (png_uint_16
)((*(sp
)<<8) | *(sp
+ 1)); sp
+= 2;
2654 if (red
!= green
|| red
!= blue
)
2657 gray16
= (png_uint_16
)((rc
*red
+ gc
*green
+ bc
*blue
)>>15);
2658 *(dp
++) = (png_byte
)((gray16
>>8) & 0xff);
2659 *(dp
++) = (png_byte
)(gray16
& 0xff);
2660 *(dp
++) = *(sp
++); /* alpha */
2666 row_info
->channels
-= 2;
2667 row_info
->color_type
= (png_byte
)(row_info
->color_type
&
2668 ~PNG_COLOR_MASK_COLOR
);
2669 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
2670 row_info
->bit_depth
);
2671 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
, row_width
);
2677 /* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
2678 * large of png_color. This lets grayscale images be treated as
2679 * paletted. Most useful for gamma correction and simplification
2683 png_build_grayscale_palette(int bit_depth
, png_colorp palette
)
2690 png_debug(1, "in png_do_build_grayscale_palette");
2692 if (palette
== NULL
)
2723 for (i
= 0, v
= 0; i
< num_palette
; i
++, v
+= color_inc
)
2725 palette
[i
].red
= (png_byte
)v
;
2726 palette
[i
].green
= (png_byte
)v
;
2727 palette
[i
].blue
= (png_byte
)v
;
2732 #ifdef PNG_READ_BACKGROUND_SUPPORTED
2733 /* Replace any alpha or transparency with the supplied background color.
2734 * "background" is already in the screen gamma, while "background_1" is
2735 * at a gamma of 1.0. Paletted files have already been taken care of.
2738 png_do_background(png_row_infop row_info
, png_bytep row
,
2739 png_const_color_16p trans_color
, png_const_color_16p background
2740 #ifdef PNG_READ_GAMMA_SUPPORTED
2741 , png_const_color_16p background_1
, png_const_bytep gamma_table
,
2742 png_const_bytep gamma_from_1
, png_const_bytep gamma_to_1
,
2743 png_const_uint_16pp gamma_16
, png_const_uint_16pp gamma_16_from_1
,
2744 png_const_uint_16pp gamma_16_to_1
, int gamma_shift
2750 png_uint_32 row_width
= row_info
->width
;
2753 png_debug(1, "in png_do_background");
2755 if (background
!= NULL
&&
2756 (!(row_info
->color_type
& PNG_COLOR_MASK_ALPHA
) ||
2757 (row_info
->color_type
!= PNG_COLOR_TYPE_PALETTE
&& trans_color
)))
2759 switch (row_info
->color_type
)
2761 case PNG_COLOR_TYPE_GRAY
:
2763 switch (row_info
->bit_depth
)
2769 for (i
= 0; i
< row_width
; i
++)
2771 if ((png_uint_16
)((*sp
>> shift
) & 0x01)
2772 == trans_color
->gray
)
2774 *sp
&= (png_byte
)((0x7f7f >> (7 - shift
)) & 0xff);
2775 *sp
|= (png_byte
)(background
->gray
<< shift
);
2792 #ifdef PNG_READ_GAMMA_SUPPORTED
2793 if (gamma_table
!= NULL
)
2797 for (i
= 0; i
< row_width
; i
++)
2799 if ((png_uint_16
)((*sp
>> shift
) & 0x03)
2800 == trans_color
->gray
)
2802 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2803 *sp
|= (png_byte
)(background
->gray
<< shift
);
2808 png_byte p
= (png_byte
)((*sp
>> shift
) & 0x03);
2809 png_byte g
= (png_byte
)((gamma_table
[p
| (p
<< 2) |
2810 (p
<< 4) | (p
<< 6)] >> 6) & 0x03);
2811 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2812 *sp
|= (png_byte
)(g
<< shift
);
2831 for (i
= 0; i
< row_width
; i
++)
2833 if ((png_uint_16
)((*sp
>> shift
) & 0x03)
2834 == trans_color
->gray
)
2836 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2837 *sp
|= (png_byte
)(background
->gray
<< shift
);
2855 #ifdef PNG_READ_GAMMA_SUPPORTED
2856 if (gamma_table
!= NULL
)
2860 for (i
= 0; i
< row_width
; i
++)
2862 if ((png_uint_16
)((*sp
>> shift
) & 0x0f)
2863 == trans_color
->gray
)
2865 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2866 *sp
|= (png_byte
)(background
->gray
<< shift
);
2871 png_byte p
= (png_byte
)((*sp
>> shift
) & 0x0f);
2872 png_byte g
= (png_byte
)((gamma_table
[p
|
2873 (p
<< 4)] >> 4) & 0x0f);
2874 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2875 *sp
|= (png_byte
)(g
<< shift
);
2894 for (i
= 0; i
< row_width
; i
++)
2896 if ((png_uint_16
)((*sp
>> shift
) & 0x0f)
2897 == trans_color
->gray
)
2899 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2900 *sp
|= (png_byte
)(background
->gray
<< shift
);
2918 #ifdef PNG_READ_GAMMA_SUPPORTED
2919 if (gamma_table
!= NULL
)
2922 for (i
= 0; i
< row_width
; i
++, sp
++)
2924 if (*sp
== trans_color
->gray
)
2925 *sp
= (png_byte
)background
->gray
;
2928 *sp
= gamma_table
[*sp
];
2935 for (i
= 0; i
< row_width
; i
++, sp
++)
2937 if (*sp
== trans_color
->gray
)
2938 *sp
= (png_byte
)background
->gray
;
2946 #ifdef PNG_READ_GAMMA_SUPPORTED
2947 if (gamma_16
!= NULL
)
2950 for (i
= 0; i
< row_width
; i
++, sp
+= 2)
2954 v
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
2956 if (v
== trans_color
->gray
)
2958 /* Background is already in screen gamma */
2959 *sp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2960 *(sp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2965 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2966 *sp
= (png_byte
)((v
>> 8) & 0xff);
2967 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2975 for (i
= 0; i
< row_width
; i
++, sp
+= 2)
2979 v
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
2981 if (v
== trans_color
->gray
)
2983 *sp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2984 *(sp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2997 case PNG_COLOR_TYPE_RGB
:
2999 if (row_info
->bit_depth
== 8)
3001 #ifdef PNG_READ_GAMMA_SUPPORTED
3002 if (gamma_table
!= NULL
)
3005 for (i
= 0; i
< row_width
; i
++, sp
+= 3)
3007 if (*sp
== trans_color
->red
&&
3008 *(sp
+ 1) == trans_color
->green
&&
3009 *(sp
+ 2) == trans_color
->blue
)
3011 *sp
= (png_byte
)background
->red
;
3012 *(sp
+ 1) = (png_byte
)background
->green
;
3013 *(sp
+ 2) = (png_byte
)background
->blue
;
3018 *sp
= gamma_table
[*sp
];
3019 *(sp
+ 1) = gamma_table
[*(sp
+ 1)];
3020 *(sp
+ 2) = gamma_table
[*(sp
+ 2)];
3028 for (i
= 0; i
< row_width
; i
++, sp
+= 3)
3030 if (*sp
== trans_color
->red
&&
3031 *(sp
+ 1) == trans_color
->green
&&
3032 *(sp
+ 2) == trans_color
->blue
)
3034 *sp
= (png_byte
)background
->red
;
3035 *(sp
+ 1) = (png_byte
)background
->green
;
3036 *(sp
+ 2) = (png_byte
)background
->blue
;
3041 else /* if (row_info->bit_depth == 16) */
3043 #ifdef PNG_READ_GAMMA_SUPPORTED
3044 if (gamma_16
!= NULL
)
3047 for (i
= 0; i
< row_width
; i
++, sp
+= 6)
3049 png_uint_16 r
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
3051 png_uint_16 g
= (png_uint_16
)(((*(sp
+ 2)) << 8)
3054 png_uint_16 b
= (png_uint_16
)(((*(sp
+ 4)) << 8)
3057 if (r
== trans_color
->red
&& g
== trans_color
->green
&&
3058 b
== trans_color
->blue
)
3060 /* Background is already in screen gamma */
3061 *sp
= (png_byte
)((background
->red
>> 8) & 0xff);
3062 *(sp
+ 1) = (png_byte
)(background
->red
& 0xff);
3063 *(sp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
3064 *(sp
+ 3) = (png_byte
)(background
->green
& 0xff);
3065 *(sp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
3066 *(sp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3071 png_uint_16 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
3072 *sp
= (png_byte
)((v
>> 8) & 0xff);
3073 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3075 v
= gamma_16
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
3076 *(sp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
3077 *(sp
+ 3) = (png_byte
)(v
& 0xff);
3079 v
= gamma_16
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
3080 *(sp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
3081 *(sp
+ 5) = (png_byte
)(v
& 0xff);
3090 for (i
= 0; i
< row_width
; i
++, sp
+= 6)
3092 png_uint_16 r
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
3094 png_uint_16 g
= (png_uint_16
)(((*(sp
+ 2)) << 8)
3097 png_uint_16 b
= (png_uint_16
)(((*(sp
+ 4)) << 8)
3100 if (r
== trans_color
->red
&& g
== trans_color
->green
&&
3101 b
== trans_color
->blue
)
3103 *sp
= (png_byte
)((background
->red
>> 8) & 0xff);
3104 *(sp
+ 1) = (png_byte
)(background
->red
& 0xff);
3105 *(sp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
3106 *(sp
+ 3) = (png_byte
)(background
->green
& 0xff);
3107 *(sp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
3108 *(sp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3116 case PNG_COLOR_TYPE_GRAY_ALPHA
:
3118 if (row_info
->bit_depth
== 8)
3120 #ifdef PNG_READ_GAMMA_SUPPORTED
3121 if (gamma_to_1
!= NULL
&& gamma_from_1
!= NULL
&&
3122 gamma_table
!= NULL
)
3126 for (i
= 0; i
< row_width
; i
++, sp
+= 2, dp
++)
3128 png_uint_16 a
= *(sp
+ 1);
3131 *dp
= gamma_table
[*sp
];
3135 /* Background is already in screen gamma */
3136 *dp
= (png_byte
)background
->gray
;
3143 v
= gamma_to_1
[*sp
];
3144 png_composite(w
, v
, a
, background_1
->gray
);
3145 *dp
= gamma_from_1
[w
];
3154 for (i
= 0; i
< row_width
; i
++, sp
+= 2, dp
++)
3156 png_byte a
= *(sp
+ 1);
3161 #ifdef PNG_READ_GAMMA_SUPPORTED
3163 *dp
= (png_byte
)background
->gray
;
3166 png_composite(*dp
, *sp
, a
, background_1
->gray
);
3169 *dp
= (png_byte
)background
->gray
;
3174 else /* if (png_ptr->bit_depth == 16) */
3176 #ifdef PNG_READ_GAMMA_SUPPORTED
3177 if (gamma_16
!= NULL
&& gamma_16_from_1
!= NULL
&&
3178 gamma_16_to_1
!= NULL
)
3182 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 2)
3184 png_uint_16 a
= (png_uint_16
)(((*(sp
+ 2)) << 8)
3187 if (a
== (png_uint_16
)0xffff)
3191 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
3192 *dp
= (png_byte
)((v
>> 8) & 0xff);
3193 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3196 #ifdef PNG_READ_GAMMA_SUPPORTED
3202 /* Background is already in screen gamma */
3203 *dp
= (png_byte
)((background
->gray
>> 8) & 0xff);
3204 *(dp
+ 1) = (png_byte
)(background
->gray
& 0xff);
3207 #ifdef PNG_READ_GAMMA_SUPPORTED
3210 png_uint_16 g
, v
, w
;
3212 g
= gamma_16_to_1
[*(sp
+ 1) >> gamma_shift
][*sp
];
3213 png_composite_16(v
, g
, a
, background_1
->gray
);
3214 w
= gamma_16_from_1
[(v
&0xff) >> gamma_shift
][v
>> 8];
3215 *dp
= (png_byte
)((w
>> 8) & 0xff);
3216 *(dp
+ 1) = (png_byte
)(w
& 0xff);
3226 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 2)
3228 png_uint_16 a
= (png_uint_16
)(((*(sp
+ 2)) << 8)
3231 if (a
== (png_uint_16
)0xffff)
3232 png_memcpy(dp
, sp
, 2);
3234 #ifdef PNG_READ_GAMMA_SUPPORTED
3240 *dp
= (png_byte
)((background
->gray
>> 8) & 0xff);
3241 *(dp
+ 1) = (png_byte
)(background
->gray
& 0xff);
3244 #ifdef PNG_READ_GAMMA_SUPPORTED
3249 g
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
3250 png_composite_16(v
, g
, a
, background_1
->gray
);
3251 *dp
= (png_byte
)((v
>> 8) & 0xff);
3252 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3261 case PNG_COLOR_TYPE_RGB_ALPHA
:
3263 if (row_info
->bit_depth
== 8)
3265 #ifdef PNG_READ_GAMMA_SUPPORTED
3266 if (gamma_to_1
!= NULL
&& gamma_from_1
!= NULL
&&
3267 gamma_table
!= NULL
)
3271 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 3)
3273 png_byte a
= *(sp
+ 3);
3277 *dp
= gamma_table
[*sp
];
3278 *(dp
+ 1) = gamma_table
[*(sp
+ 1)];
3279 *(dp
+ 2) = gamma_table
[*(sp
+ 2)];
3284 /* Background is already in screen gamma */
3285 *dp
= (png_byte
)background
->red
;
3286 *(dp
+ 1) = (png_byte
)background
->green
;
3287 *(dp
+ 2) = (png_byte
)background
->blue
;
3294 v
= gamma_to_1
[*sp
];
3295 png_composite(w
, v
, a
, background_1
->red
);
3296 *dp
= gamma_from_1
[w
];
3298 v
= gamma_to_1
[*(sp
+ 1)];
3299 png_composite(w
, v
, a
, background_1
->green
);
3300 *(dp
+ 1) = gamma_from_1
[w
];
3302 v
= gamma_to_1
[*(sp
+ 2)];
3303 png_composite(w
, v
, a
, background_1
->blue
);
3304 *(dp
+ 2) = gamma_from_1
[w
];
3313 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 3)
3315 png_byte a
= *(sp
+ 3);
3320 *(dp
+ 1) = *(sp
+ 1);
3321 *(dp
+ 2) = *(sp
+ 2);
3326 *dp
= (png_byte
)background
->red
;
3327 *(dp
+ 1) = (png_byte
)background
->green
;
3328 *(dp
+ 2) = (png_byte
)background
->blue
;
3333 png_composite(*dp
, *sp
, a
, background
->red
);
3335 png_composite(*(dp
+ 1), *(sp
+ 1), a
,
3338 png_composite(*(dp
+ 2), *(sp
+ 2), a
,
3344 else /* if (row_info->bit_depth == 16) */
3346 #ifdef PNG_READ_GAMMA_SUPPORTED
3347 if (gamma_16
!= NULL
&& gamma_16_from_1
!= NULL
&&
3348 gamma_16_to_1
!= NULL
)
3352 for (i
= 0; i
< row_width
; i
++, sp
+= 8, dp
+= 6)
3354 png_uint_16 a
= (png_uint_16
)(((png_uint_16
)(*(sp
+ 6))
3355 << 8) + (png_uint_16
)(*(sp
+ 7)));
3357 if (a
== (png_uint_16
)0xffff)
3361 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
3362 *dp
= (png_byte
)((v
>> 8) & 0xff);
3363 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3365 v
= gamma_16
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
3366 *(dp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
3367 *(dp
+ 3) = (png_byte
)(v
& 0xff);
3369 v
= gamma_16
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
3370 *(dp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
3371 *(dp
+ 5) = (png_byte
)(v
& 0xff);
3376 /* Background is already in screen gamma */
3377 *dp
= (png_byte
)((background
->red
>> 8) & 0xff);
3378 *(dp
+ 1) = (png_byte
)(background
->red
& 0xff);
3379 *(dp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
3380 *(dp
+ 3) = (png_byte
)(background
->green
& 0xff);
3381 *(dp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
3382 *(dp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3387 png_uint_16 v
, w
, x
;
3389 v
= gamma_16_to_1
[*(sp
+ 1) >> gamma_shift
][*sp
];
3390 png_composite_16(w
, v
, a
, background_1
->red
);
3392 x
= gamma_16_from_1
[((w
&0xff) >> gamma_shift
)][w
>> 8];
3393 *dp
= (png_byte
)((x
>> 8) & 0xff);
3394 *(dp
+ 1) = (png_byte
)(x
& 0xff);
3396 v
= gamma_16_to_1
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
3397 png_composite_16(w
, v
, a
, background_1
->green
);
3399 x
= gamma_16_from_1
[((w
&0xff) >> gamma_shift
)][w
>> 8];
3400 *(dp
+ 2) = (png_byte
)((x
>> 8) & 0xff);
3401 *(dp
+ 3) = (png_byte
)(x
& 0xff);
3403 v
= gamma_16_to_1
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
3404 png_composite_16(w
, v
, a
, background_1
->blue
);
3406 x
= gamma_16_from_1
[(w
& 0xff) >> gamma_shift
][w
>> 8];
3407 *(dp
+ 4) = (png_byte
)((x
>> 8) & 0xff);
3408 *(dp
+ 5) = (png_byte
)(x
& 0xff);
3418 for (i
= 0; i
< row_width
; i
++, sp
+= 8, dp
+= 6)
3420 png_uint_16 a
= (png_uint_16
)(((png_uint_16
)(*(sp
+ 6))
3421 << 8) + (png_uint_16
)(*(sp
+ 7)));
3423 if (a
== (png_uint_16
)0xffff)
3425 png_memcpy(dp
, sp
, 6);
3430 *dp
= (png_byte
)((background
->red
>> 8) & 0xff);
3431 *(dp
+ 1) = (png_byte
)(background
->red
& 0xff);
3432 *(dp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
3433 *(dp
+ 3) = (png_byte
)(background
->green
& 0xff);
3434 *(dp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
3435 *(dp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3442 png_uint_16 r
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
3443 png_uint_16 g
= (png_uint_16
)(((*(sp
+ 2)) << 8)
3445 png_uint_16 b
= (png_uint_16
)(((*(sp
+ 4)) << 8)
3448 png_composite_16(v
, r
, a
, background
->red
);
3449 *dp
= (png_byte
)((v
>> 8) & 0xff);
3450 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3452 png_composite_16(v
, g
, a
, background
->green
);
3453 *(dp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
3454 *(dp
+ 3) = (png_byte
)(v
& 0xff);
3456 png_composite_16(v
, b
, a
, background
->blue
);
3457 *(dp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
3458 *(dp
+ 5) = (png_byte
)(v
& 0xff);
3470 if (row_info
->color_type
& PNG_COLOR_MASK_ALPHA
)
3472 row_info
->color_type
= (png_byte
)(row_info
->color_type
&
3473 ~PNG_COLOR_MASK_ALPHA
);
3474 row_info
->channels
--;
3475 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
3476 row_info
->bit_depth
);
3477 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
, row_width
);
3483 #ifdef PNG_READ_GAMMA_SUPPORTED
3484 /* Gamma correct the image, avoiding the alpha channel. Make sure
3485 * you do this after you deal with the transparency issue on grayscale
3486 * or RGB images. If your bit depth is 8, use gamma_table, if it
3487 * is 16, use gamma_16_table and gamma_shift. Build these with
3488 * build_gamma_table().
3491 png_do_gamma(png_row_infop row_info
, png_bytep row
,
3492 png_const_bytep gamma_table
, png_const_uint_16pp gamma_16_table
,
3497 png_uint_32 row_width
=row_info
->width
;
3499 png_debug(1, "in png_do_gamma");
3501 if (((row_info
->bit_depth
<= 8 && gamma_table
!= NULL
) ||
3502 (row_info
->bit_depth
== 16 && gamma_16_table
!= NULL
)))
3504 switch (row_info
->color_type
)
3506 case PNG_COLOR_TYPE_RGB
:
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
++)
3529 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3530 *sp
= (png_byte
)((v
>> 8) & 0xff);
3531 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3534 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3535 *sp
= (png_byte
)((v
>> 8) & 0xff);
3536 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3539 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3540 *sp
= (png_byte
)((v
>> 8) & 0xff);
3541 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3548 case PNG_COLOR_TYPE_RGB_ALPHA
:
3550 if (row_info
->bit_depth
== 8)
3553 for (i
= 0; i
< row_width
; i
++)
3555 *sp
= gamma_table
[*sp
];
3558 *sp
= gamma_table
[*sp
];
3561 *sp
= gamma_table
[*sp
];
3568 else /* if (row_info->bit_depth == 16) */
3571 for (i
= 0; i
< row_width
; i
++)
3573 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3574 *sp
= (png_byte
)((v
>> 8) & 0xff);
3575 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3578 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3579 *sp
= (png_byte
)((v
>> 8) & 0xff);
3580 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3583 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3584 *sp
= (png_byte
)((v
>> 8) & 0xff);
3585 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3592 case PNG_COLOR_TYPE_GRAY_ALPHA
:
3594 if (row_info
->bit_depth
== 8)
3597 for (i
= 0; i
< row_width
; i
++)
3599 *sp
= gamma_table
[*sp
];
3604 else /* if (row_info->bit_depth == 16) */
3607 for (i
= 0; i
< row_width
; i
++)
3609 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3610 *sp
= (png_byte
)((v
>> 8) & 0xff);
3611 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3618 case PNG_COLOR_TYPE_GRAY
:
3620 if (row_info
->bit_depth
== 2)
3623 for (i
= 0; i
< row_width
; i
+= 4)
3631 ((((int)gamma_table
[a
|(a
>>2)|(a
>>4)|(a
>>6)]) ) & 0xc0)|
3632 ((((int)gamma_table
[(b
<<2)|b
|(b
>>2)|(b
>>4)])>>2) & 0x30)|
3633 ((((int)gamma_table
[(c
<<4)|(c
<<2)|c
|(c
>>2)])>>4) & 0x0c)|
3634 ((((int)gamma_table
[(d
<<6)|(d
<<4)|(d
<<2)|d
])>>6) ));
3639 if (row_info
->bit_depth
== 4)
3642 for (i
= 0; i
< row_width
; i
+= 2)
3644 int msb
= *sp
& 0xf0;
3645 int lsb
= *sp
& 0x0f;
3647 *sp
= (png_byte
)((((int)gamma_table
[msb
| (msb
>> 4)]) & 0xf0)
3648 | (((int)gamma_table
[(lsb
<< 4) | lsb
]) >> 4));
3653 else if (row_info
->bit_depth
== 8)
3656 for (i
= 0; i
< row_width
; i
++)
3658 *sp
= gamma_table
[*sp
];
3663 else if (row_info
->bit_depth
== 16)
3666 for (i
= 0; i
< row_width
; i
++)
3668 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3669 *sp
= (png_byte
)((v
>> 8) & 0xff);
3670 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3684 #ifdef PNG_READ_EXPAND_SUPPORTED
3685 /* Expands a palette row to an RGB or RGBA row depending
3686 * upon whether you supply trans and num_trans.
3689 png_do_expand_palette(png_row_infop row_info
, png_bytep row
,
3690 png_const_colorp palette
, png_const_bytep trans_alpha
, int num_trans
)
3695 png_uint_32 row_width
=row_info
->width
;
3697 png_debug(1, "in png_do_expand_palette");
3699 if (row_info
->color_type
== PNG_COLOR_TYPE_PALETTE
)
3701 if (row_info
->bit_depth
< 8)
3703 switch (row_info
->bit_depth
)
3707 sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
3708 dp
= row
+ (png_size_t
)row_width
- 1;
3709 shift
= 7 - (int)((row_width
+ 7) & 0x07);
3710 for (i
= 0; i
< row_width
; i
++)
3712 if ((*sp
>> shift
) & 0x01)
3734 sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
3735 dp
= row
+ (png_size_t
)row_width
- 1;
3736 shift
= (int)((3 - ((row_width
+ 3) & 0x03)) << 1);
3737 for (i
= 0; i
< row_width
; i
++)
3739 value
= (*sp
>> shift
) & 0x03;
3740 *dp
= (png_byte
)value
;
3757 sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
3758 dp
= row
+ (png_size_t
)row_width
- 1;
3759 shift
= (int)((row_width
& 0x01) << 2);
3760 for (i
= 0; i
< row_width
; i
++)
3762 value
= (*sp
>> shift
) & 0x0f;
3763 *dp
= (png_byte
)value
;
3781 row_info
->bit_depth
= 8;
3782 row_info
->pixel_depth
= 8;
3783 row_info
->rowbytes
= row_width
;
3786 if (row_info
->bit_depth
== 8)
3789 if (trans_alpha
!= NULL
)
3791 sp
= row
+ (png_size_t
)row_width
- 1;
3792 dp
= row
+ (png_size_t
)(row_width
<< 2) - 1;
3794 for (i
= 0; i
< row_width
; i
++)
3796 if ((int)(*sp
) >= num_trans
)
3800 *dp
-- = trans_alpha
[*sp
];
3802 *dp
-- = palette
[*sp
].blue
;
3803 *dp
-- = palette
[*sp
].green
;
3804 *dp
-- = palette
[*sp
].red
;
3807 row_info
->bit_depth
= 8;
3808 row_info
->pixel_depth
= 32;
3809 row_info
->rowbytes
= row_width
* 4;
3810 row_info
->color_type
= 6;
3811 row_info
->channels
= 4;
3816 sp
= row
+ (png_size_t
)row_width
- 1;
3817 dp
= row
+ (png_size_t
)(row_width
* 3) - 1;
3819 for (i
= 0; i
< row_width
; i
++)
3821 *dp
-- = palette
[*sp
].blue
;
3822 *dp
-- = palette
[*sp
].green
;
3823 *dp
-- = palette
[*sp
].red
;
3827 row_info
->bit_depth
= 8;
3828 row_info
->pixel_depth
= 24;
3829 row_info
->rowbytes
= row_width
* 3;
3830 row_info
->color_type
= 2;
3831 row_info
->channels
= 3;
3838 /* If the bit depth < 8, it is expanded to 8. Also, if the already
3839 * expanded transparency value is supplied, an alpha channel is built.
3842 png_do_expand(png_row_infop row_info
, png_bytep row
,
3843 png_const_color_16p trans_value
)
3848 png_uint_32 row_width
=row_info
->width
;
3850 png_debug(1, "in png_do_expand");
3853 if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
3855 png_uint_16 gray
= (png_uint_16
)(trans_value
? trans_value
->gray
: 0);
3857 if (row_info
->bit_depth
< 8)
3859 switch (row_info
->bit_depth
)
3863 gray
= (png_uint_16
)((gray
& 0x01) * 0xff);
3864 sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
3865 dp
= row
+ (png_size_t
)row_width
- 1;
3866 shift
= 7 - (int)((row_width
+ 7) & 0x07);
3867 for (i
= 0; i
< row_width
; i
++)
3869 if ((*sp
>> shift
) & 0x01)
3891 gray
= (png_uint_16
)((gray
& 0x03) * 0x55);
3892 sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
3893 dp
= row
+ (png_size_t
)row_width
- 1;
3894 shift
= (int)((3 - ((row_width
+ 3) & 0x03)) << 1);
3895 for (i
= 0; i
< row_width
; i
++)
3897 value
= (*sp
>> shift
) & 0x03;
3898 *dp
= (png_byte
)(value
| (value
<< 2) | (value
<< 4) |
3916 gray
= (png_uint_16
)((gray
& 0x0f) * 0x11);
3917 sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
3918 dp
= row
+ (png_size_t
)row_width
- 1;
3919 shift
= (int)((1 - ((row_width
+ 1) & 0x01)) << 2);
3920 for (i
= 0; i
< row_width
; i
++)
3922 value
= (*sp
>> shift
) & 0x0f;
3923 *dp
= (png_byte
)(value
| (value
<< 4));
3942 row_info
->bit_depth
= 8;
3943 row_info
->pixel_depth
= 8;
3944 row_info
->rowbytes
= row_width
;
3947 if (trans_value
!= NULL
)
3949 if (row_info
->bit_depth
== 8)
3952 sp
= row
+ (png_size_t
)row_width
- 1;
3953 dp
= row
+ (png_size_t
)(row_width
<< 1) - 1;
3955 for (i
= 0; i
< row_width
; i
++)
3967 else if (row_info
->bit_depth
== 16)
3969 png_byte gray_high
= (png_byte
)((gray
>> 8) & 0xff);
3970 png_byte gray_low
= (png_byte
)(gray
& 0xff);
3971 sp
= row
+ row_info
->rowbytes
- 1;
3972 dp
= row
+ (row_info
->rowbytes
<< 1) - 1;
3973 for (i
= 0; i
< row_width
; i
++)
3975 if (*(sp
- 1) == gray_high
&& *(sp
) == gray_low
)
3992 row_info
->color_type
= PNG_COLOR_TYPE_GRAY_ALPHA
;
3993 row_info
->channels
= 2;
3994 row_info
->pixel_depth
= (png_byte
)(row_info
->bit_depth
<< 1);
3995 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
,
3999 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
&& trans_value
)
4001 if (row_info
->bit_depth
== 8)
4003 png_byte red
= (png_byte
)(trans_value
->red
& 0xff);
4004 png_byte green
= (png_byte
)(trans_value
->green
& 0xff);
4005 png_byte blue
= (png_byte
)(trans_value
->blue
& 0xff);
4006 sp
= row
+ (png_size_t
)row_info
->rowbytes
- 1;
4007 dp
= row
+ (png_size_t
)(row_width
<< 2) - 1;
4008 for (i
= 0; i
< row_width
; i
++)
4010 if (*(sp
- 2) == red
&& *(sp
- 1) == green
&& *(sp
) == blue
)
4021 else if (row_info
->bit_depth
== 16)
4023 png_byte red_high
= (png_byte
)((trans_value
->red
>> 8) & 0xff);
4024 png_byte green_high
= (png_byte
)((trans_value
->green
>> 8) & 0xff);
4025 png_byte blue_high
= (png_byte
)((trans_value
->blue
>> 8) & 0xff);
4026 png_byte red_low
= (png_byte
)(trans_value
->red
& 0xff);
4027 png_byte green_low
= (png_byte
)(trans_value
->green
& 0xff);
4028 png_byte blue_low
= (png_byte
)(trans_value
->blue
& 0xff);
4029 sp
= row
+ row_info
->rowbytes
- 1;
4030 dp
= row
+ (png_size_t
)(row_width
<< 3) - 1;
4031 for (i
= 0; i
< row_width
; i
++)
4033 if (*(sp
- 5) == red_high
&&
4034 *(sp
- 4) == red_low
&&
4035 *(sp
- 3) == green_high
&&
4036 *(sp
- 2) == green_low
&&
4037 *(sp
- 1) == blue_high
&&
4058 row_info
->color_type
= PNG_COLOR_TYPE_RGB_ALPHA
;
4059 row_info
->channels
= 4;
4060 row_info
->pixel_depth
= (png_byte
)(row_info
->bit_depth
<< 2);
4061 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
, row_width
);
4067 #ifdef PNG_READ_QUANTIZE_SUPPORTED
4069 png_do_quantize(png_row_infop row_info
, png_bytep row
,
4070 png_const_bytep palette_lookup
, png_const_bytep quantize_lookup
)
4074 png_uint_32 row_width
=row_info
->width
;
4076 png_debug(1, "in png_do_quantize");
4078 if (row_info
->bit_depth
== 8)
4080 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
&& palette_lookup
)
4085 for (i
= 0; i
< row_width
; i
++)
4091 /* This looks real messy, but the compiler will reduce
4092 * it down to a reasonable formula. For example, with
4093 * 5 bits per color, we get:
4094 * p = (((r >> 3) & 0x1f) << 10) |
4095 * (((g >> 3) & 0x1f) << 5) |
4096 * ((b >> 3) & 0x1f);
4098 p
= (((r
>> (8 - PNG_QUANTIZE_RED_BITS
)) &
4099 ((1 << PNG_QUANTIZE_RED_BITS
) - 1)) <<
4100 (PNG_QUANTIZE_GREEN_BITS
+ PNG_QUANTIZE_BLUE_BITS
)) |
4101 (((g
>> (8 - PNG_QUANTIZE_GREEN_BITS
)) &
4102 ((1 << PNG_QUANTIZE_GREEN_BITS
) - 1)) <<
4103 (PNG_QUANTIZE_BLUE_BITS
)) |
4104 ((b
>> (8 - PNG_QUANTIZE_BLUE_BITS
)) &
4105 ((1 << PNG_QUANTIZE_BLUE_BITS
) - 1));
4107 *dp
++ = palette_lookup
[p
];
4110 row_info
->color_type
= PNG_COLOR_TYPE_PALETTE
;
4111 row_info
->channels
= 1;
4112 row_info
->pixel_depth
= row_info
->bit_depth
;
4113 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
, row_width
);
4116 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
&&
4117 palette_lookup
!= NULL
)
4122 for (i
= 0; i
< row_width
; i
++)
4129 p
= (((r
>> (8 - PNG_QUANTIZE_RED_BITS
)) &
4130 ((1 << PNG_QUANTIZE_RED_BITS
) - 1)) <<
4131 (PNG_QUANTIZE_GREEN_BITS
+ PNG_QUANTIZE_BLUE_BITS
)) |
4132 (((g
>> (8 - PNG_QUANTIZE_GREEN_BITS
)) &
4133 ((1 << PNG_QUANTIZE_GREEN_BITS
) - 1)) <<
4134 (PNG_QUANTIZE_BLUE_BITS
)) |
4135 ((b
>> (8 - PNG_QUANTIZE_BLUE_BITS
)) &
4136 ((1 << PNG_QUANTIZE_BLUE_BITS
) - 1));
4138 *dp
++ = palette_lookup
[p
];
4141 row_info
->color_type
= PNG_COLOR_TYPE_PALETTE
;
4142 row_info
->channels
= 1;
4143 row_info
->pixel_depth
= row_info
->bit_depth
;
4144 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
, row_width
);
4147 else if (row_info
->color_type
== PNG_COLOR_TYPE_PALETTE
&&
4152 for (i
= 0; i
< row_width
; i
++, sp
++)
4154 *sp
= quantize_lookup
[*sp
];
4159 #endif /* PNG_READ_QUANTIZE_SUPPORTED */
4161 #ifdef PNG_MNG_FEATURES_SUPPORTED
4162 /* Undoes intrapixel differencing */
4164 png_do_read_intrapixel(png_row_infop row_info
, png_bytep row
)
4166 png_debug(1, "in png_do_read_intrapixel");
4169 (row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
4171 int bytes_per_pixel
;
4172 png_uint_32 row_width
= row_info
->width
;
4174 if (row_info
->bit_depth
== 8)
4179 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
4180 bytes_per_pixel
= 3;
4182 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
4183 bytes_per_pixel
= 4;
4188 for (i
= 0, rp
= row
; i
< row_width
; i
++, rp
+= bytes_per_pixel
)
4190 *(rp
) = (png_byte
)((256 + *rp
+ *(rp
+ 1)) & 0xff);
4191 *(rp
+2) = (png_byte
)((256 + *(rp
+ 2) + *(rp
+ 1)) & 0xff);
4194 else if (row_info
->bit_depth
== 16)
4199 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
4200 bytes_per_pixel
= 6;
4202 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
4203 bytes_per_pixel
= 8;
4208 for (i
= 0, rp
= row
; i
< row_width
; i
++, rp
+= bytes_per_pixel
)
4210 png_uint_32 s0
= (*(rp
) << 8) | *(rp
+ 1);
4211 png_uint_32 s1
= (*(rp
+ 2) << 8) | *(rp
+ 3);
4212 png_uint_32 s2
= (*(rp
+ 4) << 8) | *(rp
+ 5);
4213 png_uint_32 red
= (png_uint_32
)((s0
+ s1
+ 65536L) & 0xffffL
);
4214 png_uint_32 blue
= (png_uint_32
)((s2
+ s1
+ 65536L) & 0xffffL
);
4215 *(rp
) = (png_byte
)((red
>> 8) & 0xff);
4216 *(rp
+ 1) = (png_byte
)(red
& 0xff);
4217 *(rp
+ 4) = (png_byte
)((blue
>> 8) & 0xff);
4218 *(rp
+ 5) = (png_byte
)(blue
& 0xff);
4223 #endif /* PNG_MNG_FEATURES_SUPPORTED */
4224 #endif /* PNG_READ_SUPPORTED */