OSDN Git Service

binding with libharu.
[putex/putex.git] / src / texsourc / lib / libpng / pngwrite.c
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-2014 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 #if defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)
16 #  include <errno.h>
17 #endif
18
19 #ifdef PNG_WRITE_SUPPORTED
20
21 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
22 /* Write out all the unknown chunks for the current given location */
23 static void
24 write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr,
25    unsigned int where)
26 {
27    if (info_ptr->unknown_chunks_num)
28    {
29       png_const_unknown_chunkp up;
30
31       png_debug(5, "writing extra chunks");
32
33       for (up = info_ptr->unknown_chunks;
34            up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
35            ++up)
36          if (up->location & where)
37       {
38          /* If per-chunk unknown chunk handling is enabled use it, otherwise
39           * just write the chunks the application has set.
40           */
41 #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
42          int keep = png_handle_as_unknown(png_ptr, up->name);
43
44          /* NOTE: this code is radically different from the read side in the
45           * matter of handling an ancillary unknown chunk.  In the read side
46           * the default behavior is to discard it, in the code below the default
47           * behavior is to write it.  Critical chunks are, however, only
48           * written if explicitly listed or if the default is set to write all
49           * unknown chunks.
50           *
51           * The default handling is also slightly weird - it is not possible to
52           * stop the writing of all unsafe-to-copy chunks!
53           *
54           * TODO: REVIEW: this would seem to be a bug.
55           */
56          if (keep != PNG_HANDLE_CHUNK_NEVER &&
57              ((up->name[3] & 0x20) /* safe-to-copy overrides everything */ ||
58               keep == PNG_HANDLE_CHUNK_ALWAYS ||
59               (keep == PNG_HANDLE_CHUNK_AS_DEFAULT &&
60                png_ptr->unknown_default == PNG_HANDLE_CHUNK_ALWAYS)))
61 #endif
62          {
63             /* TODO: review, what is wrong with a zero length unknown chunk? */
64             if (up->size == 0)
65                png_warning(png_ptr, "Writing zero-length unknown chunk");
66
67             png_write_chunk(png_ptr, up->name, up->data, up->size);
68          }
69       }
70    }
71 }
72 #endif /* PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED */
73
74 /* Writes all the PNG information.  This is the suggested way to use the
75  * library.  If you have a new chunk to add, make a function to write it,
76  * and put it in the correct location here.  If you want the chunk written
77  * after the image data, put it in png_write_end().  I strongly encourage
78  * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing
79  * the chunk, as that will keep the code from breaking if you want to just
80  * write a plain PNG file.  If you have long comments, I suggest writing
81  * them in png_write_end(), and compressing them.
82  */
83 void PNGAPI
84 png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr)
85 {
86    png_debug(1, "in png_write_info_before_PLTE");
87
88    if (png_ptr == NULL || info_ptr == NULL)
89       return;
90
91    if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
92    {
93    /* Write PNG signature */
94    png_write_sig(png_ptr);
95
96 #ifdef PNG_MNG_FEATURES_SUPPORTED
97    if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) && \
98        (png_ptr->mng_features_permitted))
99    {
100       png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
101       png_ptr->mng_features_permitted = 0;
102    }
103 #endif
104
105    /* Write IHDR information. */
106    png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
107        info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,
108        info_ptr->filter_type,
109 #ifdef PNG_WRITE_INTERLACING_SUPPORTED
110        info_ptr->interlace_type
111 #else
112        0
113 #endif
114       );
115
116    /* The rest of these check to see if the valid field has the appropriate
117     * flag set, and if it does, writes the chunk.
118     *
119     * 1.6.0: COLORSPACE support controls the writing of these chunks too, and
120     * the chunks will be written if the WRITE routine is there and information
121     * is available in the COLORSPACE.  (See png_colorspace_sync_info in png.c
122     * for where the valid flags get set.)
123     *
124     * Under certain circumstances the colorspace can be invalidated without
125     * syncing the info_struct 'valid' flags; this happens if libpng detects and
126     * error and calls png_error while the color space is being set, yet the
127     * application continues writing the PNG.  So check the 'invalid' flag here
128     * too.
129     */
130 #ifdef PNG_GAMMA_SUPPORTED
131 #  ifdef PNG_WRITE_gAMA_SUPPORTED
132       if (!(info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) &&
133          (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_gAMA) &&
134          (info_ptr->valid & PNG_INFO_gAMA))
135          png_write_gAMA_fixed(png_ptr, info_ptr->colorspace.gamma);
136 #  endif
137 #endif
138
139 #ifdef PNG_COLORSPACE_SUPPORTED
140    /* Write only one of sRGB or an ICC profile.  If a profile was supplied
141     * and it matches one of the known sRGB ones issue a warning.
142     */
143 #  ifdef PNG_WRITE_iCCP_SUPPORTED
144       if (!(info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) &&
145          (info_ptr->valid & PNG_INFO_iCCP))
146       {
147 #        ifdef PNG_WRITE_sRGB_SUPPORTED
148             if (info_ptr->valid & PNG_INFO_sRGB)
149                png_app_warning(png_ptr,
150                   "profile matches sRGB but writing iCCP instead");
151 #        endif
152
153          png_write_iCCP(png_ptr, info_ptr->iccp_name,
154             info_ptr->iccp_profile);
155       }
156 #     ifdef PNG_WRITE_sRGB_SUPPORTED
157          else
158 #     endif
159 #  endif
160
161 #  ifdef PNG_WRITE_sRGB_SUPPORTED
162       if (!(info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) &&
163          (info_ptr->valid & PNG_INFO_sRGB))
164          png_write_sRGB(png_ptr, info_ptr->colorspace.rendering_intent);
165 #  endif /* WRITE_sRGB */
166 #endif /* COLORSPACE */
167
168 #ifdef PNG_WRITE_sBIT_SUPPORTED
169    if (info_ptr->valid & PNG_INFO_sBIT)
170       png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);
171 #endif
172
173 #ifdef PNG_COLORSPACE_SUPPORTED
174 #  ifdef PNG_WRITE_cHRM_SUPPORTED
175       if (!(info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) &&
176          (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) &&
177          (info_ptr->valid & PNG_INFO_cHRM))
178          png_write_cHRM_fixed(png_ptr, &info_ptr->colorspace.end_points_xy);
179 #  endif
180 #endif
181
182 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
183       write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_IHDR);
184 #endif
185
186       png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE;
187    }
188 }
189
190 void PNGAPI
191 png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
192 {
193 #if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
194    int i;
195 #endif
196
197    png_debug(1, "in png_write_info");
198
199    if (png_ptr == NULL || info_ptr == NULL)
200       return;
201
202    png_write_info_before_PLTE(png_ptr, info_ptr);
203
204    if (info_ptr->valid & PNG_INFO_PLTE)
205       png_write_PLTE(png_ptr, info_ptr->palette,
206           (png_uint_32)info_ptr->num_palette);
207
208    else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
209       png_error(png_ptr, "Valid palette required for paletted images");
210
211 #ifdef PNG_WRITE_tRNS_SUPPORTED
212    if (info_ptr->valid & PNG_INFO_tRNS)
213    {
214 #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
215       /* Invert the alpha channel (in tRNS) */
216       if ((png_ptr->transformations & PNG_INVERT_ALPHA) &&
217           info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
218       {
219          int j, jend;
220
221          jend = info_ptr->num_trans;
222          if (jend > PNG_MAX_PALETTE_LENGTH)
223             jend = PNG_MAX_PALETTE_LENGTH;
224
225          for (j = 0; j<jend; ++j)
226             info_ptr->trans_alpha[j] =
227                (png_byte)(255 - info_ptr->trans_alpha[j]);
228       }
229 #endif
230       png_write_tRNS(png_ptr, info_ptr->trans_alpha, &(info_ptr->trans_color),
231           info_ptr->num_trans, info_ptr->color_type);
232    }
233 #endif
234 #ifdef PNG_WRITE_bKGD_SUPPORTED
235    if (info_ptr->valid & PNG_INFO_bKGD)
236       png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
237 #endif
238
239 #ifdef PNG_WRITE_hIST_SUPPORTED
240    if (info_ptr->valid & PNG_INFO_hIST)
241       png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
242 #endif
243
244 #ifdef PNG_WRITE_oFFs_SUPPORTED
245    if (info_ptr->valid & PNG_INFO_oFFs)
246       png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset,
247           info_ptr->offset_unit_type);
248 #endif
249
250 #ifdef PNG_WRITE_pCAL_SUPPORTED
251    if (info_ptr->valid & PNG_INFO_pCAL)
252       png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0,
253           info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams,
254           info_ptr->pcal_units, info_ptr->pcal_params);
255 #endif
256
257 #ifdef PNG_WRITE_sCAL_SUPPORTED
258    if (info_ptr->valid & PNG_INFO_sCAL)
259       png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit,
260           info_ptr->scal_s_width, info_ptr->scal_s_height);
261 #endif /* sCAL */
262
263 #ifdef PNG_WRITE_pHYs_SUPPORTED
264    if (info_ptr->valid & PNG_INFO_pHYs)
265       png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,
266           info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type);
267 #endif /* pHYs */
268
269 #ifdef PNG_WRITE_tIME_SUPPORTED
270    if (info_ptr->valid & PNG_INFO_tIME)
271    {
272       png_write_tIME(png_ptr, &(info_ptr->mod_time));
273       png_ptr->mode |= PNG_WROTE_tIME;
274    }
275 #endif /* tIME */
276
277 #ifdef PNG_WRITE_sPLT_SUPPORTED
278    if (info_ptr->valid & PNG_INFO_sPLT)
279       for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
280          png_write_sPLT(png_ptr, info_ptr->splt_palettes + i);
281 #endif /* sPLT */
282
283 #ifdef PNG_WRITE_TEXT_SUPPORTED
284    /* Check to see if we need to write text chunks */
285    for (i = 0; i < info_ptr->num_text; i++)
286    {
287       png_debug2(2, "Writing header text chunk %d, type %d", i,
288           info_ptr->text[i].compression);
289       /* An internationalized chunk? */
290       if (info_ptr->text[i].compression > 0)
291       {
292 #ifdef PNG_WRITE_iTXt_SUPPORTED
293          /* Write international chunk */
294          png_write_iTXt(png_ptr,
295              info_ptr->text[i].compression,
296              info_ptr->text[i].key,
297              info_ptr->text[i].lang,
298              info_ptr->text[i].lang_key,
299              info_ptr->text[i].text);
300 #else
301           png_warning(png_ptr, "Unable to write international text");
302 #endif
303           /* Mark this chunk as written */
304           info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
305       }
306
307       /* If we want a compressed text chunk */
308       else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt)
309       {
310 #ifdef PNG_WRITE_zTXt_SUPPORTED
311          /* Write compressed chunk */
312          png_write_zTXt(png_ptr, info_ptr->text[i].key,
313              info_ptr->text[i].text, 0,
314              info_ptr->text[i].compression);
315 #else
316          png_warning(png_ptr, "Unable to write compressed text");
317 #endif
318          /* Mark this chunk as written */
319          info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
320       }
321
322       else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
323       {
324 #ifdef PNG_WRITE_tEXt_SUPPORTED
325          /* Write uncompressed chunk */
326          png_write_tEXt(png_ptr, info_ptr->text[i].key,
327              info_ptr->text[i].text,
328              0);
329          /* Mark this chunk as written */
330          info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
331 #else
332          /* Can't get here */
333          png_warning(png_ptr, "Unable to write uncompressed text");
334 #endif
335       }
336    }
337 #endif /* tEXt */
338
339 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
340    write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_PLTE);
341 #endif
342 }
343
344 /* Writes the end of the PNG file.  If you don't want to write comments or
345  * time information, you can pass NULL for info.  If you already wrote these
346  * in png_write_info(), do not write them again here.  If you have long
347  * comments, I suggest writing them here, and compressing them.
348  */
349 void PNGAPI
350 png_write_end(png_structrp png_ptr, png_inforp info_ptr)
351 {
352    png_debug(1, "in png_write_end");
353
354    if (png_ptr == NULL)
355       return;
356
357    if (!(png_ptr->mode & PNG_HAVE_IDAT))
358       png_error(png_ptr, "No IDATs written into file");
359
360 #ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
361    if (png_ptr->num_palette_max > png_ptr->num_palette)
362       png_benign_error(png_ptr, "Wrote palette index exceeding num_palette");
363 #endif
364
365    /* See if user wants us to write information chunks */
366    if (info_ptr != NULL)
367    {
368 #ifdef PNG_WRITE_TEXT_SUPPORTED
369       int i; /* local index variable */
370 #endif
371 #ifdef PNG_WRITE_tIME_SUPPORTED
372       /* Check to see if user has supplied a time chunk */
373       if ((info_ptr->valid & PNG_INFO_tIME) &&
374           !(png_ptr->mode & PNG_WROTE_tIME))
375          png_write_tIME(png_ptr, &(info_ptr->mod_time));
376
377 #endif
378 #ifdef PNG_WRITE_TEXT_SUPPORTED
379       /* Loop through comment chunks */
380       for (i = 0; i < info_ptr->num_text; i++)
381       {
382          png_debug2(2, "Writing trailer text chunk %d, type %d", i,
383             info_ptr->text[i].compression);
384          /* An internationalized chunk? */
385          if (info_ptr->text[i].compression > 0)
386          {
387 #ifdef PNG_WRITE_iTXt_SUPPORTED
388             /* Write international chunk */
389             png_write_iTXt(png_ptr,
390                 info_ptr->text[i].compression,
391                 info_ptr->text[i].key,
392                 info_ptr->text[i].lang,
393                 info_ptr->text[i].lang_key,
394                 info_ptr->text[i].text);
395 #else
396             png_warning(png_ptr, "Unable to write international text");
397 #endif
398             /* Mark this chunk as written */
399             info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
400          }
401
402          else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
403          {
404 #ifdef PNG_WRITE_zTXt_SUPPORTED
405             /* Write compressed chunk */
406             png_write_zTXt(png_ptr, info_ptr->text[i].key,
407                 info_ptr->text[i].text, 0,
408                 info_ptr->text[i].compression);
409 #else
410             png_warning(png_ptr, "Unable to write compressed text");
411 #endif
412             /* Mark this chunk as written */
413             info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
414          }
415
416          else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
417          {
418 #ifdef PNG_WRITE_tEXt_SUPPORTED
419             /* Write uncompressed chunk */
420             png_write_tEXt(png_ptr, info_ptr->text[i].key,
421                 info_ptr->text[i].text, 0);
422 #else
423             png_warning(png_ptr, "Unable to write uncompressed text");
424 #endif
425
426             /* Mark this chunk as written */
427             info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
428          }
429       }
430 #endif
431 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
432       write_unknown_chunks(png_ptr, info_ptr, PNG_AFTER_IDAT);
433 #endif
434    }
435
436    png_ptr->mode |= PNG_AFTER_IDAT;
437
438    /* Write end of PNG file */
439    png_write_IEND(png_ptr);
440    /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03,
441     * and restored again in libpng-1.2.30, may cause some applications that
442     * do not set png_ptr->output_flush_fn to crash.  If your application
443     * experiences a problem, please try building libpng with
444     * PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED defined, and report the event to
445     * png-mng-implement at lists.sf.net .
446     */
447 #ifdef PNG_WRITE_FLUSH_SUPPORTED
448 #  ifdef PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED
449    png_flush(png_ptr);
450 #  endif
451 #endif
452 }
453
454 #ifdef PNG_CONVERT_tIME_SUPPORTED
455 void PNGAPI
456 png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm * ttime)
457 {
458    png_debug(1, "in png_convert_from_struct_tm");
459
460    ptime->year = (png_uint_16)(1900 + ttime->tm_year);
461    ptime->month = (png_byte)(ttime->tm_mon + 1);
462    ptime->day = (png_byte)ttime->tm_mday;
463    ptime->hour = (png_byte)ttime->tm_hour;
464    ptime->minute = (png_byte)ttime->tm_min;
465    ptime->second = (png_byte)ttime->tm_sec;
466 }
467
468 void PNGAPI
469 png_convert_from_time_t(png_timep ptime, time_t ttime)
470 {
471    struct tm *tbuf;
472
473    png_debug(1, "in png_convert_from_time_t");
474
475    tbuf = gmtime(&ttime);
476    png_convert_from_struct_tm(ptime, tbuf);
477 }
478 #endif
479
480 /* Initialize png_ptr structure, and allocate any memory needed */
481 PNG_FUNCTION(png_structp,PNGAPI
482 png_create_write_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
483     png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)
484 {
485 #ifndef PNG_USER_MEM_SUPPORTED
486    png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
487       error_fn, warn_fn, NULL, NULL, NULL);
488 #else
489    return png_create_write_struct_2(user_png_ver, error_ptr, error_fn,
490        warn_fn, NULL, NULL, NULL);
491 }
492
493 /* Alternate initialize png_ptr structure, and allocate any memory needed */
494 PNG_FUNCTION(png_structp,PNGAPI
495 png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
496     png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
497     png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
498 {
499    png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
500       error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
501 #endif /* PNG_USER_MEM_SUPPORTED */
502
503    if (png_ptr != NULL)
504    {
505       /* Set the zlib control values to defaults; they can be overridden by the
506        * application after the struct has been created.
507        */
508       png_ptr->zbuffer_size = PNG_ZBUF_SIZE;
509
510       /* The 'zlib_strategy' setting is irrelevant because png_default_claim in
511        * pngwutil.c defaults it according to whether or not filters will be
512        * used, and ignores this setting.
513        */
514       png_ptr->zlib_strategy = PNG_Z_DEFAULT_STRATEGY;
515       png_ptr->zlib_level = PNG_Z_DEFAULT_COMPRESSION;
516       png_ptr->zlib_mem_level = 8;
517       png_ptr->zlib_window_bits = 15;
518       png_ptr->zlib_method = 8;
519
520 #ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
521       png_ptr->zlib_text_strategy = PNG_TEXT_Z_DEFAULT_STRATEGY;
522       png_ptr->zlib_text_level = PNG_TEXT_Z_DEFAULT_COMPRESSION;
523       png_ptr->zlib_text_mem_level = 8;
524       png_ptr->zlib_text_window_bits = 15;
525       png_ptr->zlib_text_method = 8;
526 #endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */
527
528       /* This is a highly dubious configuration option; by default it is off,
529        * but it may be appropriate for private builds that are testing
530        * extensions not conformant to the current specification, or of
531        * applications that must not fail to write at all costs!
532        */
533 #ifdef PNG_BENIGN_WRITE_ERRORS_SUPPORTED
534       png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;
535       /* In stable builds only warn if an application error can be completely
536        * handled.
537        */
538 #endif
539
540       /* App warnings are warnings in release (or release candidate) builds but
541        * are errors during development.
542        */
543 #if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
544          png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN;
545 #endif
546
547       /* TODO: delay this, it can be done in png_init_io() (if the app doesn't
548        * do it itself) avoiding setting the default function if it is not
549        * required.
550        */
551       png_set_write_fn(png_ptr, NULL, NULL, NULL);
552    }
553
554    return png_ptr;
555 }
556
557
558 /* Write a few rows of image data.  If the image is interlaced,
559  * either you will have to write the 7 sub images, or, if you
560  * have called png_set_interlace_handling(), you will have to
561  * "write" the image seven times.
562  */
563 void PNGAPI
564 png_write_rows(png_structrp png_ptr, png_bytepp row,
565     png_uint_32 num_rows)
566 {
567    png_uint_32 i; /* row counter */
568    png_bytepp rp; /* row pointer */
569
570    png_debug(1, "in png_write_rows");
571
572    if (png_ptr == NULL)
573       return;
574
575    /* Loop through the rows */
576    for (i = 0, rp = row; i < num_rows; i++, rp++)
577    {
578       png_write_row(png_ptr, *rp);
579    }
580 }
581
582 /* Write the image.  You only need to call this function once, even
583  * if you are writing an interlaced image.
584  */
585 void PNGAPI
586 png_write_image(png_structrp png_ptr, png_bytepp image)
587 {
588    png_uint_32 i; /* row index */
589    int pass, num_pass; /* pass variables */
590    png_bytepp rp; /* points to current row */
591
592    if (png_ptr == NULL)
593       return;
594
595    png_debug(1, "in png_write_image");
596
597 #ifdef PNG_WRITE_INTERLACING_SUPPORTED
598    /* Initialize interlace handling.  If image is not interlaced,
599     * this will set pass to 1
600     */
601    num_pass = png_set_interlace_handling(png_ptr);
602 #else
603    num_pass = 1;
604 #endif
605    /* Loop through passes */
606    for (pass = 0; pass < num_pass; pass++)
607    {
608       /* Loop through image */
609       for (i = 0, rp = image; i < png_ptr->height; i++, rp++)
610       {
611          png_write_row(png_ptr, *rp);
612       }
613    }
614 }
615
616 #ifdef PNG_MNG_FEATURES_SUPPORTED
617 /* Performs intrapixel differencing  */
618 static void
619 png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
620 {
621    png_debug(1, "in png_do_write_intrapixel");
622
623    if ((row_info->color_type & PNG_COLOR_MASK_COLOR))
624    {
625       int bytes_per_pixel;
626       png_uint_32 row_width = row_info->width;
627       if (row_info->bit_depth == 8)
628       {
629          png_bytep rp;
630          png_uint_32 i;
631
632          if (row_info->color_type == PNG_COLOR_TYPE_RGB)
633             bytes_per_pixel = 3;
634
635          else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
636             bytes_per_pixel = 4;
637
638          else
639             return;
640
641          for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
642          {
643             *(rp)     = (png_byte)((*rp       - *(rp + 1)) & 0xff);
644             *(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff);
645          }
646       }
647
648 #ifdef PNG_WRITE_16BIT_SUPPORTED
649       else if (row_info->bit_depth == 16)
650       {
651          png_bytep rp;
652          png_uint_32 i;
653
654          if (row_info->color_type == PNG_COLOR_TYPE_RGB)
655             bytes_per_pixel = 6;
656
657          else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
658             bytes_per_pixel = 8;
659
660          else
661             return;
662
663          for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
664          {
665             png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
666             png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
667             png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
668             png_uint_32 red  = (png_uint_32)((s0 - s1) & 0xffffL);
669             png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
670             *(rp    ) = (png_byte)((red >> 8) & 0xff);
671             *(rp + 1) = (png_byte)(red & 0xff);
672             *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
673             *(rp + 5) = (png_byte)(blue & 0xff);
674          }
675       }
676 #endif /* PNG_WRITE_16BIT_SUPPORTED */
677    }
678 }
679 #endif /* PNG_MNG_FEATURES_SUPPORTED */
680
681 /* Called by user to write a row of image data */
682 void PNGAPI
683 png_write_row(png_structrp png_ptr, png_const_bytep row)
684 {
685    /* 1.5.6: moved from png_struct to be a local structure: */
686    png_row_info row_info;
687
688    if (png_ptr == NULL)
689       return;
690
691    png_debug2(1, "in png_write_row (row %u, pass %d)",
692       png_ptr->row_number, png_ptr->pass);
693
694    /* Initialize transformations and other stuff if first time */
695    if (png_ptr->row_number == 0 && png_ptr->pass == 0)
696    {
697       /* Make sure we wrote the header info */
698       if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
699          png_error(png_ptr,
700              "png_write_info was never called before png_write_row");
701
702       /* Check for transforms that have been set but were defined out */
703 #if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED)
704       if (png_ptr->transformations & PNG_INVERT_MONO)
705          png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined");
706 #endif
707
708 #if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED)
709       if (png_ptr->transformations & PNG_FILLER)
710          png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined");
711 #endif
712 #if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
713     defined(PNG_READ_PACKSWAP_SUPPORTED)
714       if (png_ptr->transformations & PNG_PACKSWAP)
715          png_warning(png_ptr,
716              "PNG_WRITE_PACKSWAP_SUPPORTED is not defined");
717 #endif
718
719 #if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED)
720       if (png_ptr->transformations & PNG_PACK)
721          png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined");
722 #endif
723
724 #if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED)
725       if (png_ptr->transformations & PNG_SHIFT)
726          png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined");
727 #endif
728
729 #if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED)
730       if (png_ptr->transformations & PNG_BGR)
731          png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined");
732 #endif
733
734 #if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED)
735       if (png_ptr->transformations & PNG_SWAP_BYTES)
736          png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined");
737 #endif
738
739       png_write_start_row(png_ptr);
740    }
741
742 #ifdef PNG_WRITE_INTERLACING_SUPPORTED
743    /* If interlaced and not interested in row, return */
744    if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
745    {
746       switch (png_ptr->pass)
747       {
748          case 0:
749             if (png_ptr->row_number & 0x07)
750             {
751                png_write_finish_row(png_ptr);
752                return;
753             }
754             break;
755
756          case 1:
757             if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
758             {
759                png_write_finish_row(png_ptr);
760                return;
761             }
762             break;
763
764          case 2:
765             if ((png_ptr->row_number & 0x07) != 4)
766             {
767                png_write_finish_row(png_ptr);
768                return;
769             }
770             break;
771
772          case 3:
773             if ((png_ptr->row_number & 0x03) || png_ptr->width < 3)
774             {
775                png_write_finish_row(png_ptr);
776                return;
777             }
778             break;
779
780          case 4:
781             if ((png_ptr->row_number & 0x03) != 2)
782             {
783                png_write_finish_row(png_ptr);
784                return;
785             }
786             break;
787
788          case 5:
789             if ((png_ptr->row_number & 0x01) || png_ptr->width < 2)
790             {
791                png_write_finish_row(png_ptr);
792                return;
793             }
794             break;
795
796          case 6:
797             if (!(png_ptr->row_number & 0x01))
798             {
799                png_write_finish_row(png_ptr);
800                return;
801             }
802             break;
803
804          default: /* error: ignore it */
805             break;
806       }
807    }
808 #endif
809
810    /* Set up row info for transformations */
811    row_info.color_type = png_ptr->color_type;
812    row_info.width = png_ptr->usr_width;
813    row_info.channels = png_ptr->usr_channels;
814    row_info.bit_depth = png_ptr->usr_bit_depth;
815    row_info.pixel_depth = (png_byte)(row_info.bit_depth * row_info.channels);
816    row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
817
818    png_debug1(3, "row_info->color_type = %d", row_info.color_type);
819    png_debug1(3, "row_info->width = %u", row_info.width);
820    png_debug1(3, "row_info->channels = %d", row_info.channels);
821    png_debug1(3, "row_info->bit_depth = %d", row_info.bit_depth);
822    png_debug1(3, "row_info->pixel_depth = %d", row_info.pixel_depth);
823    png_debug1(3, "row_info->rowbytes = %lu", (unsigned long)row_info.rowbytes);
824
825    /* Copy user's row into buffer, leaving room for filter byte. */
826    memcpy(png_ptr->row_buf + 1, row, row_info.rowbytes);
827
828 #ifdef PNG_WRITE_INTERLACING_SUPPORTED
829    /* Handle interlacing */
830    if (png_ptr->interlaced && png_ptr->pass < 6 &&
831        (png_ptr->transformations & PNG_INTERLACE))
832    {
833       png_do_write_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass);
834       /* This should always get caught above, but still ... */
835       if (!(row_info.width))
836       {
837          png_write_finish_row(png_ptr);
838          return;
839       }
840    }
841 #endif
842
843 #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
844    /* Handle other transformations */
845    if (png_ptr->transformations)
846       png_do_write_transformations(png_ptr, &row_info);
847 #endif
848
849    /* At this point the row_info pixel depth must match the 'transformed' depth,
850     * which is also the output depth.
851     */
852    if (row_info.pixel_depth != png_ptr->pixel_depth ||
853       row_info.pixel_depth != png_ptr->transformed_pixel_depth)
854       png_error(png_ptr, "internal write transform logic error");
855
856 #ifdef PNG_MNG_FEATURES_SUPPORTED
857    /* Write filter_method 64 (intrapixel differencing) only if
858     * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
859     * 2. Libpng did not write a PNG signature (this filter_method is only
860     *    used in PNG datastreams that are embedded in MNG datastreams) and
861     * 3. The application called png_permit_mng_features with a mask that
862     *    included PNG_FLAG_MNG_FILTER_64 and
863     * 4. The filter_method is 64 and
864     * 5. The color_type is RGB or RGBA
865     */
866    if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
867        (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
868    {
869       /* Intrapixel differencing */
870       png_do_write_intrapixel(&row_info, png_ptr->row_buf + 1);
871    }
872 #endif
873
874 /* Added at libpng-1.5.10 */
875 #ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
876    /* Check for out-of-range palette index */
877    if (row_info.color_type == PNG_COLOR_TYPE_PALETTE &&
878        png_ptr->num_palette_max >= 0)
879       png_do_check_palette_indexes(png_ptr, &row_info);
880 #endif
881
882    /* Find a filter if necessary, filter the row and write it out. */
883    png_write_find_filter(png_ptr, &row_info);
884
885    if (png_ptr->write_row_fn != NULL)
886       (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
887 }
888
889 #ifdef PNG_WRITE_FLUSH_SUPPORTED
890 /* Set the automatic flush interval or 0 to turn flushing off */
891 void PNGAPI
892 png_set_flush(png_structrp png_ptr, int nrows)
893 {
894    png_debug(1, "in png_set_flush");
895
896    if (png_ptr == NULL)
897       return;
898
899    png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
900 }
901
902 /* Flush the current output buffers now */
903 void PNGAPI
904 png_write_flush(png_structrp png_ptr)
905 {
906    png_debug(1, "in png_write_flush");
907
908    if (png_ptr == NULL)
909       return;
910
911    /* We have already written out all of the data */
912    if (png_ptr->row_number >= png_ptr->num_rows)
913       return;
914
915    png_compress_IDAT(png_ptr, NULL, 0, Z_SYNC_FLUSH);
916    png_ptr->flush_rows = 0;
917    png_flush(png_ptr);
918 }
919 #endif /* PNG_WRITE_FLUSH_SUPPORTED */
920
921 #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
922 static void png_reset_filter_heuristics(png_structrp png_ptr);/* forward decl */
923 #endif
924
925 /* Free any memory used in png_ptr struct without freeing the struct itself. */
926 static void
927 png_write_destroy(png_structrp png_ptr)
928 {
929    png_debug(1, "in png_write_destroy");
930
931    /* Free any memory zlib uses */
932    if (png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED)
933       deflateEnd(&png_ptr->zstream);
934
935    /* Free our memory.  png_free checks NULL for us. */
936    png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
937    png_free(png_ptr, png_ptr->row_buf);
938 #ifdef PNG_WRITE_FILTER_SUPPORTED
939    png_free(png_ptr, png_ptr->prev_row);
940    png_free(png_ptr, png_ptr->sub_row);
941    png_free(png_ptr, png_ptr->up_row);
942    png_free(png_ptr, png_ptr->avg_row);
943    png_free(png_ptr, png_ptr->paeth_row);
944 #endif
945
946 #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
947    /* Use this to save a little code space, it doesn't free the filter_costs */
948    png_reset_filter_heuristics(png_ptr);
949    png_free(png_ptr, png_ptr->filter_costs);
950    png_free(png_ptr, png_ptr->inv_filter_costs);
951 #endif
952
953 #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
954    png_free(png_ptr, png_ptr->chunk_list);
955 #endif
956
957    /* The error handling and memory handling information is left intact at this
958     * point: the jmp_buf may still have to be freed.  See png_destroy_png_struct
959     * for how this happens.
960     */
961 }
962
963 /* Free all memory used by the write.
964  * In libpng 1.6.0 this API changed quietly to no longer accept a NULL value for
965  * *png_ptr_ptr.  Prior to 1.6.0 it would accept such a value and it would free
966  * the passed in info_structs but it would quietly fail to free any of the data
967  * inside them.  In 1.6.0 it quietly does nothing (it has to be quiet because it
968  * has no png_ptr.)
969  */
970 void PNGAPI
971 png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
972 {
973    png_debug(1, "in png_destroy_write_struct");
974
975    if (png_ptr_ptr != NULL)
976    {
977       png_structrp png_ptr = *png_ptr_ptr;
978
979       if (png_ptr != NULL) /* added in libpng 1.6.0 */
980       {
981          png_destroy_info_struct(png_ptr, info_ptr_ptr);
982
983          *png_ptr_ptr = NULL;
984          png_write_destroy(png_ptr);
985          png_destroy_png_struct(png_ptr);
986       }
987    }
988 }
989
990 /* Allow the application to select one or more row filters to use. */
991 void PNGAPI
992 png_set_filter(png_structrp png_ptr, int method, int filters)
993 {
994    png_debug(1, "in png_set_filter");
995
996    if (png_ptr == NULL)
997       return;
998
999 #ifdef PNG_MNG_FEATURES_SUPPORTED
1000    if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
1001        (method == PNG_INTRAPIXEL_DIFFERENCING))
1002       method = PNG_FILTER_TYPE_BASE;
1003 #endif
1004
1005    /* The only supported method, except for the check above, is
1006     * PNG_FILTER_TYPE_BASE.  The code below does not use 'method' other than
1007     * for the check, so just keep going if png_app_error returns.
1008     */
1009    if (method != PNG_FILTER_TYPE_BASE)
1010       png_app_error(png_ptr, "Unknown custom filter method");
1011
1012    /* If filter writing is not supported the 'filters' value must be zero,
1013     * otherwise the value must be a single, valid, filter value or a set of the
1014     * mask values.  The defines in png.h are such that the filter masks used in
1015     * this API and internally are 1<<(3+value), value is in the range 0..4, so
1016     * this fits in a byte.
1017     */
1018 #  ifdef PNG_WRITE_FILTER_SUPPORTED
1019       /* Notice that PNG_NO_FILTERS is 0 and passes this test; this is OK
1020        * because filters then gets set to PNG_FILTER_NONE, as is required.
1021        */
1022       if (filters < PNG_FILTER_VALUE_LAST)
1023          filters = 0x08 << filters;
1024
1025       else if ((filters & ~PNG_ALL_FILTERS) != 0)
1026       {
1027          png_app_error(png_ptr, "png_set_filter: invalid filters mask/value");
1028
1029          /* For compatibility with the previous behavior assume a mask value was
1030           * passed and ignore the non-mask bits.
1031           */
1032          filters &= PNG_ALL_FILTERS;
1033
1034          /* For a possibly foolish consistency (it shouldn't matter) set
1035           * PNG_FILTER_NONE rather than 0.
1036           */
1037          if (filters == 0)
1038             filters = PNG_FILTER_NONE;
1039       }
1040 #  else
1041       /* PNG_FILTER_VALUE_NONE and PNG_NO_FILTERS are both 0. */
1042       if (filters != 0 && filters != PNG_FILTER_NONE)
1043          png_app_error(png_ptr, "png_set_filter: no filters supported");
1044
1045       filters = PNG_FILTER_NONE;
1046 #  endif
1047
1048 #  ifdef PNG_WRITE_FILTER_SUPPORTED
1049       /* If we have allocated the row_buf, this means we have already started
1050        * with the image and we should have allocated all of the filter buffers
1051        * that have been selected.  If prev_row isn't already allocated, then
1052        * it is too late to start using the filters that need it, since we
1053        * will be missing the data in the previous row.  If an application
1054        * wants to start and stop using particular filters during compression,
1055        * it should start out with all of the filters, and then add and
1056        * remove them after the start of compression.
1057        *
1058        * NOTE: this is a nasty constraint on the code, because it means that the
1059        * prev_row buffer must be maintained even if there are currently no
1060        * 'prev_row' requiring filters active.
1061        */
1062       if (png_ptr->row_buf != NULL)
1063       {
1064          /* Repeat the checks in png_write_start_row; 1 pixel high or wide
1065           * images cannot benefit from certain filters.  If this isn't done here
1066           * the check below will fire on 1 pixel high images.
1067           */
1068          if (png_ptr->height == 1)
1069             filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH);
1070
1071          if (png_ptr->width == 1)
1072             filters &= ~(PNG_FILTER_SUB|PNG_FILTER_AVG|PNG_FILTER_PAETH);
1073
1074          if ((filters & (PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH)) != 0
1075             && png_ptr->prev_row == NULL)
1076          {
1077             /* This is the error case, however it is benign - the previous row
1078              * is not available so the filter can't be used.  Just warn here.
1079              */
1080             png_app_warning(png_ptr,
1081                "png_set_filter: UP/AVG/PAETH cannot be added after start");
1082             filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH);
1083          }
1084
1085          /* Allocate any required buffers that have not already been allocated.
1086           */
1087          png_write_alloc_filter_row_buffers(png_ptr, filters);
1088       }
1089 #  endif /* PNG_WRITE_FILTER_SUPPORTED */
1090
1091    /* Finally store the value.
1092     * TODO: this field could probably be removed if neither READ nor
1093     * WRITE_FILTER are supported.
1094     */
1095    png_ptr->do_filter = (png_byte)filters; /* SAFE: checked above */
1096 }
1097
1098 /* This allows us to influence the way in which libpng chooses the "best"
1099  * filter for the current scanline.  While the "minimum-sum-of-absolute-
1100  * differences metric is relatively fast and effective, there is some
1101  * question as to whether it can be improved upon by trying to keep the
1102  * filtered data going to zlib more consistent, hopefully resulting in
1103  * better compression.
1104  */
1105 #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED      /* GRR 970116 */
1106 /* Convenience reset API. */
1107 static void
1108 png_reset_filter_heuristics(png_structrp png_ptr)
1109 {
1110    /* Clear out any old values in the 'weights' - this must be done because if
1111     * the app calls set_filter_heuristics multiple times with different
1112     * 'num_weights' values we would otherwise potentially have wrong sized
1113     * arrays.
1114     */
1115    png_ptr->num_prev_filters = 0;
1116    png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED;
1117    if (png_ptr->prev_filters != NULL)
1118    {
1119       png_bytep old = png_ptr->prev_filters;
1120       png_ptr->prev_filters = NULL;
1121       png_free(png_ptr, old);
1122    }
1123    if (png_ptr->filter_weights != NULL)
1124    {
1125       png_uint_16p old = png_ptr->filter_weights;
1126       png_ptr->filter_weights = NULL;
1127       png_free(png_ptr, old);
1128    }
1129
1130    if (png_ptr->inv_filter_weights != NULL)
1131    {
1132       png_uint_16p old = png_ptr->inv_filter_weights;
1133       png_ptr->inv_filter_weights = NULL;
1134       png_free(png_ptr, old);
1135    }
1136
1137    /* Leave the filter_costs - this array is fixed size. */
1138 }
1139
1140 static int
1141 png_init_filter_heuristics(png_structrp png_ptr, int heuristic_method,
1142    int num_weights)
1143 {
1144    if (png_ptr == NULL)
1145       return 0;
1146
1147    /* Clear out the arrays */
1148    png_reset_filter_heuristics(png_ptr);
1149
1150    /* Check arguments; the 'reset' function makes the correct settings for the
1151     * unweighted case, but we must handle the weight case by initializing the
1152     * arrays for the caller.
1153     */
1154    if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
1155    {
1156       int i;
1157
1158       if (num_weights > 0)
1159       {
1160          png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr,
1161              (png_uint_32)((sizeof (png_byte)) * num_weights));
1162
1163          /* To make sure that the weighting starts out fairly */
1164          for (i = 0; i < num_weights; i++)
1165          {
1166             png_ptr->prev_filters[i] = 255;
1167          }
1168
1169          png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr,
1170              (png_uint_32)((sizeof (png_uint_16)) * num_weights));
1171
1172          png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr,
1173              (png_uint_32)((sizeof (png_uint_16)) * num_weights));
1174
1175          for (i = 0; i < num_weights; i++)
1176          {
1177             png_ptr->inv_filter_weights[i] =
1178             png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
1179          }
1180
1181          /* Safe to set this now */
1182          png_ptr->num_prev_filters = (png_byte)num_weights;
1183       }
1184
1185       /* If, in the future, there are other filter methods, this would
1186        * need to be based on png_ptr->filter.
1187        */
1188       if (png_ptr->filter_costs == NULL)
1189       {
1190          png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr,
1191              (png_uint_32)((sizeof (png_uint_16)) * PNG_FILTER_VALUE_LAST));
1192
1193          png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr,
1194              (png_uint_32)((sizeof (png_uint_16)) * PNG_FILTER_VALUE_LAST));
1195       }
1196
1197       for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
1198       {
1199          png_ptr->inv_filter_costs[i] =
1200          png_ptr->filter_costs[i] = PNG_COST_FACTOR;
1201       }
1202
1203       /* All the arrays are inited, safe to set this: */
1204       png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_WEIGHTED;
1205
1206       /* Return the 'ok' code. */
1207       return 1;
1208    }
1209    else if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT ||
1210       heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED)
1211    {
1212       return 1;
1213    }
1214    else
1215    {
1216       png_warning(png_ptr, "Unknown filter heuristic method");
1217       return 0;
1218    }
1219 }
1220
1221 /* Provide floating and fixed point APIs */
1222 #ifdef PNG_FLOATING_POINT_SUPPORTED
1223 void PNGAPI
1224 png_set_filter_heuristics(png_structrp png_ptr, int heuristic_method,
1225     int num_weights, png_const_doublep filter_weights,
1226     png_const_doublep filter_costs)
1227 {
1228    png_debug(1, "in png_set_filter_heuristics");
1229
1230    /* The internal API allocates all the arrays and ensures that the elements of
1231     * those arrays are set to the default value.
1232     */
1233    if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights))
1234       return;
1235
1236    /* If using the weighted method copy in the weights. */
1237    if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
1238    {
1239       int i;
1240       for (i = 0; i < num_weights; i++)
1241       {
1242          if (filter_weights[i] <= 0.0)
1243          {
1244             png_ptr->inv_filter_weights[i] =
1245             png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
1246          }
1247
1248          else
1249          {
1250             png_ptr->inv_filter_weights[i] =
1251                 (png_uint_16)(PNG_WEIGHT_FACTOR*filter_weights[i]+.5);
1252
1253             png_ptr->filter_weights[i] =
1254                 (png_uint_16)(PNG_WEIGHT_FACTOR/filter_weights[i]+.5);
1255          }
1256       }
1257
1258       /* Here is where we set the relative costs of the different filters.  We
1259        * should take the desired compression level into account when setting
1260        * the costs, so that Paeth, for instance, has a high relative cost at low
1261        * compression levels, while it has a lower relative cost at higher
1262        * compression settings.  The filter types are in order of increasing
1263        * relative cost, so it would be possible to do this with an algorithm.
1264        */
1265       for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) if (filter_costs[i] >= 1.0)
1266       {
1267          png_ptr->inv_filter_costs[i] =
1268              (png_uint_16)(PNG_COST_FACTOR / filter_costs[i] + .5);
1269
1270          png_ptr->filter_costs[i] =
1271              (png_uint_16)(PNG_COST_FACTOR * filter_costs[i] + .5);
1272       }
1273    }
1274 }
1275 #endif /* FLOATING_POINT */
1276
1277 #ifdef PNG_FIXED_POINT_SUPPORTED
1278 void PNGAPI
1279 png_set_filter_heuristics_fixed(png_structrp png_ptr, int heuristic_method,
1280     int num_weights, png_const_fixed_point_p filter_weights,
1281     png_const_fixed_point_p filter_costs)
1282 {
1283    png_debug(1, "in png_set_filter_heuristics_fixed");
1284
1285    /* The internal API allocates all the arrays and ensures that the elements of
1286     * those arrays are set to the default value.
1287     */
1288    if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights))
1289       return;
1290
1291    /* If using the weighted method copy in the weights. */
1292    if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
1293    {
1294       int i;
1295       for (i = 0; i < num_weights; i++)
1296       {
1297          if (filter_weights[i] <= 0)
1298          {
1299             png_ptr->inv_filter_weights[i] =
1300             png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
1301          }
1302
1303          else
1304          {
1305             png_ptr->inv_filter_weights[i] = (png_uint_16)
1306                ((PNG_WEIGHT_FACTOR*filter_weights[i]+PNG_FP_HALF)/PNG_FP_1);
1307
1308             png_ptr->filter_weights[i] = (png_uint_16)((PNG_WEIGHT_FACTOR*
1309                PNG_FP_1+(filter_weights[i]/2))/filter_weights[i]);
1310          }
1311       }
1312
1313       /* Here is where we set the relative costs of the different filters.  We
1314        * should take the desired compression level into account when setting
1315        * the costs, so that Paeth, for instance, has a high relative cost at low
1316        * compression levels, while it has a lower relative cost at higher
1317        * compression settings.  The filter types are in order of increasing
1318        * relative cost, so it would be possible to do this with an algorithm.
1319        */
1320       for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
1321          if (filter_costs[i] >= PNG_FP_1)
1322       {
1323          png_uint_32 tmp;
1324
1325          /* Use a 32 bit unsigned temporary here because otherwise the
1326           * intermediate value will be a 32 bit *signed* integer (ANSI rules)
1327           * and this will get the wrong answer on division.
1328           */
1329          tmp = PNG_COST_FACTOR*PNG_FP_1 + (filter_costs[i]/2);
1330          tmp /= filter_costs[i];
1331
1332          png_ptr->inv_filter_costs[i] = (png_uint_16)tmp;
1333
1334          tmp = PNG_COST_FACTOR * filter_costs[i] + PNG_FP_HALF;
1335          tmp /= PNG_FP_1;
1336
1337          png_ptr->filter_costs[i] = (png_uint_16)tmp;
1338       }
1339    }
1340 }
1341 #endif /* FIXED_POINT */
1342 #endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
1343
1344 void PNGAPI
1345 png_set_compression_level(png_structrp png_ptr, int level)
1346 {
1347    png_debug(1, "in png_set_compression_level");
1348
1349    if (png_ptr == NULL)
1350       return;
1351
1352    png_ptr->zlib_level = level;
1353 }
1354
1355 void PNGAPI
1356 png_set_compression_mem_level(png_structrp png_ptr, int mem_level)
1357 {
1358    png_debug(1, "in png_set_compression_mem_level");
1359
1360    if (png_ptr == NULL)
1361       return;
1362
1363    png_ptr->zlib_mem_level = mem_level;
1364 }
1365
1366 void PNGAPI
1367 png_set_compression_strategy(png_structrp png_ptr, int strategy)
1368 {
1369    png_debug(1, "in png_set_compression_strategy");
1370
1371    if (png_ptr == NULL)
1372       return;
1373
1374    /* The flag setting here prevents the libpng dynamic selection of strategy.
1375     */
1376    png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY;
1377    png_ptr->zlib_strategy = strategy;
1378 }
1379
1380 /* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
1381  * smaller value of window_bits if it can do so safely.
1382  */
1383 void PNGAPI
1384 png_set_compression_window_bits(png_structrp png_ptr, int window_bits)
1385 {
1386    if (png_ptr == NULL)
1387       return;
1388
1389    /* Prior to 1.6.0 this would warn but then set the window_bits value, this
1390     * meant that negative window bits values could be selected which would cause
1391     * libpng to write a non-standard PNG file with raw deflate or gzip
1392     * compressed IDAT or ancillary chunks.  Such files can be read and there is
1393     * no warning on read, so this seems like a very bad idea.
1394     */
1395    if (window_bits > 15)
1396    {
1397       png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
1398       window_bits = 15;
1399    }
1400
1401    else if (window_bits < 8)
1402    {
1403       png_warning(png_ptr, "Only compression windows >= 256 supported by PNG");
1404       window_bits = 8;
1405    }
1406
1407    png_ptr->zlib_window_bits = window_bits;
1408 }
1409
1410 void PNGAPI
1411 png_set_compression_method(png_structrp png_ptr, int method)
1412 {
1413    png_debug(1, "in png_set_compression_method");
1414
1415    if (png_ptr == NULL)
1416       return;
1417
1418    /* This would produce an invalid PNG file if it worked, but it doesn't and
1419     * deflate will fault it, so it is harmless to just warn here.
1420     */
1421    if (method != 8)
1422       png_warning(png_ptr, "Only compression method 8 is supported by PNG");
1423
1424    png_ptr->zlib_method = method;
1425 }
1426
1427 /* The following were added to libpng-1.5.4 */
1428 #ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
1429 void PNGAPI
1430 png_set_text_compression_level(png_structrp png_ptr, int level)
1431 {
1432    png_debug(1, "in png_set_text_compression_level");
1433
1434    if (png_ptr == NULL)
1435       return;
1436
1437    png_ptr->zlib_text_level = level;
1438 }
1439
1440 void PNGAPI
1441 png_set_text_compression_mem_level(png_structrp png_ptr, int mem_level)
1442 {
1443    png_debug(1, "in png_set_text_compression_mem_level");
1444
1445    if (png_ptr == NULL)
1446       return;
1447
1448    png_ptr->zlib_text_mem_level = mem_level;
1449 }
1450
1451 void PNGAPI
1452 png_set_text_compression_strategy(png_structrp png_ptr, int strategy)
1453 {
1454    png_debug(1, "in png_set_text_compression_strategy");
1455
1456    if (png_ptr == NULL)
1457       return;
1458
1459    png_ptr->zlib_text_strategy = strategy;
1460 }
1461
1462 /* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
1463  * smaller value of window_bits if it can do so safely.
1464  */
1465 void PNGAPI
1466 png_set_text_compression_window_bits(png_structrp png_ptr, int window_bits)
1467 {
1468    if (png_ptr == NULL)
1469       return;
1470
1471    if (window_bits > 15)
1472    {
1473       png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
1474       window_bits = 15;
1475    }
1476
1477    else if (window_bits < 8)
1478    {
1479       png_warning(png_ptr, "Only compression windows >= 256 supported by PNG");
1480       window_bits = 8;
1481    }
1482
1483    png_ptr->zlib_text_window_bits = window_bits;
1484 }
1485
1486 void PNGAPI
1487 png_set_text_compression_method(png_structrp png_ptr, int method)
1488 {
1489    png_debug(1, "in png_set_text_compression_method");
1490
1491    if (png_ptr == NULL)
1492       return;
1493
1494    if (method != 8)
1495       png_warning(png_ptr, "Only compression method 8 is supported by PNG");
1496
1497    png_ptr->zlib_text_method = method;
1498 }
1499 #endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */
1500 /* end of API added to libpng-1.5.4 */
1501
1502 void PNGAPI
1503 png_set_write_status_fn(png_structrp png_ptr, png_write_status_ptr write_row_fn)
1504 {
1505    if (png_ptr == NULL)
1506       return;
1507
1508    png_ptr->write_row_fn = write_row_fn;
1509 }
1510
1511 #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
1512 void PNGAPI
1513 png_set_write_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr
1514     write_user_transform_fn)
1515 {
1516    png_debug(1, "in png_set_write_user_transform_fn");
1517
1518    if (png_ptr == NULL)
1519       return;
1520
1521    png_ptr->transformations |= PNG_USER_TRANSFORM;
1522    png_ptr->write_user_transform_fn = write_user_transform_fn;
1523 }
1524 #endif
1525
1526
1527 #ifdef PNG_INFO_IMAGE_SUPPORTED
1528 void PNGAPI
1529 png_write_png(png_structrp png_ptr, png_inforp info_ptr,
1530     int transforms, voidp params)
1531 {
1532    if (png_ptr == NULL || info_ptr == NULL)
1533       return;
1534
1535    if ((info_ptr->valid & PNG_INFO_IDAT) == 0)
1536    {
1537       png_app_error(png_ptr, "no rows for png_write_image to write");
1538       return;
1539    }
1540
1541    /* Write the file header information. */
1542    png_write_info(png_ptr, info_ptr);
1543
1544    /* ------ these transformations don't touch the info structure ------- */
1545
1546    /* Invert monochrome pixels */
1547    if (transforms & PNG_TRANSFORM_INVERT_MONO)
1548 #ifdef PNG_WRITE_INVERT_SUPPORTED
1549       png_set_invert_mono(png_ptr);
1550 #else
1551       png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported");
1552 #endif
1553
1554    /* Shift the pixels up to a legal bit depth and fill in
1555     * as appropriate to correctly scale the image.
1556     */
1557    if (transforms & PNG_TRANSFORM_SHIFT)
1558 #ifdef PNG_WRITE_SHIFT_SUPPORTED
1559       if (info_ptr->valid & PNG_INFO_sBIT)
1560          png_set_shift(png_ptr, &info_ptr->sig_bit);
1561 #else
1562       png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported");
1563 #endif
1564
1565    /* Pack pixels into bytes */
1566    if (transforms & PNG_TRANSFORM_PACKING)
1567 #ifdef PNG_WRITE_PACK_SUPPORTED
1568       png_set_packing(png_ptr);
1569 #else
1570       png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported");
1571 #endif
1572
1573    /* Swap location of alpha bytes from ARGB to RGBA */
1574    if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
1575 #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
1576       png_set_swap_alpha(png_ptr);
1577 #else
1578       png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported");
1579 #endif
1580
1581    /* Remove a filler (X) from XRGB/RGBX/AG/GA into to convert it into
1582     * RGB, note that the code expects the input color type to be G or RGB; no
1583     * alpha channel.
1584     */
1585    if (transforms &
1586       (PNG_TRANSFORM_STRIP_FILLER_AFTER|PNG_TRANSFORM_STRIP_FILLER_BEFORE))
1587    {
1588 #ifdef PNG_WRITE_FILLER_SUPPORTED
1589       if (transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER)
1590       {
1591          if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE)
1592             png_app_error(png_ptr,
1593                "PNG_TRANSFORM_STRIP_FILLER: BEFORE+AFTER not supported");
1594
1595          /* Continue if ignored - this is the pre-1.6.10 behavior */
1596          png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
1597       }
1598
1599       else if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE)
1600          png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
1601 #else
1602       png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_FILLER not supported");
1603 #endif
1604    }
1605
1606    /* Flip BGR pixels to RGB */
1607    if (transforms & PNG_TRANSFORM_BGR)
1608 #ifdef PNG_WRITE_BGR_SUPPORTED
1609       png_set_bgr(png_ptr);
1610 #else
1611       png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported");
1612 #endif
1613
1614    /* Swap bytes of 16-bit files to most significant byte first */
1615    if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
1616 #ifdef PNG_WRITE_SWAP_SUPPORTED
1617       png_set_swap(png_ptr);
1618 #else
1619       png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported");
1620 #endif
1621
1622    /* Swap bits of 1, 2, 4 bit packed pixel formats */
1623    if (transforms & PNG_TRANSFORM_PACKSWAP)
1624 #ifdef PNG_WRITE_PACKSWAP_SUPPORTED
1625       png_set_packswap(png_ptr);
1626 #else
1627       png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported");
1628 #endif
1629
1630    /* Invert the alpha channel from opacity to transparency */
1631    if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
1632 #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
1633       png_set_invert_alpha(png_ptr);
1634 #else
1635       png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported");
1636 #endif
1637
1638    /* ----------------------- end of transformations ------------------- */
1639
1640    /* Write the bits */
1641    png_write_image(png_ptr, info_ptr->row_pointers);
1642
1643    /* It is REQUIRED to call this to finish writing the rest of the file */
1644    png_write_end(png_ptr, info_ptr);
1645
1646    PNG_UNUSED(params)
1647 }
1648 #endif
1649
1650
1651 #ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
1652 #ifdef PNG_STDIO_SUPPORTED /* currently required for png_image_write_* */
1653 /* Initialize the write structure - general purpose utility. */
1654 static int
1655 png_image_write_init(png_imagep image)
1656 {
1657    png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, image,
1658           png_safe_error, png_safe_warning);
1659
1660    if (png_ptr != NULL)
1661    {
1662       png_infop info_ptr = png_create_info_struct(png_ptr);
1663
1664       if (info_ptr != NULL)
1665       {
1666          png_controlp control = png_voidcast(png_controlp,
1667             png_malloc_warn(png_ptr, (sizeof *control)));
1668
1669          if (control != NULL)
1670          {
1671             memset(control, 0, (sizeof *control));
1672
1673             control->png_ptr = png_ptr;
1674             control->info_ptr = info_ptr;
1675             control->for_write = 1;
1676
1677             image->opaque = control;
1678             return 1;
1679          }
1680
1681          /* Error clean up */
1682          png_destroy_info_struct(png_ptr, &info_ptr);
1683       }
1684
1685       png_destroy_write_struct(&png_ptr, NULL);
1686    }
1687
1688    return png_image_error(image, "png_image_write_: out of memory");
1689 }
1690
1691 /* Arguments to png_image_write_main: */
1692 typedef struct
1693 {
1694    /* Arguments: */
1695    png_imagep      image;
1696    png_const_voidp buffer;
1697    png_int_32      row_stride;
1698    png_const_voidp colormap;
1699    int             convert_to_8bit;
1700    /* Local variables: */
1701    png_const_voidp first_row;
1702    ptrdiff_t       row_bytes;
1703    png_voidp       local_row;
1704 } png_image_write_control;
1705
1706 /* Write png_uint_16 input to a 16-bit PNG; the png_ptr has already been set to
1707  * do any necessary byte swapping.  The component order is defined by the
1708  * png_image format value.
1709  */
1710 static int
1711 png_write_image_16bit(png_voidp argument)
1712 {
1713    png_image_write_control *display = png_voidcast(png_image_write_control*,
1714       argument);
1715    png_imagep image = display->image;
1716    png_structrp png_ptr = image->opaque->png_ptr;
1717
1718    png_const_uint_16p input_row = png_voidcast(png_const_uint_16p,
1719       display->first_row);
1720    png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row);
1721    png_uint_16p row_end;
1722    const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1;
1723    int aindex = 0;
1724    png_uint_32 y = image->height;
1725
1726    if (image->format & PNG_FORMAT_FLAG_ALPHA)
1727    {
1728 #     ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
1729          if (image->format & PNG_FORMAT_FLAG_AFIRST)
1730          {
1731             aindex = -1;
1732             ++input_row; /* To point to the first component */
1733             ++output_row;
1734          }
1735
1736          else
1737 #     endif
1738          aindex = channels;
1739    }
1740
1741    else
1742       png_error(png_ptr, "png_write_image: internal call error");
1743
1744    /* Work out the output row end and count over this, note that the increment
1745     * above to 'row' means that row_end can actually be beyond the end of the
1746     * row; this is correct.
1747     */
1748    row_end = output_row + image->width * (channels+1);
1749
1750    while (y-- > 0)
1751    {
1752       png_const_uint_16p in_ptr = input_row;
1753       png_uint_16p out_ptr = output_row;
1754
1755       while (out_ptr < row_end)
1756       {
1757          const png_uint_16 alpha = in_ptr[aindex];
1758          png_uint_32 reciprocal = 0;
1759          int c;
1760
1761          out_ptr[aindex] = alpha;
1762
1763          /* Calculate a reciprocal.  The correct calculation is simply
1764           * component/alpha*65535 << 15. (I.e. 15 bits of precision); this
1765           * allows correct rounding by adding .5 before the shift.  'reciprocal'
1766           * is only initialized when required.
1767           */
1768          if (alpha > 0 && alpha < 65535)
1769             reciprocal = ((0xffff<<15)+(alpha>>1))/alpha;
1770
1771          c = channels;
1772          do /* always at least one channel */
1773          {
1774             png_uint_16 component = *in_ptr++;
1775
1776             /* The following gives 65535 for an alpha of 0, which is fine,
1777              * otherwise if 0/0 is represented as some other value there is more
1778              * likely to be a discontinuity which will probably damage
1779              * compression when moving from a fully transparent area to a
1780              * nearly transparent one.  (The assumption here is that opaque
1781              * areas tend not to be 0 intensity.)
1782              */
1783             if (component >= alpha)
1784                component = 65535;
1785
1786             /* component<alpha, so component/alpha is less than one and
1787              * component*reciprocal is less than 2^31.
1788              */
1789             else if (component > 0 && alpha < 65535)
1790             {
1791                png_uint_32 calc = component * reciprocal;
1792                calc += 16384; /* round to nearest */
1793                component = (png_uint_16)(calc >> 15);
1794             }
1795
1796             *out_ptr++ = component;
1797          }
1798          while (--c > 0);
1799
1800          /* Skip to next component (skip the intervening alpha channel) */
1801          ++in_ptr;
1802          ++out_ptr;
1803       }
1804
1805       png_write_row(png_ptr, png_voidcast(png_const_bytep, display->local_row));
1806       input_row += display->row_bytes/(sizeof (png_uint_16));
1807    }
1808
1809    return 1;
1810 }
1811
1812 /* Given 16-bit input (1 to 4 channels) write 8-bit output.  If an alpha channel
1813  * is present it must be removed from the components, the components are then
1814  * written in sRGB encoding.  No components are added or removed.
1815  *
1816  * Calculate an alpha reciprocal to reverse pre-multiplication.  As above the
1817  * calculation can be done to 15 bits of accuracy; however, the output needs to
1818  * be scaled in the range 0..255*65535, so include that scaling here.
1819  */
1820 #define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+(alpha>>1))/alpha)
1821
1822 static png_byte
1823 png_unpremultiply(png_uint_32 component, png_uint_32 alpha,
1824    png_uint_32 reciprocal/*from the above macro*/)
1825 {
1826    /* The following gives 1.0 for an alpha of 0, which is fine, otherwise if 0/0
1827     * is represented as some other value there is more likely to be a
1828     * discontinuity which will probably damage compression when moving from a
1829     * fully transparent area to a nearly transparent one.  (The assumption here
1830     * is that opaque areas tend not to be 0 intensity.)
1831     *
1832     * There is a rounding problem here; if alpha is less than 128 it will end up
1833     * as 0 when scaled to 8 bits.  To avoid introducing spurious colors into the
1834     * output change for this too.
1835     */
1836    if (component >= alpha || alpha < 128)
1837       return 255;
1838
1839    /* component<alpha, so component/alpha is less than one and
1840     * component*reciprocal is less than 2^31.
1841     */
1842    else if (component > 0)
1843    {
1844       /* The test is that alpha/257 (rounded) is less than 255, the first value
1845        * that becomes 255 is 65407.
1846        * NOTE: this must agree with the PNG_DIV257 macro (which must, therefore,
1847        * be exact!)  [Could also test reciprocal != 0]
1848        */
1849       if (alpha < 65407)
1850       {
1851          component *= reciprocal;
1852          component += 64; /* round to nearest */
1853          component >>= 7;
1854       }
1855
1856       else
1857          component *= 255;
1858
1859       /* Convert the component to sRGB. */
1860       return (png_byte)PNG_sRGB_FROM_LINEAR(component);
1861    }
1862
1863    else
1864       return 0;
1865 }
1866
1867 static int
1868 png_write_image_8bit(png_voidp argument)
1869 {
1870    png_image_write_control *display = png_voidcast(png_image_write_control*,
1871       argument);
1872    png_imagep image = display->image;
1873    png_structrp png_ptr = image->opaque->png_ptr;
1874
1875    png_const_uint_16p input_row = png_voidcast(png_const_uint_16p,
1876       display->first_row);
1877    png_bytep output_row = png_voidcast(png_bytep, display->local_row);
1878    png_uint_32 y = image->height;
1879    const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1;
1880
1881    if (image->format & PNG_FORMAT_FLAG_ALPHA)
1882    {
1883       png_bytep row_end;
1884       int aindex;
1885
1886 #     ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
1887          if (image->format & PNG_FORMAT_FLAG_AFIRST)
1888          {
1889             aindex = -1;
1890             ++input_row; /* To point to the first component */
1891             ++output_row;
1892          }
1893
1894          else
1895 #     endif
1896          aindex = channels;
1897
1898       /* Use row_end in place of a loop counter: */
1899       row_end = output_row + image->width * (channels+1);
1900
1901       while (y-- > 0)
1902       {
1903          png_const_uint_16p in_ptr = input_row;
1904          png_bytep out_ptr = output_row;
1905
1906          while (out_ptr < row_end)
1907          {
1908             png_uint_16 alpha = in_ptr[aindex];
1909             png_byte alphabyte = (png_byte)PNG_DIV257(alpha);
1910             png_uint_32 reciprocal = 0;
1911             int c;
1912
1913             /* Scale and write the alpha channel. */
1914             out_ptr[aindex] = alphabyte;
1915
1916             if (alphabyte > 0 && alphabyte < 255)
1917                reciprocal = UNP_RECIPROCAL(alpha);
1918
1919             c = channels;
1920             do /* always at least one channel */
1921                *out_ptr++ = png_unpremultiply(*in_ptr++, alpha, reciprocal);
1922             while (--c > 0);
1923
1924             /* Skip to next component (skip the intervening alpha channel) */
1925             ++in_ptr;
1926             ++out_ptr;
1927          } /* while out_ptr < row_end */
1928
1929          png_write_row(png_ptr, png_voidcast(png_const_bytep,
1930             display->local_row));
1931          input_row += display->row_bytes/(sizeof (png_uint_16));
1932       } /* while y */
1933    }
1934
1935    else
1936    {
1937       /* No alpha channel, so the row_end really is the end of the row and it
1938        * is sufficient to loop over the components one by one.
1939        */
1940       png_bytep row_end = output_row + image->width * channels;
1941
1942       while (y-- > 0)
1943       {
1944          png_const_uint_16p in_ptr = input_row;
1945          png_bytep out_ptr = output_row;
1946
1947          while (out_ptr < row_end)
1948          {
1949             png_uint_32 component = *in_ptr++;
1950
1951             component *= 255;
1952             *out_ptr++ = (png_byte)PNG_sRGB_FROM_LINEAR(component);
1953          }
1954
1955          png_write_row(png_ptr, output_row);
1956          input_row += display->row_bytes/(sizeof (png_uint_16));
1957       }
1958    }
1959
1960    return 1;
1961 }
1962
1963 static void
1964 png_image_set_PLTE(png_image_write_control *display)
1965 {
1966    const png_imagep image = display->image;
1967    const void *cmap = display->colormap;
1968    const int entries = image->colormap_entries > 256 ? 256 :
1969       (int)image->colormap_entries;
1970
1971    /* NOTE: the caller must check for cmap != NULL and entries != 0 */
1972    const png_uint_32 format = image->format;
1973    const int channels = PNG_IMAGE_SAMPLE_CHANNELS(format);
1974
1975 #  if defined(PNG_FORMAT_BGR_SUPPORTED) &&\
1976       defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED)
1977       const int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
1978          (format & PNG_FORMAT_FLAG_ALPHA) != 0;
1979 #  else
1980 #     define afirst 0
1981 #  endif
1982
1983 #  ifdef PNG_FORMAT_BGR_SUPPORTED
1984       const int bgr = (format & PNG_FORMAT_FLAG_BGR) ? 2 : 0;
1985 #  else
1986 #     define bgr 0
1987 #  endif
1988
1989    int i, num_trans;
1990    png_color palette[256];
1991    png_byte tRNS[256];
1992
1993    memset(tRNS, 255, (sizeof tRNS));
1994    memset(palette, 0, (sizeof palette));
1995
1996    for (i=num_trans=0; i<entries; ++i)
1997    {
1998       /* This gets automatically converted to sRGB with reversal of the
1999        * pre-multiplication if the color-map has an alpha channel.
2000        */
2001       if (format & PNG_FORMAT_FLAG_LINEAR)
2002       {
2003          png_const_uint_16p entry = png_voidcast(png_const_uint_16p, cmap);
2004
2005          entry += i * channels;
2006
2007          if (channels & 1) /* no alpha */
2008          {
2009             if (channels >= 3) /* RGB */
2010             {
2011                palette[i].blue = (png_byte)PNG_sRGB_FROM_LINEAR(255 *
2012                   entry[(2 ^ bgr)]);
2013                palette[i].green = (png_byte)PNG_sRGB_FROM_LINEAR(255 *
2014                   entry[1]);
2015                palette[i].red = (png_byte)PNG_sRGB_FROM_LINEAR(255 *
2016                   entry[bgr]);
2017             }
2018
2019             else /* Gray */
2020                palette[i].blue = palette[i].red = palette[i].green =
2021                   (png_byte)PNG_sRGB_FROM_LINEAR(255 * *entry);
2022          }
2023
2024          else /* alpha */
2025          {
2026             png_uint_16 alpha = entry[afirst ? 0 : channels-1];
2027             png_byte alphabyte = (png_byte)PNG_DIV257(alpha);
2028             png_uint_32 reciprocal = 0;
2029
2030             /* Calculate a reciprocal, as in the png_write_image_8bit code above
2031              * this is designed to produce a value scaled to 255*65535 when
2032              * divided by 128 (i.e. asr 7).
2033              */
2034             if (alphabyte > 0 && alphabyte < 255)
2035                reciprocal = (((0xffff*0xff)<<7)+(alpha>>1))/alpha;
2036
2037             tRNS[i] = alphabyte;
2038             if (alphabyte < 255)
2039                num_trans = i+1;
2040
2041             if (channels >= 3) /* RGB */
2042             {
2043                palette[i].blue = png_unpremultiply(entry[afirst + (2 ^ bgr)],
2044                   alpha, reciprocal);
2045                palette[i].green = png_unpremultiply(entry[afirst + 1], alpha,
2046                   reciprocal);
2047                palette[i].red = png_unpremultiply(entry[afirst + bgr], alpha,
2048                   reciprocal);
2049             }
2050
2051             else /* gray */
2052                palette[i].blue = palette[i].red = palette[i].green =
2053                   png_unpremultiply(entry[afirst], alpha, reciprocal);
2054          }
2055       }
2056
2057       else /* Color-map has sRGB values */
2058       {
2059          png_const_bytep entry = png_voidcast(png_const_bytep, cmap);
2060
2061          entry += i * channels;
2062
2063          switch (channels)
2064          {
2065             case 4:
2066                tRNS[i] = entry[afirst ? 0 : 3];
2067                if (tRNS[i] < 255)
2068                   num_trans = i+1;
2069                /* FALL THROUGH */
2070             case 3:
2071                palette[i].blue = entry[afirst + (2 ^ bgr)];
2072                palette[i].green = entry[afirst + 1];
2073                palette[i].red = entry[afirst + bgr];
2074                break;
2075
2076             case 2:
2077                tRNS[i] = entry[1 ^ afirst];
2078                if (tRNS[i] < 255)
2079                   num_trans = i+1;
2080                /* FALL THROUGH */
2081             case 1:
2082                palette[i].blue = palette[i].red = palette[i].green =
2083                   entry[afirst];
2084                break;
2085
2086             default:
2087                break;
2088          }
2089       }
2090    }
2091
2092 #  ifdef afirst
2093 #     undef afirst
2094 #  endif
2095 #  ifdef bgr
2096 #     undef bgr
2097 #  endif
2098
2099    png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette,
2100       entries);
2101
2102    if (num_trans > 0)
2103       png_set_tRNS(image->opaque->png_ptr, image->opaque->info_ptr, tRNS,
2104          num_trans, NULL);
2105
2106    image->colormap_entries = entries;
2107 }
2108
2109 static int
2110 png_image_write_main(png_voidp argument)
2111 {
2112    png_image_write_control *display = png_voidcast(png_image_write_control*,
2113       argument);
2114    png_imagep image = display->image;
2115    png_structrp png_ptr = image->opaque->png_ptr;
2116    png_inforp info_ptr = image->opaque->info_ptr;
2117    png_uint_32 format = image->format;
2118
2119    int colormap = (format & PNG_FORMAT_FLAG_COLORMAP) != 0;
2120    int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR) != 0; /* input */
2121    int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA) != 0;
2122    int write_16bit = linear && !colormap && !display->convert_to_8bit;
2123
2124 #  ifdef PNG_BENIGN_ERRORS_SUPPORTED
2125       /* Make sure we error out on any bad situation */
2126       png_set_benign_errors(png_ptr, 0/*error*/);
2127 #  endif
2128
2129    /* Default the 'row_stride' parameter if required. */
2130    if (display->row_stride == 0)
2131       display->row_stride = PNG_IMAGE_ROW_STRIDE(*image);
2132
2133    /* Set the required transforms then write the rows in the correct order. */
2134    if (format & PNG_FORMAT_FLAG_COLORMAP)
2135    {
2136       if (display->colormap != NULL && image->colormap_entries > 0)
2137       {
2138          png_uint_32 entries = image->colormap_entries;
2139
2140          png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
2141             entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)),
2142             PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
2143             PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
2144
2145          png_image_set_PLTE(display);
2146       }
2147
2148       else
2149          png_error(image->opaque->png_ptr,
2150             "no color-map for color-mapped image");
2151    }
2152
2153    else
2154       png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
2155          write_16bit ? 16 : 8,
2156          ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) +
2157          ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0),
2158          PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
2159
2160    /* Counter-intuitively the data transformations must be called *after*
2161     * png_write_info, not before as in the read code, but the 'set' functions
2162     * must still be called before.  Just set the color space information, never
2163     * write an interlaced image.
2164     */
2165
2166    if (write_16bit)
2167    {
2168       /* The gamma here is 1.0 (linear) and the cHRM chunk matches sRGB. */
2169       png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_LINEAR);
2170
2171       if (!(image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB))
2172          png_set_cHRM_fixed(png_ptr, info_ptr,
2173             /* color      x       y */
2174             /* white */ 31270, 32900,
2175             /* red   */ 64000, 33000,
2176             /* green */ 30000, 60000,
2177             /* blue  */ 15000,  6000
2178          );
2179    }
2180
2181    else if (!(image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB))
2182       png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL);
2183
2184    /* Else writing an 8-bit file and the *colors* aren't sRGB, but the 8-bit
2185     * space must still be gamma encoded.
2186     */
2187    else
2188       png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE);
2189
2190    /* Write the file header. */
2191    png_write_info(png_ptr, info_ptr);
2192
2193    /* Now set up the data transformations (*after* the header is written),
2194     * remove the handled transformations from the 'format' flags for checking.
2195     *
2196     * First check for a little endian system if writing 16 bit files.
2197     */
2198    if (write_16bit)
2199    {
2200       PNG_CONST png_uint_16 le = 0x0001;
2201
2202       if (*(png_const_bytep)&le)
2203          png_set_swap(png_ptr);
2204    }
2205
2206 #  ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
2207       if (format & PNG_FORMAT_FLAG_BGR)
2208       {
2209          if (!colormap && (format & PNG_FORMAT_FLAG_COLOR) != 0)
2210             png_set_bgr(png_ptr);
2211          format &= ~PNG_FORMAT_FLAG_BGR;
2212       }
2213 #  endif
2214
2215 #  ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
2216       if (format & PNG_FORMAT_FLAG_AFIRST)
2217       {
2218          if (!colormap && (format & PNG_FORMAT_FLAG_ALPHA) != 0)
2219             png_set_swap_alpha(png_ptr);
2220          format &= ~PNG_FORMAT_FLAG_AFIRST;
2221       }
2222 #  endif
2223
2224    /* If there are 16 or fewer color-map entries we wrote a lower bit depth
2225     * above, but the application data is still byte packed.
2226     */
2227    if (colormap && image->colormap_entries <= 16)
2228       png_set_packing(png_ptr);
2229
2230    /* That should have handled all (both) the transforms. */
2231    if ((format & ~(png_uint_32)(PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_LINEAR |
2232          PNG_FORMAT_FLAG_ALPHA | PNG_FORMAT_FLAG_COLORMAP)) != 0)
2233       png_error(png_ptr, "png_write_image: unsupported transformation");
2234
2235    {
2236       png_const_bytep row = png_voidcast(png_const_bytep, display->buffer);
2237       ptrdiff_t row_bytes = display->row_stride;
2238
2239       if (linear)
2240          row_bytes *= (sizeof (png_uint_16));
2241
2242       if (row_bytes < 0)
2243          row += (image->height-1) * (-row_bytes);
2244
2245       display->first_row = row;
2246       display->row_bytes = row_bytes;
2247    }
2248
2249    /* Apply 'fast' options if the flag is set. */
2250    if ((image->flags & PNG_IMAGE_FLAG_FAST) != 0)
2251    {
2252       png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_NO_FILTERS);
2253       /* NOTE: determined by experiment using pngstest, this reflects some
2254        * balance between the time to write the image once and the time to read
2255        * it about 50 times.  The speed-up in pngstest was about 10-20% of the
2256        * total (user) time on a heavily loaded system.
2257        */
2258       png_set_compression_level(png_ptr, 3);
2259    }
2260
2261    /* Check for the cases that currently require a pre-transform on the row
2262     * before it is written.  This only applies when the input is 16-bit and
2263     * either there is an alpha channel or it is converted to 8-bit.
2264     */
2265    if ((linear && alpha) || (!colormap && display->convert_to_8bit))
2266    {
2267       png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr,
2268          png_get_rowbytes(png_ptr, info_ptr)));
2269       int result;
2270
2271       display->local_row = row;
2272       if (write_16bit)
2273          result = png_safe_execute(image, png_write_image_16bit, display);
2274       else
2275          result = png_safe_execute(image, png_write_image_8bit, display);
2276       display->local_row = NULL;
2277
2278       png_free(png_ptr, row);
2279
2280       /* Skip the 'write_end' on error: */
2281       if (!result)
2282          return 0;
2283    }
2284
2285    /* Otherwise this is the case where the input is in a format currently
2286     * supported by the rest of the libpng write code; call it directly.
2287     */
2288    else
2289    {
2290       png_const_bytep row = png_voidcast(png_const_bytep, display->first_row);
2291       ptrdiff_t row_bytes = display->row_bytes;
2292       png_uint_32 y = image->height;
2293
2294       while (y-- > 0)
2295       {
2296          png_write_row(png_ptr, row);
2297          row += row_bytes;
2298       }
2299    }
2300
2301    png_write_end(png_ptr, info_ptr);
2302    return 1;
2303 }
2304
2305 int PNGAPI
2306 png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
2307    const void *buffer, png_int_32 row_stride, const void *colormap)
2308 {
2309    /* Write the image to the given (FILE*). */
2310    if (image != NULL && image->version == PNG_IMAGE_VERSION)
2311    {
2312       if (file != NULL)
2313       {
2314          if (png_image_write_init(image))
2315          {
2316             png_image_write_control display;
2317             int result;
2318
2319             /* This is slightly evil, but png_init_io doesn't do anything other
2320              * than this and we haven't changed the standard IO functions so
2321              * this saves a 'safe' function.
2322              */
2323             image->opaque->png_ptr->io_ptr = file;
2324
2325             memset(&display, 0, (sizeof display));
2326             display.image = image;
2327             display.buffer = buffer;
2328             display.row_stride = row_stride;
2329             display.colormap = colormap;
2330             display.convert_to_8bit = convert_to_8bit;
2331
2332             result = png_safe_execute(image, png_image_write_main, &display);
2333             png_image_free(image);
2334             return result;
2335          }
2336
2337          else
2338             return 0;
2339       }
2340
2341       else
2342          return png_image_error(image,
2343             "png_image_write_to_stdio: invalid argument");
2344    }
2345
2346    else if (image != NULL)
2347       return png_image_error(image,
2348          "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION");
2349
2350    else
2351       return 0;
2352 }
2353
2354 int PNGAPI
2355 png_image_write_to_file(png_imagep image, const char *file_name,
2356    int convert_to_8bit, const void *buffer, png_int_32 row_stride,
2357    const void *colormap)
2358 {
2359    /* Write the image to the named file. */
2360    if (image != NULL && image->version == PNG_IMAGE_VERSION)
2361    {
2362       if (file_name != NULL)
2363       {
2364          FILE *fp = fopen(file_name, "wb");
2365
2366          if (fp != NULL)
2367          {
2368             if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer,
2369                row_stride, colormap))
2370             {
2371                int error; /* from fflush/fclose */
2372
2373                /* Make sure the file is flushed correctly. */
2374                if (fflush(fp) == 0 && ferror(fp) == 0)
2375                {
2376                   if (fclose(fp) == 0)
2377                      return 1;
2378
2379                   error = errno; /* from fclose */
2380                }
2381
2382                else
2383                {
2384                   error = errno; /* from fflush or ferror */
2385                   (void)fclose(fp);
2386                }
2387
2388                (void)remove(file_name);
2389                /* The image has already been cleaned up; this is just used to
2390                 * set the error (because the original write succeeded).
2391                 */
2392                return png_image_error(image, strerror(error));
2393             }
2394
2395             else
2396             {
2397                /* Clean up: just the opened file. */
2398                (void)fclose(fp);
2399                (void)remove(file_name);
2400                return 0;
2401             }
2402          }
2403
2404          else
2405             return png_image_error(image, strerror(errno));
2406       }
2407
2408       else
2409          return png_image_error(image,
2410             "png_image_write_to_file: invalid argument");
2411    }
2412
2413    else if (image != NULL)
2414       return png_image_error(image,
2415          "png_image_write_to_file: incorrect PNG_IMAGE_VERSION");
2416
2417    else
2418       return 0;
2419 }
2420 #endif /* PNG_STDIO_SUPPORTED */
2421 #endif /* SIMPLIFIED_WRITE */
2422 #endif /* PNG_WRITE_SUPPORTED */