pngset.c 33.5 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.4 [(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
90
    file_gamma)
91
{
92
   png_debug1(1, "in %s storage function", "gAMA");
93

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

97 98 99 100 101 102 103
   /* 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.)
G
[devel]  
Glenn Randers-Pehrson 已提交
104
    */
105 106
   if (file_gamma < 16 || file_gamma > 625000000)
      png_warning(png_ptr, "Out of range gamma value ignored");
107

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

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

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

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

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

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

142
      return;
143
   }
144 145

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

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

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

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

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

168
void PNGAPI
A
Andreas Dilger 已提交
169
png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
170 171 172
    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 已提交
173
{
174
   png_debug1(1, "in %s storage function", "IHDR");
175

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

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

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

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

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

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

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

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

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

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

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

234
#ifdef PNG_pCAL_SUPPORTED
235
void PNGAPI
A
Andreas Dilger 已提交
236
png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
237 238
    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 已提交
239
{
240
   png_size_t length;
241
   int i;
A
Andreas Dilger 已提交
242

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

G
[devel]  
Glenn Randers-Pehrson 已提交
338 339 340 341 342 343
   /* 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");

344
   if (swidth == NULL || (lengthw = png_strlen(swidth)) == 0 ||
345
       swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw))
G
[devel]  
Glenn Randers-Pehrson 已提交
346 347
      png_error(png_ptr, "Invalid sCAL width");

348
   if (sheight == NULL || (lengthh = png_strlen(sheight)) == 0 ||
349
       sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh))
G
[devel]  
Glenn Randers-Pehrson 已提交
350 351
      png_error(png_ptr, "Invalid sCAL height");

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

546
   png_set_sRGB(png_ptr, info_ptr, srgb_intent);
547

548
#  ifdef PNG_gAMA_SUPPORTED
549
   png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE);
550
#  endif
551

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

564

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

714 715
         else
            lang_len = 0;
716

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1034

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

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

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

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

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

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

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

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

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

1075
      return;
1076
   }
1077

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

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

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

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

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

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

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

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

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

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

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

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

1132
   info_ptr->row_pointers = row_pointers;
1133

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

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

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

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

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

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

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

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

1174

1175 1176

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

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

1193
/* This function was added to libpng 1.4.0 */
1194 1195 1196 1197
void PNGAPI
png_set_chunk_cache_max (png_structp png_ptr,
   png_uint_32 user_chunk_cache_max)
{
1198 1199 1200 1201 1202 1203 1204
    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,
1205
    png_alloc_size_t user_chunk_malloc_max)
1206
{
1207 1208
   if (png_ptr)
      png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
1209
}
1210 1211
#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */

1212

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

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

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