pngset.c 33.2 KB
Newer Older
A
Andreas Dilger 已提交
1 2

/* pngset.c - storage of image information into info struct
3
 *
4
 * Last changed in libpng 1.5.0 [(PENDING RELEASE)]
5
 * Copyright (c) 1998-2011 Glenn Randers-Pehrson
6 7
 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
 * (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 14 15 16 17
 * 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.
 */
A
Andreas Dilger 已提交
18

19
#include "pngpriv.h"
20

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

23
#ifdef PNG_bKGD_SUPPORTED
24
void PNGAPI
25 26
png_set_bKGD(png_structp png_ptr, png_infop info_ptr,
    png_const_color_16p background)
A
Andreas Dilger 已提交
27
{
28
   png_debug1(1, "in %s storage function", "bKGD");
29

30
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
31 32
      return;

33
   png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16));
A
Andreas Dilger 已提交
34 35 36 37
   info_ptr->valid |= PNG_INFO_bKGD;
}
#endif

38
#ifdef PNG_cHRM_SUPPORTED
G
[devel]  
Glenn Randers-Pehrson 已提交
39
void PNGFAPI
40
png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
41 42 43
    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)
44
{
45
   png_debug1(1, "in %s storage function", "cHRM fixed");
46

47 48
   if (png_ptr == NULL || info_ptr == NULL)
      return;
A
Andreas Dilger 已提交
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
   {
G
[devel]  
Glenn Randers-Pehrson 已提交
55 56 57 58 59 60 61 62
      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;
63
      info_ptr->valid |= PNG_INFO_cHRM;
64
   }
65 66
}

67
#  ifdef PNG_FLOATING_POINT_SUPPORTED
68
void PNGAPI
G
[devel]  
Glenn Randers-Pehrson 已提交
69 70 71
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)
A
Andreas Dilger 已提交
72
{
G
[devel]  
Glenn Randers-Pehrson 已提交
73 74 75 76 77 78 79 80 81 82
   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"));
}
83
#  endif /* PNG_FLOATING_POINT_SUPPORTED */
84

G
[devel]  
Glenn Randers-Pehrson 已提交
85
#endif /* PNG_cHRM_SUPPORTED */
86

G
[devel]  
Glenn Randers-Pehrson 已提交
87 88
#ifdef PNG_gAMA_SUPPORTED
void PNGFAPI
89
png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
G
[devel]  
Glenn Randers-Pehrson 已提交
90
    gamma)
91
{
92
   png_debug1(1, "in %s storage function", "gAMA");
93

94 95 96
   if (png_ptr == NULL || info_ptr == NULL)
      return;

G
[devel]  
Glenn Randers-Pehrson 已提交
97
   /* Previously these values were limited, however they must be
98
    * wrong, therefore storing them (and setting PNG_INFO_gAMA)
G
[devel]  
Glenn Randers-Pehrson 已提交
99 100 101 102 103 104
    * must be wrong too.
    */
   if (gamma > (png_fixed_point)PNG_UINT_31_MAX)
      png_warning(png_ptr, "Gamma too large, ignored");

   else if (gamma <= 0)
105
      png_warning(png_ptr, "Negative or zero gamma ignored");
106

107 108
   else
   {
G
[devel]  
Glenn Randers-Pehrson 已提交
109 110
      info_ptr->gamma = gamma;
      info_ptr->valid |= PNG_INFO_gAMA;
111
   }
G
[devel]  
Glenn Randers-Pehrson 已提交
112
}
113

114
#  ifdef PNG_FLOATING_POINT_SUPPORTED
G
[devel]  
Glenn Randers-Pehrson 已提交
115 116 117 118
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,
119
       "png_set_gAMA"));
A
Andreas Dilger 已提交
120
}
121
#  endif
122
#endif
A
Andreas Dilger 已提交
123

124
#ifdef PNG_hIST_SUPPORTED
125
void PNGAPI
126
png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_const_uint_16p hist)
A
Andreas Dilger 已提交
127
{
128
   int i;
129

130
   png_debug1(1, "in %s storage function", "hIST");
131

132
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
133
      return;
134

135
   if (info_ptr->num_palette == 0 || info_ptr->num_palette
136
       > PNG_MAX_PALETTE_LENGTH)
137
   {
138
      png_warning(png_ptr,
139
          "Invalid palette size, hIST allocation skipped");
140

141
      return;
142
   }
143 144

   png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
145

146 147 148
   /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in
    * version 1.2.1
    */
149
   png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr,
150
       PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16));
151

152
   if (png_ptr->hist == NULL)
153 154 155 156
   {
      png_warning(png_ptr, "Insufficient memory for hIST chunk data");
      return;
   }
