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

/* pngset.c - storage of image information into info struct
3
 *
4
 * libpng 1.2.0beta1 - May 6, 2001
5
 * For conditions of distribution and use, see copyright notice in png.h
6
 * Copyright (c) 1998-2001 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 43 44 45 46 47 48 49 50
      return;

   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;
51 52 53 54 55 56 57 58 59 60
#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);
   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);
   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);
   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);
#endif
A
Andreas Dilger 已提交
61 62 63
   info_ptr->valid |= PNG_INFO_cHRM;
}
#endif
64
#ifdef PNG_FIXED_POINT_SUPPORTED
65
void PNGAPI
66
png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
67 68 69
   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)
70 71 72 73
{
   png_debug1(1, "in %s storage function\n", "cHRM");
   if (png_ptr == NULL || info_ptr == NULL)
      return;
A
Andreas Dilger 已提交
74

75 76 77 78 79 80 81 82
   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;
83 84 85 86 87 88 89 90 91 92
#ifdef PNG_FLOATING_POINT_SUPPORTED
   info_ptr->x_white = (float)(white_x/100000.);
   info_ptr->y_white = (float)(white_y/100000.);
   info_ptr->x_red   = (float)(red_x/100000.);
   info_ptr->y_red   = (float)(red_y/100000.);
   info_ptr->x_green = (float)(green_x/100000.);
   info_ptr->y_green = (float)(green_y/100000.);
   info_ptr->x_blue  = (float)(blue_x/100000.);
   info_ptr->y_blue  = (float)(blue_y/100000.);
#endif
93 94 95 96 97 98 99
   info_ptr->valid |= PNG_INFO_cHRM;
}
#endif
#endif

#if defined(PNG_gAMA_SUPPORTED)
#ifdef PNG_FLOATING_POINT_SUPPORTED
100
void PNGAPI
A
Andreas Dilger 已提交
101 102 103
png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
{
   png_debug1(1, "in %s storage function\n", "gAMA");
104
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
105 106 107
      return;

   info_ptr->gamma = (float)file_gamma;
108 109 110 111 112 113
#ifdef PNG_FIXED_POINT_SUPPORTED
   info_ptr->int_gamma = (int)(file_gamma*100000.+.5);
#endif
   info_ptr->valid |= PNG_INFO_gAMA;
}
#endif
114
#endif
115
void PNGAPI
116 117
png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
   int_gamma)
118 119 120 121 122 123
{
   png_debug1(1, "in %s storage function\n", "gAMA");
   if (png_ptr == NULL || info_ptr == NULL)
      return;

#ifdef PNG_FLOATING_POINT_SUPPORTED
124
   info_ptr->gamma = (float)(int_gamma/100000.);
125
#endif
126
#ifdef PNG_FIXED_POINT_SUPPORTED
127
   info_ptr->int_gamma = int_gamma;
128
#endif
A
Andreas Dilger 已提交
129 130 131
   info_ptr->valid |= PNG_INFO_gAMA;
}

132
#if defined(PNG_hIST_SUPPORTED)
133
void PNGAPI
A
Andreas Dilger 已提交
134 135
png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist)
{
136 137
   int	i;

A
Andreas Dilger 已提交
138
   png_debug1(1, "in %s storage function\n", "hIST");
139
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
140
      return;
141 142
   if (info_ptr->num_palette == 0)
       png_warning(png_ptr,
143
		   "Palette size 0, hIST allocation skipped.");
144 145 146 147 148 149

#ifdef PNG_FREE_ME_SUPPORTED
   png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
#endif
   png_ptr->hist = (png_uint_16p)png_malloc(png_ptr,
      (png_uint_32)(info_ptr->num_palette * sizeof (png_uint_16)));
A
Andreas Dilger 已提交
150

151 152 153
   for (i = 0; i < info_ptr->num_palette; i++)
       png_ptr->hist[i] = hist[i];
   info_ptr->hist = png_ptr->hist;
A
Andreas Dilger 已提交
154
   info_ptr->valid |= PNG_INFO_hIST;
155 156 157 158 159 160

#ifdef PNG_FREE_ME_SUPPORTED
   info_ptr->free_me |= PNG_FREE_HIST;
#else
   png_ptr->flags |= PNG_FLAG_FREE_HIST;
#endif
A
Andreas Dilger 已提交
161 162 163
}
#endif

164
void PNGAPI
A
Andreas Dilger 已提交
165 166 167 168 169
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)
{
170
   int rowbytes_per_pixel;
A
Andreas Dilger 已提交
171
   png_debug1(1, "in %s storage function\n", "IHDR");
172
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
      return;

   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;
   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
      info_ptr->channels = 1;
   else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
      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);
191 192 193

   /* check for overflow */
   rowbytes_per_pixel = (info_ptr->pixel_depth + 7) >> 3;
