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

/* pngset.c - storage of image information into info struct
3
 *
4
 * libpng 1.2.6beta2 - November 1, 2002
5
 * For conditions of distribution and use, see copyright notice in png.h
6
 * Copyright (c) 1998-2002 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 27 28 29 30 31
      return;

   png_memcpy(&(info_ptr->background), background, sizeof(png_color_16));
   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
   if (white_x > (double) PNG_MAX_UINT || white_y > (double) PNG_MAX_UINT ||
         red_x > (double) PNG_MAX_UINT ||   red_y > (double) PNG_MAX_UINT ||
       green_x > (double) PNG_MAX_UINT || green_y > (double) PNG_MAX_UINT ||
        blue_x > (double) PNG_MAX_UINT ||  blue_y > (double) PNG_MAX_UINT)
107 108 109 110 111
   {
      png_warning(png_ptr,
        "Ignoring attempt to set chromaticity value exceeding 21474.83");
      return;
   }
112 113 114 115 116 117 118 119
   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;
120 121 122
#ifdef PNG_FLOATING_POINT_SUPPORTED
   info_ptr->x_white = (float)(white_x/100000.);
   info_ptr->y_white = (float)(white_y/100000.);
123 124
   info_ptr->x_red   = (float)(  red_x/100000.);
   info_ptr->y_red   = (float)(  red_y/100000.);
125 126
   info_ptr->x_green = (float)(green_x/100000.);
   info_ptr->y_green = (float)(green_y/100000.);
127 128
   info_ptr->x_blue  = (float)( blue_x/100000.);
   info_ptr->y_blue  = (float)( blue_y/100000.);
129
#endif
130 131 132 133 134 135 136
   info_ptr->valid |= PNG_INFO_cHRM;
}
#endif
#endif

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

145 146 147 148 149 150 151 152 153
   /* 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;
154
#ifdef PNG_FIXED_POINT_SUPPORTED
155
   info_ptr->int_gamma = (int)(gamma*100000.+.5);
156 157
#endif
   info_ptr->valid |= PNG_INFO_gAMA;
158
   if(gamma == 0.0)
159
      png_warning(png_ptr, "Setting gamma=0");
160 161
}
#endif
162
void PNGAPI
163 164
png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
   int_gamma)
165
{
166 167
   png_fixed_point gamma;

168 169 170 171
   png_debug1(1, "in %s storage function\n", "gAMA");
   if (png_ptr == NULL || info_ptr == NULL)
      return;

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

199
#if defined(PNG_hIST_SUPPORTED)
200
void PNGAPI
A
Andreas Dilger 已提交
201 202
png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist)
{
203
   int i;
204

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

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

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

#ifdef PNG_FREE_ME_SUPPORTED
   info_ptr->free_me |= PNG_FREE_HIST;
#else
   png_ptr->flags |= PNG_FLAG_FREE_HIST;
#endif
A
Andreas Dilger 已提交
237 238 239
}
#endif

240
void PNGAPI
A
Andreas Dilger 已提交
241 242 243 244 245
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)
{
246
   int rowbytes_per_pixel;
A
Andreas Dilger 已提交
247
   png_debug1(1, "in %s storage function\n", "IHDR");
248
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
249 250
      return;

251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 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
   /* check for width and height valid values */
   if (width == 0 || height == 0)
      png_error(png_ptr, "Image width or height is zero in IHDR");
   if (width > PNG_MAX_UINT || height > PNG_MAX_UINT)
      png_error(png_ptr, "Invalid image size in IHDR");

   /* 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 已提交
306 307 308 309 310 311 312
   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;
313 314 315
   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 已提交
316 317 318 319 320 321
      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);
322 323 324

   /* check for overflow */
   rowbytes_per_pixel = (info_ptr->pixel_depth + 7) >> 3;
325
   if ( width > PNG_MAX_UINT/rowbytes_per_pixel - 64)
326 327 328 329 330
   {
      png_warning(png_ptr,
         "Width too large to process image data; rowbytes will overflow.");
      info_ptr->rowbytes = (png_size_t)0;
   }
331 332
   else
      info_ptr->rowbytes = (info_ptr->width * info_ptr->pixel_depth + 7) >> 3;
A
Andreas Dilger 已提交
333 334
}

335
#if defined(PNG_oFFs_SUPPORTED)
336
void PNGAPI
A
Andreas Dilger 已提交
337
png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
338
   png_int_32 offset_x, png_int_32 offset_y, int unit_type)