A
Andreas Dilger 已提交
157

158
   for (i = 0; i < info_ptr->num_palette; i++)
159
      png_ptr->hist[i] = hist[i];
160

161
   info_ptr->hist = png_ptr->hist;
A
Andreas Dilger 已提交
162
   info_ptr->valid |= PNG_INFO_hIST;
163
   info_ptr->free_me |= PNG_FREE_HIST;
A
Andreas Dilger 已提交
164 165 166
}
#endif

167
void PNGAPI
A
Andreas Dilger 已提交
168
png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
169 170 171
    png_uint_32 width, png_uint_32 height, int bit_depth,
    int color_type, int interlace_type, int compression_type,
    int filter_type)
A
Andreas Dilger 已提交
172
{
173
   png_debug1(1, "in %s storage function", "IHDR");
174

175
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
176 177 178 179 180
      return;

   info_ptr->width = width;
   info_ptr->height = height;
   info_ptr->bit_depth = (png_byte)bit_depth;
181
   info_ptr->color_type = (png_byte)color_type;
A
Andreas Dilger 已提交
182 183 184
   info_ptr->compression_type = (png_byte)compression_type;
   info_ptr->filter_type = (png_byte)filter_type;
   info_ptr->interlace_type = (png_byte)interlace_type;
185 186 187 188 189

   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);

190 191
   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
      info_ptr->channels = 1;
192

193
   else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
A
Andreas Dilger 已提交
194
      info_ptr->channels = 3;
195

A
Andreas Dilger 已提交
196 197
   else
      info_ptr->channels = 1;
198

A
Andreas Dilger 已提交
199 200
   if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
      info_ptr->channels++;
201

A
Andreas Dilger 已提交
202
   info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
203

204
   /* Check for potential overflow */
205 206 207 208 209 210
   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 */
211
      info_ptr->rowbytes = 0;
212
   else
213
      info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
A
Andreas Dilger 已提交
214 215
}

216
#ifdef PNG_oFFs_SUPPORTED
217
void PNGAPI
A
Andreas Dilger 已提交
218
png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
219
    png_int_32 offset_x, png_int_32 offset_y, int unit_type)
A
Andreas Dilger 已提交
220
{
221
   png_debug1(1, "in %s storage function", "oFFs");
222

223
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
224 225 226 227 228 229 230 231 232
      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

233
#ifdef PNG_pCAL_SUPPORTED
234
void PNGAPI
A
Andreas Dilger 已提交
235
png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
236 237
    png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type,
    int nparams, png_const_charp units, png_charpp params)
A
Andreas Dilger 已提交
238
{
239
   png_size_t length;
240
   int i;
A
Andreas Dilger 已提交
241

242
   png_debug1(1, "in %s storage function", "pCAL");
243

244
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
245 246 247
      return;

   length = png_strlen(purpose) + 1;
248
   png_debug1(3, "allocating purpose for info (%lu bytes)",
249
       (unsigned long)length);
250

G
[devel]  
Glenn Randers-Pehrson 已提交
251 252 253 254 255 256 257 258 259 260 261
   /* 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");

262
   info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length);
263

264
   if (info_ptr->pcal_purpose == NULL)
265
   {
266
      png_warning(png_ptr, "Insufficient memory for pCAL purpose");
267 268
      return;
   }
269

270
   png_memcpy(info_ptr->pcal_purpose, purpose, length);
A
Andreas Dilger 已提交
271

272
   png_debug(3, "storing X0, X1, type, and nparams in info");
A
Andreas Dilger 已提交
273 274 275 276 277 278
   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;
279
   png_debug1(3, "allocating units for info (%lu bytes)",
280
     (unsigned long)length);
281

282
   info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length);
283

284
   if (info_ptr->pcal_units == NULL)
285
   {
286
      png_warning(png_ptr, "Insufficient memory for pCAL units");
287 288
      return;
   }
289

290
   png_memcpy(info_ptr->pcal_units, units, length);
A
Andreas Dilger 已提交
291

292
   info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr,
293
       (png_size_t)((nparams + 1) * png_sizeof(png_charp)));
294

295
   if (info_ptr->pcal_params == NULL)
296
   {
297
      png_warning(png_ptr, "Insufficient memory for pCAL params");
298 299
      return;
   }
300

301
   png_memset(info_ptr->pcal_params, 0, (nparams + 1) * png_sizeof(png_charp));
A
Andreas Dilger 已提交
302 303 304 305

   for (i = 0; i < nparams; i++)
   {
      length = png_strlen(params[i]) + 1;
306
      png_debug2(3, "allocating parameter %d for info (%lu bytes)", i,
307
          (unsigned long)length);
308

309
      info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
310

311
      if (info_ptr->pcal_params[i] == NULL)
312
      {
313 314
         png_warning(png_ptr, "Insufficient memory for pCAL parameter");
         return;
315
      }
316

317
      png_memcpy(info_ptr->pcal_params[i], params[i], length);
A
Andreas Dilger 已提交
318 319 320
   }

   info_ptr->valid |= PNG_INFO_pCAL;
321
   info_ptr->free_me |= PNG_FREE_PCAL;
A
Andreas Dilger 已提交
322 323 324
}
#endif

325
#ifdef PNG_sCAL_SUPPORTED
326
void PNGAPI
327
png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,
328
    int unit, png_const_charp swidth, png_const_charp sheight)
329
{
330
   png_size_t lengthw = 0, lengthh = 0;
331

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

334 335 336
   if (png_ptr == NULL || info_ptr == NULL)
      return;

G
[devel]  
Glenn Randers-Pehrson 已提交
337 338 339 340 341 342 343 344 345 346 347 348 349 350
   /* 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");

   if (swidth == NULL || (lengthw = png_strlen(swidth)) <= 0 ||
       swidth[0] == 45 /*'-'*/ || !png_check_fp_string(swidth, lengthw))
      png_error(png_ptr, "Invalid sCAL width");

   if (sheight == NULL || (lengthh = png_strlen(sheight)) <= 0 ||
       sheight[0] == 45 /*'-'*/ || !png_check_fp_string(sheight, lengthh))
      png_error(png_ptr, "Invalid sCAL height");

