pngset.c 35.2 KB
Newer Older
D
duke 已提交
1 2 3 4 5
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
6
 * published by the Free Software Foundation.  Oracle designates this
D
duke 已提交
7
 * particular file as subject to the "Classpath" exception as provided
8
 * by Oracle in the LICENSE file that accompanied this code.
D
duke 已提交
9 10 11 12 13 14 15 16 17 18 19
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
20 21 22
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
23 24 25 26 27 28 29 30 31
 */

/* pngset.c - storage of image information into info struct
 *
 * This file is available under and governed by the GNU General Public
 * License version 2 only, as published by the Free Software Foundation.
 * However, the following notice accompanied the original version of this
 * file and, per its terms, should not be removed:
 *
B
bae 已提交
32 33
 * Last changed in libpng 1.5.4 [July 7, 2011]
 * Copyright (c) 1998-2011 Glenn Randers-Pehrson
D
duke 已提交
34 35 36
 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
 *
B
bae 已提交
37 38 39 40
 * This code is released under the libpng license.
 * For conditions of distribution and use, see the disclaimer
 * and license in png.h
 *
D
duke 已提交
41 42 43 44 45 46
 * The functions here are used during reads to store data from the file
 * into the info struct, and during writes to store application data
 * into the info struct for writing into the file.  This abstracts the
 * info struct and allows us to change the structure in the future.
 */

B
bae 已提交
47
#include "pngpriv.h"
D
duke 已提交
48 49 50

#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)

B
bae 已提交
51
#ifdef PNG_bKGD_SUPPORTED
D
duke 已提交
52
void PNGAPI
B
bae 已提交
53 54
png_set_bKGD(png_structp png_ptr, png_infop info_ptr,
    png_const_color_16p background)
D
duke 已提交
55
{
B
bae 已提交
56 57
   png_debug1(1, "in %s storage function", "bKGD");

D
duke 已提交
58 59 60 61 62 63 64 65
   if (png_ptr == NULL || info_ptr == NULL)
      return;

   png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16));
   info_ptr->valid |= PNG_INFO_bKGD;
}
#endif

B
bae 已提交
66 67
#ifdef PNG_cHRM_SUPPORTED
void PNGFAPI
D
duke 已提交
68
png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
B
bae 已提交
69 70 71
    png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
    png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
    png_fixed_point blue_x, png_fixed_point blue_y)
D
duke 已提交
72
{
B
bae 已提交
73 74
   png_debug1(1, "in %s storage function", "cHRM fixed");

D
duke 已提交
75 76 77
   if (png_ptr == NULL || info_ptr == NULL)
      return;

B
bae 已提交
78 79 80 81
#  ifdef PNG_CHECK_cHRM_SUPPORTED
   if (png_check_cHRM_fixed(png_ptr,
       white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y))
#  endif
D
duke 已提交
82
   {
B
bae 已提交
83 84 85 86 87 88 89 90 91
      info_ptr->x_white = white_x;
      info_ptr->y_white = white_y;
      info_ptr->x_red   = red_x;
      info_ptr->y_red   = red_y;
      info_ptr->x_green = green_x;
      info_ptr->y_green = green_y;
      info_ptr->x_blue  = blue_x;
      info_ptr->y_blue  = blue_y;
      info_ptr->valid |= PNG_INFO_cHRM;
D
duke 已提交
92 93 94
   }
}

B
bae 已提交
95
#  ifdef PNG_FLOATING_POINT_SUPPORTED
D
duke 已提交
96
void PNGAPI
B
bae 已提交
97 98 99
png_set_cHRM(png_structp png_ptr, png_infop info_ptr,
    double white_x, double white_y, double red_x, double red_y,
    double green_x, double green_y, double blue_x, double blue_y)
D
duke 已提交
100
{
B
bae 已提交
101 102 103 104 105 106 107 108 109
   png_set_cHRM_fixed(png_ptr, info_ptr,
      png_fixed(png_ptr, white_x, "cHRM White X"),
      png_fixed(png_ptr, white_y, "cHRM White Y"),
      png_fixed(png_ptr, red_x, "cHRM Red X"),
      png_fixed(png_ptr, red_y, "cHRM Red Y"),
      png_fixed(png_ptr, green_x, "cHRM Green X"),
      png_fixed(png_ptr, green_y, "cHRM Green Y"),
      png_fixed(png_ptr, blue_x, "cHRM Blue X"),
      png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
D
duke 已提交
110
}
B
bae 已提交
111 112 113 114 115 116
#  endif /* PNG_FLOATING_POINT_SUPPORTED */

#endif /* PNG_cHRM_SUPPORTED */

#ifdef PNG_gAMA_SUPPORTED
void PNGFAPI
D
duke 已提交
117
png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
B
bae 已提交
118
    file_gamma)
D
duke 已提交
119
{
B
bae 已提交
120
   png_debug1(1, "in %s storage function", "gAMA");
D
duke 已提交
121 122 123 124

   if (png_ptr == NULL || info_ptr == NULL)
      return;

B
bae 已提交
125 126 127 128 129 130 131 132 133 134 135
   /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't
    * occur.  Since the fixed point representation is assymetrical it is
    * possible for 1/gamma to overflow the limit of 21474 and this means the
    * gamma value must be at least 5/100000 and hence at most 20000.0.  For
    * safety the limits here are a little narrower.  The values are 0.00016 to
    * 6250.0, which are truely ridiculous gammma values (and will produce
    * displays that are all black or all white.)
    */
   if (file_gamma < 16 || file_gamma > 625000000)
      png_warning(png_ptr, "Out of range gamma value ignored");

D
duke 已提交
136 137
   else
   {
B
bae 已提交
138 139
      info_ptr->gamma = file_gamma;
      info_ptr->valid |= PNG_INFO_gAMA;
D
duke 已提交
140 141
   }
}
B
bae 已提交
142 143 144 145 146 147 148 149 150

#  ifdef PNG_FLOATING_POINT_SUPPORTED
void PNGAPI
png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
{
   png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma,
       "png_set_gAMA"));
}
#  endif
D
duke 已提交
151 152
#endif

