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

/* pngset.c - storage of image information into info struct
3
 *
4
 * libpng 1.2.8beta1 - November 1, 2004
5
 * For conditions of distribution and use, see copyright notice in png.h
6
 * Copyright (c) 1998-2004 Glenn Randers-Pehrson
7 8
 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
9 10 11 12 13 14
 *
 * 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 已提交
15 16 17 18

#define PNG_INTERNAL
#include "png.h"

19
#if defined(PNG_bKGD_SUPPORTED)
20
void PNGAPI
A
Andreas Dilger 已提交
21 22 23
png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background)
{
   png_debug1(1, "in %s storage function\n", "bKGD");
24
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
25 26
      return;

27
   png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16));
A
Andreas Dilger 已提交
28 29 30 31
   info_ptr->valid |= PNG_INFO_bKGD;
}
#endif

32 33
#if defined(PNG_cHRM_SUPPORTED)
#ifdef PNG_FLOATING_POINT_SUPPORTED
34
void PNGAPI
A
Andreas Dilger 已提交
35 36 37 38 39
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)
{
   png_debug1(1, "in %s storage function\n", "cHRM");
40
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
41 42
      return;

43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
   if (white_x < 0.0 || white_y < 0.0 ||
         red_x < 0.0 ||   red_y < 0.0 ||
       green_x < 0.0 || green_y < 0.0 ||
        blue_x < 0.0 ||  blue_y < 0.0)
   {
      png_warning(png_ptr,
        "Ignoring attempt to set negative chromaticity value");
      return;
   }
   if (white_x > 21474.83 || white_y > 21474.83 ||
         red_x > 21474.83 ||   red_y > 21474.83 ||
       green_x > 21474.83 || green_y > 21474.83 ||
        blue_x > 21474.83 ||  blue_y > 21474.83)
   {
      png_warning(png_ptr,
        "Ignoring attempt to set chromaticity value exceeding 21474.83");
      return;
   }

A
Andreas Dilger 已提交
62 63 64 65 66 67 68 69
   info_ptr->x_white = (float)white_x;
   info_ptr->y_white = (float)white_y;
   info_ptr->x_red   = (float)red_x;
   info_ptr->y_red   = (float)red_y;
   info_ptr->x_green = (float)green_x;
   info_ptr->y_green = (float)green_y;
   info_ptr->x_blue  = (float)blue_x;
   info_ptr->y_blue  = (float)blue_y;
70 71 72
#ifdef PNG_FIXED_POINT_SUPPORTED
   info_ptr->int_x_white = (png_fixed_point)(white_x*100000.+0.5);
   info_ptr->int_y_white = (png_fixed_point)(white_y*100000.+0.5);
73 74
   info_ptr->int_x_red   = (png_fixed_point)(  red_x*100000.+0.5);
   info_ptr->int_y_red   = (png_fixed_point)(  red_y*100000.+0.5);
75 76
   info_ptr->int_x_green = (png_fixed_point)(green_x*100000.+0.5);
   info_ptr->int_y_green = (png_fixed_point)(green_y*100000.+0.5);
77 78
   info_ptr->int_x_blue  = (png_fixed_point)( blue_x*100000.+0.5);
   info_ptr->int_y_blue  = (png_fixed_point)( blue_y*100000.+0.5);
79
#endif
A
Andreas Dilger 已提交
80 81 82
   info_ptr->valid |= PNG_INFO_cHRM;
}
#endif
83
#ifdef PNG_FIXED_POINT_SUPPORTED
84
void PNGAPI
85
png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
86 87 88
   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)
89 90 91 92
{
   png_debug1(1, "in %s storage function\n", "cHRM");
   if (png_ptr == NULL || info_ptr == NULL)
      return;
A
Andreas Dilger 已提交
93

94 95 96 97 98 99 100 101 102
   if (white_x < 0 || white_y < 0 ||
         red_x < 0 ||   red_y < 0 ||
       green_x < 0 || green_y < 0 ||
        blue_x < 0 ||  blue_y < 0)
   {
      png_warning(png_ptr,
        "Ignoring attempt to set negative chromaticity value");
      return;
   }
103 104 105 106 107 108 109 110
   if (white_x > (double) PNG_UINT_31_MAX ||
       white_y > (double) PNG_UINT_31_MAX ||
         red_x > (double) PNG_UINT_31_MAX ||
         red_y > (double) PNG_UINT_31_MAX ||
       green_x > (double) PNG_UINT_31_MAX ||
       green_y > (double) PNG_UINT_31_MAX ||
        blue_x > (double) PNG_UINT_31_MAX ||
        blue_y > (double) PNG_UINT_31_MAX)
111 112 113 114 115
   {
      png_warning(png_ptr,
        "Ignoring attempt to set chromaticity value exceeding 21474.83");
      return;
   }
116 117 118 119 120 121 122 123
   info_ptr->int_x_white = white_x;
   info_ptr->int_y_white = white_y;
   info_ptr->int_x_red   = red_x;
   info_ptr->int_y_red   = red_y;
   info_ptr->int_x_green = green_x;
   info_ptr->int_y_green = green_y;
   info_ptr->int_x_blue  = blue_x;
   info_ptr->int_y_blue  = blue_y;
124 125 126
#ifdef PNG_FLOATING_POINT_SUPPORTED
   info_ptr->x_white = (float)(white_x/100000.);
   info_ptr->y_white = (float)(white_y/100000.);
127 128
   info_ptr->x_red   = (float)(  red_x/100000.);
   info_ptr->y_red   = (float)(  red_y/100000.);
129 130
   info_ptr->x_green = (float)(green_x/100000.);
   info_ptr->y_green = (float)(green_y/100000.);
131 132
   info_ptr->x_blue  = (float)( blue_x/100000.);
   info_ptr->y_blue  = (float)( blue_y/100000.);
133
#endif
134 135 136 137 138 139 140
   info_ptr->valid |= PNG_INFO_cHRM;
}
#endif
#endif

#if defined(PNG_gAMA_SUPPORTED)
#ifdef PNG_FLOATING_POINT_SUPPORTED
141
void PNGAPI
A
Andreas Dilger 已提交
142 143
png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
{
144
   double gamma;
A
Andreas Dilger 已提交
145
   png_debug1(1, "in %s storage function\n", "gAMA");
146
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
147 148
      return;

149 150 151 152 153 154 155 156 157
   /* Check for overflow */
   if (file_gamma > 21474.83)
   {
      png_warning(png_ptr, "Limiting gamma to 21474.83");
      gamma=21474.83;
   }
   else
      gamma=file_gamma;
   info_ptr->gamma = (float)gamma;
