1
2 /* pngwrite.c - general routines to write a PNG file
3 *
4 * Last changed in libpng 1.7.0 [(PENDING RELEASE)]
5 * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8 *
9 * This code is released under the libpng license.
10 * For conditions of distribution and use, see the disclaimer
11 * and license in png.h
12 */
13
14 #include "pngpriv.h"
15 #ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
16 # include <errno.h>
17 #endif /* SIMPLIFIED_WRITE_STDIO */
18
19 #define PNG_SRC_FILE PNG_SRC_FILE_pngwrite
20
21 #ifdef PNG_WRITE_SUPPORTED
22
23 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
24 /* Write out all the unknown chunks for the current given location */
25 static void
write_unknown_chunks(png_structrp png_ptr,png_const_inforp info_ptr,unsigned int where)26 write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr,
27 unsigned int where)
28 {
29 if (info_ptr->unknown_chunks_num != 0)
30 {
31 png_const_unknown_chunkp up;
32
33 png_debug(5, "writing extra chunks");
34
35 for (up = info_ptr->unknown_chunks;
36 up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
37 ++up)
38 if ((up->location & where) != 0)
39 {
40 /* If per-chunk unknown chunk handling is enabled use it, otherwise
41 * just write the chunks the application has set.
42 */
43 #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
44 int keep = png_handle_as_unknown(png_ptr, up->name);
45
46 /* NOTE: this code is radically different from the read side in the
47 * matter of handling an ancillary unknown chunk. In the read side
48 * the default behavior is to discard it, in the code below the default
49 * behavior is to write it. Critical chunks are, however, only
50 * written if explicitly listed or if the default is set to write all
51 * unknown chunks.
52 *
53 * The default handling is also slightly weird - it is not possible to
54 * stop the writing of all unsafe-to-copy chunks!
55 *
56 * TODO: REVIEW: this would seem to be a bug.
57 */
58 if (keep != PNG_HANDLE_CHUNK_NEVER &&
59 ((up->name[3] & 0x20) /* safe-to-copy overrides everything */ ||
60 keep == PNG_HANDLE_CHUNK_ALWAYS ||
61 (keep == PNG_HANDLE_CHUNK_AS_DEFAULT &&
62 png_ptr->unknown_default == PNG_HANDLE_CHUNK_ALWAYS)))
63 #endif
64 png_write_chunk(png_ptr, up->name, up->data, up->size);
65 }
66 }
67 }
68 #endif /* WRITE_UNKNOWN_CHUNKS */
69
70 #ifdef PNG_WRITE_TEXT_SUPPORTED
71 static void
png_write_text(png_structrp png_ptr,png_const_inforp info_ptr,png_byte where)72 png_write_text(png_structrp png_ptr, png_const_inforp info_ptr, png_byte where)
73 /* Text chunk helper */
74 {
75 int i;
76
77 /* Check to see if we need to write text chunks */
78 for (i = 0; i < info_ptr->num_text; i++)
79 {
80 png_debug2(2, "Writing text chunk %d, type %d", i,
81 info_ptr->text[i].compression);
82
83 /* Text chunks are written at info_ptr->text[i].location, skip the chunk
84 * if we are not writing at that location:
85 */
86 if ((info_ptr->text[i].location & where) == 0U)
87 continue;
88
89 switch (info_ptr->text[i].compression)
90 {
91 case PNG_ITXT_COMPRESSION_NONE:
92 case PNG_ITXT_COMPRESSION_zTXt:
93 # ifdef PNG_WRITE_iTXt_SUPPORTED
94 /* Write international chunk */
95 png_write_iTXt(png_ptr, info_ptr->text[i].compression,
96 info_ptr->text[i].key, info_ptr->text[i].lang,
97 info_ptr->text[i].lang_key, info_ptr->text[i].text);
98 # else /* !WRITE_iTXT */
99 png_app_error(png_ptr, "Unable to write international text");
100 # endif /* !WRITE_iTXT */
101 break;
102
103 case PNG_TEXT_COMPRESSION_zTXt:
104 # ifdef PNG_WRITE_zTXt_SUPPORTED
105 /* Write compressed chunk */
106 png_write_zTXt(png_ptr, info_ptr->text[i].key,
107 info_ptr->text[i].text, info_ptr->text[i].compression);
108 # else /* !WRITE_zTXT */
109 png_app_error(png_ptr, "Unable to write compressed text");
110 # endif /* !WRITE_zTXT */
111 break;
112
113 case PNG_TEXT_COMPRESSION_NONE:
114 # ifdef PNG_WRITE_tEXt_SUPPORTED
115 /* Write uncompressed chunk */
116 png_write_tEXt(png_ptr, info_ptr->text[i].key,
117 info_ptr->text[i].text, 0);
118 # else /* !WRITE_tEXt */
119 /* Can't get here TODO: why not? */
120 png_app_error(png_ptr, "Unable to write uncompressed text");
121 # endif /* !WRITE_tEXt */
122 break;
123
124 default:
125 /* This is an internal error because the libpng checking should
126 * never manage to set any 'compression' except the above values.
127 */
128 impossible("invalid text compression");
129 }
130
131 /* The chunk was written, record where. This allows the location to have
132 * multiple bits set; the first successful write freezes the location.
133 */
134 info_ptr->text[i].location = where;
135 }
136 }
137 #endif /* WRITE_TEXT */
138
139 /* Writes all the PNG information. This is the suggested way to use the
140 * library. If you have a new chunk to add, make a function to write it,
141 * and put it in the correct location here. If you want the chunk written
142 * after the image data, put it in png_write_end(). I strongly encourage
143 * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing
144 * the chunk, as that will keep the code from breaking if you want to just
145 * write a plain PNG file. If you have long comments, I suggest writing
146 * them in png_write_end(), and compressing them.
147 */
148 void PNGAPI
png_write_info_before_PLTE(png_structrp png_ptr,png_const_inforp info_ptr)149 png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr)
150 {
151 png_debug(1, "in png_write_info_before_PLTE");
152
153 if (png_ptr == NULL || info_ptr == NULL)
154 return;
155
156 if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
157 {
158 int color_type = PNG_COLOR_TYPE_FROM_FORMAT(info_ptr->format);
159
160 /* Write PNG signature; doesn't set PNG_HAVE_PNG_SIGNATURE if it has
161 * already been written (or rather, if at least 3 bytes have already been
162 * written; undocumented wackiness, it means the 'PNG' at the start can be
163 * replace by, e.g. "FOO" or "BAR" or "MNG").
164 */
165 png_write_sig(png_ptr);
166
167 # ifdef PNG_MNG_FEATURES_SUPPORTED
168 if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 &&
169 png_ptr->mng_features_permitted != 0)
170 {
171 png_app_error(png_ptr,
172 "MNG features are not allowed in a PNG datastream");
173 /* Recovery: disable MNG features: */
174 png_ptr->mng_features_permitted = 0;
175 }
176 # endif /* MNG_FEATURES */
177
178 /* Write IHDR information. */
179 png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
180 info_ptr->bit_depth, color_type, info_ptr->compression_type,
181 info_ptr->filter_type, info_ptr->interlace_type);
182
183 # ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
184 /* This are used for checking later on: */
185 png_ptr->info_format = info_ptr->format;
186 # endif /* WRITE_TRANSFORMS */
187
188 /* This sets the flag that prevents re-entry to the 'before PLTE' case: */
189 affirm((png_ptr->mode & PNG_HAVE_IHDR) != 0);
190
191 /* The rest of these check to see if the valid field has the appropriate
192 * flag set, and if it does, writes the chunk.
193 *
194 * 1.6.0: COLORSPACE support controls the writing of these chunks too, and
195 * the chunks will be written if the WRITE routine is there and
196 * information is available in the COLORSPACE. (See
197 * png_colorspace_sync_info in png.c for where the valid flags get set.)
198 *
199 * Under certain circumstances the colorspace can be invalidated without
200 * syncing the info_struct 'valid' flags; this happens if libpng detects
201 * an error and calls png_error while the color space is being set, yet
202 * the application continues writing the PNG. So check the 'invalid'
203 * flag here too.
204 */
205 # ifdef PNG_WRITE_tIME_SUPPORTED
206 if ((info_ptr->valid & PNG_INFO_tIME) != 0 &&
207 (info_ptr->time_location & PNG_HAVE_IHDR) != 0)
208 png_write_tIME(png_ptr, &(info_ptr->mod_time));
209 # endif /* WRITE_tIME */
210
211 # ifdef PNG_WRITE_gAMA_SUPPORTED /* enables GAMMA */
212 if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&
213 (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_gAMA) != 0 &&
214 (info_ptr->valid & PNG_INFO_gAMA) != 0)
215 {
216 /* This is the inverse of the test in png.c: */
217 affirm(info_ptr->colorspace.gamma >= 16 &&
218 info_ptr->colorspace.gamma <= 625000000);
219 png_write_gAMA_fixed(png_ptr, info_ptr->colorspace.gamma);
220 }
221 # endif /* WRITE_gAMA */
222
223 /* Write only one of sRGB or an ICC profile. If a profile was supplied
224 * and it matches one of the known sRGB ones issue a warning.
225 */
226 # ifdef PNG_WRITE_iCCP_SUPPORTED /* enables COLORSPACE, GAMMA */
227 if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&
228 (info_ptr->valid & PNG_INFO_iCCP) != 0)
229 {
230 # ifdef PNG_WRITE_sRGB_SUPPORTED
231 /* The app must have supplied an sRGB iCCP profile (and one that
232 * is recognized and therefore known to be correct) so we write
233 * that profile, even though it increases the size of the PNG
234 * significantly. A warning is reasonable:
235 */
236 if ((info_ptr->valid & PNG_INFO_sRGB) != 0)
237 png_app_warning(png_ptr,
238 "profile matches sRGB but writing iCCP instead");
239 # endif /* WRITE_sRGB */
240
241 png_write_iCCP(png_ptr, info_ptr->iccp_name,
242 info_ptr->iccp_profile);
243 }
244 # ifdef PNG_WRITE_sRGB_SUPPORTED
245 else /* iCCP not written */
246 # endif /* WRITE_sRGB */
247 # endif /* WRITE_iCCP */
248
249 # ifdef PNG_WRITE_sRGB_SUPPORTED /* enables COLORSPACE, GAMMA */
250 if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&
251 (info_ptr->valid & PNG_INFO_sRGB) != 0)
252 png_write_sRGB(png_ptr, info_ptr->colorspace.rendering_intent);
253 # endif /* WRITE_sRGB */
254
255 # ifdef PNG_WRITE_sBIT_SUPPORTED
256 if ((info_ptr->valid & PNG_INFO_sBIT) != 0)
257 png_write_sBIT(png_ptr, &(info_ptr->sig_bit), color_type);
258 # endif /* WRITE_sBIT */
259
260 # ifdef PNG_WRITE_cHRM_SUPPORTED /* enables COLORSPACE */
261 if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&
262 (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0 &&
263 (info_ptr->valid & PNG_INFO_cHRM) != 0)
264 png_write_cHRM_fixed(png_ptr, &info_ptr->colorspace.end_points_xy);
265 # endif /* WRITE_cHRM */
266
267 # ifdef PNG_WRITE_TEXT_SUPPORTED
268 if (info_ptr->num_text > 0)
269 png_write_text(png_ptr, info_ptr, PNG_HAVE_IHDR);
270 # endif /* WRITE_TEXT */
271
272 # ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
273 /* The third arugment must encode only one bit, otherwise chunks will
274 * be written twice because the test in write_unknown_chunks is
275 * 'location & where'.
276 */
277 write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_IHDR);
278 # endif
279 }
280
281 else /* 1.7.0: flag multiple calls; previously ignored */
282 png_app_error(png_ptr,
283 "png_write_info_before_PLTE called more than once");
284 }
285
286 void PNGAPI
png_write_info(png_structrp png_ptr,png_const_inforp info_ptr)287 png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
288 {
289 png_debug(1, "in png_write_info");
290
291 if (png_ptr == NULL || info_ptr == NULL)
292 return;
293
294 if ((png_ptr->mode & (PNG_HAVE_PLTE+PNG_HAVE_IDAT)) != 0)
295 {
296 png_app_error(png_ptr, "late call to png_write_info");
297 return;
298 }
299
300 /* The app may do this for us, and in 1.7.0 multiple calls are flagged as an
301 * application error, so this code must check:
302 */
303 if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
304 png_write_info_before_PLTE(png_ptr, info_ptr);
305
306 if ((info_ptr->valid & PNG_INFO_PLTE) != 0)
307 png_write_PLTE(png_ptr, info_ptr->palette, info_ptr->num_palette);
308
309 /* Validate the consistency of the PNG being produced; a palette must have
310 * been written if a palette mapped PNG is to be valid:
311 */
312 if ((png_ptr->mode & PNG_HAVE_PLTE) == 0 &&
313 png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
314 png_error(png_ptr, "Valid palette required for paletted images");
315
316 /* But always set the mode flag because without this we don't know when to
317 * write the post-palette text or unknown chunks.
318 */
319 png_ptr->mode |= PNG_HAVE_PLTE;
320
321 # ifdef PNG_WRITE_tRNS_SUPPORTED
322 if ((info_ptr->valid & PNG_INFO_tRNS) !=0)
323 {
324 png_write_tRNS(png_ptr, info_ptr->trans_alpha,
325 &(info_ptr->trans_color), info_ptr->num_trans,
326 PNG_COLOR_TYPE_FROM_FORMAT(info_ptr->format));
327 }
328 # endif /* WRITE_tRNS */
329
330 # ifdef PNG_WRITE_bKGD_SUPPORTED
331 if ((info_ptr->valid & PNG_INFO_bKGD) != 0)
332 png_write_bKGD(png_ptr, &(info_ptr->background),
333 PNG_COLOR_TYPE_FROM_FORMAT(info_ptr->format));
334 # endif /* WRITE_bKGD */
335
336 # ifdef PNG_WRITE_hIST_SUPPORTED
337 if ((info_ptr->valid & PNG_INFO_hIST) != 0)
338 png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
339 # endif /* WRITE_hIST */
340
341 # ifdef PNG_WRITE_oFFs_SUPPORTED
342 if ((info_ptr->valid & PNG_INFO_oFFs) != 0)
343 png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset,
344 info_ptr->offset_unit_type);
345 # endif /* WRITE_oFFs */
346
347 # ifdef PNG_WRITE_pCAL_SUPPORTED
348 if ((info_ptr->valid & PNG_INFO_pCAL) != 0)
349 png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0,
350 info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams,
351 info_ptr->pcal_units, info_ptr->pcal_params);
352 # endif /* WRITE_pCAL */
353
354 # ifdef PNG_WRITE_sCAL_SUPPORTED
355 if ((info_ptr->valid & PNG_INFO_sCAL) != 0)
356 png_write_sCAL_s(png_ptr, info_ptr->scal_unit, info_ptr->scal_s_width,
357 info_ptr->scal_s_height);
358 # endif /* WRITE_sCAL */
359
360 # ifdef PNG_WRITE_pHYs_SUPPORTED
361 if ((info_ptr->valid & PNG_INFO_pHYs) != 0)
362 png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,
363 info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type);
364 # endif /* WRITE_pHYs */
365
366 # ifdef PNG_WRITE_tIME_SUPPORTED
367 if ((info_ptr->valid & PNG_INFO_tIME) != 0 &&
368 (info_ptr->time_location & PNG_HAVE_PLTE) != 0)
369 png_write_tIME(png_ptr, &(info_ptr->mod_time));
370 # endif /* WRITE_tIME */
371
372 # ifdef PNG_WRITE_sPLT_SUPPORTED
373 if ((info_ptr->valid & PNG_INFO_sPLT) != 0)
374 {
375 int i;
376
377 for (i = 0; i < info_ptr->splt_palettes_num; i++)
378 png_write_sPLT(png_ptr, info_ptr->splt_palettes + i);
379 }
380 # endif /* WRITE_sPLT */
381
382 # ifdef PNG_WRITE_TEXT_SUPPORTED
383 if (info_ptr->num_text > 0)
384 png_write_text(png_ptr, info_ptr, PNG_HAVE_PLTE);
385 # endif /* WRITE_TEXT */
386
387 # ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
388 write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_PLTE);
389 # endif /* WRITE_UNKNOWN_CHUNKS */
390 }
391
392 /* Writes the end of the PNG file. If you don't want to write comments or
393 * time information, you can pass NULL for info. If you already wrote these
394 * in png_write_info(), do not write them again here. If you have long
395 * comments, I suggest writing them here, and compressing them.
396 */
397 void PNGAPI
png_write_end(png_structrp png_ptr,png_inforp info_ptr)398 png_write_end(png_structrp png_ptr, png_inforp info_ptr)
399 {
400 png_debug(1, "in png_write_end");
401
402 if (png_ptr == NULL)
403 return;
404
405 if ((png_ptr->mode &
406 (PNG_HAVE_IHDR+PNG_HAVE_IDAT+PNG_AFTER_IDAT+PNG_HAVE_IEND)) !=
407 (PNG_HAVE_IHDR+PNG_HAVE_IDAT+PNG_AFTER_IDAT))
408 {
409 /* Out of place png_write_end: */
410 if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
411 png_error(png_ptr, "Missing call to png_write_info");
412
413 else if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 && png_ptr->zowner == 0)
414 {
415 /* TODO: write unknown IDAT here, for the moment allow the app to write
416 * IDAT then call write_end:
417 */
418 png_app_error(png_ptr, "No IDATs written into file");
419 png_ptr->mode |= PNG_HAVE_IDAT+PNG_AFTER_IDAT;
420 }
421
422 else if ((png_ptr->mode & PNG_AFTER_IDAT) == 0)
423 {
424 affirm(png_ptr->zowner == png_IDAT);
425 png_error(png_ptr, "incomplete PNG image"); /* unrecoverable */
426 }
427
428 else if ((png_ptr->mode & PNG_HAVE_IEND) != 0)
429 {
430 png_app_error(png_ptr, "multiple calls to png_write_end");
431 return;
432 }
433
434 else
435 impossible("not reached");
436 }
437
438 /* And double check that the image rows were all written; this is actually
439 * a harmless error on an interlaced image because the image rows with
440 * data were all passed in or the above check would not work.
441 *
442 * Don't do this if the IDAT came from unknowns (TBD) or the app, above.
443 *
444 * The check depends on the precise logic in png_write_row.
445 */
446 else if (png_ptr->pass != 7U)
447 png_app_error(png_ptr, "png_write_row not called to last row");
448
449 else
450 debug(png_ptr->row_number == 0U);
451
452 /* See if user wants us to write information chunks */
453 if (info_ptr != NULL)
454 {
455 # ifdef PNG_WRITE_tIME_SUPPORTED
456 /* Check to see if user has supplied a time chunk */
457 if ((info_ptr->valid & PNG_INFO_tIME) != 0 &&
458 (info_ptr->time_location & PNG_AFTER_IDAT) != 0)
459 png_write_tIME(png_ptr, &(info_ptr->mod_time));
460 # endif
461
462 # ifdef PNG_WRITE_TEXT_SUPPORTED
463 if (info_ptr->num_text > 0)
464 png_write_text(png_ptr, info_ptr, PNG_AFTER_IDAT);
465 # endif /* WRITE_TEXT */
466
467 # ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
468 write_unknown_chunks(png_ptr, info_ptr, PNG_AFTER_IDAT);
469 # endif
470 }
471
472 /* Write end of PNG file */
473 png_write_IEND(png_ptr);
474
475 /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03,
476 * and restored again in libpng-1.2.30, may cause some applications that
477 * do not set png_ptr->output_flush_fn to crash. If your application
478 * experiences a problem, please try building libpng with
479 * PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED defined, and report the event to
480 * png-mng-implement at lists.sf.net .
481 */
482 # ifdef PNG_WRITE_FLUSH_SUPPORTED
483 # ifdef PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED
484 if (png_ptr->output_flush_fn != NULL)
485 png_ptr->output_flush_fn(png_ptr);
486 # endif
487 # endif
488 }
489
490 #ifdef PNG_CONVERT_tIME_SUPPORTED
491 void PNGAPI
png_convert_from_struct_tm(png_timep ptime,PNG_CONST struct tm * ttime)492 png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm * ttime)
493 {
494 png_debug(1, "in png_convert_from_struct_tm");
495
496 ptime->year = png_check_u16(0/*TODO: fixme*/, 1900 + ttime->tm_year);
497 ptime->month = png_check_byte(0/*TODO: fixme*/, ttime->tm_mon + 1);
498 ptime->day = png_check_byte(0/*TODO: fixme*/, ttime->tm_mday);
499 ptime->hour = png_check_byte(0/*TODO: fixme*/, ttime->tm_hour);
500 ptime->minute = png_check_byte(0/*TODO: fixme*/, ttime->tm_min);
501 ptime->second = png_check_byte(0/*TODO: fixme*/, ttime->tm_sec);
502 }
503
504 void PNGAPI
png_convert_from_time_t(png_timep ptime,time_t ttime)505 png_convert_from_time_t(png_timep ptime, time_t ttime)
506 {
507 struct tm *tbuf;
508
509 png_debug(1, "in png_convert_from_time_t");
510
511 tbuf = gmtime(&ttime);
512 png_convert_from_struct_tm(ptime, tbuf);
513 }
514 #endif
515
516 /* Initialize png_ptr structure, and allocate any memory needed */
517 PNG_FUNCTION(png_structp,PNGAPI
518 png_create_write_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
519 png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)
520 {
521 #ifndef PNG_USER_MEM_SUPPORTED
522 png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
523 error_fn, warn_fn, NULL, NULL, NULL);
524 #else
525 return png_create_write_struct_2(user_png_ver, error_ptr, error_fn,
526 warn_fn, NULL, NULL, NULL);
527 }
528
529 /* Alternate initialize png_ptr structure, and allocate any memory needed */
530 PNG_FUNCTION(png_structp,PNGAPI
531 png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
532 png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
533 png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
534 {
535 png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
536 error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
537 #endif /* USER_MEM */
538
539 if (png_ptr != NULL)
540 {
541 # ifdef PNG_BENIGN_ERRORS_SUPPORTED
542 # if !PNG_RELEASE_BUILD
543 /* Always quit on error prior to release */
544 png_ptr->benign_error_action = PNG_ERROR;
545 png_ptr->app_warning_action = PNG_WARN;
546 png_ptr->app_error_action = PNG_ERROR;
547 # else /* RELEASE_BUILD */
548 /* Allow benign errors on write, subject to app control. */
549 # ifdef PNG_BENIGN_WRITE_ERRORS_SUPPORTED
550 png_ptr->benign_error_action = PNG_WARN;
551 png_ptr->app_error_action = PNG_WARN;
552 png_ptr->app_warning_action = PNG_WARN;
553 # else /* !BENIGN_WRITE_ERRORS */
554 /* libpng build without benign error support; the application
555 * author has to be assumed to be correct, so:
556 */
557 png_ptr->benign_error_action = PNG_ERROR;
558 png_ptr->app_warning_action = PNG_WARN;
559 png_ptr->app_error_action = PNG_ERROR;
560 # endif /* !BENIGN_WRITE_ERRORS */
561 # endif /* RELEASE_BUILD */
562 # endif /* BENIGN_ERRORS */
563 }
564
565 return png_ptr;
566 }
567
568
569 #if defined(PNG_WRITE_INTERLACING_SUPPORTED) ||\
570 defined(PNG_WRITE_TRANSFORMS_SUPPORTED)
571 static void
write_row_buffered(png_structrp png_ptr,png_const_bytep row,unsigned int row_info_flags,void (* copy_fn)(png_const_structrp png_ptr,png_bytep row_buffer,png_const_bytep row,png_uint_32 x,unsigned int count,unsigned int p),unsigned int copy_parameter)572 write_row_buffered(png_structrp png_ptr,
573 png_const_bytep row, unsigned int row_info_flags,
574 void (*copy_fn)(png_const_structrp png_ptr, png_bytep row_buffer,
575 png_const_bytep row, png_uint_32 x, unsigned int count, unsigned int p),
576 unsigned int copy_parameter)
577 {
578 unsigned int max_pixels = png_max_pixel_block(png_ptr);
579 const unsigned int pass = png_ptr->pass;
580 const png_uint_32 width = png_ptr->interlaced == PNG_INTERLACE_NONE ?
581 png_ptr->width : PNG_PASS_COLS(png_ptr->width, pass);
582 png_uint_32 x;
583 png_byte prev_pixels[4*2*2]; /* 2 pixels up to 4 2-byte channels each */
584
585 memset(prev_pixels, 0U, sizeof prev_pixels);
586
587 for (x = 0U; x < width; x += max_pixels)
588 {
589 union
590 {
591 PNG_ROW_BUFFER_ALIGN_TYPE force_buffer_alignment;
592 png_byte buffer[PNG_ROW_BUFFER_SIZE];
593 } pixel_buffer;
594
595 if (max_pixels > width - x)
596 max_pixels = (unsigned int)/*SAFE*/(width - x);
597
598 debug((row_info_flags & png_row_end) == 0U); /* must be set here at end */
599 if (x + max_pixels >= width)
600 row_info_flags |= png_row_end;
601
602 /* Copy a block of input pixels into the buffer, effecting the interlace
603 * on the way if required. The argument is the number of pixels in the
604 * buffer, not the number handled from the input which will be larger in
605 * the interlaced case.
606 */
607 copy_fn(png_ptr, pixel_buffer.buffer, row, x, max_pixels, copy_parameter);
608
609 /* Now pixel_buffer[0..max_pixels-1] contains max_pixels pixels which may
610 * need to be transformed (the interlace has already been handled).
611 */
612 # ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
613 if (png_ptr->transform_list != NULL)
614 {
615 png_transform_control tc;
616
617 /* The initial values are the memory format; this was worked out in
618 * png_init_row_info below.
619 */
620 memset(&tc, 0, sizeof tc);
621 tc.png_ptr = png_ptr;
622 tc.sp = tc.dp = pixel_buffer.buffer;
623
624 tc.width = max_pixels; /* width of block that we have */
625 tc.format = png_ptr->row_format;
626 tc.range = png_ptr->row_range;
627 tc.bit_depth = png_ptr->row_bit_depth;
628 /* tc.init == 0 */
629 /* tc.caching: not used */
630 /* tc.palette: not used */
631 debug(PNG_TC_PIXEL_DEPTH(tc) == png_ptr->row_input_pixel_depth);
632
633 /* Run the list. */
634 png_run_transform_list_backwards(png_ptr, &tc);
635
636 /* Make sure the format that resulted is compatible with PNG: */
637 affirm((tc.format & PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA +
638 PNG_FORMAT_FLAG_COLOR + PNG_FORMAT_FLAG_LINEAR +
639 PNG_FORMAT_FLAG_COLORMAP)) == 0);
640
641 /* Now we must have the PNG format from the IHDR: */
642 affirm(png_ptr->bit_depth == tc.bit_depth &&
643 png_ptr->color_type == PNG_COLOR_TYPE_FROM_FORMAT(tc.format));
644 }
645 # endif /* WRITE_TRANSFORMS */
646
647 /* Call png_write_png_data to write this block of data, the test on
648 * maxpixels says if this is the final block in the row.
649 */
650 png_write_png_data(png_ptr, prev_pixels, pixel_buffer.buffer, x,
651 max_pixels, row_info_flags);
652 }
653 }
654 #endif /* WRITE { INTERLACING || TRANSFORMS } */
655
656 #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
657 static void
copy_row(png_const_structrp png_ptr,png_bytep row_buffer,png_const_bytep row,png_uint_32 x,unsigned int count,unsigned int pixel_depth)658 copy_row(png_const_structrp png_ptr, png_bytep row_buffer,
659 png_const_bytep row, png_uint_32 x, unsigned int count,
660 unsigned int pixel_depth)
661 {
662 /* Copy row[x..x+count] pixels to row_buffer. */
663 png_copy_row(png_ptr, row_buffer, row, x, count, pixel_depth, 1/*clear*/,
664 0/* x_in_dest; row[x]->row_buffer */);
665 }
666 #endif /* WRITE_TRANSFORMS */
667
668 #ifdef PNG_WRITE_INTERLACING_SUPPORTED
669 static void
interlace_row_lbd(png_const_structrp png_ptr,png_bytep dp,png_const_bytep sp,png_uint_32 x,unsigned int count,const unsigned int B)670 interlace_row_lbd(png_const_structrp png_ptr, png_bytep dp, png_const_bytep sp,
671 png_uint_32 x, unsigned int count, const unsigned int B)
672 {
673 /* Pick out the correct pixels for the interlace pass. The basic idea here
674 * is to go through the row with a source pointer and a destination pointer
675 * (sp and dp), and copy the correct pixels for the pass. As the row gets
676 * compacted, sp will always be >= dp, so we should never overwrite anything.
677 * See the default: case for the easiest code to understand.
678 */
679 const unsigned int pass = png_ptr->pass;
680 png_uint_32 i = PNG_COL_FROM_PASS_COL(x, pass);
681 const unsigned int inc = PNG_PASS_COL_OFFSET(pass);
682
683 /* For pixels less than one byte wide the correct pixels have to be
684 * extracted from the input bytes. Because we are reading data in
685 * the application memory format we cannot rely on the PNG big
686 * endian order. Notice that this was apparently broken before
687 * 1.7.0.
688 *
689 * In libpng 1.7.0 libpng uses a classic bit-pump to optimize the
690 * extraction. In all passes before the last (6/7) no two pixels
691 * are adjacent in the input, so we are always extracting 1 bit.
692 * At present the code uses an 8-bit buffer to avoid coding for
693 * different byte sexes, but this could easily be changed.
694 *
695 * 'i' is the bit-index of bit in the input (sp[]), so,
696 * considering the 1-bit per pixel case, sp[i>>3] is the byte
697 * and the bit is bit (i&7) (0 lowest) on swapped (little endian)
698 * data or 7-(i&7) on PNG default (big-endian) data.
699 *
700 * Define these macros, where:
701 *
702 * B: the log2 bit depth (0, 1, 2 for 1bpp, 2bpp or 4bpp) of
703 * the data; this should be a constant.
704 * sp: the source pointer (sp) (a png_const_bytep)
705 * i: the pixel index in the input (png_uint_32)
706 * j: the bit index in the output (unsigned int)
707 *
708 * Unlike 'i', 'j' is interpreted directly; for LSB bytes it counts
709 * up, for MSB it counts down.
710 *
711 * NOTE: this could all be expanded to eliminate the code below by
712 * the time honoured copy'n'paste into three separate functions. This
713 * might be worth doing in the future.
714 */
715 # define PIXEL_MASK ((1U << (1<<B))-1U)
716 # define BIT_MASK ((1U << (3-(B)))-1U) /* within a byte */
717 # define SP_BYTE (sp[i>>(3-(B))]) /* byte to use */
718 # define SP_OFFSET_LSB ((BIT_MASK & i) << (B))
719 # define SP_OFFSET_MSB ((BIT_MASK & ~i) << (B))
720 # define SP_PIXEL(sex) ((SP_BYTE >> SP_OFFSET_ ## sex) & PIXEL_MASK)
721 {
722 unsigned int j;
723 unsigned int d;
724
725 /* The data is always in the PNG, big-endian, format: */
726 for (j = 8U, d = 0U; count > 0U; --count, i += inc)
727 { /* big-endian */
728 j -= 1U<<B;
729 d |= SP_PIXEL(MSB) << j;
730 if (j == 0U) *dp++ = png_check_byte(png_ptr, d), j = 8U, d = 0U;
731 }
732
733 /* The end condition: if j is not 0 the last byte was not
734 * written:
735 */
736 if (j != 0U) *dp = png_check_byte(png_ptr, d);
737 }
738 # undef PIXEL_MASK
739 # undef BIT_MASK
740 # undef SP_BYTE
741 # undef SP_OFFSET_MSB
742 # undef SP_OFFSET_LSB
743 # undef SP_PIXEL
744 }
745
746 static void
interlace_row_byte(png_const_structrp png_ptr,png_bytep dp,png_const_bytep sp,png_uint_32 x,unsigned int count,unsigned int cbytes)747 interlace_row_byte(png_const_structrp png_ptr, png_bytep dp, png_const_bytep sp,
748 png_uint_32 x, unsigned int count, unsigned int cbytes)
749 {
750 const unsigned int pass = png_ptr->pass;
751 const unsigned int inc = PNG_PASS_COL_OFFSET(pass);
752
753 /* Loop through the input copying each pixel to the correct place
754 * in the output. Note that the loop may be executed 0 times if
755 * this is called on a narrow image that does not contain this
756 * pass.
757 */
758 for (sp += PNG_COL_FROM_PASS_COL(x, pass) * cbytes; count > 0;
759 --count, sp += inc * cbytes, dp += cbytes)
760 memcpy(dp, sp, cbytes);
761 }
762 #endif /* WRITE_INTERLACING */
763
764 #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
765 static void
write_row_core(png_structrp png_ptr,png_const_bytep row,unsigned int row_info_flags)766 write_row_core(png_structrp png_ptr, png_const_bytep row,
767 unsigned int row_info_flags)
768 {
769 # ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
770 if (png_ptr->transform_list != NULL)
771 write_row_buffered(png_ptr, row, row_info_flags,
772 copy_row, png_ptr->row_input_pixel_depth);
773
774 else
775 # endif /* WRITE_TRANSFORMS */
776
777 /* If control reaches this point the intermediate buffer is not required and
778 * the input data can be used unmodified.
779 */
780 png_write_png_rows(png_ptr, &row, 1U);
781 PNG_UNUSED(row_info_flags)
782 }
783
784 /* Write a single non-interlaced row. */
785 static void
write_row_non_interlaced(png_structrp png_ptr,png_const_bytep row)786 write_row_non_interlaced(png_structrp png_ptr, png_const_bytep row)
787 {
788 const png_uint_32 row_number = png_ptr->row_number+1U;
789 /* There is only one pass, so this is the last pass: */
790 const unsigned int row_info_flags =
791 (row_number == 1U ? png_pass_first_row : 0) |
792 (row_number >= png_ptr->height ? png_pass_last_row : 0) |
793 png_pass_last;
794
795 debug(png_ptr->interlaced == PNG_INTERLACE_NONE);
796
797 write_row_core(png_ptr, row, row_info_flags);
798 }
799
800 /* Write a single interlaced row. */
801 static void
write_row_interlaced(png_structrp png_ptr,png_const_bytep row)802 write_row_interlaced(png_structrp png_ptr, png_const_bytep row)
803 {
804 const png_uint_32 row_number = png_ptr->row_number+1U;
805 const png_uint_32 height = png_ptr->height;
806 const unsigned int pass = png_ptr->pass;
807 const unsigned int row_info_flags =
808 (row_number == 1U ? png_pass_first_row : 0) |
809 (row_number == PNG_PASS_ROWS(height, pass) ? png_pass_last_row : 0) |
810 (pass == PNG_LAST_PASS(png_ptr->width, height) ? png_pass_last : 0);
811
812 # ifdef PNG_WRITE_INTERLACING_SUPPORTED
813 /* Check that libpng is not doing the interlace: */
814 debug(png_ptr->interlaced != PNG_INTERLACE_NONE &&
815 !png_ptr->do_interlace);
816 # endif /* WRITE_INTERLACING */
817
818 write_row_core(png_ptr, row, row_info_flags);
819 }
820 #endif /* WRITE_TRANSFORMS */
821
822 #ifdef PNG_WRITE_INTERLACING_SUPPORTED
823 /* Interlace a row then write it out. */
824 static void
interlace_row(png_structrp png_ptr,png_const_bytep row)825 interlace_row(png_structrp png_ptr, png_const_bytep row)
826 {
827 /* The row may not exist in the image (for this pass). */
828 const png_uint_32 row_number = png_ptr->row_number; /* in image */
829 const unsigned int pass = png_ptr->pass;
830
831 if (png_ptr->width > PNG_PASS_START_COL(pass) &&
832 PNG_ROW_IN_INTERLACE_PASS(row_number, pass))
833 {
834 const unsigned int row_info_flags =
835 (row_number == PNG_PASS_START_ROW(pass) ? png_pass_first_row : 0) |
836 (PNG_LAST_PASS_ROW(row_number, pass, png_ptr->height) ?
837 png_pass_last_row : 0) |
838 (pass == PNG_LAST_PASS(png_ptr->width, png_ptr->height) ?
839 png_pass_last : 0);
840
841 if (pass < 6)
842 {
843 /* Libpng is doing the interlacing and pixels need to be selected
844 * from the input row for this pass.
845 */
846 /* row interlacing uses either the log bit depth for low bit
847 * depth input or the byte count for 8bpp or bigger pixels.
848 */
849 const unsigned int input_depth = png_ptr->row_input_pixel_depth;
850 unsigned int B = 0; /* log2(input_depth) */
851
852 switch (input_depth)
853 {
854 case 4U: /* B will be 2 */
855 ++B;
856 /*FALL THROUGH*/
857 case 2U: /* B will be 1 */
858 ++B;
859 /*FALL THROUGH*/
860 case 1U: /* B will be 0 */
861 write_row_buffered(png_ptr, row, row_info_flags,
862 interlace_row_lbd, B);
863 break;
864
865 default: /* Parameter is the pixel size in bytes */
866 write_row_buffered(png_ptr, row, row_info_flags,
867 interlace_row_byte, input_depth >> 3);
868 break;
869 }
870 } /* pass < 6 */
871
872 else /* pass 6: no interlacing required */
873 write_row_core(png_ptr, row, row_info_flags);
874 }
875
876 else
877 {
878 /* This code must advance row_number/pass itself; the row has been
879 * skipped.
880 */
881 if (row_number+1U < png_ptr->height)
882 png_ptr->row_number = row_number+1U;
883
884 else
885 {
886 png_ptr->row_number = 0U;
887 png_ptr->pass = 0x7U & (pass+1U);
888 }
889 }
890 }
891 #endif /* WRITE_INTERLACING */
892
893 /* Bottleneck API to actually write a number of rows, only exists because the
894 * rows parameter to png_write_rows is wrong.
895 */
896 static void
png_write_rows_internal(png_structrp png_ptr,png_const_bytep * rows,png_uint_32 num_rows)897 png_write_rows_internal(png_structrp png_ptr, png_const_bytep *rows,
898 png_uint_32 num_rows)
899 {
900 if (png_ptr != NULL && num_rows > 0U && rows != NULL)
901 {
902 /* Unlike the read code initialization happens automatically: */
903 if (png_ptr->row_number == 0U && png_ptr->pass == 0U)
904 {
905 png_init_row_info(png_ptr);
906
907 # ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
908 /* If the app takes a png_info from a read operation and if the app has
909 * performed transforms on the data the png_info can contain IHDR
910 * information that cannot be represented in PNG. The code that writes
911 * the IHDR takes the color type from the png_info::format. The app
912 * adds transforms, before or after writing the IHDR, then the IHDR
913 * color_type stored in png_struct::color_type is used in
914 * png_init_row_info above to work out the actual row format.
915 *
916 * Prior to 1.7.0 this was not verified (there was no easy way to do
917 * so). Now we can check it here, however this is an:
918 *
919 * API CHANGE: in 1.7.0 an error may be flagged against bogus
920 * info_struct formats even though the app had removed them itself.
921 * It's just a warning at present.
922 *
923 * The test is that either the row_format produced by the write
924 * transforms exactly matches that in the original info_struct::format
925 * or that the info_struct::format was a simple mapping of the
926 * color_type that ended up in the IHDR:
927 */
928 if (png_ptr->row_format != png_ptr->info_format &&
929 PNG_FORMAT_FROM_COLOR_TYPE(png_ptr->color_type) !=
930 png_ptr->info_format)
931 png_app_warning(png_ptr, "info_struct format does not match IHDR");
932 # endif /* WRITE_TRANSFORMS */
933
934 /* Perform initialization required before IDATs are written. */
935 png_write_start_IDAT(png_ptr);
936 }
937
938 else if (png_ptr->pass >= 7U) /* too many calls; write already ended */
939 {
940 debug(png_ptr->row_number == 0U);
941 png_app_error(png_ptr, "Too many calls to png_write_row");
942 return;
943 }
944
945 /* The remainder of these tests detect internal errors in libpng */
946 else if (png_ptr->interlaced == PNG_INTERLACE_NONE)
947 affirm(png_ptr->row_number < png_ptr->height && png_ptr->pass == 0U);
948
949 # ifdef PNG_WRITE_INTERLACING_SUPPORTED
950 else if (png_ptr->do_interlace)
951 affirm(png_ptr->row_number < png_ptr->height);
952 # endif /* WRITE_INTERLACING */
953
954 else /* app does interlace */
955 affirm(
956 PNG_PASS_IN_IMAGE(png_ptr->width, png_ptr->height, png_ptr->pass) &&
957 png_ptr->row_number < PNG_PASS_ROWS(png_ptr->height, png_ptr->pass)
958 );
959
960 /* First handle rows that require buffering because of the need to
961 * interlace them or the need to perform write transforms.
962 */
963 # ifdef PNG_WRITE_INTERLACING_SUPPORTED
964 /* libpng is doing the interlacing, but this only makes a difference to
965 * the first six passes (numbered, in libpng, 0..5); the seventh pass
966 * (numbered 6 by libpng) consists of complete image rows.
967 */
968 if (png_ptr->do_interlace) while (num_rows > 0U && png_ptr->pass < 6)
969 interlace_row(png_ptr, *rows++), --num_rows;
970 # endif /* WRITE_INTERLACING */
971
972 # ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
973 /* Transforms required however the row interlacing has already been
974 * handled and we have a complete (PNG) row.
975 */
976 if (png_ptr->transform_list != NULL)
977 {
978 if (png_ptr->interlaced == PNG_INTERLACE_NONE)
979 while (num_rows > 0U)
980 write_row_non_interlaced(png_ptr, *rows++), --num_rows;
981
982 # ifdef PNG_WRITE_INTERLACING_SUPPORTED
983 else if (png_ptr->do_interlace)
984 while (num_rows > 0U)
985 interlace_row(png_ptr, *rows++), --num_rows;
986 # endif /* WRITE_INTERLACING */
987
988 else /* app does the interlacing */
989 while (num_rows > 0U)
990 write_row_interlaced(png_ptr, *rows++), --num_rows;
991 }
992 # endif /* WRITE_TRANSFORMS */
993
994 /* Finally handle any remaining rows that require no (libpng) interlace
995 * and no transforms.
996 */
997 if (num_rows > 0U)
998 png_write_png_rows(png_ptr, rows, num_rows);
999
1000 /* Repeat the checks above, but allow for end-of-image. */
1001 if (png_ptr->pass < 7U)
1002 {
1003 if (png_ptr->interlaced == PNG_INTERLACE_NONE)
1004 affirm(png_ptr->row_number < png_ptr->height &&
1005 png_ptr->pass == 0U);
1006
1007 # ifdef PNG_WRITE_INTERLACING_SUPPORTED
1008 else if (png_ptr->do_interlace)
1009 affirm(png_ptr->row_number < png_ptr->height);
1010 # endif /* WRITE_INTERLACING */
1011
1012 else /* app does interlace */
1013 affirm(PNG_PASS_IN_IMAGE(png_ptr->width, png_ptr->height,
1014 png_ptr->pass) &&
1015 png_ptr->row_number <
1016 PNG_PASS_ROWS(png_ptr->height, png_ptr->pass));
1017 }
1018 } /* png_ptr, rows, num_rows all valid */
1019
1020 else if (png_ptr != NULL)
1021 png_app_warning(png_ptr, "Missing rows to row write API");
1022 }
1023
1024 /* ROW WRITE APIs */
1025 /* Called by user to write a single row of image data */
1026 void PNGAPI
png_write_row(png_structrp png_ptr,png_const_bytep row)1027 png_write_row(png_structrp png_ptr, png_const_bytep row)
1028 {
1029 png_debug(1, "in png_write_row");
1030 png_write_rows_internal(png_ptr, &row, 1U);
1031 }
1032
1033 /* Write a few rows of image data. If the image is interlaced,
1034 * either you will have to write the 7 sub images, or, if you
1035 * have called png_set_interlace_handling(), you will have to
1036 * "write" the image seven times.
1037 */
1038 void PNGAPI
png_write_rows(png_structrp png_ptr,png_bytepp rows,png_uint_32 num_rows)1039 png_write_rows(png_structrp png_ptr, png_bytepp rows, png_uint_32 num_rows)
1040 {
1041 png_debug(1, "in png_write_rows");
1042
1043 if (png_ptr != NULL)
1044 png_write_rows_internal(png_ptr, png_constcast(png_const_bytep*,rows),
1045 num_rows);
1046 }
1047
1048 /* Write the image. You only need to call this function once, even
1049 * if you are writing an interlaced image.
1050 */
1051 void PNGAPI
png_write_image(png_structrp png_ptr,png_bytepp image)1052 png_write_image(png_structrp png_ptr, png_bytepp image)
1053 {
1054 png_debug(1, "in png_write_image");
1055
1056 if (png_ptr != NULL)
1057 {
1058 int num_pass = 1;
1059
1060 /* The image is always an non-interlaced image. To write it as interlaced
1061 * interlace handling must be present:
1062 */
1063 if (png_ptr->interlaced)
1064 {
1065 # ifdef PNG_WRITE_INTERLACING_SUPPORTED
1066 num_pass = png_set_interlace_handling(png_ptr);
1067 # else /* !WRITE_INTERLACING */
1068 /* There is no recovery because the IHDR has already been written.
1069 */
1070 png_error(png_ptr, "No interlace support");
1071 # endif /* !WRITE_INTERLACING */
1072 }
1073
1074 /* And write the whole thing, 7 times if interlacing it: */
1075 for (; num_pass > 0; --num_pass)
1076 png_write_rows(png_ptr, image, png_ptr->height);
1077 }
1078 }
1079
1080 /* Free any memory used in png_ptr struct without freeing the struct itself. */
1081 static void
png_write_destroy(png_structrp png_ptr)1082 png_write_destroy(png_structrp png_ptr)
1083 {
1084 png_debug(1, "in png_write_destroy");
1085
1086 png_deflate_destroy(png_ptr);
1087
1088 #ifdef PNG_TRANSFORM_MECH_SUPPORTED
1089 png_transform_free(png_ptr, &png_ptr->transform_list);
1090 #endif
1091
1092 #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
1093 png_free(png_ptr, png_ptr->chunk_list);
1094 png_ptr->chunk_list = NULL;
1095 #endif
1096
1097 /* The error handling and memory handling information is left intact at this
1098 * point: the jmp_buf may still have to be freed. See png_destroy_png_struct
1099 * for how this happens.
1100 */
1101 }
1102
1103 /* Free all memory used by the write.
1104 * In libpng 1.6.0 this API changed quietly to no longer accept a NULL value for
1105 * *png_ptr_ptr. Prior to 1.6.0 it would accept such a value and it would free
1106 * the passed in info_structs but it would quietly fail to free any of the data
1107 * inside them. In 1.6.0 it quietly does nothing (it has to be quiet because it
1108 * has no png_ptr.)
1109 */
1110 void PNGAPI
png_destroy_write_struct(png_structpp png_ptr_ptr,png_infopp info_ptr_ptr)1111 png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
1112 {
1113 png_debug(1, "in png_destroy_write_struct");
1114
1115 if (png_ptr_ptr != NULL)
1116 {
1117 png_structrp png_ptr = *png_ptr_ptr;
1118
1119 if (png_ptr != NULL) /* added in libpng 1.6.0 */
1120 {
1121 png_destroy_info_struct(png_ptr, info_ptr_ptr);
1122
1123 *png_ptr_ptr = NULL;
1124 png_write_destroy(png_ptr);
1125 png_destroy_png_struct(png_ptr);
1126 }
1127 }
1128 }
1129
1130 void PNGAPI
png_set_write_status_fn(png_structrp png_ptr,png_write_status_ptr write_row_fn)1131 png_set_write_status_fn(png_structrp png_ptr, png_write_status_ptr write_row_fn)
1132 {
1133 if (png_ptr == NULL)
1134 return;
1135
1136 png_ptr->write_row_fn = write_row_fn;
1137 }
1138
1139 #ifdef PNG_WRITE_PNG_SUPPORTED
1140 void PNGAPI
png_write_png(png_structrp png_ptr,png_inforp info_ptr,int transforms,voidp params)1141 png_write_png(png_structrp png_ptr, png_inforp info_ptr,
1142 int transforms, voidp params)
1143 {
1144 if (png_ptr == NULL || info_ptr == NULL)
1145 return;
1146
1147 if ((info_ptr->valid & PNG_INFO_IDAT) == 0)
1148 {
1149 png_app_error(png_ptr, "no rows for png_write_image to write");
1150 return;
1151 }
1152
1153 /* Write the file header information. */
1154 png_write_info(png_ptr, info_ptr);
1155
1156 /* ------ these transformations don't touch the info structure ------- */
1157
1158 /* Invert monochrome pixels */
1159 if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0)
1160 #ifdef PNG_WRITE_INVERT_SUPPORTED
1161 png_set_invert_mono(png_ptr);
1162 #else
1163 png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported");
1164 #endif
1165
1166 /* Shift the pixels up to a legal bit depth and fill in
1167 * as appropriate to correctly scale the image.
1168 */
1169 if ((transforms & PNG_TRANSFORM_SHIFT) != 0)
1170 #ifdef PNG_WRITE_SHIFT_SUPPORTED
1171 if ((info_ptr->valid & PNG_INFO_sBIT) != 0)
1172 png_set_shift(png_ptr, &info_ptr->sig_bit);
1173 #else
1174 png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported");
1175 #endif
1176
1177 /* Pack pixels into bytes */
1178 if ((transforms & PNG_TRANSFORM_PACKING) != 0)
1179 #ifdef PNG_WRITE_PACK_SUPPORTED
1180 png_set_packing(png_ptr);
1181 #else
1182 png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported");
1183 #endif
1184
1185 /* Swap location of alpha bytes from ARGB to RGBA */
1186 if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0)
1187 #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
1188 png_set_swap_alpha(png_ptr);
1189 #else
1190 png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported");
1191 #endif
1192
1193 /* Remove a filler (X) from XRGB/RGBX/AG/GA into to convert it into
1194 * RGB, note that the code expects the input color type to be G or RGB; no
1195 * alpha channel.
1196 */
1197 if ((transforms & (PNG_TRANSFORM_STRIP_FILLER_AFTER|
1198 PNG_TRANSFORM_STRIP_FILLER_BEFORE)) != 0)
1199 {
1200 #ifdef PNG_WRITE_FILLER_SUPPORTED
1201 if ((transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) != 0)
1202 {
1203 if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0)
1204 png_app_error(png_ptr,
1205 "PNG_TRANSFORM_STRIP_FILLER: BEFORE+AFTER not supported");
1206
1207 /* Continue if ignored - this is the pre-1.6.10 behavior */
1208 png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
1209 }
1210
1211 else if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0)
1212 png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
1213 #else
1214 png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_FILLER not supported");
1215 #endif
1216 }
1217
1218 /* Flip BGR pixels to RGB */
1219 if ((transforms & PNG_TRANSFORM_BGR) != 0)
1220 #ifdef PNG_WRITE_BGR_SUPPORTED
1221 png_set_bgr(png_ptr);
1222 #else
1223 png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported");
1224 #endif
1225
1226 /* Swap bytes of 16-bit files to most significant byte first */
1227 if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0)
1228 #ifdef PNG_WRITE_SWAP_SUPPORTED
1229 png_set_swap(png_ptr);
1230 #else
1231 png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported");
1232 #endif
1233
1234 /* Swap bits of 1, 2, 4 bit packed pixel formats */
1235 if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0)
1236 #ifdef PNG_WRITE_PACKSWAP_SUPPORTED
1237 png_set_packswap(png_ptr);
1238 #else
1239 png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported");
1240 #endif
1241
1242 /* Invert the alpha channel from opacity to transparency */
1243 if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0)
1244 #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
1245 png_set_invert_alpha(png_ptr);
1246 #else
1247 png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported");
1248 #endif
1249
1250 /* ----------------------- end of transformations ------------------- */
1251
1252 /* Write the bits */
1253 png_write_image(png_ptr, info_ptr->row_pointers);
1254
1255 /* It is REQUIRED to call this to finish writing the rest of the file */
1256 png_write_end(png_ptr, info_ptr);
1257
1258 PNG_UNUSED(params)
1259 }
1260 #endif /* WRITE_PNG */
1261
1262
1263 #ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
1264 /* Initialize the write structure - general purpose utility. */
1265 static int
png_image_write_init(png_imagep image)1266 png_image_write_init(png_imagep image)
1267 {
1268 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, image,
1269 png_safe_error, png_safe_warning);
1270
1271 if (png_ptr != NULL)
1272 {
1273 png_infop info_ptr = png_create_info_struct(png_ptr);
1274
1275 if (info_ptr != NULL)
1276 {
1277 png_controlp control = png_voidcast(png_controlp,
1278 png_malloc_warn(png_ptr, (sizeof *control)));
1279
1280 if (control != NULL)
1281 {
1282 memset(control, 0, (sizeof *control));
1283
1284 control->png_ptr = png_ptr;
1285 control->info_ptr = info_ptr;
1286 control->for_write = 1;
1287
1288 image->opaque = control;
1289 return 1;
1290 }
1291
1292 /* Error clean up */
1293 png_destroy_info_struct(png_ptr, &info_ptr);
1294 }
1295
1296 png_destroy_write_struct(&png_ptr, NULL);
1297 }
1298
1299 return png_image_error(image, "png_image_write_: out of memory");
1300 }
1301
1302 /* Arguments to png_image_write_main: */
1303 typedef struct
1304 {
1305 /* Arguments: */
1306 png_imagep image;
1307 png_const_voidp buffer;
1308 ptrdiff_t row_stride;
1309 png_const_voidp colormap;
1310 int convert_to_8bit;
1311 /* Local variables: */
1312 png_const_voidp first_row;
1313 ptrdiff_t row_bytes;
1314 png_voidp local_row;
1315 /* Byte count for memory writing */
1316 png_bytep memory;
1317 png_alloc_size_t memory_bytes; /* not used for STDIO */
1318 png_alloc_size_t output_bytes; /* running total */
1319 } png_image_write_control;
1320
1321 /* Write png_uint_16 input to a 16-bit PNG; the png_ptr has already been set to
1322 * do any necessary byte swapping. The component order is defined by the
1323 * png_image format value.
1324 */
1325 static int
png_write_image_16bit(png_voidp argument)1326 png_write_image_16bit(png_voidp argument)
1327 {
1328 png_image_write_control *display = png_voidcast(png_image_write_control*,
1329 argument);
1330 png_imagep image = display->image;
1331 png_structrp png_ptr = image->opaque->png_ptr;
1332
1333 png_const_uint_16p input_row = png_voidcast(png_const_uint_16p,
1334 display->first_row);
1335 png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row);
1336 png_uint_16p row_end;
1337 const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
1338 int aindex = 0;
1339 png_uint_32 y = image->height;
1340
1341 if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0)
1342 {
1343 # ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
1344 if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0)
1345 {
1346 aindex = -1;
1347 ++input_row; /* To point to the first component */
1348 ++output_row;
1349 }
1350
1351 else
1352 # endif
1353 aindex = channels;
1354 }
1355
1356 else
1357 png_error(png_ptr, "png_write_image: internal call error");
1358
1359 /* Work out the output row end and count over this, note that the increment
1360 * above to 'row' means that row_end can actually be beyond the end of the
1361 * row; this is correct.
1362 */
1363 row_end = output_row + image->width * (channels+1);
1364
1365 while (y-- > 0)
1366 {
1367 png_const_uint_16p in_ptr = input_row;
1368 png_uint_16p out_ptr = output_row;
1369
1370 while (out_ptr < row_end)
1371 {
1372 const png_uint_16 alpha = in_ptr[aindex];
1373 png_uint_32 reciprocal = 0;
1374 int c;
1375
1376 out_ptr[aindex] = alpha;
1377
1378 /* Calculate a reciprocal. The correct calculation is simply
1379 * component/alpha*65535 << 15. (I.e. 15 bits of precision); this
1380 * allows correct rounding by adding .5 before the shift. 'reciprocal'
1381 * is only initialized when required.
1382 */
1383 if (alpha > 0 && alpha < 65535)
1384 reciprocal = ((0xffff<<15)+(alpha>>1))/alpha;
1385
1386 c = channels;
1387 do /* always at least one channel */
1388 {
1389 png_uint_16 component = *in_ptr++;
1390
1391 /* The following gives 65535 for an alpha of 0, which is fine,
1392 * otherwise if 0/0 is represented as some other value there is more
1393 * likely to be a discontinuity which will probably damage
1394 * compression when moving from a fully transparent area to a
1395 * nearly transparent one. (The assumption here is that opaque
1396 * areas tend not to be 0 intensity.)
1397 */
1398 if (component >= alpha)
1399 component = 65535;
1400
1401 /* component<alpha, so component/alpha is less than one and
1402 * component*reciprocal is less than 2^31.
1403 */
1404 else if (component > 0 && alpha < 65535)
1405 {
1406 png_uint_32 calc = component * reciprocal;
1407 calc += 16384; /* round to nearest */
1408 component = png_check_u16(png_ptr, calc >> 15);
1409 }
1410
1411 *out_ptr++ = component;
1412 }
1413 while (--c > 0);
1414
1415 /* Skip to next component (skip the intervening alpha channel) */
1416 ++in_ptr;
1417 ++out_ptr;
1418 }
1419
1420 png_write_row(png_ptr, png_voidcast(png_const_bytep, display->local_row));
1421 input_row += display->row_bytes/(sizeof (png_uint_16));
1422 }
1423
1424 return 1;
1425 }
1426
1427 /* Given 16-bit input (1 to 4 channels) write 8-bit output. If an alpha channel
1428 * is present it must be removed from the components, the components are then
1429 * written in sRGB encoding. No components are added or removed.
1430 *
1431 * Calculate an alpha reciprocal to reverse pre-multiplication. As above the
1432 * calculation can be done to 15 bits of accuracy; however, the output needs to
1433 * be scaled in the range 0..255*65535, so include that scaling here.
1434 */
1435 #define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+(alpha>>1))/alpha)
1436
1437 static png_byte
png_unpremultiply(png_const_structrp png_ptr,png_uint_32 component,png_uint_32 alpha,png_uint_32 reciprocal)1438 png_unpremultiply(png_const_structrp png_ptr, png_uint_32 component,
1439 png_uint_32 alpha, png_uint_32 reciprocal/*from the above macro*/)
1440 {
1441 /* The following gives 1.0 for an alpha of 0, which is fine, otherwise if 0/0
1442 * is represented as some other value there is more likely to be a
1443 * discontinuity which will probably damage compression when moving from a
1444 * fully transparent area to a nearly transparent one. (The assumption here
1445 * is that opaque areas tend not to be 0 intensity.)
1446 *
1447 * There is a rounding problem here; if alpha is less than 128 it will end up
1448 * as 0 when scaled to 8 bits. To avoid introducing spurious colors into the
1449 * output change for this too.
1450 */
1451 if (component >= alpha || alpha < 128)
1452 return 255;
1453
1454 /* component<alpha, so component/alpha is less than one and
1455 * component*reciprocal is less than 2^31.
1456 */
1457 else if (component > 0)
1458 {
1459 /* The test is that alpha/257 (rounded) is less than 255, the first value
1460 * that becomes 255 is 65407.
1461 * NOTE: this must agree with the PNG_DIV257 macro (which must, therefore,
1462 * be exact!) [Could also test reciprocal != 0]
1463 */
1464 if (alpha < 65407)
1465 {
1466 component *= reciprocal;
1467 component += 64; /* round to nearest */
1468 component >>= 7;
1469 }
1470
1471 else
1472 component *= 255;
1473
1474 /* Convert the component to sRGB. */
1475 return PNG_sRGB_FROM_LINEAR(png_ptr, component);
1476 }
1477
1478 else
1479 return 0;
1480
1481 PNG_UNUSEDRC(png_ptr)
1482 }
1483
1484 static int
png_write_image_8bit(png_voidp argument)1485 png_write_image_8bit(png_voidp argument)
1486 {
1487 png_image_write_control *display = png_voidcast(png_image_write_control*,
1488 argument);
1489 png_imagep image = display->image;
1490 png_structrp png_ptr = image->opaque->png_ptr;
1491
1492 png_const_uint_16p input_row = png_voidcast(png_const_uint_16p,
1493 display->first_row);
1494 png_bytep output_row = png_voidcast(png_bytep, display->local_row);
1495 png_uint_32 y = image->height;
1496 const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
1497
1498 if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0)
1499 {
1500 png_bytep row_end;
1501 int aindex;
1502
1503 # ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
1504 if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0)
1505 {
1506 aindex = -1;
1507 ++input_row; /* To point to the first component */
1508 ++output_row;
1509 }
1510
1511 else
1512 # endif
1513 aindex = channels;
1514
1515 /* Use row_end in place of a loop counter: */
1516 row_end = output_row + image->width * (channels+1);
1517
1518 while (y-- > 0)
1519 {
1520 png_const_uint_16p in_ptr = input_row;
1521 png_bytep out_ptr = output_row;
1522
1523 while (out_ptr < row_end)
1524 {
1525 png_uint_16 alpha = in_ptr[aindex];
1526 png_byte alphabyte = png_check_byte(png_ptr, PNG_DIV257(alpha));
1527 png_uint_32 reciprocal = 0;
1528 int c;
1529
1530 /* Scale and write the alpha channel. */
1531 out_ptr[aindex] = alphabyte;
1532
1533 if (alphabyte > 0 && alphabyte < 255)
1534 reciprocal = UNP_RECIPROCAL(alpha);
1535
1536 c = channels;
1537 do /* always at least one channel */
1538 *out_ptr++ = png_unpremultiply(png_ptr, *in_ptr++, alpha,
1539 reciprocal);
1540 while (--c > 0);
1541
1542 /* Skip to next component (skip the intervening alpha channel) */
1543 ++in_ptr;
1544 ++out_ptr;
1545 } /* while out_ptr < row_end */
1546
1547 png_write_row(png_ptr, png_voidcast(png_const_bytep,
1548 display->local_row));
1549 input_row += display->row_bytes/(sizeof (png_uint_16));
1550 } /* while y */
1551 }
1552
1553 else
1554 {
1555 /* No alpha channel, so the row_end really is the end of the row and it
1556 * is sufficient to loop over the components one by one.
1557 */
1558 png_bytep row_end = output_row + image->width * channels;
1559
1560 while (y-- > 0)
1561 {
1562 png_const_uint_16p in_ptr = input_row;
1563 png_bytep out_ptr = output_row;
1564
1565 while (out_ptr < row_end)
1566 {
1567 png_uint_32 component = *in_ptr++;
1568
1569 component *= 255;
1570 *out_ptr++ = PNG_sRGB_FROM_LINEAR(png_ptr, component);
1571 }
1572
1573 png_write_row(png_ptr, output_row);
1574 input_row += display->row_bytes/(sizeof (png_uint_16));
1575 }
1576 }
1577
1578 return 1;
1579 }
1580
1581 static void
png_image_set_PLTE(png_image_write_control * display)1582 png_image_set_PLTE(png_image_write_control *display)
1583 {
1584 const png_imagep image = display->image;
1585 const void *cmap = display->colormap;
1586 const int entries = image->colormap_entries > 256 ? 256 :
1587 (int)image->colormap_entries;
1588
1589 /* NOTE: the caller must check for cmap != NULL and entries != 0 */
1590 const png_uint_32 format = image->format;
1591 const int channels = PNG_IMAGE_SAMPLE_CHANNELS(format);
1592
1593 # if defined(PNG_FORMAT_BGR_SUPPORTED) &&\
1594 defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED)
1595 const int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
1596 (format & PNG_FORMAT_FLAG_ALPHA) != 0;
1597 # else
1598 # define afirst 0
1599 # endif
1600
1601 # ifdef PNG_FORMAT_BGR_SUPPORTED
1602 const int bgr = (format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0;
1603 # else
1604 # define bgr 0
1605 # endif
1606
1607 int i, num_trans;
1608 png_color palette[256];
1609 png_byte tRNS[256];
1610
1611 memset(tRNS, 255, (sizeof tRNS));
1612 memset(palette, 0, (sizeof palette));
1613
1614 for (i=num_trans=0; i<entries; ++i)
1615 {
1616 /* This gets automatically converted to sRGB with reversal of the
1617 * pre-multiplication if the color-map has an alpha channel.
1618 */
1619 if ((format & PNG_FORMAT_FLAG_LINEAR) != 0)
1620 {
1621 png_const_uint_16p entry = png_voidcast(png_const_uint_16p, cmap);
1622
1623 entry += i * channels;
1624
1625 if ((channels & 1) != 0) /* no alpha */
1626 {
1627 if (channels >= 3) /* RGB */
1628 {
1629 palette[i].blue = PNG_sRGB_FROM_LINEAR(
1630 display->image->opaque->png_ptr, 255 * entry[(2 ^ bgr)]);
1631 palette[i].green = PNG_sRGB_FROM_LINEAR(
1632 display->image->opaque->png_ptr, 255 * entry[1]);
1633 palette[i].red = PNG_sRGB_FROM_LINEAR(
1634 display->image->opaque->png_ptr, 255 * entry[bgr]);
1635 }
1636
1637 else /* Gray */
1638 palette[i].blue = palette[i].red = palette[i].green =
1639 PNG_sRGB_FROM_LINEAR(display->image->opaque->png_ptr,
1640 255 * *entry);
1641 }
1642
1643 else /* alpha */
1644 {
1645 png_uint_16 alpha = entry[afirst ? 0 : channels-1];
1646 png_byte alphabyte = png_check_byte(
1647 display->image->opaque->png_ptr, PNG_DIV257(alpha));
1648 png_uint_32 reciprocal = 0;
1649
1650 /* Calculate a reciprocal, as in the png_write_image_8bit code above
1651 * this is designed to produce a value scaled to 255*65535 when
1652 * divided by 128 (i.e. asr 7).
1653 */
1654 if (alphabyte > 0 && alphabyte < 255)
1655 reciprocal = (((0xffff*0xff)<<7)+(alpha>>1))/alpha;
1656
1657 tRNS[i] = alphabyte;
1658 if (alphabyte < 255)
1659 num_trans = i+1;
1660
1661 if (channels >= 3) /* RGB */
1662 {
1663 palette[i].blue = png_unpremultiply(
1664 display->image->opaque->png_ptr, entry[afirst + (2 ^ bgr)],
1665 alpha, reciprocal);
1666 palette[i].green = png_unpremultiply(
1667 display->image->opaque->png_ptr, entry[afirst + 1], alpha,
1668 reciprocal);
1669 palette[i].red = png_unpremultiply(
1670 display->image->opaque->png_ptr, entry[afirst + bgr], alpha,
1671 reciprocal);
1672 }
1673
1674 else /* gray */
1675 palette[i].blue = palette[i].red = palette[i].green =
1676 png_unpremultiply(display->image->opaque->png_ptr,
1677 entry[afirst], alpha, reciprocal);
1678 }
1679 }
1680
1681 else /* Color-map has sRGB values */
1682 {
1683 png_const_bytep entry = png_voidcast(png_const_bytep, cmap);
1684
1685 entry += i * channels;
1686
1687 switch (channels)
1688 {
1689 case 4:
1690 tRNS[i] = entry[afirst ? 0 : 3];
1691 if (tRNS[i] < 255)
1692 num_trans = i+1;
1693 /* FALL THROUGH */
1694 case 3:
1695 palette[i].blue = entry[afirst + (2 ^ bgr)];
1696 palette[i].green = entry[afirst + 1];
1697 palette[i].red = entry[afirst + bgr];
1698 break;
1699
1700 case 2:
1701 tRNS[i] = entry[1 ^ afirst];
1702 if (tRNS[i] < 255)
1703 num_trans = i+1;
1704 /* FALL THROUGH */
1705 case 1:
1706 palette[i].blue = palette[i].red = palette[i].green =
1707 entry[afirst];
1708 break;
1709
1710 default:
1711 break;
1712 }
1713 }
1714 }
1715
1716 # ifdef afirst
1717 # undef afirst
1718 # endif
1719 # ifdef bgr
1720 # undef bgr
1721 # endif
1722
1723 png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette,
1724 entries);
1725
1726 if (num_trans > 0)
1727 png_set_tRNS(image->opaque->png_ptr, image->opaque->info_ptr, tRNS,
1728 num_trans, NULL);
1729
1730 image->colormap_entries = entries;
1731 }
1732
1733 static int
png_image_write_main(png_voidp argument)1734 png_image_write_main(png_voidp argument)
1735 {
1736 png_image_write_control *display = png_voidcast(png_image_write_control*,
1737 argument);
1738 png_imagep image = display->image;
1739 png_structrp png_ptr = image->opaque->png_ptr;
1740 png_inforp info_ptr = image->opaque->info_ptr;
1741 png_uint_32 format = image->format;
1742
1743 /* The following four ints are actually booleans */
1744 int colormap = (format & PNG_FORMAT_FLAG_COLORMAP);
1745 int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */
1746 int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA);
1747 int write_16bit = linear && !colormap && (display->convert_to_8bit == 0);
1748
1749 # ifdef PNG_BENIGN_ERRORS_SUPPORTED
1750 /* Make sure we error out on any bad situation */
1751 png_set_benign_errors(png_ptr, 0/*error*/);
1752 # endif
1753
1754 /* Default the 'row_stride' parameter if required, also check the row stride
1755 * and total image size to ensure that they are within the system limits.
1756 */
1757 {
1758 const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format);
1759
1760 /* The test is slightly evil: it assumes that a signed pointer difference
1761 * (ptrdiff_t) can hold a maximum value of half, rounded down, of the
1762 * maximum of a (size_t). This is almost certain to be true.
1763 */
1764 if (image->width <= (PNG_SIZE_MAX >> 1)/channels) /* no overflow */
1765 {
1766 png_alloc_size_t check;
1767 const png_alloc_size_t png_row_stride =
1768 (png_alloc_size_t)/*SAFE*/image->width * channels;
1769
1770 if (display->row_stride == 0)
1771 display->row_stride = (ptrdiff_t)png_row_stride;
1772
1773 if (display->row_stride < 0)
1774 check = -display->row_stride;
1775
1776 else
1777 check = display->row_stride;
1778
1779 if (check >= png_row_stride)
1780 {
1781 /* Now check for overflow of the image buffer calculation; check for
1782 * (size_t) overflow here. This detects issues with the
1783 * PNG_IMAGE_BUFFER_SIZE macro.
1784 */
1785 if (image->height > PNG_SIZE_MAX/png_row_stride)
1786 png_error(image->opaque->png_ptr, "memory image too large");
1787 }
1788
1789 else
1790 png_error(image->opaque->png_ptr, "supplied row stride too small");
1791 }
1792
1793 else
1794 png_error(image->opaque->png_ptr, "image row stride too large");
1795 }
1796
1797 /* Set the required transforms then write the rows in the correct order. */
1798 if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0)
1799 {
1800 if (display->colormap != NULL && image->colormap_entries > 0)
1801 {
1802 png_uint_32 entries = image->colormap_entries;
1803
1804 png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
1805 entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)),
1806 PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
1807 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
1808
1809 png_image_set_PLTE(display);
1810 }
1811
1812 else
1813 png_error(image->opaque->png_ptr,
1814 "no color-map for color-mapped image");
1815 }
1816
1817 else
1818 png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
1819 write_16bit ? 16 : 8,
1820 ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) +
1821 ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0),
1822 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
1823
1824 /* Counter-intuitively the data transformations must be called *after*
1825 * png_write_info, not before as in the read code, but the 'set' functions
1826 * must still be called before. Just set the color space information, never
1827 * write an interlaced image.
1828 */
1829
1830 if (write_16bit != 0)
1831 {
1832 /* The gamma here is 1.0 (linear) and the cHRM chunk matches sRGB. */
1833 png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_LINEAR);
1834
1835 if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0)
1836 png_set_cHRM_fixed(png_ptr, info_ptr,
1837 /* color x y */
1838 /* white */ 31270, 32900,
1839 /* red */ 64000, 33000,
1840 /* green */ 30000, 60000,
1841 /* blue */ 15000, 6000
1842 );
1843 }
1844
1845 else if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0)
1846 png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL);
1847
1848 /* Else writing an 8-bit file and the *colors* aren't sRGB, but the 8-bit
1849 * space must still be gamma encoded.
1850 */
1851 else
1852 png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE);
1853
1854 /* Write the file header. */
1855 png_write_info(png_ptr, info_ptr);
1856
1857 /* Now set up the data transformations (*after* the header is written),
1858 * remove the handled transformations from the 'format' flags for checking.
1859 *
1860 * First check for a little endian system if writing 16 bit files.
1861 */
1862 if (write_16bit != 0)
1863 {
1864 PNG_CONST png_uint_16 le = 0x0001;
1865
1866 if ((*(png_const_bytep) & le) != 0)
1867 png_set_swap(png_ptr);
1868 }
1869
1870 # ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
1871 if ((format & PNG_FORMAT_FLAG_BGR) != 0)
1872 {
1873 if (colormap == 0 && (format & PNG_FORMAT_FLAG_COLOR) != 0)
1874 png_set_bgr(png_ptr);
1875 format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_BGR);
1876 }
1877 # endif
1878
1879 # ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
1880 if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
1881 {
1882 if (colormap == 0 && (format & PNG_FORMAT_FLAG_ALPHA) != 0)
1883 png_set_swap_alpha(png_ptr);
1884 format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_AFIRST);
1885 }
1886 # endif
1887
1888 /* If there are 16 or fewer color-map entries we wrote a lower bit depth
1889 * above, but the application data is still byte packed.
1890 */
1891 if (colormap != 0 && image->colormap_entries <= 16)
1892 png_set_packing(png_ptr);
1893
1894 /* That should have handled all (both) the transforms. */
1895 if ((format & PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_LINEAR |
1896 PNG_FORMAT_FLAG_ALPHA | PNG_FORMAT_FLAG_COLORMAP)) != 0)
1897 png_error(png_ptr, "png_write_image: unsupported transformation");
1898
1899 {
1900 png_const_bytep row = png_voidcast(png_const_bytep, display->buffer);
1901 ptrdiff_t row_bytes = display->row_stride;
1902
1903 if (linear != 0)
1904 row_bytes *= (sizeof (png_uint_16));
1905
1906 if (row_bytes < 0)
1907 row += (image->height-1) * (-row_bytes);
1908
1909 display->first_row = row;
1910 display->row_bytes = row_bytes;
1911 }
1912
1913 /* Select the right compression mode based on the presence or absence of the
1914 * 'fast' flag. This will use whatever options are available in the libpng
1915 * build. It is always supported.
1916 */
1917 png_set_compression(png_ptr, (image->flags & PNG_IMAGE_FLAG_FAST) != 0 ?
1918 PNG_COMPRESSION_HIGH_SPEED : PNG_COMPRESSION_HIGH);
1919
1920 /* Check for the cases that currently require a pre-transform on the row
1921 * before it is written. This only applies when the input is 16-bit and
1922 * either there is an alpha channel or it is converted to 8-bit.
1923 */
1924 if ((linear != 0 && alpha != 0 ) ||
1925 (colormap == 0 && display->convert_to_8bit != 0))
1926 {
1927 png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr,
1928 png_get_rowbytes(png_ptr, info_ptr)));
1929 int result;
1930
1931 display->local_row = row;
1932 if (write_16bit != 0)
1933 result = png_safe_execute(image, png_write_image_16bit, display);
1934 else
1935 result = png_safe_execute(image, png_write_image_8bit, display);
1936 display->local_row = NULL;
1937
1938 png_free(png_ptr, row);
1939
1940 /* Skip the 'write_end' on error: */
1941 if (result == 0)
1942 return 0;
1943 }
1944
1945 /* Otherwise this is the case where the input is in a format currently
1946 * supported by the rest of the libpng write code; call it directly.
1947 */
1948 else
1949 {
1950 png_const_bytep row = png_voidcast(png_const_bytep, display->first_row);
1951 ptrdiff_t row_bytes = display->row_bytes;
1952 png_uint_32 y = image->height;
1953
1954 while (y-- > 0)
1955 {
1956 png_write_row(png_ptr, row);
1957 row += row_bytes;
1958 }
1959 }
1960
1961 png_write_end(png_ptr, info_ptr);
1962 return 1;
1963 }
1964
1965
1966 static void (PNGCBAPI
1967 image_memory_write)(png_structp png_ptr, png_bytep/*const*/ data,
1968 png_size_t size)
1969 {
1970 png_image_write_control *display = png_voidcast(png_image_write_control*,
1971 png_ptr->io_ptr/*backdoor: png_get_io_ptr(png_ptr)*/);
1972 const png_alloc_size_t ob = display->output_bytes;
1973
1974 /* Check for overflow; this should never happen: */
1975 if (size <= ((png_alloc_size_t)-1) - ob)
1976 {
1977 /* I don't think libpng ever does this, but just in case: */
1978 if (size > 0)
1979 {
1980 if (display->memory_bytes >= ob+size) /* writing */
1981 memcpy(display->memory+ob, data, size);
1982
1983 /* Always update the size: */
1984 display->output_bytes = ob+size;
1985 }
1986 }
1987
1988 else
1989 png_error(png_ptr, "png_image_write_to_memory: PNG too big");
1990 }
1991
1992 static void (PNGCBAPI
1993 image_memory_flush)(png_structp png_ptr)
1994 {
1995 PNG_UNUSED(png_ptr)
1996 }
1997
1998 static int
png_image_write_memory(png_voidp argument)1999 png_image_write_memory(png_voidp argument)
2000 {
2001 png_image_write_control *display = png_voidcast(png_image_write_control*,
2002 argument);
2003
2004 /* The rest of the memory-specific init and write_main in an error protected
2005 * environment. This case needs to use callbacks for the write operations
2006 * since libpng has no built in support for writing to memory.
2007 */
2008 png_set_write_fn(display->image->opaque->png_ptr, display/*io_ptr*/,
2009 image_memory_write, image_memory_flush);
2010
2011 return png_image_write_main(display);
2012 }
2013
2014 int PNGAPI
png_image_write_to_memory(png_imagep image,void * memory,png_alloc_size_t * PNG_RESTRICT memory_bytes,int convert_to_8bit,const void * buffer,ptrdiff_t row_stride,const void * colormap)2015 png_image_write_to_memory(png_imagep image, void *memory,
2016 png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8bit,
2017 const void *buffer, ptrdiff_t row_stride, const void *colormap)
2018 {
2019 /* Write the image to the given buffer, or count the bytes if it is NULL */
2020 if (image != NULL && image->version == PNG_IMAGE_VERSION)
2021 {
2022 if (memory_bytes != NULL && buffer != NULL)
2023 {
2024 /* This is to give the caller an easier error detection in the NULL
2025 * case and guard against uninitialized variable problems:
2026 */
2027 if (memory == NULL)
2028 *memory_bytes = 0;
2029
2030 if (png_image_write_init(image) != 0)
2031 {
2032 png_image_write_control display;
2033 int result;
2034
2035 memset(&display, 0, (sizeof display));
2036 display.image = image;
2037 display.buffer = buffer;
2038 display.row_stride = row_stride;
2039 display.colormap = colormap;
2040 display.convert_to_8bit = convert_to_8bit;
2041 display.memory = png_voidcast(png_bytep, memory);
2042 display.memory_bytes = *memory_bytes;
2043 display.output_bytes = 0;
2044
2045 result = png_safe_execute(image, png_image_write_memory, &display);
2046 png_image_free(image);
2047
2048 /* write_memory returns true even if we ran out of buffer. */
2049 if (result)
2050 {
2051 /* On out-of-buffer this function returns '0' but still updates
2052 * memory_bytes:
2053 */
2054 if (memory != NULL && display.output_bytes > *memory_bytes)
2055 result = 0;
2056
2057 *memory_bytes = display.output_bytes;
2058 }
2059
2060 return result;
2061 }
2062
2063 else
2064 return 0;
2065 }
2066
2067 else
2068 return png_image_error(image,
2069 "png_image_write_to_memory: invalid argument");
2070 }
2071
2072 else if (image != NULL)
2073 return png_image_error(image,
2074 "png_image_write_to_memory: incorrect PNG_IMAGE_VERSION");
2075
2076 else
2077 return 0;
2078 }
2079
2080 #ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
2081 int PNGAPI
png_image_write_to_stdio(png_imagep image,FILE * file,int convert_to_8bit,const void * buffer,ptrdiff_t row_stride,const void * colormap)2082 png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
2083 const void *buffer, ptrdiff_t row_stride, const void *colormap)
2084 {
2085 /* Write the image to the given (FILE*). */
2086 if (image != NULL && image->version == PNG_IMAGE_VERSION)
2087 {
2088 if (file != NULL && buffer != NULL)
2089 {
2090 if (png_image_write_init(image) != 0 &&
2091 png_image_init_io(image, file) != 0)
2092 {
2093 png_image_write_control display;
2094 int result;
2095
2096 memset(&display, 0, (sizeof display));
2097 display.image = image;
2098 display.buffer = buffer;
2099 display.row_stride = row_stride;
2100 display.colormap = colormap;
2101 display.convert_to_8bit = convert_to_8bit;
2102
2103 result = png_safe_execute(image, png_image_write_main, &display);
2104 png_image_free(image);
2105 return result;
2106 }
2107
2108 else
2109 return 0;
2110 }
2111
2112 else
2113 return png_image_error(image,
2114 "png_image_write_to_stdio: invalid argument");
2115 }
2116
2117 else if (image != NULL)
2118 return png_image_error(image,
2119 "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION");
2120
2121 else
2122 return 0;
2123 }
2124
2125 int PNGAPI
png_image_write_to_file(png_imagep image,const char * file_name,int convert_to_8bit,const void * buffer,ptrdiff_t row_stride,const void * colormap)2126 png_image_write_to_file(png_imagep image, const char *file_name,
2127 int convert_to_8bit, const void *buffer, ptrdiff_t row_stride,
2128 const void *colormap)
2129 {
2130 /* Write the image to the named file. */
2131 if (image != NULL && image->version == PNG_IMAGE_VERSION)
2132 {
2133 if (file_name != NULL && buffer != NULL)
2134 {
2135 FILE *fp = fopen(file_name, "wb");
2136
2137 if (fp != NULL)
2138 {
2139 if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer,
2140 row_stride, colormap) != 0)
2141 {
2142 int error; /* from fflush/fclose */
2143
2144 /* Make sure the file is flushed correctly. */
2145 if (fflush(fp) == 0 && ferror(fp) == 0)
2146 {
2147 if (fclose(fp) == 0)
2148 return 1;
2149
2150 error = errno; /* from fclose */
2151 }
2152
2153 else
2154 {
2155 error = errno; /* from fflush or ferror */
2156 (void)fclose(fp);
2157 }
2158
2159 (void)remove(file_name);
2160 /* The image has already been cleaned up; this is just used to
2161 * set the error (because the original write succeeded).
2162 */
2163 return png_image_error(image, strerror(error));
2164 }
2165
2166 else
2167 {
2168 /* Clean up: just the opened file. */
2169 (void)fclose(fp);
2170 (void)remove(file_name);
2171 return 0;
2172 }
2173 }
2174
2175 else
2176 return png_image_error(image, strerror(errno));
2177 }
2178
2179 else
2180 return png_image_error(image,
2181 "png_image_write_to_file: invalid argument");
2182 }
2183
2184 else if (image != NULL)
2185 return png_image_error(image,
2186 "png_image_write_to_file: incorrect PNG_IMAGE_VERSION");
2187
2188 else
2189 return 0;
2190 }
2191 #endif /* SIMPLIFIED_WRITE_STDIO */
2192 #endif /* SIMPLIFIED_WRITE */
2193 #endif /* WRITE */
2194