B
bae 已提交
153
#ifdef PNG_hIST_SUPPORTED
D
duke 已提交
154
void PNGAPI
B
bae 已提交
155
png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_const_uint_16p hist)
D
duke 已提交
156 157 158
{
   int i;

B
bae 已提交
159 160
   png_debug1(1, "in %s storage function", "hIST");

D
duke 已提交
161 162
   if (png_ptr == NULL || info_ptr == NULL)
      return;
B
bae 已提交
163 164

   if (info_ptr->num_palette == 0 || info_ptr->num_palette
D
duke 已提交
165 166
       > PNG_MAX_PALETTE_LENGTH)
   {
B
bae 已提交
167 168 169 170
      png_warning(png_ptr,
          "Invalid palette size, hIST allocation skipped");

      return;
D
duke 已提交
171 172 173
   }

   png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
B
bae 已提交
174 175 176 177

   /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in
    * version 1.2.1
    */
D
duke 已提交
178
   png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr,
B
bae 已提交
179 180
       PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16));

D
duke 已提交
181
   if (png_ptr->hist == NULL)
B
bae 已提交
182 183 184 185
   {
      png_warning(png_ptr, "Insufficient memory for hIST chunk data");
      return;
   }
D
duke 已提交
186 187

   for (i = 0; i < info_ptr->num_palette; i++)
B
bae 已提交
188 189
      png_ptr->hist[i] = hist[i];

D
duke 已提交
190 191 192 193 194 195 196 197
   info_ptr->hist = png_ptr->hist;
   info_ptr->valid |= PNG_INFO_hIST;
   info_ptr->free_me |= PNG_FREE_HIST;
}
#endif

void PNGAPI
png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
B
bae 已提交
198 199 200
    png_uint_32 width, png_uint_32 height, int bit_depth,
    int color_type, int interlace_type, int compression_type,
    int filter_type)
D
duke 已提交
201
{
B
bae 已提交
202 203
   png_debug1(1, "in %s storage function", "IHDR");

D
duke 已提交
204 205 206 207 208 209
   if (png_ptr == NULL || info_ptr == NULL)
      return;

   info_ptr->width = width;
   info_ptr->height = height;
   info_ptr->bit_depth = (png_byte)bit_depth;
B
bae 已提交
210
   info_ptr->color_type = (png_byte)color_type;
D
duke 已提交
211 212 213
   info_ptr->compression_type = (png_byte)compression_type;
   info_ptr->filter_type = (png_byte)filter_type;
   info_ptr->interlace_type = (png_byte)interlace_type;
B
bae 已提交
214 215 216 217 218

   png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height,
       info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
       info_ptr->compression_type, info_ptr->filter_type);

D
duke 已提交
219 220
   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
      info_ptr->channels = 1;
B
bae 已提交
221

D
duke 已提交
222 223
   else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
      info_ptr->channels = 3;
B
bae 已提交
224

D
duke 已提交
225 226
   else
      info_ptr->channels = 1;
B
bae 已提交
227

D
duke 已提交
228 229
   if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
      info_ptr->channels++;
B
bae 已提交
230

D
duke 已提交
231 232
   info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);

B
bae 已提交
233 234 235 236 237 238 239 240
   /* Check for potential overflow */
   if (width >
       (PNG_UINT_32_MAX >> 3)      /* 8-byte RRGGBBAA pixels */
       - 48       /* bigrowbuf hack */
       - 1        /* filter byte */
       - 7*8      /* rounding of width to multiple of 8 pixels */
       - 8)       /* extra max_pixel_depth pad */
      info_ptr->rowbytes = 0;
D
duke 已提交
241
   else
B
bae 已提交
242
      info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
D
duke 已提交
243 244
}

B
bae 已提交
245
#ifdef PNG_oFFs_SUPPORTED
D
duke 已提交
246 247
void PNGAPI
png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
B
bae 已提交
248
    png_int_32 offset_x, png_int_32 offset_y, int unit_type)
D
duke 已提交
249
{
B
bae 已提交
250 251
   png_debug1(1, "in %s storage function", "oFFs");

D
duke 已提交
252 253 254 255 256 257 258 259 260 261
   if (png_ptr == NULL || info_ptr == NULL)
      return;

   info_ptr->x_offset = offset_x;
   info_ptr->y_offset = offset_y;
   info_ptr->offset_unit_type = (png_byte)unit_type;
   info_ptr->valid |= PNG_INFO_oFFs;
}
#endif

B
bae 已提交
262
#ifdef PNG_pCAL_SUPPORTED
D
duke 已提交
263 264
void PNGAPI
png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
B
bae 已提交
265 266
    png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type,
    int nparams, png_const_charp units, png_charpp params)
D
duke 已提交
267
{
B
bae 已提交
268
   png_size_t length;
D
duke 已提交
269 270
   int i;

B
bae 已提交
271 272
   png_debug1(1, "in %s storage function", "pCAL");

D
duke 已提交
273 274 275 276
   if (png_ptr == NULL || info_ptr == NULL)
      return;

   length = png_strlen(purpose) + 1;
B
bae 已提交
277 278 279 280 281 282 283 284 285 286 287 288 289 290
   png_debug1(3, "allocating purpose for info (%lu bytes)",
       (unsigned long)length);

   /* TODO: validate format of calibration name and unit name */

   /* Check that the type matches the specification. */
   if (type < 0 || type > 3)
      png_error(png_ptr, "Invalid pCAL equation type");

   /* Validate params[nparams] */
   for (i=0; i<nparams; ++i)
      if (!png_check_fp_string(params[i], png_strlen(params[i])))
         png_error(png_ptr, "Invalid format for pCAL parameter");

D
duke 已提交
291
   info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length);
B
bae 已提交
292

D
duke 已提交
293
   if (info_ptr->pcal_purpose == NULL)
B
bae 已提交
294 295 296 297 298 299
   {
      png_warning(png_ptr, "Insufficient memory for pCAL purpose");
      return;
   }

   png_memcpy(info_ptr->pcal_purpose, purpose, length);
D
duke 已提交
300

B
bae 已提交
301
   png_debug(3, "storing X0, X1, type, and nparams in info");
D
duke 已提交
302 303 304 305 306 307
   info_ptr->pcal_X0 = X0;
   info_ptr->pcal_X1 = X1;
   info_ptr->pcal_type = (png_byte)type;
   info_ptr->pcal_nparams = (png_byte)nparams;

   length = png_strlen(units) + 1;
B
bae 已提交
308 309 310
   png_debug1(3, "allocating units for info (%lu bytes)",
     (unsigned long)length);

