Subversion Repositories Kolibri OS

Rev

Rev 1897 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1897 Rev 3928
Line 1... Line 1...
1
/* pngset.c - storage of image information into info struct
1
/* pngset.c - storage of image information into info struct
2
 *
2
 *
3
 * Last changed in libpng 1.5.1 [February 3, 2011]
3
 * Last changed in libpng 1.6.3 [July 18, 2013]
4
 * Copyright (c) 1998-2011 Glenn Randers-Pehrson
4
 * Copyright (c) 1998-2013 Glenn Randers-Pehrson
5
 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
5
 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
6
 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
6
 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
7
 *
7
 *
8
 * This code is released under the libpng license.
8
 * This code is released under the libpng license.
9
 * For conditions of distribution and use, see the disclaimer
9
 * For conditions of distribution and use, see the disclaimer
Line 20... Line 20...
20
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
20
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
Line 21... Line 21...
21
 
21
 
22
#ifdef PNG_bKGD_SUPPORTED
22
#ifdef PNG_bKGD_SUPPORTED
23
void PNGAPI
23
void PNGAPI
24
png_set_bKGD(png_structp png_ptr, png_infop info_ptr,
24
png_set_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
25
    png_const_color_16p background)
25
    png_const_color_16p background)
26
{
26
{
Line 27... Line 27...
27
   png_debug1(1, "in %s storage function", "bKGD");
27
   png_debug1(1, "in %s storage function", "bKGD");
28
 
28
 
Line 29... Line 29...
29
   if (png_ptr == NULL || info_ptr == NULL)
29
   if (png_ptr == NULL || info_ptr == NULL || background == NULL)
30
      return;
30
      return;
31
 
31
 
32
   png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16));
32
   info_ptr->background = *background;
Line 33... Line 33...
33
   info_ptr->valid |= PNG_INFO_bKGD;
33
   info_ptr->valid |= PNG_INFO_bKGD;
34
}
34
}
35
#endif
35
#endif
36
 
36
 
37
#ifdef PNG_cHRM_SUPPORTED
37
#ifdef PNG_cHRM_SUPPORTED
38
void PNGFAPI
38
void PNGFAPI
39
png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
39
png_set_cHRM_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
-
 
40
    png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
-
 
41
    png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
40
    png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
42
    png_fixed_point blue_x, png_fixed_point blue_y)
Line 41... Line 43...
41
    png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
43
{
42
    png_fixed_point blue_x, png_fixed_point blue_y)
44
   png_xy xy;
Line 43... Line -...
43
{
-
 
44
   png_debug1(1, "in %s storage function", "cHRM fixed");
45
 
45
 
-
 
46
   if (png_ptr == NULL || info_ptr == NULL)
46
   png_debug1(1, "in %s storage function", "cHRM fixed");
47
      return;
-
 
48
 
47
 
49
#  ifdef PNG_CHECK_cHRM_SUPPORTED
48
   if (png_ptr == NULL || info_ptr == NULL)
50
   if (png_check_cHRM_fixed(png_ptr,
49
      return;
51
       white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y))
50
 
52
#  endif
51
   xy.redx = red_x;
53
   {
52
   xy.redy = red_y;
-
 
53
   xy.greenx = green_x;
54
      info_ptr->x_white = white_x;
54
   xy.greeny = green_y;
55
      info_ptr->y_white = white_y;
55
   xy.bluex = blue_x;
56
      info_ptr->x_red   = red_x;
56
   xy.bluey = blue_y;
-
 
57
   xy.whitex = white_x;
-
 
58
   xy.whitey = white_y;
57
      info_ptr->y_red   = red_y;
59
 
-
 
60
   if (png_colorspace_set_chromaticities(png_ptr, &info_ptr->colorspace, &xy,
-
 
61
      2/* override with app values*/))
-
 
62
      info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
-
 
63
 
-
 
64
   png_colorspace_sync_info(png_ptr, info_ptr);
-
 
65
}
-
 
66
 
-
 
67
void PNGFAPI
-
 
68
png_set_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
-
 
69
    png_fixed_point int_red_X, png_fixed_point int_red_Y,
-
 
70
    png_fixed_point int_red_Z, png_fixed_point int_green_X,
-
 
71
    png_fixed_point int_green_Y, png_fixed_point int_green_Z,
-
 
72
    png_fixed_point int_blue_X, png_fixed_point int_blue_Y,
-
 
73
    png_fixed_point int_blue_Z)
-
 
74
{
-
 
75
   png_XYZ XYZ;
-
 
76
 
-
 
77
   png_debug1(1, "in %s storage function", "cHRM XYZ fixed");
-
 
78
 
-
 
79
   if (png_ptr == NULL || info_ptr == NULL)
-
 
80
      return;
-
 
81
 
-
 
82
   XYZ.red_X = int_red_X;
-
 
83
   XYZ.red_Y = int_red_Y;
-
 
84
   XYZ.red_Z = int_red_Z;
-
 
85
   XYZ.green_X = int_green_X;
-
 
86
   XYZ.green_Y = int_green_Y;
-
 
87
   XYZ.green_Z = int_green_Z;
-
 
88
   XYZ.blue_X = int_blue_X;
-
 
89
   XYZ.blue_Y = int_blue_Y;
58
      info_ptr->x_green = green_x;
90
   XYZ.blue_Z = int_blue_Z;
Line 59... Line 91...
59
      info_ptr->y_green = green_y;
91
 
60
      info_ptr->x_blue  = blue_x;
92
   if (png_colorspace_set_endpoints(png_ptr, &info_ptr->colorspace, &XYZ, 2))
61
      info_ptr->y_blue  = blue_y;
93
      info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
62
      info_ptr->valid |= PNG_INFO_cHRM;
94
 
63
   }
95
   png_colorspace_sync_info(png_ptr, info_ptr);
64
}
96
}
65
 
97
 
66
#  ifdef PNG_FLOATING_POINT_SUPPORTED
98
#  ifdef PNG_FLOATING_POINT_SUPPORTED
Line 78... Line 110...
78
      png_fixed(png_ptr, green_y, "cHRM Green Y"),
110
      png_fixed(png_ptr, green_y, "cHRM Green Y"),
79
      png_fixed(png_ptr, blue_x, "cHRM Blue X"),
111
      png_fixed(png_ptr, blue_x, "cHRM Blue X"),
80
      png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
112
      png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
81
}
113
}
82
#  endif /* PNG_FLOATING_POINT_SUPPORTED */
114
 
-
 
115
void PNGAPI
-
 
116
png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X,
-
 
117
    double red_Y, double red_Z, double green_X, double green_Y, double green_Z,
-
 
118
    double blue_X, double blue_Y, double blue_Z)
-
 
119
{
-
 
120
   png_set_cHRM_XYZ_fixed(png_ptr, info_ptr,
-
 
121
      png_fixed(png_ptr, red_X, "cHRM Red X"),
-
 
122
      png_fixed(png_ptr, red_Y, "cHRM Red Y"),
-
 
123
      png_fixed(png_ptr, red_Z, "cHRM Red Z"),
-
 
124
      png_fixed(png_ptr, green_X, "cHRM Red X"),
-
 
125
      png_fixed(png_ptr, green_Y, "cHRM Red Y"),
-
 
126
      png_fixed(png_ptr, green_Z, "cHRM Red Z"),
-
 
127
      png_fixed(png_ptr, blue_X, "cHRM Red X"),
-
 
128
      png_fixed(png_ptr, blue_Y, "cHRM Red Y"),
-
 
129
      png_fixed(png_ptr, blue_Z, "cHRM Red Z"));
-
 
130
}
-
 
131
#  endif /* PNG_FLOATING_POINT_SUPPORTED */
83
 
132
 
Line 84... Line 133...
84
#endif /* PNG_cHRM_SUPPORTED */
133
#endif /* PNG_cHRM_SUPPORTED */
Line 85... Line 134...
85
 
134
 
86
#ifdef PNG_gAMA_SUPPORTED
135
#ifdef PNG_gAMA_SUPPORTED
87
void PNGFAPI
136
void PNGFAPI
88
png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
137
png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
89
    file_gamma)
138
    png_fixed_point file_gamma)
90
{
139
{
Line 91... Line 140...
91
   png_debug1(1, "in %s storage function", "gAMA");
140
   png_debug1(1, "in %s storage function", "gAMA");
92
 
141
 
Line 93... Line -...
93
   if (png_ptr == NULL || info_ptr == NULL)
-
 
94
      return;
-
 
95
 
-
 
96
   /* Previously these values were limited, however they must be
-
 
97
    * wrong, therefore storing them (and setting PNG_INFO_gAMA)
-
 
98
    * must be wrong too.
142
   if (png_ptr == NULL || info_ptr == NULL)
99
    */
-
 
100
   if (file_gamma > (png_fixed_point)PNG_UINT_31_MAX)
-
 
101
      png_warning(png_ptr, "Gamma too large, ignored");
143
      return;
102
 
-
 
103
   else if (file_gamma <= 0)
-
 
104
      png_warning(png_ptr, "Negative or zero gamma ignored");
-
 
105
 
-
 
106
   else
-
 
107
   {
-
 
108
      info_ptr->gamma = file_gamma;
144
 
Line 109... Line 145...
109
      info_ptr->valid |= PNG_INFO_gAMA;
145
   png_colorspace_set_gamma(png_ptr, &info_ptr->colorspace, file_gamma);
110
   }
146
   png_colorspace_sync_info(png_ptr, info_ptr);
111
}
147
}
112
 
148
 
113
#  ifdef PNG_FLOATING_POINT_SUPPORTED
149
#  ifdef PNG_FLOATING_POINT_SUPPORTED
114
void PNGAPI
150
void PNGAPI
115
png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
151
png_set_gAMA(png_const_structrp png_ptr, png_inforp info_ptr, double file_gamma)
116
{
152
{
117
   png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma,
153
   png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma,
Line 118... Line 154...
118
       "png_set_gAMA"));
154
       "png_set_gAMA"));
119
}
155
}
120
#  endif
156
#  endif
-
 
157
#endif
121
#endif
158
 
122
 
159
#ifdef PNG_hIST_SUPPORTED
Line 123... Line 160...
123
#ifdef PNG_hIST_SUPPORTED
160
void PNGAPI
Line 144... Line 181...
144
 
181
 
Line 145... Line 182...
145
   /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in
182
   /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in
146
    * version 1.2.1
183
    * version 1.2.1
147
    */
184
    */
148
   png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr,
185
   info_ptr->hist = png_voidcast(png_uint_16p, png_malloc_warn(png_ptr,
149
       PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16));
186
       PNG_MAX_PALETTE_LENGTH * (sizeof (png_uint_16))));
Line 150... Line 187...
150
 
187
 
151
   if (png_ptr->hist == NULL)