158
#ifdef PNG_FIXED_POINT_SUPPORTED
159
   info_ptr->int_gamma = (int)(gamma*100000.+.5);
160 161
#endif
   info_ptr->valid |= PNG_INFO_gAMA;
162
   if(gamma == 0.0)
163
      png_warning(png_ptr, "Setting gamma=0");
164 165
}
#endif
166
void PNGAPI
167 168
png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
   int_gamma)
169
{
170 171
   png_fixed_point gamma;

172 173 174 175
   png_debug1(1, "in %s storage function\n", "gAMA");
   if (png_ptr == NULL || info_ptr == NULL)
      return;

176
   if (int_gamma > (png_fixed_point) PNG_UINT_31_MAX)
177 178
   {
     png_warning(png_ptr, "Limiting gamma to 21474.83");
179
     gamma=PNG_UINT_31_MAX;
180 181 182 183 184 185 186 187 188 189 190
   }
   else
   {
     if (int_gamma < 0)
     {
       png_warning(png_ptr, "Setting negative gamma to zero");
       gamma=0;
     }
     else
       gamma=int_gamma;
   }
191
#ifdef PNG_FLOATING_POINT_SUPPORTED
192
   info_ptr->gamma = (float)(gamma/100000.);
193
#endif
194
#ifdef PNG_FIXED_POINT_SUPPORTED
195
   info_ptr->int_gamma = gamma;
196
#endif
A
Andreas Dilger 已提交
197
   info_ptr->valid |= PNG_INFO_gAMA;
198
   if(gamma == 0)
199
      png_warning(png_ptr, "Setting gamma=0");
A
Andreas Dilger 已提交
200
}
201
#endif
A
Andreas Dilger 已提交
202

203
#if defined(PNG_hIST_SUPPORTED)
204
void PNGAPI
A
Andreas Dilger 已提交
205 206
png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist)
{
207
   int i;
208

A
Andreas Dilger 已提交
209
   png_debug1(1, "in %s storage function\n", "hIST");
210
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
211
      return;
212
   if (info_ptr->num_palette == 0)
213
   {
214
       png_warning(png_ptr,
215 216 217
          "Palette size 0, hIST allocation skipped.");
       return;
   }
218 219 220 221

#ifdef PNG_FREE_ME_SUPPORTED
   png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
#endif
222
   /* Changed from info->num_palette to 256 in version 1.2.1 */
223
   png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr,
224
      (png_uint_32)(256 * png_sizeof (png_uint_16)));
225 226 227 228 229
   if (png_ptr->hist == NULL)
     {
       png_warning(png_ptr, "Insufficient memory for hIST chunk data.");
       return;
     }
A
Andreas Dilger 已提交
230

231 232 233
   for (i = 0; i < info_ptr->num_palette; i++)
       png_ptr->hist[i] = hist[i];
   info_ptr->hist = png_ptr->hist;
A
Andreas Dilger 已提交
234
   info_ptr->valid |= PNG_INFO_hIST;
235 236 237 238 239 240

#ifdef PNG_FREE_ME_SUPPORTED
   info_ptr->free_me |= PNG_FREE_HIST;
#else
   png_ptr->flags |= PNG_FLAG_FREE_HIST;
#endif
A
Andreas Dilger 已提交
241 242 243
}
#endif

