2 /* pngrtran.c - transforms the data in a row for PNG readers
4 * libpng 1.0.10 - March 30, 2001
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1998-2001 Glenn Randers-Pehrson
7 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
10 * This file contains functions optionally called by an application
11 * in order to tell libpng how to handle data when reading a PNG.
12 * Transformations that are used in both reading and writing are
19 /* Set the action on getting a CRC error for an ancillary or critical chunk. */
21 png_set_crc_action(png_structp png_ptr
, int crit_action
, int ancil_action
)
23 png_debug(1, "in png_set_crc_action\n");
24 /* Tell libpng how we react to CRC errors in critical chunks */
27 case PNG_CRC_NO_CHANGE
: /* leave setting as is */
29 case PNG_CRC_WARN_USE
: /* warn/use data */
30 png_ptr
->flags
&= ~PNG_FLAG_CRC_CRITICAL_MASK
;
31 png_ptr
->flags
|= PNG_FLAG_CRC_CRITICAL_USE
;
33 case PNG_CRC_QUIET_USE
: /* quiet/use data */
34 png_ptr
->flags
&= ~PNG_FLAG_CRC_CRITICAL_MASK
;
35 png_ptr
->flags
|= PNG_FLAG_CRC_CRITICAL_USE
|
36 PNG_FLAG_CRC_CRITICAL_IGNORE
;
38 case PNG_CRC_WARN_DISCARD
: /* not a valid action for critical data */
39 png_warning(png_ptr
, "Can't discard critical data on CRC error.");
40 case PNG_CRC_ERROR_QUIT
: /* error/quit */
43 png_ptr
->flags
&= ~PNG_FLAG_CRC_CRITICAL_MASK
;
49 case PNG_CRC_NO_CHANGE
: /* leave setting as is */
51 case PNG_CRC_WARN_USE
: /* warn/use data */
52 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
53 png_ptr
->flags
|= PNG_FLAG_CRC_ANCILLARY_USE
;
55 case PNG_CRC_QUIET_USE
: /* quiet/use data */
56 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
57 png_ptr
->flags
|= PNG_FLAG_CRC_ANCILLARY_USE
|
58 PNG_FLAG_CRC_ANCILLARY_NOWARN
;
60 case PNG_CRC_ERROR_QUIT
: /* error/quit */
61 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
62 png_ptr
->flags
|= PNG_FLAG_CRC_ANCILLARY_NOWARN
;
64 case PNG_CRC_WARN_DISCARD
: /* warn/discard data */
67 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
72 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
73 defined(PNG_FLOATING_POINT_SUPPORTED)
74 /* handle alpha and tRNS via a background color */
76 png_set_background(png_structp png_ptr
,
77 png_color_16p background_color
, int background_gamma_code
,
78 int need_expand
, double background_gamma
)
80 png_debug(1, "in png_set_background\n");
81 if (background_gamma_code
== PNG_BACKGROUND_GAMMA_UNKNOWN
)
83 png_warning(png_ptr
, "Application must supply a known background gamma");
87 png_ptr
->transformations
|= PNG_BACKGROUND
;
88 png_memcpy(&(png_ptr
->background
), background_color
, sizeof(png_color_16
));
89 png_ptr
->background_gamma
= (float)background_gamma
;
90 png_ptr
->background_gamma_type
= (png_byte
)(background_gamma_code
);
91 png_ptr
->transformations
|= (need_expand
? PNG_BACKGROUND_EXPAND
: 0);
93 /* Note: if need_expand is set and color_type is either RGB or RGB_ALPHA
94 * (in which case need_expand is superfluous anyway), the background color
95 * might actually be gray yet not be flagged as such. This is not a problem
96 * for the current code, which uses PNG_BACKGROUND_IS_GRAY only to
97 * decide when to do the png_do_gray_to_rgb() transformation.
99 if ((need_expand
&& !(png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)) ||
100 (!need_expand
&& background_color
->red
== background_color
->green
&&
101 background_color
->red
== background_color
->blue
))
102 png_ptr
->mode
|= PNG_BACKGROUND_IS_GRAY
;
106 #if defined(PNG_READ_16_TO_8_SUPPORTED)
107 /* strip 16 bit depth files to 8 bit depth */
109 png_set_strip_16(png_structp png_ptr
)
111 png_debug(1, "in png_set_strip_16\n");
112 png_ptr
->transformations
|= PNG_16_TO_8
;
116 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
118 png_set_strip_alpha(png_structp png_ptr
)
120 png_debug(1, "in png_set_strip_alpha\n");
121 png_ptr
->transformations
|= PNG_STRIP_ALPHA
;
125 #if defined(PNG_READ_DITHER_SUPPORTED)
126 /* Dither file to 8 bit. Supply a palette, the current number
127 * of elements in the palette, the maximum number of elements
128 * allowed, and a histogram if possible. If the current number
129 * of colors is greater then the maximum number, the palette will be
130 * modified to fit in the maximum number. "full_dither" indicates
131 * whether we need a dithering cube set up for RGB images, or if we
132 * simply are reducing the number of colors in a paletted image.
135 typedef struct png_dsort_struct
137 struct png_dsort_struct FAR
* next
;
141 typedef png_dsort FAR
* png_dsortp
;
142 typedef png_dsort FAR
* FAR
* png_dsortpp
;
145 png_set_dither(png_structp png_ptr
, png_colorp palette
,
146 int num_palette
, int maximum_colors
, png_uint_16p histogram
,
149 png_debug(1, "in png_set_dither\n");
150 png_ptr
->transformations
|= PNG_DITHER
;
156 png_ptr
->dither_index
= (png_bytep
)png_malloc(png_ptr
,
157 (png_uint_32
)(num_palette
* sizeof (png_byte
)));
158 for (i
= 0; i
< num_palette
; i
++)
159 png_ptr
->dither_index
[i
] = (png_byte
)i
;
162 if (num_palette
> maximum_colors
)
164 if (histogram
!= NULL
)
166 /* This is easy enough, just throw out the least used colors.
167 Perhaps not the best solution, but good enough. */
172 /* initialize an array to sort colors */
173 sort
= (png_bytep
)png_malloc(png_ptr
, (png_uint_32
)(num_palette
174 * sizeof (png_byte
)));
176 /* initialize the sort array */
177 for (i
= 0; i
< num_palette
; i
++)
178 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
[sort
[j
]] < histogram
[sort
[j
+ 1]])
199 sort
[j
] = sort
[j
+ 1];
208 /* swap the palette around, and set up a table, if necessary */
213 /* put all the useful colors within the max, but don't
215 for (i
= 0; i
< maximum_colors
; i
++)
217 if ((int)sort
[i
] >= maximum_colors
)
221 while ((int)sort
[j
] >= maximum_colors
);
222 palette
[i
] = palette
[j
];
230 /* move all the used colors inside the max limit, and
231 develop a translation table */
232 for (i
= 0; i
< maximum_colors
; i
++)
234 /* only move the colors we need to */
235 if ((int)sort
[i
] >= maximum_colors
)
241 while ((int)sort
[j
] >= maximum_colors
);
243 tmp_color
= palette
[j
];
244 palette
[j
] = palette
[i
];
245 palette
[i
] = tmp_color
;
246 /* indicate where the color went */
247 png_ptr
->dither_index
[j
] = (png_byte
)i
;
248 png_ptr
->dither_index
[i
] = (png_byte
)j
;
252 /* find closest color for those colors we are not using */
253 for (i
= 0; i
< num_palette
; i
++)
255 if ((int)png_ptr
->dither_index
[i
] >= maximum_colors
)
257 int min_d
, k
, min_k
, d_index
;
259 /* find the closest color to one we threw out */
260 d_index
= png_ptr
->dither_index
[i
];
261 min_d
= PNG_COLOR_DIST(palette
[d_index
], palette
[0]);
262 for (k
= 1, min_k
= 0; k
< maximum_colors
; k
++)
266 d
= PNG_COLOR_DIST(palette
[d_index
], palette
[k
]);
274 /* point to closest color */
275 png_ptr
->dither_index
[i
] = (png_byte
)min_k
;
279 png_free(png_ptr
, sort
);
283 /* This is much harder to do simply (and quickly). Perhaps
284 we need to go through a median cut routine, but those
285 don't always behave themselves with only a few colors
286 as input. So we will just find the closest two colors,
287 and throw out one of them (chosen somewhat randomly).
288 [We don't understand this at all, so if someone wants to
289 work on improving it, be our guest - AED, GRP]
295 png_bytep index_to_palette
;
296 /* where the original index currently is in the palette */
297 png_bytep palette_to_index
;
298 /* which original index points to this palette color */
300 /* initialize palette index arrays */
301 index_to_palette
= (png_bytep
)png_malloc(png_ptr
,
302 (png_uint_32
)(num_palette
* sizeof (png_byte
)));
303 palette_to_index
= (png_bytep
)png_malloc(png_ptr
,
304 (png_uint_32
)(num_palette
* sizeof (png_byte
)));
306 /* initialize the sort array */
307 for (i
= 0; i
< num_palette
; i
++)
309 index_to_palette
[i
] = (png_byte
)i
;
310 palette_to_index
[i
] = (png_byte
)i
;
313 hash
= (png_dsortpp
)png_malloc(png_ptr
, (png_uint_32
)(769 *
314 sizeof (png_dsortp
)));
315 for (i
= 0; i
< 769; i
++)
317 /* png_memset(hash, 0, 769 * sizeof (png_dsortp)); */
319 num_new_palette
= num_palette
;
321 /* initial wild guess at how far apart the farthest pixel
322 pair we will be eliminating will be. Larger
323 numbers mean more areas will be allocated, Smaller
324 numbers run the risk of not saving enough data, and
325 having to do this all over again.
327 I have not done extensive checking on this number.
331 while (num_new_palette
> maximum_colors
)
333 for (i
= 0; i
< num_new_palette
- 1; i
++)
337 for (j
= i
+ 1; j
< num_new_palette
; j
++)
341 d
= PNG_COLOR_DIST(palette
[i
], palette
[j
]);
347 t
= (png_dsortp
)png_malloc(png_ptr
, (png_uint_32
)(sizeof
350 t
->left
= (png_byte
)i
;
351 t
->right
= (png_byte
)j
;
357 for (i
= 0; i
<= max_d
; i
++)
363 for (p
= hash
[i
]; p
; p
= p
->next
)
365 if ((int)index_to_palette
[p
->left
] < num_new_palette
&&
366 (int)index_to_palette
[p
->right
] < num_new_palette
)
370 if (num_new_palette
& 0x01)
382 palette
[index_to_palette
[j
]] = palette
[num_new_palette
];
387 for (k
= 0; k
< num_palette
; k
++)
389 if (png_ptr
->dither_index
[k
] ==
391 png_ptr
->dither_index
[k
] =
392 index_to_palette
[next_j
];
393 if ((int)png_ptr
->dither_index
[k
] ==
395 png_ptr
->dither_index
[k
] =
400 index_to_palette
[palette_to_index
[num_new_palette
]] =
402 palette_to_index
[index_to_palette
[j
]] =
403 palette_to_index
[num_new_palette
];
405 index_to_palette
[j
] = (png_byte
)num_new_palette
;
406 palette_to_index
[num_new_palette
] = (png_byte
)j
;
408 if (num_new_palette
<= maximum_colors
)
411 if (num_new_palette
<= maximum_colors
)
416 for (i
= 0; i
< 769; i
++)
420 png_dsortp p
= hash
[i
];
426 png_free(png_ptr
, p
);
434 png_free(png_ptr
, hash
);
435 png_free(png_ptr
, palette_to_index
);
436 png_free(png_ptr
, index_to_palette
);
438 num_palette
= maximum_colors
;
440 if (png_ptr
->palette
== NULL
)
442 png_ptr
->palette
= palette
;
444 png_ptr
->num_palette
= (png_uint_16
)num_palette
;
450 int total_bits
= PNG_DITHER_RED_BITS
+ PNG_DITHER_GREEN_BITS
+
451 PNG_DITHER_BLUE_BITS
;
452 int num_red
= (1 << PNG_DITHER_RED_BITS
);
453 int num_green
= (1 << PNG_DITHER_GREEN_BITS
);
454 int num_blue
= (1 << PNG_DITHER_BLUE_BITS
);
455 png_size_t num_entries
= ((png_size_t
)1 << total_bits
);
457 png_ptr
->palette_lookup
= (png_bytep
)png_malloc(png_ptr
,
458 (png_uint_32
)(num_entries
* sizeof (png_byte
)));
460 png_memset(png_ptr
->palette_lookup
, 0, num_entries
* sizeof (png_byte
));
462 distance
= (png_bytep
)png_malloc(png_ptr
, (png_uint_32
)(num_entries
*
465 png_memset(distance
, 0xff, num_entries
* sizeof(png_byte
));
467 for (i
= 0; i
< num_palette
; i
++)
470 int r
= (palette
[i
].red
>> (8 - PNG_DITHER_RED_BITS
));
471 int g
= (palette
[i
].green
>> (8 - PNG_DITHER_GREEN_BITS
));
472 int b
= (palette
[i
].blue
>> (8 - PNG_DITHER_BLUE_BITS
));
474 for (ir
= 0; ir
< num_red
; ir
++)
476 int dr
= abs(ir
- r
);
477 int index_r
= (ir
<< (PNG_DITHER_BLUE_BITS
+ PNG_DITHER_GREEN_BITS
));
479 for (ig
= 0; ig
< num_green
; ig
++)
481 int dg
= abs(ig
- g
);
483 int dm
= ((dr
> dg
) ? dr
: dg
);
484 int index_g
= index_r
| (ig
<< PNG_DITHER_BLUE_BITS
);
486 for (ib
= 0; ib
< num_blue
; ib
++)
488 int d_index
= index_g
| ib
;
489 int db
= abs(ib
- b
);
490 int dmax
= ((dm
> db
) ? dm
: db
);
491 int d
= dmax
+ dt
+ db
;
493 if (d
< (int)distance
[d_index
])
495 distance
[d_index
] = (png_byte
)d
;
496 png_ptr
->palette_lookup
[d_index
] = (png_byte
)i
;
503 png_free(png_ptr
, distance
);
508 #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
509 /* Transform the image from the file_gamma to the screen_gamma. We
510 * only do transformations on images where the file_gamma and screen_gamma
511 * are not close reciprocals, otherwise it slows things down slightly, and
512 * also needlessly introduces small errors.
515 png_set_gamma(png_structp png_ptr
, double scrn_gamma
, double file_gamma
)
517 png_debug(1, "in png_set_gamma\n");
518 if (fabs(scrn_gamma
* file_gamma
- 1.0) > PNG_GAMMA_THRESHOLD
)
519 png_ptr
->transformations
|= PNG_GAMMA
;
520 png_ptr
->gamma
= (float)file_gamma
;
521 png_ptr
->screen_gamma
= (float)scrn_gamma
;
525 #if defined(PNG_READ_EXPAND_SUPPORTED)
526 /* Expand paletted images to RGB, expand grayscale images of
527 * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
531 png_set_expand(png_structp png_ptr
)
533 png_debug(1, "in png_set_expand\n");
534 png_ptr
->transformations
|= PNG_EXPAND
;
537 /* GRR 19990627: the following three functions currently are identical
538 * to png_set_expand(). However, it is entirely reasonable that someone
539 * might wish to expand an indexed image to RGB but *not* expand a single,
540 * fully transparent palette entry to a full alpha channel--perhaps instead
541 * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
542 * the transparent color with a particular RGB value, or drop tRNS entirely.
543 * IOW, a future version of the library may make the transformations flag
544 * a bit more fine-grained, with separate bits for each of these three
547 * More to the point, these functions make it obvious what libpng will be
548 * doing, whereas "expand" can (and does) mean any number of things.
551 /* Expand paletted images to RGB. */
553 png_set_palette_to_rgb(png_structp png_ptr
)
555 png_debug(1, "in png_set_expand\n");
556 png_ptr
->transformations
|= PNG_EXPAND
;
559 /* Expand grayscale images of less than 8-bit depth to 8 bits. */
561 png_set_gray_1_2_4_to_8(png_structp png_ptr
)
563 png_debug(1, "in png_set_expand\n");
564 png_ptr
->transformations
|= PNG_EXPAND
;
567 /* Expand tRNS chunks to alpha channels. */
569 png_set_tRNS_to_alpha(png_structp png_ptr
)
571 png_debug(1, "in png_set_expand\n");
572 png_ptr
->transformations
|= PNG_EXPAND
;
574 #endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
576 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
578 png_set_gray_to_rgb(png_structp png_ptr
)
580 png_debug(1, "in png_set_gray_to_rgb\n");
581 png_ptr
->transformations
|= PNG_GRAY_TO_RGB
;
585 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
586 #if defined(PNG_FLOATING_POINT_SUPPORTED)
587 /* Convert a RGB image to a grayscale of the same width. This allows us,
588 * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
592 png_set_rgb_to_gray(png_structp png_ptr
, int error_action
, double red
,
595 int red_fixed
= (int)((float)red
*100000.0 + 0.5);
596 int green_fixed
= (int)((float)green
*100000.0 + 0.5);
597 png_set_rgb_to_gray_fixed(png_ptr
, error_action
, red_fixed
, green_fixed
);
602 png_set_rgb_to_gray_fixed(png_structp png_ptr
, int error_action
,
603 png_fixed_point red
, png_fixed_point green
)
605 png_debug(1, "in png_set_rgb_to_gray\n");
608 case 1: png_ptr
->transformations
|= PNG_RGB_TO_GRAY
;
610 case 2: png_ptr
->transformations
|= PNG_RGB_TO_GRAY_WARN
;
612 case 3: png_ptr
->transformations
|= PNG_RGB_TO_GRAY_ERR
;
614 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
615 #if defined(PNG_READ_EXPAND_SUPPORTED)
616 png_ptr
->transformations
|= PNG_EXPAND
;
619 png_warning(png_ptr
, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
620 png_ptr
->transformations
&= ~PNG_RGB_TO_GRAY
;
624 png_uint_16 red_int
, green_int
;
625 if(red
< 0 || green
< 0)
627 red_int
= 6968; /* .212671 * 32768 + .5 */
628 green_int
= 23434; /* .715160 * 32768 + .5 */
630 else if(red
+ green
< 100000L)
632 red_int
= (png_uint_16
)(((png_uint_32
)red
*32768L)/100000L);
633 green_int
= (png_uint_16
)(((png_uint_32
)green
*32768L)/100000L);
637 png_warning(png_ptr
, "ignoring out of range rgb_to_gray coefficients");
641 png_ptr
->rgb_to_gray_red_coeff
= red_int
;
642 png_ptr
->rgb_to_gray_green_coeff
= green_int
;
643 png_ptr
->rgb_to_gray_blue_coeff
= (png_uint_16
)(32768-red_int
-green_int
);
648 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
649 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
650 defined(PNG_LEGACY_SUPPORTED)
652 png_set_read_user_transform_fn(png_structp png_ptr
, png_user_transform_ptr
653 read_user_transform_fn
)
655 png_debug(1, "in png_set_read_user_transform_fn\n");
656 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
657 png_ptr
->transformations
|= PNG_USER_TRANSFORM
;
658 png_ptr
->read_user_transform_fn
= read_user_transform_fn
;
660 #ifdef PNG_LEGACY_SUPPORTED
661 if(read_user_transform_fn
)
663 "This version of libpng does not support user transforms");
668 /* Initialize everything needed for the read. This includes modifying
672 png_init_read_transformations(png_structp png_ptr
)
674 png_debug(1, "in png_init_read_transformations\n");
675 #if defined(PNG_USELESS_TESTS_SUPPORTED)
679 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
680 || defined(PNG_READ_GAMMA_SUPPORTED)
681 int color_type
= png_ptr
->color_type
;
684 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
685 if ((png_ptr
->transformations
& PNG_BACKGROUND_EXPAND
) &&
686 (png_ptr
->transformations
& PNG_EXPAND
))
688 if (!(color_type
& PNG_COLOR_MASK_COLOR
)) /* i.e., GRAY or GRAY_ALPHA */
690 /* expand background chunk. */
691 switch (png_ptr
->bit_depth
)
694 png_ptr
->background
.gray
*= (png_uint_16
)0xff;
695 png_ptr
->background
.red
= png_ptr
->background
.green
=
696 png_ptr
->background
.blue
= png_ptr
->background
.gray
;
699 png_ptr
->background
.gray
*= (png_uint_16
)0x55;
700 png_ptr
->background
.red
= png_ptr
->background
.green
=
701 png_ptr
->background
.blue
= png_ptr
->background
.gray
;
704 png_ptr
->background
.gray
*= (png_uint_16
)0x11;
705 png_ptr
->background
.red
= png_ptr
->background
.green
=
706 png_ptr
->background
.blue
= png_ptr
->background
.gray
;
710 png_ptr
->background
.red
= png_ptr
->background
.green
=
711 png_ptr
->background
.blue
= png_ptr
->background
.gray
;
715 else if (color_type
== PNG_COLOR_TYPE_PALETTE
)
717 png_ptr
->background
.red
=
718 png_ptr
->palette
[png_ptr
->background
.index
].red
;
719 png_ptr
->background
.green
=
720 png_ptr
->palette
[png_ptr
->background
.index
].green
;
721 png_ptr
->background
.blue
=
722 png_ptr
->palette
[png_ptr
->background
.index
].blue
;
724 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
725 if (png_ptr
->transformations
& PNG_INVERT_ALPHA
)
727 #if defined(PNG_READ_EXPAND_SUPPORTED)
728 if (!(png_ptr
->transformations
& PNG_EXPAND
))
731 /* invert the alpha channel (in tRNS) unless the pixels are
732 going to be expanded, in which case leave it for later */
734 istop
=(int)png_ptr
->num_trans
;
735 for (i
=0; i
<istop
; i
++)
736 png_ptr
->trans
[i
] = (png_byte
)(255 - png_ptr
->trans
[i
]);
745 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
746 png_ptr
->background_1
= png_ptr
->background
;
748 #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
749 if (png_ptr
->transformations
& (PNG_GAMMA
| PNG_RGB_TO_GRAY
))
751 png_build_gamma_table(png_ptr
);
752 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
753 if (png_ptr
->transformations
& PNG_BACKGROUND
)
755 if (color_type
== PNG_COLOR_TYPE_PALETTE
)
757 png_color back
, back_1
;
758 png_colorp palette
= png_ptr
->palette
;
759 int num_palette
= png_ptr
->num_palette
;
761 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_FILE
)
763 back
.red
= png_ptr
->gamma_table
[png_ptr
->background
.red
];
764 back
.green
= png_ptr
->gamma_table
[png_ptr
->background
.green
];
765 back
.blue
= png_ptr
->gamma_table
[png_ptr
->background
.blue
];
767 back_1
.red
= png_ptr
->gamma_to_1
[png_ptr
->background
.red
];
768 back_1
.green
= png_ptr
->gamma_to_1
[png_ptr
->background
.green
];
769 back_1
.blue
= png_ptr
->gamma_to_1
[png_ptr
->background
.blue
];
775 switch (png_ptr
->background_gamma_type
)
777 case PNG_BACKGROUND_GAMMA_SCREEN
:
778 g
= (png_ptr
->screen_gamma
);
781 case PNG_BACKGROUND_GAMMA_FILE
:
782 g
= 1.0 / (png_ptr
->gamma
);
783 gs
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
785 case PNG_BACKGROUND_GAMMA_UNIQUE
:
786 g
= 1.0 / (png_ptr
->background_gamma
);
787 gs
= 1.0 / (png_ptr
->background_gamma
*
788 png_ptr
->screen_gamma
);
791 g
= 1.0; /* back_1 */
795 if ( fabs(gs
- 1.0) < PNG_GAMMA_THRESHOLD
)
797 back
.red
= (png_byte
)png_ptr
->background
.red
;
798 back
.green
= (png_byte
)png_ptr
->background
.green
;
799 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
803 back
.red
= (png_byte
)(pow(
804 (double)png_ptr
->background
.red
/255, gs
) * 255.0 + .5);
805 back
.green
= (png_byte
)(pow(
806 (double)png_ptr
->background
.green
/255, gs
) * 255.0 + .5);
807 back
.blue
= (png_byte
)(pow(
808 (double)png_ptr
->background
.blue
/255, gs
) * 255.0 + .5);
811 back_1
.red
= (png_byte
)(pow(
812 (double)png_ptr
->background
.red
/255, g
) * 255.0 + .5);
813 back_1
.green
= (png_byte
)(pow(
814 (double)png_ptr
->background
.green
/255, g
) * 255.0 + .5);
815 back_1
.blue
= (png_byte
)(pow(
816 (double)png_ptr
->background
.blue
/255, g
) * 255.0 + .5);
818 for (i
= 0; i
< num_palette
; i
++)
820 if (i
< (int)png_ptr
->num_trans
&& png_ptr
->trans
[i
] != 0xff)
822 if (png_ptr
->trans
[i
] == 0)
826 else /* if (png_ptr->trans[i] != 0xff) */
830 v
= png_ptr
->gamma_to_1
[palette
[i
].red
];
831 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.red
);
832 palette
[i
].red
= png_ptr
->gamma_from_1
[w
];
834 v
= png_ptr
->gamma_to_1
[palette
[i
].green
];
835 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.green
);
836 palette
[i
].green
= png_ptr
->gamma_from_1
[w
];
838 v
= png_ptr
->gamma_to_1
[palette
[i
].blue
];
839 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.blue
);
840 palette
[i
].blue
= png_ptr
->gamma_from_1
[w
];
845 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
846 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
847 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
851 /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN)*/
853 /* color_type != PNG_COLOR_TYPE_PALETTE */
855 double m
= (double)(((png_uint_32
)1 << png_ptr
->bit_depth
) - 1);
859 switch (png_ptr
->background_gamma_type
)
861 case PNG_BACKGROUND_GAMMA_SCREEN
:
862 g
= (png_ptr
->screen_gamma
);
865 case PNG_BACKGROUND_GAMMA_FILE
:
866 g
= 1.0 / (png_ptr
->gamma
);
867 gs
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
869 case PNG_BACKGROUND_GAMMA_UNIQUE
:
870 g
= 1.0 / (png_ptr
->background_gamma
);
871 gs
= 1.0 / (png_ptr
->background_gamma
*
872 png_ptr
->screen_gamma
);
876 if (color_type
& PNG_COLOR_MASK_COLOR
)
879 png_ptr
->background_1
.red
= (png_uint_16
)(pow(
880 (double)png_ptr
->background
.red
/ m
, g
) * m
+ .5);
881 png_ptr
->background_1
.green
= (png_uint_16
)(pow(
882 (double)png_ptr
->background
.green
/ m
, g
) * m
+ .5);
883 png_ptr
->background_1
.blue
= (png_uint_16
)(pow(
884 (double)png_ptr
->background
.blue
/ m
, g
) * m
+ .5);
885 png_ptr
->background
.red
= (png_uint_16
)(pow(
886 (double)png_ptr
->background
.red
/ m
, gs
) * m
+ .5);
887 png_ptr
->background
.green
= (png_uint_16
)(pow(
888 (double)png_ptr
->background
.green
/ m
, gs
) * m
+ .5);
889 png_ptr
->background
.blue
= (png_uint_16
)(pow(
890 (double)png_ptr
->background
.blue
/ m
, gs
) * m
+ .5);
894 /* GRAY or GRAY ALPHA */
895 png_ptr
->background_1
.gray
= (png_uint_16
)(pow(
896 (double)png_ptr
->background
.gray
/ m
, g
) * m
+ .5);
897 png_ptr
->background
.gray
= (png_uint_16
)(pow(
898 (double)png_ptr
->background
.gray
/ m
, gs
) * m
+ .5);
903 /* transformation does not include PNG_BACKGROUND */
905 if (color_type
== PNG_COLOR_TYPE_PALETTE
)
907 png_colorp palette
= png_ptr
->palette
;
908 int num_palette
= png_ptr
->num_palette
;
911 for (i
= 0; i
< num_palette
; i
++)
913 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
914 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
915 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
919 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
923 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
924 /* No GAMMA transformation */
925 if ((png_ptr
->transformations
& PNG_BACKGROUND
) &&
926 (color_type
== PNG_COLOR_TYPE_PALETTE
))
929 int istop
= (int)png_ptr
->num_trans
;
931 png_colorp palette
= png_ptr
->palette
;
933 back
.red
= (png_byte
)png_ptr
->background
.red
;
934 back
.green
= (png_byte
)png_ptr
->background
.green
;
935 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
937 for (i
= 0; i
< istop
; i
++)
939 if (png_ptr
->trans
[i
] == 0)
943 else if (png_ptr
->trans
[i
] != 0xff)
945 /* The png_composite() macro is defined in png.h */
946 png_composite(palette
[i
].red
, palette
[i
].red
,
947 png_ptr
->trans
[i
], back
.red
);
948 png_composite(palette
[i
].green
, palette
[i
].green
,
949 png_ptr
->trans
[i
], back
.green
);
950 png_composite(palette
[i
].blue
, palette
[i
].blue
,
951 png_ptr
->trans
[i
], back
.blue
);
957 #if defined(PNG_READ_SHIFT_SUPPORTED)
958 if ((png_ptr
->transformations
& PNG_SHIFT
) &&
959 (color_type
== PNG_COLOR_TYPE_PALETTE
))
962 png_uint_16 istop
= png_ptr
->num_palette
;
963 int sr
= 8 - png_ptr
->sig_bit
.red
;
964 int sg
= 8 - png_ptr
->sig_bit
.green
;
965 int sb
= 8 - png_ptr
->sig_bit
.blue
;
967 if (sr
< 0 || sr
> 8)
969 if (sg
< 0 || sg
> 8)
971 if (sb
< 0 || sb
> 8)
973 for (i
= 0; i
< istop
; i
++)
975 png_ptr
->palette
[i
].red
>>= sr
;
976 png_ptr
->palette
[i
].green
>>= sg
;
977 png_ptr
->palette
[i
].blue
>>= sb
;
982 #if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
983 && !defined(PNG_READ_BACKGROUND_SUPPORTED)
989 /* Modify the info structure to reflect the transformations. The
990 * info should be updated so a PNG file could be written with it,
991 * assuming the transformations result in valid PNG data.
994 png_read_transform_info(png_structp png_ptr
, png_infop info_ptr
)
996 png_debug(1, "in png_read_transform_info\n");
997 #if defined(PNG_READ_EXPAND_SUPPORTED)
998 if (png_ptr
->transformations
& PNG_EXPAND
)
1000 if (info_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1002 if (png_ptr
->num_trans
)
1003 info_ptr
->color_type
= PNG_COLOR_TYPE_RGB_ALPHA
;
1005 info_ptr
->color_type
= PNG_COLOR_TYPE_RGB
;
1006 info_ptr
->bit_depth
= 8;
1007 info_ptr
->num_trans
= 0;
1011 if (png_ptr
->num_trans
)
1012 info_ptr
->color_type
|= PNG_COLOR_MASK_ALPHA
;
1013 if (info_ptr
->bit_depth
< 8)
1014 info_ptr
->bit_depth
= 8;
1015 info_ptr
->num_trans
= 0;
1020 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1021 if (png_ptr
->transformations
& PNG_BACKGROUND
)
1023 info_ptr
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
1024 info_ptr
->num_trans
= 0;
1025 info_ptr
->background
= png_ptr
->background
;
1029 #if defined(PNG_READ_GAMMA_SUPPORTED)
1030 if (png_ptr
->transformations
& PNG_GAMMA
)
1032 #ifdef PNG_FLOATING_POINT_SUPPORTED
1033 info_ptr
->gamma
= png_ptr
->gamma
;
1035 #ifdef PNG_FIXED_POINT_SUPPORTED
1036 info_ptr
->int_gamma
= png_ptr
->int_gamma
;
1041 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1042 if ((png_ptr
->transformations
& PNG_16_TO_8
) && (info_ptr
->bit_depth
== 16))
1043 info_ptr
->bit_depth
= 8;
1046 #if defined(PNG_READ_DITHER_SUPPORTED)
1047 if (png_ptr
->transformations
& PNG_DITHER
)
1049 if (((info_ptr
->color_type
== PNG_COLOR_TYPE_RGB
) ||
1050 (info_ptr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)) &&
1051 png_ptr
->palette_lookup
&& info_ptr
->bit_depth
== 8)
1053 info_ptr
->color_type
= PNG_COLOR_TYPE_PALETTE
;
1058 #if defined(PNG_READ_PACK_SUPPORTED)
1059 if ((png_ptr
->transformations
& PNG_PACK
) && (info_ptr
->bit_depth
< 8))
1060 info_ptr
->bit_depth
= 8;
1063 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1064 if (png_ptr
->transformations
& PNG_GRAY_TO_RGB
)
1065 info_ptr
->color_type
|= PNG_COLOR_MASK_COLOR
;
1068 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1069 if (png_ptr
->transformations
& PNG_RGB_TO_GRAY
)
1070 info_ptr
->color_type
&= ~PNG_COLOR_MASK_COLOR
;
1073 if (info_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1074 info_ptr
->channels
= 1;
1075 else if (info_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
1076 info_ptr
->channels
= 3;
1078 info_ptr
->channels
= 1;
1080 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1081 if (png_ptr
->transformations
& PNG_STRIP_ALPHA
)
1082 info_ptr
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
1085 if (info_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
)
1086 info_ptr
->channels
++;
1088 #if defined(PNG_READ_FILLER_SUPPORTED)
1089 /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
1090 if ((png_ptr
->transformations
& PNG_FILLER
) &&
1091 ((info_ptr
->color_type
== PNG_COLOR_TYPE_RGB
) ||
1092 (info_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)))
1094 info_ptr
->channels
++;
1095 #if 0 /* if adding a true alpha channel not just filler */
1096 info_ptr
->color_type
|= PNG_COLOR_MASK_ALPHA
;
1101 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
1102 defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1103 if(png_ptr
->transformations
& PNG_USER_TRANSFORM
)
1105 if(info_ptr
->bit_depth
< png_ptr
->user_transform_depth
)
1106 info_ptr
->bit_depth
= png_ptr
->user_transform_depth
;
1107 if(info_ptr
->channels
< png_ptr
->user_transform_channels
)
1108 info_ptr
->channels
= png_ptr
->user_transform_channels
;
1112 info_ptr
->pixel_depth
= (png_byte
)(info_ptr
->channels
*
1113 info_ptr
->bit_depth
);
1114 info_ptr
->rowbytes
= ((info_ptr
->width
* info_ptr
->pixel_depth
+ 7) >> 3);
1116 #if !defined(PNG_READ_EXPAND_SUPPORTED)
1122 /* Transform the row. The order of transformations is significant,
1123 * and is very touchy. If you add a transformation, take care to
1124 * decide how it fits in with the other transformations here.
1127 png_do_read_transformations(png_structp png_ptr
)
1129 png_debug(1, "in png_do_read_transformations\n");
1130 #if !defined(PNG_USELESS_TESTS_SUPPORTED)
1131 if (png_ptr
->row_buf
== NULL
)
1133 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
1136 sprintf(msg
, "NULL row buffer for row %ld, pass %d", png_ptr
->row_number
,
1138 png_error(png_ptr
, msg
);
1140 png_error(png_ptr
, "NULL row buffer");
1145 #if defined(PNG_READ_EXPAND_SUPPORTED)
1146 if (png_ptr
->transformations
& PNG_EXPAND
)
1148 if (png_ptr
->row_info
.color_type
== PNG_COLOR_TYPE_PALETTE
)
1150 png_do_expand_palette(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1151 png_ptr
->palette
, png_ptr
->trans
, png_ptr
->num_trans
);
1155 if (png_ptr
->num_trans
)
1156 png_do_expand(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1157 &(png_ptr
->trans_values
));
1159 png_do_expand(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1165 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1166 if (png_ptr
->transformations
& PNG_STRIP_ALPHA
)
1167 png_do_strip_filler(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1168 PNG_FLAG_FILLER_AFTER
);
1171 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1172 if (png_ptr
->transformations
& PNG_RGB_TO_GRAY
)
1175 png_do_rgb_to_gray(png_ptr
, &(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1178 png_ptr
->rgb_to_gray_status
=1;
1179 if(png_ptr
->transformations
== PNG_RGB_TO_GRAY_WARN
)
1180 png_warning(png_ptr
, "png_do_rgb_to_gray found nongray pixel");
1181 if(png_ptr
->transformations
== PNG_RGB_TO_GRAY_ERR
)
1182 png_error(png_ptr
, "png_do_rgb_to_gray found nongray pixel");
1188 From Andreas Dilger e-mail to png-implement, 26 March 1998:
1190 In most cases, the "simple transparency" should be done prior to doing
1191 gray-to-RGB, or you will have to test 3x as many bytes to check if a
1192 pixel is transparent. You would also need to make sure that the
1193 transparency information is upgraded to RGB.
1195 To summarize, the current flow is:
1196 - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
1197 with background "in place" if transparent,
1198 convert to RGB if necessary
1199 - Gray + alpha -> composite with gray background and remove alpha bytes,
1200 convert to RGB if necessary
1202 To support RGB backgrounds for gray images we need:
1203 - Gray + simple transparency -> convert to RGB + simple transparency, compare
1204 3 or 6 bytes and composite with background
1205 "in place" if transparent (3x compare/pixel
1206 compared to doing composite with gray bkgrnd)
1207 - Gray + alpha -> convert to RGB + alpha, composite with background and
1208 remove alpha bytes (3x float operations/pixel
1209 compared with composite on gray background)
1211 Greg's change will do this. The reason it wasn't done before is for
1212 performance, as this increases the per-pixel operations. If we would check
1213 in advance if the background was gray or RGB, and position the gray-to-RGB
1214 transform appropriately, then it would save a lot of work/time.
1217 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1218 /* if gray -> RGB, do so now only if background is non-gray; else do later
1219 * for performance reasons */
1220 if ((png_ptr
->transformations
& PNG_GRAY_TO_RGB
) &&
1221 !(png_ptr
->mode
& PNG_BACKGROUND_IS_GRAY
))
1222 png_do_gray_to_rgb(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1225 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1226 if ((png_ptr
->transformations
& PNG_BACKGROUND
) &&
1227 ((png_ptr
->num_trans
!= 0 ) ||
1228 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
)))
1229 png_do_background(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1230 &(png_ptr
->trans_values
), &(png_ptr
->background
),
1231 &(png_ptr
->background_1
),
1232 png_ptr
->gamma_table
, png_ptr
->gamma_from_1
,
1233 png_ptr
->gamma_to_1
, png_ptr
->gamma_16_table
,
1234 png_ptr
->gamma_16_from_1
, png_ptr
->gamma_16_to_1
,
1235 png_ptr
->gamma_shift
);
1238 #if defined(PNG_READ_GAMMA_SUPPORTED)
1239 if ((png_ptr
->transformations
& PNG_GAMMA
) &&
1240 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1241 !((png_ptr
->transformations
& PNG_BACKGROUND
) &&
1242 ((png_ptr
->num_trans
!= 0) ||
1243 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
))) &&
1245 (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
))
1246 png_do_gamma(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1247 png_ptr
->gamma_table
, png_ptr
->gamma_16_table
,
1248 png_ptr
->gamma_shift
);
1251 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1252 if (png_ptr
->transformations
& PNG_16_TO_8
)
1253 png_do_chop(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1256 #if defined(PNG_READ_DITHER_SUPPORTED)
1257 if (png_ptr
->transformations
& PNG_DITHER
)
1259 png_do_dither((png_row_infop
)&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1260 png_ptr
->palette_lookup
, png_ptr
->dither_index
);
1261 if(png_ptr
->row_info
.rowbytes
== (png_uint_32
)0)
1262 png_error(png_ptr
, "png_do_dither returned rowbytes=0");
1266 #if defined(PNG_READ_INVERT_SUPPORTED)
1267 if (png_ptr
->transformations
& PNG_INVERT_MONO
)
1268 png_do_invert(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1271 #if defined(PNG_READ_SHIFT_SUPPORTED)
1272 if (png_ptr
->transformations
& PNG_SHIFT
)
1273 png_do_unshift(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1277 #if defined(PNG_READ_PACK_SUPPORTED)
1278 if (png_ptr
->transformations
& PNG_PACK
)
1279 png_do_unpack(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1282 #if defined(PNG_READ_BGR_SUPPORTED)
1283 if (png_ptr
->transformations
& PNG_BGR
)
1284 png_do_bgr(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1287 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1288 if (png_ptr
->transformations
& PNG_PACKSWAP
)
1289 png_do_packswap(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1292 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1293 /* if gray -> RGB, do so now only if we did not do so above */
1294 if ((png_ptr
->transformations
& PNG_GRAY_TO_RGB
) &&
1295 (png_ptr
->mode
& PNG_BACKGROUND_IS_GRAY
))
1296 png_do_gray_to_rgb(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1299 #if defined(PNG_READ_FILLER_SUPPORTED)
1300 if (png_ptr
->transformations
& PNG_FILLER
)
1301 png_do_read_filler(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1302 (png_uint_32
)png_ptr
->filler
, png_ptr
->flags
);
1305 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1306 if (png_ptr
->transformations
& PNG_INVERT_ALPHA
)
1307 png_do_read_invert_alpha(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1310 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1311 if (png_ptr
->transformations
& PNG_SWAP_ALPHA
)
1312 png_do_read_swap_alpha(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1315 #if defined(PNG_READ_SWAP_SUPPORTED)
1316 if (png_ptr
->transformations
& PNG_SWAP_BYTES
)
1317 png_do_swap(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1320 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1321 if (png_ptr
->transformations
& PNG_USER_TRANSFORM
)
1323 if(png_ptr
->read_user_transform_fn
!= NULL
)
1324 (*(png_ptr
->read_user_transform_fn
)) /* user read transform function */
1325 (png_ptr
, /* png_ptr */
1326 &(png_ptr
->row_info
), /* row_info: */
1327 /* png_uint_32 width; width of row */
1328 /* png_uint_32 rowbytes; number of bytes in row */
1329 /* png_byte color_type; color type of pixels */
1330 /* png_byte bit_depth; bit depth of samples */
1331 /* png_byte channels; number of channels (1-4) */
1332 /* png_byte pixel_depth; bits per pixel (depth*channels) */
1333 png_ptr
->row_buf
+ 1); /* start of pixel data for row */
1334 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
1335 if(png_ptr
->user_transform_depth
)
1336 png_ptr
->row_info
.bit_depth
= png_ptr
->user_transform_depth
;
1337 if(png_ptr
->user_transform_channels
)
1338 png_ptr
->row_info
.channels
= png_ptr
->user_transform_channels
;
1340 png_ptr
->row_info
.pixel_depth
= (png_byte
)(png_ptr
->row_info
.bit_depth
*
1341 png_ptr
->row_info
.channels
);
1342 png_ptr
->row_info
.rowbytes
= (png_ptr
->row_info
.width
*
1343 png_ptr
->row_info
.pixel_depth
+7)>>3;
1349 #if defined(PNG_READ_PACK_SUPPORTED)
1350 /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
1351 * without changing the actual values. Thus, if you had a row with
1352 * a bit depth of 1, you would end up with bytes that only contained
1353 * the numbers 0 or 1. If you would rather they contain 0 and 255, use
1354 * png_do_shift() after this.
1357 png_do_unpack(png_row_infop row_info
, png_bytep row
)
1359 png_debug(1, "in png_do_unpack\n");
1360 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1361 if (row
!= NULL
&& row_info
!= NULL
&& row_info
->bit_depth
< 8)
1363 if (row_info
->bit_depth
< 8)
1367 png_uint_32 row_width
=row_info
->width
;
1369 switch (row_info
->bit_depth
)
1373 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
1374 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1375 png_uint_32 shift
= 7 - (int)((row_width
+ 7) & 0x07);
1376 for (i
= 0; i
< row_width
; i
++)
1378 *dp
= (png_byte
)((*sp
>> shift
) & 0x01);
1394 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
1395 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1396 png_uint_32 shift
= (int)((3 - ((row_width
+ 3) & 0x03)) << 1);
1397 for (i
= 0; i
< row_width
; i
++)
1399 *dp
= (png_byte
)((*sp
>> shift
) & 0x03);
1414 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
1415 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1416 png_uint_32 shift
= (int)((1 - ((row_width
+ 1) & 0x01)) << 2);
1417 for (i
= 0; i
< row_width
; i
++)
1419 *dp
= (png_byte
)((*sp
>> shift
) & 0x0f);
1433 row_info
->bit_depth
= 8;
1434 row_info
->pixel_depth
= (png_byte
)(8 * row_info
->channels
);
1435 row_info
->rowbytes
= row_width
* row_info
->channels
;
1440 #if defined(PNG_READ_SHIFT_SUPPORTED)
1441 /* Reverse the effects of png_do_shift. This routine merely shifts the
1442 * pixels back to their significant bits values. Thus, if you have
1443 * a row of bit depth 8, but only 5 are significant, this will shift
1444 * the values back to 0 through 31.
1447 png_do_unshift(png_row_infop row_info
, png_bytep row
, png_color_8p sig_bits
)
1449 png_debug(1, "in png_do_unshift\n");
1451 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1452 row
!= NULL
&& row_info
!= NULL
&& sig_bits
!= NULL
&&
1454 row_info
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
1459 png_uint_16 value
= 0;
1460 png_uint_32 row_width
= row_info
->width
;
1462 if (row_info
->color_type
& PNG_COLOR_MASK_COLOR
)
1464 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->red
;
1465 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->green
;
1466 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->blue
;
1470 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->gray
;
1472 if (row_info
->color_type
& PNG_COLOR_MASK_ALPHA
)
1474 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->alpha
;
1477 for (c
= 0; c
< channels
; c
++)
1488 switch (row_info
->bit_depth
)
1494 png_uint_32 istop
= row_info
->rowbytes
;
1496 for (bp
= row
, i
= 0; i
< istop
; i
++)
1507 png_uint_32 istop
= row_info
->rowbytes
;
1508 png_byte mask
= (png_byte
)((((int)0xf0 >> shift
[0]) & (int)0xf0) |
1509 (png_byte
)((int)0xf >> shift
[0]));
1511 for (i
= 0; i
< istop
; i
++)
1522 png_uint_32 istop
= row_width
* channels
;
1524 for (i
= 0; i
< istop
; i
++)
1526 *bp
++ >>= shift
[i
%channels
];
1534 png_uint_32 istop
= channels
* row_width
;
1536 for (i
= 0; i
< istop
; i
++)
1538 value
= (png_uint_16
)((*bp
<< 8) + *(bp
+ 1));
1539 value
>>= shift
[i
%channels
];
1540 *bp
++ = (png_byte
)(value
>> 8);
1541 *bp
++ = (png_byte
)(value
& 0xff);
1550 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1551 /* chop rows of bit depth 16 down to 8 */
1553 png_do_chop(png_row_infop row_info
, png_bytep row
)
1555 png_debug(1, "in png_do_chop\n");
1556 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1557 if (row
!= NULL
&& row_info
!= NULL
&& row_info
->bit_depth
== 16)
1559 if (row_info
->bit_depth
== 16)
1565 png_uint_32 istop
= row_info
->width
* row_info
->channels
;
1567 for (i
= 0; i
<istop
; i
++, sp
+= 2, dp
++)
1569 #if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
1570 /* This does a more accurate scaling of the 16-bit color
1571 * value, rather than a simple low-byte truncation.
1573 * What the ideal calculation should be:
1574 * *dp = (((((png_uint_32)(*sp) << 8) |
1575 * (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L;
1577 * GRR: no, I think this is what it really should be:
1578 * *dp = (((((png_uint_32)(*sp) << 8) |
1579 * (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L;
1581 * GRR: here's the exact calculation with shifts:
1582 * temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L;
1583 * *dp = (temp - (temp >> 8)) >> 8;
1585 * Approximate calculation with shift/add instead of multiply/divide:
1586 * *dp = ((((png_uint_32)(*sp) << 8) |
1587 * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
1589 * What we actually do to avoid extra shifting and conversion:
1592 *dp
= *sp
+ ((((int)(*(sp
+ 1)) - *sp
) > 128) ? 1 : 0);
1594 /* Simply discard the low order byte */
1598 row_info
->bit_depth
= 8;
1599 row_info
->pixel_depth
= (png_byte
)(8 * row_info
->channels
);
1600 row_info
->rowbytes
= row_info
->width
* row_info
->channels
;
1605 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1607 png_do_read_swap_alpha(png_row_infop row_info
, png_bytep row
)
1609 png_debug(1, "in png_do_read_swap_alpha\n");
1610 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1611 if (row
!= NULL
&& row_info
!= NULL
)
1614 png_uint_32 row_width
= row_info
->width
;
1615 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
1617 /* This converts from RGBA to ARGB */
1618 if (row_info
->bit_depth
== 8)
1620 png_bytep sp
= row
+ row_info
->rowbytes
;
1625 for (i
= 0; i
< row_width
; i
++)
1634 /* This converts from RRGGBBAA to AARRGGBB */
1637 png_bytep sp
= row
+ row_info
->rowbytes
;
1642 for (i
= 0; i
< row_width
; i
++)
1657 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
1659 /* This converts from GA to AG */
1660 if (row_info
->bit_depth
== 8)
1662 png_bytep sp
= row
+ row_info
->rowbytes
;
1667 for (i
= 0; i
< row_width
; i
++)
1674 /* This converts from GGAA to AAGG */
1677 png_bytep sp
= row
+ row_info
->rowbytes
;
1682 for (i
= 0; i
< row_width
; i
++)
1697 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1699 png_do_read_invert_alpha(png_row_infop row_info
, png_bytep row
)
1701 png_debug(1, "in png_do_read_invert_alpha\n");
1702 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1703 if (row
!= NULL
&& row_info
!= NULL
)
1706 png_uint_32 row_width
= row_info
->width
;
1707 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
1709 /* This inverts the alpha channel in RGBA */
1710 if (row_info
->bit_depth
== 8)
1712 png_bytep sp
= row
+ row_info
->rowbytes
;
1716 for (i
= 0; i
< row_width
; i
++)
1718 *(--dp
) = (png_byte
)(255 - *(--sp
));
1720 /* This does nothing:
1724 We can replace it with:
1730 /* This inverts the alpha channel in RRGGBBAA */
1733 png_bytep sp
= row
+ row_info
->rowbytes
;
1737 for (i
= 0; i
< row_width
; i
++)
1739 *(--dp
) = (png_byte
)(255 - *(--sp
));
1740 *(--dp
) = (png_byte
)(255 - *(--sp
));
1742 /* This does nothing:
1749 We can replace it with:
1756 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
1758 /* This inverts the alpha channel in GA */
1759 if (row_info
->bit_depth
== 8)
1761 png_bytep sp
= row
+ row_info
->rowbytes
;
1765 for (i
= 0; i
< row_width
; i
++)
1767 *(--dp
) = (png_byte
)(255 - *(--sp
));
1771 /* This inverts the alpha channel in GGAA */
1774 png_bytep sp
= row
+ row_info
->rowbytes
;
1778 for (i
= 0; i
< row_width
; i
++)
1780 *(--dp
) = (png_byte
)(255 - *(--sp
));
1781 *(--dp
) = (png_byte
)(255 - *(--sp
));
1795 #if defined(PNG_READ_FILLER_SUPPORTED)
1796 /* Add filler channel if we have RGB color */
1798 png_do_read_filler(png_row_infop row_info
, png_bytep row
,
1799 png_uint_32 filler
, png_uint_32 flags
)
1802 png_uint_32 row_width
= row_info
->width
;
1804 png_byte hi_filler
= (png_byte
)((filler
>>8) & 0xff);
1805 png_byte lo_filler
= (png_byte
)(filler
& 0xff);
1807 png_debug(1, "in png_do_read_filler\n");
1809 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1810 row
!= NULL
&& row_info
!= NULL
&&
1812 row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
1814 if(row_info
->bit_depth
== 8)
1816 /* This changes the data from G to GX */
1817 if (flags
& PNG_FLAG_FILLER_AFTER
)
1819 png_bytep sp
= row
+ (png_size_t
)row_width
;
1820 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1821 for (i
= 1; i
< row_width
; i
++)
1823 *(--dp
) = lo_filler
;
1826 *(--dp
) = lo_filler
;
1827 row_info
->channels
= 2;
1828 row_info
->pixel_depth
= 16;
1829 row_info
->rowbytes
= row_width
* 2;
1831 /* This changes the data from G to XG */
1834 png_bytep sp
= row
+ (png_size_t
)row_width
;
1835 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1836 for (i
= 0; i
< row_width
; i
++)
1839 *(--dp
) = lo_filler
;
1841 row_info
->channels
= 2;
1842 row_info
->pixel_depth
= 16;
1843 row_info
->rowbytes
= row_width
* 2;
1846 else if(row_info
->bit_depth
== 16)
1848 /* This changes the data from GG to GGXX */
1849 if (flags
& PNG_FLAG_FILLER_AFTER
)
1851 png_bytep sp
= row
+ (png_size_t
)row_width
;
1852 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1853 for (i
= 1; i
< row_width
; i
++)
1855 *(--dp
) = hi_filler
;
1856 *(--dp
) = lo_filler
;
1860 *(--dp
) = hi_filler
;
1861 *(--dp
) = lo_filler
;
1862 row_info
->channels
= 2;
1863 row_info
->pixel_depth
= 32;
1864 row_info
->rowbytes
= row_width
* 4;
1866 /* This changes the data from GG to XXGG */
1869 png_bytep sp
= row
+ (png_size_t
)row_width
;
1870 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1871 for (i
= 0; i
< row_width
; i
++)
1875 *(--dp
) = hi_filler
;
1876 *(--dp
) = lo_filler
;
1878 row_info
->channels
= 2;
1879 row_info
->pixel_depth
= 32;
1880 row_info
->rowbytes
= row_width
* 4;
1883 } /* COLOR_TYPE == GRAY */
1884 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
1886 if(row_info
->bit_depth
== 8)
1888 /* This changes the data from RGB to RGBX */
1889 if (flags
& PNG_FLAG_FILLER_AFTER
)
1891 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
1892 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1893 for (i
= 1; i
< row_width
; i
++)
1895 *(--dp
) = lo_filler
;
1900 *(--dp
) = lo_filler
;
1901 row_info
->channels
= 4;
1902 row_info
->pixel_depth
= 32;
1903 row_info
->rowbytes
= row_width
* 4;
1905 /* This changes the data from RGB to XRGB */
1908 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
1909 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1910 for (i
= 0; i
< row_width
; i
++)
1915 *(--dp
) = lo_filler
;
1917 row_info
->channels
= 4;
1918 row_info
->pixel_depth
= 32;
1919 row_info
->rowbytes
= row_width
* 4;
1922 else if(row_info
->bit_depth
== 16)
1924 /* This changes the data from RRGGBB to RRGGBBXX */
1925 if (flags
& PNG_FLAG_FILLER_AFTER
)
1927 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
1928 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1929 for (i
= 1; i
< row_width
; i
++)
1931 *(--dp
) = hi_filler
;
1932 *(--dp
) = lo_filler
;
1940 *(--dp
) = hi_filler
;
1941 *(--dp
) = lo_filler
;
1942 row_info
->channels
= 4;
1943 row_info
->pixel_depth
= 64;
1944 row_info
->rowbytes
= row_width
* 8;
1946 /* This changes the data from RRGGBB to XXRRGGBB */
1949 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
1950 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1951 for (i
= 0; i
< row_width
; i
++)
1959 *(--dp
) = hi_filler
;
1960 *(--dp
) = lo_filler
;
1962 row_info
->channels
= 4;
1963 row_info
->pixel_depth
= 64;
1964 row_info
->rowbytes
= row_width
* 8;
1967 } /* COLOR_TYPE == RGB */
1971 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1972 /* expand grayscale files to RGB, with or without alpha */
1974 png_do_gray_to_rgb(png_row_infop row_info
, png_bytep row
)
1977 png_uint_32 row_width
= row_info
->width
;
1979 png_debug(1, "in png_do_gray_to_rgb\n");
1980 if (row_info
->bit_depth
>= 8 &&
1981 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1982 row
!= NULL
&& row_info
!= NULL
&&
1984 !(row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
1986 if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
1988 if (row_info
->bit_depth
== 8)
1990 png_bytep sp
= row
+ (png_size_t
)row_width
- 1;
1991 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
1992 for (i
= 0; i
< row_width
; i
++)
2001 png_bytep sp
= row
+ (png_size_t
)row_width
* 2 - 1;
2002 png_bytep dp
= sp
+ (png_size_t
)row_width
* 4;
2003 for (i
= 0; i
< row_width
; i
++)
2006 *(dp
--) = *(sp
- 1);
2008 *(dp
--) = *(sp
- 1);
2014 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
2016 if (row_info
->bit_depth
== 8)
2018 png_bytep sp
= row
+ (png_size_t
)row_width
* 2 - 1;
2019 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2020 for (i
= 0; i
< row_width
; i
++)
2030 png_bytep sp
= row
+ (png_size_t
)row_width
* 4 - 1;
2031 png_bytep dp
= sp
+ (png_size_t
)row_width
* 4;
2032 for (i
= 0; i
< row_width
; i
++)
2037 *(dp
--) = *(sp
- 1);
2039 *(dp
--) = *(sp
- 1);
2045 row_info
->channels
+= (png_byte
)2;
2046 row_info
->color_type
|= PNG_COLOR_MASK_COLOR
;
2047 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
2048 row_info
->bit_depth
);
2049 row_info
->rowbytes
= ((row_width
*
2050 row_info
->pixel_depth
+ 7) >> 3);
2055 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
2056 /* reduce RGB files to grayscale, with or without alpha
2057 * using the equation given in Poynton's ColorFAQ at
2058 * <http://www.inforamp.net/~poynton/>
2059 * Copyright (c) 1998-01-04 Charles Poynton poynton@inforamp.net
2061 * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
2063 * We approximate this with
2065 * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B
2067 * which can be expressed with integers as
2069 * Y = (6969 * R + 23434 * G + 2365 * B)/32768
2071 * The calculation is to be done in a linear colorspace.
2073 * Other integer coefficents can be used via png_set_rgb_to_gray().
2076 png_do_rgb_to_gray(png_structp png_ptr
, png_row_infop row_info
, png_bytep row
)
2081 png_uint_32 row_width
= row_info
->width
;
2084 png_debug(1, "in png_do_rgb_to_gray\n");
2086 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2087 row
!= NULL
&& row_info
!= NULL
&&
2089 (row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
2091 png_uint_32 rc
= png_ptr
->rgb_to_gray_red_coeff
;
2092 png_uint_32 gc
= png_ptr
->rgb_to_gray_green_coeff
;
2093 png_uint_32 bc
= png_ptr
->rgb_to_gray_blue_coeff
;
2095 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
2097 if (row_info
->bit_depth
== 8)
2099 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2100 if (png_ptr
->gamma_from_1
!= NULL
&& png_ptr
->gamma_to_1
!= NULL
)
2105 for (i
= 0; i
< row_width
; i
++)
2107 png_byte red
= png_ptr
->gamma_to_1
[*(sp
++)];
2108 png_byte green
= png_ptr
->gamma_to_1
[*(sp
++)];
2109 png_byte blue
= png_ptr
->gamma_to_1
[*(sp
++)];
2110 if(red
!= green
|| red
!= blue
)
2113 *(dp
++) = png_ptr
->gamma_from_1
[
2114 (rc
*red
+gc
*green
+bc
*blue
)>>15];
2125 for (i
= 0; i
< row_width
; i
++)
2127 png_byte red
= *(sp
++);
2128 png_byte green
= *(sp
++);
2129 png_byte blue
= *(sp
++);
2130 if(red
!= green
|| red
!= blue
)
2133 *(dp
++) = (png_byte
)((rc
*red
+gc
*green
+bc
*blue
)>>15);
2141 else /* RGB bit_depth == 16 */
2143 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2144 if (png_ptr
->gamma_16_to_1
!= NULL
&&
2145 png_ptr
->gamma_16_from_1
!= NULL
)
2149 for (i
= 0; i
< row_width
; i
++)
2151 png_uint_16 red
, green
, blue
, w
;
2153 red
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2154 green
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2155 blue
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2157 if(red
== green
&& red
== blue
)
2161 png_uint_16 red_1
= png_ptr
->gamma_16_to_1
[(red
&0xff) >>
2162 png_ptr
->gamma_shift
][red
>>8];
2163 png_uint_16 green_1
= png_ptr
->gamma_16_to_1
[(green
&0xff) >>
2164 png_ptr
->gamma_shift
][green
>>8];
2165 png_uint_16 blue_1
= png_ptr
->gamma_16_to_1
[(blue
&0xff) >>
2166 png_ptr
->gamma_shift
][blue
>>8];
2167 png_uint_16 gray16
= (png_uint_16
)((rc
*red_1
+ gc
*green_1
2169 w
= png_ptr
->gamma_16_from_1
[(gray16
&0xff) >>
2170 png_ptr
->gamma_shift
][gray16
>> 8];
2174 *(dp
++) = (png_byte
)((w
>>8) & 0xff);
2175 *(dp
++) = (png_byte
)(w
& 0xff);
2183 for (i
= 0; i
< row_width
; i
++)
2185 png_uint_16 red
, green
, blue
, gray16
;
2187 red
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2188 green
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2189 blue
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2191 if(red
!= green
|| red
!= blue
)
2193 gray16
= (png_uint_16
)((rc
*red
+ gc
*green
+ bc
*blue
)>>15);
2194 *(dp
++) = (png_byte
)((gray16
>>8) & 0xff);
2195 *(dp
++) = (png_byte
)(gray16
& 0xff);
2200 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
2202 if (row_info
->bit_depth
== 8)
2204 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2205 if (png_ptr
->gamma_from_1
!= NULL
&& png_ptr
->gamma_to_1
!= NULL
)
2209 for (i
= 0; i
< row_width
; i
++)
2211 png_byte red
= png_ptr
->gamma_to_1
[*(sp
++)];
2212 png_byte green
= png_ptr
->gamma_to_1
[*(sp
++)];
2213 png_byte blue
= png_ptr
->gamma_to_1
[*(sp
++)];
2214 if(red
!= green
|| red
!= blue
)
2216 *(dp
++) = png_ptr
->gamma_from_1
2217 [(rc
*red
+ gc
*green
+ bc
*blue
)>>15];
2218 *(dp
++) = *(sp
++); /* alpha */
2226 for (i
= 0; i
< row_width
; i
++)
2228 png_byte red
= *(sp
++);
2229 png_byte green
= *(sp
++);
2230 png_byte blue
= *(sp
++);
2231 if(red
!= green
|| red
!= blue
)
2233 *(dp
++) = (png_byte
)((gc
*red
+ gc
*green
+ bc
*blue
)>>8);
2234 *(dp
++) = *(sp
++); /* alpha */
2238 else /* RGBA bit_depth == 16 */
2240 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2241 if (png_ptr
->gamma_16_to_1
!= NULL
&&
2242 png_ptr
->gamma_16_from_1
!= NULL
)
2246 for (i
= 0; i
< row_width
; i
++)
2248 png_uint_16 red
, green
, blue
, w
;
2250 red
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2251 green
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2252 blue
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2254 if(red
== green
&& red
== blue
)
2258 png_uint_16 red_1
= png_ptr
->gamma_16_to_1
[(red
&0xff) >>
2259 png_ptr
->gamma_shift
][red
>>8];
2260 png_uint_16 green_1
= png_ptr
->gamma_16_to_1
[(green
&0xff) >>
2261 png_ptr
->gamma_shift
][green
>>8];
2262 png_uint_16 blue_1
= png_ptr
->gamma_16_to_1
[(blue
&0xff) >>
2263 png_ptr
->gamma_shift
][blue
>>8];
2264 png_uint_16 gray16
= (png_uint_16
)((rc
* red_1
2265 + gc
* green_1
+ bc
* blue_1
)>>15);
2266 w
= png_ptr
->gamma_16_from_1
[(gray16
&0xff) >>
2267 png_ptr
->gamma_shift
][gray16
>> 8];
2271 *(dp
++) = (png_byte
)((w
>>8) & 0xff);
2272 *(dp
++) = (png_byte
)(w
& 0xff);
2273 *(dp
++) = *(sp
++); /* alpha */
2282 for (i
= 0; i
< row_width
; i
++)
2284 png_uint_16 red
, green
, blue
, gray16
;
2285 red
= (png_uint_16
)((*(sp
)<<8) | *(sp
+1)); sp
+=2;
2286 green
= (png_uint_16
)((*(sp
)<<8) | *(sp
+1)); sp
+=2;
2287 blue
= (png_uint_16
)((*(sp
)<<8) | *(sp
+1)); sp
+=2;
2288 if(red
!= green
|| red
!= blue
)
2290 gray16
= (png_uint_16
)((rc
*red
+ gc
*green
+ bc
*blue
)>>15);
2291 *(dp
++) = (png_byte
)((gray16
>>8) & 0xff);
2292 *(dp
++) = (png_byte
)(gray16
& 0xff);
2293 *(dp
++) = *(sp
++); /* alpha */
2299 row_info
->channels
-= (png_byte
)2;
2300 row_info
->color_type
&= ~PNG_COLOR_MASK_COLOR
;
2301 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
2302 row_info
->bit_depth
);
2303 row_info
->rowbytes
= ((row_width
*
2304 row_info
->pixel_depth
+ 7) >> 3);
2310 /* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
2311 * large of png_color. This lets grayscale images be treated as
2312 * paletted. Most useful for gamma correction and simplification
2316 png_build_grayscale_palette(int bit_depth
, png_colorp palette
)
2323 png_debug(1, "in png_do_build_grayscale_palette\n");
2324 if (palette
== NULL
)
2351 for (i
= 0, v
= 0; i
< num_palette
; i
++, v
+= color_inc
)
2353 palette
[i
].red
= (png_byte
)v
;
2354 palette
[i
].green
= (png_byte
)v
;
2355 palette
[i
].blue
= (png_byte
)v
;
2359 /* This function is currently unused. Do we really need it? */
2360 #if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
2362 png_correct_palette(png_structp png_ptr
, png_colorp palette
,
2365 png_debug(1, "in png_correct_palette\n");
2366 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
2367 defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
2368 if (png_ptr
->transformations
& (PNG_GAMMA
| PNG_BACKGROUND
))
2370 png_color back
, back_1
;
2372 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_FILE
)
2374 back
.red
= png_ptr
->gamma_table
[png_ptr
->background
.red
];
2375 back
.green
= png_ptr
->gamma_table
[png_ptr
->background
.green
];
2376 back
.blue
= png_ptr
->gamma_table
[png_ptr
->background
.blue
];
2378 back_1
.red
= png_ptr
->gamma_to_1
[png_ptr
->background
.red
];
2379 back_1
.green
= png_ptr
->gamma_to_1
[png_ptr
->background
.green
];
2380 back_1
.blue
= png_ptr
->gamma_to_1
[png_ptr
->background
.blue
];
2386 g
= 1.0 / (png_ptr
->background_gamma
* png_ptr
->screen_gamma
);
2388 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_SCREEN
||
2389 fabs(g
- 1.0) < PNG_GAMMA_THRESHOLD
)
2391 back
.red
= png_ptr
->background
.red
;
2392 back
.green
= png_ptr
->background
.green
;
2393 back
.blue
= png_ptr
->background
.blue
;
2398 (png_byte
)(pow((double)png_ptr
->background
.red
/255, g
) *
2401 (png_byte
)(pow((double)png_ptr
->background
.green
/255, g
) *
2404 (png_byte
)(pow((double)png_ptr
->background
.blue
/255, g
) *
2408 g
= 1.0 / png_ptr
->background_gamma
;
2411 (png_byte
)(pow((double)png_ptr
->background
.red
/255, g
) *
2414 (png_byte
)(pow((double)png_ptr
->background
.green
/255, g
) *
2417 (png_byte
)(pow((double)png_ptr
->background
.blue
/255, g
) *
2421 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
2425 for (i
= 0; i
< (png_uint_32
)num_palette
; i
++)
2427 if (i
< png_ptr
->num_trans
&& png_ptr
->trans
[i
] == 0)
2431 else if (i
< png_ptr
->num_trans
&& png_ptr
->trans
[i
] != 0xff)
2435 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].red
];
2436 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.red
);
2437 palette
[i
].red
= png_ptr
->gamma_from_1
[w
];
2439 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].green
];
2440 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.green
);
2441 palette
[i
].green
= png_ptr
->gamma_from_1
[w
];
2443 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].blue
];
2444 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.blue
);
2445 palette
[i
].blue
= png_ptr
->gamma_from_1
[w
];
2449 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2450 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2451 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2459 for (i
= 0; i
< num_palette
; i
++)
2461 if (palette
[i
].red
== (png_byte
)png_ptr
->trans_values
.gray
)
2467 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2468 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2469 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2476 #if defined(PNG_READ_GAMMA_SUPPORTED)
2477 if (png_ptr
->transformations
& PNG_GAMMA
)
2481 for (i
= 0; i
< num_palette
; i
++)
2483 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2484 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2485 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2488 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2492 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2493 if (png_ptr
->transformations
& PNG_BACKGROUND
)
2495 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
2499 back
.red
= (png_byte
)png_ptr
->background
.red
;
2500 back
.green
= (png_byte
)png_ptr
->background
.green
;
2501 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
2503 for (i
= 0; i
< (int)png_ptr
->num_trans
; i
++)
2505 if (png_ptr
->trans
[i
] == 0)
2507 palette
[i
].red
= back
.red
;
2508 palette
[i
].green
= back
.green
;
2509 palette
[i
].blue
= back
.blue
;
2511 else if (png_ptr
->trans
[i
] != 0xff)
2513 png_composite(palette
[i
].red
, png_ptr
->palette
[i
].red
,
2514 png_ptr
->trans
[i
], back
.red
);
2515 png_composite(palette
[i
].green
, png_ptr
->palette
[i
].green
,
2516 png_ptr
->trans
[i
], back
.green
);
2517 png_composite(palette
[i
].blue
, png_ptr
->palette
[i
].blue
,
2518 png_ptr
->trans
[i
], back
.blue
);
2522 else /* assume grayscale palette (what else could it be?) */
2526 for (i
= 0; i
< num_palette
; i
++)
2528 if (i
== (png_byte
)png_ptr
->trans_values
.gray
)
2530 palette
[i
].red
= (png_byte
)png_ptr
->background
.red
;
2531 palette
[i
].green
= (png_byte
)png_ptr
->background
.green
;
2532 palette
[i
].blue
= (png_byte
)png_ptr
->background
.blue
;
2541 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2542 /* Replace any alpha or transparency with the supplied background color.
2543 * "background" is already in the screen gamma, while "background_1" is
2544 * at a gamma of 1.0. Paletted files have already been taken care of.
2547 png_do_background(png_row_infop row_info
, png_bytep row
,
2548 png_color_16p trans_values
, png_color_16p background
,
2549 png_color_16p background_1
,
2550 png_bytep gamma_table
, png_bytep gamma_from_1
, png_bytep gamma_to_1
,
2551 png_uint_16pp gamma_16
, png_uint_16pp gamma_16_from_1
,
2552 png_uint_16pp gamma_16_to_1
, int gamma_shift
)
2556 png_uint_32 row_width
=row_info
->width
;
2559 png_debug(1, "in png_do_background\n");
2560 if (background
!= NULL
&&
2561 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2562 row
!= NULL
&& row_info
!= NULL
&&
2564 (!(row_info
->color_type
& PNG_COLOR_MASK_ALPHA
) ||
2565 (row_info
->color_type
!= PNG_COLOR_TYPE_PALETTE
&& trans_values
)))
2567 switch (row_info
->color_type
)
2569 case PNG_COLOR_TYPE_GRAY
:
2571 switch (row_info
->bit_depth
)
2577 for (i
= 0; i
< row_width
; i
++)
2579 if ((png_uint_16
)((*sp
>> shift
) & 0x01)
2580 == trans_values
->gray
)
2582 *sp
&= (png_byte
)((0x7f7f >> (7 - shift
)) & 0xff);
2583 *sp
|= (png_byte
)(background
->gray
<< shift
);
2597 #if defined(PNG_READ_GAMMA_SUPPORTED)
2598 if (gamma_table
!= NULL
)
2602 for (i
= 0; i
< row_width
; i
++)
2604 if ((png_uint_16
)((*sp
>> shift
) & 0x03)
2605 == trans_values
->gray
)
2607 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2608 *sp
|= (png_byte
)(background
->gray
<< shift
);
2612 png_byte p
= (png_byte
)((*sp
>> shift
) & 0x03);
2613 png_byte g
= (png_byte
)((gamma_table
[p
| (p
<< 2) |
2614 (p
<< 4) | (p
<< 6)] >> 6) & 0x03);
2615 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2616 *sp
|= (png_byte
)(g
<< shift
);
2632 for (i
= 0; i
< row_width
; i
++)
2634 if ((png_uint_16
)((*sp
>> shift
) & 0x03)
2635 == trans_values
->gray
)
2637 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2638 *sp
|= (png_byte
)(background
->gray
<< shift
);
2653 #if defined(PNG_READ_GAMMA_SUPPORTED)
2654 if (gamma_table
!= NULL
)
2658 for (i
= 0; i
< row_width
; i
++)
2660 if ((png_uint_16
)((*sp
>> shift
) & 0x0f)
2661 == trans_values
->gray
)
2663 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2664 *sp
|= (png_byte
)(background
->gray
<< shift
);
2668 png_byte p
= (png_byte
)((*sp
>> shift
) & 0x0f);
2669 png_byte g
= (png_byte
)((gamma_table
[p
|
2670 (p
<< 4)] >> 4) & 0x0f);
2671 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2672 *sp
|= (png_byte
)(g
<< shift
);
2688 for (i
= 0; i
< row_width
; i
++)
2690 if ((png_uint_16
)((*sp
>> shift
) & 0x0f)
2691 == trans_values
->gray
)
2693 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2694 *sp
|= (png_byte
)(background
->gray
<< shift
);
2709 #if defined(PNG_READ_GAMMA_SUPPORTED)
2710 if (gamma_table
!= NULL
)
2713 for (i
= 0; i
< row_width
; i
++, sp
++)
2715 if (*sp
== trans_values
->gray
)
2717 *sp
= (png_byte
)background
->gray
;
2721 *sp
= gamma_table
[*sp
];
2729 for (i
= 0; i
< row_width
; i
++, sp
++)
2731 if (*sp
== trans_values
->gray
)
2733 *sp
= (png_byte
)background
->gray
;
2741 #if defined(PNG_READ_GAMMA_SUPPORTED)
2742 if (gamma_16
!= NULL
)
2745 for (i
= 0; i
< row_width
; i
++, sp
+= 2)
2749 v
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
2750 if (v
== trans_values
->gray
)
2752 /* background is already in screen gamma */
2753 *sp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2754 *(sp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2758 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2759 *sp
= (png_byte
)((v
>> 8) & 0xff);
2760 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2768 for (i
= 0; i
< row_width
; i
++, sp
+= 2)
2772 v
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
2773 if (v
== trans_values
->gray
)
2775 *sp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2776 *(sp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2785 case PNG_COLOR_TYPE_RGB
:
2787 if (row_info
->bit_depth
== 8)
2789 #if defined(PNG_READ_GAMMA_SUPPORTED)
2790 if (gamma_table
!= NULL
)
2793 for (i
= 0; i
< row_width
; i
++, sp
+= 3)
2795 if (*sp
== trans_values
->red
&&
2796 *(sp
+ 1) == trans_values
->green
&&
2797 *(sp
+ 2) == trans_values
->blue
)
2799 *sp
= (png_byte
)background
->red
;
2800 *(sp
+ 1) = (png_byte
)background
->green
;
2801 *(sp
+ 2) = (png_byte
)background
->blue
;
2805 *sp
= gamma_table
[*sp
];
2806 *(sp
+ 1) = gamma_table
[*(sp
+ 1)];
2807 *(sp
+ 2) = gamma_table
[*(sp
+ 2)];
2815 for (i
= 0; i
< row_width
; i
++, sp
+= 3)
2817 if (*sp
== trans_values
->red
&&
2818 *(sp
+ 1) == trans_values
->green
&&
2819 *(sp
+ 2) == trans_values
->blue
)
2821 *sp
= (png_byte
)background
->red
;
2822 *(sp
+ 1) = (png_byte
)background
->green
;
2823 *(sp
+ 2) = (png_byte
)background
->blue
;
2828 else /* if (row_info->bit_depth == 16) */
2830 #if defined(PNG_READ_GAMMA_SUPPORTED)
2831 if (gamma_16
!= NULL
)
2834 for (i
= 0; i
< row_width
; i
++, sp
+= 6)
2836 png_uint_16 r
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
2837 png_uint_16 g
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
2838 png_uint_16 b
= (png_uint_16
)(((*(sp
+4)) << 8) + *(sp
+5));
2839 if (r
== trans_values
->red
&& g
== trans_values
->green
&&
2840 b
== trans_values
->blue
)
2842 /* background is already in screen gamma */
2843 *sp
= (png_byte
)((background
->red
>> 8) & 0xff);
2844 *(sp
+ 1) = (png_byte
)(background
->red
& 0xff);
2845 *(sp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
2846 *(sp
+ 3) = (png_byte
)(background
->green
& 0xff);
2847 *(sp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
2848 *(sp
+ 5) = (png_byte
)(background
->blue
& 0xff);
2852 png_uint_16 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2853 *sp
= (png_byte
)((v
>> 8) & 0xff);
2854 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2855 v
= gamma_16
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
2856 *(sp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
2857 *(sp
+ 3) = (png_byte
)(v
& 0xff);
2858 v
= gamma_16
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
2859 *(sp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
2860 *(sp
+ 5) = (png_byte
)(v
& 0xff);
2868 for (i
= 0; i
< row_width
; i
++, sp
+= 6)
2870 png_uint_16 r
= (png_uint_16
)(((*sp
) << 8) + *(sp
+1));
2871 png_uint_16 g
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
2872 png_uint_16 b
= (png_uint_16
)(((*(sp
+4)) << 8) + *(sp
+5));
2874 if (r
== trans_values
->red
&& g
== trans_values
->green
&&
2875 b
== trans_values
->blue
)
2877 *sp
= (png_byte
)((background
->red
>> 8) & 0xff);
2878 *(sp
+ 1) = (png_byte
)(background
->red
& 0xff);
2879 *(sp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
2880 *(sp
+ 3) = (png_byte
)(background
->green
& 0xff);
2881 *(sp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
2882 *(sp
+ 5) = (png_byte
)(background
->blue
& 0xff);
2889 case PNG_COLOR_TYPE_GRAY_ALPHA
:
2891 if (row_info
->bit_depth
== 8)
2893 #if defined(PNG_READ_GAMMA_SUPPORTED)
2894 if (gamma_to_1
!= NULL
&& gamma_from_1
!= NULL
&&
2895 gamma_table
!= NULL
)
2899 for (i
= 0; i
< row_width
; i
++, sp
+= 2, dp
++)
2901 png_uint_16 a
= *(sp
+ 1);
2905 *dp
= gamma_table
[*sp
];
2909 /* background is already in screen gamma */
2910 *dp
= (png_byte
)background
->gray
;
2916 v
= gamma_to_1
[*sp
];
2917 png_composite(w
, v
, a
, background_1
->gray
);
2918 *dp
= gamma_from_1
[w
];
2927 for (i
= 0; i
< row_width
; i
++, sp
+= 2, dp
++)
2929 png_byte a
= *(sp
+ 1);
2937 *dp
= (png_byte
)background
->gray
;
2941 png_composite(*dp
, *sp
, a
, background_1
->gray
);
2946 else /* if (png_ptr->bit_depth == 16) */
2948 #if defined(PNG_READ_GAMMA_SUPPORTED)
2949 if (gamma_16
!= NULL
&& gamma_16_from_1
!= NULL
&&
2950 gamma_16_to_1
!= NULL
)
2954 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 2)
2956 png_uint_16 a
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
2958 if (a
== (png_uint_16
)0xffff)
2962 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2963 *dp
= (png_byte
)((v
>> 8) & 0xff);
2964 *(dp
+ 1) = (png_byte
)(v
& 0xff);
2968 /* background is already in screen gamma */
2969 *dp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2970 *(dp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2974 png_uint_16 g
, v
, w
;
2976 g
= gamma_16_to_1
[*(sp
+ 1) >> gamma_shift
][*sp
];
2977 png_composite_16(v
, g
, a
, background_1
->gray
);
2978 w
= gamma_16_from_1
[(v
&0xff) >> gamma_shift
][v
>> 8];
2979 *dp
= (png_byte
)((w
>> 8) & 0xff);
2980 *(dp
+ 1) = (png_byte
)(w
& 0xff);
2989 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 2)
2991 png_uint_16 a
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
2992 if (a
== (png_uint_16
)0xffff)
2994 png_memcpy(dp
, sp
, 2);
2998 *dp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2999 *(dp
+ 1) = (png_byte
)(background
->gray
& 0xff);
3005 g
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
3006 png_composite_16(v
, g
, a
, background_1
->gray
);
3007 *dp
= (png_byte
)((v
>> 8) & 0xff);
3008 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3015 case PNG_COLOR_TYPE_RGB_ALPHA
:
3017 if (row_info
->bit_depth
== 8)
3019 #if defined(PNG_READ_GAMMA_SUPPORTED)
3020 if (gamma_to_1
!= NULL
&& gamma_from_1
!= NULL
&&
3021 gamma_table
!= NULL
)
3025 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 3)
3027 png_byte a
= *(sp
+ 3);
3031 *dp
= gamma_table
[*sp
];
3032 *(dp
+ 1) = gamma_table
[*(sp
+ 1)];
3033 *(dp
+ 2) = gamma_table
[*(sp
+ 2)];
3037 /* background is already in screen gamma */
3038 *dp
= (png_byte
)background
->red
;
3039 *(dp
+ 1) = (png_byte
)background
->green
;
3040 *(dp
+ 2) = (png_byte
)background
->blue
;
3046 v
= gamma_to_1
[*sp
];
3047 png_composite(w
, v
, a
, background_1
->red
);
3048 *dp
= gamma_from_1
[w
];
3049 v
= gamma_to_1
[*(sp
+ 1)];
3050 png_composite(w
, v
, a
, background_1
->green
);
3051 *(dp
+ 1) = gamma_from_1
[w
];
3052 v
= gamma_to_1
[*(sp
+ 2)];
3053 png_composite(w
, v
, a
, background_1
->blue
);
3054 *(dp
+ 2) = gamma_from_1
[w
];
3063 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 3)
3065 png_byte a
= *(sp
+ 3);
3070 *(dp
+ 1) = *(sp
+ 1);
3071 *(dp
+ 2) = *(sp
+ 2);
3075 *dp
= (png_byte
)background
->red
;
3076 *(dp
+ 1) = (png_byte
)background
->green
;
3077 *(dp
+ 2) = (png_byte
)background
->blue
;
3081 png_composite(*dp
, *sp
, a
, background
->red
);
3082 png_composite(*(dp
+ 1), *(sp
+ 1), a
,
3084 png_composite(*(dp
+ 2), *(sp
+ 2), a
,
3090 else /* if (row_info->bit_depth == 16) */
3092 #if defined(PNG_READ_GAMMA_SUPPORTED)
3093 if (gamma_16
!= NULL
&& gamma_16_from_1
!= NULL
&&
3094 gamma_16_to_1
!= NULL
)
3098 for (i
= 0; i
< row_width
; i
++, sp
+= 8, dp
+= 6)
3100 png_uint_16 a
= (png_uint_16
)(((png_uint_16
)(*(sp
+ 6))
3101 << 8) + (png_uint_16
)(*(sp
+ 7)));
3102 if (a
== (png_uint_16
)0xffff)
3106 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
3107 *dp
= (png_byte
)((v
>> 8) & 0xff);
3108 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3109 v
= gamma_16
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
3110 *(dp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
3111 *(dp
+ 3) = (png_byte
)(v
& 0xff);
3112 v
= gamma_16
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
3113 *(dp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
3114 *(dp
+ 5) = (png_byte
)(v
& 0xff);
3118 /* background is already in screen gamma */
3119 *dp
= (png_byte
)((background
->red
>> 8) & 0xff);
3120 *(dp
+ 1) = (png_byte
)(background
->red
& 0xff);
3121 *(dp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
3122 *(dp
+ 3) = (png_byte
)(background
->green
& 0xff);
3123 *(dp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
3124 *(dp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3128 png_uint_16 v
, w
, x
;
3130 v
= gamma_16_to_1
[*(sp
+ 1) >> gamma_shift
][*sp
];
3131 png_composite_16(w
, v
, a
, background
->red
);
3132 x
= gamma_16_from_1
[((w
&0xff) >> gamma_shift
)][w
>> 8];
3133 *dp
= (png_byte
)((x
>> 8) & 0xff);
3134 *(dp
+ 1) = (png_byte
)(x
& 0xff);
3135 v
= gamma_16_to_1
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
3136 png_composite_16(w
, v
, a
, background
->green
);
3137 x
= gamma_16_from_1
[((w
&0xff) >> gamma_shift
)][w
>> 8];
3138 *(dp
+ 2) = (png_byte
)((x
>> 8) & 0xff);
3139 *(dp
+ 3) = (png_byte
)(x
& 0xff);
3140 v
= gamma_16_to_1
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
3141 png_composite_16(w
, v
, a
, background
->blue
);
3142 x
= gamma_16_from_1
[(w
& 0xff) >> gamma_shift
][w
>> 8];
3143 *(dp
+ 4) = (png_byte
)((x
>> 8) & 0xff);
3144 *(dp
+ 5) = (png_byte
)(x
& 0xff);
3153 for (i
= 0; i
< row_width
; i
++, sp
+= 8, dp
+= 6)
3155 png_uint_16 a
= (png_uint_16
)(((png_uint_16
)(*(sp
+ 6))
3156 << 8) + (png_uint_16
)(*(sp
+ 7)));
3157 if (a
== (png_uint_16
)0xffff)
3159 png_memcpy(dp
, sp
, 6);
3163 *dp
= (png_byte
)((background
->red
>> 8) & 0xff);
3164 *(dp
+ 1) = (png_byte
)(background
->red
& 0xff);
3165 *(dp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
3166 *(dp
+ 3) = (png_byte
)(background
->green
& 0xff);
3167 *(dp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
3168 *(dp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3174 png_uint_16 r
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
3175 png_uint_16 g
= (png_uint_16
)(((*(sp
+ 2)) << 8)
3177 png_uint_16 b
= (png_uint_16
)(((*(sp
+ 4)) << 8)
3180 png_composite_16(v
, r
, a
, background
->red
);
3181 *dp
= (png_byte
)((v
>> 8) & 0xff);
3182 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3183 png_composite_16(v
, g
, a
, background
->green
);
3184 *(dp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
3185 *(dp
+ 3) = (png_byte
)(v
& 0xff);
3186 png_composite_16(v
, b
, a
, background
->blue
);
3187 *(dp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
3188 *(dp
+ 5) = (png_byte
)(v
& 0xff);
3197 if (row_info
->color_type
& PNG_COLOR_MASK_ALPHA
)
3199 row_info
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
3200 row_info
->channels
--;
3201 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
3202 row_info
->bit_depth
);
3203 row_info
->rowbytes
= ((row_width
*
3204 row_info
->pixel_depth
+ 7) >> 3);
3210 #if defined(PNG_READ_GAMMA_SUPPORTED)
3211 /* Gamma correct the image, avoiding the alpha channel. Make sure
3212 * you do this after you deal with the transparency issue on grayscale
3213 * or RGB images. If your bit depth is 8, use gamma_table, if it
3214 * is 16, use gamma_16_table and gamma_shift. Build these with
3215 * build_gamma_table().
3218 png_do_gamma(png_row_infop row_info
, png_bytep row
,
3219 png_bytep gamma_table
, png_uint_16pp gamma_16_table
,
3224 png_uint_32 row_width
=row_info
->width
;
3226 png_debug(1, "in png_do_gamma\n");
3228 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3229 row
!= NULL
&& row_info
!= NULL
&&
3231 ((row_info
->bit_depth
<= 8 && gamma_table
!= NULL
) ||
3232 (row_info
->bit_depth
== 16 && gamma_16_table
!= NULL
)))
3234 switch (row_info
->color_type
)
3236 case PNG_COLOR_TYPE_RGB
:
3238 if (row_info
->bit_depth
== 8)
3241 for (i
= 0; i
< row_width
; i
++)
3243 *sp
= gamma_table
[*sp
];
3245 *sp
= gamma_table
[*sp
];
3247 *sp
= gamma_table
[*sp
];
3251 else /* if (row_info->bit_depth == 16) */
3254 for (i
= 0; i
< row_width
; i
++)
3258 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3259 *sp
= (png_byte
)((v
>> 8) & 0xff);
3260 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3262 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3263 *sp
= (png_byte
)((v
>> 8) & 0xff);
3264 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3266 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3267 *sp
= (png_byte
)((v
>> 8) & 0xff);
3268 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3274 case PNG_COLOR_TYPE_RGB_ALPHA
:
3276 if (row_info
->bit_depth
== 8)
3279 for (i
= 0; i
< row_width
; i
++)
3281 *sp
= gamma_table
[*sp
];
3283 *sp
= gamma_table
[*sp
];
3285 *sp
= gamma_table
[*sp
];
3290 else /* if (row_info->bit_depth == 16) */
3293 for (i
= 0; i
< row_width
; i
++)
3295 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3296 *sp
= (png_byte
)((v
>> 8) & 0xff);
3297 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3299 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3300 *sp
= (png_byte
)((v
>> 8) & 0xff);
3301 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3303 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3304 *sp
= (png_byte
)((v
>> 8) & 0xff);
3305 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3311 case PNG_COLOR_TYPE_GRAY_ALPHA
:
3313 if (row_info
->bit_depth
== 8)
3316 for (i
= 0; i
< row_width
; i
++)
3318 *sp
= gamma_table
[*sp
];
3322 else /* if (row_info->bit_depth == 16) */
3325 for (i
= 0; i
< row_width
; i
++)
3327 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3328 *sp
= (png_byte
)((v
>> 8) & 0xff);
3329 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3335 case PNG_COLOR_TYPE_GRAY
:
3337 if (row_info
->bit_depth
== 2)
3340 for (i
= 0; i
< row_width
; i
+= 4)
3348 ((((int)gamma_table
[a
|(a
>>2)|(a
>>4)|(a
>>6)]) ) & 0xc0)|
3349 ((((int)gamma_table
[(b
<<2)|b
|(b
>>2)|(b
>>4)])>>2) & 0x30)|
3350 ((((int)gamma_table
[(c
<<4)|(c
<<2)|c
|(c
>>2)])>>4) & 0x0c)|
3351 ((((int)gamma_table
[(d
<<6)|(d
<<4)|(d
<<2)|d
])>>6) ));
3355 if (row_info
->bit_depth
== 4)
3358 for (i
= 0; i
< row_width
; i
+= 2)
3360 int msb
= *sp
& 0xf0;
3361 int lsb
= *sp
& 0x0f;
3363 *sp
= (png_byte
)((((int)gamma_table
[msb
| (msb
>> 4)]) & 0xf0)
3364 | (((int)gamma_table
[(lsb
<< 4) | lsb
]) >> 4));
3368 else if (row_info
->bit_depth
== 8)
3371 for (i
= 0; i
< row_width
; i
++)
3373 *sp
= gamma_table
[*sp
];
3377 else if (row_info
->bit_depth
== 16)
3380 for (i
= 0; i
< row_width
; i
++)
3382 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3383 *sp
= (png_byte
)((v
>> 8) & 0xff);
3384 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3395 #if defined(PNG_READ_EXPAND_SUPPORTED)
3396 /* Expands a palette row to an RGB or RGBA row depending
3397 * upon whether you supply trans and num_trans.
3400 png_do_expand_palette(png_row_infop row_info
, png_bytep row
,
3401 png_colorp palette
, png_bytep trans
, int num_trans
)
3406 png_uint_32 row_width
=row_info
->width
;
3408 png_debug(1, "in png_do_expand_palette\n");
3410 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3411 row
!= NULL
&& row_info
!= NULL
&&
3413 row_info
->color_type
== PNG_COLOR_TYPE_PALETTE
)
3415 if (row_info
->bit_depth
< 8)
3417 switch (row_info
->bit_depth
)
3421 sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
3422 dp
= row
+ (png_size_t
)row_width
- 1;
3423 shift
= 7 - (int)((row_width
+ 7) & 0x07);
3424 for (i
= 0; i
< row_width
; i
++)
3426 if ((*sp
>> shift
) & 0x01)
3444 sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
3445 dp
= row
+ (png_size_t
)row_width
- 1;
3446 shift
= (int)((3 - ((row_width
+ 3) & 0x03)) << 1);
3447 for (i
= 0; i
< row_width
; i
++)
3449 value
= (*sp
>> shift
) & 0x03;
3450 *dp
= (png_byte
)value
;
3465 sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
3466 dp
= row
+ (png_size_t
)row_width
- 1;
3467 shift
= (int)((row_width
& 0x01) << 2);
3468 for (i
= 0; i
< row_width
; i
++)
3470 value
= (*sp
>> shift
) & 0x0f;
3471 *dp
= (png_byte
)value
;
3485 row_info
->bit_depth
= 8;
3486 row_info
->pixel_depth
= 8;
3487 row_info
->rowbytes
= row_width
;
3489 switch (row_info
->bit_depth
)
3495 sp
= row
+ (png_size_t
)row_width
- 1;
3496 dp
= row
+ (png_size_t
)(row_width
<< 2) - 1;
3498 for (i
= 0; i
< row_width
; i
++)
3500 if ((int)(*sp
) >= num_trans
)
3504 *dp
-- = palette
[*sp
].blue
;
3505 *dp
-- = palette
[*sp
].green
;
3506 *dp
-- = palette
[*sp
].red
;
3509 row_info
->bit_depth
= 8;
3510 row_info
->pixel_depth
= 32;
3511 row_info
->rowbytes
= row_width
* 4;
3512 row_info
->color_type
= 6;
3513 row_info
->channels
= 4;
3517 sp
= row
+ (png_size_t
)row_width
- 1;
3518 dp
= row
+ (png_size_t
)(row_width
* 3) - 1;
3520 for (i
= 0; i
< row_width
; i
++)
3522 *dp
-- = palette
[*sp
].blue
;
3523 *dp
-- = palette
[*sp
].green
;
3524 *dp
-- = palette
[*sp
].red
;
3527 row_info
->bit_depth
= 8;
3528 row_info
->pixel_depth
= 24;
3529 row_info
->rowbytes
= row_width
* 3;
3530 row_info
->color_type
= 2;
3531 row_info
->channels
= 3;
3539 /* If the bit depth < 8, it is expanded to 8. Also, if the
3540 * transparency value is supplied, an alpha channel is built.
3543 png_do_expand(png_row_infop row_info
, png_bytep row
,
3544 png_color_16p trans_value
)
3549 png_uint_32 row_width
=row_info
->width
;
3551 png_debug(1, "in png_do_expand\n");
3552 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3553 if (row
!= NULL
&& row_info
!= NULL
)
3556 if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
3558 png_uint_16 gray
= (png_uint_16
)(trans_value
? trans_value
->gray
: 0);
3560 if (row_info
->bit_depth
< 8)
3562 switch (row_info
->bit_depth
)
3566 gray
= (png_uint_16
)(gray
*0xff);
3567 sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
3568 dp
= row
+ (png_size_t
)row_width
- 1;
3569 shift
= 7 - (int)((row_width
+ 7) & 0x07);
3570 for (i
= 0; i
< row_width
; i
++)
3572 if ((*sp
>> shift
) & 0x01)
3590 gray
= (png_uint_16
)(gray
*0x55);
3591 sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
3592 dp
= row
+ (png_size_t
)row_width
- 1;
3593 shift
= (int)((3 - ((row_width
+ 3) & 0x03)) << 1);
3594 for (i
= 0; i
< row_width
; i
++)
3596 value
= (*sp
>> shift
) & 0x03;
3597 *dp
= (png_byte
)(value
| (value
<< 2) | (value
<< 4) |
3613 gray
= (png_uint_16
)(gray
*0x11);
3614 sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
3615 dp
= row
+ (png_size_t
)row_width
- 1;
3616 shift
= (int)((1 - ((row_width
+ 1) & 0x01)) << 2);
3617 for (i
= 0; i
< row_width
; i
++)
3619 value
= (*sp
>> shift
) & 0x0f;
3620 *dp
= (png_byte
)(value
| (value
<< 4));
3634 row_info
->bit_depth
= 8;
3635 row_info
->pixel_depth
= 8;
3636 row_info
->rowbytes
= row_width
;
3639 if (trans_value
!= NULL
)
3641 if (row_info
->bit_depth
== 8)
3643 sp
= row
+ (png_size_t
)row_width
- 1;
3644 dp
= row
+ (png_size_t
)(row_width
<< 1) - 1;
3645 for (i
= 0; i
< row_width
; i
++)
3654 else if (row_info
->bit_depth
== 16)
3656 sp
= row
+ row_info
->rowbytes
- 1;
3657 dp
= row
+ (row_info
->rowbytes
<< 1) - 1;
3658 for (i
= 0; i
< row_width
; i
++)
3660 if (((png_uint_16
)*(sp
) |
3661 ((png_uint_16
)*(sp
- 1) << 8)) == gray
)
3675 row_info
->color_type
= PNG_COLOR_TYPE_GRAY_ALPHA
;
3676 row_info
->channels
= 2;
3677 row_info
->pixel_depth
= (png_byte
)(row_info
->bit_depth
<< 1);
3678 row_info
->rowbytes
=
3679 ((row_width
* row_info
->pixel_depth
) >> 3);
3682 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
&& trans_value
)
3684 if (row_info
->bit_depth
== 8)
3686 sp
= row
+ (png_size_t
)row_info
->rowbytes
- 1;
3687 dp
= row
+ (png_size_t
)(row_width
<< 2) - 1;
3688 for (i
= 0; i
< row_width
; i
++)
3690 if (*(sp
- 2) == trans_value
->red
&&
3691 *(sp
- 1) == trans_value
->green
&&
3692 *(sp
- 0) == trans_value
->blue
)
3701 else if (row_info
->bit_depth
== 16)
3703 sp
= row
+ row_info
->rowbytes
- 1;
3704 dp
= row
+ (png_size_t
)(row_width
<< 3) - 1;
3705 for (i
= 0; i
< row_width
; i
++)
3707 if ((((png_uint_16
)*(sp
- 4) |
3708 ((png_uint_16
)*(sp
- 5) << 8)) == trans_value
->red
) &&
3709 (((png_uint_16
)*(sp
- 2) |
3710 ((png_uint_16
)*(sp
- 3) << 8)) == trans_value
->green
) &&
3711 (((png_uint_16
)*(sp
- 0) |
3712 ((png_uint_16
)*(sp
- 1) << 8)) == trans_value
->blue
))
3730 row_info
->color_type
= PNG_COLOR_TYPE_RGB_ALPHA
;
3731 row_info
->channels
= 4;
3732 row_info
->pixel_depth
= (png_byte
)(row_info
->bit_depth
<< 2);
3733 row_info
->rowbytes
=
3734 ((row_width
* row_info
->pixel_depth
) >> 3);
3740 #if defined(PNG_READ_DITHER_SUPPORTED)
3742 png_do_dither(png_row_infop row_info
, png_bytep row
,
3743 png_bytep palette_lookup
, png_bytep dither_lookup
)
3747 png_uint_32 row_width
=row_info
->width
;
3749 png_debug(1, "in png_do_dither\n");
3750 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3751 if (row
!= NULL
&& row_info
!= NULL
)
3754 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
&&
3755 palette_lookup
&& row_info
->bit_depth
== 8)
3760 for (i
= 0; i
< row_width
; i
++)
3766 /* this looks real messy, but the compiler will reduce
3767 it down to a reasonable formula. For example, with
3768 5 bits per color, we get:
3769 p = (((r >> 3) & 0x1f) << 10) |
3770 (((g >> 3) & 0x1f) << 5) |
3773 p
= (((r
>> (8 - PNG_DITHER_RED_BITS
)) &
3774 ((1 << PNG_DITHER_RED_BITS
) - 1)) <<
3775 (PNG_DITHER_GREEN_BITS
+ PNG_DITHER_BLUE_BITS
)) |
3776 (((g
>> (8 - PNG_DITHER_GREEN_BITS
)) &
3777 ((1 << PNG_DITHER_GREEN_BITS
) - 1)) <<
3778 (PNG_DITHER_BLUE_BITS
)) |
3779 ((b
>> (8 - PNG_DITHER_BLUE_BITS
)) &
3780 ((1 << PNG_DITHER_BLUE_BITS
) - 1));
3782 *dp
++ = palette_lookup
[p
];
3784 row_info
->color_type
= PNG_COLOR_TYPE_PALETTE
;
3785 row_info
->channels
= 1;
3786 row_info
->pixel_depth
= row_info
->bit_depth
;
3787 row_info
->rowbytes
=
3788 ((row_width
* row_info
->pixel_depth
+ 7) >> 3);
3790 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
&&
3791 palette_lookup
!= NULL
&& row_info
->bit_depth
== 8)
3796 for (i
= 0; i
< row_width
; i
++)
3803 p
= (((r
>> (8 - PNG_DITHER_RED_BITS
)) &
3804 ((1 << PNG_DITHER_RED_BITS
) - 1)) <<
3805 (PNG_DITHER_GREEN_BITS
+ PNG_DITHER_BLUE_BITS
)) |
3806 (((g
>> (8 - PNG_DITHER_GREEN_BITS
)) &
3807 ((1 << PNG_DITHER_GREEN_BITS
) - 1)) <<
3808 (PNG_DITHER_BLUE_BITS
)) |
3809 ((b
>> (8 - PNG_DITHER_BLUE_BITS
)) &
3810 ((1 << PNG_DITHER_BLUE_BITS
) - 1));
3812 *dp
++ = palette_lookup
[p
];
3814 row_info
->color_type
= PNG_COLOR_TYPE_PALETTE
;
3815 row_info
->channels
= 1;
3816 row_info
->pixel_depth
= row_info
->bit_depth
;
3817 row_info
->rowbytes
=
3818 ((row_width
* row_info
->pixel_depth
+ 7) >> 3);
3820 else if (row_info
->color_type
== PNG_COLOR_TYPE_PALETTE
&&
3821 dither_lookup
&& row_info
->bit_depth
== 8)
3824 for (i
= 0; i
< row_width
; i
++, sp
++)
3826 *sp
= dither_lookup
[*sp
];
3833 #ifdef PNG_FLOATING_POINT_SUPPORTED
3834 #if defined(PNG_READ_GAMMA_SUPPORTED)
3835 static int png_gamma_shift
[] =
3836 {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0};
3838 /* We build the 8- or 16-bit gamma tables here. Note that for 16-bit
3839 * tables, we don't make a full table if we are reducing to 8-bit in
3840 * the future. Note also how the gamma_16 tables are segmented so that
3841 * we don't need to allocate > 64K chunks for a full 16-bit table.
3844 png_build_gamma_table(png_structp png_ptr
)
3846 png_debug(1, "in png_build_gamma_table\n");
3847 if(png_ptr
->gamma
!= 0.0)
3849 if (png_ptr
->bit_depth
<= 8)
3854 if (png_ptr
->screen_gamma
> .000001)
3855 g
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
3859 png_ptr
->gamma_table
= (png_bytep
)png_malloc(png_ptr
,
3862 for (i
= 0; i
< 256; i
++)
3864 png_ptr
->gamma_table
[i
] = (png_byte
)(pow((double)i
/ 255.0,
3868 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
3869 defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
3870 if (png_ptr
->transformations
& ((PNG_BACKGROUND
) | PNG_RGB_TO_GRAY
))
3873 g
= 1.0 / (png_ptr
->gamma
);
3875 png_ptr
->gamma_to_1
= (png_bytep
)png_malloc(png_ptr
,
3878 for (i
= 0; i
< 256; i
++)
3880 png_ptr
->gamma_to_1
[i
] = (png_byte
)(pow((double)i
/ 255.0,
3885 png_ptr
->gamma_from_1
= (png_bytep
)png_malloc(png_ptr
,
3888 if(png_ptr
->screen_gamma
> 0.000001)
3889 g
= 1.0 / png_ptr
->screen_gamma
;
3891 g
= png_ptr
->gamma
; /* probably doing rgb_to_gray */
3893 for (i
= 0; i
< 256; i
++)
3895 png_ptr
->gamma_from_1
[i
] = (png_byte
)(pow((double)i
/ 255.0,
3900 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
3905 int i
, j
, shift
, num
;
3909 if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
3911 sig_bit
= (int)png_ptr
->sig_bit
.red
;
3912 if ((int)png_ptr
->sig_bit
.green
> sig_bit
)
3913 sig_bit
= png_ptr
->sig_bit
.green
;
3914 if ((int)png_ptr
->sig_bit
.blue
> sig_bit
)
3915 sig_bit
= png_ptr
->sig_bit
.blue
;
3919 sig_bit
= (int)png_ptr
->sig_bit
.gray
;
3923 shift
= 16 - sig_bit
;
3927 if (png_ptr
->transformations
& PNG_16_TO_8
)
3929 if (shift
< (16 - PNG_MAX_GAMMA_8
))
3930 shift
= (16 - PNG_MAX_GAMMA_8
);
3938 png_ptr
->gamma_shift
= (png_byte
)shift
;
3940 num
= (1 << (8 - shift
));
3942 if (png_ptr
->screen_gamma
> .000001)
3943 g
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
3947 png_ptr
->gamma_16_table
= (png_uint_16pp
)png_malloc(png_ptr
,
3948 (png_uint_32
)(num
* sizeof (png_uint_16p
)));
3950 if (png_ptr
->transformations
& (PNG_16_TO_8
| PNG_BACKGROUND
))
3953 png_uint_32 last
, max
;
3955 for (i
= 0; i
< num
; i
++)
3957 png_ptr
->gamma_16_table
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
3958 (png_uint_32
)(256 * sizeof (png_uint_16
)));
3963 for (i
= 0; i
< 256; i
++)
3965 fout
= ((double)i
+ 0.5) / 256.0;
3967 max
= (png_uint_32
)(fin
* (double)((png_uint_32
)num
<< 8));
3970 png_ptr
->gamma_16_table
[(int)(last
& (0xff >> shift
))]
3971 [(int)(last
>> (8 - shift
))] = (png_uint_16
)(
3972 (png_uint_16
)i
| ((png_uint_16
)i
<< 8));
3976 while (last
< ((png_uint_32
)num
<< 8))
3978 png_ptr
->gamma_16_table
[(int)(last
& (0xff >> shift
))]
3979 [(int)(last
>> (8 - shift
))] = (png_uint_16
)65535L;
3985 for (i
= 0; i
< num
; i
++)
3987 png_ptr
->gamma_16_table
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
3988 (png_uint_32
)(256 * sizeof (png_uint_16
)));
3990 ig
= (((png_uint_32
)i
* (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
3991 for (j
= 0; j
< 256; j
++)
3993 png_ptr
->gamma_16_table
[i
][j
] =
3994 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
3995 65535.0, g
) * 65535.0 + .5);
4000 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
4001 defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
4002 if (png_ptr
->transformations
& (PNG_BACKGROUND
| PNG_RGB_TO_GRAY
))
4005 g
= 1.0 / (png_ptr
->gamma
);
4007 png_ptr
->gamma_16_to_1
= (png_uint_16pp
)png_malloc(png_ptr
,
4008 (png_uint_32
)(num
* sizeof (png_uint_16p
)));
4010 for (i
= 0; i
< num
; i
++)
4012 png_ptr
->gamma_16_to_1
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
4013 (png_uint_32
)(256 * sizeof (png_uint_16
)));
4015 ig
= (((png_uint_32
)i
*
4016 (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
4017 for (j
= 0; j
< 256; j
++)
4019 png_ptr
->gamma_16_to_1
[i
][j
] =
4020 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
4021 65535.0, g
) * 65535.0 + .5);
4025 if(png_ptr
->screen_gamma
> 0.000001)
4026 g
= 1.0 / png_ptr
->screen_gamma
;
4028 g
= png_ptr
->gamma
; /* probably doing rgb_to_gray */
4030 png_ptr
->gamma_16_from_1
= (png_uint_16pp
)png_malloc(png_ptr
,
4031 (png_uint_32
)(num
* sizeof (png_uint_16p
)));
4033 for (i
= 0; i
< num
; i
++)
4035 png_ptr
->gamma_16_from_1
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
4036 (png_uint_32
)(256 * sizeof (png_uint_16
)));
4038 ig
= (((png_uint_32
)i
*
4039 (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
4040 for (j
= 0; j
< 256; j
++)
4042 png_ptr
->gamma_16_from_1
[i
][j
] =
4043 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
4044 65535.0, g
) * 65535.0 + .5);
4048 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
4053 /* To do: install integer version of png_build_gamma_table here */
4056 #if defined(PNG_MNG_FEATURES_SUPPORTED)
4057 /* undoes intrapixel differencing */
4059 png_do_read_intrapixel(png_row_infop row_info
, png_bytep row
)
4061 png_debug(1, "in png_do_read_intrapixel\n");
4063 #if defined(PNG_USELESS_TESTS_SUPPORTED)
4064 row
!= NULL
&& row_info
!= NULL
&&
4066 (row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
4068 int bytes_per_pixel
;
4069 png_uint_32 row_width
= row_info
->width
;
4070 if (row_info
->bit_depth
== 8)
4075 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
4076 bytes_per_pixel
= 3;
4077 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
4078 bytes_per_pixel
= 4;
4082 for (i
= 0, rp
= row
; i
< row_width
; i
++, rp
+= bytes_per_pixel
)
4084 *(rp
) = (png_byte
)((256 + *rp
+ *(rp
+1))&0xff);
4085 *(rp
+2) = (png_byte
)((256 + *(rp
+2) + *(rp
+1))&0xff);
4088 else if (row_info
->bit_depth
== 16)
4093 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
4094 bytes_per_pixel
= 6;
4095 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
4096 bytes_per_pixel
= 8;
4100 for (i
= 0, rp
= row
; i
< row_width
; i
++, rp
+= bytes_per_pixel
)
4102 png_uint_32 s0
=*(rp
)<<8 | *(rp
+1);
4103 png_uint_32 s1
=*(rp
+2)<<8 | *(rp
+3);
4104 png_uint_32 s2
=*(rp
+4)<<8 | *(rp
+5);
4105 png_uint_32 red
=(65536+s0
+s1
)&0xffff;
4106 png_uint_32 blue
=(65536+s2
+s1
)&0xffff;
4107 *(rp
) = (png_byte
)((red
>>8)&0xff);
4108 *(rp
+1) = (png_byte
)(red
&0xff);
4109 *(rp
+4) = (png_byte
)((blue
>>8)&0xff);
4110 *(rp
+5) = (png_byte
)(blue
&0xff);
4115 #endif /* PNG_MNG_FEATURES_SUPPORTED */