D
duke 已提交
311
   info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length);
B
bae 已提交
312

D
duke 已提交
313
   if (info_ptr->pcal_units == NULL)
B
bae 已提交
314 315 316 317 318 319
   {
      png_warning(png_ptr, "Insufficient memory for pCAL units");
      return;
   }

   png_memcpy(info_ptr->pcal_units, units, length);
D
duke 已提交
320 321

   info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr,
B
bae 已提交
322 323
       (png_size_t)((nparams + 1) * png_sizeof(png_charp)));

D
duke 已提交
324
   if (info_ptr->pcal_params == NULL)
B
bae 已提交
325 326 327 328
   {
      png_warning(png_ptr, "Insufficient memory for pCAL params");
      return;
   }
D
duke 已提交
329

B
bae 已提交
330
   png_memset(info_ptr->pcal_params, 0, (nparams + 1) * png_sizeof(png_charp));
D
duke 已提交
331 332 333 334

   for (i = 0; i < nparams; i++)
   {
      length = png_strlen(params[i]) + 1;
B
bae 已提交
335 336 337
      png_debug2(3, "allocating parameter %d for info (%lu bytes)", i,
          (unsigned long)length);

D
duke 已提交
338
      info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
B
bae 已提交
339

D
duke 已提交
340
      if (info_ptr->pcal_params[i] == NULL)
B
bae 已提交
341 342 343 344 345 346
      {
         png_warning(png_ptr, "Insufficient memory for pCAL parameter");
         return;
      }

      png_memcpy(info_ptr->pcal_params[i], params[i], length);
D
duke 已提交
347 348 349 350 351 352 353
   }

   info_ptr->valid |= PNG_INFO_pCAL;
   info_ptr->free_me |= PNG_FREE_PCAL;
}
#endif

B
bae 已提交
354
#ifdef PNG_sCAL_SUPPORTED
D
duke 已提交
355
void PNGAPI
B
bae 已提交
356 357
png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,
    int unit, png_const_charp swidth, png_const_charp sheight)
D
duke 已提交
358
{
B
bae 已提交
359 360 361 362
   png_size_t lengthw = 0, lengthh = 0;

   png_debug1(1, "in %s storage function", "sCAL");

D
duke 已提交
363 364 365
   if (png_ptr == NULL || info_ptr == NULL)
      return;

B
bae 已提交
366 367 368 369 370
   /* Double check the unit (should never get here with an invalid
    * unit unless this is an API call.)
    */
   if (unit != 1 && unit != 2)
      png_error(png_ptr, "Invalid sCAL unit");
D
duke 已提交
371

B
bae 已提交
372 373 374
   if (swidth == NULL || (lengthw = png_strlen(swidth)) == 0 ||
       swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw))
      png_error(png_ptr, "Invalid sCAL width");
D
duke 已提交
375

B
bae 已提交
376 377 378
   if (sheight == NULL || (lengthh = png_strlen(sheight)) == 0 ||
       sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh))
      png_error(png_ptr, "Invalid sCAL height");
D
duke 已提交
379 380 381

   info_ptr->scal_unit = (png_byte)unit;

B
bae 已提交
382 383 384 385 386 387
   ++lengthw;

   png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw);

   info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, lengthw);

D
duke 已提交
388 389
   if (info_ptr->scal_s_width == NULL)
   {
B
bae 已提交
390 391
      png_warning(png_ptr, "Memory allocation failed while processing sCAL");
      return;
D
duke 已提交
392 393
   }

B
bae 已提交
394 395 396 397 398 399 400 401
   png_memcpy(info_ptr->scal_s_width, swidth, lengthw);

   ++lengthh;

   png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh);

   info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, lengthh);

D
duke 已提交
402 403 404
   if (info_ptr->scal_s_height == NULL)
   {
      png_free (png_ptr, info_ptr->scal_s_width);
B
bae 已提交
405 406 407 408
      info_ptr->scal_s_width = NULL;

      png_warning(png_ptr, "Memory allocation failed while processing sCAL");
      return;
D
duke 已提交
409
   }
B
bae 已提交
410 411

   png_memcpy(info_ptr->scal_s_height, sheight, lengthh);
D
duke 已提交
412 413 414 415

   info_ptr->valid |= PNG_INFO_sCAL;
   info_ptr->free_me |= PNG_FREE_SCAL;
}
B
bae 已提交
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473

#  ifdef PNG_FLOATING_POINT_SUPPORTED
void PNGAPI
png_set_sCAL(png_structp png_ptr, png_infop info_ptr, int unit, double width,
    double height)
{
   png_debug1(1, "in %s storage function", "sCAL");

   /* Check the arguments. */
   if (width <= 0)
      png_warning(png_ptr, "Invalid sCAL width ignored");

   else if (height <= 0)
      png_warning(png_ptr, "Invalid sCAL height ignored");

   else
   {
      /* Convert 'width' and 'height' to ASCII. */
      char swidth[PNG_sCAL_MAX_DIGITS+1];
      char sheight[PNG_sCAL_MAX_DIGITS+1];

      png_ascii_from_fp(png_ptr, swidth, sizeof swidth, width,
         PNG_sCAL_PRECISION);
      png_ascii_from_fp(png_ptr, sheight, sizeof sheight, height,
         PNG_sCAL_PRECISION);

      png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
   }
}
#  endif

#  ifdef PNG_FIXED_POINT_SUPPORTED
void PNGAPI
png_set_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, int unit,
    png_fixed_point width, png_fixed_point height)
{
   png_debug1(1, "in %s storage function", "sCAL");

   /* Check the arguments. */
   if (width <= 0)
      png_warning(png_ptr, "Invalid sCAL width ignored");

   else if (height <= 0)
      png_warning(png_ptr, "Invalid sCAL height ignored");

   else
   {
      /* Convert 'width' and 'height' to ASCII. */
      char swidth[PNG_sCAL_MAX_DIGITS+1];
      char sheight[PNG_sCAL_MAX_DIGITS+1];

      png_ascii_from_fixed(png_ptr, swidth, sizeof swidth, width);
      png_ascii_from_fixed(png_ptr, sheight, sizeof sheight, height);

      png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
   }
}
#  endif
D
duke 已提交
474 475
#endif