244
void PNGAPI
A
Andreas Dilger 已提交
245 246 247 248 249 250
png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
   png_uint_32 width, png_uint_32 height, int bit_depth,
   int color_type, int interlace_type, int compression_type,
   int filter_type)
{
   png_debug1(1, "in %s storage function\n", "IHDR");
251
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
252 253
      return;

254 255 256
   /* check for width and height valid values */
   if (width == 0 || height == 0)
      png_error(png_ptr, "Image width or height is zero in IHDR");
257 258 259 260 261 262 263
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
   if (width > png_ptr->user_width_max || height > png_ptr->user_height_max)
      png_error(png_ptr, "image size exceeds user limits in IHDR");
#else
   if (width > PNG_USER_WIDTH_MAX || height > PNG_USER_HEIGHT_MAX)
      png_error(png_ptr, "image size exceeds user limits in IHDR");
#endif
264
   if (width > PNG_UINT_31_MAX || height > PNG_UINT_31_MAX)
265
      png_error(png_ptr, "Invalid image size in IHDR");
266 267 268 269 270 271 272
   if ( width > (PNG_UINT_32_MAX
                 >> 3)      /* 8-byte RGBA pixels */
                 - 64       /* bigrowbuf hack */
                 - 1        /* filter byte */
                 - 7*8      /* rounding of width to multiple of 8 pixels */
                 - 8)       /* extra max_pixel_depth pad */
      png_warning(png_ptr, "Width is too large for libpng to process pixels");
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322

   /* check other values */
   if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
      bit_depth != 8 && bit_depth != 16)
      png_error(png_ptr, "Invalid bit depth in IHDR");

   if (color_type < 0 || color_type == 1 ||
      color_type == 5 || color_type > 6)
      png_error(png_ptr, "Invalid color type in IHDR");

   if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
       ((color_type == PNG_COLOR_TYPE_RGB ||
         color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
         color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
      png_error(png_ptr, "Invalid color type/bit depth combination in IHDR");

   if (interlace_type >= PNG_INTERLACE_LAST)
      png_error(png_ptr, "Unknown interlace method in IHDR");

   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
      png_error(png_ptr, "Unknown compression method in IHDR");

#if defined(PNG_MNG_FEATURES_SUPPORTED)
   /* Accept filter_method 64 (intrapixel differencing) only if
    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
    * 2. Libpng did not read a PNG signature (this filter_method is only
    *    used in PNG datastreams that are embedded in MNG datastreams) and
    * 3. The application called png_permit_mng_features with a mask that
    *    included PNG_FLAG_MNG_FILTER_64 and
    * 4. The filter_method is 64 and
    * 5. The color_type is RGB or RGBA
    */
   if((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&png_ptr->mng_features_permitted)
      png_warning(png_ptr,"MNG features are not allowed in a PNG datastream\n");
   if(filter_type != PNG_FILTER_TYPE_BASE)
   {
     if(!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
        (filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
        ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
        (color_type == PNG_COLOR_TYPE_RGB || 
         color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
        png_error(png_ptr, "Unknown filter method in IHDR");
     if(png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)
        png_warning(png_ptr, "Invalid filter method in IHDR");
   }
#else
   if(filter_type != PNG_FILTER_TYPE_BASE)
      png_error(png_ptr, "Unknown filter method in IHDR");
#endif

A
Andreas Dilger 已提交
323 324 325 326 327 328 329
   info_ptr->width = width;
   info_ptr->height = height;
   info_ptr->bit_depth = (png_byte)bit_depth;
   info_ptr->color_type =(png_byte) color_type;
   info_ptr->compression_type = (png_byte)compression_type;
   info_ptr->filter_type = (png_byte)filter_type;
   info_ptr->interlace_type = (png_byte)interlace_type;
330 331 332
   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
      info_ptr->channels = 1;
   else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
A
Andreas Dilger 已提交
333 334 335 336 337 338
      info_ptr->channels = 3;
   else
      info_ptr->channels = 1;
   if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
      info_ptr->channels++;
   info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
339

340 341 342 343 344 345 346
   /* check for potential overflow */
   if ( width > (PNG_UINT_32_MAX
                 >> 3)      /* 8-byte RGBA pixels */
                 - 64       /* bigrowbuf hack */
                 - 1        /* filter byte */
                 - 7*8      /* rounding of width to multiple of 8 pixels */
                 - 8)       /* extra max_pixel_depth pad */
347
      info_ptr->rowbytes = (png_size_t)0;
348
   else
349
      info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,width);
A
Andreas Dilger 已提交
350 351
}

352
#if defined(PNG_oFFs_SUPPORTED)
353
void PNGAPI
A
Andreas Dilger 已提交
354
png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
355
   png_int_32 offset_x, png_int_32 offset_y, int unit_type)
A
Andreas Dilger 已提交
356 357
{
   png_debug1(1, "in %s storage function\n", "oFFs");
358
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
359 360 361 362 363 364 365 366 367
      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

368
#if defined(PNG_pCAL_SUPPORTED)
369
void PNGAPI
A
Andreas Dilger 已提交
370 371 372 373
png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
   png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams,
   png_charp units, png_charpp params)
{
374
   png_uint_32 length;
375
   int i;
A
Andreas Dilger 已提交
376 377

   png_debug1(1, "in %s storage function\n", "pCAL");
378
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
379 380 381
      return;

   length = png_strlen(purpose) + 1;
382
   png_debug1(3, "allocating purpose for info (%lu bytes)\n", length);
383 384 385 386 387 388
   info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length);
   if (info_ptr->pcal_purpose == NULL)
     {
       png_warning(png_ptr, "Insufficient memory for pCAL purpose.");
       return;
     }
389
   png_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length);
A
Andreas Dilger 已提交
390 391 392 393 394 395 396 397

   png_debug(3, "storing X0, X1, type, and nparams in info\n");
   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;
398
   png_debug1(3, "allocating units for info (%lu bytes)\n", length);
399 400 401 402 403 404
   info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length);
   if (info_ptr->pcal_units == NULL)
     {
       png_warning(png_ptr, "Insufficient memory for pCAL units.");
       return;
     }
405
   png_memcpy(info_ptr->pcal_units, units, (png_size_t)length);
A
Andreas Dilger 已提交
406

407
   info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr,
408
      (png_uint_32)((nparams + 1) * png_sizeof(png_charp)));
409 410 411 412 413
   if (info_ptr->pcal_params == NULL)
     {
       png_warning(png_ptr, "Insufficient memory for pCAL params.");
       return;
     }
414

A
Andreas Dilger 已提交
415 416 417 418 419
   info_ptr->pcal_params[nparams] = NULL;

   for (i = 0; i < nparams; i++)
   {
      length = png_strlen(params[i]) + 1;
420
      png_debug2(3, "allocating parameter %d for info (%lu bytes)\n", i, length);
421 422 423 424 425 426
      info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
      if (info_ptr->pcal_params[i] == NULL)
        {
          png_warning(png_ptr, "Insufficient memory for pCAL parameter.");
          return;
        }
427
      png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length);
A
Andreas Dilger 已提交
428 429 430
   }

   info_ptr->valid |= PNG_INFO_pCAL;
