2 /* pngrtran.c - transforms the data in a row for PNG readers
4 * libpng version 1.2.6 - August 15, 2004
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1998-2004 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
,
89 png_sizeof(png_color_16
));
90 png_ptr
->background_gamma
= (float)background_gamma
;
91 png_ptr
->background_gamma_type
= (png_byte
)(background_gamma_code
);
92 png_ptr
->transformations
|= (need_expand
? PNG_BACKGROUND_EXPAND
: 0);
94 /* Note: if need_expand is set and color_type is either RGB or RGB_ALPHA
95 * (in which case need_expand is superfluous anyway), the background color
96 * might actually be gray yet not be flagged as such. This is not a problem
97 * for the current code, which uses PNG_BACKGROUND_IS_GRAY only to
98 * decide when to do the png_do_gray_to_rgb() transformation.
100 if ((need_expand
&& !(png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)) ||
101 (!need_expand
&& background_color
->red
== background_color
->green
&&
102 background_color
->red
== background_color
->blue
))
103 png_ptr
->mode
|= PNG_BACKGROUND_IS_GRAY
;
107 #if defined(PNG_READ_16_TO_8_SUPPORTED)
108 /* strip 16 bit depth files to 8 bit depth */
110 png_set_strip_16(png_structp png_ptr
)
112 png_debug(1, "in png_set_strip_16\n");
113 png_ptr
->transformations
|= PNG_16_TO_8
;
117 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
119 png_set_strip_alpha(png_structp png_ptr
)
121 png_debug(1, "in png_set_strip_alpha\n");
122 png_ptr
->transformations
|= PNG_STRIP_ALPHA
;
126 #if defined(PNG_READ_DITHER_SUPPORTED)
127 /* Dither file to 8 bit. Supply a palette, the current number
128 * of elements in the palette, the maximum number of elements
129 * allowed, and a histogram if possible. If the current number
130 * of colors is greater then the maximum number, the palette will be
131 * modified to fit in the maximum number. "full_dither" indicates
132 * whether we need a dithering cube set up for RGB images, or if we
133 * simply are reducing the number of colors in a paletted image.
136 typedef struct png_dsort_struct
138 struct png_dsort_struct FAR
* next
;
142 typedef png_dsort FAR
* png_dsortp
;
143 typedef png_dsort FAR
* FAR
* png_dsortpp
;
146 png_set_dither(png_structp png_ptr
, png_colorp palette
,
147 int num_palette
, int maximum_colors
, png_uint_16p histogram
,
150 png_debug(1, "in png_set_dither\n");
151 png_ptr
->transformations
|= PNG_DITHER
;
157 png_ptr
->dither_index
= (png_bytep
)png_malloc(png_ptr
,
158 (png_uint_32
)(num_palette
* png_sizeof (png_byte
)));
159 for (i
= 0; i
< num_palette
; i
++)
160 png_ptr
->dither_index
[i
] = (png_byte
)i
;
163 if (num_palette
> maximum_colors
)
165 if (histogram
!= NULL
)
167 /* This is easy enough, just throw out the least used colors.
168 Perhaps not the best solution, but good enough. */
172 /* initialize an array to sort colors */
173 png_ptr
->dither_sort
= (png_bytep
)png_malloc(png_ptr
,
174 (png_uint_32
)(num_palette
* png_sizeof (png_byte
)));
176 /* initialize the dither_sort array */
177 for (i
= 0; i
< num_palette
; i
++)
178 png_ptr
->dither_sort
[i
] = (png_byte
)i
;
180 /* Find the least used palette entries by starting a
181 bubble sort, and running it until we have sorted
182 out enough colors. Note that we don't care about
183 sorting all the colors, just finding which are
186 for (i
= num_palette
- 1; i
>= maximum_colors
; i
--)
188 int done
; /* to stop early if the list is pre-sorted */
192 for (j
= 0; j
< i
; j
++)
194 if (histogram
[png_ptr
->dither_sort
[j
]]
195 < histogram
[png_ptr
->dither_sort
[j
+ 1]])
199 t
= png_ptr
->dither_sort
[j
];
200 png_ptr
->dither_sort
[j
] = png_ptr
->dither_sort
[j
+ 1];
201 png_ptr
->dither_sort
[j
+ 1] = t
;
209 /* swap the palette around, and set up a table, if necessary */
214 /* put all the useful colors within the max, but don't
216 for (i
= 0; i
< maximum_colors
; i
++)
218 if ((int)png_ptr
->dither_sort
[i
] >= maximum_colors
)
222 while ((int)png_ptr
->dither_sort
[j
] >= maximum_colors
);
223 palette
[i
] = palette
[j
];
231 /* move all the used colors inside the max limit, and
232 develop a translation table */
233 for (i
= 0; i
< maximum_colors
; i
++)
235 /* only move the colors we need to */
236 if ((int)png_ptr
->dither_sort
[i
] >= maximum_colors
)
242 while ((int)png_ptr
->dither_sort
[j
] >= maximum_colors
);
244 tmp_color
= palette
[j
];
245 palette
[j
] = palette
[i
];
246 palette
[i
] = tmp_color
;
247 /* indicate where the color went */
248 png_ptr
->dither_index
[j
] = (png_byte
)i
;
249 png_ptr
->dither_index
[i
] = (png_byte
)j
;
253 /* find closest color for those colors we are not using */
254 for (i
= 0; i
< num_palette
; i
++)
256 if ((int)png_ptr
->dither_index
[i
] >= maximum_colors
)
258 int min_d
, k
, min_k
, d_index
;
260 /* find the closest color to one we threw out */
261 d_index
= png_ptr
->dither_index
[i
];
262 min_d
= PNG_COLOR_DIST(palette
[d_index
], palette
[0]);
263 for (k
= 1, min_k
= 0; k
< maximum_colors
; k
++)
267 d
= PNG_COLOR_DIST(palette
[d_index
], palette
[k
]);
275 /* point to closest color */
276 png_ptr
->dither_index
[i
] = (png_byte
)min_k
;
280 png_free(png_ptr
, png_ptr
->dither_sort
);
281 png_ptr
->dither_sort
=NULL
;
285 /* This is much harder to do simply (and quickly). Perhaps
286 we need to go through a median cut routine, but those
287 don't always behave themselves with only a few colors
288 as input. So we will just find the closest two colors,
289 and throw out one of them (chosen somewhat randomly).
290 [We don't understand this at all, so if someone wants to
291 work on improving it, be our guest - AED, GRP]
301 /* initialize palette index arrays */
302 png_ptr
->index_to_palette
= (png_bytep
)png_malloc(png_ptr
,
303 (png_uint_32
)(num_palette
* png_sizeof (png_byte
)));
304 png_ptr
->palette_to_index
= (png_bytep
)png_malloc(png_ptr
,
305 (png_uint_32
)(num_palette
* png_sizeof (png_byte
)));
307 /* initialize the sort array */
308 for (i
= 0; i
< num_palette
; i
++)
310 png_ptr
->index_to_palette
[i
] = (png_byte
)i
;
311 png_ptr
->palette_to_index
[i
] = (png_byte
)i
;
314 hash
= (png_dsortpp
)png_malloc(png_ptr
, (png_uint_32
)(769 *
315 png_sizeof (png_dsortp
)));
316 for (i
= 0; i
< 769; i
++)
318 /* png_memset(hash, 0, 769 * png_sizeof (png_dsortp)); */
320 num_new_palette
= num_palette
;
322 /* initial wild guess at how far apart the farthest pixel
323 pair we will be eliminating will be. Larger
324 numbers mean more areas will be allocated, Smaller
325 numbers run the risk of not saving enough data, and
326 having to do this all over again.
328 I have not done extensive checking on this number.
332 while (num_new_palette
> maximum_colors
)
334 for (i
= 0; i
< num_new_palette
- 1; i
++)
338 for (j
= i
+ 1; j
< num_new_palette
; j
++)
342 d
= PNG_COLOR_DIST(palette
[i
], palette
[j
]);
347 t
= (png_dsortp
)png_malloc_warn(png_ptr
,
348 (png_uint_32
)(png_sizeof(png_dsort
)));
352 t
->left
= (png_byte
)i
;
353 t
->right
= (png_byte
)j
;
362 for (i
= 0; i
<= max_d
; i
++)
368 for (p
= hash
[i
]; p
; p
= p
->next
)
370 if ((int)png_ptr
->index_to_palette
[p
->left
]
372 (int)png_ptr
->index_to_palette
[p
->right
]
377 if (num_new_palette
& 0x01)
389 palette
[png_ptr
->index_to_palette
[j
]]
390 = palette
[num_new_palette
];
395 for (k
= 0; k
< num_palette
; k
++)
397 if (png_ptr
->dither_index
[k
] ==
398 png_ptr
->index_to_palette
[j
])
399 png_ptr
->dither_index
[k
] =
400 png_ptr
->index_to_palette
[next_j
];
401 if ((int)png_ptr
->dither_index
[k
] ==
403 png_ptr
->dither_index
[k
] =
404 png_ptr
->index_to_palette
[j
];
408 png_ptr
->index_to_palette
[png_ptr
->palette_to_index
409 [num_new_palette
]] = png_ptr
->index_to_palette
[j
];
410 png_ptr
->palette_to_index
[png_ptr
->index_to_palette
[j
]]
411 = png_ptr
->palette_to_index
[num_new_palette
];
413 png_ptr
->index_to_palette
[j
] = (png_byte
)num_new_palette
;
414 png_ptr
->palette_to_index
[num_new_palette
] = (png_byte
)j
;
416 if (num_new_palette
<= maximum_colors
)
419 if (num_new_palette
<= maximum_colors
)
424 for (i
= 0; i
< 769; i
++)
428 png_dsortp p
= hash
[i
];
432 png_free(png_ptr
, p
);
440 png_free(png_ptr
, hash
);
441 png_free(png_ptr
, png_ptr
->palette_to_index
);
442 png_free(png_ptr
, png_ptr
->index_to_palette
);
443 png_ptr
->palette_to_index
=NULL
;
444 png_ptr
->index_to_palette
=NULL
;
446 num_palette
= maximum_colors
;
448 if (png_ptr
->palette
== NULL
)
450 png_ptr
->palette
= palette
;
452 png_ptr
->num_palette
= (png_uint_16
)num_palette
;
458 int total_bits
= PNG_DITHER_RED_BITS
+ PNG_DITHER_GREEN_BITS
+
459 PNG_DITHER_BLUE_BITS
;
460 int num_red
= (1 << PNG_DITHER_RED_BITS
);
461 int num_green
= (1 << PNG_DITHER_GREEN_BITS
);
462 int num_blue
= (1 << PNG_DITHER_BLUE_BITS
);
463 png_size_t num_entries
= ((png_size_t
)1 << total_bits
);
465 png_ptr
->palette_lookup
= (png_bytep
)png_malloc(png_ptr
,
466 (png_uint_32
)(num_entries
* png_sizeof (png_byte
)));
468 png_memset(png_ptr
->palette_lookup
, 0, num_entries
*
469 png_sizeof (png_byte
));
471 distance
= (png_bytep
)png_malloc(png_ptr
, (png_uint_32
)(num_entries
*
472 png_sizeof(png_byte
)));
474 png_memset(distance
, 0xff, num_entries
* png_sizeof(png_byte
));
476 for (i
= 0; i
< num_palette
; i
++)
479 int r
= (palette
[i
].red
>> (8 - PNG_DITHER_RED_BITS
));
480 int g
= (palette
[i
].green
>> (8 - PNG_DITHER_GREEN_BITS
));
481 int b
= (palette
[i
].blue
>> (8 - PNG_DITHER_BLUE_BITS
));
483 for (ir
= 0; ir
< num_red
; ir
++)
485 /* int dr = abs(ir - r); */
486 int dr
= ((ir
> r
) ? ir
- r
: r
- ir
);
487 int index_r
= (ir
<< (PNG_DITHER_BLUE_BITS
+ PNG_DITHER_GREEN_BITS
));
489 for (ig
= 0; ig
< num_green
; ig
++)
491 /* int dg = abs(ig - g); */
492 int dg
= ((ig
> g
) ? ig
- g
: g
- ig
);
494 int dm
= ((dr
> dg
) ? dr
: dg
);
495 int index_g
= index_r
| (ig
<< PNG_DITHER_BLUE_BITS
);
497 for (ib
= 0; ib
< num_blue
; ib
++)
499 int d_index
= index_g
| ib
;
500 /* int db = abs(ib - b); */
501 int db
= ((ib
> b
) ? ib
- b
: b
- ib
);
502 int dmax
= ((dm
> db
) ? dm
: db
);
503 int d
= dmax
+ dt
+ db
;
505 if (d
< (int)distance
[d_index
])
507 distance
[d_index
] = (png_byte
)d
;
508 png_ptr
->palette_lookup
[d_index
] = (png_byte
)i
;
515 png_free(png_ptr
, distance
);
520 #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
521 /* Transform the image from the file_gamma to the screen_gamma. We
522 * only do transformations on images where the file_gamma and screen_gamma
523 * are not close reciprocals, otherwise it slows things down slightly, and
524 * also needlessly introduces small errors.
526 * We will turn off gamma transformation later if no semitransparent entries
527 * are present in the tRNS array for palette images. We can't do it here
528 * because we don't necessarily have the tRNS chunk yet.
531 png_set_gamma(png_structp png_ptr
, double scrn_gamma
, double file_gamma
)
533 png_debug(1, "in png_set_gamma\n");
534 if ((fabs(scrn_gamma
* file_gamma
- 1.0) > PNG_GAMMA_THRESHOLD
) ||
535 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
) ||
536 (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
))
537 png_ptr
->transformations
|= PNG_GAMMA
;
538 png_ptr
->gamma
= (float)file_gamma
;
539 png_ptr
->screen_gamma
= (float)scrn_gamma
;
543 #if defined(PNG_READ_EXPAND_SUPPORTED)
544 /* Expand paletted images to RGB, expand grayscale images of
545 * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
549 png_set_expand(png_structp png_ptr
)
551 png_debug(1, "in png_set_expand\n");
552 png_ptr
->transformations
|= PNG_EXPAND
;
555 /* GRR 19990627: the following three functions currently are identical
556 * to png_set_expand(). However, it is entirely reasonable that someone
557 * might wish to expand an indexed image to RGB but *not* expand a single,
558 * fully transparent palette entry to a full alpha channel--perhaps instead
559 * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
560 * the transparent color with a particular RGB value, or drop tRNS entirely.
561 * IOW, a future version of the library may make the transformations flag
562 * a bit more fine-grained, with separate bits for each of these three
565 * More to the point, these functions make it obvious what libpng will be
566 * doing, whereas "expand" can (and does) mean any number of things.
569 /* Expand paletted images to RGB. */
571 png_set_palette_to_rgb(png_structp png_ptr
)
573 png_debug(1, "in png_set_expand\n");
574 png_ptr
->transformations
|= PNG_EXPAND
;
577 /* Expand grayscale images of less than 8-bit depth to 8 bits. */
579 png_set_gray_1_2_4_to_8(png_structp png_ptr
)
581 png_debug(1, "in png_set_expand\n");
582 png_ptr
->transformations
|= PNG_EXPAND
;
585 /* Expand tRNS chunks to alpha channels. */
587 png_set_tRNS_to_alpha(png_structp png_ptr
)
589 png_debug(1, "in png_set_expand\n");
590 png_ptr
->transformations
|= PNG_EXPAND
;
592 #endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
594 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
596 png_set_gray_to_rgb(png_structp png_ptr
)
598 png_debug(1, "in png_set_gray_to_rgb\n");
599 png_ptr
->transformations
|= PNG_GRAY_TO_RGB
;
603 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
604 #if defined(PNG_FLOATING_POINT_SUPPORTED)
605 /* Convert a RGB image to a grayscale of the same width. This allows us,
606 * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
610 png_set_rgb_to_gray(png_structp png_ptr
, int error_action
, double red
,
613 int red_fixed
= (int)((float)red
*100000.0 + 0.5);
614 int green_fixed
= (int)((float)green
*100000.0 + 0.5);
615 png_set_rgb_to_gray_fixed(png_ptr
, error_action
, red_fixed
, green_fixed
);
620 png_set_rgb_to_gray_fixed(png_structp png_ptr
, int error_action
,
621 png_fixed_point red
, png_fixed_point green
)
623 png_debug(1, "in png_set_rgb_to_gray\n");
626 case 1: png_ptr
->transformations
|= PNG_RGB_TO_GRAY
;
628 case 2: png_ptr
->transformations
|= PNG_RGB_TO_GRAY_WARN
;
630 case 3: png_ptr
->transformations
|= PNG_RGB_TO_GRAY_ERR
;
632 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
633 #if defined(PNG_READ_EXPAND_SUPPORTED)
634 png_ptr
->transformations
|= PNG_EXPAND
;
637 png_warning(png_ptr
, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
638 png_ptr
->transformations
&= ~PNG_RGB_TO_GRAY
;
642 png_uint_16 red_int
, green_int
;
643 if(red
< 0 || green
< 0)
645 red_int
= 6968; /* .212671 * 32768 + .5 */
646 green_int
= 23434; /* .715160 * 32768 + .5 */
648 else if(red
+ green
< 100000L)
650 red_int
= (png_uint_16
)(((png_uint_32
)red
*32768L)/100000L);
651 green_int
= (png_uint_16
)(((png_uint_32
)green
*32768L)/100000L);
655 png_warning(png_ptr
, "ignoring out of range rgb_to_gray coefficients");
659 png_ptr
->rgb_to_gray_red_coeff
= red_int
;
660 png_ptr
->rgb_to_gray_green_coeff
= green_int
;
661 png_ptr
->rgb_to_gray_blue_coeff
= (png_uint_16
)(32768-red_int
-green_int
);
666 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
667 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
668 defined(PNG_LEGACY_SUPPORTED)
670 png_set_read_user_transform_fn(png_structp png_ptr
, png_user_transform_ptr
671 read_user_transform_fn
)
673 png_debug(1, "in png_set_read_user_transform_fn\n");
674 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
675 png_ptr
->transformations
|= PNG_USER_TRANSFORM
;
676 png_ptr
->read_user_transform_fn
= read_user_transform_fn
;
678 #ifdef PNG_LEGACY_SUPPORTED
679 if(read_user_transform_fn
)
681 "This version of libpng does not support user transforms");
686 /* Initialize everything needed for the read. This includes modifying
690 png_init_read_transformations(png_structp png_ptr
)
692 png_debug(1, "in png_init_read_transformations\n");
693 #if defined(PNG_USELESS_TESTS_SUPPORTED)
697 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
698 || defined(PNG_READ_GAMMA_SUPPORTED)
699 int color_type
= png_ptr
->color_type
;
702 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
703 if ((png_ptr
->transformations
& PNG_BACKGROUND_EXPAND
) &&
704 (png_ptr
->transformations
& PNG_EXPAND
))
706 if (!(color_type
& PNG_COLOR_MASK_COLOR
)) /* i.e., GRAY or GRAY_ALPHA */
708 /* expand background chunk. */
709 switch (png_ptr
->bit_depth
)
712 png_ptr
->background
.gray
*= (png_uint_16
)0xff;
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
)0x55;
718 png_ptr
->background
.red
= png_ptr
->background
.green
719 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
722 png_ptr
->background
.gray
*= (png_uint_16
)0x11;
723 png_ptr
->background
.red
= png_ptr
->background
.green
724 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
728 png_ptr
->background
.red
= png_ptr
->background
.green
729 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
733 else if (color_type
== PNG_COLOR_TYPE_PALETTE
)
735 png_ptr
->background
.red
=
736 png_ptr
->palette
[png_ptr
->background
.index
].red
;
737 png_ptr
->background
.green
=
738 png_ptr
->palette
[png_ptr
->background
.index
].green
;
739 png_ptr
->background
.blue
=
740 png_ptr
->palette
[png_ptr
->background
.index
].blue
;
742 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
743 if (png_ptr
->transformations
& PNG_INVERT_ALPHA
)
745 #if defined(PNG_READ_EXPAND_SUPPORTED)
746 if (!(png_ptr
->transformations
& PNG_EXPAND
))
749 /* invert the alpha channel (in tRNS) unless the pixels are
750 going to be expanded, in which case leave it for later */
752 istop
=(int)png_ptr
->num_trans
;
753 for (i
=0; i
<istop
; i
++)
754 png_ptr
->trans
[i
] = (png_byte
)(255 - png_ptr
->trans
[i
]);
763 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
764 png_ptr
->background_1
= png_ptr
->background
;
766 #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
768 if ((color_type
== PNG_COLOR_TYPE_PALETTE
&& png_ptr
->num_trans
!= 0)
769 && (fabs(png_ptr
->screen_gamma
* png_ptr
->gamma
- 1.0)
770 < PNG_GAMMA_THRESHOLD
))
774 for (i
=0; i
<png_ptr
->num_trans
; i
++)
776 if (png_ptr
->trans
[i
] != 0 && png_ptr
->trans
[i
] != 0xff)
777 k
=1; /* partial transparency is present */
780 png_ptr
->transformations
&= (~PNG_GAMMA
);
783 if (png_ptr
->transformations
& (PNG_GAMMA
| PNG_RGB_TO_GRAY
))
785 png_build_gamma_table(png_ptr
);
786 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
787 if (png_ptr
->transformations
& PNG_BACKGROUND
)
789 if (color_type
== PNG_COLOR_TYPE_PALETTE
)
791 /* could skip if no transparency and
793 png_color back
, back_1
;
794 png_colorp palette
= png_ptr
->palette
;
795 int num_palette
= png_ptr
->num_palette
;
797 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_FILE
)
799 back
.red
= png_ptr
->gamma_table
[png_ptr
->background
.red
];
800 back
.green
= png_ptr
->gamma_table
[png_ptr
->background
.green
];
801 back
.blue
= png_ptr
->gamma_table
[png_ptr
->background
.blue
];
803 back_1
.red
= png_ptr
->gamma_to_1
[png_ptr
->background
.red
];
804 back_1
.green
= png_ptr
->gamma_to_1
[png_ptr
->background
.green
];
805 back_1
.blue
= png_ptr
->gamma_to_1
[png_ptr
->background
.blue
];
811 switch (png_ptr
->background_gamma_type
)
813 case PNG_BACKGROUND_GAMMA_SCREEN
:
814 g
= (png_ptr
->screen_gamma
);
817 case PNG_BACKGROUND_GAMMA_FILE
:
818 g
= 1.0 / (png_ptr
->gamma
);
819 gs
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
821 case PNG_BACKGROUND_GAMMA_UNIQUE
:
822 g
= 1.0 / (png_ptr
->background_gamma
);
823 gs
= 1.0 / (png_ptr
->background_gamma
*
824 png_ptr
->screen_gamma
);
827 g
= 1.0; /* back_1 */
831 if ( fabs(gs
- 1.0) < PNG_GAMMA_THRESHOLD
)
833 back
.red
= (png_byte
)png_ptr
->background
.red
;
834 back
.green
= (png_byte
)png_ptr
->background
.green
;
835 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
839 back
.red
= (png_byte
)(pow(
840 (double)png_ptr
->background
.red
/255, gs
) * 255.0 + .5);
841 back
.green
= (png_byte
)(pow(
842 (double)png_ptr
->background
.green
/255, gs
) * 255.0 + .5);
843 back
.blue
= (png_byte
)(pow(
844 (double)png_ptr
->background
.blue
/255, gs
) * 255.0 + .5);
847 back_1
.red
= (png_byte
)(pow(
848 (double)png_ptr
->background
.red
/255, g
) * 255.0 + .5);
849 back_1
.green
= (png_byte
)(pow(
850 (double)png_ptr
->background
.green
/255, g
) * 255.0 + .5);
851 back_1
.blue
= (png_byte
)(pow(
852 (double)png_ptr
->background
.blue
/255, g
) * 255.0 + .5);
854 for (i
= 0; i
< num_palette
; i
++)
856 if (i
< (int)png_ptr
->num_trans
&& png_ptr
->trans
[i
] != 0xff)
858 if (png_ptr
->trans
[i
] == 0)
862 else /* if (png_ptr->trans[i] != 0xff) */
866 v
= png_ptr
->gamma_to_1
[palette
[i
].red
];
867 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.red
);
868 palette
[i
].red
= png_ptr
->gamma_from_1
[w
];
870 v
= png_ptr
->gamma_to_1
[palette
[i
].green
];
871 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.green
);
872 palette
[i
].green
= png_ptr
->gamma_from_1
[w
];
874 v
= png_ptr
->gamma_to_1
[palette
[i
].blue
];
875 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.blue
);
876 palette
[i
].blue
= png_ptr
->gamma_from_1
[w
];
881 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
882 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
883 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
887 /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
889 /* color_type != PNG_COLOR_TYPE_PALETTE */
891 double m
= (double)(((png_uint_32
)1 << png_ptr
->bit_depth
) - 1);
895 switch (png_ptr
->background_gamma_type
)
897 case PNG_BACKGROUND_GAMMA_SCREEN
:
898 g
= (png_ptr
->screen_gamma
);
901 case PNG_BACKGROUND_GAMMA_FILE
:
902 g
= 1.0 / (png_ptr
->gamma
);
903 gs
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
905 case PNG_BACKGROUND_GAMMA_UNIQUE
:
906 g
= 1.0 / (png_ptr
->background_gamma
);
907 gs
= 1.0 / (png_ptr
->background_gamma
*
908 png_ptr
->screen_gamma
);
912 png_ptr
->background_1
.gray
= (png_uint_16
)(pow(
913 (double)png_ptr
->background
.gray
/ m
, g
) * m
+ .5);
914 png_ptr
->background
.gray
= (png_uint_16
)(pow(
915 (double)png_ptr
->background
.gray
/ m
, gs
) * m
+ .5);
917 if ((png_ptr
->background
.red
!= png_ptr
->background
.green
) ||
918 (png_ptr
->background
.red
!= png_ptr
->background
.blue
) ||
919 (png_ptr
->background
.red
!= png_ptr
->background
.gray
))
921 /* RGB or RGBA with color background */
922 png_ptr
->background_1
.red
= (png_uint_16
)(pow(
923 (double)png_ptr
->background
.red
/ m
, g
) * m
+ .5);
924 png_ptr
->background_1
.green
= (png_uint_16
)(pow(
925 (double)png_ptr
->background
.green
/ m
, g
) * m
+ .5);
926 png_ptr
->background_1
.blue
= (png_uint_16
)(pow(
927 (double)png_ptr
->background
.blue
/ m
, g
) * m
+ .5);
928 png_ptr
->background
.red
= (png_uint_16
)(pow(
929 (double)png_ptr
->background
.red
/ m
, gs
) * m
+ .5);
930 png_ptr
->background
.green
= (png_uint_16
)(pow(
931 (double)png_ptr
->background
.green
/ m
, gs
) * m
+ .5);
932 png_ptr
->background
.blue
= (png_uint_16
)(pow(
933 (double)png_ptr
->background
.blue
/ m
, gs
) * m
+ .5);
937 /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
938 png_ptr
->background_1
.red
= png_ptr
->background_1
.green
939 = png_ptr
->background_1
.blue
= png_ptr
->background_1
.gray
;
940 png_ptr
->background
.red
= png_ptr
->background
.green
941 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
946 /* transformation does not include PNG_BACKGROUND */
947 #endif /* PNG_READ_BACKGROUND_SUPPORTED */
948 if (color_type
== PNG_COLOR_TYPE_PALETTE
)
950 png_colorp palette
= png_ptr
->palette
;
951 int num_palette
= png_ptr
->num_palette
;
954 for (i
= 0; i
< num_palette
; i
++)
956 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
957 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
958 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
962 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
965 #endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */
966 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
967 /* No GAMMA transformation */
968 if ((png_ptr
->transformations
& PNG_BACKGROUND
) &&
969 (color_type
== PNG_COLOR_TYPE_PALETTE
))
972 int istop
= (int)png_ptr
->num_trans
;
974 png_colorp palette
= png_ptr
->palette
;
976 back
.red
= (png_byte
)png_ptr
->background
.red
;
977 back
.green
= (png_byte
)png_ptr
->background
.green
;
978 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
980 for (i
= 0; i
< istop
; i
++)
982 if (png_ptr
->trans
[i
] == 0)
986 else if (png_ptr
->trans
[i
] != 0xff)
988 /* The png_composite() macro is defined in png.h */
989 png_composite(palette
[i
].red
, palette
[i
].red
,
990 png_ptr
->trans
[i
], back
.red
);
991 png_composite(palette
[i
].green
, palette
[i
].green
,
992 png_ptr
->trans
[i
], back
.green
);
993 png_composite(palette
[i
].blue
, palette
[i
].blue
,
994 png_ptr
->trans
[i
], back
.blue
);
998 #endif /* PNG_READ_BACKGROUND_SUPPORTED */
1000 #if defined(PNG_READ_SHIFT_SUPPORTED)
1001 if ((png_ptr
->transformations
& PNG_SHIFT
) &&
1002 (color_type
== PNG_COLOR_TYPE_PALETTE
))
1005 png_uint_16 istop
= png_ptr
->num_palette
;
1006 int sr
= 8 - png_ptr
->sig_bit
.red
;
1007 int sg
= 8 - png_ptr
->sig_bit
.green
;
1008 int sb
= 8 - png_ptr
->sig_bit
.blue
;
1010 if (sr
< 0 || sr
> 8)
1012 if (sg
< 0 || sg
> 8)
1014 if (sb
< 0 || sb
> 8)
1016 for (i
= 0; i
< istop
; i
++)
1018 png_ptr
->palette
[i
].red
>>= sr
;
1019 png_ptr
->palette
[i
].green
>>= sg
;
1020 png_ptr
->palette
[i
].blue
>>= sb
;
1023 #endif /* PNG_READ_SHIFT_SUPPORTED */
1025 #if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
1026 && !defined(PNG_READ_BACKGROUND_SUPPORTED)
1032 /* Modify the info structure to reflect the transformations. The
1033 * info should be updated so a PNG file could be written with it,
1034 * assuming the transformations result in valid PNG data.
1037 png_read_transform_info(png_structp png_ptr
, png_infop info_ptr
)
1039 png_debug(1, "in png_read_transform_info\n");
1040 #if defined(PNG_READ_EXPAND_SUPPORTED)
1041 if (png_ptr
->transformations
& PNG_EXPAND
)
1043 if (info_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1045 if (png_ptr
->num_trans
)
1046 info_ptr
->color_type
= PNG_COLOR_TYPE_RGB_ALPHA
;
1048 info_ptr
->color_type
= PNG_COLOR_TYPE_RGB
;
1049 info_ptr
->bit_depth
= 8;
1050 info_ptr
->num_trans
= 0;
1054 if (png_ptr
->num_trans
)
1055 info_ptr
->color_type
|= PNG_COLOR_MASK_ALPHA
;
1056 if (info_ptr
->bit_depth
< 8)
1057 info_ptr
->bit_depth
= 8;
1058 info_ptr
->num_trans
= 0;
1063 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1064 if (png_ptr
->transformations
& PNG_BACKGROUND
)
1066 info_ptr
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
1067 info_ptr
->num_trans
= 0;
1068 info_ptr
->background
= png_ptr
->background
;
1072 #if defined(PNG_READ_GAMMA_SUPPORTED)
1073 if (png_ptr
->transformations
& PNG_GAMMA
)
1075 #ifdef PNG_FLOATING_POINT_SUPPORTED
1076 info_ptr
->gamma
= png_ptr
->gamma
;
1078 #ifdef PNG_FIXED_POINT_SUPPORTED
1079 info_ptr
->int_gamma
= png_ptr
->int_gamma
;
1084 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1085 if ((png_ptr
->transformations
& PNG_16_TO_8
) && (info_ptr
->bit_depth
== 16))
1086 info_ptr
->bit_depth
= 8;
1089 #if defined(PNG_READ_DITHER_SUPPORTED)
1090 if (png_ptr
->transformations
& PNG_DITHER
)
1092 if (((info_ptr
->color_type
== PNG_COLOR_TYPE_RGB
) ||
1093 (info_ptr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)) &&
1094 png_ptr
->palette_lookup
&& info_ptr
->bit_depth
== 8)
1096 info_ptr
->color_type
= PNG_COLOR_TYPE_PALETTE
;
1101 #if defined(PNG_READ_PACK_SUPPORTED)
1102 if ((png_ptr
->transformations
& PNG_PACK
) && (info_ptr
->bit_depth
< 8))
1103 info_ptr
->bit_depth
= 8;
1106 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1107 if (png_ptr
->transformations
& PNG_GRAY_TO_RGB
)
1108 info_ptr
->color_type
|= PNG_COLOR_MASK_COLOR
;
1111 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1112 if (png_ptr
->transformations
& PNG_RGB_TO_GRAY
)
1113 info_ptr
->color_type
&= ~PNG_COLOR_MASK_COLOR
;
1116 if (info_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1117 info_ptr
->channels
= 1;
1118 else if (info_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
1119 info_ptr
->channels
= 3;
1121 info_ptr
->channels
= 1;
1123 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1124 if (png_ptr
->transformations
& PNG_STRIP_ALPHA
)
1125 info_ptr
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
1128 if (info_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
)
1129 info_ptr
->channels
++;
1131 #if defined(PNG_READ_FILLER_SUPPORTED)
1132 /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
1133 if ((png_ptr
->transformations
& PNG_FILLER
) &&
1134 ((info_ptr
->color_type
== PNG_COLOR_TYPE_RGB
) ||
1135 (info_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)))
1137 info_ptr
->channels
++;
1138 #if 0 /* if adding a true alpha channel not just filler */
1139 info_ptr
->color_type
|= PNG_COLOR_MASK_ALPHA
;
1144 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
1145 defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1146 if(png_ptr
->transformations
& PNG_USER_TRANSFORM
)
1148 if(info_ptr
->bit_depth
< png_ptr
->user_transform_depth
)
1149 info_ptr
->bit_depth
= png_ptr
->user_transform_depth
;
1150 if(info_ptr
->channels
< png_ptr
->user_transform_channels
)
1151 info_ptr
->channels
= png_ptr
->user_transform_channels
;
1155 info_ptr
->pixel_depth
= (png_byte
)(info_ptr
->channels
*
1156 info_ptr
->bit_depth
);
1158 info_ptr
->rowbytes
= PNG_ROWBYTES(info_ptr
->pixel_depth
,info_ptr
->width
);
1160 #if !defined(PNG_READ_EXPAND_SUPPORTED)
1166 /* Transform the row. The order of transformations is significant,
1167 * and is very touchy. If you add a transformation, take care to
1168 * decide how it fits in with the other transformations here.
1171 png_do_read_transformations(png_structp png_ptr
)
1173 png_debug(1, "in png_do_read_transformations\n");
1174 #if !defined(PNG_USELESS_TESTS_SUPPORTED)
1175 if (png_ptr
->row_buf
== NULL
)
1177 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
1180 sprintf(msg
, "NULL row buffer for row %ld, pass %d", png_ptr
->row_number
,
1182 png_error(png_ptr
, msg
);
1184 png_error(png_ptr
, "NULL row buffer");
1189 #if defined(PNG_READ_EXPAND_SUPPORTED)
1190 if (png_ptr
->transformations
& PNG_EXPAND
)
1192 if (png_ptr
->row_info
.color_type
== PNG_COLOR_TYPE_PALETTE
)
1194 png_do_expand_palette(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1195 png_ptr
->palette
, png_ptr
->trans
, png_ptr
->num_trans
);
1199 if (png_ptr
->num_trans
)
1200 png_do_expand(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1201 &(png_ptr
->trans_values
));
1203 png_do_expand(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1209 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1210 if (png_ptr
->transformations
& PNG_STRIP_ALPHA
)
1211 png_do_strip_filler(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1212 PNG_FLAG_FILLER_AFTER
);
1215 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1216 if (png_ptr
->transformations
& PNG_RGB_TO_GRAY
)
1219 png_do_rgb_to_gray(png_ptr
, &(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1222 png_ptr
->rgb_to_gray_status
=1;
1223 if(png_ptr
->transformations
== PNG_RGB_TO_GRAY_WARN
)
1224 png_warning(png_ptr
, "png_do_rgb_to_gray found nongray pixel");
1225 if(png_ptr
->transformations
== PNG_RGB_TO_GRAY_ERR
)
1226 png_error(png_ptr
, "png_do_rgb_to_gray found nongray pixel");
1232 From Andreas Dilger e-mail to png-implement, 26 March 1998:
1234 In most cases, the "simple transparency" should be done prior to doing
1235 gray-to-RGB, or you will have to test 3x as many bytes to check if a
1236 pixel is transparent. You would also need to make sure that the
1237 transparency information is upgraded to RGB.
1239 To summarize, the current flow is:
1240 - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
1241 with background "in place" if transparent,
1242 convert to RGB if necessary
1243 - Gray + alpha -> composite with gray background and remove alpha bytes,
1244 convert to RGB if necessary
1246 To support RGB backgrounds for gray images we need:
1247 - Gray + simple transparency -> convert to RGB + simple transparency, compare
1248 3 or 6 bytes and composite with background
1249 "in place" if transparent (3x compare/pixel
1250 compared to doing composite with gray bkgrnd)
1251 - Gray + alpha -> convert to RGB + alpha, composite with background and
1252 remove alpha bytes (3x float operations/pixel
1253 compared with composite on gray background)
1255 Greg's change will do this. The reason it wasn't done before is for
1256 performance, as this increases the per-pixel operations. If we would check
1257 in advance if the background was gray or RGB, and position the gray-to-RGB
1258 transform appropriately, then it would save a lot of work/time.
1261 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1262 /* if gray -> RGB, do so now only if background is non-gray; else do later
1263 * for performance reasons */
1264 if ((png_ptr
->transformations
& PNG_GRAY_TO_RGB
) &&
1265 !(png_ptr
->mode
& PNG_BACKGROUND_IS_GRAY
))
1266 png_do_gray_to_rgb(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1269 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1270 if ((png_ptr
->transformations
& PNG_BACKGROUND
) &&
1271 ((png_ptr
->num_trans
!= 0 ) ||
1272 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
)))
1273 png_do_background(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1274 &(png_ptr
->trans_values
), &(png_ptr
->background
)
1275 #if defined(PNG_READ_GAMMA_SUPPORTED)
1276 , &(png_ptr
->background_1
),
1277 png_ptr
->gamma_table
, png_ptr
->gamma_from_1
,
1278 png_ptr
->gamma_to_1
, png_ptr
->gamma_16_table
,
1279 png_ptr
->gamma_16_from_1
, png_ptr
->gamma_16_to_1
,
1280 png_ptr
->gamma_shift
1285 #if defined(PNG_READ_GAMMA_SUPPORTED)
1286 if ((png_ptr
->transformations
& PNG_GAMMA
) &&
1287 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1288 !((png_ptr
->transformations
& PNG_BACKGROUND
) &&
1289 ((png_ptr
->num_trans
!= 0) ||
1290 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
))) &&
1292 (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
))
1293 png_do_gamma(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1294 png_ptr
->gamma_table
, png_ptr
->gamma_16_table
,
1295 png_ptr
->gamma_shift
);
1298 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1299 if (png_ptr
->transformations
& PNG_16_TO_8
)
1300 png_do_chop(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1303 #if defined(PNG_READ_DITHER_SUPPORTED)
1304 if (png_ptr
->transformations
& PNG_DITHER
)
1306 png_do_dither((png_row_infop
)&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1307 png_ptr
->palette_lookup
, png_ptr
->dither_index
);
1308 if(png_ptr
->row_info
.rowbytes
== (png_uint_32
)0)
1309 png_error(png_ptr
, "png_do_dither returned rowbytes=0");
1313 #if defined(PNG_READ_INVERT_SUPPORTED)
1314 if (png_ptr
->transformations
& PNG_INVERT_MONO
)
1315 png_do_invert(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1318 #if defined(PNG_READ_SHIFT_SUPPORTED)
1319 if (png_ptr
->transformations
& PNG_SHIFT
)
1320 png_do_unshift(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1324 #if defined(PNG_READ_PACK_SUPPORTED)
1325 if (png_ptr
->transformations
& PNG_PACK
)
1326 png_do_unpack(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1329 #if defined(PNG_READ_BGR_SUPPORTED)
1330 if (png_ptr
->transformations
& PNG_BGR
)
1331 png_do_bgr(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1334 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1335 if (png_ptr
->transformations
& PNG_PACKSWAP
)
1336 png_do_packswap(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1339 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1340 /* if gray -> RGB, do so now only if we did not do so above */
1341 if ((png_ptr
->transformations
& PNG_GRAY_TO_RGB
) &&
1342 (png_ptr
->mode
& PNG_BACKGROUND_IS_GRAY
))
1343 png_do_gray_to_rgb(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1346 #if defined(PNG_READ_FILLER_SUPPORTED)
1347 if (png_ptr
->transformations
& PNG_FILLER
)
1348 png_do_read_filler(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1349 (png_uint_32
)png_ptr
->filler
, png_ptr
->flags
);
1352 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1353 if (png_ptr
->transformations
& PNG_INVERT_ALPHA
)
1354 png_do_read_invert_alpha(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1357 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1358 if (png_ptr
->transformations
& PNG_SWAP_ALPHA
)
1359 png_do_read_swap_alpha(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1362 #if defined(PNG_READ_SWAP_SUPPORTED)
1363 if (png_ptr
->transformations
& PNG_SWAP_BYTES
)
1364 png_do_swap(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1367 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1368 if (png_ptr
->transformations
& PNG_USER_TRANSFORM
)
1370 if(png_ptr
->read_user_transform_fn
!= NULL
)
1371 (*(png_ptr
->read_user_transform_fn
)) /* user read transform function */
1372 (png_ptr
, /* png_ptr */
1373 &(png_ptr
->row_info
), /* row_info: */
1374 /* png_uint_32 width; width of row */
1375 /* png_uint_32 rowbytes; number of bytes in row */
1376 /* png_byte color_type; color type of pixels */
1377 /* png_byte bit_depth; bit depth of samples */
1378 /* png_byte channels; number of channels (1-4) */
1379 /* png_byte pixel_depth; bits per pixel (depth*channels) */
1380 png_ptr
->row_buf
+ 1); /* start of pixel data for row */
1381 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
1382 if(png_ptr
->user_transform_depth
)
1383 png_ptr
->row_info
.bit_depth
= png_ptr
->user_transform_depth
;
1384 if(png_ptr
->user_transform_channels
)
1385 png_ptr
->row_info
.channels
= png_ptr
->user_transform_channels
;
1387 png_ptr
->row_info
.pixel_depth
= (png_byte
)(png_ptr
->row_info
.bit_depth
*
1388 png_ptr
->row_info
.channels
);
1389 png_ptr
->row_info
.rowbytes
= PNG_ROWBYTES(png_ptr
->row_info
.pixel_depth
,
1390 png_ptr
->row_info
.width
);
1396 #if defined(PNG_READ_PACK_SUPPORTED)
1397 /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
1398 * without changing the actual values. Thus, if you had a row with
1399 * a bit depth of 1, you would end up with bytes that only contained
1400 * the numbers 0 or 1. If you would rather they contain 0 and 255, use
1401 * png_do_shift() after this.
1404 png_do_unpack(png_row_infop row_info
, png_bytep row
)
1406 png_debug(1, "in png_do_unpack\n");
1407 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1408 if (row
!= NULL
&& row_info
!= NULL
&& row_info
->bit_depth
< 8)
1410 if (row_info
->bit_depth
< 8)
1414 png_uint_32 row_width
=row_info
->width
;
1416 switch (row_info
->bit_depth
)
1420 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
1421 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1422 png_uint_32 shift
= 7 - (int)((row_width
+ 7) & 0x07);
1423 for (i
= 0; i
< row_width
; i
++)
1425 *dp
= (png_byte
)((*sp
>> shift
) & 0x01);
1441 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
1442 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1443 png_uint_32 shift
= (int)((3 - ((row_width
+ 3) & 0x03)) << 1);
1444 for (i
= 0; i
< row_width
; i
++)
1446 *dp
= (png_byte
)((*sp
>> shift
) & 0x03);
1461 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
1462 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1463 png_uint_32 shift
= (int)((1 - ((row_width
+ 1) & 0x01)) << 2);
1464 for (i
= 0; i
< row_width
; i
++)
1466 *dp
= (png_byte
)((*sp
>> shift
) & 0x0f);
1480 row_info
->bit_depth
= 8;
1481 row_info
->pixel_depth
= (png_byte
)(8 * row_info
->channels
);
1482 row_info
->rowbytes
= row_width
* row_info
->channels
;
1487 #if defined(PNG_READ_SHIFT_SUPPORTED)
1488 /* Reverse the effects of png_do_shift. This routine merely shifts the
1489 * pixels back to their significant bits values. Thus, if you have
1490 * a row of bit depth 8, but only 5 are significant, this will shift
1491 * the values back to 0 through 31.
1494 png_do_unshift(png_row_infop row_info
, png_bytep row
, png_color_8p sig_bits
)
1496 png_debug(1, "in png_do_unshift\n");
1498 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1499 row
!= NULL
&& row_info
!= NULL
&& sig_bits
!= NULL
&&
1501 row_info
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
1506 png_uint_16 value
= 0;
1507 png_uint_32 row_width
= row_info
->width
;
1509 if (row_info
->color_type
& PNG_COLOR_MASK_COLOR
)
1511 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->red
;
1512 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->green
;
1513 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->blue
;
1517 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->gray
;
1519 if (row_info
->color_type
& PNG_COLOR_MASK_ALPHA
)
1521 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->alpha
;
1524 for (c
= 0; c
< channels
; c
++)
1535 switch (row_info
->bit_depth
)
1541 png_uint_32 istop
= row_info
->rowbytes
;
1543 for (bp
= row
, i
= 0; i
< istop
; i
++)
1554 png_uint_32 istop
= row_info
->rowbytes
;
1555 png_byte mask
= (png_byte
)((((int)0xf0 >> shift
[0]) & (int)0xf0) |
1556 (png_byte
)((int)0xf >> shift
[0]));
1558 for (i
= 0; i
< istop
; i
++)
1569 png_uint_32 istop
= row_width
* channels
;
1571 for (i
= 0; i
< istop
; i
++)
1573 *bp
++ >>= shift
[i%channels
];
1581 png_uint_32 istop
= channels
* row_width
;
1583 for (i
= 0; i
< istop
; i
++)
1585 value
= (png_uint_16
)((*bp
<< 8) + *(bp
+ 1));
1586 value
>>= shift
[i%channels
];
1587 *bp
++ = (png_byte
)(value
>> 8);
1588 *bp
++ = (png_byte
)(value
& 0xff);
1597 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1598 /* chop rows of bit depth 16 down to 8 */
1600 png_do_chop(png_row_infop row_info
, png_bytep row
)
1602 png_debug(1, "in png_do_chop\n");
1603 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1604 if (row
!= NULL
&& row_info
!= NULL
&& row_info
->bit_depth
== 16)
1606 if (row_info
->bit_depth
== 16)
1612 png_uint_32 istop
= row_info
->width
* row_info
->channels
;
1614 for (i
= 0; i
<istop
; i
++, sp
+= 2, dp
++)
1616 #if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
1617 /* This does a more accurate scaling of the 16-bit color
1618 * value, rather than a simple low-byte truncation.
1620 * What the ideal calculation should be:
1621 * *dp = (((((png_uint_32)(*sp) << 8) |
1622 * (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L;
1624 * GRR: no, I think this is what it really should be:
1625 * *dp = (((((png_uint_32)(*sp) << 8) |
1626 * (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L;
1628 * GRR: here's the exact calculation with shifts:
1629 * temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L;
1630 * *dp = (temp - (temp >> 8)) >> 8;
1632 * Approximate calculation with shift/add instead of multiply/divide:
1633 * *dp = ((((png_uint_32)(*sp) << 8) |
1634 * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
1636 * What we actually do to avoid extra shifting and conversion:
1639 *dp
= *sp
+ ((((int)(*(sp
+ 1)) - *sp
) > 128) ? 1 : 0);
1641 /* Simply discard the low order byte */
1645 row_info
->bit_depth
= 8;
1646 row_info
->pixel_depth
= (png_byte
)(8 * row_info
->channels
);
1647 row_info
->rowbytes
= row_info
->width
* row_info
->channels
;
1652 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1654 png_do_read_swap_alpha(png_row_infop row_info
, png_bytep row
)
1656 png_debug(1, "in png_do_read_swap_alpha\n");
1657 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1658 if (row
!= NULL
&& row_info
!= NULL
)
1661 png_uint_32 row_width
= row_info
->width
;
1662 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
1664 /* This converts from RGBA to ARGB */
1665 if (row_info
->bit_depth
== 8)
1667 png_bytep sp
= row
+ row_info
->rowbytes
;
1672 for (i
= 0; i
< row_width
; i
++)
1681 /* This converts from RRGGBBAA to AARRGGBB */
1684 png_bytep sp
= row
+ row_info
->rowbytes
;
1689 for (i
= 0; i
< row_width
; i
++)
1704 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
1706 /* This converts from GA to AG */
1707 if (row_info
->bit_depth
== 8)
1709 png_bytep sp
= row
+ row_info
->rowbytes
;
1714 for (i
= 0; i
< row_width
; i
++)
1721 /* This converts from GGAA to AAGG */
1724 png_bytep sp
= row
+ row_info
->rowbytes
;
1729 for (i
= 0; i
< row_width
; i
++)
1744 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1746 png_do_read_invert_alpha(png_row_infop row_info
, png_bytep row
)
1748 png_debug(1, "in png_do_read_invert_alpha\n");
1749 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1750 if (row
!= NULL
&& row_info
!= NULL
)
1753 png_uint_32 row_width
= row_info
->width
;
1754 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
1756 /* This inverts the alpha channel in RGBA */
1757 if (row_info
->bit_depth
== 8)
1759 png_bytep sp
= row
+ row_info
->rowbytes
;
1763 for (i
= 0; i
< row_width
; i
++)
1765 *(--dp
) = (png_byte
)(255 - *(--sp
));
1767 /* This does nothing:
1771 We can replace it with:
1777 /* This inverts the alpha channel in RRGGBBAA */
1780 png_bytep sp
= row
+ row_info
->rowbytes
;
1784 for (i
= 0; i
< row_width
; i
++)
1786 *(--dp
) = (png_byte
)(255 - *(--sp
));
1787 *(--dp
) = (png_byte
)(255 - *(--sp
));
1789 /* This does nothing:
1796 We can replace it with:
1803 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
1805 /* This inverts the alpha channel in GA */
1806 if (row_info
->bit_depth
== 8)
1808 png_bytep sp
= row
+ row_info
->rowbytes
;
1812 for (i
= 0; i
< row_width
; i
++)
1814 *(--dp
) = (png_byte
)(255 - *(--sp
));
1818 /* This inverts the alpha channel in GGAA */
1821 png_bytep sp
= row
+ row_info
->rowbytes
;
1825 for (i
= 0; i
< row_width
; i
++)
1827 *(--dp
) = (png_byte
)(255 - *(--sp
));
1828 *(--dp
) = (png_byte
)(255 - *(--sp
));
1842 #if defined(PNG_READ_FILLER_SUPPORTED)
1843 /* Add filler channel if we have RGB color */
1845 png_do_read_filler(png_row_infop row_info
, png_bytep row
,
1846 png_uint_32 filler
, png_uint_32 flags
)
1849 png_uint_32 row_width
= row_info
->width
;
1851 png_byte hi_filler
= (png_byte
)((filler
>>8) & 0xff);
1852 png_byte lo_filler
= (png_byte
)(filler
& 0xff);
1854 png_debug(1, "in png_do_read_filler\n");
1856 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1857 row
!= NULL
&& row_info
!= NULL
&&
1859 row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
1861 if(row_info
->bit_depth
== 8)
1863 /* This changes the data from G to GX */
1864 if (flags
& PNG_FLAG_FILLER_AFTER
)
1866 png_bytep sp
= row
+ (png_size_t
)row_width
;
1867 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1868 for (i
= 1; i
< row_width
; i
++)
1870 *(--dp
) = lo_filler
;
1873 *(--dp
) = lo_filler
;
1874 row_info
->channels
= 2;
1875 row_info
->pixel_depth
= 16;
1876 row_info
->rowbytes
= row_width
* 2;
1878 /* This changes the data from G to XG */
1881 png_bytep sp
= row
+ (png_size_t
)row_width
;
1882 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1883 for (i
= 0; i
< row_width
; i
++)
1886 *(--dp
) = lo_filler
;
1888 row_info
->channels
= 2;
1889 row_info
->pixel_depth
= 16;
1890 row_info
->rowbytes
= row_width
* 2;
1893 else if(row_info
->bit_depth
== 16)
1895 /* This changes the data from GG to GGXX */
1896 if (flags
& PNG_FLAG_FILLER_AFTER
)
1898 png_bytep sp
= row
+ (png_size_t
)row_width
* 2;
1899 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
1900 for (i
= 1; i
< row_width
; i
++)
1902 *(--dp
) = hi_filler
;
1903 *(--dp
) = lo_filler
;
1907 *(--dp
) = hi_filler
;
1908 *(--dp
) = lo_filler
;
1909 row_info
->channels
= 2;
1910 row_info
->pixel_depth
= 32;
1911 row_info
->rowbytes
= row_width
* 4;
1913 /* This changes the data from GG to XXGG */
1916 png_bytep sp
= row
+ (png_size_t
)row_width
* 2;
1917 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
1918 for (i
= 0; i
< row_width
; i
++)
1922 *(--dp
) = hi_filler
;
1923 *(--dp
) = lo_filler
;
1925 row_info
->channels
= 2;
1926 row_info
->pixel_depth
= 32;
1927 row_info
->rowbytes
= row_width
* 4;
1930 row_info
->color_type
|= PNG_COLOR_MASK_ALPHA
;
1931 } /* COLOR_TYPE == GRAY */
1932 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
1934 if(row_info
->bit_depth
== 8)
1936 /* This changes the data from RGB to RGBX */
1937 if (flags
& PNG_FLAG_FILLER_AFTER
)
1939 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
1940 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1941 for (i
= 1; i
< row_width
; i
++)
1943 *(--dp
) = lo_filler
;
1948 *(--dp
) = lo_filler
;
1949 row_info
->channels
= 4;
1950 row_info
->pixel_depth
= 32;
1951 row_info
->rowbytes
= row_width
* 4;
1953 /* This changes the data from RGB to XRGB */
1956 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
1957 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1958 for (i
= 0; i
< row_width
; i
++)
1963 *(--dp
) = lo_filler
;
1965 row_info
->channels
= 4;
1966 row_info
->pixel_depth
= 32;
1967 row_info
->rowbytes
= row_width
* 4;
1970 else if(row_info
->bit_depth
== 16)
1972 /* This changes the data from RRGGBB to RRGGBBXX */
1973 if (flags
& PNG_FLAG_FILLER_AFTER
)
1975 png_bytep sp
= row
+ (png_size_t
)row_width
* 6;
1976 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
1977 for (i
= 1; i
< row_width
; i
++)
1979 *(--dp
) = hi_filler
;
1980 *(--dp
) = lo_filler
;
1988 *(--dp
) = hi_filler
;
1989 *(--dp
) = lo_filler
;
1990 row_info
->channels
= 4;
1991 row_info
->pixel_depth
= 64;
1992 row_info
->rowbytes
= row_width
* 8;
1994 /* This changes the data from RRGGBB to XXRRGGBB */
1997 png_bytep sp
= row
+ (png_size_t
)row_width
* 6;
1998 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
1999 for (i
= 0; i
< row_width
; i
++)
2007 *(--dp
) = hi_filler
;
2008 *(--dp
) = lo_filler
;
2010 row_info
->channels
= 4;
2011 row_info
->pixel_depth
= 64;
2012 row_info
->rowbytes
= row_width
* 8;
2015 row_info
->color_type
|= PNG_COLOR_MASK_ALPHA
;
2016 } /* COLOR_TYPE == RGB */
2020 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
2021 /* expand grayscale files to RGB, with or without alpha */
2023 png_do_gray_to_rgb(png_row_infop row_info
, png_bytep row
)
2026 png_uint_32 row_width
= row_info
->width
;
2028 png_debug(1, "in png_do_gray_to_rgb\n");
2029 if (row_info
->bit_depth
>= 8 &&
2030 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2031 row
!= NULL
&& row_info
!= NULL
&&
2033 !(row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
2035 if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
2037 if (row_info
->bit_depth
== 8)
2039 png_bytep sp
= row
+ (png_size_t
)row_width
- 1;
2040 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2041 for (i
= 0; i
< row_width
; i
++)
2050 png_bytep sp
= row
+ (png_size_t
)row_width
* 2 - 1;
2051 png_bytep dp
= sp
+ (png_size_t
)row_width
* 4;
2052 for (i
= 0; i
< row_width
; i
++)
2055 *(dp
--) = *(sp
- 1);
2057 *(dp
--) = *(sp
- 1);
2063 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
2065 if (row_info
->bit_depth
== 8)
2067 png_bytep sp
= row
+ (png_size_t
)row_width
* 2 - 1;
2068 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2069 for (i
= 0; i
< row_width
; i
++)
2079 png_bytep sp
= row
+ (png_size_t
)row_width
* 4 - 1;
2080 png_bytep dp
= sp
+ (png_size_t
)row_width
* 4;
2081 for (i
= 0; i
< row_width
; i
++)
2086 *(dp
--) = *(sp
- 1);
2088 *(dp
--) = *(sp
- 1);
2094 row_info
->channels
+= (png_byte
)2;
2095 row_info
->color_type
|= PNG_COLOR_MASK_COLOR
;
2096 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
2097 row_info
->bit_depth
);
2098 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
,row_width
);
2103 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
2104 /* reduce RGB files to grayscale, with or without alpha
2105 * using the equation given in Poynton's ColorFAQ at
2106 * <http://www.inforamp.net/~poynton/>
2107 * Copyright (c) 1998-01-04 Charles Poynton poynton@inforamp.net
2109 * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
2111 * We approximate this with
2113 * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B
2115 * which can be expressed with integers as
2117 * Y = (6969 * R + 23434 * G + 2365 * B)/32768
2119 * The calculation is to be done in a linear colorspace.
2121 * Other integer coefficents can be used via png_set_rgb_to_gray().
2124 png_do_rgb_to_gray(png_structp png_ptr
, png_row_infop row_info
, png_bytep row
)
2129 png_uint_32 row_width
= row_info
->width
;
2132 png_debug(1, "in png_do_rgb_to_gray\n");
2134 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2135 row
!= NULL
&& row_info
!= NULL
&&
2137 (row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
2139 png_uint_32 rc
= png_ptr
->rgb_to_gray_red_coeff
;
2140 png_uint_32 gc
= png_ptr
->rgb_to_gray_green_coeff
;
2141 png_uint_32 bc
= png_ptr
->rgb_to_gray_blue_coeff
;
2143 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
2145 if (row_info
->bit_depth
== 8)
2147 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2148 if (png_ptr
->gamma_from_1
!= NULL
&& png_ptr
->gamma_to_1
!= NULL
)
2153 for (i
= 0; i
< row_width
; i
++)
2155 png_byte red
= png_ptr
->gamma_to_1
[*(sp
++)];
2156 png_byte green
= png_ptr
->gamma_to_1
[*(sp
++)];
2157 png_byte blue
= png_ptr
->gamma_to_1
[*(sp
++)];
2158 if(red
!= green
|| red
!= blue
)
2161 *(dp
++) = png_ptr
->gamma_from_1
[
2162 (rc
*red
+gc
*green
+bc
*blue
)>>15];
2173 for (i
= 0; i
< row_width
; i
++)
2175 png_byte red
= *(sp
++);
2176 png_byte green
= *(sp
++);
2177 png_byte blue
= *(sp
++);
2178 if(red
!= green
|| red
!= blue
)
2181 *(dp
++) = (png_byte
)((rc
*red
+gc
*green
+bc
*blue
)>>15);
2189 else /* RGB bit_depth == 16 */
2191 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2192 if (png_ptr
->gamma_16_to_1
!= NULL
&&
2193 png_ptr
->gamma_16_from_1
!= NULL
)
2197 for (i
= 0; i
< row_width
; i
++)
2199 png_uint_16 red
, green
, blue
, w
;
2201 red
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2202 green
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2203 blue
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2205 if(red
== green
&& red
== blue
)
2209 png_uint_16 red_1
= png_ptr
->gamma_16_to_1
[(red
&0xff) >>
2210 png_ptr
->gamma_shift
][red
>>8];
2211 png_uint_16 green_1
= png_ptr
->gamma_16_to_1
[(green
&0xff) >>
2212 png_ptr
->gamma_shift
][green
>>8];
2213 png_uint_16 blue_1
= png_ptr
->gamma_16_to_1
[(blue
&0xff) >>
2214 png_ptr
->gamma_shift
][blue
>>8];
2215 png_uint_16 gray16
= (png_uint_16
)((rc
*red_1
+ gc
*green_1
2217 w
= png_ptr
->gamma_16_from_1
[(gray16
&0xff) >>
2218 png_ptr
->gamma_shift
][gray16
>> 8];
2222 *(dp
++) = (png_byte
)((w
>>8) & 0xff);
2223 *(dp
++) = (png_byte
)(w
& 0xff);
2231 for (i
= 0; i
< row_width
; i
++)
2233 png_uint_16 red
, green
, blue
, gray16
;
2235 red
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2236 green
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2237 blue
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2239 if(red
!= green
|| red
!= blue
)
2241 gray16
= (png_uint_16
)((rc
*red
+ gc
*green
+ bc
*blue
)>>15);
2242 *(dp
++) = (png_byte
)((gray16
>>8) & 0xff);
2243 *(dp
++) = (png_byte
)(gray16
& 0xff);
2248 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
2250 if (row_info
->bit_depth
== 8)
2252 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2253 if (png_ptr
->gamma_from_1
!= NULL
&& png_ptr
->gamma_to_1
!= NULL
)
2257 for (i
= 0; i
< row_width
; i
++)
2259 png_byte red
= png_ptr
->gamma_to_1
[*(sp
++)];
2260 png_byte green
= png_ptr
->gamma_to_1
[*(sp
++)];
2261 png_byte blue
= png_ptr
->gamma_to_1
[*(sp
++)];
2262 if(red
!= green
|| red
!= blue
)
2264 *(dp
++) = png_ptr
->gamma_from_1
2265 [(rc
*red
+ gc
*green
+ bc
*blue
)>>15];
2266 *(dp
++) = *(sp
++); /* alpha */
2274 for (i
= 0; i
< row_width
; i
++)
2276 png_byte red
= *(sp
++);
2277 png_byte green
= *(sp
++);
2278 png_byte blue
= *(sp
++);
2279 if(red
!= green
|| red
!= blue
)
2281 *(dp
++) = (png_byte
)((rc
*red
+ gc
*green
+ bc
*blue
)>>15);
2282 *(dp
++) = *(sp
++); /* alpha */
2286 else /* RGBA bit_depth == 16 */
2288 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2289 if (png_ptr
->gamma_16_to_1
!= NULL
&&
2290 png_ptr
->gamma_16_from_1
!= NULL
)
2294 for (i
= 0; i
< row_width
; i
++)
2296 png_uint_16 red
, green
, blue
, w
;
2298 red
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2299 green
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2300 blue
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2302 if(red
== green
&& red
== blue
)
2306 png_uint_16 red_1
= png_ptr
->gamma_16_to_1
[(red
&0xff) >>
2307 png_ptr
->gamma_shift
][red
>>8];
2308 png_uint_16 green_1
= png_ptr
->gamma_16_to_1
[(green
&0xff) >>
2309 png_ptr
->gamma_shift
][green
>>8];
2310 png_uint_16 blue_1
= png_ptr
->gamma_16_to_1
[(blue
&0xff) >>
2311 png_ptr
->gamma_shift
][blue
>>8];
2312 png_uint_16 gray16
= (png_uint_16
)((rc
* red_1
2313 + gc
* green_1
+ bc
* blue_1
)>>15);
2314 w
= png_ptr
->gamma_16_from_1
[(gray16
&0xff) >>
2315 png_ptr
->gamma_shift
][gray16
>> 8];
2319 *(dp
++) = (png_byte
)((w
>>8) & 0xff);
2320 *(dp
++) = (png_byte
)(w
& 0xff);
2321 *(dp
++) = *(sp
++); /* alpha */
2330 for (i
= 0; i
< row_width
; i
++)
2332 png_uint_16 red
, green
, blue
, gray16
;
2333 red
= (png_uint_16
)((*(sp
)<<8) | *(sp
+1)); sp
+=2;
2334 green
= (png_uint_16
)((*(sp
)<<8) | *(sp
+1)); sp
+=2;
2335 blue
= (png_uint_16
)((*(sp
)<<8) | *(sp
+1)); sp
+=2;
2336 if(red
!= green
|| red
!= blue
)
2338 gray16
= (png_uint_16
)((rc
*red
+ gc
*green
+ bc
*blue
)>>15);
2339 *(dp
++) = (png_byte
)((gray16
>>8) & 0xff);
2340 *(dp
++) = (png_byte
)(gray16
& 0xff);
2341 *(dp
++) = *(sp
++); /* alpha */
2347 row_info
->channels
-= (png_byte
)2;
2348 row_info
->color_type
&= ~PNG_COLOR_MASK_COLOR
;
2349 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
2350 row_info
->bit_depth
);
2351 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
,row_width
);
2357 /* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
2358 * large of png_color. This lets grayscale images be treated as
2359 * paletted. Most useful for gamma correction and simplification
2363 png_build_grayscale_palette(int bit_depth
, png_colorp palette
)
2370 png_debug(1, "in png_do_build_grayscale_palette\n");
2371 if (palette
== NULL
)
2398 for (i
= 0, v
= 0; i
< num_palette
; i
++, v
+= color_inc
)
2400 palette
[i
].red
= (png_byte
)v
;
2401 palette
[i
].green
= (png_byte
)v
;
2402 palette
[i
].blue
= (png_byte
)v
;
2406 /* This function is currently unused. Do we really need it? */
2407 #if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
2409 png_correct_palette(png_structp png_ptr
, png_colorp palette
,
2412 png_debug(1, "in png_correct_palette\n");
2413 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
2414 defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
2415 if (png_ptr
->transformations
& (PNG_GAMMA
| PNG_BACKGROUND
))
2417 png_color back
, back_1
;
2419 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_FILE
)
2421 back
.red
= png_ptr
->gamma_table
[png_ptr
->background
.red
];
2422 back
.green
= png_ptr
->gamma_table
[png_ptr
->background
.green
];
2423 back
.blue
= png_ptr
->gamma_table
[png_ptr
->background
.blue
];
2425 back_1
.red
= png_ptr
->gamma_to_1
[png_ptr
->background
.red
];
2426 back_1
.green
= png_ptr
->gamma_to_1
[png_ptr
->background
.green
];
2427 back_1
.blue
= png_ptr
->gamma_to_1
[png_ptr
->background
.blue
];
2433 g
= 1.0 / (png_ptr
->background_gamma
* png_ptr
->screen_gamma
);
2435 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_SCREEN
||
2436 fabs(g
- 1.0) < PNG_GAMMA_THRESHOLD
)
2438 back
.red
= png_ptr
->background
.red
;
2439 back
.green
= png_ptr
->background
.green
;
2440 back
.blue
= png_ptr
->background
.blue
;
2445 (png_byte
)(pow((double)png_ptr
->background
.red
/255, g
) *
2448 (png_byte
)(pow((double)png_ptr
->background
.green
/255, g
) *
2451 (png_byte
)(pow((double)png_ptr
->background
.blue
/255, g
) *
2455 g
= 1.0 / png_ptr
->background_gamma
;
2458 (png_byte
)(pow((double)png_ptr
->background
.red
/255, g
) *
2461 (png_byte
)(pow((double)png_ptr
->background
.green
/255, g
) *
2464 (png_byte
)(pow((double)png_ptr
->background
.blue
/255, g
) *
2468 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
2472 for (i
= 0; i
< (png_uint_32
)num_palette
; i
++)
2474 if (i
< png_ptr
->num_trans
&& png_ptr
->trans
[i
] == 0)
2478 else if (i
< png_ptr
->num_trans
&& png_ptr
->trans
[i
] != 0xff)
2482 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].red
];
2483 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.red
);
2484 palette
[i
].red
= png_ptr
->gamma_from_1
[w
];
2486 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].green
];
2487 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.green
);
2488 palette
[i
].green
= png_ptr
->gamma_from_1
[w
];
2490 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].blue
];
2491 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.blue
);
2492 palette
[i
].blue
= png_ptr
->gamma_from_1
[w
];
2496 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2497 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2498 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2506 for (i
= 0; i
< num_palette
; i
++)
2508 if (palette
[i
].red
== (png_byte
)png_ptr
->trans_values
.gray
)
2514 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2515 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2516 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2523 #if defined(PNG_READ_GAMMA_SUPPORTED)
2524 if (png_ptr
->transformations
& PNG_GAMMA
)
2528 for (i
= 0; i
< num_palette
; i
++)
2530 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2531 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2532 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2535 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2539 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2540 if (png_ptr
->transformations
& PNG_BACKGROUND
)
2542 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
2546 back
.red
= (png_byte
)png_ptr
->background
.red
;
2547 back
.green
= (png_byte
)png_ptr
->background
.green
;
2548 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
2550 for (i
= 0; i
< (int)png_ptr
->num_trans
; i
++)
2552 if (png_ptr
->trans
[i
] == 0)
2554 palette
[i
].red
= back
.red
;
2555 palette
[i
].green
= back
.green
;
2556 palette
[i
].blue
= back
.blue
;
2558 else if (png_ptr
->trans
[i
] != 0xff)
2560 png_composite(palette
[i
].red
, png_ptr
->palette
[i
].red
,
2561 png_ptr
->trans
[i
], back
.red
);
2562 png_composite(palette
[i
].green
, png_ptr
->palette
[i
].green
,
2563 png_ptr
->trans
[i
], back
.green
);
2564 png_composite(palette
[i
].blue
, png_ptr
->palette
[i
].blue
,
2565 png_ptr
->trans
[i
], back
.blue
);
2569 else /* assume grayscale palette (what else could it be?) */
2573 for (i
= 0; i
< num_palette
; i
++)
2575 if (i
== (png_byte
)png_ptr
->trans_values
.gray
)
2577 palette
[i
].red
= (png_byte
)png_ptr
->background
.red
;
2578 palette
[i
].green
= (png_byte
)png_ptr
->background
.green
;
2579 palette
[i
].blue
= (png_byte
)png_ptr
->background
.blue
;
2588 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2589 /* Replace any alpha or transparency with the supplied background color.
2590 * "background" is already in the screen gamma, while "background_1" is
2591 * at a gamma of 1.0. Paletted files have already been taken care of.
2594 png_do_background(png_row_infop row_info
, png_bytep row
,
2595 png_color_16p trans_values
, png_color_16p background
2596 #if defined(PNG_READ_GAMMA_SUPPORTED)
2597 , png_color_16p background_1
,
2598 png_bytep gamma_table
, png_bytep gamma_from_1
, png_bytep gamma_to_1
,
2599 png_uint_16pp gamma_16
, png_uint_16pp gamma_16_from_1
,
2600 png_uint_16pp gamma_16_to_1
, int gamma_shift
2606 png_uint_32 row_width
=row_info
->width
;
2609 png_debug(1, "in png_do_background\n");
2610 if (background
!= NULL
&&
2611 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2612 row
!= NULL
&& row_info
!= NULL
&&
2614 (!(row_info
->color_type
& PNG_COLOR_MASK_ALPHA
) ||
2615 (row_info
->color_type
!= PNG_COLOR_TYPE_PALETTE
&& trans_values
)))
2617 switch (row_info
->color_type
)
2619 case PNG_COLOR_TYPE_GRAY
:
2621 switch (row_info
->bit_depth
)
2627 for (i
= 0; i
< row_width
; i
++)
2629 if ((png_uint_16
)((*sp
>> shift
) & 0x01)
2630 == trans_values
->gray
)
2632 *sp
&= (png_byte
)((0x7f7f >> (7 - shift
)) & 0xff);
2633 *sp
|= (png_byte
)(background
->gray
<< shift
);
2647 #if defined(PNG_READ_GAMMA_SUPPORTED)
2648 if (gamma_table
!= NULL
)
2652 for (i
= 0; i
< row_width
; i
++)
2654 if ((png_uint_16
)((*sp
>> shift
) & 0x03)
2655 == trans_values
->gray
)
2657 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2658 *sp
|= (png_byte
)(background
->gray
<< shift
);
2662 png_byte p
= (png_byte
)((*sp
>> shift
) & 0x03);
2663 png_byte g
= (png_byte
)((gamma_table
[p
| (p
<< 2) |
2664 (p
<< 4) | (p
<< 6)] >> 6) & 0x03);
2665 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2666 *sp
|= (png_byte
)(g
<< shift
);
2682 for (i
= 0; i
< row_width
; i
++)
2684 if ((png_uint_16
)((*sp
>> shift
) & 0x03)
2685 == trans_values
->gray
)
2687 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2688 *sp
|= (png_byte
)(background
->gray
<< shift
);
2703 #if defined(PNG_READ_GAMMA_SUPPORTED)
2704 if (gamma_table
!= NULL
)
2708 for (i
= 0; i
< row_width
; i
++)
2710 if ((png_uint_16
)((*sp
>> shift
) & 0x0f)
2711 == trans_values
->gray
)
2713 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2714 *sp
|= (png_byte
)(background
->gray
<< shift
);
2718 png_byte p
= (png_byte
)((*sp
>> shift
) & 0x0f);
2719 png_byte g
= (png_byte
)((gamma_table
[p
|
2720 (p
<< 4)] >> 4) & 0x0f);
2721 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2722 *sp
|= (png_byte
)(g
<< shift
);
2738 for (i
= 0; i
< row_width
; i
++)
2740 if ((png_uint_16
)((*sp
>> shift
) & 0x0f)
2741 == trans_values
->gray
)
2743 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2744 *sp
|= (png_byte
)(background
->gray
<< shift
);
2759 #if defined(PNG_READ_GAMMA_SUPPORTED)
2760 if (gamma_table
!= NULL
)
2763 for (i
= 0; i
< row_width
; i
++, sp
++)
2765 if (*sp
== trans_values
->gray
)
2767 *sp
= (png_byte
)background
->gray
;
2771 *sp
= gamma_table
[*sp
];
2779 for (i
= 0; i
< row_width
; i
++, sp
++)
2781 if (*sp
== trans_values
->gray
)
2783 *sp
= (png_byte
)background
->gray
;
2791 #if defined(PNG_READ_GAMMA_SUPPORTED)
2792 if (gamma_16
!= NULL
)
2795 for (i
= 0; i
< row_width
; i
++, sp
+= 2)
2799 v
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
2800 if (v
== trans_values
->gray
)
2802 /* background is already in screen gamma */
2803 *sp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2804 *(sp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2808 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2809 *sp
= (png_byte
)((v
>> 8) & 0xff);
2810 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2818 for (i
= 0; i
< row_width
; i
++, sp
+= 2)
2822 v
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
2823 if (v
== trans_values
->gray
)
2825 *sp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2826 *(sp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2835 case PNG_COLOR_TYPE_RGB
:
2837 if (row_info
->bit_depth
== 8)
2839 #if defined(PNG_READ_GAMMA_SUPPORTED)
2840 if (gamma_table
!= NULL
)
2843 for (i
= 0; i
< row_width
; i
++, sp
+= 3)
2845 if (*sp
== trans_values
->red
&&
2846 *(sp
+ 1) == trans_values
->green
&&
2847 *(sp
+ 2) == trans_values
->blue
)
2849 *sp
= (png_byte
)background
->red
;
2850 *(sp
+ 1) = (png_byte
)background
->green
;
2851 *(sp
+ 2) = (png_byte
)background
->blue
;
2855 *sp
= gamma_table
[*sp
];
2856 *(sp
+ 1) = gamma_table
[*(sp
+ 1)];
2857 *(sp
+ 2) = gamma_table
[*(sp
+ 2)];
2865 for (i
= 0; i
< row_width
; i
++, sp
+= 3)
2867 if (*sp
== trans_values
->red
&&
2868 *(sp
+ 1) == trans_values
->green
&&
2869 *(sp
+ 2) == trans_values
->blue
)
2871 *sp
= (png_byte
)background
->red
;
2872 *(sp
+ 1) = (png_byte
)background
->green
;
2873 *(sp
+ 2) = (png_byte
)background
->blue
;
2878 else /* if (row_info->bit_depth == 16) */
2880 #if defined(PNG_READ_GAMMA_SUPPORTED)
2881 if (gamma_16
!= NULL
)
2884 for (i
= 0; i
< row_width
; i
++, sp
+= 6)
2886 png_uint_16 r
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
2887 png_uint_16 g
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
2888 png_uint_16 b
= (png_uint_16
)(((*(sp
+4)) << 8) + *(sp
+5));
2889 if (r
== trans_values
->red
&& g
== trans_values
->green
&&
2890 b
== trans_values
->blue
)
2892 /* background is already in screen gamma */
2893 *sp
= (png_byte
)((background
->red
>> 8) & 0xff);
2894 *(sp
+ 1) = (png_byte
)(background
->red
& 0xff);
2895 *(sp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
2896 *(sp
+ 3) = (png_byte
)(background
->green
& 0xff);
2897 *(sp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
2898 *(sp
+ 5) = (png_byte
)(background
->blue
& 0xff);
2902 png_uint_16 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2903 *sp
= (png_byte
)((v
>> 8) & 0xff);
2904 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2905 v
= gamma_16
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
2906 *(sp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
2907 *(sp
+ 3) = (png_byte
)(v
& 0xff);
2908 v
= gamma_16
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
2909 *(sp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
2910 *(sp
+ 5) = (png_byte
)(v
& 0xff);
2918 for (i
= 0; i
< row_width
; i
++, sp
+= 6)
2920 png_uint_16 r
= (png_uint_16
)(((*sp
) << 8) + *(sp
+1));
2921 png_uint_16 g
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
2922 png_uint_16 b
= (png_uint_16
)(((*(sp
+4)) << 8) + *(sp
+5));
2924 if (r
== trans_values
->red
&& g
== trans_values
->green
&&
2925 b
== trans_values
->blue
)
2927 *sp
= (png_byte
)((background
->red
>> 8) & 0xff);
2928 *(sp
+ 1) = (png_byte
)(background
->red
& 0xff);
2929 *(sp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
2930 *(sp
+ 3) = (png_byte
)(background
->green
& 0xff);
2931 *(sp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
2932 *(sp
+ 5) = (png_byte
)(background
->blue
& 0xff);
2939 case PNG_COLOR_TYPE_GRAY_ALPHA
:
2941 if (row_info
->bit_depth
== 8)
2943 #if defined(PNG_READ_GAMMA_SUPPORTED)
2944 if (gamma_to_1
!= NULL
&& gamma_from_1
!= NULL
&&
2945 gamma_table
!= NULL
)
2949 for (i
= 0; i
< row_width
; i
++, sp
+= 2, dp
++)
2951 png_uint_16 a
= *(sp
+ 1);
2955 *dp
= gamma_table
[*sp
];
2959 /* background is already in screen gamma */
2960 *dp
= (png_byte
)background
->gray
;
2966 v
= gamma_to_1
[*sp
];
2967 png_composite(w
, v
, a
, background_1
->gray
);
2968 *dp
= gamma_from_1
[w
];
2977 for (i
= 0; i
< row_width
; i
++, sp
+= 2, dp
++)
2979 png_byte a
= *(sp
+ 1);
2985 #if defined(PNG_READ_GAMMA_SUPPORTED)
2988 *dp
= (png_byte
)background
->gray
;
2992 png_composite(*dp
, *sp
, a
, background_1
->gray
);
2995 *dp
= (png_byte
)background
->gray
;
3000 else /* if (png_ptr->bit_depth == 16) */
3002 #if defined(PNG_READ_GAMMA_SUPPORTED)
3003 if (gamma_16
!= NULL
&& gamma_16_from_1
!= NULL
&&
3004 gamma_16_to_1
!= NULL
)
3008 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 2)
3010 png_uint_16 a
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
3012 if (a
== (png_uint_16
)0xffff)
3016 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
3017 *dp
= (png_byte
)((v
>> 8) & 0xff);
3018 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3020 #if defined(PNG_READ_GAMMA_SUPPORTED)
3026 /* background is already in screen gamma */
3027 *dp
= (png_byte
)((background
->gray
>> 8) & 0xff);
3028 *(dp
+ 1) = (png_byte
)(background
->gray
& 0xff);
3030 #if defined(PNG_READ_GAMMA_SUPPORTED)
3033 png_uint_16 g
, v
, w
;
3035 g
= gamma_16_to_1
[*(sp
+ 1) >> gamma_shift
][*sp
];
3036 png_composite_16(v
, g
, a
, background_1
->gray
);
3037 w
= gamma_16_from_1
[(v
&0xff) >> gamma_shift
][v
>> 8];
3038 *dp
= (png_byte
)((w
>> 8) & 0xff);
3039 *(dp
+ 1) = (png_byte
)(w
& 0xff);
3049 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 2)
3051 png_uint_16 a
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
3052 if (a
== (png_uint_16
)0xffff)
3054 png_memcpy(dp
, sp
, 2);
3056 #if defined(PNG_READ_GAMMA_SUPPORTED)
3062 *dp
= (png_byte
)((background
->gray
>> 8) & 0xff);
3063 *(dp
+ 1) = (png_byte
)(background
->gray
& 0xff);
3065 #if defined(PNG_READ_GAMMA_SUPPORTED)
3070 g
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
3071 png_composite_16(v
, g
, a
, background_1
->gray
);
3072 *dp
= (png_byte
)((v
>> 8) & 0xff);
3073 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3081 case PNG_COLOR_TYPE_RGB_ALPHA
:
3083 if (row_info
->bit_depth
== 8)
3085 #if defined(PNG_READ_GAMMA_SUPPORTED)
3086 if (gamma_to_1
!= NULL
&& gamma_from_1
!= NULL
&&
3087 gamma_table
!= NULL
)
3091 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 3)
3093 png_byte a
= *(sp
+ 3);
3097 *dp
= gamma_table
[*sp
];
3098 *(dp
+ 1) = gamma_table
[*(sp
+ 1)];
3099 *(dp
+ 2) = gamma_table
[*(sp
+ 2)];
3103 /* background is already in screen gamma */
3104 *dp
= (png_byte
)background
->red
;
3105 *(dp
+ 1) = (png_byte
)background
->green
;
3106 *(dp
+ 2) = (png_byte
)background
->blue
;
3112 v
= gamma_to_1
[*sp
];
3113 png_composite(w
, v
, a
, background_1
->red
);
3114 *dp
= gamma_from_1
[w
];
3115 v
= gamma_to_1
[*(sp
+ 1)];
3116 png_composite(w
, v
, a
, background_1
->green
);
3117 *(dp
+ 1) = gamma_from_1
[w
];
3118 v
= gamma_to_1
[*(sp
+ 2)];
3119 png_composite(w
, v
, a
, background_1
->blue
);
3120 *(dp
+ 2) = gamma_from_1
[w
];
3129 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 3)
3131 png_byte a
= *(sp
+ 3);
3136 *(dp
+ 1) = *(sp
+ 1);
3137 *(dp
+ 2) = *(sp
+ 2);
3141 *dp
= (png_byte
)background
->red
;
3142 *(dp
+ 1) = (png_byte
)background
->green
;
3143 *(dp
+ 2) = (png_byte
)background
->blue
;
3147 png_composite(*dp
, *sp
, a
, background
->red
);
3148 png_composite(*(dp
+ 1), *(sp
+ 1), a
,
3150 png_composite(*(dp
+ 2), *(sp
+ 2), a
,
3156 else /* if (row_info->bit_depth == 16) */
3158 #if defined(PNG_READ_GAMMA_SUPPORTED)
3159 if (gamma_16
!= NULL
&& gamma_16_from_1
!= NULL
&&
3160 gamma_16_to_1
!= NULL
)
3164 for (i
= 0; i
< row_width
; i
++, sp
+= 8, dp
+= 6)
3166 png_uint_16 a
= (png_uint_16
)(((png_uint_16
)(*(sp
+ 6))
3167 << 8) + (png_uint_16
)(*(sp
+ 7)));
3168 if (a
== (png_uint_16
)0xffff)
3172 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
3173 *dp
= (png_byte
)((v
>> 8) & 0xff);
3174 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3175 v
= gamma_16
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
3176 *(dp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
3177 *(dp
+ 3) = (png_byte
)(v
& 0xff);
3178 v
= gamma_16
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
3179 *(dp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
3180 *(dp
+ 5) = (png_byte
)(v
& 0xff);
3184 /* background is already in screen gamma */
3185 *dp
= (png_byte
)((background
->red
>> 8) & 0xff);
3186 *(dp
+ 1) = (png_byte
)(background
->red
& 0xff);
3187 *(dp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
3188 *(dp
+ 3) = (png_byte
)(background
->green
& 0xff);
3189 *(dp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
3190 *(dp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3194 png_uint_16 v
, w
, x
;
3196 v
= gamma_16_to_1
[*(sp
+ 1) >> gamma_shift
][*sp
];
3197 png_composite_16(w
, v
, a
, background_1
->red
);
3198 x
= gamma_16_from_1
[((w
&0xff) >> gamma_shift
)][w
>> 8];
3199 *dp
= (png_byte
)((x
>> 8) & 0xff);
3200 *(dp
+ 1) = (png_byte
)(x
& 0xff);
3201 v
= gamma_16_to_1
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
3202 png_composite_16(w
, v
, a
, background_1
->green
);
3203 x
= gamma_16_from_1
[((w
&0xff) >> gamma_shift
)][w
>> 8];
3204 *(dp
+ 2) = (png_byte
)((x
>> 8) & 0xff);
3205 *(dp
+ 3) = (png_byte
)(x
& 0xff);
3206 v
= gamma_16_to_1
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
3207 png_composite_16(w
, v
, a
, background_1
->blue
);
3208 x
= gamma_16_from_1
[(w
& 0xff) >> gamma_shift
][w
>> 8];
3209 *(dp
+ 4) = (png_byte
)((x
>> 8) & 0xff);
3210 *(dp
+ 5) = (png_byte
)(x
& 0xff);
3219 for (i
= 0; i
< row_width
; i
++, sp
+= 8, dp
+= 6)
3221 png_uint_16 a
= (png_uint_16
)(((png_uint_16
)(*(sp
+ 6))
3222 << 8) + (png_uint_16
)(*(sp
+ 7)));
3223 if (a
== (png_uint_16
)0xffff)
3225 png_memcpy(dp
, sp
, 6);
3229 *dp
= (png_byte
)((background
->red
>> 8) & 0xff);
3230 *(dp
+ 1) = (png_byte
)(background
->red
& 0xff);
3231 *(dp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
3232 *(dp
+ 3) = (png_byte
)(background
->green
& 0xff);
3233 *(dp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
3234 *(dp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3240 png_uint_16 r
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
3241 png_uint_16 g
= (png_uint_16
)(((*(sp
+ 2)) << 8)
3243 png_uint_16 b
= (png_uint_16
)(((*(sp
+ 4)) << 8)
3246 png_composite_16(v
, r
, a
, background
->red
);
3247 *dp
= (png_byte
)((v
>> 8) & 0xff);
3248 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3249 png_composite_16(v
, g
, a
, background
->green
);
3250 *(dp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
3251 *(dp
+ 3) = (png_byte
)(v
& 0xff);
3252 png_composite_16(v
, b
, a
, background
->blue
);
3253 *(dp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
3254 *(dp
+ 5) = (png_byte
)(v
& 0xff);
3263 if (row_info
->color_type
& PNG_COLOR_MASK_ALPHA
)
3265 row_info
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
3266 row_info
->channels
--;
3267 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
3268 row_info
->bit_depth
);
3269 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
,row_width
);
3275 #if defined(PNG_READ_GAMMA_SUPPORTED)
3276 /* Gamma correct the image, avoiding the alpha channel. Make sure
3277 * you do this after you deal with the transparency issue on grayscale
3278 * or RGB images. If your bit depth is 8, use gamma_table, if it
3279 * is 16, use gamma_16_table and gamma_shift. Build these with
3280 * build_gamma_table().
3283 png_do_gamma(png_row_infop row_info
, png_bytep row
,
3284 png_bytep gamma_table
, png_uint_16pp gamma_16_table
,
3289 png_uint_32 row_width
=row_info
->width
;
3291 png_debug(1, "in png_do_gamma\n");
3293 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3294 row
!= NULL
&& row_info
!= NULL
&&
3296 ((row_info
->bit_depth
<= 8 && gamma_table
!= NULL
) ||
3297 (row_info
->bit_depth
== 16 && gamma_16_table
!= NULL
)))
3299 switch (row_info
->color_type
)
3301 case PNG_COLOR_TYPE_RGB
:
3303 if (row_info
->bit_depth
== 8)
3306 for (i
= 0; i
< row_width
; i
++)
3308 *sp
= gamma_table
[*sp
];
3310 *sp
= gamma_table
[*sp
];
3312 *sp
= gamma_table
[*sp
];
3316 else /* if (row_info->bit_depth == 16) */
3319 for (i
= 0; i
< row_width
; i
++)
3323 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3324 *sp
= (png_byte
)((v
>> 8) & 0xff);
3325 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3327 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3328 *sp
= (png_byte
)((v
>> 8) & 0xff);
3329 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3331 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3332 *sp
= (png_byte
)((v
>> 8) & 0xff);
3333 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3339 case PNG_COLOR_TYPE_RGB_ALPHA
:
3341 if (row_info
->bit_depth
== 8)
3344 for (i
= 0; i
< row_width
; i
++)
3346 *sp
= gamma_table
[*sp
];
3348 *sp
= gamma_table
[*sp
];
3350 *sp
= gamma_table
[*sp
];
3355 else /* if (row_info->bit_depth == 16) */
3358 for (i
= 0; i
< row_width
; i
++)
3360 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3361 *sp
= (png_byte
)((v
>> 8) & 0xff);
3362 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3364 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3365 *sp
= (png_byte
)((v
>> 8) & 0xff);
3366 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3368 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3369 *sp
= (png_byte
)((v
>> 8) & 0xff);
3370 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3376 case PNG_COLOR_TYPE_GRAY_ALPHA
:
3378 if (row_info
->bit_depth
== 8)
3381 for (i
= 0; i
< row_width
; i
++)
3383 *sp
= gamma_table
[*sp
];
3387 else /* if (row_info->bit_depth == 16) */
3390 for (i
= 0; i
< row_width
; i
++)
3392 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3393 *sp
= (png_byte
)((v
>> 8) & 0xff);
3394 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3400 case PNG_COLOR_TYPE_GRAY
:
3402 if (row_info
->bit_depth
== 2)
3405 for (i
= 0; i
< row_width
; i
+= 4)
3413 ((((int)gamma_table
[a
|(a
>>2)|(a
>>4)|(a
>>6)]) ) & 0xc0)|
3414 ((((int)gamma_table
[(b
<<2)|b
|(b
>>2)|(b
>>4)])>>2) & 0x30)|
3415 ((((int)gamma_table
[(c
<<4)|(c
<<2)|c
|(c
>>2)])>>4) & 0x0c)|
3416 ((((int)gamma_table
[(d
<<6)|(d
<<4)|(d
<<2)|d
])>>6) ));
3420 if (row_info
->bit_depth
== 4)
3423 for (i
= 0; i
< row_width
; i
+= 2)
3425 int msb
= *sp
& 0xf0;
3426 int lsb
= *sp
& 0x0f;
3428 *sp
= (png_byte
)((((int)gamma_table
[msb
| (msb
>> 4)]) & 0xf0)
3429 | (((int)gamma_table
[(lsb
<< 4) | lsb
]) >> 4));
3433 else if (row_info
->bit_depth
== 8)
3436 for (i
= 0; i
< row_width
; i
++)
3438 *sp
= gamma_table
[*sp
];
3442 else if (row_info
->bit_depth
== 16)
3445 for (i
= 0; i
< row_width
; i
++)
3447 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3448 *sp
= (png_byte
)((v
>> 8) & 0xff);
3449 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3460 #if defined(PNG_READ_EXPAND_SUPPORTED)
3461 /* Expands a palette row to an RGB or RGBA row depending
3462 * upon whether you supply trans and num_trans.
3465 png_do_expand_palette(png_row_infop row_info
, png_bytep row
,
3466 png_colorp palette
, png_bytep trans
, int num_trans
)
3471 png_uint_32 row_width
=row_info
->width
;
3473 png_debug(1, "in png_do_expand_palette\n");
3475 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3476 row
!= NULL
&& row_info
!= NULL
&&
3478 row_info
->color_type
== PNG_COLOR_TYPE_PALETTE
)
3480 if (row_info
->bit_depth
< 8)
3482 switch (row_info
->bit_depth
)
3486 sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
3487 dp
= row
+ (png_size_t
)row_width
- 1;
3488 shift
= 7 - (int)((row_width
+ 7) & 0x07);
3489 for (i
= 0; i
< row_width
; i
++)
3491 if ((*sp
>> shift
) & 0x01)
3509 sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
3510 dp
= row
+ (png_size_t
)row_width
- 1;
3511 shift
= (int)((3 - ((row_width
+ 3) & 0x03)) << 1);
3512 for (i
= 0; i
< row_width
; i
++)
3514 value
= (*sp
>> shift
) & 0x03;
3515 *dp
= (png_byte
)value
;
3530 sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
3531 dp
= row
+ (png_size_t
)row_width
- 1;
3532 shift
= (int)((row_width
& 0x01) << 2);
3533 for (i
= 0; i
< row_width
; i
++)
3535 value
= (*sp
>> shift
) & 0x0f;
3536 *dp
= (png_byte
)value
;
3550 row_info
->bit_depth
= 8;
3551 row_info
->pixel_depth
= 8;
3552 row_info
->rowbytes
= row_width
;
3554 switch (row_info
->bit_depth
)
3560 sp
= row
+ (png_size_t
)row_width
- 1;
3561 dp
= row
+ (png_size_t
)(row_width
<< 2) - 1;
3563 for (i
= 0; i
< row_width
; i
++)
3565 if ((int)(*sp
) >= num_trans
)
3569 *dp
-- = palette
[*sp
].blue
;
3570 *dp
-- = palette
[*sp
].green
;
3571 *dp
-- = palette
[*sp
].red
;
3574 row_info
->bit_depth
= 8;
3575 row_info
->pixel_depth
= 32;
3576 row_info
->rowbytes
= row_width
* 4;
3577 row_info
->color_type
= 6;
3578 row_info
->channels
= 4;
3582 sp
= row
+ (png_size_t
)row_width
- 1;
3583 dp
= row
+ (png_size_t
)(row_width
* 3) - 1;
3585 for (i
= 0; i
< row_width
; i
++)
3587 *dp
-- = palette
[*sp
].blue
;
3588 *dp
-- = palette
[*sp
].green
;
3589 *dp
-- = palette
[*sp
].red
;
3592 row_info
->bit_depth
= 8;
3593 row_info
->pixel_depth
= 24;
3594 row_info
->rowbytes
= row_width
* 3;
3595 row_info
->color_type
= 2;
3596 row_info
->channels
= 3;
3604 /* If the bit depth < 8, it is expanded to 8. Also, if the
3605 * transparency value is supplied, an alpha channel is built.
3608 png_do_expand(png_row_infop row_info
, png_bytep row
,
3609 png_color_16p trans_value
)
3614 png_uint_32 row_width
=row_info
->width
;
3616 png_debug(1, "in png_do_expand\n");
3617 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3618 if (row
!= NULL
&& row_info
!= NULL
)
3621 if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
3623 png_uint_16 gray
= (png_uint_16
)(trans_value
? trans_value
->gray
: 0);
3625 if (row_info
->bit_depth
< 8)
3627 switch (row_info
->bit_depth
)
3631 gray
= (png_uint_16
)(gray
*0xff);
3632 sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
3633 dp
= row
+ (png_size_t
)row_width
- 1;
3634 shift
= 7 - (int)((row_width
+ 7) & 0x07);
3635 for (i
= 0; i
< row_width
; i
++)
3637 if ((*sp
>> shift
) & 0x01)
3655 gray
= (png_uint_16
)(gray
*0x55);
3656 sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
3657 dp
= row
+ (png_size_t
)row_width
- 1;
3658 shift
= (int)((3 - ((row_width
+ 3) & 0x03)) << 1);
3659 for (i
= 0; i
< row_width
; i
++)
3661 value
= (*sp
>> shift
) & 0x03;
3662 *dp
= (png_byte
)(value
| (value
<< 2) | (value
<< 4) |
3678 gray
= (png_uint_16
)(gray
*0x11);
3679 sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
3680 dp
= row
+ (png_size_t
)row_width
- 1;
3681 shift
= (int)((1 - ((row_width
+ 1) & 0x01)) << 2);
3682 for (i
= 0; i
< row_width
; i
++)
3684 value
= (*sp
>> shift
) & 0x0f;
3685 *dp
= (png_byte
)(value
| (value
<< 4));
3699 row_info
->bit_depth
= 8;
3700 row_info
->pixel_depth
= 8;
3701 row_info
->rowbytes
= row_width
;
3704 if (trans_value
!= NULL
)
3706 if (row_info
->bit_depth
== 8)
3708 sp
= row
+ (png_size_t
)row_width
- 1;
3709 dp
= row
+ (png_size_t
)(row_width
<< 1) - 1;
3710 for (i
= 0; i
< row_width
; i
++)
3719 else if (row_info
->bit_depth
== 16)
3721 sp
= row
+ row_info
->rowbytes
- 1;
3722 dp
= row
+ (row_info
->rowbytes
<< 1) - 1;
3723 for (i
= 0; i
< row_width
; i
++)
3725 if (((png_uint_16
)*(sp
) |
3726 ((png_uint_16
)*(sp
- 1) << 8)) == gray
)
3740 row_info
->color_type
= PNG_COLOR_TYPE_GRAY_ALPHA
;
3741 row_info
->channels
= 2;
3742 row_info
->pixel_depth
= (png_byte
)(row_info
->bit_depth
<< 1);
3743 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
,
3747 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
&& trans_value
)
3749 if (row_info
->bit_depth
== 8)
3751 sp
= row
+ (png_size_t
)row_info
->rowbytes
- 1;
3752 dp
= row
+ (png_size_t
)(row_width
<< 2) - 1;
3753 for (i
= 0; i
< row_width
; i
++)
3755 if (*(sp
- 2) == trans_value
->red
&&
3756 *(sp
- 1) == trans_value
->green
&&
3757 *(sp
- 0) == trans_value
->blue
)
3766 else if (row_info
->bit_depth
== 16)
3768 sp
= row
+ row_info
->rowbytes
- 1;
3769 dp
= row
+ (png_size_t
)(row_width
<< 3) - 1;
3770 for (i
= 0; i
< row_width
; i
++)
3772 if ((((png_uint_16
)*(sp
- 4) |
3773 ((png_uint_16
)*(sp
- 5) << 8)) == trans_value
->red
) &&
3774 (((png_uint_16
)*(sp
- 2) |
3775 ((png_uint_16
)*(sp
- 3) << 8)) == trans_value
->green
) &&
3776 (((png_uint_16
)*(sp
- 0) |
3777 ((png_uint_16
)*(sp
- 1) << 8)) == trans_value
->blue
))
3795 row_info
->color_type
= PNG_COLOR_TYPE_RGB_ALPHA
;
3796 row_info
->channels
= 4;
3797 row_info
->pixel_depth
= (png_byte
)(row_info
->bit_depth
<< 2);
3798 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
,row_width
);
3804 #if defined(PNG_READ_DITHER_SUPPORTED)
3806 png_do_dither(png_row_infop row_info
, png_bytep row
,
3807 png_bytep palette_lookup
, png_bytep dither_lookup
)
3811 png_uint_32 row_width
=row_info
->width
;
3813 png_debug(1, "in png_do_dither\n");
3814 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3815 if (row
!= NULL
&& row_info
!= NULL
)
3818 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
&&
3819 palette_lookup
&& row_info
->bit_depth
== 8)
3824 for (i
= 0; i
< row_width
; i
++)
3830 /* this looks real messy, but the compiler will reduce
3831 it down to a reasonable formula. For example, with
3832 5 bits per color, we get:
3833 p = (((r >> 3) & 0x1f) << 10) |
3834 (((g >> 3) & 0x1f) << 5) |
3837 p
= (((r
>> (8 - PNG_DITHER_RED_BITS
)) &
3838 ((1 << PNG_DITHER_RED_BITS
) - 1)) <<
3839 (PNG_DITHER_GREEN_BITS
+ PNG_DITHER_BLUE_BITS
)) |
3840 (((g
>> (8 - PNG_DITHER_GREEN_BITS
)) &
3841 ((1 << PNG_DITHER_GREEN_BITS
) - 1)) <<
3842 (PNG_DITHER_BLUE_BITS
)) |
3843 ((b
>> (8 - PNG_DITHER_BLUE_BITS
)) &
3844 ((1 << PNG_DITHER_BLUE_BITS
) - 1));
3846 *dp
++ = palette_lookup
[p
];
3848 row_info
->color_type
= PNG_COLOR_TYPE_PALETTE
;
3849 row_info
->channels
= 1;
3850 row_info
->pixel_depth
= row_info
->bit_depth
;
3851 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
,row_width
);
3853 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
&&
3854 palette_lookup
!= NULL
&& row_info
->bit_depth
== 8)
3859 for (i
= 0; i
< row_width
; i
++)
3866 p
= (((r
>> (8 - PNG_DITHER_RED_BITS
)) &
3867 ((1 << PNG_DITHER_RED_BITS
) - 1)) <<
3868 (PNG_DITHER_GREEN_BITS
+ PNG_DITHER_BLUE_BITS
)) |
3869 (((g
>> (8 - PNG_DITHER_GREEN_BITS
)) &
3870 ((1 << PNG_DITHER_GREEN_BITS
) - 1)) <<
3871 (PNG_DITHER_BLUE_BITS
)) |
3872 ((b
>> (8 - PNG_DITHER_BLUE_BITS
)) &
3873 ((1 << PNG_DITHER_BLUE_BITS
) - 1));
3875 *dp
++ = palette_lookup
[p
];
3877 row_info
->color_type
= PNG_COLOR_TYPE_PALETTE
;
3878 row_info
->channels
= 1;
3879 row_info
->pixel_depth
= row_info
->bit_depth
;
3880 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
,row_width
);
3882 else if (row_info
->color_type
== PNG_COLOR_TYPE_PALETTE
&&
3883 dither_lookup
&& row_info
->bit_depth
== 8)
3886 for (i
= 0; i
< row_width
; i
++, sp
++)
3888 *sp
= dither_lookup
[*sp
];
3895 #ifdef PNG_FLOATING_POINT_SUPPORTED
3896 #if defined(PNG_READ_GAMMA_SUPPORTED)
3897 static int png_gamma_shift
[] =
3898 {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0};
3900 /* We build the 8- or 16-bit gamma tables here. Note that for 16-bit
3901 * tables, we don't make a full table if we are reducing to 8-bit in
3902 * the future. Note also how the gamma_16 tables are segmented so that
3903 * we don't need to allocate > 64K chunks for a full 16-bit table.
3906 png_build_gamma_table(png_structp png_ptr
)
3908 png_debug(1, "in png_build_gamma_table\n");
3909 if(png_ptr
->gamma
!= 0.0)
3911 if (png_ptr
->bit_depth
<= 8)
3916 if (png_ptr
->screen_gamma
> .000001)
3917 g
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
3921 png_ptr
->gamma_table
= (png_bytep
)png_malloc(png_ptr
,
3924 for (i
= 0; i
< 256; i
++)
3926 png_ptr
->gamma_table
[i
] = (png_byte
)(pow((double)i
/ 255.0,
3930 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
3931 defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
3932 if (png_ptr
->transformations
& ((PNG_BACKGROUND
) | PNG_RGB_TO_GRAY
))
3935 g
= 1.0 / (png_ptr
->gamma
);
3937 png_ptr
->gamma_to_1
= (png_bytep
)png_malloc(png_ptr
,
3940 for (i
= 0; i
< 256; i
++)
3942 png_ptr
->gamma_to_1
[i
] = (png_byte
)(pow((double)i
/ 255.0,
3947 png_ptr
->gamma_from_1
= (png_bytep
)png_malloc(png_ptr
,
3950 if(png_ptr
->screen_gamma
> 0.000001)
3951 g
= 1.0 / png_ptr
->screen_gamma
;
3953 g
= png_ptr
->gamma
; /* probably doing rgb_to_gray */
3955 for (i
= 0; i
< 256; i
++)
3957 png_ptr
->gamma_from_1
[i
] = (png_byte
)(pow((double)i
/ 255.0,
3962 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
3967 int i
, j
, shift
, num
;
3971 if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
3973 sig_bit
= (int)png_ptr
->sig_bit
.red
;
3974 if ((int)png_ptr
->sig_bit
.green
> sig_bit
)
3975 sig_bit
= png_ptr
->sig_bit
.green
;
3976 if ((int)png_ptr
->sig_bit
.blue
> sig_bit
)
3977 sig_bit
= png_ptr
->sig_bit
.blue
;
3981 sig_bit
= (int)png_ptr
->sig_bit
.gray
;
3985 shift
= 16 - sig_bit
;
3989 if (png_ptr
->transformations
& PNG_16_TO_8
)
3991 if (shift
< (16 - PNG_MAX_GAMMA_8
))
3992 shift
= (16 - PNG_MAX_GAMMA_8
);
4000 png_ptr
->gamma_shift
= (png_byte
)shift
;
4002 num
= (1 << (8 - shift
));
4004 if (png_ptr
->screen_gamma
> .000001)
4005 g
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
4009 png_ptr
->gamma_16_table
= (png_uint_16pp
)png_malloc(png_ptr
,
4010 (png_uint_32
)(num
* png_sizeof (png_uint_16p
)));
4012 if (png_ptr
->transformations
& (PNG_16_TO_8
| PNG_BACKGROUND
))
4015 png_uint_32 last
, max
;
4017 for (i
= 0; i
< num
; i
++)
4019 png_ptr
->gamma_16_table
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
4020 (png_uint_32
)(256 * png_sizeof (png_uint_16
)));
4025 for (i
= 0; i
< 256; i
++)
4027 fout
= ((double)i
+ 0.5) / 256.0;
4029 max
= (png_uint_32
)(fin
* (double)((png_uint_32
)num
<< 8));
4032 png_ptr
->gamma_16_table
[(int)(last
& (0xff >> shift
))]
4033 [(int)(last
>> (8 - shift
))] = (png_uint_16
)(
4034 (png_uint_16
)i
| ((png_uint_16
)i
<< 8));
4038 while (last
< ((png_uint_32
)num
<< 8))
4040 png_ptr
->gamma_16_table
[(int)(last
& (0xff >> shift
))]
4041 [(int)(last
>> (8 - shift
))] = (png_uint_16
)65535L;
4047 for (i
= 0; i
< num
; i
++)
4049 png_ptr
->gamma_16_table
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
4050 (png_uint_32
)(256 * png_sizeof (png_uint_16
)));
4052 ig
= (((png_uint_32
)i
* (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
4053 for (j
= 0; j
< 256; j
++)
4055 png_ptr
->gamma_16_table
[i
][j
] =
4056 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
4057 65535.0, g
) * 65535.0 + .5);
4062 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
4063 defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
4064 if (png_ptr
->transformations
& (PNG_BACKGROUND
| PNG_RGB_TO_GRAY
))
4067 g
= 1.0 / (png_ptr
->gamma
);
4069 png_ptr
->gamma_16_to_1
= (png_uint_16pp
)png_malloc(png_ptr
,
4070 (png_uint_32
)(num
* png_sizeof (png_uint_16p
)));
4072 for (i
= 0; i
< num
; i
++)
4074 png_ptr
->gamma_16_to_1
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
4075 (png_uint_32
)(256 * png_sizeof (png_uint_16
)));
4077 ig
= (((png_uint_32
)i
*
4078 (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
4079 for (j
= 0; j
< 256; j
++)
4081 png_ptr
->gamma_16_to_1
[i
][j
] =
4082 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
4083 65535.0, g
) * 65535.0 + .5);
4087 if(png_ptr
->screen_gamma
> 0.000001)
4088 g
= 1.0 / png_ptr
->screen_gamma
;
4090 g
= png_ptr
->gamma
; /* probably doing rgb_to_gray */
4092 png_ptr
->gamma_16_from_1
= (png_uint_16pp
)png_malloc(png_ptr
,
4093 (png_uint_32
)(num
* png_sizeof (png_uint_16p
)));
4095 for (i
= 0; i
< num
; i
++)
4097 png_ptr
->gamma_16_from_1
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
4098 (png_uint_32
)(256 * png_sizeof (png_uint_16
)));
4100 ig
= (((png_uint_32
)i
*
4101 (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
4102 for (j
= 0; j
< 256; j
++)
4104 png_ptr
->gamma_16_from_1
[i
][j
] =
4105 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
4106 65535.0, g
) * 65535.0 + .5);
4110 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
4115 /* To do: install integer version of png_build_gamma_table here */
4118 #if defined(PNG_MNG_FEATURES_SUPPORTED)
4119 /* undoes intrapixel differencing */
4121 png_do_read_intrapixel(png_row_infop row_info
, png_bytep row
)
4123 png_debug(1, "in png_do_read_intrapixel\n");
4125 #if defined(PNG_USELESS_TESTS_SUPPORTED)
4126 row
!= NULL
&& row_info
!= NULL
&&
4128 (row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
4130 int bytes_per_pixel
;
4131 png_uint_32 row_width
= row_info
->width
;
4132 if (row_info
->bit_depth
== 8)
4137 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
4138 bytes_per_pixel
= 3;
4139 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
4140 bytes_per_pixel
= 4;
4144 for (i
= 0, rp
= row
; i
< row_width
; i
++, rp
+= bytes_per_pixel
)
4146 *(rp
) = (png_byte
)((256 + *rp
+ *(rp
+1))&0xff);
4147 *(rp
+2) = (png_byte
)((256 + *(rp
+2) + *(rp
+1))&0xff);
4150 else if (row_info
->bit_depth
== 16)
4155 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
4156 bytes_per_pixel
= 6;
4157 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
4158 bytes_per_pixel
= 8;
4162 for (i
= 0, rp
= row
; i
< row_width
; i
++, rp
+= bytes_per_pixel
)
4164 png_uint_32 s0
= (*(rp
) << 8) | *(rp
+1);
4165 png_uint_32 s1
= (*(rp
+2) << 8) | *(rp
+3);
4166 png_uint_32 s2
= (*(rp
+4) << 8) | *(rp
+5);
4167 png_uint_32 red
= (png_uint_32
)((s0
+s1
+65536L) & 0xffffL
);
4168 png_uint_32 blue
= (png_uint_32
)((s2
+s1
+65536L) & 0xffffL
);
4169 *(rp
) = (png_byte
)((red
>> 8) & 0xff);
4170 *(rp
+1) = (png_byte
)(red
& 0xff);
4171 *(rp
+4) = (png_byte
)((blue
>> 8) & 0xff);
4172 *(rp
+5) = (png_byte
)(blue
& 0xff);
4177 #endif /* PNG_MNG_FEATURES_SUPPORTED */