12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 */
24
25 /* pngset.c - storage of image information into info struct
26 *
27 * This file is available under and governed by the GNU General Public
28 * License version 2 only, as published by the Free Software Foundation.
29 * However, the following notice accompanied the original version of this
30 * file and, per its terms, should not be removed:
31 *
32 * Last changed in libpng 1.6.26 [October 20, 2016]
33 * Copyright (c) 1998-2016 Glenn Randers-Pehrson
34 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
35 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
36 *
37 * This code is released under the libpng license.
38 * For conditions of distribution and use, see the disclaimer
39 * and license in png.h
40 *
41 * The functions here are used during reads to store data from the file
42 * into the info struct, and during writes to store application data
43 * into the info struct for writing into the file. This abstracts the
44 * info struct and allows us to change the structure in the future.
45 */
46
47 #include "pngpriv.h"
48
49 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
50
51 #ifdef PNG_bKGD_SUPPORTED
52 void PNGAPI
53 png_set_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
145 void PNGAPI
146 png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X,
147 double red_Y, double red_Z, double green_X, double green_Y, double green_Z,
148 double blue_X, double blue_Y, double blue_Z)
149 {
150 png_set_cHRM_XYZ_fixed(png_ptr, info_ptr,
151 png_fixed(png_ptr, red_X, "cHRM Red X"),
152 png_fixed(png_ptr, red_Y, "cHRM Red Y"),
153 png_fixed(png_ptr, red_Z, "cHRM Red Z"),
154 png_fixed(png_ptr, green_X, "cHRM Green X"),
155 png_fixed(png_ptr, green_Y, "cHRM Green Y"),
156 png_fixed(png_ptr, green_Z, "cHRM Green Z"),
157 png_fixed(png_ptr, blue_X, "cHRM Blue X"),
158 png_fixed(png_ptr, blue_Y, "cHRM Blue Y"),
159 png_fixed(png_ptr, blue_Z, "cHRM Blue Z"));
160 }
161 # endif /* FLOATING_POINT */
162
163 #endif /* cHRM */
164
165 #ifdef PNG_gAMA_SUPPORTED
166 void PNGFAPI
167 png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
168 png_fixed_point file_gamma)
169 {
170 png_debug1(1, "in %s storage function", "gAMA");
171
172 if (png_ptr == NULL || info_ptr == NULL)
173 return;
174
175 png_colorspace_set_gamma(png_ptr, &info_ptr->colorspace, file_gamma);
176 png_colorspace_sync_info(png_ptr, info_ptr);
177 }
178
179 # ifdef PNG_FLOATING_POINT_SUPPORTED
180 void PNGAPI
181 png_set_gAMA(png_const_structrp png_ptr, png_inforp info_ptr, double file_gamma)
182 {
183 png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma,
184 "png_set_gAMA"));
1113 if (np->entries == NULL)
1114 {
1115 png_free(png_ptr, np->name);
1116 np->name = NULL;
1117 break;
1118 }
1119
1120 np->nentries = entries->nentries;
1121 /* This multiply can't overflow because png_malloc_array has already
1122 * checked it when doing the allocation.
1123 */
1124 memcpy(np->entries, entries->entries,
1125 (unsigned int)entries->nentries * sizeof (png_sPLT_entry));
1126
1127 /* Note that 'continue' skips the advance of the out pointer and out
1128 * count, so an invalid entry is not added.
1129 */
1130 info_ptr->valid |= PNG_INFO_sPLT;
1131 ++(info_ptr->splt_palettes_num);
1132 ++np;
1133 }
1134 while (++entries, --nentries);
1135
1136 if (nentries > 0)
1137 png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR);
1138 }
1139 #endif /* sPLT */
1140
1141 #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
1142 static png_byte
1143 check_location(png_const_structrp png_ptr, int location)
1144 {
1145 location &= (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT);
1146
1147 /* New in 1.6.0; copy the location and check it. This is an API
1148 * change; previously the app had to use the
1149 * png_set_unknown_chunk_location API below for each chunk.
1150 */
1151 if (location == 0 && (png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
1152 {
1153 /* Write struct, so unknown chunks come from the app */
1154 png_app_warning(png_ptr,
1365 return;
1366 }
1367
1368 if (num_chunks_in <= 0)
1369 {
1370 png_ptr->unknown_default = keep;
1371
1372 /* '0' means just set the flags, so stop here */
1373 if (num_chunks_in == 0)
1374 return;
1375 }
1376
1377 if (num_chunks_in < 0)
1378 {
1379 /* Ignore all unknown chunks and all chunks recognized by
1380 * libpng except for IHDR, PLTE, tRNS, IDAT, and IEND
1381 */
1382 static PNG_CONST png_byte chunks_to_ignore[] = {
1383 98, 75, 71, 68, '\0', /* bKGD */
1384 99, 72, 82, 77, '\0', /* cHRM */
1385 103, 65, 77, 65, '\0', /* gAMA */
1386 104, 73, 83, 84, '\0', /* hIST */
1387 105, 67, 67, 80, '\0', /* iCCP */
1388 105, 84, 88, 116, '\0', /* iTXt */
1389 111, 70, 70, 115, '\0', /* oFFs */
1390 112, 67, 65, 76, '\0', /* pCAL */
1391 112, 72, 89, 115, '\0', /* pHYs */
1392 115, 66, 73, 84, '\0', /* sBIT */
1393 115, 67, 65, 76, '\0', /* sCAL */
1394 115, 80, 76, 84, '\0', /* sPLT */
1395 115, 84, 69, 82, '\0', /* sTER */
1396 115, 82, 71, 66, '\0', /* sRGB */
1397 116, 69, 88, 116, '\0', /* tEXt */
1398 116, 73, 77, 69, '\0', /* tIME */
1399 122, 84, 88, 116, '\0' /* zTXt */
1400 };
1401
1402 chunk_list = chunks_to_ignore;
1403 num_chunks = (unsigned int)/*SAFE*/(sizeof chunks_to_ignore)/5U;
1404 }
1707 #ifdef PNG_WARNINGS_SUPPORTED
1708 png_const_charp orig_key = key;
1709 #endif
1710 png_uint_32 key_len = 0;
1711 int bad_character = 0;
1712 int space = 1;
1713
1714 png_debug(1, "in png_check_keyword");
1715
1716 if (key == NULL)
1717 {
1718 *new_key = 0;
1719 return 0;
1720 }
1721
1722 while (*key && key_len < 79)
1723 {
1724 png_byte ch = (png_byte)*key++;
1725
1726 if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/))
1727 *new_key++ = ch, ++key_len, space = 0;
1728
1729 else if (space == 0)
1730 {
1731 /* A space or an invalid character when one wasn't seen immediately
1732 * before; output just a space.
1733 */
1734 *new_key++ = 32, ++key_len, space = 1;
1735
1736 /* If the character was not a space then it is invalid. */
1737 if (ch != 32)
1738 bad_character = ch;
1739 }
1740
1741 else if (bad_character == 0)
1742 bad_character = ch; /* just skip it, record the first error */
1743 }
1744
1745 if (key_len > 0 && space != 0) /* trailing space */
1746 {
1747 --key_len, --new_key;
1748 if (bad_character == 0)
1749 bad_character = 32;
1750 }
1751
1752 /* Terminate the keyword */
1753 *new_key = 0;
1754
1755 if (key_len == 0)
1756 return 0;
1757
1758 #ifdef PNG_WARNINGS_SUPPORTED
1759 /* Try to only output one warning per keyword: */
1760 if (*key != 0) /* keyword too long */
1761 png_warning(png_ptr, "keyword truncated");
1762
1763 else if (bad_character != 0)
1764 {
1765 PNG_WARNING_PARAMETERS(p)
1766
1767 png_warning_parameter(p, 1, orig_key);
|
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 */
24
25 /* pngset.c - storage of image information into info struct
26 *
27 * This file is available under and governed by the GNU General Public
28 * License version 2 only, as published by the Free Software Foundation.
29 * However, the following notice accompanied the original version of this
30 * file and, per its terms, should not be removed:
31 *
32 * Last changed in libpng 1.6.32 [August 24, 2017]
33 * Copyright (c) 1998-2017 Glenn Randers-Pehrson
34 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
35 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
36 *
37 * This code is released under the libpng license.
38 * For conditions of distribution and use, see the disclaimer
39 * and license in png.h
40 *
41 * The functions here are used during reads to store data from the file
42 * into the info struct, and during writes to store application data
43 * into the info struct for writing into the file. This abstracts the
44 * info struct and allows us to change the structure in the future.
45 */
46
47 #include "pngpriv.h"
48
49 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
50
51 #ifdef PNG_bKGD_SUPPORTED
52 void PNGAPI
53 png_set_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
145 void PNGAPI
146 png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X,
147 double red_Y, double red_Z, double green_X, double green_Y, double green_Z,
148 double blue_X, double blue_Y, double blue_Z)
149 {
150 png_set_cHRM_XYZ_fixed(png_ptr, info_ptr,
151 png_fixed(png_ptr, red_X, "cHRM Red X"),
152 png_fixed(png_ptr, red_Y, "cHRM Red Y"),
153 png_fixed(png_ptr, red_Z, "cHRM Red Z"),
154 png_fixed(png_ptr, green_X, "cHRM Green X"),
155 png_fixed(png_ptr, green_Y, "cHRM Green Y"),
156 png_fixed(png_ptr, green_Z, "cHRM Green Z"),
157 png_fixed(png_ptr, blue_X, "cHRM Blue X"),
158 png_fixed(png_ptr, blue_Y, "cHRM Blue Y"),
159 png_fixed(png_ptr, blue_Z, "cHRM Blue Z"));
160 }
161 # endif /* FLOATING_POINT */
162
163 #endif /* cHRM */
164
165 #ifdef PNG_eXIf_SUPPORTED
166 void PNGAPI
167 png_set_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
168 const png_bytep eXIf_buf)
169 {
170 png_warning(png_ptr, "png_set_eXIf does not work; use png_set_eXIf_1");
171 PNG_UNUSED(info_ptr)
172 PNG_UNUSED(eXIf_buf)
173 }
174
175 void PNGAPI
176 png_set_eXIf_1(png_const_structrp png_ptr, png_inforp info_ptr,
177 const png_uint_32 num_exif, const png_bytep eXIf_buf)
178 {
179 int i;
180
181 png_debug1(1, "in %s storage function", "eXIf");
182
183 if (png_ptr == NULL || info_ptr == NULL)
184 return;
185
186 if (info_ptr->exif)
187 {
188 png_free(png_ptr, info_ptr->exif);
189 info_ptr->exif = NULL;
190 }
191
192 info_ptr->num_exif = num_exif;
193
194 info_ptr->exif = png_voidcast(png_bytep, png_malloc_warn(png_ptr,
195 info_ptr->num_exif));
196
197 if (info_ptr->exif == NULL)
198 {
199 png_warning(png_ptr, "Insufficient memory for eXIf chunk data");
200 return;
201 }
202
203 info_ptr->free_me |= PNG_FREE_EXIF;
204
205 for (i = 0; i < (int) info_ptr->num_exif; i++)
206 info_ptr->exif[i] = eXIf_buf[i];
207
208 info_ptr->valid |= PNG_INFO_eXIf;
209 }
210 #endif /* eXIf */
211
212 #ifdef PNG_gAMA_SUPPORTED
213 void PNGFAPI
214 png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
215 png_fixed_point file_gamma)
216 {
217 png_debug1(1, "in %s storage function", "gAMA");
218
219 if (png_ptr == NULL || info_ptr == NULL)
220 return;
221
222 png_colorspace_set_gamma(png_ptr, &info_ptr->colorspace, file_gamma);
223 png_colorspace_sync_info(png_ptr, info_ptr);
224 }
225
226 # ifdef PNG_FLOATING_POINT_SUPPORTED
227 void PNGAPI
228 png_set_gAMA(png_const_structrp png_ptr, png_inforp info_ptr, double file_gamma)
229 {
230 png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma,
231 "png_set_gAMA"));
1160 if (np->entries == NULL)
1161 {
1162 png_free(png_ptr, np->name);
1163 np->name = NULL;
1164 break;
1165 }
1166
1167 np->nentries = entries->nentries;
1168 /* This multiply can't overflow because png_malloc_array has already
1169 * checked it when doing the allocation.
1170 */
1171 memcpy(np->entries, entries->entries,
1172 (unsigned int)entries->nentries * sizeof (png_sPLT_entry));
1173
1174 /* Note that 'continue' skips the advance of the out pointer and out
1175 * count, so an invalid entry is not added.
1176 */
1177 info_ptr->valid |= PNG_INFO_sPLT;
1178 ++(info_ptr->splt_palettes_num);
1179 ++np;
1180 ++entries;
1181 }
1182 while (--nentries);
1183
1184 if (nentries > 0)
1185 png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR);
1186 }
1187 #endif /* sPLT */
1188
1189 #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
1190 static png_byte
1191 check_location(png_const_structrp png_ptr, int location)
1192 {
1193 location &= (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT);
1194
1195 /* New in 1.6.0; copy the location and check it. This is an API
1196 * change; previously the app had to use the
1197 * png_set_unknown_chunk_location API below for each chunk.
1198 */
1199 if (location == 0 && (png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
1200 {
1201 /* Write struct, so unknown chunks come from the app */
1202 png_app_warning(png_ptr,
1413 return;
1414 }
1415
1416 if (num_chunks_in <= 0)
1417 {
1418 png_ptr->unknown_default = keep;
1419
1420 /* '0' means just set the flags, so stop here */
1421 if (num_chunks_in == 0)
1422 return;
1423 }
1424
1425 if (num_chunks_in < 0)
1426 {
1427 /* Ignore all unknown chunks and all chunks recognized by
1428 * libpng except for IHDR, PLTE, tRNS, IDAT, and IEND
1429 */
1430 static PNG_CONST png_byte chunks_to_ignore[] = {
1431 98, 75, 71, 68, '\0', /* bKGD */
1432 99, 72, 82, 77, '\0', /* cHRM */
1433 101, 88, 73, 102, '\0', /* eXIf */
1434 103, 65, 77, 65, '\0', /* gAMA */
1435 104, 73, 83, 84, '\0', /* hIST */
1436 105, 67, 67, 80, '\0', /* iCCP */
1437 105, 84, 88, 116, '\0', /* iTXt */
1438 111, 70, 70, 115, '\0', /* oFFs */
1439 112, 67, 65, 76, '\0', /* pCAL */
1440 112, 72, 89, 115, '\0', /* pHYs */
1441 115, 66, 73, 84, '\0', /* sBIT */
1442 115, 67, 65, 76, '\0', /* sCAL */
1443 115, 80, 76, 84, '\0', /* sPLT */
1444 115, 84, 69, 82, '\0', /* sTER */
1445 115, 82, 71, 66, '\0', /* sRGB */
1446 116, 69, 88, 116, '\0', /* tEXt */
1447 116, 73, 77, 69, '\0', /* tIME */
1448 122, 84, 88, 116, '\0' /* zTXt */
1449 };
1450
1451 chunk_list = chunks_to_ignore;
1452 num_chunks = (unsigned int)/*SAFE*/(sizeof chunks_to_ignore)/5U;
1453 }
1756 #ifdef PNG_WARNINGS_SUPPORTED
1757 png_const_charp orig_key = key;
1758 #endif
1759 png_uint_32 key_len = 0;
1760 int bad_character = 0;
1761 int space = 1;
1762
1763 png_debug(1, "in png_check_keyword");
1764
1765 if (key == NULL)
1766 {
1767 *new_key = 0;
1768 return 0;
1769 }
1770
1771 while (*key && key_len < 79)
1772 {
1773 png_byte ch = (png_byte)*key++;
1774
1775 if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/))
1776 {
1777 *new_key++ = ch; ++key_len; space = 0;
1778 }
1779
1780 else if (space == 0)
1781 {
1782 /* A space or an invalid character when one wasn't seen immediately
1783 * before; output just a space.
1784 */
1785 *new_key++ = 32; ++key_len; space = 1;
1786
1787 /* If the character was not a space then it is invalid. */
1788 if (ch != 32)
1789 bad_character = ch;
1790 }
1791
1792 else if (bad_character == 0)
1793 bad_character = ch; /* just skip it, record the first error */
1794 }
1795
1796 if (key_len > 0 && space != 0) /* trailing space */
1797 {
1798 --key_len; --new_key;
1799 if (bad_character == 0)
1800 bad_character = 32;
1801 }
1802
1803 /* Terminate the keyword */
1804 *new_key = 0;
1805
1806 if (key_len == 0)
1807 return 0;
1808
1809 #ifdef PNG_WARNINGS_SUPPORTED
1810 /* Try to only output one warning per keyword: */
1811 if (*key != 0) /* keyword too long */
1812 png_warning(png_ptr, "keyword truncated");
1813
1814 else if (bad_character != 0)
1815 {
1816 PNG_WARNING_PARAMETERS(p)
1817
1818 png_warning_parameter(p, 1, orig_key);
|