A
Andreas Dilger 已提交
339 340
{
   png_debug1(1, "in %s storage function\n", "oFFs");
341
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
342 343 344 345 346 347 348 349 350
      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

351
#if defined(PNG_pCAL_SUPPORTED)
352
void PNGAPI
A
Andreas Dilger 已提交
353 354 355 356
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)
{
357
   png_uint_32 length;
358
   int i;
A
Andreas Dilger 已提交
359 360

   png_debug1(1, "in %s storage function\n", "pCAL");
361
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
362 363 364
      return;

   length = png_strlen(purpose) + 1;
365
   png_debug1(3, "allocating purpose for info (%lu bytes)\n", length);
366 367 368 369 370 371
   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;
     }
372
   png_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length);
A
Andreas Dilger 已提交
373 374 375 376 377 378 379 380

   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;
381
   png_debug1(3, "allocating units for info (%lu bytes)\n", length);
382 383 384 385 386 387
   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;
     }
388
   png_memcpy(info_ptr->pcal_units, units, (png_size_t)length);
A
Andreas Dilger 已提交
389

390
   info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr,
391
      (png_uint_32)((nparams + 1) * sizeof(png_charp)));
392 393 394 395 396
   if (info_ptr->pcal_params == NULL)
     {
       png_warning(png_ptr, "Insufficient memory for pCAL params.");
       return;
     }
397

A
Andreas Dilger 已提交
398 399 400 401 402
   info_ptr->pcal_params[nparams] = NULL;

   for (i = 0; i < nparams; i++)
   {
      length = png_strlen(params[i]) + 1;
403
      png_debug2(3, "allocating parameter %d for info (%lu bytes)\n", i, length);
404 405 406 407 408 409
      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;
        }
410
      png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length);
A
Andreas Dilger 已提交
411 412 413
   }

   info_ptr->valid |= PNG_INFO_pCAL;
414 415 416
#ifdef PNG_FREE_ME_SUPPORTED
   info_ptr->free_me |= PNG_FREE_PCAL;
#endif
A
Andreas Dilger 已提交
417 418 419
}
#endif

420 421
#if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED)
#ifdef PNG_FLOATING_POINT_SUPPORTED
422
void PNGAPI
423
png_set_sCAL(png_structp png_ptr, png_infop info_ptr,
424
             int unit, double width, double height)
425 426 427 428 429
{
   png_debug1(1, "in %s storage function\n", "sCAL");
   if (png_ptr == NULL || info_ptr == NULL)
      return;

430
   info_ptr->scal_unit = (png_byte)unit;
431 432 433 434 435
   info_ptr->scal_pixel_width = width;
   info_ptr->scal_pixel_height = height;

   info_ptr->valid |= PNG_INFO_sCAL;
}
436 437
#else
#ifdef PNG_FIXED_POINT_SUPPORTED
438
void PNGAPI
439
png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,
440
             int unit, png_charp swidth, png_charp sheight)
441 442 443 444 445 446 447
{
   png_uint_32 length;

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

448
   info_ptr->scal_unit = (png_byte)unit;
449 450 451 452

   length = png_strlen(swidth) + 1;
   png_debug1(3, "allocating unit for info (%d bytes)\n", length);
   info_ptr->scal_s_width = (png_charp)png_malloc(png_ptr, length);
453
   png_memcpy(info_ptr->scal_s_width, swidth, (png_size_t)length);
454 455 456

   length = png_strlen(sheight) + 1;
   png_debug1(3, "allocating unit for info (%d bytes)\n", length);
457
   info_ptr->scal_s_height = (png_charp)png_malloc(png_ptr, length);
458
   png_memcpy(info_ptr->scal_s_height, sheight, (png_size_t)length);
459 460

   info_ptr->valid |= PNG_INFO_sCAL;
461 462 463
#ifdef PNG_FREE_ME_SUPPORTED
   info_ptr->free_me |= PNG_FREE_SCAL;
#endif
464 465
}
#endif
466 467
#endif
#endif
468 469

#if defined(PNG_pHYs_SUPPORTED)
470
void PNGAPI
A
Andreas Dilger 已提交
471 472 473 474
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");
475
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
476 477 478 479 480 481 482 483 484
      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