431 432 433
#ifdef PNG_FREE_ME_SUPPORTED
   info_ptr->free_me |= PNG_FREE_PCAL;
#endif
A
Andreas Dilger 已提交
434 435 436
}
#endif

437 438
#if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED)
#ifdef PNG_FLOATING_POINT_SUPPORTED
439
void PNGAPI
440
png_set_sCAL(png_structp png_ptr, png_infop info_ptr,
441
             int unit, double width, double height)
442 443 444 445 446
{
   png_debug1(1, "in %s storage function\n", "sCAL");
   if (png_ptr == NULL || info_ptr == NULL)
      return;

447
   info_ptr->scal_unit = (png_byte)unit;
448 449 450 451 452
   info_ptr->scal_pixel_width = width;
   info_ptr->scal_pixel_height = height;

   info_ptr->valid |= PNG_INFO_sCAL;
}
453 454
#else
#ifdef PNG_FIXED_POINT_SUPPORTED
455
void PNGAPI
456
png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,
457
             int unit, png_charp swidth, png_charp sheight)
458 459 460 461 462 463 464
{
   png_uint_32 length;

   png_debug1(1, "in %s storage function\n", "sCAL");
   if (png_ptr == NULL || info_ptr == NULL)
      return;

465
   info_ptr->scal_unit = (png_byte)unit;
466 467 468

   length = png_strlen(swidth) + 1;
   png_debug1(3, "allocating unit for info (%d bytes)\n", length);
469 470 471 472 473
   info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, length);
   if (info_ptr->scal_s_width == NULL)
   {
      png_warning(png_ptr, "Memory allocation failed while processing sCAL.");
   }
474
   png_memcpy(info_ptr->scal_s_width, swidth, (png_size_t)length);
475 476 477

   length = png_strlen(sheight) + 1;
   png_debug1(3, "allocating unit for info (%d bytes)\n", length);
478 479 480 481 482 483
   info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, length);
   if (info_ptr->scal_s_height == NULL)
   {
      png_free (png_ptr, info_ptr->scal_s_width);
      png_warning(png_ptr, "Memory allocation failed while processing sCAL.");
   }
484
   png_memcpy(info_ptr->scal_s_height, sheight, (png_size_t)length);
485 486

   info_ptr->valid |= PNG_INFO_sCAL;
487 488 489
#ifdef PNG_FREE_ME_SUPPORTED
   info_ptr->free_me |= PNG_FREE_SCAL;
#endif
490 491
}
#endif
492 493
#endif
#endif
494 495

#if defined(PNG_pHYs_SUPPORTED)
496
void PNGAPI
A
Andreas Dilger 已提交
497 498 499 500
png_set_pHYs(png_structp png_ptr, png_infop info_ptr,
   png_uint_32 res_x, png_uint_32 res_y, int unit_type)
{
   png_debug1(1, "in %s storage function\n", "pHYs");
501
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
502 503 504 505 506 507 508 509 510
      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

511
void PNGAPI
A
Andreas Dilger 已提交
512 513 514
png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
   png_colorp palette, int num_palette)
{
515

A
Andreas Dilger 已提交
516
   png_debug1(1, "in %s storage function\n", "PLTE");
517
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
518 519
      return;

520 521 522 523 524 525 526 527
   /*
    * It may not actually be necessary to set png_ptr->palette here;
    * we do it for backward compatibility with the way the png_handle_tRNS
    * function used to do the allocation.
    */
#ifdef PNG_FREE_ME_SUPPORTED
   png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
#endif
528

529 530
   /* Changed in libpng-1.2.1 to allocate 256 instead of num_palette entries,
      in case of an invalid PNG file that has too-large sample values. */
531 532 533 534
   png_ptr->palette = (png_colorp)png_malloc(png_ptr,
      256 * png_sizeof(png_color));
   png_memset(png_ptr->palette, 0, 256 * png_sizeof(png_color));
   png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof (png_color));
535 536 537 538 539 540 541 542
   info_ptr->palette = png_ptr->palette;
   info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;

#ifdef PNG_FREE_ME_SUPPORTED
   info_ptr->free_me |= PNG_FREE_PLTE;
#else
   png_ptr->flags |= PNG_FLAG_FREE_PLTE;
#endif
543

544
   info_ptr->valid |= PNG_INFO_PLTE;
A
Andreas Dilger 已提交
545 546
}

547
#if defined(PNG_sBIT_SUPPORTED)
548
void PNGAPI
A
Andreas Dilger 已提交
549 550 551 552
png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
   png_color_8p sig_bit)
{
   png_debug1(1, "in %s storage function\n", "sBIT");
553
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
554 555
      return;

556
   png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof (png_color_8));
A
Andreas Dilger 已提交
557 558 559 560
   info_ptr->valid |= PNG_INFO_sBIT;
}
#endif

561
#if defined(PNG_sRGB_SUPPORTED)
562
void PNGAPI
563
png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent)
564 565
{
   png_debug1(1, "in %s storage function\n", "sRGB");
566
   if (png_ptr == NULL || info_ptr == NULL)
567 568
      return;

569
   info_ptr->srgb_intent = (png_byte)intent;
570 571
   info_ptr->valid |= PNG_INFO_sRGB;
}
572

573
void PNGAPI
574
png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
575
   int intent)
