QtBase  v6.3.1
pngwrite.c
Go to the documentation of this file.
1 
2 /* pngwrite.c - general routines to write a PNG file
3  *
4  * Copyright (c) 2018-2019 Cosmin Truta
5  * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
6  * Copyright (c) 1996-1997 Andreas Dilger
7  * 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
24 write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr,
25  unsigned int where)
26 {
27  if (info_ptr->unknown_chunks_num != 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 */
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  {
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)
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 
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 
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 */
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 */
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 */
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
466 # endif
467 #endif
468 }
469 
470 #ifdef PNG_CONVERT_tIME_SUPPORTED
471 void PNGAPI
472 png_convert_from_struct_tm(png_timep ptime, const struct tm * ttime)
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,
499  png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)
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,
513  png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
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
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  */
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
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  */
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
634 png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
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)
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)
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 
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  {
768  return;
769  }
770  break;
771 
772  case 1:
773  if ((png_ptr->row_number & 0x07) != 0 || png_ptr->width < 5)
774  {
776  return;
777  }
778  break;
779 
780  case 2:
781  if ((png_ptr->row_number & 0x07) != 4)
782  {
784  return;
785  }
786  break;
787 
788  case 3:
789  if ((png_ptr->row_number & 0x03) != 0 || png_ptr->width < 3)
790  {
792  return;
793  }
794  break;
795 
796  case 4:
797  if ((png_ptr->row_number & 0x03) != 2)
798  {
800  return;
801  }
802  break;
803 
804  case 5:
805  if ((png_ptr->row_number & 0x01) != 0 || png_ptr->width < 2)
806  {
808  return;
809  }
810  break;
811 
812  case 6:
813  if ((png_ptr->row_number & 0x01) == 0)
814  {
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  {
854  return;
855  }
856  }
857 #endif
858 
859 #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
860  /* Handle other transformations */
861  if (png_ptr->transformations != 0)
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)
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
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 
932  png_ptr->flush_rows = 0;
934 }
935 #endif /* WRITE_FLUSH */
936 
937 /* Free any memory used in png_ptr struct without freeing the struct itself. */
938 static void
939 png_write_destroy(png_structrp png_ptr)
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);
994  }
995  }
996 }
997 
998 /* Allow the application to select one or more row filters to use. */
999 void PNGAPI
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 
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  */
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
1130  int num_weights, png_const_doublep filter_weights,
1131  png_const_doublep filter_costs)
1132 {
1137  PNG_UNUSED(filter_costs)
1138 }
1139 #endif /* FLOATING_POINT */
1140 
1141 #ifdef PNG_FIXED_POINT_SUPPORTED
1142 void PNGAPI
1145  png_const_fixed_point_p filter_costs)
1146 {
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
1317 png_set_write_status_fn(png_structrp png_ptr, png_write_status_ptr write_row_fn)
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. */
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
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
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
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)
1407  "PNG_TRANSFORM_STRIP_FILLER: BEFORE+AFTER not supported");
1408 
1409  /* Continue if ignored - this is the pre-1.6.10 behavior */
1411  }
1412 
1413  else if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0)
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
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
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
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
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 */
1459 
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 {
1470  png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, image,
1471  png_safe_error, png_safe_warning);
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  {
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 */
1496  }
1497 
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: */
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
1528 png_write_image_16bit(png_voidp argument)
1529 {
1531  argument);
1532  png_imagep image = display->image;
1533  png_structrp png_ptr = image->opaque->png_ptr;
1534 
1536  display->first_row);
1538  png_uint_16p row_end;
1539  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  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 
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
1687 png_write_image_8bit(png_voidp argument)
1688 {
1690  argument);
1691  png_imagep image = display->image;
1692  png_structrp png_ptr = image->opaque->png_ptr;
1693 
1695  display->first_row);
1697  png_uint_32 y = image->height;
1698  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));
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 
1777  }
1778  }
1779 
1780  return 1;
1781 }
1782 
1783 static void
1784 png_image_set_PLTE(png_image_write_control *display)
1785 {
1786  png_imagep image = display->image;
1787  const void *cmap = display->colormap;
1788  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  png_uint_32 format = image->format;
1793  unsigned int channels = PNG_IMAGE_SAMPLE_CHANNELS(format);
1794 
1795 # if defined(PNG_FORMAT_BGR_SUPPORTED) &&\
1796  defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED)
1797  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  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
1930 png_image_write_main(png_voidp argument)
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 && (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  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  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,
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. */
2025 
2026  if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0)
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)
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
2044 
2045  /* Write the file header. */
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_uint_16 le = 0x0001;
2056 
2057  if ((*(png_const_bytep) & le) != 0)
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)
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)
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)
2084 
2085  /* That should have handled all (both) the transforms. */
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
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,
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  {
2155  row += row_bytes;
2156  }
2157  }
2158 
2160  return 1;
2161 }
2162 
2163 
2164 static void (PNGCBAPI
2165 image_memory_write)(png_structp png_ptr, png_bytep/*const*/ data, size_t size)
2166 {
2168  png_ptr->io_ptr/*backdoor: png_get_io_ptr(png_ptr)*/);
2170 
2171  /* Check for overflow; this should never happen: */
2172  if (size <= ((png_alloc_size_t)-1) - ob)
2173  {
2174  /* I don't think libpng ever does this, but just in case: */
2175  if (size > 0)
2176  {
2177  if (display->memory_bytes >= ob+size) /* writing */
2178  memcpy(display->memory+ob, data, size);
2179 
2180  /* Always update the size: */
2181  display->output_bytes = ob+size;
2182  }
2183  }
2184 
2185  else
2186  png_error(png_ptr, "png_image_write_to_memory: PNG too big");
2187 }
2188 
2189 static void (PNGCBAPI
2190 image_memory_flush)(png_structp png_ptr)
2191 {
2193 }
2194 
2195 static int
2196 png_image_write_memory(png_voidp argument)
2197 {
2199  argument);
2200 
2201  /* The rest of the memory-specific init and write_main in an error protected
2202  * environment. This case needs to use callbacks for the write operations
2203  * since libpng has no built in support for writing to memory.
2204  */
2205  png_set_write_fn(display->image->opaque->png_ptr, display/*io_ptr*/,
2206  image_memory_write, image_memory_flush);
2207 
2208  return png_image_write_main(display);
2209 }
2210 
2211 int PNGAPI
2213  png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8bit,
2214  const void *buffer, png_int_32 row_stride, const void *colormap)
2215 {
2216  /* Write the image to the given buffer, or count the bytes if it is NULL */
2217  if (image != NULL && image->version == PNG_IMAGE_VERSION)
2218  {
2219  if (memory_bytes != NULL && buffer != NULL)
2220  {
2221  /* This is to give the caller an easier error detection in the NULL
2222  * case and guard against uninitialized variable problems:
2223  */
2224  if (memory == NULL)
2225  *memory_bytes = 0;
2226 
2227  if (png_image_write_init(image) != 0)
2228  {
2229  png_image_write_control display;
2230  int result;
2231 
2232  memset(&display, 0, (sizeof display));
2233  display.image = image;
2234  display.buffer = buffer;
2235  display.row_stride = row_stride;
2236  display.colormap = colormap;
2237  display.convert_to_8bit = convert_to_8bit;
2238  display.memory = png_voidcast(png_bytep, memory);
2239  display.memory_bytes = *memory_bytes;
2240  display.output_bytes = 0;
2241 
2242  result = png_safe_execute(image, png_image_write_memory, &display);
2244 
2245  /* write_memory returns true even if we ran out of buffer. */
2246  if (result)
2247  {
2248  /* On out-of-buffer this function returns '0' but still updates
2249  * memory_bytes:
2250  */
2251  if (memory != NULL && display.output_bytes > *memory_bytes)
2252  result = 0;
2253 
2254  *memory_bytes = display.output_bytes;
2255  }
2256 
2257  return result;
2258  }
2259 
2260  else
2261  return 0;
2262  }
2263 
2264  else
2265  return png_image_error(image,
2266  "png_image_write_to_memory: invalid argument");
2267  }
2268 
2269  else if (image != NULL)
2270  return png_image_error(image,
2271  "png_image_write_to_memory: incorrect PNG_IMAGE_VERSION");
2272 
2273  else
2274  return 0;
2275 }
2276 
2277 #ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
2278 int PNGAPI
2279 png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
2280  const void *buffer, png_int_32 row_stride, const void *colormap)
2281 {
2282  /* Write the image to the given (FILE*). */
2283  if (image != NULL && image->version == PNG_IMAGE_VERSION)
2284  {
2285  if (file != NULL && buffer != NULL)
2286  {
2287  if (png_image_write_init(image) != 0)
2288  {
2289  png_image_write_control display;
2290  int result;
2291 
2292  /* This is slightly evil, but png_init_io doesn't do anything other
2293  * than this and we haven't changed the standard IO functions so
2294  * this saves a 'safe' function.
2295  */
2296  image->opaque->png_ptr->io_ptr = file;
2297 
2298  memset(&display, 0, (sizeof display));
2299  display.image = image;
2300  display.buffer = buffer;
2301  display.row_stride = row_stride;
2302  display.colormap = colormap;
2303  display.convert_to_8bit = convert_to_8bit;
2304 
2305  result = png_safe_execute(image, png_image_write_main, &display);
2307  return result;
2308  }
2309 
2310  else
2311  return 0;
2312  }
2313 
2314  else
2315  return png_image_error(image,
2316  "png_image_write_to_stdio: invalid argument");
2317  }
2318 
2319  else if (image != NULL)
2320  return png_image_error(image,
2321  "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION");
2322 
2323  else
2324  return 0;
2325 }
2326 
2327 int PNGAPI
2329  int convert_to_8bit, const void *buffer, png_int_32 row_stride,
2330  const void *colormap)
2331 {
2332  /* Write the image to the named file. */
2333  if (image != NULL && image->version == PNG_IMAGE_VERSION)
2334  {
2335  if (file_name != NULL && buffer != NULL)
2336  {
2337  FILE *fp = fopen(file_name, "wb");
2338 
2339  if (fp != NULL)
2340  {
2341  if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer,
2342  row_stride, colormap) != 0)
2343  {
2344  int error; /* from fflush/fclose */
2345 
2346  /* Make sure the file is flushed correctly. */
2347  if (fflush(fp) == 0 && ferror(fp) == 0)
2348  {
2349  if (fclose(fp) == 0)
2350  return 1;
2351 
2352  error = errno; /* from fclose */
2353  }
2354 
2355  else
2356  {
2357  error = errno; /* from fflush or ferror */
2358  (void)fclose(fp);
2359  }
2360 
2361  (void)remove(file_name);
2362  /* The image has already been cleaned up; this is just used to
2363  * set the error (because the original write succeeded).
2364  */
2365  return png_image_error(image, strerror(error));
2366  }
2367 
2368  else
2369  {
2370  /* Clean up: just the opened file. */
2371  (void)fclose(fp);
2372  (void)remove(file_name);
2373  return 0;
2374  }
2375  }
2376 
2377  else
2378  return png_image_error(image, strerror(errno));
2379  }
2380 
2381  else
2382  return png_image_error(image,
2383  "png_image_write_to_file: invalid argument");
2384  }
2385 
2386  else if (image != NULL)
2387  return png_image_error(image,
2388  "png_image_write_to_file: incorrect PNG_IMAGE_VERSION");
2389 
2390  else
2391  return 0;
2392 }
2393 #endif /* SIMPLIFIED_WRITE_STDIO */
2394 #endif /* SIMPLIFIED_WRITE */
2395 #endif /* WRITE */
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
sizeof(AF_ModuleRec)
FT_Error error
Definition: cffdrivr.c:657
char * data()
int ZEXPORT deflateEnd(z_streamp strm)
Definition: deflate.c:1119
palette
#define Z_SYNC_FLUSH
Definition: zlib.h:127
#define NULL
Definition: ftobjs.h:61
Byte * voidp
Definition: ftzconf.h:240
JBLOCKROW output_row
Definition: jpegint.h:365
int JSAMPARRAY int int num_rows
Definition: jpegint.h:364
JSAMPIMAGE JDIMENSION input_row
Definition: jsimd.h:30
Definition: image.cpp:51
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld endif[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld SRC pixld MASK if DST_R else pixld DST_R endif if
int png_image_error(png_imagep image, png_const_charp error_message)
Definition: png.c:4597
void PNGAPI png_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr)
Definition: png.c:386
int PNGAPI png_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name)
Definition: png.c:926
void PNGAPI png_image_free(png_imagep image)
Definition: png.c:4582
#define PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB
Definition: png.h:2935
#define PNG_FORMAT_FLAG_COLOR
Definition: png.h:2776
#define PNG_TRANSFORM_SWAP_ENDIAN
Definition: png.h:839
#define PNG_INFO_cHRM
Definition: png.h:731
#define PNG_IMAGE_VERSION
Definition: png.h:2666
#define PNG_FILTER_SUB
Definition: png.h:1463
#define PNG_TEXT_COMPRESSION_zTXt_WR
Definition: png.h:584
#define PNG_TRANSFORM_INVERT_ALPHA
Definition: png.h:840
#define PNG_FILTER_PAETH
Definition: png.h:1466
#define PNG_INTRAPIXEL_DIFFERENCING
Definition: png.h:680
#define PNG_FILLER_BEFORE
Definition: png.h:1245
#define PNG_TRANSFORM_PACKING
Definition: png.h:832
#define PNG_FORMAT_FLAG_AFIRST
Definition: png.h:2785
#define PNG_HAVE_PLTE
Definition: png.h:642
#define PNG_INFO_gAMA
Definition: png.h:729
#define PNG_GAMMA_LINEAR
Definition: png.h:1147
#define PNG_COLOR_TYPE_RGB
Definition: png.h:667
#define PNG_MAX_PALETTE_LENGTH
Definition: png.h:722
#define PNG_FILTER_NONE
Definition: png.h:1462
png_structrp png_ptr
Definition: png.h:1080
#define PNG_TRANSFORM_SWAP_ALPHA
Definition: png.h:838
#define PNG_FORMAT_FLAG_COLORMAP
Definition: png.h:2778
#define PNG_FILTER_AVG
Definition: png.h:1465
png_uint_32
Definition: png.h:1936
#define PNG_INFO_pHYs
Definition: png.h:736
void
Definition: png.h:1080
#define PNG_INFO_sPLT
Definition: png.h:742
#define PNG_TRANSFORM_INVERT_MONO
Definition: png.h:835
#define PNG_TEXT_COMPRESSION_zTXt
Definition: png.h:586
#define PNG_IMAGE_FLAG_FAST
Definition: png.h:2940
#define PNG_COLOR_TYPE_RGB_ALPHA
Definition: png.h:668
#define PNG_FLAG_MNG_FILTER_64
Definition: png.h:855
#define PNG_INFO_pCAL
Definition: png.h:739
png_structrp int int num_weights
Definition: png.h:1486
#define PNG_TRANSFORM_PACKSWAP
Definition: png.h:833
#define PNG_TEXT_COMPRESSION_NONE
Definition: png.h:585
png_structrp int png_fixed_point red
Definition: png.h:1081
#define PNG_TEXT_COMPRESSION_NONE_WR
Definition: png.h:583
#define PNG_INFO_IDAT
Definition: png.h:744
#define PNG_FORMAT_FLAG_BGR
Definition: png.h:2781
#define PNG_FILTER_VALUE_AVG
Definition: png.h:1476
#define PNG_COLOR_MASK_COLOR
Definition: png.h:661
#define PNG_INFO_eXIf
Definition: png.h:745
#define PNG_ALL_FILTERS
Definition: png.h:1468
#define PNG_TRANSFORM_STRIP_FILLER_AFTER
Definition: png.h:844
#define PNG_FILTER_VALUE_UP
Definition: png.h:1475
#define PNG_TRANSFORM_BGR
Definition: png.h:837
#define PNG_INFO_tIME
Definition: png.h:738
#define PNG_TRANSFORM_STRIP_FILLER_BEFORE
Definition: png.h:843
#define PNG_INFO_sRGB
Definition: png.h:740
#define PNG_FILTER_TYPE_BASE
Definition: png.h:679
#define PNG_FILLER_AFTER
Definition: png.h:1246
#define PNG_HANDLE_CHUNK_NEVER
Definition: png.h:2343
#define PNG_AFTER_IDAT
Definition: png.h:643
#define PNG_COLOR_MASK_ALPHA
Definition: png.h:662
#define PNG_HANDLE_CHUNK_ALWAYS
Definition: png.h:2345
#define PNG_FORMAT_FLAG_LINEAR
Definition: png.h:2777
#define PNG_HAVE_IHDR
Definition: png.h:641
#define PNG_INFO_sBIT
Definition: png.h:730
#define PNG_sRGB_INTENT_PERCEPTUAL
Definition: png.h:712
png_structrp int heuristic_method
Definition: png.h:1486
#define PNG_INFO_tRNS
Definition: png.h:733
#define PNG_INFO_sCAL
Definition: png.h:743
#define PNG_INFO_bKGD
Definition: png.h:734
#define PNG_FILTER_UP
Definition: png.h:1464
#define PNG_INFO_hIST
Definition: png.h:735
const png_info *PNG_RESTRICT png_const_inforp
Definition: png.h:469
#define PNG_INFO_iCCP
Definition: png.h:741
#define PNG_INFO_PLTE
Definition: png.h:732
#define PNG_COLOR_TYPE_PALETTE
Definition: png.h:666
#define PNG_FILTER_VALUE_PAETH
Definition: png.h:1477
#define PNG_LIBPNG_VER_STRING
Definition: png.h:281
#define PNG_FORMAT_FLAG_ALPHA
Definition: png.h:2775
#define PNG_NO_FILTERS
Definition: png.h:1461
#define PNG_FILTER_VALUE_NONE
Definition: png.h:1473
png_structrp int int png_const_fixed_point_p filter_weights
Definition: png.h:1487
png_const_structrp png_const_inforp png_fixed_point *int_file_gamma png_set_gAMA_fixed
Definition: png.h:2001
#define PNG_INTERLACE_NONE
Definition: png.h:684
#define PNG_INFO_oFFs
Definition: png.h:737
#define PNG_IMAGE_SAMPLE_CHANNELS(fmt)
Definition: png.h:2843
png_info *PNG_RESTRICT png_inforp
Definition: png.h:468
#define PNG_COMPRESSION_TYPE_BASE
Definition: png.h:675
#define PNG_FILTER_VALUE_SUB
Definition: png.h:1474
#define PNG_IMAGE_PIXEL_CHANNELS(fmt)
Definition: png.h:2879
#define PNG_HANDLE_CHUNK_AS_DEFAULT
Definition: png.h:2342
png_struct *PNG_RESTRICT png_structrp
Definition: png.h:466
#define PNG_TRANSFORM_SHIFT
Definition: png.h:836
png_const_structrp png_const_inforp info_ptr
Definition: png.h:1937
const png_byte * png_const_bytep
Definition: pngconf.h:580
const png_uint_16 * png_const_uint_16p
Definition: pngconf.h:586
size_t png_alloc_size_t
Definition: pngconf.h:557
#define PNGAPI
Definition: pngconf.h:261
png_byte * png_bytep
Definition: pngconf.h:579
png_byte ** png_bytepp
Definition: pngconf.h:606
png_uint_16 * png_uint_16p
Definition: pngconf.h:585
#define PNGCBAPI
Definition: pngconf.h:258
void * png_voidp
Definition: pngconf.h:577
const void * png_const_voidp
Definition: pngconf.h:578
const png_fixed_point * png_const_fixed_point_p
Definition: pngconf.h:592
#define PNG_ALLOCATED
Definition: pngconf.h:439
const char * png_const_charp
Definition: pngconf.h:590
#define PNG_RESTRICT
Definition: pngconf.h:445
#define png_debug2(l, m, p1, p2)
Definition: pngdebug.h:151
#define png_debug(l, m)
Definition: pngdebug.h:145
#define png_debug1(l, m, p1)
Definition: pngdebug.h:148
void PNGAPI png_benign_error(png_const_structrp png_ptr, png_const_charp error_message)
Definition: pngerror.c:362
void png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)
Definition: pngerror.c:392
void PNGAPI png_warning(png_const_structrp png_ptr, png_const_charp warning_message)
Definition: pngerror.c:216
void PNGCBAPI png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message)
Definition: pngerror.c:921
int png_safe_execute(png_imagep image_in, int(*function)(png_voidp), png_voidp arg)
Definition: pngerror.c:936
void png_app_error(png_const_structrp png_ptr, png_const_charp error_message)
Definition: pngerror.c:405
size_t PNGAPI png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr)
Definition: pngget.c:30
#define PNG_Z_DEFAULT_STRATEGY
Definition: pnglibconf.h:215
#define PNG_TEXT_Z_DEFAULT_COMPRESSION
Definition: pnglibconf.h:205
#define PNG_WRITE_INTERLACING_SUPPORTED
Definition: pnglibconf.h:138
#define PNG_Z_DEFAULT_COMPRESSION
Definition: pnglibconf.h:213
#define PNG_ZBUF_SIZE
Definition: pnglibconf.h:211
#define PNG_TEXT_Z_DEFAULT_STRATEGY
Definition: pnglibconf.h:206
void PNGAPI png_free(png_const_structrp png_ptr, png_voidp ptr)
Definition: pngmem.c:232
void png_destroy_png_struct(png_structrp png_ptr)
Definition: pngmem.c:25
#define PNG_UNUSED(param)
Definition: pngpriv.h:449
#define PNG_HAVE_PNG_SIGNATURE
Definition: pngpriv.h:647
#define PNG_INTERLACE
Definition: pngpriv.h:654
#define PNG_ROWBYTES(pixel_bits, width)
Definition: pngpriv.h:749
#define PNG_FLAG_BENIGN_ERRORS_WARN
Definition: pngpriv.h:710
#define PNG_INVERT_ALPHA
Definition: pngpriv.h:672
#define PNG_DIV257(v16)
Definition: pngpriv.h:746
#define PNG_USER_TRANSFORM
Definition: pngpriv.h:673
#define PNG_WROTE_INFO_BEFORE_PLTE
Definition: pngpriv.h:645
#define PNG_SHIFT
Definition: pngpriv.h:656
#define PNG_HAVE_IDAT
Definition: pngpriv.h:637
#define PNG_FLAG_APP_WARNINGS_WARN
Definition: pngpriv.h:711
#define PNG_FILLER
Definition: pngpriv.h:668
#define PNG_WROTE_tIME
Definition: pngpriv.h:644
#define PNG_FLAG_ZSTREAM_INITIALIZED
Definition: pngpriv.h:691
#define PNG_GAMMA_sRGB_INVERSE
Definition: pngpriv.h:917
#define PNG_sRGB_FROM_LINEAR(linear)
Definition: pngpriv.h:963
#define png_voidcast(type, value)
Definition: pngpriv.h:505
#define PNG_INVERT_MONO
Definition: pngpriv.h:658
#define PNG_PACK
Definition: pngpriv.h:655
#define PNG_PACKSWAP
Definition: pngpriv.h:669
#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY
Definition: pngpriv.h:690
#define PNG_SWAP_BYTES
Definition: pngpriv.h:657
#define PNG_BGR
Definition: pngpriv.h:653
png_int_32(PNGAPI png_get_int_32)(png_const_bytep buf)
Definition: pngrutil.c:84
png_uint_16(PNGAPI png_get_uint_16)(png_const_bytep buf)
Definition: pngrutil.c:102
void PNGAPI png_set_benign_errors(png_structrp png_ptr, int allowed)
Definition: pngset.c:1671
void PNGAPI 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_type, int compression_type, int filter_type)
Definition: pngset.c:254
void PNGAPI png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_const_colorp palette, int num_palette)
Definition: pngset.c:572
void PNGFAPI png_set_cHRM_fixed(png_const_structrp png_ptr, png_inforp info_ptr, png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x, png_fixed_point blue_y)
Definition: pngset.c:40
void PNGAPI png_set_sRGB(png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent)
Definition: pngset.c:653
void PNGAPI 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
void PNGAPI png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
Definition: pngtrans.c:120
void png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
Definition: pngtrans.c:699
void PNGAPI png_set_bgr(png_structrp png_ptr)
Definition: pngtrans.c:21
void PNGAPI png_set_swap(png_structrp png_ptr)
Definition: pngtrans.c:35
void PNGAPI png_set_packswap(png_structrp png_ptr)
Definition: pngtrans.c:70
void PNGAPI png_set_invert_mono(png_structrp png_ptr)
Definition: pngtrans.c:250
void PNGAPI png_set_packing(png_structrp png_ptr)
Definition: pngtrans.c:50
void PNGAPI png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits)
Definition: pngtrans.c:84
void PNGAPI png_set_invert_alpha(png_structrp png_ptr)
Definition: pngtrans.c:237
int PNGAPI png_set_interlace_handling(png_structrp png_ptr)
Definition: pngtrans.c:99
void PNGAPI png_set_swap_alpha(png_structrp png_ptr)
Definition: pngtrans.c:223
void PNGAPI 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
void png_flush(png_structrp png_ptr)
Definition: pngwio.c:71
void PNGAPI 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
void PNGAPI png_convert_from_struct_tm(png_timep ptime, const struct tm *ttime)
Definition: pngwrite.c:472
int PNGAPI 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:2328
void PNGAPI png_write_png(png_structrp png_ptr, png_inforp info_ptr, int transforms, voidp params)
Definition: pngwrite.c:1343
static png_bytep size_t size
Definition: pngwrite.c:2166
void PNGAPI png_set_compression_method(png_structrp png_ptr, int method)
Definition: pngwrite.c:1224
else png_error(png_ptr, "png_image_write_to_memory: PNG too big")
void PNGAPI png_set_write_status_fn(png_structrp png_ptr, png_write_status_ptr write_row_fn)
Definition: pngwrite.c:1317
void PNGAPI png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
Definition: pngwrite.c:192
void PNGAPI png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr)
Definition: pngwrite.c:84
void PNGAPI png_set_flush(png_structrp png_ptr, int nrows)
Definition: pngwrite.c:908
void PNGAPI png_set_write_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr write_user_transform_fn)
Definition: pngwrite.c:1327
void PNGAPI png_set_compression_strategy(png_structrp png_ptr, int strategy)
Definition: pngwrite.c:1180
png_alloc_size_t ob
Definition: pngwrite.c:2169
void PNGAPI png_set_text_compression_mem_level(png_structrp png_ptr, int mem_level)
Definition: pngwrite.c:1255
if(size<=((png_alloc_size_t) -1) - ob)
Definition: pngwrite.c:2172
#define UNP_RECIPROCAL(alpha)
Definition: pngwrite.c:1639
void PNGAPI png_set_filter(png_structrp png_ptr, int method, int filters)
Definition: pngwrite.c:1000
void PNGAPI 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_FUNCTION(png_structp, PNGAPI png_create_write_struct,(png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn), PNG_ALLOCATED)
Definition: pngwrite.c:497
void PNGAPI png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
Definition: pngwrite.c:979
void PNGAPI png_set_compression_window_bits(png_structrp png_ptr, int window_bits)
Definition: pngwrite.c:1197
void PNGAPI png_write_row(png_structrp png_ptr, png_const_bytep row)
Definition: pngwrite.c:698
void PNGAPI png_convert_from_time_t(png_timep ptime, time_t ttime)
Definition: pngwrite.c:485
void PNGAPI png_write_end(png_structrp png_ptr, png_inforp info_ptr)
Definition: pngwrite.c:358
void PNGAPI png_set_text_compression_strategy(png_structrp png_ptr, int strategy)
Definition: pngwrite.c:1266
void PNGAPI png_write_flush(png_structrp png_ptr)
Definition: pngwrite.c:920
void PNGAPI png_write_rows(png_structrp png_ptr, png_bytepp row, png_uint_32 num_rows)
Definition: pngwrite.c:579
int PNGAPI 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:2279
void PNGAPI png_set_compression_mem_level(png_structrp png_ptr, int mem_level)
Definition: pngwrite.c:1169
void PNGAPI png_set_text_compression_method(png_structrp png_ptr, int method)
Definition: pngwrite.c:1301
void PNGAPI png_write_image(png_structrp png_ptr, png_bytepp image)
Definition: pngwrite.c:601
void PNGAPI png_set_compression_level(png_structrp png_ptr, int level)
Definition: pngwrite.c:1158
void PNGAPI png_set_text_compression_window_bits(png_structrp png_ptr, int window_bits)
Definition: pngwrite.c:1280
int PNGAPI png_image_write_to_memory(png_imagep image, void *memory, png_alloc_size_t *PNG_RESTRICT memory_bytes, int convert_to_8bit, const void *buffer, png_int_32 row_stride, const void *colormap)
Definition: pngwrite.c:2212
void PNGAPI png_set_text_compression_level(png_structrp png_ptr, int level)
Definition: pngwrite.c:1244
void png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)
Definition: pngwtran.c:501
void png_write_finish_row(png_structrp png_ptr)
Definition: pngwutil.c:2005
void png_write_sRGB(png_structrp png_ptr, int srgb_intent)
Definition: pngwutil.c:1099
void png_free_buffer_list(png_structrp png_ptr, png_compression_bufferp *listp)
Definition: pngwutil.c:439
void png_write_sCAL_s(png_structrp png_ptr, int unit, png_const_charp width, png_const_charp height)
Definition: pngwutil.c:1809
void png_write_iCCP(png_structrp png_ptr, png_const_charp name, png_const_bytep profile)
Definition: pngwutil.c:1117
void png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist)
Definition: pngwutil.c:1499
void PNGAPI png_write_sig(png_structrp png_ptr)
Definition: pngwutil.c:51
void png_write_IEND(png_structrp png_ptr)
Definition: pngwutil.c:1073
void png_write_oFFs(png_structrp png_ptr, png_int_32 x_offset, png_int_32 y_offset, int unit_type)
Definition: pngwutil.c:1724
void png_write_gAMA_fixed(png_structrp png_ptr, png_fixed_point file_gamma)
Definition: pngwutil.c:1084
void png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type)
Definition: pngwutil.c:1263
void png_write_PLTE(png_structrp png_ptr, png_const_colorp palette, png_uint_32 num_pal)
Definition: pngwutil.c:842
void png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type)
Definition: pngwutil.c:1414
void PNGAPI png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string, png_const_bytep data, size_t length)
Definition: pngwutil.c:192
void png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette)
Definition: pngwutil.c:1179
void png_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, int compression)
Definition: pngwutil.c:1573
void png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
Definition: pngwutil.c:2096
void png_compress_IDAT(png_structrp png_ptr, png_const_bytep input, png_alloc_size_t input_len, int flush)
Definition: pngwutil.c:931
void png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
Definition: pngwutil.c:2550
void png_write_tIME(png_structrp png_ptr, png_const_timep mod_time)
Definition: pngwutil.c:1863
void png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, int color_type, int compression_type, int filter_type, int interlace_type)
Definition: pngwutil.c:672
void png_write_eXIf(png_structrp png_ptr, png_bytep exif, int num_exif)
Definition: pngwutil.c:1477
void png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha, png_const_color_16p tran, int num_trans, int color_type)
Definition: pngwutil.c:1348
void png_write_cHRM_fixed(png_structrp png_ptr, const png_xy *xy)
Definition: pngwutil.c:1322
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:1744
void png_write_start_row(png_structrp png_ptr)
Definition: pngwutil.c:1890
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:1839
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:1624
void png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, size_t text_len)
Definition: pngwutil.c:1530
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char * method
GLenum GLuint GLint level
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
GLenum GLuint buffer
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint GLsizei GLsizei GLenum format
GLsizei GLenum GLsizei GLsizei GLuint memory
GLint y
void ** params
GLeglImageOES image
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s0
GLbyte GLbyte blue
Definition: qopenglext.h:385
const GLubyte * c
Definition: qopenglext.h:12701
GLuint entry
Definition: qopenglext.h:11002
GLenum GLenum GLsizei void * row
Definition: qopenglext.h:2747
GLuint64EXT * result
[6]
Definition: qopenglext.h:10932
GLfloat GLfloat GLfloat alpha
Definition: qopenglext.h:418
#define s2
QFile file
[0]
settings remove("monkey")
QPointer< QFile > fp(new QFile)
[11]
const QStringList filters({"Image files (*.png *.xpm *.jpg)", "Text files (*.txt)", "Any files (*)" })
[6]
QPointer< QLineEdit > le
QDBusArgument argument
png_infop info_ptr
Definition: pngpriv.h:2049
png_structp png_ptr
Definition: pngpriv.h:2048
unsigned int for_write
Definition: pngpriv.h:2055
png_const_voidp buffer
Definition: pngwrite.c:1509
png_alloc_size_t output_bytes
Definition: pngwrite.c:1520
png_alloc_size_t memory_bytes
Definition: pngwrite.c:1519
png_const_voidp colormap
Definition: pngwrite.c:1511
png_const_voidp first_row
Definition: pngwrite.c:1514
png_controlp opaque
Definition: png.h:2671
png_uint_32 width
Definition: png.h:753
png_byte color_type
Definition: png.h:755
png_byte bit_depth
Definition: png.h:756
png_byte pixel_depth
Definition: png.h:758
png_byte channels
Definition: png.h:757
size_t rowbytes
Definition: png.h:754
png_byte month
Definition: png.h:600
png_uint_16 year
Definition: png.h:599
png_byte hour
Definition: png.h:602
png_byte second
Definition: png.h:604
png_byte minute
Definition: png.h:603
png_byte day
Definition: png.h:601
png_byte * data
Definition: png.h:622
size_t size
Definition: png.h:623
png_byte name[5]
Definition: png.h:621
png_byte location
Definition: png.h:631