[master] Imported from libpng-1.4.0.tar

This commit is contained in:
Glenn Randers-Pehrson
2010-01-02 23:05:45 -06:00
parent 115817d118
commit 7e3a82cd9c
130 changed files with 4698 additions and 8343 deletions

View File

@@ -1,8 +1,8 @@
/* pngwutil.c - utilities to write a PNG file
*
* Last changed in libpng 1.2.41 [December 3, 2009]
* Copyright (c) 1998-2009 Glenn Randers-Pehrson
* Last changed in libpng 1.4.0 [January 3, 2010]
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
@@ -11,10 +11,10 @@
* and license in png.h
*/
#define PNG_INTERNAL
#define PNG_NO_PEDANTIC_WARNINGS
#include "png.h"
#ifdef PNG_WRITE_SUPPORTED
#include "pngpriv.h"
/* Place a 32-bit number into a buffer in PNG byte order. We work
* with unsigned numbers for convenience, although one supported
@@ -29,6 +29,7 @@ png_save_uint_32(png_bytep buf, png_uint_32 i)
buf[3] = (png_byte)(i & 0xff);
}
#ifdef PNG_SAVE_INT_32_SUPPORTED
/* The png_save_int_32 function assumes integers are stored in two's
* complement format. If this isn't the case, then this routine needs to
* be modified to write data in two's complement format.
@@ -41,6 +42,7 @@ png_save_int_32(png_bytep buf, png_int_32 i)
buf[2] = (png_byte)((i >> 8) & 0xff);
buf[3] = (png_byte)(i & 0xff);
}
#endif
/* Place a 16-bit number into a buffer in PNG byte order.
* The parameter is declared unsigned int, not png_uint_16,
@@ -64,6 +66,11 @@ png_write_sig(png_structp png_ptr)
{
png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
#ifdef PNG_IO_STATE_SUPPORTED
/* Inform the I/O callback that the signature is being written */
png_ptr->io_state = PNG_IO_WRITING | PNG_IO_SIGNATURE;
#endif
/* Write the rest of the 8 byte signature */
png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
(png_size_t)(8 - png_ptr->sig_bytes));
@@ -107,6 +114,12 @@ png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name,
if (png_ptr == NULL)
return;
#ifdef PNG_IO_STATE_SUPPORTED
/* Inform the I/O callback that the chunk header is being written.
* PNG_IO_CHUNK_HDR requires a single I/O call.
*/
png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR;
#endif
/* Write the length and the chunk name */
png_save_uint_32(buf, length);
@@ -116,7 +129,14 @@ png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name,
png_memcpy(png_ptr->chunk_name, chunk_name, 4);
/* Reset the crc and run it over the chunk name */
png_reset_crc(png_ptr);
png_calculate_crc(png_ptr, chunk_name, (png_size_t)4);
png_calculate_crc(png_ptr, chunk_name, 4);
#ifdef PNG_IO_STATE_SUPPORTED
/* Inform the I/O callback that chunk data will (possibly) be written.
* PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls.
*/
png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA;
#endif
}
/* Write the data of a PNG chunk started with png_write_chunk_start().
@@ -148,6 +168,13 @@ png_write_chunk_end(png_structp png_ptr)
if (png_ptr == NULL) return;
#ifdef PNG_IO_STATE_SUPPORTED
/* Inform the I/O callback that the chunk CRC is being written.
* PNG_IO_CHUNK_CRC requires a single I/O function call.
*/
png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC;
#endif
/* Write the crc in a single operation */
png_save_uint_32(buf, png_ptr->crc);
@@ -194,7 +221,7 @@ png_text_compress(png_structp png_ptr,
if (compression >= PNG_TEXT_COMPRESSION_LAST)
{
#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
#ifdef PNG_STDIO_SUPPORTED
char msg[50];
png_snprintf(msg, 50, "Unknown compression type %d", compression);
png_warning(png_ptr, msg);
@@ -253,7 +280,7 @@ png_text_compress(png_structp png_ptr,
old_ptr = comp->output_ptr;
comp->output_ptr = (png_charpp)png_malloc(png_ptr,
(png_uint_32)
(png_alloc_size_t)
(comp->max_output_ptr * png_sizeof(png_charpp)));
png_memcpy(comp->output_ptr, old_ptr, old_max
* png_sizeof(png_charp));
@@ -261,14 +288,14 @@ png_text_compress(png_structp png_ptr,
}
else
comp->output_ptr = (png_charpp)png_malloc(png_ptr,
(png_uint_32)
(png_alloc_size_t)
(comp->max_output_ptr * png_sizeof(png_charp)));
}
/* Save the data */
comp->output_ptr[comp->num_output_ptr] =
(png_charp)png_malloc(png_ptr,
(png_uint_32)png_ptr->zbuf_size);
(png_alloc_size_t)png_ptr->zbuf_size);
png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
png_ptr->zbuf_size);
comp->num_output_ptr++;
@@ -305,7 +332,7 @@ png_text_compress(png_structp png_ptr,
old_ptr = comp->output_ptr;
/* This could be optimized to realloc() */
comp->output_ptr = (png_charpp)png_malloc(png_ptr,
(png_uint_32)(comp->max_output_ptr *
(png_alloc_size_t)(comp->max_output_ptr *
png_sizeof(png_charp)));
png_memcpy(comp->output_ptr, old_ptr,
old_max * png_sizeof(png_charp));
@@ -313,14 +340,14 @@ png_text_compress(png_structp png_ptr,
}
else
comp->output_ptr = (png_charpp)png_malloc(png_ptr,
(png_uint_32)(comp->max_output_ptr *
(png_alloc_size_t)(comp->max_output_ptr *
png_sizeof(png_charp)));
}
/* Save the data */
comp->output_ptr[comp->num_output_ptr] =
(png_charp)png_malloc(png_ptr,
(png_uint_32)png_ptr->zbuf_size);
(png_alloc_size_t)png_ptr->zbuf_size);
png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
png_ptr->zbuf_size);
comp->num_output_ptr++;
@@ -368,11 +395,9 @@ png_write_compressed_data_out(png_structp png_ptr, compression_state *comp)
png_write_chunk_data(png_ptr, (png_bytep)comp->output_ptr[i],
(png_size_t)png_ptr->zbuf_size);
png_free(png_ptr, comp->output_ptr[i]);
comp->output_ptr[i]=NULL;
}
if (comp->max_output_ptr != 0)
png_free(png_ptr, comp->output_ptr);
comp->output_ptr=NULL;
/* Write anything left in zbuf */
if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)
png_write_chunk_data(png_ptr, png_ptr->zbuf,
@@ -393,9 +418,7 @@ 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)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_IHDR;
#endif
int ret;
png_byte buf[13]; /* Buffer to store the IHDR info */
@@ -571,9 +594,7 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
void /* PRIVATE */
png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_PLTE;
#endif
png_uint_32 i;
png_colorp pal_ptr;
png_byte buf[3];
@@ -636,9 +657,7 @@ png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal)
void /* PRIVATE */
png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_IDAT;
#endif
png_debug(1, "in png_write_IDAT");
@@ -691,13 +710,11 @@ png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
void /* PRIVATE */
png_write_IEND(png_structp png_ptr)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_IEND;
#endif
png_debug(1, "in png_write_IEND");
png_write_chunk(png_ptr, (png_bytep)png_IEND, png_bytep_NULL,
png_write_chunk(png_ptr, (png_bytep)png_IEND, NULL,
(png_size_t)0);
png_ptr->mode |= PNG_HAVE_IEND;
}
@@ -708,9 +725,7 @@ png_write_IEND(png_structp png_ptr)
void /* PRIVATE */
png_write_gAMA(png_structp png_ptr, double file_gamma)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_gAMA;
#endif
png_uint_32 igamma;
png_byte buf[4];
@@ -726,9 +741,7 @@ png_write_gAMA(png_structp png_ptr, double file_gamma)
void /* PRIVATE */
png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_gAMA;
#endif
png_byte buf[4];
png_debug(1, "in png_write_gAMA");
@@ -745,9 +758,7 @@ png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma)
void /* PRIVATE */
png_write_sRGB(png_structp png_ptr, int srgb_intent)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_sRGB;
#endif
png_byte buf[1];
png_debug(1, "in png_write_sRGB");
@@ -766,9 +777,7 @@ void /* PRIVATE */
png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type,
png_charp profile, int profile_len)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_iCCP;
#endif
png_size_t name_len;
png_charp new_name;
compression_state comp;
@@ -846,14 +855,12 @@ png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type,
void /* PRIVATE */
png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_sPLT;
#endif
png_size_t name_len;
png_charp new_name;
png_byte entrybuf[10];
int entry_size = (spalette->depth == 8 ? 6 : 10);
int palette_size = entry_size * spalette->nentries;
png_size_t entry_size = (spalette->depth == 8 ? 6 : 10);
png_size_t palette_size = entry_size * spalette->nentries;
png_sPLT_entryp ep;
#ifndef PNG_POINTER_INDEXING_SUPPORTED
int i;
@@ -927,9 +934,7 @@ png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette)
void /* PRIVATE */
png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_sBIT;
#endif
png_byte buf[4];
png_size_t size;
@@ -987,9 +992,7 @@ png_write_cHRM(png_structp png_ptr, double white_x, double white_y,
double red_x, double red_y, double green_x, double green_y,
double blue_x, double blue_y)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_cHRM;
#endif
png_byte buf[32];
png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y,
@@ -1036,9 +1039,7 @@ png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x,
png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x,
png_fixed_point blue_y)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_cHRM;
#endif
png_byte buf[32];
png_debug(1, "in png_write_cHRM");
@@ -1070,12 +1071,10 @@ png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x,
#ifdef PNG_WRITE_tRNS_SUPPORTED
/* Write the tRNS chunk */
void /* PRIVATE */
png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran,
png_write_tRNS(png_structp png_ptr, png_bytep trans_alpha, png_color_16p tran,
int num_trans, int color_type)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_tRNS;
#endif
png_byte buf[6];
png_debug(1, "in png_write_tRNS");
@@ -1088,7 +1087,7 @@ png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran,
return;
}
/* Write the chunk out as it is */
png_write_chunk(png_ptr, (png_bytep)png_tRNS, trans,
png_write_chunk(png_ptr, (png_bytep)png_tRNS, trans_alpha,
(png_size_t)num_trans);
}
else if (color_type == PNG_COLOR_TYPE_GRAY)
@@ -1129,9 +1128,7 @@ png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran,
void /* PRIVATE */
png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_bKGD;
#endif
png_byte buf[6];
png_debug(1, "in png_write_bKGD");
@@ -1183,9 +1180,7 @@ png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type)
void /* PRIVATE */
png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_hIST;
#endif
int i;
png_byte buf[3];
@@ -1255,7 +1250,7 @@ png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key)
if ((png_byte)*kp < 0x20 ||
((png_byte)*kp > 0x7E && (png_byte)*kp < 0xA1))
{
#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
#ifdef PNG_STDIO_SUPPORTED
char msg[40];
png_snprintf(msg, 40,
@@ -1327,7 +1322,6 @@ png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key)
if (key_len == 0)
{
png_free(png_ptr, *new_key);
*new_key=NULL;
png_warning(png_ptr, "Zero length keyword");
}
@@ -1348,9 +1342,7 @@ void /* PRIVATE */
png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text,
png_size_t text_len)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_tEXt;
#endif
png_size_t key_len;
png_charp new_key;
@@ -1389,9 +1381,7 @@ void /* PRIVATE */
png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text,
png_size_t text_len, int compression)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_zTXt;
#endif
png_size_t key_len;
char buf[1];
png_charp new_key;
@@ -1449,9 +1439,7 @@ void /* PRIVATE */
png_write_iTXt(png_structp png_ptr, int compression, png_charp key,
png_charp lang, png_charp lang_key, png_charp text)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_iTXt;
#endif
png_size_t lang_len, key_len, lang_key_len, text_len;
png_charp new_lang;
png_charp new_key = NULL;
@@ -1538,9 +1526,7 @@ void /* PRIVATE */
png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
int unit_type)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_oFFs;
#endif
png_byte buf[9];
png_debug(1, "in png_write_oFFs");
@@ -1561,9 +1547,7 @@ void /* PRIVATE */
png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
png_int_32 X1, int type, int nparams, png_charp units, png_charpp params)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_pCAL;
#endif
png_size_t purpose_len, units_len, total_len;
png_uint_32p params_len;
png_byte buf[10];
@@ -1582,7 +1566,7 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
total_len = purpose_len + units_len + 10;
params_len = (png_uint_32p)png_malloc(png_ptr,
(png_uint_32)(nparams * png_sizeof(png_uint_32)));
(png_alloc_size_t)(nparams * png_sizeof(png_uint_32)));
/* Find the length of each parameter, making sure we don't count the
null terminator for the last parameter. */
@@ -1624,36 +1608,17 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
void /* PRIVATE */
png_write_sCAL(png_structp png_ptr, int unit, double width, double height)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_sCAL;
#endif
char buf[64];
png_size_t total_len;
png_debug(1, "in png_write_sCAL");
buf[0] = (char)unit;
#ifdef _WIN32_WCE
/* sprintf() function is not supported on WindowsCE */
{
wchar_t wc_buf[32];
size_t wc_len;
swprintf(wc_buf, TEXT("%12.12e"), width);
wc_len = wcslen(wc_buf);
WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + 1, wc_len, NULL, NULL);
total_len = wc_len + 2;
swprintf(wc_buf, TEXT("%12.12e"), height);
wc_len = wcslen(wc_buf);
WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + total_len, wc_len,
NULL, NULL);
total_len += wc_len;
}
#else
png_snprintf(buf + 1, 63, "%12.12e", width);
total_len = 1 + png_strlen(buf + 1) + 1;
png_snprintf(buf + total_len, 64-total_len, "%12.12e", height);
total_len += png_strlen(buf + total_len);
#endif
png_debug1(3, "sCAL total length = %u", (unsigned int)total_len);
png_write_chunk(png_ptr, (png_bytep)png_sCAL, (png_bytep)buf, total_len);
@@ -1664,9 +1629,7 @@ void /* PRIVATE */
png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width,
png_charp height)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_sCAL;
#endif
png_byte buf[64];
png_size_t wlen, hlen, total_len;
@@ -1699,9 +1662,7 @@ png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
png_uint_32 y_pixels_per_unit,
int unit_type)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_pHYs;
#endif
png_byte buf[9];
png_debug(1, "in png_write_pHYs");
@@ -1724,9 +1685,7 @@ png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
void /* PRIVATE */
png_write_tIME(png_structp png_ptr, png_timep mod_time)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_tIME;
#endif
png_byte buf[7];
png_debug(1, "in png_write_tIME");
@@ -1779,7 +1738,7 @@ png_write_start_row(png_structp png_ptr)
/* Set up row buffer */
png_ptr->row_buf = (png_bytep)png_malloc(png_ptr,
(png_uint_32)buf_size);
(png_alloc_size_t)buf_size);
png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
#ifdef PNG_WRITE_FILTER_SUPPORTED
@@ -1787,7 +1746,7 @@ png_write_start_row(png_structp png_ptr)
if (png_ptr->do_filter & PNG_FILTER_SUB)
{
png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
(png_uint_32)(png_ptr->rowbytes + 1));
(png_alloc_size_t)(png_ptr->rowbytes + 1));
png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
}
@@ -1796,26 +1755,26 @@ png_write_start_row(png_structp png_ptr)
{
/* Set up previous row buffer */
png_ptr->prev_row = (png_bytep)png_calloc(png_ptr,
(png_uint_32)buf_size);
(png_alloc_size_t)buf_size);
if (png_ptr->do_filter & PNG_FILTER_UP)
{
png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
(png_uint_32)(png_ptr->rowbytes + 1));
(png_size_t)(png_ptr->rowbytes + 1));
png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
}
if (png_ptr->do_filter & PNG_FILTER_AVG)
{
png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
(png_uint_32)(png_ptr->rowbytes + 1));
(png_alloc_size_t)(png_ptr->rowbytes + 1));
png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
}
if (png_ptr->do_filter & PNG_FILTER_PAETH)
{
png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
(png_uint_32)(png_ptr->rowbytes + 1));
(png_size_t)(png_ptr->rowbytes + 1));
png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
}
}
@@ -1981,11 +1940,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
png_debug(1, "in png_do_write_interlace");
/* We don't have to do anything on the last pass (6) */
#ifdef PNG_USELESS_TESTS_SUPPORTED
if (row != NULL && row_info != NULL && pass < 6)
#else
if (pass < 6)
#endif
{
/* Each pixel depth is handled separately */
switch (row_info->pixel_depth)