+ if (png_ptr == NULL)
+ return;
+
+ /* On 64 bit architectures 'length' may not fit in a png_uint_32. */
+ if (length > PNG_UINT_32_MAX)
+ png_error(png_ptr, "length exceeds PNG maxima");
+
+ png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length);
+ png_write_chunk_data(png_ptr, data, length);
+ png_write_chunk_end(png_ptr);
+}
+
+/* This is the API that calls the internal function above. */
+void PNGAPI
+png_write_chunk(png_structp png_ptr, png_const_bytep chunk_string,
+ png_const_bytep data, png_size_t length)
+{
+ png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data,
+ length);
+}
+
+/* Initialize the compressor for the appropriate type of compression. */
+static void
+png_zlib_claim(png_structp png_ptr, png_uint_32 state)
+{
+ if (!(png_ptr->zlib_state & PNG_ZLIB_IN_USE))
+ {
+ /* If already initialized for 'state' do not re-init. */
+ if (png_ptr->zlib_state != state)
+ {
+ int ret = Z_OK;
+ png_const_charp who = "-";
+
+ /* If actually initialized for another state do a deflateEnd. */
+ if (png_ptr->zlib_state != PNG_ZLIB_UNINITIALIZED)
+ {
+ ret = deflateEnd(&png_ptr->zstream);
+ who = "end";
+ png_ptr->zlib_state = PNG_ZLIB_UNINITIALIZED;
+ }
+
+ /* zlib itself detects an incomplete state on deflateEnd */
+ if (ret == Z_OK) switch (state)
+ {
+# ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
+ case PNG_ZLIB_FOR_TEXT:
+ ret = deflateInit2(&png_ptr->zstream,
+ png_ptr->zlib_text_level, png_ptr->zlib_text_method,
+ png_ptr->zlib_text_window_bits,
+ png_ptr->zlib_text_mem_level, png_ptr->zlib_text_strategy);
+ who = "text";
+ break;
+# endif
+
+ case PNG_ZLIB_FOR_IDAT:
+ ret = deflateInit2(&png_ptr->zstream, png_ptr->zlib_level,
+ png_ptr->zlib_method, png_ptr->zlib_window_bits,
+ png_ptr->zlib_mem_level, png_ptr->zlib_strategy);
+ who = "IDAT";
+ break;
+
+ default:
+ png_error(png_ptr, "invalid zlib state");
+ }
+
+ if (ret == Z_OK)
+ png_ptr->zlib_state = state;
+
+ else /* an error in deflateEnd or deflateInit2 */
+ {
+ size_t pos = 0;
+ char msg[64];
+
+ pos = png_safecat(msg, sizeof msg, pos,
+ "zlib failed to initialize compressor (");
+ pos = png_safecat(msg, sizeof msg, pos, who);
+
+ switch (ret)
+ {
+ case Z_VERSION_ERROR:
+ pos = png_safecat(msg, sizeof msg, pos, ") version error");
+ break;
+
+ case Z_STREAM_ERROR:
+ pos = png_safecat(msg, sizeof msg, pos, ") stream error");
+ break;
+
+ case Z_MEM_ERROR:
+ pos = png_safecat(msg, sizeof msg, pos, ") memory error");
+ break;
+
+ default:
+ pos = png_safecat(msg, sizeof msg, pos, ") unknown error");
+ break;
+ }
+
+ png_error(png_ptr, msg);
+ }
+ }
+
+ /* Here on success, claim the zstream: */
+ png_ptr->zlib_state |= PNG_ZLIB_IN_USE;
+ }
+
+ else
+ png_error(png_ptr, "zstream already in use (internal error)");