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