188
   if (info_ptr->hist == NULL)
152
   {
189
   {
153
      png_warning(png_ptr, "Insufficient memory for hIST chunk data");
190
      png_warning(png_ptr, "Insufficient memory for hIST chunk data");
154
      return;
191
      return;
Line -... Line 192...
-
 
192
   }
-
 
193
 
155
   }
194
   info_ptr->free_me |= PNG_FREE_HIST;
156
 
195
 
Line 157... Line -...
157
   for (i = 0; i < info_ptr->num_palette; i++)
-
 
158
      png_ptr->hist[i] = hist[i];
196
   for (i = 0; i < info_ptr->num_palette; i++)
159
 
-
 
160
   info_ptr->hist = png_ptr->hist;
197
      info_ptr->hist[i] = hist[i];
161
   info_ptr->valid |= PNG_INFO_hIST;
198
 
Line 162... Line 199...
162
   info_ptr->free_me |= PNG_FREE_HIST;
199
   info_ptr->valid |= PNG_INFO_hIST;
163
}
200
}
164
#endif
201
#endif
165
 
202
 
166
void PNGAPI
203
void PNGAPI
167
png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
204
png_set_IHDR(png_const_structrp png_ptr, png_inforp info_ptr,
168
    png_uint_32 width, png_uint_32 height, int bit_depth,
205
    png_uint_32 width, png_uint_32 height, int bit_depth,
Line 199... Line 236...
199
      info_ptr->channels++;
236
      info_ptr->channels++;
200
 
237
 
Line 201... Line 238...
201
   info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
238
   info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
Line 202... Line -...
202
 
-
 
203
   /* Check for potential overflow */
-
 
204
   if (width >
-
 
205
       (PNG_UINT_32_MAX >> 3)      /* 8-byte RRGGBBAA pixels */
-
 
206
       - 48       /* bigrowbuf hack */
-
 
207
       - 1        /* filter byte */
-
 
208
       - 7*8      /* rounding of width to multiple of 8 pixels */
-
 
209
       - 8)       /* extra max_pixel_depth pad */
-
 
210
      info_ptr->rowbytes = 0;
-
 
211
   else
239
 
212
      info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
240
   info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
Line 213... Line 241...
213
}
241
}
214
 
242
 
215
#ifdef PNG_oFFs_SUPPORTED
243
#ifdef PNG_oFFs_SUPPORTED
216
void PNGAPI
244
void PNGAPI
217
png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
245
png_set_oFFs(png_const_structrp png_ptr, png_inforp info_ptr,
218
    png_int_32 offset_x, png_int_32 offset_y, int unit_type)
246
    png_int_32 offset_x, png_int_32 offset_y, int unit_type)
Line 219... Line 247...
219
{
247
{
Line 230... Line 258...
230
#endif
258
#endif
231
 
259
 
Line 232... Line 260...
232
#ifdef PNG_pCAL_SUPPORTED
260
#ifdef PNG_pCAL_SUPPORTED
233
void PNGAPI
261
void PNGAPI
234
png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
262
png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
235
    png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type,
263
    png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type,
236
    int nparams, png_const_charp units, png_charpp params)
264
    int nparams, png_const_charp units, png_charpp params)
237
{
265
{
238
   png_size_t length;
266
   png_size_t length;
239
   int i;
267
   int i;
Line 240... Line 268...
240
 
268
 
Line 241... Line 269...
241
   png_debug1(1, "in %s storage function", "pCAL");
269
   png_debug1(1, "in %s storage function", "pCAL");
-
 
270
 
242
 
271
   if (png_ptr == NULL || info_ptr == NULL || purpose == NULL || units == NULL
Line 243... Line 272...
243
   if (png_ptr == NULL || info_ptr == NULL)
272
      || (nparams > 0 && params == NULL))
244
      return;
273
      return;
245
 
274
 
Line 246... Line 275...
246
   length = png_strlen(purpose) + 1;
275
   length = strlen(purpose) + 1;
Line 247... Line 276...
247
   png_debug1(3, "allocating purpose for info (%lu bytes)",
276
   png_debug1(3, "allocating purpose for info (%lu bytes)",
248
       (unsigned long)length);
277
       (unsigned long)length);
249
 
278
 
Line -... Line 279...
-
 
279
   /* TODO: validate format of calibration name and unit name */
-
 
280
 
-
 
281
   /* Check that the type matches the specification. */
250
   /* TODO: validate format of calibration name and unit name */
282
   if (type < 0 || type > 3)
251
 
283
      png_error(png_ptr, "Invalid pCAL equation type");
-
 
284
 
252
   /* Check that the type matches the specification. */
285
   if (nparams < 0 || nparams > 255)
253
   if (type < 0 || type > 3)
286
      png_error(png_ptr, "Invalid pCAL parameter count");
Line 254... Line 287...
254
      png_error(png_ptr, "Invalid pCAL equation type");
287
 
-
 
288
   /* Validate params[nparams] */
Line 255... Line 289...
255
 
289
   for (i=0; i
256
   /* Validate params[nparams] */
290
      if (params[i] == NULL ||
257
   for (i=0; i
291
         !png_check_fp_string(params[i], strlen(params[i])))
258
      if (!png_check_fp_string(params[i], png_strlen(params[i])))
292
         png_error(png_ptr, "Invalid format for pCAL parameter");
259
         png_error(png_ptr, "Invalid format for pCAL parameter");
293
 
Line 260... Line 294...
260
 
294
   info_ptr->pcal_purpose = png_voidcast(png_charp,
Line 261... Line 295...
261
   info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length);
295
      png_malloc_warn(png_ptr, length));
262
 
296
 
263
   if (info_ptr->pcal_purpose == NULL)
297
   if (info_ptr->pcal_purpose == NULL)
264
   {
298
   {
265
      png_warning(png_ptr, "Insufficient memory for pCAL purpose");
299
      png_warning(png_ptr, "Insufficient memory for pCAL purpose");
Line 266... Line 300...
266
      return;
300
      return;
267
   }
301
   }
268
 
302
 
Line 269... Line 303...
269
   png_memcpy(info_ptr->pcal_purpose, purpose, length);
303
   memcpy(info_ptr->pcal_purpose, purpose, length);
-
 
304
 
Line 270... Line 305...
270
 
305
   png_debug(3, "storing X0, X1, type, and nparams in info");
271
   png_debug(3, "storing X0, X1, type, and nparams in info");
306
   info_ptr->pcal_X0 = X0;
272
   info_ptr->pcal_X0 = X0;
307
   info_ptr->pcal_X1 = X1;
273
   info_ptr->pcal_X1 = X1;
308
   info_ptr->pcal_type = (png_byte)type;
274
   info_ptr->pcal_type = (png_byte)type;
309
   info_ptr->pcal_nparams = (png_byte)nparams;
Line 275... Line 310...
275
   info_ptr->pcal_nparams = (png_byte)nparams;
310
 
Line 276... Line 311...
276
 
311
   length = strlen(units) + 1;
277
   length = png_strlen(units) + 1;
312
   png_debug1(3, "allocating units for info (%lu bytes)",
Line 278... Line 313...
278
   png_debug1(3, "allocating units for info (%lu bytes)",
313
     (unsigned long)length);
279
     (unsigned long)length);
314
 
280
 
315
   info_ptr->pcal_units = png_voidcast(png_charp,
281
   info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length);
316
      png_malloc_warn(png_ptr, length));
282
 
317
 
Line 283... Line 318...
283
   if (info_ptr->pcal_units == NULL)
318
   if (info_ptr->pcal_units == NULL)
Line 284... Line 319...
284
   {
319
   {
285
      png_warning(png_ptr, "Insufficient memory for pCAL units");
320
      png_warning(png_ptr, "Insufficient memory for pCAL units");
286
      return;
321
      return;
287
   }
322
   }
288
 
323
 
Line 289... Line 324...
289
   png_memcpy(info_ptr->pcal_units, units, length);
324
   memcpy(info_ptr->pcal_units, units, length);
Line 312... Line 347...
312
         png_warning(png_ptr, "Insufficient memory for pCAL parameter");
347
         png_warning(png_ptr, "Insufficient memory for pCAL parameter");
313
         return;
348
         return;
314
      }
349
      }
315
 
350
 
Line 316... Line 351...
316
      png_memcpy(info_ptr->pcal_params[i], params[i], length);
351
      memcpy(info_ptr->pcal_params[i], params[i], length);
317
   }
352
   }
Line 318... Line 353...
318
 
353
 
319
   info_ptr->valid |= PNG_INFO_pCAL;
354
   info_ptr->valid |= PNG_INFO_pCAL;
320
   info_ptr->free_me |= PNG_FREE_PCAL;
355
   info_ptr->free_me |= PNG_FREE_PCAL;
321
}
356
}
Line 322... Line 357...
322
#endif
357
#endif
323
 
358
 
324
#ifdef PNG_sCAL_SUPPORTED
359
#ifdef PNG_sCAL_SUPPORTED
325
void PNGAPI
360
void PNGAPI
326
png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,
361
png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr,
327
    int unit, png_const_charp swidth, png_const_charp sheight)
362
    int unit, png_const_charp swidth, png_const_charp sheight)
Line 328... Line 363...
328
{
363
{
Line 338... Line 373...
338
    */
373
    */
339
   if (unit != 1 && unit != 2)
374
   if (unit != 1 && unit != 2)
340
      png_error(png_ptr, "Invalid sCAL unit");
375
      png_error(png_ptr, "Invalid sCAL unit");
341
 
376
 
Line 342... Line 377...
342
   if (swidth == NULL || (lengthw = png_strlen(swidth)) <= 0 ||
377
   if (swidth == NULL || (lengthw = strlen(swidth)) == 0 ||
343
       swidth[0] == 45 /*'-'*/ || !png_check_fp_string(swidth, lengthw))
378
       swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw))
344
      png_error(png_ptr, "Invalid sCAL width");
379
      png_error(png_ptr, "Invalid sCAL width");
Line 345... Line 380...
345
 
380
 
346
   if (sheight == NULL || (lengthh = png_strlen(sheight)) <= 0 ||
381
   if (sheight == NULL || (lengthh = strlen(sheight)) == 0 ||
347
       sheight[0] == 45 /*'-'*/ || !png_check_fp_string(sheight, lengthh))
382
       sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh))
Line 348... Line 383...
348
      png_error(png_ptr, "Invalid sCAL height");
383
      png_error(png_ptr, "Invalid sCAL height");
Line 349... Line 384...
349
 
384
 
Line 350... Line 385...
350
   info_ptr->scal_unit = (png_byte)unit;
385
   info_ptr->scal_unit = (png_byte)unit;
Line 351... Line 386...
351
 
386
 
-
 
387
   ++lengthw;
Line 352... Line 388...
352
   ++lengthw;