576
{
577 578
#if defined(PNG_gAMA_SUPPORTED)
#ifdef PNG_FLOATING_POINT_SUPPORTED
579 580
   float file_gamma;
#endif
581
#ifdef PNG_FIXED_POINT_SUPPORTED
582
   png_fixed_point int_file_gamma;
583 584 585 586
#endif
#endif
#if defined(PNG_cHRM_SUPPORTED)
#ifdef PNG_FLOATING_POINT_SUPPORTED
587
   float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
588 589
#endif
#ifdef PNG_FIXED_POINT_SUPPORTED
590
   png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, int_green_x,
591 592
      int_green_y, int_blue_x, int_blue_y;
#endif
593 594
#endif
   png_debug1(1, "in %s storage function\n", "sRGB_gAMA_and_cHRM");
595
   if (png_ptr == NULL || info_ptr == NULL)
596 597 598 599
      return;

   png_set_sRGB(png_ptr, info_ptr, intent);

600 601
#if defined(PNG_gAMA_SUPPORTED)
#ifdef PNG_FLOATING_POINT_SUPPORTED
602
   file_gamma = (float).45455;
603 604
   png_set_gAMA(png_ptr, info_ptr, file_gamma);
#endif
605 606 607 608 609
#ifdef PNG_FIXED_POINT_SUPPORTED
   int_file_gamma = 45455L;
   png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma);
#endif
#endif
610

611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626
#if defined(PNG_cHRM_SUPPORTED)
#ifdef PNG_FIXED_POINT_SUPPORTED
   int_white_x = 31270L;
   int_white_y = 32900L;
   int_red_x   = 64000L;
   int_red_y   = 33000L;
   int_green_x = 30000L;
   int_green_y = 60000L;
   int_blue_x  = 15000L;
   int_blue_y  =  6000L;

   png_set_cHRM_fixed(png_ptr, info_ptr,
      int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, int_green_y,
      int_blue_x, int_blue_y);
#endif
#ifdef PNG_FLOATING_POINT_SUPPORTED
627 628 629 630 631 632 633 634
   white_x = (float).3127;
   white_y = (float).3290;
   red_x   = (float).64;
   red_y   = (float).33;
   green_x = (float).30;
   green_y = (float).60;
   blue_x  = (float).15;
   blue_y  = (float).06;
635 636 637

   png_set_cHRM(png_ptr, info_ptr,
      white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
638
#endif
639 640 641 642
#endif
}
#endif

643 644

#if defined(PNG_iCCP_SUPPORTED)
645
void PNGAPI
646 647
png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
             png_charp name, int compression_type,
648
             png_charp profile, png_uint_32 proflen)
649
{
650 651 652
   png_charp new_iccp_name;
   png_charp new_iccp_profile;

653 654 655 656
   png_debug1(1, "in %s storage function\n", "iCCP");
   if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
      return;

657 658 659 660 661 662
   new_iccp_name = (png_charp)png_malloc_warn(png_ptr, png_strlen(name)+1);
   if (new_iccp_name == NULL)
   {
      png_warning(png_ptr, "Insufficient memory to process iCCP chunk.");
      return;
   }
663
   png_strcpy(new_iccp_name, name);
664 665 666 667 668 669 670
   new_iccp_profile = (png_charp)png_malloc_warn(png_ptr, proflen);
   if (new_iccp_profile == NULL)
   {
      png_free (png_ptr, new_iccp_name);
      png_warning(png_ptr, "Insufficient memory to process iCCP profile.");
      return;
   }
671 672
   png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);

673
   png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
674

675
   info_ptr->iccp_proflen = proflen;
676 677
   info_ptr->iccp_name = new_iccp_name;
   info_ptr->iccp_profile = new_iccp_profile;
678
   /* Compression is always zero but is here so the API and info structure
679
    * does not have to change if we introduce multiple compression types */
680
   info_ptr->iccp_compression = (png_byte)compression_type;
681
#ifdef PNG_FREE_ME_SUPPORTED
682
   info_ptr->free_me |= PNG_FREE_ICCP;
683
#endif
684 685 686 687 688
   info_ptr->valid |= PNG_INFO_iCCP;
}
#endif

#if defined(PNG_TEXT_SUPPORTED)
689
void PNGAPI
A
Andreas Dilger 已提交
690 691
png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
   int num_text)
692 693 694 695 696 697 698 699 700 701
{
   int ret;
   ret=png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
   if (ret)
     png_error(png_ptr, "Insufficient memory to store text");
}

int /* PRIVATE */
png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
   int num_text)
A
Andreas Dilger 已提交
702 703 704 705
{
   int i;

   png_debug1(1, "in %s storage function\n", (png_ptr->chunk_name[0] == '\0' ?
706
      "text" : (png_const_charp)png_ptr->chunk_name));
A
Andreas Dilger 已提交
707

708
   if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
709
      return(0);
A
Andreas Dilger 已提交
710 711 712 713 714 715 716 717 718 719 720 721 722 723

   /* 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;
724
         info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
725
            (png_uint_32)(info_ptr->max_text * png_sizeof (png_text)));
726 727 728 729 730
         if (info_ptr->text == NULL)
           {
             png_free(png_ptr, old_text);
             return(1);
           }
731
         png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
732
            png_sizeof(png_text)));
A
Andreas Dilger 已提交
733 734 735 736 737 738
         png_free(png_ptr, old_text);
      }
      else
      {
         info_ptr->max_text = num_text + 8;
         info_ptr->num_text = 0;
739
         info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
740
            (png_uint_32)(info_ptr->max_text * png_sizeof (png_text)));
741 742
         if (info_ptr->text == NULL)
           return(1);
743 744 745
#ifdef PNG_FREE_ME_SUPPORTED
         info_ptr->free_me |= PNG_FREE_TEXT;
#endif
A
Andreas Dilger 已提交
746 747 748 749 750 751
      }
      png_debug1(3, "allocated %d entries for info_ptr->text\n",
         info_ptr->max_text);
   }
   for (i = 0; i < num_text; i++)
   {
752 753
      png_size_t text_length,key_len;
      png_size_t lang_len,lang_key_len;
A
Andreas Dilger 已提交
754 755
      png_textp textp = &(info_ptr->text[info_ptr->num_text]);

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

759 760
      key_len = png_strlen(text_ptr[i].key);

761 762 763 764 765 766
      if(text_ptr[i].compression <= 0)
      {
        lang_len = 0;
        lang_key_len = 0;
      }
      else
767
#ifdef PNG_iTXt_SUPPORTED
768 769
      {
        /* set iTXt data */
770
        if (text_ptr[i].lang != NULL)
771 772 773
          lang_len = png_strlen(text_ptr[i].lang);
        else
          lang_len = 0;
774
        if (text_ptr[i].lang_key != NULL)
775 776 777
          lang_key_len = png_strlen(text_ptr[i].lang_key);
        else
          lang_key_len = 0;
778
      }