485
void PNGAPI
A
Andreas Dilger 已提交
486 487 488
png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
   png_colorp palette, int num_palette)
{
489

A
Andreas Dilger 已提交
490
   png_debug1(1, "in %s storage function\n", "PLTE");
491
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
492 493
      return;

494 495 496 497 498 499 500 501
   /*
    * 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
502 503 504
   /* 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. */
   png_ptr->palette = (png_colorp)png_zalloc(png_ptr, (uInt)256,
505
      sizeof (png_color));
506 507
   if (png_ptr->palette == NULL)
      png_error(png_ptr, "Unable to malloc palette");
508
   png_memcpy(png_ptr->palette, palette, num_palette * sizeof (png_color));
509 510 511 512 513 514 515 516
   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
517

518
   info_ptr->valid |= PNG_INFO_PLTE;
A
Andreas Dilger 已提交
519 520
}

521
#if defined(PNG_sBIT_SUPPORTED)
522
void PNGAPI
A
Andreas Dilger 已提交
523 524 525 526
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");
527
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
528 529 530 531 532 533 534
      return;

   png_memcpy(&(info_ptr->sig_bit), sig_bit, sizeof (png_color_8));
   info_ptr->valid |= PNG_INFO_sBIT;
}
#endif

535
#if defined(PNG_sRGB_SUPPORTED)
536
void PNGAPI
537
png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent)
538 539
{
   png_debug1(1, "in %s storage function\n", "sRGB");
540
   if (png_ptr == NULL || info_ptr == NULL)
541 542
      return;

543
   info_ptr->srgb_intent = (png_byte)intent;
544 545
   info_ptr->valid |= PNG_INFO_sRGB;
}
546

547
void PNGAPI
548
png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
549
   int intent)
550
{
551 552
#if defined(PNG_gAMA_SUPPORTED)
#ifdef PNG_FLOATING_POINT_SUPPORTED
553 554
   float file_gamma;
#endif
555
#ifdef PNG_FIXED_POINT_SUPPORTED
556
   png_fixed_point int_file_gamma;
557 558 559 560
#endif
#endif
#if defined(PNG_cHRM_SUPPORTED)
#ifdef PNG_FLOATING_POINT_SUPPORTED
561
   float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
562 563
#endif
#ifdef PNG_FIXED_POINT_SUPPORTED
564
   png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, int_green_x,
565 566
      int_green_y, int_blue_x, int_blue_y;
#endif
567 568
#endif
   png_debug1(1, "in %s storage function\n", "sRGB_gAMA_and_cHRM");
569
   if (png_ptr == NULL || info_ptr == NULL)
570 571 572 573
      return;

   png_set_sRGB(png_ptr, info_ptr, intent);

574 575
#if defined(PNG_gAMA_SUPPORTED)
#ifdef PNG_FLOATING_POINT_SUPPORTED
576
   file_gamma = (float).45455;
577 578
   png_set_gAMA(png_ptr, info_ptr, file_gamma);
#endif
579 580 581 582 583
#ifdef PNG_FIXED_POINT_SUPPORTED
   int_file_gamma = 45455L;
   png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma);
#endif
#endif
584

585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600
#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
601 602 603 604 605 606 607 608
   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;
609 610 611

   png_set_cHRM(png_ptr, info_ptr,
      white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
612
#endif
613 614 615 616
#endif
}
#endif

617 618

#if defined(PNG_iCCP_SUPPORTED)
619
void PNGAPI
620 621
png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
             png_charp name, int compression_type,
622
             png_charp profile, png_uint_32 proflen)
623
{
624 625 626
   png_charp new_iccp_name;
   png_charp new_iccp_profile;

627 628 629 630
   png_debug1(1, "in %s storage function\n", "iCCP");
   if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
      return;

631 632 633
   new_iccp_name = (png_charp)png_malloc(png_ptr, png_strlen(name)+1);
   png_strcpy(new_iccp_name, name);
   new_iccp_profile = (png_charp)png_malloc(png_ptr, proflen);
634 635
   png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);

636
   png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
637

638
   info_ptr->iccp_proflen = proflen;
639 640
   info_ptr->iccp_name = new_iccp_name;
   info_ptr->iccp_profile = new_iccp_profile;
641
   /* Compression is always zero but is here so the API and info structure
642
    * does not have to change if we introduce multiple compression types */
643
   info_ptr->iccp_compression = (png_byte)compression_type;
644
#ifdef PNG_FREE_ME_SUPPORTED
645
   info_ptr->free_me |= PNG_FREE_ICCP;
646
#endif
647 648 649 650 651
   info_ptr->valid |= PNG_INFO_iCCP;
}
#endif

#if defined(PNG_TEXT_SUPPORTED)
652
void PNGAPI
A
Andreas Dilger 已提交
653 654
png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
   int num_text)
