14d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* pngrtran.c - transforms the data in a row for PNG readers
34d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
44d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Last changed in libpng 1.6.22 [May 26, 2016]
54d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
64d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
74d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
84d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
94d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * This code is released under the libpng license.
104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * For conditions of distribution and use, see the disclaimer
114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * and license in png.h
124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * This file contains functions optionally called by an application
144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * in order to tell libpng how to handle data when reading a PNG.
154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Transformations that are used in both reading and writing are
164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * in pngtrans.c.
174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "pngpriv.h"
204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_SUPPORTED
224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Set the action on getting a CRC error for an ancillary or critical chunk. */
244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action)
264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_set_crc_action");
284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr == NULL)
304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Tell libpng how we react to CRC errors in critical chunks */
334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   switch (crit_action)
344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_CRC_NO_CHANGE:                        /* Leave setting as is */
364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_CRC_WARN_USE:                               /* Warn/use data */
394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_CRC_QUIET_USE:                             /* Quiet/use data */
444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           PNG_FLAG_CRC_CRITICAL_IGNORE;
474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_CRC_WARN_DISCARD:    /* Not a valid action for critical data */
504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_warning(png_ptr,
514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            "Can't discard critical data on CRC error");
524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_CRC_ERROR_QUIT:                                /* Error/quit */
534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_CRC_DEFAULT:
554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      default:
564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Tell libpng how we react to CRC errors in ancillary chunks */
614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   switch (ancil_action)
624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_CRC_NO_CHANGE:                       /* Leave setting as is */
644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_CRC_WARN_USE:                              /* Warn/use data */
674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_CRC_QUIET_USE:                            /* Quiet/use data */
724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           PNG_FLAG_CRC_ANCILLARY_NOWARN;
754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_CRC_ERROR_QUIT:                               /* Error/quit */
784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_CRC_WARN_DISCARD:                      /* Warn/discard data */
834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_CRC_DEFAULT:
854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      default:
864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_TRANSFORMS_SUPPORTED
924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Is it OK to set a transformation now?  Only if png_start_read_image or
934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * png_read_update_info have not been called.  It is not necessary for the IHDR
944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * to have been read in all cases; the need_IHDR parameter allows for this
954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * check too.
964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int
984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_rtran_ok(png_structrp png_ptr, int need_IHDR)
994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
1004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr != NULL)
1014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
1024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if ((png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
1034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_app_error(png_ptr,
1044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            "invalid after png_start_read_image or png_read_update_info");
1054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0)
1074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_app_error(png_ptr, "invalid before the PNG header has been read");
1084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
1104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
1114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Turn on failure to initialize correctly for all transforms. */
1124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED;
1134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return 1; /* Ok */
1154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
1164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
1174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 0; /* no png_error possible! */
1194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
1204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
1214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_BACKGROUND_SUPPORTED
1234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Handle alpha and tRNS via a background color */
1244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGFAPI
1254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_background_fixed(png_structrp png_ptr,
1264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    png_const_color_16p background_color, int background_gamma_code,
1274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int need_expand, png_fixed_point background_gamma)
1284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
1294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_set_background_fixed");
1304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_rtran_ok(png_ptr, 0) == 0 || background_color == NULL)
1324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
1334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
1354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
1364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_warning(png_ptr, "Application must supply a known background gamma");
1374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
1384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
1394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA;
1414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
1424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->background = *background_color;
1454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->background_gamma = background_gamma;
1464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
1474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (need_expand != 0)
1484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->transformations |= PNG_BACKGROUND_EXPAND;
1494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else
1504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
1514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
1524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  ifdef PNG_FLOATING_POINT_SUPPORTED
1544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
1554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_background(png_structrp png_ptr,
1564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    png_const_color_16p background_color, int background_gamma_code,
1574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int need_expand, double background_gamma)
1584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
1594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_set_background_fixed(png_ptr, background_color, background_gamma_code,
1604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      need_expand, png_fixed(png_ptr, background_gamma, "png_set_background"));
1614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
1624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  endif /* FLOATING_POINT */
1634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_BACKGROUND */
1644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Scale 16-bit depth files to 8-bit depth.  If both of these are set then the
1664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * one that pngrtran does first (scale) happens.  This is necessary to allow the
1674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * TRANSFORM and API behavior to be somewhat consistent, and it's simpler.
1684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
1694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
1704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
1714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_scale_16(png_structrp png_ptr)
1724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
1734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_set_scale_16");
1744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_rtran_ok(png_ptr, 0) == 0)
1764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
1774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->transformations |= PNG_SCALE_16_TO_8;
1794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
1804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
1814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
1834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Chop 16-bit depth files to 8-bit depth */
1844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
1854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_strip_16(png_structrp png_ptr)
1864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
1874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_set_strip_16");
1884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_rtran_ok(png_ptr, 0) == 0)
1904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
1914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->transformations |= PNG_16_TO_8;
1934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
1944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
1954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
1974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
1984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_strip_alpha(png_structrp png_ptr)
1994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
2004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_set_strip_alpha");
2014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_rtran_ok(png_ptr, 0) == 0)
2034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
2044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->transformations |= PNG_STRIP_ALPHA;
2064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
2074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
2084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED)
2104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic png_fixed_point
2114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmanntranslate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma,
2124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int is_screen)
2134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
2144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Check for flag values.  The main reason for having the old Mac value as a
2154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * flag is that it is pretty near impossible to work out what the correct
2164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * value is from Apple documentation - a working Mac system is needed to
2174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * discover the value!
2184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
2194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (output_gamma == PNG_DEFAULT_sRGB ||
2204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB)
2214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
2224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* If there is no sRGB support this just sets the gamma to the standard
2234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * sRGB value.  (This is a side effect of using this function!)
2244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
2254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     ifdef PNG_READ_sRGB_SUPPORTED
2264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->flags |= PNG_FLAG_ASSUME_sRGB;
2274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     else
2284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         PNG_UNUSED(png_ptr)
2294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     endif
2304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (is_screen != 0)
2314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         output_gamma = PNG_GAMMA_sRGB;
2324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
2334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         output_gamma = PNG_GAMMA_sRGB_INVERSE;
2344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
2354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else if (output_gamma == PNG_GAMMA_MAC_18 ||
2374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18)
2384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
2394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (is_screen != 0)
2404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         output_gamma = PNG_GAMMA_MAC_OLD;
2414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
2424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         output_gamma = PNG_GAMMA_MAC_INVERSE;
2434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
2444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return output_gamma;
2464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
2474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  ifdef PNG_FLOATING_POINT_SUPPORTED
2494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic png_fixed_point
2504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannconvert_gamma_value(png_structrp png_ptr, double output_gamma)
2514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
2524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* The following silently ignores cases where fixed point (times 100,000)
2534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * gamma values are passed to the floating point API.  This is safe and it
2544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * means the fixed point constants work just fine with the floating point
2554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * API.  The alternative would just lead to undetected errors and spurious
2564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * bug reports.  Negative values fail inside the _fixed API unless they
2574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * correspond to the flag values.
2584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
2594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (output_gamma > 0 && output_gamma < 128)
2604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      output_gamma *= PNG_FP_1;
2614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* This preserves -1 and -2 exactly: */
2634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   output_gamma = floor(output_gamma + .5);
2644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN)
2664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_fixed_error(png_ptr, "gamma value");
2674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return (png_fixed_point)output_gamma;
2694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
2704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  endif
2714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_ALPHA_MODE || READ_GAMMA */
2724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
2744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGFAPI
2754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
2764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_fixed_point output_gamma)
2774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
2784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int compose = 0;
2794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_fixed_point file_gamma;
2804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_set_alpha_mode");
2824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_rtran_ok(png_ptr, 0) == 0)
2844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
2854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/);
2874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Validate the value to ensure it is in a reasonable range. The value
2894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * is expected to be 1 or greater, but this range test allows for some
2904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * viewing correction values.  The intent is to weed out users of this API
2914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * who use the inverse of the gamma value accidentally!  Since some of these
2924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * values are reasonable this may have to be changed:
2934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
2944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 1.6.x: changed from 0.07..3 to 0.01..100 (to accomodate the optimal 16-bit
2954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * gamma of 36, and its reciprocal.)
2964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
2974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (output_gamma < 1000 || output_gamma > 10000000)
2984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_error(png_ptr, "output gamma out of expected range");
2994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* The default file gamma is the inverse of the output gamma; the output
3014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * gamma may be changed below so get the file value first:
3024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
3034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   file_gamma = png_reciprocal(output_gamma);
3044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* There are really 8 possibilities here, composed of any combination
3064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * of:
3074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
3084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    premultiply the color channels
3094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    do not encode non-opaque pixels
3104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    encode the alpha as well as the color channels
3114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
3124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * The differences disappear if the input/output ('screen') gamma is 1.0,
3134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * because then the encoding is a no-op and there is only the choice of
3144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * premultiplying the color channels or not.
3154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
3164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * png_set_alpha_mode and png_set_background interact because both use
3174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * png_compose to do the work.  Calling both is only useful when
3184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along
3194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * with a default gamma value.  Otherwise PNG_COMPOSE must not be set.
3204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
3214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   switch (mode)
3224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
3234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_ALPHA_PNG:        /* default: png standard */
3244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* No compose, but it may be set by png_set_background! */
3254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
3264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
3274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
3284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */
3304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         compose = 1;
3314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
3324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
3334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* The output is linear: */
3344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         output_gamma = PNG_FP_1;
3354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
3364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_ALPHA_OPTIMIZED:  /* associated, non-opaque pixels linear */
3384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         compose = 1;
3394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
3404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA;
3414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* output_gamma records the encoding of opaque pixels! */
3424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
3434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_ALPHA_BROKEN:     /* associated, non-linear, alpha encoded */
3454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         compose = 1;
3464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->transformations |= PNG_ENCODE_ALPHA;
3474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
3484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
3494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      default:
3514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_error(png_ptr, "invalid alpha mode");
3524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
3534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Only set the default gamma if the file gamma has not been set (this has
3554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * the side effect that the gamma in a second call to png_set_alpha_mode will
3564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * be ignored.)
3574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
3584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr->colorspace.gamma == 0)
3594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
3604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->colorspace.gamma = file_gamma;
3614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
3624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
3634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* But always set the output gamma: */
3654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->screen_gamma = output_gamma;
3664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Finally, if pre-multiplying, set the background fields to achieve the
3684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * desired result.
3694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
3704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (compose != 0)
3714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
3724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* And obtain alpha pre-multiplication by composing on black: */
3734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      memset(&png_ptr->background, 0, (sizeof png_ptr->background));
3744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */
3754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE;
3764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
3774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if ((png_ptr->transformations & PNG_COMPOSE) != 0)
3794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_error(png_ptr,
3804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            "conflicting calls to set alpha mode and background");
3814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->transformations |= PNG_COMPOSE;
3834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
3844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
3854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  ifdef PNG_FLOATING_POINT_SUPPORTED
3874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
3884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma)
3894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
3904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr,
3914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      output_gamma));
3924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
3934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  endif
3944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
3954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_QUANTIZE_SUPPORTED
3974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Dither file to 8-bit.  Supply a palette, the current number
3984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * of elements in the palette, the maximum number of elements
3994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * allowed, and a histogram if possible.  If the current number
4004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * of colors is greater than the maximum number, the palette will be
4014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * modified to fit in the maximum number.  "full_quantize" indicates
4024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * whether we need a quantizing cube set up for RGB images, or if we
4034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * simply are reducing the number of colors in a paletted image.
4044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
4054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmanntypedef struct png_dsort_struct
4074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
4084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   struct png_dsort_struct * next;
4094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_byte left;
4104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_byte right;
4114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} png_dsort;
4124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmanntypedef png_dsort *   png_dsortp;
4134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmanntypedef png_dsort * * png_dsortpp;
4144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
4164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_quantize(png_structrp png_ptr, png_colorp palette,
4174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int num_palette, int maximum_colors, png_const_uint_16p histogram,
4184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int full_quantize)
4194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
4204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_set_quantize");
4214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_rtran_ok(png_ptr, 0) == 0)
4234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
4244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->transformations |= PNG_QUANTIZE;
4264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (full_quantize == 0)
4284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
4294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int i;
4304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,
4324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          (png_uint_32)(num_palette * (sizeof (png_byte))));
4334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      for (i = 0; i < num_palette; i++)
4344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->quantize_index[i] = (png_byte)i;
4354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
4364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (num_palette > maximum_colors)
4384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
4394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (histogram != NULL)
4404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
4414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* This is easy enough, just throw out the least used colors.
4424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * Perhaps not the best solution, but good enough.
4434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
4444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         int i;
4464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Initialize an array to sort colors */
4484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,
4494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             (png_uint_32)(num_palette * (sizeof (png_byte))));
4504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Initialize the quantize_sort array */
4524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         for (i = 0; i < num_palette; i++)
4534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->quantize_sort[i] = (png_byte)i;
4544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Find the least used palette entries by starting a
4564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * bubble sort, and running it until we have sorted
4574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * out enough colors.  Note that we don't care about
4584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * sorting all the colors, just finding which are
4594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * least used.
4604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
4614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         for (i = num_palette - 1; i >= maximum_colors; i--)
4634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
4644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int done; /* To stop early if the list is pre-sorted */
4654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int j;
4664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            done = 1;
4684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (j = 0; j < i; j++)
4694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
4704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (histogram[png_ptr->quantize_sort[j]]
4714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   < histogram[png_ptr->quantize_sort[j + 1]])
4724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
4734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_byte t;
4744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  t = png_ptr->quantize_sort[j];
4764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1];
4774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_ptr->quantize_sort[j + 1] = t;
4784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  done = 0;
4794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
4804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
4814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (done != 0)
4834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               break;
4844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
4854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Swap the palette around, and set up a table, if necessary */
4874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (full_quantize != 0)
4884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
4894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int j = num_palette;
4904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* Put all the useful colors within the max, but don't
4924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * move the others.
4934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             */
4944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < maximum_colors; i++)
4954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
4964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
4974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
4984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  do
4994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     j--;
5004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
5014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  palette[i] = palette[j];
5034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
5044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
5054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
5064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else
5074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
5084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int j = num_palette;
5094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* Move all the used colors inside the max limit, and
5114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * develop a translation table.
5124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             */
5134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < maximum_colors; i++)
5144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
5154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               /* Only move the colors we need to */
5164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
5174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
5184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_color tmp_color;
5194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  do
5214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     j--;
5224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
5234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  tmp_color = palette[j];
5254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  palette[j] = palette[i];
5264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  palette[i] = tmp_color;
5274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  /* Indicate where the color went */
5284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_ptr->quantize_index[j] = (png_byte)i;
5294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_ptr->quantize_index[i] = (png_byte)j;
5304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
5314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
5324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* Find closest color for those colors we are not using */
5344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < num_palette; i++)
5354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
5364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if ((int)png_ptr->quantize_index[i] >= maximum_colors)
5374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
5384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  int min_d, k, min_k, d_index;
5394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  /* Find the closest color to one we threw out */
5414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  d_index = png_ptr->quantize_index[i];
5424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
5434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  for (k = 1, min_k = 0; k < maximum_colors; k++)
5444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
5454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     int d;
5464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     d = PNG_COLOR_DIST(palette[d_index], palette[k]);
5484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if (d < min_d)
5504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
5514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        min_d = d;
5524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        min_k = k;
5534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
5544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
5554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  /* Point to closest color */
5564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_ptr->quantize_index[i] = (png_byte)min_k;
5574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
5584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
5594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
5604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_free(png_ptr, png_ptr->quantize_sort);
5614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->quantize_sort = NULL;
5624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
5634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
5644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
5654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* This is much harder to do simply (and quickly).  Perhaps
5664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * we need to go through a median cut routine, but those
5674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * don't always behave themselves with only a few colors
5684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * as input.  So we will just find the closest two colors,
5694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * and throw out one of them (chosen somewhat randomly).
5704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * [We don't understand this at all, so if someone wants to
5714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          *  work on improving it, be our guest - AED, GRP]
5724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
5734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         int i;
5744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         int max_d;
5754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         int num_new_palette;
5764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_dsortp t;
5774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_dsortpp hash;
5784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         t = NULL;
5804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Initialize palette index arrays */
5824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
5834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             (png_uint_32)(num_palette * (sizeof (png_byte))));
5844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
5854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             (png_uint_32)(num_palette * (sizeof (png_byte))));
5864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Initialize the sort array */
5884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         for (i = 0; i < num_palette; i++)
5894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
5904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->index_to_palette[i] = (png_byte)i;
5914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->palette_to_index[i] = (png_byte)i;
5924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
5934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 *
5954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             (sizeof (png_dsortp))));
5964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         num_new_palette = num_palette;
5984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Initial wild guess at how far apart the farthest pixel
6004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * pair we will be eliminating will be.  Larger
6014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * numbers mean more areas will be allocated, Smaller
6024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * numbers run the risk of not saving enough data, and
6034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * having to do this all over again.
6044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          *
6054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * I have not done extensive checking on this number.
6064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
6074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         max_d = 96;
6084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         while (num_new_palette > maximum_colors)
6104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
6114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < num_new_palette - 1; i++)
6124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
6134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               int j;
6144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               for (j = i + 1; j < num_new_palette; j++)
6164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
6174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  int d;
6184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  d = PNG_COLOR_DIST(palette[i], palette[j]);
6204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if (d <= max_d)
6224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
6234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     t = (png_dsortp)png_malloc_warn(png_ptr,
6254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         (png_uint_32)(sizeof (png_dsort)));
6264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if (t == NULL)
6284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         break;
6294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     t->next = hash[d];
6314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     t->left = (png_byte)i;
6324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     t->right = (png_byte)j;
6334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     hash[d] = t;
6344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
6354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
6364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (t == NULL)
6374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  break;
6384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
6394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (t != NULL)
6414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i <= max_d; i++)
6424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
6434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (hash[i] != NULL)
6444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
6454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_dsortp p;
6464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  for (p = hash[i]; p; p = p->next)
6484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
6494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if ((int)png_ptr->index_to_palette[p->left]
6504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         < num_new_palette &&
6514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         (int)png_ptr->index_to_palette[p->right]
6524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         < num_new_palette)
6534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
6544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        int j, next_j;
6554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if (num_new_palette & 0x01)
6574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        {
6584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           j = p->left;
6594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           next_j = p->right;
6604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        }
6614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        else
6624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        {
6634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           j = p->right;
6644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           next_j = p->left;
6654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        }
6664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        num_new_palette--;
6684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        palette[png_ptr->index_to_palette[j]]
6694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            = palette[num_new_palette];
6704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if (full_quantize == 0)
6714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        {
6724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           int k;
6734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           for (k = 0; k < num_palette; k++)
6754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           {
6764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                              if (png_ptr->quantize_index[k] ==
6774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                  png_ptr->index_to_palette[j])
6784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                 png_ptr->quantize_index[k] =
6794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                     png_ptr->index_to_palette[next_j];
6804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                              if ((int)png_ptr->quantize_index[k] ==
6824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                  num_new_palette)
6834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                 png_ptr->quantize_index[k] =
6844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                     png_ptr->index_to_palette[j];
6854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           }
6864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        }
6874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_ptr->index_to_palette[png_ptr->palette_to_index
6894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            [num_new_palette]] = png_ptr->index_to_palette[j];
6904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
6924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            = png_ptr->palette_to_index[num_new_palette];
6934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_ptr->index_to_palette[j] =
6954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            (png_byte)num_new_palette;
6964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_ptr->palette_to_index[num_new_palette] =
6984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            (png_byte)j;
6994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
7004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if (num_new_palette <= maximum_colors)
7014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        break;
7024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
7034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if (num_new_palette <= maximum_colors)
7044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     break;
7054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
7064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
7074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < 769; i++)
7094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
7104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (hash[i] != NULL)
7114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
7124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_dsortp p = hash[i];
7134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  while (p)
7144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
7154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     t = p->next;
7164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_free(png_ptr, p);
7174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     p = t;
7184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
7194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
7204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               hash[i] = 0;
7214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
7224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            max_d += 96;
7234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
7244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_free(png_ptr, hash);
7254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_free(png_ptr, png_ptr->palette_to_index);
7264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_free(png_ptr, png_ptr->index_to_palette);
7274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->palette_to_index = NULL;
7284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->index_to_palette = NULL;
7294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
7304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      num_palette = maximum_colors;
7314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
7324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr->palette == NULL)
7334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
7344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->palette = palette;
7354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
7364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->num_palette = (png_uint_16)num_palette;
7374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (full_quantize != 0)
7394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
7404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int i;
7414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_bytep distance;
7424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS +
7434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          PNG_QUANTIZE_BLUE_BITS;
7444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int num_red = (1 << PNG_QUANTIZE_RED_BITS);
7454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int num_green = (1 << PNG_QUANTIZE_GREEN_BITS);
7464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS);
7474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_size_t num_entries = ((png_size_t)1 << total_bits);
7484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr,
7504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          (png_uint_32)(num_entries * (sizeof (png_byte))));
7514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
7534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          (sizeof (png_byte))));
7544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      memset(distance, 0xff, num_entries * (sizeof (png_byte)));
7564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      for (i = 0; i < num_palette; i++)
7584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
7594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         int ir, ig, ib;
7604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS));
7614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS));
7624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS));
7634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         for (ir = 0; ir < num_red; ir++)
7654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
7664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* int dr = abs(ir - r); */
7674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int dr = ((ir > r) ? ir - r : r - ir);
7684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS +
7694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                PNG_QUANTIZE_GREEN_BITS));
7704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (ig = 0; ig < num_green; ig++)
7724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
7734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               /* int dg = abs(ig - g); */
7744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               int dg = ((ig > g) ? ig - g : g - ig);
7754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               int dt = dr + dg;
7764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               int dm = ((dr > dg) ? dr : dg);
7774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS);
7784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               for (ib = 0; ib < num_blue; ib++)
7804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
7814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  int d_index = index_g | ib;
7824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  /* int db = abs(ib - b); */
7834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  int db = ((ib > b) ? ib - b : b - ib);
7844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  int dmax = ((dm > db) ? dm : db);
7854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  int d = dmax + dt + db;
7864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if (d < (int)distance[d_index])
7884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
7894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     distance[d_index] = (png_byte)d;
7904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_ptr->palette_lookup[d_index] = (png_byte)i;
7914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
7924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
7934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
7944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
7954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
7964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_free(png_ptr, distance);
7984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
7994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
8004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_QUANTIZE */
8014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED
8034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGFAPI
8044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma,
8054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_fixed_point file_gamma)
8064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
8074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_set_gamma_fixed");
8084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_rtran_ok(png_ptr, 0) == 0)
8104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
8114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* New in libpng-1.5.4 - reserve particular negative values as flags. */
8134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/);
8144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/);
8154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Checking the gamma values for being >0 was added in 1.5.4 along with the
8174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * premultiplied alpha support; this actually hides an undocumented feature
8184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * of the previous implementation which allowed gamma processing to be
8194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * disabled in background handling.  There is no evidence (so far) that this
8204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * was being used; however, png_set_background itself accepted and must still
8214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * accept '0' for the gamma value it takes, because it isn't always used.
8224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
8234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * Since this is an API change (albeit a very minor one that removes an
8244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * undocumented API feature) the following checks were only enabled in
8254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * libpng-1.6.0.
8264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
8274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (file_gamma <= 0)
8284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_error(png_ptr, "invalid file gamma in png_set_gamma");
8294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (scrn_gamma <= 0)
8314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_error(png_ptr, "invalid screen gamma in png_set_gamma");
8324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Set the gamma values unconditionally - this overrides the value in the PNG
8344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * file if a gAMA chunk was present.  png_set_alpha_mode provides a
8354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * different, easier, way to default the file gamma.
8364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
8374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->colorspace.gamma = file_gamma;
8384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
8394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->screen_gamma = scrn_gamma;
8404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
8414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  ifdef PNG_FLOATING_POINT_SUPPORTED
8434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
8444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma)
8454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
8464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma),
8474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      convert_gamma_value(png_ptr, file_gamma));
8484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
8494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  endif /* FLOATING_POINT */
8504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_GAMMA */
8514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_EXPAND_SUPPORTED
8534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Expand paletted images to RGB, expand grayscale images of
8544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
8554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * to alpha channels.
8564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
8574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
8584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_expand(png_structrp png_ptr)
8594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
8604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_set_expand");
8614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_rtran_ok(png_ptr, 0) == 0)
8634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
8644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
8664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
8674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* GRR 19990627:  the following three functions currently are identical
8694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  to png_set_expand().  However, it is entirely reasonable that someone
8704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  might wish to expand an indexed image to RGB but *not* expand a single,
8714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  fully transparent palette entry to a full alpha channel--perhaps instead
8724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
8734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  the transparent color with a particular RGB value, or drop tRNS entirely.
8744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  IOW, a future version of the library may make the transformations flag
8754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  a bit more fine-grained, with separate bits for each of these three
8764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  functions.
8774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
8784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  More to the point, these functions make it obvious what libpng will be
8794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  doing, whereas "expand" can (and does) mean any number of things.
8804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
8814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified
8824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  to expand only the sample depth but not to expand the tRNS to alpha
8834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  and its name was changed to png_set_expand_gray_1_2_4_to_8().
8844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
8854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Expand paletted images to RGB. */
8874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
8884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_palette_to_rgb(png_structrp png_ptr)
8894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
8904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_set_palette_to_rgb");
8914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_rtran_ok(png_ptr, 0) == 0)
8934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
8944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
8964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
8974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Expand grayscale images of less than 8-bit depth to 8 bits. */
8994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
9004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_expand_gray_1_2_4_to_8(png_structrp png_ptr)
9014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
9024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_set_expand_gray_1_2_4_to_8");
9034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_rtran_ok(png_ptr, 0) == 0)
9054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
9064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->transformations |= PNG_EXPAND;
9084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
9094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Expand tRNS chunks to alpha channels. */
9114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
9124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_tRNS_to_alpha(png_structrp png_ptr)
9134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
9144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_set_tRNS_to_alpha");
9154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_rtran_ok(png_ptr, 0) == 0)
9174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
9184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
9204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
9214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_EXPAND */
9224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_EXPAND_16_SUPPORTED
9244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise
9254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * it may not work correctly.)
9264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
9274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
9284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_expand_16(png_structrp png_ptr)
9294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
9304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_set_expand_16");
9314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_rtran_ok(png_ptr, 0) == 0)
9334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
9344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS);
9364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
9374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
9384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
9404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
9414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_gray_to_rgb(png_structrp png_ptr)
9424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
9434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_set_gray_to_rgb");
9444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_rtran_ok(png_ptr, 0) == 0)
9464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
9474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Because rgb must be 8 bits or more: */
9494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_set_expand_gray_1_2_4_to_8(png_ptr);
9504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->transformations |= PNG_GRAY_TO_RGB;
9514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
9524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
9534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
9554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGFAPI
9564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
9574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    png_fixed_point red, png_fixed_point green)
9584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
9594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_set_rgb_to_gray");
9604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Need the IHDR here because of the check on color_type below. */
9624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* TODO: fix this */
9634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_rtran_ok(png_ptr, 1) == 0)
9644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
9654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   switch (error_action)
9674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
9684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_ERROR_ACTION_NONE:
9694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->transformations |= PNG_RGB_TO_GRAY;
9704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
9714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_ERROR_ACTION_WARN:
9734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
9744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
9754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_ERROR_ACTION_ERROR:
9774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
9784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
9794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      default:
9814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_error(png_ptr, "invalid error action to rgb_to_gray");
9824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
9834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
9854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_EXPAND_SUPPORTED
9864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->transformations |= PNG_EXPAND;
9874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else
9884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
9894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Make this an error in 1.6 because otherwise the application may assume
9904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * that it just worked and get a memory overwrite.
9914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
9924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_error(png_ptr,
9934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");
9944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */
9964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
9974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
9984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
9994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (red >= 0 && green >= 0 && red + green <= PNG_FP_1)
10004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
10014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_uint_16 red_int, green_int;
10024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* NOTE: this calculation does not round, but this behavior is retained
10044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * for consistency; the inaccuracy is very small.  The code here always
10054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * overwrites the coefficients, regardless of whether they have been
10064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * defaulted or set already.
10074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
10084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         red_int = (png_uint_16)(((png_uint_32)red*32768)/100000);
10094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         green_int = (png_uint_16)(((png_uint_32)green*32768)/100000);
10104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->rgb_to_gray_red_coeff   = red_int;
10124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->rgb_to_gray_green_coeff = green_int;
10134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->rgb_to_gray_coefficients_set = 1;
10144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
10154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
10174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
10184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (red >= 0 && green >= 0)
10194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_app_warning(png_ptr,
10204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               "ignoring out of range rgb_to_gray coefficients");
10214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Use the defaults, from the cHRM chunk if set, else the historical
10234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * values which are close to the sRGB/HDTV/ITU-Rec 709 values.  See
10244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * png_do_rgb_to_gray for more discussion of the values.  In this case
10254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * the coefficients are not marked as 'set' and are not overwritten if
10264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * something has already provided a default.
10274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
10284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (png_ptr->rgb_to_gray_red_coeff == 0 &&
10294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->rgb_to_gray_green_coeff == 0)
10304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
10314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->rgb_to_gray_red_coeff   = 6968;
10324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->rgb_to_gray_green_coeff = 23434;
10334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* png_ptr->rgb_to_gray_blue_coeff  = 2366; */
10344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
10354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
10364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
10374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
10384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_FLOATING_POINT_SUPPORTED
10404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Convert a RGB image to a grayscale of the same width.  This allows us,
10414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
10424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
10434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
10454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red,
10464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   double green)
10474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
10484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_set_rgb_to_gray_fixed(png_ptr, error_action,
10494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_fixed(png_ptr, red, "rgb to gray red coefficient"),
10504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_fixed(png_ptr, green, "rgb to gray green coefficient"));
10514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
10524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* FLOATING POINT */
10534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* RGB_TO_GRAY */
10554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
10574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
10584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
10594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr
10604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    read_user_transform_fn)
10614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
10624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_set_read_user_transform_fn");
10634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
10654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->transformations |= PNG_USER_TRANSFORM;
10664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->read_user_transform_fn = read_user_transform_fn;
10674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
10684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
10694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
10704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_TRANSFORMS_SUPPORTED
10724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED
10734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* In the case of gamma transformations only do transformations on images where
10744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the [file] gamma and screen_gamma are not close reciprocals, otherwise it
10754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * slows things down slightly, and also needlessly introduces small errors.
10764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
10774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int /* PRIVATE */
10784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma)
10794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
10804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma
10814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * correction as a difference of the overall transform from 1.0
10824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
10834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * We want to compare the threshold with s*f - 1, if we get
10844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * overflow here it is because of wacky gamma values so we
10854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * turn on processing anyway.
10864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
10874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_fixed_point gtest;
10884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return !png_muldiv(&gtest, screen_gamma, file_gamma, PNG_FP_1) ||
10894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       png_gamma_significant(gtest);
10904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
10914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
10924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Initialize everything needed for the read.  This includes modifying
10944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the palette.
10954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
10964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* For the moment 'png_init_palette_transformations' and
10984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 'png_init_rgb_transformations' only do some flag canceling optimizations.
10994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * The intent is that these two routines should have palette or rgb operations
11004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * extracted from 'png_init_read_transformations'.
11014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
11024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void /* PRIVATE */
11034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_init_palette_transformations(png_structrp png_ptr)
11044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
11054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Called to handle the (input) palette case.  In png_do_read_transformations
11064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * the first step is to expand the palette if requested, so this code must
11074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * take care to only make changes that are invariant with respect to the
11084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * palette expansion, or only do them if there is no expansion.
11094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
11104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * STRIP_ALPHA has already been handled in the caller (by setting num_trans
11114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * to 0.)
11124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
11134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int input_has_alpha = 0;
11144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int input_has_transparency = 0;
11154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr->num_trans > 0)
11174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
11184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int i;
11194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Ignore if all the entries are opaque (unlikely!) */
11214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      for (i=0; i<png_ptr->num_trans; ++i)
11224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
11234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (png_ptr->trans_alpha[i] == 255)
11244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            continue;
11254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else if (png_ptr->trans_alpha[i] == 0)
11264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            input_has_transparency = 1;
11274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else
11284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
11294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            input_has_transparency = 1;
11304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            input_has_alpha = 1;
11314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            break;
11324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
11334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
11344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
11354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* If no alpha we can optimize. */
11374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (input_has_alpha == 0)
11384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
11394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Any alpha means background and associative alpha processing is
11404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA
11414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * and ENCODE_ALPHA are irrelevant.
11424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
11434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
11444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
11454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (input_has_transparency == 0)
11474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
11484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
11494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
11514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* png_set_background handling - deals with the complexity of whether the
11524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * background color is in the file format or the screen format in the case
11534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * where an 'expand' will happen.
11544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
11554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* The following code cannot be entered in the alpha pre-multiplication case
11574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * because PNG_BACKGROUND_EXPAND is cancelled below.
11584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
11594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 &&
11604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (png_ptr->transformations & PNG_EXPAND) != 0)
11614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
11624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
11634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->background.red   =
11644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             png_ptr->palette[png_ptr->background.index].red;
11654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->background.green =
11664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             png_ptr->palette[png_ptr->background.index].green;
11674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->background.blue  =
11684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             png_ptr->palette[png_ptr->background.index].blue;
11694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
11714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
11724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        {
11734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann           if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0)
11744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann           {
11754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann              /* Invert the alpha channel (in tRNS) unless the pixels are
11764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               * going to be expanded, in which case leave it for later
11774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               */
11784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann              int i, istop = png_ptr->num_trans;
11794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann              for (i=0; i<istop; i++)
11814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                 png_ptr->trans_alpha[i] = (png_byte)(255 -
11824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    png_ptr->trans_alpha[i]);
11834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann           }
11844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
11854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_INVERT_ALPHA */
11864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
11874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   } /* background expand and (therefore) no alpha association. */
11884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_EXPAND && READ_BACKGROUND */
11894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
11904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void /* PRIVATE */
11924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_init_rgb_transformations(png_structrp png_ptr)
11934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
11944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Added to libpng-1.5.4: check the color type to determine whether there
11954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * is any alpha or transparency in the image and simply cancel the
11964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * background and alpha mode stuff if there isn't.
11974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
11984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0;
11994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int input_has_transparency = png_ptr->num_trans > 0;
12004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* If no alpha we can optimize. */
12024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (input_has_alpha == 0)
12034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
12044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Any alpha means background and associative alpha processing is
12054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA
12064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * and ENCODE_ALPHA are irrelevant.
12074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
12084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     ifdef PNG_READ_ALPHA_MODE_SUPPORTED
12094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
12104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
12114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     endif
12124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (input_has_transparency == 0)
12144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
12154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
12164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
12184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* png_set_background handling - deals with the complexity of whether the
12194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * background color is in the file format or the screen format in the case
12204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * where an 'expand' will happen.
12214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
12224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* The following code cannot be entered in the alpha pre-multiplication case
12244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * because PNG_BACKGROUND_EXPAND is cancelled below.
12254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
12264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 &&
12274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (png_ptr->transformations & PNG_EXPAND) != 0 &&
12284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
12294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       /* i.e., GRAY or GRAY_ALPHA */
12304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
12314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
12324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Expand background and tRNS chunks */
12334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         int gray = png_ptr->background.gray;
12344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         int trans_gray = png_ptr->trans_color.gray;
12354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         switch (png_ptr->bit_depth)
12374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
12384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            case 1:
12394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               gray *= 0xff;
12404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               trans_gray *= 0xff;
12414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               break;
12424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            case 2:
12444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               gray *= 0x55;
12454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               trans_gray *= 0x55;
12464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               break;
12474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            case 4:
12494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               gray *= 0x11;
12504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               trans_gray *= 0x11;
12514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               break;
12524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            default:
12544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            case 8:
12564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               /* FALL THROUGH (Already 8 bits) */
12574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            case 16:
12594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               /* Already a full 16 bits */
12604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               break;
12614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
12624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->background.red = png_ptr->background.green =
12644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->background.blue = (png_uint_16)gray;
12654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0)
12674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
12684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->trans_color.red = png_ptr->trans_color.green =
12694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               png_ptr->trans_color.blue = (png_uint_16)trans_gray;
12704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
12714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
12724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   } /* background expand and (therefore) no alpha association. */
12734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_EXPAND && READ_BACKGROUND */
12744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
12754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */
12774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_init_read_transformations(png_structrp png_ptr)
12784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
12794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_init_read_transformations");
12804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* This internal function is called from png_read_start_row in pngrutil.c
12824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * and it is called before the 'rowbytes' calculation is done, so the code
12834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * in here can change or update the transformations flags.
12844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
12854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * First do updates that do not depend on the details of the PNG image data
12864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * being processed.
12874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
12884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED
12904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds
12914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * png_set_alpha_mode and this is another source for a default file gamma so
12924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * the test needs to be performed later - here.  In addition prior to 1.5.4
12934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * the tests were repeated for the PALETTE color type here - this is no
12944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * longer necessary (and doesn't seem to have been necessary before.)
12954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
12964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
12974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* The following temporary indicates if overall gamma correction is
12984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * required.
12994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
13004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int gamma_correction = 0;
13014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
13024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (png_ptr->colorspace.gamma != 0) /* has been set */
13034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
13044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (png_ptr->screen_gamma != 0) /* screen set too */
13054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma,
13064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               png_ptr->screen_gamma);
13074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
13084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else
13094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* Assume the output matches the input; a long time default behavior
13104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * of libpng, although the standard has nothing to say about this.
13114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             */
13124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->screen_gamma = png_reciprocal(png_ptr->colorspace.gamma);
13134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
13144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
13154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else if (png_ptr->screen_gamma != 0)
13164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* The converse - assume the file matches the screen, note that this
13174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * perhaps undesireable default can (from 1.5.4) be changed by calling
13184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * png_set_alpha_mode (even if the alpha handling mode isn't required
13194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * or isn't changed from the default.)
13204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
13214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->colorspace.gamma = png_reciprocal(png_ptr->screen_gamma);
13224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
13234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else /* neither are set */
13244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Just in case the following prevents any processing - file and screen
13254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * are both assumed to be linear and there is no way to introduce a
13264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * third gamma value other than png_set_background with 'UNIQUE', and,
13274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * prior to 1.5.4
13284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
13294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->screen_gamma = png_ptr->colorspace.gamma = PNG_FP_1;
13304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
13314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* We have a gamma value now. */
13324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
13334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
13344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Now turn the gamma transformation on or off as appropriate.  Notice
13354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * that PNG_GAMMA just refers to the file->screen correction.  Alpha
13364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * composition may independently cause gamma correction because it needs
13374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * linear data (e.g. if the file has a gAMA chunk but the screen gamma
13384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * hasn't been specified.)  In any case this flag may get turned off in
13394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * the code immediately below if the transform can be handled outside the
13404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * row loop.
13414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
13424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (gamma_correction != 0)
13434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->transformations |= PNG_GAMMA;
13444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
13454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
13464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->transformations &= ~PNG_GAMMA;
13474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
13484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
13494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
13504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Certain transformations have the effect of preventing other
13514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * transformations that happen afterward in png_do_read_transformations;
13524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * resolve the interdependencies here.  From the code of
13534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * png_do_read_transformations the order is:
13544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *  1) PNG_EXPAND (including PNG_EXPAND_tRNS)
13564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *  2) PNG_STRIP_ALPHA (if no compose)
13574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *  3) PNG_RGB_TO_GRAY
13584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *  4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY
13594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *  5) PNG_COMPOSE
13604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *  6) PNG_GAMMA
13614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *  7) PNG_STRIP_ALPHA (if compose)
13624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *  8) PNG_ENCODE_ALPHA
13634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *  9) PNG_SCALE_16_TO_8
13644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 10) PNG_16_TO_8
13654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 11) PNG_QUANTIZE (converts to palette)
13664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 12) PNG_EXPAND_16
13674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY
13684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 14) PNG_INVERT_MONO
13694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 15) PNG_INVERT_ALPHA
13704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 16) PNG_SHIFT
13714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 17) PNG_PACK
13724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 18) PNG_BGR
13734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 19) PNG_PACKSWAP
13744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 20) PNG_FILLER (includes PNG_ADD_ALPHA)
13754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 21) PNG_SWAP_ALPHA
13764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 22) PNG_SWAP_BYTES
13774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 23) PNG_USER_TRANSFORM [must be last]
13784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
13794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
13804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
13814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (png_ptr->transformations & PNG_COMPOSE) == 0)
13824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
13834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Stripping the alpha channel happens immediately after the 'expand'
13844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * transformations, before all other transformation, so it cancels out
13854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * the alpha handling.  It has the side effect negating the effect of
13864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * PNG_EXPAND_tRNS too:
13874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
13884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA |
13894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         PNG_EXPAND_tRNS);
13904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
13914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
13924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Kill the tRNS chunk itself too.  Prior to 1.5.4 this did not happen
13934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * so transparency information would remain just so long as it wasn't
13944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * expanded.  This produces unexpected API changes if the set of things
13954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * that do PNG_EXPAND_tRNS changes (perfectly possible given the
13964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * documentation - which says ask for what you want, accept what you
13974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * get.)  This makes the behavior consistent from 1.5.4:
13984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
13994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->num_trans = 0;
14004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
14014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* STRIP_ALPHA supported, no COMPOSE */
14024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
14034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
14044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA
14054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * settings will have no effect.
14064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
14074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_gamma_significant(png_ptr->screen_gamma) == 0)
14084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
14094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
14104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
14114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
14124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
14134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
14144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
14154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Make sure the coefficients for the rgb to gray conversion are set
14164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * appropriately.
14174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
14184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
14194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_colorspace_set_rgb_coefficients(png_ptr);
14204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
14214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
14224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
14234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
14244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Detect gray background and attempt to enable optimization for
14254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * gray --> RGB case.
14264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
14274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * Note:  if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
14284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * RGB_ALPHA (in which case need_expand is superfluous anyway), the
14294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * background color might actually be gray yet not be flagged as such.
14304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * This is not a problem for the current code, which uses
14314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * PNG_BACKGROUND_IS_GRAY only to decide when to do the
14324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * png_do_gray_to_rgb() transformation.
14334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
14344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * TODO: this code needs to be revised to avoid the complexity and
14354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * interdependencies.  The color type of the background should be recorded in
14364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * png_set_background, along with the bit depth, then the code has a record
14374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * of exactly what color space the background is currently in.
14384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
14394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0)
14404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
14414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if
14424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * the file was grayscale the background value is gray.
14434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
14444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
14454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
14464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
14474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
14484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else if ((png_ptr->transformations & PNG_COMPOSE) != 0)
14494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
14504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* PNG_COMPOSE: png_set_background was called with need_expand false,
14514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * so the color is in the color space of the output or png_set_alpha_mode
14524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * was called and the color is black.  Ignore RGB_TO_GRAY because that
14534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * happens before GRAY_TO_RGB.
14544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
14554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)
14564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
14574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (png_ptr->background.red == png_ptr->background.green &&
14584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             png_ptr->background.red == png_ptr->background.blue)
14594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
14604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
14614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->background.gray = png_ptr->background.red;
14624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
14634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
14644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
14654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_EXPAND && READ_BACKGROUND */
14664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_GRAY_TO_RGB */
14674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
14684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations
14694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * can be performed directly on the palette, and some (such as rgb to gray)
14704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * can be optimized inside the palette.  This is particularly true of the
14714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * composite (background and alpha) stuff, which can be pretty much all done
14724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * in the palette even if the result is expanded to RGB or gray afterward.
14734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
14744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and
14754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * earlier and the palette stuff is actually handled on the first row.  This
14764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * leads to the reported bug that the palette returned by png_get_PLTE is not
14774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * updated.
14784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
14794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
14804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_init_palette_transformations(png_ptr);
14814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
14824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else
14834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_init_rgb_transformations(png_ptr);
14844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
14854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
14864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   defined(PNG_READ_EXPAND_16_SUPPORTED)
14874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_EXPAND_16) != 0 &&
14884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (png_ptr->transformations & PNG_COMPOSE) != 0 &&
14894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 &&
14904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       png_ptr->bit_depth != 16)
14914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
14924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* TODO: fix this.  Because the expand_16 operation is after the compose
14934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * handling the background color must be 8, not 16, bits deep, but the
14944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * application will supply a 16-bit value so reduce it here.
14954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       *
14964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at
14974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * present, so that case is ok (until do_expand_16 is moved.)
14984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       *
14994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * NOTE: this discards the low 16 bits of the user supplied background
15004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * color, but until expand_16 works properly there is no choice!
15014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
15024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x))
15034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      CHOP(png_ptr->background.red);
15044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      CHOP(png_ptr->background.green);
15054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      CHOP(png_ptr->background.blue);
15064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      CHOP(png_ptr->background.gray);
15074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     undef CHOP
15084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
15094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_BACKGROUND && READ_EXPAND_16 */
15104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
15114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
15124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \
15134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   defined(PNG_READ_STRIP_16_TO_8_SUPPORTED))
15144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) != 0 &&
15154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (png_ptr->transformations & PNG_COMPOSE) != 0 &&
15164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 &&
15174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       png_ptr->bit_depth == 16)
15184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
15194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* On the other hand, if a 16-bit file is to be reduced to 8-bits per
15204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * component this will also happen after PNG_COMPOSE and so the background
15214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * color must be pre-expanded here.
15224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       *
15234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * TODO: fix this too.
15244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
15254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257);
15264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->background.green =
15274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         (png_uint_16)(png_ptr->background.green * 257);
15284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257);
15294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257);
15304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
15314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
15324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
15334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the
15344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * background support (see the comments in scripts/pnglibconf.dfa), this
15354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * allows pre-multiplication of the alpha channel to be implemented as
15364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * compositing on black.  This is probably sub-optimal and has been done in
15374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 1.5.4 betas simply to enable external critique and testing (i.e. to
15384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * implement the new API quickly, without lots of internal changes.)
15394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
15404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
15414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED
15424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  ifdef PNG_READ_BACKGROUND_SUPPORTED
15434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Includes ALPHA_MODE */
15444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->background_1 = png_ptr->background;
15454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  endif
15464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
15474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* This needs to change - in the palette image case a whole set of tables are
15484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * built when it would be quicker to just calculate the correct value for
15494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * each palette entry directly.  Also, the test is too tricky - why check
15504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * PNG_RGB_TO_GRAY if PNG_GAMMA is not set?  The answer seems to be that
15514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * PNG_GAMMA is cancelled even if the gamma is known?  The test excludes the
15524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * PNG_COMPOSE case, so apparently if there is no *overall* gamma correction
15534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * the gamma tables will not be built even if composition is required on a
15544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * gamma encoded value.
15554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
15564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * In 1.5.4 this is addressed below by an additional check on the individual
15574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the
15584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * tables.
15594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
15604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_GAMMA) != 0 ||
15614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0 &&
15624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        (png_gamma_significant(png_ptr->colorspace.gamma) != 0 ||
15634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_gamma_significant(png_ptr->screen_gamma) != 0)) ||
15644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        ((png_ptr->transformations & PNG_COMPOSE) != 0 &&
15654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         (png_gamma_significant(png_ptr->colorspace.gamma) != 0 ||
15664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          png_gamma_significant(png_ptr->screen_gamma) != 0
15674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  ifdef PNG_READ_BACKGROUND_SUPPORTED
15684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE &&
15694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann           png_gamma_significant(png_ptr->background_gamma) != 0)
15704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  endif
15714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 &&
15724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       png_gamma_significant(png_ptr->screen_gamma) != 0))
15734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
15744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_build_gamma_table(png_ptr, png_ptr->bit_depth);
15754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
15764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_BACKGROUND_SUPPORTED
15774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if ((png_ptr->transformations & PNG_COMPOSE) != 0)
15784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
15794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Issue a warning about this combination: because RGB_TO_GRAY is
15804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * optimized to do the gamma transform if present yet do_background has
15814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * to do the same thing if both options are set a
15824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * double-gamma-correction happens.  This is true in all versions of
15834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * libpng to date.
15844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
15854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
15864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_warning(png_ptr,
15874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               "libpng does not support gamma+background+rgb_to_gray");
15884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
15894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if ((png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) != 0)
15904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
15914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* We don't get to here unless there is a tRNS chunk with non-opaque
15924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * entries - see the checking code at the start of this function.
15934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             */
15944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_color back, back_1;
15954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_colorp palette = png_ptr->palette;
15964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int num_palette = png_ptr->num_palette;
15974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int i;
15984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
15994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
16004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               back.red = png_ptr->gamma_table[png_ptr->background.red];
16024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               back.green = png_ptr->gamma_table[png_ptr->background.green];
16034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               back.blue = png_ptr->gamma_table[png_ptr->background.blue];
16044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
16064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
16074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
16084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
16094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            else
16104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
16114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               png_fixed_point g, gs;
16124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               switch (png_ptr->background_gamma_type)
16144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
16154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  case PNG_BACKGROUND_GAMMA_SCREEN:
16164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     g = (png_ptr->screen_gamma);
16174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     gs = PNG_FP_1;
16184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     break;
16194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  case PNG_BACKGROUND_GAMMA_FILE:
16214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     g = png_reciprocal(png_ptr->colorspace.gamma);
16224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     gs = png_reciprocal2(png_ptr->colorspace.gamma,
16234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_ptr->screen_gamma);
16244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     break;
16254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  case PNG_BACKGROUND_GAMMA_UNIQUE:
16274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     g = png_reciprocal(png_ptr->background_gamma);
16284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     gs = png_reciprocal2(png_ptr->background_gamma,
16294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_ptr->screen_gamma);
16304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     break;
16314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  default:
16324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     g = PNG_FP_1;    /* back_1 */
16334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     gs = PNG_FP_1;   /* back */
16344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     break;
16354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
16364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (png_gamma_significant(gs) != 0)
16384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
16394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  back.red = png_gamma_8bit_correct(png_ptr->background.red,
16404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      gs);
16414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  back.green = png_gamma_8bit_correct(png_ptr->background.green,
16424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      gs);
16434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  back.blue = png_gamma_8bit_correct(png_ptr->background.blue,
16444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      gs);
16454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
16464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               else
16484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
16494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  back.red   = (png_byte)png_ptr->background.red;
16504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  back.green = (png_byte)png_ptr->background.green;
16514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  back.blue  = (png_byte)png_ptr->background.blue;
16524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
16534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (png_gamma_significant(g) != 0)
16554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
16564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  back_1.red = png_gamma_8bit_correct(png_ptr->background.red,
16574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     g);
16584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  back_1.green = png_gamma_8bit_correct(
16594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_ptr->background.green, g);
16604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue,
16614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     g);
16624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
16634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               else
16654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
16664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  back_1.red   = (png_byte)png_ptr->background.red;
16674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  back_1.green = (png_byte)png_ptr->background.green;
16684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  back_1.blue  = (png_byte)png_ptr->background.blue;
16694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
16704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
16714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < num_palette; i++)
16734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
16744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (i < (int)png_ptr->num_trans &&
16754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   png_ptr->trans_alpha[i] != 0xff)
16764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
16774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if (png_ptr->trans_alpha[i] == 0)
16784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
16794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     palette[i] = back;
16804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
16814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  else /* if (png_ptr->trans_alpha[i] != 0xff) */
16824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
16834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_byte v, w;
16844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     v = png_ptr->gamma_to_1[palette[i].red];
16864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_composite(w, v, png_ptr->trans_alpha[i], back_1.red);
16874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     palette[i].red = png_ptr->gamma_from_1[w];
16884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     v = png_ptr->gamma_to_1[palette[i].green];
16904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_composite(w, v, png_ptr->trans_alpha[i], back_1.green);
16914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     palette[i].green = png_ptr->gamma_from_1[w];
16924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     v = png_ptr->gamma_to_1[palette[i].blue];
16944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue);
16954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     palette[i].blue = png_ptr->gamma_from_1[w];
16964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
16974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
16984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               else
16994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
17004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  palette[i].red = png_ptr->gamma_table[palette[i].red];
17014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  palette[i].green = png_ptr->gamma_table[palette[i].green];
17024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  palette[i].blue = png_ptr->gamma_table[palette[i].blue];
17034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
17044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
17054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* Prevent the transformations being done again.
17074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             *
17084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * NOTE: this is highly dubious; it removes the transformations in
17094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * place.  This seems inconsistent with the general treatment of the
17104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * transformations elsewhere.
17114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             */
17124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA);
17134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         } /* color_type == PNG_COLOR_TYPE_PALETTE */
17144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
17164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else /* color_type != PNG_COLOR_TYPE_PALETTE */
17174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
17184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int gs_sig, g_sig;
17194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_fixed_point g = PNG_FP_1;  /* Correction to linear */
17204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_fixed_point gs = PNG_FP_1; /* Correction to screen */
17214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            switch (png_ptr->background_gamma_type)
17234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
17244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               case PNG_BACKGROUND_GAMMA_SCREEN:
17254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  g = png_ptr->screen_gamma;
17264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  /* gs = PNG_FP_1; */
17274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  break;
17284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               case PNG_BACKGROUND_GAMMA_FILE:
17304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  g = png_reciprocal(png_ptr->colorspace.gamma);
17314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  gs = png_reciprocal2(png_ptr->colorspace.gamma,
17324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_ptr->screen_gamma);
17334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  break;
17344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               case PNG_BACKGROUND_GAMMA_UNIQUE:
17364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  g = png_reciprocal(png_ptr->background_gamma);
17374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  gs = png_reciprocal2(png_ptr->background_gamma,
17384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      png_ptr->screen_gamma);
17394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  break;
17404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               default:
17424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_error(png_ptr, "invalid background gamma type");
17434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
17444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            g_sig = png_gamma_significant(g);
17464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            gs_sig = png_gamma_significant(gs);
17474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (g_sig != 0)
17494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               png_ptr->background_1.gray = png_gamma_correct(png_ptr,
17504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   png_ptr->background.gray, g);
17514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (gs_sig != 0)
17534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               png_ptr->background.gray = png_gamma_correct(png_ptr,
17544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   png_ptr->background.gray, gs);
17554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if ((png_ptr->background.red != png_ptr->background.green) ||
17574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                (png_ptr->background.red != png_ptr->background.blue) ||
17584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                (png_ptr->background.red != png_ptr->background.gray))
17594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
17604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               /* RGB or RGBA with color background */
17614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (g_sig != 0)
17624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
17634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_ptr->background_1.red = png_gamma_correct(png_ptr,
17644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      png_ptr->background.red, g);
17654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_ptr->background_1.green = png_gamma_correct(png_ptr,
17674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      png_ptr->background.green, g);
17684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_ptr->background_1.blue = png_gamma_correct(png_ptr,
17704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      png_ptr->background.blue, g);
17714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
17724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (gs_sig != 0)
17744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
17754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_ptr->background.red = png_gamma_correct(png_ptr,
17764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      png_ptr->background.red, gs);
17774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_ptr->background.green = png_gamma_correct(png_ptr,
17794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      png_ptr->background.green, gs);
17804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_ptr->background.blue = png_gamma_correct(png_ptr,
17824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      png_ptr->background.blue, gs);
17834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
17844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
17854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            else
17874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
17884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
17894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               png_ptr->background_1.red = png_ptr->background_1.green
17904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   = png_ptr->background_1.blue = png_ptr->background_1.gray;
17914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               png_ptr->background.red = png_ptr->background.green
17934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   = png_ptr->background.blue = png_ptr->background.gray;
17944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
17954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* The background is now in screen gamma: */
17974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN;
17984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         } /* color_type != PNG_COLOR_TYPE_PALETTE */
17994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }/* png_ptr->transformations & PNG_BACKGROUND */
18004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
18024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Transformation does not include PNG_BACKGROUND */
18034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_BACKGROUND */
18044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE
18054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
18064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* RGB_TO_GRAY needs to have non-gamma-corrected values! */
18074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         && ((png_ptr->transformations & PNG_EXPAND) == 0 ||
18084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0)
18094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
18104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         )
18114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
18124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_colorp palette = png_ptr->palette;
18134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         int num_palette = png_ptr->num_palette;
18144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         int i;
18154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* NOTE: there are other transformations that should probably be in
18174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * here too.
18184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
18194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         for (i = 0; i < num_palette; i++)
18204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
18214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            palette[i].red = png_ptr->gamma_table[palette[i].red];
18224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            palette[i].green = png_ptr->gamma_table[palette[i].green];
18234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            palette[i].blue = png_ptr->gamma_table[palette[i].blue];
18244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
18254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Done the gamma correction. */
18274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->transformations &= ~PNG_GAMMA;
18284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      } /* color_type == PALETTE && !PNG_BACKGROUND transformation */
18294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
18304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_BACKGROUND_SUPPORTED
18314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else
18324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
18334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_GAMMA */
18344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_BACKGROUND_SUPPORTED
18364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* No GAMMA transformation (see the hanging else 4 lines above) */
18374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_COMPOSE) != 0 &&
18384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
18394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
18404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int i;
18414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int istop = (int)png_ptr->num_trans;
18424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_color back;
18434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_colorp palette = png_ptr->palette;
18444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      back.red   = (png_byte)png_ptr->background.red;
18464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      back.green = (png_byte)png_ptr->background.green;
18474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      back.blue  = (png_byte)png_ptr->background.blue;
18484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      for (i = 0; i < istop; i++)
18504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
18514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (png_ptr->trans_alpha[i] == 0)
18524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
18534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            palette[i] = back;
18544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
18554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else if (png_ptr->trans_alpha[i] != 0xff)
18574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
18584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* The png_composite() macro is defined in png.h */
18594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_composite(palette[i].red, palette[i].red,
18604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                png_ptr->trans_alpha[i], back.red);
18614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_composite(palette[i].green, palette[i].green,
18634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                png_ptr->trans_alpha[i], back.green);
18644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_composite(palette[i].blue, palette[i].blue,
18664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                png_ptr->trans_alpha[i], back.blue);
18674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
18684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
18694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->transformations &= ~PNG_COMPOSE;
18714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
18724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_BACKGROUND */
18734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_SHIFT_SUPPORTED
18754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_SHIFT) != 0 &&
18764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (png_ptr->transformations & PNG_EXPAND) == 0 &&
18774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
18784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
18794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int i;
18804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int istop = png_ptr->num_palette;
18814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int shift = 8 - png_ptr->sig_bit.red;
18824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->transformations &= ~PNG_SHIFT;
18844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* significant bits can be in the range 1 to 7 for a meaninful result, if
18864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * the number of significant bits is 0 then no shift is done (this is an
18874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * error condition which is silently ignored.)
18884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
18894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (shift > 0 && shift < 8)
18904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         for (i=0; i<istop; ++i)
18914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
18924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int component = png_ptr->palette[i].red;
18934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            component >>= shift;
18954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->palette[i].red = (png_byte)component;
18964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
18974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      shift = 8 - png_ptr->sig_bit.green;
18994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (shift > 0 && shift < 8)
19004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         for (i=0; i<istop; ++i)
19014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
19024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int component = png_ptr->palette[i].green;
19034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            component >>= shift;
19054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->palette[i].green = (png_byte)component;
19064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
19074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      shift = 8 - png_ptr->sig_bit.blue;
19094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (shift > 0 && shift < 8)
19104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         for (i=0; i<istop; ++i)
19114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
19124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int component = png_ptr->palette[i].blue;
19134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            component >>= shift;
19154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->palette[i].blue = (png_byte)component;
19164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
19174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
19184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_SHIFT */
19194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
19204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Modify the info structure to reflect the transformations.  The
19224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * info should be updated so a PNG file could be written with it,
19234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * assuming the transformations result in valid PNG data.
19244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
19254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */
19264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)
19274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
19284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_read_transform_info");
19294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_EXPAND_SUPPORTED
19314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_EXPAND) != 0)
19324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
19334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
19344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
19354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* This check must match what actually happens in
19364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * png_do_expand_palette; if it ever checks the tRNS chunk to see if
19374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * it is all opaque we must do the same (at present it does not.)
19384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
19394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (png_ptr->num_trans > 0)
19404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
19414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else
19434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            info_ptr->color_type = PNG_COLOR_TYPE_RGB;
19444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->bit_depth = 8;
19464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->num_trans = 0;
19474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (png_ptr->palette == NULL)
19494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_error (png_ptr, "Palette is NULL in indexed image");
19504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
19514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
19524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
19534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (png_ptr->num_trans != 0)
19544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
19554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if ((png_ptr->transformations & PNG_EXPAND_tRNS) != 0)
19564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
19574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
19584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (info_ptr->bit_depth < 8)
19594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            info_ptr->bit_depth = 8;
19604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->num_trans = 0;
19624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
19634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
19644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
19654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
19674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
19684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* The following is almost certainly wrong unless the background value is in
19694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * the screen space!
19704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
19714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_COMPOSE) != 0)
19724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->background = png_ptr->background;
19734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
19744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED
19764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* The following used to be conditional on PNG_GAMMA (prior to 1.5.4),
19774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * however it seems that the code in png_init_read_transformations, which has
19784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * been called before this from png_read_update_info->png_read_start_row
19794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * sometimes does the gamma transform and cancels the flag.
19804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
19814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * TODO: this looks wrong; the info_ptr should end up with a gamma equal to
19824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * the screen_gamma value.  The following probably results in weirdness if
19834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * the info_ptr is used by the app after the rows have been read.
19844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
19854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   info_ptr->colorspace.gamma = png_ptr->colorspace.gamma;
19864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
19874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (info_ptr->bit_depth == 16)
19894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
19904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  ifdef PNG_READ_16BIT_SUPPORTED
19914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
19924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0)
19934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            info_ptr->bit_depth = 8;
19944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     endif
19954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
19974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if ((png_ptr->transformations & PNG_16_TO_8) != 0)
19984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            info_ptr->bit_depth = 8;
19994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     endif
20004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  else
20024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* No 16-bit support: force chopping 16-bit input down to 8, in this case
20034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * the app program can chose if both APIs are available by setting the
20044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * correct scaling to use.
20054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
20064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
20074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* For compatibility with previous versions use the strip method by
20084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * default.  This code works because if PNG_SCALE_16_TO_8 is already
20094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * set the code below will do that in preference to the chop.
20104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
20114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->transformations |= PNG_16_TO_8;
20124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->bit_depth = 8;
20134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     else
20144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#        ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
20164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->transformations |= PNG_SCALE_16_TO_8;
20174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            info_ptr->bit_depth = 8;
20184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#        else
20194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            CONFIGURATION ERROR: you must enable at least one 16 to 8 method
20214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#        endif
20224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#    endif
20234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* !READ_16BIT */
20244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
20254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
20274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)
20284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->color_type = (png_byte)(info_ptr->color_type |
20294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         PNG_COLOR_MASK_COLOR);
20304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
20314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
20334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
20344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->color_type = (png_byte)(info_ptr->color_type &
20354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         ~PNG_COLOR_MASK_COLOR);
20364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
20374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_QUANTIZE_SUPPORTED
20394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_QUANTIZE) != 0)
20404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
20414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
20424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
20434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          png_ptr->palette_lookup != 0 && info_ptr->bit_depth == 8)
20444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
20454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
20464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
20474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
20484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
20494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_EXPAND_16_SUPPORTED
20514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_EXPAND_16) != 0 &&
20524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       info_ptr->bit_depth == 8 &&
20534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       info_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
20544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
20554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->bit_depth = 16;
20564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
20574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
20584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_PACK_SUPPORTED
20604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_PACK) != 0 &&
20614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (info_ptr->bit_depth < 8))
20624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->bit_depth = 8;
20634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
20644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
20664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->channels = 1;
20674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
20694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->channels = 3;
20704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else
20724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->channels = 1;
20734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
20754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0)
20764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
20774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->color_type = (png_byte)(info_ptr->color_type &
20784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         ~PNG_COLOR_MASK_ALPHA);
20794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->num_trans = 0;
20804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
20814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
20824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
20844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->channels++;
20854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_FILLER_SUPPORTED
20874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* STRIP_ALPHA and FILLER allowed:  MASK_ALPHA bit stripped above */
20884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_FILLER) != 0 &&
20894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (info_ptr->color_type == PNG_COLOR_TYPE_RGB ||
20904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       info_ptr->color_type == PNG_COLOR_TYPE_GRAY))
20914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
20924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->channels++;
20934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* If adding a true alpha channel not just filler */
20944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if ((png_ptr->transformations & PNG_ADD_ALPHA) != 0)
20954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
20964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
20974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
20984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
21004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmanndefined(PNG_READ_USER_TRANSFORM_SUPPORTED)
21014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
21024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
21034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (png_ptr->user_transform_depth != 0)
21044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->bit_depth = png_ptr->user_transform_depth;
21054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (png_ptr->user_transform_channels != 0)
21074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->channels = png_ptr->user_transform_channels;
21084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
21094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
21104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
21124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       info_ptr->bit_depth);
21134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);
21154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Adding in 1.5.4: cache the above value in png_struct so that we can later
21174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * check in png_rowbytes that the user buffer won't get overwritten.  Note
21184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * that the field is not always set - if png_read_update_info isn't called
21194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * the application has to either not do any transforms or get the calculation
21204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * right itself.
21214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
21224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->info_rowbytes = info_ptr->rowbytes;
21234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifndef PNG_READ_EXPAND_SUPPORTED
21254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr != NULL)
21264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
21274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
21284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
21294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_PACK_SUPPORTED
21314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
21324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * without changing the actual values.  Thus, if you had a row with
21334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * a bit depth of 1, you would end up with bytes that only contained
21344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the numbers 0 or 1.  If you would rather they contain 0 and 255, use
21354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * png_do_shift() after this.
21364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
21374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void
21384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_do_unpack(png_row_infop row_info, png_bytep row)
21394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
21404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_do_unpack");
21414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (row_info->bit_depth < 8)
21434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
21444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_uint_32 i;
21454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_uint_32 row_width=row_info->width;
21464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      switch (row_info->bit_depth)
21484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
21494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         case 1:
21504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
21514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
21524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep dp = row + (png_size_t)row_width - 1;
21534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
21544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < row_width; i++)
21554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
21564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *dp = (png_byte)((*sp >> shift) & 0x01);
21574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (shift == 7)
21594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
21604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  shift = 0;
21614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp--;
21624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
21634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               else
21654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  shift++;
21664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               dp--;
21684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
21694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            break;
21704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
21714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         case 2:
21734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
21744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
21764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep dp = row + (png_size_t)row_width - 1;
21774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
21784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < row_width; i++)
21794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
21804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *dp = (png_byte)((*sp >> shift) & 0x03);
21814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (shift == 6)
21834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
21844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  shift = 0;
21854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp--;
21864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
21874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               else
21894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  shift += 2;
21904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               dp--;
21924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
21934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            break;
21944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
21954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         case 4:
21974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
21984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
21994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep dp = row + (png_size_t)row_width - 1;
22004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
22014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < row_width; i++)
22024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
22034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *dp = (png_byte)((*sp >> shift) & 0x0f);
22044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (shift == 4)
22064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
22074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  shift = 0;
22084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp--;
22094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
22104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               else
22124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  shift = 4;
22134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               dp--;
22154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
22164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            break;
22174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
22184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         default:
22204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            break;
22214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
22224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      row_info->bit_depth = 8;
22234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
22244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      row_info->rowbytes = row_width * row_info->channels;
22254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
22264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
22274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
22284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_SHIFT_SUPPORTED
22304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Reverse the effects of png_do_shift.  This routine merely shifts the
22314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * pixels back to their significant bits values.  Thus, if you have
22324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * a row of bit depth 8, but only 5 are significant, this will shift
22334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the values back to 0 through 31.
22344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
22354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void
22364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_do_unshift(png_row_infop row_info, png_bytep row,
22374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    png_const_color_8p sig_bits)
22384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
22394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int color_type;
22404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_do_unshift");
22424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* The palette case has already been handled in the _init routine. */
22444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   color_type = row_info->color_type;
22454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (color_type != PNG_COLOR_TYPE_PALETTE)
22474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
22484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int shift[4];
22494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int channels = 0;
22504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int bit_depth = row_info->bit_depth;
22514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
22534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
22544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         shift[channels++] = bit_depth - sig_bits->red;
22554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         shift[channels++] = bit_depth - sig_bits->green;
22564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         shift[channels++] = bit_depth - sig_bits->blue;
22574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
22584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
22604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
22614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         shift[channels++] = bit_depth - sig_bits->gray;
22624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
22634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if ((color_type & PNG_COLOR_MASK_ALPHA) != 0)
22654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
22664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         shift[channels++] = bit_depth - sig_bits->alpha;
22674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
22684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
22704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         int c, have_shift;
22714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         for (c = have_shift = 0; c < channels; ++c)
22734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
22744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* A shift of more than the bit depth is an error condition but it
22754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * gets ignored here.
22764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             */
22774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (shift[c] <= 0 || shift[c] >= bit_depth)
22784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               shift[c] = 0;
22794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            else
22814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               have_shift = 1;
22824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
22834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (have_shift == 0)
22854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return;
22864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
22874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      switch (bit_depth)
22894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
22904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         default:
22914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Must be 1bpp gray: should not be here! */
22924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* NOTREACHED */
22934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            break;
22944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         case 2:
22964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Must be 2bpp gray */
22974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* assert(channels == 1 && shift[0] == 1) */
22984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
22994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep bp = row;
23004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep bp_end = bp + row_info->rowbytes;
23014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            while (bp < bp_end)
23034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
23044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               int b = (*bp >> 1) & 0x55;
23054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *bp++ = (png_byte)b;
23064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
23074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            break;
23084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
23094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         case 4:
23114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Must be 4bpp gray */
23124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* assert(channels == 1) */
23134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
23144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep bp = row;
23154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep bp_end = bp + row_info->rowbytes;
23164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int gray_shift = shift[0];
23174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int mask =  0xf >> gray_shift;
23184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            mask |= mask << 4;
23204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            while (bp < bp_end)
23224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
23234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               int b = (*bp >> gray_shift) & mask;
23244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *bp++ = (png_byte)b;
23254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
23264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            break;
23274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
23284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         case 8:
23304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Single byte components, G, GA, RGB, RGBA */
23314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
23324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep bp = row;
23334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep bp_end = bp + row_info->rowbytes;
23344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int channel = 0;
23354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            while (bp < bp_end)
23374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
23384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               int b = *bp >> shift[channel];
23394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (++channel >= channels)
23404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  channel = 0;
23414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *bp++ = (png_byte)b;
23424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
23434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            break;
23444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
23454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_16BIT_SUPPORTED
23474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         case 16:
23484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Double byte components, G, GA, RGB, RGBA */
23494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
23504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep bp = row;
23514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep bp_end = bp + row_info->rowbytes;
23524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int channel = 0;
23534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            while (bp < bp_end)
23554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
23564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               int value = (bp[0] << 8) + bp[1];
23574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               value >>= shift[channel];
23594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (++channel >= channels)
23604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  channel = 0;
23614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *bp++ = (png_byte)(value >> 8);
23624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *bp++ = (png_byte)value;
23634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
23644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            break;
23654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
23664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
23674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
23684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
23694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
23704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
23714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
23734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Scale rows of bit depth 16 down to 8 accurately */
23744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void
23754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_do_scale_16_to_8(png_row_infop row_info, png_bytep row)
23764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
23774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_do_scale_16_to_8");
23784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (row_info->bit_depth == 16)
23804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
23814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_bytep sp = row; /* source */
23824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_bytep dp = row; /* destination */
23834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_bytep ep = sp + row_info->rowbytes; /* end+1 */
23844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      while (sp < ep)
23864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
23874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* The input is an array of 16-bit components, these must be scaled to
23884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * 8 bits each.  For a 16-bit value V the required value (from the PNG
23894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * specification) is:
23904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          *
23914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          *    (V * 255) / 65535
23924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          *
23934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * This reduces to round(V / 257), or floor((V + 128.5)/257)
23944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          *
23954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * Represent V as the two byte value vhi.vlo.  Make a guess that the
23964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * result is the top byte of V, vhi, then the correction to this value
23974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * is:
23984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          *
23994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          *    error = floor(((V-vhi.vhi) + 128.5) / 257)
24004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          *          = floor(((vlo-vhi) + 128.5) / 257)
24014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          *
24024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * This can be approximated using integer arithmetic (and a signed
24034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * shift):
24044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          *
24054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          *    error = (vlo-vhi+128) >> 8;
24064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          *
24074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * The approximate differs from the exact answer only when (vlo-vhi) is
24084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * 128; it then gives a correction of +1 when the exact correction is
24094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * 0.  This gives 128 errors.  The exact answer (correct for all 16-bit
24104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * input values) is:
24114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          *
24124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          *    error = (vlo-vhi+128)*65535 >> 24;
24134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          *
24144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * An alternative arithmetic calculation which also gives no errors is:
24154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          *
24164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          *    (V * 255 + 32895) >> 16
24174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
24184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_int_32 tmp = *sp++; /* must be signed! */
24204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24;
24214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         *dp++ = (png_byte)tmp;
24224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
24234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      row_info->bit_depth = 8;
24254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
24264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      row_info->rowbytes = row_info->width * row_info->channels;
24274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
24284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
24294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
24304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
24324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void
24334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Simply discard the low byte.  This was the default behavior prior
24344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * to libpng-1.5.4.
24354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
24364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_do_chop(png_row_infop row_info, png_bytep row)
24374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
24384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_do_chop");
24394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (row_info->bit_depth == 16)
24414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
24424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_bytep sp = row; /* source */
24434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_bytep dp = row; /* destination */
24444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_bytep ep = sp + row_info->rowbytes; /* end+1 */
24454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      while (sp < ep)
24474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
24484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         *dp++ = *sp;
24494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         sp += 2; /* skip low byte */
24504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
24514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      row_info->bit_depth = 8;
24534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
24544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      row_info->rowbytes = row_info->width * row_info->channels;
24554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
24564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
24574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
24584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
24604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void
24614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
24624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
24634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_do_read_swap_alpha");
24644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
24664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_uint_32 row_width = row_info->width;
24674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
24684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
24694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* This converts from RGBA to ARGB */
24704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (row_info->bit_depth == 8)
24714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
24724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep sp = row + row_info->rowbytes;
24734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep dp = sp;
24744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_byte save;
24754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_uint_32 i;
24764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < row_width; i++)
24784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
24794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               save = *(--sp);
24804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
24814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
24824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
24834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = save;
24844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
24854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
24864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_16BIT_SUPPORTED
24884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* This converts from RRGGBBAA to AARRGGBB */
24894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else
24904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
24914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep sp = row + row_info->rowbytes;
24924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep dp = sp;
24934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_byte save[2];
24944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_uint_32 i;
24954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < row_width; i++)
24974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
24984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               save[0] = *(--sp);
24994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               save[1] = *(--sp);
25004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
25014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
25024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
25034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
25044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
25054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
25064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = save[0];
25074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = save[1];
25084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
25094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
25104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
25114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
25124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
25134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
25144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
25154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* This converts from GA to AG */
25164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (row_info->bit_depth == 8)
25174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
25184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep sp = row + row_info->rowbytes;
25194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep dp = sp;
25204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_byte save;
25214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_uint_32 i;
25224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
25234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < row_width; i++)
25244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
25254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               save = *(--sp);
25264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
25274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = save;
25284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
25294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
25304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
25314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_16BIT_SUPPORTED
25324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* This converts from GGAA to AAGG */
25334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else
25344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
25354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep sp = row + row_info->rowbytes;
25364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep dp = sp;
25374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_byte save[2];
25384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_uint_32 i;
25394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
25404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < row_width; i++)
25414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
25424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               save[0] = *(--sp);
25434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               save[1] = *(--sp);
25444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
25454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
25464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = save[0];
25474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = save[1];
25484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
25494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
25504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
25514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
25524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
25534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
25544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
25554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
25564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
25574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void
25584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
25594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
25604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 row_width;
25614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_do_read_invert_alpha");
25624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
25634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   row_width = row_info->width;
25644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
25654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
25664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (row_info->bit_depth == 8)
25674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
25684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* This inverts the alpha channel in RGBA */
25694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_bytep sp = row + row_info->rowbytes;
25704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_bytep dp = sp;
25714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_uint_32 i;
25724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
25734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         for (i = 0; i < row_width; i++)
25744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
25754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = (png_byte)(255 - *(--sp));
25764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
25774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/*          This does nothing:
25784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = *(--sp);
25794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = *(--sp);
25804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = *(--sp);
25814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            We can replace it with:
25824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann*/
25834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            sp-=3;
25844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            dp=sp;
25854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
25864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
25874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
25884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_16BIT_SUPPORTED
25894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* This inverts the alpha channel in RRGGBBAA */
25904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
25914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
25924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_bytep sp = row + row_info->rowbytes;
25934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_bytep dp = sp;
25944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_uint_32 i;
25954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
25964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         for (i = 0; i < row_width; i++)
25974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
25984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = (png_byte)(255 - *(--sp));
25994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = (png_byte)(255 - *(--sp));
26004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
26014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/*          This does nothing:
26024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = *(--sp);
26034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = *(--sp);
26044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = *(--sp);
26054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = *(--sp);
26064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = *(--sp);
26074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = *(--sp);
26084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            We can replace it with:
26094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann*/
26104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            sp-=6;
26114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            dp=sp;
26124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
26134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
26144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
26154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
26164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
26174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
26184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (row_info->bit_depth == 8)
26194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
26204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* This inverts the alpha channel in GA */
26214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_bytep sp = row + row_info->rowbytes;
26224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_bytep dp = sp;
26234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_uint_32 i;
26244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
26254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         for (i = 0; i < row_width; i++)
26264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
26274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = (png_byte)(255 - *(--sp));
26284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = *(--sp);
26294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
26304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
26314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
26324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_16BIT_SUPPORTED
26334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
26344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
26354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* This inverts the alpha channel in GGAA */
26364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_bytep sp  = row + row_info->rowbytes;
26374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_bytep dp = sp;
26384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_uint_32 i;
26394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
26404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         for (i = 0; i < row_width; i++)
26414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
26424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = (png_byte)(255 - *(--sp));
26434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = (png_byte)(255 - *(--sp));
26444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/*
26454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = *(--sp);
26464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = *(--sp);
26474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann*/
26484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            sp-=2;
26494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            dp=sp;
26504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
26514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
26524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
26534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
26544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
26554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
26564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
26574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_FILLER_SUPPORTED
26584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Add filler channel if we have RGB color */
26594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void
26604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_do_read_filler(png_row_infop row_info, png_bytep row,
26614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    png_uint_32 filler, png_uint_32 flags)
26624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
26634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 i;
26644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 row_width = row_info->width;
26654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
26664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_16BIT_SUPPORTED
26674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_byte hi_filler = (png_byte)(filler>>8);
26684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
26694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_byte lo_filler = (png_byte)filler;
26704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
26714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_do_read_filler");
26724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
26734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (
26744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       row_info->color_type == PNG_COLOR_TYPE_GRAY)
26754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
26764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (row_info->bit_depth == 8)
26774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
26784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
26794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
26804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* This changes the data from G to GX */
26814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep sp = row + (png_size_t)row_width;
26824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep dp =  sp + (png_size_t)row_width;
26834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 1; i < row_width; i++)
26844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
26854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = lo_filler;
26864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
26874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
26884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = lo_filler;
26894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->channels = 2;
26904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->pixel_depth = 16;
26914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->rowbytes = row_width * 2;
26924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
26934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
26944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else
26954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
26964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* This changes the data from G to XG */
26974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep sp = row + (png_size_t)row_width;
26984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep dp = sp  + (png_size_t)row_width;
26994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < row_width; i++)
27004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
27014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
27024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = lo_filler;
27034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
27044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->channels = 2;
27054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->pixel_depth = 16;
27064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->rowbytes = row_width * 2;
27074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
27084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
27094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_16BIT_SUPPORTED
27114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else if (row_info->bit_depth == 16)
27124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
27134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
27144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
27154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* This changes the data from GG to GGXX */
27164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep sp = row + (png_size_t)row_width * 2;
27174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep dp = sp  + (png_size_t)row_width * 2;
27184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 1; i < row_width; i++)
27194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
27204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = lo_filler;
27214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = hi_filler;
27224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
27234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
27244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
27254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = lo_filler;
27264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = hi_filler;
27274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->channels = 2;
27284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->pixel_depth = 32;
27294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->rowbytes = row_width * 4;
27304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
27314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else
27334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
27344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* This changes the data from GG to XXGG */
27354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep sp = row + (png_size_t)row_width * 2;
27364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep dp = sp  + (png_size_t)row_width * 2;
27374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < row_width; i++)
27384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
27394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
27404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
27414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = lo_filler;
27424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = hi_filler;
27434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
27444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->channels = 2;
27454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->pixel_depth = 32;
27464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->rowbytes = row_width * 4;
27474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
27484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
27494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
27504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   } /* COLOR_TYPE == GRAY */
27514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
27524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
27534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (row_info->bit_depth == 8)
27544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
27554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
27564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
27574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* This changes the data from RGB to RGBX */
27584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep sp = row + (png_size_t)row_width * 3;
27594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep dp = sp  + (png_size_t)row_width;
27604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 1; i < row_width; i++)
27614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
27624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = lo_filler;
27634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
27644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
27654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
27664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
27674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = lo_filler;
27684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->channels = 4;
27694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->pixel_depth = 32;
27704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->rowbytes = row_width * 4;
27714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
27724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else
27744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
27754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* This changes the data from RGB to XRGB */
27764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep sp = row + (png_size_t)row_width * 3;
27774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep dp = sp + (png_size_t)row_width;
27784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < row_width; i++)
27794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
27804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
27814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
27824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
27834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = lo_filler;
27844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
27854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->channels = 4;
27864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->pixel_depth = 32;
27874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->rowbytes = row_width * 4;
27884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
27894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
27904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_16BIT_SUPPORTED
27924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else if (row_info->bit_depth == 16)
27934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
27944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
27954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
27964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* This changes the data from RRGGBB to RRGGBBXX */
27974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep sp = row + (png_size_t)row_width * 6;
27984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep dp = sp  + (png_size_t)row_width * 2;
27994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 1; i < row_width; i++)
28004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
28014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = lo_filler;
28024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = hi_filler;
28034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
28044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
28054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
28064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
28074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
28084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
28094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
28104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = lo_filler;
28114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *(--dp) = hi_filler;
28124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->channels = 4;
28134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->pixel_depth = 64;
28144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->rowbytes = row_width * 8;
28154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
28164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
28174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else
28184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
28194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* This changes the data from RRGGBB to XXRRGGBB */
28204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep sp = row + (png_size_t)row_width * 6;
28214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep dp = sp  + (png_size_t)row_width * 2;
28224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < row_width; i++)
28234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
28244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
28254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
28264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
28274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
28284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
28294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = *(--sp);
28304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = lo_filler;
28314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(--dp) = hi_filler;
28324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
28334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
28344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->channels = 4;
28354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->pixel_depth = 64;
28364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->rowbytes = row_width * 8;
28374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
28384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
28394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
28404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   } /* COLOR_TYPE == RGB */
28414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
28424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
28434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
28444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
28454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Expand grayscale files to RGB, with or without alpha */
28464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void
28474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
28484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
28494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 i;
28504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 row_width = row_info->width;
28514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
28524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_do_gray_to_rgb");
28534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
28544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (row_info->bit_depth >= 8 &&
28554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (row_info->color_type & PNG_COLOR_MASK_COLOR) == 0)
28564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
28574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
28584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
28594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (row_info->bit_depth == 8)
28604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
28614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* This changes G to RGB */
28624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep sp = row + (png_size_t)row_width - 1;
28634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep dp = sp  + (png_size_t)row_width * 2;
28644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < row_width; i++)
28654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
28664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp--) = *sp;
28674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp--) = *sp;
28684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp--) = *(sp--);
28694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
28704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
28714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
28724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else
28734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
28744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* This changes GG to RRGGBB */
28754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
28764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep dp = sp  + (png_size_t)row_width * 4;
28774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < row_width; i++)
28784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
28794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp--) = *sp;
28804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp--) = *(sp - 1);
28814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp--) = *sp;
28824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp--) = *(sp - 1);
28834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp--) = *(sp--);
28844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp--) = *(sp--);
28854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
28864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
28874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
28884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
28894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
28904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
28914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (row_info->bit_depth == 8)
28924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
28934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* This changes GA to RGBA */
28944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
28954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep dp = sp  + (png_size_t)row_width * 2;
28964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < row_width; i++)
28974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
28984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp--) = *(sp--);
28994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp--) = *sp;
29004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp--) = *sp;
29014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp--) = *(sp--);
29024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
29034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
29044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
29054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else
29064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
29074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* This changes GGAA to RRGGBBAA */
29084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep sp = row + (png_size_t)row_width * 4 - 1;
29094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep dp = sp  + (png_size_t)row_width * 4;
29104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < row_width; i++)
29114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
29124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp--) = *(sp--);
29134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp--) = *(sp--);
29144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp--) = *sp;
29154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp--) = *(sp - 1);
29164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp--) = *sp;
29174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp--) = *(sp - 1);
29184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp--) = *(sp--);
29194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp--) = *(sp--);
29204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
29214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
29224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
29234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      row_info->channels = (png_byte)(row_info->channels + 2);
29244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      row_info->color_type |= PNG_COLOR_MASK_COLOR;
29254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      row_info->pixel_depth = (png_byte)(row_info->channels *
29264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          row_info->bit_depth);
29274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
29284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
29294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
29304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
29314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
29324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
29334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Reduce RGB files to grayscale, with or without alpha
29344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * using the equation given in Poynton's ColorFAQ of 1998-01-04 at
29354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * <http://www.inforamp.net/~poynton/>  (THIS LINK IS DEAD June 2008 but
29364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * versions dated 1998 through November 2002 have been archived at
29374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * http://web.archive.org/web/20000816232553/http://www.inforamp.net/
29384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * ~poynton/notes/colour_and_gamma/ColorFAQ.txt )
29394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Charles Poynton poynton at poynton.com
29404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
29414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *     Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
29424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
29434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  which can be expressed with integers as
29444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
29454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *     Y = (6969 * R + 23434 * G + 2365 * B)/32768
29464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
29474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Poynton's current link (as of January 2003 through July 2011):
29484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * <http://www.poynton.com/notes/colour_and_gamma/>
29494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * has changed the numbers slightly:
29504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
29514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *     Y = 0.2126*R + 0.7152*G + 0.0722*B
29524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
29534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  which can be expressed with integers as
29544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
29554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *     Y = (6966 * R + 23436 * G + 2366 * B)/32768
29564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
29574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  Historically, however, libpng uses numbers derived from the ITU-R Rec 709
29584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  end point chromaticities and the D65 white point.  Depending on the
29594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  precision used for the D65 white point this produces a variety of different
29604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  numbers, however if the four decimal place value used in ITU-R Rec 709 is
29614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  used (0.3127,0.3290) the Y calculation would be:
29624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
29634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *     Y = (6968 * R + 23435 * G + 2366 * B)/32768
29644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
29654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  While this is correct the rounding results in an overflow for white, because
29664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  the sum of the rounded coefficients is 32769, not 32768.  Consequently
29674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  libpng uses, instead, the closest non-overflowing approximation:
29684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
29694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *     Y = (6968 * R + 23434 * G + 2366 * B)/32768
29704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
29714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  Starting with libpng-1.5.5, if the image being converted has a cHRM chunk
29724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  (including an sRGB chunk) then the chromaticities are used to calculate the
29734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  coefficients.  See the chunk handling in pngrutil.c for more information.
29744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
29754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  In all cases the calculation is to be done in a linear colorspace.  If no
29764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  gamma information is available to correct the encoding of the original RGB
29774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  values this results in an implicit assumption that the original PNG RGB
29784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  values were linear.
29794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
29804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  Other integer coefficents can be used via png_set_rgb_to_gray().  Because
29814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  the API takes just red and green coefficients the blue coefficient is
29824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  calculated to make the sum 32768.  This will result in different rounding
29834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  to that used above.
29844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
29854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int
29864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
29874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
29884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
29894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int rgb_error = 0;
29904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
29914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_do_rgb_to_gray");
29924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
29934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 &&
29944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
29954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
29964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
29974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
29984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      PNG_CONST png_uint_32 bc = 32768 - rc - gc;
29994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      PNG_CONST png_uint_32 row_width = row_info->width;
30004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      PNG_CONST int have_alpha =
30014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0;
30024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (row_info->bit_depth == 8)
30044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
30054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED
30064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Notice that gamma to/from 1 are not necessarily inverses (if
30074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * there is an overall gamma correction).  Prior to 1.5.5 this code
30084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * checked the linearized values for equality; this doesn't match
30094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * the documentation, the original values must be checked.
30104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
30114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
30124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
30134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep sp = row;
30144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep dp = row;
30154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_uint_32 i;
30164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < row_width; i++)
30184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
30194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               png_byte red   = *(sp++);
30204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               png_byte green = *(sp++);
30214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               png_byte blue  = *(sp++);
30224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (red != green || red != blue)
30244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
30254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  red = png_ptr->gamma_to_1[red];
30264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  green = png_ptr->gamma_to_1[green];
30274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  blue = png_ptr->gamma_to_1[blue];
30284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  rgb_error |= 1;
30304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *(dp++) = png_ptr->gamma_from_1[
30314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      (rc*red + gc*green + bc*blue + 16384)>>15];
30324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
30334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               else
30354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
30364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  /* If there is no overall correction the table will not be
30374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   * set.
30384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   */
30394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if (png_ptr->gamma_table != NULL)
30404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     red = png_ptr->gamma_table[red];
30414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *(dp++) = red;
30434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
30444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (have_alpha != 0)
30464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *(dp++) = *(sp++);
30474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
30484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
30494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else
30504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
30514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
30524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep sp = row;
30534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep dp = row;
30544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_uint_32 i;
30554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < row_width; i++)
30574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
30584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               png_byte red   = *(sp++);
30594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               png_byte green = *(sp++);
30604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               png_byte blue  = *(sp++);
30614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (red != green || red != blue)
30634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
30644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  rgb_error |= 1;
30654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  /* NOTE: this is the historical approach which simply
30664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   * truncates the results.
30674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   */
30684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
30694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
30704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               else
30724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *(dp++) = red;
30734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (have_alpha != 0)
30754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *(dp++) = *(sp++);
30764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
30774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
30784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
30794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else /* RGB bit_depth == 16 */
30814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
30824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED
30834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL)
30844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
30854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep sp = row;
30864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep dp = row;
30874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_uint_32 i;
30884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < row_width; i++)
30904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
30914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               png_uint_16 red, green, blue, w;
30924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               png_byte hi,lo;
30934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               hi=*(sp)++; lo=*(sp)++; red   = (png_uint_16)((hi << 8) | (lo));
30954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo));
30964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               hi=*(sp)++; lo=*(sp)++; blue  = (png_uint_16)((hi << 8) | (lo));
30974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (red == green && red == blue)
30994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
31004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if (png_ptr->gamma_16_table != NULL)
31014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     w = png_ptr->gamma_16_table[(red & 0xff)
31024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         >> png_ptr->gamma_shift][red >> 8];
31034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
31044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  else
31054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     w = red;
31064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
31074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
31084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               else
31094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
31104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red & 0xff)
31114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      >> png_ptr->gamma_shift][red>>8];
31124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_uint_16 green_1 =
31134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      png_ptr->gamma_16_to_1[(green & 0xff) >>
31144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      png_ptr->gamma_shift][green>>8];
31154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue & 0xff)
31164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      >> png_ptr->gamma_shift][blue>>8];
31174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_uint_16 gray16  = (png_uint_16)((rc*red_1 + gc*green_1
31184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      + bc*blue_1 + 16384)>>15);
31194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  w = png_ptr->gamma_16_from_1[(gray16 & 0xff) >>
31204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      png_ptr->gamma_shift][gray16 >> 8];
31214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  rgb_error |= 1;
31224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
31234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
31244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp++) = (png_byte)((w>>8) & 0xff);
31254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp++) = (png_byte)(w & 0xff);
31264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
31274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (have_alpha != 0)
31284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
31294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *(dp++) = *(sp++);
31304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *(dp++) = *(sp++);
31314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
31324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
31334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
31344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else
31354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
31364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
31374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep sp = row;
31384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_bytep dp = row;
31394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_uint_32 i;
31404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
31414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < row_width; i++)
31424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
31434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               png_uint_16 red, green, blue, gray16;
31444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               png_byte hi,lo;
31454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
31464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               hi=*(sp)++; lo=*(sp)++; red   = (png_uint_16)((hi << 8) | (lo));
31474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo));
31484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               hi=*(sp)++; lo=*(sp)++; blue  = (png_uint_16)((hi << 8) | (lo));
31494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
31504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (red != green || red != blue)
31514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  rgb_error |= 1;
31524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
31534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               /* From 1.5.5 in the 16-bit case do the accurate conversion even
31544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                * in the 'fast' case - this is because this is where the code
31554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                * ends up when handling linear 16-bit data.
31564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                */
31574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               gray16  = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >>
31584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  15);
31594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp++) = (png_byte)((gray16 >> 8) & 0xff);
31604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(dp++) = (png_byte)(gray16 & 0xff);
31614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
31624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (have_alpha != 0)
31634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
31644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *(dp++) = *(sp++);
31654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *(dp++) = *(sp++);
31664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
31674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
31684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
31694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
31704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
31714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      row_info->channels = (png_byte)(row_info->channels - 2);
31724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      row_info->color_type = (png_byte)(row_info->color_type &
31734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          ~PNG_COLOR_MASK_COLOR);
31744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      row_info->pixel_depth = (png_byte)(row_info->channels *
31754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          row_info->bit_depth);
31764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
31774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
31784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return rgb_error;
31794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
31804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
31814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
31824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
31834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
31844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Replace any alpha or transparency with the supplied background color.
31854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * "background" is already in the screen gamma, while "background_1" is
31864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * at a gamma of 1.0.  Paletted files have already been taken care of.
31874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
31884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void
31894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
31904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
31914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED
31924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_const_bytep gamma_table = png_ptr->gamma_table;
31934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_const_bytep gamma_from_1 = png_ptr->gamma_from_1;
31944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_const_bytep gamma_to_1 = png_ptr->gamma_to_1;
31954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table;
31964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1;
31974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1;
31984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int gamma_shift = png_ptr->gamma_shift;
31994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0;
32004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
32014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
32024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_bytep sp;
32034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 i;
32044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 row_width = row_info->width;
32054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int shift;
32064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
32074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_do_compose");
32084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
32094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
32104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      switch (row_info->color_type)
32114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
32124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         case PNG_COLOR_TYPE_GRAY:
32134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
32144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            switch (row_info->bit_depth)
32154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
32164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               case 1:
32174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
32184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp = row;
32194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  shift = 7;
32204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  for (i = 0; i < row_width; i++)
32214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
32224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if ((png_uint_16)((*sp >> shift) & 0x01)
32234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        == png_ptr->trans_color.gray)
32244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
32254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        unsigned int tmp = *sp & (0x7f7f >> (7 - shift));
32264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        tmp |= png_ptr->background.gray << shift;
32274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = (png_byte)(tmp & 0xff);
32284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
32294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
32304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if (shift == 0)
32314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
32324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        shift = 7;
32334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        sp++;
32344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
32354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
32364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     else
32374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        shift--;
32384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
32394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  break;
32404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
32414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
32424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               case 2:
32434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
32444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED
32454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if (gamma_table != NULL)
32464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
32474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     sp = row;
32484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     shift = 6;
32494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     for (i = 0; i < row_width; i++)
32504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
32514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if ((png_uint_16)((*sp >> shift) & 0x03)
32524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            == png_ptr->trans_color.gray)
32534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        {
32544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
32554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           tmp |= png_ptr->background.gray << shift;
32564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           *sp = (png_byte)(tmp & 0xff);
32574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        }
32584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
32594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        else
32604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        {
32614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           unsigned int p = (*sp >> shift) & 0x03;
32624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           unsigned int g = (gamma_table [p | (p << 2) |
32634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                               (p << 4) | (p << 6)] >> 6) & 0x03;
32644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
32654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           tmp |= g << shift;
32664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           *sp = (png_byte)(tmp & 0xff);
32674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        }
32684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
32694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if (shift == 0)
32704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        {
32714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           shift = 6;
32724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           sp++;
32734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        }
32744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
32754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        else
32764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           shift -= 2;
32774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
32784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
32794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
32804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  else
32814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
32824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
32834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     sp = row;
32844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     shift = 6;
32854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     for (i = 0; i < row_width; i++)
32864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
32874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if ((png_uint_16)((*sp >> shift) & 0x03)
32884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            == png_ptr->trans_color.gray)
32894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        {
32904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
32914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           tmp |= png_ptr->background.gray << shift;
32924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           *sp = (png_byte)(tmp & 0xff);
32934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        }
32944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
32954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if (shift == 0)
32964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        {
32974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           shift = 6;
32984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           sp++;
32994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        }
33004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        else
33024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           shift -= 2;
33034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
33044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
33054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  break;
33064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
33074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               case 4:
33094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
33104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED
33114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if (gamma_table != NULL)
33124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
33134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     sp = row;
33144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     shift = 4;
33154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     for (i = 0; i < row_width; i++)
33164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
33174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if ((png_uint_16)((*sp >> shift) & 0x0f)
33184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            == png_ptr->trans_color.gray)
33194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        {
33204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
33214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           tmp |= png_ptr->background.gray << shift;
33224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           *sp = (png_byte)(tmp & 0xff);
33234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        }
33244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        else
33264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        {
33274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           unsigned int p = (*sp >> shift) & 0x0f;
33284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           unsigned int g = (gamma_table[p | (p << 4)] >> 4) &
33294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                              0x0f;
33304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
33314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           tmp |= g << shift;
33324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           *sp = (png_byte)(tmp & 0xff);
33334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        }
33344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if (shift == 0)
33364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        {
33374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           shift = 4;
33384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           sp++;
33394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        }
33404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        else
33424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           shift -= 4;
33434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
33444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
33454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  else
33474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
33484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
33494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     sp = row;
33504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     shift = 4;
33514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     for (i = 0; i < row_width; i++)
33524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
33534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if ((png_uint_16)((*sp >> shift) & 0x0f)
33544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            == png_ptr->trans_color.gray)
33554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        {
33564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
33574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           tmp |= png_ptr->background.gray << shift;
33584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           *sp = (png_byte)(tmp & 0xff);
33594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        }
33604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if (shift == 0)
33624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        {
33634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           shift = 4;
33644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           sp++;
33654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        }
33664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        else
33684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           shift -= 4;
33694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
33704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
33714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  break;
33724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
33734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               case 8:
33754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
33764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED
33774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if (gamma_table != NULL)
33784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
33794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     sp = row;
33804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     for (i = 0; i < row_width; i++, sp++)
33814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
33824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if (*sp == png_ptr->trans_color.gray)
33834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           *sp = (png_byte)png_ptr->background.gray;
33844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        else
33864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           *sp = gamma_table[*sp];
33874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
33884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
33894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  else
33904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
33914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
33924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     sp = row;
33934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     for (i = 0; i < row_width; i++, sp++)
33944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
33954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if (*sp == png_ptr->trans_color.gray)
33964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           *sp = (png_byte)png_ptr->background.gray;
33974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
33984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
33994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  break;
34004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
34014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
34024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               case 16:
34034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
34044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED
34054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if (gamma_16 != NULL)
34064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
34074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     sp = row;
34084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     for (i = 0; i < row_width; i++, sp += 2)
34094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
34104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_uint_16 v;
34114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
34124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
34134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
34144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if (v == png_ptr->trans_color.gray)
34154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        {
34164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           /* Background is already in screen gamma */
34174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           *sp = (png_byte)((png_ptr->background.gray >> 8)
34184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                & 0xff);
34194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           *(sp + 1) = (png_byte)(png_ptr->background.gray
34204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                & 0xff);
34214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        }
34224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
34234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        else
34244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        {
34254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
34264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           *sp = (png_byte)((v >> 8) & 0xff);
34274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           *(sp + 1) = (png_byte)(v & 0xff);
34284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        }
34294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
34304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
34314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  else
34324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
34334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
34344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     sp = row;
34354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     for (i = 0; i < row_width; i++, sp += 2)
34364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
34374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_uint_16 v;
34384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
34394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
34404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
34414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if (v == png_ptr->trans_color.gray)
34424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        {
34434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           *sp = (png_byte)((png_ptr->background.gray >> 8)
34444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                & 0xff);
34454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           *(sp + 1) = (png_byte)(png_ptr->background.gray
34464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                & 0xff);
34474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        }
34484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
34494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
34504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  break;
34514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
34524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
34534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               default:
34544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  break;
34554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
34564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            break;
34574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
34584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
34594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         case PNG_COLOR_TYPE_RGB:
34604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
34614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (row_info->bit_depth == 8)
34624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
34634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED
34644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (gamma_table != NULL)
34654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
34664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp = row;
34674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  for (i = 0; i < row_width; i++, sp += 3)
34684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
34694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if (*sp == png_ptr->trans_color.red &&
34704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         *(sp + 1) == png_ptr->trans_color.green &&
34714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         *(sp + 2) == png_ptr->trans_color.blue)
34724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
34734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = (png_byte)png_ptr->background.red;
34744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 1) = (png_byte)png_ptr->background.green;
34754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 2) = (png_byte)png_ptr->background.blue;
34764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
34774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
34784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     else
34794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
34804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = gamma_table[*sp];
34814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 1) = gamma_table[*(sp + 1)];
34824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 2) = gamma_table[*(sp + 2)];
34834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
34844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
34854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
34864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               else
34874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
34884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
34894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp = row;
34904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  for (i = 0; i < row_width; i++, sp += 3)
34914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
34924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if (*sp == png_ptr->trans_color.red &&
34934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         *(sp + 1) == png_ptr->trans_color.green &&
34944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         *(sp + 2) == png_ptr->trans_color.blue)
34954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
34964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = (png_byte)png_ptr->background.red;
34974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 1) = (png_byte)png_ptr->background.green;
34984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 2) = (png_byte)png_ptr->background.blue;
34994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
35004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
35014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
35024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
35034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            else /* if (row_info->bit_depth == 16) */
35044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
35054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED
35064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (gamma_16 != NULL)
35074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
35084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp = row;
35094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  for (i = 0; i < row_width; i++, sp += 6)
35104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
35114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
35124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
35134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
35144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         + *(sp + 3));
35154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
35164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
35174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         + *(sp + 5));
35184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
35194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if (r == png_ptr->trans_color.red &&
35204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         g == png_ptr->trans_color.green &&
35214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         b == png_ptr->trans_color.blue)
35224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
35234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        /* Background is already in screen gamma */
35244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
35254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
35264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
35274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                & 0xff);
35284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 3) = (png_byte)(png_ptr->background.green
35294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                & 0xff);
35304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
35314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                & 0xff);
35324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
35334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
35344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
35354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     else
35364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
35374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
35384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = (png_byte)((v >> 8) & 0xff);
35394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 1) = (png_byte)(v & 0xff);
35404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
35414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
35424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
35434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 3) = (png_byte)(v & 0xff);
35444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
35454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
35464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
35474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 5) = (png_byte)(v & 0xff);
35484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
35494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
35504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
35514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
35524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               else
35534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
35544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
35554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp = row;
35564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  for (i = 0; i < row_width; i++, sp += 6)
35574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
35584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
35594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
35604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
35614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         + *(sp + 3));
35624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
35634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
35644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         + *(sp + 5));
35654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
35664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if (r == png_ptr->trans_color.red &&
35674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         g == png_ptr->trans_color.green &&
35684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         b == png_ptr->trans_color.blue)
35694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
35704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
35714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
35724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
35734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                & 0xff);
35744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 3) = (png_byte)(png_ptr->background.green
35754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                & 0xff);
35764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
35774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                & 0xff);
35784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
35794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
35804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
35814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
35824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
35834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            break;
35844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
35854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
35864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         case PNG_COLOR_TYPE_GRAY_ALPHA:
35874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
35884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (row_info->bit_depth == 8)
35894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
35904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED
35914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
35924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   gamma_table != NULL)
35934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
35944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp = row;
35954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  for (i = 0; i < row_width; i++, sp += 2)
35964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
35974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_uint_16 a = *(sp + 1);
35984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
35994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if (a == 0xff)
36004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = gamma_table[*sp];
36014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     else if (a == 0)
36034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
36044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        /* Background is already in screen gamma */
36054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = (png_byte)png_ptr->background.gray;
36064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
36074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     else
36094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
36104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_byte v, w;
36114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        v = gamma_to_1[*sp];
36134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_composite(w, v, a, png_ptr->background_1.gray);
36144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if (optimize == 0)
36154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           w = gamma_from_1[w];
36164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = w;
36174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
36184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
36194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
36204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               else
36214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
36224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
36234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp = row;
36244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  for (i = 0; i < row_width; i++, sp += 2)
36254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
36264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_byte a = *(sp + 1);
36274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if (a == 0)
36294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = (png_byte)png_ptr->background.gray;
36304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     else if (a < 0xff)
36324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_composite(*sp, *sp, a, png_ptr->background.gray);
36334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
36344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
36354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
36364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            else /* if (png_ptr->bit_depth == 16) */
36374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
36384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED
36394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
36404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   gamma_16_to_1 != NULL)
36414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
36424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp = row;
36434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  for (i = 0; i < row_width; i++, sp += 4)
36444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
36454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
36464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         + *(sp + 3));
36474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if (a == (png_uint_16)0xffff)
36494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
36504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_uint_16 v;
36514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
36534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = (png_byte)((v >> 8) & 0xff);
36544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 1) = (png_byte)(v & 0xff);
36554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
36564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     else if (a == 0)
36584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
36594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        /* Background is already in screen gamma */
36604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = (png_byte)((png_ptr->background.gray >> 8)
36614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                & 0xff);
36624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
36634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
36644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     else
36664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
36674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_uint_16 g, v, w;
36684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
36704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_composite_16(v, g, a, png_ptr->background_1.gray);
36714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if (optimize != 0)
36724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           w = v;
36734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        else
36744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           w = gamma_16_from_1[(v & 0xff) >>
36754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                               gamma_shift][v >> 8];
36764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = (png_byte)((w >> 8) & 0xff);
36774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 1) = (png_byte)(w & 0xff);
36784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
36794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
36804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
36814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               else
36824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
36834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
36844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp = row;
36854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  for (i = 0; i < row_width; i++, sp += 4)
36864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
36874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
36884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         + *(sp + 3));
36894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if (a == 0)
36914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
36924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = (png_byte)((png_ptr->background.gray >> 8)
36934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                & 0xff);
36944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
36954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
36964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     else if (a < 0xffff)
36984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
36994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_uint_16 g, v;
37004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
37024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_composite_16(v, g, a, png_ptr->background.gray);
37034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = (png_byte)((v >> 8) & 0xff);
37044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 1) = (png_byte)(v & 0xff);
37054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
37064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
37074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
37084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
37094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            break;
37104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
37114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         case PNG_COLOR_TYPE_RGB_ALPHA:
37134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
37144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (row_info->bit_depth == 8)
37154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
37164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED
37174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
37184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   gamma_table != NULL)
37194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
37204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp = row;
37214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  for (i = 0; i < row_width; i++, sp += 4)
37224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
37234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_byte a = *(sp + 3);
37244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if (a == 0xff)
37264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
37274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = gamma_table[*sp];
37284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 1) = gamma_table[*(sp + 1)];
37294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 2) = gamma_table[*(sp + 2)];
37304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
37314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     else if (a == 0)
37334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
37344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        /* Background is already in screen gamma */
37354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = (png_byte)png_ptr->background.red;
37364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 1) = (png_byte)png_ptr->background.green;
37374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 2) = (png_byte)png_ptr->background.blue;
37384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
37394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     else
37414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
37424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_byte v, w;
37434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        v = gamma_to_1[*sp];
37454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_composite(w, v, a, png_ptr->background_1.red);
37464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if (optimize == 0) w = gamma_from_1[w];
37474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = w;
37484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        v = gamma_to_1[*(sp + 1)];
37504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_composite(w, v, a, png_ptr->background_1.green);
37514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if (optimize == 0) w = gamma_from_1[w];
37524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 1) = w;
37534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        v = gamma_to_1[*(sp + 2)];
37554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_composite(w, v, a, png_ptr->background_1.blue);
37564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if (optimize == 0) w = gamma_from_1[w];
37574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 2) = w;
37584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
37594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
37604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
37614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               else
37624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
37634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
37644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp = row;
37654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  for (i = 0; i < row_width; i++, sp += 4)
37664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
37674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_byte a = *(sp + 3);
37684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if (a == 0)
37704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
37714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = (png_byte)png_ptr->background.red;
37724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 1) = (png_byte)png_ptr->background.green;
37734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 2) = (png_byte)png_ptr->background.blue;
37744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
37754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     else if (a < 0xff)
37774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
37784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_composite(*sp, *sp, a, png_ptr->background.red);
37794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_composite(*(sp + 1), *(sp + 1), a,
37814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            png_ptr->background.green);
37824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_composite(*(sp + 2), *(sp + 2), a,
37844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            png_ptr->background.blue);
37854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
37864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
37874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
37884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
37894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            else /* if (row_info->bit_depth == 16) */
37904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
37914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED
37924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
37934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   gamma_16_to_1 != NULL)
37944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
37954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp = row;
37964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  for (i = 0; i < row_width; i++, sp += 8)
37974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
37984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
37994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         << 8) + (png_uint_16)(*(sp + 7)));
38004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if (a == (png_uint_16)0xffff)
38024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
38034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_uint_16 v;
38044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
38064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = (png_byte)((v >> 8) & 0xff);
38074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 1) = (png_byte)(v & 0xff);
38084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
38104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
38114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 3) = (png_byte)(v & 0xff);
38124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
38144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
38154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 5) = (png_byte)(v & 0xff);
38164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
38174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     else if (a == 0)
38194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
38204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        /* Background is already in screen gamma */
38214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
38224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
38234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
38244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                & 0xff);
38254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 3) = (png_byte)(png_ptr->background.green
38264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                & 0xff);
38274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
38284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                & 0xff);
38294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
38304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
38314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     else
38334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
38344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_uint_16 v, w;
38354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
38374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_composite_16(w, v, a, png_ptr->background_1.red);
38384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if (optimize == 0)
38394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
38404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                8];
38414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = (png_byte)((w >> 8) & 0xff);
38424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 1) = (png_byte)(w & 0xff);
38434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
38454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_composite_16(w, v, a, png_ptr->background_1.green);
38464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if (optimize == 0)
38474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
38484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                8];
38494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 2) = (png_byte)((w >> 8) & 0xff);
38514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 3) = (png_byte)(w & 0xff);
38524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
38544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_composite_16(w, v, a, png_ptr->background_1.blue);
38554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if (optimize == 0)
38564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
38574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                8];
38584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 4) = (png_byte)((w >> 8) & 0xff);
38604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 5) = (png_byte)(w & 0xff);
38614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
38624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
38634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
38644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               else
38664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
38674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
38684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp = row;
38694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  for (i = 0; i < row_width; i++, sp += 8)
38704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
38714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
38724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         << 8) + (png_uint_16)(*(sp + 7)));
38734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if (a == 0)
38754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
38764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
38774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
38784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
38794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                & 0xff);
38804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 3) = (png_byte)(png_ptr->background.green
38814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                & 0xff);
38824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
38834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                & 0xff);
38844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
38854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
38864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     else if (a < 0xffff)
38884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
38894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_uint_16 v;
38904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
38924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
38934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            + *(sp + 3));
38944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
38954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                            + *(sp + 5));
38964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_composite_16(v, r, a, png_ptr->background.red);
38984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *sp = (png_byte)((v >> 8) & 0xff);
38994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 1) = (png_byte)(v & 0xff);
39004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_composite_16(v, g, a, png_ptr->background.green);
39024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
39034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 3) = (png_byte)(v & 0xff);
39044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        png_composite_16(v, b, a, png_ptr->background.blue);
39064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
39074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *(sp + 5) = (png_byte)(v & 0xff);
39084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
39094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
39104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
39114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
39124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            break;
39134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
39144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         default:
39164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            break;
39174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
39184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
39194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
39204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_BACKGROUND || READ_ALPHA_MODE */
39214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED
39234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Gamma correct the image, avoiding the alpha channel.  Make sure
39244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * you do this after you deal with the transparency issue on grayscale
39254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * or RGB images. If your bit depth is 8, use gamma_table, if it
39264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * is 16, use gamma_16_table and gamma_shift.  Build these with
39274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * build_gamma_table().
39284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
39294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void
39304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
39314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
39324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_const_bytep gamma_table = png_ptr->gamma_table;
39334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table;
39344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int gamma_shift = png_ptr->gamma_shift;
39354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_bytep sp;
39374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 i;
39384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 row_width=row_info->width;
39394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_do_gamma");
39414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (((row_info->bit_depth <= 8 && gamma_table != NULL) ||
39434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (row_info->bit_depth == 16 && gamma_16_table != NULL)))
39444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
39454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      switch (row_info->color_type)
39464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
39474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         case PNG_COLOR_TYPE_RGB:
39484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
39494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (row_info->bit_depth == 8)
39504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
39514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               sp = row;
39524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               for (i = 0; i < row_width; i++)
39534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
39544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *sp = gamma_table[*sp];
39554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp++;
39564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *sp = gamma_table[*sp];
39574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp++;
39584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *sp = gamma_table[*sp];
39594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp++;
39604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
39614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
39624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            else /* if (row_info->bit_depth == 16) */
39644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
39654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               sp = row;
39664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               for (i = 0; i < row_width; i++)
39674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
39684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_uint_16 v;
39694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
39714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *sp = (png_byte)((v >> 8) & 0xff);
39724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *(sp + 1) = (png_byte)(v & 0xff);
39734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp += 2;
39744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
39764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *sp = (png_byte)((v >> 8) & 0xff);
39774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *(sp + 1) = (png_byte)(v & 0xff);
39784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp += 2;
39794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
39814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *sp = (png_byte)((v >> 8) & 0xff);
39824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *(sp + 1) = (png_byte)(v & 0xff);
39834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp += 2;
39844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
39854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
39864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            break;
39874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
39884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         case PNG_COLOR_TYPE_RGB_ALPHA:
39904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
39914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (row_info->bit_depth == 8)
39924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
39934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               sp = row;
39944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               for (i = 0; i < row_width; i++)
39954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
39964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *sp = gamma_table[*sp];
39974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp++;
39984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *sp = gamma_table[*sp];
40004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp++;
40014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
40024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *sp = gamma_table[*sp];
40034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp++;
40044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
40054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp++;
40064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
40074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
40084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
40094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            else /* if (row_info->bit_depth == 16) */
40104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
40114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               sp = row;
40124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               for (i = 0; i < row_width; i++)
40134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
40144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
40154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *sp = (png_byte)((v >> 8) & 0xff);
40164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *(sp + 1) = (png_byte)(v & 0xff);
40174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp += 2;
40184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
40194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
40204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *sp = (png_byte)((v >> 8) & 0xff);
40214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *(sp + 1) = (png_byte)(v & 0xff);
40224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp += 2;
40234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
40244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
40254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *sp = (png_byte)((v >> 8) & 0xff);
40264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *(sp + 1) = (png_byte)(v & 0xff);
40274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp += 4;
40284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
40294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
40304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            break;
40314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
40324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
40334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         case PNG_COLOR_TYPE_GRAY_ALPHA:
40344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
40354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (row_info->bit_depth == 8)
40364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
40374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               sp = row;
40384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               for (i = 0; i < row_width; i++)
40394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
40404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *sp = gamma_table[*sp];
40414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp += 2;
40424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
40434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
40444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
40454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            else /* if (row_info->bit_depth == 16) */
40464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
40474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               sp = row;
40484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               for (i = 0; i < row_width; i++)
40494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
40504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
40514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *sp = (png_byte)((v >> 8) & 0xff);
40524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *(sp + 1) = (png_byte)(v & 0xff);
40534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp += 4;
40544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
40554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
40564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            break;
40574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
40584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
40594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         case PNG_COLOR_TYPE_GRAY:
40604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
40614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (row_info->bit_depth == 2)
40624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
40634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               sp = row;
40644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               for (i = 0; i < row_width; i += 4)
40654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
40664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  int a = *sp & 0xc0;
40674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  int b = *sp & 0x30;
40684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  int c = *sp & 0x0c;
40694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  int d = *sp & 0x03;
40704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
40714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *sp = (png_byte)(
40724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)])   ) & 0xc0)|
40734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
40744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
40754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
40764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp++;
40774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
40784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
40794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
40804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (row_info->bit_depth == 4)
40814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
40824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               sp = row;
40834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               for (i = 0; i < row_width; i += 2)
40844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
40854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  int msb = *sp & 0xf0;
40864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  int lsb = *sp & 0x0f;
40874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
40884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
40894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
40904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp++;
40914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
40924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
40934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
40944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            else if (row_info->bit_depth == 8)
40954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
40964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               sp = row;
40974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               for (i = 0; i < row_width; i++)
40984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
40994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *sp = gamma_table[*sp];
41004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp++;
41014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
41024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
41034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            else if (row_info->bit_depth == 16)
41054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
41064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               sp = row;
41074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               for (i = 0; i < row_width; i++)
41084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
41094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
41104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *sp = (png_byte)((v >> 8) & 0xff);
41114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *(sp + 1) = (png_byte)(v & 0xff);
41124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp += 2;
41134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
41144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
41154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            break;
41164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
41174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         default:
41194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            break;
41204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
41214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
41224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
41234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
41244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
41264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Encode the alpha channel to the output gamma (the input channel is always
41274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * linear.)  Called only with color types that have an alpha channel.  Needs the
41284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * from_1 tables.
41294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
41304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void
41314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
41324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
41334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 row_width = row_info->width;
41344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_do_encode_alpha");
41364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
41384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
41394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (row_info->bit_depth == 8)
41404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
41414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         PNG_CONST png_bytep table = png_ptr->gamma_from_1;
41424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (table != NULL)
41444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
41454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            PNG_CONST int step =
41464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2;
41474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* The alpha channel is the last component: */
41494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row += step - 1;
41504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (; row_width > 0; --row_width, row += step)
41524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *row = table[*row];
41534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return;
41554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
41564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
41574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else if (row_info->bit_depth == 16)
41594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
41604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1;
41614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         PNG_CONST int gamma_shift = png_ptr->gamma_shift;
41624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (table != NULL)
41644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
41654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            PNG_CONST int step =
41664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4;
41674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* The alpha channel is the last component: */
41694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row += step - 2;
41704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (; row_width > 0; --row_width, row += step)
41724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
41734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               png_uint_16 v;
41744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               v = table[*(row + 1) >> gamma_shift][*row];
41764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *row = (png_byte)((v >> 8) & 0xff);
41774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *(row + 1) = (png_byte)(v & 0xff);
41784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
41794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return;
41814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
41824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
41834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
41844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Only get to here if called with a weird row_info; no harm has been done,
41864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * so just issue a warning.
41874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
41884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_warning(png_ptr, "png_do_encode_alpha: unexpected call");
41894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
41904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
41914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_EXPAND_SUPPORTED
41934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Expands a palette row to an RGB or RGBA row depending
41944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * upon whether you supply trans and num_trans.
41954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
41964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void
41974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_do_expand_palette(png_row_infop row_info, png_bytep row,
41984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)
41994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
42004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int shift, value;
42014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_bytep sp, dp;
42024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 i;
42034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 row_width=row_info->width;
42044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
42054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_do_expand_palette");
42064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
42074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
42084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
42094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (row_info->bit_depth < 8)
42104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
42114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         switch (row_info->bit_depth)
42124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
42134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            case 1:
42144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
42154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               sp = row + (png_size_t)((row_width - 1) >> 3);
42164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               dp = row + (png_size_t)row_width - 1;
42174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               shift = 7 - (int)((row_width + 7) & 0x07);
42184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               for (i = 0; i < row_width; i++)
42194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
42204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if ((*sp >> shift) & 0x01)
42214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     *dp = 1;
42224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
42234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  else
42244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     *dp = 0;
42254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
42264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if (shift == 7)
42274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
42284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     shift = 0;
42294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     sp--;
42304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
42314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
42324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  else
42334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     shift++;
42344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
42354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  dp--;
42364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
42374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               break;
42384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
42394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
42404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            case 2:
42414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
42424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               sp = row + (png_size_t)((row_width - 1) >> 2);
42434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               dp = row + (png_size_t)row_width - 1;
42444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
42454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               for (i = 0; i < row_width; i++)
42464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
42474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  value = (*sp >> shift) & 0x03;
42484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *dp = (png_byte)value;
42494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if (shift == 6)
42504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
42514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     shift = 0;
42524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     sp--;
42534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
42544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
42554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  else
42564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     shift += 2;
42574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
42584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  dp--;
42594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
42604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               break;
42614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
42624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
42634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            case 4:
42644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
42654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               sp = row + (png_size_t)((row_width - 1) >> 1);
42664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               dp = row + (png_size_t)row_width - 1;
42674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               shift = (int)((row_width & 0x01) << 2);
42684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               for (i = 0; i < row_width; i++)
42694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
42704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  value = (*sp >> shift) & 0x0f;
42714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *dp = (png_byte)value;
42724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if (shift == 4)
42734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
42744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     shift = 0;
42754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     sp--;
42764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
42774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
42784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  else
42794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     shift += 4;
42804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
42814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  dp--;
42824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
42834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               break;
42844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
42854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
42864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            default:
42874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               break;
42884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
42894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         row_info->bit_depth = 8;
42904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         row_info->pixel_depth = 8;
42914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         row_info->rowbytes = row_width;
42924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
42934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
42944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (row_info->bit_depth == 8)
42954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
42964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
42974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (num_trans > 0)
42984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
42994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               sp = row + (png_size_t)row_width - 1;
43004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               dp = row + (png_size_t)(row_width << 2) - 1;
43014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
43024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               for (i = 0; i < row_width; i++)
43034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
43044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if ((int)(*sp) >= num_trans)
43054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     *dp-- = 0xff;
43064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
43074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  else
43084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     *dp-- = trans_alpha[*sp];
43094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
43104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *dp-- = palette[*sp].blue;
43114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *dp-- = palette[*sp].green;
43124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *dp-- = palette[*sp].red;
43134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp--;
43144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
43154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               row_info->bit_depth = 8;
43164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               row_info->pixel_depth = 32;
43174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               row_info->rowbytes = row_width * 4;
43184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               row_info->color_type = 6;
43194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               row_info->channels = 4;
43204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
43214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
43224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            else
43234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
43244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               sp = row + (png_size_t)row_width - 1;
43254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               dp = row + (png_size_t)(row_width * 3) - 1;
43264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
43274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               for (i = 0; i < row_width; i++)
43284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
43294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *dp-- = palette[*sp].blue;
43304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *dp-- = palette[*sp].green;
43314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *dp-- = palette[*sp].red;
43324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp--;
43334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
43344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
43354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               row_info->bit_depth = 8;
43364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               row_info->pixel_depth = 24;
43374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               row_info->rowbytes = row_width * 3;
43384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               row_info->color_type = 2;
43394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               row_info->channels = 3;
43404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
43414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
43424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
43434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
43444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
43454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
43464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* If the bit depth < 8, it is expanded to 8.  Also, if the already
43474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * expanded transparency value is supplied, an alpha channel is built.
43484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
43494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void
43504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_do_expand(png_row_infop row_info, png_bytep row,
43514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    png_const_color_16p trans_color)
43524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
43534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int shift, value;
43544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_bytep sp, dp;
43554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 i;
43564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 row_width=row_info->width;
43574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
43584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_do_expand");
43594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
43604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
43614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
43624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
43634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         unsigned int gray = trans_color != NULL ? trans_color->gray : 0;
43644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
43654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (row_info->bit_depth < 8)
43664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
43674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            switch (row_info->bit_depth)
43684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
43694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               case 1:
43704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
43714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  gray = (gray & 0x01) * 0xff;
43724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp = row + (png_size_t)((row_width - 1) >> 3);
43734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  dp = row + (png_size_t)row_width - 1;
43744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  shift = 7 - (int)((row_width + 7) & 0x07);
43754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  for (i = 0; i < row_width; i++)
43764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
43774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if ((*sp >> shift) & 0x01)
43784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *dp = 0xff;
43794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
43804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     else
43814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *dp = 0;
43824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
43834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if (shift == 7)
43844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
43854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        shift = 0;
43864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        sp--;
43874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
43884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
43894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     else
43904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        shift++;
43914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
43924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     dp--;
43934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
43944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  break;
43954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
43964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
43974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               case 2:
43984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
43994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  gray = (gray & 0x03) * 0x55;
44004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp = row + (png_size_t)((row_width - 1) >> 2);
44014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  dp = row + (png_size_t)row_width - 1;
44024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
44034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  for (i = 0; i < row_width; i++)
44044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
44054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     value = (*sp >> shift) & 0x03;
44064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     *dp = (png_byte)(value | (value << 2) | (value << 4) |
44074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        (value << 6));
44084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if (shift == 6)
44094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
44104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        shift = 0;
44114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        sp--;
44124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
44134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     else
44154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        shift += 2;
44164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     dp--;
44184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
44194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  break;
44204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
44214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               case 4:
44234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
44244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  gray = (gray & 0x0f) * 0x11;
44254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  sp = row + (png_size_t)((row_width - 1) >> 1);
44264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  dp = row + (png_size_t)row_width - 1;
44274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
44284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  for (i = 0; i < row_width; i++)
44294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
44304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     value = (*sp >> shift) & 0x0f;
44314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     *dp = (png_byte)(value | (value << 4));
44324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if (shift == 4)
44334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
44344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        shift = 0;
44354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        sp--;
44364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
44374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     else
44394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        shift = 4;
44404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     dp--;
44424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
44434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  break;
44444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
44454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               default:
44474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  break;
44484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
44494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->bit_depth = 8;
44514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->pixel_depth = 8;
44524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->rowbytes = row_width;
44534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
44544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (trans_color != NULL)
44564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
44574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (row_info->bit_depth == 8)
44584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
44594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               gray = gray & 0xff;
44604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               sp = row + (png_size_t)row_width - 1;
44614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               dp = row + (png_size_t)(row_width << 1) - 1;
44624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               for (i = 0; i < row_width; i++)
44644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
44654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if ((*sp & 0xffU) == gray)
44664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     *dp-- = 0;
44674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  else
44694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     *dp-- = 0xff;
44704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *dp-- = *sp--;
44724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
44734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
44744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            else if (row_info->bit_depth == 16)
44764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
44774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               unsigned int gray_high = (gray >> 8) & 0xff;
44784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               unsigned int gray_low = gray & 0xff;
44794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               sp = row + row_info->rowbytes - 1;
44804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               dp = row + (row_info->rowbytes << 1) - 1;
44814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               for (i = 0; i < row_width; i++)
44824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
44834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if ((*(sp - 1) & 0xffU) == gray_high &&
44844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      (*(sp) & 0xffU) == gray_low)
44854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
44864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     *dp-- = 0;
44874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     *dp-- = 0;
44884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
44894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  else
44914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
44924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     *dp-- = 0xff;
44934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     *dp-- = 0xff;
44944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
44954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *dp-- = *sp--;
44974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *dp-- = *sp--;
44984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
44994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
45004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
45014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
45024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->channels = 2;
45034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
45044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
45054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               row_width);
45064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
45074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
45084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
45094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          trans_color != NULL)
45104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
45114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (row_info->bit_depth == 8)
45124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
45134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_byte red = (png_byte)(trans_color->red & 0xff);
45144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_byte green = (png_byte)(trans_color->green & 0xff);
45154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_byte blue = (png_byte)(trans_color->blue & 0xff);
45164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            sp = row + (png_size_t)row_info->rowbytes - 1;
45174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            dp = row + (png_size_t)(row_width << 2) - 1;
45184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < row_width; i++)
45194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
45204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
45214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *dp-- = 0;
45224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
45234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               else
45244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *dp-- = 0xff;
45254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
45264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *dp-- = *sp--;
45274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *dp-- = *sp--;
45284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *dp-- = *sp--;
45294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
45304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
45314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else if (row_info->bit_depth == 16)
45324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
45334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff);
45344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff);
45354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff);
45364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_byte red_low = (png_byte)(trans_color->red & 0xff);
45374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_byte green_low = (png_byte)(trans_color->green & 0xff);
45384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_byte blue_low = (png_byte)(trans_color->blue & 0xff);
45394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            sp = row + row_info->rowbytes - 1;
45404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            dp = row + (png_size_t)(row_width << 3) - 1;
45414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < row_width; i++)
45424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
45434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (*(sp - 5) == red_high &&
45444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   *(sp - 4) == red_low &&
45454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   *(sp - 3) == green_high &&
45464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   *(sp - 2) == green_low &&
45474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   *(sp - 1) == blue_high &&
45484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   *(sp    ) == blue_low)
45494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
45504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *dp-- = 0;
45514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *dp-- = 0;
45524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
45534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
45544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               else
45554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
45564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *dp-- = 0xff;
45574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *dp-- = 0xff;
45584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
45594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
45604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *dp-- = *sp--;
45614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *dp-- = *sp--;
45624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *dp-- = *sp--;
45634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *dp-- = *sp--;
45644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *dp-- = *sp--;
45654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *dp-- = *sp--;
45664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
45674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
45684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
45694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         row_info->channels = 4;
45704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
45714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
45724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
45734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
45744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
45754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
45764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
45774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_EXPAND_16_SUPPORTED
45784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* If the bit depth is 8 and the color type is not a palette type expand the
45794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * whole row to 16 bits.  Has no effect otherwise.
45804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
45814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void
45824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_do_expand_16(png_row_infop row_info, png_bytep row)
45834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
45844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (row_info->bit_depth == 8 &&
45854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      row_info->color_type != PNG_COLOR_TYPE_PALETTE)
45864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
45874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* The row have a sequence of bytes containing [0..255] and we need
45884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * to turn it into another row containing [0..65535], to do this we
45894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * calculate:
45904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       *
45914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       *  (input / 255) * 65535
45924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       *
45934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       *  Which happens to be exactly input * 257 and this can be achieved
45944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       *  simply by byte replication in place (copying backwards).
45954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
45964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */
45974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_byte *dp = sp + row_info->rowbytes;  /* destination, end + 1 */
45984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      while (dp > sp)
45994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         dp[-2] = dp[-1] = *--sp, dp -= 2;
46004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
46014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      row_info->rowbytes *= 2;
46024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      row_info->bit_depth = 16;
46034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      row_info->pixel_depth = (png_byte)(row_info->channels * 16);
46044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
46054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
46064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
46074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
46084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_QUANTIZE_SUPPORTED
46094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void
46104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_do_quantize(png_row_infop row_info, png_bytep row,
46114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    png_const_bytep palette_lookup, png_const_bytep quantize_lookup)
46124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
46134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_bytep sp, dp;
46144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 i;
46154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 row_width=row_info->width;
46164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
46174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_do_quantize");
46184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
46194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (row_info->bit_depth == 8)
46204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
46214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup)
46224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
46234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         int r, g, b, p;
46244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         sp = row;
46254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         dp = row;
46264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         for (i = 0; i < row_width; i++)
46274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
46284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            r = *sp++;
46294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            g = *sp++;
46304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            b = *sp++;
46314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
46324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* This looks real messy, but the compiler will reduce
46334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * it down to a reasonable formula.  For example, with
46344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * 5 bits per color, we get:
46354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * p = (((r >> 3) & 0x1f) << 10) |
46364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             *    (((g >> 3) & 0x1f) << 5) |
46374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             *    ((b >> 3) & 0x1f);
46384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             */
46394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
46404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
46414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
46424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
46434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
46444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                (PNG_QUANTIZE_BLUE_BITS)) |
46454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
46464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
46474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
46484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *dp++ = palette_lookup[p];
46494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
46504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
46514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
46524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         row_info->channels = 1;
46534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         row_info->pixel_depth = row_info->bit_depth;
46544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
46554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
46564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
46574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
46584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         palette_lookup != NULL)
46594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
46604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         int r, g, b, p;
46614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         sp = row;
46624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         dp = row;
46634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         for (i = 0; i < row_width; i++)
46644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
46654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            r = *sp++;
46664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            g = *sp++;
46674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            b = *sp++;
46684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            sp++;
46694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
46704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
46714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
46724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
46734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
46744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
46754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                (PNG_QUANTIZE_BLUE_BITS)) |
46764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
46774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
46784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
46794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *dp++ = palette_lookup[p];
46804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
46814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
46824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
46834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         row_info->channels = 1;
46844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         row_info->pixel_depth = row_info->bit_depth;
46854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
46864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
46874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
46884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
46894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         quantize_lookup)
46904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
46914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         sp = row;
46924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
46934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         for (i = 0; i < row_width; i++, sp++)
46944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
46954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *sp = quantize_lookup[*sp];
46964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
46974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
46984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
46994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
47004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_QUANTIZE */
47014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
47024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Transform the row.  The order of transformations is significant,
47034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * and is very touchy.  If you add a transformation, take care to
47044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * decide how it fits in with the other transformations here.
47054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
47064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */
47074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
47084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
47094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_do_read_transformations");
47104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
47114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr->row_buf == NULL)
47124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
47134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this
47144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * error is incredibly rare and incredibly easy to debug without this
47154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * information.
47164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
47174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_error(png_ptr, "NULL row buffer");
47184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
47194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
47204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* The following is debugging; prior to 1.5.4 the code was never compiled in;
47214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro
47224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * PNG_WARN_UNINITIALIZED_ROW removed.  In 1.6 the new flag is set only for
47234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * all transformations, however in practice the ROW_INIT always gets done on
47244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * demand, if necessary.
47254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
47264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 &&
47274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
47284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
47294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Application has failed to call either png_read_start_image() or
47304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * png_read_update_info() after setting transforms that expand pixels.
47314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * This check added to libpng-1.2.19 (but not enabled until 1.5.4).
47324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
47334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_error(png_ptr, "Uninitialized row");
47344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
47354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
47364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_EXPAND_SUPPORTED
47374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_EXPAND) != 0)
47384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
47394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
47404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
47414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_do_expand_palette(row_info, png_ptr->row_buf + 1,
47424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
47434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
47444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
47454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
47464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
47474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (png_ptr->num_trans != 0 &&
47484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             (png_ptr->transformations & PNG_EXPAND_tRNS) != 0)
47494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_do_expand(row_info, png_ptr->row_buf + 1,
47504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                &(png_ptr->trans_color));
47514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
47524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else
47534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_do_expand(row_info, png_ptr->row_buf + 1,
47544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                NULL);
47554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
47564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
47574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
47584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
47594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
47604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
47614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (png_ptr->transformations & PNG_COMPOSE) == 0 &&
47624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
47634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
47644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_do_strip_channel(row_info, png_ptr->row_buf + 1,
47654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         0 /* at_start == false, because SWAP_ALPHA happens later */);
47664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
47674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
47684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
47694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
47704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
47714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int rgb_error =
47724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          png_do_rgb_to_gray(png_ptr, row_info,
47734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann              png_ptr->row_buf + 1);
47744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
47754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (rgb_error != 0)
47764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
47774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->rgb_to_gray_status=1;
47784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
47794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             PNG_RGB_TO_GRAY_WARN)
47804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
47814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
47824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
47834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             PNG_RGB_TO_GRAY_ERR)
47844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
47854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
47864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
47874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
47884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
47894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* From Andreas Dilger e-mail to png-implement, 26 March 1998:
47904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
47914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *   In most cases, the "simple transparency" should be done prior to doing
47924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *   gray-to-RGB, or you will have to test 3x as many bytes to check if a
47934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *   pixel is transparent.  You would also need to make sure that the
47944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *   transparency information is upgraded to RGB.
47954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
47964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *   To summarize, the current flow is:
47974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *   - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
47984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *                                   with background "in place" if transparent,
47994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *                                   convert to RGB if necessary
48004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *   - Gray + alpha -> composite with gray background and remove alpha bytes,
48014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *                                   convert to RGB if necessary
48024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
48034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *   To support RGB backgrounds for gray images we need:
48044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *   - Gray + simple transparency -> convert to RGB + simple transparency,
48054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *                                   compare 3 or 6 bytes and composite with
48064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *                                   background "in place" if transparent
48074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *                                   (3x compare/pixel compared to doing
48084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *                                   composite with gray bkgrnd)
48094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *   - Gray + alpha -> convert to RGB + alpha, composite with background and
48104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *                                   remove alpha bytes (3x float
48114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *                                   operations/pixel compared with composite
48124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *                                   on gray background)
48134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
48144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  Greg's change will do this.  The reason it wasn't done before is for
48154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  performance, as this increases the per-pixel operations.  If we would check
48164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  in advance if the background was gray or RGB, and position the gray-to-RGB
48174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *  transform appropriately, then it would save a lot of work/time.
48184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
48194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
48204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
48214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* If gray -> RGB, do so now only if background is non-gray; else do later
48224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * for performance reasons
48234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
48244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 &&
48254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) == 0)
48264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
48274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
48284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
48294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
48304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
48314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_COMPOSE) != 0)
48324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr);
48334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
48344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
48354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED
48364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_GAMMA) != 0 &&
48374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
48384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Because RGB_TO_GRAY does the gamma transform. */
48394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0 &&
48404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
48414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
48424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
48434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Because PNG_COMPOSE does the gamma transform if there is something to
48444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * do (if there is an alpha channel or transparency.)
48454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
48464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       !((png_ptr->transformations & PNG_COMPOSE) != 0 &&
48474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       ((png_ptr->num_trans != 0) ||
48484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)) &&
48494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
48504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Because png_init_read_transformations transforms the palette, unless
48514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * RGB_TO_GRAY will do the transform.
48524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
48534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
48544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr);
48554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
48564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
48574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
48584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
48594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (png_ptr->transformations & PNG_COMPOSE) != 0 &&
48604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
48614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
48624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_do_strip_channel(row_info, png_ptr->row_buf + 1,
48634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          0 /* at_start == false, because SWAP_ALPHA happens later */);
48644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
48654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
48664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
48674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 &&
48684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
48694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr);
48704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
48714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
48724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
48734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0)
48744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1);
48754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
48764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
48774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
48784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* There is no harm in doing both of these because only one has any effect,
48794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * by putting the 'scale' option first if the app asks for scale (either by
48804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * calling the API or in a TRANSFORM flag) this is what happens.
48814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
48824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_16_TO_8) != 0)
48834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_do_chop(row_info, png_ptr->row_buf + 1);
48844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
48854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
48864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_QUANTIZE_SUPPORTED
48874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_QUANTIZE) != 0)
48884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
48894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_do_quantize(row_info, png_ptr->row_buf + 1,
48904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          png_ptr->palette_lookup, png_ptr->quantize_index);
48914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
48924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (row_info->rowbytes == 0)
48934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_error(png_ptr, "png_do_quantize returned rowbytes=0");
48944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
48954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_QUANTIZE */
48964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
48974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_EXPAND_16_SUPPORTED
48984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Do the expansion now, after all the arithmetic has been done.  Notice
48994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * that previous transformations can handle the PNG_EXPAND_16 flag if this
49004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * is efficient (particularly true in the case of gamma correction, where
49014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * better accuracy results faster!)
49024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
49034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_EXPAND_16) != 0)
49044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_do_expand_16(row_info, png_ptr->row_buf + 1);
49054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
49064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
49074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
49084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* NOTE: moved here in 1.5.4 (from much later in this list.) */
49094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 &&
49104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) != 0)
49114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
49124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
49134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
49144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_INVERT_SUPPORTED
49154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
49164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_do_invert(row_info, png_ptr->row_buf + 1);
49174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
49184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
49194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
49204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
49214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1);
49224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
49234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
49244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_SHIFT_SUPPORTED
49254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_SHIFT) != 0)
49264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_do_unshift(row_info, png_ptr->row_buf + 1,
49274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          &(png_ptr->shift));
49284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
49294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
49304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_PACK_SUPPORTED
49314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_PACK) != 0)
49324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_do_unpack(row_info, png_ptr->row_buf + 1);
49334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
49344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
49354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
49364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Added at libpng-1.5.10 */
49374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
49384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       png_ptr->num_palette_max >= 0)
49394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_do_check_palette_indexes(png_ptr, row_info);
49404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
49414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
49424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_BGR_SUPPORTED
49434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_BGR) != 0)
49444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_do_bgr(row_info, png_ptr->row_buf + 1);
49454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
49464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
49474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_PACKSWAP_SUPPORTED
49484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
49494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_do_packswap(row_info, png_ptr->row_buf + 1);
49504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
49514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
49524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_FILLER_SUPPORTED
49534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_FILLER) != 0)
49544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_do_read_filler(row_info, png_ptr->row_buf + 1,
49554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          (png_uint_32)png_ptr->filler, png_ptr->flags);
49564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
49574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
49584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
49594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0)
49604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1);
49614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
49624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
49634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_16BIT_SUPPORTED
49644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_SWAP_SUPPORTED
49654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
49664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_do_swap(row_info, png_ptr->row_buf + 1);
49674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
49684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
49694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
49704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
49714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
49724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
49734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (png_ptr->read_user_transform_fn != NULL)
49744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         (*(png_ptr->read_user_transform_fn)) /* User read transform function */
49754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             (png_ptr,     /* png_ptr */
49764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             row_info,     /* row_info: */
49774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                /*  png_uint_32 width;       width of row */
49784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                /*  png_size_t rowbytes;     number of bytes in row */
49794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                /*  png_byte color_type;     color type of pixels */
49804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                /*  png_byte bit_depth;      bit depth of samples */
49814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                /*  png_byte channels;       number of channels (1-4) */
49824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                /*  png_byte pixel_depth;    bits per pixel (depth*channels) */
49834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             png_ptr->row_buf + 1);    /* start of pixel data for row */
49844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
49854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (png_ptr->user_transform_depth != 0)
49864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         row_info->bit_depth = png_ptr->user_transform_depth;
49874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
49884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (png_ptr->user_transform_channels != 0)
49894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         row_info->channels = png_ptr->user_transform_channels;
49904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
49914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      row_info->pixel_depth = (png_byte)(row_info->bit_depth *
49924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          row_info->channels);
49934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
49944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width);
49954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
49964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
49974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
49984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
49994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_TRANSFORMS */
50004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ */
5001