388
 
353
 
389
   png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw);
354
   png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw);
390
 
355
 
391
   info_ptr->scal_s_width = png_voidcast(png_charp,
356
   info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, lengthw);
392
      png_malloc_warn(png_ptr, lengthw));
Line 357... Line 393...
357
 
393
 
Line 358... Line 394...
358
   if (info_ptr->scal_s_width == NULL)
394
   if (info_ptr->scal_s_width == NULL)
Line 359... Line 395...
359
   {
395
   {
Line 360... Line 396...
360
      png_warning(png_ptr, "Memory allocation failed while processing sCAL");
396
      png_warning(png_ptr, "Memory allocation failed while processing sCAL");
-
 
397
      return;
Line 361... Line 398...
361
      return;
398
   }
362
   }
399
 
363
 
400
   memcpy(info_ptr->scal_s_width, swidth, lengthw);
364
   png_memcpy(info_ptr->scal_s_width, swidth, lengthw);
401
 
Line 365... Line 402...
365
 
402
   ++lengthh;
366
   ++lengthh;
403
 
367
 
404
   png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh);
Line 368... Line 405...
368
   png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh);
405
 
Line 369... Line 406...
369
 
406
   info_ptr->scal_s_height = png_voidcast(png_charp,
370
   info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, lengthh);
407
      png_malloc_warn(png_ptr, lengthh));
371
 
408
 
Line 372... Line 409...
372
   if (info_ptr->scal_s_height == NULL)
409
   if (info_ptr->scal_s_height == NULL)
373
   {
410
   {
374
      png_free (png_ptr, info_ptr->scal_s_width);
411
      png_free (png_ptr, info_ptr->scal_s_width);
375
      info_ptr->scal_s_width = NULL;
412
      info_ptr->scal_s_width = NULL;
376
 
413
 
377
      png_warning(png_ptr, "Memory allocation failed while processing sCAL");
414
      png_warning(png_ptr, "Memory allocation failed while processing sCAL");
Line 378... Line 415...
378
      return;
415
      return;
379
   }
416
   }
Line 403... Line 440...
403
      /* Convert 'width' and 'height' to ASCII. */
440
      /* Convert 'width' and 'height' to ASCII. */
404
      char swidth[PNG_sCAL_MAX_DIGITS+1];
441
      char swidth[PNG_sCAL_MAX_DIGITS+1];
405
      char sheight[PNG_sCAL_MAX_DIGITS+1];
442
      char sheight[PNG_sCAL_MAX_DIGITS+1];
406
 
443
 
Line 407... Line 444...
407
      png_ascii_from_fp(png_ptr, swidth, sizeof swidth, width,
444
      png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width,
408
         PNG_sCAL_PRECISION);
445
         PNG_sCAL_PRECISION);
409
      png_ascii_from_fp(png_ptr, sheight, sizeof sheight, height,
446
      png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height,
410
         PNG_sCAL_PRECISION);
447
         PNG_sCAL_PRECISION);
Line 411... Line 448...
411
 
448
 
412
      png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
449
      png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
413
   }
450
   }
414
}
451
}
Line 415... Line 452...
415
#  endif
452
#  endif
416
 
453
 
417
#  ifdef PNG_FIXED_POINT_SUPPORTED
454
#  ifdef PNG_FIXED_POINT_SUPPORTED
418
void PNGAPI
455
void PNGAPI
419
png_set_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, int unit,
456
png_set_sCAL_fixed(png_const_structrp png_ptr, png_inforp info_ptr, int unit,
420
    png_fixed_point width, png_fixed_point height)
457
    png_fixed_point width, png_fixed_point height)
Line 421... Line 458...
421
{
458
{
Line 433... Line 470...
433
      /* Convert 'width' and 'height' to ASCII. */
470
      /* Convert 'width' and 'height' to ASCII. */
434
      char swidth[PNG_sCAL_MAX_DIGITS+1];
471
      char swidth[PNG_sCAL_MAX_DIGITS+1];
435
      char sheight[PNG_sCAL_MAX_DIGITS+1];
472
      char sheight[PNG_sCAL_MAX_DIGITS+1];
436
 
473
 
Line 437... Line 474...
437
      png_ascii_from_fixed(png_ptr, swidth, sizeof swidth, width);
474
      png_ascii_from_fixed(png_ptr, swidth, (sizeof swidth), width);
438
      png_ascii_from_fixed(png_ptr, sheight, sizeof sheight, height);
475
      png_ascii_from_fixed(png_ptr, sheight, (sizeof sheight), height);
Line 439... Line 476...
439
 
476
 
440
      png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
477
      png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
441
   }
478
   }
442
}
479
}
443
#  endif
480
#  endif
Line 444... Line 481...
444
#endif
481
#endif
445
 
482
 
446
#ifdef PNG_pHYs_SUPPORTED
483
#ifdef PNG_pHYs_SUPPORTED
447
void PNGAPI
484
void PNGAPI
448
png_set_pHYs(png_structp png_ptr, png_infop info_ptr,
485
png_set_pHYs(png_const_structrp png_ptr, png_inforp info_ptr,
449
    png_uint_32 res_x, png_uint_32 res_y, int unit_type)
486
    png_uint_32 res_x, png_uint_32 res_y, int unit_type)
Line 450... Line 487...
450
{
487
{
Line 460... Line 497...
460
}
497
}
461
#endif
498
#endif
462
 
499
 
Line 463... Line 500...
463
void PNGAPI
500
void PNGAPI
464
png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
501
png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr,
465
    png_const_colorp palette, int num_palette)
502
    png_const_colorp palette, int num_palette)
466
{
503
{
Line 467... Line 504...
467
 
504
 
Line 481... Line 518...
481
         return;
518
         return;
482
      }
519
      }
483
   }
520
   }
484
 
521
 
Line -... Line 522...
-
 
522
   if ((num_palette > 0 && palette == NULL) ||
-
 
523
      (num_palette == 0
-
 
524
#        ifdef PNG_MNG_FEATURES_SUPPORTED
-
 
525
            && (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0
-
 
526
#        endif
-
 
527
      ))
-
 
528
   {
-
 
529
      png_chunk_report(png_ptr, "Invalid palette", PNG_CHUNK_ERROR);
-
 
530
      return;
-
 
531
   }
-
 
532
 
485
   /* It may not actually be necessary to set png_ptr->palette here;
533
   /* It may not actually be necessary to set png_ptr->palette here;
486
    * we do it for backward compatibility with the way the png_handle_tRNS
534
    * we do it for backward compatibility with the way the png_handle_tRNS
487
    * function used to do the allocation.
535
    * function used to do the allocation.
-
 
536
    *
-
 
537
    * 1.6.0: the above statement appears to be incorrect; something has to set
-
 
538
    * the palette inside png_struct on read.
488
    */
539
    */
489
   png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
540
   png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
Line 490... Line 541...
490
 
541
 
491
   /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
542
   /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
492
    * of num_palette entries, in case of an invalid PNG file that has
543
    * of num_palette entries, in case of an invalid PNG file that has
493
    * too-large sample values.
544
    * too-large sample values.
494
    */
545
    */
495
   png_ptr->palette = (png_colorp)png_calloc(png_ptr,
546
   png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr,
Line -... Line 547...
-
 
547
       PNG_MAX_PALETTE_LENGTH * (sizeof (png_color))));
496
       PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color));
548
 
497
 
549
   if (num_palette > 0)
498
   png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof(png_color));
550
      memcpy(png_ptr->palette, palette, num_palette * (sizeof (png_color)));
Line 499... Line 551...
499
   info_ptr->palette = png_ptr->palette;
551
   info_ptr->palette = png_ptr->palette;
Line 500... Line 552...
500
   info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
552
   info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
501
 
553
 
Line 502... Line 554...
502
   info_ptr->free_me |= PNG_FREE_PLTE;
554
   info_ptr->free_me |= PNG_FREE_PLTE;
503
 
555
 
504
   info_ptr->valid |= PNG_INFO_PLTE;
556
   info_ptr->valid |= PNG_INFO_PLTE;
505
}
557
}
506
 
558
 
507
#ifdef PNG_sBIT_SUPPORTED
559
#ifdef PNG_sBIT_SUPPORTED
Line 508... Line 560...
508
void PNGAPI
560
void PNGAPI
509
png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
561
png_set_sBIT(png_const_structrp png_ptr, png_inforp info_ptr,
Line 510... Line 562...
510
    png_const_color_8p sig_bit)
562
    png_const_color_8p sig_bit)
511
{
563
{
512
   png_debug1(1, "in %s storage function", "sBIT");
564
   png_debug1(1, "in %s storage function", "sBIT");
513
 
565
 
Line 514... Line 566...
514
   if (png_ptr == NULL || info_ptr == NULL)
566
   if (png_ptr == NULL || info_ptr == NULL || sig_bit == NULL)
515
      return;
567
      return;
516
 
568
 
517
   png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof(png_color_8));
569
   info_ptr->sig_bit = *sig_bit;
518
   info_ptr->valid |= PNG_INFO_sBIT;
570
   info_ptr->valid |= PNG_INFO_sBIT;
Line 519... Line 571...
519
}
571
}
520
#endif
572
#endif
Line 521... Line 573...
521
 
573
 
522
#ifdef PNG_sRGB_SUPPORTED
574
#ifdef PNG_sRGB_SUPPORTED
523
void PNGAPI
575
void PNGAPI
Line 524... Line 576...
524
png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int srgb_intent)
576
png_set_sRGB(png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent)
525
{
577
{
526
   png_debug1(1, "in %s storage function", "sRGB");
578
   png_debug1(1, "in %s storage function", "sRGB");
527
 
579
 
528
   if (png_ptr == NULL || info_ptr == NULL)
580
   if (png_ptr == NULL || info_ptr == NULL)
Line 529... Line 581...
529
      return;
581
      return;
530
 
582
 
Line 531... Line 583...
531
   info_ptr->srgb_intent = (png_byte)srgb_intent;
583
   (void)png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent);
532
   info_ptr->valid |= PNG_INFO_sRGB;
584
   png_colorspace_sync_info(png_ptr, info_ptr);
-
 
585
}
533
}
586
 
534
 
587
void PNGAPI
535
void PNGAPI
588
png_set_sRGB_gAMA_and_cHRM(png_const_structrp png_ptr, png_inforp info_ptr,
Line 536... Line -...
536
png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
-
 
537
    int srgb_intent)
589
    int srgb_intent)