B
bae 已提交
476
#ifdef PNG_pHYs_SUPPORTED
D
duke 已提交
477 478
void PNGAPI
png_set_pHYs(png_structp png_ptr, png_infop info_ptr,
B
bae 已提交
479
    png_uint_32 res_x, png_uint_32 res_y, int unit_type)
D
duke 已提交
480
{
B
bae 已提交
481 482
   png_debug1(1, "in %s storage function", "pHYs");

D
duke 已提交
483 484 485 486 487 488 489 490 491 492 493 494
   if (png_ptr == NULL || info_ptr == NULL)
      return;

   info_ptr->x_pixels_per_unit = res_x;
   info_ptr->y_pixels_per_unit = res_y;
   info_ptr->phys_unit_type = (png_byte)unit_type;
   info_ptr->valid |= PNG_INFO_pHYs;
}
#endif

void PNGAPI
png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
B
bae 已提交
495
    png_const_colorp palette, int num_palette)
D
duke 已提交
496 497
{

B
bae 已提交
498 499
   png_debug1(1, "in %s storage function", "PLTE");

D
duke 已提交
500 501 502 503
   if (png_ptr == NULL || info_ptr == NULL)
      return;

   if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH)
B
bae 已提交
504 505
   {
      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
D
duke 已提交
506
         png_error(png_ptr, "Invalid palette length");
B
bae 已提交
507 508 509

      else
      {
D
duke 已提交
510 511
         png_warning(png_ptr, "Invalid palette length");
         return;
B
bae 已提交
512 513
      }
   }
D
duke 已提交
514

S
serb 已提交
515 516 517 518 519 520 521 522 523 524 525
   if ((num_palette > 0 && palette == NULL) ||
      (num_palette == 0
#        ifdef PNG_MNG_FEATURES_SUPPORTED
            && (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0
#        endif
      ))
   {
      png_error(png_ptr, "Invalid palette");
      return;
   }

B
bae 已提交
526
   /* It may not actually be necessary to set png_ptr->palette here;
D
duke 已提交
527 528 529 530 531 532
    * we do it for backward compatibility with the way the png_handle_tRNS
    * function used to do the allocation.
    */
   png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);

   /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
B
bae 已提交
533 534 535 536 537 538 539
    * of num_palette entries, in case of an invalid PNG file that has
    * too-large sample values.
    */
   png_ptr->palette = (png_colorp)png_calloc(png_ptr,
       PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color));

   png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof(png_color));
D
duke 已提交
540 541 542 543 544 545 546 547
   info_ptr->palette = png_ptr->palette;
   info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;

   info_ptr->free_me |= PNG_FREE_PLTE;

   info_ptr->valid |= PNG_INFO_PLTE;
}

B
bae 已提交
548
#ifdef PNG_sBIT_SUPPORTED
D
duke 已提交
549 550
void PNGAPI
png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
B
bae 已提交
551
    png_const_color_8p sig_bit)
D
duke 已提交
552
{
B
bae 已提交
553 554
   png_debug1(1, "in %s storage function", "sBIT");

D
duke 已提交
555 556 557
   if (png_ptr == NULL || info_ptr == NULL)
      return;

B
bae 已提交
558
   png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof(png_color_8));
D
duke 已提交
559 560 561 562
   info_ptr->valid |= PNG_INFO_sBIT;
}
#endif

B
bae 已提交
563
#ifdef PNG_sRGB_SUPPORTED
D
duke 已提交
564
void PNGAPI
B
bae 已提交
565
png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int srgb_intent)
D
duke 已提交
566
{
B
bae 已提交
567 568
   png_debug1(1, "in %s storage function", "sRGB");

D
duke 已提交
569 570 571
   if (png_ptr == NULL || info_ptr == NULL)
      return;

B
bae 已提交
572
   info_ptr->srgb_intent = (png_byte)srgb_intent;
D
duke 已提交
573 574 575 576 577
   info_ptr->valid |= PNG_INFO_sRGB;
}

void PNGAPI
png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
B
bae 已提交
578
    int srgb_intent)
D
duke 已提交
579
{
B
bae 已提交
580 581
   png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM");

D
duke 已提交
582 583 584
   if (png_ptr == NULL || info_ptr == NULL)
      return;

B
bae 已提交
585
   png_set_sRGB(png_ptr, info_ptr, srgb_intent);
D
duke 已提交
586

B
bae 已提交
587 588 589
#  ifdef PNG_gAMA_SUPPORTED
   png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE);
#  endif
D
duke 已提交
590

B
bae 已提交
591
#  ifdef PNG_cHRM_SUPPORTED
D
duke 已提交
592
   png_set_cHRM_fixed(png_ptr, info_ptr,
B
bae 已提交
593 594 595 596 597 598 599
      /* color      x       y */
      /* white */ 31270L, 32900L,
      /* red   */ 64000L, 33000L,
      /* green */ 30000L, 60000L,
      /* blue  */ 15000L,  6000L
   );
#  endif /* cHRM */
D
duke 已提交
600
}
B
bae 已提交
601
#endif /* sRGB */
D
duke 已提交
602 603


B
bae 已提交
604
#ifdef PNG_iCCP_SUPPORTED
D
duke 已提交
605 606
void PNGAPI
png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
B
bae 已提交
607 608
    png_const_charp name, int compression_type,
    png_const_bytep profile, png_uint_32 proflen)
D
duke 已提交
609 610
{
   png_charp new_iccp_name;
B
bae 已提交
611 612 613 614
   png_bytep new_iccp_profile;
   png_uint_32 length;

   png_debug1(1, "in %s storage function", "iCCP");
D
duke 已提交
615 616 617 618

   if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
      return;

B
bae 已提交
619 620 621
   length = png_strlen(name)+1;
   new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length);

D
duke 已提交
622 623
   if (new_iccp_name == NULL)
   {
B
bae 已提交
624
        png_warning(png_ptr, "Insufficient memory to process iCCP chunk");
D
duke 已提交
625 626
      return;
   }
B
bae 已提交
627 628 629 630

   png_memcpy(new_iccp_name, name, length);
   new_iccp_profile = (png_bytep)png_malloc_warn(png_ptr, proflen);

D
duke 已提交
631 632 633
   if (new_iccp_profile == NULL)
   {
      png_free (png_ptr, new_iccp_name);
B
bae 已提交
634 635
      png_warning(png_ptr,
          "Insufficient memory to process iCCP profile");
D
duke 已提交
636 637
      return;
   }