655 656 657 658 659 660 661 662 663 664
{
   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 已提交
665 666 667 668
{
   int i;

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

671
   if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
672
      return(0);
A
Andreas Dilger 已提交
673 674 675 676 677 678 679 680 681 682 683 684 685 686

   /* 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;
687
         info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
688
            (png_uint_32)(info_ptr->max_text * sizeof (png_text)));
689 690 691 692 693
         if (info_ptr->text == NULL)
           {
             png_free(png_ptr, old_text);
             return(1);
           }
694 695
         png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
            sizeof(png_text)));
A
Andreas Dilger 已提交
696 697 698 699 700 701
         png_free(png_ptr, old_text);
      }
      else
      {
         info_ptr->max_text = num_text + 8;
         info_ptr->num_text = 0;
702
         info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
703
            (png_uint_32)(info_ptr->max_text * sizeof (png_text)));
704 705
         if (info_ptr->text == NULL)
           return(1);
706 707 708
#ifdef PNG_FREE_ME_SUPPORTED
         info_ptr->free_me |= PNG_FREE_TEXT;
#endif
A
Andreas Dilger 已提交
709 710 711 712 713 714
      }
      png_debug1(3, "allocated %d entries for info_ptr->text\n",
         info_ptr->max_text);
   }
   for (i = 0; i < num_text; i++)
   {
715 716
      png_size_t text_length,key_len;
      png_size_t lang_len,lang_key_len;
A
Andreas Dilger 已提交
717 718
      png_textp textp = &(info_ptr->text[info_ptr->num_text]);

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

722 723
      key_len = png_strlen(text_ptr[i].key);

724 725 726 727 728 729
      if(text_ptr[i].compression <= 0)
      {
        lang_len = 0;
        lang_key_len = 0;
      }
      else
730
#ifdef PNG_iTXt_SUPPORTED
731 732
      {
        /* set iTXt data */
733
        if (text_ptr[i].lang != NULL)
734 735 736
          lang_len = png_strlen(text_ptr[i].lang);
        else
          lang_len = 0;
737
        if (text_ptr[i].lang_key != NULL)
738 739 740
          lang_key_len = png_strlen(text_ptr[i].lang_key);
        else
          lang_key_len = 0;
741
      }
742 743 744 745 746 747
#else
      {
        png_warning(png_ptr, "iTXt chunk not supported.");
        continue;
      }
#endif
A
Andreas Dilger 已提交
748

749
      if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
A
Andreas Dilger 已提交
750
      {
751
         text_length = 0;
752
#ifdef PNG_iTXt_SUPPORTED
753 754 755
         if(text_ptr[i].compression > 0)
            textp->compression = PNG_ITXT_COMPRESSION_NONE;
         else
756
#endif
757
            textp->compression = PNG_TEXT_COMPRESSION_NONE;
A
Andreas Dilger 已提交
758 759 760
      }
      else
      {
761
         text_length = png_strlen(text_ptr[i].text);
A
Andreas Dilger 已提交
762 763
         textp->compression = text_ptr[i].compression;
      }
764

765
      textp->key = (png_charp)png_malloc_warn(png_ptr,
766
         (png_uint_32)(key_len + text_length + lang_len + lang_key_len + 4));
767 768
      if (textp->key == NULL)
        return(1);
769 770 771
      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);
772 773

      png_memcpy(textp->key, text_ptr[i].key,
774 775
         (png_size_t)(key_len));
      *(textp->key+key_len) = '\0';
776
#ifdef PNG_iTXt_SUPPORTED
777 778 779 780 781 782 783 784 785 786 787
      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
788
#endif
789
      {
790
#ifdef PNG_iTXt_SUPPORTED
791 792
         textp->lang=NULL;
         textp->lang_key=NULL;
793
#endif
794 795 796
         textp->text=textp->key + key_len + 1;
      }
      if(text_length)
797
         png_memcpy(textp->text, text_ptr[i].text,
798
            (png_size_t)(text_length));
799
      *(textp->text+text_length) = '\0';
800

801
#ifdef PNG_iTXt_SUPPORTED
802 803 804 805 806 807
      if(textp->compression > 0)
      {
         textp->text_length = 0;
         textp->itxt_length = text_length;
      }
      else
808
#endif
809 810
      {
         textp->text_length = text_length;
811
#ifdef PNG_iTXt_SUPPORTED
812
         textp->itxt_length = 0;
813
#endif
814
      }
815
      info_ptr->text[info_ptr->num_text]= *textp;