538
{
-
 
539
   png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM");
-
 
540
 
-
 
541
   if (png_ptr == NULL || info_ptr == NULL)
-
 
542
      return;
-
 
543
 
-
 
544
   png_set_sRGB(png_ptr, info_ptr, srgb_intent);
-
 
545
 
590
{
546
#  ifdef PNG_gAMA_SUPPORTED
591
   png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM");
Line 547... Line 592...
547
   png_set_gAMA_fixed(png_ptr, info_ptr, 45455L);
592
 
548
#  endif
593
   if (png_ptr == NULL || info_ptr == NULL)
549
 
594
      return;
550
#  ifdef PNG_cHRM_SUPPORTED
595
 
551
   png_set_cHRM_fixed(png_ptr, info_ptr,
596
   if (png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent))
552
      /* color      x       y */
597
   {
553
      /* white */ 31270L, 32900L,
598
      /* This causes the gAMA and cHRM to be written too */
554
      /* red   */ 64000L, 33000L,
599
      info_ptr->colorspace.flags |=
555
      /* green */ 30000L, 60000L,
600
         PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM;
Line 556... Line 601...
556
      /* blue  */ 15000L,  6000L
601
   }
Line 557... Line 602...
557
   );
602
 
558
#  endif /* cHRM */
603
   png_colorspace_sync_info(png_ptr, info_ptr);
Line -... Line 604...
-
 
604
}
-
 
605
#endif /* sRGB */
-
 
606
 
-
 
607
 
-
 
608
#ifdef PNG_iCCP_SUPPORTED
-
 
609
void PNGAPI
-
 
610
png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
-
 
611
    png_const_charp name, int compression_type,
-
 
612
    png_const_bytep profile, png_uint_32 proflen)
-
 
613
{
-
 
614
   png_charp new_iccp_name;
-
 
615
   png_bytep new_iccp_profile;
-
 
616
   png_size_t length;
-
 
617
 
-
 
618
   png_debug1(1, "in %s storage function", "iCCP");
-
 
619
 
-
 
620
   if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
-
 
621
      return;
-
 
622
 
-
 
623
   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
-
 
624
      png_app_error(png_ptr, "Invalid iCCP compression method");
-
 
625
 
-
 
626
   /* Set the colorspace first because this validates the profile; do not
-
 
627
    * override previously set app cHRM or gAMA here (because likely as not the
559
}
628
    * application knows better than libpng what the correct values are.)  Pass
560
#endif /* sRGB */
629
    * the info_ptr color_type field to png_colorspace_set_ICC because in the
Line 561... Line 630...
561
 
630
    * write case it has not yet been stored in png_ptr.
562
 
631
    */
563
#ifdef PNG_iCCP_SUPPORTED
632
   {
564
void PNGAPI
633
      int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name,
565
png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
634
         proflen, profile, info_ptr->color_type);
Line 566... Line 635...
566
    png_const_charp name, int compression_type,
635
 
-
 
636
      png_colorspace_sync_info(png_ptr, info_ptr);
567
    png_const_bytep profile, png_uint_32 proflen)
637
 
Line 568... Line 638...
568
{
638
      /* Don't do any of the copying if the profile was bad, or inconsistent. */
569
   png_charp new_iccp_name;
639
      if (!result)
570
   png_bytep new_iccp_profile;
640
         return;
571
   png_uint_32 length;
641
 
572
 
642
      /* But do write the gAMA and cHRM chunks from the profile. */
573
   png_debug1(1, "in %s storage function", "iCCP");
643
      info_ptr->colorspace.flags |=
574
 
644
         PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM;
Line 575... Line 645...
575
   if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
645
   }
Line 576... Line 646...
576
      return;
646
 
Line 577... Line 647...
577
 
647
   length = strlen(name)+1;
578
   length = png_strlen(name)+1;
648
   new_iccp_name = png_voidcast(png_charp, png_malloc_warn(png_ptr, length));
579
   new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length);
649
 
580
 
-
 
581
   if (new_iccp_name == NULL)
-
 
582
   {
-
 
583
        png_warning(png_ptr, "Insufficient memory to process iCCP chunk");
-
 
584
      return;
650
   if (new_iccp_name == NULL)
585
   }
651
   {
586
 
652
      png_benign_error(png_ptr, "Insufficient memory to process iCCP chunk");
587
   png_memcpy(new_iccp_name, name, length);
653
      return;
Line 588... Line 654...
588
   new_iccp_profile = (png_bytep)png_malloc_warn(png_ptr, proflen);
654
   }
589
 
655
 
590
   if (new_iccp_profile == NULL)
656
   memcpy(new_iccp_name, name, length);
591
   {
657
   new_iccp_profile = png_voidcast(png_bytep,
592
      png_free (png_ptr, new_iccp_name);
658
      png_malloc_warn(png_ptr, proflen));
593
      png_warning(png_ptr,
659
 
594
          "Insufficient memory to process iCCP profile");
660
   if (new_iccp_profile == NULL)
Line 595... Line 661...
595
      return;
661
   {
596
   }
662
      png_free(png_ptr, new_iccp_name);
597
 
663
      png_benign_error(png_ptr,
Line 598... Line 664...
598
   png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);
664
          "Insufficient memory to process iCCP profile");
599
 
665
      return;
600
   png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
666
   }
601
 
667
 
602
   info_ptr->iccp_proflen = proflen;
668
   memcpy(new_iccp_profile, profile, proflen);
Line 603... Line 669...
603
   info_ptr->iccp_name = new_iccp_name;
669
 
604
   info_ptr->iccp_profile = new_iccp_profile;
-
 
605
   /* Compression is always zero but is here so the API and info structure
670
   png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
Line 606... Line 671...
606
    * does not have to change if we introduce multiple compression types
671
 
607
    */
672
   info_ptr->iccp_proflen = proflen;
Line 608... Line 673...
608
   info_ptr->iccp_compression = (png_byte)compression_type;
673
   info_ptr->iccp_name = new_iccp_name;
609
   info_ptr->free_me |= PNG_FREE_ICCP;
674
   info_ptr->iccp_profile = new_iccp_profile;
-
 
675
   info_ptr->free_me |= PNG_FREE_ICCP;
-
 
676
   info_ptr->valid |= PNG_INFO_iCCP;
610
   info_ptr->valid |= PNG_INFO_iCCP;
677
}
611
}
678
#endif
612
#endif
679
 
-
 
680
#ifdef PNG_TEXT_SUPPORTED
-
 
681
void PNGAPI
613
 
682
png_set_text(png_const_structrp png_ptr, png_inforp info_ptr,
-
 
683
    png_const_textp text_ptr, int num_text)
-
 
684
{
-
 
685
   int ret;
-
 
686
   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
614
#ifdef PNG_TEXT_SUPPORTED
687
 
615
void PNGAPI
688
   if (ret)
616
png_set_text(png_structp png_ptr, png_infop info_ptr, png_const_textp text_ptr,
-
 
Line 617... Line 689...
617
    int num_text)
689
      png_error(png_ptr, "Insufficient memory to store text");
618
{
-
 
619
   int ret;
690
}
620
   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
691
 
621
 
-
 
Line 622... Line -...
622
   if (ret)
-
 
623
      png_error(png_ptr, "Insufficient memory to store text");
692
int /* PRIVATE */
624
}
-
 
625
 
693
png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
626
int /* PRIVATE */
-
 
Line 627... Line 694...
627
png_set_text_2(png_structp png_ptr, png_infop info_ptr,
694
    png_const_textp text_ptr, int num_text)
628
    png_const_textp text_ptr, int num_text)