779 780 781 782 783 784
#else
      {
        png_warning(png_ptr, "iTXt chunk not supported.");
        continue;
      }
#endif
A
Andreas Dilger 已提交
785

786
      if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
A
Andreas Dilger 已提交
787
      {
788
         text_length = 0;
789
#ifdef PNG_iTXt_SUPPORTED
790 791 792
         if(text_ptr[i].compression > 0)
            textp->compression = PNG_ITXT_COMPRESSION_NONE;
         else
793
#endif
794
            textp->compression = PNG_TEXT_COMPRESSION_NONE;
A
Andreas Dilger 已提交
795 796 797
      }
      else
      {
798
         text_length = png_strlen(text_ptr[i].text);
A
Andreas Dilger 已提交
799 800
         textp->compression = text_ptr[i].compression;
      }
801

802
      textp->key = (png_charp)png_malloc_warn(png_ptr,
803
         (png_uint_32)(key_len + text_length + lang_len + lang_key_len + 4));
804 805
      if (textp->key == NULL)
        return(1);
806 807 808
      png_debug2(2, "Allocated %lu bytes at %x in png_set_text\n",
         (png_uint_32)(key_len + lang_len + lang_key_len + text_length + 4),
         (int)textp->key);
809 810

      png_memcpy(textp->key, text_ptr[i].key,
811 812
         (png_size_t)(key_len));
      *(textp->key+key_len) = '\0';
813
#ifdef PNG_iTXt_SUPPORTED
814 815 816 817 818 819 820 821 822 823 824
      if (text_ptr[i].compression > 0)
      {
         textp->lang=textp->key + key_len + 1;
         png_memcpy(textp->lang, text_ptr[i].lang, lang_len);
         *(textp->lang+lang_len) = '\0';
         textp->lang_key=textp->lang + lang_len + 1;
         png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
         *(textp->lang_key+lang_key_len) = '\0';
         textp->text=textp->lang_key + lang_key_len + 1;
      }
      else
825
#endif
826
      {
827
#ifdef PNG_iTXt_SUPPORTED
828 829
         textp->lang=NULL;
         textp->lang_key=NULL;
830
#endif
831 832 833
         textp->text=textp->key + key_len + 1;
      }
      if(text_length)
834
         png_memcpy(textp->text, text_ptr[i].text,
835
            (png_size_t)(text_length));
836
      *(textp->text+text_length) = '\0';
837

838
#ifdef PNG_iTXt_SUPPORTED
839 840 841 842 843 844
      if(textp->compression > 0)
      {
         textp->text_length = 0;
         textp->itxt_length = text_length;
      }
      else
845
#endif
846 847
      {
         textp->text_length = text_length;
848
#ifdef PNG_iTXt_SUPPORTED
849
         textp->itxt_length = 0;
850
#endif
851
      }
852
      info_ptr->text[info_ptr->num_text]= *textp;
A
Andreas Dilger 已提交
853 854 855
      info_ptr->num_text++;
      png_debug1(3, "transferred text chunk %d\n", info_ptr->num_text);
   }
856
   return(0);
A
Andreas Dilger 已提交
857 858 859
}
#endif

860
#if defined(PNG_tIME_SUPPORTED)
861
void PNGAPI
A
Andreas Dilger 已提交
862 863 864
png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time)
{
   png_debug1(1, "in %s storage function\n", "tIME");
865
   if (png_ptr == NULL || info_ptr == NULL ||
866
       (png_ptr->mode & PNG_WROTE_tIME))
A
Andreas Dilger 已提交
867 868
      return;

869
   png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof (png_time));
A
Andreas Dilger 已提交
870 871 872 873
   info_ptr->valid |= PNG_INFO_tIME;
}
#endif

874
#if defined(PNG_tRNS_SUPPORTED)
875
void PNGAPI
A
Andreas Dilger 已提交
876 877 878 879
png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
   png_bytep trans, int num_trans, png_color_16p trans_values)
{
   png_debug1(1, "in %s storage function\n", "tRNS");
880
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
881 882 883
      return;

   if (trans != NULL)
884 885
   {
       /*
886 887 888 889
        * It may not actually be necessary to set png_ptr->trans here;
        * we do it for backward compatibility with the way the png_handle_tRNS
        * function used to do the allocation.
        */
890 891 892
#ifdef PNG_FREE_ME_SUPPORTED
       png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
#endif
893
       /* Changed from num_trans to 256 in version 1.2.1 */
894
       png_ptr->trans = info_ptr->trans = (png_bytep)png_malloc(png_ptr,
895
           (png_uint_32)256);
896
       png_memcpy(info_ptr->trans, trans, (png_size_t)num_trans);
897 898 899 900 901 902
#ifdef PNG_FREE_ME_SUPPORTED
       info_ptr->free_me |= PNG_FREE_TRNS;
#else
       png_ptr->flags |= PNG_FLAG_FREE_TRNS;
#endif
   }
A
Andreas Dilger 已提交
903 904 905 906

   if (trans_values != NULL)
   {
      png_memcpy(&(info_ptr->trans_values), trans_values,
907
         png_sizeof(png_color_16));
908 909
      if (num_trans == 0)
        num_trans = 1;
A
Andreas Dilger 已提交
910 911 912 913 914 915
   }
   info_ptr->num_trans = (png_uint_16)num_trans;
   info_ptr->valid |= PNG_INFO_tRNS;
}
#endif