351
   info_ptr->scal_unit = (png_byte)unit;
352

G
[devel]  
Glenn Randers-Pehrson 已提交
353
   ++lengthw;
354

G
[devel]  
Glenn Randers-Pehrson 已提交
355
   png_debug1(3, "allocating unit for info (%u bytes)", lengthw);
356

G
[devel]  
Glenn Randers-Pehrson 已提交
357
   info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, lengthw);
358

359 360
   if (info_ptr->scal_s_width == NULL)
   {
G
[devel]  
Glenn Randers-Pehrson 已提交
361
      png_warning(png_ptr, "Memory allocation failed while processing sCAL");
362
      return;
363
   }
364

G
[devel]  
Glenn Randers-Pehrson 已提交
365
   png_memcpy(info_ptr->scal_s_width, swidth, lengthw);
366

G
[devel]  
Glenn Randers-Pehrson 已提交
367
   ++lengthh;
368

G
[devel]  
Glenn Randers-Pehrson 已提交
369
   png_debug1(3, "allocating unit for info (%u bytes)", lengthh);
370

G
[devel]  
Glenn Randers-Pehrson 已提交
371
   info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, lengthh);
372

373 374 375
   if (info_ptr->scal_s_height == NULL)
   {
      png_free (png_ptr, info_ptr->scal_s_width);
376
      info_ptr->scal_s_width = NULL;
377

G
[devel]  
Glenn Randers-Pehrson 已提交
378
      png_warning(png_ptr, "Memory allocation failed while processing sCAL");
379
      return;
380
   }
381

G
[devel]  
Glenn Randers-Pehrson 已提交
382 383
   png_memcpy(info_ptr->scal_s_height, sheight, lengthh);

384
   info_ptr->valid |= PNG_INFO_sCAL;
385
   info_ptr->free_me |= PNG_FREE_SCAL;
386
}
G
[devel]  
Glenn Randers-Pehrson 已提交
387

388
#  ifdef PNG_FLOATING_POINT_SUPPORTED
G
[devel]  
Glenn Randers-Pehrson 已提交
389 390
void PNGAPI
png_set_sCAL(png_structp png_ptr, png_infop info_ptr, int unit, double width,
391
    double height)
G
[devel]  
Glenn Randers-Pehrson 已提交
392 393 394 395 396 397
{
   png_debug1(1, "in %s storage function", "sCAL");

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

G
[devel]  
Glenn Randers-Pehrson 已提交
399 400
   else if (height <= 0)
      png_warning(png_ptr, "Invalid sCAL height ignored");
401

G
[devel]  
Glenn Randers-Pehrson 已提交
402 403 404 405 406 407 408 409 410 411 412 413 414 415
   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);
   }
}
416
#  endif
417

418
#  ifdef PNG_FIXED_POINT_SUPPORTED
419 420
void PNGAPI
png_set_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, int unit,
421
    png_fixed_point width, png_fixed_point height)
422 423 424 425 426 427
{
   png_debug1(1, "in %s storage function", "sCAL");

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

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

432 433 434 435 436 437 438 439 440 441 442 443
   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);
   }
}
444
#  endif
445
#endif
446