194
   if (( width > PNG_MAX_UINT/rowbytes_per_pixel))
195 196 197 198 199
   {
      png_warning(png_ptr,
         "Width too large to process image data; rowbytes will overflow.");
      info_ptr->rowbytes = (png_size_t)0;
   }
200 201
   else
      info_ptr->rowbytes = (info_ptr->width * info_ptr->pixel_depth + 7) >> 3;
A
Andreas Dilger 已提交
202 203
}

204
#if defined(PNG_oFFs_SUPPORTED)
205
void PNGAPI
A
Andreas Dilger 已提交
206
png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
207
   png_int_32 offset_x, png_int_32 offset_y, int unit_type)
A
Andreas Dilger 已提交
208 209
{
   png_debug1(1, "in %s storage function\n", "oFFs");
210
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
211 212 213 214 215 216 217 218 219
      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

220
#if defined(PNG_pCAL_SUPPORTED)
221
void PNGAPI
A
Andreas Dilger 已提交
222 223 224 225
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)
{
226
   png_uint_32 length;
227
   int i;
A
Andreas Dilger 已提交
228 229

   png_debug1(1, "in %s storage function\n", "pCAL");
230
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
231 232 233
      return;

   length = png_strlen(purpose) + 1;
234
   png_debug1(3, "allocating purpose for info (%lu bytes)\n", length);
A
Andreas Dilger 已提交
235
   info_ptr->pcal_purpose = (png_charp)png_malloc(png_ptr, length);
236
   png_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length);
A
Andreas Dilger 已提交
237 238 239 240 241 242 243 244

   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;
245
   png_debug1(3, "allocating units for info (%lu bytes)\n", length);
A
Andreas Dilger 已提交
246
   info_ptr->pcal_units = (png_charp)png_malloc(png_ptr, length);
247
   png_memcpy(info_ptr->pcal_units, units, (png_size_t)length);
A
Andreas Dilger 已提交
248 249

   info_ptr->pcal_params = (png_charpp)png_malloc(png_ptr,
250
      (png_uint_32)((nparams + 1) * sizeof(png_charp)));
A
Andreas Dilger 已提交
251 252 253 254 255
   info_ptr->pcal_params[nparams] = NULL;

   for (i = 0; i < nparams; i++)
   {
      length = png_strlen(params[i]) + 1;
256
      png_debug2(3, "allocating parameter %d for info (%lu bytes)\n", i, length);
A
Andreas Dilger 已提交
257
      info_ptr->pcal_params[i] = (png_charp)png_malloc(png_ptr, length);
258
      png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length);
A
Andreas Dilger 已提交
259 260 261
   }

   info_ptr->valid |= PNG_INFO_pCAL;
262 263 264
#ifdef PNG_FREE_ME_SUPPORTED
   info_ptr->free_me |= PNG_FREE_PCAL;
#endif
A
Andreas Dilger 已提交
265 266 267
}
#endif

268 269
#if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED)
#ifdef PNG_FLOATING_POINT_SUPPORTED
270
void PNGAPI
271
png_set_sCAL(png_structp png_ptr, png_infop info_ptr,
272
             int unit, double width, double height)
273 274 275 276 277
{
   png_debug1(1, "in %s storage function\n", "sCAL");
   if (png_ptr == NULL || info_ptr == NULL)
      return;

278
   info_ptr->scal_unit = (png_byte)unit;
279 280 281 282 283
   info_ptr->scal_pixel_width = width;
   info_ptr->scal_pixel_height = height;

   info_ptr->valid |= PNG_INFO_sCAL;
}
284 285
#else
#ifdef PNG_FIXED_POINT_SUPPORTED
286
void PNGAPI
287
png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,
288
             int unit, png_charp swidth, png_charp sheight)
289 290 291 292 293 294 295
{
   png_uint_32 length;

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

296
   info_ptr->scal_unit = (png_byte)unit;
297 298 299 300

   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);
301
   png_memcpy(info_ptr->scal_s_width, swidth, (png_size_t)length);
302 303 304

   length = png_strlen(sheight) + 1;
   png_debug1(3, "allocating unit for info (%d bytes)\n", length);