916
#if defined(PNG_sPLT_SUPPORTED)
917
void PNGAPI
918
png_set_sPLT(png_structp png_ptr,
919
             png_infop info_ptr, png_sPLT_tp entries, int nentries)
920
{
921
    png_sPLT_tp np;
922 923
    int i;

924
    np = (png_sPLT_tp)png_malloc_warn(png_ptr,
925
        (info_ptr->splt_palettes_num + nentries) * png_sizeof(png_sPLT_t));
926 927
    if (np == NULL)
    {
928
      png_warning(png_ptr, "No memory for sPLT palettes.");
929 930
      return;
    }
931

932
    png_memcpy(np, info_ptr->splt_palettes,
933
           info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t));
934
    png_free(png_ptr, info_ptr->splt_palettes);
935
    info_ptr->splt_palettes=NULL;
936 937 938

    for (i = 0; i < nentries; i++)
    {
939 940
        png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
        png_sPLT_tp from = entries + i;
941 942

        to->name = (png_charp)png_malloc(png_ptr,
943
            png_strlen(from->name) + 1);
944
        /* TODO: use png_malloc_warn */
945
        png_strcpy(to->name, from->name);
946
        to->entries = (png_sPLT_entryp)png_malloc(png_ptr,
947 948
            from->nentries * png_sizeof(png_sPLT_t));
        /* TODO: use png_malloc_warn */
949
        png_memcpy(to->entries, from->entries,
950
            from->nentries * png_sizeof(png_sPLT_t));
951 952
        to->nentries = from->nentries;
        to->depth = from->depth;
953 954 955 956
    }

    info_ptr->splt_palettes = np;
    info_ptr->splt_palettes_num += nentries;
957
    info_ptr->valid |= PNG_INFO_sPLT;
958
#ifdef PNG_FREE_ME_SUPPORTED
959
    info_ptr->free_me |= PNG_FREE_SPLT;
960
#endif
961 962 963
}
#endif /* PNG_sPLT_SUPPORTED */

964
#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
965
void PNGAPI
966
png_set_unknown_chunks(png_structp png_ptr,
967
   png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)
968 969 970 971
{
    png_unknown_chunkp np;
    int i;

972 973 974
    if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)
        return;

975
    np = (png_unknown_chunkp)png_malloc_warn(png_ptr,
976
        (info_ptr->unknown_chunks_num + num_unknowns) *
977
        png_sizeof(png_unknown_chunk));
978 979 980 981 982
    if (np == NULL)
    {
       png_warning(png_ptr, "Out of memory while processing unknown chunk.");
       return;
    }
983

984
    png_memcpy(np, info_ptr->unknown_chunks,
985
           info_ptr->unknown_chunks_num * png_sizeof(png_unknown_chunk));
986
    png_free(png_ptr, info_ptr->unknown_chunks);
987
    info_ptr->unknown_chunks=NULL;
988

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

994 995
        png_strncpy((png_charp)to->name, (png_charp)from->name, 5);
        to->data = (png_bytep)png_malloc_warn(png_ptr, from->size);
996
        if (to->data == NULL)
997 998 999
        {
           png_warning(png_ptr, "Out of memory processing unknown chunk.");
        }
1000 1001
        else
        {
1002 1003
           png_memcpy(to->data, from->data, from->size);
           to->size = from->size;
1004

1005 1006
           /* note our location in the read or write sequence */
           to->location = (png_byte)(png_ptr->mode & 0xff);
1007
        }
1008 1009 1010
    }

    info_ptr->unknown_chunks = np;
1011
    info_ptr->unknown_chunks_num += num_unknowns;
1012
#ifdef PNG_FREE_ME_SUPPORTED
1013
    info_ptr->free_me |= PNG_FREE_UNKN;
1014
#endif
1015
}
1016
void PNGAPI
1017 1018 1019
png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
   int chunk, int location)
{
1020
   if(png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <
1021 1022 1023
         (int)info_ptr->unknown_chunks_num)
      info_ptr->unknown_chunks[chunk].location = (png_byte)location;
}
1024 1025
#endif

1026 1027
#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
    defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
1028
void PNGAPI
1029 1030
png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted)
{
1031 1032 1033
   /* This function is deprecated in favor of png_permit_mng_features()
      and will be removed from libpng-2.0.0 */
   png_debug(1, "in png_permit_empty_plte, DEPRECATED.\n");
1034 1035
   if (png_ptr == NULL)
      return;
1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051
   png_ptr->mng_features_permitted = (png_byte)
     ((png_ptr->mng_features_permitted & (~(PNG_FLAG_MNG_EMPTY_PLTE))) |
     ((empty_plte_permitted & PNG_FLAG_MNG_EMPTY_PLTE)));
}
#endif

#if defined(PNG_MNG_FEATURES_SUPPORTED)
png_uint_32 PNGAPI
png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features)
{
   png_debug(1, "in png_permit_mng_features\n");
   if (png_ptr == NULL)
      return (png_uint_32)0;
   png_ptr->mng_features_permitted =
     (png_byte)(mng_features & PNG_ALL_MNG_FEATURES);
   return (png_uint_32)png_ptr->mng_features_permitted;
1052 1053
}
#endif
1054