447
#ifdef PNG_pHYs_SUPPORTED
448
void PNGAPI
A
Andreas Dilger 已提交
449
png_set_pHYs(png_structp png_ptr, png_infop info_ptr,
450
    png_uint_32 res_x, png_uint_32 res_y, int unit_type)
A
Andreas Dilger 已提交
451
{
452
   png_debug1(1, "in %s storage function", "pHYs");
453

454
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
455 456 457 458 459 460 461 462 463
      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

464
void PNGAPI
A
Andreas Dilger 已提交
465
png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
466
    png_const_colorp palette, int num_palette)
A
Andreas Dilger 已提交
467
{
468

469
   png_debug1(1, "in %s storage function", "PLTE");
470

471
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
472 473
      return;

474
   if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH)
475 476
   {
      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
477
         png_error(png_ptr, "Invalid palette length");
478

479 480
      else
      {
481 482
         png_warning(png_ptr, "Invalid palette length");
         return;
483 484
      }
   }
485

486
   /* It may not actually be necessary to set png_ptr->palette here;
487 488 489 490
    * 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);
491

492
   /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
493 494 495
    * of num_palette entries, in case of an invalid PNG file that has
    * too-large sample values.
    */
496
   png_ptr->palette = (png_colorp)png_calloc(png_ptr,
497
       PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color));
498

499
   png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof(png_color));
500 501 502 503
   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;
504

505
   info_ptr->valid |= PNG_INFO_PLTE;
A
Andreas Dilger 已提交
506 507
}

508
#ifdef PNG_sBIT_SUPPORTED
509
void PNGAPI
A
Andreas Dilger 已提交
510
png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
511
    png_const_color_8p sig_bit)
A
Andreas Dilger 已提交
512
{
513
   png_debug1(1, "in %s storage function", "sBIT");
514

515
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
516 517
      return;

518
   png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof(png_color_8));
A
Andreas Dilger 已提交
519 520 521 522
   info_ptr->valid |= PNG_INFO_sBIT;
}
#endif

523
#ifdef PNG_sRGB_SUPPORTED
524
void PNGAPI
525
png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent)
526
{
527
   png_debug1(1, "in %s storage function", "sRGB");
528

529
   if (png_ptr == NULL || info_ptr == NULL)
530 531
      return;

532
   info_ptr->srgb_intent = (png_byte)intent;
533 534
   info_ptr->valid |= PNG_INFO_sRGB;
}
535

536
void PNGAPI
537
png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
538
    int intent)
539
{
540
   png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM");
541

542
   if (png_ptr == NULL || info_ptr == NULL)
543 544 545 546
      return;

   png_set_sRGB(png_ptr, info_ptr, intent);

547
#  ifdef PNG_gAMA_SUPPORTED
548
   png_set_gAMA_fixed(png_ptr, info_ptr, 45455L);
549
#  endif
550

551
#  ifdef PNG_cHRM_SUPPORTED
552
   png_set_cHRM_fixed(png_ptr, info_ptr,
553 554 555 556 557 558
      /* color      x       y */
      /* white */ 31270L, 32900L,
      /* red   */ 64000L, 33000L,
      /* green */ 30000L, 60000L,
      /* blue  */ 15000L,  6000L
   );
559
#  endif /* cHRM */
560
}
561
#endif /* sRGB */
562

563

564
#ifdef PNG_iCCP_SUPPORTED
565
void PNGAPI
566
png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
567 568
    png_const_charp name, int compression_type,
    png_const_bytep profile, png_uint_32 proflen)
569
{
570
   png_charp new_iccp_name;
G
[devel]  
Glenn Randers-Pehrson 已提交
571
   png_bytep new_iccp_profile;
572
   png_uint_32 length;
573

574
   png_debug1(1, "in %s storage function", "iCCP");
575

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

579 580
   length = png_strlen(name)+1;
   new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length);
581

582 583
   if (new_iccp_name == NULL)
   {
584
        png_warning(png_ptr, "Insufficient memory to process iCCP chunk");
585 586
      return;
   }
587

588
   png_memcpy(new_iccp_name, name, length);
G
[devel]  
Glenn Randers-Pehrson 已提交
589
   new_iccp_profile = (png_bytep)png_malloc_warn(png_ptr, proflen);
590

591 592 593
   if (new_iccp_profile == NULL)
   {
      png_free (png_ptr, new_iccp_name);
594
      png_warning(png_ptr,
595
          "Insufficient memory to process iCCP profile");
596 597
      return;
   }
598

599 600
   png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);

601
   png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