305
   info_ptr->scal_s_width = (png_charp)png_malloc(png_ptr, length);
306
   png_memcpy(info_ptr->scal_s_height, sheight, (png_size_t)length);
307 308

   info_ptr->valid |= PNG_INFO_sCAL;
309 310 311
#ifdef PNG_FREE_ME_SUPPORTED
   info_ptr->free_me |= PNG_FREE_SCAL;
#endif
312 313
}
#endif
314 315
#endif
#endif
316 317

#if defined(PNG_pHYs_SUPPORTED)
318
void PNGAPI
A
Andreas Dilger 已提交
319 320 321 322
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");
323
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
324 325 326 327 328 329 330 331 332
      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

333
void PNGAPI
A
Andreas Dilger 已提交
334 335 336
png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
   png_colorp palette, int num_palette)
{
337

A
Andreas Dilger 已提交
338
   png_debug1(1, "in %s storage function\n", "PLTE");
339
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
340 341
      return;

342 343 344 345 346 347 348 349 350 351
   /*
    * 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
   png_ptr->palette = (png_colorp)png_zalloc(png_ptr, (uInt)num_palette,
      sizeof (png_color));
352
   memcpy(png_ptr->palette, palette, num_palette * sizeof (png_color));
353 354 355 356 357 358 359 360
   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
361

362
   info_ptr->valid |= PNG_INFO_PLTE;
A
Andreas Dilger 已提交
363 364
}

365
#if defined(PNG_sBIT_SUPPORTED)
366
void PNGAPI
A
Andreas Dilger 已提交
367 368 369 370
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");
371
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
372 373 374 375 376 377 378
      return;

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

379
#if defined(PNG_sRGB_SUPPORTED)
380
void PNGAPI
381
png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent)
382 383
{
   png_debug1(1, "in %s storage function\n", "sRGB");
384
   if (png_ptr == NULL || info_ptr == NULL)
385 386
      return;

387
   info_ptr->srgb_intent = (png_byte)intent;
388 389
   info_ptr->valid |= PNG_INFO_sRGB;
}
390

391
void PNGAPI
392
png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
393
   int intent)
394
{
395 396
#if defined(PNG_gAMA_SUPPORTED)
#ifdef PNG_FLOATING_POINT_SUPPORTED
397 398
   float file_gamma;
#endif
399
#ifdef PNG_FIXED_POINT_SUPPORTED
400
   png_fixed_point int_file_gamma;
401 402 403 404
#endif
#endif
#if defined(PNG_cHRM_SUPPORTED)
#ifdef PNG_FLOATING_POINT_SUPPORTED
405
   float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
406 407
#endif
#ifdef PNG_FIXED_POINT_SUPPORTED
408
   png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, int_green_x,
409 410
      int_green_y, int_blue_x, int_blue_y;
#endif
411 412
#endif
   png_debug1(1, "in %s storage function\n", "sRGB_gAMA_and_cHRM");
413
   if (png_ptr == NULL || info_ptr == NULL)
414 415 416 417
      return;

   png_set_sRGB(png_ptr, info_ptr, intent);

418 419
#if defined(PNG_gAMA_SUPPORTED)
#ifdef PNG_FLOATING_POINT_SUPPORTED
420
   file_gamma = (float).45455;
421 422
   png_set_gAMA(png_ptr, info_ptr, file_gamma);
#endif
423 424 425 426 427
#ifdef PNG_FIXED_POINT_SUPPORTED
   int_file_gamma = 45455L;
   png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma);
#endif
#endif
428

429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444
#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
445 446 447 448 449 450 451 452
   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;
453 454 455

   png_set_cHRM(png_ptr, info_ptr,
      white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
456
#endif
457 458 459 460
#endif
}
#endif

461 462

#if defined(PNG_iCCP_SUPPORTED)
463
void PNGAPI
464 465
png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
             png_charp name, int compression_type,
466
             png_charp profile, png_uint_32 proflen)
467
{
468 469 470
   png_charp new_iccp_name;
   png_charp new_iccp_profile;

471 472 473 474
   png_debug1(1, "in %s storage function\n", "iCCP");
   if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
      return;

475 476 477
   new_iccp_name = png_malloc(png_ptr, png_strlen(name)+1);
   strcpy(new_iccp_name, name);
   new_iccp_profile = png_malloc(png_ptr, proflen);
478 479
   png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);

480
   png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
481

482
   info_ptr->iccp_proflen = proflen;
483 484
   info_ptr->iccp_name = new_iccp_name;
   info_ptr->iccp_profile = new_iccp_profile;
485
   /* Compression is always zero but is here so the API and info structure
486
    * does not have to change if we introduce multiple compression types */
487
   info_ptr->iccp_compression = (png_byte)compression_type;
488
#ifdef PNG_FREE_ME_SUPPORTED
489
   info_ptr->free_me |= PNG_FREE_ICCP;
490
#endif
491 492 493 494 495
   info_ptr->valid |= PNG_INFO_iCCP;
}
#endif

