zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
pngwutil.c
Go to the documentation of this file.
1 
2 /* pngwutil.c - utilities to write a PNG file
3  *
4  * Last changed in libpng 1.5.6 [November 3, 2011]
5  * Copyright (c) 1998-2011 Glenn Randers-Pehrson
6  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8  *
9  * This code is released under the libpng license.
10  * For conditions of distribution and use, see the disclaimer
11  * and license in png.h
12  */
13 
14 #include "pngpriv.h"
15 
16 #ifdef PNG_WRITE_SUPPORTED
17 
18 #ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
19 /* Place a 32-bit number into a buffer in PNG byte order. We work
20  * with unsigned numbers for convenience, although one supported
21  * ancillary chunk uses signed (two's complement) numbers.
22  */
23 void PNGAPI
25 {
26  buf[0] = (png_byte)((i >> 24) & 0xff);
27  buf[1] = (png_byte)((i >> 16) & 0xff);
28  buf[2] = (png_byte)((i >> 8) & 0xff);
29  buf[3] = (png_byte)(i & 0xff);
30 }
31 
32 #ifdef PNG_SAVE_INT_32_SUPPORTED
33 /* The png_save_int_32 function assumes integers are stored in two's
34  * complement format. If this isn't the case, then this routine needs to
35  * be modified to write data in two's complement format. Note that,
36  * the following works correctly even if png_int_32 has more than 32 bits
37  * (compare the more complex code required on read for sign extention.)
38  */
39 void PNGAPI
41 {
42  buf[0] = (png_byte)((i >> 24) & 0xff);
43  buf[1] = (png_byte)((i >> 16) & 0xff);
44  buf[2] = (png_byte)((i >> 8) & 0xff);
45  buf[3] = (png_byte)(i & 0xff);
46 }
47 #endif
48 
49 /* Place a 16-bit number into a buffer in PNG byte order.
50  * The parameter is declared unsigned int, not png_uint_16,
51  * just to avoid potential problems on pre-ANSI C compilers.
52  */
53 void PNGAPI
55 {
56  buf[0] = (png_byte)((i >> 8) & 0xff);
57  buf[1] = (png_byte)(i & 0xff);
58 }
59 #endif
60 
61 /* Simple function to write the signature. If we have already written
62  * the magic bytes of the signature, or more likely, the PNG stream is
63  * being embedded into another stream and doesn't need its own signature,
64  * we should call png_set_sig_bytes() to tell libpng how many of the
65  * bytes have already been written.
66  */
67 void PNGAPI
69 {
70  png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
71 
72 #ifdef PNG_IO_STATE_SUPPORTED
73  /* Inform the I/O callback that the signature is being written */
74  png_ptr->io_state = PNG_IO_WRITING | PNG_IO_SIGNATURE;
75 #endif
76 
77  /* Write the rest of the 8 byte signature */
78  png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
79  (png_size_t)(8 - png_ptr->sig_bytes));
80 
81  if (png_ptr->sig_bytes < 3)
82  png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
83 }
84 
85 /* Write the start of a PNG chunk. The type is the chunk type.
86  * The total_length is the sum of the lengths of all the data you will be
87  * passing in png_write_chunk_data().
88  */
89 static void
92 {
93  png_byte buf[8];
94 
95 #if defined(PNG_DEBUG) && (PNG_DEBUG > 0)
96  PNG_CSTRING_FROM_CHUNK(buf, chunk_name);
97  png_debug2(0, "Writing %s chunk, length = %lu", buf, (unsigned long)length);
98 #endif
99 
100  if (png_ptr == NULL)
101  return;
102 
103 #ifdef PNG_IO_STATE_SUPPORTED
104  /* Inform the I/O callback that the chunk header is being written.
105  * PNG_IO_CHUNK_HDR requires a single I/O call.
106  */
107  png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR;
108 #endif
109 
110  /* Write the length and the chunk name */
111  png_save_uint_32(buf, length);
112  png_save_uint_32(buf + 4, chunk_name);
113  png_write_data(png_ptr, buf, 8);
114 
115  /* Put the chunk name into png_ptr->chunk_name */
116  png_ptr->chunk_name = chunk_name;
117 
118  /* Reset the crc and run it over the chunk name */
119  png_reset_crc(png_ptr);
120 
121  png_calculate_crc(png_ptr, buf + 4, 4);
122 
123 #ifdef PNG_IO_STATE_SUPPORTED
124  /* Inform the I/O callback that chunk data will (possibly) be written.
125  * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls.
126  */
127  png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA;
128 #endif
129 }
130 
131 void PNGAPI
134 {
135  png_write_chunk_header(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), length);
136 }
137 
138 /* Write the data of a PNG chunk started with png_write_chunk_header().
139  * Note that multiple calls to this function are allowed, and that the
140  * sum of the lengths from these calls *must* add up to the total_length
141  * given to png_write_chunk_header().
142  */
143 void PNGAPI
146 {
147  /* Write the data, and run the CRC over it */
148  if (png_ptr == NULL)
149  return;
150 
151  if (data != NULL && length > 0)
152  {
153  png_write_data(png_ptr, data, length);
154 
155  /* Update the CRC after writing the data,
156  * in case that the user I/O routine alters it.
157  */
158  png_calculate_crc(png_ptr, data, length);
159  }
160 }
161 
162 /* Finish a chunk started with png_write_chunk_header(). */
163 void PNGAPI
165 {
166  png_byte buf[4];
167 
168  if (png_ptr == NULL) return;
169 
170 #ifdef PNG_IO_STATE_SUPPORTED
171  /* Inform the I/O callback that the chunk CRC is being written.
172  * PNG_IO_CHUNK_CRC requires a single I/O function call.
173  */
174  png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC;
175 #endif
176 
177  /* Write the crc in a single operation */
178  png_save_uint_32(buf, png_ptr->crc);
179 
180  png_write_data(png_ptr, buf, (png_size_t)4);
181 }
182 
183 /* Write a PNG chunk all at once. The type is an array of ASCII characters
184  * representing the chunk name. The array must be at least 4 bytes in
185  * length, and does not need to be null terminated. To be safe, pass the
186  * pre-defined chunk names here, and if you need a new one, define it
187  * where the others are defined. The length is the length of the data.
188  * All the data must be present. If that is not possible, use the
189  * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
190  * functions instead.
191  */
192 static void
195 {
196  if (png_ptr == NULL)
197  return;
198 
199  /* On 64 bit architectures 'length' may not fit in a png_uint_32. */
200  if (length > PNG_UINT_32_MAX)
201  png_error(png_ptr, "length exceeds PNG maxima");
202 
203  png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length);
204  png_write_chunk_data(png_ptr, data, length);
205  png_write_chunk_end(png_ptr);
206 }
207 
208 /* This is the API that calls the internal function above. */
209 void PNGAPI
212 {
213  png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data,
214  length);
215 }
216 
217 /* Initialize the compressor for the appropriate type of compression. */
218 static void
220 {
221  if (!(png_ptr->zlib_state & PNG_ZLIB_IN_USE))
222  {
223  /* If already initialized for 'state' do not re-init. */
224  if (png_ptr->zlib_state != state)
225  {
226  int ret = Z_OK;
227  png_const_charp who = "-";
228 
229  /* If actually initialized for another state do a deflateEnd. */
230  if (png_ptr->zlib_state != PNG_ZLIB_UNINITIALIZED)
231  {
232  ret = deflateEnd(&png_ptr->zstream);
233  who = "end";
234  png_ptr->zlib_state = PNG_ZLIB_UNINITIALIZED;
235  }
236 
237  /* zlib itself detects an incomplete state on deflateEnd */
238  if (ret == Z_OK) switch (state)
239  {
240 # ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
241  case PNG_ZLIB_FOR_TEXT:
242  ret = deflateInit2(&png_ptr->zstream,
243  png_ptr->zlib_text_level, png_ptr->zlib_text_method,
244  png_ptr->zlib_text_window_bits,
245  png_ptr->zlib_text_mem_level, png_ptr->zlib_text_strategy);
246  who = "text";
247  break;
248 # endif
249 
250  case PNG_ZLIB_FOR_IDAT:
251  ret = deflateInit2(&png_ptr->zstream, png_ptr->zlib_level,
252  png_ptr->zlib_method, png_ptr->zlib_window_bits,
253  png_ptr->zlib_mem_level, png_ptr->zlib_strategy);
254  who = "IDAT";
255  break;
256 
257  default:
258  png_error(png_ptr, "invalid zlib state");
259  }
260 
261  if (ret == Z_OK)
262  png_ptr->zlib_state = state;
263 
264  else /* an error in deflateEnd or deflateInit2 */
265  {
266  size_t pos = 0;
267  char msg[64];
268 
269  pos = png_safecat(msg, sizeof msg, pos,
270  "zlib failed to initialize compressor (");
271  pos = png_safecat(msg, sizeof msg, pos, who);
272 
273  switch (ret)
274  {
275  case Z_VERSION_ERROR:
276  pos = png_safecat(msg, sizeof msg, pos, ") version error");
277  break;
278 
279  case Z_STREAM_ERROR:
280  pos = png_safecat(msg, sizeof msg, pos, ") stream error");
281  break;
282 
283  case Z_MEM_ERROR:
284  pos = png_safecat(msg, sizeof msg, pos, ") memory error");
285  break;
286 
287  default:
288  pos = png_safecat(msg, sizeof msg, pos, ") unknown error");
289  break;
290  }
291 
292  png_error(png_ptr, msg);
293  }
294  }
295 
296  /* Here on success, claim the zstream: */
297  png_ptr->zlib_state |= PNG_ZLIB_IN_USE;
298  }
299 
300  else
301  png_error(png_ptr, "zstream already in use (internal error)");
302 }
303 
304 /* The opposite: release the stream. It is also reset, this API will warn on
305  * error but will not fail.
306  */
307 static void
309 {
310  if (png_ptr->zlib_state & PNG_ZLIB_IN_USE)
311  {
312  int ret = deflateReset(&png_ptr->zstream);
313 
314  png_ptr->zlib_state &= ~PNG_ZLIB_IN_USE;
315 
316  if (ret != Z_OK)
317  {
318  png_const_charp err;
320 
321  switch (ret)
322  {
323  case Z_VERSION_ERROR:
324  err = "version";
325  break;
326 
327  case Z_STREAM_ERROR:
328  err = "stream";
329  break;
330 
331  case Z_MEM_ERROR:
332  err = "memory";
333  break;
334 
335  default:
336  err = "unknown";
337  break;
338  }
339 
341  png_warning_parameter(p, 2, err);
342 
343  if (png_ptr->zstream.msg)
344  err = png_ptr->zstream.msg;
345  else
346  err = "[no zlib message]";
347 
348  png_warning_parameter(p, 3, err);
349 
350  png_formatted_warning(png_ptr, p,
351  "zlib failed to reset compressor: @1(@2): @3");
352  }
353  }
354 
355  else
356  png_warning(png_ptr, "zstream not in use (internal error)");
357 }
358 
359 #ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
360 /* This pair of functions encapsulates the operation of (a) compressing a
361  * text string, and (b) issuing it later as a series of chunk data writes.
362  * The compression_state structure is shared context for these functions
363  * set up by the caller in order to make the whole mess thread-safe.
364  */
365 
366 typedef struct
367 {
368  png_const_bytep input; /* The uncompressed input data */
369  png_size_t input_len; /* Its length */
370  int num_output_ptr; /* Number of output pointers used */
371  int max_output_ptr; /* Size of output_ptr */
372  png_bytep *output_ptr; /* Array of pointers to output */
373 } compression_state;
374 
375 /* Compress given text into storage in the png_ptr structure */
376 static int /* PRIVATE */
378  png_const_charp text, png_size_t text_len, int compression,
379  compression_state *comp)
380 {
381  int ret;
382 
383  comp->num_output_ptr = 0;
384  comp->max_output_ptr = 0;
385  comp->output_ptr = NULL;
386  comp->input = NULL;
387  comp->input_len = text_len;
388 
389  /* We may just want to pass the text right through */
390  if (compression == PNG_TEXT_COMPRESSION_NONE)
391  {
392  comp->input = (png_const_bytep)text;
393  return((int)text_len);
394  }
395 
396  if (compression >= PNG_TEXT_COMPRESSION_LAST)
397  {
399 
401  compression);
402  png_formatted_warning(png_ptr, p, "Unknown compression type @1");
403  }
404 
405  /* We can't write the chunk until we find out how much data we have,
406  * which means we need to run the compressor first and save the
407  * output. This shouldn't be a problem, as the vast majority of
408  * comments should be reasonable, but we will set up an array of
409  * malloc'd pointers to be sure.
410  *
411  * If we knew the application was well behaved, we could simplify this
412  * greatly by assuming we can always malloc an output buffer large
413  * enough to hold the compressed text ((1001 * text_len / 1000) + 12)
414  * and malloc this directly. The only time this would be a bad idea is
415  * if we can't malloc more than 64K and we have 64K of random input
416  * data, or if the input string is incredibly large (although this
417  * wouldn't cause a failure, just a slowdown due to swapping).
418  */
419  png_zlib_claim(png_ptr, PNG_ZLIB_FOR_TEXT);
420 
421  /* Set up the compression buffers */
422  /* TODO: the following cast hides a potential overflow problem. */
423  png_ptr->zstream.avail_in = (uInt)text_len;
424 
425  /* NOTE: assume zlib doesn't overwrite the input */
426  png_ptr->zstream.next_in = (Bytef *)text;
427  png_ptr->zstream.avail_out = png_ptr->zbuf_size;
428  png_ptr->zstream.next_out = png_ptr->zbuf;
429 
430  /* This is the same compression loop as in png_write_row() */
431  do
432  {
433  /* Compress the data */
434  ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
435 
436  if (ret != Z_OK)
437  {
438  /* Error */
439  if (png_ptr->zstream.msg != NULL)
440  png_error(png_ptr, png_ptr->zstream.msg);
441 
442  else
443  png_error(png_ptr, "zlib error");
444  }
445 
446  /* Check to see if we need more room */
447  if (!(png_ptr->zstream.avail_out))
448  {
449  /* Make sure the output array has room */
450  if (comp->num_output_ptr >= comp->max_output_ptr)
451  {
452  int old_max;
453 
454  old_max = comp->max_output_ptr;
455  comp->max_output_ptr = comp->num_output_ptr + 4;
456  if (comp->output_ptr != NULL)
457  {
458  png_bytepp old_ptr;
459 
460  old_ptr = comp->output_ptr;
461 
462  comp->output_ptr = (png_bytepp)png_malloc(png_ptr,
464  (comp->max_output_ptr * png_sizeof(png_charpp)));
465 
466  png_memcpy(comp->output_ptr, old_ptr, old_max
467  * png_sizeof(png_charp));
468 
469  png_free(png_ptr, old_ptr);
470  }
471  else
472  comp->output_ptr = (png_bytepp)png_malloc(png_ptr,
474  (comp->max_output_ptr * png_sizeof(png_charp)));
475  }
476 
477  /* Save the data */
478  comp->output_ptr[comp->num_output_ptr] =
479  (png_bytep)png_malloc(png_ptr,
480  (png_alloc_size_t)png_ptr->zbuf_size);
481 
482  png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
483  png_ptr->zbuf_size);
484 
485  comp->num_output_ptr++;
486 
487  /* and reset the buffer */
488  png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
489  png_ptr->zstream.next_out = png_ptr->zbuf;
490  }
491  /* Continue until we don't have any more to compress */
492  } while (png_ptr->zstream.avail_in);
493 
494  /* Finish the compression */
495  do
496  {
497  /* Tell zlib we are finished */
498  ret = deflate(&png_ptr->zstream, Z_FINISH);
499 
500  if (ret == Z_OK)
501  {
502  /* Check to see if we need more room */
503  if (!(png_ptr->zstream.avail_out))
504  {
505  /* Check to make sure our output array has room */
506  if (comp->num_output_ptr >= comp->max_output_ptr)
507  {
508  int old_max;
509 
510  old_max = comp->max_output_ptr;
511  comp->max_output_ptr = comp->num_output_ptr + 4;
512  if (comp->output_ptr != NULL)
513  {
514  png_bytepp old_ptr;
515 
516  old_ptr = comp->output_ptr;
517 
518  /* This could be optimized to realloc() */
519  comp->output_ptr = (png_bytepp)png_malloc(png_ptr,
520  (png_alloc_size_t)(comp->max_output_ptr *
522 
523  png_memcpy(comp->output_ptr, old_ptr,
524  old_max * png_sizeof(png_charp));
525 
526  png_free(png_ptr, old_ptr);
527  }
528 
529  else
530  comp->output_ptr = (png_bytepp)png_malloc(png_ptr,
531  (png_alloc_size_t)(comp->max_output_ptr *
533  }
534 
535  /* Save the data */
536  comp->output_ptr[comp->num_output_ptr] =
537  (png_bytep)png_malloc(png_ptr,
538  (png_alloc_size_t)png_ptr->zbuf_size);
539 
540  png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
541  png_ptr->zbuf_size);
542 
543  comp->num_output_ptr++;
544 
545  /* and reset the buffer pointers */
546  png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
547  png_ptr->zstream.next_out = png_ptr->zbuf;
548  }
549  }
550  else if (ret != Z_STREAM_END)
551  {
552  /* We got an error */
553  if (png_ptr->zstream.msg != NULL)
554  png_error(png_ptr, png_ptr->zstream.msg);
555 
556  else
557  png_error(png_ptr, "zlib error");
558  }
559  } while (ret != Z_STREAM_END);
560 
561  /* Text length is number of buffers plus last buffer */
562  text_len = png_ptr->zbuf_size * comp->num_output_ptr;
563 
564  if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
565  text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out;
566 
567  return((int)text_len);
568 }
569 
570 /* Ship the compressed text out via chunk writes */
571 static void /* PRIVATE */
572 png_write_compressed_data_out(png_structp png_ptr, compression_state *comp)
573 {
574  int i;
575 
576  /* Handle the no-compression case */
577  if (comp->input)
578  {
579  png_write_chunk_data(png_ptr, comp->input, comp->input_len);
580 
581  return;
582  }
583 
584 #ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
585  /* The zbuf_size test is because the code below doesn't work if zbuf_size is
586  * '1'; simply skip it to avoid memory overwrite.
587  */
588  if (comp->input_len >= 2 && comp->input_len < 16384 && png_ptr->zbuf_size > 1)
589  {
590  unsigned int z_cmf; /* zlib compression method and flags */
591 
592  /* Optimize the CMF field in the zlib stream. This hack of the zlib
593  * stream is compliant to the stream specification.
594  */
595 
596  if (comp->num_output_ptr)
597  z_cmf = comp->output_ptr[0][0];
598  else
599  z_cmf = png_ptr->zbuf[0];
600 
601  if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
602  {
603  unsigned int z_cinfo;
604  unsigned int half_z_window_size;
605  png_size_t uncompressed_text_size = comp->input_len;
606 
607  z_cinfo = z_cmf >> 4;
608  half_z_window_size = 1 << (z_cinfo + 7);
609 
610  while (uncompressed_text_size <= half_z_window_size &&
611  half_z_window_size >= 256)
612  {
613  z_cinfo--;
614  half_z_window_size >>= 1;
615  }
616 
617  z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
618 
619  if (comp->num_output_ptr)
620  {
621 
622  if (comp->output_ptr[0][0] != z_cmf)
623  {
624  int tmp;
625 
626  comp->output_ptr[0][0] = (png_byte)z_cmf;
627  tmp = comp->output_ptr[0][1] & 0xe0;
628  tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f;
629  comp->output_ptr[0][1] = (png_byte)tmp;
630  }
631  }
632  else
633  {
634  int tmp;
635 
636  png_ptr->zbuf[0] = (png_byte)z_cmf;
637  tmp = png_ptr->zbuf[1] & 0xe0;
638  tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f;
639  png_ptr->zbuf[1] = (png_byte)tmp;
640  }
641  }
642 
643  else
644  png_error(png_ptr,
645  "Invalid zlib compression method or flags in non-IDAT chunk");
646  }
647 #endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */
648 
649  /* Write saved output buffers, if any */
650  for (i = 0; i < comp->num_output_ptr; i++)
651  {
652  png_write_chunk_data(png_ptr, comp->output_ptr[i],
653  (png_size_t)png_ptr->zbuf_size);
654 
655  png_free(png_ptr, comp->output_ptr[i]);
656  }
657 
658  if (comp->max_output_ptr != 0)
659  png_free(png_ptr, comp->output_ptr);
660 
661  /* Write anything left in zbuf */
662  if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)
663  png_write_chunk_data(png_ptr, png_ptr->zbuf,
664  (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream.avail_out));
665 
666  /* Reset zlib for another zTXt/iTXt or image data */
667  png_zlib_release(png_ptr);
668 }
669 #endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */
670 
671 /* Write the IHDR chunk, and update the png_struct with the necessary
672  * information. Note that the rest of this code depends upon this
673  * information being correct.
674  */
675 void /* PRIVATE */
677  int bit_depth, int color_type, int compression_type, int filter_type,
678  int interlace_type)
679 {
680  png_byte buf[13]; /* Buffer to store the IHDR info */
681 
682  png_debug(1, "in png_write_IHDR");
683 
684  /* Check that we have valid input data from the application info */
685  switch (color_type)
686  {
687  case PNG_COLOR_TYPE_GRAY:
688  switch (bit_depth)
689  {
690  case 1:
691  case 2:
692  case 4:
693  case 8:
694 #ifdef PNG_WRITE_16BIT_SUPPORTED
695  case 16:
696 #endif
697  png_ptr->channels = 1; break;
698 
699  default:
700  png_error(png_ptr,
701  "Invalid bit depth for grayscale image");
702  }
703  break;
704 
705  case PNG_COLOR_TYPE_RGB:
706 #ifdef PNG_WRITE_16BIT_SUPPORTED
707  if (bit_depth != 8 && bit_depth != 16)
708 #else
709  if (bit_depth != 8)
710 #endif
711  png_error(png_ptr, "Invalid bit depth for RGB image");
712 
713  png_ptr->channels = 3;
714  break;
715 
717  switch (bit_depth)
718  {
719  case 1:
720  case 2:
721  case 4:
722  case 8:
723  png_ptr->channels = 1;
724  break;
725 
726  default:
727  png_error(png_ptr, "Invalid bit depth for paletted image");
728  }
729  break;
730 
732  if (bit_depth != 8 && bit_depth != 16)
733  png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
734 
735  png_ptr->channels = 2;
736  break;
737 
739 #ifdef PNG_WRITE_16BIT_SUPPORTED
740  if (bit_depth != 8 && bit_depth != 16)
741 #else
742  if (bit_depth != 8)
743 #endif
744  png_error(png_ptr, "Invalid bit depth for RGBA image");
745 
746  png_ptr->channels = 4;
747  break;
748 
749  default:
750  png_error(png_ptr, "Invalid image color type specified");
751  }
752 
753  if (compression_type != PNG_COMPRESSION_TYPE_BASE)
754  {
755  png_warning(png_ptr, "Invalid compression type specified");
756  compression_type = PNG_COMPRESSION_TYPE_BASE;
757  }
758 
759  /* Write filter_method 64 (intrapixel differencing) only if
760  * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
761  * 2. Libpng did not write a PNG signature (this filter_method is only
762  * used in PNG datastreams that are embedded in MNG datastreams) and
763  * 3. The application called png_permit_mng_features with a mask that
764  * included PNG_FLAG_MNG_FILTER_64 and
765  * 4. The filter_method is 64 and
766  * 5. The color_type is RGB or RGBA
767  */
768  if (
770  !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
771  ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
772  (color_type == PNG_COLOR_TYPE_RGB ||
773  color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
774  (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&
775 #endif
776  filter_type != PNG_FILTER_TYPE_BASE)
777  {
778  png_warning(png_ptr, "Invalid filter type specified");
779  filter_type = PNG_FILTER_TYPE_BASE;
780  }
781 
782 #ifdef PNG_WRITE_INTERLACING_SUPPORTED
783  if (interlace_type != PNG_INTERLACE_NONE &&
784  interlace_type != PNG_INTERLACE_ADAM7)
785  {
786  png_warning(png_ptr, "Invalid interlace type specified");
787  interlace_type = PNG_INTERLACE_ADAM7;
788  }
789 #else
790  interlace_type=PNG_INTERLACE_NONE;
791 #endif
792 
793  /* Save the relevent information */
794  png_ptr->bit_depth = (png_byte)bit_depth;
795  png_ptr->color_type = (png_byte)color_type;
796  png_ptr->interlaced = (png_byte)interlace_type;
797 #ifdef PNG_MNG_FEATURES_SUPPORTED
798  png_ptr->filter_type = (png_byte)filter_type;
799 #endif
800  png_ptr->compression_type = (png_byte)compression_type;
801  png_ptr->width = width;
802  png_ptr->height = height;
803 
804  png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
805  png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
806  /* Set the usr info, so any transformations can modify it */
807  png_ptr->usr_width = png_ptr->width;
808  png_ptr->usr_bit_depth = png_ptr->bit_depth;
809  png_ptr->usr_channels = png_ptr->channels;
810 
811  /* Pack the header information into the buffer */
812  png_save_uint_32(buf, width);
813  png_save_uint_32(buf + 4, height);
814  buf[8] = (png_byte)bit_depth;
815  buf[9] = (png_byte)color_type;
816  buf[10] = (png_byte)compression_type;
817  buf[11] = (png_byte)filter_type;
818  buf[12] = (png_byte)interlace_type;
819 
820  /* Write the chunk */
821  png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);
822 
823  /* Initialize zlib with PNG info */
824  png_ptr->zstream.zalloc = png_zalloc;
825  png_ptr->zstream.zfree = png_zfree;
826  png_ptr->zstream.opaque = (voidpf)png_ptr;
827 
828  if (!(png_ptr->do_filter))
829  {
830  if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
831  png_ptr->bit_depth < 8)
832  png_ptr->do_filter = PNG_FILTER_NONE;
833 
834  else
835  png_ptr->do_filter = PNG_ALL_FILTERS;
836  }
837 
838  if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY))
839  {
840  if (png_ptr->do_filter != PNG_FILTER_NONE)
841  png_ptr->zlib_strategy = Z_FILTERED;
842 
843  else
844  png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY;
845  }
846 
847  if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL))
848  png_ptr->zlib_level = Z_DEFAULT_COMPRESSION;
849 
850  if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL))
851  png_ptr->zlib_mem_level = 8;
852 
853  if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS))
854  png_ptr->zlib_window_bits = 15;
855 
856  if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD))
857  png_ptr->zlib_method = 8;
858 
861  if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_STRATEGY))
862  png_ptr->zlib_text_strategy = Z_DEFAULT_STRATEGY;
863 
864  if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_LEVEL))
865  png_ptr->zlib_text_level = png_ptr->zlib_level;
866 
867  if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL))
868  png_ptr->zlib_text_mem_level = png_ptr->zlib_mem_level;
869 
870  if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS))
871  png_ptr->zlib_text_window_bits = png_ptr->zlib_window_bits;
872 
873  if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_METHOD))
874  png_ptr->zlib_text_method = png_ptr->zlib_method;
875 #else
876  png_ptr->zlib_text_strategy = Z_DEFAULT_STRATEGY;
877  png_ptr->zlib_text_level = png_ptr->zlib_level;
878  png_ptr->zlib_text_mem_level = png_ptr->zlib_mem_level;
879  png_ptr->zlib_text_window_bits = png_ptr->zlib_window_bits;
880  png_ptr->zlib_text_method = png_ptr->zlib_method;
881 #endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */
882 #endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */
883 
884  /* Record that the compressor has not yet been initialized. */
885  png_ptr->zlib_state = PNG_ZLIB_UNINITIALIZED;
886 
887  png_ptr->mode = PNG_HAVE_IHDR; /* not READY_FOR_ZTXT */
888 }
889 
890 /* Write the palette. We are careful not to trust png_color to be in the
891  * correct order for PNG, so people can redefine it to any convenient
892  * structure.
893  */
894 void /* PRIVATE */
896  png_uint_32 num_pal)
897 {
898  png_uint_32 i;
899  png_const_colorp pal_ptr;
900  png_byte buf[3];
901 
902  png_debug(1, "in png_write_PLTE");
903 
904  if ((
906  !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) &&
907 #endif
908  num_pal == 0) || num_pal > 256)
909  {
910  if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
911  {
912  png_error(png_ptr, "Invalid number of colors in palette");
913  }
914 
915  else
916  {
917  png_warning(png_ptr, "Invalid number of colors in palette");
918  return;
919  }
920  }
921 
922  if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
923  {
924  png_warning(png_ptr,
925  "Ignoring request to write a PLTE chunk in grayscale PNG");
926 
927  return;
928  }
929 
930  png_ptr->num_palette = (png_uint_16)num_pal;
931  png_debug1(3, "num_palette = %d", png_ptr->num_palette);
932 
933  png_write_chunk_header(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3));
934 #ifdef PNG_POINTER_INDEXING_SUPPORTED
935 
936  for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
937  {
938  buf[0] = pal_ptr->red;
939  buf[1] = pal_ptr->green;
940  buf[2] = pal_ptr->blue;
941  png_write_chunk_data(png_ptr, buf, (png_size_t)3);
942  }
943 
944 #else
945  /* This is a little slower but some buggy compilers need to do this
946  * instead
947  */
948  pal_ptr=palette;
949 
950  for (i = 0; i < num_pal; i++)
951  {
952  buf[0] = pal_ptr[i].red;
953  buf[1] = pal_ptr[i].green;
954  buf[2] = pal_ptr[i].blue;
955  png_write_chunk_data(png_ptr, buf, (png_size_t)3);
956  }
957 
958 #endif
959  png_write_chunk_end(png_ptr);
960  png_ptr->mode |= PNG_HAVE_PLTE;
961 }
962 
963 /* Write an IDAT chunk */
964 void /* PRIVATE */
966 {
967  png_debug(1, "in png_write_IDAT");
968 
969 #ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
970  if (!(png_ptr->mode & PNG_HAVE_IDAT) &&
971  png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
972  {
973  /* Optimize the CMF field in the zlib stream. This hack of the zlib
974  * stream is compliant to the stream specification.
975  */
976  unsigned int z_cmf = data[0]; /* zlib compression method and flags */
977 
978  if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
979  {
980  /* Avoid memory underflows and multiplication overflows.
981  *
982  * The conditions below are practically always satisfied;
983  * however, they still must be checked.
984  */
985  if (length >= 2 &&
986  png_ptr->height < 16384 && png_ptr->width < 16384)
987  {
988  /* Compute the maximum possible length of the datastream */
989 
990  /* Number of pixels, plus for each row a filter byte
991  * and possibly a padding byte, so increase the maximum
992  * size to account for these.
993  */
994  unsigned int z_cinfo;
995  unsigned int half_z_window_size;
996  png_uint_32 uncompressed_idat_size = png_ptr->height *
997  ((png_ptr->width *
998  png_ptr->channels * png_ptr->bit_depth + 15) >> 3);
999 
1000  /* If it's interlaced, each block of 8 rows is sent as up to
1001  * 14 rows, i.e., 6 additional rows, each with a filter byte
1002  * and possibly a padding byte
1003  */
1004  if (png_ptr->interlaced)
1005  uncompressed_idat_size += ((png_ptr->height + 7)/8) *
1006  (png_ptr->bit_depth < 8 ? 12 : 6);
1007 
1008  z_cinfo = z_cmf >> 4;
1009  half_z_window_size = 1 << (z_cinfo + 7);
1010 
1011  while (uncompressed_idat_size <= half_z_window_size &&
1012  half_z_window_size >= 256)
1013  {
1014  z_cinfo--;
1015  half_z_window_size >>= 1;
1016  }
1017 
1018  z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
1019 
1020  if (data[0] != z_cmf)
1021  {
1022  int tmp;
1023  data[0] = (png_byte)z_cmf;
1024  tmp = data[1] & 0xe0;
1025  tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f;
1026  data[1] = (png_byte)tmp;
1027  }
1028  }
1029  }
1030 
1031  else
1032  png_error(png_ptr,
1033  "Invalid zlib compression method or flags in IDAT");
1034  }
1035 #endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */
1036 
1037  png_write_complete_chunk(png_ptr, png_IDAT, data, length);
1038  png_ptr->mode |= PNG_HAVE_IDAT;
1039 
1040  /* Prior to 1.5.4 this code was replicated in every caller (except at the
1041  * end, where it isn't technically necessary). Since this function has
1042  * flushed the data we can safely reset the zlib output buffer here.
1043  */
1044  png_ptr->zstream.next_out = png_ptr->zbuf;
1045  png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
1046 }
1047 
1048 /* Write an IEND chunk */
1049 void /* PRIVATE */
1051 {
1052  png_debug(1, "in png_write_IEND");
1053 
1055  png_ptr->mode |= PNG_HAVE_IEND;
1056 }
1057 
1058 #ifdef PNG_WRITE_gAMA_SUPPORTED
1059 /* Write a gAMA chunk */
1060 void /* PRIVATE */
1062 {
1063  png_byte buf[4];
1064 
1065  png_debug(1, "in png_write_gAMA");
1066 
1067  /* file_gamma is saved in 1/100,000ths */
1068  png_save_uint_32(buf, (png_uint_32)file_gamma);
1069  png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4);
1070 }
1071 #endif
1072 
1073 #ifdef PNG_WRITE_sRGB_SUPPORTED
1074 /* Write a sRGB chunk */
1075 void /* PRIVATE */
1076 png_write_sRGB(png_structp png_ptr, int srgb_intent)
1077 {
1078  png_byte buf[1];
1079 
1080  png_debug(1, "in png_write_sRGB");
1081 
1082  if (srgb_intent >= PNG_sRGB_INTENT_LAST)
1083  png_warning(png_ptr,
1084  "Invalid sRGB rendering intent specified");
1085 
1086  buf[0]=(png_byte)srgb_intent;
1087  png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1);
1088 }
1089 #endif
1090 
1091 #ifdef PNG_WRITE_iCCP_SUPPORTED
1092 /* Write an iCCP chunk */
1093 void /* PRIVATE */
1095  png_const_charp profile, int profile_len)
1096 {
1097  png_size_t name_len;
1098  png_charp new_name;
1099  compression_state comp;
1100  int embedded_profile_len = 0;
1101 
1102  png_debug(1, "in png_write_iCCP");
1103 
1104  comp.num_output_ptr = 0;
1105  comp.max_output_ptr = 0;
1106  comp.output_ptr = NULL;
1107  comp.input = NULL;
1108  comp.input_len = 0;
1109 
1110  if ((name_len = png_check_keyword(png_ptr, name, &new_name)) == 0)
1111  return;
1112 
1113  if (compression_type != PNG_COMPRESSION_TYPE_BASE)
1114  png_warning(png_ptr, "Unknown compression type in iCCP chunk");
1115 
1116  if (profile == NULL)
1117  profile_len = 0;
1118 
1119  if (profile_len > 3)
1120  embedded_profile_len =
1121  ((*( (png_const_bytep)profile ))<<24) |
1122  ((*( (png_const_bytep)profile + 1))<<16) |
1123  ((*( (png_const_bytep)profile + 2))<< 8) |
1124  ((*( (png_const_bytep)profile + 3)) );
1125 
1126  if (embedded_profile_len < 0)
1127  {
1128  png_warning(png_ptr,
1129  "Embedded profile length in iCCP chunk is negative");
1130 
1131  png_free(png_ptr, new_name);
1132  return;
1133  }
1134 
1135  if (profile_len < embedded_profile_len)
1136  {
1137  png_warning(png_ptr,
1138  "Embedded profile length too large in iCCP chunk");
1139 
1140  png_free(png_ptr, new_name);
1141  return;
1142  }
1143 
1144  if (profile_len > embedded_profile_len)
1145  {
1146  png_warning(png_ptr,
1147  "Truncating profile to actual length in iCCP chunk");
1148 
1149  profile_len = embedded_profile_len;
1150  }
1151 
1152  if (profile_len)
1153  profile_len = png_text_compress(png_ptr, profile,
1154  (png_size_t)profile_len, PNG_COMPRESSION_TYPE_BASE, &comp);
1155 
1156  /* Make sure we include the NULL after the name and the compression type */
1158  (png_uint_32)(name_len + profile_len + 2));
1159 
1160  new_name[name_len + 1] = 0x00;
1161 
1162  png_write_chunk_data(png_ptr, (png_bytep)new_name,
1163  (png_size_t)(name_len + 2));
1164 
1165  if (profile_len)
1166  {
1167  comp.input_len = profile_len;
1168  png_write_compressed_data_out(png_ptr, &comp);
1169  }
1170 
1171  png_write_chunk_end(png_ptr);
1172  png_free(png_ptr, new_name);
1173 }
1174 #endif
1175 
1176 #ifdef PNG_WRITE_sPLT_SUPPORTED
1177 /* Write a sPLT chunk */
1178 void /* PRIVATE */
1180 {
1181  png_size_t name_len;
1182  png_charp new_name;
1183  png_byte entrybuf[10];
1184  png_size_t entry_size = (spalette->depth == 8 ? 6 : 10);
1185  png_size_t palette_size = entry_size * spalette->nentries;
1186  png_sPLT_entryp ep;
1187 #ifndef PNG_POINTER_INDEXING_SUPPORTED
1188  int i;
1189 #endif
1190 
1191  png_debug(1, "in png_write_sPLT");
1192 
1193  if ((name_len = png_check_keyword(png_ptr,spalette->name, &new_name))==0)
1194  return;
1195 
1196  /* Make sure we include the NULL after the name */
1198  (png_uint_32)(name_len + 2 + palette_size));
1199 
1200  png_write_chunk_data(png_ptr, (png_bytep)new_name,
1201  (png_size_t)(name_len + 1));
1202 
1203  png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1);
1204 
1205  /* Loop through each palette entry, writing appropriately */
1206 #ifdef PNG_POINTER_INDEXING_SUPPORTED
1207  for (ep = spalette->entries; ep<spalette->entries + spalette->nentries; ep++)
1208  {
1209  if (spalette->depth == 8)
1210  {
1211  entrybuf[0] = (png_byte)ep->red;
1212  entrybuf[1] = (png_byte)ep->green;
1213  entrybuf[2] = (png_byte)ep->blue;
1214  entrybuf[3] = (png_byte)ep->alpha;
1215  png_save_uint_16(entrybuf + 4, ep->frequency);
1216  }
1217 
1218  else
1219  {
1220  png_save_uint_16(entrybuf + 0, ep->red);
1221  png_save_uint_16(entrybuf + 2, ep->green);
1222  png_save_uint_16(entrybuf + 4, ep->blue);
1223  png_save_uint_16(entrybuf + 6, ep->alpha);
1224  png_save_uint_16(entrybuf + 8, ep->frequency);
1225  }
1226 
1227  png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size);
1228  }
1229 #else
1230  ep=spalette->entries;
1231  for (i = 0; i>spalette->nentries; i++)
1232  {
1233  if (spalette->depth == 8)
1234  {
1235  entrybuf[0] = (png_byte)ep[i].red;
1236  entrybuf[1] = (png_byte)ep[i].green;
1237  entrybuf[2] = (png_byte)ep[i].blue;
1238  entrybuf[3] = (png_byte)ep[i].alpha;
1239  png_save_uint_16(entrybuf + 4, ep[i].frequency);
1240  }
1241 
1242  else
1243  {
1244  png_save_uint_16(entrybuf + 0, ep[i].red);
1245  png_save_uint_16(entrybuf + 2, ep[i].green);
1246  png_save_uint_16(entrybuf + 4, ep[i].blue);
1247  png_save_uint_16(entrybuf + 6, ep[i].alpha);
1248  png_save_uint_16(entrybuf + 8, ep[i].frequency);
1249  }
1250 
1251  png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size);
1252  }
1253 #endif
1254 
1255  png_write_chunk_end(png_ptr);
1256  png_free(png_ptr, new_name);
1257 }
1258 #endif
1259 
1260 #ifdef PNG_WRITE_sBIT_SUPPORTED
1261 /* Write the sBIT chunk */
1262 void /* PRIVATE */
1263 png_write_sBIT(png_structp png_ptr, png_const_color_8p sbit, int color_type)
1264 {
1265  png_byte buf[4];
1266  png_size_t size;
1267 
1268  png_debug(1, "in png_write_sBIT");
1269 
1270  /* Make sure we don't depend upon the order of PNG_COLOR_8 */
1271  if (color_type & PNG_COLOR_MASK_COLOR)
1272  {
1273  png_byte maxbits;
1274 
1275  maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
1276  png_ptr->usr_bit_depth);
1277 
1278  if (sbit->red == 0 || sbit->red > maxbits ||
1279  sbit->green == 0 || sbit->green > maxbits ||
1280  sbit->blue == 0 || sbit->blue > maxbits)
1281  {
1282  png_warning(png_ptr, "Invalid sBIT depth specified");
1283  return;
1284  }
1285 
1286  buf[0] = sbit->red;
1287  buf[1] = sbit->green;
1288  buf[2] = sbit->blue;
1289  size = 3;
1290  }
1291 
1292  else
1293  {
1294  if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)
1295  {
1296  png_warning(png_ptr, "Invalid sBIT depth specified");
1297  return;
1298  }
1299 
1300  buf[0] = sbit->gray;
1301  size = 1;
1302  }
1303 
1304  if (color_type & PNG_COLOR_MASK_ALPHA)
1305  {
1306  if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
1307  {
1308  png_warning(png_ptr, "Invalid sBIT depth specified");
1309  return;
1310  }
1311 
1312  buf[size++] = sbit->alpha;
1313  }
1314 
1315  png_write_complete_chunk(png_ptr, png_sBIT, buf, size);
1316 }
1317 #endif
1318 
1319 #ifdef PNG_WRITE_cHRM_SUPPORTED
1320 /* Write the cHRM chunk */
1321 void /* PRIVATE */
1323  png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y,
1324  png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x,
1325  png_fixed_point blue_y)
1326 {
1327  png_byte buf[32];
1328 
1329  png_debug(1, "in png_write_cHRM");
1330 
1331  /* Each value is saved in 1/100,000ths */
1332 #ifdef PNG_CHECK_cHRM_SUPPORTED
1333  if (png_check_cHRM_fixed(png_ptr, white_x, white_y, red_x, red_y,
1334  green_x, green_y, blue_x, blue_y))
1335 #endif
1336  {
1337  png_save_uint_32(buf, (png_uint_32)white_x);
1338  png_save_uint_32(buf + 4, (png_uint_32)white_y);
1339 
1340  png_save_uint_32(buf + 8, (png_uint_32)red_x);
1341  png_save_uint_32(buf + 12, (png_uint_32)red_y);
1342 
1343  png_save_uint_32(buf + 16, (png_uint_32)green_x);
1344  png_save_uint_32(buf + 20, (png_uint_32)green_y);
1345 
1346  png_save_uint_32(buf + 24, (png_uint_32)blue_x);
1347  png_save_uint_32(buf + 28, (png_uint_32)blue_y);
1348 
1349  png_write_complete_chunk(png_ptr, png_cHRM, buf, (png_size_t)32);
1350  }
1351 }
1352 #endif
1353 
1354 #ifdef PNG_WRITE_tRNS_SUPPORTED
1355 /* Write the tRNS chunk */
1356 void /* PRIVATE */
1358  png_const_color_16p tran, int num_trans, int color_type)
1359 {
1360  png_byte buf[6];
1361 
1362  png_debug(1, "in png_write_tRNS");
1363 
1364  if (color_type == PNG_COLOR_TYPE_PALETTE)
1365  {
1366  if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)
1367  {
1368  png_warning(png_ptr, "Invalid number of transparent colors specified");
1369  return;
1370  }
1371 
1372  /* Write the chunk out as it is */
1373  png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha, (png_size_t)num_trans);
1374  }
1375 
1376  else if (color_type == PNG_COLOR_TYPE_GRAY)
1377  {
1378  /* One 16 bit value */
1379  if (tran->gray >= (1 << png_ptr->bit_depth))
1380  {
1381  png_warning(png_ptr,
1382  "Ignoring attempt to write tRNS chunk out-of-range for bit_depth");
1383 
1384  return;
1385  }
1386 
1387  png_save_uint_16(buf, tran->gray);
1388  png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2);
1389  }
1390 
1391  else if (color_type == PNG_COLOR_TYPE_RGB)
1392  {
1393  /* Three 16 bit values */
1394  png_save_uint_16(buf, tran->red);
1395  png_save_uint_16(buf + 2, tran->green);
1396  png_save_uint_16(buf + 4, tran->blue);
1397 #ifdef PNG_WRITE_16BIT_SUPPORTED
1398  if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
1399 #else
1400  if (buf[0] | buf[2] | buf[4])
1401 #endif
1402  {
1403  png_warning(png_ptr,
1404  "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
1405  return;
1406  }
1407 
1408  png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6);
1409  }
1410 
1411  else
1412  {
1413  png_warning(png_ptr, "Can't write tRNS with an alpha channel");
1414  }
1415 }
1416 #endif
1417 
1418 #ifdef PNG_WRITE_bKGD_SUPPORTED
1419 /* Write the background chunk */
1420 void /* PRIVATE */
1421 png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type)
1422 {
1423  png_byte buf[6];
1424 
1425  png_debug(1, "in png_write_bKGD");
1426 
1427  if (color_type == PNG_COLOR_TYPE_PALETTE)
1428  {
1429  if (
1431  (png_ptr->num_palette ||
1432  (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) &&
1433 #endif
1434  back->index >= png_ptr->num_palette)
1435  {
1436  png_warning(png_ptr, "Invalid background palette index");
1437  return;
1438  }
1439 
1440  buf[0] = back->index;
1441  png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1);
1442  }
1443 
1444  else if (color_type & PNG_COLOR_MASK_COLOR)
1445  {
1446  png_save_uint_16(buf, back->red);
1447  png_save_uint_16(buf + 2, back->green);
1448  png_save_uint_16(buf + 4, back->blue);
1449 #ifdef PNG_WRITE_16BIT_SUPPORTED
1450  if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
1451 #else
1452  if (buf[0] | buf[2] | buf[4])
1453 #endif
1454  {
1455  png_warning(png_ptr,
1456  "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8");
1457 
1458  return;
1459  }
1460 
1461  png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6);
1462  }
1463 
1464  else
1465  {
1466  if (back->gray >= (1 << png_ptr->bit_depth))
1467  {
1468  png_warning(png_ptr,
1469  "Ignoring attempt to write bKGD chunk out-of-range for bit_depth");
1470 
1471  return;
1472  }
1473 
1474  png_save_uint_16(buf, back->gray);
1475  png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2);
1476  }
1477 }
1478 #endif
1479 
1480 #ifdef PNG_WRITE_hIST_SUPPORTED
1481 /* Write the histogram */
1482 void /* PRIVATE */
1483 png_write_hIST(png_structp png_ptr, png_const_uint_16p hist, int num_hist)
1484 {
1485  int i;
1486  png_byte buf[3];
1487 
1488  png_debug(1, "in png_write_hIST");
1489 
1490  if (num_hist > (int)png_ptr->num_palette)
1491  {
1492  png_debug2(3, "num_hist = %d, num_palette = %d", num_hist,
1493  png_ptr->num_palette);
1494 
1495  png_warning(png_ptr, "Invalid number of histogram entries specified");
1496  return;
1497  }
1498 
1499  png_write_chunk_header(png_ptr, png_hIST, (png_uint_32)(num_hist * 2));
1500 
1501  for (i = 0; i < num_hist; i++)
1502  {
1503  png_save_uint_16(buf, hist[i]);
1504  png_write_chunk_data(png_ptr, buf, (png_size_t)2);
1505  }
1506 
1507  png_write_chunk_end(png_ptr);
1508 }
1509 #endif
1510 
1511 #if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
1512  defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
1513 /* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
1514  * and if invalid, correct the keyword rather than discarding the entire
1515  * chunk. The PNG 1.0 specification requires keywords 1-79 characters in
1516  * length, forbids leading or trailing whitespace, multiple internal spaces,
1517  * and the non-break space (0x80) from ISO 8859-1. Returns keyword length.
1518  *
1519  * The new_key is allocated to hold the corrected keyword and must be freed
1520  * by the calling routine. This avoids problems with trying to write to
1521  * static keywords without having to have duplicate copies of the strings.
1522  */
1523 png_size_t /* PRIVATE */
1525 {
1526  png_size_t key_len;
1527  png_const_charp ikp;
1528  png_charp kp, dp;
1529  int kflag;
1530  int kwarn=0;
1531 
1532  png_debug(1, "in png_check_keyword");
1533 
1534  *new_key = NULL;
1535 
1536  if (key == NULL || (key_len = png_strlen(key)) == 0)
1537  {
1538  png_warning(png_ptr, "zero length keyword");
1539  return ((png_size_t)0);
1540  }
1541 
1542  png_debug1(2, "Keyword to be checked is '%s'", key);
1543 
1544  *new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2));
1545 
1546  if (*new_key == NULL)
1547  {
1548  png_warning(png_ptr, "Out of memory while procesing keyword");
1549  return ((png_size_t)0);
1550  }
1551 
1552  /* Replace non-printing characters with a blank and print a warning */
1553  for (ikp = key, dp = *new_key; *ikp != '\0'; ikp++, dp++)
1554  {
1555  if ((png_byte)*ikp < 0x20 ||
1556  ((png_byte)*ikp > 0x7E && (png_byte)*ikp < 0xA1))
1557  {
1559 
1561  (png_byte)*ikp);
1562  png_formatted_warning(png_ptr, p, "invalid keyword character 0x@1");
1563  *dp = ' ';
1564  }
1565 
1566  else
1567  {
1568  *dp = *ikp;
1569  }
1570  }
1571  *dp = '\0';
1572 
1573  /* Remove any trailing white space. */
1574  kp = *new_key + key_len - 1;
1575  if (*kp == ' ')
1576  {
1577  png_warning(png_ptr, "trailing spaces removed from keyword");
1578 
1579  while (*kp == ' ')
1580  {
1581  *(kp--) = '\0';
1582  key_len--;
1583  }
1584  }
1585 
1586  /* Remove any leading white space. */
1587  kp = *new_key;
1588  if (*kp == ' ')
1589  {
1590  png_warning(png_ptr, "leading spaces removed from keyword");
1591 
1592  while (*kp == ' ')
1593  {
1594  kp++;
1595  key_len--;
1596  }
1597  }
1598 
1599  png_debug1(2, "Checking for multiple internal spaces in '%s'", kp);
1600 
1601  /* Remove multiple internal spaces. */
1602  for (kflag = 0, dp = *new_key; *kp != '\0'; kp++)
1603  {
1604  if (*kp == ' ' && kflag == 0)
1605  {
1606  *(dp++) = *kp;
1607  kflag = 1;
1608  }
1609 
1610  else if (*kp == ' ')
1611  {
1612  key_len--;
1613  kwarn = 1;
1614  }
1615 
1616  else
1617  {
1618  *(dp++) = *kp;
1619  kflag = 0;
1620  }
1621  }
1622  *dp = '\0';
1623  if (kwarn)
1624  png_warning(png_ptr, "extra interior spaces removed from keyword");
1625 
1626  if (key_len == 0)
1627  {
1628  png_free(png_ptr, *new_key);
1629  png_warning(png_ptr, "Zero length keyword");
1630  }
1631 
1632  if (key_len > 79)
1633  {
1634  png_warning(png_ptr, "keyword length must be 1 - 79 characters");
1635  (*new_key)[79] = '\0';
1636  key_len = 79;
1637  }
1638 
1639  return (key_len);
1640 }
1641 #endif
1642 
1643 #ifdef PNG_WRITE_tEXt_SUPPORTED
1644 /* Write a tEXt chunk */
1645 void /* PRIVATE */
1647  png_size_t text_len)
1648 {
1649  png_size_t key_len;
1650  png_charp new_key;
1651 
1652  png_debug(1, "in png_write_tEXt");
1653 
1654  if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0)
1655  return;
1656 
1657  if (text == NULL || *text == '\0')
1658  text_len = 0;
1659 
1660  else
1661  text_len = png_strlen(text);
1662 
1663  /* Make sure we include the 0 after the key */
1665  (png_uint_32)(key_len + text_len + 1));
1666  /*
1667  * We leave it to the application to meet PNG-1.0 requirements on the
1668  * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of
1669  * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them.
1670  * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
1671  */
1672  png_write_chunk_data(png_ptr, (png_bytep)new_key,
1673  (png_size_t)(key_len + 1));
1674 
1675  if (text_len)
1676  png_write_chunk_data(png_ptr, (png_const_bytep)text,
1677  (png_size_t)text_len);
1678 
1679  png_write_chunk_end(png_ptr);
1680  png_free(png_ptr, new_key);
1681 }
1682 #endif
1683 
1684 #ifdef PNG_WRITE_zTXt_SUPPORTED
1685 /* Write a compressed text chunk */
1686 void /* PRIVATE */
1688  png_size_t text_len, int compression)
1689 {
1690  png_size_t key_len;
1691  png_byte buf;
1692  png_charp new_key;
1693  compression_state comp;
1694 
1695  png_debug(1, "in png_write_zTXt");
1696 
1697  comp.num_output_ptr = 0;
1698  comp.max_output_ptr = 0;
1699  comp.output_ptr = NULL;
1700  comp.input = NULL;
1701  comp.input_len = 0;
1702 
1703  if ((key_len = png_check_keyword(png_ptr, key, &new_key)) == 0)
1704  {
1705  png_free(png_ptr, new_key);
1706  return;
1707  }
1708 
1709  if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE)
1710  {
1711  png_write_tEXt(png_ptr, new_key, text, (png_size_t)0);
1712  png_free(png_ptr, new_key);
1713  return;
1714  }
1715 
1716  text_len = png_strlen(text);
1717 
1718  /* Compute the compressed data; do it now for the length */
1719  text_len = png_text_compress(png_ptr, text, text_len, compression,
1720  &comp);
1721 
1722  /* Write start of chunk */
1724  (png_uint_32)(key_len+text_len + 2));
1725 
1726  /* Write key */
1727  png_write_chunk_data(png_ptr, (png_bytep)new_key,
1728  (png_size_t)(key_len + 1));
1729 
1730  png_free(png_ptr, new_key);
1731 
1732  buf = (png_byte)compression;
1733 
1734  /* Write compression */
1735  png_write_chunk_data(png_ptr, &buf, (png_size_t)1);
1736 
1737  /* Write the compressed data */
1738  comp.input_len = text_len;
1739  png_write_compressed_data_out(png_ptr, &comp);
1740 
1741  /* Close the chunk */
1742  png_write_chunk_end(png_ptr);
1743 }
1744 #endif
1745 
1746 #ifdef PNG_WRITE_iTXt_SUPPORTED
1747 /* Write an iTXt chunk */
1748 void /* PRIVATE */
1749 png_write_iTXt(png_structp png_ptr, int compression, png_const_charp key,
1750  png_const_charp lang, png_const_charp lang_key, png_const_charp text)
1751 {
1752  png_size_t lang_len, key_len, lang_key_len, text_len;
1753  png_charp new_lang;
1754  png_charp new_key = NULL;
1755  png_byte cbuf[2];
1756  compression_state comp;
1757 
1758  png_debug(1, "in png_write_iTXt");
1759 
1760  comp.num_output_ptr = 0;
1761  comp.max_output_ptr = 0;
1762  comp.output_ptr = NULL;
1763  comp.input = NULL;
1764 
1765  if ((key_len = png_check_keyword(png_ptr, key, &new_key)) == 0)
1766  return;
1767 
1768  if ((lang_len = png_check_keyword(png_ptr, lang, &new_lang)) == 0)
1769  {
1770  png_warning(png_ptr, "Empty language field in iTXt chunk");
1771  new_lang = NULL;
1772  lang_len = 0;
1773  }
1774 
1775  if (lang_key == NULL)
1776  lang_key_len = 0;
1777 
1778  else
1779  lang_key_len = png_strlen(lang_key);
1780 
1781  if (text == NULL)
1782  text_len = 0;
1783 
1784  else
1785  text_len = png_strlen(text);
1786 
1787  /* Compute the compressed data; do it now for the length */
1788  text_len = png_text_compress(png_ptr, text, text_len, compression - 2,
1789  &comp);
1790 
1791 
1792  /* Make sure we include the compression flag, the compression byte,
1793  * and the NULs after the key, lang, and lang_key parts
1794  */
1795 
1797  5 /* comp byte, comp flag, terminators for key, lang and lang_key */
1798  + key_len
1799  + lang_len
1800  + lang_key_len
1801  + text_len));
1802 
1803  /* We leave it to the application to meet PNG-1.0 requirements on the
1804  * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of
1805  * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them.
1806  * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
1807  */
1808  png_write_chunk_data(png_ptr, (png_bytep)new_key, (png_size_t)(key_len + 1));
1809 
1810  /* Set the compression flag */
1811  if (compression == PNG_ITXT_COMPRESSION_NONE ||
1812  compression == PNG_TEXT_COMPRESSION_NONE)
1813  cbuf[0] = 0;
1814 
1815  else /* compression == PNG_ITXT_COMPRESSION_zTXt */
1816  cbuf[0] = 1;
1817 
1818  /* Set the compression method */
1819  cbuf[1] = 0;
1820 
1821  png_write_chunk_data(png_ptr, cbuf, (png_size_t)2);
1822 
1823  cbuf[0] = 0;
1824  png_write_chunk_data(png_ptr, (new_lang ? (png_const_bytep)new_lang : cbuf),
1825  (png_size_t)(lang_len + 1));
1826 
1827  png_write_chunk_data(png_ptr, (lang_key ? (png_const_bytep)lang_key : cbuf),
1828  (png_size_t)(lang_key_len + 1));
1829 
1830  png_write_compressed_data_out(png_ptr, &comp);
1831 
1832  png_write_chunk_end(png_ptr);
1833 
1834  png_free(png_ptr, new_key);
1835  png_free(png_ptr, new_lang);
1836 }
1837 #endif
1838 
1839 #ifdef PNG_WRITE_oFFs_SUPPORTED
1840 /* Write the oFFs chunk */
1841 void /* PRIVATE */
1842 png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
1843  int unit_type)
1844 {
1845  png_byte buf[9];
1846 
1847  png_debug(1, "in png_write_oFFs");
1848 
1849  if (unit_type >= PNG_OFFSET_LAST)
1850  png_warning(png_ptr, "Unrecognized unit type for oFFs chunk");
1851 
1852  png_save_int_32(buf, x_offset);
1853  png_save_int_32(buf + 4, y_offset);
1854  buf[8] = (png_byte)unit_type;
1855 
1856  png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9);
1857 }
1858 #endif
1859 #ifdef PNG_WRITE_pCAL_SUPPORTED
1860 /* Write the pCAL chunk (described in the PNG extensions document) */
1861 void /* PRIVATE */
1863  png_int_32 X1, int type, int nparams, png_const_charp units,
1865 {
1866  png_size_t purpose_len, units_len, total_len;
1867  png_size_tp params_len;
1868  png_byte buf[10];
1869  png_charp new_purpose;
1870  int i;
1871 
1872  png_debug1(1, "in png_write_pCAL (%d parameters)", nparams);
1873 
1874  if (type >= PNG_EQUATION_LAST)
1875  png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
1876 
1877  purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1;
1878  png_debug1(3, "pCAL purpose length = %d", (int)purpose_len);
1879  units_len = png_strlen(units) + (nparams == 0 ? 0 : 1);
1880  png_debug1(3, "pCAL units length = %d", (int)units_len);
1881  total_len = purpose_len + units_len + 10;
1882 
1883  params_len = (png_size_tp)png_malloc(png_ptr,
1884  (png_alloc_size_t)(nparams * png_sizeof(png_size_t)));
1885 
1886  /* Find the length of each parameter, making sure we don't count the
1887  * null terminator for the last parameter.
1888  */
1889  for (i = 0; i < nparams; i++)
1890  {
1891  params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
1892  png_debug2(3, "pCAL parameter %d length = %lu", i,
1893  (unsigned long)params_len[i]);
1894  total_len += params_len[i];
1895  }
1896 
1897  png_debug1(3, "pCAL total length = %d", (int)total_len);
1898  png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len);
1899  png_write_chunk_data(png_ptr, (png_const_bytep)new_purpose, purpose_len);
1900  png_save_int_32(buf, X0);
1901  png_save_int_32(buf + 4, X1);
1902  buf[8] = (png_byte)type;
1903  buf[9] = (png_byte)nparams;
1904  png_write_chunk_data(png_ptr, buf, (png_size_t)10);
1905  png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len);
1906 
1907  png_free(png_ptr, new_purpose);
1908 
1909  for (i = 0; i < nparams; i++)
1910  {
1911  png_write_chunk_data(png_ptr, (png_const_bytep)params[i], params_len[i]);
1912  }
1913 
1914  png_free(png_ptr, params_len);
1915  png_write_chunk_end(png_ptr);
1916 }
1917 #endif
1918 
1919 #ifdef PNG_WRITE_sCAL_SUPPORTED
1920 /* Write the sCAL chunk */
1921 void /* PRIVATE */
1924 {
1925  png_byte buf[64];
1926  png_size_t wlen, hlen, total_len;
1927 
1928  png_debug(1, "in png_write_sCAL_s");
1929 
1930  wlen = png_strlen(width);
1931  hlen = png_strlen(height);
1932  total_len = wlen + hlen + 2;
1933 
1934  if (total_len > 64)
1935  {
1936  png_warning(png_ptr, "Can't write sCAL (buffer too small)");
1937  return;
1938  }
1939 
1940  buf[0] = (png_byte)unit;
1941  png_memcpy(buf + 1, width, wlen + 1); /* Append the '\0' here */
1942  png_memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */
1943 
1944  png_debug1(3, "sCAL total length = %u", (unsigned int)total_len);
1945  png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len);
1946 }
1947 #endif
1948 
1949 #ifdef PNG_WRITE_pHYs_SUPPORTED
1950 /* Write the pHYs chunk */
1951 void /* PRIVATE */
1952 png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
1953  png_uint_32 y_pixels_per_unit,
1954  int unit_type)
1955 {
1956  png_byte buf[9];
1957 
1958  png_debug(1, "in png_write_pHYs");
1959 
1960  if (unit_type >= PNG_RESOLUTION_LAST)
1961  png_warning(png_ptr, "Unrecognized unit type for pHYs chunk");
1962 
1963  png_save_uint_32(buf, x_pixels_per_unit);
1964  png_save_uint_32(buf + 4, y_pixels_per_unit);
1965  buf[8] = (png_byte)unit_type;
1966 
1967  png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9);
1968 }
1969 #endif
1970 
1971 #ifdef PNG_WRITE_tIME_SUPPORTED
1972 /* Write the tIME chunk. Use either png_convert_from_struct_tm()
1973  * or png_convert_from_time_t(), or fill in the structure yourself.
1974  */
1975 void /* PRIVATE */
1977 {
1978  png_byte buf[7];
1979 
1980  png_debug(1, "in png_write_tIME");
1981 
1982  if (mod_time->month > 12 || mod_time->month < 1 ||
1983  mod_time->day > 31 || mod_time->day < 1 ||
1984  mod_time->hour > 23 || mod_time->second > 60)
1985  {
1986  png_warning(png_ptr, "Invalid time specified for tIME chunk");
1987  return;
1988  }
1989 
1990  png_save_uint_16(buf, mod_time->year);
1991  buf[2] = mod_time->month;
1992  buf[3] = mod_time->day;
1993  buf[4] = mod_time->hour;
1994  buf[5] = mod_time->minute;
1995  buf[6] = mod_time->second;
1996 
1997  png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7);
1998 }
1999 #endif
2000 
2001 /* Initializes the row writing capability of libpng */
2002 void /* PRIVATE */
2004 {
2005 #ifdef PNG_WRITE_INTERLACING_SUPPORTED
2006  /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2007 
2008  /* Start of interlace block */
2009  static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
2010 
2011  /* Offset to next interlace block */
2012  static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2013 
2014  /* Start of interlace block in the y direction */
2015  static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
2016 
2017  /* Offset to next interlace block in the y direction */
2018  static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
2019 #endif
2020 
2021  png_alloc_size_t buf_size;
2022  int usr_pixel_depth;
2023 
2024  png_debug(1, "in png_write_start_row");
2025 
2026  usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth;
2027  buf_size = PNG_ROWBYTES(usr_pixel_depth, png_ptr->width) + 1;
2028 
2029  /* 1.5.6: added to allow checking in the row write code. */
2030  png_ptr->transformed_pixel_depth = png_ptr->pixel_depth;
2031  png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth;
2032 
2033  /* Set up row buffer */
2034  png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, buf_size);
2035 
2036  png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
2037 
2038 #ifdef PNG_WRITE_FILTER_SUPPORTED
2039  /* Set up filtering buffer, if using this filter */
2040  if (png_ptr->do_filter & PNG_FILTER_SUB)
2041  {
2042  png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1);
2043 
2044  png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
2045  }
2046 
2047  /* We only need to keep the previous row if we are using one of these. */
2048  if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH))
2049  {
2050  /* Set up previous row buffer */
2051  png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, buf_size);
2052 
2053  if (png_ptr->do_filter & PNG_FILTER_UP)
2054  {
2055  png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
2056  png_ptr->rowbytes + 1);
2057 
2058  png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
2059  }
2060 
2061  if (png_ptr->do_filter & PNG_FILTER_AVG)
2062  {
2063  png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
2064  png_ptr->rowbytes + 1);
2065 
2066  png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
2067  }
2068 
2069  if (png_ptr->do_filter & PNG_FILTER_PAETH)
2070  {
2071  png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
2072  png_ptr->rowbytes + 1);
2073 
2074  png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
2075  }
2076  }
2077 #endif /* PNG_WRITE_FILTER_SUPPORTED */
2078 
2079 #ifdef PNG_WRITE_INTERLACING_SUPPORTED
2080  /* If interlaced, we need to set up width and height of pass */
2081  if (png_ptr->interlaced)
2082  {
2083  if (!(png_ptr->transformations & PNG_INTERLACE))
2084  {
2085  png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
2086  png_pass_ystart[0]) / png_pass_yinc[0];
2087 
2088  png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 -
2089  png_pass_start[0]) / png_pass_inc[0];
2090  }
2091 
2092  else
2093  {
2094  png_ptr->num_rows = png_ptr->height;
2095  png_ptr->usr_width = png_ptr->width;
2096  }
2097  }
2098 
2099  else
2100 #endif
2101  {
2102  png_ptr->num_rows = png_ptr->height;
2103  png_ptr->usr_width = png_ptr->width;
2104  }
2105 
2106  png_zlib_claim(png_ptr, PNG_ZLIB_FOR_IDAT);
2107  png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
2108  png_ptr->zstream.next_out = png_ptr->zbuf;
2109 }
2110 
2111 /* Internal use only. Called when finished processing a row of data. */
2112 void /* PRIVATE */
2114 {
2115 #ifdef PNG_WRITE_INTERLACING_SUPPORTED
2116  /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2117 
2118  /* Start of interlace block */
2119  static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
2120 
2121  /* Offset to next interlace block */
2122  static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2123 
2124  /* Start of interlace block in the y direction */
2125  static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
2126 
2127  /* Offset to next interlace block in the y direction */
2128  static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
2129 #endif
2130 
2131  int ret;
2132 
2133  png_debug(1, "in png_write_finish_row");
2134 
2135  /* Next row */
2136  png_ptr->row_number++;
2137 
2138  /* See if we are done */
2139  if (png_ptr->row_number < png_ptr->num_rows)
2140  return;
2141 
2142 #ifdef PNG_WRITE_INTERLACING_SUPPORTED
2143  /* If interlaced, go to next pass */
2144  if (png_ptr->interlaced)
2145  {
2146  png_ptr->row_number = 0;
2147  if (png_ptr->transformations & PNG_INTERLACE)
2148  {
2149  png_ptr->pass++;
2150  }
2151 
2152  else
2153  {
2154  /* Loop until we find a non-zero width or height pass */
2155  do
2156  {
2157  png_ptr->pass++;
2158 
2159  if (png_ptr->pass >= 7)
2160  break;
2161 
2162  png_ptr->usr_width = (png_ptr->width +
2163  png_pass_inc[png_ptr->pass] - 1 -
2164  png_pass_start[png_ptr->pass]) /
2165  png_pass_inc[png_ptr->pass];
2166 
2167  png_ptr->num_rows = (png_ptr->height +
2168  png_pass_yinc[png_ptr->pass] - 1 -
2169  png_pass_ystart[png_ptr->pass]) /
2170  png_pass_yinc[png_ptr->pass];
2171 
2172  if (png_ptr->transformations & PNG_INTERLACE)
2173  break;
2174 
2175  } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);
2176 
2177  }
2178 
2179  /* Reset the row above the image for the next pass */
2180  if (png_ptr->pass < 7)
2181  {
2182  if (png_ptr->prev_row != NULL)
2183  png_memset(png_ptr->prev_row, 0,
2184  (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels*
2185  png_ptr->usr_bit_depth, png_ptr->width)) + 1);
2186 
2187  return;
2188  }
2189  }
2190 #endif
2191 
2192  /* If we get here, we've just written the last row, so we need
2193  to flush the compressor */
2194  do
2195  {
2196  /* Tell the compressor we are done */
2197  ret = deflate(&png_ptr->zstream, Z_FINISH);
2198 
2199  /* Check for an error */
2200  if (ret == Z_OK)
2201  {
2202  /* Check to see if we need more room */
2203  if (!(png_ptr->zstream.avail_out))
2204  {
2205  png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
2206  png_ptr->zstream.next_out = png_ptr->zbuf;
2207  png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
2208  }
2209  }
2210 
2211  else if (ret != Z_STREAM_END)
2212  {
2213  if (png_ptr->zstream.msg != NULL)
2214  png_error(png_ptr, png_ptr->zstream.msg);
2215 
2216  else
2217  png_error(png_ptr, "zlib error");
2218  }
2219  } while (ret != Z_STREAM_END);
2220 
2221  /* Write any extra space */
2222  if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
2223  {
2224  png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size -
2225  png_ptr->zstream.avail_out);
2226  }
2227 
2228  png_zlib_release(png_ptr);
2229  png_ptr->zstream.data_type = Z_BINARY;
2230 }
2231 
2232 #ifdef PNG_WRITE_INTERLACING_SUPPORTED
2233 /* Pick out the correct pixels for the interlace pass.
2234  * The basic idea here is to go through the row with a source
2235  * pointer and a destination pointer (sp and dp), and copy the
2236  * correct pixels for the pass. As the row gets compacted,
2237  * sp will always be >= dp, so we should never overwrite anything.
2238  * See the default: case for the easiest code to understand.
2239  */
2240 void /* PRIVATE */
2242 {
2243  /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2244 
2245  /* Start of interlace block */
2246  static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
2247 
2248  /* Offset to next interlace block */
2249  static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2250 
2251  png_debug(1, "in png_do_write_interlace");
2252 
2253  /* We don't have to do anything on the last pass (6) */
2254  if (pass < 6)
2255  {
2256  /* Each pixel depth is handled separately */
2257  switch (row_info->pixel_depth)
2258  {
2259  case 1:
2260  {
2261  png_bytep sp;
2262  png_bytep dp;
2263  int shift;
2264  int d;
2265  int value;
2266  png_uint_32 i;
2267  png_uint_32 row_width = row_info->width;
2268 
2269  dp = row;
2270  d = 0;
2271  shift = 7;
2272 
2273  for (i = png_pass_start[pass]; i < row_width;
2274  i += png_pass_inc[pass])
2275  {
2276  sp = row + (png_size_t)(i >> 3);
2277  value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
2278  d |= (value << shift);
2279 
2280  if (shift == 0)
2281  {
2282  shift = 7;
2283  *dp++ = (png_byte)d;
2284  d = 0;
2285  }
2286 
2287  else
2288  shift--;
2289 
2290  }
2291  if (shift != 7)
2292  *dp = (png_byte)d;
2293 
2294  break;
2295  }
2296 
2297  case 2:
2298  {
2299  png_bytep sp;
2300  png_bytep dp;
2301  int shift;
2302  int d;
2303  int value;
2304  png_uint_32 i;
2305  png_uint_32 row_width = row_info->width;
2306 
2307  dp = row;
2308  shift = 6;
2309  d = 0;
2310 
2311  for (i = png_pass_start[pass]; i < row_width;
2312  i += png_pass_inc[pass])
2313  {
2314  sp = row + (png_size_t)(i >> 2);
2315  value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
2316  d |= (value << shift);
2317 
2318  if (shift == 0)
2319  {
2320  shift = 6;
2321  *dp++ = (png_byte)d;
2322  d = 0;
2323  }
2324 
2325  else
2326  shift -= 2;
2327  }
2328  if (shift != 6)
2329  *dp = (png_byte)d;
2330 
2331  break;
2332  }
2333 
2334  case 4:
2335  {
2336  png_bytep sp;
2337  png_bytep dp;
2338  int shift;
2339  int d;
2340  int value;
2341  png_uint_32 i;
2342  png_uint_32 row_width = row_info->width;
2343 
2344  dp = row;
2345  shift = 4;
2346  d = 0;
2347  for (i = png_pass_start[pass]; i < row_width;
2348  i += png_pass_inc[pass])
2349  {
2350  sp = row + (png_size_t)(i >> 1);
2351  value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
2352  d |= (value << shift);
2353 
2354  if (shift == 0)
2355  {
2356  shift = 4;
2357  *dp++ = (png_byte)d;
2358  d = 0;
2359  }
2360 
2361  else
2362  shift -= 4;
2363  }
2364  if (shift != 4)
2365  *dp = (png_byte)d;
2366 
2367  break;
2368  }
2369 
2370  default:
2371  {
2372  png_bytep sp;
2373  png_bytep dp;
2374  png_uint_32 i;
2375  png_uint_32 row_width = row_info->width;
2376  png_size_t pixel_bytes;
2377 
2378  /* Start at the beginning */
2379  dp = row;
2380 
2381  /* Find out how many bytes each pixel takes up */
2382  pixel_bytes = (row_info->pixel_depth >> 3);
2383 
2384  /* Loop through the row, only looking at the pixels that matter */
2385  for (i = png_pass_start[pass]; i < row_width;
2386  i += png_pass_inc[pass])
2387  {
2388  /* Find out where the original pixel is */
2389  sp = row + (png_size_t)i * pixel_bytes;
2390 
2391  /* Move the pixel */
2392  if (dp != sp)
2393  png_memcpy(dp, sp, pixel_bytes);
2394 
2395  /* Next pixel */
2396  dp += pixel_bytes;
2397  }
2398  break;
2399  }
2400  }
2401  /* Set new row width */
2402  row_info->width = (row_info->width +
2403  png_pass_inc[pass] - 1 -
2404  png_pass_start[pass]) /
2405  png_pass_inc[pass];
2406 
2407  row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
2408  row_info->width);
2409  }
2410 }
2411 #endif
2412 
2413 /* This filters the row, chooses which filter to use, if it has not already
2414  * been specified by the application, and then writes the row out with the
2415  * chosen filter.
2416  */
2417 static void png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row,
2418  png_size_t row_bytes);
2419 
2420 #define PNG_MAXSUM (((png_uint_32)(-1)) >> 1)
2421 #define PNG_HISHIFT 10
2422 #define PNG_LOMASK ((png_uint_32)0xffffL)
2423 #define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
2424 void /* PRIVATE */
2426 {
2427  png_bytep best_row;
2428 #ifdef PNG_WRITE_FILTER_SUPPORTED
2429  png_bytep prev_row, row_buf;
2430  png_uint_32 mins, bpp;
2431  png_byte filter_to_do = png_ptr->do_filter;
2432  png_size_t row_bytes = row_info->rowbytes;
2433 #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2434  int num_p_filters = png_ptr->num_prev_filters;
2435 #endif
2436 
2437  png_debug(1, "in png_write_find_filter");
2438 
2439 #ifndef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2440  if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS)
2441  {
2442  /* These will never be selected so we need not test them. */
2443  filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH);
2444  }
2445 #endif
2446 
2447  /* Find out how many bytes offset each pixel is */
2448  bpp = (row_info->pixel_depth + 7) >> 3;
2449 
2450  prev_row = png_ptr->prev_row;
2451 #endif
2452  best_row = png_ptr->row_buf;
2453 #ifdef PNG_WRITE_FILTER_SUPPORTED
2454  row_buf = best_row;
2455  mins = PNG_MAXSUM;
2456 
2457  /* The prediction method we use is to find which method provides the
2458  * smallest value when summing the absolute values of the distances
2459  * from zero, using anything >= 128 as negative numbers. This is known
2460  * as the "minimum sum of absolute differences" heuristic. Other
2461  * heuristics are the "weighted minimum sum of absolute differences"
2462  * (experimental and can in theory improve compression), and the "zlib
2463  * predictive" method (not implemented yet), which does test compressions
2464  * of lines using different filter methods, and then chooses the
2465  * (series of) filter(s) that give minimum compressed data size (VERY
2466  * computationally expensive).
2467  *
2468  * GRR 980525: consider also
2469  *
2470  * (1) minimum sum of absolute differences from running average (i.e.,
2471  * keep running sum of non-absolute differences & count of bytes)
2472  * [track dispersion, too? restart average if dispersion too large?]
2473  *
2474  * (1b) minimum sum of absolute differences from sliding average, probably
2475  * with window size <= deflate window (usually 32K)
2476  *
2477  * (2) minimum sum of squared differences from zero or running average
2478  * (i.e., ~ root-mean-square approach)
2479  */
2480 
2481 
2482  /* We don't need to test the 'no filter' case if this is the only filter
2483  * that has been chosen, as it doesn't actually do anything to the data.
2484  */
2485  if ((filter_to_do & PNG_FILTER_NONE) && filter_to_do != PNG_FILTER_NONE)
2486  {
2487  png_bytep rp;
2488  png_uint_32 sum = 0;
2489  png_size_t i;
2490  int v;
2491 
2492  for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
2493  {
2494  v = *rp;
2495  sum += (v < 128) ? v : 256 - v;
2496  }
2497 
2498 #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2499  if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2500  {
2501  png_uint_32 sumhi, sumlo;
2502  int j;
2503  sumlo = sum & PNG_LOMASK;
2504  sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */
2505 
2506  /* Reduce the sum if we match any of the previous rows */
2507  for (j = 0; j < num_p_filters; j++)
2508  {
2509  if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
2510  {
2511  sumlo = (sumlo * png_ptr->filter_weights[j]) >>
2513 
2514  sumhi = (sumhi * png_ptr->filter_weights[j]) >>
2516  }
2517  }
2518 
2519  /* Factor in the cost of this filter (this is here for completeness,
2520  * but it makes no sense to have a "cost" for the NONE filter, as
2521  * it has the minimum possible computational cost - none).
2522  */
2523  sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
2525 
2526  sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
2528 
2529  if (sumhi > PNG_HIMASK)
2530  sum = PNG_MAXSUM;
2531 
2532  else
2533  sum = (sumhi << PNG_HISHIFT) + sumlo;
2534  }
2535 #endif
2536  mins = sum;
2537  }
2538 
2539  /* Sub filter */
2540  if (filter_to_do == PNG_FILTER_SUB)
2541  /* It's the only filter so no testing is needed */
2542  {
2543  png_bytep rp, lp, dp;
2544  png_size_t i;
2545 
2546  for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
2547  i++, rp++, dp++)
2548  {
2549  *dp = *rp;
2550  }
2551 
2552  for (lp = row_buf + 1; i < row_bytes;
2553  i++, rp++, lp++, dp++)
2554  {
2555  *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
2556  }
2557 
2558  best_row = png_ptr->sub_row;
2559  }
2560 
2561  else if (filter_to_do & PNG_FILTER_SUB)
2562  {
2563  png_bytep rp, dp, lp;
2564  png_uint_32 sum = 0, lmins = mins;
2565  png_size_t i;
2566  int v;
2567 
2568 #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2569  /* We temporarily increase the "minimum sum" by the factor we
2570  * would reduce the sum of this filter, so that we can do the
2571  * early exit comparison without scaling the sum each time.
2572  */
2573  if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2574  {
2575  int j;
2576  png_uint_32 lmhi, lmlo;
2577  lmlo = lmins & PNG_LOMASK;
2578  lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
2579 
2580  for (j = 0; j < num_p_filters; j++)
2581  {
2582  if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
2583  {
2584  lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2586 
2587  lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
2589  }
2590  }
2591 
2592  lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
2594 
2595  lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
2597 
2598  if (lmhi > PNG_HIMASK)
2599  lmins = PNG_MAXSUM;
2600 
2601  else
2602  lmins = (lmhi << PNG_HISHIFT) + lmlo;
2603  }
2604 #endif
2605 
2606  for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
2607  i++, rp++, dp++)
2608  {
2609  v = *dp = *rp;
2610 
2611  sum += (v < 128) ? v : 256 - v;
2612  }
2613 
2614  for (lp = row_buf + 1; i < row_bytes;
2615  i++, rp++, lp++, dp++)
2616  {
2617  v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
2618 
2619  sum += (v < 128) ? v : 256 - v;
2620 
2621  if (sum > lmins) /* We are already worse, don't continue. */
2622  break;
2623  }
2624 
2625 #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2626  if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2627  {
2628  int j;
2629  png_uint_32 sumhi, sumlo;
2630  sumlo = sum & PNG_LOMASK;
2631  sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
2632 
2633  for (j = 0; j < num_p_filters; j++)
2634  {
2635  if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
2636  {
2637  sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >>
2639 
2640  sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >>
2642  }
2643  }
2644 
2645  sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
2647 
2648  sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
2650 
2651  if (sumhi > PNG_HIMASK)
2652  sum = PNG_MAXSUM;
2653 
2654  else
2655  sum = (sumhi << PNG_HISHIFT) + sumlo;
2656  }
2657 #endif
2658 
2659  if (sum < mins)
2660  {
2661  mins = sum;
2662  best_row = png_ptr->sub_row;
2663  }
2664  }
2665 
2666  /* Up filter */
2667  if (filter_to_do == PNG_FILTER_UP)
2668  {
2669  png_bytep rp, dp, pp;
2670  png_size_t i;
2671 
2672  for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
2673  pp = prev_row + 1; i < row_bytes;
2674  i++, rp++, pp++, dp++)
2675  {
2676  *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
2677  }
2678 
2679  best_row = png_ptr->up_row;
2680  }
2681 
2682  else if (filter_to_do & PNG_FILTER_UP)
2683  {
2684  png_bytep rp, dp, pp;
2685  png_uint_32 sum = 0, lmins = mins;
2686  png_size_t i;
2687  int v;
2688 
2689 
2690 #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2691  if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2692  {
2693  int j;
2694  png_uint_32 lmhi, lmlo;
2695  lmlo = lmins & PNG_LOMASK;
2696  lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
2697 
2698  for (j = 0; j < num_p_filters; j++)
2699  {
2700  if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
2701  {
2702  lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2704 
2705  lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
2707  }
2708  }
2709 
2710  lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
2712 
2713  lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
2715 
2716  if (lmhi > PNG_HIMASK)
2717  lmins = PNG_MAXSUM;
2718 
2719  else
2720  lmins = (lmhi << PNG_HISHIFT) + lmlo;
2721  }
2722 #endif
2723 
2724  for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
2725  pp = prev_row + 1; i < row_bytes; i++)
2726  {
2727  v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
2728 
2729  sum += (v < 128) ? v : 256 - v;
2730 
2731  if (sum > lmins) /* We are already worse, don't continue. */
2732  break;
2733  }
2734 
2735 #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2736  if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2737  {
2738  int j;
2739  png_uint_32 sumhi, sumlo;
2740  sumlo = sum & PNG_LOMASK;
2741  sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
2742 
2743  for (j = 0; j < num_p_filters; j++)
2744  {
2745  if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
2746  {
2747  sumlo = (sumlo * png_ptr->filter_weights[j]) >>
2749 
2750  sumhi = (sumhi * png_ptr->filter_weights[j]) >>
2752  }
2753  }
2754 
2755  sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
2757 
2758  sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
2760 
2761  if (sumhi > PNG_HIMASK)
2762  sum = PNG_MAXSUM;
2763 
2764  else
2765  sum = (sumhi << PNG_HISHIFT) + sumlo;
2766  }
2767 #endif
2768 
2769  if (sum < mins)
2770  {
2771  mins = sum;
2772  best_row = png_ptr->up_row;
2773  }
2774  }
2775 
2776  /* Avg filter */
2777  if (filter_to_do == PNG_FILTER_AVG)
2778  {
2779  png_bytep rp, dp, pp, lp;
2780  png_uint_32 i;
2781 
2782  for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
2783  pp = prev_row + 1; i < bpp; i++)
2784  {
2785  *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
2786  }
2787 
2788  for (lp = row_buf + 1; i < row_bytes; i++)
2789  {
2790  *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
2791  & 0xff);
2792  }
2793  best_row = png_ptr->avg_row;
2794  }
2795 
2796  else if (filter_to_do & PNG_FILTER_AVG)
2797  {
2798  png_bytep rp, dp, pp, lp;
2799  png_uint_32 sum = 0, lmins = mins;
2800  png_size_t i;
2801  int v;
2802 
2803 #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2804  if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2805  {
2806  int j;
2807  png_uint_32 lmhi, lmlo;
2808  lmlo = lmins & PNG_LOMASK;
2809  lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
2810 
2811  for (j = 0; j < num_p_filters; j++)
2812  {
2813  if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG)
2814  {
2815  lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2817 
2818  lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
2820  }
2821  }
2822 
2823  lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
2825 
2826  lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
2828 
2829  if (lmhi > PNG_HIMASK)
2830  lmins = PNG_MAXSUM;
2831 
2832  else
2833  lmins = (lmhi << PNG_HISHIFT) + lmlo;
2834  }
2835 #endif
2836 
2837  for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
2838  pp = prev_row + 1; i < bpp; i++)
2839  {
2840  v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
2841 
2842  sum += (v < 128) ? v : 256 - v;
2843  }
2844 
2845  for (lp = row_buf + 1; i < row_bytes; i++)
2846  {
2847  v = *dp++ =
2848  (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff);
2849 
2850  sum += (v < 128) ? v : 256 - v;
2851 
2852  if (sum > lmins) /* We are already worse, don't continue. */
2853  break;
2854  }
2855 
2856 #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2857  if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2858  {
2859  int j;
2860  png_uint_32 sumhi, sumlo;
2861  sumlo = sum & PNG_LOMASK;
2862  sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
2863 
2864  for (j = 0; j < num_p_filters; j++)
2865  {
2866  if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
2867  {
2868  sumlo = (sumlo * png_ptr->filter_weights[j]) >>
2870 
2871  sumhi = (sumhi * png_ptr->filter_weights[j]) >>
2873  }
2874  }
2875 
2876  sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
2878 
2879  sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
2881 
2882  if (sumhi > PNG_HIMASK)
2883  sum = PNG_MAXSUM;
2884 
2885  else
2886  sum = (sumhi << PNG_HISHIFT) + sumlo;
2887  }
2888 #endif
2889 
2890  if (sum < mins)
2891  {
2892  mins = sum;
2893  best_row = png_ptr->avg_row;
2894  }
2895  }
2896 
2897  /* Paeth filter */
2898  if (filter_to_do == PNG_FILTER_PAETH)
2899  {
2900  png_bytep rp, dp, pp, cp, lp;
2901  png_size_t i;
2902 
2903  for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
2904  pp = prev_row + 1; i < bpp; i++)
2905  {
2906  *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
2907  }
2908 
2909  for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
2910  {
2911  int a, b, c, pa, pb, pc, p;
2912 
2913  b = *pp++;
2914  c = *cp++;
2915  a = *lp++;
2916 
2917  p = b - c;
2918  pc = a - c;
2919 
2920 #ifdef PNG_USE_ABS
2921  pa = abs(p);
2922  pb = abs(pc);
2923  pc = abs(p + pc);
2924 #else
2925  pa = p < 0 ? -p : p;
2926  pb = pc < 0 ? -pc : pc;
2927  pc = (p + pc) < 0 ? -(p + pc) : p + pc;
2928 #endif
2929 
2930  p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
2931 
2932  *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
2933  }
2934  best_row = png_ptr->paeth_row;
2935  }
2936 
2937  else if (filter_to_do & PNG_FILTER_PAETH)
2938  {
2939  png_bytep rp, dp, pp, cp, lp;
2940  png_uint_32 sum = 0, lmins = mins;
2941  png_size_t i;
2942  int v;
2943 
2944 #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2945  if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2946  {
2947  int j;
2948  png_uint_32 lmhi, lmlo;
2949  lmlo = lmins & PNG_LOMASK;
2950  lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
2951 
2952  for (j = 0; j < num_p_filters; j++)
2953  {
2954  if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
2955  {
2956  lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2958 
2959  lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
2961  }
2962  }
2963 
2964  lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
2966 
2967  lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
2969 
2970  if (lmhi > PNG_HIMASK)
2971  lmins = PNG_MAXSUM;
2972 
2973  else
2974  lmins = (lmhi << PNG_HISHIFT) + lmlo;
2975  }
2976 #endif
2977 
2978  for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
2979  pp = prev_row + 1; i < bpp; i++)
2980  {
2981  v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
2982 
2983  sum += (v < 128) ? v : 256 - v;
2984  }
2985 
2986  for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
2987  {
2988  int a, b, c, pa, pb, pc, p;
2989 
2990  b = *pp++;
2991  c = *cp++;
2992  a = *lp++;
2993 
2994 #ifndef PNG_SLOW_PAETH
2995  p = b - c;
2996  pc = a - c;
2997 #ifdef PNG_USE_ABS
2998  pa = abs(p);
2999  pb = abs(pc);
3000  pc = abs(p + pc);
3001 #else
3002  pa = p < 0 ? -p : p;
3003  pb = pc < 0 ? -pc : pc;
3004  pc = (p + pc) < 0 ? -(p + pc) : p + pc;
3005 #endif
3006  p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
3007 #else /* PNG_SLOW_PAETH */
3008  p = a + b - c;
3009  pa = abs(p - a);
3010  pb = abs(p - b);
3011  pc = abs(p - c);
3012 
3013  if (pa <= pb && pa <= pc)
3014  p = a;
3015 
3016  else if (pb <= pc)
3017  p = b;
3018 
3019  else
3020  p = c;
3021 #endif /* PNG_SLOW_PAETH */
3022 
3023  v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
3024 
3025  sum += (v < 128) ? v : 256 - v;
3026 
3027  if (sum > lmins) /* We are already worse, don't continue. */
3028  break;
3029  }
3030 
3031 #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
3032  if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
3033  {
3034  int j;
3035  png_uint_32 sumhi, sumlo;
3036  sumlo = sum & PNG_LOMASK;
3037  sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
3038 
3039  for (j = 0; j < num_p_filters; j++)
3040  {
3041  if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
3042  {
3043  sumlo = (sumlo * png_ptr->filter_weights[j]) >>
3045 
3046  sumhi = (sumhi * png_ptr->filter_weights[j]) >>
3048  }
3049  }
3050 
3051  sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
3053 
3054  sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
3056 
3057  if (sumhi > PNG_HIMASK)
3058  sum = PNG_MAXSUM;
3059 
3060  else
3061  sum = (sumhi << PNG_HISHIFT) + sumlo;
3062  }
3063 #endif
3064 
3065  if (sum < mins)
3066  {
3067  best_row = png_ptr->paeth_row;
3068  }
3069  }
3070 #endif /* PNG_WRITE_FILTER_SUPPORTED */
3071 
3072  /* Do the actual writing of the filtered row data from the chosen filter. */
3073  png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1);
3074 
3075 #ifdef PNG_WRITE_FILTER_SUPPORTED
3076 #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
3077  /* Save the type of filter we picked this time for future calculations */
3078  if (png_ptr->num_prev_filters > 0)
3079  {
3080  int j;
3081 
3082  for (j = 1; j < num_p_filters; j++)
3083  {
3084  png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1];
3085  }
3086 
3087  png_ptr->prev_filters[j] = best_row[0];
3088  }
3089 #endif
3090 #endif /* PNG_WRITE_FILTER_SUPPORTED */
3091 }
3092 
3093 
3094 /* Do the actual writing of a previously filtered row. */
3095 static void
3097  png_size_t avail/*includes filter byte*/)
3098 {
3099  png_debug(1, "in png_write_filtered_row");
3100 
3101  png_debug1(2, "filter = %d", filtered_row[0]);
3102  /* Set up the zlib input buffer */
3103 
3104  png_ptr->zstream.next_in = filtered_row;
3105  png_ptr->zstream.avail_in = 0;
3106  /* Repeat until we have compressed all the data */
3107  do
3108  {
3109  int ret; /* Return of zlib */
3110 
3111  /* Record the number of bytes available - zlib supports at least 65535
3112  * bytes at one step, depending on the size of the zlib type 'uInt', the
3113  * maximum size zlib can write at once is ZLIB_IO_MAX (from pngpriv.h).
3114  * Use this because on 16 bit systems 'rowbytes' can be up to 65536 (i.e.
3115  * one more than 16 bits) and, in this case 'rowbytes+1' can overflow a
3116  * uInt. ZLIB_IO_MAX can be safely reduced to cause zlib to be called
3117  * with smaller chunks of data.
3118  */
3119  if (png_ptr->zstream.avail_in == 0)
3120  {
3121  if (avail > ZLIB_IO_MAX)
3122  {
3123  png_ptr->zstream.avail_in = ZLIB_IO_MAX;
3124  avail -= ZLIB_IO_MAX;
3125  }
3126 
3127  else
3128  {
3129  /* So this will fit in the available uInt space: */
3130  png_ptr->zstream.avail_in = (uInt)avail;
3131  avail = 0;
3132  }
3133  }
3134 
3135  /* Compress the data */
3136  ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
3137 
3138  /* Check for compression errors */
3139  if (ret != Z_OK)
3140  {
3141  if (png_ptr->zstream.msg != NULL)
3142  png_error(png_ptr, png_ptr->zstream.msg);
3143 
3144  else
3145  png_error(png_ptr, "zlib error");
3146  }
3147 
3148  /* See if it is time to write another IDAT */
3149  if (!(png_ptr->zstream.avail_out))
3150  {
3151  /* Write the IDAT and reset the zlib output buffer */
3152  png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
3153  }
3154  /* Repeat until all data has been compressed */
3155  } while (avail > 0 || png_ptr->zstream.avail_in > 0);
3156 
3157  /* Swap the current and previous rows */
3158  if (png_ptr->prev_row != NULL)
3159  {
3160  png_bytep tptr;
3161 
3162  tptr = png_ptr->prev_row;
3163  png_ptr->prev_row = png_ptr->row_buf;
3164  png_ptr->row_buf = tptr;
3165  }
3166 
3167  /* Finish row - updates counters and flushes zlib if last row */
3168  png_write_finish_row(png_ptr);
3169 
3170 #ifdef PNG_WRITE_FLUSH_SUPPORTED
3171  png_ptr->flush_rows++;
3172 
3173  if (png_ptr->flush_dist > 0 &&
3174  png_ptr->flush_rows >= png_ptr->flush_dist)
3175  {
3176  png_write_flush(png_ptr);
3177  }
3178 #endif
3179 }
3180 #endif /* PNG_WRITE_SUPPORTED */
static void png_write_chunk_header(png_structp png_ptr, png_uint_32 chunk_name, png_uint_32 length)
Definition: pngwutil.c:90
#define PNG_FILTER_VALUE_AVG
Definition: png.h:1628
#define PNG_WEIGHT_SHIFT
Definition: pnglibconf.h:38
#define PNG_TEXT_COMPRESSION_LAST
Definition: png.h:665
void png_write_start_row(png_structp png_ptr)
Definition: pngwutil.c:2003
void png_zfree(voidpf png_ptr, voidpf ptr)
Definition: png.c:99
#define png_memcpy
Definition: pngpriv.h:353
png_charp profile
Definition: pngrutil.c:1240
#define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
Definition: pnglibconf.h:150
void png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette)
Definition: pngwutil.c:1179
void PNGAPI png_write_chunk_start(png_structp png_ptr, png_const_bytep chunk_string, png_uint_32 length)
Definition: pngwutil.c:132
void png_write_PLTE(png_structp png_ptr, png_const_colorp palette, png_uint_32 num_pal)
Definition: pngwutil.c:895
#define PNG_FILTER_PAETH
Definition: png.h:1618
#define png_PLTE
Definition: pngpriv.h:604
#define png_sCAL
Definition: pngpriv.h:613
#define png_iTXt
Definition: pngpriv.h:610
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
Definition: gl2ext.h:845
PNG_CONST png_time FAR * png_const_timep
Definition: png.h:683
#define PNG_FILTER_HEURISTIC_WEIGHTED
Definition: png.h:1675
void png_write_sBIT(png_structp png_ptr, png_const_color_8p sbit, int color_type)
Definition: pngwutil.c:1263
png_size_t FAR * png_size_tp
Definition: pngconf.h:540
#define PNG_FILTER_SUB
Definition: png.h:1615
void png_warning_parameter(png_warning_parameters p, int number, png_const_charp string)
Definition: pngerror.c:244
#define png_bKGD
Definition: pngpriv.h:605
void PNGAPI png_save_int_32(png_bytep buf, png_int_32 i)
Definition: pngwutil.c:40
#define NULL
Definition: ftobjs.h:61
#define Z_STREAM_ERROR
Definition: zlib.h:136
Byte FAR Bytef
Definition: zconf.h:228
#define png_tRNS
Definition: pngpriv.h:621
#define PNG_INTERLACE_NONE
Definition: png.h:764
#define png_sRGB
Definition: pngpriv.h:617
#define PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS
Definition: pngpriv.h:499
int entry_size
Definition: pngrutil.c:1377
#define PNG_COLOR_TYPE_RGB
Definition: png.h:747
#define PNG_COLOR_TYPE_GRAY_ALPHA
Definition: png.h:749
#define png_iCCP
Definition: pngpriv.h:609
void png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma)
Definition: pngwutil.c:1061
#define PNG_INTERLACE_ADAM7
Definition: png.h:765
char FAR * png_charp
Definition: pngconf.h:536
#define PNG_COLOR_TYPE_PALETTE
Definition: png.h:746
#define png_IEND
Definition: pngpriv.h:603
#define PNG_FILTER_VALUE_PAETH
Definition: png.h:1629
png_sPLT_entryp pp
Definition: pngrutil.c:1375
png_error(png_ptr,"Missing IHDR before iCCP")
#define PNG_IO_CHUNK_DATA
Definition: png.h:2478
int png_int_32
Definition: pngconf.h:442
int32_t j
Definition: e_log.c:102
#define Z_BINARY
Definition: zlib.h:156
void png_write_zTXt(png_structp png_ptr, png_const_charp key, png_const_charp text, png_size_t text_len, int compression)
Definition: pngwutil.c:1687
#define png_sPLT
Definition: pngpriv.h:616
void PNGAPI png_write_chunk(png_structp png_ptr, png_const_bytep chunk_string, png_const_bytep data, png_size_t length)
Definition: pngwutil.c:210
EGLSurface EGLint EGLint EGLint EGLint height
Definition: eglext.h:293
unsigned int png_uint_32
Definition: pngconf.h:441
#define png_debug(l, m)
Definition: pngdebug.h:149
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:8736
#define Z_FILTERED
Definition: zlib.h:151
#define PNG_COLOR_TYPE_RGB_ALPHA
Definition: png.h:748
PNG_CONST png_color FAR * png_const_colorp
Definition: png.h:558
#define PNG_HAVE_PLTE
Definition: png.h:713
#define png_memset
Definition: pngpriv.h:354
EGLImageKHR EGLint * name
Definition: eglext.h:284
static int comp(const void *a, const void *b)
Definition: lsp.c:298
PNG_CONST char FAR * png_const_charp
Definition: pngconf.h:537
GLclampf green
Definition: glew.h:1506
#define PNG_HIMASK
Definition: pngwutil.c:2423
int ZEXPORT deflateEnd(z_streamp strm)
Definition: deflate.c:895
#define PNG_OFFSET_LAST
Definition: png.h:771
void png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, int unit_type)
Definition: pngwutil.c:1842
Byte FAR * voidpf
Definition: zconf.h:239
return Display return Display Bool Bool int d
Definition: SDL_x11sym.h:30
void png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
Definition: pngwutil.c:965
#define PNG_NUMBER_FORMAT_02x
Definition: pngpriv.h:1409
PNG_CONST png_color_8 FAR * png_const_color_8p
Definition: png.h:582
if(!yyg->yy_init)
#define Z_DEFAULT_COMPRESSION
Definition: zlib.h:148
unsigned int uInt
Definition: zconf.h:221
#define PNG_sRGB_INTENT_LAST
Definition: png.h:796
#define PNG_WARNING_PARAMETERS(p)
Definition: pngpriv.h:221
#define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL
Definition: pngpriv.h:474
ret
Definition: glew_str_glx.c:2
#define PNG_FLAG_ZTXT_CUSTOM_STRATEGY
Definition: pngpriv.h:496
void png_write_pCAL(png_structp 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:1862
size_t png_safecat(png_charp buffer, size_t bufsize, size_t pos, png_const_charp string)
Definition: pngerror.c:110
png_size_t png_alloc_size_t
Definition: pngconf.h:591
#define Z_OK
Definition: zlib.h:132
void png_write_data(png_structp png_ptr, png_const_bytep data, png_size_t length)
Definition: pngwio.c:33
GLenum GLvoid ** params
Definition: gl2ext.h:806
void png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit, int unit_type)
Definition: pngwutil.c:1952
#define PNG_HAVE_IDAT
Definition: pngpriv.h:417
const GLubyte GLuint red
Definition: SDL_glfuncs.h:57
#define PNG_MNG_FEATURES_SUPPORTED
Definition: pnglibconf.h:65
png_byte FAR *FAR * png_bytepp
Definition: pngconf.h:553
#define PNG_HAVE_IHDR
Definition: png.h:712
#define png_IHDR
Definition: pngpriv.h:601
#define PNG_LOMASK
Definition: pngwutil.c:2422
#define PNG_TEXT_COMPRESSION_NONE
Definition: png.h:661
GLenum GLenum GLvoid * row
Definition: glew.h:4447
#define PNGAPI
Definition: pngconf.h:260
png_struct FAR * png_structp
Definition: png.h:849
void png_write_tIME(png_structp png_ptr, png_const_timep mod_time)
Definition: pngwutil.c:1976
void png_write_cHRM_fixed(png_structp png_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: pngwutil.c:1322
void png_write_tEXt(png_structp png_ptr, png_const_charp key, png_const_charp text, png_size_t text_len)
Definition: pngwutil.c:1646
static void png_write_complete_chunk(png_structp png_ptr, png_uint_32 chunk_name, png_const_bytep data, png_size_t length)
Definition: pngwutil.c:193
void png_warning_parameter_signed(png_warning_parameters p, int number, int format, png_int_32 value)
Definition: pngerror.c:260
const GLdouble * v
Definition: glew.h:1377
#define PNG_COLOR_MASK_COLOR
Definition: png.h:741
static void png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row, png_size_t row_bytes)
Definition: pngwutil.c:3096
#define PNG_ITXT_COMPRESSION_NONE
Definition: png.h:663
#define png_tEXt
Definition: pngpriv.h:619
#define PNG_CONST
Definition: pngconf.h:426
int
Definition: SDL_systhread.c:37
GLsizei GLsizei * length
Definition: gl2ext.h:792
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
#define PNG_CHUNK_FROM_STRING(s)
Definition: pngpriv.h:627
void PNGAPI png_write_flush(png_structp png_ptr)
Definition: pngwrite.c:823
new_palette entries
Definition: pngrutil.c:1486
EGLSurface EGLint EGLint EGLint width
Definition: eglext.h:293
void png_write_find_filter(png_structp png_ptr, png_row_infop row_info)
Definition: pngwutil.c:2425
#define Z_FINISH
Definition: zlib.h:129
unsigned char png_byte
Definition: pngconf.h:449
unsigned short png_uint_16
Definition: pngconf.h:447
#define PNG_FILTER_VALUE_SUB
Definition: png.h:1626
void png_write_IHDR(png_structp 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:676
#define PNG_COLOR_TYPE_GRAY
Definition: png.h:745
GLfloat GLfloat p
Definition: glew.h:14938
png_sPLT_entry FAR * png_sPLT_entryp
Definition: png.h:597
void PNGAPI png_warning(png_structp png_ptr, png_const_charp warning_message)
Definition: pngerror.c:214
const GLfloat * c
Definition: glew.h:14913
int png_check_cHRM_fixed(png_structp png_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: png.c:780
#define PNG_NUMBER_FORMAT_d
Definition: pngpriv.h:1406
#define PNG_ALL_FILTERS
Definition: png.h:1619
#define PNG_IO_CHUNK_HDR
Definition: png.h:2477
#define PNG_FLAG_ZTXT_CUSTOM_METHOD
Definition: pngpriv.h:500
#define PNG_UINT_32_MAX
Definition: png.h:727
#define PNG_IO_SIGNATURE
Definition: png.h:2476
PNG_CONST png_byte FAR * png_const_bytep
Definition: pngconf.h:527
#define png_debug1(l, m, p1)
Definition: pngdebug.h:152
#define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
Definition: pnglibconf.h:149
#define PNG_FLAG_ZTXT_CUSTOM_LEVEL
Definition: pngpriv.h:497
#define Z_DEFAULT_STRATEGY
Definition: zlib.h:153
#define png_IDAT
Definition: pngpriv.h:602
#define PNG_FILTER_UP
Definition: png.h:1616
GLclampf GLclampf GLclampf alpha
Definition: glew.h:1506
#define png_strlen
Definition: pngpriv.h:351
#define PNG_FILTER_AVG
Definition: png.h:1617
#define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS
Definition: pngpriv.h:475
#define PNG_EQUATION_LAST
Definition: png.h:778
#define PNG_RESOLUTION_LAST
Definition: png.h:789
compression_type
Definition: pngrutil.c:1309
static void png_zlib_release(png_structp png_ptr)
Definition: pngwutil.c:308
PNG_CONST png_color_16 FAR * png_const_color_16p
Definition: png.h:570
#define PNG_IO_CHUNK_CRC
Definition: png.h:2479
void png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type, png_const_charp profile, int profile_len)
Definition: pngwutil.c:1094
#define png_oFFs
Definition: pngpriv.h:611
#define PNG_FILTER_VALUE_UP
Definition: png.h:1627
int ZEXPORT deflate(z_streamp strm, int flush)
Definition: deflate.c:582
void PNGAPI png_save_uint_32(png_bytep buf, png_uint_32 i)
Definition: pngwutil.c:24
#define PNG_FLAG_ZLIB_CUSTOM_METHOD
Definition: pngpriv.h:476
png_size_t png_check_keyword(png_structp png_ptr, png_const_charp key, png_charpp new_key)
Definition: pngwutil.c:1524
#define Z_VERSION_ERROR
Definition: zlib.h:140
#define png_gAMA
Definition: pngpriv.h:607
#define png_pCAL
Definition: pngpriv.h:612
#define PNG_FLAG_MNG_FILTER_64
Definition: png.h:939
#define PNG_IO_WRITING
Definition: png.h:2475
#define PNG_INTERLACE
Definition: pngpriv.h:432
png_byte FAR * png_bytep
Definition: pngconf.h:526
#define PNG_FLAG_ZLIB_CUSTOM_LEVEL
Definition: pngpriv.h:473
static void png_write_compressed_data_out(png_structp png_ptr, compression_state *comp)
Definition: pngwutil.c:572
void PNGAPI png_write_chunk_end(png_structp png_ptr)
Definition: pngwutil.c:164
#define PNG_FILTER_TYPE_BASE
Definition: png.h:759
#define Z_NO_FLUSH
Definition: zlib.h:125
#define Z_STREAM_END
Definition: zlib.h:133
GLenum GLenum GLenum input
Definition: glew.h:12631
EGLSurface EGLint void ** value
Definition: eglext.h:301
#define png_cHRM
Definition: pngpriv.h:606
#define PNG_COLOR_MASK_ALPHA
Definition: png.h:742
png_row_info FAR * png_row_infop
Definition: png.h:840
#define PNG_COMPRESSION_TYPE_BASE
Definition: png.h:755
void png_write_sRGB(png_structp png_ptr, int srgb_intent)
Definition: pngwutil.c:1076
GLenum GLuint GLsizei const GLchar * buf
Definition: glew.h:2539
#define PNG_HISHIFT
Definition: pngwutil.c:2421
void PNGAPI png_write_sig(png_structp png_ptr)
Definition: pngwutil.c:68
#define PNG_HAVE_IEND
Definition: pngpriv.h:419
#define PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL
Definition: pngpriv.h:498
void png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha, png_const_color_16p tran, int num_trans, int color_type)
Definition: pngwutil.c:1357
void png_write_IEND(png_structp png_ptr)
Definition: pngwutil.c:1050
void png_write_iTXt(png_structp png_ptr, int compression, png_const_charp key, png_const_charp lang, png_const_charp lang_key, png_const_charp text)
Definition: pngwutil.c:1749
png_int_32 png_fixed_point
Definition: pngconf.h:521
char FAR *FAR * png_charpp
Definition: pngconf.h:559
GLdouble GLdouble GLdouble b
Definition: glew.h:8383
#define PNG_FILTER_VALUE_NONE
Definition: png.h:1625
void png_calculate_crc(png_structp png_ptr, png_const_bytep ptr, png_size_t length)
Definition: png.c:120
static void png_zlib_claim(png_structp png_ptr, png_uint_32 state)
Definition: pngwutil.c:219
size_t png_size_t
Definition: pngconf.h:454
void PNGAPI png_save_uint_16(png_bytep buf, unsigned int i)
Definition: pngwutil.c:54
#define PNG_INTRAPIXEL_DIFFERENCING
Definition: png.h:760
#define PNG_FLAG_MNG_EMPTY_PLTE
Definition: png.h:938
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy)
Definition: zlib.h:819
void png_write_hIST(png_structp png_ptr, png_const_uint_16p hist, int num_hist)
Definition: pngwutil.c:1483
#define Z_MEM_ERROR
Definition: zlib.h:138
PNG_CONST png_sPLT_t FAR * png_const_sPLT_tp
Definition: png.h:614
#define png_sBIT
Definition: pngpriv.h:615
#define png_hIST
Definition: pngpriv.h:608
int ZEXPORT deflateReset(z_streamp strm)
Definition: deflate.c:353
void png_write_finish_row(png_structp png_ptr)
Definition: pngwutil.c:2113
int i
Definition: pngrutil.c:1377
#define PNG_FILTER_NONE
Definition: png.h:1614
#define PNG_MAXSUM
Definition: pngwutil.c:2420
#define png_pHYs
Definition: pngpriv.h:614
void PNGAPI png_free(png_structp png_ptr, png_voidp ptr)
Definition: pngmem.c:578
GLclampf GLclampf blue
Definition: glew.h:1506
#define PNG_COST_SHIFT
Definition: pnglibconf.h:26
#define PNG_ROWBYTES(pixel_bits, width)
Definition: pngpriv.h:532
#define png_tIME
Definition: pngpriv.h:620
#define PNG_HAVE_PNG_SIGNATURE
Definition: pngpriv.h:427
GLfloat units
Definition: glew.h:12417
void png_write_sCAL_s(png_structp png_ptr, int unit, png_const_charp width, png_const_charp height)
Definition: pngwutil.c:1922
void png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
Definition: pngwutil.c:2241
static int png_text_compress(png_structp png_ptr, png_const_charp text, png_size_t text_len, int compression, compression_state *comp)
Definition: pngwutil.c:377
void png_formatted_warning(png_structp png_ptr, png_warning_parameters p, png_const_charp message)
Definition: pngerror.c:281
PNG_CONST png_uint_16 FAR * png_const_uint_16p
Definition: pngconf.h:533
void png_reset_crc(png_structp png_ptr)
Definition: png.c:108
#define PNG_CSTRING_FROM_CHUNK(s, c)
Definition: pngpriv.h:639
void png_warning_parameter_unsigned(png_warning_parameters p, int number, int format, png_alloc_size_t value)
Definition: pngerror.c:252
static double cp
Definition: e_pow.c:96
#define png_zTXt
Definition: pngpriv.h:622
void PNGAPI png_write_chunk_data(png_structp png_ptr, png_const_bytep data, png_size_t length)
Definition: pngwutil.c:144
#define png_sizeof(x)
Definition: pngconf.h:456
#define ZLIB_IO_MAX
Definition: pngpriv.h:522
#define png_debug2(l, m, p1, p2)
Definition: pngdebug.h:155
void png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type)
Definition: pngwutil.c:1421
GLsizei size
Definition: gl2ext.h:1467
#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY
Definition: pngpriv.h:472