602

603
   info_ptr->iccp_proflen = proflen;
604 605
   info_ptr->iccp_name = new_iccp_name;
   info_ptr->iccp_profile = new_iccp_profile;
606
   /* Compression is always zero but is here so the API and info structure
607 608
    * does not have to change if we introduce multiple compression types
    */
609
   info_ptr->iccp_compression = (png_byte)compression_type;
610
   info_ptr->free_me |= PNG_FREE_ICCP;
611 612 613 614
   info_ptr->valid |= PNG_INFO_iCCP;
}
#endif

615
#ifdef PNG_TEXT_SUPPORTED
616
void PNGAPI
617
png_set_text(png_structp png_ptr, png_infop info_ptr, png_const_textp text_ptr,
618
    int num_text)
619 620
{
   int ret;
621
   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
622

623
   if (ret)
624
      png_error(png_ptr, "Insufficient memory to store text");
625 626 627
}

int /* PRIVATE */
628 629
png_set_text_2(png_structp png_ptr, png_infop info_ptr,
    png_const_textp text_ptr, int num_text)
A
Andreas Dilger 已提交
630 631 632
{
   int i;

633
   png_debug1(1, "in %s storage function", ((png_ptr == NULL ||
634 635
       png_ptr->chunk_name[0] == '\0') ?
       "text" : (png_const_charp)png_ptr->chunk_name));
A
Andreas Dilger 已提交
636

637
   if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
638
      return(0);
A
Andreas Dilger 已提交
639 640 641 642 643 644 645 646 647 648 649 650 651 652

   /* 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;
653
         info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
654
            (png_size_t)(info_ptr->max_text * png_sizeof(png_text)));
655

656
         if (info_ptr->text == NULL)
657 658 659 660
         {
            png_free(png_ptr, old_text);
            return(1);
         }
661

662
         png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
663
             png_sizeof(png_text)));
A
Andreas Dilger 已提交
664 665
         png_free(png_ptr, old_text);
      }
666

A
Andreas Dilger 已提交
667 668 669 670
      else
      {
         info_ptr->max_text = num_text + 8;
         info_ptr->num_text = 0;
671
         info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
672
             (png_size_t)(info_ptr->max_text * png_sizeof(png_text)));
673
         if (info_ptr->text == NULL)
674
            return(1);
675
         info_ptr->free_me |= PNG_FREE_TEXT;
A
Andreas Dilger 已提交
676
      }
677

678
      png_debug1(3, "allocated %d entries for info_ptr->text",
679
          info_ptr->max_text);
A
Andreas Dilger 已提交
680 681 682
   }
   for (i = 0; i < num_text; i++)
   {
683 684
      png_size_t text_length, key_len;
      png_size_t lang_len, lang_key_len;
A
Andreas Dilger 已提交
685 686
      png_textp textp = &(info_ptr->text[info_ptr->num_text]);

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

690 691
      if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE ||
          text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
692 693 694 695 696
      {
         png_warning(png_ptr, "text compression mode is out of range");
         continue;
      }

697 698
      key_len = png_strlen(text_ptr[i].key);

699
      if (text_ptr[i].compression <= 0)
700
      {
701 702
         lang_len = 0;
         lang_key_len = 0;
703
      }
704

705
      else
706
#  ifdef PNG_iTXt_SUPPORTED
707
      {
708
         /* Set iTXt data */
709

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

713 714
         else
            lang_len = 0;
715

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

719 720
         else
            lang_key_len = 0;
721
      }
722
#  else /* PNG_iTXt_SUPPORTED */
723
      {
724 725
         png_warning(png_ptr, "iTXt chunk not supported");
         continue;
726
      }
727
#  endif
A
Andreas Dilger 已提交
728

729
      if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
A
Andreas Dilger 已提交
730
      {
731
         text_length = 0;
732
#  ifdef PNG_iTXt_SUPPORTED
733
         if (text_ptr[i].compression > 0)
734
            textp->compression = PNG_ITXT_COMPRESSION_NONE;
735

736
         else
737
#  endif
738
            textp->compression = PNG_TEXT_COMPRESSION_NONE;
A
Andreas Dilger 已提交
739
      }
740

A
Andreas Dilger 已提交
741 742
      else
      {
743
         text_length = png_strlen(text_ptr[i].text);
A
Andreas Dilger 已提交
744 745
         textp->compression = text_ptr[i].compression;
      }
746

747
      textp->key = (png_charp)png_malloc_warn(png_ptr,
748 749
          (png_size_t)
          (key_len + text_length + lang_len + lang_key_len + 4));
750

751
      if (textp->key == NULL)
752
         return(1);
753