B
bae 已提交
638

D
duke 已提交
639 640 641 642 643 644 645 646
   png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);

   png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);

   info_ptr->iccp_proflen = proflen;
   info_ptr->iccp_name = new_iccp_name;
   info_ptr->iccp_profile = new_iccp_profile;
   /* Compression is always zero but is here so the API and info structure
B
bae 已提交
647 648
    * does not have to change if we introduce multiple compression types
    */
D
duke 已提交
649 650 651 652 653 654
   info_ptr->iccp_compression = (png_byte)compression_type;
   info_ptr->free_me |= PNG_FREE_ICCP;
   info_ptr->valid |= PNG_INFO_iCCP;
}
#endif

B
bae 已提交
655
#ifdef PNG_TEXT_SUPPORTED
D
duke 已提交
656
void PNGAPI
B
bae 已提交
657 658
png_set_text(png_structp png_ptr, png_infop info_ptr, png_const_textp text_ptr,
    int num_text)
D
duke 已提交
659 660
{
   int ret;
B
bae 已提交
661 662
   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);

D
duke 已提交
663
   if (ret)
B
bae 已提交
664
      png_error(png_ptr, "Insufficient memory to store text");
D
duke 已提交
665 666 667
}

int /* PRIVATE */
B
bae 已提交
668 669
png_set_text_2(png_structp png_ptr, png_infop info_ptr,
    png_const_textp text_ptr, int num_text)
D
duke 已提交
670 671 672
{
   int i;

B
bae 已提交
673 674 675
   png_debug1(1, "in %s storage function", ((png_ptr == NULL ||
       png_ptr->chunk_name[0] == '\0') ?
       "text" : (png_const_charp)png_ptr->chunk_name));
D
duke 已提交
676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693

   if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
      return(0);

   /* Make sure we have enough space in the "text" array in info_struct
    * to hold all of the incoming text_ptr objects.
    */
   if (info_ptr->num_text + num_text > info_ptr->max_text)
   {
      if (info_ptr->text != NULL)
      {
         png_textp old_text;
         int old_max;

         old_max = info_ptr->max_text;
         info_ptr->max_text = info_ptr->num_text + num_text + 8;
         old_text = info_ptr->text;
         info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
B
bae 已提交
694 695
            (png_size_t)(info_ptr->max_text * png_sizeof(png_text)));

D
duke 已提交
696
         if (info_ptr->text == NULL)
B
bae 已提交
697 698 699 700 701
         {
            png_free(png_ptr, old_text);
            return(1);
         }

D
duke 已提交
702
         png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
B
bae 已提交
703
             png_sizeof(png_text)));
D
duke 已提交
704 705
         png_free(png_ptr, old_text);
      }
B
bae 已提交
706

D
duke 已提交
707 708 709 710 711
      else
      {
         info_ptr->max_text = num_text + 8;
         info_ptr->num_text = 0;
         info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
B
bae 已提交
712
             (png_size_t)(info_ptr->max_text * png_sizeof(png_text)));
D
duke 已提交
713
         if (info_ptr->text == NULL)
B
bae 已提交
714
            return(1);
D
duke 已提交
715 716
         info_ptr->free_me |= PNG_FREE_TEXT;
      }
B
bae 已提交
717 718 719

      png_debug1(3, "allocated %d entries for info_ptr->text",
          info_ptr->max_text);
D
duke 已提交
720 721 722
   }
   for (i = 0; i < num_text; i++)
   {
B
bae 已提交
723 724
      png_size_t text_length, key_len;
      png_size_t lang_len, lang_key_len;
D
duke 已提交
725 726 727 728 729
      png_textp textp = &(info_ptr->text[info_ptr->num_text]);

      if (text_ptr[i].key == NULL)
          continue;

B
bae 已提交
730 731 732 733 734 735 736
      if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE ||
          text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
      {
         png_warning(png_ptr, "text compression mode is out of range");
         continue;
      }

D
duke 已提交
737 738
      key_len = png_strlen(text_ptr[i].key);

B
bae 已提交
739
      if (text_ptr[i].compression <= 0)
D
duke 已提交
740
      {
B
bae 已提交
741 742
         lang_len = 0;
         lang_key_len = 0;
D
duke 已提交
743
      }
B
bae 已提交
744

D
duke 已提交
745
      else
B
bae 已提交
746
#  ifdef PNG_iTXt_SUPPORTED
D
duke 已提交
747
      {
B
bae 已提交
748 749 750 751 752 753 754 755 756 757 758 759 760
         /* Set iTXt data */

         if (text_ptr[i].lang != NULL)
            lang_len = png_strlen(text_ptr[i].lang);

         else
            lang_len = 0;

         if (text_ptr[i].lang_key != NULL)
            lang_key_len = png_strlen(text_ptr[i].lang_key);

         else
            lang_key_len = 0;
D
duke 已提交
761
      }
B
bae 已提交
762
#  else /* PNG_iTXt_SUPPORTED */
D
duke 已提交
763
      {
B
bae 已提交
764 765
         png_warning(png_ptr, "iTXt chunk not supported");
         continue;
D
duke 已提交
766
      }
B
bae 已提交
767
#  endif
D
duke 已提交
768 769 770 771

      if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
      {
         text_length = 0;
B
bae 已提交
772 773
#  ifdef PNG_iTXt_SUPPORTED
         if (text_ptr[i].compression > 0)
D
duke 已提交
774
            textp->compression = PNG_ITXT_COMPRESSION_NONE;
B
bae 已提交
775

D
duke 已提交
776
         else
B
bae 已提交
777
#  endif
D
duke 已提交
778 779
            textp->compression = PNG_TEXT_COMPRESSION_NONE;
      }
B
bae 已提交
780

D
duke 已提交
781 782 783 784 785 786 787
      else
      {
         text_length = png_strlen(text_ptr[i].text);
         textp->compression = text_ptr[i].compression;
      }

      textp->key = (png_charp)png_malloc_warn(png_ptr,
B
bae 已提交
788 789 790
          (png_size_t)
          (key_len + text_length + lang_len + lang_key_len + 4));

D
duke 已提交
791
      if (textp->key == NULL)
B
bae 已提交
792 793 794 795 796 797 798 799 800 801
         return(1);

      png_debug2(2, "Allocated %lu bytes at %p in png_set_text",
          (unsigned long)(png_uint_32)
          (key_len + lang_len + lang_key_len + text_length + 4),
          textp->key);

      png_memcpy(textp->key, text_ptr[i].key,(png_size_t)(key_len));
      *(textp->key + key_len) = '\0';

D
duke 已提交
802 803
      if (text_ptr[i].compression > 0)
      {
B
bae 已提交
804
         textp->lang = textp->key + key_len + 1;
D
duke 已提交
805
         png_memcpy(textp->lang, text_ptr[i].lang, lang_len);
B
bae 已提交
806 807
         *(textp->lang + lang_len) = '\0';
         textp->lang_key = textp->lang + lang_len + 1;
D
duke 已提交
808
         png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
B
bae 已提交
809 810
         *(textp->lang_key + lang_key_len) = '\0';
         textp->text = textp->lang_key + lang_key_len + 1;
D
duke 已提交
811
      }
B
bae 已提交
812

D
duke 已提交
813 814 815 816
      else
      {
         textp->lang=NULL;
         textp->lang_key=NULL;
B
bae 已提交
817
         textp->text = textp->key + key_len + 1;
D
duke 已提交
818
      }
B
bae 已提交
819 820

      if (text_length)
D
duke 已提交
821
         png_memcpy(textp->text, text_ptr[i].text,
B
bae 已提交
822
             (png_size_t)(text_length));
D
duke 已提交
823

B
bae 已提交
824 825 826 827
      *(textp->text + text_length) = '\0';

#  ifdef PNG_iTXt_SUPPORTED
      if (textp->compression > 0)
D
duke 已提交
828 829 830 831
      {
         textp->text_length = 0;
         textp->itxt_length = text_length;
      }
B
bae 已提交
832

D
duke 已提交
833
      else
B
bae 已提交
834
#  endif
D
duke 已提交
835 836 837 838
      {
         textp->text_length = text_length;
         textp->itxt_length = 0;
      }
B
bae 已提交
839

D
duke 已提交
840
      info_ptr->num_text++;
B
bae 已提交
841
      png_debug1(3, "transferred text chunk %d", info_ptr->num_text);
D
duke 已提交
842 843 844 845 846
   }
   return(0);
}
#endif