695
{
-
 
696
   int i;
-
 
697
 
-
 
698
   png_debug1(1, "in %lx storage function", png_ptr == NULL ? "unexpected" :
629
{
699
      (unsigned long)png_ptr->chunk_name);
630
   int i;
700
 
Line 631... Line 701...
631
 
701
   if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL)
632
   png_debug1(1, "in %s storage function", ((png_ptr == NULL ||
702
      return(0);
633
       png_ptr->chunk_name[0] == '\0') ?
-
 
634
       "text" : (png_const_charp)png_ptr->chunk_name));
-
 
635
 
703
 
636
   if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
-
 
637
      return(0);
704
   /* Make sure we have enough space in the "text" array in info_struct
638
 
705
    * to hold all of the incoming text_ptr objects.  This compare can't overflow
639
   /* Make sure we have enough space in the "text" array in info_struct
-
 
640
    * to hold all of the incoming text_ptr objects.
706
    * because max_text >= num_text (anyway, subtract of two positive integers
Line 641... Line 707...
641
    */
707
    * can't overflow in any case.)
-
 
708
    */
642
   if (info_ptr->num_text + num_text > info_ptr->max_text)
709
   if (num_text > info_ptr->max_text - info_ptr->num_text)
-
 
710
   {
-
 
711
      int old_num_text = info_ptr->num_text;
-
 
712
      int max_text;
-
 
713
      png_textp new_text = NULL;
-
 
714
 
643
   {
715
      /* Calculate an appropriate max_text, checking for overflow. */
-
 
716
      max_text = old_num_text;
644
      if (info_ptr->text != NULL)
717
      if (num_text <= INT_MAX - max_text)
645
      {
718
      {
646
         png_textp old_text;
719
         max_text += num_text;
647
         int old_max;
720
 
648
 
721
         /* Round up to a multiple of 8 */
Line 649... Line 722...
649
         old_max = info_ptr->max_text;
722
         if (max_text < INT_MAX-8)
650
         info_ptr->max_text = info_ptr->num_text + num_text + 8;
723
            max_text = (max_text + 8) & ~0x7;
Line 651... Line 724...
651
         old_text = info_ptr->text;
724
 
652
         info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
725
         else
653
            (png_size_t)(info_ptr->max_text * png_sizeof(png_text)));
726
            max_text = INT_MAX;
654
 
727
 
-
 
728
         /* Now allocate a new array and copy the old members in, this does all
655
         if (info_ptr->text == NULL)
729
          * the overflow checks.
656
         {
730
          */
Line 657... Line 731...
657
            png_free(png_ptr, old_text);
731
         new_text = png_voidcast(png_textp,png_realloc_array(png_ptr,
Line 658... Line 732...
658
            return(1);
732
            info_ptr->text, old_num_text, max_text-old_num_text,
659
         }
733
            sizeof *new_text));
660
 
734
      }
661
         png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
735
 
Line 706... Line 780...
706
      {
780
      {
707
         /* Set iTXt data */
781
         /* Set iTXt data */
708
 
782
 
Line 709... Line 783...
709
         if (text_ptr[i].lang != NULL)
783
         if (text_ptr[i].lang != NULL)
710
            lang_len = png_strlen(text_ptr[i].lang);
784
            lang_len = strlen(text_ptr[i].lang);
Line 711... Line 785...
711
 
785
 
712
         else
786
         else
Line 713... Line 787...
713
            lang_len = 0;
787
            lang_len = 0;
714
 
788
 
Line 715... Line 789...
715
         if (text_ptr[i].lang_key != NULL)
789
         if (text_ptr[i].lang_key != NULL)
716
            lang_key_len = png_strlen(text_ptr[i].lang_key);
790
            lang_key_len = strlen(text_ptr[i].lang_key);
717
 
791
 
718
         else
792
         else
719
            lang_key_len = 0;
793
            lang_key_len = 0;
720
      }
794
      }
-
 
795
#  else /* PNG_iTXt_SUPPORTED */
721
#  else /* PNG_iTXt_SUPPORTED */
796
      {
722
      {
797
         png_chunk_report(png_ptr, "iTXt chunk not supported",
723
         png_warning(png_ptr, "iTXt chunk not supported");
798
            PNG_CHUNK_WRITE_ERROR);
Line 724... Line 799...
724
         continue;
799
         continue;
Line 738... Line 813...
738
      }
813
      }
739
 
814
 
Line 740... Line 815...
740
      else
815
      else
741
      {
816
      {
742
         text_length = png_strlen(text_ptr[i].text);
817
         text_length = strlen(text_ptr[i].text);
743
         textp->compression = text_ptr[i].compression;
818
         textp->compression = text_ptr[i].compression;
744
      }
819
      }
Line 745... Line 820...
745
 
820
 
746
      textp->key = (png_charp)png_malloc_warn(png_ptr,
-
 
747
          (png_size_t)
821
      textp->key = png_voidcast(png_charp,png_malloc_base(png_ptr,
Line 748... Line 822...
748
          (key_len + text_length + lang_len + lang_key_len + 4));
822
          key_len + text_length + lang_len + lang_key_len + 4));
-
 
823
 
-
 
824
      if (textp->key == NULL)
-
 
825
      {
749
 
826
         png_chunk_report(png_ptr, "text chunk: out of memory",
-
 
827
               PNG_CHUNK_WRITE_ERROR);
Line 750... Line 828...
750
      if (textp->key == NULL)
828
         return 1;
751
         return(1);
829
      }
752
 
830
 
753
      png_debug2(2, "Allocated %lu bytes at %p in png_set_text",
831
      png_debug2(2, "Allocated %lu bytes at %p in png_set_text",
Line 754... Line 832...
754
          (unsigned long)(png_uint_32)
832
          (unsigned long)(png_uint_32)
755
          (key_len + lang_len + lang_key_len + text_length + 4),
833
          (key_len + lang_len + lang_key_len + text_length + 4),
Line 756... Line 834...
756
          textp->key);
834
          textp->key);
757
 
835
 
758
      png_memcpy(textp->key, text_ptr[i].key,(png_size_t)(key_len));
836
      memcpy(textp->key, text_ptr[i].key, key_len);
759
      *(textp->key + key_len) = '\0';
837
      *(textp->key + key_len) = '\0';
760
 
838
 
761
      if (text_ptr[i].compression > 0)
839
      if (text_ptr[i].compression > 0)
762
      {
840
      {
763
         textp->lang = textp->key + key_len + 1;
841
         textp->lang = textp->key + key_len + 1;
764
         png_memcpy(textp->lang, text_ptr[i].lang, lang_len);
842
         memcpy(textp->lang, text_ptr[i].lang, lang_len);
765
         *(textp->lang + lang_len) = '\0';
843
         *(textp->lang + lang_len) = '\0';
Line 766... Line 844...
766
         textp->lang_key = textp->lang + lang_len + 1;
844
         textp->lang_key = textp->lang + lang_len + 1;
Line 776... Line 854...
776
         textp->text = textp->key + key_len + 1;
854
         textp->text = textp->key + key_len + 1;
777
      }
855
      }
778
 
856
 
Line 779... Line 857...
779
      if (text_length)
857
      if (text_length)
780
         png_memcpy(textp->text, text_ptr[i].text,
858
         memcpy(textp->text, text_ptr[i].text, text_length);
781
             (png_size_t)(text_length));
-
 
Line 782... Line 859...
782
 
859
 
Line 783... Line 860...
783
      *(textp->text + text_length) = '\0';
860
      *(textp->text + text_length) = '\0';
784
 
861
 
Line 798... Line 875...
798
 
875
 
Line 799... Line 876...
799
      info_ptr->num_text++;
876
      info_ptr->num_text++;
800
      png_debug1(3, "transferred text chunk %d", info_ptr->num_text);
877
      png_debug1(3, "transferred text chunk %d", info_ptr->num_text);
801
   }
878
   }
-
 
879
 
802
   return(0);
880
   return(0);
803
}
881
}
804
#endif
882
#endif
Line 805... Line 883...
805
 
883
 
806
#ifdef PNG_tIME_SUPPORTED
884
#ifdef PNG_tIME_SUPPORTED
807
void PNGAPI
885
void PNGAPI
-
 
886
png_set_tIME(png_const_structrp png_ptr, png_inforp info_ptr,
808
png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time)
887
    png_const_timep mod_time)
809
{
888
{
Line 810... Line 889...
810
   png_debug1(1, "in %s storage function", "tIME");
889
   png_debug1(1, "in %s storage function", "tIME");
811
 
890
 
812
   if (png_ptr == NULL || info_ptr == NULL ||
891
   if (png_ptr == NULL || info_ptr == NULL || mod_time == NULL ||
Line -... Line 892...
-
 
892
       (png_ptr->mode & PNG_WROTE_tIME))
-
 
893
      return;
-
 
894
 
-
 
895
   if (mod_time->month == 0   || mod_time->month > 12  ||
-
 
896
       mod_time->day   == 0   || mod_time->day   > 31  ||
-
 
897
       mod_time->hour  > 23   || mod_time->minute > 59 ||
-
 
898
       mod_time->second > 60)
-
 
899
   {
-
 
900
      png_warning(png_ptr, "Ignoring invalid time value");
813
       (png_ptr->mode & PNG_WROTE_tIME))
901
      return;
814
      return;
902
   }
815
 
903
 
816
   png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof(png_time));
904
   info_ptr->mod_time = *mod_time;
Line 817... Line 905...
817
   info_ptr->valid |= PNG_INFO_tIME;
905
   info_ptr->valid |= PNG_INFO_tIME;
818
}
906
}
819
#endif
907
#endif
820
 
908
 
821
#ifdef PNG_tRNS_SUPPORTED
909
#ifdef PNG_tRNS_SUPPORTED
822
void PNGAPI
910
void PNGAPI
Line 823... Line 911...
823
png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
911
png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr,
Line 832... Line 920...
832
   {
920
   {
833
       /* It may not actually be necessary to set png_ptr->trans_alpha here;
921
       /* It may not actually be necessary to set png_ptr->trans_alpha here;
834
        * we do it for backward compatibility with the way the png_handle_tRNS
922
        * we do it for backward compatibility with the way the png_handle_tRNS
835
        * function used to do the allocation.
923
        * function used to do the allocation.
836
        */
924
        *
-
 
925
        * 1.6.0: The above statement is incorrect; png_handle_tRNS effectively
-
 
926
        * relies on png_set_tRNS storing the information in png_struct
-
 
927
        * (otherwise it won't be there for the code in pngrtran.c).
-
 
928
        */
837
 
929
 
Line 838... Line 930...
838
       png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
930
       png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
Line 839... Line 931...
839
 
931
 
840
       /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
932
       /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
841
       png_ptr->trans_alpha = info_ptr->trans_alpha =
933
       png_ptr->trans_alpha = info_ptr->trans_alpha = png_voidcast(png_bytep,
Line 842... Line 934...
842
           (png_bytep)png_malloc(png_ptr, (png_size_t)PNG_MAX_PALETTE_LENGTH);
934
         png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
843
 
935
 
844
       if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
936
       if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
Line 845... Line 937...
845
          png_memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans);
937
          memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans);
846
   }
938
   }
847
 
939
 
Line 848... Line 940...
848
   if (trans_color != NULL)
940
   if (trans_color != NULL)
849
   {
941
   {
850
      int sample_max = (1 << info_ptr->bit_depth);
942
      int sample_max = (1 << info_ptr->bit_depth);
851
 
943
 
852
      if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
944
      if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
853
          (int)trans_color->gray > sample_max) ||
945
          trans_color->gray > sample_max) ||
854
          (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
946
          (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
855
          ((int)trans_color->red > sample_max ||
947
          (trans_color->red > sample_max ||
Line 856... Line 948...
856
          (int)trans_color->green > sample_max ||
948
          trans_color->green > sample_max ||
857
          (int)trans_color->blue > sample_max)))
-
 
Line 858... Line 949...
858
         png_warning(png_ptr,
949
          trans_color->blue > sample_max)))
859
            "tRNS chunk has out-of-range samples for bit_depth");
950
         png_warning(png_ptr,
860
 
951
            "tRNS chunk has out-of-range samples for bit_depth");
Line 876... Line 967...
876
#endif
967
#endif
877
 
968
 
Line 878... Line 969...
878
#ifdef PNG_sPLT_SUPPORTED
969
#ifdef PNG_sPLT_SUPPORTED
879
void PNGAPI
970
void PNGAPI
880
png_set_sPLT(png_structp png_ptr,
971
png_set_sPLT(png_const_structrp png_ptr,
881
    png_infop info_ptr, png_const_sPLT_tp entries, int nentries)
972
    png_inforp info_ptr, png_const_sPLT_tp entries, int nentries)
882
/*
973
/*
883
 *  entries        - array of png_sPLT_t structures
974
 *  entries        - array of png_sPLT_t structures
884
 *                   to be added to the list of palettes
975
 *                   to be added to the list of palettes
885
 *                   in the info structure.
976
 *                   in the info structure.
886
 *
977
 *
887
 *  nentries       - number of palette structures to be
978
 *  nentries       - number of palette structures to be
888
 *                   added.
979
 *                   added.
889
 */
980
 */
890
{
981
{
891
   png_sPLT_tp np;
982
   png_sPLT_tp np;
892
   int i;
-
 
Line 893... Line 983...
893
 
983
 
894
   if (png_ptr == NULL || info_ptr == NULL)
984
   if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL)
Line -... Line 985...
-
 
985
      return;
-
 
986
 
-
 
987
   /* Use the internal realloc function, which checks for all the possible
895
      return;
988
    * overflows.  Notice that the parameters are (int) and (size_t)
896
 
989
    */
897
   np = (png_sPLT_tp)png_malloc_warn(png_ptr,
990
   np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr,
Line 898... Line 991...
898
       (info_ptr->splt_palettes_num + nentries) *
991
      info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries,
899
       (png_size_t)png_sizeof(png_sPLT_t));
992
      sizeof *np));
-
 
993
 
900
 
994
   if (np == NULL)
901
   if (np == NULL)