#if defined(PNG_TEXT_SUPPORTED)
496
void PNGAPI
A
Andreas Dilger 已提交
497 498 499 500 501 502
png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
   int num_text)
{
   int i;

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

505
   if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
A
Andreas Dilger 已提交
506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521
      return;

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

         old_max = info_ptr->max_text;
         info_ptr->max_text = info_ptr->num_text + num_text + 8;
         old_text = info_ptr->text;
         info_ptr->text = (png_textp)png_malloc(png_ptr,
522
            (png_uint_32)(info_ptr->max_text * sizeof (png_text)));
523 524
         png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
            sizeof(png_text)));
A
Andreas Dilger 已提交
525 526 527 528 529 530 531
         png_free(png_ptr, old_text);
      }
      else
      {
         info_ptr->max_text = num_text + 8;
         info_ptr->num_text = 0;
         info_ptr->text = (png_textp)png_malloc(png_ptr,
532
            (png_uint_32)(info_ptr->max_text * sizeof (png_text)));
533 534 535
#ifdef PNG_FREE_ME_SUPPORTED
         info_ptr->free_me |= PNG_FREE_TEXT;
#endif
A
Andreas Dilger 已提交
536 537 538 539 540 541
      }
      png_debug1(3, "allocated %d entries for info_ptr->text\n",
         info_ptr->max_text);
   }
   for (i = 0; i < num_text; i++)
   {
542 543
      png_size_t text_length,key_len;
      png_size_t lang_len,lang_key_len;
A
Andreas Dilger 已提交
544 545
      png_textp textp = &(info_ptr->text[info_ptr->num_text]);

546
      if (text_ptr[i].key == (png_charp)NULL)
547 548
          continue;

549 550
      key_len = png_strlen(text_ptr[i].key);

551 552 553 554 555 556
      if(text_ptr[i].compression <= 0)
      {
        lang_len = 0;
        lang_key_len = 0;
      }
      else
557
#ifdef PNG_iTXt_SUPPORTED
558 559
      {
        /* set iTXt data */
560
        if (text_ptr[i].key != (png_charp)NULL)
561 562 563
          lang_len = png_strlen(text_ptr[i].lang);
        else
          lang_len = 0;
564
        if (text_ptr[i].lang_key != (png_charp)NULL)
565 566 567
          lang_key_len = png_strlen(text_ptr[i].lang_key);
        else
          lang_key_len = 0;
568
      }
569 570 571 572 573 574
#else
      {
        png_warning(png_ptr, "iTXt chunk not supported.");
        continue;
      }
#endif
A
Andreas Dilger 已提交
575

576
      if (text_ptr[i].text == (png_charp)NULL || text_ptr[i].text[0] == '\0')
A
Andreas Dilger 已提交
577
      {
578
         text_length = 0;
579
#ifdef PNG_iTXt_SUPPORTED
580 581 582
         if(text_ptr[i].compression > 0)
            textp->compression = PNG_ITXT_COMPRESSION_NONE;
         else
583
#endif
584
            textp->compression = PNG_TEXT_COMPRESSION_NONE;
A
Andreas Dilger 已提交
585 586 587
      }
      else
      {
588
         text_length = png_strlen(text_ptr[i].text);
A
Andreas Dilger 已提交
589 590
         textp->compression = text_ptr[i].compression;
      }
591 592

      textp->key = (png_charp)png_malloc(png_ptr,
593
         (png_uint_32)(key_len + text_length + lang_len + lang_key_len + 4));
594 595
      png_debug2(2, "Allocated %d bytes at %x in png_set_text\n",
         key_len + lang_len + lang_key_len + text_length + 4, (int)textp->key);
596 597

      png_memcpy(textp->key, text_ptr[i].key,
598 599
         (png_size_t)(key_len));
      *(textp->key+key_len) = '\0';
600
#ifdef PNG_iTXt_SUPPORTED
601 602 603 604 605 606 607 608 609 610 611
      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
612
#endif
613
      {
614
#ifdef PNG_iTXt_SUPPORTED
615 616
         textp->lang=(png_charp)NULL;
         textp->lang_key=(png_charp)NULL;
617
#endif
618 619 620
         textp->text=textp->key + key_len + 1;
      }
      if(text_length)
621
         png_memcpy(textp->text, text_ptr[i].text,
622
            (png_size_t)(text_length));
623
      *(textp->text+text_length) = '\0';
624

625
#ifdef PNG_iTXt_SUPPORTED
626 627 628 629 630 631
      if(textp->compression > 0)
      {
         textp->text_length = 0;
         textp->itxt_length = text_length;
      }
      else
632
#endif
633 634
      {
         textp->text_length = text_length;
635
#ifdef PNG_iTXt_SUPPORTED
636
         textp->itxt_length = 0;
637
#endif
638
      }
639
      info_ptr->text[info_ptr->num_text]= *textp;
A
Andreas Dilger 已提交
640 641 642 643 644 645
      info_ptr->num_text++;
      png_debug1(3, "transferred text chunk %d\n", info_ptr->num_text);
   }
}
#endif

