PageRenderTime 98ms CodeModel.GetById 9ms app.highlight 79ms RepoModel.GetById 2ms app.codeStats 0ms

/src/FreeImage/Source/LibPNG/pngset.c

https://bitbucket.org/cabalistic/ogredeps/
C | 1284 lines | 950 code | 256 blank | 78 comment | 257 complexity | 614e584cfbad593078cacb3b1e30d782 MD5 | raw file
   1
   2/* pngset.c - storage of image information into info struct
   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 * The functions here are used during reads to store data from the file
  14 * into the info struct, and during writes to store application data
  15 * into the info struct for writing into the file.  This abstracts the
  16 * info struct and allows us to change the structure in the future.
  17 */
  18
  19#include "pngpriv.h"
  20
  21#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
  22
  23#ifdef PNG_bKGD_SUPPORTED
  24void PNGAPI
  25png_set_bKGD(png_structp png_ptr, png_infop info_ptr,
  26    png_const_color_16p background)
  27{
  28   png_debug1(1, "in %s storage function", "bKGD");
  29
  30   if (png_ptr == NULL || info_ptr == NULL)
  31      return;
  32
  33   png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16));
  34   info_ptr->valid |= PNG_INFO_bKGD;
  35}
  36#endif
  37
  38#ifdef PNG_cHRM_SUPPORTED
  39void PNGFAPI
  40png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
  41    png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
  42    png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
  43    png_fixed_point blue_x, png_fixed_point blue_y)
  44{
  45   png_debug1(1, "in %s storage function", "cHRM fixed");
  46
  47   if (png_ptr == NULL || info_ptr == NULL)
  48      return;
  49
  50#  ifdef PNG_CHECK_cHRM_SUPPORTED
  51   if (png_check_cHRM_fixed(png_ptr,
  52       white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y))
  53#  endif
  54   {
  55      info_ptr->x_white = white_x;
  56      info_ptr->y_white = white_y;
  57      info_ptr->x_red   = red_x;
  58      info_ptr->y_red   = red_y;
  59      info_ptr->x_green = green_x;
  60      info_ptr->y_green = green_y;
  61      info_ptr->x_blue  = blue_x;
  62      info_ptr->y_blue  = blue_y;
  63      info_ptr->valid |= PNG_INFO_cHRM;
  64   }
  65}
  66
  67void PNGFAPI
  68png_set_cHRM_XYZ_fixed(png_structp png_ptr, png_infop info_ptr,
  69    png_fixed_point int_red_X, png_fixed_point int_red_Y,
  70    png_fixed_point int_red_Z, png_fixed_point int_green_X,
  71    png_fixed_point int_green_Y, png_fixed_point int_green_Z,
  72    png_fixed_point int_blue_X, png_fixed_point int_blue_Y,
  73    png_fixed_point int_blue_Z)
  74{
  75   png_XYZ XYZ;
  76   png_xy xy;
  77
  78   png_debug1(1, "in %s storage function", "cHRM XYZ fixed");
  79
  80   if (png_ptr == NULL || info_ptr == NULL)
  81      return;
  82
  83   XYZ.redX = int_red_X;
  84   XYZ.redY = int_red_Y;
  85   XYZ.redZ = int_red_Z;
  86   XYZ.greenX = int_green_X;
  87   XYZ.greenY = int_green_Y;
  88   XYZ.greenZ = int_green_Z;
  89   XYZ.blueX = int_blue_X;
  90   XYZ.blueY = int_blue_Y;
  91   XYZ.blueZ = int_blue_Z;
  92
  93   if (png_xy_from_XYZ(&xy, XYZ))
  94      png_error(png_ptr, "XYZ values out of representable range");
  95
  96   png_set_cHRM_fixed(png_ptr, info_ptr, xy.whitex, xy.whitey, xy.redx, xy.redy,
  97      xy.greenx, xy.greeny, xy.bluex, xy.bluey);
  98}
  99
 100#  ifdef PNG_FLOATING_POINT_SUPPORTED
 101void PNGAPI
 102png_set_cHRM(png_structp png_ptr, png_infop info_ptr,
 103    double white_x, double white_y, double red_x, double red_y,
 104    double green_x, double green_y, double blue_x, double blue_y)
 105{
 106   png_set_cHRM_fixed(png_ptr, info_ptr,
 107      png_fixed(png_ptr, white_x, "cHRM White X"),
 108      png_fixed(png_ptr, white_y, "cHRM White Y"),
 109      png_fixed(png_ptr, red_x, "cHRM Red X"),
 110      png_fixed(png_ptr, red_y, "cHRM Red Y"),
 111      png_fixed(png_ptr, green_x, "cHRM Green X"),
 112      png_fixed(png_ptr, green_y, "cHRM Green Y"),
 113      png_fixed(png_ptr, blue_x, "cHRM Blue X"),
 114      png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
 115}
 116
 117void PNGAPI
 118png_set_cHRM_XYZ(png_structp png_ptr, png_infop info_ptr, double red_X,
 119    double red_Y, double red_Z, double green_X, double green_Y, double green_Z,
 120    double blue_X, double blue_Y, double blue_Z)
 121{
 122   png_set_cHRM_XYZ_fixed(png_ptr, info_ptr,
 123      png_fixed(png_ptr, red_X, "cHRM Red X"),
 124      png_fixed(png_ptr, red_Y, "cHRM Red Y"),
 125      png_fixed(png_ptr, red_Z, "cHRM Red Z"),
 126      png_fixed(png_ptr, green_X, "cHRM Red X"),
 127      png_fixed(png_ptr, green_Y, "cHRM Red Y"),
 128      png_fixed(png_ptr, green_Z, "cHRM Red Z"),
 129      png_fixed(png_ptr, blue_X, "cHRM Red X"),
 130      png_fixed(png_ptr, blue_Y, "cHRM Red Y"),
 131      png_fixed(png_ptr, blue_Z, "cHRM Red Z"));
 132}
 133#  endif /* PNG_FLOATING_POINT_SUPPORTED */
 134
 135#endif /* PNG_cHRM_SUPPORTED */
 136
 137#ifdef PNG_gAMA_SUPPORTED
 138void PNGFAPI
 139png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
 140    file_gamma)
 141{
 142   png_debug1(1, "in %s storage function", "gAMA");
 143
 144   if (png_ptr == NULL || info_ptr == NULL)
 145      return;
 146
 147   /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't
 148    * occur.  Since the fixed point representation is assymetrical it is
 149    * possible for 1/gamma to overflow the limit of 21474 and this means the
 150    * gamma value must be at least 5/100000 and hence at most 20000.0.  For
 151    * safety the limits here are a little narrower.  The values are 0.00016 to
 152    * 6250.0, which are truly ridiculous gammma values (and will produce
 153    * displays that are all black or all white.)
 154    */
 155   if (file_gamma < 16 || file_gamma > 625000000)
 156      png_warning(png_ptr, "Out of range gamma value ignored");
 157
 158   else
 159   {
 160      info_ptr->gamma = file_gamma;
 161      info_ptr->valid |= PNG_INFO_gAMA;
 162   }
 163}
 164
 165#  ifdef PNG_FLOATING_POINT_SUPPORTED
 166void PNGAPI
 167png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
 168{
 169   png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma,
 170       "png_set_gAMA"));
 171}
 172#  endif
 173#endif
 174
 175#ifdef PNG_hIST_SUPPORTED
 176void PNGAPI
 177png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_const_uint_16p hist)
 178{
 179   int i;
 180
 181   png_debug1(1, "in %s storage function", "hIST");
 182
 183   if (png_ptr == NULL || info_ptr == NULL)
 184      return;
 185
 186   if (info_ptr->num_palette == 0 || info_ptr->num_palette
 187       > PNG_MAX_PALETTE_LENGTH)
 188   {
 189      png_warning(png_ptr,
 190          "Invalid palette size, hIST allocation skipped");
 191
 192      return;
 193   }
 194
 195   png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
 196
 197   /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in
 198    * version 1.2.1
 199    */
 200   png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr,
 201       PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16));
 202
 203   if (png_ptr->hist == NULL)
 204   {
 205      png_warning(png_ptr, "Insufficient memory for hIST chunk data");
 206      return;
 207   }
 208
 209   for (i = 0; i < info_ptr->num_palette; i++)
 210      png_ptr->hist[i] = hist[i];
 211
 212   info_ptr->hist = png_ptr->hist;
 213   info_ptr->valid |= PNG_INFO_hIST;
 214   info_ptr->free_me |= PNG_FREE_HIST;
 215}
 216#endif
 217
 218void PNGAPI
 219png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
 220    png_uint_32 width, png_uint_32 height, int bit_depth,
 221    int color_type, int interlace_type, int compression_type,
 222    int filter_type)
 223{
 224   png_debug1(1, "in %s storage function", "IHDR");
 225
 226   if (png_ptr == NULL || info_ptr == NULL)
 227      return;
 228
 229   info_ptr->width = width;
 230   info_ptr->height = height;
 231   info_ptr->bit_depth = (png_byte)bit_depth;
 232   info_ptr->color_type = (png_byte)color_type;
 233   info_ptr->compression_type = (png_byte)compression_type;
 234   info_ptr->filter_type = (png_byte)filter_type;
 235   info_ptr->interlace_type = (png_byte)interlace_type;
 236
 237   png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height,
 238       info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
 239       info_ptr->compression_type, info_ptr->filter_type);
 240
 241   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 242      info_ptr->channels = 1;
 243
 244   else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
 245      info_ptr->channels = 3;
 246
 247   else
 248      info_ptr->channels = 1;
 249
 250   if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
 251      info_ptr->channels++;
 252
 253   info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
 254
 255   /* Check for potential overflow */
 256   if (width >
 257       (PNG_UINT_32_MAX >> 3)      /* 8-byte RRGGBBAA pixels */
 258       - 48       /* bigrowbuf hack */
 259       - 1        /* filter byte */
 260       - 7*8      /* rounding of width to multiple of 8 pixels */
 261       - 8)       /* extra max_pixel_depth pad */
 262      info_ptr->rowbytes = 0;
 263   else
 264      info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
 265}
 266
 267#ifdef PNG_oFFs_SUPPORTED
 268void PNGAPI
 269png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
 270    png_int_32 offset_x, png_int_32 offset_y, int unit_type)
 271{
 272   png_debug1(1, "in %s storage function", "oFFs");
 273
 274   if (png_ptr == NULL || info_ptr == NULL)
 275      return;
 276
 277   info_ptr->x_offset = offset_x;
 278   info_ptr->y_offset = offset_y;
 279   info_ptr->offset_unit_type = (png_byte)unit_type;
 280   info_ptr->valid |= PNG_INFO_oFFs;
 281}
 282#endif
 283
 284#ifdef PNG_pCAL_SUPPORTED
 285void PNGAPI
 286png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
 287    png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type,
 288    int nparams, png_const_charp units, png_charpp params)
 289{
 290   png_size_t length;
 291   int i;
 292
 293   png_debug1(1, "in %s storage function", "pCAL");
 294
 295   if (png_ptr == NULL || info_ptr == NULL)
 296      return;
 297
 298   length = png_strlen(purpose) + 1;
 299   png_debug1(3, "allocating purpose for info (%lu bytes)",
 300       (unsigned long)length);
 301
 302   /* TODO: validate format of calibration name and unit name */
 303
 304   /* Check that the type matches the specification. */
 305   if (type < 0 || type > 3)
 306      png_error(png_ptr, "Invalid pCAL equation type");
 307
 308   /* Validate params[nparams] */
 309   for (i=0; i<nparams; ++i)
 310      if (!png_check_fp_string(params[i], png_strlen(params[i])))
 311         png_error(png_ptr, "Invalid format for pCAL parameter");
 312
 313   info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length);
 314
 315   if (info_ptr->pcal_purpose == NULL)
 316   {
 317      png_warning(png_ptr, "Insufficient memory for pCAL purpose");
 318      return;
 319   }
 320
 321   png_memcpy(info_ptr->pcal_purpose, purpose, length);
 322
 323   png_debug(3, "storing X0, X1, type, and nparams in info");
 324   info_ptr->pcal_X0 = X0;
 325   info_ptr->pcal_X1 = X1;
 326   info_ptr->pcal_type = (png_byte)type;
 327   info_ptr->pcal_nparams = (png_byte)nparams;
 328
 329   length = png_strlen(units) + 1;
 330   png_debug1(3, "allocating units for info (%lu bytes)",
 331     (unsigned long)length);
 332
 333   info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length);
 334
 335   if (info_ptr->pcal_units == NULL)
 336   {
 337      png_warning(png_ptr, "Insufficient memory for pCAL units");
 338      return;
 339   }
 340
 341   png_memcpy(info_ptr->pcal_units, units, length);
 342
 343   info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr,
 344       (png_size_t)((nparams + 1) * png_sizeof(png_charp)));
 345
 346   if (info_ptr->pcal_params == NULL)
 347   {
 348      png_warning(png_ptr, "Insufficient memory for pCAL params");
 349      return;
 350   }
 351
 352   png_memset(info_ptr->pcal_params, 0, (nparams + 1) * png_sizeof(png_charp));
 353
 354   for (i = 0; i < nparams; i++)
 355   {
 356      length = png_strlen(params[i]) + 1;
 357      png_debug2(3, "allocating parameter %d for info (%lu bytes)", i,
 358          (unsigned long)length);
 359
 360      info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
 361
 362      if (info_ptr->pcal_params[i] == NULL)
 363      {
 364         png_warning(png_ptr, "Insufficient memory for pCAL parameter");
 365         return;
 366      }
 367
 368      png_memcpy(info_ptr->pcal_params[i], params[i], length);
 369   }
 370
 371   info_ptr->valid |= PNG_INFO_pCAL;
 372   info_ptr->free_me |= PNG_FREE_PCAL;
 373}
 374#endif
 375
 376#ifdef PNG_sCAL_SUPPORTED
 377void PNGAPI
 378png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,
 379    int unit, png_const_charp swidth, png_const_charp sheight)
 380{
 381   png_size_t lengthw = 0, lengthh = 0;
 382
 383   png_debug1(1, "in %s storage function", "sCAL");
 384
 385   if (png_ptr == NULL || info_ptr == NULL)
 386      return;
 387
 388   /* Double check the unit (should never get here with an invalid
 389    * unit unless this is an API call.)
 390    */
 391   if (unit != 1 && unit != 2)
 392      png_error(png_ptr, "Invalid sCAL unit");
 393
 394   if (swidth == NULL || (lengthw = png_strlen(swidth)) == 0 ||
 395       swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw))
 396      png_error(png_ptr, "Invalid sCAL width");
 397
 398   if (sheight == NULL || (lengthh = png_strlen(sheight)) == 0 ||
 399       sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh))
 400      png_error(png_ptr, "Invalid sCAL height");
 401
 402   info_ptr->scal_unit = (png_byte)unit;
 403
 404   ++lengthw;
 405
 406   png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw);
 407
 408   info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, lengthw);
 409
 410   if (info_ptr->scal_s_width == NULL)
 411   {
 412      png_warning(png_ptr, "Memory allocation failed while processing sCAL");
 413      return;
 414   }
 415
 416   png_memcpy(info_ptr->scal_s_width, swidth, lengthw);
 417
 418   ++lengthh;
 419
 420   png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh);
 421
 422   info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, lengthh);
 423
 424   if (info_ptr->scal_s_height == NULL)
 425   {
 426      png_free (png_ptr, info_ptr->scal_s_width);
 427      info_ptr->scal_s_width = NULL;
 428
 429      png_warning(png_ptr, "Memory allocation failed while processing sCAL");
 430      return;
 431   }
 432
 433   png_memcpy(info_ptr->scal_s_height, sheight, lengthh);
 434
 435   info_ptr->valid |= PNG_INFO_sCAL;
 436   info_ptr->free_me |= PNG_FREE_SCAL;
 437}
 438
 439#  ifdef PNG_FLOATING_POINT_SUPPORTED
 440void PNGAPI
 441png_set_sCAL(png_structp png_ptr, png_infop info_ptr, int unit, double width,
 442    double height)
 443{
 444   png_debug1(1, "in %s storage function", "sCAL");
 445
 446   /* Check the arguments. */
 447   if (width <= 0)
 448      png_warning(png_ptr, "Invalid sCAL width ignored");
 449
 450   else if (height <= 0)
 451      png_warning(png_ptr, "Invalid sCAL height ignored");
 452
 453   else
 454   {
 455      /* Convert 'width' and 'height' to ASCII. */
 456      char swidth[PNG_sCAL_MAX_DIGITS+1];
 457      char sheight[PNG_sCAL_MAX_DIGITS+1];
 458
 459      png_ascii_from_fp(png_ptr, swidth, sizeof swidth, width,
 460         PNG_sCAL_PRECISION);
 461      png_ascii_from_fp(png_ptr, sheight, sizeof sheight, height,
 462         PNG_sCAL_PRECISION);
 463
 464      png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
 465   }
 466}
 467#  endif
 468
 469#  ifdef PNG_FIXED_POINT_SUPPORTED
 470void PNGAPI
 471png_set_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, int unit,
 472    png_fixed_point width, png_fixed_point height)
 473{
 474   png_debug1(1, "in %s storage function", "sCAL");
 475
 476   /* Check the arguments. */
 477   if (width <= 0)
 478      png_warning(png_ptr, "Invalid sCAL width ignored");
 479
 480   else if (height <= 0)
 481      png_warning(png_ptr, "Invalid sCAL height ignored");
 482
 483   else
 484   {
 485      /* Convert 'width' and 'height' to ASCII. */
 486      char swidth[PNG_sCAL_MAX_DIGITS+1];
 487      char sheight[PNG_sCAL_MAX_DIGITS+1];
 488
 489      png_ascii_from_fixed(png_ptr, swidth, sizeof swidth, width);
 490      png_ascii_from_fixed(png_ptr, sheight, sizeof sheight, height);
 491
 492      png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
 493   }
 494}
 495#  endif
 496#endif
 497
 498#ifdef PNG_pHYs_SUPPORTED
 499void PNGAPI
 500png_set_pHYs(png_structp png_ptr, png_infop info_ptr,
 501    png_uint_32 res_x, png_uint_32 res_y, int unit_type)
 502{
 503   png_debug1(1, "in %s storage function", "pHYs");
 504
 505   if (png_ptr == NULL || info_ptr == NULL)
 506      return;
 507
 508   info_ptr->x_pixels_per_unit = res_x;
 509   info_ptr->y_pixels_per_unit = res_y;
 510   info_ptr->phys_unit_type = (png_byte)unit_type;
 511   info_ptr->valid |= PNG_INFO_pHYs;
 512}
 513#endif
 514
 515void PNGAPI
 516png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
 517    png_const_colorp palette, int num_palette)
 518{
 519
 520   png_debug1(1, "in %s storage function", "PLTE");
 521
 522   if (png_ptr == NULL || info_ptr == NULL)
 523      return;
 524
 525   if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH)
 526   {
 527      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 528         png_error(png_ptr, "Invalid palette length");
 529
 530      else
 531      {
 532         png_warning(png_ptr, "Invalid palette length");
 533         return;
 534      }
 535   }
 536
 537   /* It may not actually be necessary to set png_ptr->palette here;
 538    * we do it for backward compatibility with the way the png_handle_tRNS
 539    * function used to do the allocation.
 540    */
 541   png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
 542
 543   /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
 544    * of num_palette entries, in case of an invalid PNG file that has
 545    * too-large sample values.
 546    */
 547   png_ptr->palette = (png_colorp)png_calloc(png_ptr,
 548       PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color));
 549
 550   png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof(png_color));
 551   info_ptr->palette = png_ptr->palette;
 552   info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
 553
 554   info_ptr->free_me |= PNG_FREE_PLTE;
 555
 556   info_ptr->valid |= PNG_INFO_PLTE;
 557}
 558
 559#ifdef PNG_sBIT_SUPPORTED
 560void PNGAPI
 561png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
 562    png_const_color_8p sig_bit)
 563{
 564   png_debug1(1, "in %s storage function", "sBIT");
 565
 566   if (png_ptr == NULL || info_ptr == NULL)
 567      return;
 568
 569   png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof(png_color_8));
 570   info_ptr->valid |= PNG_INFO_sBIT;
 571}
 572#endif
 573
 574#ifdef PNG_sRGB_SUPPORTED
 575void PNGAPI
 576png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int srgb_intent)
 577{
 578   png_debug1(1, "in %s storage function", "sRGB");
 579
 580   if (png_ptr == NULL || info_ptr == NULL)
 581      return;
 582
 583   info_ptr->srgb_intent = (png_byte)srgb_intent;
 584   info_ptr->valid |= PNG_INFO_sRGB;
 585}
 586
 587void PNGAPI
 588png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
 589    int srgb_intent)
 590{
 591   png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM");
 592
 593   if (png_ptr == NULL || info_ptr == NULL)
 594      return;
 595
 596   png_set_sRGB(png_ptr, info_ptr, srgb_intent);
 597
 598#  ifdef PNG_gAMA_SUPPORTED
 599   png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE);
 600#  endif
 601
 602#  ifdef PNG_cHRM_SUPPORTED
 603   png_set_cHRM_fixed(png_ptr, info_ptr,
 604      /* color      x       y */
 605      /* white */ 31270, 32900,
 606      /* red   */ 64000, 33000,
 607      /* green */ 30000, 60000,
 608      /* blue  */ 15000,  6000
 609   );
 610#  endif /* cHRM */
 611}
 612#endif /* sRGB */
 613
 614
 615#ifdef PNG_iCCP_SUPPORTED
 616void PNGAPI
 617png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
 618    png_const_charp name, int compression_type,
 619    png_const_bytep profile, png_uint_32 proflen)
 620{
 621   png_charp new_iccp_name;
 622   png_bytep new_iccp_profile;
 623   png_size_t length;
 624
 625   png_debug1(1, "in %s storage function", "iCCP");
 626
 627   if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
 628      return;
 629
 630   length = png_strlen(name)+1;
 631   new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length);
 632
 633   if (new_iccp_name == NULL)
 634   {
 635        png_warning(png_ptr, "Insufficient memory to process iCCP chunk");
 636      return;
 637   }
 638
 639   png_memcpy(new_iccp_name, name, length);
 640   new_iccp_profile = (png_bytep)png_malloc_warn(png_ptr, proflen);
 641
 642   if (new_iccp_profile == NULL)
 643   {
 644      png_free (png_ptr, new_iccp_name);
 645      png_warning(png_ptr,
 646          "Insufficient memory to process iCCP profile");
 647      return;
 648   }
 649
 650   png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);
 651
 652   png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
 653
 654   info_ptr->iccp_proflen = proflen;
 655   info_ptr->iccp_name = new_iccp_name;
 656   info_ptr->iccp_profile = new_iccp_profile;
 657   /* Compression is always zero but is here so the API and info structure
 658    * does not have to change if we introduce multiple compression types
 659    */
 660   info_ptr->iccp_compression = (png_byte)compression_type;
 661   info_ptr->free_me |= PNG_FREE_ICCP;
 662   info_ptr->valid |= PNG_INFO_iCCP;
 663}
 664#endif
 665
 666#ifdef PNG_TEXT_SUPPORTED
 667void PNGAPI
 668png_set_text(png_structp png_ptr, png_infop info_ptr, png_const_textp text_ptr,
 669    int num_text)
 670{
 671   int ret;
 672   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
 673
 674   if (ret)
 675      png_error(png_ptr, "Insufficient memory to store text");
 676}
 677
 678int /* PRIVATE */
 679png_set_text_2(png_structp png_ptr, png_infop info_ptr,
 680    png_const_textp text_ptr, int num_text)
 681{
 682   int i;
 683
 684   png_debug1(1, "in %lx storage function", png_ptr == NULL ? "unexpected" :
 685      (unsigned long)png_ptr->chunk_name);
 686
 687   if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
 688      return(0);
 689
 690   /* Make sure we have enough space in the "text" array in info_struct
 691    * to hold all of the incoming text_ptr objects.
 692    */
 693   if (info_ptr->num_text + num_text > info_ptr->max_text)
 694   {
 695      if (info_ptr->text != NULL)
 696      {
 697         png_textp old_text;
 698         int old_max;
 699
 700         old_max = info_ptr->max_text;
 701         info_ptr->max_text = info_ptr->num_text + num_text + 8;
 702         old_text = info_ptr->text;
 703         info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
 704            (png_size_t)(info_ptr->max_text * png_sizeof(png_text)));
 705
 706         if (info_ptr->text == NULL)
 707         {
 708            png_free(png_ptr, old_text);
 709            return(1);
 710         }
 711
 712         png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
 713             png_sizeof(png_text)));
 714         png_free(png_ptr, old_text);
 715      }
 716
 717      else
 718      {
 719         info_ptr->max_text = num_text + 8;
 720         info_ptr->num_text = 0;
 721         info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
 722             (png_size_t)(info_ptr->max_text * png_sizeof(png_text)));
 723         if (info_ptr->text == NULL)
 724            return(1);
 725         info_ptr->free_me |= PNG_FREE_TEXT;
 726      }
 727
 728      png_debug1(3, "allocated %d entries for info_ptr->text",
 729          info_ptr->max_text);
 730   }
 731   for (i = 0; i < num_text; i++)
 732   {
 733      png_size_t text_length, key_len;
 734      png_size_t lang_len, lang_key_len;
 735      png_textp textp = &(info_ptr->text[info_ptr->num_text]);
 736
 737      if (text_ptr[i].key == NULL)
 738          continue;
 739
 740      if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE ||
 741          text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
 742      {
 743         png_warning(png_ptr, "text compression mode is out of range");
 744         continue;
 745      }
 746
 747      key_len = png_strlen(text_ptr[i].key);
 748
 749      if (text_ptr[i].compression <= 0)
 750      {
 751         lang_len = 0;
 752         lang_key_len = 0;
 753      }
 754
 755      else
 756#  ifdef PNG_iTXt_SUPPORTED
 757      {
 758         /* Set iTXt data */
 759
 760         if (text_ptr[i].lang != NULL)
 761            lang_len = png_strlen(text_ptr[i].lang);
 762
 763         else
 764            lang_len = 0;
 765
 766         if (text_ptr[i].lang_key != NULL)
 767            lang_key_len = png_strlen(text_ptr[i].lang_key);
 768
 769         else
 770            lang_key_len = 0;
 771      }
 772#  else /* PNG_iTXt_SUPPORTED */
 773      {
 774         png_warning(png_ptr, "iTXt chunk not supported");
 775         continue;
 776      }
 777#  endif
 778
 779      if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
 780      {
 781         text_length = 0;
 782#  ifdef PNG_iTXt_SUPPORTED
 783         if (text_ptr[i].compression > 0)
 784            textp->compression = PNG_ITXT_COMPRESSION_NONE;
 785
 786         else
 787#  endif
 788            textp->compression = PNG_TEXT_COMPRESSION_NONE;
 789      }
 790
 791      else
 792      {
 793         text_length = png_strlen(text_ptr[i].text);
 794         textp->compression = text_ptr[i].compression;
 795      }
 796
 797      textp->key = (png_charp)png_malloc_warn(png_ptr,
 798          (png_size_t)
 799          (key_len + text_length + lang_len + lang_key_len + 4));
 800
 801      if (textp->key == NULL)
 802         return(1);
 803
 804      png_debug2(2, "Allocated %lu bytes at %p in png_set_text",
 805          (unsigned long)(png_uint_32)
 806          (key_len + lang_len + lang_key_len + text_length + 4),
 807          textp->key);
 808
 809      png_memcpy(textp->key, text_ptr[i].key,(png_size_t)(key_len));
 810      *(textp->key + key_len) = '\0';
 811
 812      if (text_ptr[i].compression > 0)
 813      {
 814         textp->lang = textp->key + key_len + 1;
 815         png_memcpy(textp->lang, text_ptr[i].lang, lang_len);
 816         *(textp->lang + lang_len) = '\0';
 817         textp->lang_key = textp->lang + lang_len + 1;
 818         png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
 819         *(textp->lang_key + lang_key_len) = '\0';
 820         textp->text = textp->lang_key + lang_key_len + 1;
 821      }
 822
 823      else
 824      {
 825         textp->lang=NULL;
 826         textp->lang_key=NULL;
 827         textp->text = textp->key + key_len + 1;
 828      }
 829
 830      if (text_length)
 831         png_memcpy(textp->text, text_ptr[i].text,
 832             (png_size_t)(text_length));
 833
 834      *(textp->text + text_length) = '\0';
 835
 836#  ifdef PNG_iTXt_SUPPORTED
 837      if (textp->compression > 0)
 838      {
 839         textp->text_length = 0;
 840         textp->itxt_length = text_length;
 841      }
 842
 843      else
 844#  endif
 845      {
 846         textp->text_length = text_length;
 847         textp->itxt_length = 0;
 848      }
 849
 850      info_ptr->num_text++;
 851      png_debug1(3, "transferred text chunk %d", info_ptr->num_text);
 852   }
 853   return(0);
 854}
 855#endif
 856
 857#ifdef PNG_tIME_SUPPORTED
 858void PNGAPI
 859png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time)
 860{
 861   png_debug1(1, "in %s storage function", "tIME");
 862
 863   if (png_ptr == NULL || info_ptr == NULL ||
 864       (png_ptr->mode & PNG_WROTE_tIME))
 865      return;
 866
 867   if (mod_time->month == 0   || mod_time->month > 12  ||
 868       mod_time->day   == 0   || mod_time->day   > 31  ||
 869       mod_time->hour  > 23   || mod_time->minute > 59 ||
 870       mod_time->second > 60)
 871   {
 872      png_warning(png_ptr, "Ignoring invalid time value");
 873      return;
 874   }
 875
 876   png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof(png_time));
 877   info_ptr->valid |= PNG_INFO_tIME;
 878}
 879#endif
 880
 881#ifdef PNG_tRNS_SUPPORTED
 882void PNGAPI
 883png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
 884    png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color)
 885{
 886   png_debug1(1, "in %s storage function", "tRNS");
 887
 888   if (png_ptr == NULL || info_ptr == NULL)
 889      return;
 890
 891   if (trans_alpha != NULL)
 892   {
 893       /* It may not actually be necessary to set png_ptr->trans_alpha here;
 894        * we do it for backward compatibility with the way the png_handle_tRNS
 895        * function used to do the allocation.
 896        */
 897
 898       png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
 899
 900       /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
 901       png_ptr->trans_alpha = info_ptr->trans_alpha =
 902           (png_bytep)png_malloc(png_ptr, (png_size_t)PNG_MAX_PALETTE_LENGTH);
 903
 904       if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
 905          png_memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans);
 906   }
 907
 908   if (trans_color != NULL)
 909   {
 910      int sample_max = (1 << info_ptr->bit_depth);
 911
 912      if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
 913          (int)trans_color->gray > sample_max) ||
 914          (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
 915          ((int)trans_color->red > sample_max ||
 916          (int)trans_color->green > sample_max ||
 917          (int)trans_color->blue > sample_max)))
 918         png_warning(png_ptr,
 919            "tRNS chunk has out-of-range samples for bit_depth");
 920
 921      png_memcpy(&(info_ptr->trans_color), trans_color,
 922         png_sizeof(png_color_16));
 923
 924      if (num_trans == 0)
 925         num_trans = 1;
 926   }
 927
 928   info_ptr->num_trans = (png_uint_16)num_trans;
 929
 930   if (num_trans != 0)
 931   {
 932      info_ptr->valid |= PNG_INFO_tRNS;
 933      info_ptr->free_me |= PNG_FREE_TRNS;
 934   }
 935}
 936#endif
 937
 938#ifdef PNG_sPLT_SUPPORTED
 939void PNGAPI
 940png_set_sPLT(png_structp png_ptr,
 941    png_infop info_ptr, png_const_sPLT_tp entries, int nentries)
 942/*
 943 *  entries        - array of png_sPLT_t structures
 944 *                   to be added to the list of palettes
 945 *                   in the info structure.
 946 *
 947 *  nentries       - number of palette structures to be
 948 *                   added.
 949 */
 950{
 951   png_sPLT_tp np;
 952   int i;
 953
 954   if (png_ptr == NULL || info_ptr == NULL)
 955      return;
 956
 957   np = (png_sPLT_tp)png_malloc_warn(png_ptr,
 958       (info_ptr->splt_palettes_num + nentries) *
 959       (png_size_t)png_sizeof(png_sPLT_t));
 960
 961   if (np == NULL)
 962   {
 963      png_warning(png_ptr, "No memory for sPLT palettes");
 964      return;
 965   }
 966
 967   png_memcpy(np, info_ptr->splt_palettes,
 968       info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t));
 969
 970   png_free(png_ptr, info_ptr->splt_palettes);
 971   info_ptr->splt_palettes=NULL;
 972
 973   for (i = 0; i < nentries; i++)
 974   {
 975      png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
 976      png_const_sPLT_tp from = entries + i;
 977      png_size_t length;
 978
 979      length = png_strlen(from->name) + 1;
 980      to->name = (png_charp)png_malloc_warn(png_ptr, length);
 981
 982      if (to->name == NULL)
 983      {
 984         png_warning(png_ptr,
 985             "Out of memory while processing sPLT chunk");
 986         continue;
 987      }
 988
 989      png_memcpy(to->name, from->name, length);
 990      to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr,
 991          from->nentries * png_sizeof(png_sPLT_entry));
 992
 993      if (to->entries == NULL)
 994      {
 995         png_warning(png_ptr,
 996             "Out of memory while processing sPLT chunk");
 997         png_free(png_ptr, to->name);
 998         to->name = NULL;
 999         continue;
1000      }
1001
1002      png_memcpy(to->entries, from->entries,
1003          from->nentries * png_sizeof(png_sPLT_entry));
1004
1005      to->nentries = from->nentries;
1006      to->depth = from->depth;
1007   }
1008
1009   info_ptr->splt_palettes = np;
1010   info_ptr->splt_palettes_num += nentries;
1011   info_ptr->valid |= PNG_INFO_sPLT;
1012   info_ptr->free_me |= PNG_FREE_SPLT;
1013}
1014#endif /* PNG_sPLT_SUPPORTED */
1015
1016#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
1017void PNGAPI
1018png_set_unknown_chunks(png_structp png_ptr,
1019   png_infop info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
1020{
1021   png_unknown_chunkp np;
1022   int i;
1023
1024   if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)
1025      return;
1026
1027   np = (png_unknown_chunkp)png_malloc_warn(png_ptr,
1028       (png_size_t)(info_ptr->unknown_chunks_num + num_unknowns) *
1029       png_sizeof(png_unknown_chunk));
1030
1031   if (np == NULL)
1032   {
1033      png_warning(png_ptr,
1034          "Out of memory while processing unknown chunk");
1035      return;
1036   }
1037
1038   png_memcpy(np, info_ptr->unknown_chunks,
1039       (png_size_t)info_ptr->unknown_chunks_num *
1040       png_sizeof(png_unknown_chunk));
1041
1042   png_free(png_ptr, info_ptr->unknown_chunks);
1043   info_ptr->unknown_chunks = NULL;
1044
1045   for (i = 0; i < num_unknowns; i++)
1046   {
1047      png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;
1048      png_const_unknown_chunkp from = unknowns + i;
1049
1050      png_memcpy(to->name, from->name, png_sizeof(from->name));
1051      to->name[png_sizeof(to->name)-1] = '\0';
1052      to->size = from->size;
1053
1054      /* Note our location in the read or write sequence */
1055      to->location = (png_byte)(png_ptr->mode & 0xff);
1056
1057      if (from->size == 0)
1058         to->data=NULL;
1059
1060      else
1061      {
1062         to->data = (png_bytep)png_malloc_warn(png_ptr,
1063             (png_size_t)from->size);
1064
1065         if (to->data == NULL)
1066         {
1067            png_warning(png_ptr,
1068                "Out of memory while processing unknown chunk");
1069            to->size = 0;
1070         }
1071
1072         else
1073            png_memcpy(to->data, from->data, from->size);
1074      }
1075   }
1076
1077   info_ptr->unknown_chunks = np;
1078   info_ptr->unknown_chunks_num += num_unknowns;
1079   info_ptr->free_me |= PNG_FREE_UNKN;
1080}
1081
1082void PNGAPI
1083png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
1084    int chunk, int location)
1085{
1086   if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <
1087       info_ptr->unknown_chunks_num)
1088      info_ptr->unknown_chunks[chunk].location = (png_byte)location;
1089}
1090#endif
1091
1092
1093#ifdef PNG_MNG_FEATURES_SUPPORTED
1094png_uint_32 PNGAPI
1095png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features)
1096{
1097   png_debug(1, "in png_permit_mng_features");
1098
1099   if (png_ptr == NULL)
1100      return (png_uint_32)0;
1101
1102   png_ptr->mng_features_permitted =
1103       (png_byte)(mng_features & PNG_ALL_MNG_FEATURES);
1104
1105   return (png_uint_32)png_ptr->mng_features_permitted;
1106}
1107#endif
1108
1109#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
1110void PNGAPI
1111png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_const_bytep
1112    chunk_list, int num_chunks)
1113{
1114   png_bytep new_list, p;
1115   int i, old_num_chunks;
1116   if (png_ptr == NULL)
1117      return;
1118
1119   if (num_chunks == 0)
1120   {
1121      if (keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE)
1122         png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
1123
1124      else
1125         png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
1126
1127      if (keep == PNG_HANDLE_CHUNK_ALWAYS)
1128         png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS;
1129
1130      else
1131         png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS;
1132
1133      return;
1134   }
1135
1136   if (chunk_list == NULL)
1137      return;
1138
1139   old_num_chunks = png_ptr->num_chunk_list;
1140   new_list=(png_bytep)png_malloc(png_ptr,
1141       (png_size_t)(5*(num_chunks + old_num_chunks)));
1142
1143   if (png_ptr->chunk_list != NULL)
1144   {
1145      png_memcpy(new_list, png_ptr->chunk_list,
1146          (png_size_t)(5*old_num_chunks));
1147      png_free(png_ptr, png_ptr->chunk_list);
1148      png_ptr->chunk_list=NULL;
1149   }
1150
1151   png_memcpy(new_list + 5*old_num_chunks, chunk_list,
1152       (png_size_t)(5*num_chunks));
1153
1154   for (p = new_list + 5*old_num_chunks + 4, i = 0; i<num_chunks; i++, p += 5)
1155      *p=(png_byte)keep;
1156
1157   png_ptr->num_chunk_list = old_num_chunks + num_chunks;
1158   png_ptr->chunk_list = new_list;
1159   png_ptr->free_me |= PNG_FREE_LIST;
1160}
1161#endif
1162
1163#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
1164void PNGAPI
1165png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr,
1166    png_user_chunk_ptr read_user_chunk_fn)
1167{
1168   png_debug(1, "in png_set_read_user_chunk_fn");
1169
1170   if (png_ptr == NULL)
1171      return;
1172
1173   png_ptr->read_user_chunk_fn = read_user_chunk_fn;
1174   png_ptr->user_chunk_ptr = user_chunk_ptr;
1175}
1176#endif
1177
1178#ifdef PNG_INFO_IMAGE_SUPPORTED
1179void PNGAPI
1180png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
1181{
1182   png_debug1(1, "in %s storage function", "rows");
1183
1184   if (png_ptr == NULL || info_ptr == NULL)
1185      return;
1186
1187   if (info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
1188      png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
1189
1190   info_ptr->row_pointers = row_pointers;
1191
1192   if (row_pointers)
1193      info_ptr->valid |= PNG_INFO_IDAT;
1194}
1195#endif
1196
1197void PNGAPI
1198png_set_compression_buffer_size(png_structp png_ptr, png_size_t size)
1199{
1200    if (png_ptr == NULL)
1201       return;
1202
1203    png_free(png_ptr, png_ptr->zbuf);
1204
1205    if (size > ZLIB_IO_MAX)
1206    {
1207       png_warning(png_ptr, "Attempt to set buffer size beyond max ignored");
1208       png_ptr->zbuf_size = ZLIB_IO_MAX;
1209       size = ZLIB_IO_MAX; /* must fit */
1210    }
1211
1212    else
1213       png_ptr->zbuf_size = (uInt)size;
1214
1215    png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size);
1216
1217    /* The following ensures a relatively safe failure if this gets called while
1218     * the buffer is actually in use.
1219     */
1220    png_ptr->zstream.next_out = png_ptr->zbuf;
1221    png_ptr->zstream.avail_out = 0;
1222    png_ptr->zstream.avail_in = 0;
1223}
1224
1225void PNGAPI
1226png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask)
1227{
1228   if (png_ptr && info_ptr)
1229      info_ptr->valid &= ~mask;
1230}
1231
1232
1233
1234#ifdef PNG_SET_USER_LIMITS_SUPPORTED
1235/* This function was added to libpng 1.2.6 */
1236void PNGAPI
1237png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max,
1238    png_uint_32 user_height_max)
1239{
1240   /* Images with dimensions larger than these limits will be
1241    * rejected by png_set_IHDR().  To accept any PNG datastream
1242    * regardless of dimensions, set both limits to 0x7ffffffL.
1243    */
1244   if (png_ptr == NULL)
1245      return;
1246
1247   png_ptr->user_width_max = user_width_max;
1248   png_ptr->user_height_max = user_height_max;
1249}
1250
1251/* This function was added to libpng 1.4.0 */
1252void PNGAPI
1253png_set_chunk_cache_max (png_structp png_ptr,
1254   png_uint_32 user_chunk_cache_max)
1255{
1256    if (png_ptr)
1257       png_ptr->user_chunk_cache_max = user_chunk_cache_max;
1258}
1259
1260/* This function was added to libpng 1.4.1 */
1261void PNGAPI
1262png_set_chunk_malloc_max (png_structp png_ptr,
1263    png_alloc_size_t user_chunk_malloc_max)
1264{
1265   if (png_ptr)
1266      png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
1267}
1268#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
1269
1270
1271#ifdef PNG_BENIGN_ERRORS_SUPPORTED
1272void PNGAPI
1273png_set_benign_errors(png_structp png_ptr, int allowed)
1274{
1275   png_debug(1, "in png_set_benign_errors");
1276
1277   if (allowed)
1278      png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;
1279
1280   else
1281      png_ptr->flags &= ~PNG_FLAG_BENIGN_ERRORS_WARN;
1282}
1283#endif /* PNG_BENIGN_ERRORS_SUPPORTED */
1284#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */