f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* pngrtran.c - transforms the data in a row for PNG readers
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * libpng version 1.2.8 - December 3, 2004
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * For conditions of distribution and use, see copyright notice in png.h
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * Copyright (c) 1998-2004 Glenn Randers-Pehrson
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * This file contains functions optionally called by an application
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * in order to tell libpng how to handle data when reading a PNG.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * Transformations that are used in both reading and writing are
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * in pngtrans.c.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#define PNG_INTERNAL
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#include "png.h"
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Set the action on getting a CRC error for an ancillary or critical chunk. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid PNGAPI
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_set_crc_action\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* Tell libpng how we react to CRC errors in critical chunks */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync switch (crit_action)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_CRC_NO_CHANGE: /* leave setting as is */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_CRC_WARN_USE: /* warn/use data */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_CRC_QUIET_USE: /* quiet/use data */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync PNG_FLAG_CRC_CRITICAL_IGNORE;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_CRC_WARN_DISCARD: /* not a valid action for critical data */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Can't discard critical data on CRC error.");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_CRC_ERROR_QUIT: /* error/quit */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_CRC_DEFAULT:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync default:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync switch (ancil_action)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_CRC_NO_CHANGE: /* leave setting as is */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_CRC_WARN_USE: /* warn/use data */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_CRC_QUIET_USE: /* quiet/use data */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync PNG_FLAG_CRC_ANCILLARY_NOWARN;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_CRC_ERROR_QUIT: /* error/quit */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_CRC_WARN_DISCARD: /* warn/discard data */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_CRC_DEFAULT:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync default:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync defined(PNG_FLOATING_POINT_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* handle alpha and tRNS via a background color */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid PNGAPI
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_set_background(png_structp png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_color_16p background_color, int background_gamma_code,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int need_expand, double background_gamma)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_set_background\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Application must supply a known background gamma");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->transformations |= PNG_BACKGROUND;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_memcpy(&(png_ptr->background), background_color,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_sizeof(png_color_16));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background_gamma = (float)background_gamma;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* Note: if need_expand is set and color_type is either RGB or RGB_ALPHA
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * (in which case need_expand is superfluous anyway), the background color
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * might actually be gray yet not be flagged as such. This is not a problem
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * for the current code, which uses PNG_BACKGROUND_IS_GRAY only to
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * decide when to do the png_do_gray_to_rgb() transformation.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((need_expand && !(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (!need_expand && background_color->red == background_color->green &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync background_color->red == background_color->blue))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_16_TO_8_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* strip 16 bit depth files to 8 bit depth */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid PNGAPI
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_set_strip_16(png_structp png_ptr)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_set_strip_16\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->transformations |= PNG_16_TO_8;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid PNGAPI
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_set_strip_alpha(png_structp png_ptr)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_set_strip_alpha\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->flags |= PNG_FLAG_STRIP_ALPHA;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_DITHER_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Dither file to 8 bit. Supply a palette, the current number
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * of elements in the palette, the maximum number of elements
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * allowed, and a histogram if possible. If the current number
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * of colors is greater then the maximum number, the palette will be
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * modified to fit in the maximum number. "full_dither" indicates
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * whether we need a dithering cube set up for RGB images, or if we
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * simply are reducing the number of colors in a paletted image.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsynctypedef struct png_dsort_struct
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync struct png_dsort_struct FAR * next;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte left;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte right;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync} png_dsort;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsynctypedef png_dsort FAR * png_dsortp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsynctypedef png_dsort FAR * FAR * png_dsortpp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid PNGAPI
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_set_dither(png_structp png_ptr, png_colorp palette,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int num_palette, int maximum_colors, png_uint_16p histogram,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int full_dither)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_set_dither\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->transformations |= PNG_DITHER;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!full_dither)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)(num_palette * png_sizeof (png_byte)));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < num_palette; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->dither_index[i] = (png_byte)i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (num_palette > maximum_colors)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (histogram != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* This is easy enough, just throw out the least used colors.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync Perhaps not the best solution, but good enough. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* initialize an array to sort colors */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)(num_palette * png_sizeof (png_byte)));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* initialize the dither_sort array */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < num_palette; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->dither_sort[i] = (png_byte)i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* Find the least used palette entries by starting a
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync bubble sort, and running it until we have sorted
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync out enough colors. Note that we don't care about
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sorting all the colors, just finding which are
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync least used. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = num_palette - 1; i >= maximum_colors; i--)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int done; /* to stop early if the list is pre-sorted */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int j;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync done = 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (j = 0; j < i; j++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (histogram[png_ptr->dither_sort[j]]
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync < histogram[png_ptr->dither_sort[j + 1]])
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte t;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync t = png_ptr->dither_sort[j];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->dither_sort[j] = png_ptr->dither_sort[j + 1];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->dither_sort[j + 1] = t;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync done = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (done)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* swap the palette around, and set up a table, if necessary */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (full_dither)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int j = num_palette;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* put all the useful colors within the max, but don't
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync move the others */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < maximum_colors; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((int)png_ptr->dither_sort[i] >= maximum_colors)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync do
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync j--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync while ((int)png_ptr->dither_sort[j] >= maximum_colors);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i] = palette[j];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int j = num_palette;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* move all the used colors inside the max limit, and
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync develop a translation table */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < maximum_colors; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* only move the colors we need to */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((int)png_ptr->dither_sort[i] >= maximum_colors)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_color tmp_color;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync do
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync j--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync while ((int)png_ptr->dither_sort[j] >= maximum_colors);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync tmp_color = palette[j];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[j] = palette[i];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i] = tmp_color;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* indicate where the color went */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->dither_index[j] = (png_byte)i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->dither_index[i] = (png_byte)j;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* find closest color for those colors we are not using */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < num_palette; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((int)png_ptr->dither_index[i] >= maximum_colors)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int min_d, k, min_k, d_index;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* find the closest color to one we threw out */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync d_index = png_ptr->dither_index[i];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (k = 1, min_k = 0; k < maximum_colors; k++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int d;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync d = PNG_COLOR_DIST(palette[d_index], palette[k]);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (d < min_d)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync min_d = d;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync min_k = k;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* point to closest color */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->dither_index[i] = (png_byte)min_k;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, png_ptr->dither_sort);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->dither_sort=NULL;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* This is much harder to do simply (and quickly). Perhaps
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync we need to go through a median cut routine, but those
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync don't always behave themselves with only a few colors
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync as input. So we will just find the closest two colors,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync and throw out one of them (chosen somewhat randomly).
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync [We don't understand this at all, so if someone wants to
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync work on improving it, be our guest - AED, GRP]
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int max_d;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int num_new_palette;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_dsortp t;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_dsortpp hash;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync t=NULL;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* initialize palette index arrays */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)(num_palette * png_sizeof (png_byte)));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)(num_palette * png_sizeof (png_byte)));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* initialize the sort array */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < num_palette; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->index_to_palette[i] = (png_byte)i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->palette_to_index[i] = (png_byte)i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_sizeof (png_dsortp)));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < 769; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync hash[i] = NULL;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* png_memset(hash, 0, 769 * png_sizeof (png_dsortp)); */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync num_new_palette = num_palette;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* initial wild guess at how far apart the farthest pixel
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pair we will be eliminating will be. Larger
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync numbers mean more areas will be allocated, Smaller
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync numbers run the risk of not saving enough data, and
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync having to do this all over again.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync I have not done extensive checking on this number.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync max_d = 96;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync while (num_new_palette > maximum_colors)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < num_new_palette - 1; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int j;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (j = i + 1; j < num_new_palette; j++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int d;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync d = PNG_COLOR_DIST(palette[i], palette[j]);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (d <= max_d)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync t = (png_dsortp)png_malloc_warn(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)(png_sizeof(png_dsort)));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (t == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync t->next = hash[d];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync t->left = (png_byte)i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync t->right = (png_byte)j;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync hash[d] = t;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (t == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (t != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i <= max_d; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (hash[i] != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_dsortp p;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (p = hash[i]; p; p = p->next)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((int)png_ptr->index_to_palette[p->left]
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync < num_new_palette &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (int)png_ptr->index_to_palette[p->right]
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync < num_new_palette)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int j, next_j;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (num_new_palette & 0x01)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync j = p->left;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync next_j = p->right;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync j = p->right;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync next_j = p->left;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync num_new_palette--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[png_ptr->index_to_palette[j]]
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync = palette[num_new_palette];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!full_dither)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int k;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (k = 0; k < num_palette; k++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->dither_index[k] ==
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->index_to_palette[j])
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->dither_index[k] =
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->index_to_palette[next_j];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((int)png_ptr->dither_index[k] ==
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync num_new_palette)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->dither_index[k] =
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->index_to_palette[j];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->index_to_palette[png_ptr->palette_to_index
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync [num_new_palette]] = png_ptr->index_to_palette[j];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync = png_ptr->palette_to_index[num_new_palette];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->index_to_palette[j] = (png_byte)num_new_palette;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->palette_to_index[num_new_palette] = (png_byte)j;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (num_new_palette <= maximum_colors)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (num_new_palette <= maximum_colors)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < 769; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (hash[i] != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_dsortp p = hash[i];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync while (p)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync t = p->next;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, p);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync p = t;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync hash[i] = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync max_d += 96;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, hash);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, png_ptr->palette_to_index);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, png_ptr->index_to_palette);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->palette_to_index=NULL;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->index_to_palette=NULL;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync num_palette = maximum_colors;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->palette == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->palette = palette;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->num_palette = (png_uint_16)num_palette;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (full_dither)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep distance;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync PNG_DITHER_BLUE_BITS;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int num_red = (1 << PNG_DITHER_RED_BITS);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int num_green = (1 << PNG_DITHER_GREEN_BITS);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int num_blue = (1 << PNG_DITHER_BLUE_BITS);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_size_t num_entries = ((png_size_t)1 << total_bits);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)(num_entries * png_sizeof (png_byte)));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_memset(png_ptr->palette_lookup, 0, num_entries *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_sizeof (png_byte));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_sizeof(png_byte)));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_memset(distance, 0xff, num_entries * png_sizeof(png_byte));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < num_palette; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int ir, ig, ib;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (ir = 0; ir < num_red; ir++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* int dr = abs(ir - r); */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int dr = ((ir > r) ? ir - r : r - ir);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (ig = 0; ig < num_green; ig++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* int dg = abs(ig - g); */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int dg = ((ig > g) ? ig - g : g - ig);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int dt = dr + dg;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int dm = ((dr > dg) ? dr : dg);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (ib = 0; ib < num_blue; ib++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int d_index = index_g | ib;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* int db = abs(ib - b); */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int db = ((ib > b) ? ib - b : b - ib);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int dmax = ((dm > db) ? dm : db);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int d = dmax + dt + db;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (d < (int)distance[d_index])
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync distance[d_index] = (png_byte)d;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->palette_lookup[d_index] = (png_byte)i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, distance);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Transform the image from the file_gamma to the screen_gamma. We
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * only do transformations on images where the file_gamma and screen_gamma
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * are not close reciprocals, otherwise it slows things down slightly, and
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * also needlessly introduces small errors.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * We will turn off gamma transformation later if no semitransparent entries
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * are present in the tRNS array for palette images. We can't do it here
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * because we don't necessarily have the tRNS chunk yet.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid PNGAPI
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_set_gamma\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->transformations |= PNG_GAMMA;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma = (float)file_gamma;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->screen_gamma = (float)scrn_gamma;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_EXPAND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Expand paletted images to RGB, expand grayscale images of
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * to alpha channels.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid PNGAPI
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_set_expand(png_structp png_ptr)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_set_expand\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->transformations |= PNG_EXPAND;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* GRR 19990627: the following three functions currently are identical
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * to png_set_expand(). However, it is entirely reasonable that someone
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * might wish to expand an indexed image to RGB but *not* expand a single,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * fully transparent palette entry to a full alpha channel--perhaps instead
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * the transparent color with a particular RGB value, or drop tRNS entirely.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * IOW, a future version of the library may make the transformations flag
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * a bit more fine-grained, with separate bits for each of these three
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * functions.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * More to the point, these functions make it obvious what libpng will be
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * doing, whereas "expand" can (and does) mean any number of things.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Expand paletted images to RGB. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid PNGAPI
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_set_palette_to_rgb(png_structp png_ptr)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_set_expand\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->transformations |= PNG_EXPAND;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Expand grayscale images of less than 8-bit depth to 8 bits. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid PNGAPI
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_set_gray_1_2_4_to_8(png_structp png_ptr)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_set_expand\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->transformations |= PNG_EXPAND;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Expand tRNS chunks to alpha channels. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid PNGAPI
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_set_tRNS_to_alpha(png_structp png_ptr)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_set_expand\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->transformations |= PNG_EXPAND;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid PNGAPI
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_set_gray_to_rgb(png_structp png_ptr)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_set_gray_to_rgb\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->transformations |= PNG_GRAY_TO_RGB;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_FLOATING_POINT_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Convert a RGB image to a grayscale of the same width. This allows us,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid PNGAPI
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync double green)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int red_fixed = (int)((float)red*100000.0 + 0.5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int green_fixed = (int)((float)green*100000.0 + 0.5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid PNGAPI
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_fixed_point red, png_fixed_point green)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_set_rgb_to_gray\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync switch(error_action)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_EXPAND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->transformations |= PNG_EXPAND;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->transformations &= ~PNG_RGB_TO_GRAY;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 red_int, green_int;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(red < 0 || green < 0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync red_int = 6968; /* .212671 * 32768 + .5 */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync green_int = 23434; /* .715160 * 32768 + .5 */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if(red + green < 100000L)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync red_int = 6968;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync green_int = 23434;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->rgb_to_gray_red_coeff = red_int;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->rgb_to_gray_green_coeff = green_int;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->rgb_to_gray_blue_coeff = (png_uint_16)(32768-red_int-green_int);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync defined(PNG_LEGACY_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid PNGAPI
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync read_user_transform_fn)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_set_read_user_transform_fn\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->transformations |= PNG_USER_TRANSFORM;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->read_user_transform_fn = read_user_transform_fn;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_LEGACY_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(read_user_transform_fn)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync "This version of libpng does not support user transforms");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Initialize everything needed for the read. This includes modifying
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * the palette.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_init_read_transformations(png_structp png_ptr)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_init_read_transformations\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_USELESS_TESTS_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(png_ptr != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync || defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int color_type = png_ptr->color_type;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_ptr->transformations & PNG_EXPAND))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(color_type & PNG_COLOR_MASK_COLOR)) /* i.e., GRAY or GRAY_ALPHA */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* expand background chunk. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync switch (png_ptr->bit_depth)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 1:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.gray *= (png_uint_16)0xff;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.red = png_ptr->background.green
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync = png_ptr->background.blue = png_ptr->background.gray;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 2:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.gray *= (png_uint_16)0x55;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.red = png_ptr->background.green
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync = png_ptr->background.blue = png_ptr->background.gray;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 4:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.gray *= (png_uint_16)0x11;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.red = png_ptr->background.green
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync = png_ptr->background.blue = png_ptr->background.gray;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 8:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 16:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.red = png_ptr->background.green
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync = png_ptr->background.blue = png_ptr->background.gray;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (color_type == PNG_COLOR_TYPE_PALETTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.red =
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->palette[png_ptr->background.index].red;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.green =
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->palette[png_ptr->background.index].green;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.blue =
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->palette[png_ptr->background.index].blue;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_INVERT_ALPHA)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_EXPAND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->transformations & PNG_EXPAND))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* invert the alpha channel (in tRNS) unless the pixels are
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync going to be expanded, in which case leave it for later */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int i,istop;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync istop=(int)png_ptr->num_trans;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i=0; i<istop; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background_1 = png_ptr->background;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync < PNG_GAMMA_THRESHOLD))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int i,k;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync k=0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i=0; i<png_ptr->num_trans; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync k=1; /* partial transparency is present */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (k == 0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->transformations &= (~PNG_GAMMA);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_build_gamma_table(png_ptr);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_BACKGROUND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_BACKGROUND)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (color_type == PNG_COLOR_TYPE_PALETTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* could skip if no transparency and
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_color back, back_1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_colorp palette = png_ptr->palette;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int num_palette = png_ptr->num_palette;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.red = png_ptr->gamma_table[png_ptr->background.red];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.green = png_ptr->gamma_table[png_ptr->background.green];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.blue = png_ptr->gamma_table[png_ptr->background.blue];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync double g, gs;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync switch (png_ptr->background_gamma_type)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_BACKGROUND_GAMMA_SCREEN:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = (png_ptr->screen_gamma);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync gs = 1.0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_BACKGROUND_GAMMA_FILE:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = 1.0 / (png_ptr->gamma);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_BACKGROUND_GAMMA_UNIQUE:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = 1.0 / (png_ptr->background_gamma);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync gs = 1.0 / (png_ptr->background_gamma *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->screen_gamma);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync default:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = 1.0; /* back_1 */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync gs = 1.0; /* back */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.red = (png_byte)png_ptr->background.red;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.green = (png_byte)png_ptr->background.green;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.blue = (png_byte)png_ptr->background.blue;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.red = (png_byte)(pow(
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (double)png_ptr->background.red/255, gs) * 255.0 + .5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.green = (png_byte)(pow(
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (double)png_ptr->background.green/255, gs) * 255.0 + .5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.blue = (png_byte)(pow(
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (double)png_ptr->background.blue/255, gs) * 255.0 + .5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back_1.red = (png_byte)(pow(
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (double)png_ptr->background.red/255, g) * 255.0 + .5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back_1.green = (png_byte)(pow(
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (double)png_ptr->background.green/255, g) * 255.0 + .5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back_1.blue = (png_byte)(pow(
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (double)png_ptr->background.blue/255, g) * 255.0 + .5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < num_palette; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->trans[i] == 0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i] = back;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else /* if (png_ptr->trans[i] != 0xff) */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte v, w;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = png_ptr->gamma_to_1[palette[i].red];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite(w, v, png_ptr->trans[i], back_1.red);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].red = png_ptr->gamma_from_1[w];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = png_ptr->gamma_to_1[palette[i].green];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite(w, v, png_ptr->trans[i], back_1.green);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].green = png_ptr->gamma_from_1[w];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = png_ptr->gamma_to_1[palette[i].blue];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite(w, v, png_ptr->trans[i], back_1.blue);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].blue = png_ptr->gamma_from_1[w];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].red = png_ptr->gamma_table[palette[i].red];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].green = png_ptr->gamma_table[palette[i].green];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].blue = png_ptr->gamma_table[palette[i].blue];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* color_type != PNG_COLOR_TYPE_PALETTE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync double g = 1.0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync double gs = 1.0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync switch (png_ptr->background_gamma_type)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_BACKGROUND_GAMMA_SCREEN:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = (png_ptr->screen_gamma);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync gs = 1.0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_BACKGROUND_GAMMA_FILE:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = 1.0 / (png_ptr->gamma);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_BACKGROUND_GAMMA_UNIQUE:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = 1.0 / (png_ptr->background_gamma);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync gs = 1.0 / (png_ptr->background_gamma *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->screen_gamma);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background_1.gray = (png_uint_16)(pow(
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (double)png_ptr->background.gray / m, g) * m + .5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.gray = (png_uint_16)(pow(
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (double)png_ptr->background.gray / m, gs) * m + .5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((png_ptr->background.red != png_ptr->background.green) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_ptr->background.red != png_ptr->background.blue) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_ptr->background.red != png_ptr->background.gray))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* RGB or RGBA with color background */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background_1.red = (png_uint_16)(pow(
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (double)png_ptr->background.red / m, g) * m + .5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background_1.green = (png_uint_16)(pow(
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (double)png_ptr->background.green / m, g) * m + .5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background_1.blue = (png_uint_16)(pow(
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (double)png_ptr->background.blue / m, g) * m + .5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.red = (png_uint_16)(pow(
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (double)png_ptr->background.red / m, gs) * m + .5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.green = (png_uint_16)(pow(
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (double)png_ptr->background.green / m, gs) * m + .5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.blue = (png_uint_16)(pow(
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (double)png_ptr->background.blue / m, gs) * m + .5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background_1.red = png_ptr->background_1.green
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync = png_ptr->background_1.blue = png_ptr->background_1.gray;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.red = png_ptr->background.green
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync = png_ptr->background.blue = png_ptr->background.gray;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* transformation does not include PNG_BACKGROUND */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif /* PNG_READ_BACKGROUND_SUPPORTED */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (color_type == PNG_COLOR_TYPE_PALETTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_colorp palette = png_ptr->palette;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int num_palette = png_ptr->num_palette;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < num_palette; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].red = png_ptr->gamma_table[palette[i].red];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].green = png_ptr->gamma_table[palette[i].green];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].blue = png_ptr->gamma_table[palette[i].blue];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_BACKGROUND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_BACKGROUND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* No GAMMA transformation */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((png_ptr->transformations & PNG_BACKGROUND) &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (color_type == PNG_COLOR_TYPE_PALETTE))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int istop = (int)png_ptr->num_trans;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_color back;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_colorp palette = png_ptr->palette;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.red = (png_byte)png_ptr->background.red;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.green = (png_byte)png_ptr->background.green;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.blue = (png_byte)png_ptr->background.blue;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < istop; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->trans[i] == 0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i] = back;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->trans[i] != 0xff)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* The png_composite() macro is defined in png.h */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite(palette[i].red, palette[i].red,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->trans[i], back.red);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite(palette[i].green, palette[i].green,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->trans[i], back.green);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite(palette[i].blue, palette[i].blue,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->trans[i], back.blue);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif /* PNG_READ_BACKGROUND_SUPPORTED */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_SHIFT_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((png_ptr->transformations & PNG_SHIFT) &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (color_type == PNG_COLOR_TYPE_PALETTE))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 istop = png_ptr->num_palette;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int sr = 8 - png_ptr->sig_bit.red;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int sg = 8 - png_ptr->sig_bit.green;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int sb = 8 - png_ptr->sig_bit.blue;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (sr < 0 || sr > 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sr = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (sg < 0 || sg > 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sg = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (sb < 0 || sb > 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sb = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < istop; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->palette[i].red >>= sr;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->palette[i].green >>= sg;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->palette[i].blue >>= sb;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif /* PNG_READ_SHIFT_SUPPORTED */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync && !defined(PNG_READ_BACKGROUND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(png_ptr)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Modify the info structure to reflect the transformations. The
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * info should be updated so a PNG file could be written with it,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * assuming the transformations result in valid PNG data.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_read_transform_info(png_structp png_ptr, png_infop info_ptr)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_read_transform_info\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_EXPAND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_EXPAND)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->num_trans)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->color_type = PNG_COLOR_TYPE_RGB;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->bit_depth = 8;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->num_trans = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->num_trans)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (info_ptr->bit_depth < 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->bit_depth = 8;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->num_trans = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_BACKGROUND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_BACKGROUND)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->num_trans = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->background = png_ptr->background;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_GAMMA)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_FLOATING_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->gamma = png_ptr->gamma;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_FIXED_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->int_gamma = png_ptr->int_gamma;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_16_TO_8_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->bit_depth = 8;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_DITHER_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_DITHER)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->palette_lookup && info_ptr->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_PACK_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->bit_depth = 8;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_GRAY_TO_RGB)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_RGB_TO_GRAY)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->channels = 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->channels = 3;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->channels = 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->channels++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_FILLER_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((png_ptr->transformations & PNG_FILLER) &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->channels++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* if adding a true alpha channel not just filler */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if !defined(PNG_1_0_X)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_ADD_ALPHA)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncdefined(PNG_READ_USER_TRANSFORM_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(png_ptr->transformations & PNG_USER_TRANSFORM)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(info_ptr->bit_depth < png_ptr->user_transform_depth)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->bit_depth = png_ptr->user_transform_depth;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(info_ptr->channels < png_ptr->user_transform_channels)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->channels = png_ptr->user_transform_channels;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->bit_depth);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,info_ptr->width);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if !defined(PNG_READ_EXPAND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(png_ptr)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Transform the row. The order of transformations is significant,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * and is very touchy. If you add a transformation, take care to
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * decide how it fits in with the other transformations here.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_do_read_transformations(png_structp png_ptr)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_do_read_transformations\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if !defined(PNG_USELESS_TESTS_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->row_buf == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync char msg[50];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sprintf(msg, "NULL row buffer for row %ld, pass %d", png_ptr->row_number,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->pass);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, msg);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "NULL row buffer");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_EXPAND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_EXPAND)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->num_trans)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync &(png_ptr->trans_values));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync NULL);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_RGB_TO_GRAY)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int rgb_error =
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(rgb_error)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->rgb_to_gray_status=1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(png_ptr->transformations == PNG_RGB_TO_GRAY_WARN)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(png_ptr->transformations == PNG_RGB_TO_GRAY_ERR)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/*
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncFrom Andreas Dilger e-mail to png-implement, 26 March 1998:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync In most cases, the "simple transparency" should be done prior to doing
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync gray-to-RGB, or you will have to test 3x as many bytes to check if a
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pixel is transparent. You would also need to make sure that the
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync transparency information is upgraded to RGB.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync To summarize, the current flow is:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync with background "in place" if transparent,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync convert to RGB if necessary
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync - Gray + alpha -> composite with gray background and remove alpha bytes,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync convert to RGB if necessary
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync To support RGB backgrounds for gray images we need:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync - Gray + simple transparency -> convert to RGB + simple transparency, compare
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync 3 or 6 bytes and composite with background
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync "in place" if transparent (3x compare/pixel
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync compared to doing composite with gray bkgrnd)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync - Gray + alpha -> convert to RGB + alpha, composite with background and
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync remove alpha bytes (3x float operations/pixel
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync compared with composite on gray background)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync Greg's change will do this. The reason it wasn't done before is for
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync performance, as this increases the per-pixel operations. If we would check
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync in advance if the background was gray or RGB, and position the gray-to-RGB
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync transform appropriately, then it would save a lot of work/time.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* if gray -> RGB, do so now only if background is non-gray; else do later
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * for performance reasons */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_BACKGROUND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((png_ptr->transformations & PNG_BACKGROUND) &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((png_ptr->num_trans != 0 ) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync &(png_ptr->trans_values), &(png_ptr->background)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync , &(png_ptr->background_1),
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_table, png_ptr->gamma_from_1,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_to_1, png_ptr->gamma_16_table,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_shift
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((png_ptr->transformations & PNG_GAMMA) &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_BACKGROUND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync !((png_ptr->transformations & PNG_BACKGROUND) &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((png_ptr->num_trans != 0) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_table, png_ptr->gamma_16_table,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_shift);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_16_TO_8_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_16_TO_8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_DITHER_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_DITHER)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->palette_lookup, png_ptr->dither_index);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(png_ptr->row_info.rowbytes == (png_uint_32)0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "png_do_dither returned rowbytes=0");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_INVERT_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_INVERT_MONO)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_SHIFT_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_SHIFT)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync &(png_ptr->shift));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_PACK_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_PACK)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_BGR_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_BGR)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_PACKSWAP_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_PACKSWAP)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* if gray -> RGB, do so now only if we did not do so above */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_FILLER_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_FILLER)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)png_ptr->filler, png_ptr->flags);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_INVERT_ALPHA)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_SWAP_ALPHA)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_SWAP_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_SWAP_BYTES)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_USER_TRANSFORM)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(png_ptr->read_user_transform_fn != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (*(png_ptr->read_user_transform_fn)) /* user read transform function */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_ptr, /* png_ptr */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync &(png_ptr->row_info), /* row_info: */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* png_uint_32 width; width of row */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* png_uint_32 rowbytes; number of bytes in row */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* png_byte color_type; color type of pixels */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* png_byte bit_depth; bit depth of samples */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* png_byte channels; number of channels (1-4) */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* png_byte pixel_depth; bits per pixel (depth*channels) */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->row_buf + 1); /* start of pixel data for row */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(png_ptr->user_transform_depth)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->row_info.bit_depth = png_ptr->user_transform_depth;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(png_ptr->user_transform_channels)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->row_info.channels = png_ptr->user_transform_channels;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->row_info.channels);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->row_info.width);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_PACK_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * without changing the actual values. Thus, if you had a row with
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * a bit depth of 1, you would end up with bytes that only contained
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * the numbers 0 or 1. If you would rather they contain 0 and 255, use
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * png_do_shift() after this.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_do_unpack(png_row_infop row_info, png_bytep row)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_do_unpack\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_USELESS_TESTS_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row != NULL && row_info != NULL && row_info->bit_depth < 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth < 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 row_width=row_info->width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync switch (row_info->bit_depth)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 1:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = row + (png_size_t)row_width - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = (png_byte)((*sp >> shift) & 0x01);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (shift == 7)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 2:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = row + (png_size_t)row_width - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = (png_byte)((*sp >> shift) & 0x03);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (shift == 6)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift += 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 4:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = row + (png_size_t)row_width - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = (png_byte)((*sp >> shift) & 0x0f);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (shift == 4)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->bit_depth = 8;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->pixel_depth = (png_byte)(8 * row_info->channels);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->rowbytes = row_width * row_info->channels;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_SHIFT_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Reverse the effects of png_do_shift. This routine merely shifts the
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * pixels back to their significant bits values. Thus, if you have
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * a row of bit depth 8, but only 5 are significant, this will shift
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * the values back to 0 through 31.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_do_unshift\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_USELESS_TESTS_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row != NULL && row_info != NULL && sig_bits != NULL &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->color_type != PNG_COLOR_TYPE_PALETTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int shift[4];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int channels = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int c;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 value = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 row_width = row_info->width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->color_type & PNG_COLOR_MASK_COLOR)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift[channels++] = row_info->bit_depth - sig_bits->red;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift[channels++] = row_info->bit_depth - sig_bits->green;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift[channels++] = row_info->bit_depth - sig_bits->blue;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift[channels++] = row_info->bit_depth - sig_bits->gray;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift[channels++] = row_info->bit_depth - sig_bits->alpha;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (c = 0; c < channels; c++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (shift[c] <= 0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift[c] = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync value = 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!value)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync switch (row_info->bit_depth)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 2:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep bp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 istop = row_info->rowbytes;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (bp = row, i = 0; i < istop; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *bp >>= 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *bp++ &= 0x55;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 4:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep bp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 istop = row_info->rowbytes;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) |
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_byte)((int)0xf >> shift[0]));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < istop; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *bp >>= shift[0];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *bp++ &= mask;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 8:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep bp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 istop = row_width * channels;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < istop; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *bp++ >>= shift[i%channels];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 16:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep bp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 istop = channels * row_width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < istop; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync value = (png_uint_16)((*bp << 8) + *(bp + 1));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync value >>= shift[i%channels];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *bp++ = (png_byte)(value >> 8);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *bp++ = (png_byte)(value & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_16_TO_8_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* chop rows of bit depth 16 down to 8 */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_do_chop(png_row_infop row_info, png_bytep row)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_do_chop\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_USELESS_TESTS_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row != NULL && row_info != NULL && row_info->bit_depth == 16)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth == 16)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 istop = row_info->width * row_info->channels;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i<istop; i++, sp += 2, dp++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* This does a more accurate scaling of the 16-bit color
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * value, rather than a simple low-byte truncation.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * What the ideal calculation should be:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * *dp = (((((png_uint_32)(*sp) << 8) |
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * GRR: no, I think this is what it really should be:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * *dp = (((((png_uint_32)(*sp) << 8) |
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * GRR: here's the exact calculation with shifts:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * *dp = (temp - (temp >> 8)) >> 8;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * Approximate calculation with shift/add instead of multiply/divide:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * *dp = ((((png_uint_32)(*sp) << 8) |
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * What we actually do to avoid extra shifting and conversion:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* Simply discard the low order byte */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = *sp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->bit_depth = 8;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->pixel_depth = (png_byte)(8 * row_info->channels);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->rowbytes = row_info->width * row_info->channels;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_do_read_swap_alpha\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_USELESS_TESTS_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row != NULL && row_info != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 row_width = row_info->width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* This converts from RGBA to ARGB */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + row_info->rowbytes;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = sp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte save;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync save = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = save;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* This converts from RRGGBBAA to AARRGGBB */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + row_info->rowbytes;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = sp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte save[2];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync save[0] = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync save[1] = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = save[0];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = save[1];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* This converts from GA to AG */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + row_info->rowbytes;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = sp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte save;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync save = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = save;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* This converts from GGAA to AAGG */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + row_info->rowbytes;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = sp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte save[2];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync save[0] = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync save[1] = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = save[0];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = save[1];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_do_read_invert_alpha\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_USELESS_TESTS_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row != NULL && row_info != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 row_width = row_info->width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* This inverts the alpha channel in RGBA */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + row_info->rowbytes;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = sp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = (png_byte)(255 - *(--sp));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* This does nothing:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync We can replace it with:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync*/
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp-=3;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp=sp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* This inverts the alpha channel in RRGGBBAA */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + row_info->rowbytes;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = sp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = (png_byte)(255 - *(--sp));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = (png_byte)(255 - *(--sp));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* This does nothing:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync We can replace it with:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync*/
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp-=6;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp=sp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* This inverts the alpha channel in GA */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + row_info->rowbytes;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = sp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = (png_byte)(255 - *(--sp));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* This inverts the alpha channel in GGAA */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + row_info->rowbytes;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = sp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = (png_byte)(255 - *(--sp));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = (png_byte)(255 - *(--sp));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/*
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync*/
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp-=2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp=sp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_FILLER_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Add filler channel if we have RGB color */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_do_read_filler(png_row_infop row_info, png_bytep row,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 filler, png_uint_32 flags)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 row_width = row_info->width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte lo_filler = (png_byte)(filler & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_do_read_filler\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_USELESS_TESTS_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row != NULL && row_info != NULL &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->color_type == PNG_COLOR_TYPE_GRAY)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(row_info->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* This changes the data from G to GX */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (flags & PNG_FLAG_FILLER_AFTER)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + (png_size_t)row_width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = sp + (png_size_t)row_width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 1; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = lo_filler;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = lo_filler;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->channels = 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->pixel_depth = 16;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->rowbytes = row_width * 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* This changes the data from G to XG */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + (png_size_t)row_width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = sp + (png_size_t)row_width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = lo_filler;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->channels = 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->pixel_depth = 16;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->rowbytes = row_width * 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if(row_info->bit_depth == 16)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* This changes the data from GG to GGXX */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (flags & PNG_FLAG_FILLER_AFTER)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + (png_size_t)row_width * 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = sp + (png_size_t)row_width * 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 1; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = hi_filler;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = lo_filler;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = hi_filler;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = lo_filler;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->channels = 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->pixel_depth = 32;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->rowbytes = row_width * 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* This changes the data from GG to XXGG */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + (png_size_t)row_width * 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = sp + (png_size_t)row_width * 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = hi_filler;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = lo_filler;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->channels = 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->pixel_depth = 32;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->rowbytes = row_width * 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync } /* COLOR_TYPE == GRAY */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(row_info->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* This changes the data from RGB to RGBX */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (flags & PNG_FLAG_FILLER_AFTER)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + (png_size_t)row_width * 3;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = sp + (png_size_t)row_width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 1; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = lo_filler;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = lo_filler;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->channels = 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->pixel_depth = 32;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->rowbytes = row_width * 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* This changes the data from RGB to XRGB */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + (png_size_t)row_width * 3;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = sp + (png_size_t)row_width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = lo_filler;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->channels = 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->pixel_depth = 32;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->rowbytes = row_width * 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if(row_info->bit_depth == 16)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* This changes the data from RRGGBB to RRGGBBXX */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (flags & PNG_FLAG_FILLER_AFTER)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + (png_size_t)row_width * 6;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = sp + (png_size_t)row_width * 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 1; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = hi_filler;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = lo_filler;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = hi_filler;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = lo_filler;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->channels = 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->pixel_depth = 64;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->rowbytes = row_width * 8;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* This changes the data from RRGGBB to XXRRGGBB */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + (png_size_t)row_width * 6;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = sp + (png_size_t)row_width * 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = *(--sp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = hi_filler;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(--dp) = lo_filler;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->channels = 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->pixel_depth = 64;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->rowbytes = row_width * 8;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync } /* COLOR_TYPE == RGB */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* expand grayscale files to RGB, with or without alpha */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 row_width = row_info->width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_do_gray_to_rgb\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth >= 8 &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_USELESS_TESTS_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row != NULL && row_info != NULL &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync !(row_info->color_type & PNG_COLOR_MASK_COLOR))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + (png_size_t)row_width - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = sp + (png_size_t)row_width * 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp--) = *sp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp--) = *sp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp--) = *(sp--);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + (png_size_t)row_width * 2 - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = sp + (png_size_t)row_width * 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp--) = *sp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp--) = *(sp - 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp--) = *sp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp--) = *(sp - 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp--) = *(sp--);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp--) = *(sp--);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + (png_size_t)row_width * 2 - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = sp + (png_size_t)row_width * 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp--) = *(sp--);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp--) = *sp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp--) = *sp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp--) = *(sp--);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + (png_size_t)row_width * 4 - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = sp + (png_size_t)row_width * 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp--) = *(sp--);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp--) = *(sp--);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp--) = *sp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp--) = *(sp - 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp--) = *sp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp--) = *(sp - 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp--) = *(sp--);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp--) = *(sp--);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->channels += (png_byte)2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->color_type |= PNG_COLOR_MASK_COLOR;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->pixel_depth = (png_byte)(row_info->channels *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->bit_depth);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* reduce RGB files to grayscale, with or without alpha
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * using the equation given in Poynton's ColorFAQ at
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * <http://www.inforamp.net/~poynton/>
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * Copyright (c) 1998-01-04 Charles Poynton poynton at inforamp.net
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * We approximate this with
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * which can be expressed with integers as
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * Y = (6969 * R + 23434 * G + 2365 * B)/32768
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * The calculation is to be done in a linear colorspace.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * Other integer coefficents can be used via png_set_rgb_to_gray().
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncint /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 row_width = row_info->width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int rgb_error = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_do_rgb_to_gray\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_USELESS_TESTS_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row != NULL && row_info != NULL &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (row_info->color_type & PNG_COLOR_MASK_COLOR))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->color_type == PNG_COLOR_TYPE_RGB)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte red = png_ptr->gamma_to_1[*(sp++)];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte green = png_ptr->gamma_to_1[*(sp++)];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte blue = png_ptr->gamma_to_1[*(sp++)];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(red != green || red != blue)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync rgb_error |= 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp++) = png_ptr->gamma_from_1[
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (rc*red+gc*green+bc*blue)>>15];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp++) = *(sp-1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte red = *(sp++);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte green = *(sp++);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte blue = *(sp++);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(red != green || red != blue)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync rgb_error |= 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp++) = (png_byte)((rc*red+gc*green+bc*blue)>>15);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp++) = *(sp-1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else /* RGB bit_depth == 16 */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->gamma_16_to_1 != NULL &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_16_from_1 != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 red, green, blue, w;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(red == green && red == blue)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync w = red;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >>
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_shift][red>>8];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_shift][green>>8];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_shift][blue>>8];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync + bc*blue_1)>>15);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_shift][gray16 >> 8];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync rgb_error |= 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp++) = (png_byte)((w>>8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp++) = (png_byte)(w & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 red, green, blue, gray16;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(red != green || red != blue)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync rgb_error |= 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp++) = (png_byte)((gray16>>8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp++) = (png_byte)(gray16 & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte red = png_ptr->gamma_to_1[*(sp++)];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte green = png_ptr->gamma_to_1[*(sp++)];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte blue = png_ptr->gamma_to_1[*(sp++)];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(red != green || red != blue)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync rgb_error |= 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp++) = png_ptr->gamma_from_1
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync [(rc*red + gc*green + bc*blue)>>15];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp++) = *(sp++); /* alpha */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte red = *(sp++);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte green = *(sp++);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte blue = *(sp++);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(red != green || red != blue)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync rgb_error |= 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp++) = *(sp++); /* alpha */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else /* RGBA bit_depth == 16 */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->gamma_16_to_1 != NULL &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_16_from_1 != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 red, green, blue, w;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(red == green && red == blue)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync w = red;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >>
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_shift][red>>8];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_shift][green>>8];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_shift][blue>>8];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 gray16 = (png_uint_16)((rc * red_1
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync + gc * green_1 + bc * blue_1)>>15);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_shift][gray16 >> 8];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync rgb_error |= 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp++) = (png_byte)((w>>8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp++) = (png_byte)(w & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp++) = *(sp++); /* alpha */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp++) = *(sp++);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 red, green, blue, gray16;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync red = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync blue = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(red != green || red != blue)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync rgb_error |= 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp++) = (png_byte)((gray16>>8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp++) = (png_byte)(gray16 & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp++) = *(sp++); /* alpha */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp++) = *(sp++);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->channels -= (png_byte)2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->color_type &= ~PNG_COLOR_MASK_COLOR;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->pixel_depth = (png_byte)(row_info->channels *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->bit_depth);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return rgb_error;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * large of png_color. This lets grayscale images be treated as
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * paletted. Most useful for gamma correction and simplification
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * of code.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid PNGAPI
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_build_grayscale_palette(int bit_depth, png_colorp palette)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int num_palette;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int color_inc;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int v;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_do_build_grayscale_palette\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (palette == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync switch (bit_depth)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 1:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync num_palette = 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync color_inc = 0xff;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 2:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync num_palette = 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync color_inc = 0x55;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 4:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync num_palette = 16;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync color_inc = 0x11;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 8:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync num_palette = 256;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync color_inc = 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync default:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync num_palette = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync color_inc = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].red = (png_byte)v;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].green = (png_byte)v;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].blue = (png_byte)v;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* This function is currently unused. Do we really need it? */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_correct_palette(png_structp png_ptr, png_colorp palette,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int num_palette)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_correct_palette\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_color back, back_1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.red = png_ptr->gamma_table[png_ptr->background.red];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.green = png_ptr->gamma_table[png_ptr->background.green];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.blue = png_ptr->gamma_table[png_ptr->background.blue];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync double g;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync fabs(g - 1.0) < PNG_GAMMA_THRESHOLD)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.red = png_ptr->background.red;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.green = png_ptr->background.green;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.blue = png_ptr->background.blue;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.red =
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_byte)(pow((double)png_ptr->background.red/255, g) *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync 255.0 + 0.5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.green =
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_byte)(pow((double)png_ptr->background.green/255, g) *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync 255.0 + 0.5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.blue =
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_byte)(pow((double)png_ptr->background.blue/255, g) *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync 255.0 + 0.5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = 1.0 / png_ptr->background_gamma;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back_1.red =
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_byte)(pow((double)png_ptr->background.red/255, g) *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync 255.0 + 0.5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back_1.green =
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_byte)(pow((double)png_ptr->background.green/255, g) *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync 255.0 + 0.5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back_1.blue =
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_byte)(pow((double)png_ptr->background.blue/255, g) *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync 255.0 + 0.5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < (png_uint_32)num_palette; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (i < png_ptr->num_trans && png_ptr->trans[i] == 0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i] = back;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte v, w;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite(w, v, png_ptr->trans[i], back_1.red);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].red = png_ptr->gamma_from_1[w];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite(w, v, png_ptr->trans[i], back_1.green);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].green = png_ptr->gamma_from_1[w];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite(w, v, png_ptr->trans[i], back_1.blue);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].blue = png_ptr->gamma_from_1[w];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].red = png_ptr->gamma_table[palette[i].red];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].green = png_ptr->gamma_table[palette[i].green];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].blue = png_ptr->gamma_table[palette[i].blue];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < num_palette; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (palette[i].red == (png_byte)png_ptr->trans_values.gray)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i] = back;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].red = png_ptr->gamma_table[palette[i].red];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].green = png_ptr->gamma_table[palette[i].green];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].blue = png_ptr->gamma_table[palette[i].blue];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_GAMMA)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < num_palette; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].red = png_ptr->gamma_table[palette[i].red];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].green = png_ptr->gamma_table[palette[i].green];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].blue = png_ptr->gamma_table[palette[i].blue];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_BACKGROUND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_BACKGROUND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_BACKGROUND)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_color back;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.red = (png_byte)png_ptr->background.red;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.green = (png_byte)png_ptr->background.green;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync back.blue = (png_byte)png_ptr->background.blue;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < (int)png_ptr->num_trans; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->trans[i] == 0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].red = back.red;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].green = back.green;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].blue = back.blue;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->trans[i] != 0xff)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite(palette[i].red, png_ptr->palette[i].red,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->trans[i], back.red);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite(palette[i].green, png_ptr->palette[i].green,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->trans[i], back.green);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite(palette[i].blue, png_ptr->palette[i].blue,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->trans[i], back.blue);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else /* assume grayscale palette (what else could it be?) */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < num_palette; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (i == (png_byte)png_ptr->trans_values.gray)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].red = (png_byte)png_ptr->background.red;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].green = (png_byte)png_ptr->background.green;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].blue = (png_byte)png_ptr->background.blue;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_BACKGROUND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Replace any alpha or transparency with the supplied background color.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * "background" is already in the screen gamma, while "background_1" is
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * at a gamma of 1.0. Paletted files have already been taken care of.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_do_background(png_row_infop row_info, png_bytep row,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_color_16p trans_values, png_color_16p background
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync , png_color_16p background_1,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16pp gamma_16_to_1, int gamma_shift
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync )
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp, dp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 row_width=row_info->width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int shift;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_do_background\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (background != NULL &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_USELESS_TESTS_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row != NULL && row_info != NULL &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values)))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync switch (row_info->color_type)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_COLOR_TYPE_GRAY:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync switch (row_info->bit_depth)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 1:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 7;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((png_uint_16)((*sp >> shift) & 0x01)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync == trans_values->gray)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp |= (png_byte)(background->gray << shift);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!shift)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 7;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 2:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (gamma_table != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 6;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((png_uint_16)((*sp >> shift) & 0x03)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync == trans_values->gray)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp |= (png_byte)(background->gray << shift);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte p = (png_byte)((*sp >> shift) & 0x03);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte g = (png_byte)((gamma_table [p | (p << 2) |
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (p << 4) | (p << 6)] >> 6) & 0x03);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp |= (png_byte)(g << shift);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!shift)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 6;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift -= 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 6;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((png_uint_16)((*sp >> shift) & 0x03)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync == trans_values->gray)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp |= (png_byte)(background->gray << shift);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!shift)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 6;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift -= 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 4:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (gamma_table != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((png_uint_16)((*sp >> shift) & 0x0f)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync == trans_values->gray)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp |= (png_byte)(background->gray << shift);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte p = (png_byte)((*sp >> shift) & 0x0f);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte g = (png_byte)((gamma_table[p |
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (p << 4)] >> 4) & 0x0f);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp |= (png_byte)(g << shift);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!shift)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift -= 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((png_uint_16)((*sp >> shift) & 0x0f)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync == trans_values->gray)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp |= (png_byte)(background->gray << shift);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!shift)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift -= 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 8:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (gamma_table != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++, sp++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (*sp == trans_values->gray)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = (png_byte)background->gray;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = gamma_table[*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++, sp++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (*sp == trans_values->gray)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = (png_byte)background->gray;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 16:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (gamma_16 != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++, sp += 2)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 v;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (v == trans_values->gray)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* background is already in screen gamma */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = (png_byte)((background->gray >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 1) = (png_byte)(background->gray & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = (png_byte)((v >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 1) = (png_byte)(v & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++, sp += 2)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 v;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (v == trans_values->gray)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = (png_byte)((background->gray >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 1) = (png_byte)(background->gray & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_COLOR_TYPE_RGB:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (gamma_table != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++, sp += 3)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (*sp == trans_values->red &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 1) == trans_values->green &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 2) == trans_values->blue)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = (png_byte)background->red;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 1) = (png_byte)background->green;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 2) = (png_byte)background->blue;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = gamma_table[*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 1) = gamma_table[*(sp + 1)];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 2) = gamma_table[*(sp + 2)];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++, sp += 3)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (*sp == trans_values->red &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 1) == trans_values->green &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 2) == trans_values->blue)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = (png_byte)background->red;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 1) = (png_byte)background->green;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 2) = (png_byte)background->blue;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else /* if (row_info->bit_depth == 16) */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (gamma_16 != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++, sp += 6)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (r == trans_values->red && g == trans_values->green &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync b == trans_values->blue)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* background is already in screen gamma */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = (png_byte)((background->red >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 1) = (png_byte)(background->red & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 3) = (png_byte)(background->green & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 5) = (png_byte)(background->blue & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = (png_byte)((v >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 1) = (png_byte)(v & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 2) = (png_byte)((v >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 3) = (png_byte)(v & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 4) = (png_byte)((v >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 5) = (png_byte)(v & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++, sp += 6)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (r == trans_values->red && g == trans_values->green &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync b == trans_values->blue)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = (png_byte)((background->red >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 1) = (png_byte)(background->red & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 3) = (png_byte)(background->green & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 5) = (png_byte)(background->blue & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_COLOR_TYPE_GRAY_ALPHA:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync gamma_table != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++, sp += 2, dp++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 a = *(sp + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (a == 0xff)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = gamma_table[*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (a == 0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* background is already in screen gamma */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = (png_byte)background->gray;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte v, w;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = gamma_to_1[*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite(w, v, a, background_1->gray);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = gamma_from_1[w];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++, sp += 2, dp++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte a = *(sp + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (a == 0xff)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = *sp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (a == 0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = (png_byte)background->gray;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite(*dp, *sp, a, background_1->gray);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = (png_byte)background->gray;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else /* if (png_ptr->bit_depth == 16) */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync gamma_16_to_1 != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++, sp += 4, dp += 2)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (a == (png_uint_16)0xffff)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 v;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = (png_byte)((v >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 1) = (png_byte)(v & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (a == 0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* background is already in screen gamma */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = (png_byte)((background->gray >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 1) = (png_byte)(background->gray & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 g, v, w;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite_16(v, g, a, background_1->gray);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = (png_byte)((w >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 1) = (png_byte)(w & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++, sp += 4, dp += 2)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (a == (png_uint_16)0xffff)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_memcpy(dp, sp, 2);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (a == 0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = (png_byte)((background->gray >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 1) = (png_byte)(background->gray & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 g, v;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite_16(v, g, a, background_1->gray);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = (png_byte)((v >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 1) = (png_byte)(v & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_COLOR_TYPE_RGB_ALPHA:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync gamma_table != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++, sp += 4, dp += 3)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte a = *(sp + 3);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (a == 0xff)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = gamma_table[*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 1) = gamma_table[*(sp + 1)];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 2) = gamma_table[*(sp + 2)];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (a == 0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* background is already in screen gamma */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = (png_byte)background->red;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 1) = (png_byte)background->green;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 2) = (png_byte)background->blue;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte v, w;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = gamma_to_1[*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite(w, v, a, background_1->red);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = gamma_from_1[w];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = gamma_to_1[*(sp + 1)];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite(w, v, a, background_1->green);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 1) = gamma_from_1[w];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = gamma_to_1[*(sp + 2)];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite(w, v, a, background_1->blue);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 2) = gamma_from_1[w];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++, sp += 4, dp += 3)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte a = *(sp + 3);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (a == 0xff)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = *sp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 1) = *(sp + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 2) = *(sp + 2);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (a == 0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = (png_byte)background->red;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 1) = (png_byte)background->green;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 2) = (png_byte)background->blue;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite(*dp, *sp, a, background->red);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite(*(dp + 1), *(sp + 1), a,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync background->green);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite(*(dp + 2), *(sp + 2), a,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync background->blue);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else /* if (row_info->bit_depth == 16) */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync gamma_16_to_1 != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++, sp += 8, dp += 6)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync << 8) + (png_uint_16)(*(sp + 7)));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (a == (png_uint_16)0xffff)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 v;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = (png_byte)((v >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 1) = (png_byte)(v & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 2) = (png_byte)((v >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 3) = (png_byte)(v & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 4) = (png_byte)((v >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 5) = (png_byte)(v & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (a == 0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* background is already in screen gamma */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = (png_byte)((background->red >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 1) = (png_byte)(background->red & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 3) = (png_byte)(background->green & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 5) = (png_byte)(background->blue & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 v, w, x;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite_16(w, v, a, background_1->red);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = (png_byte)((x >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 1) = (png_byte)(x & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite_16(w, v, a, background_1->green);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 2) = (png_byte)((x >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 3) = (png_byte)(x & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite_16(w, v, a, background_1->blue);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 4) = (png_byte)((x >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 5) = (png_byte)(x & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++, sp += 8, dp += 6)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync << 8) + (png_uint_16)(*(sp + 7)));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (a == (png_uint_16)0xffff)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_memcpy(dp, sp, 6);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (a == 0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = (png_byte)((background->red >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 1) = (png_byte)(background->red & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 3) = (png_byte)(background->green & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 5) = (png_byte)(background->blue & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 v;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync + *(sp + 3));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync + *(sp + 5));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite_16(v, r, a, background->red);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = (png_byte)((v >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 1) = (png_byte)(v & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite_16(v, g, a, background->green);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 2) = (png_byte)((v >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 3) = (png_byte)(v & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_composite_16(v, b, a, background->blue);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 4) = (png_byte)((v >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(dp + 5) = (png_byte)(v & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->channels--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->pixel_depth = (png_byte)(row_info->channels *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->bit_depth);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Gamma correct the image, avoiding the alpha channel. Make sure
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * you do this after you deal with the transparency issue on grayscale
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * or RGB images. If your bit depth is 8, use gamma_table, if it
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * is 16, use gamma_16_table and gamma_shift. Build these with
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * build_gamma_table().
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_do_gamma(png_row_infop row_info, png_bytep row,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep gamma_table, png_uint_16pp gamma_16_table,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int gamma_shift)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 row_width=row_info->width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_do_gamma\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_USELESS_TESTS_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row != NULL && row_info != NULL &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((row_info->bit_depth <= 8 && gamma_table != NULL) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (row_info->bit_depth == 16 && gamma_16_table != NULL)))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync switch (row_info->color_type)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_COLOR_TYPE_RGB:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = gamma_table[*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = gamma_table[*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = gamma_table[*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else /* if (row_info->bit_depth == 16) */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 v;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = (png_byte)((v >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 1) = (png_byte)(v & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp += 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = (png_byte)((v >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 1) = (png_byte)(v & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp += 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = (png_byte)((v >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 1) = (png_byte)(v & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp += 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_COLOR_TYPE_RGB_ALPHA:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = gamma_table[*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = gamma_table[*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = gamma_table[*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else /* if (row_info->bit_depth == 16) */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = (png_byte)((v >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 1) = (png_byte)(v & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp += 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = (png_byte)((v >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 1) = (png_byte)(v & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp += 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = (png_byte)((v >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 1) = (png_byte)(v & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp += 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_COLOR_TYPE_GRAY_ALPHA:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = gamma_table[*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp += 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else /* if (row_info->bit_depth == 16) */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = (png_byte)((v >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 1) = (png_byte)(v & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp += 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_COLOR_TYPE_GRAY:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth == 2)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i += 4)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int a = *sp & 0xc0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int b = *sp & 0x30;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int c = *sp & 0x0c;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int d = *sp & 0x03;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = (png_byte)(
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)|
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth == 4)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i += 2)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int msb = *sp & 0xf0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int lsb = *sp & 0x0f;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (row_info->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = gamma_table[*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (row_info->bit_depth == 16)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = (png_byte)((v >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp + 1) = (png_byte)(v & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp += 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_EXPAND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Expands a palette row to an RGB or RGBA row depending
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * upon whether you supply trans and num_trans.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_do_expand_palette(png_row_infop row_info, png_bytep row,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_colorp palette, png_bytep trans, int num_trans)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int shift, value;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp, dp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 row_width=row_info->width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_do_expand_palette\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_USELESS_TESTS_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row != NULL && row_info != NULL &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->color_type == PNG_COLOR_TYPE_PALETTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth < 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync switch (row_info->bit_depth)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 1:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row + (png_size_t)((row_width - 1) >> 3);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp = row + (png_size_t)row_width - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 7 - (int)((row_width + 7) & 0x07);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((*sp >> shift) & 0x01)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (shift == 7)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 2:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row + (png_size_t)((row_width - 1) >> 2);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp = row + (png_size_t)row_width - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync value = (*sp >> shift) & 0x03;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = (png_byte)value;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (shift == 6)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift += 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 4:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row + (png_size_t)((row_width - 1) >> 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp = row + (png_size_t)row_width - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = (int)((row_width & 0x01) << 2);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync value = (*sp >> shift) & 0x0f;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = (png_byte)value;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (shift == 4)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift += 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->bit_depth = 8;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->pixel_depth = 8;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->rowbytes = row_width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync switch (row_info->bit_depth)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 8:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (trans != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row + (png_size_t)row_width - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp = row + (png_size_t)(row_width << 2) - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((int)(*sp) >= num_trans)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = 0xff;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = trans[*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = palette[*sp].blue;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = palette[*sp].green;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = palette[*sp].red;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->bit_depth = 8;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->pixel_depth = 32;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->rowbytes = row_width * 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->color_type = 6;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->channels = 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row + (png_size_t)row_width - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp = row + (png_size_t)(row_width * 3) - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = palette[*sp].blue;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = palette[*sp].green;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = palette[*sp].red;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->bit_depth = 8;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->pixel_depth = 24;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->rowbytes = row_width * 3;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->color_type = 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->channels = 3;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* If the bit depth < 8, it is expanded to 8. Also, if the
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * transparency value is supplied, an alpha channel is built.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_do_expand(png_row_infop row_info, png_bytep row,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_color_16p trans_value)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int shift, value;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp, dp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 row_width=row_info->width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_do_expand\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_USELESS_TESTS_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row != NULL && row_info != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth < 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync switch (row_info->bit_depth)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 1:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync gray = (png_uint_16)(gray*0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row + (png_size_t)((row_width - 1) >> 3);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp = row + (png_size_t)row_width - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 7 - (int)((row_width + 7) & 0x07);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((*sp >> shift) & 0x01)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = 0xff;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (shift == 7)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 2:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync gray = (png_uint_16)(gray*0x55);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row + (png_size_t)((row_width - 1) >> 2);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp = row + (png_size_t)row_width - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync value = (*sp >> shift) & 0x03;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = (png_byte)(value | (value << 2) | (value << 4) |
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (value << 6));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (shift == 6)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift += 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 4:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync gray = (png_uint_16)(gray*0x11);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row + (png_size_t)((row_width - 1) >> 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp = row + (png_size_t)row_width - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync value = (*sp >> shift) & 0x0f;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp = (png_byte)(value | (value << 4));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (shift == 4)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->bit_depth = 8;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->pixel_depth = 8;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->rowbytes = row_width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (trans_value != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row + (png_size_t)row_width - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp = row + (png_size_t)(row_width << 1) - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (*sp == gray)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = 0xff;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = *sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (row_info->bit_depth == 16)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row + row_info->rowbytes - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp = row + (row_info->rowbytes << 1) - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (((png_uint_16)*(sp) |
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((png_uint_16)*(sp - 1) << 8)) == gray)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = 0xff;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = 0xff;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = *sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = *sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->channels = 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_width);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row + (png_size_t)row_info->rowbytes - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp = row + (png_size_t)(row_width << 2) - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (*(sp - 2) == trans_value->red &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp - 1) == trans_value->green &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(sp - 0) == trans_value->blue)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = 0xff;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = *sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = *sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = *sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (row_info->bit_depth == 16)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row + row_info->rowbytes - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp = row + (png_size_t)(row_width << 3) - 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((((png_uint_16)*(sp - 4) |
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((png_uint_16)*(sp - 5) << 8)) == trans_value->red) &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (((png_uint_16)*(sp - 2) |
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((png_uint_16)*(sp - 3) << 8)) == trans_value->green) &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (((png_uint_16)*(sp - 0) |
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((png_uint_16)*(sp - 1) << 8)) == trans_value->blue))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = 0xff;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = 0xff;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = *sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = *sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = *sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = *sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = *sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp-- = *sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->channels = 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_DITHER_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_do_dither(png_row_infop row_info, png_bytep row,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep palette_lookup, png_bytep dither_lookup)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp, dp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 row_width=row_info->width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_do_dither\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_USELESS_TESTS_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row != NULL && row_info != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette_lookup && row_info->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int r, g, b, p;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync r = *sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = *sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync b = *sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* this looks real messy, but the compiler will reduce
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync it down to a reasonable formula. For example, with
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync 5 bits per color, we get:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync p = (((r >> 3) & 0x1f) << 10) |
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (((g >> 3) & 0x1f) << 5) |
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((b >> 3) & 0x1f);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((1 << PNG_DITHER_RED_BITS) - 1)) <<
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (PNG_DITHER_BLUE_BITS)) |
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((1 << PNG_DITHER_BLUE_BITS) - 1));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp++ = palette_lookup[p];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->color_type = PNG_COLOR_TYPE_PALETTE;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->channels = 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->pixel_depth = row_info->bit_depth;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette_lookup != NULL && row_info->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int r, g, b, p;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync r = *sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = *sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync b = *sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((1 << PNG_DITHER_RED_BITS) - 1)) <<
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (PNG_DITHER_BLUE_BITS)) |
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((1 << PNG_DITHER_BLUE_BITS) - 1));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp++ = palette_lookup[p];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->color_type = PNG_COLOR_TYPE_PALETTE;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->channels = 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->pixel_depth = row_info->bit_depth;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dither_lookup && row_info->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++, sp++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *sp = dither_lookup[*sp];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_FLOATING_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncstatic int png_gamma_shift[] =
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0};
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * tables, we don't make a full table if we are reducing to 8-bit in
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * the future. Note also how the gamma_16 tables are segmented so that
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * we don't need to allocate > 64K chunks for a full 16-bit table.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_build_gamma_table(png_structp png_ptr)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_build_gamma_table\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(png_ptr->gamma != 0.0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->bit_depth <= 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync double g;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->screen_gamma > .000001)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = 1.0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)256);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < 256; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g) * 255.0 + .5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = 1.0 / (png_ptr->gamma);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)256);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < 256; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g) * 255.0 + .5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)256);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(png_ptr->screen_gamma > 0.000001)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = 1.0 / png_ptr->screen_gamma;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = png_ptr->gamma; /* probably doing rgb_to_gray */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < 256; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g) * 255.0 + .5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync double g;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int i, j, shift, num;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int sig_bit;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 ig;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sig_bit = (int)png_ptr->sig_bit.red;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((int)png_ptr->sig_bit.green > sig_bit)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sig_bit = png_ptr->sig_bit.green;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((int)png_ptr->sig_bit.blue > sig_bit)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sig_bit = png_ptr->sig_bit.blue;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sig_bit = (int)png_ptr->sig_bit.gray;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (sig_bit > 0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 16 - sig_bit;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_16_TO_8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (shift < (16 - PNG_MAX_GAMMA_8))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = (16 - PNG_MAX_GAMMA_8);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (shift > 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 8;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (shift < 0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_shift = (png_byte)shift;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync num = (1 << (8 - shift));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->screen_gamma > .000001)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = 1.0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)(num * png_sizeof (png_uint_16p)));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync double fin, fout;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 last, max;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < num; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)(256 * png_sizeof (png_uint_16)));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = 1.0 / g;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync last = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < 256; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync fout = ((double)i + 0.5) / 256.0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync fin = pow(fout, g);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync while (last <= max)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync [(int)(last >> (8 - shift))] = (png_uint_16)(
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_16)i | ((png_uint_16)i << 8));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync last++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync while (last < ((png_uint_32)num << 8))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync [(int)(last >> (8 - shift))] = (png_uint_16)65535L;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync last++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < num; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)(256 * png_sizeof (png_uint_16)));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (j = 0; j < 256; j++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_16_table[i][j] =
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync 65535.0, g) * 65535.0 + .5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = 1.0 / (png_ptr->gamma);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)(num * png_sizeof (png_uint_16p )));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < num; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)(256 * png_sizeof (png_uint_16)));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ig = (((png_uint_32)i *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)png_gamma_shift[shift]) >> 4);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (j = 0; j < 256; j++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_16_to_1[i][j] =
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync 65535.0, g) * 65535.0 + .5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(png_ptr->screen_gamma > 0.000001)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = 1.0 / png_ptr->screen_gamma;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync g = png_ptr->gamma; /* probably doing rgb_to_gray */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)(num * png_sizeof (png_uint_16p)));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < num; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)(256 * png_sizeof (png_uint_16)));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ig = (((png_uint_32)i *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)png_gamma_shift[shift]) >> 4);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (j = 0; j < 256; j++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma_16_from_1[i][j] =
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync 65535.0, g) * 65535.0 + .5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* To do: install integer version of png_build_gamma_table here */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_MNG_FEATURES_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* undoes intrapixel differencing */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_do_read_intrapixel(png_row_infop row_info, png_bytep row)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_do_read_intrapixel\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_USELESS_TESTS_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row != NULL && row_info != NULL &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (row_info->color_type & PNG_COLOR_MASK_COLOR))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int bytes_per_pixel;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 row_width = row_info->width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->bit_depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep rp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->color_type == PNG_COLOR_TYPE_RGB)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync bytes_per_pixel = 3;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync bytes_per_pixel = 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (row_info->bit_depth == 16)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep rp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_info->color_type == PNG_COLOR_TYPE_RGB)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync bytes_per_pixel = 6;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync bytes_per_pixel = 8;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 s0 = (*(rp ) << 8) | *(rp+1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 red = (png_uint_32)((s0+s1+65536L) & 0xffffL);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 blue = (png_uint_32)((s2+s1+65536L) & 0xffffL);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(rp ) = (png_byte)((red >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(rp+1) = (png_byte)(red & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(rp+4) = (png_byte)((blue >> 8) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(rp+5) = (png_byte)(blue & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif /* PNG_MNG_FEATURES_SUPPORTED */