PageRenderTime 105ms CodeModel.GetById 14ms app.highlight 75ms RepoModel.GetById 1ms app.codeStats 1ms

/src/FreeImage/Source/LibPNG/pngrtran.c

https://bitbucket.org/cabalistic/ogredeps/
C | 5023 lines | 3620 code | 639 blank | 764 comment | 777 complexity | ce6789b8366bc3c5861c3acda0174527 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1
   2/* pngrtran.c - transforms the data in a row for PNG readers
   3 *
   4 * Last changed in libpng 1.5.7 [December 15, 2011]
   5 * Copyright (c) 1998-2011 Glenn Randers-Pehrson
   6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
   7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
   8 *
   9 * This code is released under the libpng license.
  10 * For conditions of distribution and use, see the disclaimer
  11 * and license in png.h
  12 *
  13 * This file contains functions optionally called by an application
  14 * in order to tell libpng how to handle data when reading a PNG.
  15 * Transformations that are used in both reading and writing are
  16 * in pngtrans.c.
  17 */
  18
  19#include "pngpriv.h"
  20
  21#ifdef PNG_READ_SUPPORTED
  22
  23/* Set the action on getting a CRC error for an ancillary or critical chunk. */
  24void PNGAPI
  25png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
  26{
  27   png_debug(1, "in png_set_crc_action");
  28
  29   if (png_ptr == NULL)
  30      return;
  31
  32   /* Tell libpng how we react to CRC errors in critical chunks */
  33   switch (crit_action)
  34   {
  35      case PNG_CRC_NO_CHANGE:                        /* Leave setting as is */
  36         break;
  37
  38      case PNG_CRC_WARN_USE:                               /* Warn/use data */
  39         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
  40         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
  41         break;
  42
  43      case PNG_CRC_QUIET_USE:                             /* Quiet/use data */
  44         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
  45         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
  46                           PNG_FLAG_CRC_CRITICAL_IGNORE;
  47         break;
  48
  49      case PNG_CRC_WARN_DISCARD:    /* Not a valid action for critical data */
  50         png_warning(png_ptr,
  51            "Can't discard critical data on CRC error");
  52      case PNG_CRC_ERROR_QUIT:                                /* Error/quit */
  53
  54      case PNG_CRC_DEFAULT:
  55      default:
  56         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
  57         break;
  58   }
  59
  60   /* Tell libpng how we react to CRC errors in ancillary chunks */
  61   switch (ancil_action)
  62   {
  63      case PNG_CRC_NO_CHANGE:                       /* Leave setting as is */
  64         break;
  65
  66      case PNG_CRC_WARN_USE:                              /* Warn/use data */
  67         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
  68         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
  69         break;
  70
  71      case PNG_CRC_QUIET_USE:                            /* Quiet/use data */
  72         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
  73         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
  74                           PNG_FLAG_CRC_ANCILLARY_NOWARN;
  75         break;
  76
  77      case PNG_CRC_ERROR_QUIT:                               /* Error/quit */
  78         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
  79         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
  80         break;
  81
  82      case PNG_CRC_WARN_DISCARD:                      /* Warn/discard data */
  83
  84      case PNG_CRC_DEFAULT:
  85      default:
  86         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
  87         break;
  88   }
  89}
  90
  91#ifdef PNG_READ_BACKGROUND_SUPPORTED
  92/* Handle alpha and tRNS via a background color */
  93void PNGFAPI
  94png_set_background_fixed(png_structp png_ptr,
  95    png_const_color_16p background_color, int background_gamma_code,
  96    int need_expand, png_fixed_point background_gamma)
  97{
  98   png_debug(1, "in png_set_background_fixed");
  99
 100   if (png_ptr == NULL)
 101      return;
 102
 103   if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
 104   {
 105      png_warning(png_ptr, "Application must supply a known background gamma");
 106      return;
 107   }
 108
 109   png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA;
 110   png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
 111   png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
 112
 113   png_memcpy(&(png_ptr->background), background_color,
 114      png_sizeof(png_color_16));
 115   png_ptr->background_gamma = background_gamma;
 116   png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
 117   if (need_expand)
 118      png_ptr->transformations |= PNG_BACKGROUND_EXPAND;
 119   else
 120      png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
 121}
 122
 123#  ifdef PNG_FLOATING_POINT_SUPPORTED
 124void PNGAPI
 125png_set_background(png_structp png_ptr,
 126    png_const_color_16p background_color, int background_gamma_code,
 127    int need_expand, double background_gamma)
 128{
 129   png_set_background_fixed(png_ptr, background_color, background_gamma_code,
 130      need_expand, png_fixed(png_ptr, background_gamma, "png_set_background"));
 131}
 132#  endif  /* FLOATING_POINT */
 133#endif /* READ_BACKGROUND */
 134
 135/* Scale 16-bit depth files to 8-bit depth.  If both of these are set then the
 136 * one that pngrtran does first (scale) happens.  This is necessary to allow the
 137 * TRANSFORM and API behavior to be somewhat consistent, and it's simpler.
 138 */
 139#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
 140void PNGAPI
 141png_set_scale_16(png_structp png_ptr)
 142{
 143   png_debug(1, "in png_set_scale_16");
 144
 145   if (png_ptr == NULL)
 146      return;
 147
 148   png_ptr->transformations |= PNG_SCALE_16_TO_8;
 149}
 150#endif
 151
 152#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
 153/* Chop 16-bit depth files to 8-bit depth */
 154void PNGAPI
 155png_set_strip_16(png_structp png_ptr)
 156{
 157   png_debug(1, "in png_set_strip_16");
 158
 159   if (png_ptr == NULL)
 160      return;
 161
 162   png_ptr->transformations |= PNG_16_TO_8;
 163}
 164#endif
 165
 166#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
 167void PNGAPI
 168png_set_strip_alpha(png_structp png_ptr)
 169{
 170   png_debug(1, "in png_set_strip_alpha");
 171
 172   if (png_ptr == NULL)
 173      return;
 174
 175   png_ptr->transformations |= PNG_STRIP_ALPHA;
 176}
 177#endif
 178
 179#if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED)
 180static png_fixed_point
 181translate_gamma_flags(png_structp png_ptr, png_fixed_point output_gamma,
 182   int is_screen)
 183{
 184   /* Check for flag values.  The main reason for having the old Mac value as a
 185    * flag is that it is pretty near impossible to work out what the correct
 186    * value is from Apple documentation - a working Mac system is needed to
 187    * discover the value!
 188    */
 189   if (output_gamma == PNG_DEFAULT_sRGB ||
 190      output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB)
 191   {
 192      /* If there is no sRGB support this just sets the gamma to the standard
 193       * sRGB value.  (This is a side effect of using this function!)
 194       */
 195#     ifdef PNG_READ_sRGB_SUPPORTED
 196         png_ptr->flags |= PNG_FLAG_ASSUME_sRGB;
 197#     endif
 198      if (is_screen)
 199         output_gamma = PNG_GAMMA_sRGB;
 200      else
 201         output_gamma = PNG_GAMMA_sRGB_INVERSE;
 202   }
 203
 204   else if (output_gamma == PNG_GAMMA_MAC_18 ||
 205      output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18)
 206   {
 207      if (is_screen)
 208         output_gamma = PNG_GAMMA_MAC_OLD;
 209      else
 210         output_gamma = PNG_GAMMA_MAC_INVERSE;
 211   }
 212
 213   return output_gamma;
 214}
 215
 216#  ifdef PNG_FLOATING_POINT_SUPPORTED
 217static png_fixed_point
 218convert_gamma_value(png_structp png_ptr, double output_gamma)
 219{
 220   /* The following silently ignores cases where fixed point (times 100,000)
 221    * gamma values are passed to the floating point API.  This is safe and it
 222    * means the fixed point constants work just fine with the floating point
 223    * API.  The alternative would just lead to undetected errors and spurious
 224    * bug reports.  Negative values fail inside the _fixed API unless they
 225    * correspond to the flag values.
 226    */
 227   if (output_gamma > 0 && output_gamma < 128)
 228      output_gamma *= PNG_FP_1;
 229
 230   /* This preserves -1 and -2 exactly: */
 231   output_gamma = floor(output_gamma + .5);
 232
 233   if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN)
 234      png_fixed_error(png_ptr, "gamma value");
 235
 236   return (png_fixed_point)output_gamma;
 237}
 238#  endif
 239#endif /* READ_ALPHA_MODE || READ_GAMMA */
 240
 241#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
 242void PNGFAPI
 243png_set_alpha_mode_fixed(png_structp png_ptr, int mode,
 244   png_fixed_point output_gamma)
 245{
 246   int compose = 0;
 247   png_fixed_point file_gamma;
 248
 249   png_debug(1, "in png_set_alpha_mode");
 250
 251   if (png_ptr == NULL)
 252      return;
 253
 254   output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/);
 255
 256   /* Validate the value to ensure it is in a reasonable range. The value
 257    * is expected to be 1 or greater, but this range test allows for some
 258    * viewing correction values.  The intent is to weed out users of this API
 259    * who use the inverse of the gamma value accidentally!  Since some of these
 260    * values are reasonable this may have to be changed.
 261    */
 262   if (output_gamma < 70000 || output_gamma > 300000)
 263      png_error(png_ptr, "output gamma out of expected range");
 264
 265   /* The default file gamma is the inverse of the output gamma; the output
 266    * gamma may be changed below so get the file value first:
 267    */
 268   file_gamma = png_reciprocal(output_gamma);
 269
 270   /* There are really 8 possibilities here, composed of any combination
 271    * of:
 272    *
 273    *    premultiply the color channels
 274    *    do not encode non-opaque pixels
 275    *    encode the alpha as well as the color channels
 276    *
 277    * The differences disappear if the input/output ('screen') gamma is 1.0,
 278    * because then the encoding is a no-op and there is only the choice of
 279    * premultiplying the color channels or not.
 280    *
 281    * png_set_alpha_mode and png_set_background interact because both use
 282    * png_compose to do the work.  Calling both is only useful when
 283    * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along
 284    * with a default gamma value.  Otherwise PNG_COMPOSE must not be set.
 285    */
 286   switch (mode)
 287   {
 288      case PNG_ALPHA_PNG:        /* default: png standard */
 289         /* No compose, but it may be set by png_set_background! */
 290         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
 291         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
 292         break;
 293
 294      case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */
 295         compose = 1;
 296         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
 297         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
 298         /* The output is linear: */
 299         output_gamma = PNG_FP_1;
 300         break;
 301
 302      case PNG_ALPHA_OPTIMIZED:  /* associated, non-opaque pixels linear */
 303         compose = 1;
 304         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
 305         png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA;
 306         /* output_gamma records the encoding of opaque pixels! */
 307         break;
 308
 309      case PNG_ALPHA_BROKEN:     /* associated, non-linear, alpha encoded */
 310         compose = 1;
 311         png_ptr->transformations |= PNG_ENCODE_ALPHA;
 312         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
 313         break;
 314
 315      default:
 316         png_error(png_ptr, "invalid alpha mode");
 317   }
 318
 319   /* Only set the default gamma if the file gamma has not been set (this has
 320    * the side effect that the gamma in a second call to png_set_alpha_mode will
 321    * be ignored.)
 322    */
 323   if (png_ptr->gamma == 0)
 324      png_ptr->gamma = file_gamma;
 325
 326   /* But always set the output gamma: */
 327   png_ptr->screen_gamma = output_gamma;
 328
 329   /* Finally, if pre-multiplying, set the background fields to achieve the
 330    * desired result.
 331    */
 332   if (compose)
 333   {
 334      /* And obtain alpha pre-multiplication by composing on black: */
 335      png_memset(&png_ptr->background, 0, sizeof png_ptr->background);
 336      png_ptr->background_gamma = png_ptr->gamma; /* just in case */
 337      png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE;
 338      png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
 339
 340      if (png_ptr->transformations & PNG_COMPOSE)
 341         png_error(png_ptr,
 342            "conflicting calls to set alpha mode and background");
 343
 344      png_ptr->transformations |= PNG_COMPOSE;
 345   }
 346
 347   /* New API, make sure apps call the correct initializers: */
 348   png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED;
 349}
 350
 351#  ifdef PNG_FLOATING_POINT_SUPPORTED
 352void PNGAPI
 353png_set_alpha_mode(png_structp png_ptr, int mode, double output_gamma)
 354{
 355   png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr,
 356      output_gamma));
 357}
 358#  endif
 359#endif
 360
 361#ifdef PNG_READ_QUANTIZE_SUPPORTED
 362/* Dither file to 8-bit.  Supply a palette, the current number
 363 * of elements in the palette, the maximum number of elements
 364 * allowed, and a histogram if possible.  If the current number
 365 * of colors is greater then the maximum number, the palette will be
 366 * modified to fit in the maximum number.  "full_quantize" indicates
 367 * whether we need a quantizing cube set up for RGB images, or if we
 368 * simply are reducing the number of colors in a paletted image.
 369 */
 370
 371typedef struct png_dsort_struct
 372{
 373   struct png_dsort_struct FAR * next;
 374   png_byte left;
 375   png_byte right;
 376} png_dsort;
 377typedef png_dsort FAR *       png_dsortp;
 378typedef png_dsort FAR * FAR * png_dsortpp;
 379
 380void PNGAPI
 381png_set_quantize(png_structp png_ptr, png_colorp palette,
 382    int num_palette, int maximum_colors, png_const_uint_16p histogram,
 383    int full_quantize)
 384{
 385   png_debug(1, "in png_set_quantize");
 386
 387   if (png_ptr == NULL)
 388      return;
 389
 390   png_ptr->transformations |= PNG_QUANTIZE;
 391
 392   if (!full_quantize)
 393   {
 394      int i;
 395
 396      png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,
 397          (png_uint_32)(num_palette * png_sizeof(png_byte)));
 398      for (i = 0; i < num_palette; i++)
 399         png_ptr->quantize_index[i] = (png_byte)i;
 400   }
 401
 402   if (num_palette > maximum_colors)
 403   {
 404      if (histogram != NULL)
 405      {
 406         /* This is easy enough, just throw out the least used colors.
 407          * Perhaps not the best solution, but good enough.
 408          */
 409
 410         int i;
 411
 412         /* Initialize an array to sort colors */
 413         png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,
 414             (png_uint_32)(num_palette * png_sizeof(png_byte)));
 415
 416         /* Initialize the quantize_sort array */
 417         for (i = 0; i < num_palette; i++)
 418            png_ptr->quantize_sort[i] = (png_byte)i;
 419
 420         /* Find the least used palette entries by starting a
 421          * bubble sort, and running it until we have sorted
 422          * out enough colors.  Note that we don't care about
 423          * sorting all the colors, just finding which are
 424          * least used.
 425          */
 426
 427         for (i = num_palette - 1; i >= maximum_colors; i--)
 428         {
 429            int done; /* To stop early if the list is pre-sorted */
 430            int j;
 431
 432            done = 1;
 433            for (j = 0; j < i; j++)
 434            {
 435               if (histogram[png_ptr->quantize_sort[j]]
 436                   < histogram[png_ptr->quantize_sort[j + 1]])
 437               {
 438                  png_byte t;
 439
 440                  t = png_ptr->quantize_sort[j];
 441                  png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1];
 442                  png_ptr->quantize_sort[j + 1] = t;
 443                  done = 0;
 444               }
 445            }
 446
 447            if (done)
 448               break;
 449         }
 450
 451         /* Swap the palette around, and set up a table, if necessary */
 452         if (full_quantize)
 453         {
 454            int j = num_palette;
 455
 456            /* Put all the useful colors within the max, but don't
 457             * move the others.
 458             */
 459            for (i = 0; i < maximum_colors; i++)
 460            {
 461               if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
 462               {
 463                  do
 464                     j--;
 465                  while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
 466
 467                  palette[i] = palette[j];
 468               }
 469            }
 470         }
 471         else
 472         {
 473            int j = num_palette;
 474
 475            /* Move all the used colors inside the max limit, and
 476             * develop a translation table.
 477             */
 478            for (i = 0; i < maximum_colors; i++)
 479            {
 480               /* Only move the colors we need to */
 481               if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
 482               {
 483                  png_color tmp_color;
 484
 485                  do
 486                     j--;
 487                  while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
 488
 489                  tmp_color = palette[j];
 490                  palette[j] = palette[i];
 491                  palette[i] = tmp_color;
 492                  /* Indicate where the color went */
 493                  png_ptr->quantize_index[j] = (png_byte)i;
 494                  png_ptr->quantize_index[i] = (png_byte)j;
 495               }
 496            }
 497
 498            /* Find closest color for those colors we are not using */
 499            for (i = 0; i < num_palette; i++)
 500            {
 501               if ((int)png_ptr->quantize_index[i] >= maximum_colors)
 502               {
 503                  int min_d, k, min_k, d_index;
 504
 505                  /* Find the closest color to one we threw out */
 506                  d_index = png_ptr->quantize_index[i];
 507                  min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
 508                  for (k = 1, min_k = 0; k < maximum_colors; k++)
 509                  {
 510                     int d;
 511
 512                     d = PNG_COLOR_DIST(palette[d_index], palette[k]);
 513
 514                     if (d < min_d)
 515                     {
 516                        min_d = d;
 517                        min_k = k;
 518                     }
 519                  }
 520                  /* Point to closest color */
 521                  png_ptr->quantize_index[i] = (png_byte)min_k;
 522               }
 523            }
 524         }
 525         png_free(png_ptr, png_ptr->quantize_sort);
 526         png_ptr->quantize_sort = NULL;
 527      }
 528      else
 529      {
 530         /* This is much harder to do simply (and quickly).  Perhaps
 531          * we need to go through a median cut routine, but those
 532          * don't always behave themselves with only a few colors
 533          * as input.  So we will just find the closest two colors,
 534          * and throw out one of them (chosen somewhat randomly).
 535          * [We don't understand this at all, so if someone wants to
 536          *  work on improving it, be our guest - AED, GRP]
 537          */
 538         int i;
 539         int max_d;
 540         int num_new_palette;
 541         png_dsortp t;
 542         png_dsortpp hash;
 543
 544         t = NULL;
 545
 546         /* Initialize palette index arrays */
 547         png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
 548             (png_uint_32)(num_palette * png_sizeof(png_byte)));
 549         png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
 550             (png_uint_32)(num_palette * png_sizeof(png_byte)));
 551
 552         /* Initialize the sort array */
 553         for (i = 0; i < num_palette; i++)
 554         {
 555            png_ptr->index_to_palette[i] = (png_byte)i;
 556            png_ptr->palette_to_index[i] = (png_byte)i;
 557         }
 558
 559         hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 *
 560             png_sizeof(png_dsortp)));
 561
 562         num_new_palette = num_palette;
 563
 564         /* Initial wild guess at how far apart the farthest pixel
 565          * pair we will be eliminating will be.  Larger
 566          * numbers mean more areas will be allocated, Smaller
 567          * numbers run the risk of not saving enough data, and
 568          * having to do this all over again.
 569          *
 570          * I have not done extensive checking on this number.
 571          */
 572         max_d = 96;
 573
 574         while (num_new_palette > maximum_colors)
 575         {
 576            for (i = 0; i < num_new_palette - 1; i++)
 577            {
 578               int j;
 579
 580               for (j = i + 1; j < num_new_palette; j++)
 581               {
 582                  int d;
 583
 584                  d = PNG_COLOR_DIST(palette[i], palette[j]);
 585
 586                  if (d <= max_d)
 587                  {
 588
 589                     t = (png_dsortp)png_malloc_warn(png_ptr,
 590                         (png_uint_32)(png_sizeof(png_dsort)));
 591
 592                     if (t == NULL)
 593                         break;
 594
 595                     t->next = hash[d];
 596                     t->left = (png_byte)i;
 597                     t->right = (png_byte)j;
 598                     hash[d] = t;
 599                  }
 600               }
 601               if (t == NULL)
 602                  break;
 603            }
 604
 605            if (t != NULL)
 606            for (i = 0; i <= max_d; i++)
 607            {
 608               if (hash[i] != NULL)
 609               {
 610                  png_dsortp p;
 611
 612                  for (p = hash[i]; p; p = p->next)
 613                  {
 614                     if ((int)png_ptr->index_to_palette[p->left]
 615                         < num_new_palette &&
 616                         (int)png_ptr->index_to_palette[p->right]
 617                         < num_new_palette)
 618                     {
 619                        int j, next_j;
 620
 621                        if (num_new_palette & 0x01)
 622                        {
 623                           j = p->left;
 624                           next_j = p->right;
 625                        }
 626                        else
 627                        {
 628                           j = p->right;
 629                           next_j = p->left;
 630                        }
 631
 632                        num_new_palette--;
 633                        palette[png_ptr->index_to_palette[j]]
 634                            = palette[num_new_palette];
 635                        if (!full_quantize)
 636                        {
 637                           int k;
 638
 639                           for (k = 0; k < num_palette; k++)
 640                           {
 641                              if (png_ptr->quantize_index[k] ==
 642                                  png_ptr->index_to_palette[j])
 643                                 png_ptr->quantize_index[k] =
 644                                     png_ptr->index_to_palette[next_j];
 645
 646                              if ((int)png_ptr->quantize_index[k] ==
 647                                  num_new_palette)
 648                                 png_ptr->quantize_index[k] =
 649                                     png_ptr->index_to_palette[j];
 650                           }
 651                        }
 652
 653                        png_ptr->index_to_palette[png_ptr->palette_to_index
 654                            [num_new_palette]] = png_ptr->index_to_palette[j];
 655
 656                        png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
 657                            = png_ptr->palette_to_index[num_new_palette];
 658
 659                        png_ptr->index_to_palette[j] =
 660                            (png_byte)num_new_palette;
 661
 662                        png_ptr->palette_to_index[num_new_palette] =
 663                            (png_byte)j;
 664                     }
 665                     if (num_new_palette <= maximum_colors)
 666                        break;
 667                  }
 668                  if (num_new_palette <= maximum_colors)
 669                     break;
 670               }
 671            }
 672
 673            for (i = 0; i < 769; i++)
 674            {
 675               if (hash[i] != NULL)
 676               {
 677                  png_dsortp p = hash[i];
 678                  while (p)
 679                  {
 680                     t = p->next;
 681                     png_free(png_ptr, p);
 682                     p = t;
 683                  }
 684               }
 685               hash[i] = 0;
 686            }
 687            max_d += 96;
 688         }
 689         png_free(png_ptr, hash);
 690         png_free(png_ptr, png_ptr->palette_to_index);
 691         png_free(png_ptr, png_ptr->index_to_palette);
 692         png_ptr->palette_to_index = NULL;
 693         png_ptr->index_to_palette = NULL;
 694      }
 695      num_palette = maximum_colors;
 696   }
 697   if (png_ptr->palette == NULL)
 698   {
 699      png_ptr->palette = palette;
 700   }
 701   png_ptr->num_palette = (png_uint_16)num_palette;
 702
 703   if (full_quantize)
 704   {
 705      int i;
 706      png_bytep distance;
 707      int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS +
 708          PNG_QUANTIZE_BLUE_BITS;
 709      int num_red = (1 << PNG_QUANTIZE_RED_BITS);
 710      int num_green = (1 << PNG_QUANTIZE_GREEN_BITS);
 711      int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS);
 712      png_size_t num_entries = ((png_size_t)1 << total_bits);
 713
 714      png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr,
 715          (png_uint_32)(num_entries * png_sizeof(png_byte)));
 716
 717      distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
 718          png_sizeof(png_byte)));
 719
 720      png_memset(distance, 0xff, num_entries * png_sizeof(png_byte));
 721
 722      for (i = 0; i < num_palette; i++)
 723      {
 724         int ir, ig, ib;
 725         int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS));
 726         int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS));
 727         int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS));
 728
 729         for (ir = 0; ir < num_red; ir++)
 730         {
 731            /* int dr = abs(ir - r); */
 732            int dr = ((ir > r) ? ir - r : r - ir);
 733            int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS +
 734                PNG_QUANTIZE_GREEN_BITS));
 735
 736            for (ig = 0; ig < num_green; ig++)
 737            {
 738               /* int dg = abs(ig - g); */
 739               int dg = ((ig > g) ? ig - g : g - ig);
 740               int dt = dr + dg;
 741               int dm = ((dr > dg) ? dr : dg);
 742               int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS);
 743
 744               for (ib = 0; ib < num_blue; ib++)
 745               {
 746                  int d_index = index_g | ib;
 747                  /* int db = abs(ib - b); */
 748                  int db = ((ib > b) ? ib - b : b - ib);
 749                  int dmax = ((dm > db) ? dm : db);
 750                  int d = dmax + dt + db;
 751
 752                  if (d < (int)distance[d_index])
 753                  {
 754                     distance[d_index] = (png_byte)d;
 755                     png_ptr->palette_lookup[d_index] = (png_byte)i;
 756                  }
 757               }
 758            }
 759         }
 760      }
 761
 762      png_free(png_ptr, distance);
 763   }
 764}
 765#endif /* PNG_READ_QUANTIZE_SUPPORTED */
 766
 767#ifdef PNG_READ_GAMMA_SUPPORTED
 768void PNGFAPI
 769png_set_gamma_fixed(png_structp png_ptr, png_fixed_point scrn_gamma,
 770   png_fixed_point file_gamma)
 771{
 772   png_debug(1, "in png_set_gamma_fixed");
 773
 774   if (png_ptr == NULL)
 775      return;
 776
 777   /* New in libpng-1.5.4 - reserve particular negative values as flags. */
 778   scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/);
 779   file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/);
 780
 781#if PNG_LIBPNG_VER >= 10600
 782   /* Checking the gamma values for being >0 was added in 1.5.4 along with the
 783    * premultiplied alpha support; this actually hides an undocumented feature
 784    * of the previous implementation which allowed gamma processing to be
 785    * disabled in background handling.  There is no evidence (so far) that this
 786    * was being used; however, png_set_background itself accepted and must still
 787    * accept '0' for the gamma value it takes, because it isn't always used.
 788    *
 789    * Since this is an API change (albeit a very minor one that removes an
 790    * undocumented API feature) it will not be made until libpng-1.6.0.
 791    */
 792   if (file_gamma <= 0)
 793      png_error(png_ptr, "invalid file gamma in png_set_gamma");
 794
 795   if (scrn_gamma <= 0)
 796      png_error(png_ptr, "invalid screen gamma in png_set_gamma");
 797#endif
 798
 799   /* Set the gamma values unconditionally - this overrides the value in the PNG
 800    * file if a gAMA chunk was present.  png_set_alpha_mode provides a
 801    * different, easier, way to default the file gamma.
 802    */
 803   png_ptr->gamma = file_gamma;
 804   png_ptr->screen_gamma = scrn_gamma;
 805}
 806
 807#  ifdef PNG_FLOATING_POINT_SUPPORTED
 808void PNGAPI
 809png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
 810{
 811   png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma),
 812      convert_gamma_value(png_ptr, file_gamma));
 813}
 814#  endif /* FLOATING_POINT_SUPPORTED */
 815#endif /* READ_GAMMA */
 816
 817#ifdef PNG_READ_EXPAND_SUPPORTED
 818/* Expand paletted images to RGB, expand grayscale images of
 819 * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
 820 * to alpha channels.
 821 */
 822void PNGAPI
 823png_set_expand(png_structp png_ptr)
 824{
 825   png_debug(1, "in png_set_expand");
 826
 827   if (png_ptr == NULL)
 828      return;
 829
 830   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
 831   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
 832}
 833
 834/* GRR 19990627:  the following three functions currently are identical
 835 *  to png_set_expand().  However, it is entirely reasonable that someone
 836 *  might wish to expand an indexed image to RGB but *not* expand a single,
 837 *  fully transparent palette entry to a full alpha channel--perhaps instead
 838 *  convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
 839 *  the transparent color with a particular RGB value, or drop tRNS entirely.
 840 *  IOW, a future version of the library may make the transformations flag
 841 *  a bit more fine-grained, with separate bits for each of these three
 842 *  functions.
 843 *
 844 *  More to the point, these functions make it obvious what libpng will be
 845 *  doing, whereas "expand" can (and does) mean any number of things.
 846 *
 847 *  GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified
 848 *  to expand only the sample depth but not to expand the tRNS to alpha
 849 *  and its name was changed to png_set_expand_gray_1_2_4_to_8().
 850 */
 851
 852/* Expand paletted images to RGB. */
 853void PNGAPI
 854png_set_palette_to_rgb(png_structp png_ptr)
 855{
 856   png_debug(1, "in png_set_palette_to_rgb");
 857
 858   if (png_ptr == NULL)
 859      return;
 860
 861   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
 862   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
 863}
 864
 865/* Expand grayscale images of less than 8-bit depth to 8 bits. */
 866void PNGAPI
 867png_set_expand_gray_1_2_4_to_8(png_structp png_ptr)
 868{
 869   png_debug(1, "in png_set_expand_gray_1_2_4_to_8");
 870
 871   if (png_ptr == NULL)
 872      return;
 873
 874   png_ptr->transformations |= PNG_EXPAND;
 875   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
 876}
 877
 878
 879
 880/* Expand tRNS chunks to alpha channels. */
 881void PNGAPI
 882png_set_tRNS_to_alpha(png_structp png_ptr)
 883{
 884   png_debug(1, "in png_set_tRNS_to_alpha");
 885
 886   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
 887   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
 888}
 889#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
 890
 891#ifdef PNG_READ_EXPAND_16_SUPPORTED
 892/* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise
 893 * it may not work correctly.)
 894 */
 895void PNGAPI
 896png_set_expand_16(png_structp png_ptr)
 897{
 898   png_debug(1, "in png_set_expand_16");
 899
 900   if (png_ptr == NULL)
 901      return;
 902
 903   png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS);
 904   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
 905
 906   /* New API, make sure apps call the correct initializers: */
 907   png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED;
 908}
 909#endif
 910
 911#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
 912void PNGAPI
 913png_set_gray_to_rgb(png_structp png_ptr)
 914{
 915   png_debug(1, "in png_set_gray_to_rgb");
 916
 917   if (png_ptr != NULL)
 918   {
 919      /* Because rgb must be 8 bits or more: */
 920      png_set_expand_gray_1_2_4_to_8(png_ptr);
 921      png_ptr->transformations |= PNG_GRAY_TO_RGB;
 922      png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
 923   }
 924}
 925#endif
 926
 927#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
 928void PNGFAPI
 929png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
 930    png_fixed_point red, png_fixed_point green)
 931{
 932   png_debug(1, "in png_set_rgb_to_gray");
 933
 934   if (png_ptr == NULL)
 935      return;
 936
 937   switch(error_action)
 938   {
 939      case PNG_ERROR_ACTION_NONE:
 940         png_ptr->transformations |= PNG_RGB_TO_GRAY;
 941         break;
 942
 943      case PNG_ERROR_ACTION_WARN:
 944         png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
 945         break;
 946
 947      case PNG_ERROR_ACTION_ERROR:
 948         png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
 949         break;
 950
 951      default:
 952         png_error(png_ptr, "invalid error action to rgb_to_gray");
 953         break;
 954   }
 955   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 956#ifdef PNG_READ_EXPAND_SUPPORTED
 957      png_ptr->transformations |= PNG_EXPAND;
 958#else
 959   {
 960      png_warning(png_ptr,
 961        "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");
 962
 963      png_ptr->transformations &= ~PNG_RGB_TO_GRAY;
 964   }
 965#endif
 966   {
 967      if (red >= 0 && green >= 0 && red + green <= PNG_FP_1)
 968      {
 969         png_uint_16 red_int, green_int;
 970
 971         /* NOTE: this calculation does not round, but this behavior is retained
 972          * for consistency, the inaccuracy is very small.  The code here always
 973          * overwrites the coefficients, regardless of whether they have been
 974          * defaulted or set already.
 975          */
 976         red_int = (png_uint_16)(((png_uint_32)red*32768)/100000);
 977         green_int = (png_uint_16)(((png_uint_32)green*32768)/100000);
 978
 979         png_ptr->rgb_to_gray_red_coeff   = red_int;
 980         png_ptr->rgb_to_gray_green_coeff = green_int;
 981         png_ptr->rgb_to_gray_coefficients_set = 1;
 982      }
 983
 984      else
 985      {
 986         if (red >= 0 && green >= 0)
 987            png_warning(png_ptr,
 988               "ignoring out of range rgb_to_gray coefficients");
 989
 990         /* Use the defaults, from the cHRM chunk if set, else the historical
 991          * values which are close to the sRGB/HDTV/ITU-Rec 709 values.  See
 992          * png_do_rgb_to_gray for more discussion of the values.  In this case
 993          * the coefficients are not marked as 'set' and are not overwritten if
 994          * something has already provided a default.
 995          */
 996         if (png_ptr->rgb_to_gray_red_coeff == 0 &&
 997            png_ptr->rgb_to_gray_green_coeff == 0)
 998         {
 999            png_ptr->rgb_to_gray_red_coeff   = 6968;
1000            png_ptr->rgb_to_gray_green_coeff = 23434;
1001            /* png_ptr->rgb_to_gray_blue_coeff  = 2366; */
1002         }
1003      }
1004   }
1005}
1006
1007#ifdef PNG_FLOATING_POINT_SUPPORTED
1008/* Convert a RGB image to a grayscale of the same width.  This allows us,
1009 * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
1010 */
1011
1012void PNGAPI
1013png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
1014   double green)
1015{
1016   if (png_ptr == NULL)
1017      return;
1018
1019   png_set_rgb_to_gray_fixed(png_ptr, error_action,
1020      png_fixed(png_ptr, red, "rgb to gray red coefficient"),
1021      png_fixed(png_ptr, green, "rgb to gray green coefficient"));
1022}
1023#endif /* FLOATING POINT */
1024
1025#endif
1026
1027#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
1028    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
1029void PNGAPI
1030png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
1031    read_user_transform_fn)
1032{
1033   png_debug(1, "in png_set_read_user_transform_fn");
1034
1035   if (png_ptr == NULL)
1036      return;
1037
1038#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
1039   png_ptr->transformations |= PNG_USER_TRANSFORM;
1040   png_ptr->read_user_transform_fn = read_user_transform_fn;
1041#endif
1042}
1043#endif
1044
1045#ifdef PNG_READ_TRANSFORMS_SUPPORTED
1046#ifdef PNG_READ_GAMMA_SUPPORTED
1047/* In the case of gamma transformations only do transformations on images where
1048 * the [file] gamma and screen_gamma are not close reciprocals, otherwise it
1049 * slows things down slightly, and also needlessly introduces small errors.
1050 */
1051static int /* PRIVATE */
1052png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma)
1053{
1054   /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma
1055    * correction as a difference of the overall transform from 1.0
1056    *
1057    * We want to compare the threshold with s*f - 1, if we get
1058    * overflow here it is because of wacky gamma values so we
1059    * turn on processing anyway.
1060    */
1061   png_fixed_point gtest;
1062   return !png_muldiv(&gtest, screen_gamma, file_gamma, PNG_FP_1) ||
1063       png_gamma_significant(gtest);
1064}
1065#endif
1066
1067/* Initialize everything needed for the read.  This includes modifying
1068 * the palette.
1069 */
1070
1071/*For the moment 'png_init_palette_transformations' and
1072 * 'png_init_rgb_transformations' only do some flag canceling optimizations.
1073 * The intent is that these two routines should have palette or rgb operations
1074 * extracted from 'png_init_read_transformations'.
1075 */
1076static void /* PRIVATE */
1077png_init_palette_transformations(png_structp png_ptr)
1078{
1079   /* Called to handle the (input) palette case.  In png_do_read_transformations
1080    * the first step is to expand the palette if requested, so this code must
1081    * take care to only make changes that are invariant with respect to the
1082    * palette expansion, or only do them if there is no expansion.
1083    *
1084    * STRIP_ALPHA has already been handled in the caller (by setting num_trans
1085    * to 0.)
1086    */
1087   int input_has_alpha = 0;
1088   int input_has_transparency = 0;
1089
1090   if (png_ptr->num_trans > 0)
1091   {
1092      int i;
1093
1094      /* Ignore if all the entries are opaque (unlikely!) */
1095      for (i=0; i<png_ptr->num_trans; ++i)
1096         if (png_ptr->trans_alpha[i] == 255)
1097            continue;
1098         else if (png_ptr->trans_alpha[i] == 0)
1099            input_has_transparency = 1;
1100         else
1101            input_has_alpha = 1;
1102   }
1103
1104   /* If no alpha we can optimize. */
1105   if (!input_has_alpha)
1106   {
1107      /* Any alpha means background and associative alpha processing is
1108       * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA
1109       * and ENCODE_ALPHA are irrelevant.
1110       */
1111      png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
1112      png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1113
1114      if (!input_has_transparency)
1115         png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
1116   }
1117
1118#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
1119   /* png_set_background handling - deals with the complexity of whether the
1120    * background color is in the file format or the screen format in the case
1121    * where an 'expand' will happen.
1122    */
1123
1124   /* The following code cannot be entered in the alpha pre-multiplication case
1125    * because PNG_BACKGROUND_EXPAND is cancelled below.
1126    */
1127   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
1128       (png_ptr->transformations & PNG_EXPAND))
1129   {
1130      {
1131         png_ptr->background.red   =
1132             png_ptr->palette[png_ptr->background.index].red;
1133         png_ptr->background.green =
1134             png_ptr->palette[png_ptr->background.index].green;
1135         png_ptr->background.blue  =
1136             png_ptr->palette[png_ptr->background.index].blue;
1137
1138#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
1139        if (png_ptr->transformations & PNG_INVERT_ALPHA)
1140        {
1141           if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
1142           {
1143              /* Invert the alpha channel (in tRNS) unless the pixels are
1144               * going to be expanded, in which case leave it for later
1145               */
1146              int i, istop = png_ptr->num_trans;
1147
1148              for (i=0; i<istop; i++)
1149                 png_ptr->trans_alpha[i] = (png_byte)(255 -
1150                    png_ptr->trans_alpha[i]);
1151           }
1152        }
1153#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */
1154      }
1155   } /* background expand and (therefore) no alpha association. */
1156#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */
1157}
1158
1159static void /* PRIVATE */
1160png_init_rgb_transformations(png_structp png_ptr)
1161{
1162   /* Added to libpng-1.5.4: check the color type to determine whether there
1163    * is any alpha or transparency in the image and simply cancel the
1164    * background and alpha mode stuff if there isn't.
1165    */
1166   int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0;
1167   int input_has_transparency = png_ptr->num_trans > 0;
1168
1169   /* If no alpha we can optimize. */
1170   if (!input_has_alpha)
1171   {
1172      /* Any alpha means background and associative alpha processing is
1173       * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA
1174       * and ENCODE_ALPHA are irrelevant.
1175       */
1176#     ifdef PNG_READ_ALPHA_MODE_SUPPORTED
1177         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
1178         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1179#     endif
1180
1181      if (!input_has_transparency)
1182         png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
1183   }
1184
1185#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
1186   /* png_set_background handling - deals with the complexity of whether the
1187    * background color is in the file format or the screen format in the case
1188    * where an 'expand' will happen.
1189    */
1190
1191   /* The following code cannot be entered in the alpha pre-multiplication case
1192    * because PNG_BACKGROUND_EXPAND is cancelled below.
1193    */
1194   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
1195       (png_ptr->transformations & PNG_EXPAND) &&
1196       !(png_ptr->color_type & PNG_COLOR_MASK_COLOR))
1197       /* i.e., GRAY or GRAY_ALPHA */
1198   {
1199      {
1200         /* Expand background and tRNS chunks */
1201         int gray = png_ptr->background.gray;
1202         int trans_gray = png_ptr->trans_color.gray;
1203
1204         switch (png_ptr->bit_depth)
1205         {
1206            case 1:
1207               gray *= 0xff;
1208               trans_gray *= 0xff;
1209               break;
1210
1211            case 2:
1212               gray *= 0x55;
1213               trans_gray *= 0x55;
1214               break;
1215
1216            case 4:
1217               gray *= 0x11;
1218               trans_gray *= 0x11;
1219               break;
1220
1221            default:
1222
1223            case 8:
1224               /* Already 8 bits, fall through */
1225
1226            case 16:
1227               /* Already a full 16 bits */
1228               break;
1229         }
1230
1231         png_ptr->background.red = png_ptr->background.green =
1232            png_ptr->background.blue = (png_uint_16)gray;
1233
1234         if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
1235         {
1236            png_ptr->trans_color.red = png_ptr->trans_color.green =
1237               png_ptr->trans_color.blue = (png_uint_16)trans_gray;
1238         }
1239      }
1240   } /* background expand and (therefore) no alpha association. */
1241#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */
1242}
1243
1244void /* PRIVATE */
1245png_init_read_transformations(png_structp png_ptr)
1246{
1247   png_debug(1, "in png_init_read_transformations");
1248
1249   /* This internal function is called from png_read_start_row in pngrutil.c
1250    * and it is called before the 'rowbytes' calculation is done, so the code
1251    * in here can change or update the transformations flags.
1252    *
1253    * First do updates that do not depend on the details of the PNG image data
1254    * being processed.
1255    */
1256
1257#ifdef PNG_READ_GAMMA_SUPPORTED
1258   /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds
1259    * png_set_alpha_mode and this is another source for a default file gamma so
1260    * the test needs to be performed later - here.  In addition prior to 1.5.4
1261    * the tests were repeated for the PALETTE color type here - this is no
1262    * longer necessary (and doesn't seem to have been necessary before.)
1263    */
1264   {
1265      /* The following temporary indicates if overall gamma correction is
1266       * required.
1267       */
1268      int gamma_correction = 0;
1269
1270      if (png_ptr->gamma != 0) /* has been set */
1271      {
1272         if (png_ptr->screen_gamma != 0) /* screen set too */
1273            gamma_correction = png_gamma_threshold(png_ptr->gamma,
1274               png_ptr->screen_gamma);
1275
1276         else
1277            /* Assume the output matches the input; a long time default behavior
1278             * of libpng, although the standard has nothing to say about this.
1279             */
1280            png_ptr->screen_gamma = png_reciprocal(png_ptr->gamma);
1281      }
1282
1283      else if (png_ptr->screen_gamma != 0)
1284         /* The converse - assume the file matches the screen, note that this
1285          * perhaps undesireable default can (from 1.5.4) be changed by calling
1286          * png_set_alpha_mode (even if the alpha handling mode isn't required
1287          * or isn't changed from the default.)
1288          */
1289         png_ptr->gamma = png_reciprocal(png_ptr->screen_gamma);
1290
1291      else /* neither are set */
1292         /* Just in case the following prevents any processing - file and screen
1293          * are both assumed to be linear and there is no way to introduce a
1294          * third gamma value other than png_set_background with 'UNIQUE', and,
1295          * prior to 1.5.4
1296          */
1297         png_ptr->screen_gamma = png_ptr->gamma = PNG_FP_1;
1298
1299      /* Now turn the gamma transformation on or off as appropriate.  Notice
1300       * that PNG_GAMMA just refers to the file->screen correction.  Alpha
1301       * composition may independently cause gamma correction because it needs
1302       * linear data (e.g. if the file has a gAMA chunk but the screen gamma
1303       * hasn't been specified.)  In any case this flag may get turned off in
1304       * the code immediately below if the transform can be handled outside the
1305       * row loop.
1306       */
1307      if (gamma_correction)
1308         png_ptr->transformations |= PNG_GAMMA;
1309
1310      else
1311         png_ptr->transformations &= ~PNG_GAMMA;
1312   }
1313#endif
1314
1315   /* Certain transformations have the effect of preventing other
1316    * transformations that happen afterward in png_do_read_transformations,
1317    * resolve the interdependencies here.  From the code of
1318    * png_do_read_transformations the order is:
1319    *
1320    *  1) PNG_EXPAND (including PNG_EXPAND_tRNS)
1321    *  2) PNG_STRIP_ALPHA (if no compose)
1322    *  3) PNG_RGB_TO_GRAY
1323    *  4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY
1324    *  5) PNG_COMPOSE
1325    *  6) PNG_GAMMA
1326    *  7) PNG_STRIP_ALPHA (if compose)
1327    *  8) PNG_ENCODE_ALPHA
1328    *  9) PNG_SCALE_16_TO_8
1329    * 10) PNG_16_TO_8
1330    * 11) PNG_QUANTIZE (converts to palette)
1331    * 12) PNG_EXPAND_16
1332    * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY
1333    * 14) PNG_INVERT_MONO
1334    * 15) PNG_SHIFT
1335    * 16) PNG_PACK
1336    * 17) PNG_BGR
1337    * 18) PNG_PACKSWAP
1338    * 19) PNG_FILLER (includes PNG_ADD_ALPHA)
1339    * 20) PNG_INVERT_ALPHA
1340    * 21) PNG_SWAP_ALPHA
1341    * 22) PNG_SWAP_BYTES
1342    * 23) PNG_USER_TRANSFORM [must be last]
1343    */
1344#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
1345   if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
1346      !(png_ptr->transformations & PNG_COMPOSE))
1347   {
1348      /* Stripping the alpha channel happens immediately after the 'expand'
1349       * transformations, before all other transformation, so it cancels out
1350       * the alpha handling.  It has the side effect negating the effect of
1351       * PNG_EXPAND_tRNS too:
1352       */
1353      png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA |
1354         PNG_EXPAND_tRNS);
1355      png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1356
1357      /* Kill the tRNS chunk itself too.  Prior to 1.5.4 this did not happen
1358       * so transparency information would remain just so long as it wasn't
1359       * expanded.  This produces unexpected API changes if the set of things
1360       * that do PNG_EXPAND_tRNS changes (perfectly possible given the
1361       * documentation - which says ask for what you want, accept what you
1362       * get.)  This makes the behavior consistent from 1.5.4:
1363       */
1364      png_ptr->num_trans = 0;
1365   }
1366#endif /* STRIP_ALPHA supported, no COMPOSE */
1367
1368#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
1369   /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA
1370    * settings will have no effect.
1371    */
1372   if (!png_gamma_significant(png_ptr->screen_gamma))
1373   {
1374      png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
1375      png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1376   }
1377#endif
1378
1379#if defined(PNG_READ_EXPAND_SUPPORTED) && \
1380   defined(PNG_READ_BACKGROUND_SUPPORTED) && \
1381   defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1382   /* Detect gray background and attempt to enable optimization for
1383    * gray --> RGB case.
1384    *
1385    * Note:  if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
1386    * RGB_ALPHA (in which case need_expand is superfluous anyway), the
1387    * background color might actually be gray yet not be flagged as such.
1388    * This is not a problem for the current code, which uses
1389    * PNG_BACKGROUND_IS_GRAY only to decide when to do the
1390    * png_do_gray_to_rgb() transformation.
1391    *
1392    * TODO: this code needs to be revised to avoid the complexity and
1393    * interdependencies.  The color type of the background should be recorded in
1394    * png_set_background, along with the bit depth, then the code has a record
1395    * of exactly what color space the background is currently in.
1396    */
1397   if (png_ptr->transformations & PNG_BACKGROUND_EXPAND)
1398   {
1399      /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if
1400       * the file was grayscale the background value is gray.
1401       */
1402      if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR))
1403         png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
1404   }
1405
1406   else if (png_ptr->transformations & PNG_COMPOSE)
1407   {
1408      /* PNG_COMPOSE: png_set_background was called with need_expand false,
1409       * so the color is in the color space of the output or png_set_alpha_mode
1410       * was called and the color is black.  Ignore RGB_TO_GRAY because that
1411       * happens before GRAY_TO_RGB.
1412       */
1413      if (png_ptr->transformations & PNG_GRAY_TO_RGB)
1414      {
1415         if (png_ptr->background.red == png_ptr->background.green &&
1416             png_ptr->background.red == png_ptr->background.blue)
1417         {
1418            png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
1419            png_ptr->background.gray = png_ptr->background.red;
1420         }
1421      }
1422   }
1423#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED (etc) */
1424
1425   /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations
1426    * can be performed directly on the palette, and some (such as rgb to gray)
1427    * can be optimized inside the palette.  This is particularly true of the
1428    * composite (background and alpha) stuff, which can be pretty much all done
1429    * in the palette even if the result is expanded to RGB or gray afterward.
1430    *
1431    * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and
1432    * earlier and the palette stuff is actually handled on the first row.  This
1433    * leads to the reported bug that the palette returned by png_get_PLTE is not
1434    * updated.
1435    */
1436   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1437      png_init_palette_transformations(png_ptr);
1438
1439   else
1440      png_init_rgb_transformations(png_ptr);
1441
1442#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
1443   defined(PNG_READ_EXPAND_16_SUPPORTED)
1444   if ((png_ptr->transformations & PNG_EXPAND_16) &&
1445      (png_ptr->transformations & PNG_COMPOSE) &&
1446      !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
1447      png_ptr->bit_depth != 16)
1448   {
1449      /* TODO: fix this.  Because the expand_16 operation is after the compose
1450       * handling the background color must be 8, not 16, bits deep, but the
1451       * application will supply a 16-bit value so reduce it here.
1452       *
1453       * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at
1454       *…

Large files files are truncated, but you can click here to view the full file