1055
#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
1056
void PNGAPI
1057 1058 1059 1060 1061 1062 1063
png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep
   chunk_list, int num_chunks)
{
    png_bytep new_list, p;
    int i, old_num_chunks;
    if (num_chunks == 0)
    {
1064
      if(keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE)
1065 1066 1067
        png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
      else
        png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
1068

1069
      if(keep == PNG_HANDLE_CHUNK_ALWAYS)
1070 1071 1072 1073 1074 1075 1076 1077
        png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS;
      else
        png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS;
      return;
    }
    if (chunk_list == NULL)
      return;
    old_num_chunks=png_ptr->num_chunk_list;
1078 1079
    new_list=(png_bytep)png_malloc(png_ptr,
       (png_uint_32)(5*(num_chunks+old_num_chunks)));
1080
    if(png_ptr->chunk_list != NULL)
1081
    {
1082 1083
       png_memcpy(new_list, png_ptr->chunk_list,
          (png_size_t)(5*old_num_chunks));
1084
       png_free(png_ptr, png_ptr->chunk_list);
1085
       png_ptr->chunk_list=NULL;
1086
    }
1087 1088
    png_memcpy(new_list+5*old_num_chunks, chunk_list,
       (png_size_t)(5*num_chunks));
1089 1090 1091 1092
    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;
1093
#ifdef PNG_FREE_ME_SUPPORTED
1094
    png_ptr->free_me |= PNG_FREE_LIST;
1095
#endif
1096 1097
}
#endif
1098

1099
#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
1100
void PNGAPI
1101 1102 1103 1104 1105 1106 1107 1108
png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr,
   png_user_chunk_ptr read_user_chunk_fn)
{
   png_debug(1, "in png_set_read_user_chunk_fn\n");
   png_ptr->read_user_chunk_fn = read_user_chunk_fn;
   png_ptr->user_chunk_ptr = user_chunk_ptr;
}
#endif
1109

1110
#if defined(PNG_INFO_IMAGE_SUPPORTED)
1111
void PNGAPI
1112 1113 1114
png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
{
   png_debug1(1, "in %s storage function\n", "rows");
1115

1116 1117 1118
   if (png_ptr == NULL || info_ptr == NULL)
      return;

1119
   if(info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
1120
      png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
1121 1122 1123
   info_ptr->row_pointers = row_pointers;
   if(row_pointers)
      info_ptr->valid |= PNG_INFO_IDAT;
1124 1125 1126
}
#endif

1127
#ifdef PNG_WRITE_SUPPORTED
1128
void PNGAPI
1129 1130 1131 1132 1133 1134 1135 1136 1137
png_set_compression_buffer_size(png_structp png_ptr, png_uint_32 size)
{
    if(png_ptr->zbuf)
       png_free(png_ptr, png_ptr->zbuf);
    png_ptr->zbuf_size = (png_size_t)size;
    png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size);
    png_ptr->zstream.next_out = png_ptr->zbuf;
    png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
}
1138
#endif
1139 1140 1141 1142 1143 1144 1145

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

1147

1148
#ifndef PNG_1_0_X
1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186
#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
/* this function was added to libpng 1.2.0 and should always exist by default */
void PNGAPI
png_set_asm_flags (png_structp png_ptr, png_uint_32 asm_flags)
{
    png_uint_32 settable_asm_flags;
    png_uint_32 settable_mmx_flags;

    settable_mmx_flags =
#ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW
                         PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  |
#endif
#ifdef PNG_HAVE_ASSEMBLER_READ_INTERLACE
                         PNG_ASM_FLAG_MMX_READ_INTERLACE    |
#endif
#ifdef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
                         PNG_ASM_FLAG_MMX_READ_FILTER_SUB   |
                         PNG_ASM_FLAG_MMX_READ_FILTER_UP    |
                         PNG_ASM_FLAG_MMX_READ_FILTER_AVG   |
                         PNG_ASM_FLAG_MMX_READ_FILTER_PAETH |
#endif
                         0;

    /* could be some non-MMX ones in the future, but not currently: */
    settable_asm_flags = settable_mmx_flags;

    if (!(png_ptr->asm_flags & PNG_ASM_FLAG_MMX_SUPPORT_COMPILED) ||
        !(png_ptr->asm_flags & PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU))
    {
        /* clear all MMX flags if MMX isn't supported */
        settable_asm_flags &= ~settable_mmx_flags;
        png_ptr->asm_flags &= ~settable_mmx_flags;
    }

    /* we're replacing the settable bits with those passed in by the user,
     * so first zero them out of the master copy, then logical-OR in the
     * allowed subset that was requested */

1187 1188
    png_ptr->asm_flags &= ~settable_asm_flags;               /* zero them */
    png_ptr->asm_flags |= (asm_flags & settable_asm_flags);  /* set them */
1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202
}
#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */

#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
/* this function was added to libpng 1.2.0 */
void PNGAPI
png_set_mmx_thresholds (png_structp png_ptr,
                        png_byte mmx_bitdepth_threshold,
                        png_uint_32 mmx_rowbytes_threshold)
{
    png_ptr->mmx_bitdepth_threshold = mmx_bitdepth_threshold;
    png_ptr->mmx_rowbytes_threshold = mmx_rowbytes_threshold;
}
#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218

#ifdef PNG_SET_USER_LIMITS_SUPPORTED
/* this function was added to libpng 1.2.6 */
void PNGAPI
png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max,
    png_uint_32 user_height_max)
{
    /* 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.
     */
    png_ptr->user_width_max = user_width_max;
    png_ptr->user_height_max = user_height_max;
}
#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */

1219
#endif /* ?PNG_1_0_X */