pngcrush  1.8.13
About: Pngcrush is an optimizer for PNG (Portable Network Graphics) files.
  Fossies Dox: pngcrush-1.8.13.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

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