A
Andreas Dilger 已提交
816 817 818
      info_ptr->num_text++;
      png_debug1(3, "transferred text chunk %d\n", info_ptr->num_text);
   }
819
   return(0);
A
Andreas Dilger 已提交
820 821 822
}
#endif

823
#if defined(PNG_tIME_SUPPORTED)
824
void PNGAPI
A
Andreas Dilger 已提交
825 826 827
png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time)
{
   png_debug1(1, "in %s storage function\n", "tIME");
828
   if (png_ptr == NULL || info_ptr == NULL ||
829
       (png_ptr->mode & PNG_WROTE_tIME))
A
Andreas Dilger 已提交
830 831 832 833 834 835 836
      return;

   png_memcpy(&(info_ptr->mod_time), mod_time, sizeof (png_time));
   info_ptr->valid |= PNG_INFO_tIME;
}
#endif

837
#if defined(PNG_tRNS_SUPPORTED)
838
void PNGAPI
A
Andreas Dilger 已提交
839 840 841 842
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");
843
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
844 845 846
      return;

   if (trans != NULL)
847 848
   {
       /*
849 850 851 852
        * 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.
        */
853 854 855
#ifdef PNG_FREE_ME_SUPPORTED
       png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
#endif
856
       /* Changed from num_trans to 256 in version 1.2.1 */
857
       png_ptr->trans = info_ptr->trans = (png_bytep)png_malloc(png_ptr,
858
           (png_uint_32)256);
859
       png_memcpy(info_ptr->trans, trans, (png_size_t)num_trans);
860 861 862 863 864 865
#ifdef PNG_FREE_ME_SUPPORTED
       info_ptr->free_me |= PNG_FREE_TRNS;
#else
       png_ptr->flags |= PNG_FLAG_FREE_TRNS;
#endif
   }
A
Andreas Dilger 已提交
866 867 868 869 870

   if (trans_values != NULL)
   {
      png_memcpy(&(info_ptr->trans_values), trans_values,
         sizeof(png_color_16));
871 872
      if (num_trans == 0)
        num_trans = 1;
A
Andreas Dilger 已提交
873 874 875 876 877 878
   }
   info_ptr->num_trans = (png_uint_16)num_trans;
   info_ptr->valid |= PNG_INFO_tRNS;
}
#endif

879
#if defined(PNG_sPLT_SUPPORTED)
880
void PNGAPI
881
png_set_sPLT(png_structp png_ptr,
882
             png_infop info_ptr, png_sPLT_tp entries, int nentries)
883
{
884
    png_sPLT_tp np;
885 886
    int i;

887
    np = (png_sPLT_tp)png_malloc_warn(png_ptr,
888
        (info_ptr->splt_palettes_num + nentries) * sizeof(png_sPLT_t));
889 890
    if (np == NULL)
    {
891
      png_warning(png_ptr, "No memory for sPLT palettes.");
892 893
      return;
    }
894

895
    png_memcpy(np, info_ptr->splt_palettes,
896
           info_ptr->splt_palettes_num * sizeof(png_sPLT_t));
897
    png_free(png_ptr, info_ptr->splt_palettes);
898
    info_ptr->splt_palettes=NULL;
899 900 901

    for (i = 0; i < nentries; i++)
    {
902 903
        png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
        png_sPLT_tp from = entries + i;
904 905

        to->name = (png_charp)png_malloc(png_ptr,
906
            png_strlen(from->name) + 1);
907
        png_strcpy(to->name, from->name);
908
        to->entries = (png_sPLT_entryp)png_malloc(png_ptr,
909
            from->nentries * sizeof(png_sPLT_t));
910
        png_memcpy(to->entries, from->entries,
911
            from->nentries * sizeof(png_sPLT_t));
912 913
        to->nentries = from->nentries;
        to->depth = from->depth;
914 915 916 917
    }

    info_ptr->splt_palettes = np;
    info_ptr->splt_palettes_num += nentries;
918
    info_ptr->valid |= PNG_INFO_sPLT;
919
#ifdef PNG_FREE_ME_SUPPORTED
920
    info_ptr->free_me |= PNG_FREE_SPLT;
921
#endif
922 923 924
}
#endif /* PNG_sPLT_SUPPORTED */

925
#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
926
void PNGAPI
927
png_set_unknown_chunks(png_structp png_ptr,
928
   png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)
929 930 931 932
{
    png_unknown_chunkp np;
    int i;

933 934 935
    if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)
        return;