B
bae 已提交
847
#ifdef PNG_tIME_SUPPORTED
D
duke 已提交
848
void PNGAPI
B
bae 已提交
849
png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time)
D
duke 已提交
850
{
B
bae 已提交
851 852
   png_debug1(1, "in %s storage function", "tIME");

D
duke 已提交
853 854 855 856
   if (png_ptr == NULL || info_ptr == NULL ||
       (png_ptr->mode & PNG_WROTE_tIME))
      return;

B
bae 已提交
857
   png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof(png_time));
D
duke 已提交
858 859 860 861
   info_ptr->valid |= PNG_INFO_tIME;
}
#endif

B
bae 已提交
862
#ifdef PNG_tRNS_SUPPORTED
D
duke 已提交
863 864
void PNGAPI
png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
B
bae 已提交
865
    png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color)
D
duke 已提交
866
{
B
bae 已提交
867 868
   png_debug1(1, "in %s storage function", "tRNS");

D
duke 已提交
869 870 871
   if (png_ptr == NULL || info_ptr == NULL)
      return;

B
bae 已提交
872
   if (trans_alpha != NULL)
D
duke 已提交
873
   {
B
bae 已提交
874
       /* It may not actually be necessary to set png_ptr->trans_alpha here;
D
duke 已提交
875 876 877
        * we do it for backward compatibility with the way the png_handle_tRNS
        * function used to do the allocation.
        */
B
bae 已提交
878

D
duke 已提交
879
       png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
B
bae 已提交
880

D
duke 已提交
881
       /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
B
bae 已提交
882 883 884 885 886
       png_ptr->trans_alpha = info_ptr->trans_alpha =
           (png_bytep)png_malloc(png_ptr, (png_size_t)PNG_MAX_PALETTE_LENGTH);

       if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
          png_memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans);
D
duke 已提交
887 888
   }

B
bae 已提交
889
   if (trans_color != NULL)
D
duke 已提交
890
   {
B
bae 已提交
891 892 893 894 895 896 897 898 899 900 901 902
      int sample_max = (1 << info_ptr->bit_depth);

      if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
          (int)trans_color->gray > sample_max) ||
          (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
          ((int)trans_color->red > sample_max ||
          (int)trans_color->green > sample_max ||
          (int)trans_color->blue > sample_max)))
         png_warning(png_ptr,
            "tRNS chunk has out-of-range samples for bit_depth");

      png_memcpy(&(info_ptr->trans_color), trans_color,
D
duke 已提交
903
         png_sizeof(png_color_16));
B
bae 已提交
904

D
duke 已提交
905
      if (num_trans == 0)
B
bae 已提交
906
         num_trans = 1;
D
duke 已提交
907
   }
B
bae 已提交
908

D
duke 已提交
909
   info_ptr->num_trans = (png_uint_16)num_trans;
B
bae 已提交
910 911 912 913 914 915

   if (num_trans != 0)
   {
      info_ptr->valid |= PNG_INFO_tRNS;
      info_ptr->free_me |= PNG_FREE_TRNS;
   }
D
duke 已提交
916 917 918
}
#endif

B
bae 已提交
919
#ifdef PNG_sPLT_SUPPORTED
D
duke 已提交
920 921
void PNGAPI
png_set_sPLT(png_structp png_ptr,
B
bae 已提交
922 923 924 925 926 927 928 929 930
    png_infop info_ptr, png_const_sPLT_tp entries, int nentries)
/*
 *  entries        - array of png_sPLT_t structures
 *                   to be added to the list of palettes
 *                   in the info structure.
 *
 *  nentries       - number of palette structures to be
 *                   added.
 */
D
duke 已提交
931
{
B
bae 已提交
932 933
   png_sPLT_tp np;
   int i;
D
duke 已提交
934

B
bae 已提交
935 936
   if (png_ptr == NULL || info_ptr == NULL)
      return;
D
duke 已提交
937

B
bae 已提交
938 939 940 941 942 943 944
   np = (png_sPLT_tp)png_malloc_warn(png_ptr,
       (info_ptr->splt_palettes_num + nentries) *
       (png_size_t)png_sizeof(png_sPLT_t));

   if (np == NULL)
   {
      png_warning(png_ptr, "No memory for sPLT palettes");
D
duke 已提交
945
      return;
B
bae 已提交
946
   }
D
duke 已提交
947

B
bae 已提交
948 949
   png_memcpy(np, info_ptr->splt_palettes,
       info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t));