646
#if defined(PNG_tIME_SUPPORTED)
647
void PNGAPI
A
Andreas Dilger 已提交
648 649 650
png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time)
{
   png_debug1(1, "in %s storage function\n", "tIME");
651
   if (png_ptr == NULL || info_ptr == NULL ||
652
       (png_ptr->mode & PNG_WROTE_tIME))
A
Andreas Dilger 已提交
653 654 655 656 657 658 659
      return;

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

660
#if defined(PNG_tRNS_SUPPORTED)
661
void PNGAPI
A
Andreas Dilger 已提交
662 663 664 665
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");
666
   if (png_ptr == NULL || info_ptr == NULL)
A
Andreas Dilger 已提交
667 668 669
      return;

   if (trans != NULL)
670 671 672 673 674 675 676 677 678
   {
       /*
	* 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.
	*/
#ifdef PNG_FREE_ME_SUPPORTED
       png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
#endif
679 680
       png_ptr->trans = info_ptr->trans = png_malloc(png_ptr, num_trans);
       memcpy(info_ptr->trans, trans, num_trans);
681 682 683 684 685 686
#ifdef PNG_FREE_ME_SUPPORTED
       info_ptr->free_me |= PNG_FREE_TRNS;
#else
       png_ptr->flags |= PNG_FLAG_FREE_TRNS;
#endif
   }
A
Andreas Dilger 已提交
687 688 689 690 691

   if (trans_values != NULL)
   {
      png_memcpy(&(info_ptr->trans_values), trans_values,
         sizeof(png_color_16));
692 693
      if (num_trans == 0)
        num_trans = 1;
A
Andreas Dilger 已提交
694 695 696 697 698 699
   }
   info_ptr->num_trans = (png_uint_16)num_trans;
   info_ptr->valid |= PNG_INFO_tRNS;
}
#endif

700
#if defined(PNG_sPLT_SUPPORTED)
701
void PNGAPI
702
png_set_sPLT(png_structp png_ptr,
703
             png_infop info_ptr, png_sPLT_tp entries, int nentries)
704
{
705
    png_sPLT_tp np;
706 707
    int i;

708 709
    np = (png_sPLT_tp)png_malloc(png_ptr,
        (info_ptr->splt_palettes_num + nentries) * sizeof(png_sPLT_t));
710

711
    png_memcpy(np, info_ptr->splt_palettes,
712
           info_ptr->splt_palettes_num * sizeof(png_sPLT_t));
713
    png_free(png_ptr, info_ptr->splt_palettes);
714
    info_ptr->splt_palettes=NULL;
715 716 717

    for (i = 0; i < nentries; i++)
    {
718 719
        png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
        png_sPLT_tp from = entries + i;
720 721

        to->name = (png_charp)png_malloc(png_ptr,
722
                                        png_strlen(from->name) + 1);
723
        png_strcpy(to->name, from->name);
724
        to->entries = (png_sPLT_entryp)png_malloc(png_ptr,
725
                                 from->nentries * sizeof(png_sPLT_t));
726
        png_memcpy(to->entries, from->entries,
727
               from->nentries * sizeof(png_sPLT_t));
728 729
        to->nentries = from->nentries;
        to->depth = from->depth;
730 731 732 733
    }

    info_ptr->splt_palettes = np;
    info_ptr->splt_palettes_num += nentries;
734
    info_ptr->valid |= PNG_INFO_sPLT;
735
#ifdef PNG_FREE_ME_SUPPORTED
736
    info_ptr->free_me |= PNG_FREE_SPLT;
737
#endif
738 739 740
}
#endif /* PNG_sPLT_SUPPORTED */