754
      png_debug2(2, "Allocated %lu bytes at %x in png_set_text",
755 756 757
          (unsigned long)(png_uint_32)
          (key_len + lang_len + lang_key_len + text_length + 4),
          (int)textp->key);
758

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

762 763
      if (text_ptr[i].compression > 0)
      {
764
         textp->lang = textp->key + key_len + 1;
765
         png_memcpy(textp->lang, text_ptr[i].lang, lang_len);
766
         *(textp->lang + lang_len) = '\0';
767
         textp->lang_key = textp->lang + lang_len + 1;
768
         png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
769
         *(textp->lang_key + lang_key_len) = '\0';
770
         textp->text = textp->lang_key + lang_key_len + 1;
771
      }
772

773 774
      else
      {
775 776
         textp->lang=NULL;
         textp->lang_key=NULL;
777
         textp->text = textp->key + key_len + 1;
778
      }
779

780
      if (text_length)
781
         png_memcpy(textp->text, text_ptr[i].text,
782
             (png_size_t)(text_length));
783

784
      *(textp->text + text_length) = '\0';
785

786
#  ifdef PNG_iTXt_SUPPORTED
787
      if (textp->compression > 0)
788 789 790 791
      {
         textp->text_length = 0;
         textp->itxt_length = text_length;
      }
792

793
      else
794
#  endif
795 796 797 798
      {
         textp->text_length = text_length;
         textp->itxt_length = 0;
      }
799

A
Andreas Dilger 已提交
800
      info_ptr->num_text++;
801
      png_debug1(3, "transferred text chunk %d", info_ptr->num_text);
A
Andreas Dilger 已提交
802
   }
803
   return(0);
A
Andreas Dilger 已提交
804 805 806
}
#endif

807
#ifdef PNG_tIME_SUPPORTED
808
void PNGAPI
809
png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time)
A
Andreas Dilger 已提交
810
{
811
   png_debug1(1, "in %s storage function", "tIME");
812

813
   if (png_ptr == NULL || info_ptr == NULL ||
814
       (png_ptr->mode & PNG_WROTE_tIME))
A
Andreas Dilger 已提交
815 816
      return;

817
   png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof(png_time));
A
Andreas Dilger 已提交
818 819 820 821
   info_ptr->valid |= PNG_INFO_tIME;
}
#endif

822
#ifdef PNG_tRNS_SUPPORTED
823
void PNGAPI
A
Andreas Dilger 已提交
824
png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
825
    png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color)
A
Andreas Dilger 已提交
826
{
827
   png_debug1(1, "in %s storage function", "tRNS");
828

829
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
830 831
      return;

832
   if (trans_alpha != NULL)
833
   {
834
       /* It may not actually be necessary to set png_ptr->trans_alpha here;
835 836 837
        * we do it for backward compatibility with the way the png_handle_tRNS
        * function used to do the allocation.
        */
838

839
       png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
840

841
       /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
G
[devel]  
Glenn Randers-Pehrson 已提交
842
       png_ptr->trans_alpha = info_ptr->trans_alpha =
843
           (png_bytep)png_malloc(png_ptr, (png_size_t)PNG_MAX_PALETTE_LENGTH);
844

845
       if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
846
          png_memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans);
847
   }
A
Andreas Dilger 已提交
848

849
   if (trans_color != NULL)
A
Andreas Dilger 已提交
850
   {
851
      int sample_max = (1 << info_ptr->bit_depth);
852

853
      if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
854
          (int)trans_color->gray > sample_max) ||
855
          (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
856 857 858
          ((int)trans_color->red > sample_max ||
          (int)trans_color->green > sample_max ||
          (int)trans_color->blue > sample_max)))
859 860
         png_warning(png_ptr,
            "tRNS chunk has out-of-range samples for bit_depth");
861

G
[devel]  
Glenn Randers-Pehrson 已提交
862 863
      png_memcpy(&(info_ptr->trans_color), trans_color,
         png_sizeof(png_color_16));
864

865
      if (num_trans == 0)
866
         num_trans = 1;
A
Andreas Dilger 已提交
867
   }
868

A
Andreas Dilger 已提交
869
   info_ptr->num_trans = (png_uint_16)num_trans;
870

871 872 873 874 875
   if (num_trans != 0)
   {
      info_ptr->valid |= PNG_INFO_tRNS;
      info_ptr->free_me |= PNG_FREE_TRNS;
   }
A
Andreas Dilger 已提交
876 877 878
}
#endif

879
#ifdef PNG_sPLT_SUPPORTED
880
void PNGAPI
881
png_set_sPLT(png_structp png_ptr,
882
    png_infop info_ptr, png_const_sPLT_tp entries, int nentries)