936
    np = (png_unknown_chunkp)png_malloc_warn(png_ptr,
937 938
        (info_ptr->unknown_chunks_num + num_unknowns) *
        sizeof(png_unknown_chunk));
939 940 941 942 943
    if (np == NULL)
    {
       png_warning(png_ptr, "Out of memory while processing unknown chunk.");
       return;
    }
944

945
    png_memcpy(np, info_ptr->unknown_chunks,
946 947
           info_ptr->unknown_chunks_num * sizeof(png_unknown_chunk));
    png_free(png_ptr, info_ptr->unknown_chunks);
948
    info_ptr->unknown_chunks=NULL;
949

950
    for (i = 0; i < num_unknowns; i++)
951 952 953 954
    {
        png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;
        png_unknown_chunkp from = unknowns + i;

955
        png_strcpy((png_charp)to->name, (png_charp)from->name);
956
        to->data = (png_bytep)png_malloc(png_ptr, from->size);
957 958 959 960 961 962
        if (to->data == NULL)
           png_warning(png_ptr, "Out of memory while processing unknown chunk.");
        else
        {
          png_memcpy(to->data, from->data, from->size);
          to->size = from->size;
963

964 965 966
          /* note our location in the read or write sequence */
          to->location = (png_byte)(png_ptr->mode & 0xff);
        }
967 968 969
    }

    info_ptr->unknown_chunks = np;
970
    info_ptr->unknown_chunks_num += num_unknowns;
971
#ifdef PNG_FREE_ME_SUPPORTED
972
    info_ptr->free_me |= PNG_FREE_UNKN;
973
#endif
974
}
975
void PNGAPI
976 977 978
png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
   int chunk, int location)
{
979
   if(png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <
980 981 982
         (int)info_ptr->unknown_chunks_num)
      info_ptr->unknown_chunks[chunk].location = (png_byte)location;
}
983 984
#endif

985 986
#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
    defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
987
void PNGAPI
988 989
png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted)
{
990 991 992
   /* 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");
993 994
   if (png_ptr == NULL)
      return;
995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
   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;
1011 1012
}
#endif
1013

1014
#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
1015
void PNGAPI
1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026
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)
    {
      if(keep == HANDLE_CHUNK_ALWAYS || keep == HANDLE_CHUNK_IF_SAFE)
        png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
      else
        png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
1027

1028 1029 1030 1031 1032 1033 1034 1035 1036
      if(keep == HANDLE_CHUNK_ALWAYS)
        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;
1037 1038
    new_list=(png_bytep)png_malloc(png_ptr,
       (png_uint_32)(5*(num_chunks+old_num_chunks)));
1039
    if(png_ptr->chunk_list != NULL)
1040
    {
1041 1042
       png_memcpy(new_list, png_ptr->chunk_list,
          (png_size_t)(5*old_num_chunks));
1043
       png_free(png_ptr, png_ptr->chunk_list);
1044
       png_ptr->chunk_list=NULL;
1045
    }
1046 1047
    png_memcpy(new_list+5*old_num_chunks, chunk_list,
       (png_size_t)(5*num_chunks));
1048 1049 1050 1051
    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;
1052
#ifdef PNG_FREE_ME_SUPPORTED
1053
    png_ptr->free_me |= PNG_FREE_LIST;
1054
#endif
1055 1056
}
#endif
1057

1058
#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
1059
void PNGAPI
1060 1061 1062 1063 1064 1065 1066 1067
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
1068

1069
#if defined(PNG_INFO_IMAGE_SUPPORTED)
1070
void PNGAPI
1071 1072 1073
png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
{
   png_debug1(1, "in %s storage function\n", "rows");
1074

1075 1076 1077
   if (png_ptr == NULL || info_ptr == NULL)
      return;

1078
   if(info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
1079
      png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
1080 1081 1082
   info_ptr->row_pointers = row_pointers;
   if(row_pointers)
      info_ptr->valid |= PNG_INFO_IDAT;
1083 1084 1085
}
#endif

1086
void PNGAPI
1087 1088 1089 1090 1091 1092 1093 1094 1095
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;
}
1096 1097 1098 1099 1100 1101 1102

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

1104

1105
#ifndef PNG_1_0_X
1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143
#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 */

1144 1145
    png_ptr->asm_flags &= ~settable_asm_flags;               /* zero them */
    png_ptr->asm_flags |= (asm_flags & settable_asm_flags);  /* set them */
1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159
}
#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 */
1160
#endif /* ?PNG_1_0_X */