995
   {
902
   {
996
      /* Out of memory or too many chunks */
Line 903... Line -...
903
      png_warning(png_ptr, "No memory for sPLT palettes");
-
 
904
      return;
-
 
905
   }
-
 
906
 
997
      png_chunk_report(png_ptr, "too many sPLT chunks", PNG_CHUNK_WRITE_ERROR);
907
   png_memcpy(np, info_ptr->splt_palettes,
998
      return;
-
 
999
   }
Line 908... Line -...
908
       info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t));
-
 
909
 
-
 
910
   png_free(png_ptr, info_ptr->splt_palettes);
1000
 
911
   info_ptr->splt_palettes=NULL;
-
 
912
 
-
 
Line -... Line 1001...
-
 
1001
   png_free(png_ptr, info_ptr->splt_palettes);
-
 
1002
   info_ptr->splt_palettes = np;
913
   for (i = 0; i < nentries; i++)
1003
   info_ptr->free_me |= PNG_FREE_SPLT;
914
   {
-
 
Line -... Line 1004...
-
 
1004
 
915
      png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
1005
   np += info_ptr->splt_palettes_num;
916
      png_const_sPLT_tp from = entries + i;
1006
 
-
 
1007
   do
917
      png_uint_32 length;
1008
   {
918
 
1009
      png_size_t length;
919
      length = png_strlen(from->name) + 1;
1010
 
920
      to->name = (png_charp)png_malloc_warn(png_ptr, (png_size_t)length);
1011
      /* Skip invalid input entries */
Line -... Line 1012...
-
 
1012
      if (entries->name == NULL || entries->entries == NULL)
-
 
1013
      {
-
 
1014
         /* png_handle_sPLT doesn't do this, so this is an app error */
-
 
1015
         png_app_error(png_ptr, "png_set_sPLT: invalid sPLT");
-
 
1016
         /* Just skip the invalid entry */
-
 
1017
         continue;
-
 
1018
      }
-
 
1019
 
-
 
1020
      np->depth = entries->depth;
-
 
1021
 
-
 
1022
      /* In the even of out-of-memory just return - there's no point keeping on
921
 
1023
       * trying to add sPLT chunks.
-
 
1024
       */
-
 
1025
      length = strlen(entries->name) + 1;
-
 
1026
      np->name = png_voidcast(png_charp, png_malloc_base(png_ptr, length));
-
 
1027
 
-
 
1028
      if (np->name == NULL)
922
      if (to->name == NULL)
1029
         break;
923
      {
1030
 
Line 924... Line 1031...
924
         png_warning(png_ptr,
1031
      memcpy(np->name, entries->name, length);
925
             "Out of memory while processing sPLT chunk");
1032
 
926
         continue;
-
 
927
      }
-
 
928
 
1033
      /* IMPORTANT: we have memory now that won't get freed if something else
929
      png_memcpy(to->name, from->name, length);
-
 
930
      to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr,
1034
       * goes wrong, this code must free it.  png_malloc_array produces no
931
          (png_size_t)(from->nentries * png_sizeof(png_sPLT_entry)));
1035
       * warnings, use a png_chunk_report (below) if there is an error.
Line -... Line 1036...
-
 
1036
       */
-
 
1037
      np->entries = png_voidcast(png_sPLT_entryp, png_malloc_array(png_ptr,
-
 
1038
          entries->nentries, sizeof (png_sPLT_entry)));
-
 
1039
 
932
 
1040
      if (np->entries == NULL)
933
      if (to->entries == NULL)
1041
      {
Line -... Line 1042...
-
 
1042
         png_free(png_ptr, np->name);
934
      {
1043
         break;
-
 
1044
      }
935
         png_warning(png_ptr,
1045
 
-
 
1046
      np->nentries = entries->nentries;
-
 
1047
      /* This multiply can't overflow because png_malloc_array has already
936
             "Out of memory while processing sPLT chunk");
1048
       * checked it when doing the allocation.
-
 
1049
       */
Line 937... Line 1050...
937
         png_free(png_ptr, to->name);
1050
      memcpy(np->entries, entries->entries,
938
         to->name = NULL;
-
 
939
         continue;
-
 
940
      }
1051
         entries->nentries * sizeof (png_sPLT_entry));
941
 
1052
 
942
      png_memcpy(to->entries, from->entries,
1053
      /* Note that 'continue' skips the advance of the out pointer and out
Line 943... Line 1054...
943
          from->nentries * png_sizeof(png_sPLT_entry));
1054
       * count, so an invalid entry is not added.
-
 
1055
       */
-
 
1056
      info_ptr->valid |= PNG_INFO_sPLT;
-
 
1057
      ++(info_ptr->splt_palettes_num);
-
 
1058
      ++np;
-
 
1059
   }
-
 
1060
   while (++entries, --nentries);
-
 
1061
 
-
 
1062
   if (nentries > 0)
-
 
1063
      png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR);
-
 
1064
}
-
 
1065
#endif /* PNG_sPLT_SUPPORTED */
-
 
1066
 
-
 
1067
#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
-
 
1068
static png_byte
-
 
1069
check_location(png_const_structrp png_ptr, int location)
-
 
1070
{
-
 
1071
   location &= (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT);
-
 
1072
 
-
 
1073
   /* New in 1.6.0; copy the location and check it.  This is an API
-
 
1074
    * change, previously the app had to use the
-
 
1075
    * png_set_unknown_chunk_location API below for each chunk.
-
 
1076
    */
-
 
1077
   if (location == 0 && !(png_ptr->mode & PNG_IS_READ_STRUCT))
-
 
1078
   {
-
 
1079
      /* Write struct, so unknown chunks come from the app */
-
 
1080
      png_app_warning(png_ptr,
-
 
1081
         "png_set_unknown_chunks now expects a valid location");
-
 
1082
      /* Use the old behavior */
-
 
1083
      location = (png_byte)(png_ptr->mode &
-
 
1084
         (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT));
-
 
1085
   }
-
 
1086
 
-
 
1087
   /* This need not be an internal error - if the app calls
-
 
1088
    * png_set_unknown_chunks on a read pointer it must get the location right.
-
 
1089
    */
-
 
1090
   if (location == 0)
-
 
1091
      png_error(png_ptr, "invalid location in png_set_unknown_chunks");
944
 
1092
 
945
      to->nentries = from->nentries;
1093
   /* Now reduce the location to the top-most set bit by removing each least
946
      to->depth = from->depth;
1094
    * significant bit in turn.
947
   }
1095
    */
948
 
1096
   while (location != (location & -location))
949
   info_ptr->splt_palettes = np;
-
 
Line 950... Line 1097...
950
   info_ptr->splt_palettes_num += nentries;
1097
      location &= ~(location & -location);
-
 
1098
 
951
   info_ptr->valid |= PNG_INFO_sPLT;
1099
   /* The cast is safe because 'location' is a bit mask and only the low four
Line -... Line 1100...
-
 
1100
    * bits are significant.
-
 
1101
    */
-
 
1102
   return (png_byte)location;
-
 
1103
}
-
 
1104
 
-
 
1105
void PNGAPI
-
 
1106
png_set_unknown_chunks(png_const_structrp png_ptr,
-
 
1107
   png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
-
 
1108
{
-
 
1109
   png_unknown_chunkp np;
-
 
1110
 
-
 
1111
   if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0 ||
-
 
1112
      unknowns == NULL)
-
 
1113
      return;
-
 
1114
 
-
 
1115
   /* Check for the failure cases where support has been disabled at compile
-
 
1116
    * time.  This code is hardly ever compiled - it's here because
-
 
1117
    * STORE_UNKNOWN_CHUNKS is set by both read and write code (compiling in this
-
 
1118
    * code) but may be meaningless if the read or write handling of unknown
-
 
1119
    * chunks is not compiled in.
-
 
1120
    */
-
 
1121
#  if !defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) && \
-
 
1122
      defined(PNG_READ_SUPPORTED)
-
 
1123
      if (png_ptr->mode & PNG_IS_READ_STRUCT)
-
 
1124
      {
-
 
1125
         png_app_error(png_ptr, "no unknown chunk support on read");
-
 
1126
         return;
-
 
1127
      }
952
   info_ptr->free_me |= PNG_FREE_SPLT;
1128
#  endif
953
}
1129
#  if !defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) && \
954
#endif /* PNG_sPLT_SUPPORTED */
1130
      defined(PNG_WRITE_SUPPORTED)
Line 955... Line 1131...
955
 
1131
      if (!(png_ptr->mode & PNG_IS_READ_STRUCT))
956
#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
1132
      {
957
void PNGAPI
1133
         png_app_error(png_ptr, "no unknown chunk support on write");
958
png_set_unknown_chunks(png_structp png_ptr,
1134
         return;
959
   png_infop info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
1135
      }
960
{
1136
#  endif
Line 961... Line -...
961
   png_unknown_chunkp np;
-
 
962
   int i;
-
 
963
 
-
 
964
   if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)
-
 
965
      return;
1137
 
966
 
-
 
967
   np = (png_unknown_chunkp)png_malloc_warn(png_ptr,
-
 
968
       (png_size_t)(info_ptr->unknown_chunks_num + num_unknowns) *
-
 
969
       png_sizeof(png_unknown_chunk));
-
 
970
 
1138
   /* Prior to 1.6.0 this code used png_malloc_warn; however, this meant that
971
   if (np == NULL)
1139
    * unknown critical chunks could be lost with just a warning resulting in
Line 972... Line -...
972
   {
-
 
973
      png_warning(png_ptr,
-
 
974
          "Out of memory while processing unknown chunk");
1140
    * undefined behavior.  Now png_chunk_report is used to provide behavior
Line 975... Line 1141...
975
      return;
1141
    * appropriate to read or write.
-
 
1142
    */
-
 
1143
   np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr,
-
 
1144
         info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns,
-
 
1145
         sizeof *np));
-
 
1146
 
-
 
1147
   if (np == NULL)
976
   }
1148
   {
Line 977... Line 1149...
977
 
1149
      png_chunk_report(png_ptr, "too many unknown chunks",
-
 
1150
         PNG_CHUNK_WRITE_ERROR);
978
   png_memcpy(np, info_ptr->unknown_chunks,
1151
      return;
-
 
1152
   }
-
 
1153
 
Line 979... Line 1154...
979
       (png_size_t)info_ptr->unknown_chunks_num *
1154
   png_free(png_ptr, info_ptr->unknown_chunks);
980
       png_sizeof(png_unknown_chunk));
1155
   info_ptr->unknown_chunks = np; /* safe because it is initialized */
981
 
1156
   info_ptr->free_me |= PNG_FREE_UNKN;
982
   png_free(png_ptr, info_ptr->unknown_chunks);
1157
 
Line 983... Line 1158...
983
   info_ptr->unknown_chunks = NULL;
1158
   np += info_ptr->unknown_chunks_num;
984
 
1159
 
-
 