D
duke 已提交
950

B
bae 已提交
951 952
   png_free(png_ptr, info_ptr->splt_palettes);
   info_ptr->splt_palettes=NULL;
D
duke 已提交
953

B
bae 已提交
954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993
   for (i = 0; i < nentries; i++)
   {
      png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
      png_const_sPLT_tp from = entries + i;
      png_uint_32 length;

      length = png_strlen(from->name) + 1;
      to->name = (png_charp)png_malloc_warn(png_ptr, (png_size_t)length);

      if (to->name == NULL)
      {
         png_warning(png_ptr,
             "Out of memory while processing sPLT chunk");
         continue;
      }

      png_memcpy(to->name, from->name, length);
      to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr,
          (png_size_t)(from->nentries * png_sizeof(png_sPLT_entry)));

      if (to->entries == NULL)
      {
         png_warning(png_ptr,
             "Out of memory while processing sPLT chunk");
         png_free(png_ptr, to->name);
         to->name = NULL;
         continue;
      }

      png_memcpy(to->entries, from->entries,
          from->nentries * png_sizeof(png_sPLT_entry));

      to->nentries = from->nentries;
      to->depth = from->depth;
   }

   info_ptr->splt_palettes = np;
   info_ptr->splt_palettes_num += nentries;
   info_ptr->valid |= PNG_INFO_sPLT;
   info_ptr->free_me |= PNG_FREE_SPLT;
D
duke 已提交
994 995 996
}
#endif /* PNG_sPLT_SUPPORTED */

B
bae 已提交
997
#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
D
duke 已提交
998 999
void PNGAPI
png_set_unknown_chunks(png_structp png_ptr,
B
bae 已提交
1000
   png_infop info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
D
duke 已提交
1001
{
B
bae 已提交
1002 1003 1004 1005 1006
   png_unknown_chunkp np;
   int i;

   if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)
      return;
D
duke 已提交
1007

B
bae 已提交
1008 1009 1010
   np = (png_unknown_chunkp)png_malloc_warn(png_ptr,
       (png_size_t)(info_ptr->unknown_chunks_num + num_unknowns) *
       png_sizeof(png_unknown_chunk));
D
duke 已提交
1011

B
bae 已提交
1012 1013 1014 1015 1016 1017
   if (np == NULL)
   {
      png_warning(png_ptr,
          "Out of memory while processing unknown chunk");
      return;
   }
D
duke 已提交
1018

B
bae 已提交
1019 1020 1021
   png_memcpy(np, info_ptr->unknown_chunks,
       (png_size_t)info_ptr->unknown_chunks_num *
       png_sizeof(png_unknown_chunk));
D
duke 已提交
1022

B
bae 已提交
1023 1024
   png_free(png_ptr, info_ptr->unknown_chunks);
   info_ptr->unknown_chunks = NULL;
D
duke 已提交
1025

B
bae 已提交
1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060
   for (i = 0; i < num_unknowns; i++)
   {
      png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;
      png_const_unknown_chunkp from = unknowns + i;

      png_memcpy(to->name, from->name, png_sizeof(from->name));
      to->name[png_sizeof(to->name)-1] = '\0';
      to->size = from->size;

      /* Note our location in the read or write sequence */
      to->location = (png_byte)(png_ptr->mode & 0xff);

      if (from->size == 0)
         to->data=NULL;

      else
      {
         to->data = (png_bytep)png_malloc_warn(png_ptr,
             (png_size_t)from->size);

         if (to->data == NULL)
         {
            png_warning(png_ptr,
                "Out of memory while processing unknown chunk");
            to->size = 0;
         }

         else
            png_memcpy(to->data, from->data, from->size);
      }
   }

   info_ptr->unknown_chunks = np;
   info_ptr->unknown_chunks_num += num_unknowns;
   info_ptr->free_me |= PNG_FREE_UNKN;
D
duke 已提交
1061
}
B
bae 已提交
1062

D
duke 已提交
1063 1064
void PNGAPI
png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
B
bae 已提交
1065
    int chunk, int location)
D
duke 已提交
1066
{
B
bae 已提交
1067 1068
   if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <
       info_ptr->unknown_chunks_num)
D
duke 已提交
1069 1070 1071 1072 1073
      info_ptr->unknown_chunks[chunk].location = (png_byte)location;
}
#endif


B
bae 已提交
1074
#ifdef PNG_MNG_FEATURES_SUPPORTED
D
duke 已提交
1075 1076 1077
png_uint_32 PNGAPI
png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features)
{
B
bae 已提交
1078 1079
   png_debug(1, "in png_permit_mng_features");

D
duke 已提交
1080 1081
   if (png_ptr == NULL)
      return (png_uint_32)0;
B
bae 已提交
1082

D
duke 已提交
1083
   png_ptr->mng_features_permitted =
B
bae 已提交
1084 1085
       (png_byte)(mng_features & PNG_ALL_MNG_FEATURES);

D
duke 已提交
1086 1087 1088 1089
   return (png_uint_32)png_ptr->mng_features_permitted;
}
#endif

B
bae 已提交
1090
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
D
duke 已提交
1091
void PNGAPI
B
bae 已提交
1092 1093
png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_const_bytep
    chunk_list, int num_chunks)