883 884 885 886
/*
 *  entries        - array of png_sPLT_t structures
 *                   to be added to the list of palettes
 *                   in the info structure.
887
 *
888 889 890
 *  nentries       - number of palette structures to be
 *                   added.
 */
891
{
892 893
   png_sPLT_tp np;
   int i;
894

895 896
   if (png_ptr == NULL || info_ptr == NULL)
      return;
897

898 899
   np = (png_sPLT_tp)png_malloc_warn(png_ptr,
       (info_ptr->splt_palettes_num + nentries) *
900
       (png_size_t)png_sizeof(png_sPLT_t));
901

902 903
   if (np == NULL)
   {
904
      png_warning(png_ptr, "No memory for sPLT palettes");
905
      return;
906
   }
907

908
   png_memcpy(np, info_ptr->splt_palettes,
909
       info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t));
910

911 912
   png_free(png_ptr, info_ptr->splt_palettes);
   info_ptr->splt_palettes=NULL;
913

914 915 916
   for (i = 0; i < nentries; i++)
   {
      png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
917
      png_const_sPLT_tp from = entries + i;
918
      png_uint_32 length;
919

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

923 924 925
      if (to->name == NULL)
      {
         png_warning(png_ptr,
926
             "Out of memory while processing sPLT chunk");
927 928
         continue;
      }
929

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

934 935 936
      if (to->entries == NULL)
      {
         png_warning(png_ptr,
937
             "Out of memory while processing sPLT chunk");
938 939 940 941
         png_free(png_ptr, to->name);
         to->name = NULL;
         continue;
      }
942

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

946 947 948 949 950 951 952 953
      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;
954 955 956
}
#endif /* PNG_sPLT_SUPPORTED */

957
#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
958
void PNGAPI
959
png_set_unknown_chunks(png_structp png_ptr,
960
   png_infop info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
961
{
962 963 964 965
   png_unknown_chunkp np;
   int i;

   if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)
966
      return;
967 968

   np = (png_unknown_chunkp)png_malloc_warn(png_ptr,
969 970
       (png_size_t)(info_ptr->unknown_chunks_num + num_unknowns) *
       png_sizeof(png_unknown_chunk));
971

972 973 974
   if (np == NULL)
   {
      png_warning(png_ptr,
975
          "Out of memory while processing unknown chunk");
976 977 978 979
      return;
   }

   png_memcpy(np, info_ptr->unknown_chunks,
980 981
       (png_size_t)info_ptr->unknown_chunks_num *
       png_sizeof(png_unknown_chunk));
982

983
   png_free(png_ptr, info_ptr->unknown_chunks);
984
   info_ptr->unknown_chunks = NULL;
985 986 987 988

   for (i = 0; i < num_unknowns; i++)
   {
      png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;
989
      png_const_unknown_chunkp from = unknowns + i;
990

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

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

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

1001 1002 1003
      else
      {
         to->data = (png_bytep)png_malloc_warn(png_ptr,
1004
             (png_size_t)from->size);
1005

1006 1007 1008
         if (to->data == NULL)
         {
            png_warning(png_ptr,
1009
                "Out of memory while processing unknown chunk");
1010 1011
            to->size = 0;
         }
1012

1013 1014 1015 1016 1017 1018 1019 1020
         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;
1021
}
1022

1023
void PNGAPI
1024
png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
1025
    int chunk, int location)
1026
{
1027
   if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <
1028
       info_ptr->unknown_chunks_num)
1029 1030
      info_ptr->unknown_chunks[chunk].location = (png_byte)location;
}
1031 1032
#endif

1033

1034
#ifdef PNG_MNG_FEATURES_SUPPORTED
1035 1036 1037
png_uint_32 PNGAPI
png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features)
{
1038
   png_debug(1, "in png_permit_mng_features");
1039

1040 1041
   if (png_ptr == NULL)
      return (png_uint_32)0;
1042

1043
   png_ptr->mng_features_permitted =
1044
       (png_byte)(mng_features & PNG_ALL_MNG_FEATURES);
1045

1046
   return (png_uint_32)png_ptr->mng_features_permitted;
1047 1048
}
#endif
1049

1050
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
1051
void PNGAPI
1052
png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_const_bytep
1053
    chunk_list, int num_chunks)
