2 /* pngrtran.c - transforms the data in a row for PNG readers
4 * Last changed in libpng 1.2.19 August 19, 2007
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1998-2007 Glenn Randers-Pehrson
7 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
10 * This file contains functions optionally called by an application
11 * in order to tell libpng how to handle data when reading a PNG.
12 * Transformations that are used in both reading and writing are
19 #if defined(PNG_READ_SUPPORTED)
21 /* Set the action on getting a CRC error for an ancillary or critical chunk. */
23 png_set_crc_action(png_structp png_ptr
, int crit_action
, int ancil_action
)
25 png_debug(1, "in png_set_crc_action\n");
26 /* Tell libpng how we react to CRC errors in critical chunks */
27 if(png_ptr
== NULL
) return;
30 case PNG_CRC_NO_CHANGE
: /* leave setting as is */
32 case PNG_CRC_WARN_USE
: /* warn/use data */
33 png_ptr
->flags
&= ~PNG_FLAG_CRC_CRITICAL_MASK
;
34 png_ptr
->flags
|= PNG_FLAG_CRC_CRITICAL_USE
;
36 case PNG_CRC_QUIET_USE
: /* quiet/use data */
37 png_ptr
->flags
&= ~PNG_FLAG_CRC_CRITICAL_MASK
;
38 png_ptr
->flags
|= PNG_FLAG_CRC_CRITICAL_USE
|
39 PNG_FLAG_CRC_CRITICAL_IGNORE
;
41 case PNG_CRC_WARN_DISCARD
: /* not a valid action for critical data */
42 png_warning(png_ptr
, "Can't discard critical data on CRC error.");
43 case PNG_CRC_ERROR_QUIT
: /* error/quit */
46 png_ptr
->flags
&= ~PNG_FLAG_CRC_CRITICAL_MASK
;
52 case PNG_CRC_NO_CHANGE
: /* leave setting as is */
54 case PNG_CRC_WARN_USE
: /* warn/use data */
55 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
56 png_ptr
->flags
|= PNG_FLAG_CRC_ANCILLARY_USE
;
58 case PNG_CRC_QUIET_USE
: /* quiet/use data */
59 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
60 png_ptr
->flags
|= PNG_FLAG_CRC_ANCILLARY_USE
|
61 PNG_FLAG_CRC_ANCILLARY_NOWARN
;
63 case PNG_CRC_ERROR_QUIT
: /* error/quit */
64 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
65 png_ptr
->flags
|= PNG_FLAG_CRC_ANCILLARY_NOWARN
;
67 case PNG_CRC_WARN_DISCARD
: /* warn/discard data */
70 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
75 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
76 defined(PNG_FLOATING_POINT_SUPPORTED)
77 /* handle alpha and tRNS via a background color */
79 png_set_background(png_structp png_ptr
,
80 png_color_16p background_color
, int background_gamma_code
,
81 int need_expand
, double background_gamma
)
83 png_debug(1, "in png_set_background\n");
84 if(png_ptr
== NULL
) return;
85 if (background_gamma_code
== PNG_BACKGROUND_GAMMA_UNKNOWN
)
87 png_warning(png_ptr
, "Application must supply a known background gamma");
91 png_ptr
->transformations
|= PNG_BACKGROUND
;
92 png_memcpy(&(png_ptr
->background
), background_color
,
93 png_sizeof(png_color_16
));
94 png_ptr
->background_gamma
= (float)background_gamma
;
95 png_ptr
->background_gamma_type
= (png_byte
)(background_gamma_code
);
96 png_ptr
->transformations
|= (need_expand
? PNG_BACKGROUND_EXPAND
: 0);
100 #if defined(PNG_READ_16_TO_8_SUPPORTED)
101 /* strip 16 bit depth files to 8 bit depth */
103 png_set_strip_16(png_structp png_ptr
)
105 png_debug(1, "in png_set_strip_16\n");
106 if(png_ptr
== NULL
) return;
107 png_ptr
->transformations
|= PNG_16_TO_8
;
111 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
113 png_set_strip_alpha(png_structp png_ptr
)
115 png_debug(1, "in png_set_strip_alpha\n");
116 if(png_ptr
== NULL
) return;
117 png_ptr
->flags
|= PNG_FLAG_STRIP_ALPHA
;
121 #if defined(PNG_READ_DITHER_SUPPORTED)
122 /* Dither file to 8 bit. Supply a palette, the current number
123 * of elements in the palette, the maximum number of elements
124 * allowed, and a histogram if possible. If the current number
125 * of colors is greater then the maximum number, the palette will be
126 * modified to fit in the maximum number. "full_dither" indicates
127 * whether we need a dithering cube set up for RGB images, or if we
128 * simply are reducing the number of colors in a paletted image.
131 typedef struct png_dsort_struct
133 struct png_dsort_struct FAR
* next
;
137 typedef png_dsort FAR
* png_dsortp
;
138 typedef png_dsort FAR
* FAR
* png_dsortpp
;
141 png_set_dither(png_structp png_ptr
, png_colorp palette
,
142 int num_palette
, int maximum_colors
, png_uint_16p histogram
,
145 png_debug(1, "in png_set_dither\n");
146 if(png_ptr
== NULL
) return;
147 png_ptr
->transformations
|= PNG_DITHER
;
153 png_ptr
->dither_index
= (png_bytep
)png_malloc(png_ptr
,
154 (png_uint_32
)(num_palette
* png_sizeof (png_byte
)));
155 for (i
= 0; i
< num_palette
; i
++)
156 png_ptr
->dither_index
[i
] = (png_byte
)i
;
159 if (num_palette
> maximum_colors
)
161 if (histogram
!= NULL
)
163 /* This is easy enough, just throw out the least used colors.
164 Perhaps not the best solution, but good enough. */
168 /* initialize an array to sort colors */
169 png_ptr
->dither_sort
= (png_bytep
)png_malloc(png_ptr
,
170 (png_uint_32
)(num_palette
* png_sizeof (png_byte
)));
172 /* initialize the dither_sort array */
173 for (i
= 0; i
< num_palette
; i
++)
174 png_ptr
->dither_sort
[i
] = (png_byte
)i
;
176 /* Find the least used palette entries by starting a
177 bubble sort, and running it until we have sorted
178 out enough colors. Note that we don't care about
179 sorting all the colors, just finding which are
182 for (i
= num_palette
- 1; i
>= maximum_colors
; i
--)
184 int done
; /* to stop early if the list is pre-sorted */
188 for (j
= 0; j
< i
; j
++)
190 if (histogram
[png_ptr
->dither_sort
[j
]]
191 < histogram
[png_ptr
->dither_sort
[j
+ 1]])
195 t
= png_ptr
->dither_sort
[j
];
196 png_ptr
->dither_sort
[j
] = png_ptr
->dither_sort
[j
+ 1];
197 png_ptr
->dither_sort
[j
+ 1] = t
;
205 /* swap the palette around, and set up a table, if necessary */
210 /* put all the useful colors within the max, but don't
212 for (i
= 0; i
< maximum_colors
; i
++)
214 if ((int)png_ptr
->dither_sort
[i
] >= maximum_colors
)
218 while ((int)png_ptr
->dither_sort
[j
] >= maximum_colors
);
219 palette
[i
] = palette
[j
];
227 /* move all the used colors inside the max limit, and
228 develop a translation table */
229 for (i
= 0; i
< maximum_colors
; i
++)
231 /* only move the colors we need to */
232 if ((int)png_ptr
->dither_sort
[i
] >= maximum_colors
)
238 while ((int)png_ptr
->dither_sort
[j
] >= maximum_colors
);
240 tmp_color
= palette
[j
];
241 palette
[j
] = palette
[i
];
242 palette
[i
] = tmp_color
;
243 /* indicate where the color went */
244 png_ptr
->dither_index
[j
] = (png_byte
)i
;
245 png_ptr
->dither_index
[i
] = (png_byte
)j
;
249 /* find closest color for those colors we are not using */
250 for (i
= 0; i
< num_palette
; i
++)
252 if ((int)png_ptr
->dither_index
[i
] >= maximum_colors
)
254 int min_d
, k
, min_k
, d_index
;
256 /* find the closest color to one we threw out */
257 d_index
= png_ptr
->dither_index
[i
];
258 min_d
= PNG_COLOR_DIST(palette
[d_index
], palette
[0]);
259 for (k
= 1, min_k
= 0; k
< maximum_colors
; k
++)
263 d
= PNG_COLOR_DIST(palette
[d_index
], palette
[k
]);
271 /* point to closest color */
272 png_ptr
->dither_index
[i
] = (png_byte
)min_k
;
276 png_free(png_ptr
, png_ptr
->dither_sort
);
277 png_ptr
->dither_sort
=NULL
;
281 /* This is much harder to do simply (and quickly). Perhaps
282 we need to go through a median cut routine, but those
283 don't always behave themselves with only a few colors
284 as input. So we will just find the closest two colors,
285 and throw out one of them (chosen somewhat randomly).
286 [We don't understand this at all, so if someone wants to
287 work on improving it, be our guest - AED, GRP]
297 /* initialize palette index arrays */
298 png_ptr
->index_to_palette
= (png_bytep
)png_malloc(png_ptr
,
299 (png_uint_32
)(num_palette
* png_sizeof (png_byte
)));
300 png_ptr
->palette_to_index
= (png_bytep
)png_malloc(png_ptr
,
301 (png_uint_32
)(num_palette
* png_sizeof (png_byte
)));
303 /* initialize the sort array */
304 for (i
= 0; i
< num_palette
; i
++)
306 png_ptr
->index_to_palette
[i
] = (png_byte
)i
;
307 png_ptr
->palette_to_index
[i
] = (png_byte
)i
;
310 hash
= (png_dsortpp
)png_malloc(png_ptr
, (png_uint_32
)(769 *
311 png_sizeof (png_dsortp
)));
312 for (i
= 0; i
< 769; i
++)
314 /* png_memset(hash, 0, 769 * png_sizeof (png_dsortp)); */
316 num_new_palette
= num_palette
;
318 /* initial wild guess at how far apart the farthest pixel
319 pair we will be eliminating will be. Larger
320 numbers mean more areas will be allocated, Smaller
321 numbers run the risk of not saving enough data, and
322 having to do this all over again.
324 I have not done extensive checking on this number.
328 while (num_new_palette
> maximum_colors
)
330 for (i
= 0; i
< num_new_palette
- 1; i
++)
334 for (j
= i
+ 1; j
< num_new_palette
; j
++)
338 d
= PNG_COLOR_DIST(palette
[i
], palette
[j
]);
343 t
= (png_dsortp
)png_malloc_warn(png_ptr
,
344 (png_uint_32
)(png_sizeof(png_dsort
)));
348 t
->left
= (png_byte
)i
;
349 t
->right
= (png_byte
)j
;
358 for (i
= 0; i
<= max_d
; i
++)
364 for (p
= hash
[i
]; p
; p
= p
->next
)
366 if ((int)png_ptr
->index_to_palette
[p
->left
]
368 (int)png_ptr
->index_to_palette
[p
->right
]
373 if (num_new_palette
& 0x01)
385 palette
[png_ptr
->index_to_palette
[j
]]
386 = palette
[num_new_palette
];
391 for (k
= 0; k
< num_palette
; k
++)
393 if (png_ptr
->dither_index
[k
] ==
394 png_ptr
->index_to_palette
[j
])
395 png_ptr
->dither_index
[k
] =
396 png_ptr
->index_to_palette
[next_j
];
397 if ((int)png_ptr
->dither_index
[k
] ==
399 png_ptr
->dither_index
[k
] =
400 png_ptr
->index_to_palette
[j
];
404 png_ptr
->index_to_palette
[png_ptr
->palette_to_index
405 [num_new_palette
]] = png_ptr
->index_to_palette
[j
];
406 png_ptr
->palette_to_index
[png_ptr
->index_to_palette
[j
]]
407 = png_ptr
->palette_to_index
[num_new_palette
];
409 png_ptr
->index_to_palette
[j
] = (png_byte
)num_new_palette
;
410 png_ptr
->palette_to_index
[num_new_palette
] = (png_byte
)j
;
412 if (num_new_palette
<= maximum_colors
)
415 if (num_new_palette
<= maximum_colors
)
420 for (i
= 0; i
< 769; i
++)
424 png_dsortp p
= hash
[i
];
428 png_free(png_ptr
, p
);
436 png_free(png_ptr
, hash
);
437 png_free(png_ptr
, png_ptr
->palette_to_index
);
438 png_free(png_ptr
, png_ptr
->index_to_palette
);
439 png_ptr
->palette_to_index
=NULL
;
440 png_ptr
->index_to_palette
=NULL
;
442 num_palette
= maximum_colors
;
444 if (png_ptr
->palette
== NULL
)
446 png_ptr
->palette
= palette
;
448 png_ptr
->num_palette
= (png_uint_16
)num_palette
;
454 int total_bits
= PNG_DITHER_RED_BITS
+ PNG_DITHER_GREEN_BITS
+
455 PNG_DITHER_BLUE_BITS
;
456 int num_red
= (1 << PNG_DITHER_RED_BITS
);
457 int num_green
= (1 << PNG_DITHER_GREEN_BITS
);
458 int num_blue
= (1 << PNG_DITHER_BLUE_BITS
);
459 png_size_t num_entries
= ((png_size_t
)1 << total_bits
);
461 png_ptr
->palette_lookup
= (png_bytep
)png_malloc(png_ptr
,
462 (png_uint_32
)(num_entries
* png_sizeof (png_byte
)));
464 png_memset(png_ptr
->palette_lookup
, 0, num_entries
*
465 png_sizeof (png_byte
));
467 distance
= (png_bytep
)png_malloc(png_ptr
, (png_uint_32
)(num_entries
*
468 png_sizeof(png_byte
)));
470 png_memset(distance
, 0xff, num_entries
* png_sizeof(png_byte
));
472 for (i
= 0; i
< num_palette
; i
++)
475 int r
= (palette
[i
].red
>> (8 - PNG_DITHER_RED_BITS
));
476 int g
= (palette
[i
].green
>> (8 - PNG_DITHER_GREEN_BITS
));
477 int b
= (palette
[i
].blue
>> (8 - PNG_DITHER_BLUE_BITS
));
479 for (ir
= 0; ir
< num_red
; ir
++)
481 /* int dr = abs(ir - r); */
482 int dr
= ((ir
> r
) ? ir
- r
: r
- ir
);
483 int index_r
= (ir
<< (PNG_DITHER_BLUE_BITS
+ PNG_DITHER_GREEN_BITS
));
485 for (ig
= 0; ig
< num_green
; ig
++)
487 /* int dg = abs(ig - g); */
488 int dg
= ((ig
> g
) ? ig
- g
: g
- ig
);
490 int dm
= ((dr
> dg
) ? dr
: dg
);
491 int index_g
= index_r
| (ig
<< PNG_DITHER_BLUE_BITS
);
493 for (ib
= 0; ib
< num_blue
; ib
++)
495 int d_index
= index_g
| ib
;
496 /* int db = abs(ib - b); */
497 int db
= ((ib
> b
) ? ib
- b
: b
- ib
);
498 int dmax
= ((dm
> db
) ? dm
: db
);
499 int d
= dmax
+ dt
+ db
;
501 if (d
< (int)distance
[d_index
])
503 distance
[d_index
] = (png_byte
)d
;
504 png_ptr
->palette_lookup
[d_index
] = (png_byte
)i
;
511 png_free(png_ptr
, distance
);
516 #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
517 /* Transform the image from the file_gamma to the screen_gamma. We
518 * only do transformations on images where the file_gamma and screen_gamma
519 * are not close reciprocals, otherwise it slows things down slightly, and
520 * also needlessly introduces small errors.
522 * We will turn off gamma transformation later if no semitransparent entries
523 * are present in the tRNS array for palette images. We can't do it here
524 * because we don't necessarily have the tRNS chunk yet.
527 png_set_gamma(png_structp png_ptr
, double scrn_gamma
, double file_gamma
)
529 png_debug(1, "in png_set_gamma\n");
530 if(png_ptr
== NULL
) return;
531 if ((fabs(scrn_gamma
* file_gamma
- 1.0) > PNG_GAMMA_THRESHOLD
) ||
532 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
) ||
533 (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
))
534 png_ptr
->transformations
|= PNG_GAMMA
;
535 png_ptr
->gamma
= (float)file_gamma
;
536 png_ptr
->screen_gamma
= (float)scrn_gamma
;
540 #if defined(PNG_READ_EXPAND_SUPPORTED)
541 /* Expand paletted images to RGB, expand grayscale images of
542 * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
546 png_set_expand(png_structp png_ptr
)
548 png_debug(1, "in png_set_expand\n");
549 if(png_ptr
== NULL
) return;
550 png_ptr
->transformations
|= (PNG_EXPAND
| PNG_EXPAND_tRNS
);
551 #ifdef PNG_WARN_UNINITIALIZED_ROW
552 png_ptr
->flags
&= !(PNG_FLAG_ROW_INIT
);
556 /* GRR 19990627: the following three functions currently are identical
557 * to png_set_expand(). However, it is entirely reasonable that someone
558 * might wish to expand an indexed image to RGB but *not* expand a single,
559 * fully transparent palette entry to a full alpha channel--perhaps instead
560 * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
561 * the transparent color with a particular RGB value, or drop tRNS entirely.
562 * IOW, a future version of the library may make the transformations flag
563 * a bit more fine-grained, with separate bits for each of these three
566 * More to the point, these functions make it obvious what libpng will be
567 * doing, whereas "expand" can (and does) mean any number of things.
569 * GRP 20060307: In libpng-1.4.0, png_set_gray_1_2_4_to_8() was modified
570 * to expand only the sample depth but not to expand the tRNS to alpha.
573 /* Expand paletted images to RGB. */
575 png_set_palette_to_rgb(png_structp png_ptr
)
577 png_debug(1, "in png_set_palette_to_rgb\n");
578 if(png_ptr
== NULL
) return;
579 png_ptr
->transformations
|= (PNG_EXPAND
| PNG_EXPAND_tRNS
);
580 #ifdef PNG_WARN_UNINITIALIZED_ROW
581 png_ptr
->flags
&= !(PNG_FLAG_ROW_INIT
);
585 #if !defined(PNG_1_0_X)
586 /* Expand grayscale images of less than 8-bit depth to 8 bits. */
588 png_set_expand_gray_1_2_4_to_8(png_structp png_ptr
)
590 png_debug(1, "in png_set_expand_gray_1_2_4_to_8\n");
591 if(png_ptr
== NULL
) return;
592 png_ptr
->transformations
|= PNG_EXPAND
;
593 #ifdef PNG_WARN_UNINITIALIZED_ROW
594 png_ptr
->flags
&= !(PNG_FLAG_ROW_INIT
);
599 #if defined(PNG_1_0_X) || defined(PNG_1_2_X)
600 /* Expand grayscale images of less than 8-bit depth to 8 bits. */
601 /* Deprecated as of libpng-1.2.9 */
603 png_set_gray_1_2_4_to_8(png_structp png_ptr
)
605 png_debug(1, "in png_set_gray_1_2_4_to_8\n");
606 if(png_ptr
== NULL
) return;
607 png_ptr
->transformations
|= (PNG_EXPAND
| PNG_EXPAND_tRNS
);
612 /* Expand tRNS chunks to alpha channels. */
614 png_set_tRNS_to_alpha(png_structp png_ptr
)
616 png_debug(1, "in png_set_tRNS_to_alpha\n");
617 png_ptr
->transformations
|= (PNG_EXPAND
| PNG_EXPAND_tRNS
);
618 #ifdef PNG_WARN_UNINITIALIZED_ROW
619 png_ptr
->flags
&= !(PNG_FLAG_ROW_INIT
);
622 #endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
624 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
626 png_set_gray_to_rgb(png_structp png_ptr
)
628 png_debug(1, "in png_set_gray_to_rgb\n");
629 png_ptr
->transformations
|= PNG_GRAY_TO_RGB
;
630 #ifdef PNG_WARN_UNINITIALIZED_ROW
631 png_ptr
->flags
&= !(PNG_FLAG_ROW_INIT
);
636 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
637 #if defined(PNG_FLOATING_POINT_SUPPORTED)
638 /* Convert a RGB image to a grayscale of the same width. This allows us,
639 * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
643 png_set_rgb_to_gray(png_structp png_ptr
, int error_action
, double red
,
646 int red_fixed
= (int)((float)red
*100000.0 + 0.5);
647 int green_fixed
= (int)((float)green
*100000.0 + 0.5);
648 if(png_ptr
== NULL
) return;
649 png_set_rgb_to_gray_fixed(png_ptr
, error_action
, red_fixed
, green_fixed
);
654 png_set_rgb_to_gray_fixed(png_structp png_ptr
, int error_action
,
655 png_fixed_point red
, png_fixed_point green
)
657 png_debug(1, "in png_set_rgb_to_gray\n");
658 if(png_ptr
== NULL
) return;
661 case 1: png_ptr
->transformations
|= PNG_RGB_TO_GRAY
;
663 case 2: png_ptr
->transformations
|= PNG_RGB_TO_GRAY_WARN
;
665 case 3: png_ptr
->transformations
|= PNG_RGB_TO_GRAY_ERR
;
667 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
668 #if defined(PNG_READ_EXPAND_SUPPORTED)
669 png_ptr
->transformations
|= PNG_EXPAND
;
672 png_warning(png_ptr
, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
673 png_ptr
->transformations
&= ~PNG_RGB_TO_GRAY
;
677 png_uint_16 red_int
, green_int
;
678 if(red
< 0 || green
< 0)
680 red_int
= 6968; /* .212671 * 32768 + .5 */
681 green_int
= 23434; /* .715160 * 32768 + .5 */
683 else if(red
+ green
< 100000L)
685 red_int
= (png_uint_16
)(((png_uint_32
)red
*32768L)/100000L);
686 green_int
= (png_uint_16
)(((png_uint_32
)green
*32768L)/100000L);
690 png_warning(png_ptr
, "ignoring out of range rgb_to_gray coefficients");
694 png_ptr
->rgb_to_gray_red_coeff
= red_int
;
695 png_ptr
->rgb_to_gray_green_coeff
= green_int
;
696 png_ptr
->rgb_to_gray_blue_coeff
= (png_uint_16
)(32768-red_int
-green_int
);
701 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
702 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
703 defined(PNG_LEGACY_SUPPORTED)
705 png_set_read_user_transform_fn(png_structp png_ptr
, png_user_transform_ptr
706 read_user_transform_fn
)
708 png_debug(1, "in png_set_read_user_transform_fn\n");
709 if(png_ptr
== NULL
) return;
710 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
711 png_ptr
->transformations
|= PNG_USER_TRANSFORM
;
712 png_ptr
->read_user_transform_fn
= read_user_transform_fn
;
714 #ifdef PNG_LEGACY_SUPPORTED
715 if(read_user_transform_fn
)
717 "This version of libpng does not support user transforms");
722 /* Initialize everything needed for the read. This includes modifying
726 png_init_read_transformations(png_structp png_ptr
)
728 png_debug(1, "in png_init_read_transformations\n");
729 #if defined(PNG_USELESS_TESTS_SUPPORTED)
733 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
734 || defined(PNG_READ_GAMMA_SUPPORTED)
735 int color_type
= png_ptr
->color_type
;
738 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
740 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
741 /* Detect gray background and attempt to enable optimization
742 * for gray --> RGB case */
743 /* Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
744 * RGB_ALPHA (in which case need_expand is superfluous anyway), the
745 * background color might actually be gray yet not be flagged as such.
746 * This is not a problem for the current code, which uses
747 * PNG_BACKGROUND_IS_GRAY only to decide when to do the
748 * png_do_gray_to_rgb() transformation.
750 if ((png_ptr
->transformations
& PNG_BACKGROUND_EXPAND
) &&
751 !(color_type
& PNG_COLOR_MASK_COLOR
))
753 png_ptr
->mode
|= PNG_BACKGROUND_IS_GRAY
;
754 } else if ((png_ptr
->transformations
& PNG_BACKGROUND
) &&
755 !(png_ptr
->transformations
& PNG_BACKGROUND_EXPAND
) &&
756 (png_ptr
->transformations
& PNG_GRAY_TO_RGB
) &&
757 png_ptr
->background
.red
== png_ptr
->background
.green
&&
758 png_ptr
->background
.red
== png_ptr
->background
.blue
)
760 png_ptr
->mode
|= PNG_BACKGROUND_IS_GRAY
;
761 png_ptr
->background
.gray
= png_ptr
->background
.red
;
765 if ((png_ptr
->transformations
& PNG_BACKGROUND_EXPAND
) &&
766 (png_ptr
->transformations
& PNG_EXPAND
))
768 if (!(color_type
& PNG_COLOR_MASK_COLOR
)) /* i.e., GRAY or GRAY_ALPHA */
770 /* expand background and tRNS chunks */
771 switch (png_ptr
->bit_depth
)
774 png_ptr
->background
.gray
*= (png_uint_16
)0xff;
775 png_ptr
->background
.red
= png_ptr
->background
.green
776 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
777 if (!(png_ptr
->transformations
& PNG_EXPAND_tRNS
))
779 png_ptr
->trans_values
.gray
*= (png_uint_16
)0xff;
780 png_ptr
->trans_values
.red
= png_ptr
->trans_values
.green
781 = png_ptr
->trans_values
.blue
= png_ptr
->trans_values
.gray
;
785 png_ptr
->background
.gray
*= (png_uint_16
)0x55;
786 png_ptr
->background
.red
= png_ptr
->background
.green
787 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
788 if (!(png_ptr
->transformations
& PNG_EXPAND_tRNS
))
790 png_ptr
->trans_values
.gray
*= (png_uint_16
)0x55;
791 png_ptr
->trans_values
.red
= png_ptr
->trans_values
.green
792 = png_ptr
->trans_values
.blue
= png_ptr
->trans_values
.gray
;
796 png_ptr
->background
.gray
*= (png_uint_16
)0x11;
797 png_ptr
->background
.red
= png_ptr
->background
.green
798 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
799 if (!(png_ptr
->transformations
& PNG_EXPAND_tRNS
))
801 png_ptr
->trans_values
.gray
*= (png_uint_16
)0x11;
802 png_ptr
->trans_values
.red
= png_ptr
->trans_values
.green
803 = png_ptr
->trans_values
.blue
= png_ptr
->trans_values
.gray
;
808 png_ptr
->background
.red
= png_ptr
->background
.green
809 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
813 else if (color_type
== PNG_COLOR_TYPE_PALETTE
)
815 png_ptr
->background
.red
=
816 png_ptr
->palette
[png_ptr
->background
.index
].red
;
817 png_ptr
->background
.green
=
818 png_ptr
->palette
[png_ptr
->background
.index
].green
;
819 png_ptr
->background
.blue
=
820 png_ptr
->palette
[png_ptr
->background
.index
].blue
;
822 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
823 if (png_ptr
->transformations
& PNG_INVERT_ALPHA
)
825 #if defined(PNG_READ_EXPAND_SUPPORTED)
826 if (!(png_ptr
->transformations
& PNG_EXPAND_tRNS
))
829 /* invert the alpha channel (in tRNS) unless the pixels are
830 going to be expanded, in which case leave it for later */
832 istop
=(int)png_ptr
->num_trans
;
833 for (i
=0; i
<istop
; i
++)
834 png_ptr
->trans
[i
] = (png_byte
)(255 - png_ptr
->trans
[i
]);
843 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
844 png_ptr
->background_1
= png_ptr
->background
;
846 #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
848 if ((color_type
== PNG_COLOR_TYPE_PALETTE
&& png_ptr
->num_trans
!= 0)
849 && (fabs(png_ptr
->screen_gamma
* png_ptr
->gamma
- 1.0)
850 < PNG_GAMMA_THRESHOLD
))
854 for (i
=0; i
<png_ptr
->num_trans
; i
++)
856 if (png_ptr
->trans
[i
] != 0 && png_ptr
->trans
[i
] != 0xff)
857 k
=1; /* partial transparency is present */
860 png_ptr
->transformations
&= (~PNG_GAMMA
);
863 if ((png_ptr
->transformations
& (PNG_GAMMA
| PNG_RGB_TO_GRAY
)) &&
864 png_ptr
->gamma
!= 0.0)
866 png_build_gamma_table(png_ptr
);
867 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
868 if (png_ptr
->transformations
& PNG_BACKGROUND
)
870 if (color_type
== PNG_COLOR_TYPE_PALETTE
)
872 /* could skip if no transparency and
874 png_color back
, back_1
;
875 png_colorp palette
= png_ptr
->palette
;
876 int num_palette
= png_ptr
->num_palette
;
878 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_FILE
)
880 back
.red
= png_ptr
->gamma_table
[png_ptr
->background
.red
];
881 back
.green
= png_ptr
->gamma_table
[png_ptr
->background
.green
];
882 back
.blue
= png_ptr
->gamma_table
[png_ptr
->background
.blue
];
884 back_1
.red
= png_ptr
->gamma_to_1
[png_ptr
->background
.red
];
885 back_1
.green
= png_ptr
->gamma_to_1
[png_ptr
->background
.green
];
886 back_1
.blue
= png_ptr
->gamma_to_1
[png_ptr
->background
.blue
];
892 switch (png_ptr
->background_gamma_type
)
894 case PNG_BACKGROUND_GAMMA_SCREEN
:
895 g
= (png_ptr
->screen_gamma
);
898 case PNG_BACKGROUND_GAMMA_FILE
:
899 g
= 1.0 / (png_ptr
->gamma
);
900 gs
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
902 case PNG_BACKGROUND_GAMMA_UNIQUE
:
903 g
= 1.0 / (png_ptr
->background_gamma
);
904 gs
= 1.0 / (png_ptr
->background_gamma
*
905 png_ptr
->screen_gamma
);
908 g
= 1.0; /* back_1 */
912 if ( fabs(gs
- 1.0) < PNG_GAMMA_THRESHOLD
)
914 back
.red
= (png_byte
)png_ptr
->background
.red
;
915 back
.green
= (png_byte
)png_ptr
->background
.green
;
916 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
920 back
.red
= (png_byte
)(pow(
921 (double)png_ptr
->background
.red
/255, gs
) * 255.0 + .5);
922 back
.green
= (png_byte
)(pow(
923 (double)png_ptr
->background
.green
/255, gs
) * 255.0 + .5);
924 back
.blue
= (png_byte
)(pow(
925 (double)png_ptr
->background
.blue
/255, gs
) * 255.0 + .5);
928 back_1
.red
= (png_byte
)(pow(
929 (double)png_ptr
->background
.red
/255, g
) * 255.0 + .5);
930 back_1
.green
= (png_byte
)(pow(
931 (double)png_ptr
->background
.green
/255, g
) * 255.0 + .5);
932 back_1
.blue
= (png_byte
)(pow(
933 (double)png_ptr
->background
.blue
/255, g
) * 255.0 + .5);
935 for (i
= 0; i
< num_palette
; i
++)
937 if (i
< (int)png_ptr
->num_trans
&& png_ptr
->trans
[i
] != 0xff)
939 if (png_ptr
->trans
[i
] == 0)
943 else /* if (png_ptr->trans[i] != 0xff) */
947 v
= png_ptr
->gamma_to_1
[palette
[i
].red
];
948 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.red
);
949 palette
[i
].red
= png_ptr
->gamma_from_1
[w
];
951 v
= png_ptr
->gamma_to_1
[palette
[i
].green
];
952 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.green
);
953 palette
[i
].green
= png_ptr
->gamma_from_1
[w
];
955 v
= png_ptr
->gamma_to_1
[palette
[i
].blue
];
956 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.blue
);
957 palette
[i
].blue
= png_ptr
->gamma_from_1
[w
];
962 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
963 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
964 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
968 /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
970 /* color_type != PNG_COLOR_TYPE_PALETTE */
972 double m
= (double)(((png_uint_32
)1 << png_ptr
->bit_depth
) - 1);
976 switch (png_ptr
->background_gamma_type
)
978 case PNG_BACKGROUND_GAMMA_SCREEN
:
979 g
= (png_ptr
->screen_gamma
);
982 case PNG_BACKGROUND_GAMMA_FILE
:
983 g
= 1.0 / (png_ptr
->gamma
);
984 gs
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
986 case PNG_BACKGROUND_GAMMA_UNIQUE
:
987 g
= 1.0 / (png_ptr
->background_gamma
);
988 gs
= 1.0 / (png_ptr
->background_gamma
*
989 png_ptr
->screen_gamma
);
993 png_ptr
->background_1
.gray
= (png_uint_16
)(pow(
994 (double)png_ptr
->background
.gray
/ m
, g
) * m
+ .5);
995 png_ptr
->background
.gray
= (png_uint_16
)(pow(
996 (double)png_ptr
->background
.gray
/ m
, gs
) * m
+ .5);
998 if ((png_ptr
->background
.red
!= png_ptr
->background
.green
) ||
999 (png_ptr
->background
.red
!= png_ptr
->background
.blue
) ||
1000 (png_ptr
->background
.red
!= png_ptr
->background
.gray
))
1002 /* RGB or RGBA with color background */
1003 png_ptr
->background_1
.red
= (png_uint_16
)(pow(
1004 (double)png_ptr
->background
.red
/ m
, g
) * m
+ .5);
1005 png_ptr
->background_1
.green
= (png_uint_16
)(pow(
1006 (double)png_ptr
->background
.green
/ m
, g
) * m
+ .5);
1007 png_ptr
->background_1
.blue
= (png_uint_16
)(pow(
1008 (double)png_ptr
->background
.blue
/ m
, g
) * m
+ .5);
1009 png_ptr
->background
.red
= (png_uint_16
)(pow(
1010 (double)png_ptr
->background
.red
/ m
, gs
) * m
+ .5);
1011 png_ptr
->background
.green
= (png_uint_16
)(pow(
1012 (double)png_ptr
->background
.green
/ m
, gs
) * m
+ .5);
1013 png_ptr
->background
.blue
= (png_uint_16
)(pow(
1014 (double)png_ptr
->background
.blue
/ m
, gs
) * m
+ .5);
1018 /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
1019 png_ptr
->background_1
.red
= png_ptr
->background_1
.green
1020 = png_ptr
->background_1
.blue
= png_ptr
->background_1
.gray
;
1021 png_ptr
->background
.red
= png_ptr
->background
.green
1022 = png_ptr
->background
.blue
= png_ptr
->background
.gray
;
1027 /* transformation does not include PNG_BACKGROUND */
1028 #endif /* PNG_READ_BACKGROUND_SUPPORTED */
1029 if (color_type
== PNG_COLOR_TYPE_PALETTE
)
1031 png_colorp palette
= png_ptr
->palette
;
1032 int num_palette
= png_ptr
->num_palette
;
1035 for (i
= 0; i
< num_palette
; i
++)
1037 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
1038 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
1039 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
1043 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1046 #endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */
1047 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1048 /* No GAMMA transformation */
1049 if ((png_ptr
->transformations
& PNG_BACKGROUND
) &&
1050 (color_type
== PNG_COLOR_TYPE_PALETTE
))
1053 int istop
= (int)png_ptr
->num_trans
;
1055 png_colorp palette
= png_ptr
->palette
;
1057 back
.red
= (png_byte
)png_ptr
->background
.red
;
1058 back
.green
= (png_byte
)png_ptr
->background
.green
;
1059 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
1061 for (i
= 0; i
< istop
; i
++)
1063 if (png_ptr
->trans
[i
] == 0)
1067 else if (png_ptr
->trans
[i
] != 0xff)
1069 /* The png_composite() macro is defined in png.h */
1070 png_composite(palette
[i
].red
, palette
[i
].red
,
1071 png_ptr
->trans
[i
], back
.red
);
1072 png_composite(palette
[i
].green
, palette
[i
].green
,
1073 png_ptr
->trans
[i
], back
.green
);
1074 png_composite(palette
[i
].blue
, palette
[i
].blue
,
1075 png_ptr
->trans
[i
], back
.blue
);
1079 #endif /* PNG_READ_BACKGROUND_SUPPORTED */
1081 #if defined(PNG_READ_SHIFT_SUPPORTED)
1082 if ((png_ptr
->transformations
& PNG_SHIFT
) &&
1083 (color_type
== PNG_COLOR_TYPE_PALETTE
))
1086 png_uint_16 istop
= png_ptr
->num_palette
;
1087 int sr
= 8 - png_ptr
->sig_bit
.red
;
1088 int sg
= 8 - png_ptr
->sig_bit
.green
;
1089 int sb
= 8 - png_ptr
->sig_bit
.blue
;
1091 if (sr
< 0 || sr
> 8)
1093 if (sg
< 0 || sg
> 8)
1095 if (sb
< 0 || sb
> 8)
1097 for (i
= 0; i
< istop
; i
++)
1099 png_ptr
->palette
[i
].red
>>= sr
;
1100 png_ptr
->palette
[i
].green
>>= sg
;
1101 png_ptr
->palette
[i
].blue
>>= sb
;
1104 #endif /* PNG_READ_SHIFT_SUPPORTED */
1106 #if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
1107 && !defined(PNG_READ_BACKGROUND_SUPPORTED)
1113 /* Modify the info structure to reflect the transformations. The
1114 * info should be updated so a PNG file could be written with it,
1115 * assuming the transformations result in valid PNG data.
1118 png_read_transform_info(png_structp png_ptr
, png_infop info_ptr
)
1120 png_debug(1, "in png_read_transform_info\n");
1121 #if defined(PNG_READ_EXPAND_SUPPORTED)
1122 if (png_ptr
->transformations
& PNG_EXPAND
)
1124 if (info_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1126 if (png_ptr
->num_trans
&& (png_ptr
->transformations
& PNG_EXPAND_tRNS
))
1127 info_ptr
->color_type
= PNG_COLOR_TYPE_RGB_ALPHA
;
1129 info_ptr
->color_type
= PNG_COLOR_TYPE_RGB
;
1130 info_ptr
->bit_depth
= 8;
1131 info_ptr
->num_trans
= 0;
1135 if (png_ptr
->num_trans
)
1137 if (png_ptr
->transformations
& PNG_EXPAND_tRNS
)
1138 info_ptr
->color_type
|= PNG_COLOR_MASK_ALPHA
;
1140 info_ptr
->color_type
|= PNG_COLOR_MASK_COLOR
;
1142 if (info_ptr
->bit_depth
< 8)
1143 info_ptr
->bit_depth
= 8;
1144 info_ptr
->num_trans
= 0;
1149 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1150 if (png_ptr
->transformations
& PNG_BACKGROUND
)
1152 info_ptr
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
1153 info_ptr
->num_trans
= 0;
1154 info_ptr
->background
= png_ptr
->background
;
1158 #if defined(PNG_READ_GAMMA_SUPPORTED)
1159 if (png_ptr
->transformations
& PNG_GAMMA
)
1161 #ifdef PNG_FLOATING_POINT_SUPPORTED
1162 info_ptr
->gamma
= png_ptr
->gamma
;
1164 #ifdef PNG_FIXED_POINT_SUPPORTED
1165 info_ptr
->int_gamma
= png_ptr
->int_gamma
;
1170 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1171 if ((png_ptr
->transformations
& PNG_16_TO_8
) && (info_ptr
->bit_depth
== 16))
1172 info_ptr
->bit_depth
= 8;
1175 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1176 if (png_ptr
->transformations
& PNG_GRAY_TO_RGB
)
1177 info_ptr
->color_type
|= PNG_COLOR_MASK_COLOR
;
1180 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1181 if (png_ptr
->transformations
& PNG_RGB_TO_GRAY
)
1182 info_ptr
->color_type
&= ~PNG_COLOR_MASK_COLOR
;
1185 #if defined(PNG_READ_DITHER_SUPPORTED)
1186 if (png_ptr
->transformations
& PNG_DITHER
)
1188 if (((info_ptr
->color_type
== PNG_COLOR_TYPE_RGB
) ||
1189 (info_ptr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)) &&
1190 png_ptr
->palette_lookup
&& info_ptr
->bit_depth
== 8)
1192 info_ptr
->color_type
= PNG_COLOR_TYPE_PALETTE
;
1197 #if defined(PNG_READ_PACK_SUPPORTED)
1198 if ((png_ptr
->transformations
& PNG_PACK
) && (info_ptr
->bit_depth
< 8))
1199 info_ptr
->bit_depth
= 8;
1202 if (info_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1203 info_ptr
->channels
= 1;
1204 else if (info_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
1205 info_ptr
->channels
= 3;
1207 info_ptr
->channels
= 1;
1209 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1210 if (png_ptr
->flags
& PNG_FLAG_STRIP_ALPHA
)
1211 info_ptr
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
1214 if (info_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
)
1215 info_ptr
->channels
++;
1217 #if defined(PNG_READ_FILLER_SUPPORTED)
1218 /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
1219 if ((png_ptr
->transformations
& PNG_FILLER
) &&
1220 ((info_ptr
->color_type
== PNG_COLOR_TYPE_RGB
) ||
1221 (info_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)))
1223 info_ptr
->channels
++;
1224 /* if adding a true alpha channel not just filler */
1225 #if !defined(PNG_1_0_X)
1226 if (png_ptr
->transformations
& PNG_ADD_ALPHA
)
1227 info_ptr
->color_type
|= PNG_COLOR_MASK_ALPHA
;
1232 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
1233 defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1234 if(png_ptr
->transformations
& PNG_USER_TRANSFORM
)
1236 if(info_ptr
->bit_depth
< png_ptr
->user_transform_depth
)
1237 info_ptr
->bit_depth
= png_ptr
->user_transform_depth
;
1238 if(info_ptr
->channels
< png_ptr
->user_transform_channels
)
1239 info_ptr
->channels
= png_ptr
->user_transform_channels
;
1243 info_ptr
->pixel_depth
= (png_byte
)(info_ptr
->channels
*
1244 info_ptr
->bit_depth
);
1246 info_ptr
->rowbytes
= PNG_ROWBYTES(info_ptr
->pixel_depth
,info_ptr
->width
);
1248 #if !defined(PNG_READ_EXPAND_SUPPORTED)
1254 /* Transform the row. The order of transformations is significant,
1255 * and is very touchy. If you add a transformation, take care to
1256 * decide how it fits in with the other transformations here.
1259 png_do_read_transformations(png_structp png_ptr
)
1261 png_debug(1, "in png_do_read_transformations\n");
1262 if (png_ptr
->row_buf
== NULL
)
1264 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
1267 png_snprintf2(msg
, 50,
1268 "NULL row buffer for row %ld, pass %d", png_ptr
->row_number
,
1270 png_error(png_ptr
, msg
);
1272 png_error(png_ptr
, "NULL row buffer");
1275 #ifdef PNG_WARN_UNINITIALIZED_ROW
1276 if (!(png_ptr
->flags
& PNG_FLAG_ROW_INIT
))
1277 /* Application has failed to call either png_read_start_image()
1278 * or png_read_update_info() after setting transforms that expand
1279 * pixels. This check added to libpng-1.2.19 */
1280 #if (PNG_WARN_UNINITIALIZED_ROW==1)
1281 png_error(png_ptr
, "Uninitialized row");
1283 png_warning(png_ptr
, "Uninitialized row");
1287 #if defined(PNG_READ_EXPAND_SUPPORTED)
1288 if (png_ptr
->transformations
& PNG_EXPAND
)
1290 if (png_ptr
->row_info
.color_type
== PNG_COLOR_TYPE_PALETTE
)
1292 png_do_expand_palette(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1293 png_ptr
->palette
, png_ptr
->trans
, png_ptr
->num_trans
);
1297 if (png_ptr
->num_trans
&&
1298 (png_ptr
->transformations
& PNG_EXPAND_tRNS
))
1299 png_do_expand(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1300 &(png_ptr
->trans_values
));
1302 png_do_expand(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1308 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1309 if (png_ptr
->flags
& PNG_FLAG_STRIP_ALPHA
)
1310 png_do_strip_filler(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1311 PNG_FLAG_FILLER_AFTER
| (png_ptr
->flags
& PNG_FLAG_STRIP_ALPHA
));
1314 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1315 if (png_ptr
->transformations
& PNG_RGB_TO_GRAY
)
1318 png_do_rgb_to_gray(png_ptr
, &(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1321 png_ptr
->rgb_to_gray_status
=1;
1322 if((png_ptr
->transformations
& PNG_RGB_TO_GRAY
) ==
1323 PNG_RGB_TO_GRAY_WARN
)
1324 png_warning(png_ptr
, "png_do_rgb_to_gray found nongray pixel");
1325 if((png_ptr
->transformations
& PNG_RGB_TO_GRAY
) ==
1326 PNG_RGB_TO_GRAY_ERR
)
1327 png_error(png_ptr
, "png_do_rgb_to_gray found nongray pixel");
1333 From Andreas Dilger e-mail to png-implement, 26 March 1998:
1335 In most cases, the "simple transparency" should be done prior to doing
1336 gray-to-RGB, or you will have to test 3x as many bytes to check if a
1337 pixel is transparent. You would also need to make sure that the
1338 transparency information is upgraded to RGB.
1340 To summarize, the current flow is:
1341 - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
1342 with background "in place" if transparent,
1343 convert to RGB if necessary
1344 - Gray + alpha -> composite with gray background and remove alpha bytes,
1345 convert to RGB if necessary
1347 To support RGB backgrounds for gray images we need:
1348 - Gray + simple transparency -> convert to RGB + simple transparency, compare
1349 3 or 6 bytes and composite with background
1350 "in place" if transparent (3x compare/pixel
1351 compared to doing composite with gray bkgrnd)
1352 - Gray + alpha -> convert to RGB + alpha, composite with background and
1353 remove alpha bytes (3x float operations/pixel
1354 compared with composite on gray background)
1356 Greg's change will do this. The reason it wasn't done before is for
1357 performance, as this increases the per-pixel operations. If we would check
1358 in advance if the background was gray or RGB, and position the gray-to-RGB
1359 transform appropriately, then it would save a lot of work/time.
1362 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1363 /* if gray -> RGB, do so now only if background is non-gray; else do later
1364 * for performance reasons */
1365 if ((png_ptr
->transformations
& PNG_GRAY_TO_RGB
) &&
1366 !(png_ptr
->mode
& PNG_BACKGROUND_IS_GRAY
))
1367 png_do_gray_to_rgb(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1370 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1371 if ((png_ptr
->transformations
& PNG_BACKGROUND
) &&
1372 ((png_ptr
->num_trans
!= 0 ) ||
1373 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
)))
1374 png_do_background(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1375 &(png_ptr
->trans_values
), &(png_ptr
->background
)
1376 #if defined(PNG_READ_GAMMA_SUPPORTED)
1377 , &(png_ptr
->background_1
),
1378 png_ptr
->gamma_table
, png_ptr
->gamma_from_1
,
1379 png_ptr
->gamma_to_1
, png_ptr
->gamma_16_table
,
1380 png_ptr
->gamma_16_from_1
, png_ptr
->gamma_16_to_1
,
1381 png_ptr
->gamma_shift
1386 #if defined(PNG_READ_GAMMA_SUPPORTED)
1387 if ((png_ptr
->transformations
& PNG_GAMMA
) &&
1388 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1389 !((png_ptr
->transformations
& PNG_BACKGROUND
) &&
1390 ((png_ptr
->num_trans
!= 0) ||
1391 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
))) &&
1393 (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
))
1394 png_do_gamma(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1395 png_ptr
->gamma_table
, png_ptr
->gamma_16_table
,
1396 png_ptr
->gamma_shift
);
1399 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1400 if (png_ptr
->transformations
& PNG_16_TO_8
)
1401 png_do_chop(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1404 #if defined(PNG_READ_DITHER_SUPPORTED)
1405 if (png_ptr
->transformations
& PNG_DITHER
)
1407 png_do_dither((png_row_infop
)&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1408 png_ptr
->palette_lookup
, png_ptr
->dither_index
);
1409 if(png_ptr
->row_info
.rowbytes
== (png_uint_32
)0)
1410 png_error(png_ptr
, "png_do_dither returned rowbytes=0");
1414 #if defined(PNG_READ_INVERT_SUPPORTED)
1415 if (png_ptr
->transformations
& PNG_INVERT_MONO
)
1416 png_do_invert(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1419 #if defined(PNG_READ_SHIFT_SUPPORTED)
1420 if (png_ptr
->transformations
& PNG_SHIFT
)
1421 png_do_unshift(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1425 #if defined(PNG_READ_PACK_SUPPORTED)
1426 if (png_ptr
->transformations
& PNG_PACK
)
1427 png_do_unpack(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1430 #if defined(PNG_READ_BGR_SUPPORTED)
1431 if (png_ptr
->transformations
& PNG_BGR
)
1432 png_do_bgr(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1435 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1436 if (png_ptr
->transformations
& PNG_PACKSWAP
)
1437 png_do_packswap(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1440 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1441 /* if gray -> RGB, do so now only if we did not do so above */
1442 if ((png_ptr
->transformations
& PNG_GRAY_TO_RGB
) &&
1443 (png_ptr
->mode
& PNG_BACKGROUND_IS_GRAY
))
1444 png_do_gray_to_rgb(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1447 #if defined(PNG_READ_FILLER_SUPPORTED)
1448 if (png_ptr
->transformations
& PNG_FILLER
)
1449 png_do_read_filler(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1450 (png_uint_32
)png_ptr
->filler
, png_ptr
->flags
);
1453 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1454 if (png_ptr
->transformations
& PNG_INVERT_ALPHA
)
1455 png_do_read_invert_alpha(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1458 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1459 if (png_ptr
->transformations
& PNG_SWAP_ALPHA
)
1460 png_do_read_swap_alpha(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1463 #if defined(PNG_READ_SWAP_SUPPORTED)
1464 if (png_ptr
->transformations
& PNG_SWAP_BYTES
)
1465 png_do_swap(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1468 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1469 if (png_ptr
->transformations
& PNG_USER_TRANSFORM
)
1471 if(png_ptr
->read_user_transform_fn
!= NULL
)
1472 (*(png_ptr
->read_user_transform_fn
)) /* user read transform function */
1473 (png_ptr
, /* png_ptr */
1474 &(png_ptr
->row_info
), /* row_info: */
1475 /* png_uint_32 width; width of row */
1476 /* png_uint_32 rowbytes; number of bytes in row */
1477 /* png_byte color_type; color type of pixels */
1478 /* png_byte bit_depth; bit depth of samples */
1479 /* png_byte channels; number of channels (1-4) */
1480 /* png_byte pixel_depth; bits per pixel (depth*channels) */
1481 png_ptr
->row_buf
+ 1); /* start of pixel data for row */
1482 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
1483 if(png_ptr
->user_transform_depth
)
1484 png_ptr
->row_info
.bit_depth
= png_ptr
->user_transform_depth
;
1485 if(png_ptr
->user_transform_channels
)
1486 png_ptr
->row_info
.channels
= png_ptr
->user_transform_channels
;
1488 png_ptr
->row_info
.pixel_depth
= (png_byte
)(png_ptr
->row_info
.bit_depth
*
1489 png_ptr
->row_info
.channels
);
1490 png_ptr
->row_info
.rowbytes
= PNG_ROWBYTES(png_ptr
->row_info
.pixel_depth
,
1491 png_ptr
->row_info
.width
);
1497 #if defined(PNG_READ_PACK_SUPPORTED)
1498 /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
1499 * without changing the actual values. Thus, if you had a row with
1500 * a bit depth of 1, you would end up with bytes that only contained
1501 * the numbers 0 or 1. If you would rather they contain 0 and 255, use
1502 * png_do_shift() after this.
1505 png_do_unpack(png_row_infop row_info
, png_bytep row
)
1507 png_debug(1, "in png_do_unpack\n");
1508 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1509 if (row
!= NULL
&& row_info
!= NULL
&& row_info
->bit_depth
< 8)
1511 if (row_info
->bit_depth
< 8)
1515 png_uint_32 row_width
=row_info
->width
;
1517 switch (row_info
->bit_depth
)
1521 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
1522 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1523 png_uint_32 shift
= 7 - (int)((row_width
+ 7) & 0x07);
1524 for (i
= 0; i
< row_width
; i
++)
1526 *dp
= (png_byte
)((*sp
>> shift
) & 0x01);
1542 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
1543 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1544 png_uint_32 shift
= (int)((3 - ((row_width
+ 3) & 0x03)) << 1);
1545 for (i
= 0; i
< row_width
; i
++)
1547 *dp
= (png_byte
)((*sp
>> shift
) & 0x03);
1562 png_bytep sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
1563 png_bytep dp
= row
+ (png_size_t
)row_width
- 1;
1564 png_uint_32 shift
= (int)((1 - ((row_width
+ 1) & 0x01)) << 2);
1565 for (i
= 0; i
< row_width
; i
++)
1567 *dp
= (png_byte
)((*sp
>> shift
) & 0x0f);
1581 row_info
->bit_depth
= 8;
1582 row_info
->pixel_depth
= (png_byte
)(8 * row_info
->channels
);
1583 row_info
->rowbytes
= row_width
* row_info
->channels
;
1588 #if defined(PNG_READ_SHIFT_SUPPORTED)
1589 /* Reverse the effects of png_do_shift. This routine merely shifts the
1590 * pixels back to their significant bits values. Thus, if you have
1591 * a row of bit depth 8, but only 5 are significant, this will shift
1592 * the values back to 0 through 31.
1595 png_do_unshift(png_row_infop row_info
, png_bytep row
, png_color_8p sig_bits
)
1597 png_debug(1, "in png_do_unshift\n");
1599 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1600 row
!= NULL
&& row_info
!= NULL
&& sig_bits
!= NULL
&&
1602 row_info
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
1607 png_uint_16 value
= 0;
1608 png_uint_32 row_width
= row_info
->width
;
1610 if (row_info
->color_type
& PNG_COLOR_MASK_COLOR
)
1612 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->red
;
1613 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->green
;
1614 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->blue
;
1618 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->gray
;
1620 if (row_info
->color_type
& PNG_COLOR_MASK_ALPHA
)
1622 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->alpha
;
1625 for (c
= 0; c
< channels
; c
++)
1636 switch (row_info
->bit_depth
)
1642 png_uint_32 istop
= row_info
->rowbytes
;
1644 for (bp
= row
, i
= 0; i
< istop
; i
++)
1655 png_uint_32 istop
= row_info
->rowbytes
;
1656 png_byte mask
= (png_byte
)((((int)0xf0 >> shift
[0]) & (int)0xf0) |
1657 (png_byte
)((int)0xf >> shift
[0]));
1659 for (i
= 0; i
< istop
; i
++)
1670 png_uint_32 istop
= row_width
* channels
;
1672 for (i
= 0; i
< istop
; i
++)
1674 *bp
++ >>= shift
[i%channels
];
1682 png_uint_32 istop
= channels
* row_width
;
1684 for (i
= 0; i
< istop
; i
++)
1686 value
= (png_uint_16
)((*bp
<< 8) + *(bp
+ 1));
1687 value
>>= shift
[i%channels
];
1688 *bp
++ = (png_byte
)(value
>> 8);
1689 *bp
++ = (png_byte
)(value
& 0xff);
1698 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1699 /* chop rows of bit depth 16 down to 8 */
1701 png_do_chop(png_row_infop row_info
, png_bytep row
)
1703 png_debug(1, "in png_do_chop\n");
1704 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1705 if (row
!= NULL
&& row_info
!= NULL
&& row_info
->bit_depth
== 16)
1707 if (row_info
->bit_depth
== 16)
1713 png_uint_32 istop
= row_info
->width
* row_info
->channels
;
1715 for (i
= 0; i
<istop
; i
++, sp
+= 2, dp
++)
1717 #if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
1718 /* This does a more accurate scaling of the 16-bit color
1719 * value, rather than a simple low-byte truncation.
1721 * What the ideal calculation should be:
1722 * *dp = (((((png_uint_32)(*sp) << 8) |
1723 * (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L;
1725 * GRR: no, I think this is what it really should be:
1726 * *dp = (((((png_uint_32)(*sp) << 8) |
1727 * (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L;
1729 * GRR: here's the exact calculation with shifts:
1730 * temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L;
1731 * *dp = (temp - (temp >> 8)) >> 8;
1733 * Approximate calculation with shift/add instead of multiply/divide:
1734 * *dp = ((((png_uint_32)(*sp) << 8) |
1735 * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
1737 * What we actually do to avoid extra shifting and conversion:
1740 *dp
= *sp
+ ((((int)(*(sp
+ 1)) - *sp
) > 128) ? 1 : 0);
1742 /* Simply discard the low order byte */
1746 row_info
->bit_depth
= 8;
1747 row_info
->pixel_depth
= (png_byte
)(8 * row_info
->channels
);
1748 row_info
->rowbytes
= row_info
->width
* row_info
->channels
;
1753 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1755 png_do_read_swap_alpha(png_row_infop row_info
, png_bytep row
)
1757 png_debug(1, "in png_do_read_swap_alpha\n");
1758 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1759 if (row
!= NULL
&& row_info
!= NULL
)
1762 png_uint_32 row_width
= row_info
->width
;
1763 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
1765 /* This converts from RGBA to ARGB */
1766 if (row_info
->bit_depth
== 8)
1768 png_bytep sp
= row
+ row_info
->rowbytes
;
1773 for (i
= 0; i
< row_width
; i
++)
1782 /* This converts from RRGGBBAA to AARRGGBB */
1785 png_bytep sp
= row
+ row_info
->rowbytes
;
1790 for (i
= 0; i
< row_width
; i
++)
1805 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
1807 /* This converts from GA to AG */
1808 if (row_info
->bit_depth
== 8)
1810 png_bytep sp
= row
+ row_info
->rowbytes
;
1815 for (i
= 0; i
< row_width
; i
++)
1822 /* This converts from GGAA to AAGG */
1825 png_bytep sp
= row
+ row_info
->rowbytes
;
1830 for (i
= 0; i
< row_width
; i
++)
1845 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1847 png_do_read_invert_alpha(png_row_infop row_info
, png_bytep row
)
1849 png_debug(1, "in png_do_read_invert_alpha\n");
1850 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1851 if (row
!= NULL
&& row_info
!= NULL
)
1854 png_uint_32 row_width
= row_info
->width
;
1855 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
1857 /* This inverts the alpha channel in RGBA */
1858 if (row_info
->bit_depth
== 8)
1860 png_bytep sp
= row
+ row_info
->rowbytes
;
1864 for (i
= 0; i
< row_width
; i
++)
1866 *(--dp
) = (png_byte
)(255 - *(--sp
));
1868 /* This does nothing:
1872 We can replace it with:
1878 /* This inverts the alpha channel in RRGGBBAA */
1881 png_bytep sp
= row
+ row_info
->rowbytes
;
1885 for (i
= 0; i
< row_width
; i
++)
1887 *(--dp
) = (png_byte
)(255 - *(--sp
));
1888 *(--dp
) = (png_byte
)(255 - *(--sp
));
1890 /* This does nothing:
1897 We can replace it with:
1904 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
1906 /* This inverts the alpha channel in GA */
1907 if (row_info
->bit_depth
== 8)
1909 png_bytep sp
= row
+ row_info
->rowbytes
;
1913 for (i
= 0; i
< row_width
; i
++)
1915 *(--dp
) = (png_byte
)(255 - *(--sp
));
1919 /* This inverts the alpha channel in GGAA */
1922 png_bytep sp
= row
+ row_info
->rowbytes
;
1926 for (i
= 0; i
< row_width
; i
++)
1928 *(--dp
) = (png_byte
)(255 - *(--sp
));
1929 *(--dp
) = (png_byte
)(255 - *(--sp
));
1943 #if defined(PNG_READ_FILLER_SUPPORTED)
1944 /* Add filler channel if we have RGB color */
1946 png_do_read_filler(png_row_infop row_info
, png_bytep row
,
1947 png_uint_32 filler
, png_uint_32 flags
)
1950 png_uint_32 row_width
= row_info
->width
;
1952 png_byte hi_filler
= (png_byte
)((filler
>>8) & 0xff);
1953 png_byte lo_filler
= (png_byte
)(filler
& 0xff);
1955 png_debug(1, "in png_do_read_filler\n");
1957 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1958 row
!= NULL
&& row_info
!= NULL
&&
1960 row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
1962 if(row_info
->bit_depth
== 8)
1964 /* This changes the data from G to GX */
1965 if (flags
& PNG_FLAG_FILLER_AFTER
)
1967 png_bytep sp
= row
+ (png_size_t
)row_width
;
1968 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1969 for (i
= 1; i
< row_width
; i
++)
1971 *(--dp
) = lo_filler
;
1974 *(--dp
) = lo_filler
;
1975 row_info
->channels
= 2;
1976 row_info
->pixel_depth
= 16;
1977 row_info
->rowbytes
= row_width
* 2;
1979 /* This changes the data from G to XG */
1982 png_bytep sp
= row
+ (png_size_t
)row_width
;
1983 png_bytep dp
= sp
+ (png_size_t
)row_width
;
1984 for (i
= 0; i
< row_width
; i
++)
1987 *(--dp
) = lo_filler
;
1989 row_info
->channels
= 2;
1990 row_info
->pixel_depth
= 16;
1991 row_info
->rowbytes
= row_width
* 2;
1994 else if(row_info
->bit_depth
== 16)
1996 /* This changes the data from GG to GGXX */
1997 if (flags
& PNG_FLAG_FILLER_AFTER
)
1999 png_bytep sp
= row
+ (png_size_t
)row_width
* 2;
2000 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2001 for (i
= 1; i
< row_width
; i
++)
2003 *(--dp
) = hi_filler
;
2004 *(--dp
) = lo_filler
;
2008 *(--dp
) = hi_filler
;
2009 *(--dp
) = lo_filler
;
2010 row_info
->channels
= 2;
2011 row_info
->pixel_depth
= 32;
2012 row_info
->rowbytes
= row_width
* 4;
2014 /* This changes the data from GG to XXGG */
2017 png_bytep sp
= row
+ (png_size_t
)row_width
* 2;
2018 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2019 for (i
= 0; i
< row_width
; i
++)
2023 *(--dp
) = hi_filler
;
2024 *(--dp
) = lo_filler
;
2026 row_info
->channels
= 2;
2027 row_info
->pixel_depth
= 32;
2028 row_info
->rowbytes
= row_width
* 4;
2031 } /* COLOR_TYPE == GRAY */
2032 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
2034 if(row_info
->bit_depth
== 8)
2036 /* This changes the data from RGB to RGBX */
2037 if (flags
& PNG_FLAG_FILLER_AFTER
)
2039 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
2040 png_bytep dp
= sp
+ (png_size_t
)row_width
;
2041 for (i
= 1; i
< row_width
; i
++)
2043 *(--dp
) = lo_filler
;
2048 *(--dp
) = lo_filler
;
2049 row_info
->channels
= 4;
2050 row_info
->pixel_depth
= 32;
2051 row_info
->rowbytes
= row_width
* 4;
2053 /* This changes the data from RGB to XRGB */
2056 png_bytep sp
= row
+ (png_size_t
)row_width
* 3;
2057 png_bytep dp
= sp
+ (png_size_t
)row_width
;
2058 for (i
= 0; i
< row_width
; i
++)
2063 *(--dp
) = lo_filler
;
2065 row_info
->channels
= 4;
2066 row_info
->pixel_depth
= 32;
2067 row_info
->rowbytes
= row_width
* 4;
2070 else if(row_info
->bit_depth
== 16)
2072 /* This changes the data from RRGGBB to RRGGBBXX */
2073 if (flags
& PNG_FLAG_FILLER_AFTER
)
2075 png_bytep sp
= row
+ (png_size_t
)row_width
* 6;
2076 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2077 for (i
= 1; i
< row_width
; i
++)
2079 *(--dp
) = hi_filler
;
2080 *(--dp
) = lo_filler
;
2088 *(--dp
) = hi_filler
;
2089 *(--dp
) = lo_filler
;
2090 row_info
->channels
= 4;
2091 row_info
->pixel_depth
= 64;
2092 row_info
->rowbytes
= row_width
* 8;
2094 /* This changes the data from RRGGBB to XXRRGGBB */
2097 png_bytep sp
= row
+ (png_size_t
)row_width
* 6;
2098 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2099 for (i
= 0; i
< row_width
; i
++)
2107 *(--dp
) = hi_filler
;
2108 *(--dp
) = lo_filler
;
2110 row_info
->channels
= 4;
2111 row_info
->pixel_depth
= 64;
2112 row_info
->rowbytes
= row_width
* 8;
2115 } /* COLOR_TYPE == RGB */
2119 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
2120 /* expand grayscale files to RGB, with or without alpha */
2122 png_do_gray_to_rgb(png_row_infop row_info
, png_bytep row
)
2125 png_uint_32 row_width
= row_info
->width
;
2127 png_debug(1, "in png_do_gray_to_rgb\n");
2128 if (row_info
->bit_depth
>= 8 &&
2129 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2130 row
!= NULL
&& row_info
!= NULL
&&
2132 !(row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
2134 if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
2136 if (row_info
->bit_depth
== 8)
2138 png_bytep sp
= row
+ (png_size_t
)row_width
- 1;
2139 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2140 for (i
= 0; i
< row_width
; i
++)
2149 png_bytep sp
= row
+ (png_size_t
)row_width
* 2 - 1;
2150 png_bytep dp
= sp
+ (png_size_t
)row_width
* 4;
2151 for (i
= 0; i
< row_width
; i
++)
2154 *(dp
--) = *(sp
- 1);
2156 *(dp
--) = *(sp
- 1);
2162 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
2164 if (row_info
->bit_depth
== 8)
2166 png_bytep sp
= row
+ (png_size_t
)row_width
* 2 - 1;
2167 png_bytep dp
= sp
+ (png_size_t
)row_width
* 2;
2168 for (i
= 0; i
< row_width
; i
++)
2178 png_bytep sp
= row
+ (png_size_t
)row_width
* 4 - 1;
2179 png_bytep dp
= sp
+ (png_size_t
)row_width
* 4;
2180 for (i
= 0; i
< row_width
; i
++)
2185 *(dp
--) = *(sp
- 1);
2187 *(dp
--) = *(sp
- 1);
2193 row_info
->channels
+= (png_byte
)2;
2194 row_info
->color_type
|= PNG_COLOR_MASK_COLOR
;
2195 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
2196 row_info
->bit_depth
);
2197 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
,row_width
);
2202 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
2203 /* reduce RGB files to grayscale, with or without alpha
2204 * using the equation given in Poynton's ColorFAQ at
2205 * <http://www.inforamp.net/~poynton/>
2206 * Copyright (c) 1998-01-04 Charles Poynton poynton at inforamp.net
2208 * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
2210 * We approximate this with
2212 * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B
2214 * which can be expressed with integers as
2216 * Y = (6969 * R + 23434 * G + 2365 * B)/32768
2218 * The calculation is to be done in a linear colorspace.
2220 * Other integer coefficents can be used via png_set_rgb_to_gray().
2223 png_do_rgb_to_gray(png_structp png_ptr
, png_row_infop row_info
, png_bytep row
)
2228 png_uint_32 row_width
= row_info
->width
;
2231 png_debug(1, "in png_do_rgb_to_gray\n");
2233 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2234 row
!= NULL
&& row_info
!= NULL
&&
2236 (row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
2238 png_uint_32 rc
= png_ptr
->rgb_to_gray_red_coeff
;
2239 png_uint_32 gc
= png_ptr
->rgb_to_gray_green_coeff
;
2240 png_uint_32 bc
= png_ptr
->rgb_to_gray_blue_coeff
;
2242 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
2244 if (row_info
->bit_depth
== 8)
2246 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2247 if (png_ptr
->gamma_from_1
!= NULL
&& png_ptr
->gamma_to_1
!= NULL
)
2252 for (i
= 0; i
< row_width
; i
++)
2254 png_byte red
= png_ptr
->gamma_to_1
[*(sp
++)];
2255 png_byte green
= png_ptr
->gamma_to_1
[*(sp
++)];
2256 png_byte blue
= png_ptr
->gamma_to_1
[*(sp
++)];
2257 if(red
!= green
|| red
!= blue
)
2260 *(dp
++) = png_ptr
->gamma_from_1
[
2261 (rc
*red
+gc
*green
+bc
*blue
)>>15];
2272 for (i
= 0; i
< row_width
; i
++)
2274 png_byte red
= *(sp
++);
2275 png_byte green
= *(sp
++);
2276 png_byte blue
= *(sp
++);
2277 if(red
!= green
|| red
!= blue
)
2280 *(dp
++) = (png_byte
)((rc
*red
+gc
*green
+bc
*blue
)>>15);
2288 else /* RGB bit_depth == 16 */
2290 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2291 if (png_ptr
->gamma_16_to_1
!= NULL
&&
2292 png_ptr
->gamma_16_from_1
!= NULL
)
2296 for (i
= 0; i
< row_width
; i
++)
2298 png_uint_16 red
, green
, blue
, w
;
2300 red
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2301 green
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2302 blue
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2304 if(red
== green
&& red
== blue
)
2308 png_uint_16 red_1
= png_ptr
->gamma_16_to_1
[(red
&0xff) >>
2309 png_ptr
->gamma_shift
][red
>>8];
2310 png_uint_16 green_1
= png_ptr
->gamma_16_to_1
[(green
&0xff) >>
2311 png_ptr
->gamma_shift
][green
>>8];
2312 png_uint_16 blue_1
= png_ptr
->gamma_16_to_1
[(blue
&0xff) >>
2313 png_ptr
->gamma_shift
][blue
>>8];
2314 png_uint_16 gray16
= (png_uint_16
)((rc
*red_1
+ gc
*green_1
2316 w
= png_ptr
->gamma_16_from_1
[(gray16
&0xff) >>
2317 png_ptr
->gamma_shift
][gray16
>> 8];
2321 *(dp
++) = (png_byte
)((w
>>8) & 0xff);
2322 *(dp
++) = (png_byte
)(w
& 0xff);
2330 for (i
= 0; i
< row_width
; i
++)
2332 png_uint_16 red
, green
, blue
, gray16
;
2334 red
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2335 green
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2336 blue
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2338 if(red
!= green
|| red
!= blue
)
2340 gray16
= (png_uint_16
)((rc
*red
+ gc
*green
+ bc
*blue
)>>15);
2341 *(dp
++) = (png_byte
)((gray16
>>8) & 0xff);
2342 *(dp
++) = (png_byte
)(gray16
& 0xff);
2347 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
2349 if (row_info
->bit_depth
== 8)
2351 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2352 if (png_ptr
->gamma_from_1
!= NULL
&& png_ptr
->gamma_to_1
!= NULL
)
2356 for (i
= 0; i
< row_width
; i
++)
2358 png_byte red
= png_ptr
->gamma_to_1
[*(sp
++)];
2359 png_byte green
= png_ptr
->gamma_to_1
[*(sp
++)];
2360 png_byte blue
= png_ptr
->gamma_to_1
[*(sp
++)];
2361 if(red
!= green
|| red
!= blue
)
2363 *(dp
++) = png_ptr
->gamma_from_1
2364 [(rc
*red
+ gc
*green
+ bc
*blue
)>>15];
2365 *(dp
++) = *(sp
++); /* alpha */
2373 for (i
= 0; i
< row_width
; i
++)
2375 png_byte red
= *(sp
++);
2376 png_byte green
= *(sp
++);
2377 png_byte blue
= *(sp
++);
2378 if(red
!= green
|| red
!= blue
)
2380 *(dp
++) = (png_byte
)((rc
*red
+ gc
*green
+ bc
*blue
)>>15);
2381 *(dp
++) = *(sp
++); /* alpha */
2385 else /* RGBA bit_depth == 16 */
2387 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2388 if (png_ptr
->gamma_16_to_1
!= NULL
&&
2389 png_ptr
->gamma_16_from_1
!= NULL
)
2393 for (i
= 0; i
< row_width
; i
++)
2395 png_uint_16 red
, green
, blue
, w
;
2397 red
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2398 green
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2399 blue
= (png_uint_16
)(((*(sp
))<<8) | *(sp
+1)); sp
+=2;
2401 if(red
== green
&& red
== blue
)
2405 png_uint_16 red_1
= png_ptr
->gamma_16_to_1
[(red
&0xff) >>
2406 png_ptr
->gamma_shift
][red
>>8];
2407 png_uint_16 green_1
= png_ptr
->gamma_16_to_1
[(green
&0xff) >>
2408 png_ptr
->gamma_shift
][green
>>8];
2409 png_uint_16 blue_1
= png_ptr
->gamma_16_to_1
[(blue
&0xff) >>
2410 png_ptr
->gamma_shift
][blue
>>8];
2411 png_uint_16 gray16
= (png_uint_16
)((rc
* red_1
2412 + gc
* green_1
+ bc
* blue_1
)>>15);
2413 w
= png_ptr
->gamma_16_from_1
[(gray16
&0xff) >>
2414 png_ptr
->gamma_shift
][gray16
>> 8];
2418 *(dp
++) = (png_byte
)((w
>>8) & 0xff);
2419 *(dp
++) = (png_byte
)(w
& 0xff);
2420 *(dp
++) = *(sp
++); /* alpha */
2429 for (i
= 0; i
< row_width
; i
++)
2431 png_uint_16 red
, green
, blue
, gray16
;
2432 red
= (png_uint_16
)((*(sp
)<<8) | *(sp
+1)); sp
+=2;
2433 green
= (png_uint_16
)((*(sp
)<<8) | *(sp
+1)); sp
+=2;
2434 blue
= (png_uint_16
)((*(sp
)<<8) | *(sp
+1)); sp
+=2;
2435 if(red
!= green
|| red
!= blue
)
2437 gray16
= (png_uint_16
)((rc
*red
+ gc
*green
+ bc
*blue
)>>15);
2438 *(dp
++) = (png_byte
)((gray16
>>8) & 0xff);
2439 *(dp
++) = (png_byte
)(gray16
& 0xff);
2440 *(dp
++) = *(sp
++); /* alpha */
2446 row_info
->channels
-= (png_byte
)2;
2447 row_info
->color_type
&= ~PNG_COLOR_MASK_COLOR
;
2448 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
2449 row_info
->bit_depth
);
2450 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
,row_width
);
2456 /* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
2457 * large of png_color. This lets grayscale images be treated as
2458 * paletted. Most useful for gamma correction and simplification
2462 png_build_grayscale_palette(int bit_depth
, png_colorp palette
)
2469 png_debug(1, "in png_do_build_grayscale_palette\n");
2470 if (palette
== NULL
)
2497 for (i
= 0, v
= 0; i
< num_palette
; i
++, v
+= color_inc
)
2499 palette
[i
].red
= (png_byte
)v
;
2500 palette
[i
].green
= (png_byte
)v
;
2501 palette
[i
].blue
= (png_byte
)v
;
2505 /* This function is currently unused. Do we really need it? */
2506 #if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
2508 png_correct_palette(png_structp png_ptr
, png_colorp palette
,
2511 png_debug(1, "in png_correct_palette\n");
2512 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
2513 defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
2514 if (png_ptr
->transformations
& (PNG_GAMMA
| PNG_BACKGROUND
))
2516 png_color back
, back_1
;
2518 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_FILE
)
2520 back
.red
= png_ptr
->gamma_table
[png_ptr
->background
.red
];
2521 back
.green
= png_ptr
->gamma_table
[png_ptr
->background
.green
];
2522 back
.blue
= png_ptr
->gamma_table
[png_ptr
->background
.blue
];
2524 back_1
.red
= png_ptr
->gamma_to_1
[png_ptr
->background
.red
];
2525 back_1
.green
= png_ptr
->gamma_to_1
[png_ptr
->background
.green
];
2526 back_1
.blue
= png_ptr
->gamma_to_1
[png_ptr
->background
.blue
];
2532 g
= 1.0 / (png_ptr
->background_gamma
* png_ptr
->screen_gamma
);
2534 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_SCREEN
||
2535 fabs(g
- 1.0) < PNG_GAMMA_THRESHOLD
)
2537 back
.red
= png_ptr
->background
.red
;
2538 back
.green
= png_ptr
->background
.green
;
2539 back
.blue
= png_ptr
->background
.blue
;
2544 (png_byte
)(pow((double)png_ptr
->background
.red
/255, g
) *
2547 (png_byte
)(pow((double)png_ptr
->background
.green
/255, g
) *
2550 (png_byte
)(pow((double)png_ptr
->background
.blue
/255, g
) *
2554 g
= 1.0 / png_ptr
->background_gamma
;
2557 (png_byte
)(pow((double)png_ptr
->background
.red
/255, g
) *
2560 (png_byte
)(pow((double)png_ptr
->background
.green
/255, g
) *
2563 (png_byte
)(pow((double)png_ptr
->background
.blue
/255, g
) *
2567 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
2571 for (i
= 0; i
< (png_uint_32
)num_palette
; i
++)
2573 if (i
< png_ptr
->num_trans
&& png_ptr
->trans
[i
] == 0)
2577 else if (i
< png_ptr
->num_trans
&& png_ptr
->trans
[i
] != 0xff)
2581 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].red
];
2582 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.red
);
2583 palette
[i
].red
= png_ptr
->gamma_from_1
[w
];
2585 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].green
];
2586 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.green
);
2587 palette
[i
].green
= png_ptr
->gamma_from_1
[w
];
2589 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].blue
];
2590 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.blue
);
2591 palette
[i
].blue
= png_ptr
->gamma_from_1
[w
];
2595 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2596 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2597 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2605 for (i
= 0; i
< num_palette
; i
++)
2607 if (palette
[i
].red
== (png_byte
)png_ptr
->trans_values
.gray
)
2613 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2614 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2615 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2622 #if defined(PNG_READ_GAMMA_SUPPORTED)
2623 if (png_ptr
->transformations
& PNG_GAMMA
)
2627 for (i
= 0; i
< num_palette
; i
++)
2629 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
2630 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
2631 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
2634 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2638 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2639 if (png_ptr
->transformations
& PNG_BACKGROUND
)
2641 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
2645 back
.red
= (png_byte
)png_ptr
->background
.red
;
2646 back
.green
= (png_byte
)png_ptr
->background
.green
;
2647 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
2649 for (i
= 0; i
< (int)png_ptr
->num_trans
; i
++)
2651 if (png_ptr
->trans
[i
] == 0)
2653 palette
[i
].red
= back
.red
;
2654 palette
[i
].green
= back
.green
;
2655 palette
[i
].blue
= back
.blue
;
2657 else if (png_ptr
->trans
[i
] != 0xff)
2659 png_composite(palette
[i
].red
, png_ptr
->palette
[i
].red
,
2660 png_ptr
->trans
[i
], back
.red
);
2661 png_composite(palette
[i
].green
, png_ptr
->palette
[i
].green
,
2662 png_ptr
->trans
[i
], back
.green
);
2663 png_composite(palette
[i
].blue
, png_ptr
->palette
[i
].blue
,
2664 png_ptr
->trans
[i
], back
.blue
);
2668 else /* assume grayscale palette (what else could it be?) */
2672 for (i
= 0; i
< num_palette
; i
++)
2674 if (i
== (png_byte
)png_ptr
->trans_values
.gray
)
2676 palette
[i
].red
= (png_byte
)png_ptr
->background
.red
;
2677 palette
[i
].green
= (png_byte
)png_ptr
->background
.green
;
2678 palette
[i
].blue
= (png_byte
)png_ptr
->background
.blue
;
2687 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2688 /* Replace any alpha or transparency with the supplied background color.
2689 * "background" is already in the screen gamma, while "background_1" is
2690 * at a gamma of 1.0. Paletted files have already been taken care of.
2693 png_do_background(png_row_infop row_info
, png_bytep row
,
2694 png_color_16p trans_values
, png_color_16p background
2695 #if defined(PNG_READ_GAMMA_SUPPORTED)
2696 , png_color_16p background_1
,
2697 png_bytep gamma_table
, png_bytep gamma_from_1
, png_bytep gamma_to_1
,
2698 png_uint_16pp gamma_16
, png_uint_16pp gamma_16_from_1
,
2699 png_uint_16pp gamma_16_to_1
, int gamma_shift
2705 png_uint_32 row_width
=row_info
->width
;
2708 png_debug(1, "in png_do_background\n");
2709 if (background
!= NULL
&&
2710 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2711 row
!= NULL
&& row_info
!= NULL
&&
2713 (!(row_info
->color_type
& PNG_COLOR_MASK_ALPHA
) ||
2714 (row_info
->color_type
!= PNG_COLOR_TYPE_PALETTE
&& trans_values
)))
2716 switch (row_info
->color_type
)
2718 case PNG_COLOR_TYPE_GRAY
:
2720 switch (row_info
->bit_depth
)
2726 for (i
= 0; i
< row_width
; i
++)
2728 if ((png_uint_16
)((*sp
>> shift
) & 0x01)
2729 == trans_values
->gray
)
2731 *sp
&= (png_byte
)((0x7f7f >> (7 - shift
)) & 0xff);
2732 *sp
|= (png_byte
)(background
->gray
<< shift
);
2746 #if defined(PNG_READ_GAMMA_SUPPORTED)
2747 if (gamma_table
!= NULL
)
2751 for (i
= 0; i
< row_width
; i
++)
2753 if ((png_uint_16
)((*sp
>> shift
) & 0x03)
2754 == trans_values
->gray
)
2756 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2757 *sp
|= (png_byte
)(background
->gray
<< shift
);
2761 png_byte p
= (png_byte
)((*sp
>> shift
) & 0x03);
2762 png_byte g
= (png_byte
)((gamma_table
[p
| (p
<< 2) |
2763 (p
<< 4) | (p
<< 6)] >> 6) & 0x03);
2764 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2765 *sp
|= (png_byte
)(g
<< shift
);
2781 for (i
= 0; i
< row_width
; i
++)
2783 if ((png_uint_16
)((*sp
>> shift
) & 0x03)
2784 == trans_values
->gray
)
2786 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2787 *sp
|= (png_byte
)(background
->gray
<< shift
);
2802 #if defined(PNG_READ_GAMMA_SUPPORTED)
2803 if (gamma_table
!= NULL
)
2807 for (i
= 0; i
< row_width
; i
++)
2809 if ((png_uint_16
)((*sp
>> shift
) & 0x0f)
2810 == trans_values
->gray
)
2812 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2813 *sp
|= (png_byte
)(background
->gray
<< shift
);
2817 png_byte p
= (png_byte
)((*sp
>> shift
) & 0x0f);
2818 png_byte g
= (png_byte
)((gamma_table
[p
|
2819 (p
<< 4)] >> 4) & 0x0f);
2820 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2821 *sp
|= (png_byte
)(g
<< shift
);
2837 for (i
= 0; i
< row_width
; i
++)
2839 if ((png_uint_16
)((*sp
>> shift
) & 0x0f)
2840 == trans_values
->gray
)
2842 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2843 *sp
|= (png_byte
)(background
->gray
<< shift
);
2858 #if defined(PNG_READ_GAMMA_SUPPORTED)
2859 if (gamma_table
!= NULL
)
2862 for (i
= 0; i
< row_width
; i
++, sp
++)
2864 if (*sp
== trans_values
->gray
)
2866 *sp
= (png_byte
)background
->gray
;
2870 *sp
= gamma_table
[*sp
];
2878 for (i
= 0; i
< row_width
; i
++, sp
++)
2880 if (*sp
== trans_values
->gray
)
2882 *sp
= (png_byte
)background
->gray
;
2890 #if defined(PNG_READ_GAMMA_SUPPORTED)
2891 if (gamma_16
!= NULL
)
2894 for (i
= 0; i
< row_width
; i
++, sp
+= 2)
2898 v
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
2899 if (v
== trans_values
->gray
)
2901 /* background is already in screen gamma */
2902 *sp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2903 *(sp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2907 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2908 *sp
= (png_byte
)((v
>> 8) & 0xff);
2909 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2917 for (i
= 0; i
< row_width
; i
++, sp
+= 2)
2921 v
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
2922 if (v
== trans_values
->gray
)
2924 *sp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2925 *(sp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2934 case PNG_COLOR_TYPE_RGB
:
2936 if (row_info
->bit_depth
== 8)
2938 #if defined(PNG_READ_GAMMA_SUPPORTED)
2939 if (gamma_table
!= NULL
)
2942 for (i
= 0; i
< row_width
; i
++, sp
+= 3)
2944 if (*sp
== trans_values
->red
&&
2945 *(sp
+ 1) == trans_values
->green
&&
2946 *(sp
+ 2) == trans_values
->blue
)
2948 *sp
= (png_byte
)background
->red
;
2949 *(sp
+ 1) = (png_byte
)background
->green
;
2950 *(sp
+ 2) = (png_byte
)background
->blue
;
2954 *sp
= gamma_table
[*sp
];
2955 *(sp
+ 1) = gamma_table
[*(sp
+ 1)];
2956 *(sp
+ 2) = gamma_table
[*(sp
+ 2)];
2964 for (i
= 0; i
< row_width
; i
++, sp
+= 3)
2966 if (*sp
== trans_values
->red
&&
2967 *(sp
+ 1) == trans_values
->green
&&
2968 *(sp
+ 2) == trans_values
->blue
)
2970 *sp
= (png_byte
)background
->red
;
2971 *(sp
+ 1) = (png_byte
)background
->green
;
2972 *(sp
+ 2) = (png_byte
)background
->blue
;
2977 else /* if (row_info->bit_depth == 16) */
2979 #if defined(PNG_READ_GAMMA_SUPPORTED)
2980 if (gamma_16
!= NULL
)
2983 for (i
= 0; i
< row_width
; i
++, sp
+= 6)
2985 png_uint_16 r
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
2986 png_uint_16 g
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
2987 png_uint_16 b
= (png_uint_16
)(((*(sp
+4)) << 8) + *(sp
+5));
2988 if (r
== trans_values
->red
&& g
== trans_values
->green
&&
2989 b
== trans_values
->blue
)
2991 /* background is already in screen gamma */
2992 *sp
= (png_byte
)((background
->red
>> 8) & 0xff);
2993 *(sp
+ 1) = (png_byte
)(background
->red
& 0xff);
2994 *(sp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
2995 *(sp
+ 3) = (png_byte
)(background
->green
& 0xff);
2996 *(sp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
2997 *(sp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3001 png_uint_16 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
3002 *sp
= (png_byte
)((v
>> 8) & 0xff);
3003 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3004 v
= gamma_16
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
3005 *(sp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
3006 *(sp
+ 3) = (png_byte
)(v
& 0xff);
3007 v
= gamma_16
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
3008 *(sp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
3009 *(sp
+ 5) = (png_byte
)(v
& 0xff);
3017 for (i
= 0; i
< row_width
; i
++, sp
+= 6)
3019 png_uint_16 r
= (png_uint_16
)(((*sp
) << 8) + *(sp
+1));
3020 png_uint_16 g
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
3021 png_uint_16 b
= (png_uint_16
)(((*(sp
+4)) << 8) + *(sp
+5));
3023 if (r
== trans_values
->red
&& g
== trans_values
->green
&&
3024 b
== trans_values
->blue
)
3026 *sp
= (png_byte
)((background
->red
>> 8) & 0xff);
3027 *(sp
+ 1) = (png_byte
)(background
->red
& 0xff);
3028 *(sp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
3029 *(sp
+ 3) = (png_byte
)(background
->green
& 0xff);
3030 *(sp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
3031 *(sp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3038 case PNG_COLOR_TYPE_GRAY_ALPHA
:
3040 if (row_info
->bit_depth
== 8)
3042 #if defined(PNG_READ_GAMMA_SUPPORTED)
3043 if (gamma_to_1
!= NULL
&& gamma_from_1
!= NULL
&&
3044 gamma_table
!= NULL
)
3048 for (i
= 0; i
< row_width
; i
++, sp
+= 2, dp
++)
3050 png_uint_16 a
= *(sp
+ 1);
3054 *dp
= gamma_table
[*sp
];
3058 /* background is already in screen gamma */
3059 *dp
= (png_byte
)background
->gray
;
3065 v
= gamma_to_1
[*sp
];
3066 png_composite(w
, v
, a
, background_1
->gray
);
3067 *dp
= gamma_from_1
[w
];
3076 for (i
= 0; i
< row_width
; i
++, sp
+= 2, dp
++)
3078 png_byte a
= *(sp
+ 1);
3084 #if defined(PNG_READ_GAMMA_SUPPORTED)
3087 *dp
= (png_byte
)background
->gray
;
3091 png_composite(*dp
, *sp
, a
, background_1
->gray
);
3094 *dp
= (png_byte
)background
->gray
;
3099 else /* if (png_ptr->bit_depth == 16) */
3101 #if defined(PNG_READ_GAMMA_SUPPORTED)
3102 if (gamma_16
!= NULL
&& gamma_16_from_1
!= NULL
&&
3103 gamma_16_to_1
!= NULL
)
3107 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 2)
3109 png_uint_16 a
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
3111 if (a
== (png_uint_16
)0xffff)
3115 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
3116 *dp
= (png_byte
)((v
>> 8) & 0xff);
3117 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3119 #if defined(PNG_READ_GAMMA_SUPPORTED)
3125 /* background is already in screen gamma */
3126 *dp
= (png_byte
)((background
->gray
>> 8) & 0xff);
3127 *(dp
+ 1) = (png_byte
)(background
->gray
& 0xff);
3129 #if defined(PNG_READ_GAMMA_SUPPORTED)
3132 png_uint_16 g
, v
, w
;
3134 g
= gamma_16_to_1
[*(sp
+ 1) >> gamma_shift
][*sp
];
3135 png_composite_16(v
, g
, a
, background_1
->gray
);
3136 w
= gamma_16_from_1
[(v
&0xff) >> gamma_shift
][v
>> 8];
3137 *dp
= (png_byte
)((w
>> 8) & 0xff);
3138 *(dp
+ 1) = (png_byte
)(w
& 0xff);
3148 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 2)
3150 png_uint_16 a
= (png_uint_16
)(((*(sp
+2)) << 8) + *(sp
+3));
3151 if (a
== (png_uint_16
)0xffff)
3153 png_memcpy(dp
, sp
, 2);
3155 #if defined(PNG_READ_GAMMA_SUPPORTED)
3161 *dp
= (png_byte
)((background
->gray
>> 8) & 0xff);
3162 *(dp
+ 1) = (png_byte
)(background
->gray
& 0xff);
3164 #if defined(PNG_READ_GAMMA_SUPPORTED)
3169 g
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
3170 png_composite_16(v
, g
, a
, background_1
->gray
);
3171 *dp
= (png_byte
)((v
>> 8) & 0xff);
3172 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3180 case PNG_COLOR_TYPE_RGB_ALPHA
:
3182 if (row_info
->bit_depth
== 8)
3184 #if defined(PNG_READ_GAMMA_SUPPORTED)
3185 if (gamma_to_1
!= NULL
&& gamma_from_1
!= NULL
&&
3186 gamma_table
!= NULL
)
3190 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 3)
3192 png_byte a
= *(sp
+ 3);
3196 *dp
= gamma_table
[*sp
];
3197 *(dp
+ 1) = gamma_table
[*(sp
+ 1)];
3198 *(dp
+ 2) = gamma_table
[*(sp
+ 2)];
3202 /* background is already in screen gamma */
3203 *dp
= (png_byte
)background
->red
;
3204 *(dp
+ 1) = (png_byte
)background
->green
;
3205 *(dp
+ 2) = (png_byte
)background
->blue
;
3211 v
= gamma_to_1
[*sp
];
3212 png_composite(w
, v
, a
, background_1
->red
);
3213 *dp
= gamma_from_1
[w
];
3214 v
= gamma_to_1
[*(sp
+ 1)];
3215 png_composite(w
, v
, a
, background_1
->green
);
3216 *(dp
+ 1) = gamma_from_1
[w
];
3217 v
= gamma_to_1
[*(sp
+ 2)];
3218 png_composite(w
, v
, a
, background_1
->blue
);
3219 *(dp
+ 2) = gamma_from_1
[w
];
3228 for (i
= 0; i
< row_width
; i
++, sp
+= 4, dp
+= 3)
3230 png_byte a
= *(sp
+ 3);
3235 *(dp
+ 1) = *(sp
+ 1);
3236 *(dp
+ 2) = *(sp
+ 2);
3240 *dp
= (png_byte
)background
->red
;
3241 *(dp
+ 1) = (png_byte
)background
->green
;
3242 *(dp
+ 2) = (png_byte
)background
->blue
;
3246 png_composite(*dp
, *sp
, a
, background
->red
);
3247 png_composite(*(dp
+ 1), *(sp
+ 1), a
,
3249 png_composite(*(dp
+ 2), *(sp
+ 2), a
,
3255 else /* if (row_info->bit_depth == 16) */
3257 #if defined(PNG_READ_GAMMA_SUPPORTED)
3258 if (gamma_16
!= NULL
&& gamma_16_from_1
!= NULL
&&
3259 gamma_16_to_1
!= NULL
)
3263 for (i
= 0; i
< row_width
; i
++, sp
+= 8, dp
+= 6)
3265 png_uint_16 a
= (png_uint_16
)(((png_uint_16
)(*(sp
+ 6))
3266 << 8) + (png_uint_16
)(*(sp
+ 7)));
3267 if (a
== (png_uint_16
)0xffff)
3271 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
3272 *dp
= (png_byte
)((v
>> 8) & 0xff);
3273 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3274 v
= gamma_16
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
3275 *(dp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
3276 *(dp
+ 3) = (png_byte
)(v
& 0xff);
3277 v
= gamma_16
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
3278 *(dp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
3279 *(dp
+ 5) = (png_byte
)(v
& 0xff);
3283 /* background is already in screen gamma */
3284 *dp
= (png_byte
)((background
->red
>> 8) & 0xff);
3285 *(dp
+ 1) = (png_byte
)(background
->red
& 0xff);
3286 *(dp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
3287 *(dp
+ 3) = (png_byte
)(background
->green
& 0xff);
3288 *(dp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
3289 *(dp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3293 png_uint_16 v
, w
, x
;
3295 v
= gamma_16_to_1
[*(sp
+ 1) >> gamma_shift
][*sp
];
3296 png_composite_16(w
, v
, a
, background_1
->red
);
3297 x
= gamma_16_from_1
[((w
&0xff) >> gamma_shift
)][w
>> 8];
3298 *dp
= (png_byte
)((x
>> 8) & 0xff);
3299 *(dp
+ 1) = (png_byte
)(x
& 0xff);
3300 v
= gamma_16_to_1
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
3301 png_composite_16(w
, v
, a
, background_1
->green
);
3302 x
= gamma_16_from_1
[((w
&0xff) >> gamma_shift
)][w
>> 8];
3303 *(dp
+ 2) = (png_byte
)((x
>> 8) & 0xff);
3304 *(dp
+ 3) = (png_byte
)(x
& 0xff);
3305 v
= gamma_16_to_1
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
3306 png_composite_16(w
, v
, a
, background_1
->blue
);
3307 x
= gamma_16_from_1
[(w
& 0xff) >> gamma_shift
][w
>> 8];
3308 *(dp
+ 4) = (png_byte
)((x
>> 8) & 0xff);
3309 *(dp
+ 5) = (png_byte
)(x
& 0xff);
3318 for (i
= 0; i
< row_width
; i
++, sp
+= 8, dp
+= 6)
3320 png_uint_16 a
= (png_uint_16
)(((png_uint_16
)(*(sp
+ 6))
3321 << 8) + (png_uint_16
)(*(sp
+ 7)));
3322 if (a
== (png_uint_16
)0xffff)
3324 png_memcpy(dp
, sp
, 6);
3328 *dp
= (png_byte
)((background
->red
>> 8) & 0xff);
3329 *(dp
+ 1) = (png_byte
)(background
->red
& 0xff);
3330 *(dp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
3331 *(dp
+ 3) = (png_byte
)(background
->green
& 0xff);
3332 *(dp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
3333 *(dp
+ 5) = (png_byte
)(background
->blue
& 0xff);
3339 png_uint_16 r
= (png_uint_16
)(((*sp
) << 8) + *(sp
+ 1));
3340 png_uint_16 g
= (png_uint_16
)(((*(sp
+ 2)) << 8)
3342 png_uint_16 b
= (png_uint_16
)(((*(sp
+ 4)) << 8)
3345 png_composite_16(v
, r
, a
, background
->red
);
3346 *dp
= (png_byte
)((v
>> 8) & 0xff);
3347 *(dp
+ 1) = (png_byte
)(v
& 0xff);
3348 png_composite_16(v
, g
, a
, background
->green
);
3349 *(dp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
3350 *(dp
+ 3) = (png_byte
)(v
& 0xff);
3351 png_composite_16(v
, b
, a
, background
->blue
);
3352 *(dp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
3353 *(dp
+ 5) = (png_byte
)(v
& 0xff);
3362 if (row_info
->color_type
& PNG_COLOR_MASK_ALPHA
)
3364 row_info
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
3365 row_info
->channels
--;
3366 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
3367 row_info
->bit_depth
);
3368 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
,row_width
);
3374 #if defined(PNG_READ_GAMMA_SUPPORTED)
3375 /* Gamma correct the image, avoiding the alpha channel. Make sure
3376 * you do this after you deal with the transparency issue on grayscale
3377 * or RGB images. If your bit depth is 8, use gamma_table, if it
3378 * is 16, use gamma_16_table and gamma_shift. Build these with
3379 * build_gamma_table().
3382 png_do_gamma(png_row_infop row_info
, png_bytep row
,
3383 png_bytep gamma_table
, png_uint_16pp gamma_16_table
,
3388 png_uint_32 row_width
=row_info
->width
;
3390 png_debug(1, "in png_do_gamma\n");
3392 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3393 row
!= NULL
&& row_info
!= NULL
&&
3395 ((row_info
->bit_depth
<= 8 && gamma_table
!= NULL
) ||
3396 (row_info
->bit_depth
== 16 && gamma_16_table
!= NULL
)))
3398 switch (row_info
->color_type
)
3400 case PNG_COLOR_TYPE_RGB
:
3402 if (row_info
->bit_depth
== 8)
3405 for (i
= 0; i
< row_width
; i
++)
3407 *sp
= gamma_table
[*sp
];
3409 *sp
= gamma_table
[*sp
];
3411 *sp
= gamma_table
[*sp
];
3415 else /* if (row_info->bit_depth == 16) */
3418 for (i
= 0; i
< row_width
; i
++)
3422 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3423 *sp
= (png_byte
)((v
>> 8) & 0xff);
3424 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3426 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3427 *sp
= (png_byte
)((v
>> 8) & 0xff);
3428 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3430 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3431 *sp
= (png_byte
)((v
>> 8) & 0xff);
3432 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3438 case PNG_COLOR_TYPE_RGB_ALPHA
:
3440 if (row_info
->bit_depth
== 8)
3443 for (i
= 0; i
< row_width
; i
++)
3445 *sp
= gamma_table
[*sp
];
3447 *sp
= gamma_table
[*sp
];
3449 *sp
= gamma_table
[*sp
];
3454 else /* if (row_info->bit_depth == 16) */
3457 for (i
= 0; i
< row_width
; i
++)
3459 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3460 *sp
= (png_byte
)((v
>> 8) & 0xff);
3461 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3463 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3464 *sp
= (png_byte
)((v
>> 8) & 0xff);
3465 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3467 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3468 *sp
= (png_byte
)((v
>> 8) & 0xff);
3469 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3475 case PNG_COLOR_TYPE_GRAY_ALPHA
:
3477 if (row_info
->bit_depth
== 8)
3480 for (i
= 0; i
< row_width
; i
++)
3482 *sp
= gamma_table
[*sp
];
3486 else /* if (row_info->bit_depth == 16) */
3489 for (i
= 0; i
< row_width
; i
++)
3491 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3492 *sp
= (png_byte
)((v
>> 8) & 0xff);
3493 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3499 case PNG_COLOR_TYPE_GRAY
:
3501 if (row_info
->bit_depth
== 2)
3504 for (i
= 0; i
< row_width
; i
+= 4)
3512 ((((int)gamma_table
[a
|(a
>>2)|(a
>>4)|(a
>>6)]) ) & 0xc0)|
3513 ((((int)gamma_table
[(b
<<2)|b
|(b
>>2)|(b
>>4)])>>2) & 0x30)|
3514 ((((int)gamma_table
[(c
<<4)|(c
<<2)|c
|(c
>>2)])>>4) & 0x0c)|
3515 ((((int)gamma_table
[(d
<<6)|(d
<<4)|(d
<<2)|d
])>>6) ));
3519 if (row_info
->bit_depth
== 4)
3522 for (i
= 0; i
< row_width
; i
+= 2)
3524 int msb
= *sp
& 0xf0;
3525 int lsb
= *sp
& 0x0f;
3527 *sp
= (png_byte
)((((int)gamma_table
[msb
| (msb
>> 4)]) & 0xf0)
3528 | (((int)gamma_table
[(lsb
<< 4) | lsb
]) >> 4));
3532 else if (row_info
->bit_depth
== 8)
3535 for (i
= 0; i
< row_width
; i
++)
3537 *sp
= gamma_table
[*sp
];
3541 else if (row_info
->bit_depth
== 16)
3544 for (i
= 0; i
< row_width
; i
++)
3546 png_uint_16 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
3547 *sp
= (png_byte
)((v
>> 8) & 0xff);
3548 *(sp
+ 1) = (png_byte
)(v
& 0xff);
3559 #if defined(PNG_READ_EXPAND_SUPPORTED)
3560 /* Expands a palette row to an RGB or RGBA row depending
3561 * upon whether you supply trans and num_trans.
3564 png_do_expand_palette(png_row_infop row_info
, png_bytep row
,
3565 png_colorp palette
, png_bytep trans
, int num_trans
)
3570 png_uint_32 row_width
=row_info
->width
;
3572 png_debug(1, "in png_do_expand_palette\n");
3574 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3575 row
!= NULL
&& row_info
!= NULL
&&
3577 row_info
->color_type
== PNG_COLOR_TYPE_PALETTE
)
3579 if (row_info
->bit_depth
< 8)
3581 switch (row_info
->bit_depth
)
3585 sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
3586 dp
= row
+ (png_size_t
)row_width
- 1;
3587 shift
= 7 - (int)((row_width
+ 7) & 0x07);
3588 for (i
= 0; i
< row_width
; i
++)
3590 if ((*sp
>> shift
) & 0x01)
3608 sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
3609 dp
= row
+ (png_size_t
)row_width
- 1;
3610 shift
= (int)((3 - ((row_width
+ 3) & 0x03)) << 1);
3611 for (i
= 0; i
< row_width
; i
++)
3613 value
= (*sp
>> shift
) & 0x03;
3614 *dp
= (png_byte
)value
;
3629 sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
3630 dp
= row
+ (png_size_t
)row_width
- 1;
3631 shift
= (int)((row_width
& 0x01) << 2);
3632 for (i
= 0; i
< row_width
; i
++)
3634 value
= (*sp
>> shift
) & 0x0f;
3635 *dp
= (png_byte
)value
;
3649 row_info
->bit_depth
= 8;
3650 row_info
->pixel_depth
= 8;
3651 row_info
->rowbytes
= row_width
;
3653 switch (row_info
->bit_depth
)
3659 sp
= row
+ (png_size_t
)row_width
- 1;
3660 dp
= row
+ (png_size_t
)(row_width
<< 2) - 1;
3662 for (i
= 0; i
< row_width
; i
++)
3664 if ((int)(*sp
) >= num_trans
)
3668 *dp
-- = palette
[*sp
].blue
;
3669 *dp
-- = palette
[*sp
].green
;
3670 *dp
-- = palette
[*sp
].red
;
3673 row_info
->bit_depth
= 8;
3674 row_info
->pixel_depth
= 32;
3675 row_info
->rowbytes
= row_width
* 4;
3676 row_info
->color_type
= 6;
3677 row_info
->channels
= 4;
3681 sp
= row
+ (png_size_t
)row_width
- 1;
3682 dp
= row
+ (png_size_t
)(row_width
* 3) - 1;
3684 for (i
= 0; i
< row_width
; i
++)
3686 *dp
-- = palette
[*sp
].blue
;
3687 *dp
-- = palette
[*sp
].green
;
3688 *dp
-- = palette
[*sp
].red
;
3691 row_info
->bit_depth
= 8;
3692 row_info
->pixel_depth
= 24;
3693 row_info
->rowbytes
= row_width
* 3;
3694 row_info
->color_type
= 2;
3695 row_info
->channels
= 3;
3703 /* If the bit depth < 8, it is expanded to 8. Also, if the already
3704 * expanded transparency value is supplied, an alpha channel is built.
3707 png_do_expand(png_row_infop row_info
, png_bytep row
,
3708 png_color_16p trans_value
)
3713 png_uint_32 row_width
=row_info
->width
;
3715 png_debug(1, "in png_do_expand\n");
3716 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3717 if (row
!= NULL
&& row_info
!= NULL
)
3720 if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
3722 png_uint_16 gray
= (png_uint_16
)(trans_value
? trans_value
->gray
: 0);
3724 if (row_info
->bit_depth
< 8)
3726 switch (row_info
->bit_depth
)
3730 gray
= (png_uint_16
)((gray
&0x01)*0xff);
3731 sp
= row
+ (png_size_t
)((row_width
- 1) >> 3);
3732 dp
= row
+ (png_size_t
)row_width
- 1;
3733 shift
= 7 - (int)((row_width
+ 7) & 0x07);
3734 for (i
= 0; i
< row_width
; i
++)
3736 if ((*sp
>> shift
) & 0x01)
3754 gray
= (png_uint_16
)((gray
&0x03)*0x55);
3755 sp
= row
+ (png_size_t
)((row_width
- 1) >> 2);
3756 dp
= row
+ (png_size_t
)row_width
- 1;
3757 shift
= (int)((3 - ((row_width
+ 3) & 0x03)) << 1);
3758 for (i
= 0; i
< row_width
; i
++)
3760 value
= (*sp
>> shift
) & 0x03;
3761 *dp
= (png_byte
)(value
| (value
<< 2) | (value
<< 4) |
3777 gray
= (png_uint_16
)((gray
&0x0f)*0x11);
3778 sp
= row
+ (png_size_t
)((row_width
- 1) >> 1);
3779 dp
= row
+ (png_size_t
)row_width
- 1;
3780 shift
= (int)((1 - ((row_width
+ 1) & 0x01)) << 2);
3781 for (i
= 0; i
< row_width
; i
++)
3783 value
= (*sp
>> shift
) & 0x0f;
3784 *dp
= (png_byte
)(value
| (value
<< 4));
3798 row_info
->bit_depth
= 8;
3799 row_info
->pixel_depth
= 8;
3800 row_info
->rowbytes
= row_width
;
3803 if (trans_value
!= NULL
)
3805 if (row_info
->bit_depth
== 8)
3808 sp
= row
+ (png_size_t
)row_width
- 1;
3809 dp
= row
+ (png_size_t
)(row_width
<< 1) - 1;
3810 for (i
= 0; i
< row_width
; i
++)
3819 else if (row_info
->bit_depth
== 16)
3821 png_byte gray_high
= (gray
>> 8) & 0xff;
3822 png_byte gray_low
= gray
& 0xff;
3823 sp
= row
+ row_info
->rowbytes
- 1;
3824 dp
= row
+ (row_info
->rowbytes
<< 1) - 1;
3825 for (i
= 0; i
< row_width
; i
++)
3827 if (*(sp
-1) == gray_high
&& *(sp
) == gray_low
)
3841 row_info
->color_type
= PNG_COLOR_TYPE_GRAY_ALPHA
;
3842 row_info
->channels
= 2;
3843 row_info
->pixel_depth
= (png_byte
)(row_info
->bit_depth
<< 1);
3844 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
,
3848 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
&& trans_value
)
3850 if (row_info
->bit_depth
== 8)
3852 png_byte red
= trans_value
->red
& 0xff;
3853 png_byte green
= trans_value
->green
& 0xff;
3854 png_byte blue
= trans_value
->blue
& 0xff;
3855 sp
= row
+ (png_size_t
)row_info
->rowbytes
- 1;
3856 dp
= row
+ (png_size_t
)(row_width
<< 2) - 1;
3857 for (i
= 0; i
< row_width
; i
++)
3859 if (*(sp
- 2) == red
&& *(sp
- 1) == green
&& *(sp
) == blue
)
3868 else if (row_info
->bit_depth
== 16)
3870 png_byte red_high
= (trans_value
->red
> 8) & 0xff;
3871 png_byte green_high
= (trans_value
->green
> 8) & 0xff;
3872 png_byte blue_high
= (trans_value
->blue
> 8) & 0xff;
3873 png_byte red_low
= trans_value
->red
& 0xff;
3874 png_byte green_low
= trans_value
->green
& 0xff;
3875 png_byte blue_low
= trans_value
->blue
& 0xff;
3876 sp
= row
+ row_info
->rowbytes
- 1;
3877 dp
= row
+ (png_size_t
)(row_width
<< 3) - 1;
3878 for (i
= 0; i
< row_width
; i
++)
3880 if (*(sp
- 5) == red_high
&&
3881 *(sp
- 4) == red_low
&&
3882 *(sp
- 3) == green_high
&&
3883 *(sp
- 2) == green_low
&&
3884 *(sp
- 1) == blue_high
&&
3903 row_info
->color_type
= PNG_COLOR_TYPE_RGB_ALPHA
;
3904 row_info
->channels
= 4;
3905 row_info
->pixel_depth
= (png_byte
)(row_info
->bit_depth
<< 2);
3906 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
,row_width
);
3912 #if defined(PNG_READ_DITHER_SUPPORTED)
3914 png_do_dither(png_row_infop row_info
, png_bytep row
,
3915 png_bytep palette_lookup
, png_bytep dither_lookup
)
3919 png_uint_32 row_width
=row_info
->width
;
3921 png_debug(1, "in png_do_dither\n");
3922 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3923 if (row
!= NULL
&& row_info
!= NULL
)
3926 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
&&
3927 palette_lookup
&& row_info
->bit_depth
== 8)
3932 for (i
= 0; i
< row_width
; i
++)
3938 /* this looks real messy, but the compiler will reduce
3939 it down to a reasonable formula. For example, with
3940 5 bits per color, we get:
3941 p = (((r >> 3) & 0x1f) << 10) |
3942 (((g >> 3) & 0x1f) << 5) |
3945 p
= (((r
>> (8 - PNG_DITHER_RED_BITS
)) &
3946 ((1 << PNG_DITHER_RED_BITS
) - 1)) <<
3947 (PNG_DITHER_GREEN_BITS
+ PNG_DITHER_BLUE_BITS
)) |
3948 (((g
>> (8 - PNG_DITHER_GREEN_BITS
)) &
3949 ((1 << PNG_DITHER_GREEN_BITS
) - 1)) <<
3950 (PNG_DITHER_BLUE_BITS
)) |
3951 ((b
>> (8 - PNG_DITHER_BLUE_BITS
)) &
3952 ((1 << PNG_DITHER_BLUE_BITS
) - 1));
3954 *dp
++ = palette_lookup
[p
];
3956 row_info
->color_type
= PNG_COLOR_TYPE_PALETTE
;
3957 row_info
->channels
= 1;
3958 row_info
->pixel_depth
= row_info
->bit_depth
;
3959 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
,row_width
);
3961 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
&&
3962 palette_lookup
!= NULL
&& row_info
->bit_depth
== 8)
3967 for (i
= 0; i
< row_width
; i
++)
3974 p
= (((r
>> (8 - PNG_DITHER_RED_BITS
)) &
3975 ((1 << PNG_DITHER_RED_BITS
) - 1)) <<
3976 (PNG_DITHER_GREEN_BITS
+ PNG_DITHER_BLUE_BITS
)) |
3977 (((g
>> (8 - PNG_DITHER_GREEN_BITS
)) &
3978 ((1 << PNG_DITHER_GREEN_BITS
) - 1)) <<
3979 (PNG_DITHER_BLUE_BITS
)) |
3980 ((b
>> (8 - PNG_DITHER_BLUE_BITS
)) &
3981 ((1 << PNG_DITHER_BLUE_BITS
) - 1));
3983 *dp
++ = palette_lookup
[p
];
3985 row_info
->color_type
= PNG_COLOR_TYPE_PALETTE
;
3986 row_info
->channels
= 1;
3987 row_info
->pixel_depth
= row_info
->bit_depth
;
3988 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
,row_width
);
3990 else if (row_info
->color_type
== PNG_COLOR_TYPE_PALETTE
&&
3991 dither_lookup
&& row_info
->bit_depth
== 8)
3994 for (i
= 0; i
< row_width
; i
++, sp
++)
3996 *sp
= dither_lookup
[*sp
];
4003 #ifdef PNG_FLOATING_POINT_SUPPORTED
4004 #if defined(PNG_READ_GAMMA_SUPPORTED)
4005 static PNG_CONST
int png_gamma_shift
[] =
4006 {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00};
4008 /* We build the 8- or 16-bit gamma tables here. Note that for 16-bit
4009 * tables, we don't make a full table if we are reducing to 8-bit in
4010 * the future. Note also how the gamma_16 tables are segmented so that
4011 * we don't need to allocate > 64K chunks for a full 16-bit table.
4014 png_build_gamma_table(png_structp png_ptr
)
4016 png_debug(1, "in png_build_gamma_table\n");
4018 if (png_ptr
->bit_depth
<= 8)
4023 if (png_ptr
->screen_gamma
> .000001)
4024 g
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
4028 png_ptr
->gamma_table
= (png_bytep
)png_malloc(png_ptr
,
4031 for (i
= 0; i
< 256; i
++)
4033 png_ptr
->gamma_table
[i
] = (png_byte
)(pow((double)i
/ 255.0,
4037 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
4038 defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
4039 if (png_ptr
->transformations
& ((PNG_BACKGROUND
) | PNG_RGB_TO_GRAY
))
4042 g
= 1.0 / (png_ptr
->gamma
);
4044 png_ptr
->gamma_to_1
= (png_bytep
)png_malloc(png_ptr
,
4047 for (i
= 0; i
< 256; i
++)
4049 png_ptr
->gamma_to_1
[i
] = (png_byte
)(pow((double)i
/ 255.0,
4054 png_ptr
->gamma_from_1
= (png_bytep
)png_malloc(png_ptr
,
4057 if(png_ptr
->screen_gamma
> 0.000001)
4058 g
= 1.0 / png_ptr
->screen_gamma
;
4060 g
= png_ptr
->gamma
; /* probably doing rgb_to_gray */
4062 for (i
= 0; i
< 256; i
++)
4064 png_ptr
->gamma_from_1
[i
] = (png_byte
)(pow((double)i
/ 255.0,
4069 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
4074 int i
, j
, shift
, num
;
4078 if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
4080 sig_bit
= (int)png_ptr
->sig_bit
.red
;
4081 if ((int)png_ptr
->sig_bit
.green
> sig_bit
)
4082 sig_bit
= png_ptr
->sig_bit
.green
;
4083 if ((int)png_ptr
->sig_bit
.blue
> sig_bit
)
4084 sig_bit
= png_ptr
->sig_bit
.blue
;
4088 sig_bit
= (int)png_ptr
->sig_bit
.gray
;
4092 shift
= 16 - sig_bit
;
4096 if (png_ptr
->transformations
& PNG_16_TO_8
)
4098 if (shift
< (16 - PNG_MAX_GAMMA_8
))
4099 shift
= (16 - PNG_MAX_GAMMA_8
);
4107 png_ptr
->gamma_shift
= (png_byte
)shift
;
4109 num
= (1 << (8 - shift
));
4111 if (png_ptr
->screen_gamma
> .000001)
4112 g
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
4116 png_ptr
->gamma_16_table
= (png_uint_16pp
)png_malloc(png_ptr
,
4117 (png_uint_32
)(num
* png_sizeof (png_uint_16p
)));
4119 if (png_ptr
->transformations
& (PNG_16_TO_8
| PNG_BACKGROUND
))
4122 png_uint_32 last
, max
;
4124 for (i
= 0; i
< num
; i
++)
4126 png_ptr
->gamma_16_table
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
4127 (png_uint_32
)(256 * png_sizeof (png_uint_16
)));
4132 for (i
= 0; i
< 256; i
++)
4134 fout
= ((double)i
+ 0.5) / 256.0;
4136 max
= (png_uint_32
)(fin
* (double)((png_uint_32
)num
<< 8));
4139 png_ptr
->gamma_16_table
[(int)(last
& (0xff >> shift
))]
4140 [(int)(last
>> (8 - shift
))] = (png_uint_16
)(
4141 (png_uint_16
)i
| ((png_uint_16
)i
<< 8));
4145 while (last
< ((png_uint_32
)num
<< 8))
4147 png_ptr
->gamma_16_table
[(int)(last
& (0xff >> shift
))]
4148 [(int)(last
>> (8 - shift
))] = (png_uint_16
)65535L;
4154 for (i
= 0; i
< num
; i
++)
4156 png_ptr
->gamma_16_table
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
4157 (png_uint_32
)(256 * png_sizeof (png_uint_16
)));
4159 ig
= (((png_uint_32
)i
* (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
4160 for (j
= 0; j
< 256; j
++)
4162 png_ptr
->gamma_16_table
[i
][j
] =
4163 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
4164 65535.0, g
) * 65535.0 + .5);
4169 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
4170 defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
4171 if (png_ptr
->transformations
& (PNG_BACKGROUND
| PNG_RGB_TO_GRAY
))
4174 g
= 1.0 / (png_ptr
->gamma
);
4176 png_ptr
->gamma_16_to_1
= (png_uint_16pp
)png_malloc(png_ptr
,
4177 (png_uint_32
)(num
* png_sizeof (png_uint_16p
)));
4179 for (i
= 0; i
< num
; i
++)
4181 png_ptr
->gamma_16_to_1
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
4182 (png_uint_32
)(256 * png_sizeof (png_uint_16
)));
4184 ig
= (((png_uint_32
)i
*
4185 (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
4186 for (j
= 0; j
< 256; j
++)
4188 png_ptr
->gamma_16_to_1
[i
][j
] =
4189 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
4190 65535.0, g
) * 65535.0 + .5);
4194 if(png_ptr
->screen_gamma
> 0.000001)
4195 g
= 1.0 / png_ptr
->screen_gamma
;
4197 g
= png_ptr
->gamma
; /* probably doing rgb_to_gray */
4199 png_ptr
->gamma_16_from_1
= (png_uint_16pp
)png_malloc(png_ptr
,
4200 (png_uint_32
)(num
* png_sizeof (png_uint_16p
)));
4202 for (i
= 0; i
< num
; i
++)
4204 png_ptr
->gamma_16_from_1
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
4205 (png_uint_32
)(256 * png_sizeof (png_uint_16
)));
4207 ig
= (((png_uint_32
)i
*
4208 (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
4209 for (j
= 0; j
< 256; j
++)
4211 png_ptr
->gamma_16_from_1
[i
][j
] =
4212 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
4213 65535.0, g
) * 65535.0 + .5);
4217 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
4221 /* To do: install integer version of png_build_gamma_table here */
4224 #if defined(PNG_MNG_FEATURES_SUPPORTED)
4225 /* undoes intrapixel differencing */
4227 png_do_read_intrapixel(png_row_infop row_info
, png_bytep row
)
4229 png_debug(1, "in png_do_read_intrapixel\n");
4231 #if defined(PNG_USELESS_TESTS_SUPPORTED)
4232 row
!= NULL
&& row_info
!= NULL
&&
4234 (row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
4236 int bytes_per_pixel
;
4237 png_uint_32 row_width
= row_info
->width
;
4238 if (row_info
->bit_depth
== 8)
4243 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
4244 bytes_per_pixel
= 3;
4245 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
4246 bytes_per_pixel
= 4;
4250 for (i
= 0, rp
= row
; i
< row_width
; i
++, rp
+= bytes_per_pixel
)
4252 *(rp
) = (png_byte
)((256 + *rp
+ *(rp
+1))&0xff);
4253 *(rp
+2) = (png_byte
)((256 + *(rp
+2) + *(rp
+1))&0xff);
4256 else if (row_info
->bit_depth
== 16)
4261 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
)
4262 bytes_per_pixel
= 6;
4263 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
4264 bytes_per_pixel
= 8;
4268 for (i
= 0, rp
= row
; i
< row_width
; i
++, rp
+= bytes_per_pixel
)
4270 png_uint_32 s0
= (*(rp
) << 8) | *(rp
+1);
4271 png_uint_32 s1
= (*(rp
+2) << 8) | *(rp
+3);
4272 png_uint_32 s2
= (*(rp
+4) << 8) | *(rp
+5);
4273 png_uint_32 red
= (png_uint_32
)((s0
+s1
+65536L) & 0xffffL
);
4274 png_uint_32 blue
= (png_uint_32
)((s2
+s1
+65536L) & 0xffffL
);
4275 *(rp
) = (png_byte
)((red
>> 8) & 0xff);
4276 *(rp
+1) = (png_byte
)(red
& 0xff);
4277 *(rp
+4) = (png_byte
)((blue
>> 8) & 0xff);
4278 *(rp
+5) = (png_byte
)(blue
& 0xff);
4283 #endif /* PNG_MNG_FEATURES_SUPPORTED */
4284 #endif /* PNG_READ_SUPPORTED */