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