D
duke 已提交
1094
{
B
bae 已提交
1095 1096 1097 1098 1099 1100 1101 1102 1103 1104
   png_bytep new_list, p;
   int i, old_num_chunks;
   if (png_ptr == NULL)
      return;

   if (num_chunks == 0)
   {
      if (keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE)
         png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS;

D
duke 已提交
1105
      else
B
bae 已提交
1106 1107 1108 1109
         png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS;

      if (keep == PNG_HANDLE_CHUNK_ALWAYS)
         png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS;
D
duke 已提交
1110 1111

      else
B
bae 已提交
1112 1113
         png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS;

D
duke 已提交
1114
      return;
B
bae 已提交
1115 1116 1117
   }

   if (chunk_list == NULL)
D
duke 已提交
1118
      return;
B
bae 已提交
1119 1120 1121 1122 1123 1124 1125 1126

   old_num_chunks = png_ptr->num_chunk_list;
   new_list=(png_bytep)png_malloc(png_ptr,
       (png_size_t)(5*(num_chunks + old_num_chunks)));

   if (png_ptr->chunk_list != NULL)
   {
      png_memcpy(new_list, png_ptr->chunk_list,
D
duke 已提交
1127
          (png_size_t)(5*old_num_chunks));
B
bae 已提交
1128 1129 1130 1131 1132
      png_free(png_ptr, png_ptr->chunk_list);
      png_ptr->chunk_list=NULL;
   }

   png_memcpy(new_list + 5*old_num_chunks, chunk_list,
D
duke 已提交
1133
       (png_size_t)(5*num_chunks));
B
bae 已提交
1134 1135 1136 1137 1138 1139 1140

   for (p = new_list + 5*old_num_chunks + 4, i = 0; i<num_chunks; i++, p += 5)
      *p=(png_byte)keep;

   png_ptr->num_chunk_list = old_num_chunks + num_chunks;
   png_ptr->chunk_list = new_list;
   png_ptr->free_me |= PNG_FREE_LIST;
D
duke 已提交
1141 1142 1143
}
#endif

B
bae 已提交
1144
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
D
duke 已提交
1145 1146
void PNGAPI
png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr,
B
bae 已提交
1147
    png_user_chunk_ptr read_user_chunk_fn)
D
duke 已提交
1148
{
B
bae 已提交
1149 1150
   png_debug(1, "in png_set_read_user_chunk_fn");

D
duke 已提交
1151 1152
   if (png_ptr == NULL)
      return;
B
bae 已提交
1153

D
duke 已提交
1154 1155 1156 1157 1158
   png_ptr->read_user_chunk_fn = read_user_chunk_fn;
   png_ptr->user_chunk_ptr = user_chunk_ptr;
}
#endif

B
bae 已提交
1159
#ifdef PNG_INFO_IMAGE_SUPPORTED
D
duke 已提交
1160 1161 1162
void PNGAPI
png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
{
B
bae 已提交
1163
   png_debug1(1, "in %s storage function", "rows");
D
duke 已提交
1164 1165 1166 1167

   if (png_ptr == NULL || info_ptr == NULL)
      return;

B
bae 已提交
1168
   if (info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
D
duke 已提交
1169
      png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
B
bae 已提交
1170

D
duke 已提交
1171
   info_ptr->row_pointers = row_pointers;
B
bae 已提交
1172 1173

   if (row_pointers)
D
duke 已提交
1174 1175 1176 1177 1178
      info_ptr->valid |= PNG_INFO_IDAT;
}
#endif

void PNGAPI
B
bae 已提交
1179
png_set_compression_buffer_size(png_structp png_ptr, png_size_t size)
D
duke 已提交
1180 1181 1182
{
    if (png_ptr == NULL)
       return;
B
bae 已提交
1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195

    png_free(png_ptr, png_ptr->zbuf);

    if (size > ZLIB_IO_MAX)
    {
       png_warning(png_ptr, "Attempt to set buffer size beyond max ignored");
       png_ptr->zbuf_size = ZLIB_IO_MAX;
       size = ZLIB_IO_MAX; /* must fit */
    }

    else
       png_ptr->zbuf_size = (uInt)size;

D
duke 已提交
1196
    png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size);
B
bae 已提交
1197 1198 1199 1200

    /* The following ensures a relatively safe failure if this gets called while
     * the buffer is actually in use.
     */
D
duke 已提交
1201
    png_ptr->zstream.next_out = png_ptr->zbuf;
B
bae 已提交
1202 1203
    png_ptr->zstream.avail_out = 0;
    png_ptr->zstream.avail_in = 0;
D
duke 已提交
1204 1205 1206 1207 1208 1209
}

void PNGAPI
png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask)
{
   if (png_ptr && info_ptr)
B
bae 已提交
1210
      info_ptr->valid &= ~mask;
D
duke 已提交
1211 1212 1213
}


B
bae 已提交
1214 1215 1216

#ifdef PNG_SET_USER_LIMITS_SUPPORTED
/* This function was added to libpng 1.2.6 */
D
duke 已提交
1217
void PNGAPI
B
bae 已提交
1218 1219
png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max,
    png_uint_32 user_height_max)
D
duke 已提交
1220
{
B
bae 已提交
1221 1222 1223 1224 1225 1226
   /* Images with dimensions larger than these limits will be
    * rejected by png_set_IHDR().  To accept any PNG datastream
    * regardless of dimensions, set both limits to 0x7ffffffL.
    */
   if (png_ptr == NULL)
      return;
D
duke 已提交
1227

B
bae 已提交
1228 1229
   png_ptr->user_width_max = user_width_max;
   png_ptr->user_height_max = user_height_max;
D
duke 已提交
1230 1231
}

B
bae 已提交
1232
/* This function was added to libpng 1.4.0 */
D
duke 已提交
1233
void PNGAPI
B
bae 已提交
1234 1235
png_set_chunk_cache_max (png_structp png_ptr,
   png_uint_32 user_chunk_cache_max)
D
duke 已提交
1236
{
B
bae 已提交
1237 1238
    if (png_ptr)
       png_ptr->user_chunk_cache_max = user_chunk_cache_max;
D
duke 已提交
1239 1240
}

B
bae 已提交
1241
/* This function was added to libpng 1.4.1 */
D
duke 已提交
1242
void PNGAPI
B
bae 已提交
1243 1244
png_set_chunk_malloc_max (png_structp png_ptr,
    png_alloc_size_t user_chunk_malloc_max)
D
duke 已提交
1245
{
B
bae 已提交
1246 1247
   if (png_ptr)
      png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
D
duke 已提交
1248 1249 1250
}
#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */

B
bae 已提交
1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264

#ifdef PNG_BENIGN_ERRORS_SUPPORTED
void PNGAPI
png_set_benign_errors(png_structp png_ptr, int allowed)
{
   png_debug(1, "in png_set_benign_errors");

   if (allowed)
      png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;

   else
      png_ptr->flags &= ~PNG_FLAG_BENIGN_ERRORS_WARN;
}
#endif /* PNG_BENIGN_ERRORS_SUPPORTED */
D
duke 已提交
1265
#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */