1893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* pngset.c - storage of image information into info struct
3893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
4b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * Last changed in libpng 1.6.8 [December 19, 2013]
5b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Copyright (c) 1998-2013 Glenn Randers-Pehrson
6893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
9a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * This code is released under the libpng license.
10a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * For conditions of distribution and use, see the disclaimer
11a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * and license in png.h
12a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *
13893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * The functions here are used during reads to store data from the file
14893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * into the info struct, and during writes to store application data
15893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * into the info struct for writing into the file.  This abstracts the
16893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * info struct and allows us to change the structure in the future.
17893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
18893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
19b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#include "pngpriv.h"
20b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
21893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
22893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
235f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_bKGD_SUPPORTED
24893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
25b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
26b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_const_color_16p background)
27893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
284215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(1, "in %s storage function", "bKGD");
295f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
30b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (png_ptr == NULL || info_ptr == NULL || background == NULL)
31893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
32893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
33b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   info_ptr->background = *background;
34893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->valid |= PNG_INFO_bKGD;
35893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
36893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
37893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
385f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_cHRM_SUPPORTED
39b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGFAPI
40b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_cHRM_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
41b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
42b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
43b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_fixed_point blue_x, png_fixed_point blue_y)
44893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
45b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_xy xy;
46b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
47b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_debug1(1, "in %s storage function", "cHRM fixed");
485f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
49893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr == NULL || info_ptr == NULL)
50893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
51893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
52b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   xy.redx = red_x;
53b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   xy.redy = red_y;
54b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   xy.greenx = green_x;
55b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   xy.greeny = green_y;
56b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   xy.bluex = blue_x;
57b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   xy.bluey = blue_y;
58b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   xy.whitex = white_x;
59b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   xy.whitey = white_y;
60b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
61b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (png_colorspace_set_chromaticities(png_ptr, &info_ptr->colorspace, &xy,
62b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      2/* override with app values*/))
63b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
64b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
65b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_colorspace_sync_info(png_ptr, info_ptr);
66893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
674215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project
68b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGFAPI
69b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
70b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_fixed_point int_red_X, png_fixed_point int_red_Y,
71b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_fixed_point int_red_Z, png_fixed_point int_green_X,
72b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_fixed_point int_green_Y, png_fixed_point int_green_Z,
73b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_fixed_point int_blue_X, png_fixed_point int_blue_Y,
74b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_fixed_point int_blue_Z)
75893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
76b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_XYZ XYZ;
77b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
78b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_debug1(1, "in %s storage function", "cHRM XYZ fixed");
795f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
80893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr == NULL || info_ptr == NULL)
81893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
82893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
83b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   XYZ.red_X = int_red_X;
84b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   XYZ.red_Y = int_red_Y;
85b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   XYZ.red_Z = int_red_Z;
86b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   XYZ.green_X = int_green_X;
87b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   XYZ.green_Y = int_green_Y;
88b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   XYZ.green_Z = int_green_Z;
89b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   XYZ.blue_X = int_blue_X;
90b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   XYZ.blue_Y = int_blue_Y;
91b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   XYZ.blue_Z = int_blue_Z;
92b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
93b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (png_colorspace_set_endpoints(png_ptr, &info_ptr->colorspace, &XYZ, 2))
94b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
95b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
96b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_colorspace_sync_info(png_ptr, info_ptr);
97893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
98893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
99b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#  ifdef PNG_FLOATING_POINT_SUPPORTED
100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
101b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_cHRM(png_const_structrp png_ptr, png_inforp info_ptr,
102b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    double white_x, double white_y, double red_x, double red_y,
103b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    double green_x, double green_y, double blue_x, double blue_y)
104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
105b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_set_cHRM_fixed(png_ptr, info_ptr,
106b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_fixed(png_ptr, white_x, "cHRM White X"),
107b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_fixed(png_ptr, white_y, "cHRM White Y"),
108b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_fixed(png_ptr, red_x, "cHRM Red X"),
109b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_fixed(png_ptr, red_y, "cHRM Red Y"),
110b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_fixed(png_ptr, green_x, "cHRM Green X"),
111b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_fixed(png_ptr, green_y, "cHRM Green Y"),
112b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_fixed(png_ptr, blue_x, "cHRM Blue X"),
113b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
115b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
117b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X,
118b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    double red_Y, double red_Z, double green_X, double green_Y, double green_Z,
119b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    double blue_X, double blue_Y, double blue_Z)
120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
121b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_set_cHRM_XYZ_fixed(png_ptr, info_ptr,
122b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_fixed(png_ptr, red_X, "cHRM Red X"),
123b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_fixed(png_ptr, red_Y, "cHRM Red Y"),
124b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_fixed(png_ptr, red_Z, "cHRM Red Z"),
125b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_fixed(png_ptr, green_X, "cHRM Red X"),
126b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_fixed(png_ptr, green_Y, "cHRM Red Y"),
127b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_fixed(png_ptr, green_Z, "cHRM Red Z"),
128b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_fixed(png_ptr, blue_X, "cHRM Red X"),
129b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_fixed(png_ptr, blue_Y, "cHRM Red Y"),
130b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_fixed(png_ptr, blue_Z, "cHRM Red Z"));
131b50c217251b086440efcdb273c22f86a06c80cbaChris Craik}
132b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#  endif /* PNG_FLOATING_POINT_SUPPORTED */
133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
134b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* PNG_cHRM_SUPPORTED */
135b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
136b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_gAMA_SUPPORTED
137b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGFAPI
138b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
139b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_fixed_point file_gamma)
140b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{
1414215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(1, "in %s storage function", "gAMA");
1425f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr == NULL || info_ptr == NULL)
144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
146b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_colorspace_set_gamma(png_ptr, &info_ptr->colorspace, file_gamma);
147b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_colorspace_sync_info(png_ptr, info_ptr);
148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
149b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
150b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#  ifdef PNG_FLOATING_POINT_SUPPORTED
151b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGAPI
152b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_gAMA(png_const_structrp png_ptr, png_inforp info_ptr, double file_gamma)
153b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{
154b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma,
155b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       "png_set_gAMA"));
156b50c217251b086440efcdb273c22f86a06c80cbaChris Craik}
157b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#  endif
158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1605f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_hIST_SUPPORTED
161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
162b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
163b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_const_uint_16p hist)
164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int i;
166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1674215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(1, "in %s storage function", "hIST");
1685f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr == NULL || info_ptr == NULL)
170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1715f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (info_ptr->num_palette == 0 || info_ptr->num_palette
173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       > PNG_MAX_PALETTE_LENGTH)
174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
175a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      png_warning(png_ptr,
176b50c217251b086440efcdb273c22f86a06c80cbaChris Craik          "Invalid palette size, hIST allocation skipped");
177b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
178a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      return;
179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
182b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
183a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in
184a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    * version 1.2.1
185a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    */
186b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   info_ptr->hist = png_voidcast(png_uint_16p, png_malloc_warn(png_ptr,
187b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       PNG_MAX_PALETTE_LENGTH * (sizeof (png_uint_16))));
188b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
189b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (info_ptr->hist == NULL)
190a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   {
191b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_warning(png_ptr, "Insufficient memory for hIST chunk data");
192a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      return;
193a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   }
194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
195b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   info_ptr->free_me |= PNG_FREE_HIST;
196b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   for (i = 0; i < info_ptr->num_palette; i++)
198b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      info_ptr->hist[i] = hist[i];
199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
200b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   info_ptr->valid |= PNG_INFO_hIST;
201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
205b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_IHDR(png_const_structrp png_ptr, png_inforp info_ptr,
206b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_uint_32 width, png_uint_32 height, int bit_depth,
207b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    int color_type, int interlace_type, int compression_type,
208b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    int filter_type)
209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
2104215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(1, "in %s storage function", "IHDR");
2115f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr == NULL || info_ptr == NULL)
213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->width = width;
216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->height = height;
217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->bit_depth = (png_byte)bit_depth;
2185f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   info_ptr->color_type = (png_byte)color_type;
219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->compression_type = (png_byte)compression_type;
220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->filter_type = (png_byte)filter_type;
221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->interlace_type = (png_byte)interlace_type;
2225f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
2235f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height,
2245f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott       info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
2255f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott       info_ptr->compression_type, info_ptr->filter_type);
2265f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->channels = 1;
229b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->channels = 3;
232b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else
234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->channels = 1;
235b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->channels++;
238b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
241b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2445f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_oFFs_SUPPORTED
245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
246b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_oFFs(png_const_structrp png_ptr, png_inforp info_ptr,
247b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_int_32 offset_x, png_int_32 offset_y, int unit_type)
248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
2494215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(1, "in %s storage function", "oFFs");
2505f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr == NULL || info_ptr == NULL)
252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->x_offset = offset_x;
255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->y_offset = offset_y;
256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->offset_unit_type = (png_byte)unit_type;
257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->valid |= PNG_INFO_oFFs;
258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2615f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_pCAL_SUPPORTED
262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
263b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
264b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type,
265b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    int nparams, png_const_charp units, png_charpp params)
266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
267b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_size_t length;
268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int i;
269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2704215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(1, "in %s storage function", "pCAL");
2715f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
272b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (png_ptr == NULL || info_ptr == NULL || purpose == NULL || units == NULL
273b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      || (nparams > 0 && params == NULL))
274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
276b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   length = strlen(purpose) + 1;
2774215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(3, "allocating purpose for info (%lu bytes)",
278b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       (unsigned long)length);
279b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
280b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   /* TODO: validate format of calibration name and unit name */
281b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
282b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   /* Check that the type matches the specification. */
283b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (type < 0 || type > 3)
284b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_error(png_ptr, "Invalid pCAL equation type");
285b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
286b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (nparams < 0 || nparams > 255)
287b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_error(png_ptr, "Invalid pCAL parameter count");
288b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
289b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   /* Validate params[nparams] */
290b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   for (i=0; i<nparams; ++i)
291b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      if (params[i] == NULL ||
292b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         !png_check_fp_string(params[i], strlen(params[i])))
293b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         png_error(png_ptr, "Invalid format for pCAL parameter");
294b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
295b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   info_ptr->pcal_purpose = png_voidcast(png_charp,
296b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_malloc_warn(png_ptr, length));
297b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (info_ptr->pcal_purpose == NULL)
2994215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   {
300b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_warning(png_ptr, "Insufficient memory for pCAL purpose");
3014215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      return;
3024215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   }
303b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
304b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   memcpy(info_ptr->pcal_purpose, purpose, length);
305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3064215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(3, "storing X0, X1, type, and nparams in info");
307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->pcal_X0 = X0;
308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->pcal_X1 = X1;
309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->pcal_type = (png_byte)type;
310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->pcal_nparams = (png_byte)nparams;
311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
312b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   length = strlen(units) + 1;
3134215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(3, "allocating units for info (%lu bytes)",
3144215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project     (unsigned long)length);
315b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
316b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   info_ptr->pcal_units = png_voidcast(png_charp,
317b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_malloc_warn(png_ptr, length));
318b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (info_ptr->pcal_units == NULL)
3204215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   {
321b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_warning(png_ptr, "Insufficient memory for pCAL units");
3224215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      return;
3234215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   }
324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
325b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   memcpy(info_ptr->pcal_units, units, length);
326b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
327b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr,
328b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       (png_size_t)((nparams + 1) * (sizeof (png_charp)))));
329b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (info_ptr->pcal_params == NULL)
3314215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   {
332b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_warning(png_ptr, "Insufficient memory for pCAL params");
3334215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      return;
3344215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   }
335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
336b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   memset(info_ptr->pcal_params, 0, (nparams + 1) * (sizeof (png_charp)));
337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   for (i = 0; i < nparams; i++)
339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
340b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      length = strlen(params[i]) + 1;
3414215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_debug2(3, "allocating parameter %d for info (%lu bytes)", i,
342b50c217251b086440efcdb273c22f86a06c80cbaChris Craik          (unsigned long)length);
343b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
345b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (info_ptr->pcal_params[i] == NULL)
3474215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      {
348b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         png_warning(png_ptr, "Insufficient memory for pCAL parameter");
349a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         return;
3504215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      }
351b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
352b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      memcpy(info_ptr->pcal_params[i], params[i], length);
353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->valid |= PNG_INFO_pCAL;
356a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   info_ptr->free_me |= PNG_FREE_PCAL;
357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
360b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_sCAL_SUPPORTED
361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
362b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr,
363b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    int unit, png_const_charp swidth, png_const_charp sheight)
364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
365b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_size_t lengthw = 0, lengthh = 0;
366b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
3674215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(1, "in %s storage function", "sCAL");
3685f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr == NULL || info_ptr == NULL)
370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
372b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   /* Double check the unit (should never get here with an invalid
373b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * unit unless this is an API call.)
374b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    */
375b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (unit != 1 && unit != 2)
376b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_error(png_ptr, "Invalid sCAL unit");
377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
378b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (swidth == NULL || (lengthw = strlen(swidth)) == 0 ||
379b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw))
380b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_error(png_ptr, "Invalid sCAL width");
3815f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
382b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (sheight == NULL || (lengthh = strlen(sheight)) == 0 ||
383b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh))
384b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_error(png_ptr, "Invalid sCAL height");
385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->scal_unit = (png_byte)unit;
387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
388b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   ++lengthw;
389b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
390b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw);
391b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
392b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   info_ptr->scal_s_width = png_voidcast(png_charp,
393b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_malloc_warn(png_ptr, lengthw));
394b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (info_ptr->scal_s_width == NULL)
396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
397b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_warning(png_ptr, "Memory allocation failed while processing sCAL");
398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
401b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   memcpy(info_ptr->scal_s_width, swidth, lengthw);
402b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
403b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   ++lengthh;
404b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
405b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh);
406b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
407b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   info_ptr->scal_s_height = png_voidcast(png_charp,
408b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_malloc_warn(png_ptr, lengthh));
409b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (info_ptr->scal_s_height == NULL)
411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_free (png_ptr, info_ptr->scal_s_width);
4134215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      info_ptr->scal_s_width = NULL;
414b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
415b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_warning(png_ptr, "Memory allocation failed while processing sCAL");
416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
418b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
419b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   memcpy(info_ptr->scal_s_height, sheight, lengthh);
420b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->valid |= PNG_INFO_sCAL;
422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->free_me |= PNG_FREE_SCAL;
423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
424b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
425b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#  ifdef PNG_FLOATING_POINT_SUPPORTED
426b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGAPI
427b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_sCAL(png_const_structrp png_ptr, png_inforp info_ptr, int unit,
428b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    double width, double height)
429b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{
430b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_debug1(1, "in %s storage function", "sCAL");
431b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
432b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   /* Check the arguments. */
433b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (width <= 0)
434b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_warning(png_ptr, "Invalid sCAL width ignored");
435b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
436b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   else if (height <= 0)
437b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_warning(png_ptr, "Invalid sCAL height ignored");
438b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
439b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   else
440b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   {
441b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      /* Convert 'width' and 'height' to ASCII. */
442b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      char swidth[PNG_sCAL_MAX_DIGITS+1];
443b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      char sheight[PNG_sCAL_MAX_DIGITS+1];
444b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
445b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width,
446b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         PNG_sCAL_PRECISION);
447b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height,
448b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         PNG_sCAL_PRECISION);
449b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
450b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
451b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   }
452b50c217251b086440efcdb273c22f86a06c80cbaChris Craik}
453b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#  endif
454b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
455b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#  ifdef PNG_FIXED_POINT_SUPPORTED
456b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGAPI
457b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_sCAL_fixed(png_const_structrp png_ptr, png_inforp info_ptr, int unit,
458b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_fixed_point width, png_fixed_point height)
459b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{
460b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_debug1(1, "in %s storage function", "sCAL");
461b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
462b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   /* Check the arguments. */
463b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (width <= 0)
464b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_warning(png_ptr, "Invalid sCAL width ignored");
465b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
466b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   else if (height <= 0)
467b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_warning(png_ptr, "Invalid sCAL height ignored");
468b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
469b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   else
470b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   {
471b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      /* Convert 'width' and 'height' to ASCII. */
472b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      char swidth[PNG_sCAL_MAX_DIGITS+1];
473b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      char sheight[PNG_sCAL_MAX_DIGITS+1];
474b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
475b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_ascii_from_fixed(png_ptr, swidth, (sizeof swidth), width);
476b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_ascii_from_fixed(png_ptr, sheight, (sizeof sheight), height);
477b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
478b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
479b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   }
480b50c217251b086440efcdb273c22f86a06c80cbaChris Craik}
481b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#  endif
482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4845f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_pHYs_SUPPORTED
485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
486b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_pHYs(png_const_structrp png_ptr, png_inforp info_ptr,
487b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_uint_32 res_x, png_uint_32 res_y, int unit_type)
488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
4894215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(1, "in %s storage function", "pHYs");
4905f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr == NULL || info_ptr == NULL)
492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->x_pixels_per_unit = res_x;
495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->y_pixels_per_unit = res_y;
496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->phys_unit_type = (png_byte)unit_type;
497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->valid |= PNG_INFO_pHYs;
498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
502b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_PLTE(png_structrp png_ptr, png_inforp info_ptr,
503b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_const_colorp palette, int num_palette)
504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
5064215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(1, "in %s storage function", "PLTE");
5075f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr == NULL || info_ptr == NULL)
509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH)
512a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   {
513a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_error(png_ptr, "Invalid palette length");
515b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
516a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      else
517a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      {
518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_warning(png_ptr, "Invalid palette length");
519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         return;
520a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      }
521a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   }
522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
523b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if ((num_palette > 0 && palette == NULL) ||
524b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      (num_palette == 0
525b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#        ifdef PNG_MNG_FEATURES_SUPPORTED
526b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            && (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0
527b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#        endif
528b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      ))
529b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   {
530b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari      png_error(png_ptr, "Invalid palette");
531b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      return;
532b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   }
533b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
5345f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   /* It may not actually be necessary to set png_ptr->palette here;
535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    * we do it for backward compatibility with the way the png_handle_tRNS
536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    * function used to do the allocation.
537b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    *
538b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * 1.6.0: the above statement appears to be incorrect; something has to set
539b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * the palette inside png_struct on read.
540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    */
541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
544a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    * of num_palette entries, in case of an invalid PNG file that has
545a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    * too-large sample values.
546a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    */
547b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr,
548b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       PNG_MAX_PALETTE_LENGTH * (sizeof (png_color))));
549b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
550b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (num_palette > 0)
551b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      memcpy(png_ptr->palette, palette, num_palette * (sizeof (png_color)));
552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->palette = png_ptr->palette;
553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->free_me |= PNG_FREE_PLTE;
556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->valid |= PNG_INFO_PLTE;
558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
5605f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_sBIT_SUPPORTED
561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
562b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_sBIT(png_const_structrp png_ptr, png_inforp info_ptr,
563b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_const_color_8p sig_bit)
564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
5654215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(1, "in %s storage function", "sBIT");
5665f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
567b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (png_ptr == NULL || info_ptr == NULL || sig_bit == NULL)
568893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
570b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   info_ptr->sig_bit = *sig_bit;
571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->valid |= PNG_INFO_sBIT;
572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
5755f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_sRGB_SUPPORTED
576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
577b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_sRGB(png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent)
578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
5794215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(1, "in %s storage function", "sRGB");
5805f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr == NULL || info_ptr == NULL)
582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
584b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   (void)png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent);
585b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_colorspace_sync_info(png_ptr, info_ptr);
586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
587893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
589b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_sRGB_gAMA_and_cHRM(png_const_structrp png_ptr, png_inforp info_ptr,
590b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    int srgb_intent)
591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
5924215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM");
5935f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr == NULL || info_ptr == NULL)
595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
597b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent))
598b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   {
599b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      /* This causes the gAMA and cHRM to be written too */
600b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      info_ptr->colorspace.flags |=
601b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM;
602b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   }
603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
604b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_colorspace_sync_info(png_ptr, info_ptr);
6054215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project}
6064215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project#endif /* sRGB */
607893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
6095f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_iCCP_SUPPORTED
610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
611b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
612b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_const_charp name, int compression_type,
613b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_const_bytep profile, png_uint_32 proflen)
614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_charp new_iccp_name;
616b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_bytep new_iccp_profile;
617b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_size_t length;
618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
6194215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(1, "in %s storage function", "iCCP");
6205f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
621893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
622893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
623893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
624b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
625b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_app_error(png_ptr, "Invalid iCCP compression method");
626b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
627b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   /* Set the colorspace first because this validates the profile; do not
628b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * override previously set app cHRM or gAMA here (because likely as not the
629b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * application knows better than libpng what the correct values are.)  Pass
630b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * the info_ptr color_type field to png_colorspace_set_ICC because in the
631b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * write case it has not yet been stored in png_ptr.
632b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    */
633b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   {
634b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name,
635b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         proflen, profile, info_ptr->color_type);
636b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
637b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_colorspace_sync_info(png_ptr, info_ptr);
638b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
639b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      /* Don't do any of the copying if the profile was bad, or inconsistent. */
640b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      if (!result)
641b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         return;
642b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
643b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      /* But do write the gAMA and cHRM chunks from the profile. */
644b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      info_ptr->colorspace.flags |=
645b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM;
646b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   }
647b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
648b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   length = strlen(name)+1;
649b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   new_iccp_name = png_voidcast(png_charp, png_malloc_warn(png_ptr, length));
650b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (new_iccp_name == NULL)
652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
653b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_benign_error(png_ptr, "Insufficient memory to process iCCP chunk");
654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
656b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
657b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   memcpy(new_iccp_name, name, length);
658b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   new_iccp_profile = png_voidcast(png_bytep,
659b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_malloc_warn(png_ptr, proflen));
660b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (new_iccp_profile == NULL)
662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
663b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_free(png_ptr, new_iccp_name);
664b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_benign_error(png_ptr,
665b50c217251b086440efcdb273c22f86a06c80cbaChris Craik          "Insufficient memory to process iCCP profile");
666893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
667893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
668b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
669b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   memcpy(new_iccp_profile, profile, proflen);
670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
672893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->iccp_proflen = proflen;
674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->iccp_name = new_iccp_name;
675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->iccp_profile = new_iccp_profile;
676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->free_me |= PNG_FREE_ICCP;
677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->valid |= PNG_INFO_iCCP;
678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
6815f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_TEXT_SUPPORTED
682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
683b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_text(png_const_structrp png_ptr, png_inforp info_ptr,
684b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_const_textp text_ptr, int num_text)
685893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
686893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int ret;
6874215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
688b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
689893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (ret)
690a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      png_error(png_ptr, "Insufficient memory to store text");
691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
692893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
693893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectint /* PRIVATE */
694b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
695b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_const_textp text_ptr, int num_text)
696893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
697893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int i;
698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
699b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_debug1(1, "in %lx storage function", png_ptr == NULL ? "unexpected" :
700b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      (unsigned long)png_ptr->chunk_name);
701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
702b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL)
703893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return(0);
704893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
705893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   /* Make sure we have enough space in the "text" array in info_struct
706b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * to hold all of the incoming text_ptr objects.  This compare can't overflow
707b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * because max_text >= num_text (anyway, subtract of two positive integers
708b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * can't overflow in any case.)
709893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    */
710b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (num_text > info_ptr->max_text - info_ptr->num_text)
711893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
7125e12401790abb7416c1a27ff077e0a823e8cefd8Terry Heo (Woncheol)      int old_num_text = info_ptr->num_text;
713b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      int max_text;
714b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_textp new_text = NULL;
7155e12401790abb7416c1a27ff077e0a823e8cefd8Terry Heo (Woncheol)
716b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      /* Calculate an appropriate max_text, checking for overflow. */
717b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      max_text = old_num_text;
718b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      if (num_text <= INT_MAX - max_text)
719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
720b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         max_text += num_text;
721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
722b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         /* Round up to a multiple of 8 */
723b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         if (max_text < INT_MAX-8)
724b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            max_text = (max_text + 8) & ~0x7;
7255e12401790abb7416c1a27ff077e0a823e8cefd8Terry Heo (Woncheol)
726b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         else
727b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            max_text = INT_MAX;
728b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
729b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         /* Now allocate a new array and copy the old members in, this does all
730b50c217251b086440efcdb273c22f86a06c80cbaChris Craik          * the overflow checks.
731b50c217251b086440efcdb273c22f86a06c80cbaChris Craik          */
732b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         new_text = png_voidcast(png_textp,png_realloc_array(png_ptr,
733b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            info_ptr->text, old_num_text, max_text-old_num_text,
734b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            sizeof *new_text));
735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
736b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
737b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      if (new_text == NULL)
738893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
739b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         png_chunk_report(png_ptr, "too many text chunks",
740b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            PNG_CHUNK_WRITE_ERROR);
741b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         return 1;
742893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
743b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
744b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_free(png_ptr, info_ptr->text);
745b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
746b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      info_ptr->text = new_text;
747b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      info_ptr->free_me |= PNG_FREE_TEXT;
748b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      info_ptr->max_text = max_text;
749b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      /* num_text is adjusted below as the entries are copied in */
750b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
751b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_debug1(3, "allocated %d entries for info_ptr->text", max_text);
752893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
7535e12401790abb7416c1a27ff077e0a823e8cefd8Terry Heo (Woncheol)
754893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   for (i = 0; i < num_text; i++)
755893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
756b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      size_t text_length, key_len;
757b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      size_t lang_len, lang_key_len;
758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_textp textp = &(info_ptr->text[info_ptr->num_text]);
759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
760893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (text_ptr[i].key == NULL)
761893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          continue;
762893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
763b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE ||
764b50c217251b086440efcdb273c22f86a06c80cbaChris Craik          text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
765b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      {
766b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         png_chunk_report(png_ptr, "text compression mode is out of range",
767b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            PNG_CHUNK_WRITE_ERROR);
768b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         continue;
769b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      }
770b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
771b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      key_len = strlen(text_ptr[i].key);
772893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
7734215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      if (text_ptr[i].compression <= 0)
774893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
775a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         lang_len = 0;
776a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         lang_key_len = 0;
777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
7785f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
780b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#  ifdef PNG_iTXt_SUPPORTED
781893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
782a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         /* Set iTXt data */
7835f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
784a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         if (text_ptr[i].lang != NULL)
785b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            lang_len = strlen(text_ptr[i].lang);
786b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
787a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         else
788a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott            lang_len = 0;
789b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
790a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         if (text_ptr[i].lang_key != NULL)
791b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            lang_key_len = strlen(text_ptr[i].lang_key);
792b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
793a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         else
794a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott            lang_key_len = 0;
795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
796b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#  else /* PNG_iTXt_SUPPORTED */
797893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
798b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         png_chunk_report(png_ptr, "iTXt chunk not supported",
799b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            PNG_CHUNK_WRITE_ERROR);
800a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         continue;
801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
802b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#  endif
803893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
804893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
805893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
806893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         text_length = 0;
807b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#  ifdef PNG_iTXt_SUPPORTED
8084215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         if (text_ptr[i].compression > 0)
809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            textp->compression = PNG_ITXT_COMPRESSION_NONE;
810b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
812b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#  endif
813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            textp->compression = PNG_TEXT_COMPRESSION_NONE;
814893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
8155f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
816893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
817893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
818b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         text_length = strlen(text_ptr[i].text);
819893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         textp->compression = text_ptr[i].compression;
820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
821893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
822b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      textp->key = png_voidcast(png_charp,png_malloc_base(png_ptr,
823b50c217251b086440efcdb273c22f86a06c80cbaChris Craik          key_len + text_length + lang_len + lang_key_len + 4));
824b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (textp->key == NULL)
826b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      {
827b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         png_chunk_report(png_ptr, "text chunk: out of memory",
828b50c217251b086440efcdb273c22f86a06c80cbaChris Craik               PNG_CHUNK_WRITE_ERROR);
829b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         return 1;
830b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      }
831893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
832b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_debug2(2, "Allocated %lu bytes at %p in png_set_text",
833b50c217251b086440efcdb273c22f86a06c80cbaChris Craik          (unsigned long)(png_uint_32)
834b50c217251b086440efcdb273c22f86a06c80cbaChris Craik          (key_len + lang_len + lang_key_len + text_length + 4),
835b50c217251b086440efcdb273c22f86a06c80cbaChris Craik          textp->key);
836b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
837b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      memcpy(textp->key, text_ptr[i].key, key_len);
8384215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      *(textp->key + key_len) = '\0';
839b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
840893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (text_ptr[i].compression > 0)
841893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
8424215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         textp->lang = textp->key + key_len + 1;
843b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         memcpy(textp->lang, text_ptr[i].lang, lang_len);
8444215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         *(textp->lang + lang_len) = '\0';
8454215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         textp->lang_key = textp->lang + lang_len + 1;
846b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
8474215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         *(textp->lang_key + lang_key_len) = '\0';
8484215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         textp->text = textp->lang_key + lang_key_len + 1;
849893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
850b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
851893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
852893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
853893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         textp->lang=NULL;
854893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         textp->lang_key=NULL;
8554215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         textp->text = textp->key + key_len + 1;
856893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
857b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
8584215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      if (text_length)
859b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         memcpy(textp->text, text_ptr[i].text, text_length);
860b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
8614215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      *(textp->text + text_length) = '\0';
862893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
863b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#  ifdef PNG_iTXt_SUPPORTED
8644215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      if (textp->compression > 0)
865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         textp->text_length = 0;
867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         textp->itxt_length = text_length;
868893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
8695f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
870b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      else
871b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#  endif
872893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
873893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         textp->text_length = text_length;
874893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         textp->itxt_length = 0;
875893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
876b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
877893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->num_text++;
8784215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_debug1(3, "transferred text chunk %d", info_ptr->num_text);
879893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
880b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
881893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   return(0);
882893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
883893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
884893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
8855f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_tIME_SUPPORTED
886893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
887b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_tIME(png_const_structrp png_ptr, png_inforp info_ptr,
888b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_const_timep mod_time)
889893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
8904215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(1, "in %s storage function", "tIME");
8915f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
892b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (png_ptr == NULL || info_ptr == NULL || mod_time == NULL ||
893893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       (png_ptr->mode & PNG_WROTE_tIME))
894893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
895893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
896b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (mod_time->month == 0   || mod_time->month > 12  ||
897b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       mod_time->day   == 0   || mod_time->day   > 31  ||
898b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       mod_time->hour  > 23   || mod_time->minute > 59 ||
899b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       mod_time->second > 60)
900b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   {
901b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_warning(png_ptr, "Ignoring invalid time value");
902b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      return;
903b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   }
904b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
905b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   info_ptr->mod_time = *mod_time;
906893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->valid |= PNG_INFO_tIME;
907893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
908893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
909893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
9105f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_tRNS_SUPPORTED
911893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
912b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_tRNS(png_structrp png_ptr, png_inforp info_ptr,
913b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color)
914893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
9154215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(1, "in %s storage function", "tRNS");
9165f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
917893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr == NULL || info_ptr == NULL)
918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
920b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (trans_alpha != NULL)
921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
922b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       /* It may not actually be necessary to set png_ptr->trans_alpha here;
923893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        * we do it for backward compatibility with the way the png_handle_tRNS
924893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        * function used to do the allocation.
925b50c217251b086440efcdb273c22f86a06c80cbaChris Craik        *
926b50c217251b086440efcdb273c22f86a06c80cbaChris Craik        * 1.6.0: The above statement is incorrect; png_handle_tRNS effectively
927b50c217251b086440efcdb273c22f86a06c80cbaChris Craik        * relies on png_set_tRNS storing the information in png_struct
928b50c217251b086440efcdb273c22f86a06c80cbaChris Craik        * (otherwise it won't be there for the code in pngrtran.c).
929893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        */
930893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
9314215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project       png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
9324215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project
933893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
934b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       png_ptr->trans_alpha = info_ptr->trans_alpha = png_voidcast(png_bytep,
935b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
936b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
937893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
938b50c217251b086440efcdb273c22f86a06c80cbaChris Craik          memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans);
939893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
940893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
941b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (trans_color != NULL)
942893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
943893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int sample_max = (1 << info_ptr->bit_depth);
944b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
945893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
946b50c217251b086440efcdb273c22f86a06c80cbaChris Craik          trans_color->gray > sample_max) ||
947893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
948b50c217251b086440efcdb273c22f86a06c80cbaChris Craik          (trans_color->red > sample_max ||
949b50c217251b086440efcdb273c22f86a06c80cbaChris Craik          trans_color->green > sample_max ||
950b50c217251b086440efcdb273c22f86a06c80cbaChris Craik          trans_color->blue > sample_max)))
951a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         png_warning(png_ptr,
952a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott            "tRNS chunk has out-of-range samples for bit_depth");
953b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
954b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      info_ptr->trans_color = *trans_color;
955b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
956893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (num_trans == 0)
957a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         num_trans = 1;
958893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
959893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
960893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->num_trans = (png_uint_16)num_trans;
961b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
962893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (num_trans != 0)
963893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
964893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->valid |= PNG_INFO_tRNS;
965893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->free_me |= PNG_FREE_TRNS;
966893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
967893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
968893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
969893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
9705f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_sPLT_SUPPORTED
971893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
972b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_sPLT(png_const_structrp png_ptr,
973b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_inforp info_ptr, png_const_sPLT_tp entries, int nentries)
9744215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project/*
9754215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project *  entries        - array of png_sPLT_t structures
9764215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project *                   to be added to the list of palettes
9774215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project *                   in the info structure.
978b50c217251b086440efcdb273c22f86a06c80cbaChris Craik *
9794215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project *  nentries       - number of palette structures to be
9804215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project *                   added.
9814215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project */
982893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
983a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   png_sPLT_tp np;
984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
985b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL)
986a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      return;
987893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
988b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   /* Use the internal realloc function, which checks for all the possible
989b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * overflows.  Notice that the parameters are (int) and (size_t)
990b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    */
991b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr,
992b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries,
993b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      sizeof *np));
994b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
995a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   if (np == NULL)
996a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   {
997b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      /* Out of memory or too many chunks */
998b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_chunk_report(png_ptr, "too many sPLT chunks", PNG_CHUNK_WRITE_ERROR);
9995f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      return;
1000a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   }
10014215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project
1002a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   png_free(png_ptr, info_ptr->splt_palettes);
1003b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   info_ptr->splt_palettes = np;
1004b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   info_ptr->free_me |= PNG_FREE_SPLT;
1005b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1006b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   np += info_ptr->splt_palettes_num;
1007893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1008b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   do
1009a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   {
1010b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_size_t length;
1011893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1012b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      /* Skip invalid input entries */
1013b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      if (entries->name == NULL || entries->entries == NULL)
1014a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      {
1015b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         /* png_handle_sPLT doesn't do this, so this is an app error */
1016b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         png_app_error(png_ptr, "png_set_sPLT: invalid sPLT");
1017b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         /* Just skip the invalid entry */
1018a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         continue;
1019a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      }
1020b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1021b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      np->depth = entries->depth;
1022b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1023b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      /* In the even of out-of-memory just return - there's no point keeping on
1024b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       * trying to add sPLT chunks.
1025b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       */
1026b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      length = strlen(entries->name) + 1;
1027b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      np->name = png_voidcast(png_charp, png_malloc_base(png_ptr, length));
1028b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1029b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      if (np->name == NULL)
1030b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         break;
1031b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1032b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      memcpy(np->name, entries->name, length);
1033b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1034b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      /* IMPORTANT: we have memory now that won't get freed if something else
1035b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       * goes wrong, this code must free it.  png_malloc_array produces no
1036b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       * warnings, use a png_chunk_report (below) if there is an error.
1037b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       */
1038b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      np->entries = png_voidcast(png_sPLT_entryp, png_malloc_array(png_ptr,
1039b50c217251b086440efcdb273c22f86a06c80cbaChris Craik          entries->nentries, sizeof (png_sPLT_entry)));
1040b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1041b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      if (np->entries == NULL)
1042a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      {
1043b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         png_free(png_ptr, np->name);
1044b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         break;
1045a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      }
1046b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1047b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      np->nentries = entries->nentries;
1048b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      /* This multiply can't overflow because png_malloc_array has already
1049b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       * checked it when doing the allocation.
1050b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       */
1051b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      memcpy(np->entries, entries->entries,
1052b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         entries->nentries * sizeof (png_sPLT_entry));
1053b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1054b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      /* Note that 'continue' skips the advance of the out pointer and out
1055b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       * count, so an invalid entry is not added.
1056b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       */
1057b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      info_ptr->valid |= PNG_INFO_sPLT;
1058b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      ++(info_ptr->splt_palettes_num);
1059b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      ++np;
1060a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   }
1061b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   while (++entries, --nentries);
1062a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
1063b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (nentries > 0)
1064b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR);
1065893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1066893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_sPLT_SUPPORTED */
1067893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1068b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
1069b50c217251b086440efcdb273c22f86a06c80cbaChris Craikstatic png_byte
1070b50c217251b086440efcdb273c22f86a06c80cbaChris Craikcheck_location(png_const_structrp png_ptr, int location)
1071b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{
1072b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   location &= (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT);
1073b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1074b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   /* New in 1.6.0; copy the location and check it.  This is an API
1075b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * change, previously the app had to use the
1076b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * png_set_unknown_chunk_location API below for each chunk.
1077b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    */
1078b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (location == 0 && !(png_ptr->mode & PNG_IS_READ_STRUCT))
1079b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   {
1080b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      /* Write struct, so unknown chunks come from the app */
1081b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_app_warning(png_ptr,
1082b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         "png_set_unknown_chunks now expects a valid location");
1083b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      /* Use the old behavior */
1084b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      location = (png_byte)(png_ptr->mode &
1085b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT));
1086b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   }
1087b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1088b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   /* This need not be an internal error - if the app calls
1089b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * png_set_unknown_chunks on a read pointer it must get the location right.
1090b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    */
1091b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (location == 0)
1092b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_error(png_ptr, "invalid location in png_set_unknown_chunks");
1093b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1094b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   /* Now reduce the location to the top-most set bit by removing each least
1095b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * significant bit in turn.
1096b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    */
1097b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   while (location != (location & -location))
1098b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      location &= ~(location & -location);
1099b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1100b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   /* The cast is safe because 'location' is a bit mask and only the low four
1101b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * bits are significant.
1102b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    */
1103b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   return (png_byte)location;
1104b50c217251b086440efcdb273c22f86a06c80cbaChris Craik}
1105b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
1107b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_unknown_chunks(png_const_structrp png_ptr,
1108b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
1109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1110a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   png_unknown_chunkp np;
1111a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
1112b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0 ||
1113b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      unknowns == NULL)
1114a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      return;
1115a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
1116b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   /* Check for the failure cases where support has been disabled at compile
1117b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * time.  This code is hardly ever compiled - it's here because
1118b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * STORE_UNKNOWN_CHUNKS is set by both read and write code (compiling in this
1119b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * code) but may be meaningless if the read or write handling of unknown
1120b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * chunks is not compiled in.
1121b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    */
1122b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#  if !defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) && \
1123b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      defined(PNG_READ_SUPPORTED)
1124b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      if (png_ptr->mode & PNG_IS_READ_STRUCT)
1125b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      {
1126b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         png_app_error(png_ptr, "no unknown chunk support on read");
1127b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         return;
1128b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      }
1129b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#  endif
1130b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#  if !defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) && \
1131b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      defined(PNG_WRITE_SUPPORTED)
1132b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      if (!(png_ptr->mode & PNG_IS_READ_STRUCT))
1133b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      {
1134b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         png_app_error(png_ptr, "no unknown chunk support on write");
1135b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         return;
1136b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      }
1137b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#  endif
1138b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1139b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   /* Prior to 1.6.0 this code used png_malloc_warn; however, this meant that
1140b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * unknown critical chunks could be lost with just a warning resulting in
1141b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * undefined behavior.  Now png_chunk_report is used to provide behavior
1142b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * appropriate to read or write.
1143b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    */
1144b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr,
1145b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns,
1146b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         sizeof *np));
1147b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1148a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   if (np == NULL)
1149a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   {
1150b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_chunk_report(png_ptr, "too many unknown chunks",
1151b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         PNG_CHUNK_WRITE_ERROR);
1152a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      return;
1153a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   }
1154a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
1155a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   png_free(png_ptr, info_ptr->unknown_chunks);
1156b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   info_ptr->unknown_chunks = np; /* safe because it is initialized */
1157b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   info_ptr->free_me |= PNG_FREE_UNKN;
1158b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1159b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   np += info_ptr->unknown_chunks_num;
1160a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
1161b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   /* Increment unknown_chunks_num each time round the loop to protect the
1162b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * just-allocated chunk data.
1163b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    */
1164b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   for (; num_unknowns > 0; --num_unknowns, ++unknowns)
1165a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   {
1166b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      memcpy(np->name, unknowns->name, (sizeof np->name));
1167b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      np->name[(sizeof np->name)-1] = '\0';
1168b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      np->location = check_location(png_ptr, unknowns->location);
1169b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1170b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      if (unknowns->size == 0)
1171b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      {
1172b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         np->data = NULL;
1173b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         np->size = 0;
1174b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      }
1175b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1176a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      else
1177a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      {
1178b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         np->data = png_voidcast(png_bytep,
1179b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            png_malloc_base(png_ptr, unknowns->size));
1180b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1181b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         if (np->data == NULL)
1182a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         {
1183b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            png_chunk_report(png_ptr, "unknown chunk: out of memory",
1184b50c217251b086440efcdb273c22f86a06c80cbaChris Craik               PNG_CHUNK_WRITE_ERROR);
1185b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            /* But just skip storing the unknown chunk */
1186b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            continue;
1187a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         }
1188b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1189b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         memcpy(np->data, unknowns->data, unknowns->size);
1190b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         np->size = unknowns->size;
1191a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      }
1192a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
1193b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      /* These increments are skipped on out-of-memory for the data - the
1194b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       * unknown chunk entry gets overwritten if the png_chunk_report returns.
1195b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       * This is correct in the read case (the chunk is just dropped.)
1196b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       */
1197b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      ++np;
1198b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      ++(info_ptr->unknown_chunks_num);
1199b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   }
1200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
1203b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr,
1204b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    int chunk, int location)
1205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1206b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   /* This API is pretty pointless in 1.6.0 because the location can be set
1207b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * before the call to png_set_unknown_chunks.
1208b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    *
1209b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * TODO: add a png_app_warning in 1.7
1210b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    */
1211b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 &&
1212b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      chunk < info_ptr->unknown_chunks_num)
1213b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   {
1214b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      if ((location & (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)) == 0)
1215b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      {
1216b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         png_app_error(png_ptr, "invalid unknown chunk location");
1217b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         /* Fake out the pre 1.6.0 behavior: */
1218b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         if ((location & PNG_HAVE_IDAT)) /* undocumented! */
1219b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            location = PNG_AFTER_IDAT;
12205f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
1221b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         else
1222b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            location = PNG_HAVE_IHDR; /* also undocumented */
1223b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      }
12245f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
1225b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      info_ptr->unknown_chunks[chunk].location =
1226b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         check_location(png_ptr, location);
1227b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   }
1228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1230b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
12325f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_MNG_FEATURES_SUPPORTED
1233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_uint_32 PNGAPI
1234b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_permit_mng_features (png_structrp png_ptr, png_uint_32 mng_features)
1235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
12364215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_permit_mng_features");
12375f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
1238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr == NULL)
1239b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      return 0;
1240b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1241b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_ptr->mng_features_permitted = mng_features & PNG_ALL_MNG_FEATURES;
1242b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1243b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   return png_ptr->mng_features_permitted;
1244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
12475f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
1248b50c217251b086440efcdb273c22f86a06c80cbaChris Craikstatic unsigned int
1249b50c217251b086440efcdb273c22f86a06c80cbaChris Craikadd_one_chunk(png_bytep list, unsigned int count, png_const_bytep add, int keep)
1250b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{
1251b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   unsigned int i;
1252b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1253b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   /* Utility function: update the 'keep' state of a chunk if it is already in
1254b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * the list, otherwise add it to the list.
1255b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    */
1256b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   for (i=0; i<count; ++i, list += 5) if (memcmp(list, add, 4) == 0)
1257b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   {
1258b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      list[4] = (png_byte)keep;
1259b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      return count;
1260b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   }
1261b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1262b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (keep != PNG_HANDLE_CHUNK_AS_DEFAULT)
1263b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   {
1264b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      ++count;
1265b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      memcpy(list, add, 4);
1266b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      list[4] = (png_byte)keep;
1267b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   }
1268b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1269b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   return count;
1270b50c217251b086440efcdb273c22f86a06c80cbaChris Craik}
1271b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
1273b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
1274b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_const_bytep chunk_list, int num_chunks_in)
1275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1276b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_bytep new_list;
1277b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   unsigned int num_chunks, old_num_chunks;
1278b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1279a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   if (png_ptr == NULL)
1280a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      return;
1281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1282b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (keep < 0 || keep >= PNG_HANDLE_CHUNK_LAST)
1283b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   {
1284b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_app_error(png_ptr, "png_set_keep_unknown_chunks: invalid keep");
1285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1286a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   }
1287b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1288b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (num_chunks_in <= 0)
1289b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   {
1290b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_ptr->unknown_default = keep;
1291b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1292b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      /* '0' means just set the flags, so stop here */
1293b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      if (num_chunks_in == 0)
1294b50c217251b086440efcdb273c22f86a06c80cbaChris Craik        return;
1295b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   }
1296b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1297b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (num_chunks_in < 0)
1298b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   {
1299b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      /* Ignore all unknown chunks and all chunks recognized by
1300b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       * libpng except for IHDR, PLTE, tRNS, IDAT, and IEND
1301b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       */
1302b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      static PNG_CONST png_byte chunks_to_ignore[] = {
1303b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         98,  75,  71,  68, '\0',  /* bKGD */
1304b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         99,  72,  82,  77, '\0',  /* cHRM */
1305b50c217251b086440efcdb273c22f86a06c80cbaChris Craik        103,  65,  77,  65, '\0',  /* gAMA */
1306b50c217251b086440efcdb273c22f86a06c80cbaChris Craik        104,  73,  83,  84, '\0',  /* hIST */
1307b50c217251b086440efcdb273c22f86a06c80cbaChris Craik        105,  67,  67,  80, '\0',  /* iCCP */
1308b50c217251b086440efcdb273c22f86a06c80cbaChris Craik        105,  84,  88, 116, '\0',  /* iTXt */
1309b50c217251b086440efcdb273c22f86a06c80cbaChris Craik        111,  70,  70, 115, '\0',  /* oFFs */
1310b50c217251b086440efcdb273c22f86a06c80cbaChris Craik        112,  67,  65,  76, '\0',  /* pCAL */
1311b50c217251b086440efcdb273c22f86a06c80cbaChris Craik        112,  72,  89, 115, '\0',  /* pHYs */
1312b50c217251b086440efcdb273c22f86a06c80cbaChris Craik        115,  66,  73,  84, '\0',  /* sBIT */
1313b50c217251b086440efcdb273c22f86a06c80cbaChris Craik        115,  67,  65,  76, '\0',  /* sCAL */
1314b50c217251b086440efcdb273c22f86a06c80cbaChris Craik        115,  80,  76,  84, '\0',  /* sPLT */
1315b50c217251b086440efcdb273c22f86a06c80cbaChris Craik        115,  84,  69,  82, '\0',  /* sTER */
1316b50c217251b086440efcdb273c22f86a06c80cbaChris Craik        115,  82,  71,  66, '\0',  /* sRGB */
1317b50c217251b086440efcdb273c22f86a06c80cbaChris Craik        116,  69,  88, 116, '\0',  /* tEXt */
1318b50c217251b086440efcdb273c22f86a06c80cbaChris Craik        116,  73,  77,  69, '\0',  /* tIME */
1319b50c217251b086440efcdb273c22f86a06c80cbaChris Craik        122,  84,  88, 116, '\0'   /* zTXt */
1320b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      };
1321b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1322b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      chunk_list = chunks_to_ignore;
1323b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      num_chunks = (sizeof chunks_to_ignore)/5;
1324b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   }
1325b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1326b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   else /* num_chunks_in > 0 */
1327b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   {
1328b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      if (chunk_list == NULL)
1329b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      {
1330b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         /* Prior to 1.6.0 this was silently ignored, now it is an app_error
1331b50c217251b086440efcdb273c22f86a06c80cbaChris Craik          * which can be switched off.
1332b50c217251b086440efcdb273c22f86a06c80cbaChris Craik          */
1333b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         png_app_error(png_ptr, "png_set_keep_unknown_chunks: no chunk list");
1334b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         return;
1335b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      }
1336b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1337b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      num_chunks = num_chunks_in;
1338b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   }
1339b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1340a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   old_num_chunks = png_ptr->num_chunk_list;
1341b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (png_ptr->chunk_list == NULL)
1342b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      old_num_chunks = 0;
1343b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1344b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   /* Since num_chunks is always restricted to UINT_MAX/5 this can't overflow.
1345b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    */
1346b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (num_chunks + old_num_chunks > UINT_MAX/5)
1347a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   {
1348b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_app_error(png_ptr, "png_set_keep_unknown_chunks: too many chunks");
1349b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      return;
1350b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   }
1351b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1352b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   /* If these chunks are being reset to the default then no more memory is
1353b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * required because add_one_chunk above doesn't extend the list if the 'keep'
1354b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * parameter is the default.
1355b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    */
1356b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (keep)
1357b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   {
1358b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      new_list = png_voidcast(png_bytep, png_malloc(png_ptr,
1359b50c217251b086440efcdb273c22f86a06c80cbaChris Craik          5 * (num_chunks + old_num_chunks)));
1360b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1361b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      if (old_num_chunks > 0)
1362b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         memcpy(new_list, png_ptr->chunk_list, 5*old_num_chunks);
1363b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   }
1364b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1365b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   else if (old_num_chunks > 0)
1366b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      new_list = png_ptr->chunk_list;
1367b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1368b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   else
1369b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      new_list = NULL;
1370b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1371b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   /* Add the new chunks together with each one's handling code.  If the chunk
1372b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * already exists the code is updated, otherwise the chunk is added to the
1373b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * end.  (In libpng 1.6.0 order no longer matters because this code enforces
1374b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * the earlier convention that the last setting is the one that is used.)
1375b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    */
1376b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (new_list != NULL)
1377b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   {
1378b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_const_bytep inlist;
1379b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_bytep outlist;
1380b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      unsigned int i;
1381b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1382b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      for (i=0; i<num_chunks; ++i)
1383b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         old_num_chunks = add_one_chunk(new_list, old_num_chunks,
1384b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            chunk_list+5*i, keep);
1385b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1386b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      /* Now remove any spurious 'default' entries. */
1387b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      num_chunks = 0;
1388b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      for (i=0, inlist=outlist=new_list; i<old_num_chunks; ++i, inlist += 5)
1389b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         if (inlist[4])
1390b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         {
1391b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            if (outlist != inlist)
1392b50c217251b086440efcdb273c22f86a06c80cbaChris Craik               memcpy(outlist, inlist, 5);
1393b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            outlist += 5;
1394b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            ++num_chunks;
1395b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         }
1396b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1397b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      /* This means the application has removed all the specialized handling. */
1398b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      if (num_chunks == 0)
1399b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      {
1400b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         if (png_ptr->chunk_list != new_list)
1401b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            png_free(png_ptr, new_list);
1402b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1403b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         new_list = NULL;
1404b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      }
1405b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   }
1406b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1407b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   else
1408b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      num_chunks = 0;
1409b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1410b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_ptr->num_chunk_list = num_chunks;
1411b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1412b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (png_ptr->chunk_list != new_list)
1413b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   {
1414b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      if (png_ptr->chunk_list != NULL)
1415b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         png_free(png_ptr, png_ptr->chunk_list);
1416b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1417b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_ptr->chunk_list = new_list;
1418a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   }
1419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
14225f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
1423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
1424b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_read_user_chunk_fn(png_structrp png_ptr, png_voidp user_chunk_ptr,
1425b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_user_chunk_ptr read_user_chunk_fn)
1426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
14274215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_read_user_chunk_fn");
14285f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
1429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr == NULL)
1430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
14315f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
1432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->read_user_chunk_fn = read_user_chunk_fn;
1433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->user_chunk_ptr = user_chunk_ptr;
1434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
14375f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_INFO_IMAGE_SUPPORTED
1438893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
1439b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_rows(png_const_structrp png_ptr, png_inforp info_ptr,
1440b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_bytepp row_pointers)
1441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
14424215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(1, "in %s storage function", "rows");
1443893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1444893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr == NULL || info_ptr == NULL)
1445893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
14474215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
1448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
1449b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->row_pointers = row_pointers;
1451b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
14524215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (row_pointers)
1453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->valid |= PNG_INFO_IDAT;
1454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
1458b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_compression_buffer_size(png_structrp png_ptr, png_size_t size)
1459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (png_ptr == NULL)
1461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       return;
1462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1463b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    if (size == 0 || size > PNG_UINT_31_MAX)
1464b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       png_error(png_ptr, "invalid compression buffer size");
1465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1466b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#  ifdef PNG_SEQUENTIAL_READ_SUPPORTED
1467b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      if (png_ptr->mode & PNG_IS_READ_STRUCT)
1468b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      {
1469b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */
1470b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         return;
1471b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      }
1472b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#  endif
1473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1474b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#  ifdef PNG_WRITE_SUPPORTED
1475b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      if (!(png_ptr->mode & PNG_IS_READ_STRUCT))
1476b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      {
1477b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         if (png_ptr->zowner != 0)
1478b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         {
1479b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            png_warning(png_ptr,
1480b50c217251b086440efcdb273c22f86a06c80cbaChris Craik              "Compression buffer size cannot be changed because it is in use");
1481b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            return;
1482b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         }
1483b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1484b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         if (size > ZLIB_IO_MAX)
1485b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         {
1486b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            png_warning(png_ptr,
1487b50c217251b086440efcdb273c22f86a06c80cbaChris Craik               "Compression buffer size limited to system maximum");
1488b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            size = ZLIB_IO_MAX; /* must fit */
1489b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         }
1490b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1491b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         else if (size < 6)
1492b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         {
1493b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH
1494b50c217251b086440efcdb273c22f86a06c80cbaChris Craik             * if this is permitted.
1495b50c217251b086440efcdb273c22f86a06c80cbaChris Craik             */
1496b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            png_warning(png_ptr,
1497b50c217251b086440efcdb273c22f86a06c80cbaChris Craik               "Compression buffer size cannot be reduced below 6");
1498b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            return;
1499b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         }
1500b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1501b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         if (png_ptr->zbuffer_size != size)
1502b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         {
1503b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
1504b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            png_ptr->zbuffer_size = (uInt)size;
1505b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         }
1506b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      }
1507b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#  endif
1508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
1511b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask)
1512893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1513b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (png_ptr && info_ptr)
1514b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      info_ptr->valid &= ~mask;
1515893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1516b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_SET_USER_LIMITS_SUPPORTED
1519a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* This function was added to libpng 1.2.6 */
1520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
1521b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_user_limits (png_structrp png_ptr, png_uint_32 user_width_max,
1522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_uint_32 user_height_max)
1523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1524a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Images with dimensions larger than these limits will be
1525a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    * rejected by png_set_IHDR().  To accept any PNG datastream
1526a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    * regardless of dimensions, set both limits to 0x7ffffffL.
1527a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    */
1528a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   if (png_ptr == NULL)
1529a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      return;
1530b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1531a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   png_ptr->user_width_max = user_width_max;
1532a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   png_ptr->user_height_max = user_height_max;
1533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1534b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1535b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* This function was added to libpng 1.4.0 */
1536b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGAPI
1537b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_chunk_cache_max (png_structrp png_ptr, png_uint_32 user_chunk_cache_max)
1538b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{
1539b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    if (png_ptr)
1540b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       png_ptr->user_chunk_cache_max = user_chunk_cache_max;
1541b50c217251b086440efcdb273c22f86a06c80cbaChris Craik}
1542b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1543b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* This function was added to libpng 1.4.1 */
1544b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGAPI
1545b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_chunk_malloc_max (png_structrp png_ptr,
1546b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    png_alloc_size_t user_chunk_malloc_max)
1547b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{
1548b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (png_ptr)
1549b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
1550b50c217251b086440efcdb273c22f86a06c80cbaChris Craik}
1551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
1552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
15535f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
15545f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_BENIGN_ERRORS_SUPPORTED
15555f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scottvoid PNGAPI
1556b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_benign_errors(png_structrp png_ptr, int allowed)
15575f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott{
15585f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   png_debug(1, "in png_set_benign_errors");
15595f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
1560b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   /* If allowed is 1, png_benign_error() is treated as a warning.
1561b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    *
1562b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * If allowed is 0, png_benign_error() is treated as an error (which
1563b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * is the default behavior if png_set_benign_errors() is not called).
1564b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    */
1565b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
15665f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   if (allowed)
1567b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN |
1568b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN;
1569b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
15705f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   else
1571b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_ptr->flags &= ~(PNG_FLAG_BENIGN_ERRORS_WARN |
1572b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN);
15735f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott}
15745f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#endif /* PNG_BENIGN_ERRORS_SUPPORTED */
1575b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1576b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
1577b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   /* Whether to report invalid palette index; added at libng-1.5.10.
1578b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * It is possible for an indexed (color-type==3) PNG file to contain
1579b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * pixels with invalid (out-of-range) indexes if the PLTE chunk has
1580b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * fewer entries than the image's bit-depth would allow. We recover
1581b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * from this gracefully by filling any incomplete palette with zeroes
1582b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * (opaque black).  By default, when this occurs libpng will issue
1583b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    * a benign error.  This API can be used to override that behavior.
1584b50c217251b086440efcdb273c22f86a06c80cbaChris Craik    */
1585b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGAPI
1586b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_check_for_invalid_index(png_structrp png_ptr, int allowed)
1587b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{
1588b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   png_debug(1, "in png_set_check_for_invalid_index");
1589b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1590b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (allowed > 0)
1591b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_ptr->num_palette_max = 0;
1592b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
1593b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   else
1594b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      png_ptr->num_palette_max = -1;
1595b50c217251b086440efcdb273c22f86a06c80cbaChris Craik}
1596b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif
1597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
1598