1160
   /* Increment unknown_chunks_num each time round the loop to protect the
985
   for (i = 0; i < num_unknowns; i++)
1161
    * just-allocated chunk data.
986
   {
1162
    */
987
      png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;
1163
   for (; num_unknowns > 0; --num_unknowns, ++unknowns)
988
      png_const_unknown_chunkp from = unknowns + i;
1164
   {
Line 989... Line -...
989
 
-
 
990
      png_memcpy(to->name, from->name, png_sizeof(from->name));
1165
      memcpy(np->name, unknowns->name, (sizeof np->name));
991
      to->name[png_sizeof(to->name)-1] = '\0';
1166
      np->name[(sizeof np->name)-1] = '\0';
992
      to->size = from->size;
1167
      np->location = check_location(png_ptr, unknowns->location);
Line 993... Line 1168...
993
 
1168
 
994
      /* Note our location in the read or write sequence */
1169
      if (unknowns->size == 0)
-
 
1170
      {
-
 
1171
         np->data = NULL;
-
 
1172
         np->size = 0;
995
      to->location = (png_byte)(png_ptr->mode & 0xff);
1173
      }
-
 
1174
 
996
 
1175
      else
Line 997... Line 1176...
997
      if (from->size == 0)
1176
      {
998
         to->data=NULL;
1177
         np->data = png_voidcast(png_bytep,
999
 
1178
            png_malloc_base(png_ptr, unknowns->size));
1000
      else
1179
 
-
 
1180
         if (np->data == NULL)
-
 
1181
         {
-
 
1182
            png_chunk_report(png_ptr, "unknown chunk: out of memory",
-
 
1183
               PNG_CHUNK_WRITE_ERROR);
-
 
1184
            /* But just skip storing the unknown chunk */
1001
      {
1185
            continue;
1002
         to->data = (png_bytep)png_malloc_warn(png_ptr,
1186
         }
-
 
1187
 
-
 
1188
         memcpy(np->data, unknowns->data, unknowns->size);
-
 
1189
         np->size = unknowns->size;
-
 
1190
      }
-
 
1191
 
-
 
1192
      /* These increments are skipped on out-of-memory for the data - the
-
 
1193
       * unknown chunk entry gets overwritten if the png_chunk_report returns.
-
 
1194
       * This is correct in the read case (the chunk is just dropped.)
-
 
1195
       */
-
 
1196
      ++np;
-
 
1197
      ++(info_ptr->unknown_chunks_num);
-
 
1198
   }
1003
             (png_size_t)from->size);
1199
}
-
 
1200
 
-
 
1201
void PNGAPI
1004
 
1202
png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr,
1005
         if (to->data == NULL)
1203
    int chunk, int location)
Line 1006... Line 1204...
1006
         {
1204
{
1007
            png_warning(png_ptr,
1205
   /* This API is pretty pointless in 1.6.0 because the location can be set
1008
                "Out of memory while processing unknown chunk");
1206
    * before the call to png_set_unknown_chunks.
1009
            to->size = 0;
1207
    *
1010
         }
1208
    * TODO: add a png_app_warning in 1.7
Line 1011... Line 1209...
1011
 
1209
    */
1012
         else
1210
   if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 &&
Line 1013... Line -...
1013
            png_memcpy(to->data, from->data, from->size);
-
 
1014
      }
1211
      chunk < info_ptr->unknown_chunks_num)
Line 1015... Line 1212...
1015
   }
1212
   {
1016
 
1213
      if ((location & (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)) == 0)
1017
   info_ptr->unknown_chunks = np;
1214
      {
Line 1018... Line 1215...
1018
   info_ptr->unknown_chunks_num += num_unknowns;
1215
         png_app_error(png_ptr, "invalid unknown chunk location");
-
 
1216
         /* Fake out the pre 1.6.0 behavior: */
-
 
1217
         if ((location & PNG_HAVE_IDAT)) /* undocumented! */
-
 
1218
            location = PNG_AFTER_IDAT;
-
 
1219
 
-
 
1220
         else
-
 
1221
            location = PNG_HAVE_IHDR; /* also undocumented */
-
 
1222
      }
-
 
1223
 
-
 
1224
      info_ptr->unknown_chunks[chunk].location =
-
 
1225
         check_location(png_ptr, location);
-
 
1226
   }
-
 
1227
}
-
 
1228
#endif
-
 
1229
 
-
 
1230
 
-
 
1231
#ifdef PNG_MNG_FEATURES_SUPPORTED
-
 
1232
png_uint_32 PNGAPI
-
 
1233
png_permit_mng_features (png_structrp png_ptr, png_uint_32 mng_features)
-
 
1234
{
-
 
1235
   png_debug(1, "in png_permit_mng_features");
-
 
1236
 
-
 
1237
   if (png_ptr == NULL)
-
 
1238
      return 0;
-
 
1239
 
1019
   info_ptr->free_me |= PNG_FREE_UNKN;
1240
   png_ptr->mng_features_permitted = mng_features & PNG_ALL_MNG_FEATURES;
1020
}
1241
 
1021
 
1242
   return png_ptr->mng_features_permitted;
1022
void PNGAPI
1243
}
1023
png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
1244
#endif
1024
    int chunk, int location)
1245
 
-
 
1246
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
1025
{
1247
static unsigned int
1026
   if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <
1248
add_one_chunk(png_bytep list, unsigned int count, png_const_bytep add, int keep)
Line 1027... Line 1249...
1027
       info_ptr->unknown_chunks_num)
1249
{
1028
      info_ptr->unknown_chunks[chunk].location = (png_byte)location;
1250
   unsigned int i;
1029
}
1251
 
1030
#endif
1252
   /* Utility function: update the 'keep' state of a chunk if it is already in
-
 
1253
    * the list, otherwise add it to the list.
Line -... Line 1254...
-
 
1254
    */
1031
 
1255
   for (i=0; i
1032
 
1256
   {
Line 1033... Line 1257...
1033
#ifdef PNG_MNG_FEATURES_SUPPORTED
1257
      list[4] = (png_byte)keep;
1034
png_uint_32 PNGAPI
1258
      return count;
-
 
1259
   }
-
 
1260
 
Line -... Line 1261...
-
 
1261
   if (keep != PNG_HANDLE_CHUNK_AS_DEFAULT)
-
 
1262
   {
-
 
1263
      ++count;
-
 
1264
      memcpy(list, add, 4);
1035
png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features)
1265
      list[4] = (png_byte)keep;
-
 
1266
   }
-
 
1267
 
1036
{
1268
   return count;
-
 
1269
}
-
 
1270
 
-
 
1271
void PNGAPI
-
 
1272
png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
-
 
1273
    png_const_bytep chunk_list, int num_chunks_in)
-
 
1274
{
-
 
1275
   png_bytep new_list;
-
 
1276
   unsigned int num_chunks, old_num_chunks;
-
 
1277
 
-
 
1278
   if (png_ptr == NULL)
-
 
1279
      return;
-
 
1280
 
-
 
1281
   if (keep < 0 || keep >= PNG_HANDLE_CHUNK_LAST)
-
 
1282
   {
-
 
1283
      png_app_error(png_ptr, "png_set_keep_unknown_chunks: invalid keep");
-
 
1284
      return;
Line 1037... Line 1285...
1037
   png_debug(1, "in png_permit_mng_features");
1285
   }
-
 
1286
 
1038
 
1287
   if (num_chunks_in <= 0)
Line -... Line 1288...
-
 
1288
   {
-
 
1289
      png_ptr->unknown_default = keep;
1039
   if (png_ptr == NULL)
1290
 
-
 
1291
      /* '0' means just set the flags, so stop here */
-
 
1292
      if (num_chunks_in == 0)
-
 
1293
        return;
-
 
1294
   }
-
 
1295
 
1040
      return (png_uint_32)0;
1296
   if (num_chunks_in < 0)
-
 
1297
   {
-
 
1298
      /* Ignore all unknown chunks and all chunks recognized by
-
 
1299
       * libpng except for IHDR, PLTE, tRNS, IDAT, and IEND
-
 
1300
       */
Line 1041... Line 1301...
1041
 
1301
      static PNG_CONST png_byte chunks_to_ignore[] = {
1042
   png_ptr->mng_features_permitted =
1302
         98,  75,  71,  68, '\0',  /* bKGD */
1043
       (png_byte)(mng_features & PNG_ALL_MNG_FEATURES);
1303
         99,  72,  82,  77, '\0',  /* cHRM */
Line -... Line 1304...
-
 
1304
        103,  65,  77,  65, '\0',  /* gAMA */
-
 
1305
        104,  73,  83,  84, '\0',  /* hIST */
1044
 
1306
        105,  67,  67,  80, '\0',  /* iCCP */
1045
   return (png_uint_32)png_ptr->mng_features_permitted;
1307
        105,  84,  88, 116, '\0',  /* iTXt */
1046
}
-
 
1047
#endif
-
 
1048
 
1308
        111,  70,  70, 115, '\0',  /* oFFs */
1049
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
1309
        112,  67,  65,  76, '\0',  /* pCAL */
1050
void PNGAPI
1310
        112,  72,  89, 115, '\0',  /* pHYs */
Line -... Line 1311...
-
 
1311
        115,  66,  73,  84, '\0',  /* sBIT */
-
 
1312
        115,  67,  65,  76, '\0',  /* sCAL */
-
 
1313
        115,  80,  76,  84, '\0',  /* sPLT */
-
 
1314
        115,  84,  69,  82, '\0',  /* sTER */
-
 
1315
        115,  82,  71,  66, '\0',  /* sRGB */
-
 
1316
        116,  69,  88, 116, '\0',  /* tEXt */
1051
png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_const_bytep
1317
        116,  73,  77,  69, '\0',  /* tIME */
1052
    chunk_list, int num_chunks)
1318
        122,  84,  88, 116, '\0'   /* zTXt */
Line -... Line 1319...
-
 
1319
      };
1053
{
1320
 
-
 
1321
      chunk_list = chunks_to_ignore;
-
 
1322
      num_chunks = (sizeof chunks_to_ignore)/5;
-
 
1323
   }
-
 
1324
 
-
 
1325
   else /* num_chunks_in > 0 */
-
 
1326
   {
-
 
1327
      if (chunk_list == NULL)
-
 
1328
      {
-
 
1329
         /* Prior to 1.6.0 this was silently ignored, now it is an app_error
-
 
1330
          * which can be switched off.
-
 
1331
          */
-
 
1332
         png_app_error(png_ptr, "png_set_keep_unknown_chunks: no chunk list");
-
 
1333
         return;
-
 
1334
      }
-
 
1335
 
-
 
1336
      num_chunks = num_chunks_in;
1054
   png_bytep new_list, p;
1337
   }
-
 
1338
 
-
 
1339
   old_num_chunks = png_ptr->num_chunk_list;
-
 
1340
   if (png_ptr->chunk_list == NULL)
