2 /* pngrtran.c - transforms the data in a row for PNG readers
4 * libpng 1.2.4 - July 8, 2002
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1998-2002 Glenn Randers-Pehrson
7 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
10 * This file contains functions optionally called by an application
11 * in order to tell libpng how to handle data when reading a PNG.
12 * Transformations that are used in both reading and writing are
19 #if defined(_MSC_VER) && !defined(__MWERKS__)
20 #define __VISUALC__ _MSC_VER
24 #pragma warning(disable:4135)
28 /* Set the action on getting a CRC error for an ancillary or critical chunk. */
30 png_set_crc_action(png_structp png_ptr
, int crit_action
, int ancil_action
)
32 png_debug(1, "in png_set_crc_action\n");
33 /* Tell libpng how we react to CRC errors in critical chunks */
36 case PNG_CRC_NO_CHANGE
: /* leave setting as is */
38 case PNG_CRC_WARN_USE
: /* warn/use data */
39 png_ptr
->flags
&= ~PNG_FLAG_CRC_CRITICAL_MASK
;
40 png_ptr
->flags
|= PNG_FLAG_CRC_CRITICAL_USE
;
42 case PNG_CRC_QUIET_USE
: /* quiet/use data */
43 png_ptr
->flags
&= ~PNG_FLAG_CRC_CRITICAL_MASK
;
44 png_ptr
->flags
|= PNG_FLAG_CRC_CRITICAL_USE
|
45 PNG_FLAG_CRC_CRITICAL_IGNORE
;
47 case PNG_CRC_WARN_DISCARD
: /* not a valid action for critical data */
48 png_warning(png_ptr
, "Can't discard critical data on CRC error.");
49 case PNG_CRC_ERROR_QUIT
: /* error/quit */
52 png_ptr
->flags
&= ~PNG_FLAG_CRC_CRITICAL_MASK
;
58 case PNG_CRC_NO_CHANGE
: /* leave setting as is */
60 case PNG_CRC_WARN_USE
: /* warn/use data */
61 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
62 png_ptr
->flags
|= PNG_FLAG_CRC_ANCILLARY_USE
;
64 case PNG_CRC_QUIET_USE
: /* quiet/use data */
65 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
66 png_ptr
->flags
|= PNG_FLAG_CRC_ANCILLARY_USE
|
67 PNG_FLAG_CRC_ANCILLARY_NOWARN
;
69 case PNG_CRC_ERROR_QUIT
: /* error/quit */
70 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
71 png_ptr
->flags
|= PNG_FLAG_CRC_ANCILLARY_NOWARN
;
73 case PNG_CRC_WARN_DISCARD
: /* warn/discard data */
76 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
81 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
82 defined(PNG_FLOATING_POINT_SUPPORTED)
83 /* handle alpha and tRNS via a background color */
85 png_set_background(png_structp png_ptr
,
86 png_color_16p background_color
, int background_gamma_code
,
87 int need_expand
, double background_gamma
)
89 png_debug(1, "in png_set_background\n");
90 if (background_gamma_code
== PNG_BACKGROUND_GAMMA_UNKNOWN
)
92 png_warning(png_ptr
, "Application must supply a known background gamma");
96 png_ptr
->transformations
|= PNG_BACKGROUND
;
97 png_memcpy(&(png_ptr
->background
), background_color
, sizeof(png_color_16
));
98 png_ptr
->background_gamma
= (float)background_gamma
;
99 png_ptr
->background_gamma_type
= (png_byte
)(background_gamma_code
);
100 png_ptr
->transformations
|= (need_expand
? PNG_BACKGROUND_EXPAND
: 0);
102 /* Note: if need_expand is set and color_type is either RGB or RGB_ALPHA
103 * (in which case need_expand is superfluous anyway), the background color
104 * might actually be gray yet not be flagged as such. This is not a problem
105 * for the current code, which uses PNG_BACKGROUND_IS_GRAY only to
106 * decide when to do the png_do_gray_to_rgb() transformation.
108 if ((need_expand
&& !(png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)) ||
109 (!need_expand
&& background_color
->red
== background_color
->green
&&
110 background_color
->red
== background_color
->blue
))
111 png_ptr
->mode
|= PNG_BACKGROUND_IS_GRAY
;
115 #if defined(PNG_READ_16_TO_8_SUPPORTED)
116 /* strip 16 bit depth files to 8 bit depth */
118 png_set_strip_16(png_structp png_ptr
)
120 png_debug(1, "in png_set_strip_16\n");
121 png_ptr
->transformations
|= PNG_16_TO_8
;
125 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
127 png_set_strip_alpha(png_structp png_ptr
)
129 png_debug(1, "in png_set_strip_alpha\n");
130 png_ptr
->transformations
|= PNG_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\n");
159 png_ptr
->transformations
|= PNG_DITHER
;
165 png_ptr
->dither_index
= (png_bytep
)png_malloc(png_ptr
,
166 (png_uint_32
)(num_palette
* sizeof (png_byte
)));
167 for (i
= 0; i
< num_palette
; i
++)
168 png_ptr
->dither_index
[i
] = (png_byte
)i
;
171 if (num_palette
> maximum_colors
)
173 if (histogram
!= NULL
)
175 /* This is easy enough, just throw out the least used colors.
176 Perhaps not the best solution, but good enough. */
180 /* initialize an array to sort colors */
181 png_ptr
->dither_sort
= (png_bytep
)png_malloc(png_ptr
,
182 (png_uint_32
)(num_palette
* sizeof (png_byte
)));
184 /* initialize the dither_sort array */
185 for (i
= 0; i
< num_palette
; i
++)
186 png_ptr
->dither_sort
[i
] = (png_byte
)i
;
188 /* Find the least used palette entries by starting a
189 bubble sort, and running it until we have sorted
190 out enough colors. Note that we don't care about
191 sorting all the colors, just finding which are
194 for (i
= num_palette
- 1; i
>= maximum_colors
; i
--)
196 int done
; /* to stop early if the list is pre-sorted */
200 for (j
= 0; j
< i
; j
++)
202 if (histogram
[png_ptr
->dither_sort
[j
]]
203 < histogram
[png_ptr
->dither_sort
[j
+ 1]])
207 t
= png_ptr
->dither_sort
[j
];
208 png_ptr
->dither_sort
[j
] = png_ptr
->dither_sort
[j
+ 1];
209 png_ptr
->dither_sort
[j
+ 1] = t
;
217 /* swap the palette around, and set up a table, if necessary */
222 /* put all the useful colors within the max, but don't
224 for (i
= 0; i
< maximum_colors
; i
++)
226 if ((int)png_ptr
->dither_sort
[i
] >= maximum_colors
)
230 while ((int)png_ptr
->dither_sort
[j
] >= maximum_colors
);
231 palette
[i
] = palette
[j
];
239 /* move all the used colors inside the max limit, and
240 develop a translation table */
241 for (i
= 0; i
< maximum_colors
; i
++)
243 /* only move the colors we need to */
244 if ((int)png_ptr
->dither_sort
[i
] >= maximum_colors
)
250 while ((int)png_ptr
->dither_sort
[j
] >= maximum_colors
);
252 tmp_color
= palette
[j
];
253 palette
[j
] = palette
[i
];
254 palette
[i
] = tmp_color
;
255 /* indicate where the color went */
256 png_ptr
->dither_index
[j
] = (png_byte
)i
;
257 png_ptr
->dither_index
[i
] = (png_byte
)j
;
261 /* find closest color for those colors we are not using */
262 for (i
= 0; i
< num_palette
; i
++)
264 if ((int)png_ptr
->dither_index
[i
] >= maximum_colors
)
266 int min_d
, k
, min_k
, d_index
;
268 /* find the closest color to one we threw out */
269 d_index
= png_ptr
->dither_index
[i
];
270 min_d
= PNG_COLOR_DIST(palette
[d_index
], palette
[0]);
271 for (k
= 1, min_k
= 0; k
< maximum_colors
; k
++)
275 d
= PNG_COLOR_DIST(palette
[d_index
], palette
[k
]);
283 /* point to closest color */
284 png_ptr
->dither_index
[i
] = (png_byte
)min_k
;
288 png_free(png_ptr
, png_ptr
->dither_sort
);
289 png_ptr
->dither_sort
=NULL
;
293 /* This is much harder to do simply (and quickly). Perhaps
294 we need to go through a median cut routine, but those
295 don't always behave themselves with only a few colors
296 as input. So we will just find the closest two colors,
297 and throw out one of them (chosen somewhat randomly).
298 [We don't understand this at all, so if someone wants to
299 work on improving it, be our guest - AED, GRP]
309 /* initialize palette index arrays */
310 png_ptr
->index_to_palette
= (png_bytep
)png_malloc(png_ptr
,
311 (png_uint_32
)(num_palette
* sizeof (png_byte
)));
312 png_ptr
->palette_to_index
= (png_bytep
)png_malloc(png_ptr
,
313 (png_uint_32
)(num_palette
* sizeof (png_byte
)));
315 /* initialize the sort array */
316 for (i
= 0; i
< num_palette
; i
++)
318 png_ptr
->index_to_palette
[i
] = (png_byte
)i
;
319 png_ptr
->palette_to_index
[i
] = (png_byte
)i
;
322 hash
= (png_dsortpp
)png_malloc(png_ptr
, (png_uint_32
)(769 *
323 sizeof (png_dsortp
)));
324 for (i
= 0; i
< 769; i
++)
326 /* png_memset(hash, 0, 769 * sizeof (png_dsortp)); */
328 num_new_palette
= num_palette
;
330 /* initial wild guess at how far apart the farthest pixel
331 pair we will be eliminating will be. Larger
332 numbers mean more areas will be allocated, Smaller
333 numbers run the risk of not saving enough data, and
334 having to do this all over again.
336 I have not done extensive checking on this number.
340 while (num_new_palette
> maximum_colors
)
342 for (i
= 0; i
< num_new_palette
- 1; i
++)
346 for (j
= i
+ 1; j
< num_new_palette
; j
++)
350 d
= PNG_COLOR_DIST(palette
[i
], palette
[j
]);
355 t
= (png_dsortp
)png_malloc_warn(png_ptr
,
356 (png_uint_32
)(sizeof(png_dsort
)));
360 t
->left
= (png_byte
)i
;
361 t
->right
= (png_byte
)j
;
370 for (i
= 0; i
<= max_d
; i
++)
376 for (p
= hash
[i
]; p
; p
= p
->next
)
378 if ((int)png_ptr
->index_to_palette
[p
->left
]
380 (int)png_ptr
->index_to_palette
[p
->right
]
385 if (num_new_palette
& 0x01)
397 palette
[png_ptr
->index_to_palette
[j
]]
398 = palette
[num_new_palette
];
403 for (k
= 0; k
< num_palette
; k
++)
405 if (png_ptr
->dither_index
[k
] ==
406 png_ptr
->index_to_palette
[j
])
407 png_ptr
->dither_index
[k
] =
408 png_ptr
->index_to_palette
[next_j
];
409 if ((int)png_ptr
->dither_index
[k
] ==
411 png_ptr
->dither_index
[k
] =
412 png_ptr
->index_to_palette
[j
];
416 png_ptr
->index_to_palette
[png_ptr
->palette_to_index
417 [num_new_palette
]] = png_ptr
->index_to_palette
[j
];
418 png_ptr
->palette_to_index
[png_ptr
->index_to_palette
[j
]]
419 = png_ptr
->palette_to_index
[num_new_palette
];
421 png_ptr
->index_to_palette
[j
] = (png_byte
)num_new_palette
;
422 png_ptr
->palette_to_index
[num_new_palette
] = (png_byte
)j
;
424 if (num_new_palette
<= maximum_colors
)
427 if (num_new_palette
<= maximum_colors
)
432 for (i
= 0; i
< 769; i
++)
436 png_dsortp p
= hash
[i
];
440 png_free(png_ptr
, p
);
448 png_free(png_ptr
, hash
);
449 png_free(png_ptr
, png_ptr
->palette_to_index
);
450 png_free(png_ptr
, png_ptr
->index_to_palette
);
451 png_ptr
->palette_to_index
=NULL
;
452 png_ptr
->index_to_palette
=NULL
;
454 num_palette
= maximum_colors
;
456 if (png_ptr
->palette
== NULL
)
458 png_ptr
->palette
= palette
;
460 png_ptr
->num_palette
= (png_uint_16
)num_palette
;
466 int total_bits
= PNG_DITHER_RED_BITS
+ PNG_DITHER_GREEN_BITS
+
467 PNG_DITHER_BLUE_BITS
;
468 int num_red
= (1 << PNG_DITHER_RED_BITS
);
469 int num_green
= (1 << PNG_DITHER_GREEN_BITS
);
470 int num_blue
= (1 << PNG_DITHER_BLUE_BITS
);
471 png_size_t num_entries
= ((png_size_t
)1 << total_bits
);
473 png_ptr
->palette_lookup
= (png_bytep
)png_malloc(png_ptr
,
474 (png_uint_32
)(num_entries
* sizeof (png_byte
)));
476 png_memset(png_ptr
->palette_lookup
, 0, num_entries
* sizeof (png_byte
));
478 distance
= (png_bytep
)png_malloc(png_ptr
, (png_uint_32
)(num_entries
*
481 png_memset(distance
, 0xff, num_entries
* sizeof(png_byte
));
483 for (i
= 0; i
< num_palette
; i
++)
486 int r
= (palette
[i
].red
>> (8 - PNG_DITHER_RED_BITS
));
487 int g
= (palette
[i
].green
>> (8 - PNG_DITHER_GREEN_BITS
));
488 int b
= (palette
[i
].blue
>> (8 - PNG_DITHER_BLUE_BITS
));
490 for (ir
= 0; ir
< num_red
; ir
++)
492 int dr
= abs(ir
- r
);
493 int index_r
= (ir
<< (PNG_DITHER_BLUE_BITS
+ PNG_DITHER_GREEN_BITS
));
495 for (ig
= 0; ig
< num_green
; ig
++)
497 int dg
= abs(ig
- g
);
499 int dm
= ((dr
> dg
) ? dr
: dg
);
500 int index_g
= index_r
| (ig
<< PNG_DITHER_BLUE_BITS
);
502 for (ib
= 0; ib
< num_blue
; ib
++)
504 int d_index
= index_g
| ib
;
505 int db
= abs(ib
- b
);
506 int dmax
= ((dm
> db
) ? dm
: db
);
507 int d
= dmax
+ dt
+ db
;
509 if (d
< (int)distance
[d_index
])
511 distance
[d_index
] = (png_byte
)d
;
512 png_ptr
->palette_lookup
[d_index
] = (png_byte
)i
;
519 png_free(png_ptr
, distance
);
524 #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
525 /* Transform the image from the file_gamma to the screen_gamma. We
526 * only do transformations on images where the file_gamma and screen_gamma
527 * are not close reciprocals, otherwise it slows things down slightly, and
528 * also needlessly introduces small errors.
530 * We will turn off gamma transformation later if no semitransparent entries
531 * are present in the tRNS array for palette images. We can't do it here
532 * because we don't necessarily have the tRNS chunk yet.
535 png_set_gamma(png_structp png_ptr
, double scrn_gamma
, double file_gamma
)
537 png_debug(1, "in png_set_gamma\n");
538 if ((fabs(scrn_gamma
* file_gamma
- 1.0) > PNG_GAMMA_THRESHOLD
) ||
539 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
) ||
540 (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
))
541 png_ptr
->transformations
|= PNG_GAMMA
;
542 png_ptr
->gamma
= (float)file_gamma
;
543 png_ptr
->screen_gamma
= (float)scrn_gamma
;
547 #if defined(PNG_READ_EXPAND_SUPPORTED)
548 /* Expand paletted images to RGB, expand grayscale images of
549 * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
553 png_set_expand(png_structp png_ptr
)
555 png_debug(1, "in png_set_expand\n");
556 png_ptr
->transformations
|= PNG_EXPAND
;
559 /* GRR 19990627: the following three functions currently are identical
560 * to png_set_expand(). However, it is entirely reasonable that someone
561 * might wish to expand an indexed image to RGB but *not* expand a single,
562 * fully transparent palette entry to a full alpha channel--perhaps instead
563 * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
564 * the transparent color with a particular RGB value, or drop tRNS entirely.
565 * IOW, a future version of the library may make the transformations flag
566 * a bit more fine-grained, with separate bits for each of these three
569 * More to the point, these functions make it obvious what libpng will be
570 * doing, whereas "expand" can (and does) mean any number of things.
573 /* Expand paletted images to RGB. */
575 png_set_palette_to_rgb(png_structp png_ptr
)
577 png_debug(1, "in png_set_expand\n");
578 png_ptr
->transformations
|= PNG_EXPAND
;
581 /* Expand grayscale images of less than 8-bit depth to 8 bits. */
583 png_set_gray_1_2_4_to_8(png_structp png_ptr
)
585 png_debug(1, "in png_set_expand\n");
586 png_ptr
->transformations
|= PNG_EXPAND
;
589 /* Expand tRNS chunks to alpha channels. */
591 png_set_tRNS_to_alpha(png_structp png_ptr
)
593 png_debug(1, "in png_set_expand\n");
594 png_ptr
->transformations
|= PNG_EXPAND
;
596 #endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
598 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
600 png_set_gray_to_rgb(png_structp png_ptr
)
602 png_debug(1, "in png_set_gray_to_rgb\n");
603 png_ptr
->transformations
|= PNG_GRAY_TO_RGB
;
607 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
608 #if defined(PNG_FLOATING_POINT_SUPPORTED)
609 /* Convert a RGB image to a grayscale of the same width. This allows us,
610 * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
614 png_set_rgb_to_gray(png_structp png_ptr
, int error_action
, double red
,
617 int red_fixed
= (int)((float)red
*100000.0 + 0.5);
618 int green_fixed
= (int)((float)green
*100000.0 + 0.5);
619 png_set_rgb_to_gray_fixed(png_ptr
, error_action
, red_fixed
, green_fixed
);
624 png_set_rgb_to_gray_fixed(png_structp png_ptr
, int error_action
,
625 png_fixed_point red
, png_fixed_point green
)
627 png_debug(1, "in png_set_rgb_to_gray\n");
630 case 1: png_ptr
->transformations
|= PNG_RGB_TO_GRAY
;
632 case 2: png_ptr
->transformations
|= PNG_RGB_TO_GRAY_WARN
;
634 case 3: png_ptr
->transformations
|= PNG_RGB_TO_GRAY_ERR
;
636 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
637 #if defined(PNG_READ_EXPAND_SUPPORTED)
638 png_ptr
->transformations
|= PNG_EXPAND
;
641 png_warning(png_ptr
, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
642 png_ptr
->transformations
&= ~PNG_RGB_TO_GRAY
;
646 png_uint_16 red_int
, green_int
;
647 if(red
< 0 || green
< 0)
649 red_int
= 6968; /* .212671 * 32768 + .5 */
650 green_int
= 23434; /* .715160 * 32768 + .5 */
652 else if(red
+ green
< 100000L)
654 red_int
= (png_uint_16
)(((png_uint_32
)red
*32768L)/100000L);
655 green_int
= (png_uint_16
)(((png_uint_32
)green
*32768L)/100000L);
659 png_warning(png_ptr
, "ignoring out of range rgb_to_gray coefficients");
663 png_ptr
->rgb_to_gray_red_coeff
= red_int
;
664 png_ptr
->rgb_to_gray_green_coeff
= green_int
;
665 png_ptr
->rgb_to_gray_blue_coeff
= (png_uint_16
)(32768-red_int
-green_int
);
670 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
671 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
672 defined(PNG_LEGACY_SUPPORTED)
674 png_set_read_user_transform_fn(png_structp png_ptr
, png_user_transform_ptr
675 read_user_transform_fn
)
677 png_debug(1, "in png_set_read_user_transform_fn\n");
678 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
679 png_ptr
->transformations
|= PNG_USER_TRANSFORM
;
680 png_ptr
->read_user_transform_fn
= read_user_transform_fn
;
682 #ifdef PNG_LEGACY_SUPPORTED
683 if(read_user_transform_fn
)
685 "This version of libpng does not support user transforms");
690 /* Initialize everything needed for the read. This includes modifying
694 png_init_read_transformations(png_structp png_ptr
)
696 png_debug(1, "in png_init_read_transformations\n");
697 #if defined(PNG_USELESS_TESTS_SUPPORTED)
701 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
702 || defined(PNG_READ_GAMMA_SUPPORTED)
703 int color_type
= png_ptr
->color_type
;
706 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
707 if ((png_ptr
->transformations
& PNG_BACKGROUND_EXPAND
) &&
708 (png_ptr
->transformations
& PNG_EXPAND
))
710 if (!(color_type
& PNG_COLOR_MASK_COLOR
)) /* i.e., GRAY or GRAY_ALPHA */
712 /* expand background chunk. */
713 switch (png_ptr
->bit_depth
)
716 png_ptr
->background
.gray
*= (png_uint_16
)0xff;
717 png_ptr
->background
.red
= png_ptr
->background
.green
718 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
721 png_ptr
->background
.gray
*= (png_uint_16
)0x55;
722 png_ptr
->background
.red
= png_ptr
->background
.green
723 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
726 png_ptr
->background
.gray
*= (png_uint_16
)0x11;
727 png_ptr
->background
.red
= png_ptr
->background
.green
728 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
732 png_ptr
->background
.red
= png_ptr
->background
.green
733 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
737 else if (color_type
== PNG_COLOR_TYPE_PALETTE
)
739 png_ptr
->background
.red
=
740 png_ptr
->palette
[png_ptr
->background
.index
].red
;
741 png_ptr
->background
.green
=
742 png_ptr
->palette
[png_ptr
->background
.index
].green
;
743 png_ptr
->background
.blue
=
744 png_ptr
->palette
[png_ptr
->background
.index
].blue
;
746 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
747 if (png_ptr
->transformations
& PNG_INVERT_ALPHA
)
749 #if defined(PNG_READ_EXPAND_SUPPORTED)
750 if (!(png_ptr
->transformations
& PNG_EXPAND
))
753 /* invert the alpha channel (in tRNS) unless the pixels are
754 going to be expanded, in which case leave it for later */
756 istop
=(int)png_ptr
->num_trans
;
757 for (i
=0; i
<istop
; i
++)
758 png_ptr
->trans
[i
] = (png_byte
)(255 - png_ptr
->trans
[i
]);
767 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
768 png_ptr
->background_1
= png_ptr
->background
;
770 #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
772 if ((color_type
== PNG_COLOR_TYPE_PALETTE
&& png_ptr
->num_trans
!= 0)
773 && (fabs(png_ptr
->screen_gamma
* png_ptr
->gamma
- 1.0)
774 < PNG_GAMMA_THRESHOLD
))
778 for (i
=0; i
<png_ptr
->num_trans
; i
++)
780 if (png_ptr
->trans
[i
] != 0 && png_ptr
->trans
[i
] != 0xff)
781 k
=1; /* partial transparency is present */
784 png_ptr
->transformations
&= (~PNG_GAMMA
);
787 if (png_ptr
->transformations
& (PNG_GAMMA
| PNG_RGB_TO_GRAY
))
789 png_build_gamma_table(png_ptr
);
790 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
791 if (png_ptr
->transformations
& PNG_BACKGROUND
)
793 if (color_type
== PNG_COLOR_TYPE_PALETTE
)
795 /* could skip if no transparency and
797 png_color back
, back_1
;
798 png_colorp palette
= png_ptr
->palette
;
799 int num_palette
= png_ptr
->num_palette
;
801 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_FILE
)
803 back
.red
= png_ptr
->gamma_table
[png_ptr
->background
.red
];
804 back
.green
= png_ptr
->gamma_table
[png_ptr
->background
.green
];
805 back
.blue
= png_ptr
->gamma_table
[png_ptr
->background
.blue
];
807 back_1
.red
= png_ptr
->gamma_to_1
[png_ptr
->background
.red
];
808 back_1
.green
= png_ptr
->gamma_to_1
[png_ptr
->background
.green
];
809 back_1
.blue
= png_ptr
->gamma_to_1
[png_ptr
->background
.blue
];
815 switch (png_ptr
->background_gamma_type
)
817 case PNG_BACKGROUND_GAMMA_SCREEN
:
818 g
= (png_ptr
->screen_gamma
);
821 case PNG_BACKGROUND_GAMMA_FILE
:
822 g
= 1.0 / (png_ptr
->gamma
);
823 gs
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
825 case PNG_BACKGROUND_GAMMA_UNIQUE
:
826 g
= 1.0 / (png_ptr
->background_gamma
);
827 gs
= 1.0 / (png_ptr
->background_gamma
*
828 png_ptr
->screen_gamma
);
831 g
= 1.0; /* back_1 */
835 if ( fabs(gs
- 1.0) < PNG_GAMMA_THRESHOLD
)
837 back
.red
= (png_byte
)png_ptr
->background
.red
;
838 back
.green
= (png_byte
)png_ptr
->background
.green
;
839 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
843 back
.red
= (png_byte
)(pow(
844 (double)png_ptr
->background
.red
/255, gs
) * 255.0 + .5);
845 back
.green
= (png_byte
)(pow(
846 (double)png_ptr
->background
.green
/255, gs
) * 255.0 + .5);
847 back
.blue
= (png_byte
)(pow(
848 (double)png_ptr
->background
.blue
/255, gs
) * 255.0 + .5);
851 back_1
.red
= (png_byte
)(pow(
852 (double)png_ptr
->background
.red
/255, g
) * 255.0 + .5);
853 back_1
.green
= (png_byte
)(pow(
854 (double)png_ptr
->background
.green
/255, g
) * 255.0 + .5);
855 back_1
.blue
= (png_byte
)(pow(
856 (double)png_ptr
->background
.blue
/255, g
) * 255.0 + .5);
858 for (i
= 0; i
< num_palette
; i
++)
860 if (i
< (int)png_ptr
->num_trans
&& png_ptr
->trans
[i
] != 0xff)
862 if (png_ptr
->trans
[i
] == 0)
866 else /* if (png_ptr->trans[i] != 0xff) */
870 v
= png_ptr
->gamma_to_1
[palette
[i
].red
];
871 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.red
);
872 palette
[i
].red
= png_ptr
->gamma_from_1
[w
];
874 v
= png_ptr
->gamma_to_1
[palette
[i
].green
];
875 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.green
);
876 palette
[i
].green
= png_ptr
->gamma_from_1
[w
];
878 v
= png_ptr
->gamma_to_1
[palette
[i
].blue
];
879 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.blue
);
880 palette
[i
].blue
= png_ptr
->gamma_from_1
[w
];
885 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
886 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
887 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
891 /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
893 /* color_type != PNG_COLOR_TYPE_PALETTE */
895 double m
= (double)(((png_uint_32
)1 << png_ptr
->bit_depth
) - 1);
899 switch (png_ptr
->background_gamma_type
)
901 case PNG_BACKGROUND_GAMMA_SCREEN
:
902 g
= (png_ptr
->screen_gamma
);
905 case PNG_BACKGROUND_GAMMA_FILE
:
906 g
= 1.0 / (png_ptr
->gamma
);
907 gs
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
909 case PNG_BACKGROUND_GAMMA_UNIQUE
:
910 g
= 1.0 / (png_ptr
->background_gamma
);
911 gs
= 1.0 / (png_ptr
->background_gamma
*
912 png_ptr
->screen_gamma
);
916 png_ptr
->background_1
.gray
= (png_uint_16
)(pow(
917 (double)png_ptr
->background
.gray
/ m
, g
) * m
+ .5);
918 png_ptr
->background
.gray
= (png_uint_16
)(pow(
919 (double)png_ptr
->background
.gray
/ m
, gs
) * m
+ .5);
921 if ((png_ptr
->background
.red
!= png_ptr
->background
.green
) ||
922 (png_ptr
->background
.red
!= png_ptr
->background
.blue
) ||
923 (png_ptr
->background
.red
!= png_ptr
->background
.gray
))
925 /* RGB or RGBA with color background */
926 png_ptr
->background_1
.red
= (png_uint_16
)(pow(
927 (double)png_ptr
->background
.red
/ m
, g
) * m
+ .5);
928 png_ptr
->background_1
.green
= (png_uint_16
)(pow(
929 (double)png_ptr
->background
.green
/ m
, g
) * m
+ .5);
930 png_ptr
->background_1
.blue
= (png_uint_16
)(pow(
931 (double)png_ptr
->background
.blue
/ m
, g
) * m
+ .5);
932 png_ptr
->background
.red
= (png_uint_16
)(pow(
933 (double)png_ptr
->background
.red
/ m
, gs
) * m
+ .5);
934 png_ptr
->background
.green
= (png_uint_16
)(pow(
935 (double)png_ptr
->background
.green
/ m
, gs
) * m
+ .5);
936 png_ptr
->background
.blue
= (png_uint_16
)(pow(
937 (double)png_ptr
->background
.blue
/ m
, gs
) * m
+ .5);
941 /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
942 png_ptr
->background_1
.red
= png_ptr
->background_1
.green
943 = png_ptr
->background_1
.blue
= png_ptr
->background_1
.gray
;
944 png_ptr
->background
.red
= png_ptr
->background
.green
945 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
950 /* transformation does not include PNG_BACKGROUND */
951 #endif /* PNG_READ_BACKGROUND_SUPPORTED */
952 if (color_type
== PNG_COLOR_TYPE_PALETTE
)
954 png_colorp palette
= png_ptr
->palette
;
955 int num_palette
= png_ptr
->num_palette
;
958 for (i
= 0; i
< num_palette
; i
++)
960 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
961 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
962 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
966 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
969 #endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */
970 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
971 /* No GAMMA transformation */
972 if ((png_ptr
->transformations
& PNG_BACKGROUND
) &&
973 (color_type
== PNG_COLOR_TYPE_PALETTE
))
976 int istop
= (int)png_ptr
->num_trans
;
978 png_colorp palette
= png_ptr
->palette
;
980 back
.red
= (png_byte
)png_ptr
->background
.red
;
981 back
.green
= (png_byte
)png_ptr
->background
.green
;
982 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
984 for (i
= 0; i
< istop
; i
++)
986 if (png_ptr
->trans
[i
] == 0)
990 else if (png_ptr
->trans
[i
] != 0xff)
992 /* The png_composite() macro is defined in png.h */
993 png_composite(palette
[i
].red
, palette
[i
].red
,
994 png_ptr
->trans
[i
], back
.red
);
995 png_composite(palette
[i
].green
, palette
[i
].green
,
996 png_ptr
->trans
[i
], back
.green
);
997 png_composite(palette
[i
].blue
, palette
[i
].blue
,
998 png_ptr
->trans
[i
], back
.blue
);
1002 #endif /* PNG_READ_BACKGROUND_SUPPORTED */
1004 #if defined(PNG_READ_SHIFT_SUPPORTED)
1005 if ((png_ptr
->transformations
& PNG_SHIFT
) &&
1006 (color_type
== PNG_COLOR_TYPE_PALETTE
))
1009 png_uint_16 istop
= png_ptr
->num_palette
;
1010 int sr
= 8 - png_ptr
->sig_bit
.red
;
1011 int sg
= 8 - png_ptr
->sig_bit
.green
;
1012 int sb
= 8 - png_ptr
->sig_bit
.blue
;
1014 if (sr
< 0 || sr
> 8)
1016 if (sg
< 0 || sg
> 8)
1018 if (sb
< 0 || sb
> 8)
1020 for (i
= 0; i
< istop
; i
++)
1022 png_ptr
->palette
[i
].red
>>= sr
;
1023 png_ptr
->palette
[i
].green
>>= sg
;
1024 png_ptr
->palette
[i
].blue
>>= sb
;
1027 #endif /* PNG_READ_SHIFT_SUPPORTED */
1029 #if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
1030 && !defined(PNG_READ_BACKGROUND_SUPPORTED)
1036 /* Modify the info structure to reflect the transformations. The
1037 * info should be updated so a PNG file could be written with it,
1038 * assuming the transformations result in valid PNG data.
1041 png_read_transform_info(png_structp png_ptr
, png_infop info_ptr
)
1043 png_debug(1, "in png_read_transform_info\n");
1044 #if defined(PNG_READ_EXPAND_SUPPORTED)
1045 if (png_ptr
->transformations
& PNG_EXPAND
)
1047 if (info_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1049 if (png_ptr
->num_trans
)
1050 info_ptr
->color_type
= PNG_COLOR_TYPE_RGB_ALPHA
;
1052 info_ptr
->color_type
= PNG_COLOR_TYPE_RGB
;
1053 info_ptr
->bit_depth
= 8;
1054 info_ptr
->num_trans
= 0;
1058 if (png_ptr
->num_trans
)
1059 info_ptr
->color_type
|= PNG_COLOR_MASK_ALPHA
;
1060 if (info_ptr
->bit_depth
< 8)
1061 info_ptr
->bit_depth
= 8;
1062 info_ptr
->num_trans
= 0;
1067 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1068 if (png_ptr
->transformations
& PNG_BACKGROUND
)
1070 info_ptr
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
1071 info_ptr
->num_trans
= 0;
1072 info_ptr
->background
= png_ptr
->background
;
1076 #if defined(PNG_READ_GAMMA_SUPPORTED)
1077 if (png_ptr
->transformations
& PNG_GAMMA
)
1079 #ifdef PNG_FLOATING_POINT_SUPPORTED
1080 info_ptr
->gamma
= png_ptr
->gamma
;
1082 #ifdef PNG_FIXED_POINT_SUPPORTED
1083 info_ptr
->int_gamma
= png_ptr
->int_gamma
;
1088 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1089 if ((png_ptr
->transformations
& PNG_16_TO_8
) && (info_ptr
->bit_depth
== 16))
1090 info_ptr
->bit_depth
= 8;
1093 #if defined(PNG_READ_DITHER_SUPPORTED)
1094 if (png_ptr
->transformations
& PNG_DITHER
)
1096 if (((info_ptr
->color_type
== PNG_COLOR_TYPE_RGB
) ||
1097 (info_ptr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)) &&
1098 png_ptr
->palette_lookup
&& info_ptr
->bit_depth
== 8)
1100 info_ptr
->color_type
= PNG_COLOR_TYPE_PALETTE
;
1105 #if defined(PNG_READ_PACK_SUPPORTED)
1106 if ((png_ptr
->transformations
& PNG_PACK
) && (info_ptr
->bit_depth
< 8))
1107 info_ptr
->bit_depth
= 8;
1110 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1111 if (png_ptr
->transformations
& PNG_GRAY_TO_RGB
)
1112 info_ptr
->color_type
|= PNG_COLOR_MASK_COLOR
;
1115 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1116 if (png_ptr
->transformations
& PNG_RGB_TO_GRAY
)
1117 info_ptr
->color_type
&= ~PNG_COLOR_MASK_COLOR
;
1120 if (info_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1121 info_ptr
->channels
= 1;
1122 else if (info_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
1123 info_ptr
->channels
= 3;
1125 info_ptr
->channels
= 1;
1127 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1128 if (png_ptr
->transformations
& PNG_STRIP_ALPHA
)
1129 info_ptr
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
1132 if (info_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
)
1133 info_ptr
->channels
++;
1135 #if defined(PNG_READ_FILLER_SUPPORTED)
1136 /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
1137 if ((png_ptr
->transformations
& PNG_FILLER
) &&
1138 ((info_ptr
->color_type
== PNG_COLOR_TYPE_RGB
) ||
1139 (info_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)))
1141 info_ptr
->channels
++;
1142 #if 0 /* if adding a true alpha channel not just filler */
1143 info_ptr
->color_type
|= PNG_COLOR_MASK_ALPHA
;
1148 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
1149 defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1150 if(png_ptr
->transformations
& PNG_USER_TRANSFORM
)
1152 if(info_ptr
->bit_depth
< png_ptr
->user_transform_depth
)
1153 info_ptr
->bit_depth
= png_ptr
->user_transform_depth
;
1154 if(info_ptr
->channels
< png_ptr
->user_transform_channels
)
1155 info_ptr
->channels
= png_ptr
->user_transform_channels
;
1159 info_ptr
->pixel_depth
= (png_byte
)(info_ptr
->channels
*
1160 info_ptr
->bit_depth
);
1161 info_ptr
->rowbytes
= ((info_ptr
->width
* info_ptr
->pixel_depth
+ 7) >> 3);
1163 #if !defined(PNG_READ_EXPAND_SUPPORTED)
1169 /* Transform the row. The order of transformations is significant,
1170 * and is very touchy. If you add a transformation, take care to
1171 * decide how it fits in with the other transformations here.
1174 png_do_read_transformations(png_structp png_ptr
)
1176 png_debug(1, "in png_do_read_transformations\n");
1177 #if !defined(PNG_USELESS_TESTS_SUPPORTED)
1178 if (png_ptr
->row_buf
== NULL
)
1180 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
1183 sprintf(msg
, "NULL row buffer for row %ld, pass %d", png_ptr
->row_number
,
1185 png_error(png_ptr
, msg
);
1187 png_error(png_ptr
, "NULL row buffer");
1192 #if defined(PNG_READ_EXPAND_SUPPORTED)
1193 if (png_ptr
->transformations
& PNG_EXPAND
)
1195 if (png_ptr
->row_info
.color_type
== PNG_COLOR_TYPE_PALETTE
)
1197 png_do_expand_palette(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1198 png_ptr
->palette
, png_ptr
->trans
, png_ptr
->num_trans
);
1202 if (png_ptr
->num_trans
)
1203 png_do_expand(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1204 &(png_ptr
->trans_values
));
1206 png_do_expand(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1212 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1213 if (png_ptr
->transformations
& PNG_STRIP_ALPHA
)
1214 png_do_strip_filler(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1215 PNG_FLAG_FILLER_AFTER
);
1218 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1219 if (png_ptr
->transformations
& PNG_RGB_TO_GRAY
)
1222 png_do_rgb_to_gray(png_ptr
, &(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1225 png_ptr
->rgb_to_gray_status
=1;
1226 if(png_ptr
->transformations
== PNG_RGB_TO_GRAY_WARN
)
1227 png_warning(png_ptr
, "png_do_rgb_to_gray found nongray pixel");
1228 if(png_ptr
->transformations
== PNG_RGB_TO_GRAY_ERR
)
1229 png_error(png_ptr
, "png_do_rgb_to_gray found nongray pixel");
1235 From Andreas Dilger e-mail to png-implement, 26 March 1998:
1237 In most cases, the "simple transparency" should be done prior to doing
1238 gray-to-RGB, or you will have to test 3x as many bytes to check if a
1239 pixel is transparent. You would also need to make sure that the
1240 transparency information is upgraded to RGB.
1242 To summarize, the current flow is:
1243 - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
1244 with background "in place" if transparent,
1245 convert to RGB if necessary
1246 - Gray + alpha -> composite with gray background and remove alpha bytes,
1247 convert to RGB if necessary
1249 To support RGB backgrounds for gray images we need:
1250 - Gray + simple transparency -> convert to RGB + simple transparency, compare
1251 3 or 6 bytes and composite with background
1252 "in place" if transparent (3x compare/pixel
1253 compared to doing composite with gray bkgrnd)
1254 - Gray + alpha -> convert to RGB + alpha, composite with background and
1255 remove alpha bytes (3x float operations/pixel
1256 compared with composite on gray background)
1258 Greg's change will do this. The reason it wasn't done before is for
1259 performance, as this increases the per-pixel operations. If we would check
1260 in advance if the background was gray or RGB, and position the gray-to-RGB
1261 transform appropriately, then it would save a lot of work/time.
1264 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1265 /* if gray -> RGB, do so now only if background is non-gray; else do later
1266 * for performance reasons */
1267 if ((png_ptr
->transformations
& PNG_GRAY_TO_RGB
) &&
1268 !(png_ptr
->mode
& PNG_BACKGROUND_IS_GRAY
))
1269 png_do_gray_to_rgb(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1272 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1273 if ((png_ptr
->transformations
& PNG_BACKGROUND
) &&
1274 ((png_ptr
->num_trans
!= 0 ) ||
1275 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
)))
1276 png_do_background(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1277 &(png_ptr
->trans_values
), &(png_ptr
->background
)
1278 #if defined(PNG_READ_GAMMA_SUPPORTED)
1279 , &(png_ptr
->background_1
),
1280 png_ptr
->gamma_table
, png_ptr
->gamma_from_1
,
1281 png_ptr
->gamma_to_1
, png_ptr
->gamma_16_table
,
1282 png_ptr
->gamma_16_from_1
, png_ptr
->gamma_16_to_1
,
1283 png_ptr
->gamma_shift
1288 #if defined(PNG_READ_GAMMA_SUPPORTED)
1289 if ((png_ptr
->transformations
& PNG_GAMMA
) &&
1290 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1291 !((png_ptr
->transformations
& PNG_BACKGROUND
) &&
1292 ((png_ptr
->num_trans
!= 0) ||
1293 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
))) &&
1295 (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
))
1296 png_do_gamma(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1297 png_ptr
->gamma_table
, png_ptr
->gamma_16_table
,
1298 png_ptr
->gamma_shift
);
1301 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1302 if (png_ptr
->transformations
& PNG_16_TO_8
)
1303 png_do_chop(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1306 #if defined(PNG_READ_DITHER_SUPPORTED)
1307 if (png_ptr
->transformations
& PNG_DITHER
)
1309 png_do_dither((png_row_infop
)&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1310 png_ptr
->palette_lookup
, png_ptr
->dither_index
);
1311 if(png_ptr
->row_info
.rowbytes
== (png_uint_32
)0)
1312 png_error(png_ptr
, "png_do_dither returned rowbytes=0");
1316 #if defined(PNG_READ_INVERT_SUPPORTED)
1317 if (png_ptr
->transformations
& PNG_INVERT_MONO
)
1318 png_do_invert(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1321 #if defined(PNG_READ_SHIFT_SUPPORTED)
1322 if (png_ptr
->transformations
& PNG_SHIFT
)
1323 png_do_unshift(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1327 #if defined(PNG_READ_PACK_SUPPORTED)
1328 if (png_ptr
->transformations
& PNG_PACK
)
1329 png_do_unpack(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1332 #if defined(PNG_READ_BGR_SUPPORTED)
1333 if (png_ptr
->transformations
& PNG_BGR
)
1334 png_do_bgr(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1337 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1338 if (png_ptr
->transformations
& PNG_PACKSWAP
)
1339 png_do_packswap(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1342 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1343 /* if gray -> RGB, do so now only if we did not do so above */
1344 if ((png_ptr
->transformations
& PNG_GRAY_TO_RGB
) &&
1345 (png_ptr
->mode
& PNG_BACKGROUND_IS_GRAY
))
1346 png_do_gray_to_rgb(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1349 #if defined(PNG_READ_FILLER_SUPPORTED)
1350 if (png_ptr
->transformations
& PNG_FILLER
)
1351 png_do_read_filler(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1352 (png_uint_32
)png_ptr
->filler
, png_ptr
->flags
);
1355 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1356 if (png_ptr
->transformations
& PNG_INVERT_ALPHA
)
1357 png_do_read_invert_alpha(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1360 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1361 if (png_ptr
->transformations
& PNG_SWAP_ALPHA
)
1362 png_do_read_swap_alpha(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1365 #if defined(PNG_READ_SWAP_SUPPORTED)
1366 if (png_ptr
->transformations
& PNG_SWAP_BYTES
)
1367 png_do_swap(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1370 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1371 if (png_ptr
->transformations
& PNG_USER_TRANSFORM
)
1373 if(png_ptr
->read_user_transform_fn
!= NULL
)
1374 (*(png_ptr
->read_user_transform_fn
)) /* user read transform function */
1375 (png_ptr
, /* png_ptr */
1376 &(png_ptr
->row_info
), /* row_info: */
1377 /* png_uint_32 width; width of row */
1378 /* png_uint_32 rowbytes; number of bytes in row */
1379 /* png_byte color_type; color type of pixels */
1380 /* png_byte bit_depth; bit depth of samples */
1381 /* png_byte channels; number of channels (1-4) */
1382 /* png_byte pixel_depth; bits per pixel (depth*channels) */
1383 png_ptr
->row_buf
+ 1); /* start of pixel data for row */
1384 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
1385 if(png_ptr
->user_transform_depth
)
1386 png_ptr
->row_info
.bit_depth
= png_ptr
->user_transform_depth
;
1387 if(png_ptr
->user_transform_channels
)
1388 png_ptr
->row_info
.channels
= png_ptr
->user_transform_channels
;
1390 png_ptr
->row_info
.pixel_depth
= (png_byte
)(png_ptr
->row_info
.bit_depth
*
1391 png_ptr
->row_info
.channels
);
1392 png_ptr
->row_info
.rowbytes
= (png_ptr
->row_info
.width
*
1393 png_ptr
->row_info
.pixel_depth
+7)>>3;
1399 #if defined(PNG_READ_PACK_SUPPORTED)
1400 /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
1401 * without changing the actual values. Thus, if you had a row with
1402 * a bit depth of 1, you would end up with bytes that only contained
1403 * the numbers 0 or 1. If you would rather they contain 0 and 255, use
1404 * png_do_shift() after this.
1407 png_do_unpack(png_row_infop row_info
, png_bytep row
)
1409 png_debug(1, "in png_do_unpack\n");
1410 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1411 if (row
!= NULL
&& row_info
!= NULL
&& row_info
->bit_depth
< 8)
1413 if (row_info
->bit_depth
< 8)
1417 png_uint_32 row_width
=row_info
->width
;
1419 switch (row_info
->bit_depth
)
1423 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
1424 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1425 png_uint_32 shift
= 7 - (int)((row_width
+ 7) & 0x07);
1426 for (i
= 0; i
< row_width
; i
++)
1428 *dp
= (png_byte
)((*sp
>> shift
) & 0x01);
1444 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
1445 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1446 png_uint_32 shift
= (int)((3 - ((row_width
+ 3) & 0x03)) << 1);
1447 for (i
= 0; i
< row_width
; i
++)
1449 *dp
= (png_byte
)((*sp
>> shift
) & 0x03);
1464 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
1465 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1466 png_uint_32 shift
= (int)((1 - ((row_width
+ 1) & 0x01)) << 2);
1467 for (i
= 0; i
< row_width
; i
++)
1469 *dp
= (png_byte
)((*sp
>> shift
) & 0x0f);
1483 row_info
->bit_depth
= 8;
1484 row_info
->pixel_depth
= (png_byte
)(8 * row_info
->channels
);
1485 row_info
->rowbytes
= row_width
* row_info
->channels
;
1490 #if defined(PNG_READ_SHIFT_SUPPORTED)
1491 /* Reverse the effects of png_do_shift. This routine merely shifts the
1492 * pixels back to their significant bits values. Thus, if you have
1493 * a row of bit depth 8, but only 5 are significant, this will shift
1494 * the values back to 0 through 31.
1497 png_do_unshift(png_row_infop row_info
, png_bytep row
, png_color_8p sig_bits
)
1499 png_debug(1, "in png_do_unshift\n");
1501 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1502 row
!= NULL
&& row_info
!= NULL
&& sig_bits
!= NULL
&&
1504 row_info
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
1509 png_uint_16 value
= 0;
1510 png_uint_32 row_width
= row_info
->width
;
1512 if (row_info
->color_type
& PNG_COLOR_MASK_COLOR
)
1514 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->red
;
1515 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->green
;
1516 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->blue
;
1520 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->gray
;
1522 if (row_info
->color_type
& PNG_COLOR_MASK_ALPHA
)
1524 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->alpha
;
1527 for (c
= 0; c
< channels
; c
++)
1538 switch (row_info
->bit_depth
)
1544 png_uint_32 istop
= row_info
->rowbytes
;
1546 for (bp
= row
, i
= 0; i
< istop
; i
++)
1557 png_uint_32 istop
= row_info
->rowbytes
;
1558 png_byte mask
= (png_byte
)((((int)0xf0 >> shift
[0]) & (int)0xf0) |
1559 (png_byte
)((int)0xf >> shift
[0]));
1561 for (i
= 0; i
< istop
; i
++)
1572 png_uint_32 istop
= row_width
* channels
;
1574 for (i
= 0; i
< istop
; i
++)
1576 *bp
++ >>= shift
[i%channels
];
1584 png_uint_32 istop
= channels
* row_width
;
1586 for (i
= 0; i
< istop
; i
++)
1588 value
= (png_uint_16
)((*bp
<< 8) + *(bp
+ 1));
1589 value
>>= shift
[i%channels
];
1590 *bp
++ = (png_byte
)(value
>> 8);
1591 *bp
++ = (png_byte
)(value
& 0xff);
1600 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1601 /* chop rows of bit depth 16 down to 8 */
1603 png_do_chop(png_row_infop row_info
, png_bytep row
)
1605 png_debug(1, "in png_do_chop\n");
1606 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1607 if (row
!= NULL
&& row_info
!= NULL
&& row_info
->bit_depth
== 16)
1609 if (row_info
->bit_depth
== 16)
1615 png_uint_32 istop
= row_info
->width
* row_info
->channels
;
1617 for (i
= 0; i
<istop
; i
++, sp
+= 2, dp
++)
1619 #if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
1620 /* This does a more accurate scaling of the 16-bit color
1621 * value, rather than a simple low-byte truncation.
1623 * What the ideal calculation should be:
1624 * *dp = (((((png_uint_32)(*sp) << 8) |
1625 * (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L;
1627 * GRR: no, I think this is what it really should be:
1628 * *dp = (((((png_uint_32)(*sp) << 8) |
1629 * (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L;
1631 * GRR: here's the exact calculation with shifts:
1632 * temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L;
1633 * *dp = (temp - (temp >> 8)) >> 8;
1635 * Approximate calculation with shift/add instead of multiply/divide:
1636 * *dp = ((((png_uint_32)(*sp) << 8) |
1637 * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
1639 * What we actually do to avoid extra shifting and conversion:
1642 *dp
= *sp
+ ((((int)(*(sp
+ 1)) - *sp
) > 128) ? 1 : 0);
1644 /* Simply discard the low order byte */
1648 row_info
->bit_depth
= 8;
1649 row_info
->pixel_depth
= (png_byte
)(8 * row_info
->channels
);
1650 row_info
->rowbytes
= row_info
->width
* row_info
->channels
;
1655 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1657 png_do_read_swap_alpha(png_row_infop row_info
, png_bytep row
)
1659 png_debug(1, "in png_do_read_swap_alpha\n");
1660 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1661 if (row
!= NULL
&& row_info
!= NULL
)
1664 png_uint_32 row_width
= row_info
->width
;
1665 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
1667 /* This converts from RGBA to ARGB */
1668 if (row_info
->bit_depth
== 8)
1670 png_bytep sp
= row
+ row_info
->rowbytes
;
1675 for (i
= 0; i
< row_width
; i
++)
1684 /* This converts from RRGGBBAA to AARRGGBB */
1687 png_bytep sp
= row
+ row_info
->rowbytes
;
1692 for (i
= 0; i
< row_width
; i
++)
1707 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
1709 /* This converts from GA to AG */
1710 if (row_info
->bit_depth
== 8)
1712 png_bytep sp
= row
+ row_info
->rowbytes
;
1717 for (i
= 0; i
< row_width
; i
++)
1724 /* This converts from GGAA to AAGG */
1727 png_bytep sp
= row
+ row_info
->rowbytes
;
1732 for (i
= 0; i
< row_width
; i
++)
1747 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1749 png_do_read_invert_alpha(png_row_infop row_info
, png_bytep row
)
1751 png_debug(1, "in png_do_read_invert_alpha\n");
1752 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1753 if (row
!= NULL
&& row_info
!= NULL
)
1756 png_uint_32 row_width
= row_info
->width
;
1757 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
1759 /* This inverts the alpha channel in RGBA */
1760 if (row_info
->bit_depth
== 8)
1762 png_bytep sp
= row
+ row_info
->rowbytes
;
1766 for (i
= 0; i
< row_width
; i
++)
1768 *(--dp
) = (png_byte
)(255 - *(--sp
));
1770 /* This does nothing:
1774 We can replace it with:
1780 /* This inverts the alpha channel in RRGGBBAA */
1783 png_bytep sp
= row
+ row_info
->rowbytes
;
1787 for (i
= 0; i
< row_width
; i
++)
1789 *(--dp
) = (png_byte
)(255 - *(--sp
));
1790 *(--dp
) = (png_byte
)(255 - *(--sp
));
1792 /* This does nothing:
1799 We can replace it with:
1806 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
1808 /* This inverts the alpha channel in GA */
1809 if (row_info
->bit_depth
== 8)
1811 png_bytep sp
= row
+ row_info
->rowbytes
;
1815 for (i
= 0; i
< row_width
; i
++)
1817 *(--dp
) = (png_byte
)(255 - *(--sp
));
1821 /* This inverts the alpha channel in GGAA */
1824 png_bytep sp
= row
+ row_info
->rowbytes
;
1828 for (i
= 0; i
< row_width
; i
++)
1830 *(--dp
) = (png_byte
)(255 - *(--sp
));
1831 *(--dp
) = (png_byte
)(255 - *(--sp
));
1845 #if defined(PNG_READ_FILLER_SUPPORTED)
1846 /* Add filler channel if we have RGB color */
1848 png_do_read_filler(png_row_infop row_info
, png_bytep row
,
1849 png_uint_32 filler
, png_uint_32 flags
)
1852 png_uint_32 row_width
= row_info
->width
;
1854 png_byte hi_filler
= (png_byte
)((filler
>>8) & 0xff);
1855 png_byte lo_filler
= (png_byte
)(filler
& 0xff);
1857 png_debug(1, "in png_do_read_filler\n");
1859 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1860 row
!= NULL
&& row_info
!= NULL
&&
1862 row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
1864 if(row_info
->bit_depth
== 8)
1866 /* This changes the data from G to GX */
1867 if (flags
& PNG_FLAG_FILLER_AFTER
)
1869 png_bytep sp
= row
+ (png_size_t
)row_width
;
1870 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1871 for (i
= 1; i
< row_width
; i
++)
1873 *(--dp
) = lo_filler
;
1876 *(--dp
) = lo_filler
;
1877 row_info
->channels
= 2;
1878 row_info
->pixel_depth
= 16;
1879 row_info
->rowbytes
= row_width
* 2;
1881 /* This changes the data from G to XG */
1884 png_bytep sp
= row
+ (png_size_t
)row_width
;
1885 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1886 for (i
= 0; i
< row_width
; i
++)
1889 *(--dp
) = lo_filler
;
1891 row_info
->channels
= 2;
1892 row_info
->pixel_depth
= 16;
1893 row_info
->rowbytes
= row_width
* 2;
1896 else if(row_info
->bit_depth
== 16)
1898 /* This changes the data from GG to GGXX */
1899 if (flags
& PNG_FLAG_FILLER_AFTER
)
1901 png_bytep sp
= row
+ (png_size_t
)row_width
;
1902 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1903 for (i
= 1; i
< row_width
; i
++)
1905 *(--dp
) = hi_filler
;
1906 *(--dp
) = lo_filler
;
1910 *(--dp
) = hi_filler
;
1911 *(--dp
) = lo_filler
;
1912 row_info
->channels
= 2;
1913 row_info
->pixel_depth
= 32;
1914 row_info
->rowbytes
= row_width
* 4;
1916 /* This changes the data from GG to XXGG */
1919 png_bytep sp
= row
+ (png_size_t
)row_width
;
1920 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1921 for (i
= 0; i
< row_width
; i
++)
1925 *(--dp
) = hi_filler
;
1926 *(--dp
) = lo_filler
;
1928 row_info
->channels
= 2;
1929 row_info
->pixel_depth
= 32;
1930 row_info
->rowbytes
= row_width
* 4;
1933 } /* COLOR_TYPE == GRAY */
1934 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
1936 if(row_info
->bit_depth
== 8)
1938 /* This changes the data from RGB to RGBX */
1939 if (flags
& PNG_FLAG_FILLER_AFTER
)
1941 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
1942 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1943 for (i
= 1; i
< row_width
; i
++)
1945 *(--dp
) = lo_filler
;
1950 *(--dp
) = lo_filler
;
1951 row_info
->channels
= 4;
1952 row_info
->pixel_depth
= 32;
1953 row_info
->rowbytes
= row_width
* 4;
1955 /* This changes the data from RGB to XRGB */
1958 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
1959 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1960 for (i
= 0; i
< row_width
; i
++)
1965 *(--dp
) = lo_filler
;
1967 row_info
->channels
= 4;
1968 row_info
->pixel_depth
= 32;
1969 row_info
->rowbytes
= row_width
* 4;
1972 else if(row_info
->bit_depth
== 16)
1974 /* This changes the data from RRGGBB to RRGGBBXX */
1975 if (flags
& PNG_FLAG_FILLER_AFTER
)
1977 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
1978 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1979 for (i
= 1; i
< row_width
; i
++)
1981 *(--dp
) = hi_filler
;
1982 *(--dp
) = lo_filler
;
1990 *(--dp
) = hi_filler
;
1991 *(--dp
) = lo_filler
;
1992 row_info
->channels
= 4;
1993 row_info
->pixel_depth
= 64;
1994 row_info
->rowbytes
= row_width
* 8;
1996 /* This changes the data from RRGGBB to XXRRGGBB */
1999 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
2000 png_bytep dp
= sp
+ (png_size_t
)row_width
;
2001 for (i
= 0; i
< row_width
; i
++)
2009 *(--dp
) = hi_filler
;
2010 *(--dp
) = lo_filler
;
2012 row_info
->channels
= 4;
2013 row_info
->pixel_depth
= 64;
2014 row_info
->rowbytes
= row_width
* 8;
2017 } /* COLOR_TYPE == RGB */
2021 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
2022 /* expand grayscale files to RGB, with or without alpha */
2024 png_do_gray_to_rgb(png_row_infop row_info
, png_bytep row
)
2027 png_uint_32 row_width
= row_info
->width
;
2029 png_debug(1, "in png_do_gray_to_rgb\n");
2030 if (row_info
->bit_depth
>= 8 &&
2031 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2032 row
!= NULL
&& row_info
!= NULL
&&
2034 !(row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
2036 if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
2038 if (row_info
->bit_depth
== 8)
2040 png_bytep sp
= row
+ (png_size_t
)row_width
- 1;
2041 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2042 for (i
= 0; i
< row_width
; i
++)
2051 png_bytep sp
= row
+ (png_size_t
)row_width
* 2 - 1;
2052 png_bytep dp
= sp
+ (png_size_t
)row_width
* 4;
2053 for (i
= 0; i
< row_width
; i
++)
2056 *(dp
--) = *(sp
- 1);
2058 *(dp
--) = *(sp
- 1);
2064 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
2066 if (row_info
->bit_depth
== 8)
2068 png_bytep sp
= row
+ (png_size_t
)row_width
* 2 - 1;
2069 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2070 for (i
= 0; i
< row_width
; i
++)
2080 png_bytep sp
= row
+ (png_size_t
)row_width
* 4 - 1;
2081 png_bytep dp
= sp
+ (png_size_t
)row_width
* 4;
2082 for (i
= 0; i
< row_width
; i
++)
2087 *(dp
--) = *(sp
- 1);
2089 *(dp
--) = *(sp
- 1);
2095 row_info
->channels
+= (png_byte
)2;
2096 row_info
->color_type
|= PNG_COLOR_MASK_COLOR
;
2097 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
2098 row_info
->bit_depth
);
2099 row_info
->rowbytes
= ((row_width
*
2100 row_info
->pixel_depth
+ 7) >> 3);
2105 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
2106 /* reduce RGB files to grayscale, with or without alpha
2107 * using the equation given in Poynton's ColorFAQ at
2108 * <http://www.inforamp.net/~poynton/>
2109 * Copyright (c) 1998-01-04 Charles Poynton poynton@inforamp.net
2111 * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
2113 * We approximate this with
2115 * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B
2117 * which can be expressed with integers as
2119 * Y = (6969 * R + 23434 * G + 2365 * B)/32768
2121 * The calculation is to be done in a linear colorspace.
2123 * Other integer coefficents can be used via png_set_rgb_to_gray().
2126 png_do_rgb_to_gray(png_structp png_ptr
, png_row_infop row_info
, png_bytep row
)
2131 png_uint_32 row_width
= row_info
->width
;
2134 png_debug(1, "in png_do_rgb_to_gray\n");
2136 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2137 row
!= NULL
&& row_info
!= NULL
&&
2139 (row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
2141 png_uint_32 rc
= png_ptr
->rgb_to_gray_red_coeff
;
2142 png_uint_32 gc
= png_ptr
->rgb_to_gray_green_coeff
;
2143 png_uint_32 bc
= png_ptr
->rgb_to_gray_blue_coeff
;
2145 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
2147 if (row_info
->bit_depth
== 8)
2149 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2150 if (png_ptr
->gamma_from_1
!= NULL
&& png_ptr
->gamma_to_1
!= NULL
)
2155 for (i
= 0; i
< row_width
; i
++)
2157 png_byte red
= png_ptr
->gamma_to_1
[*(sp
++)];
2158 png_byte green
= png_ptr
->gamma_to_1
[*(sp
++)];
2159 png_byte blue
= png_ptr
->gamma_to_1
[*(sp
++)];
2160 if(red
!= green
|| red
!= blue
)
2163 *(dp
++) = png_ptr
->gamma_from_1
[
2164 (rc
*red
+gc
*green
+bc
*blue
)>>15];
2175 for (i
= 0; i
< row_width
; i
++)
2177 png_byte red
= *(sp
++);
2178 png_byte green
= *(sp
++);
2179 png_byte blue
= *(sp
++);
2180 if(red
!= green
|| red
!= blue
)
2183 *(dp
++) = (png_byte
)((rc
*red
+gc
*green
+bc
*blue
)>>15);
2191 else /* RGB bit_depth == 16 */
2193 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2194 if (png_ptr
->gamma_16_to_1
!= NULL
&&
2195 png_ptr
->gamma_16_from_1
!= NULL
)
2199 for (i
= 0; i
< row_width
; i
++)
2201 png_uint_16 red
, green
, blue
, w
;
2203 red
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2204 green
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2205 blue
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2207 if(red
== green
&& red
== blue
)
2211 png_uint_16 red_1
= png_ptr
->gamma_16_to_1
[(red
&0xff) >>
2212 png_ptr
->gamma_shift
][red
>>8];
2213 png_uint_16 green_1
= png_ptr
->gamma_16_to_1
[(green
&0xff) >>
2214 png_ptr
->gamma_shift
][green
>>8];
2215 png_uint_16 blue_1
= png_ptr
->gamma_16_to_1
[(blue
&0xff) >>
2216 png_ptr
->gamma_shift
][blue
>>8];
2217 png_uint_16 gray16
= (png_uint_16
)((rc
*red_1
+ gc
*green_1
2219 w
= png_ptr
->gamma_16_from_1
[(gray16
&0xff) >>
2220 png_ptr
->gamma_shift
][gray16
>> 8];
2224 *(dp
++) = (png_byte
)((w
>>8) & 0xff);
2225 *(dp
++) = (png_byte
)(w
& 0xff);
2233 for (i
= 0; i
< row_width
; i
++)
2235 png_uint_16 red
, green
, blue
, gray16
;
2237 red
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2238 green
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2239 blue
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2241 if(red
!= green
|| red
!= blue
)
2243 gray16
= (png_uint_16
)((rc
*red
+ gc
*green
+ bc
*blue
)>>15);
2244 *(dp
++) = (png_byte
)((gray16
>>8) & 0xff);
2245 *(dp
++) = (png_byte
)(gray16
& 0xff);
2250 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
2252 if (row_info
->bit_depth
== 8)
2254 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2255 if (png_ptr
->gamma_from_1
!= NULL
&& png_ptr
->gamma_to_1
!= NULL
)
2259 for (i
= 0; i
< row_width
; i
++)
2261 png_byte red
= png_ptr
->gamma_to_1
[*(sp
++)];
2262 png_byte green
= png_ptr
->gamma_to_1
[*(sp
++)];
2263 png_byte blue
= png_ptr
->gamma_to_1
[*(sp
++)];
2264 if(red
!= green
|| red
!= blue
)
2266 *(dp
++) = png_ptr
->gamma_from_1
2267 [(rc
*red
+ gc
*green
+ bc
*blue
)>>15];
2268 *(dp
++) = *(sp
++); /* alpha */
2276 for (i
= 0; i
< row_width
; i
++)
2278 png_byte red
= *(sp
++);
2279 png_byte green
= *(sp
++);
2280 png_byte blue
= *(sp
++);
2281 if(red
!= green
|| red
!= blue
)
2283 *(dp
++) = (png_byte
)((gc
*red
+ gc
*green
+ bc
*blue
)>>8);
2284 *(dp
++) = *(sp
++); /* alpha */
2288 else /* RGBA bit_depth == 16 */
2290 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2291 if (png_ptr
->gamma_16_to_1
!= NULL
&&
2292 png_ptr
->gamma_16_from_1
!= NULL
)
2296 for (i
= 0; i
< row_width
; i
++)
2298 png_uint_16 red
, green
, blue
, w
;
2300 red
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2301 green
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2302 blue
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2304 if(red
== green
&& red
== blue
)
2308 png_uint_16 red_1
= png_ptr
->gamma_16_to_1
[(red
&0xff) >>
2309 png_ptr
->gamma_shift
][red
>>8];
2310 png_uint_16 green_1
= png_ptr
->gamma_16_to_1
[(green
&0xff) >>
2311 png_ptr
->gamma_shift
][green
>>8];
2312 png_uint_16 blue_1
= png_ptr
->gamma_16_to_1
[(blue
&0xff) >>
2313 png_ptr
->gamma_shift
][blue
>>8];
2314 png_uint_16 gray16
= (png_uint_16
)((rc
* red_1
2315 + gc
* green_1
+ bc
* blue_1
)>>15);
2316 w
= png_ptr
->gamma_16_from_1
[(gray16
&0xff) >>
2317 png_ptr
->gamma_shift
][gray16
>> 8];
2321 *(dp
++) = (png_byte
)((w
>>8) & 0xff);
2322 *(dp
++) = (png_byte
)(w
& 0xff);
2323 *(dp
++) = *(sp
++); /* alpha */
2332 for (i
= 0; i
< row_width
; i
++)
2334 png_uint_16 red
, green
, blue
, gray16
;
2335 red
= (png_uint_16
)((*(sp
)<<8) | *(sp
+1)); sp
+=2;
2336 green
= (png_uint_16
)((*(sp
)<<8) | *(sp
+1)); sp
+=2;
2337 blue
= (png_uint_16
)((*(sp
)<<8) | *(sp
+1)); sp
+=2;
2338 if(red
!= green
|| red
!= blue
)
2340 gray16
= (png_uint_16
)((rc
*red
+ gc
*green
+ bc
*blue
)>>15);
2341 *(dp
++) = (png_byte
)((gray16
>>8) & 0xff);
2342 *(dp
++) = (png_byte
)(gray16
& 0xff);
2343 *(dp
++) = *(sp
++); /* alpha */
2349 row_info
->channels
-= (png_byte
)2;
2350 row_info
->color_type
&= ~PNG_COLOR_MASK_COLOR
;
2351 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
2352 row_info
->bit_depth
);
2353 row_info
->rowbytes
= ((row_width
*
2354 row_info
->pixel_depth
+ 7) >> 3);
2360 /* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
2361 * large of png_color. This lets grayscale images be treated as
2362 * paletted. Most useful for gamma correction and simplification
2366 png_build_grayscale_palette(int bit_depth
, png_colorp palette
)
2373 png_debug(1, "in png_do_build_grayscale_palette\n");
2374 if (palette
== NULL
)
2401 for (i
= 0, v
= 0; i
< num_palette
; i
++, v
+= color_inc
)
2403 palette
[i
].red
= (png_byte
)v
;
2404 palette
[i
].green
= (png_byte
)v
;
2405 palette
[i
].blue
= (png_byte
)v
;
2409 /* This function is currently unused. Do we really need it? */
2410 #if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
2412 png_correct_palette(png_structp png_ptr
, png_colorp palette
,
2415 png_debug(1, "in png_correct_palette\n");
2416 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
2417 defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
2418 if (png_ptr
->transformations
& (PNG_GAMMA
| PNG_BACKGROUND
))
2420 png_color back
, back_1
;
2422 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_FILE
)
2424 back
.red
= png_ptr
->gamma_table
[png_ptr
->background
.red
];
2425 back
.green
= png_ptr
->gamma_table
[png_ptr
->background
.green
];
2426 back
.blue
= png_ptr
->gamma_table
[png_ptr
->background
.blue
];
2428 back_1
.red
= png_ptr
->gamma_to_1
[png_ptr
->background
.red
];
2429 back_1
.green
= png_ptr
->gamma_to_1
[png_ptr
->background
.green
];
2430 back_1
.blue
= png_ptr
->gamma_to_1
[png_ptr
->background
.blue
];
2436 g
= 1.0 / (png_ptr
->background_gamma
* png_ptr
->screen_gamma
);
2438 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_SCREEN
||
2439 fabs(g
- 1.0) < PNG_GAMMA_THRESHOLD
)
2441 back
.red
= png_ptr
->background
.red
;
2442 back
.green
= png_ptr
->background
.green
;
2443 back
.blue
= png_ptr
->background
.blue
;
2448 (png_byte
)(pow((double)png_ptr
->background
.red
/255, g
) *
2451 (png_byte
)(pow((double)png_ptr
->background
.green
/255, g
) *
2454 (png_byte
)(pow((double)png_ptr
->background
.blue
/255, g
) *
2458 g
= 1.0 / png_ptr
->background_gamma
;
2461 (png_byte
)(pow((double)png_ptr
->background
.red
/255, g
) *
2464 (png_byte
)(pow((double)png_ptr
->background
.green
/255, g
) *
2467 (png_byte
)(pow((double)png_ptr
->background
.blue
/255, g
) *
2471 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
2475 for (i
= 0; i
< (png_uint_32
)num_palette
; i
++)
2477 if (i
< png_ptr
->num_trans
&& png_ptr
->trans
[i
] == 0)
2481 else if (i
< png_ptr
->num_trans
&& png_ptr
->trans
[i
] != 0xff)
2485 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].red
];
2486 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.red
);
2487 palette
[i
].red
= png_ptr
->gamma_from_1
[w
];
2489 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].green
];
2490 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.green
);
2491 palette
[i
].green
= png_ptr
->gamma_from_1
[w
];
2493 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].blue
];
2494 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.blue
);
2495 palette
[i
].blue
= png_ptr
->gamma_from_1
[w
];
2499 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2500 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2501 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2509 for (i
= 0; i
< num_palette
; i
++)
2511 if (palette
[i
].red
== (png_byte
)png_ptr
->trans_values
.gray
)
2517 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2518 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2519 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2526 #if defined(PNG_READ_GAMMA_SUPPORTED)
2527 if (png_ptr
->transformations
& PNG_GAMMA
)
2531 for (i
= 0; i
< num_palette
; i
++)
2533 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2534 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2535 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2538 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2542 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2543 if (png_ptr
->transformations
& PNG_BACKGROUND
)
2545 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
2549 back
.red
= (png_byte
)png_ptr
->background
.red
;
2550 back
.green
= (png_byte
)png_ptr
->background
.green
;
2551 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
2553 for (i
= 0; i
< (int)png_ptr
->num_trans
; i
++)
2555 if (png_ptr
->trans
[i
] == 0)
2557 palette
[i
].red
= back
.red
;
2558 palette
[i
].green
= back
.green
;
2559 palette
[i
].blue
= back
.blue
;
2561 else if (png_ptr
->trans
[i
] != 0xff)
2563 png_composite(palette
[i
].red
, png_ptr
->palette
[i
].red
,
2564 png_ptr
->trans
[i
], back
.red
);
2565 png_composite(palette
[i
].green
, png_ptr
->palette
[i
].green
,
2566 png_ptr
->trans
[i
], back
.green
);
2567 png_composite(palette
[i
].blue
, png_ptr
->palette
[i
].blue
,
2568 png_ptr
->trans
[i
], back
.blue
);
2572 else /* assume grayscale palette (what else could it be?) */
2576 for (i
= 0; i
< num_palette
; i
++)
2578 if (i
== (png_byte
)png_ptr
->trans_values
.gray
)
2580 palette
[i
].red
= (png_byte
)png_ptr
->background
.red
;
2581 palette
[i
].green
= (png_byte
)png_ptr
->background
.green
;
2582 palette
[i
].blue
= (png_byte
)png_ptr
->background
.blue
;
2591 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2592 /* Replace any alpha or transparency with the supplied background color.
2593 * "background" is already in the screen gamma, while "background_1" is
2594 * at a gamma of 1.0. Paletted files have already been taken care of.
2597 png_do_background(png_row_infop row_info
, png_bytep row
,
2598 png_color_16p trans_values
, png_color_16p background
2599 #if defined(PNG_READ_GAMMA_SUPPORTED)
2600 , png_color_16p background_1
,
2601 png_bytep gamma_table
, png_bytep gamma_from_1
, png_bytep gamma_to_1
,
2602 png_uint_16pp gamma_16
, png_uint_16pp gamma_16_from_1
,
2603 png_uint_16pp gamma_16_to_1
, int gamma_shift
2609 png_uint_32 row_width
=row_info
->width
;
2612 png_debug(1, "in png_do_background\n");
2613 if (background
!= NULL
&&
2614 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2615 row
!= NULL
&& row_info
!= NULL
&&
2617 (!(row_info
->color_type
& PNG_COLOR_MASK_ALPHA
) ||
2618 (row_info
->color_type
!= PNG_COLOR_TYPE_PALETTE
&& trans_values
)))
2620 switch (row_info
->color_type
)
2622 case PNG_COLOR_TYPE_GRAY
:
2624 switch (row_info
->bit_depth
)
2630 for (i
= 0; i
< row_width
; i
++)
2632 if ((png_uint_16
)((*sp
>> shift
) & 0x01)
2633 == trans_values
->gray
)
2635 *sp
&= (png_byte
)((0x7f7f >> (7 - shift
)) & 0xff);
2636 *sp
|= (png_byte
)(background
->gray
<< shift
);
2650 #if defined(PNG_READ_GAMMA_SUPPORTED)
2651 if (gamma_table
!= NULL
)
2655 for (i
= 0; i
< row_width
; i
++)
2657 if ((png_uint_16
)((*sp
>> shift
) & 0x03)
2658 == trans_values
->gray
)
2660 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2661 *sp
|= (png_byte
)(background
->gray
<< shift
);
2665 png_byte p
= (png_byte
)((*sp
>> shift
) & 0x03);
2666 png_byte g
= (png_byte
)((gamma_table
[p
| (p
<< 2) |
2667 (p
<< 4) | (p
<< 6)] >> 6) & 0x03);
2668 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2669 *sp
|= (png_byte
)(g
<< shift
);
2685 for (i
= 0; i
< row_width
; i
++)
2687 if ((png_uint_16
)((*sp
>> shift
) & 0x03)
2688 == trans_values
->gray
)
2690 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2691 *sp
|= (png_byte
)(background
->gray
<< shift
);
2706 #if defined(PNG_READ_GAMMA_SUPPORTED)
2707 if (gamma_table
!= NULL
)
2711 for (i
= 0; i
< row_width
; i
++)
2713 if ((png_uint_16
)((*sp
>> shift
) & 0x0f)
2714 == trans_values
->gray
)
2716 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2717 *sp
|= (png_byte
)(background
->gray
<< shift
);
2721 png_byte p
= (png_byte
)((*sp
>> shift
) & 0x0f);
2722 png_byte g
= (png_byte
)((gamma_table
[p
|
2723 (p
<< 4)] >> 4) & 0x0f);
2724 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2725 *sp
|= (png_byte
)(g
<< shift
);
2741 for (i
= 0; i
< row_width
; i
++)
2743 if ((png_uint_16
)((*sp
>> shift
) & 0x0f)
2744 == trans_values
->gray
)
2746 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2747 *sp
|= (png_byte
)(background
->gray
<< shift
);
2762 #if defined(PNG_READ_GAMMA_SUPPORTED)
2763 if (gamma_table
!= NULL
)
2766 for (i
= 0; i
< row_width
; i
++, sp
++)
2768 if (*sp
== trans_values
->gray
)
2770 *sp
= (png_byte
)background
->gray
;
2774 *sp
= gamma_table
[*sp
];
2782 for (i
= 0; i
< row_width
; i
++, sp
++)
2784 if (*sp
== trans_values
->gray
)
2786 *sp
= (png_byte
)background
->gray
;
2794 #if defined(PNG_READ_GAMMA_SUPPORTED)
2795 if (gamma_16
!= NULL
)
2798 for (i
= 0; i
< row_width
; i
++, sp
+= 2)
2802 v
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
2803 if (v
== trans_values
->gray
)
2805 /* background is already in screen gamma */
2806 *sp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2807 *(sp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2811 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2812 *sp
= (png_byte
)((v
>> 8) & 0xff);
2813 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2821 for (i
= 0; i
< row_width
; i
++, sp
+= 2)
2825 v
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
2826 if (v
== trans_values
->gray
)
2828 *sp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2829 *(sp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2838 case PNG_COLOR_TYPE_RGB
:
2840 if (row_info
->bit_depth
== 8)
2842 #if defined(PNG_READ_GAMMA_SUPPORTED)
2843 if (gamma_table
!= NULL
)
2846 for (i
= 0; i
< row_width
; i
++, sp
+= 3)
2848 if (*sp
== trans_values
->red
&&
2849 *(sp
+ 1) == trans_values
->green
&&
2850 *(sp
+ 2) == trans_values
->blue
)
2852 *sp
= (png_byte
)background
->red
;
2853 *(sp
+ 1) = (png_byte
)background
->green
;
2854 *(sp
+ 2) = (png_byte
)background
->blue
;
2858 *sp
= gamma_table
[*sp
];
2859 *(sp
+ 1) = gamma_table
[*(sp
+ 1)];
2860 *(sp
+ 2) = gamma_table
[*(sp
+ 2)];
2868 for (i
= 0; i
< row_width
; i
++, sp
+= 3)
2870 if (*sp
== trans_values
->red
&&
2871 *(sp
+ 1) == trans_values
->green
&&
2872 *(sp
+ 2) == trans_values
->blue
)
2874 *sp
= (png_byte
)background
->red
;
2875 *(sp
+ 1) = (png_byte
)background
->green
;
2876 *(sp
+ 2) = (png_byte
)background
->blue
;
2881 else /* if (row_info->bit_depth == 16) */
2883 #if defined(PNG_READ_GAMMA_SUPPORTED)
2884 if (gamma_16
!= NULL
)
2887 for (i
= 0; i
< row_width
; i
++, sp
+= 6)
2889 png_uint_16 r
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
2890 png_uint_16 g
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
2891 png_uint_16 b
= (png_uint_16
)(((*(sp
+4)) << 8) + *(sp
+5));
2892 if (r
== trans_values
->red
&& g
== trans_values
->green
&&
2893 b
== trans_values
->blue
)
2895 /* background is already in screen gamma */
2896 *sp
= (png_byte
)((background
->red
>> 8) & 0xff);
2897 *(sp
+ 1) = (png_byte
)(background
->red
& 0xff);
2898 *(sp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
2899 *(sp
+ 3) = (png_byte
)(background
->green
& 0xff);
2900 *(sp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
2901 *(sp
+ 5) = (png_byte
)(background
->blue
& 0xff);
2905 png_uint_16 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2906 *sp
= (png_byte
)((v
>> 8) & 0xff);
2907 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2908 v
= gamma_16
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
2909 *(sp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
2910 *(sp
+ 3) = (png_byte
)(v
& 0xff);
2911 v
= gamma_16
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
2912 *(sp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
2913 *(sp
+ 5) = (png_byte
)(v
& 0xff);
2921 for (i
= 0; i
< row_width
; i
++, sp
+= 6)
2923 png_uint_16 r
= (png_uint_16
)(((*sp
) << 8) + *(sp
+1));
2924 png_uint_16 g
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
2925 png_uint_16 b
= (png_uint_16
)(((*(sp
+4)) << 8) + *(sp
+5));
2927 if (r
== trans_values
->red
&& g
== trans_values
->green
&&
2928 b
== trans_values
->blue
)
2930 *sp
= (png_byte
)((background
->red
>> 8) & 0xff);
2931 *(sp
+ 1) = (png_byte
)(background
->red
& 0xff);
2932 *(sp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
2933 *(sp
+ 3) = (png_byte
)(background
->green
& 0xff);
2934 *(sp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
2935 *(sp
+ 5) = (png_byte
)(background
->blue
& 0xff);
2942 case PNG_COLOR_TYPE_GRAY_ALPHA
:
2944 if (row_info
->bit_depth
== 8)
2946 #if defined(PNG_READ_GAMMA_SUPPORTED)
2947 if (gamma_to_1
!= NULL
&& gamma_from_1
!= NULL
&&
2948 gamma_table
!= NULL
)
2952 for (i
= 0; i
< row_width
; i
++, sp
+= 2, dp
++)
2954 png_uint_16 a
= *(sp
+ 1);
2958 *dp
= gamma_table
[*sp
];
2962 /* background is already in screen gamma */
2963 *dp
= (png_byte
)background
->gray
;
2969 v
= gamma_to_1
[*sp
];
2970 png_composite(w
, v
, a
, background_1
->gray
);
2971 *dp
= gamma_from_1
[w
];
2980 for (i
= 0; i
< row_width
; i
++, sp
+= 2, dp
++)
2982 png_byte a
= *(sp
+ 1);
2988 #if defined(PNG_READ_GAMMA_SUPPORTED)
2991 *dp
= (png_byte
)background
->gray
;
2995 png_composite(*dp
, *sp
, a
, background_1
->gray
);
2998 *dp
= (png_byte
)background
->gray
;
3003 else /* if (png_ptr->bit_depth == 16) */
3005 #if defined(PNG_READ_GAMMA_SUPPORTED)
3006 if (gamma_16
!= NULL
&& gamma_16_from_1
!= NULL
&&
3007 gamma_16_to_1
!= NULL
)
3011 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 2)
3013 png_uint_16 a
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
3015 if (a
== (png_uint_16
)0xffff)
3019 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
3020 *dp
= (png_byte
)((v
>> 8) & 0xff);
3021 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3023 #if defined(PNG_READ_GAMMA_SUPPORTED)
3029 /* background is already in screen gamma */
3030 *dp
= (png_byte
)((background
->gray
>> 8) & 0xff);
3031 *(dp
+ 1) = (png_byte
)(background
->gray
& 0xff);
3033 #if defined(PNG_READ_GAMMA_SUPPORTED)
3036 png_uint_16 g
, v
, w
;
3038 g
= gamma_16_to_1
[*(sp
+ 1) >> gamma_shift
][*sp
];
3039 png_composite_16(v
, g
, a
, background_1
->gray
);
3040 w
= gamma_16_from_1
[(v
&0xff) >> gamma_shift
][v
>> 8];
3041 *dp
= (png_byte
)((w
>> 8) & 0xff);
3042 *(dp
+ 1) = (png_byte
)(w
& 0xff);
3052 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 2)
3054 png_uint_16 a
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
3055 if (a
== (png_uint_16
)0xffff)
3057 png_memcpy(dp
, sp
, 2);
3059 #if defined(PNG_READ_GAMMA_SUPPORTED)
3065 *dp
= (png_byte
)((background
->gray
>> 8) & 0xff);
3066 *(dp
+ 1) = (png_byte
)(background
->gray
& 0xff);
3068 #if defined(PNG_READ_GAMMA_SUPPORTED)
3073 g
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
3074 png_composite_16(v
, g
, a
, background_1
->gray
);
3075 *dp
= (png_byte
)((v
>> 8) & 0xff);
3076 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3084 case PNG_COLOR_TYPE_RGB_ALPHA
:
3086 if (row_info
->bit_depth
== 8)
3088 #if defined(PNG_READ_GAMMA_SUPPORTED)
3089 if (gamma_to_1
!= NULL
&& gamma_from_1
!= NULL
&&
3090 gamma_table
!= NULL
)
3094 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 3)
3096 png_byte a
= *(sp
+ 3);
3100 *dp
= gamma_table
[*sp
];
3101 *(dp
+ 1) = gamma_table
[*(sp
+ 1)];
3102 *(dp
+ 2) = gamma_table
[*(sp
+ 2)];
3106 /* background is already in screen gamma */
3107 *dp
= (png_byte
)background
->red
;
3108 *(dp
+ 1) = (png_byte
)background
->green
;
3109 *(dp
+ 2) = (png_byte
)background
->blue
;
3115 v
= gamma_to_1
[*sp
];
3116 png_composite(w
, v
, a
, background_1
->red
);
3117 *dp
= gamma_from_1
[w
];
3118 v
= gamma_to_1
[*(sp
+ 1)];
3119 png_composite(w
, v
, a
, background_1
->green
);
3120 *(dp
+ 1) = gamma_from_1
[w
];
3121 v
= gamma_to_1
[*(sp
+ 2)];
3122 png_composite(w
, v
, a
, background_1
->blue
);
3123 *(dp
+ 2) = gamma_from_1
[w
];
3132 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 3)
3134 png_byte a
= *(sp
+ 3);
3139 *(dp
+ 1) = *(sp
+ 1);
3140 *(dp
+ 2) = *(sp
+ 2);
3144 *dp
= (png_byte
)background
->red
;
3145 *(dp
+ 1) = (png_byte
)background
->green
;
3146 *(dp
+ 2) = (png_byte
)background
->blue
;
3150 png_composite(*dp
, *sp
, a
, background
->red
);
3151 png_composite(*(dp
+ 1), *(sp
+ 1), a
,
3153 png_composite(*(dp
+ 2), *(sp
+ 2), a
,
3159 else /* if (row_info->bit_depth == 16) */
3161 #if defined(PNG_READ_GAMMA_SUPPORTED)
3162 if (gamma_16
!= NULL
&& gamma_16_from_1
!= NULL
&&
3163 gamma_16_to_1
!= NULL
)
3167 for (i
= 0; i
< row_width
; i
++, sp
+= 8, dp
+= 6)
3169 png_uint_16 a
= (png_uint_16
)(((png_uint_16
)(*(sp
+ 6))
3170 << 8) + (png_uint_16
)(*(sp
+ 7)));
3171 if (a
== (png_uint_16
)0xffff)
3175 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
3176 *dp
= (png_byte
)((v
>> 8) & 0xff);
3177 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3178 v
= gamma_16
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
3179 *(dp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
3180 *(dp
+ 3) = (png_byte
)(v
& 0xff);
3181 v
= gamma_16
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
3182 *(dp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
3183 *(dp
+ 5) = (png_byte
)(v
& 0xff);
3187 /* background is already in screen gamma */
3188 *dp
= (png_byte
)((background
->red
>> 8) & 0xff);
3189 *(dp
+ 1) = (png_byte
)(background
->red
& 0xff);
3190 *(dp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
3191 *(dp
+ 3) = (png_byte
)(background
->green
& 0xff);
3192 *(dp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
3193 *(dp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3197 png_uint_16 v
, w
, x
;
3199 v
= gamma_16_to_1
[*(sp
+ 1) >> gamma_shift
][*sp
];
3200 png_composite_16(w
, v
, a
, background_1
->red
);
3201 x
= gamma_16_from_1
[((w
&0xff) >> gamma_shift
)][w
>> 8];
3202 *dp
= (png_byte
)((x
>> 8) & 0xff);
3203 *(dp
+ 1) = (png_byte
)(x
& 0xff);
3204 v
= gamma_16_to_1
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
3205 png_composite_16(w
, v
, a
, background_1
->green
);
3206 x
= gamma_16_from_1
[((w
&0xff) >> gamma_shift
)][w
>> 8];
3207 *(dp
+ 2) = (png_byte
)((x
>> 8) & 0xff);
3208 *(dp
+ 3) = (png_byte
)(x
& 0xff);
3209 v
= gamma_16_to_1
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
3210 png_composite_16(w
, v
, a
, background_1
->blue
);
3211 x
= gamma_16_from_1
[(w
& 0xff) >> gamma_shift
][w
>> 8];
3212 *(dp
+ 4) = (png_byte
)((x
>> 8) & 0xff);
3213 *(dp
+ 5) = (png_byte
)(x
& 0xff);
3222 for (i
= 0; i
< row_width
; i
++, sp
+= 8, dp
+= 6)
3224 png_uint_16 a
= (png_uint_16
)(((png_uint_16
)(*(sp
+ 6))
3225 << 8) + (png_uint_16
)(*(sp
+ 7)));
3226 if (a
== (png_uint_16
)0xffff)
3228 png_memcpy(dp
, sp
, 6);
3232 *dp
= (png_byte
)((background
->red
>> 8) & 0xff);
3233 *(dp
+ 1) = (png_byte
)(background
->red
& 0xff);
3234 *(dp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
3235 *(dp
+ 3) = (png_byte
)(background
->green
& 0xff);
3236 *(dp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
3237 *(dp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3243 png_uint_16 r
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
3244 png_uint_16 g
= (png_uint_16
)(((*(sp
+ 2)) << 8)
3246 png_uint_16 b
= (png_uint_16
)(((*(sp
+ 4)) << 8)
3249 png_composite_16(v
, r
, a
, background
->red
);
3250 *dp
= (png_byte
)((v
>> 8) & 0xff);
3251 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3252 png_composite_16(v
, g
, a
, background
->green
);
3253 *(dp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
3254 *(dp
+ 3) = (png_byte
)(v
& 0xff);
3255 png_composite_16(v
, b
, a
, background
->blue
);
3256 *(dp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
3257 *(dp
+ 5) = (png_byte
)(v
& 0xff);
3266 if (row_info
->color_type
& PNG_COLOR_MASK_ALPHA
)
3268 row_info
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
3269 row_info
->channels
--;
3270 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
3271 row_info
->bit_depth
);
3272 row_info
->rowbytes
= ((row_width
*
3273 row_info
->pixel_depth
+ 7) >> 3);
3279 #if defined(PNG_READ_GAMMA_SUPPORTED)
3280 /* Gamma correct the image, avoiding the alpha channel. Make sure
3281 * you do this after you deal with the transparency issue on grayscale
3282 * or RGB images. If your bit depth is 8, use gamma_table, if it
3283 * is 16, use gamma_16_table and gamma_shift. Build these with
3284 * build_gamma_table().
3287 png_do_gamma(png_row_infop row_info
, png_bytep row
,
3288 png_bytep gamma_table
, png_uint_16pp gamma_16_table
,
3293 png_uint_32 row_width
=row_info
->width
;
3295 png_debug(1, "in png_do_gamma\n");
3297 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3298 row
!= NULL
&& row_info
!= NULL
&&
3300 ((row_info
->bit_depth
<= 8 && gamma_table
!= NULL
) ||
3301 (row_info
->bit_depth
== 16 && gamma_16_table
!= NULL
)))
3303 switch (row_info
->color_type
)
3305 case PNG_COLOR_TYPE_RGB
:
3307 if (row_info
->bit_depth
== 8)
3310 for (i
= 0; i
< row_width
; i
++)
3312 *sp
= gamma_table
[*sp
];
3314 *sp
= gamma_table
[*sp
];
3316 *sp
= gamma_table
[*sp
];
3320 else /* if (row_info->bit_depth == 16) */
3323 for (i
= 0; i
< row_width
; i
++)
3327 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3328 *sp
= (png_byte
)((v
>> 8) & 0xff);
3329 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3331 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3332 *sp
= (png_byte
)((v
>> 8) & 0xff);
3333 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3335 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3336 *sp
= (png_byte
)((v
>> 8) & 0xff);
3337 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3343 case PNG_COLOR_TYPE_RGB_ALPHA
:
3345 if (row_info
->bit_depth
== 8)
3348 for (i
= 0; i
< row_width
; i
++)
3350 *sp
= gamma_table
[*sp
];
3352 *sp
= gamma_table
[*sp
];
3354 *sp
= gamma_table
[*sp
];
3359 else /* if (row_info->bit_depth == 16) */
3362 for (i
= 0; i
< row_width
; i
++)
3364 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3365 *sp
= (png_byte
)((v
>> 8) & 0xff);
3366 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3368 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3369 *sp
= (png_byte
)((v
>> 8) & 0xff);
3370 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3372 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3373 *sp
= (png_byte
)((v
>> 8) & 0xff);
3374 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3380 case PNG_COLOR_TYPE_GRAY_ALPHA
:
3382 if (row_info
->bit_depth
== 8)
3385 for (i
= 0; i
< row_width
; i
++)
3387 *sp
= gamma_table
[*sp
];
3391 else /* if (row_info->bit_depth == 16) */
3394 for (i
= 0; i
< row_width
; i
++)
3396 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3397 *sp
= (png_byte
)((v
>> 8) & 0xff);
3398 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3404 case PNG_COLOR_TYPE_GRAY
:
3406 if (row_info
->bit_depth
== 2)
3409 for (i
= 0; i
< row_width
; i
+= 4)
3417 ((((int)gamma_table
[a
|(a
>>2)|(a
>>4)|(a
>>6)]) ) & 0xc0)|
3418 ((((int)gamma_table
[(b
<<2)|b
|(b
>>2)|(b
>>4)])>>2) & 0x30)|
3419 ((((int)gamma_table
[(c
<<4)|(c
<<2)|c
|(c
>>2)])>>4) & 0x0c)|
3420 ((((int)gamma_table
[(d
<<6)|(d
<<4)|(d
<<2)|d
])>>6) ));
3424 if (row_info
->bit_depth
== 4)
3427 for (i
= 0; i
< row_width
; i
+= 2)
3429 int msb
= *sp
& 0xf0;
3430 int lsb
= *sp
& 0x0f;
3432 *sp
= (png_byte
)((((int)gamma_table
[msb
| (msb
>> 4)]) & 0xf0)
3433 | (((int)gamma_table
[(lsb
<< 4) | lsb
]) >> 4));
3437 else if (row_info
->bit_depth
== 8)
3440 for (i
= 0; i
< row_width
; i
++)
3442 *sp
= gamma_table
[*sp
];
3446 else if (row_info
->bit_depth
== 16)
3449 for (i
= 0; i
< row_width
; i
++)
3451 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3452 *sp
= (png_byte
)((v
>> 8) & 0xff);
3453 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3464 #if defined(PNG_READ_EXPAND_SUPPORTED)
3465 /* Expands a palette row to an RGB or RGBA row depending
3466 * upon whether you supply trans and num_trans.
3469 png_do_expand_palette(png_row_infop row_info
, png_bytep row
,
3470 png_colorp palette
, png_bytep trans
, int num_trans
)
3475 png_uint_32 row_width
=row_info
->width
;
3477 png_debug(1, "in png_do_expand_palette\n");
3479 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3480 row
!= NULL
&& row_info
!= NULL
&&
3482 row_info
->color_type
== PNG_COLOR_TYPE_PALETTE
)
3484 if (row_info
->bit_depth
< 8)
3486 switch (row_info
->bit_depth
)
3490 sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
3491 dp
= row
+ (png_size_t
)row_width
- 1;
3492 shift
= 7 - (int)((row_width
+ 7) & 0x07);
3493 for (i
= 0; i
< row_width
; i
++)
3495 if ((*sp
>> shift
) & 0x01)
3513 sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
3514 dp
= row
+ (png_size_t
)row_width
- 1;
3515 shift
= (int)((3 - ((row_width
+ 3) & 0x03)) << 1);
3516 for (i
= 0; i
< row_width
; i
++)
3518 value
= (*sp
>> shift
) & 0x03;
3519 *dp
= (png_byte
)value
;
3534 sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
3535 dp
= row
+ (png_size_t
)row_width
- 1;
3536 shift
= (int)((row_width
& 0x01) << 2);
3537 for (i
= 0; i
< row_width
; i
++)
3539 value
= (*sp
>> shift
) & 0x0f;
3540 *dp
= (png_byte
)value
;
3554 row_info
->bit_depth
= 8;
3555 row_info
->pixel_depth
= 8;
3556 row_info
->rowbytes
= row_width
;
3558 switch (row_info
->bit_depth
)
3564 sp
= row
+ (png_size_t
)row_width
- 1;
3565 dp
= row
+ (png_size_t
)(row_width
<< 2) - 1;
3567 for (i
= 0; i
< row_width
; i
++)
3569 if ((int)(*sp
) >= num_trans
)
3573 *dp
-- = palette
[*sp
].blue
;
3574 *dp
-- = palette
[*sp
].green
;
3575 *dp
-- = palette
[*sp
].red
;
3578 row_info
->bit_depth
= 8;
3579 row_info
->pixel_depth
= 32;
3580 row_info
->rowbytes
= row_width
* 4;
3581 row_info
->color_type
= 6;
3582 row_info
->channels
= 4;
3586 sp
= row
+ (png_size_t
)row_width
- 1;
3587 dp
= row
+ (png_size_t
)(row_width
* 3) - 1;
3589 for (i
= 0; i
< row_width
; i
++)
3591 *dp
-- = palette
[*sp
].blue
;
3592 *dp
-- = palette
[*sp
].green
;
3593 *dp
-- = palette
[*sp
].red
;
3596 row_info
->bit_depth
= 8;
3597 row_info
->pixel_depth
= 24;
3598 row_info
->rowbytes
= row_width
* 3;
3599 row_info
->color_type
= 2;
3600 row_info
->channels
= 3;
3608 /* If the bit depth < 8, it is expanded to 8. Also, if the
3609 * transparency value is supplied, an alpha channel is built.
3612 png_do_expand(png_row_infop row_info
, png_bytep row
,
3613 png_color_16p trans_value
)
3618 png_uint_32 row_width
=row_info
->width
;
3620 png_debug(1, "in png_do_expand\n");
3621 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3622 if (row
!= NULL
&& row_info
!= NULL
)
3625 if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
3627 png_uint_16 gray
= (png_uint_16
)(trans_value
? trans_value
->gray
: 0);
3629 if (row_info
->bit_depth
< 8)
3631 switch (row_info
->bit_depth
)
3635 gray
= (png_uint_16
)(gray
*0xff);
3636 sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
3637 dp
= row
+ (png_size_t
)row_width
- 1;
3638 shift
= 7 - (int)((row_width
+ 7) & 0x07);
3639 for (i
= 0; i
< row_width
; i
++)
3641 if ((*sp
>> shift
) & 0x01)
3659 gray
= (png_uint_16
)(gray
*0x55);
3660 sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
3661 dp
= row
+ (png_size_t
)row_width
- 1;
3662 shift
= (int)((3 - ((row_width
+ 3) & 0x03)) << 1);
3663 for (i
= 0; i
< row_width
; i
++)
3665 value
= (*sp
>> shift
) & 0x03;
3666 *dp
= (png_byte
)(value
| (value
<< 2) | (value
<< 4) |
3682 gray
= (png_uint_16
)(gray
*0x11);
3683 sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
3684 dp
= row
+ (png_size_t
)row_width
- 1;
3685 shift
= (int)((1 - ((row_width
+ 1) & 0x01)) << 2);
3686 for (i
= 0; i
< row_width
; i
++)
3688 value
= (*sp
>> shift
) & 0x0f;
3689 *dp
= (png_byte
)(value
| (value
<< 4));
3703 row_info
->bit_depth
= 8;
3704 row_info
->pixel_depth
= 8;
3705 row_info
->rowbytes
= row_width
;
3708 if (trans_value
!= NULL
)
3710 if (row_info
->bit_depth
== 8)
3712 sp
= row
+ (png_size_t
)row_width
- 1;
3713 dp
= row
+ (png_size_t
)(row_width
<< 1) - 1;
3714 for (i
= 0; i
< row_width
; i
++)
3723 else if (row_info
->bit_depth
== 16)
3725 sp
= row
+ row_info
->rowbytes
- 1;
3726 dp
= row
+ (row_info
->rowbytes
<< 1) - 1;
3727 for (i
= 0; i
< row_width
; i
++)
3729 if (((png_uint_16
)*(sp
) |
3730 ((png_uint_16
)*(sp
- 1) << 8)) == gray
)
3744 row_info
->color_type
= PNG_COLOR_TYPE_GRAY_ALPHA
;
3745 row_info
->channels
= 2;
3746 row_info
->pixel_depth
= (png_byte
)(row_info
->bit_depth
<< 1);
3747 row_info
->rowbytes
=
3748 ((row_width
* row_info
->pixel_depth
) >> 3);
3751 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
&& trans_value
)
3753 if (row_info
->bit_depth
== 8)
3755 sp
= row
+ (png_size_t
)row_info
->rowbytes
- 1;
3756 dp
= row
+ (png_size_t
)(row_width
<< 2) - 1;
3757 for (i
= 0; i
< row_width
; i
++)
3759 if (*(sp
- 2) == trans_value
->red
&&
3760 *(sp
- 1) == trans_value
->green
&&
3761 *(sp
- 0) == trans_value
->blue
)
3770 else if (row_info
->bit_depth
== 16)
3772 sp
= row
+ row_info
->rowbytes
- 1;
3773 dp
= row
+ (png_size_t
)(row_width
<< 3) - 1;
3774 for (i
= 0; i
< row_width
; i
++)
3776 if ((((png_uint_16
)*(sp
- 4) |
3777 ((png_uint_16
)*(sp
- 5) << 8)) == trans_value
->red
) &&
3778 (((png_uint_16
)*(sp
- 2) |
3779 ((png_uint_16
)*(sp
- 3) << 8)) == trans_value
->green
) &&
3780 (((png_uint_16
)*(sp
- 0) |
3781 ((png_uint_16
)*(sp
- 1) << 8)) == trans_value
->blue
))
3799 row_info
->color_type
= PNG_COLOR_TYPE_RGB_ALPHA
;
3800 row_info
->channels
= 4;
3801 row_info
->pixel_depth
= (png_byte
)(row_info
->bit_depth
<< 2);
3802 row_info
->rowbytes
=
3803 ((row_width
* row_info
->pixel_depth
) >> 3);
3809 #if defined(PNG_READ_DITHER_SUPPORTED)
3811 png_do_dither(png_row_infop row_info
, png_bytep row
,
3812 png_bytep palette_lookup
, png_bytep dither_lookup
)
3816 png_uint_32 row_width
=row_info
->width
;
3818 png_debug(1, "in png_do_dither\n");
3819 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3820 if (row
!= NULL
&& row_info
!= NULL
)
3823 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
&&
3824 palette_lookup
&& row_info
->bit_depth
== 8)
3829 for (i
= 0; i
< row_width
; i
++)
3835 /* this looks real messy, but the compiler will reduce
3836 it down to a reasonable formula. For example, with
3837 5 bits per color, we get:
3838 p = (((r >> 3) & 0x1f) << 10) |
3839 (((g >> 3) & 0x1f) << 5) |
3842 p
= (((r
>> (8 - PNG_DITHER_RED_BITS
)) &
3843 ((1 << PNG_DITHER_RED_BITS
) - 1)) <<
3844 (PNG_DITHER_GREEN_BITS
+ PNG_DITHER_BLUE_BITS
)) |
3845 (((g
>> (8 - PNG_DITHER_GREEN_BITS
)) &
3846 ((1 << PNG_DITHER_GREEN_BITS
) - 1)) <<
3847 (PNG_DITHER_BLUE_BITS
)) |
3848 ((b
>> (8 - PNG_DITHER_BLUE_BITS
)) &
3849 ((1 << PNG_DITHER_BLUE_BITS
) - 1));
3851 *dp
++ = palette_lookup
[p
];
3853 row_info
->color_type
= PNG_COLOR_TYPE_PALETTE
;
3854 row_info
->channels
= 1;
3855 row_info
->pixel_depth
= row_info
->bit_depth
;
3856 row_info
->rowbytes
=
3857 ((row_width
* row_info
->pixel_depth
+ 7) >> 3);
3859 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
&&
3860 palette_lookup
!= NULL
&& row_info
->bit_depth
== 8)
3865 for (i
= 0; i
< row_width
; i
++)
3872 p
= (((r
>> (8 - PNG_DITHER_RED_BITS
)) &
3873 ((1 << PNG_DITHER_RED_BITS
) - 1)) <<
3874 (PNG_DITHER_GREEN_BITS
+ PNG_DITHER_BLUE_BITS
)) |
3875 (((g
>> (8 - PNG_DITHER_GREEN_BITS
)) &
3876 ((1 << PNG_DITHER_GREEN_BITS
) - 1)) <<
3877 (PNG_DITHER_BLUE_BITS
)) |
3878 ((b
>> (8 - PNG_DITHER_BLUE_BITS
)) &
3879 ((1 << PNG_DITHER_BLUE_BITS
) - 1));
3881 *dp
++ = palette_lookup
[p
];
3883 row_info
->color_type
= PNG_COLOR_TYPE_PALETTE
;
3884 row_info
->channels
= 1;
3885 row_info
->pixel_depth
= row_info
->bit_depth
;
3886 row_info
->rowbytes
=
3887 ((row_width
* row_info
->pixel_depth
+ 7) >> 3);
3889 else if (row_info
->color_type
== PNG_COLOR_TYPE_PALETTE
&&
3890 dither_lookup
&& row_info
->bit_depth
== 8)
3893 for (i
= 0; i
< row_width
; i
++, sp
++)
3895 *sp
= dither_lookup
[*sp
];
3902 #ifdef PNG_FLOATING_POINT_SUPPORTED
3903 #if defined(PNG_READ_GAMMA_SUPPORTED)
3904 static int png_gamma_shift
[] =
3905 {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0};
3907 /* We build the 8- or 16-bit gamma tables here. Note that for 16-bit
3908 * tables, we don't make a full table if we are reducing to 8-bit in
3909 * the future. Note also how the gamma_16 tables are segmented so that
3910 * we don't need to allocate > 64K chunks for a full 16-bit table.
3913 png_build_gamma_table(png_structp png_ptr
)
3915 png_debug(1, "in png_build_gamma_table\n");
3916 if(png_ptr
->gamma
!= 0.0)
3918 if (png_ptr
->bit_depth
<= 8)
3923 if (png_ptr
->screen_gamma
> .000001)
3924 g
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
3928 png_ptr
->gamma_table
= (png_bytep
)png_malloc(png_ptr
,
3931 for (i
= 0; i
< 256; i
++)
3933 png_ptr
->gamma_table
[i
] = (png_byte
)(pow((double)i
/ 255.0,
3937 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
3938 defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
3939 if (png_ptr
->transformations
& ((PNG_BACKGROUND
) | PNG_RGB_TO_GRAY
))
3942 g
= 1.0 / (png_ptr
->gamma
);
3944 png_ptr
->gamma_to_1
= (png_bytep
)png_malloc(png_ptr
,
3947 for (i
= 0; i
< 256; i
++)
3949 png_ptr
->gamma_to_1
[i
] = (png_byte
)(pow((double)i
/ 255.0,
3954 png_ptr
->gamma_from_1
= (png_bytep
)png_malloc(png_ptr
,
3957 if(png_ptr
->screen_gamma
> 0.000001)
3958 g
= 1.0 / png_ptr
->screen_gamma
;
3960 g
= png_ptr
->gamma
; /* probably doing rgb_to_gray */
3962 for (i
= 0; i
< 256; i
++)
3964 png_ptr
->gamma_from_1
[i
] = (png_byte
)(pow((double)i
/ 255.0,
3969 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
3974 int i
, j
, shift
, num
;
3978 if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
3980 sig_bit
= (int)png_ptr
->sig_bit
.red
;
3981 if ((int)png_ptr
->sig_bit
.green
> sig_bit
)
3982 sig_bit
= png_ptr
->sig_bit
.green
;
3983 if ((int)png_ptr
->sig_bit
.blue
> sig_bit
)
3984 sig_bit
= png_ptr
->sig_bit
.blue
;
3988 sig_bit
= (int)png_ptr
->sig_bit
.gray
;
3992 shift
= 16 - sig_bit
;
3996 if (png_ptr
->transformations
& PNG_16_TO_8
)
3998 if (shift
< (16 - PNG_MAX_GAMMA_8
))
3999 shift
= (16 - PNG_MAX_GAMMA_8
);
4007 png_ptr
->gamma_shift
= (png_byte
)shift
;
4009 num
= (1 << (8 - shift
));
4011 if (png_ptr
->screen_gamma
> .000001)
4012 g
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
4016 png_ptr
->gamma_16_table
= (png_uint_16pp
)png_malloc(png_ptr
,
4017 (png_uint_32
)(num
* sizeof (png_uint_16p
)));
4019 if (png_ptr
->transformations
& (PNG_16_TO_8
| PNG_BACKGROUND
))
4022 png_uint_32 last
, max
;
4024 for (i
= 0; i
< num
; i
++)
4026 png_ptr
->gamma_16_table
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
4027 (png_uint_32
)(256 * sizeof (png_uint_16
)));
4032 for (i
= 0; i
< 256; i
++)
4034 fout
= ((double)i
+ 0.5) / 256.0;
4036 max
= (png_uint_32
)(fin
* (double)((png_uint_32
)num
<< 8));
4039 png_ptr
->gamma_16_table
[(int)(last
& (0xff >> shift
))]
4040 [(int)(last
>> (8 - shift
))] = (png_uint_16
)(
4041 (png_uint_16
)i
| ((png_uint_16
)i
<< 8));
4045 while (last
< ((png_uint_32
)num
<< 8))
4047 png_ptr
->gamma_16_table
[(int)(last
& (0xff >> shift
))]
4048 [(int)(last
>> (8 - shift
))] = (png_uint_16
)65535L;
4054 for (i
= 0; i
< num
; i
++)
4056 png_ptr
->gamma_16_table
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
4057 (png_uint_32
)(256 * sizeof (png_uint_16
)));
4059 ig
= (((png_uint_32
)i
* (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
4060 for (j
= 0; j
< 256; j
++)
4062 png_ptr
->gamma_16_table
[i
][j
] =
4063 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
4064 65535.0, g
) * 65535.0 + .5);
4069 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
4070 defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
4071 if (png_ptr
->transformations
& (PNG_BACKGROUND
| PNG_RGB_TO_GRAY
))
4074 g
= 1.0 / (png_ptr
->gamma
);
4076 png_ptr
->gamma_16_to_1
= (png_uint_16pp
)png_malloc(png_ptr
,
4077 (png_uint_32
)(num
* sizeof (png_uint_16p
)));
4079 for (i
= 0; i
< num
; i
++)
4081 png_ptr
->gamma_16_to_1
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
4082 (png_uint_32
)(256 * sizeof (png_uint_16
)));
4084 ig
= (((png_uint_32
)i
*
4085 (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
4086 for (j
= 0; j
< 256; j
++)
4088 png_ptr
->gamma_16_to_1
[i
][j
] =
4089 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
4090 65535.0, g
) * 65535.0 + .5);
4094 if(png_ptr
->screen_gamma
> 0.000001)
4095 g
= 1.0 / png_ptr
->screen_gamma
;
4097 g
= png_ptr
->gamma
; /* probably doing rgb_to_gray */
4099 png_ptr
->gamma_16_from_1
= (png_uint_16pp
)png_malloc(png_ptr
,
4100 (png_uint_32
)(num
* sizeof (png_uint_16p
)));
4102 for (i
= 0; i
< num
; i
++)
4104 png_ptr
->gamma_16_from_1
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
4105 (png_uint_32
)(256 * sizeof (png_uint_16
)));
4107 ig
= (((png_uint_32
)i
*
4108 (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
4109 for (j
= 0; j
< 256; j
++)
4111 png_ptr
->gamma_16_from_1
[i
][j
] =
4112 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
4113 65535.0, g
) * 65535.0 + .5);
4117 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
4122 /* To do: install integer version of png_build_gamma_table here */
4125 #if defined(PNG_MNG_FEATURES_SUPPORTED)
4126 /* undoes intrapixel differencing */
4128 png_do_read_intrapixel(png_row_infop row_info
, png_bytep row
)
4130 png_debug(1, "in png_do_read_intrapixel\n");
4132 #if defined(PNG_USELESS_TESTS_SUPPORTED)
4133 row
!= NULL
&& row_info
!= NULL
&&
4135 (row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
4137 int bytes_per_pixel
;
4138 png_uint_32 row_width
= row_info
->width
;
4139 if (row_info
->bit_depth
== 8)
4144 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
4145 bytes_per_pixel
= 3;
4146 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
4147 bytes_per_pixel
= 4;
4151 for (i
= 0, rp
= row
; i
< row_width
; i
++, rp
+= bytes_per_pixel
)
4153 *(rp
) = (png_byte
)((256 + *rp
+ *(rp
+1))&0xff);
4154 *(rp
+2) = (png_byte
)((256 + *(rp
+2) + *(rp
+1))&0xff);
4157 else if (row_info
->bit_depth
== 16)
4162 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
4163 bytes_per_pixel
= 6;
4164 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
4165 bytes_per_pixel
= 8;
4169 for (i
= 0, rp
= row
; i
< row_width
; i
++, rp
+= bytes_per_pixel
)
4171 png_uint_32 s0
=*(rp
)<<8 | *(rp
+1);
4172 png_uint_32 s1
=*(rp
+2)<<8 | *(rp
+3);
4173 png_uint_32 s2
=*(rp
+4)<<8 | *(rp
+5);
4174 png_uint_32 red
=(65536+s0
+s1
)&0xffff;
4175 png_uint_32 blue
=(65536+s2
+s1
)&0xffff;
4176 *(rp
) = (png_byte
)((red
>>8)&0xff);
4177 *(rp
+1) = (png_byte
)(red
&0xff);
4178 *(rp
+4) = (png_byte
)((blue
>>8)&0xff);
4179 *(rp
+5) = (png_byte
)(blue
&0xff);
4184 #endif /* PNG_MNG_FEATURES_SUPPORTED */