741
#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
742
void PNGAPI
743
png_set_unknown_chunks(png_structp png_ptr,
744
   png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)
745 746 747 748
{
    png_unknown_chunkp np;
    int i;

749 750 751
    if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)
        return;

752
    np = (png_unknown_chunkp)png_malloc(png_ptr,
753 754
        (info_ptr->unknown_chunks_num + num_unknowns) *
        sizeof(png_unknown_chunk));
755

756
    png_memcpy(np, info_ptr->unknown_chunks,
757 758
           info_ptr->unknown_chunks_num * sizeof(png_unknown_chunk));
    png_free(png_ptr, info_ptr->unknown_chunks);
759
    info_ptr->unknown_chunks=NULL;
760

761
    for (i = 0; i < num_unknowns; i++)
762 763 764 765
    {
        png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;
        png_unknown_chunkp from = unknowns + i;

766
        png_strcpy((png_charp)to->name, (png_charp)from->name);
767
        to->data = (png_bytep)png_malloc(png_ptr, from->size);
768 769
        png_memcpy(to->data, from->data, from->size);
        to->size = from->size;
770

771 772
        /* note our location in the read or write sequence */
        to->location = (png_byte)(png_ptr->mode & 0xff);
773 774 775
    }

    info_ptr->unknown_chunks = np;
776
    info_ptr->unknown_chunks_num += num_unknowns;
777
#ifdef PNG_FREE_ME_SUPPORTED
778
    info_ptr->free_me |= PNG_FREE_UNKN;
779
#endif
780
}
781
void PNGAPI
782 783 784
png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
   int chunk, int location)
{
785
   if(png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <
786 787 788
         (int)info_ptr->unknown_chunks_num)
      info_ptr->unknown_chunks[chunk].location = (png_byte)location;
}
789 790
#endif

791 792
#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
    defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
793
void PNGAPI
794 795
png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted)
{
796 797 798
   /* 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");
799 800
   if (png_ptr == NULL)
      return;
801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816
   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;
817 818
}
#endif
819

820
#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
821
void PNGAPI
822 823 824 825 826 827 828 829 830 831 832
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;
833

834 835 836 837 838 839 840 841 842
      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;
843 844
    new_list=png_malloc(png_ptr,5*(num_chunks+old_num_chunks));
    if(png_ptr->chunk_list != (png_bytep)NULL)
845 846
    {
       png_memcpy(new_list, png_ptr->chunk_list, 5*old_num_chunks);
847
       png_free(png_ptr, png_ptr->chunk_list);
848
       png_ptr->chunk_list=NULL;
849 850 851 852 853 854
    }
    png_memcpy(new_list+5*old_num_chunks, chunk_list, 5*num_chunks);
    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;
855
#ifdef PNG_FREE_ME_SUPPORTED
856
    png_ptr->free_me |= PNG_FREE_LIST;
857
#endif
858 859
}
#endif
860

861
#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
862
void PNGAPI
863 864 865 866 867 868 869 870
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
871

872
#if defined(PNG_INFO_IMAGE_SUPPORTED)
873
void PNGAPI
874 875 876
png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
{
   png_debug1(1, "in %s storage function\n", "rows");
877

878 879 880
   if (png_ptr == NULL || info_ptr == NULL)
      return;

881
   if(info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
882
      png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
883 884 885
   info_ptr->row_pointers = row_pointers;
   if(row_pointers)
      info_ptr->valid |= PNG_INFO_IDAT;
886

887 888 889
}
#endif

890
void PNGAPI
891 892 893 894 895 896
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);
897 898
    if(!png_ptr->zbuf)
       png_error(png_ptr,"Unable to malloc zbuf");
899 900 901
    png_ptr->zstream.next_out = png_ptr->zbuf;
    png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
}
902 903 904 905 906 907 908

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

910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964

#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 */

    png_ptr->asm_flags &= ~settable_asm_flags;			/* zero them */
    png_ptr->asm_flags |= (asm_flags & settable_asm_flags);	/* set them */
}
#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 */