-
 
1341
      old_num_chunks = 0;
-
 
1342
 
-
 
1343
   /* Since num_chunks is always restricted to UINT_MAX/5 this can't overflow.
-
 
1344
    */
-
 
1345
   if (num_chunks + old_num_chunks > UINT_MAX/5)
-
 
1346
   {
-
 
1347
      png_app_error(png_ptr, "png_set_keep_unknown_chunks: too many chunks");
-
 
1348
      return;
-
 
1349
   }
-
 
1350
 
-
 
1351
   /* If these chunks are being reset to the default then no more memory is
-
 
1352
    * required because add_one_chunk above doesn't extend the list if the 'keep'
-
 
1353
    * parameter is the default.
-
 
1354
    */
-
 
1355
   if (keep)
-
 
1356
   {
-
 
1357
      new_list = png_voidcast(png_bytep, png_malloc(png_ptr,
-
 
1358
          5 * (num_chunks + old_num_chunks)));
-
 
1359
 
-
 
1360
      if (old_num_chunks > 0)
-
 
1361
         memcpy(new_list, png_ptr->chunk_list, 5*old_num_chunks);
-
 
1362
   }
-
 
1363
 
-
 
1364
   else if (old_num_chunks > 0)
-
 
1365
      new_list = png_ptr->chunk_list;
-
 
1366
 
-
 
1367
   else
-
 
1368
      new_list = NULL;
-
 
1369
 
-
 
1370
   /* Add the new chunks together with each one's handling code.  If the chunk
-
 
1371
    * already exists the code is updated, otherwise the chunk is added to the
-
 
1372
    * end.  (In libpng 1.6.0 order no longer matters because this code enforces
-
 
1373
    * the earlier convention that the last setting is the one that is used.)
Line 1055... Line -...
1055
   int i, old_num_chunks;
-
 
1056
   if (png_ptr == NULL)
1374
    */
1057
      return;
1375
   if (new_list != NULL)
1058
 
1376
   {
1059
   if (num_chunks == 0)
1377
      png_const_bytep inlist;
Line 1060... Line 1378...
1060
   {
1378
      png_bytep outlist;
1061
      if (keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE)
1379
      unsigned int i;
1062
         png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
1380
 
1063
 
1381
      for (i=0; i
1064
      else
1382
         old_num_chunks = add_one_chunk(new_list, old_num_chunks,
1065
         png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
1383
            chunk_list+5*i, keep);
Line 1066... Line 1384...
1066
 
1384
 
Line 1116... Line 1434...
1116
#endif
1434
#endif
1117
 
1435
 
Line 1118... Line 1436...
1118
#ifdef PNG_INFO_IMAGE_SUPPORTED
1436
#ifdef PNG_INFO_IMAGE_SUPPORTED
1119
void PNGAPI
1437
void PNGAPI
1120
png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
1438
png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr,
-
 
1439
    png_bytepp row_pointers)
1121
{
1440
{
1122
   png_debug1(1, "in %s storage function", "rows");
1441
   png_debug1(1, "in %s storage function", "rows");
Line 1123... Line 1442...
1123
 
1442
 
1124
   if (png_ptr == NULL || info_ptr == NULL)
1443
   if (png_ptr == NULL || info_ptr == NULL)
Line 1134... Line 1453...
1134
}
1453
}
1135
#endif
1454
#endif
1136
 
1455
 
Line 1137... Line 1456...
1137
void PNGAPI
1456
void PNGAPI
1138
png_set_compression_buffer_size(png_structp png_ptr, png_size_t size)
1457
png_set_compression_buffer_size(png_structrp png_ptr, png_size_t size)
1139
{
1458
{
1140
    if (png_ptr == NULL)
1459
    if (png_ptr == NULL)
1141
       return;
1460
       return;
Line -... Line 1461...
-
 
1461
 
1142
 
1462
    if (size == 0 || size > PNG_UINT_31_MAX)
Line -... Line 1463...
-
 
1463
       png_error(png_ptr, "invalid compression buffer size");
1143
    png_free(png_ptr, png_ptr->zbuf);
1464
 
1144
 
1465
#  ifdef PNG_SEQUENTIAL_READ_SUPPORTED
1145
    if (size > ZLIB_IO_MAX)
1466
      if (png_ptr->mode & PNG_IS_READ_STRUCT)
1146
    {
1467
      {
1147
       png_warning(png_ptr, "Attempt to set buffer size beyond max ignored");
-
 
1148
       png_ptr->zbuf_size = ZLIB_IO_MAX;
1468
         png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */
-
 
1469
         return;
Line -... Line 1470...
-
 
1470
      }
-
 
1471
#  endif
1149
       size = ZLIB_IO_MAX; /* must fit */
1472
 
1150
    }
1473
#  ifdef PNG_WRITE_SUPPORTED
-
 
1474
      if (!(png_ptr->mode & PNG_IS_READ_STRUCT))
-
 
1475
      {
-
 
1476
         if (png_ptr->zowner != 0)
-
 
1477
         {
-
 
1478
            png_warning(png_ptr,
Line -... Line 1479...
-
 
1479
              "Compression buffer size cannot be changed because it is in use");
-
 
1480
            return;
1151
 
1481
         }
-
 
1482
 
-
 
1483
         if (size > ZLIB_IO_MAX)
-
 
1484
         {
Line -... Line 1485...
-
 
1485
            png_warning(png_ptr,
-
 
1486
               "Compression buffer size limited to system maximum");
1152
    else
1487
            size = ZLIB_IO_MAX; /* must fit */
1153
       png_ptr->zbuf_size = (uInt)size;
1488
         }
1154
 
1489
 
1155
    png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size);
1490
         else if (size < 6)
-
 
1491
         {
-
 
1492
            /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH
-
 
1493
             * if this is permitted.
-
 
1494
             */
1156
 
1495
            png_warning(png_ptr,
-
 
1496
               "Compression buffer size cannot be reduced below 6");
-
 
1497
            return;
1157
    /* The following ensures a relatively safe failure if this gets called while
1498
         }
-
 
1499
 
-
 
1500
         if (png_ptr->zbuffer_size != size)
-
 
1501
         {
1158
     * the buffer is actually in use.
1502
            png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
Line 1159... Line 1503...
1159
     */
1503
            png_ptr->zbuffer_size = (uInt)size;
1160
    png_ptr->zstream.next_out = png_ptr->zbuf;
1504
         }
1161
    png_ptr->zstream.avail_out = 0;
1505
      }
1162
    png_ptr->zstream.avail_in = 0;
1506
#  endif
1163
}
1507
}
1164
 
1508
 
Line 1165... Line -...
1165
void PNGAPI
-
 
1166
png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask)
1509
void PNGAPI
1167
{
1510
png_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask)
1168
   if (png_ptr && info_ptr)
1511
{
1169
      info_ptr->valid &= ~mask;
1512
   if (png_ptr && info_ptr)
1170
}
1513
      info_ptr->valid &= ~mask;
1171
 
1514
}
1172
 
1515
 
1173
 
1516
 
1174
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
1517
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
Line 1189... Line 1532...
1189
}
1532
}
1190
 
1533
 
Line 1191... Line 1534...
1191
/* This function was added to libpng 1.4.0 */
1534
/* This function was added to libpng 1.4.0 */
1192
void PNGAPI
1535
void PNGAPI
1193
png_set_chunk_cache_max (png_structp png_ptr,
1536
png_set_chunk_cache_max (png_structrp png_ptr, png_uint_32 user_chunk_cache_max)
1194
   png_uint_32 user_chunk_cache_max)
-
 
1195
{
1537
{
1196
    if (png_ptr)
1538
    if (png_ptr)
1197
       png_ptr->user_chunk_cache_max = user_chunk_cache_max;
1539
       png_ptr->user_chunk_cache_max = user_chunk_cache_max;
1198
}
1540
}
Line 1199... Line 1541...
1199
 
1541
 
1200
/* This function was added to libpng 1.4.1 */
1542
/* This function was added to libpng 1.4.1 */
1201
void PNGAPI
1543
void PNGAPI
1202
png_set_chunk_malloc_max (png_structp png_ptr,
1544
png_set_chunk_malloc_max (png_structrp png_ptr,
1203
    png_alloc_size_t user_chunk_malloc_max)
1545
    png_alloc_size_t user_chunk_malloc_max)
1204
{
1546
{
1205
   if (png_ptr)
1547
   if (png_ptr)
1206
      png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
1548
      png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
1207
}
1549
}
Line 1208... Line 1550...
1208
#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
1550
#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
1209
 
1551
 
1210
 
1552
 
1211
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
1553
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
1212
void PNGAPI
1554
void PNGAPI
Line -... Line 1555...
-
 
1555
png_set_benign_errors(png_structrp png_ptr, int allowed)
-
 
1556
{
-
 
1557
   png_debug(1, "in png_set_benign_errors");
-
 
1558
 
-
 
1559
   /* If allowed is 1, png_benign_error() is treated as a warning.
-
 
1560
    *
1213
png_set_benign_errors(png_structp png_ptr, int allowed)
1561
    * If allowed is 0, png_benign_error() is treated as an error (which
1214
{
1562
    * is the default behavior if png_set_benign_errors() is not called).
-
 
1563
    */
Line 1215... Line 1564...
1215
   png_debug(1, "in png_set_benign_errors");
1564
 
1216
 
1565
   if (allowed)
-
 
1566
      png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN |
1217
   if (allowed)
1567
         PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN;
1218
      png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;
1568
 
-
 
1569
   else
-
 
1570
      png_ptr->flags &= ~(PNG_FLAG_BENIGN_ERRORS_WARN |
-
 
1571
         PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN);
-
 
1572
}
-
 
1573
#endif /* PNG_BENIGN_ERRORS_SUPPORTED */
-
 
1574
 
-
 
1575
#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
-
 
1576
   /* Whether to report invalid palette index; added at libng-1.5.10.
-
 
1577
    * It is possible for an indexed (color-type==3) PNG file to contain
-
 
1578
    * pixels with invalid (out-of-range) indexes if the PLTE chunk has
-
 
1579
    * fewer entries than the image's bit-depth would allow. We recover
-
 
1580
    * from this gracefully by filling any incomplete palette with zeroes
-
 
1581
    * (opaque black).  By default, when this occurs libpng will issue
-
 
1582
    * a benign error.  This API can be used to override that behavior.
-
 
1583
    */
-
 
1584
void PNGAPI
-
 
1585
png_set_check_for_invalid_index(png_structrp png_ptr, int allowed)
-
 
1586
{
-
 
1587
   png_debug(1, "in png_set_check_for_invalid_index");
-
 
1588
 
-
 
1589
   if (allowed > 0)
-
 
1590
      png_ptr->num_palette_max = 0;
1219
 
1591