2 /* pngrtran.c - transforms the data in a row for PNG readers
4 * libpng 1.2.5rc3 - September 18, 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 /* Set the action on getting a CRC error for an ancillary or critical chunk. */
21 png_set_crc_action(png_structp png_ptr
, int crit_action
, int ancil_action
)
23 png_debug(1, "in png_set_crc_action\n");
24 /* Tell libpng how we react to CRC errors in critical chunks */
27 case PNG_CRC_NO_CHANGE
: /* leave setting as is */
29 case PNG_CRC_WARN_USE
: /* warn/use data */
30 png_ptr
->flags
&= ~PNG_FLAG_CRC_CRITICAL_MASK
;
31 png_ptr
->flags
|= PNG_FLAG_CRC_CRITICAL_USE
;
33 case PNG_CRC_QUIET_USE
: /* quiet/use data */
34 png_ptr
->flags
&= ~PNG_FLAG_CRC_CRITICAL_MASK
;
35 png_ptr
->flags
|= PNG_FLAG_CRC_CRITICAL_USE
|
36 PNG_FLAG_CRC_CRITICAL_IGNORE
;
38 case PNG_CRC_WARN_DISCARD
: /* not a valid action for critical data */
39 png_warning(png_ptr
, "Can't discard critical data on CRC error.");
40 case PNG_CRC_ERROR_QUIT
: /* error/quit */
43 png_ptr
->flags
&= ~PNG_FLAG_CRC_CRITICAL_MASK
;
49 case PNG_CRC_NO_CHANGE
: /* leave setting as is */
51 case PNG_CRC_WARN_USE
: /* warn/use data */
52 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
53 png_ptr
->flags
|= PNG_FLAG_CRC_ANCILLARY_USE
;
55 case PNG_CRC_QUIET_USE
: /* quiet/use data */
56 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
57 png_ptr
->flags
|= PNG_FLAG_CRC_ANCILLARY_USE
|
58 PNG_FLAG_CRC_ANCILLARY_NOWARN
;
60 case PNG_CRC_ERROR_QUIT
: /* error/quit */
61 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
62 png_ptr
->flags
|= PNG_FLAG_CRC_ANCILLARY_NOWARN
;
64 case PNG_CRC_WARN_DISCARD
: /* warn/discard data */
67 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
72 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
73 defined(PNG_FLOATING_POINT_SUPPORTED)
74 /* handle alpha and tRNS via a background color */
76 png_set_background(png_structp png_ptr
,
77 png_color_16p background_color
, int background_gamma_code
,
78 int need_expand
, double background_gamma
)
80 png_debug(1, "in png_set_background\n");
81 if (background_gamma_code
== PNG_BACKGROUND_GAMMA_UNKNOWN
)
83 png_warning(png_ptr
, "Application must supply a known background gamma");
87 png_ptr
->transformations
|= PNG_BACKGROUND
;
88 png_memcpy(&(png_ptr
->background
), background_color
, sizeof(png_color_16
));
89 png_ptr
->background_gamma
= (float)background_gamma
;
90 png_ptr
->background_gamma_type
= (png_byte
)(background_gamma_code
);
91 png_ptr
->transformations
|= (need_expand
? PNG_BACKGROUND_EXPAND
: 0);
93 /* Note: if need_expand is set and color_type is either RGB or RGB_ALPHA
94 * (in which case need_expand is superfluous anyway), the background color
95 * might actually be gray yet not be flagged as such. This is not a problem
96 * for the current code, which uses PNG_BACKGROUND_IS_GRAY only to
97 * decide when to do the png_do_gray_to_rgb() transformation.
99 if ((need_expand
&& !(png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)) ||
100 (!need_expand
&& background_color
->red
== background_color
->green
&&
101 background_color
->red
== background_color
->blue
))
102 png_ptr
->mode
|= PNG_BACKGROUND_IS_GRAY
;
106 #if defined(PNG_READ_16_TO_8_SUPPORTED)
107 /* strip 16 bit depth files to 8 bit depth */
109 png_set_strip_16(png_structp png_ptr
)
111 png_debug(1, "in png_set_strip_16\n");
112 png_ptr
->transformations
|= PNG_16_TO_8
;
116 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
118 png_set_strip_alpha(png_structp png_ptr
)
120 png_debug(1, "in png_set_strip_alpha\n");
121 png_ptr
->transformations
|= PNG_STRIP_ALPHA
;
125 #if defined(PNG_READ_DITHER_SUPPORTED)
126 /* Dither file to 8 bit. Supply a palette, the current number
127 * of elements in the palette, the maximum number of elements
128 * allowed, and a histogram if possible. If the current number
129 * of colors is greater then the maximum number, the palette will be
130 * modified to fit in the maximum number. "full_dither" indicates
131 * whether we need a dithering cube set up for RGB images, or if we
132 * simply are reducing the number of colors in a paletted image.
135 typedef struct png_dsort_struct
137 struct png_dsort_struct FAR
* next
;
141 typedef png_dsort FAR
* png_dsortp
;
142 typedef png_dsort FAR
* FAR
* png_dsortpp
;
145 png_set_dither(png_structp png_ptr
, png_colorp palette
,
146 int num_palette
, int maximum_colors
, png_uint_16p histogram
,
149 png_debug(1, "in png_set_dither\n");
150 png_ptr
->transformations
|= PNG_DITHER
;
156 png_ptr
->dither_index
= (png_bytep
)png_malloc(png_ptr
,
157 (png_uint_32
)(num_palette
* sizeof (png_byte
)));
158 for (i
= 0; i
< num_palette
; i
++)
159 png_ptr
->dither_index
[i
] = (png_byte
)i
;
162 if (num_palette
> maximum_colors
)
164 if (histogram
!= NULL
)
166 /* This is easy enough, just throw out the least used colors.
167 Perhaps not the best solution, but good enough. */
171 /* initialize an array to sort colors */
172 png_ptr
->dither_sort
= (png_bytep
)png_malloc(png_ptr
,
173 (png_uint_32
)(num_palette
* sizeof (png_byte
)));
175 /* initialize the dither_sort array */
176 for (i
= 0; i
< num_palette
; i
++)
177 png_ptr
->dither_sort
[i
] = (png_byte
)i
;
179 /* Find the least used palette entries by starting a
180 bubble sort, and running it until we have sorted
181 out enough colors. Note that we don't care about
182 sorting all the colors, just finding which are
185 for (i
= num_palette
- 1; i
>= maximum_colors
; i
--)
187 int done
; /* to stop early if the list is pre-sorted */
191 for (j
= 0; j
< i
; j
++)
193 if (histogram
[png_ptr
->dither_sort
[j
]]
194 < histogram
[png_ptr
->dither_sort
[j
+ 1]])
198 t
= png_ptr
->dither_sort
[j
];
199 png_ptr
->dither_sort
[j
] = png_ptr
->dither_sort
[j
+ 1];
200 png_ptr
->dither_sort
[j
+ 1] = t
;
208 /* swap the palette around, and set up a table, if necessary */
213 /* put all the useful colors within the max, but don't
215 for (i
= 0; i
< maximum_colors
; i
++)
217 if ((int)png_ptr
->dither_sort
[i
] >= maximum_colors
)
221 while ((int)png_ptr
->dither_sort
[j
] >= maximum_colors
);
222 palette
[i
] = palette
[j
];
230 /* move all the used colors inside the max limit, and
231 develop a translation table */
232 for (i
= 0; i
< maximum_colors
; i
++)
234 /* only move the colors we need to */
235 if ((int)png_ptr
->dither_sort
[i
] >= maximum_colors
)
241 while ((int)png_ptr
->dither_sort
[j
] >= maximum_colors
);
243 tmp_color
= palette
[j
];
244 palette
[j
] = palette
[i
];
245 palette
[i
] = tmp_color
;
246 /* indicate where the color went */
247 png_ptr
->dither_index
[j
] = (png_byte
)i
;
248 png_ptr
->dither_index
[i
] = (png_byte
)j
;
252 /* find closest color for those colors we are not using */
253 for (i
= 0; i
< num_palette
; i
++)
255 if ((int)png_ptr
->dither_index
[i
] >= maximum_colors
)
257 int min_d
, k
, min_k
, d_index
;
259 /* find the closest color to one we threw out */
260 d_index
= png_ptr
->dither_index
[i
];
261 min_d
= PNG_COLOR_DIST(palette
[d_index
], palette
[0]);
262 for (k
= 1, min_k
= 0; k
< maximum_colors
; k
++)
266 d
= PNG_COLOR_DIST(palette
[d_index
], palette
[k
]);
274 /* point to closest color */
275 png_ptr
->dither_index
[i
] = (png_byte
)min_k
;
279 png_free(png_ptr
, png_ptr
->dither_sort
);
280 png_ptr
->dither_sort
=NULL
;
284 /* This is much harder to do simply (and quickly). Perhaps
285 we need to go through a median cut routine, but those
286 don't always behave themselves with only a few colors
287 as input. So we will just find the closest two colors,
288 and throw out one of them (chosen somewhat randomly).
289 [We don't understand this at all, so if someone wants to
290 work on improving it, be our guest - AED, GRP]
300 /* initialize palette index arrays */
301 png_ptr
->index_to_palette
= (png_bytep
)png_malloc(png_ptr
,
302 (png_uint_32
)(num_palette
* sizeof (png_byte
)));
303 png_ptr
->palette_to_index
= (png_bytep
)png_malloc(png_ptr
,
304 (png_uint_32
)(num_palette
* sizeof (png_byte
)));
306 /* initialize the sort array */
307 for (i
= 0; i
< num_palette
; i
++)
309 png_ptr
->index_to_palette
[i
] = (png_byte
)i
;
310 png_ptr
->palette_to_index
[i
] = (png_byte
)i
;
313 hash
= (png_dsortpp
)png_malloc(png_ptr
, (png_uint_32
)(769 *
314 sizeof (png_dsortp
)));
315 for (i
= 0; i
< 769; i
++)
317 /* png_memset(hash, 0, 769 * sizeof (png_dsortp)); */
319 num_new_palette
= num_palette
;
321 /* initial wild guess at how far apart the farthest pixel
322 pair we will be eliminating will be. Larger
323 numbers mean more areas will be allocated, Smaller
324 numbers run the risk of not saving enough data, and
325 having to do this all over again.
327 I have not done extensive checking on this number.
331 while (num_new_palette
> maximum_colors
)
333 for (i
= 0; i
< num_new_palette
- 1; i
++)
337 for (j
= i
+ 1; j
< num_new_palette
; j
++)
341 d
= PNG_COLOR_DIST(palette
[i
], palette
[j
]);
346 t
= (png_dsortp
)png_malloc_warn(png_ptr
,
347 (png_uint_32
)(sizeof(png_dsort
)));
351 t
->left
= (png_byte
)i
;
352 t
->right
= (png_byte
)j
;
361 for (i
= 0; i
<= max_d
; i
++)
367 for (p
= hash
[i
]; p
; p
= p
->next
)
369 if ((int)png_ptr
->index_to_palette
[p
->left
]
371 (int)png_ptr
->index_to_palette
[p
->right
]
376 if (num_new_palette
& 0x01)
388 palette
[png_ptr
->index_to_palette
[j
]]
389 = palette
[num_new_palette
];
394 for (k
= 0; k
< num_palette
; k
++)
396 if (png_ptr
->dither_index
[k
] ==
397 png_ptr
->index_to_palette
[j
])
398 png_ptr
->dither_index
[k
] =
399 png_ptr
->index_to_palette
[next_j
];
400 if ((int)png_ptr
->dither_index
[k
] ==
402 png_ptr
->dither_index
[k
] =
403 png_ptr
->index_to_palette
[j
];
407 png_ptr
->index_to_palette
[png_ptr
->palette_to_index
408 [num_new_palette
]] = png_ptr
->index_to_palette
[j
];
409 png_ptr
->palette_to_index
[png_ptr
->index_to_palette
[j
]]
410 = png_ptr
->palette_to_index
[num_new_palette
];
412 png_ptr
->index_to_palette
[j
] = (png_byte
)num_new_palette
;
413 png_ptr
->palette_to_index
[num_new_palette
] = (png_byte
)j
;
415 if (num_new_palette
<= maximum_colors
)
418 if (num_new_palette
<= maximum_colors
)
423 for (i
= 0; i
< 769; i
++)
427 png_dsortp p
= hash
[i
];
431 png_free(png_ptr
, p
);
439 png_free(png_ptr
, hash
);
440 png_free(png_ptr
, png_ptr
->palette_to_index
);
441 png_free(png_ptr
, png_ptr
->index_to_palette
);
442 png_ptr
->palette_to_index
=NULL
;
443 png_ptr
->index_to_palette
=NULL
;
445 num_palette
= maximum_colors
;
447 if (png_ptr
->palette
== NULL
)
449 png_ptr
->palette
= palette
;
451 png_ptr
->num_palette
= (png_uint_16
)num_palette
;
457 int total_bits
= PNG_DITHER_RED_BITS
+ PNG_DITHER_GREEN_BITS
+
458 PNG_DITHER_BLUE_BITS
;
459 int num_red
= (1 << PNG_DITHER_RED_BITS
);
460 int num_green
= (1 << PNG_DITHER_GREEN_BITS
);
461 int num_blue
= (1 << PNG_DITHER_BLUE_BITS
);
462 png_size_t num_entries
= ((png_size_t
)1 << total_bits
);
464 png_ptr
->palette_lookup
= (png_bytep
)png_malloc(png_ptr
,
465 (png_uint_32
)(num_entries
* sizeof (png_byte
)));
467 png_memset(png_ptr
->palette_lookup
, 0, num_entries
* sizeof (png_byte
));
469 distance
= (png_bytep
)png_malloc(png_ptr
, (png_uint_32
)(num_entries
*
472 png_memset(distance
, 0xff, num_entries
* sizeof(png_byte
));
474 for (i
= 0; i
< num_palette
; i
++)
477 int r
= (palette
[i
].red
>> (8 - PNG_DITHER_RED_BITS
));
478 int g
= (palette
[i
].green
>> (8 - PNG_DITHER_GREEN_BITS
));
479 int b
= (palette
[i
].blue
>> (8 - PNG_DITHER_BLUE_BITS
));
481 for (ir
= 0; ir
< num_red
; ir
++)
483 int dr
= abs(ir
- r
);
484 int index_r
= (ir
<< (PNG_DITHER_BLUE_BITS
+ PNG_DITHER_GREEN_BITS
));
486 for (ig
= 0; ig
< num_green
; ig
++)
488 int dg
= abs(ig
- g
);
490 int dm
= ((dr
> dg
) ? dr
: dg
);
491 int index_g
= index_r
| (ig
<< PNG_DITHER_BLUE_BITS
);
493 for (ib
= 0; ib
< num_blue
; ib
++)
495 int d_index
= index_g
| ib
;
496 int db
= abs(ib
- b
);
497 int dmax
= ((dm
> db
) ? dm
: db
);
498 int d
= dmax
+ dt
+ db
;
500 if (d
< (int)distance
[d_index
])
502 distance
[d_index
] = (png_byte
)d
;
503 png_ptr
->palette_lookup
[d_index
] = (png_byte
)i
;
510 png_free(png_ptr
, distance
);
515 #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
516 /* Transform the image from the file_gamma to the screen_gamma. We
517 * only do transformations on images where the file_gamma and screen_gamma
518 * are not close reciprocals, otherwise it slows things down slightly, and
519 * also needlessly introduces small errors.
521 * We will turn off gamma transformation later if no semitransparent entries
522 * are present in the tRNS array for palette images. We can't do it here
523 * because we don't necessarily have the tRNS chunk yet.
526 png_set_gamma(png_structp png_ptr
, double scrn_gamma
, double file_gamma
)
528 png_debug(1, "in png_set_gamma\n");
529 if ((fabs(scrn_gamma
* file_gamma
- 1.0) > PNG_GAMMA_THRESHOLD
) ||
530 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
) ||
531 (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
))
532 png_ptr
->transformations
|= PNG_GAMMA
;
533 png_ptr
->gamma
= (float)file_gamma
;
534 png_ptr
->screen_gamma
= (float)scrn_gamma
;
538 #if defined(PNG_READ_EXPAND_SUPPORTED)
539 /* Expand paletted images to RGB, expand grayscale images of
540 * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
544 png_set_expand(png_structp png_ptr
)
546 png_debug(1, "in png_set_expand\n");
547 png_ptr
->transformations
|= PNG_EXPAND
;
550 /* GRR 19990627: the following three functions currently are identical
551 * to png_set_expand(). However, it is entirely reasonable that someone
552 * might wish to expand an indexed image to RGB but *not* expand a single,
553 * fully transparent palette entry to a full alpha channel--perhaps instead
554 * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
555 * the transparent color with a particular RGB value, or drop tRNS entirely.
556 * IOW, a future version of the library may make the transformations flag
557 * a bit more fine-grained, with separate bits for each of these three
560 * More to the point, these functions make it obvious what libpng will be
561 * doing, whereas "expand" can (and does) mean any number of things.
564 /* Expand paletted images to RGB. */
566 png_set_palette_to_rgb(png_structp png_ptr
)
568 png_debug(1, "in png_set_expand\n");
569 png_ptr
->transformations
|= PNG_EXPAND
;
572 /* Expand grayscale images of less than 8-bit depth to 8 bits. */
574 png_set_gray_1_2_4_to_8(png_structp png_ptr
)
576 png_debug(1, "in png_set_expand\n");
577 png_ptr
->transformations
|= PNG_EXPAND
;
580 /* Expand tRNS chunks to alpha channels. */
582 png_set_tRNS_to_alpha(png_structp png_ptr
)
584 png_debug(1, "in png_set_expand\n");
585 png_ptr
->transformations
|= PNG_EXPAND
;
587 #endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
589 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
591 png_set_gray_to_rgb(png_structp png_ptr
)
593 png_debug(1, "in png_set_gray_to_rgb\n");
594 png_ptr
->transformations
|= PNG_GRAY_TO_RGB
;
598 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
599 #if defined(PNG_FLOATING_POINT_SUPPORTED)
600 /* Convert a RGB image to a grayscale of the same width. This allows us,
601 * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
605 png_set_rgb_to_gray(png_structp png_ptr
, int error_action
, double red
,
608 int red_fixed
= (int)((float)red
*100000.0 + 0.5);
609 int green_fixed
= (int)((float)green
*100000.0 + 0.5);
610 png_set_rgb_to_gray_fixed(png_ptr
, error_action
, red_fixed
, green_fixed
);
615 png_set_rgb_to_gray_fixed(png_structp png_ptr
, int error_action
,
616 png_fixed_point red
, png_fixed_point green
)
618 png_debug(1, "in png_set_rgb_to_gray\n");
621 case 1: png_ptr
->transformations
|= PNG_RGB_TO_GRAY
;
623 case 2: png_ptr
->transformations
|= PNG_RGB_TO_GRAY_WARN
;
625 case 3: png_ptr
->transformations
|= PNG_RGB_TO_GRAY_ERR
;
627 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
628 #if defined(PNG_READ_EXPAND_SUPPORTED)
629 png_ptr
->transformations
|= PNG_EXPAND
;
632 png_warning(png_ptr
, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
633 png_ptr
->transformations
&= ~PNG_RGB_TO_GRAY
;
637 png_uint_16 red_int
, green_int
;
638 if(red
< 0 || green
< 0)
640 red_int
= 6968; /* .212671 * 32768 + .5 */
641 green_int
= 23434; /* .715160 * 32768 + .5 */
643 else if(red
+ green
< 100000L)
645 red_int
= (png_uint_16
)(((png_uint_32
)red
*32768L)/100000L);
646 green_int
= (png_uint_16
)(((png_uint_32
)green
*32768L)/100000L);
650 png_warning(png_ptr
, "ignoring out of range rgb_to_gray coefficients");
654 png_ptr
->rgb_to_gray_red_coeff
= red_int
;
655 png_ptr
->rgb_to_gray_green_coeff
= green_int
;
656 png_ptr
->rgb_to_gray_blue_coeff
= (png_uint_16
)(32768-red_int
-green_int
);
661 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
662 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
663 defined(PNG_LEGACY_SUPPORTED)
665 png_set_read_user_transform_fn(png_structp png_ptr
, png_user_transform_ptr
666 read_user_transform_fn
)
668 png_debug(1, "in png_set_read_user_transform_fn\n");
669 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
670 png_ptr
->transformations
|= PNG_USER_TRANSFORM
;
671 png_ptr
->read_user_transform_fn
= read_user_transform_fn
;
673 #ifdef PNG_LEGACY_SUPPORTED
674 if(read_user_transform_fn
)
676 "This version of libpng does not support user transforms");
681 /* Initialize everything needed for the read. This includes modifying
685 png_init_read_transformations(png_structp png_ptr
)
687 png_debug(1, "in png_init_read_transformations\n");
688 #if defined(PNG_USELESS_TESTS_SUPPORTED)
692 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
693 || defined(PNG_READ_GAMMA_SUPPORTED)
694 int color_type
= png_ptr
->color_type
;
697 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
698 if ((png_ptr
->transformations
& PNG_BACKGROUND_EXPAND
) &&
699 (png_ptr
->transformations
& PNG_EXPAND
))
701 if (!(color_type
& PNG_COLOR_MASK_COLOR
)) /* i.e., GRAY or GRAY_ALPHA */
703 /* expand background chunk. */
704 switch (png_ptr
->bit_depth
)
707 png_ptr
->background
.gray
*= (png_uint_16
)0xff;
708 png_ptr
->background
.red
= png_ptr
->background
.green
709 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
712 png_ptr
->background
.gray
*= (png_uint_16
)0x55;
713 png_ptr
->background
.red
= png_ptr
->background
.green
714 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
717 png_ptr
->background
.gray
*= (png_uint_16
)0x11;
718 png_ptr
->background
.red
= png_ptr
->background
.green
719 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
723 png_ptr
->background
.red
= png_ptr
->background
.green
724 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
728 else if (color_type
== PNG_COLOR_TYPE_PALETTE
)
730 png_ptr
->background
.red
=
731 png_ptr
->palette
[png_ptr
->background
.index
].red
;
732 png_ptr
->background
.green
=
733 png_ptr
->palette
[png_ptr
->background
.index
].green
;
734 png_ptr
->background
.blue
=
735 png_ptr
->palette
[png_ptr
->background
.index
].blue
;
737 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
738 if (png_ptr
->transformations
& PNG_INVERT_ALPHA
)
740 #if defined(PNG_READ_EXPAND_SUPPORTED)
741 if (!(png_ptr
->transformations
& PNG_EXPAND
))
744 /* invert the alpha channel (in tRNS) unless the pixels are
745 going to be expanded, in which case leave it for later */
747 istop
=(int)png_ptr
->num_trans
;
748 for (i
=0; i
<istop
; i
++)
749 png_ptr
->trans
[i
] = (png_byte
)(255 - png_ptr
->trans
[i
]);
758 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
759 png_ptr
->background_1
= png_ptr
->background
;
761 #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
763 if ((color_type
== PNG_COLOR_TYPE_PALETTE
&& png_ptr
->num_trans
!= 0)
764 && (fabs(png_ptr
->screen_gamma
* png_ptr
->gamma
- 1.0)
765 < PNG_GAMMA_THRESHOLD
))
769 for (i
=0; i
<png_ptr
->num_trans
; i
++)
771 if (png_ptr
->trans
[i
] != 0 && png_ptr
->trans
[i
] != 0xff)
772 k
=1; /* partial transparency is present */
775 png_ptr
->transformations
&= (~PNG_GAMMA
);
778 if (png_ptr
->transformations
& (PNG_GAMMA
| PNG_RGB_TO_GRAY
))
780 png_build_gamma_table(png_ptr
);
781 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
782 if (png_ptr
->transformations
& PNG_BACKGROUND
)
784 if (color_type
== PNG_COLOR_TYPE_PALETTE
)
786 /* could skip if no transparency and
788 png_color back
, back_1
;
789 png_colorp palette
= png_ptr
->palette
;
790 int num_palette
= png_ptr
->num_palette
;
792 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_FILE
)
794 back
.red
= png_ptr
->gamma_table
[png_ptr
->background
.red
];
795 back
.green
= png_ptr
->gamma_table
[png_ptr
->background
.green
];
796 back
.blue
= png_ptr
->gamma_table
[png_ptr
->background
.blue
];
798 back_1
.red
= png_ptr
->gamma_to_1
[png_ptr
->background
.red
];
799 back_1
.green
= png_ptr
->gamma_to_1
[png_ptr
->background
.green
];
800 back_1
.blue
= png_ptr
->gamma_to_1
[png_ptr
->background
.blue
];
806 switch (png_ptr
->background_gamma_type
)
808 case PNG_BACKGROUND_GAMMA_SCREEN
:
809 g
= (png_ptr
->screen_gamma
);
812 case PNG_BACKGROUND_GAMMA_FILE
:
813 g
= 1.0 / (png_ptr
->gamma
);
814 gs
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
816 case PNG_BACKGROUND_GAMMA_UNIQUE
:
817 g
= 1.0 / (png_ptr
->background_gamma
);
818 gs
= 1.0 / (png_ptr
->background_gamma
*
819 png_ptr
->screen_gamma
);
822 g
= 1.0; /* back_1 */
826 if ( fabs(gs
- 1.0) < PNG_GAMMA_THRESHOLD
)
828 back
.red
= (png_byte
)png_ptr
->background
.red
;
829 back
.green
= (png_byte
)png_ptr
->background
.green
;
830 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
834 back
.red
= (png_byte
)(pow(
835 (double)png_ptr
->background
.red
/255, gs
) * 255.0 + .5);
836 back
.green
= (png_byte
)(pow(
837 (double)png_ptr
->background
.green
/255, gs
) * 255.0 + .5);
838 back
.blue
= (png_byte
)(pow(
839 (double)png_ptr
->background
.blue
/255, gs
) * 255.0 + .5);
842 back_1
.red
= (png_byte
)(pow(
843 (double)png_ptr
->background
.red
/255, g
) * 255.0 + .5);
844 back_1
.green
= (png_byte
)(pow(
845 (double)png_ptr
->background
.green
/255, g
) * 255.0 + .5);
846 back_1
.blue
= (png_byte
)(pow(
847 (double)png_ptr
->background
.blue
/255, g
) * 255.0 + .5);
849 for (i
= 0; i
< num_palette
; i
++)
851 if (i
< (int)png_ptr
->num_trans
&& png_ptr
->trans
[i
] != 0xff)
853 if (png_ptr
->trans
[i
] == 0)
857 else /* if (png_ptr->trans[i] != 0xff) */
861 v
= png_ptr
->gamma_to_1
[palette
[i
].red
];
862 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.red
);
863 palette
[i
].red
= png_ptr
->gamma_from_1
[w
];
865 v
= png_ptr
->gamma_to_1
[palette
[i
].green
];
866 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.green
);
867 palette
[i
].green
= png_ptr
->gamma_from_1
[w
];
869 v
= png_ptr
->gamma_to_1
[palette
[i
].blue
];
870 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.blue
);
871 palette
[i
].blue
= png_ptr
->gamma_from_1
[w
];
876 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
877 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
878 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
882 /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
884 /* color_type != PNG_COLOR_TYPE_PALETTE */
886 double m
= (double)(((png_uint_32
)1 << png_ptr
->bit_depth
) - 1);
890 switch (png_ptr
->background_gamma_type
)
892 case PNG_BACKGROUND_GAMMA_SCREEN
:
893 g
= (png_ptr
->screen_gamma
);
896 case PNG_BACKGROUND_GAMMA_FILE
:
897 g
= 1.0 / (png_ptr
->gamma
);
898 gs
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
900 case PNG_BACKGROUND_GAMMA_UNIQUE
:
901 g
= 1.0 / (png_ptr
->background_gamma
);
902 gs
= 1.0 / (png_ptr
->background_gamma
*
903 png_ptr
->screen_gamma
);
907 png_ptr
->background_1
.gray
= (png_uint_16
)(pow(
908 (double)png_ptr
->background
.gray
/ m
, g
) * m
+ .5);
909 png_ptr
->background
.gray
= (png_uint_16
)(pow(
910 (double)png_ptr
->background
.gray
/ m
, gs
) * m
+ .5);
912 if ((png_ptr
->background
.red
!= png_ptr
->background
.green
) ||
913 (png_ptr
->background
.red
!= png_ptr
->background
.blue
) ||
914 (png_ptr
->background
.red
!= png_ptr
->background
.gray
))
916 /* RGB or RGBA with color background */
917 png_ptr
->background_1
.red
= (png_uint_16
)(pow(
918 (double)png_ptr
->background
.red
/ m
, g
) * m
+ .5);
919 png_ptr
->background_1
.green
= (png_uint_16
)(pow(
920 (double)png_ptr
->background
.green
/ m
, g
) * m
+ .5);
921 png_ptr
->background_1
.blue
= (png_uint_16
)(pow(
922 (double)png_ptr
->background
.blue
/ m
, g
) * m
+ .5);
923 png_ptr
->background
.red
= (png_uint_16
)(pow(
924 (double)png_ptr
->background
.red
/ m
, gs
) * m
+ .5);
925 png_ptr
->background
.green
= (png_uint_16
)(pow(
926 (double)png_ptr
->background
.green
/ m
, gs
) * m
+ .5);
927 png_ptr
->background
.blue
= (png_uint_16
)(pow(
928 (double)png_ptr
->background
.blue
/ m
, gs
) * m
+ .5);
932 /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
933 png_ptr
->background_1
.red
= png_ptr
->background_1
.green
934 = png_ptr
->background_1
.blue
= png_ptr
->background_1
.gray
;
935 png_ptr
->background
.red
= png_ptr
->background
.green
936 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
941 /* transformation does not include PNG_BACKGROUND */
942 #endif /* PNG_READ_BACKGROUND_SUPPORTED */
943 if (color_type
== PNG_COLOR_TYPE_PALETTE
)
945 png_colorp palette
= png_ptr
->palette
;
946 int num_palette
= png_ptr
->num_palette
;
949 for (i
= 0; i
< num_palette
; i
++)
951 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
952 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
953 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
957 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
960 #endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */
961 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
962 /* No GAMMA transformation */
963 if ((png_ptr
->transformations
& PNG_BACKGROUND
) &&
964 (color_type
== PNG_COLOR_TYPE_PALETTE
))
967 int istop
= (int)png_ptr
->num_trans
;
969 png_colorp palette
= png_ptr
->palette
;
971 back
.red
= (png_byte
)png_ptr
->background
.red
;
972 back
.green
= (png_byte
)png_ptr
->background
.green
;
973 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
975 for (i
= 0; i
< istop
; i
++)
977 if (png_ptr
->trans
[i
] == 0)
981 else if (png_ptr
->trans
[i
] != 0xff)
983 /* The png_composite() macro is defined in png.h */
984 png_composite(palette
[i
].red
, palette
[i
].red
,
985 png_ptr
->trans
[i
], back
.red
);
986 png_composite(palette
[i
].green
, palette
[i
].green
,
987 png_ptr
->trans
[i
], back
.green
);
988 png_composite(palette
[i
].blue
, palette
[i
].blue
,
989 png_ptr
->trans
[i
], back
.blue
);
993 #endif /* PNG_READ_BACKGROUND_SUPPORTED */
995 #if defined(PNG_READ_SHIFT_SUPPORTED)
996 if ((png_ptr
->transformations
& PNG_SHIFT
) &&
997 (color_type
== PNG_COLOR_TYPE_PALETTE
))
1000 png_uint_16 istop
= png_ptr
->num_palette
;
1001 int sr
= 8 - png_ptr
->sig_bit
.red
;
1002 int sg
= 8 - png_ptr
->sig_bit
.green
;
1003 int sb
= 8 - png_ptr
->sig_bit
.blue
;
1005 if (sr
< 0 || sr
> 8)
1007 if (sg
< 0 || sg
> 8)
1009 if (sb
< 0 || sb
> 8)
1011 for (i
= 0; i
< istop
; i
++)
1013 png_ptr
->palette
[i
].red
>>= sr
;
1014 png_ptr
->palette
[i
].green
>>= sg
;
1015 png_ptr
->palette
[i
].blue
>>= sb
;
1018 #endif /* PNG_READ_SHIFT_SUPPORTED */
1020 #if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
1021 && !defined(PNG_READ_BACKGROUND_SUPPORTED)
1027 /* Modify the info structure to reflect the transformations. The
1028 * info should be updated so a PNG file could be written with it,
1029 * assuming the transformations result in valid PNG data.
1032 png_read_transform_info(png_structp png_ptr
, png_infop info_ptr
)
1034 png_debug(1, "in png_read_transform_info\n");
1035 #if defined(PNG_READ_EXPAND_SUPPORTED)
1036 if (png_ptr
->transformations
& PNG_EXPAND
)
1038 if (info_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1040 if (png_ptr
->num_trans
)
1041 info_ptr
->color_type
= PNG_COLOR_TYPE_RGB_ALPHA
;
1043 info_ptr
->color_type
= PNG_COLOR_TYPE_RGB
;
1044 info_ptr
->bit_depth
= 8;
1045 info_ptr
->num_trans
= 0;
1049 if (png_ptr
->num_trans
)
1050 info_ptr
->color_type
|= PNG_COLOR_MASK_ALPHA
;
1051 if (info_ptr
->bit_depth
< 8)
1052 info_ptr
->bit_depth
= 8;
1053 info_ptr
->num_trans
= 0;
1058 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1059 if (png_ptr
->transformations
& PNG_BACKGROUND
)
1061 info_ptr
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
1062 info_ptr
->num_trans
= 0;
1063 info_ptr
->background
= png_ptr
->background
;
1067 #if defined(PNG_READ_GAMMA_SUPPORTED)
1068 if (png_ptr
->transformations
& PNG_GAMMA
)
1070 #ifdef PNG_FLOATING_POINT_SUPPORTED
1071 info_ptr
->gamma
= png_ptr
->gamma
;
1073 #ifdef PNG_FIXED_POINT_SUPPORTED
1074 info_ptr
->int_gamma
= png_ptr
->int_gamma
;
1079 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1080 if ((png_ptr
->transformations
& PNG_16_TO_8
) && (info_ptr
->bit_depth
== 16))
1081 info_ptr
->bit_depth
= 8;
1084 #if defined(PNG_READ_DITHER_SUPPORTED)
1085 if (png_ptr
->transformations
& PNG_DITHER
)
1087 if (((info_ptr
->color_type
== PNG_COLOR_TYPE_RGB
) ||
1088 (info_ptr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)) &&
1089 png_ptr
->palette_lookup
&& info_ptr
->bit_depth
== 8)
1091 info_ptr
->color_type
= PNG_COLOR_TYPE_PALETTE
;
1096 #if defined(PNG_READ_PACK_SUPPORTED)
1097 if ((png_ptr
->transformations
& PNG_PACK
) && (info_ptr
->bit_depth
< 8))
1098 info_ptr
->bit_depth
= 8;
1101 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1102 if (png_ptr
->transformations
& PNG_GRAY_TO_RGB
)
1103 info_ptr
->color_type
|= PNG_COLOR_MASK_COLOR
;
1106 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1107 if (png_ptr
->transformations
& PNG_RGB_TO_GRAY
)
1108 info_ptr
->color_type
&= ~PNG_COLOR_MASK_COLOR
;
1111 if (info_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1112 info_ptr
->channels
= 1;
1113 else if (info_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
1114 info_ptr
->channels
= 3;
1116 info_ptr
->channels
= 1;
1118 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1119 if (png_ptr
->transformations
& PNG_STRIP_ALPHA
)
1120 info_ptr
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
1123 if (info_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
)
1124 info_ptr
->channels
++;
1126 #if defined(PNG_READ_FILLER_SUPPORTED)
1127 /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
1128 if ((png_ptr
->transformations
& PNG_FILLER
) &&
1129 ((info_ptr
->color_type
== PNG_COLOR_TYPE_RGB
) ||
1130 (info_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)))
1132 info_ptr
->channels
++;
1133 #if 0 /* if adding a true alpha channel not just filler */
1134 info_ptr
->color_type
|= PNG_COLOR_MASK_ALPHA
;
1139 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
1140 defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1141 if(png_ptr
->transformations
& PNG_USER_TRANSFORM
)
1143 if(info_ptr
->bit_depth
< png_ptr
->user_transform_depth
)
1144 info_ptr
->bit_depth
= png_ptr
->user_transform_depth
;
1145 if(info_ptr
->channels
< png_ptr
->user_transform_channels
)
1146 info_ptr
->channels
= png_ptr
->user_transform_channels
;
1150 info_ptr
->pixel_depth
= (png_byte
)(info_ptr
->channels
*
1151 info_ptr
->bit_depth
);
1152 info_ptr
->rowbytes
= ((info_ptr
->width
* info_ptr
->pixel_depth
+ 7) >> 3);
1154 #if !defined(PNG_READ_EXPAND_SUPPORTED)
1160 /* Transform the row. The order of transformations is significant,
1161 * and is very touchy. If you add a transformation, take care to
1162 * decide how it fits in with the other transformations here.
1165 png_do_read_transformations(png_structp png_ptr
)
1167 png_debug(1, "in png_do_read_transformations\n");
1168 #if !defined(PNG_USELESS_TESTS_SUPPORTED)
1169 if (png_ptr
->row_buf
== NULL
)
1171 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
1174 sprintf(msg
, "NULL row buffer for row %ld, pass %d", png_ptr
->row_number
,
1176 png_error(png_ptr
, msg
);
1178 png_error(png_ptr
, "NULL row buffer");
1183 #if defined(PNG_READ_EXPAND_SUPPORTED)
1184 if (png_ptr
->transformations
& PNG_EXPAND
)
1186 if (png_ptr
->row_info
.color_type
== PNG_COLOR_TYPE_PALETTE
)
1188 png_do_expand_palette(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1189 png_ptr
->palette
, png_ptr
->trans
, png_ptr
->num_trans
);
1193 if (png_ptr
->num_trans
)
1194 png_do_expand(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1195 &(png_ptr
->trans_values
));
1197 png_do_expand(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1203 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1204 if (png_ptr
->transformations
& PNG_STRIP_ALPHA
)
1205 png_do_strip_filler(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1206 PNG_FLAG_FILLER_AFTER
);
1209 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1210 if (png_ptr
->transformations
& PNG_RGB_TO_GRAY
)
1213 png_do_rgb_to_gray(png_ptr
, &(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1216 png_ptr
->rgb_to_gray_status
=1;
1217 if(png_ptr
->transformations
== PNG_RGB_TO_GRAY_WARN
)
1218 png_warning(png_ptr
, "png_do_rgb_to_gray found nongray pixel");
1219 if(png_ptr
->transformations
== PNG_RGB_TO_GRAY_ERR
)
1220 png_error(png_ptr
, "png_do_rgb_to_gray found nongray pixel");
1226 From Andreas Dilger e-mail to png-implement, 26 March 1998:
1228 In most cases, the "simple transparency" should be done prior to doing
1229 gray-to-RGB, or you will have to test 3x as many bytes to check if a
1230 pixel is transparent. You would also need to make sure that the
1231 transparency information is upgraded to RGB.
1233 To summarize, the current flow is:
1234 - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
1235 with background "in place" if transparent,
1236 convert to RGB if necessary
1237 - Gray + alpha -> composite with gray background and remove alpha bytes,
1238 convert to RGB if necessary
1240 To support RGB backgrounds for gray images we need:
1241 - Gray + simple transparency -> convert to RGB + simple transparency, compare
1242 3 or 6 bytes and composite with background
1243 "in place" if transparent (3x compare/pixel
1244 compared to doing composite with gray bkgrnd)
1245 - Gray + alpha -> convert to RGB + alpha, composite with background and
1246 remove alpha bytes (3x float operations/pixel
1247 compared with composite on gray background)
1249 Greg's change will do this. The reason it wasn't done before is for
1250 performance, as this increases the per-pixel operations. If we would check
1251 in advance if the background was gray or RGB, and position the gray-to-RGB
1252 transform appropriately, then it would save a lot of work/time.
1255 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1256 /* if gray -> RGB, do so now only if background is non-gray; else do later
1257 * for performance reasons */
1258 if ((png_ptr
->transformations
& PNG_GRAY_TO_RGB
) &&
1259 !(png_ptr
->mode
& PNG_BACKGROUND_IS_GRAY
))
1260 png_do_gray_to_rgb(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1263 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1264 if ((png_ptr
->transformations
& PNG_BACKGROUND
) &&
1265 ((png_ptr
->num_trans
!= 0 ) ||
1266 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
)))
1267 png_do_background(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1268 &(png_ptr
->trans_values
), &(png_ptr
->background
)
1269 #if defined(PNG_READ_GAMMA_SUPPORTED)
1270 , &(png_ptr
->background_1
),
1271 png_ptr
->gamma_table
, png_ptr
->gamma_from_1
,
1272 png_ptr
->gamma_to_1
, png_ptr
->gamma_16_table
,
1273 png_ptr
->gamma_16_from_1
, png_ptr
->gamma_16_to_1
,
1274 png_ptr
->gamma_shift
1279 #if defined(PNG_READ_GAMMA_SUPPORTED)
1280 if ((png_ptr
->transformations
& PNG_GAMMA
) &&
1281 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1282 !((png_ptr
->transformations
& PNG_BACKGROUND
) &&
1283 ((png_ptr
->num_trans
!= 0) ||
1284 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
))) &&
1286 (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
))
1287 png_do_gamma(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1288 png_ptr
->gamma_table
, png_ptr
->gamma_16_table
,
1289 png_ptr
->gamma_shift
);
1292 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1293 if (png_ptr
->transformations
& PNG_16_TO_8
)
1294 png_do_chop(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1297 #if defined(PNG_READ_DITHER_SUPPORTED)
1298 if (png_ptr
->transformations
& PNG_DITHER
)
1300 png_do_dither((png_row_infop
)&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1301 png_ptr
->palette_lookup
, png_ptr
->dither_index
);
1302 if(png_ptr
->row_info
.rowbytes
== (png_uint_32
)0)
1303 png_error(png_ptr
, "png_do_dither returned rowbytes=0");
1307 #if defined(PNG_READ_INVERT_SUPPORTED)
1308 if (png_ptr
->transformations
& PNG_INVERT_MONO
)
1309 png_do_invert(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1312 #if defined(PNG_READ_SHIFT_SUPPORTED)
1313 if (png_ptr
->transformations
& PNG_SHIFT
)
1314 png_do_unshift(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1318 #if defined(PNG_READ_PACK_SUPPORTED)
1319 if (png_ptr
->transformations
& PNG_PACK
)
1320 png_do_unpack(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1323 #if defined(PNG_READ_BGR_SUPPORTED)
1324 if (png_ptr
->transformations
& PNG_BGR
)
1325 png_do_bgr(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1328 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1329 if (png_ptr
->transformations
& PNG_PACKSWAP
)
1330 png_do_packswap(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1333 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1334 /* if gray -> RGB, do so now only if we did not do so above */
1335 if ((png_ptr
->transformations
& PNG_GRAY_TO_RGB
) &&
1336 (png_ptr
->mode
& PNG_BACKGROUND_IS_GRAY
))
1337 png_do_gray_to_rgb(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1340 #if defined(PNG_READ_FILLER_SUPPORTED)
1341 if (png_ptr
->transformations
& PNG_FILLER
)
1342 png_do_read_filler(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1343 (png_uint_32
)png_ptr
->filler
, png_ptr
->flags
);
1346 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1347 if (png_ptr
->transformations
& PNG_INVERT_ALPHA
)
1348 png_do_read_invert_alpha(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1351 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1352 if (png_ptr
->transformations
& PNG_SWAP_ALPHA
)
1353 png_do_read_swap_alpha(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1356 #if defined(PNG_READ_SWAP_SUPPORTED)
1357 if (png_ptr
->transformations
& PNG_SWAP_BYTES
)
1358 png_do_swap(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1361 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1362 if (png_ptr
->transformations
& PNG_USER_TRANSFORM
)
1364 if(png_ptr
->read_user_transform_fn
!= NULL
)
1365 (*(png_ptr
->read_user_transform_fn
)) /* user read transform function */
1366 (png_ptr
, /* png_ptr */
1367 &(png_ptr
->row_info
), /* row_info: */
1368 /* png_uint_32 width; width of row */
1369 /* png_uint_32 rowbytes; number of bytes in row */
1370 /* png_byte color_type; color type of pixels */
1371 /* png_byte bit_depth; bit depth of samples */
1372 /* png_byte channels; number of channels (1-4) */
1373 /* png_byte pixel_depth; bits per pixel (depth*channels) */
1374 png_ptr
->row_buf
+ 1); /* start of pixel data for row */
1375 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
1376 if(png_ptr
->user_transform_depth
)
1377 png_ptr
->row_info
.bit_depth
= png_ptr
->user_transform_depth
;
1378 if(png_ptr
->user_transform_channels
)
1379 png_ptr
->row_info
.channels
= png_ptr
->user_transform_channels
;
1381 png_ptr
->row_info
.pixel_depth
= (png_byte
)(png_ptr
->row_info
.bit_depth
*
1382 png_ptr
->row_info
.channels
);
1383 png_ptr
->row_info
.rowbytes
= (png_ptr
->row_info
.width
*
1384 png_ptr
->row_info
.pixel_depth
+7)>>3;
1390 #if defined(PNG_READ_PACK_SUPPORTED)
1391 /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
1392 * without changing the actual values. Thus, if you had a row with
1393 * a bit depth of 1, you would end up with bytes that only contained
1394 * the numbers 0 or 1. If you would rather they contain 0 and 255, use
1395 * png_do_shift() after this.
1398 png_do_unpack(png_row_infop row_info
, png_bytep row
)
1400 png_debug(1, "in png_do_unpack\n");
1401 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1402 if (row
!= NULL
&& row_info
!= NULL
&& row_info
->bit_depth
< 8)
1404 if (row_info
->bit_depth
< 8)
1408 png_uint_32 row_width
=row_info
->width
;
1410 switch (row_info
->bit_depth
)
1414 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
1415 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1416 png_uint_32 shift
= 7 - (int)((row_width
+ 7) & 0x07);
1417 for (i
= 0; i
< row_width
; i
++)
1419 *dp
= (png_byte
)((*sp
>> shift
) & 0x01);
1435 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
1436 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1437 png_uint_32 shift
= (int)((3 - ((row_width
+ 3) & 0x03)) << 1);
1438 for (i
= 0; i
< row_width
; i
++)
1440 *dp
= (png_byte
)((*sp
>> shift
) & 0x03);
1455 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
1456 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1457 png_uint_32 shift
= (int)((1 - ((row_width
+ 1) & 0x01)) << 2);
1458 for (i
= 0; i
< row_width
; i
++)
1460 *dp
= (png_byte
)((*sp
>> shift
) & 0x0f);
1474 row_info
->bit_depth
= 8;
1475 row_info
->pixel_depth
= (png_byte
)(8 * row_info
->channels
);
1476 row_info
->rowbytes
= row_width
* row_info
->channels
;
1481 #if defined(PNG_READ_SHIFT_SUPPORTED)
1482 /* Reverse the effects of png_do_shift. This routine merely shifts the
1483 * pixels back to their significant bits values. Thus, if you have
1484 * a row of bit depth 8, but only 5 are significant, this will shift
1485 * the values back to 0 through 31.
1488 png_do_unshift(png_row_infop row_info
, png_bytep row
, png_color_8p sig_bits
)
1490 png_debug(1, "in png_do_unshift\n");
1492 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1493 row
!= NULL
&& row_info
!= NULL
&& sig_bits
!= NULL
&&
1495 row_info
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
1500 png_uint_16 value
= 0;
1501 png_uint_32 row_width
= row_info
->width
;
1503 if (row_info
->color_type
& PNG_COLOR_MASK_COLOR
)
1505 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->red
;
1506 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->green
;
1507 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->blue
;
1511 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->gray
;
1513 if (row_info
->color_type
& PNG_COLOR_MASK_ALPHA
)
1515 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->alpha
;
1518 for (c
= 0; c
< channels
; c
++)
1529 switch (row_info
->bit_depth
)
1535 png_uint_32 istop
= row_info
->rowbytes
;
1537 for (bp
= row
, i
= 0; i
< istop
; i
++)
1548 png_uint_32 istop
= row_info
->rowbytes
;
1549 png_byte mask
= (png_byte
)((((int)0xf0 >> shift
[0]) & (int)0xf0) |
1550 (png_byte
)((int)0xf >> shift
[0]));
1552 for (i
= 0; i
< istop
; i
++)
1563 png_uint_32 istop
= row_width
* channels
;
1565 for (i
= 0; i
< istop
; i
++)
1567 *bp
++ >>= shift
[i%channels
];
1575 png_uint_32 istop
= channels
* row_width
;
1577 for (i
= 0; i
< istop
; i
++)
1579 value
= (png_uint_16
)((*bp
<< 8) + *(bp
+ 1));
1580 value
>>= shift
[i%channels
];
1581 *bp
++ = (png_byte
)(value
>> 8);
1582 *bp
++ = (png_byte
)(value
& 0xff);
1591 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1592 /* chop rows of bit depth 16 down to 8 */
1594 png_do_chop(png_row_infop row_info
, png_bytep row
)
1596 png_debug(1, "in png_do_chop\n");
1597 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1598 if (row
!= NULL
&& row_info
!= NULL
&& row_info
->bit_depth
== 16)
1600 if (row_info
->bit_depth
== 16)
1606 png_uint_32 istop
= row_info
->width
* row_info
->channels
;
1608 for (i
= 0; i
<istop
; i
++, sp
+= 2, dp
++)
1610 #if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
1611 /* This does a more accurate scaling of the 16-bit color
1612 * value, rather than a simple low-byte truncation.
1614 * What the ideal calculation should be:
1615 * *dp = (((((png_uint_32)(*sp) << 8) |
1616 * (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L;
1618 * GRR: no, I think this is what it really should be:
1619 * *dp = (((((png_uint_32)(*sp) << 8) |
1620 * (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L;
1622 * GRR: here's the exact calculation with shifts:
1623 * temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L;
1624 * *dp = (temp - (temp >> 8)) >> 8;
1626 * Approximate calculation with shift/add instead of multiply/divide:
1627 * *dp = ((((png_uint_32)(*sp) << 8) |
1628 * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
1630 * What we actually do to avoid extra shifting and conversion:
1633 *dp
= *sp
+ ((((int)(*(sp
+ 1)) - *sp
) > 128) ? 1 : 0);
1635 /* Simply discard the low order byte */
1639 row_info
->bit_depth
= 8;
1640 row_info
->pixel_depth
= (png_byte
)(8 * row_info
->channels
);
1641 row_info
->rowbytes
= row_info
->width
* row_info
->channels
;
1646 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1648 png_do_read_swap_alpha(png_row_infop row_info
, png_bytep row
)
1650 png_debug(1, "in png_do_read_swap_alpha\n");
1651 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1652 if (row
!= NULL
&& row_info
!= NULL
)
1655 png_uint_32 row_width
= row_info
->width
;
1656 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
1658 /* This converts from RGBA to ARGB */
1659 if (row_info
->bit_depth
== 8)
1661 png_bytep sp
= row
+ row_info
->rowbytes
;
1666 for (i
= 0; i
< row_width
; i
++)
1675 /* This converts from RRGGBBAA to AARRGGBB */
1678 png_bytep sp
= row
+ row_info
->rowbytes
;
1683 for (i
= 0; i
< row_width
; i
++)
1698 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
1700 /* This converts from GA to AG */
1701 if (row_info
->bit_depth
== 8)
1703 png_bytep sp
= row
+ row_info
->rowbytes
;
1708 for (i
= 0; i
< row_width
; i
++)
1715 /* This converts from GGAA to AAGG */
1718 png_bytep sp
= row
+ row_info
->rowbytes
;
1723 for (i
= 0; i
< row_width
; i
++)
1738 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1740 png_do_read_invert_alpha(png_row_infop row_info
, png_bytep row
)
1742 png_debug(1, "in png_do_read_invert_alpha\n");
1743 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1744 if (row
!= NULL
&& row_info
!= NULL
)
1747 png_uint_32 row_width
= row_info
->width
;
1748 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
1750 /* This inverts the alpha channel in RGBA */
1751 if (row_info
->bit_depth
== 8)
1753 png_bytep sp
= row
+ row_info
->rowbytes
;
1757 for (i
= 0; i
< row_width
; i
++)
1759 *(--dp
) = (png_byte
)(255 - *(--sp
));
1761 /* This does nothing:
1765 We can replace it with:
1771 /* This inverts the alpha channel in RRGGBBAA */
1774 png_bytep sp
= row
+ row_info
->rowbytes
;
1778 for (i
= 0; i
< row_width
; i
++)
1780 *(--dp
) = (png_byte
)(255 - *(--sp
));
1781 *(--dp
) = (png_byte
)(255 - *(--sp
));
1783 /* This does nothing:
1790 We can replace it with:
1797 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
1799 /* This inverts the alpha channel in GA */
1800 if (row_info
->bit_depth
== 8)
1802 png_bytep sp
= row
+ row_info
->rowbytes
;
1806 for (i
= 0; i
< row_width
; i
++)
1808 *(--dp
) = (png_byte
)(255 - *(--sp
));
1812 /* This inverts the alpha channel in GGAA */
1815 png_bytep sp
= row
+ row_info
->rowbytes
;
1819 for (i
= 0; i
< row_width
; i
++)
1821 *(--dp
) = (png_byte
)(255 - *(--sp
));
1822 *(--dp
) = (png_byte
)(255 - *(--sp
));
1836 #if defined(PNG_READ_FILLER_SUPPORTED)
1837 /* Add filler channel if we have RGB color */
1839 png_do_read_filler(png_row_infop row_info
, png_bytep row
,
1840 png_uint_32 filler
, png_uint_32 flags
)
1843 png_uint_32 row_width
= row_info
->width
;
1845 png_byte hi_filler
= (png_byte
)((filler
>>8) & 0xff);
1846 png_byte lo_filler
= (png_byte
)(filler
& 0xff);
1848 png_debug(1, "in png_do_read_filler\n");
1850 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1851 row
!= NULL
&& row_info
!= NULL
&&
1853 row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
1855 if(row_info
->bit_depth
== 8)
1857 /* This changes the data from G to GX */
1858 if (flags
& PNG_FLAG_FILLER_AFTER
)
1860 png_bytep sp
= row
+ (png_size_t
)row_width
;
1861 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1862 for (i
= 1; i
< row_width
; i
++)
1864 *(--dp
) = lo_filler
;
1867 *(--dp
) = lo_filler
;
1868 row_info
->channels
= 2;
1869 row_info
->pixel_depth
= 16;
1870 row_info
->rowbytes
= row_width
* 2;
1872 /* This changes the data from G to XG */
1875 png_bytep sp
= row
+ (png_size_t
)row_width
;
1876 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1877 for (i
= 0; i
< row_width
; i
++)
1880 *(--dp
) = lo_filler
;
1882 row_info
->channels
= 2;
1883 row_info
->pixel_depth
= 16;
1884 row_info
->rowbytes
= row_width
* 2;
1887 else if(row_info
->bit_depth
== 16)
1889 /* This changes the data from GG to GGXX */
1890 if (flags
& PNG_FLAG_FILLER_AFTER
)
1892 png_bytep sp
= row
+ (png_size_t
)row_width
;
1893 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1894 for (i
= 1; i
< row_width
; i
++)
1896 *(--dp
) = hi_filler
;
1897 *(--dp
) = lo_filler
;
1901 *(--dp
) = hi_filler
;
1902 *(--dp
) = lo_filler
;
1903 row_info
->channels
= 2;
1904 row_info
->pixel_depth
= 32;
1905 row_info
->rowbytes
= row_width
* 4;
1907 /* This changes the data from GG to XXGG */
1910 png_bytep sp
= row
+ (png_size_t
)row_width
;
1911 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1912 for (i
= 0; i
< row_width
; i
++)
1916 *(--dp
) = hi_filler
;
1917 *(--dp
) = lo_filler
;
1919 row_info
->channels
= 2;
1920 row_info
->pixel_depth
= 32;
1921 row_info
->rowbytes
= row_width
* 4;
1924 } /* COLOR_TYPE == GRAY */
1925 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
1927 if(row_info
->bit_depth
== 8)
1929 /* This changes the data from RGB to RGBX */
1930 if (flags
& PNG_FLAG_FILLER_AFTER
)
1932 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
1933 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1934 for (i
= 1; i
< row_width
; i
++)
1936 *(--dp
) = lo_filler
;
1941 *(--dp
) = lo_filler
;
1942 row_info
->channels
= 4;
1943 row_info
->pixel_depth
= 32;
1944 row_info
->rowbytes
= row_width
* 4;
1946 /* This changes the data from RGB to XRGB */
1949 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
1950 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1951 for (i
= 0; i
< row_width
; i
++)
1956 *(--dp
) = lo_filler
;
1958 row_info
->channels
= 4;
1959 row_info
->pixel_depth
= 32;
1960 row_info
->rowbytes
= row_width
* 4;
1963 else if(row_info
->bit_depth
== 16)
1965 /* This changes the data from RRGGBB to RRGGBBXX */
1966 if (flags
& PNG_FLAG_FILLER_AFTER
)
1968 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
1969 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1970 for (i
= 1; i
< row_width
; i
++)
1972 *(--dp
) = hi_filler
;
1973 *(--dp
) = lo_filler
;
1981 *(--dp
) = hi_filler
;
1982 *(--dp
) = lo_filler
;
1983 row_info
->channels
= 4;
1984 row_info
->pixel_depth
= 64;
1985 row_info
->rowbytes
= row_width
* 8;
1987 /* This changes the data from RRGGBB to XXRRGGBB */
1990 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
1991 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1992 for (i
= 0; i
< row_width
; i
++)
2000 *(--dp
) = hi_filler
;
2001 *(--dp
) = lo_filler
;
2003 row_info
->channels
= 4;
2004 row_info
->pixel_depth
= 64;
2005 row_info
->rowbytes
= row_width
* 8;
2008 } /* COLOR_TYPE == RGB */
2012 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
2013 /* expand grayscale files to RGB, with or without alpha */
2015 png_do_gray_to_rgb(png_row_infop row_info
, png_bytep row
)
2018 png_uint_32 row_width
= row_info
->width
;
2020 png_debug(1, "in png_do_gray_to_rgb\n");
2021 if (row_info
->bit_depth
>= 8 &&
2022 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2023 row
!= NULL
&& row_info
!= NULL
&&
2025 !(row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
2027 if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
2029 if (row_info
->bit_depth
== 8)
2031 png_bytep sp
= row
+ (png_size_t
)row_width
- 1;
2032 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2033 for (i
= 0; i
< row_width
; i
++)
2042 png_bytep sp
= row
+ (png_size_t
)row_width
* 2 - 1;
2043 png_bytep dp
= sp
+ (png_size_t
)row_width
* 4;
2044 for (i
= 0; i
< row_width
; i
++)
2047 *(dp
--) = *(sp
- 1);
2049 *(dp
--) = *(sp
- 1);
2055 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
2057 if (row_info
->bit_depth
== 8)
2059 png_bytep sp
= row
+ (png_size_t
)row_width
* 2 - 1;
2060 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2061 for (i
= 0; i
< row_width
; i
++)
2071 png_bytep sp
= row
+ (png_size_t
)row_width
* 4 - 1;
2072 png_bytep dp
= sp
+ (png_size_t
)row_width
* 4;
2073 for (i
= 0; i
< row_width
; i
++)
2078 *(dp
--) = *(sp
- 1);
2080 *(dp
--) = *(sp
- 1);
2086 row_info
->channels
+= (png_byte
)2;
2087 row_info
->color_type
|= PNG_COLOR_MASK_COLOR
;
2088 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
2089 row_info
->bit_depth
);
2090 row_info
->rowbytes
= ((row_width
*
2091 row_info
->pixel_depth
+ 7) >> 3);
2096 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
2097 /* reduce RGB files to grayscale, with or without alpha
2098 * using the equation given in Poynton's ColorFAQ at
2099 * <http://www.inforamp.net/~poynton/>
2100 * Copyright (c) 1998-01-04 Charles Poynton poynton@inforamp.net
2102 * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
2104 * We approximate this with
2106 * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B
2108 * which can be expressed with integers as
2110 * Y = (6969 * R + 23434 * G + 2365 * B)/32768
2112 * The calculation is to be done in a linear colorspace.
2114 * Other integer coefficents can be used via png_set_rgb_to_gray().
2117 png_do_rgb_to_gray(png_structp png_ptr
, png_row_infop row_info
, png_bytep row
)
2122 png_uint_32 row_width
= row_info
->width
;
2125 png_debug(1, "in png_do_rgb_to_gray\n");
2127 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2128 row
!= NULL
&& row_info
!= NULL
&&
2130 (row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
2132 png_uint_32 rc
= png_ptr
->rgb_to_gray_red_coeff
;
2133 png_uint_32 gc
= png_ptr
->rgb_to_gray_green_coeff
;
2134 png_uint_32 bc
= png_ptr
->rgb_to_gray_blue_coeff
;
2136 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
2138 if (row_info
->bit_depth
== 8)
2140 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2141 if (png_ptr
->gamma_from_1
!= NULL
&& png_ptr
->gamma_to_1
!= NULL
)
2146 for (i
= 0; i
< row_width
; i
++)
2148 png_byte red
= png_ptr
->gamma_to_1
[*(sp
++)];
2149 png_byte green
= png_ptr
->gamma_to_1
[*(sp
++)];
2150 png_byte blue
= png_ptr
->gamma_to_1
[*(sp
++)];
2151 if(red
!= green
|| red
!= blue
)
2154 *(dp
++) = png_ptr
->gamma_from_1
[
2155 (rc
*red
+gc
*green
+bc
*blue
)>>15];
2166 for (i
= 0; i
< row_width
; i
++)
2168 png_byte red
= *(sp
++);
2169 png_byte green
= *(sp
++);
2170 png_byte blue
= *(sp
++);
2171 if(red
!= green
|| red
!= blue
)
2174 *(dp
++) = (png_byte
)((rc
*red
+gc
*green
+bc
*blue
)>>15);
2182 else /* RGB bit_depth == 16 */
2184 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2185 if (png_ptr
->gamma_16_to_1
!= NULL
&&
2186 png_ptr
->gamma_16_from_1
!= NULL
)
2190 for (i
= 0; i
< row_width
; i
++)
2192 png_uint_16 red
, green
, blue
, w
;
2194 red
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2195 green
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2196 blue
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2198 if(red
== green
&& red
== blue
)
2202 png_uint_16 red_1
= png_ptr
->gamma_16_to_1
[(red
&0xff) >>
2203 png_ptr
->gamma_shift
][red
>>8];
2204 png_uint_16 green_1
= png_ptr
->gamma_16_to_1
[(green
&0xff) >>
2205 png_ptr
->gamma_shift
][green
>>8];
2206 png_uint_16 blue_1
= png_ptr
->gamma_16_to_1
[(blue
&0xff) >>
2207 png_ptr
->gamma_shift
][blue
>>8];
2208 png_uint_16 gray16
= (png_uint_16
)((rc
*red_1
+ gc
*green_1
2210 w
= png_ptr
->gamma_16_from_1
[(gray16
&0xff) >>
2211 png_ptr
->gamma_shift
][gray16
>> 8];
2215 *(dp
++) = (png_byte
)((w
>>8) & 0xff);
2216 *(dp
++) = (png_byte
)(w
& 0xff);
2224 for (i
= 0; i
< row_width
; i
++)
2226 png_uint_16 red
, green
, blue
, gray16
;
2228 red
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2229 green
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2230 blue
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2232 if(red
!= green
|| red
!= blue
)
2234 gray16
= (png_uint_16
)((rc
*red
+ gc
*green
+ bc
*blue
)>>15);
2235 *(dp
++) = (png_byte
)((gray16
>>8) & 0xff);
2236 *(dp
++) = (png_byte
)(gray16
& 0xff);
2241 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
2243 if (row_info
->bit_depth
== 8)
2245 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2246 if (png_ptr
->gamma_from_1
!= NULL
&& png_ptr
->gamma_to_1
!= NULL
)
2250 for (i
= 0; i
< row_width
; i
++)
2252 png_byte red
= png_ptr
->gamma_to_1
[*(sp
++)];
2253 png_byte green
= png_ptr
->gamma_to_1
[*(sp
++)];
2254 png_byte blue
= png_ptr
->gamma_to_1
[*(sp
++)];
2255 if(red
!= green
|| red
!= blue
)
2257 *(dp
++) = png_ptr
->gamma_from_1
2258 [(rc
*red
+ gc
*green
+ bc
*blue
)>>15];
2259 *(dp
++) = *(sp
++); /* alpha */
2267 for (i
= 0; i
< row_width
; i
++)
2269 png_byte red
= *(sp
++);
2270 png_byte green
= *(sp
++);
2271 png_byte blue
= *(sp
++);
2272 if(red
!= green
|| red
!= blue
)
2274 *(dp
++) = (png_byte
)((gc
*red
+ gc
*green
+ bc
*blue
)>>8);
2275 *(dp
++) = *(sp
++); /* alpha */
2279 else /* RGBA bit_depth == 16 */
2281 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2282 if (png_ptr
->gamma_16_to_1
!= NULL
&&
2283 png_ptr
->gamma_16_from_1
!= NULL
)
2287 for (i
= 0; i
< row_width
; i
++)
2289 png_uint_16 red
, green
, blue
, w
;
2291 red
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2292 green
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2293 blue
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2295 if(red
== green
&& red
== blue
)
2299 png_uint_16 red_1
= png_ptr
->gamma_16_to_1
[(red
&0xff) >>
2300 png_ptr
->gamma_shift
][red
>>8];
2301 png_uint_16 green_1
= png_ptr
->gamma_16_to_1
[(green
&0xff) >>
2302 png_ptr
->gamma_shift
][green
>>8];
2303 png_uint_16 blue_1
= png_ptr
->gamma_16_to_1
[(blue
&0xff) >>
2304 png_ptr
->gamma_shift
][blue
>>8];
2305 png_uint_16 gray16
= (png_uint_16
)((rc
* red_1
2306 + gc
* green_1
+ bc
* blue_1
)>>15);
2307 w
= png_ptr
->gamma_16_from_1
[(gray16
&0xff) >>
2308 png_ptr
->gamma_shift
][gray16
>> 8];
2312 *(dp
++) = (png_byte
)((w
>>8) & 0xff);
2313 *(dp
++) = (png_byte
)(w
& 0xff);
2314 *(dp
++) = *(sp
++); /* alpha */
2323 for (i
= 0; i
< row_width
; i
++)
2325 png_uint_16 red
, green
, blue
, gray16
;
2326 red
= (png_uint_16
)((*(sp
)<<8) | *(sp
+1)); sp
+=2;
2327 green
= (png_uint_16
)((*(sp
)<<8) | *(sp
+1)); sp
+=2;
2328 blue
= (png_uint_16
)((*(sp
)<<8) | *(sp
+1)); sp
+=2;
2329 if(red
!= green
|| red
!= blue
)
2331 gray16
= (png_uint_16
)((rc
*red
+ gc
*green
+ bc
*blue
)>>15);
2332 *(dp
++) = (png_byte
)((gray16
>>8) & 0xff);
2333 *(dp
++) = (png_byte
)(gray16
& 0xff);
2334 *(dp
++) = *(sp
++); /* alpha */
2340 row_info
->channels
-= (png_byte
)2;
2341 row_info
->color_type
&= ~PNG_COLOR_MASK_COLOR
;
2342 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
2343 row_info
->bit_depth
);
2344 row_info
->rowbytes
= ((row_width
*
2345 row_info
->pixel_depth
+ 7) >> 3);
2351 /* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
2352 * large of png_color. This lets grayscale images be treated as
2353 * paletted. Most useful for gamma correction and simplification
2357 png_build_grayscale_palette(int bit_depth
, png_colorp palette
)
2364 png_debug(1, "in png_do_build_grayscale_palette\n");
2365 if (palette
== NULL
)
2392 for (i
= 0, v
= 0; i
< num_palette
; i
++, v
+= color_inc
)
2394 palette
[i
].red
= (png_byte
)v
;
2395 palette
[i
].green
= (png_byte
)v
;
2396 palette
[i
].blue
= (png_byte
)v
;
2400 /* This function is currently unused. Do we really need it? */
2401 #if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
2403 png_correct_palette(png_structp png_ptr
, png_colorp palette
,
2406 png_debug(1, "in png_correct_palette\n");
2407 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
2408 defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
2409 if (png_ptr
->transformations
& (PNG_GAMMA
| PNG_BACKGROUND
))
2411 png_color back
, back_1
;
2413 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_FILE
)
2415 back
.red
= png_ptr
->gamma_table
[png_ptr
->background
.red
];
2416 back
.green
= png_ptr
->gamma_table
[png_ptr
->background
.green
];
2417 back
.blue
= png_ptr
->gamma_table
[png_ptr
->background
.blue
];
2419 back_1
.red
= png_ptr
->gamma_to_1
[png_ptr
->background
.red
];
2420 back_1
.green
= png_ptr
->gamma_to_1
[png_ptr
->background
.green
];
2421 back_1
.blue
= png_ptr
->gamma_to_1
[png_ptr
->background
.blue
];
2427 g
= 1.0 / (png_ptr
->background_gamma
* png_ptr
->screen_gamma
);
2429 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_SCREEN
||
2430 fabs(g
- 1.0) < PNG_GAMMA_THRESHOLD
)
2432 back
.red
= png_ptr
->background
.red
;
2433 back
.green
= png_ptr
->background
.green
;
2434 back
.blue
= png_ptr
->background
.blue
;
2439 (png_byte
)(pow((double)png_ptr
->background
.red
/255, g
) *
2442 (png_byte
)(pow((double)png_ptr
->background
.green
/255, g
) *
2445 (png_byte
)(pow((double)png_ptr
->background
.blue
/255, g
) *
2449 g
= 1.0 / png_ptr
->background_gamma
;
2452 (png_byte
)(pow((double)png_ptr
->background
.red
/255, g
) *
2455 (png_byte
)(pow((double)png_ptr
->background
.green
/255, g
) *
2458 (png_byte
)(pow((double)png_ptr
->background
.blue
/255, g
) *
2462 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
2466 for (i
= 0; i
< (png_uint_32
)num_palette
; i
++)
2468 if (i
< png_ptr
->num_trans
&& png_ptr
->trans
[i
] == 0)
2472 else if (i
< png_ptr
->num_trans
&& png_ptr
->trans
[i
] != 0xff)
2476 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].red
];
2477 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.red
);
2478 palette
[i
].red
= png_ptr
->gamma_from_1
[w
];
2480 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].green
];
2481 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.green
);
2482 palette
[i
].green
= png_ptr
->gamma_from_1
[w
];
2484 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].blue
];
2485 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.blue
);
2486 palette
[i
].blue
= png_ptr
->gamma_from_1
[w
];
2490 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2491 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2492 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2500 for (i
= 0; i
< num_palette
; i
++)
2502 if (palette
[i
].red
== (png_byte
)png_ptr
->trans_values
.gray
)
2508 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2509 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2510 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2517 #if defined(PNG_READ_GAMMA_SUPPORTED)
2518 if (png_ptr
->transformations
& PNG_GAMMA
)
2522 for (i
= 0; i
< num_palette
; i
++)
2524 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2525 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2526 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2529 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2533 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2534 if (png_ptr
->transformations
& PNG_BACKGROUND
)
2536 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
2540 back
.red
= (png_byte
)png_ptr
->background
.red
;
2541 back
.green
= (png_byte
)png_ptr
->background
.green
;
2542 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
2544 for (i
= 0; i
< (int)png_ptr
->num_trans
; i
++)
2546 if (png_ptr
->trans
[i
] == 0)
2548 palette
[i
].red
= back
.red
;
2549 palette
[i
].green
= back
.green
;
2550 palette
[i
].blue
= back
.blue
;
2552 else if (png_ptr
->trans
[i
] != 0xff)
2554 png_composite(palette
[i
].red
, png_ptr
->palette
[i
].red
,
2555 png_ptr
->trans
[i
], back
.red
);
2556 png_composite(palette
[i
].green
, png_ptr
->palette
[i
].green
,
2557 png_ptr
->trans
[i
], back
.green
);
2558 png_composite(palette
[i
].blue
, png_ptr
->palette
[i
].blue
,
2559 png_ptr
->trans
[i
], back
.blue
);
2563 else /* assume grayscale palette (what else could it be?) */
2567 for (i
= 0; i
< num_palette
; i
++)
2569 if (i
== (png_byte
)png_ptr
->trans_values
.gray
)
2571 palette
[i
].red
= (png_byte
)png_ptr
->background
.red
;
2572 palette
[i
].green
= (png_byte
)png_ptr
->background
.green
;
2573 palette
[i
].blue
= (png_byte
)png_ptr
->background
.blue
;
2582 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2583 /* Replace any alpha or transparency with the supplied background color.
2584 * "background" is already in the screen gamma, while "background_1" is
2585 * at a gamma of 1.0. Paletted files have already been taken care of.
2588 png_do_background(png_row_infop row_info
, png_bytep row
,
2589 png_color_16p trans_values
, png_color_16p background
2590 #if defined(PNG_READ_GAMMA_SUPPORTED)
2591 , png_color_16p background_1
,
2592 png_bytep gamma_table
, png_bytep gamma_from_1
, png_bytep gamma_to_1
,
2593 png_uint_16pp gamma_16
, png_uint_16pp gamma_16_from_1
,
2594 png_uint_16pp gamma_16_to_1
, int gamma_shift
2600 png_uint_32 row_width
=row_info
->width
;
2603 png_debug(1, "in png_do_background\n");
2604 if (background
!= NULL
&&
2605 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2606 row
!= NULL
&& row_info
!= NULL
&&
2608 (!(row_info
->color_type
& PNG_COLOR_MASK_ALPHA
) ||
2609 (row_info
->color_type
!= PNG_COLOR_TYPE_PALETTE
&& trans_values
)))
2611 switch (row_info
->color_type
)
2613 case PNG_COLOR_TYPE_GRAY
:
2615 switch (row_info
->bit_depth
)
2621 for (i
= 0; i
< row_width
; i
++)
2623 if ((png_uint_16
)((*sp
>> shift
) & 0x01)
2624 == trans_values
->gray
)
2626 *sp
&= (png_byte
)((0x7f7f >> (7 - shift
)) & 0xff);
2627 *sp
|= (png_byte
)(background
->gray
<< shift
);
2641 #if defined(PNG_READ_GAMMA_SUPPORTED)
2642 if (gamma_table
!= NULL
)
2646 for (i
= 0; i
< row_width
; i
++)
2648 if ((png_uint_16
)((*sp
>> shift
) & 0x03)
2649 == trans_values
->gray
)
2651 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2652 *sp
|= (png_byte
)(background
->gray
<< shift
);
2656 png_byte p
= (png_byte
)((*sp
>> shift
) & 0x03);
2657 png_byte g
= (png_byte
)((gamma_table
[p
| (p
<< 2) |
2658 (p
<< 4) | (p
<< 6)] >> 6) & 0x03);
2659 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2660 *sp
|= (png_byte
)(g
<< shift
);
2676 for (i
= 0; i
< row_width
; i
++)
2678 if ((png_uint_16
)((*sp
>> shift
) & 0x03)
2679 == trans_values
->gray
)
2681 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2682 *sp
|= (png_byte
)(background
->gray
<< shift
);
2697 #if defined(PNG_READ_GAMMA_SUPPORTED)
2698 if (gamma_table
!= NULL
)
2702 for (i
= 0; i
< row_width
; i
++)
2704 if ((png_uint_16
)((*sp
>> shift
) & 0x0f)
2705 == trans_values
->gray
)
2707 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2708 *sp
|= (png_byte
)(background
->gray
<< shift
);
2712 png_byte p
= (png_byte
)((*sp
>> shift
) & 0x0f);
2713 png_byte g
= (png_byte
)((gamma_table
[p
|
2714 (p
<< 4)] >> 4) & 0x0f);
2715 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2716 *sp
|= (png_byte
)(g
<< shift
);
2732 for (i
= 0; i
< row_width
; i
++)
2734 if ((png_uint_16
)((*sp
>> shift
) & 0x0f)
2735 == trans_values
->gray
)
2737 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2738 *sp
|= (png_byte
)(background
->gray
<< shift
);
2753 #if defined(PNG_READ_GAMMA_SUPPORTED)
2754 if (gamma_table
!= NULL
)
2757 for (i
= 0; i
< row_width
; i
++, sp
++)
2759 if (*sp
== trans_values
->gray
)
2761 *sp
= (png_byte
)background
->gray
;
2765 *sp
= gamma_table
[*sp
];
2773 for (i
= 0; i
< row_width
; i
++, sp
++)
2775 if (*sp
== trans_values
->gray
)
2777 *sp
= (png_byte
)background
->gray
;
2785 #if defined(PNG_READ_GAMMA_SUPPORTED)
2786 if (gamma_16
!= NULL
)
2789 for (i
= 0; i
< row_width
; i
++, sp
+= 2)
2793 v
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
2794 if (v
== trans_values
->gray
)
2796 /* background is already in screen gamma */
2797 *sp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2798 *(sp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2802 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2803 *sp
= (png_byte
)((v
>> 8) & 0xff);
2804 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2812 for (i
= 0; i
< row_width
; i
++, sp
+= 2)
2816 v
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
2817 if (v
== trans_values
->gray
)
2819 *sp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2820 *(sp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2829 case PNG_COLOR_TYPE_RGB
:
2831 if (row_info
->bit_depth
== 8)
2833 #if defined(PNG_READ_GAMMA_SUPPORTED)
2834 if (gamma_table
!= NULL
)
2837 for (i
= 0; i
< row_width
; i
++, sp
+= 3)
2839 if (*sp
== trans_values
->red
&&
2840 *(sp
+ 1) == trans_values
->green
&&
2841 *(sp
+ 2) == trans_values
->blue
)
2843 *sp
= (png_byte
)background
->red
;
2844 *(sp
+ 1) = (png_byte
)background
->green
;
2845 *(sp
+ 2) = (png_byte
)background
->blue
;
2849 *sp
= gamma_table
[*sp
];
2850 *(sp
+ 1) = gamma_table
[*(sp
+ 1)];
2851 *(sp
+ 2) = gamma_table
[*(sp
+ 2)];
2859 for (i
= 0; i
< row_width
; i
++, sp
+= 3)
2861 if (*sp
== trans_values
->red
&&
2862 *(sp
+ 1) == trans_values
->green
&&
2863 *(sp
+ 2) == trans_values
->blue
)
2865 *sp
= (png_byte
)background
->red
;
2866 *(sp
+ 1) = (png_byte
)background
->green
;
2867 *(sp
+ 2) = (png_byte
)background
->blue
;
2872 else /* if (row_info->bit_depth == 16) */
2874 #if defined(PNG_READ_GAMMA_SUPPORTED)
2875 if (gamma_16
!= NULL
)
2878 for (i
= 0; i
< row_width
; i
++, sp
+= 6)
2880 png_uint_16 r
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
2881 png_uint_16 g
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
2882 png_uint_16 b
= (png_uint_16
)(((*(sp
+4)) << 8) + *(sp
+5));
2883 if (r
== trans_values
->red
&& g
== trans_values
->green
&&
2884 b
== trans_values
->blue
)
2886 /* background is already in screen gamma */
2887 *sp
= (png_byte
)((background
->red
>> 8) & 0xff);
2888 *(sp
+ 1) = (png_byte
)(background
->red
& 0xff);
2889 *(sp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
2890 *(sp
+ 3) = (png_byte
)(background
->green
& 0xff);
2891 *(sp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
2892 *(sp
+ 5) = (png_byte
)(background
->blue
& 0xff);
2896 png_uint_16 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2897 *sp
= (png_byte
)((v
>> 8) & 0xff);
2898 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2899 v
= gamma_16
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
2900 *(sp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
2901 *(sp
+ 3) = (png_byte
)(v
& 0xff);
2902 v
= gamma_16
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
2903 *(sp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
2904 *(sp
+ 5) = (png_byte
)(v
& 0xff);
2912 for (i
= 0; i
< row_width
; i
++, sp
+= 6)
2914 png_uint_16 r
= (png_uint_16
)(((*sp
) << 8) + *(sp
+1));
2915 png_uint_16 g
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
2916 png_uint_16 b
= (png_uint_16
)(((*(sp
+4)) << 8) + *(sp
+5));
2918 if (r
== trans_values
->red
&& g
== trans_values
->green
&&
2919 b
== trans_values
->blue
)
2921 *sp
= (png_byte
)((background
->red
>> 8) & 0xff);
2922 *(sp
+ 1) = (png_byte
)(background
->red
& 0xff);
2923 *(sp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
2924 *(sp
+ 3) = (png_byte
)(background
->green
& 0xff);
2925 *(sp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
2926 *(sp
+ 5) = (png_byte
)(background
->blue
& 0xff);
2933 case PNG_COLOR_TYPE_GRAY_ALPHA
:
2935 if (row_info
->bit_depth
== 8)
2937 #if defined(PNG_READ_GAMMA_SUPPORTED)
2938 if (gamma_to_1
!= NULL
&& gamma_from_1
!= NULL
&&
2939 gamma_table
!= NULL
)
2943 for (i
= 0; i
< row_width
; i
++, sp
+= 2, dp
++)
2945 png_uint_16 a
= *(sp
+ 1);
2949 *dp
= gamma_table
[*sp
];
2953 /* background is already in screen gamma */
2954 *dp
= (png_byte
)background
->gray
;
2960 v
= gamma_to_1
[*sp
];
2961 png_composite(w
, v
, a
, background_1
->gray
);
2962 *dp
= gamma_from_1
[w
];
2971 for (i
= 0; i
< row_width
; i
++, sp
+= 2, dp
++)
2973 png_byte a
= *(sp
+ 1);
2979 #if defined(PNG_READ_GAMMA_SUPPORTED)
2982 *dp
= (png_byte
)background
->gray
;
2986 png_composite(*dp
, *sp
, a
, background_1
->gray
);
2989 *dp
= (png_byte
)background
->gray
;
2994 else /* if (png_ptr->bit_depth == 16) */
2996 #if defined(PNG_READ_GAMMA_SUPPORTED)
2997 if (gamma_16
!= NULL
&& gamma_16_from_1
!= NULL
&&
2998 gamma_16_to_1
!= NULL
)
3002 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 2)
3004 png_uint_16 a
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
3006 if (a
== (png_uint_16
)0xffff)
3010 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
3011 *dp
= (png_byte
)((v
>> 8) & 0xff);
3012 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3014 #if defined(PNG_READ_GAMMA_SUPPORTED)
3020 /* background is already in screen gamma */
3021 *dp
= (png_byte
)((background
->gray
>> 8) & 0xff);
3022 *(dp
+ 1) = (png_byte
)(background
->gray
& 0xff);
3024 #if defined(PNG_READ_GAMMA_SUPPORTED)
3027 png_uint_16 g
, v
, w
;
3029 g
= gamma_16_to_1
[*(sp
+ 1) >> gamma_shift
][*sp
];
3030 png_composite_16(v
, g
, a
, background_1
->gray
);
3031 w
= gamma_16_from_1
[(v
&0xff) >> gamma_shift
][v
>> 8];
3032 *dp
= (png_byte
)((w
>> 8) & 0xff);
3033 *(dp
+ 1) = (png_byte
)(w
& 0xff);
3043 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 2)
3045 png_uint_16 a
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
3046 if (a
== (png_uint_16
)0xffff)
3048 png_memcpy(dp
, sp
, 2);
3050 #if defined(PNG_READ_GAMMA_SUPPORTED)
3056 *dp
= (png_byte
)((background
->gray
>> 8) & 0xff);
3057 *(dp
+ 1) = (png_byte
)(background
->gray
& 0xff);
3059 #if defined(PNG_READ_GAMMA_SUPPORTED)
3064 g
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
3065 png_composite_16(v
, g
, a
, background_1
->gray
);
3066 *dp
= (png_byte
)((v
>> 8) & 0xff);
3067 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3075 case PNG_COLOR_TYPE_RGB_ALPHA
:
3077 if (row_info
->bit_depth
== 8)
3079 #if defined(PNG_READ_GAMMA_SUPPORTED)
3080 if (gamma_to_1
!= NULL
&& gamma_from_1
!= NULL
&&
3081 gamma_table
!= NULL
)
3085 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 3)
3087 png_byte a
= *(sp
+ 3);
3091 *dp
= gamma_table
[*sp
];
3092 *(dp
+ 1) = gamma_table
[*(sp
+ 1)];
3093 *(dp
+ 2) = gamma_table
[*(sp
+ 2)];
3097 /* background is already in screen gamma */
3098 *dp
= (png_byte
)background
->red
;
3099 *(dp
+ 1) = (png_byte
)background
->green
;
3100 *(dp
+ 2) = (png_byte
)background
->blue
;
3106 v
= gamma_to_1
[*sp
];
3107 png_composite(w
, v
, a
, background_1
->red
);
3108 *dp
= gamma_from_1
[w
];
3109 v
= gamma_to_1
[*(sp
+ 1)];
3110 png_composite(w
, v
, a
, background_1
->green
);
3111 *(dp
+ 1) = gamma_from_1
[w
];
3112 v
= gamma_to_1
[*(sp
+ 2)];
3113 png_composite(w
, v
, a
, background_1
->blue
);
3114 *(dp
+ 2) = gamma_from_1
[w
];
3123 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 3)
3125 png_byte a
= *(sp
+ 3);
3130 *(dp
+ 1) = *(sp
+ 1);
3131 *(dp
+ 2) = *(sp
+ 2);
3135 *dp
= (png_byte
)background
->red
;
3136 *(dp
+ 1) = (png_byte
)background
->green
;
3137 *(dp
+ 2) = (png_byte
)background
->blue
;
3141 png_composite(*dp
, *sp
, a
, background
->red
);
3142 png_composite(*(dp
+ 1), *(sp
+ 1), a
,
3144 png_composite(*(dp
+ 2), *(sp
+ 2), a
,
3150 else /* if (row_info->bit_depth == 16) */
3152 #if defined(PNG_READ_GAMMA_SUPPORTED)
3153 if (gamma_16
!= NULL
&& gamma_16_from_1
!= NULL
&&
3154 gamma_16_to_1
!= NULL
)
3158 for (i
= 0; i
< row_width
; i
++, sp
+= 8, dp
+= 6)
3160 png_uint_16 a
= (png_uint_16
)(((png_uint_16
)(*(sp
+ 6))
3161 << 8) + (png_uint_16
)(*(sp
+ 7)));
3162 if (a
== (png_uint_16
)0xffff)
3166 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
3167 *dp
= (png_byte
)((v
>> 8) & 0xff);
3168 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3169 v
= gamma_16
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
3170 *(dp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
3171 *(dp
+ 3) = (png_byte
)(v
& 0xff);
3172 v
= gamma_16
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
3173 *(dp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
3174 *(dp
+ 5) = (png_byte
)(v
& 0xff);
3178 /* background is already in screen gamma */
3179 *dp
= (png_byte
)((background
->red
>> 8) & 0xff);
3180 *(dp
+ 1) = (png_byte
)(background
->red
& 0xff);
3181 *(dp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
3182 *(dp
+ 3) = (png_byte
)(background
->green
& 0xff);
3183 *(dp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
3184 *(dp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3188 png_uint_16 v
, w
, x
;
3190 v
= gamma_16_to_1
[*(sp
+ 1) >> gamma_shift
][*sp
];
3191 png_composite_16(w
, v
, a
, background_1
->red
);
3192 x
= gamma_16_from_1
[((w
&0xff) >> gamma_shift
)][w
>> 8];
3193 *dp
= (png_byte
)((x
>> 8) & 0xff);
3194 *(dp
+ 1) = (png_byte
)(x
& 0xff);
3195 v
= gamma_16_to_1
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
3196 png_composite_16(w
, v
, a
, background_1
->green
);
3197 x
= gamma_16_from_1
[((w
&0xff) >> gamma_shift
)][w
>> 8];
3198 *(dp
+ 2) = (png_byte
)((x
>> 8) & 0xff);
3199 *(dp
+ 3) = (png_byte
)(x
& 0xff);
3200 v
= gamma_16_to_1
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
3201 png_composite_16(w
, v
, a
, background_1
->blue
);
3202 x
= gamma_16_from_1
[(w
& 0xff) >> gamma_shift
][w
>> 8];
3203 *(dp
+ 4) = (png_byte
)((x
>> 8) & 0xff);
3204 *(dp
+ 5) = (png_byte
)(x
& 0xff);
3213 for (i
= 0; i
< row_width
; i
++, sp
+= 8, dp
+= 6)
3215 png_uint_16 a
= (png_uint_16
)(((png_uint_16
)(*(sp
+ 6))
3216 << 8) + (png_uint_16
)(*(sp
+ 7)));
3217 if (a
== (png_uint_16
)0xffff)
3219 png_memcpy(dp
, sp
, 6);
3223 *dp
= (png_byte
)((background
->red
>> 8) & 0xff);
3224 *(dp
+ 1) = (png_byte
)(background
->red
& 0xff);
3225 *(dp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
3226 *(dp
+ 3) = (png_byte
)(background
->green
& 0xff);
3227 *(dp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
3228 *(dp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3234 png_uint_16 r
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
3235 png_uint_16 g
= (png_uint_16
)(((*(sp
+ 2)) << 8)
3237 png_uint_16 b
= (png_uint_16
)(((*(sp
+ 4)) << 8)
3240 png_composite_16(v
, r
, a
, background
->red
);
3241 *dp
= (png_byte
)((v
>> 8) & 0xff);
3242 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3243 png_composite_16(v
, g
, a
, background
->green
);
3244 *(dp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
3245 *(dp
+ 3) = (png_byte
)(v
& 0xff);
3246 png_composite_16(v
, b
, a
, background
->blue
);
3247 *(dp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
3248 *(dp
+ 5) = (png_byte
)(v
& 0xff);
3257 if (row_info
->color_type
& PNG_COLOR_MASK_ALPHA
)
3259 row_info
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
3260 row_info
->channels
--;
3261 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
3262 row_info
->bit_depth
);
3263 row_info
->rowbytes
= ((row_width
*
3264 row_info
->pixel_depth
+ 7) >> 3);
3270 #if defined(PNG_READ_GAMMA_SUPPORTED)
3271 /* Gamma correct the image, avoiding the alpha channel. Make sure
3272 * you do this after you deal with the transparency issue on grayscale
3273 * or RGB images. If your bit depth is 8, use gamma_table, if it
3274 * is 16, use gamma_16_table and gamma_shift. Build these with
3275 * build_gamma_table().
3278 png_do_gamma(png_row_infop row_info
, png_bytep row
,
3279 png_bytep gamma_table
, png_uint_16pp gamma_16_table
,
3284 png_uint_32 row_width
=row_info
->width
;
3286 png_debug(1, "in png_do_gamma\n");
3288 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3289 row
!= NULL
&& row_info
!= NULL
&&
3291 ((row_info
->bit_depth
<= 8 && gamma_table
!= NULL
) ||
3292 (row_info
->bit_depth
== 16 && gamma_16_table
!= NULL
)))
3294 switch (row_info
->color_type
)
3296 case PNG_COLOR_TYPE_RGB
:
3298 if (row_info
->bit_depth
== 8)
3301 for (i
= 0; i
< row_width
; i
++)
3303 *sp
= gamma_table
[*sp
];
3305 *sp
= gamma_table
[*sp
];
3307 *sp
= gamma_table
[*sp
];
3311 else /* if (row_info->bit_depth == 16) */
3314 for (i
= 0; i
< row_width
; i
++)
3318 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3319 *sp
= (png_byte
)((v
>> 8) & 0xff);
3320 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3322 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3323 *sp
= (png_byte
)((v
>> 8) & 0xff);
3324 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3326 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3327 *sp
= (png_byte
)((v
>> 8) & 0xff);
3328 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3334 case PNG_COLOR_TYPE_RGB_ALPHA
:
3336 if (row_info
->bit_depth
== 8)
3339 for (i
= 0; i
< row_width
; i
++)
3341 *sp
= gamma_table
[*sp
];
3343 *sp
= gamma_table
[*sp
];
3345 *sp
= gamma_table
[*sp
];
3350 else /* if (row_info->bit_depth == 16) */
3353 for (i
= 0; i
< row_width
; i
++)
3355 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3356 *sp
= (png_byte
)((v
>> 8) & 0xff);
3357 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3359 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3360 *sp
= (png_byte
)((v
>> 8) & 0xff);
3361 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3363 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3364 *sp
= (png_byte
)((v
>> 8) & 0xff);
3365 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3371 case PNG_COLOR_TYPE_GRAY_ALPHA
:
3373 if (row_info
->bit_depth
== 8)
3376 for (i
= 0; i
< row_width
; i
++)
3378 *sp
= gamma_table
[*sp
];
3382 else /* if (row_info->bit_depth == 16) */
3385 for (i
= 0; i
< row_width
; i
++)
3387 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3388 *sp
= (png_byte
)((v
>> 8) & 0xff);
3389 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3395 case PNG_COLOR_TYPE_GRAY
:
3397 if (row_info
->bit_depth
== 2)
3400 for (i
= 0; i
< row_width
; i
+= 4)
3408 ((((int)gamma_table
[a
|(a
>>2)|(a
>>4)|(a
>>6)]) ) & 0xc0)|
3409 ((((int)gamma_table
[(b
<<2)|b
|(b
>>2)|(b
>>4)])>>2) & 0x30)|
3410 ((((int)gamma_table
[(c
<<4)|(c
<<2)|c
|(c
>>2)])>>4) & 0x0c)|
3411 ((((int)gamma_table
[(d
<<6)|(d
<<4)|(d
<<2)|d
])>>6) ));
3415 if (row_info
->bit_depth
== 4)
3418 for (i
= 0; i
< row_width
; i
+= 2)
3420 int msb
= *sp
& 0xf0;
3421 int lsb
= *sp
& 0x0f;
3423 *sp
= (png_byte
)((((int)gamma_table
[msb
| (msb
>> 4)]) & 0xf0)
3424 | (((int)gamma_table
[(lsb
<< 4) | lsb
]) >> 4));
3428 else if (row_info
->bit_depth
== 8)
3431 for (i
= 0; i
< row_width
; i
++)
3433 *sp
= gamma_table
[*sp
];
3437 else if (row_info
->bit_depth
== 16)
3440 for (i
= 0; i
< row_width
; i
++)
3442 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3443 *sp
= (png_byte
)((v
>> 8) & 0xff);
3444 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3455 #if defined(PNG_READ_EXPAND_SUPPORTED)
3456 /* Expands a palette row to an RGB or RGBA row depending
3457 * upon whether you supply trans and num_trans.
3460 png_do_expand_palette(png_row_infop row_info
, png_bytep row
,
3461 png_colorp palette
, png_bytep trans
, int num_trans
)
3466 png_uint_32 row_width
=row_info
->width
;
3468 png_debug(1, "in png_do_expand_palette\n");
3470 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3471 row
!= NULL
&& row_info
!= NULL
&&
3473 row_info
->color_type
== PNG_COLOR_TYPE_PALETTE
)
3475 if (row_info
->bit_depth
< 8)
3477 switch (row_info
->bit_depth
)
3481 sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
3482 dp
= row
+ (png_size_t
)row_width
- 1;
3483 shift
= 7 - (int)((row_width
+ 7) & 0x07);
3484 for (i
= 0; i
< row_width
; i
++)
3486 if ((*sp
>> shift
) & 0x01)
3504 sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
3505 dp
= row
+ (png_size_t
)row_width
- 1;
3506 shift
= (int)((3 - ((row_width
+ 3) & 0x03)) << 1);
3507 for (i
= 0; i
< row_width
; i
++)
3509 value
= (*sp
>> shift
) & 0x03;
3510 *dp
= (png_byte
)value
;
3525 sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
3526 dp
= row
+ (png_size_t
)row_width
- 1;
3527 shift
= (int)((row_width
& 0x01) << 2);
3528 for (i
= 0; i
< row_width
; i
++)
3530 value
= (*sp
>> shift
) & 0x0f;
3531 *dp
= (png_byte
)value
;
3545 row_info
->bit_depth
= 8;
3546 row_info
->pixel_depth
= 8;
3547 row_info
->rowbytes
= row_width
;
3549 switch (row_info
->bit_depth
)
3555 sp
= row
+ (png_size_t
)row_width
- 1;
3556 dp
= row
+ (png_size_t
)(row_width
<< 2) - 1;
3558 for (i
= 0; i
< row_width
; i
++)
3560 if ((int)(*sp
) >= num_trans
)
3564 *dp
-- = palette
[*sp
].blue
;
3565 *dp
-- = palette
[*sp
].green
;
3566 *dp
-- = palette
[*sp
].red
;
3569 row_info
->bit_depth
= 8;
3570 row_info
->pixel_depth
= 32;
3571 row_info
->rowbytes
= row_width
* 4;
3572 row_info
->color_type
= 6;
3573 row_info
->channels
= 4;
3577 sp
= row
+ (png_size_t
)row_width
- 1;
3578 dp
= row
+ (png_size_t
)(row_width
* 3) - 1;
3580 for (i
= 0; i
< row_width
; i
++)
3582 *dp
-- = palette
[*sp
].blue
;
3583 *dp
-- = palette
[*sp
].green
;
3584 *dp
-- = palette
[*sp
].red
;
3587 row_info
->bit_depth
= 8;
3588 row_info
->pixel_depth
= 24;
3589 row_info
->rowbytes
= row_width
* 3;
3590 row_info
->color_type
= 2;
3591 row_info
->channels
= 3;
3599 /* If the bit depth < 8, it is expanded to 8. Also, if the
3600 * transparency value is supplied, an alpha channel is built.
3603 png_do_expand(png_row_infop row_info
, png_bytep row
,
3604 png_color_16p trans_value
)
3609 png_uint_32 row_width
=row_info
->width
;
3611 png_debug(1, "in png_do_expand\n");
3612 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3613 if (row
!= NULL
&& row_info
!= NULL
)
3616 if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
3618 png_uint_16 gray
= (png_uint_16
)(trans_value
? trans_value
->gray
: 0);
3620 if (row_info
->bit_depth
< 8)
3622 switch (row_info
->bit_depth
)
3626 gray
= (png_uint_16
)(gray
*0xff);
3627 sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
3628 dp
= row
+ (png_size_t
)row_width
- 1;
3629 shift
= 7 - (int)((row_width
+ 7) & 0x07);
3630 for (i
= 0; i
< row_width
; i
++)
3632 if ((*sp
>> shift
) & 0x01)
3650 gray
= (png_uint_16
)(gray
*0x55);
3651 sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
3652 dp
= row
+ (png_size_t
)row_width
- 1;
3653 shift
= (int)((3 - ((row_width
+ 3) & 0x03)) << 1);
3654 for (i
= 0; i
< row_width
; i
++)
3656 value
= (*sp
>> shift
) & 0x03;
3657 *dp
= (png_byte
)(value
| (value
<< 2) | (value
<< 4) |
3673 gray
= (png_uint_16
)(gray
*0x11);
3674 sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
3675 dp
= row
+ (png_size_t
)row_width
- 1;
3676 shift
= (int)((1 - ((row_width
+ 1) & 0x01)) << 2);
3677 for (i
= 0; i
< row_width
; i
++)
3679 value
= (*sp
>> shift
) & 0x0f;
3680 *dp
= (png_byte
)(value
| (value
<< 4));
3694 row_info
->bit_depth
= 8;
3695 row_info
->pixel_depth
= 8;
3696 row_info
->rowbytes
= row_width
;
3699 if (trans_value
!= NULL
)
3701 if (row_info
->bit_depth
== 8)
3703 sp
= row
+ (png_size_t
)row_width
- 1;
3704 dp
= row
+ (png_size_t
)(row_width
<< 1) - 1;
3705 for (i
= 0; i
< row_width
; i
++)
3714 else if (row_info
->bit_depth
== 16)
3716 sp
= row
+ row_info
->rowbytes
- 1;
3717 dp
= row
+ (row_info
->rowbytes
<< 1) - 1;
3718 for (i
= 0; i
< row_width
; i
++)
3720 if (((png_uint_16
)*(sp
) |
3721 ((png_uint_16
)*(sp
- 1) << 8)) == gray
)
3735 row_info
->color_type
= PNG_COLOR_TYPE_GRAY_ALPHA
;
3736 row_info
->channels
= 2;
3737 row_info
->pixel_depth
= (png_byte
)(row_info
->bit_depth
<< 1);
3738 row_info
->rowbytes
=
3739 ((row_width
* row_info
->pixel_depth
) >> 3);
3742 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
&& trans_value
)
3744 if (row_info
->bit_depth
== 8)
3746 sp
= row
+ (png_size_t
)row_info
->rowbytes
- 1;
3747 dp
= row
+ (png_size_t
)(row_width
<< 2) - 1;
3748 for (i
= 0; i
< row_width
; i
++)
3750 if (*(sp
- 2) == trans_value
->red
&&
3751 *(sp
- 1) == trans_value
->green
&&
3752 *(sp
- 0) == trans_value
->blue
)
3761 else if (row_info
->bit_depth
== 16)
3763 sp
= row
+ row_info
->rowbytes
- 1;
3764 dp
= row
+ (png_size_t
)(row_width
<< 3) - 1;
3765 for (i
= 0; i
< row_width
; i
++)
3767 if ((((png_uint_16
)*(sp
- 4) |
3768 ((png_uint_16
)*(sp
- 5) << 8)) == trans_value
->red
) &&
3769 (((png_uint_16
)*(sp
- 2) |
3770 ((png_uint_16
)*(sp
- 3) << 8)) == trans_value
->green
) &&
3771 (((png_uint_16
)*(sp
- 0) |
3772 ((png_uint_16
)*(sp
- 1) << 8)) == trans_value
->blue
))
3790 row_info
->color_type
= PNG_COLOR_TYPE_RGB_ALPHA
;
3791 row_info
->channels
= 4;
3792 row_info
->pixel_depth
= (png_byte
)(row_info
->bit_depth
<< 2);
3793 row_info
->rowbytes
=
3794 ((row_width
* row_info
->pixel_depth
) >> 3);
3800 #if defined(PNG_READ_DITHER_SUPPORTED)
3802 png_do_dither(png_row_infop row_info
, png_bytep row
,
3803 png_bytep palette_lookup
, png_bytep dither_lookup
)
3807 png_uint_32 row_width
=row_info
->width
;
3809 png_debug(1, "in png_do_dither\n");
3810 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3811 if (row
!= NULL
&& row_info
!= NULL
)
3814 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
&&
3815 palette_lookup
&& row_info
->bit_depth
== 8)
3820 for (i
= 0; i
< row_width
; i
++)
3826 /* this looks real messy, but the compiler will reduce
3827 it down to a reasonable formula. For example, with
3828 5 bits per color, we get:
3829 p = (((r >> 3) & 0x1f) << 10) |
3830 (((g >> 3) & 0x1f) << 5) |
3833 p
= (((r
>> (8 - PNG_DITHER_RED_BITS
)) &
3834 ((1 << PNG_DITHER_RED_BITS
) - 1)) <<
3835 (PNG_DITHER_GREEN_BITS
+ PNG_DITHER_BLUE_BITS
)) |
3836 (((g
>> (8 - PNG_DITHER_GREEN_BITS
)) &
3837 ((1 << PNG_DITHER_GREEN_BITS
) - 1)) <<
3838 (PNG_DITHER_BLUE_BITS
)) |
3839 ((b
>> (8 - PNG_DITHER_BLUE_BITS
)) &
3840 ((1 << PNG_DITHER_BLUE_BITS
) - 1));
3842 *dp
++ = palette_lookup
[p
];
3844 row_info
->color_type
= PNG_COLOR_TYPE_PALETTE
;
3845 row_info
->channels
= 1;
3846 row_info
->pixel_depth
= row_info
->bit_depth
;
3847 row_info
->rowbytes
=
3848 ((row_width
* row_info
->pixel_depth
+ 7) >> 3);
3850 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
&&
3851 palette_lookup
!= NULL
&& row_info
->bit_depth
== 8)
3856 for (i
= 0; i
< row_width
; i
++)
3863 p
= (((r
>> (8 - PNG_DITHER_RED_BITS
)) &
3864 ((1 << PNG_DITHER_RED_BITS
) - 1)) <<
3865 (PNG_DITHER_GREEN_BITS
+ PNG_DITHER_BLUE_BITS
)) |
3866 (((g
>> (8 - PNG_DITHER_GREEN_BITS
)) &
3867 ((1 << PNG_DITHER_GREEN_BITS
) - 1)) <<
3868 (PNG_DITHER_BLUE_BITS
)) |
3869 ((b
>> (8 - PNG_DITHER_BLUE_BITS
)) &
3870 ((1 << PNG_DITHER_BLUE_BITS
) - 1));
3872 *dp
++ = palette_lookup
[p
];
3874 row_info
->color_type
= PNG_COLOR_TYPE_PALETTE
;
3875 row_info
->channels
= 1;
3876 row_info
->pixel_depth
= row_info
->bit_depth
;
3877 row_info
->rowbytes
=
3878 ((row_width
* row_info
->pixel_depth
+ 7) >> 3);
3880 else if (row_info
->color_type
== PNG_COLOR_TYPE_PALETTE
&&
3881 dither_lookup
&& row_info
->bit_depth
== 8)
3884 for (i
= 0; i
< row_width
; i
++, sp
++)
3886 *sp
= dither_lookup
[*sp
];
3893 #ifdef PNG_FLOATING_POINT_SUPPORTED
3894 #if defined(PNG_READ_GAMMA_SUPPORTED)
3895 static int png_gamma_shift
[] =
3896 {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0};
3898 /* We build the 8- or 16-bit gamma tables here. Note that for 16-bit
3899 * tables, we don't make a full table if we are reducing to 8-bit in
3900 * the future. Note also how the gamma_16 tables are segmented so that
3901 * we don't need to allocate > 64K chunks for a full 16-bit table.
3904 png_build_gamma_table(png_structp png_ptr
)
3906 png_debug(1, "in png_build_gamma_table\n");
3907 if(png_ptr
->gamma
!= 0.0)
3909 if (png_ptr
->bit_depth
<= 8)
3914 if (png_ptr
->screen_gamma
> .000001)
3915 g
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
3919 png_ptr
->gamma_table
= (png_bytep
)png_malloc(png_ptr
,
3922 for (i
= 0; i
< 256; i
++)
3924 png_ptr
->gamma_table
[i
] = (png_byte
)(pow((double)i
/ 255.0,
3928 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
3929 defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
3930 if (png_ptr
->transformations
& ((PNG_BACKGROUND
) | PNG_RGB_TO_GRAY
))
3933 g
= 1.0 / (png_ptr
->gamma
);
3935 png_ptr
->gamma_to_1
= (png_bytep
)png_malloc(png_ptr
,
3938 for (i
= 0; i
< 256; i
++)
3940 png_ptr
->gamma_to_1
[i
] = (png_byte
)(pow((double)i
/ 255.0,
3945 png_ptr
->gamma_from_1
= (png_bytep
)png_malloc(png_ptr
,
3948 if(png_ptr
->screen_gamma
> 0.000001)
3949 g
= 1.0 / png_ptr
->screen_gamma
;
3951 g
= png_ptr
->gamma
; /* probably doing rgb_to_gray */
3953 for (i
= 0; i
< 256; i
++)
3955 png_ptr
->gamma_from_1
[i
] = (png_byte
)(pow((double)i
/ 255.0,
3960 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
3965 int i
, j
, shift
, num
;
3969 if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
3971 sig_bit
= (int)png_ptr
->sig_bit
.red
;
3972 if ((int)png_ptr
->sig_bit
.green
> sig_bit
)
3973 sig_bit
= png_ptr
->sig_bit
.green
;
3974 if ((int)png_ptr
->sig_bit
.blue
> sig_bit
)
3975 sig_bit
= png_ptr
->sig_bit
.blue
;
3979 sig_bit
= (int)png_ptr
->sig_bit
.gray
;
3983 shift
= 16 - sig_bit
;
3987 if (png_ptr
->transformations
& PNG_16_TO_8
)
3989 if (shift
< (16 - PNG_MAX_GAMMA_8
))
3990 shift
= (16 - PNG_MAX_GAMMA_8
);
3998 png_ptr
->gamma_shift
= (png_byte
)shift
;
4000 num
= (1 << (8 - shift
));
4002 if (png_ptr
->screen_gamma
> .000001)
4003 g
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
4007 png_ptr
->gamma_16_table
= (png_uint_16pp
)png_malloc(png_ptr
,
4008 (png_uint_32
)(num
* sizeof (png_uint_16p
)));
4010 if (png_ptr
->transformations
& (PNG_16_TO_8
| PNG_BACKGROUND
))
4013 png_uint_32 last
, max
;
4015 for (i
= 0; i
< num
; i
++)
4017 png_ptr
->gamma_16_table
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
4018 (png_uint_32
)(256 * sizeof (png_uint_16
)));
4023 for (i
= 0; i
< 256; i
++)
4025 fout
= ((double)i
+ 0.5) / 256.0;
4027 max
= (png_uint_32
)(fin
* (double)((png_uint_32
)num
<< 8));
4030 png_ptr
->gamma_16_table
[(int)(last
& (0xff >> shift
))]
4031 [(int)(last
>> (8 - shift
))] = (png_uint_16
)(
4032 (png_uint_16
)i
| ((png_uint_16
)i
<< 8));
4036 while (last
< ((png_uint_32
)num
<< 8))
4038 png_ptr
->gamma_16_table
[(int)(last
& (0xff >> shift
))]
4039 [(int)(last
>> (8 - shift
))] = (png_uint_16
)65535L;
4045 for (i
= 0; i
< num
; i
++)
4047 png_ptr
->gamma_16_table
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
4048 (png_uint_32
)(256 * sizeof (png_uint_16
)));
4050 ig
= (((png_uint_32
)i
* (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
4051 for (j
= 0; j
< 256; j
++)
4053 png_ptr
->gamma_16_table
[i
][j
] =
4054 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
4055 65535.0, g
) * 65535.0 + .5);
4060 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
4061 defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
4062 if (png_ptr
->transformations
& (PNG_BACKGROUND
| PNG_RGB_TO_GRAY
))
4065 g
= 1.0 / (png_ptr
->gamma
);
4067 png_ptr
->gamma_16_to_1
= (png_uint_16pp
)png_malloc(png_ptr
,
4068 (png_uint_32
)(num
* sizeof (png_uint_16p
)));
4070 for (i
= 0; i
< num
; i
++)
4072 png_ptr
->gamma_16_to_1
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
4073 (png_uint_32
)(256 * sizeof (png_uint_16
)));
4075 ig
= (((png_uint_32
)i
*
4076 (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
4077 for (j
= 0; j
< 256; j
++)
4079 png_ptr
->gamma_16_to_1
[i
][j
] =
4080 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
4081 65535.0, g
) * 65535.0 + .5);
4085 if(png_ptr
->screen_gamma
> 0.000001)
4086 g
= 1.0 / png_ptr
->screen_gamma
;
4088 g
= png_ptr
->gamma
; /* probably doing rgb_to_gray */
4090 png_ptr
->gamma_16_from_1
= (png_uint_16pp
)png_malloc(png_ptr
,
4091 (png_uint_32
)(num
* sizeof (png_uint_16p
)));
4093 for (i
= 0; i
< num
; i
++)
4095 png_ptr
->gamma_16_from_1
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
4096 (png_uint_32
)(256 * sizeof (png_uint_16
)));
4098 ig
= (((png_uint_32
)i
*
4099 (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
4100 for (j
= 0; j
< 256; j
++)
4102 png_ptr
->gamma_16_from_1
[i
][j
] =
4103 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
4104 65535.0, g
) * 65535.0 + .5);
4108 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
4113 /* To do: install integer version of png_build_gamma_table here */
4116 #if defined(PNG_MNG_FEATURES_SUPPORTED)
4117 /* undoes intrapixel differencing */
4119 png_do_read_intrapixel(png_row_infop row_info
, png_bytep row
)
4121 png_debug(1, "in png_do_read_intrapixel\n");
4123 #if defined(PNG_USELESS_TESTS_SUPPORTED)
4124 row
!= NULL
&& row_info
!= NULL
&&
4126 (row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
4128 int bytes_per_pixel
;
4129 png_uint_32 row_width
= row_info
->width
;
4130 if (row_info
->bit_depth
== 8)
4135 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
4136 bytes_per_pixel
= 3;
4137 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
4138 bytes_per_pixel
= 4;
4142 for (i
= 0, rp
= row
; i
< row_width
; i
++, rp
+= bytes_per_pixel
)
4144 *(rp
) = (png_byte
)((256 + *rp
+ *(rp
+1))&0xff);
4145 *(rp
+2) = (png_byte
)((256 + *(rp
+2) + *(rp
+1))&0xff);
4148 else if (row_info
->bit_depth
== 16)
4153 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
4154 bytes_per_pixel
= 6;
4155 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
4156 bytes_per_pixel
= 8;
4160 for (i
= 0, rp
= row
; i
< row_width
; i
++, rp
+= bytes_per_pixel
)
4162 png_uint_32 s0
=*(rp
)<<8 | *(rp
+1);
4163 png_uint_32 s1
=*(rp
+2)<<8 | *(rp
+3);
4164 png_uint_32 s2
=*(rp
+4)<<8 | *(rp
+5);
4165 png_uint_32 red
=(65536+s0
+s1
)&0xffff;
4166 png_uint_32 blue
=(65536+s2
+s1
)&0xffff;
4167 *(rp
) = (png_byte
)((red
>>8)&0xff);
4168 *(rp
+1) = (png_byte
)(red
&0xff);
4169 *(rp
+4) = (png_byte
)((blue
>>8)&0xff);
4170 *(rp
+5) = (png_byte
)(blue
&0xff);
4175 #endif /* PNG_MNG_FEATURES_SUPPORTED */