1054
{
1055 1056 1057 1058
   png_bytep new_list, p;
   int i, old_num_chunks;
   if (png_ptr == NULL)
      return;
1059

1060 1061
   if (num_chunks == 0)
   {
1062
      if (keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE)
1063
         png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
1064

1065
      else
1066
         png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
1067

1068
      if (keep == PNG_HANDLE_CHUNK_ALWAYS)
1069
         png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS;
1070

1071
      else
1072
         png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS;
1073

1074
      return;
1075
   }
1076

1077
   if (chunk_list == NULL)
1078
      return;
1079

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

1084 1085 1086
   if (png_ptr->chunk_list != NULL)
   {
      png_memcpy(new_list, png_ptr->chunk_list,
1087
          (png_size_t)(5*old_num_chunks));
1088 1089 1090
      png_free(png_ptr, png_ptr->chunk_list);
      png_ptr->chunk_list=NULL;
   }
1091

1092
   png_memcpy(new_list + 5*old_num_chunks, chunk_list,
1093
       (png_size_t)(5*num_chunks));
1094

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

1098 1099 1100
   png_ptr->num_chunk_list = old_num_chunks + num_chunks;
   png_ptr->chunk_list = new_list;
   png_ptr->free_me |= PNG_FREE_LIST;
1101 1102
}
#endif
1103

1104
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
1105
void PNGAPI
1106
png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr,
1107
    png_user_chunk_ptr read_user_chunk_fn)
1108
{
1109
   png_debug(1, "in png_set_read_user_chunk_fn");
1110

1111 1112
   if (png_ptr == NULL)
      return;
1113

1114 1115 1116 1117
   png_ptr->read_user_chunk_fn = read_user_chunk_fn;
   png_ptr->user_chunk_ptr = user_chunk_ptr;
}
#endif
1118

1119
#ifdef PNG_INFO_IMAGE_SUPPORTED
1120
void PNGAPI
1121 1122
png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
{
1123
   png_debug1(1, "in %s storage function", "rows");
1124

1125 1126 1127
   if (png_ptr == NULL || info_ptr == NULL)
      return;

1128
   if (info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
1129
      png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
1130

1131
   info_ptr->row_pointers = row_pointers;
1132

1133
   if (row_pointers)
1134
      info_ptr->valid |= PNG_INFO_IDAT;
1135 1136 1137
}
#endif

1138
void PNGAPI
1139
png_set_compression_buffer_size(png_structp png_ptr, png_size_t size)
1140
{
1141 1142
    if (png_ptr == NULL)
       return;
1143

1144
    png_free(png_ptr, png_ptr->zbuf);
1145

1146 1147
    if (size > ZLIB_IO_MAX)
    {
1148 1149 1150
       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 */
1151
    }
1152

1153
    else
1154
       png_ptr->zbuf_size = (uInt)size;
1155

1156
    png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size);
1157

1158 1159 1160
    /* The following ensures a relatively safe failure if this gets called while
     * the buffer is actually in use.
     */
1161
    png_ptr->zstream.next_out = png_ptr->zbuf;
1162 1163
    png_ptr->zstream.avail_out = 0;
    png_ptr->zstream.avail_in = 0;
1164
}
1165 1166 1167 1168 1169

void PNGAPI
png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask)
{
   if (png_ptr && info_ptr)
1170
      info_ptr->valid &= ~mask;
1171
}
1172

1173

1174 1175

#ifdef PNG_SET_USER_LIMITS_SUPPORTED
1176
/* This function was added to libpng 1.2.6 */
1177 1178 1179 1180
void PNGAPI
png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max,
    png_uint_32 user_height_max)
{
1181 1182 1183 1184 1185 1186
   /* 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;
1187

1188 1189
   png_ptr->user_width_max = user_width_max;
   png_ptr->user_height_max = user_height_max;
1190
}
1191

1192
/* This function was added to libpng 1.4.0 */
1193 1194 1195 1196
void PNGAPI
png_set_chunk_cache_max (png_structp png_ptr,
   png_uint_32 user_chunk_cache_max)
{
1197 1198 1199 1200 1201 1202 1203
    if (png_ptr)
       png_ptr->user_chunk_cache_max = user_chunk_cache_max;
}

/* This function was added to libpng 1.4.1 */
void PNGAPI
png_set_chunk_malloc_max (png_structp png_ptr,
1204
    png_alloc_size_t user_chunk_malloc_max)
1205
{
1206 1207
   if (png_ptr)
      png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
1208
}
1209 1210
#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */

1211

1212
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
1213 1214 1215
void PNGAPI
png_set_benign_errors(png_structp png_ptr, int allowed)
{
1216
   png_debug(1, "in png_set_benign_errors");
1217

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

1221
   else
1222
      png_ptr->flags &= ~PNG_FLAG_BENIGN_ERRORS_WARN;
1223 1224
}
#endif /* PNG_BENIGN_ERRORS_SUPPORTED */
1225
#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */