Updated internal PNG library code to latest released version (1.5.2).

git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2218 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2011-04-22 00:04:04 +00:00
parent 138c03090f
commit 94c34ddb72
24 changed files with 8769 additions and 8826 deletions

View File

@ -1,838 +0,0 @@
#if 0 /* in case someone actually tries to compile this */
/* example.c - an example of using libpng
* Last changed in libpng 1.4.2 [May 6, 2010]
* This file has been placed in the public domain by the authors.
* Maintained 1998-2010 Glenn Randers-Pehrson
* Maintained 1996, 1997 Andreas Dilger)
* Written 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*/
/* This is an example of how to use libpng to read and write PNG files.
* The file libpng.txt is much more verbose then this. If you have not
* read it, do so first. This was designed to be a starting point of an
* implementation. This is not officially part of libpng, is hereby placed
* in the public domain, and therefore does not require a copyright notice.
*
* This file does not currently compile, because it is missing certain
* parts, like allocating memory to hold an image. You will have to
* supply these parts to get it to compile. For an example of a minimal
* working PNG reader/writer, see pngtest.c, included in this distribution;
* see also the programs in the contrib directory.
*/
#include "png.h"
/* The png_jmpbuf() macro, used in error handling, became available in
* libpng version 1.0.6. If you want to be able to run your code with older
* versions of libpng, you must define the macro yourself (but only if it
* is not already defined by libpng!).
*/
#ifndef png_jmpbuf
# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
#endif
/* Check to see if a file is a PNG file using png_sig_cmp(). png_sig_cmp()
* returns zero if the image is a PNG and nonzero if it isn't a PNG.
*
* The function check_if_png() shown here, but not used, returns nonzero (true)
* if the file can be opened and is a PNG, 0 (false) otherwise.
*
* If this call is successful, and you are going to keep the file open,
* you should call png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); once
* you have created the png_ptr, so that libpng knows your application
* has read that many bytes from the start of the file. Make sure you
* don't call png_set_sig_bytes() with more than 8 bytes read or give it
* an incorrect number of bytes read, or you will either have read too
* many bytes (your fault), or you are telling libpng to read the wrong
* number of magic bytes (also your fault).
*
* Many applications already read the first 2 or 4 bytes from the start
* of the image to determine the file type, so it would be easiest just
* to pass the bytes to png_sig_cmp() or even skip that if you know
* you have a PNG file, and call png_set_sig_bytes().
*/
#define PNG_BYTES_TO_CHECK 4
int check_if_png(char *file_name, FILE **fp)
{
char buf[PNG_BYTES_TO_CHECK];
/* Open the prospective PNG file. */
if ((*fp = fopen(file_name, "rb")) == NULL)
return 0;
/* Read in some of the signature bytes */
if (fread(buf, 1, PNG_BYTES_TO_CHECK, *fp) != PNG_BYTES_TO_CHECK)
return 0;
/* Compare the first PNG_BYTES_TO_CHECK bytes of the signature.
Return nonzero (true) if they match */
return(!png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK));
}
/* Read a PNG file. You may want to return an error code if the read
* fails (depending upon the failure). There are two "prototypes" given
* here - one where we are given the filename, and we need to open the
* file, and the other where we are given an open file (possibly with
* some or all of the magic bytes read - see comments above).
*/
#ifdef open_file /* prototype 1 */
void read_png(char *file_name) /* We need to open the file */
{
png_structp png_ptr;
png_infop info_ptr;
unsigned int sig_read = 0;
png_uint_32 width, height;
int bit_depth, color_type, interlace_type;
FILE *fp;
if ((fp = fopen(file_name, "rb")) == NULL)
return (ERROR);
#else no_open_file /* prototype 2 */
void read_png(FILE *fp, unsigned int sig_read) /* File is already open */
{
png_structp png_ptr;
png_infop info_ptr;
png_uint_32 width, height;
int bit_depth, color_type, interlace_type;
#endif no_open_file /* Only use one prototype! */
/* Create and initialize the png_struct with the desired error handler
* functions. If you want to use the default stderr and longjump method,
* you can supply NULL for the last three parameters. We also supply the
* the compiler header file version, so that we know if the application
* was compiled with a compatible version of the library. REQUIRED
*/
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
png_voidp user_error_ptr, user_error_fn, user_warning_fn);
if (png_ptr == NULL)
{
fclose(fp);
return (ERROR);
}
/* Allocate/initialize the memory for image information. REQUIRED. */
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL)
{
fclose(fp);
png_destroy_read_struct(&png_ptr, NULL, NULL);
return (ERROR);
}
/* Set error handling if you are using the setjmp/longjmp method (this is
* the normal method of doing things with libpng). REQUIRED unless you
* set up your own error handlers in the png_create_read_struct() earlier.
*/
if (setjmp(png_jmpbuf(png_ptr)))
{
/* Free all of the memory associated with the png_ptr and info_ptr */
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(fp);
/* If we get here, we had a problem reading the file */
return (ERROR);
}
/* One of the following I/O initialization methods is REQUIRED */
#ifdef streams /* PNG file I/O method 1 */
/* Set up the input control if you are using standard C streams */
png_init_io(png_ptr, fp);
#else no_streams /* PNG file I/O method 2 */
/* If you are using replacement read functions, instead of calling
* png_init_io() here you would call:
*/
png_set_read_fn(png_ptr, (void *)user_io_ptr, user_read_fn);
/* where user_io_ptr is a structure you want available to the callbacks */
#endif no_streams /* Use only one I/O method! */
/* If we have already read some of the signature */
png_set_sig_bytes(png_ptr, sig_read);
#ifdef hilevel
/*
* If you have enough memory to read in the entire image at once,
* and you need to specify only transforms that can be controlled
* with one of the PNG_TRANSFORM_* bits (this presently excludes
* quantizing, filling, setting background, and doing gamma
* adjustment), then you can read the entire image (including
* pixels) into the info structure with this call:
*/
png_read_png(png_ptr, info_ptr, png_transforms, NULL);
#else
/* OK, you're doing it the hard way, with the lower-level functions */
/* The call to png_read_info() gives us all of the information from the
* PNG file before the first IDAT (image data chunk). REQUIRED
*/
png_read_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
&interlace_type, NULL, NULL);
/* Set up the data transformations you want. Note that these are all
* optional. Only call them if you want/need them. Many of the
* transformations only work on specific types of images, and many
* are mutually exclusive.
*/
/* Tell libpng to strip 16 bit/color files down to 8 bits/color */
png_set_strip_16(png_ptr);
/* Strip alpha bytes from the input data without combining with the
* background (not recommended).
*/
png_set_strip_alpha(png_ptr);
/* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
* byte into separate bytes (useful for paletted and grayscale images).
*/
png_set_packing(png_ptr);
/* Change the order of packed pixels to least significant bit first
* (not useful if you are using png_set_packing). */
png_set_packswap(png_ptr);
/* Expand paletted colors into true RGB triplets */
if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_palette_to_rgb(png_ptr);
/* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
png_set_expand_gray_1_2_4_to_8(png_ptr);
/* Expand paletted or RGB images with transparency to full alpha channels
* so the data will be available as RGBA quartets.
*/
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
png_set_tRNS_to_alpha(png_ptr);
/* Set the background color to draw transparent and alpha images over.
* It is possible to set the red, green, and blue components directly
* for paletted images instead of supplying a palette index. Note that
* even if the PNG file supplies a background, you are not required to
* use it - you should use the (solid) application background if it has one.
*/
png_color_16 my_background, *image_background;
if (png_get_bKGD(png_ptr, info_ptr, &image_background))
png_set_background(png_ptr, image_background,
PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
else
png_set_background(png_ptr, &my_background,
PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
/* Some suggestions as to how to get a screen gamma value
*
* Note that screen gamma is the display_exponent, which includes
* the CRT_exponent and any correction for viewing conditions
*/
if (/* We have a user-defined screen gamma value */)
{
screen_gamma = user-defined screen_gamma;
}
/* This is one way that applications share the same screen gamma value */
else if ((gamma_str = getenv("SCREEN_GAMMA")) != NULL)
{
screen_gamma = atof(gamma_str);
}
/* If we don't have another value */
else
{
screen_gamma = 2.2; /* A good guess for a PC monitor in a dimly
lit room */
screen_gamma = 1.7 or 1.0; /* A good guess for Mac systems */
}
/* Tell libpng to handle the gamma conversion for you. The final call
* is a good guess for PC generated images, but it should be configurable
* by the user at run time by the user. It is strongly suggested that
* your application support gamma correction.
*/
int intent;
if (png_get_sRGB(png_ptr, info_ptr, &intent))
png_set_gamma(png_ptr, screen_gamma, 0.45455);
else
{
double image_gamma;
if (png_get_gAMA(png_ptr, info_ptr, &image_gamma))
png_set_gamma(png_ptr, screen_gamma, image_gamma);
else
png_set_gamma(png_ptr, screen_gamma, 0.45455);
}
#ifdef PNG_READ_QUANTIZE_SUPPORTED
/* Quantize RGB files down to 8 bit palette or reduce palettes
* to the number of colors available on your screen.
*/
if (color_type & PNG_COLOR_MASK_COLOR)
{
int num_palette;
png_colorp palette;
/* This reduces the image to the application supplied palette */
if (/* We have our own palette */)
{
/* An array of colors to which the image should be quantized */
png_color std_color_cube[MAX_SCREEN_COLORS];
/* Prior to libpng-1.4.2, this was png_set_dither(). */
png_set_quantize(png_ptr, std_color_cube, MAX_SCREEN_COLORS,
MAX_SCREEN_COLORS, NULL, 0);
}
/* This reduces the image to the palette supplied in the file */
else if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette))
{
png_uint_16p histogram = NULL;
png_get_hIST(png_ptr, info_ptr, &histogram);
png_set_quantize(png_ptr, palette, num_palette,
max_screen_colors, histogram, 0);
}
}
#endif /* PNG_READ_QUANTIZE_SUPPORTED */
/* Invert monochrome files to have 0 as white and 1 as black */
png_set_invert_mono(png_ptr);
/* If you want to shift the pixel values from the range [0,255] or
* [0,65535] to the original [0,7] or [0,31], or whatever range the
* colors were originally in:
*/
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
{
png_color_8p sig_bit_p;
png_get_sBIT(png_ptr, info_ptr, &sig_bit_p);
png_set_shift(png_ptr, sig_bit_p);
}
/* Flip the RGB pixels to BGR (or RGBA to BGRA) */
if (color_type & PNG_COLOR_MASK_COLOR)
png_set_bgr(png_ptr);
/* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
png_set_swap_alpha(png_ptr);
/* Swap bytes of 16 bit files to least significant byte first */
png_set_swap(png_ptr);
/* Add filler (or alpha) byte (before/after each RGB triplet) */
png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
/* Turn on interlace handling. REQUIRED if you are not using
* png_read_image(). To see how to handle interlacing passes,
* see the png_read_row() method below:
*/
number_passes = png_set_interlace_handling(png_ptr);
/* Optional call to gamma correct and add the background to the palette
* and update info structure. REQUIRED if you are expecting libpng to
* update the palette for you (ie you selected such a transform above).
*/
png_read_update_info(png_ptr, info_ptr);
/* Allocate the memory to hold the image using the fields of info_ptr. */
/* The easiest way to read the image: */
png_bytep row_pointers[height];
/* Clear the pointer array */
for (row = 0; row < height; row++)
row_pointers[row] = NULL;
for (row = 0; row < height; row++)
row_pointers[row] = png_malloc(png_ptr, png_get_rowbytes(png_ptr,
info_ptr));
/* Now it's time to read the image. One of these methods is REQUIRED */
#ifdef entire /* Read the entire image in one go */
png_read_image(png_ptr, row_pointers);
#else no_entire /* Read the image one or more scanlines at a time */
/* The other way to read images - deal with interlacing: */
for (pass = 0; pass < number_passes; pass++)
{
#ifdef single /* Read the image a single row at a time */
for (y = 0; y < height; y++)
{
png_read_rows(png_ptr, &row_pointers[y], NULL, 1);
}
#else no_single /* Read the image several rows at a time */
for (y = 0; y < height; y += number_of_rows)
{
#ifdef sparkle /* Read the image using the "sparkle" effect. */
png_read_rows(png_ptr, &row_pointers[y], NULL,
number_of_rows);
#else no_sparkle /* Read the image using the "rectangle" effect */
png_read_rows(png_ptr, NULL, &row_pointers[y],
number_of_rows);
#endif no_sparkle /* Use only one of these two methods */
}
/* If you want to display the image after every pass, do so here */
#endif no_single /* Use only one of these two methods */
}
#endif no_entire /* Use only one of these two methods */
/* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
png_read_end(png_ptr, info_ptr);
#endif hilevel
/* At this point you have read the entire image */
/* Clean up after the read, and free any memory allocated - REQUIRED */
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
/* Close the file */
fclose(fp);
/* That's it */
return (OK);
}
/* Progressively read a file */
int
initialize_png_reader(png_structp *png_ptr, png_infop *info_ptr)
{
/* Create and initialize the png_struct with the desired error handler
* functions. If you want to use the default stderr and longjump method,
* you can supply NULL for the last three parameters. We also check that
* the library version is compatible in case we are using dynamically
* linked libraries.
*/
*png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
png_voidp user_error_ptr, user_error_fn, user_warning_fn);
if (*png_ptr == NULL)
{
*info_ptr = NULL;
return (ERROR);
}
*info_ptr = png_create_info_struct(png_ptr);
if (*info_ptr == NULL)
{
png_destroy_read_struct(png_ptr, info_ptr, NULL);
return (ERROR);
}
if (setjmp(png_jmpbuf((*png_ptr))))
{
png_destroy_read_struct(png_ptr, info_ptr, NULL);
return (ERROR);
}
/* This one's new. You will need to provide all three
* function callbacks, even if you aren't using them all.
* If you aren't using all functions, you can specify NULL
* parameters. Even when all three functions are NULL,
* you need to call png_set_progressive_read_fn().
* These functions shouldn't be dependent on global or
* static variables if you are decoding several images
* simultaneously. You should store stream specific data
* in a separate struct, given as the second parameter,
* and retrieve the pointer from inside the callbacks using
* the function png_get_progressive_ptr(png_ptr).
*/
png_set_progressive_read_fn(*png_ptr, (void *)stream_data,
info_callback, row_callback, end_callback);
return (OK);
}
int
process_data(png_structp *png_ptr, png_infop *info_ptr,
png_bytep buffer, png_uint_32 length)
{
if (setjmp(png_jmpbuf((*png_ptr))))
{
/* Free the png_ptr and info_ptr memory on error */
png_destroy_read_struct(png_ptr, info_ptr, NULL);
return (ERROR);
}
/* This one's new also. Simply give it chunks of data as
* they arrive from the data stream (in order, of course).
* On segmented machines, don't give it any more than 64K.
* The library seems to run fine with sizes of 4K, although
* you can give it much less if necessary (I assume you can
* give it chunks of 1 byte, but I haven't tried with less
* than 256 bytes yet). When this function returns, you may
* want to display any rows that were generated in the row
* callback, if you aren't already displaying them there.
*/
png_process_data(*png_ptr, *info_ptr, buffer, length);
return (OK);
}
info_callback(png_structp png_ptr, png_infop info)
{
/* Do any setup here, including setting any of the transformations
* mentioned in the Reading PNG files section. For now, you _must_
* call either png_start_read_image() or png_read_update_info()
* after all the transformations are set (even if you don't set
* any). You may start getting rows before png_process_data()
* returns, so this is your last chance to prepare for that.
*/
}
row_callback(png_structp png_ptr, png_bytep new_row,
png_uint_32 row_num, int pass)
{
/*
* This function is called for every row in the image. If the
* image is interlaced, and you turned on the interlace handler,
* this function will be called for every row in every pass.
*
* In this function you will receive a pointer to new row data from
* libpng called new_row that is to replace a corresponding row (of
* the same data format) in a buffer allocated by your application.
*
* The new row data pointer "new_row" may be NULL, indicating there is
* no new data to be replaced (in cases of interlace loading).
*
* If new_row is not NULL then you need to call
* png_progressive_combine_row() to replace the corresponding row as
* shown below:
*/
/* Get pointer to corresponding row in our
* PNG read buffer.
*/
png_bytep old_row = ((png_bytep *)our_data)[row_num];
/* If both rows are allocated then copy the new row
* data to the corresponding row data.
*/
if ((old_row != NULL) && (new_row != NULL))
png_progressive_combine_row(png_ptr, old_row, new_row);
/*
* The rows and passes are called in order, so you don't really
* need the row_num and pass, but I'm supplying them because it
* may make your life easier.
*
* For the non-NULL rows of interlaced images, you must call
* png_progressive_combine_row() passing in the new row and the
* old row, as demonstrated above. You can call this function for
* NULL rows (it will just return) and for non-interlaced images
* (it just does the png_memcpy for you) if it will make the code
* easier. Thus, you can just do this for all cases:
*/
png_progressive_combine_row(png_ptr, old_row, new_row);
/* where old_row is what was displayed for previous rows. Note
* that the first pass (pass == 0 really) will completely cover
* the old row, so the rows do not have to be initialized. After
* the first pass (and only for interlaced images), you will have
* to pass the current row as new_row, and the function will combine
* the old row and the new row.
*/
}
end_callback(png_structp png_ptr, png_infop info)
{
/* This function is called when the whole image has been read,
* including any chunks after the image (up to and including
* the IEND). You will usually have the same info chunk as you
* had in the header, although some data may have been added
* to the comments and time fields.
*
* Most people won't do much here, perhaps setting a flag that
* marks the image as finished.
*/
}
/* Write a png file */
void write_png(char *file_name /* , ... other image information ... */)
{
FILE *fp;
png_structp png_ptr;
png_infop info_ptr;
png_colorp palette;
/* Open the file */
fp = fopen(file_name, "wb");
if (fp == NULL)
return (ERROR);
/* Create and initialize the png_struct with the desired error handler
* functions. If you want to use the default stderr and longjump method,
* you can supply NULL for the last three parameters. We also check that
* the library version is compatible with the one used at compile time,
* in case we are using dynamically linked libraries. REQUIRED.
*/
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
png_voidp user_error_ptr, user_error_fn, user_warning_fn);
if (png_ptr == NULL)
{
fclose(fp);
return (ERROR);
}
/* Allocate/initialize the image information data. REQUIRED */
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL)
{
fclose(fp);
png_destroy_write_struct(&png_ptr, NULL);
return (ERROR);
}
/* Set error handling. REQUIRED if you aren't supplying your own
* error handling functions in the png_create_write_struct() call.
*/
if (setjmp(png_jmpbuf(png_ptr)))
{
/* If we get here, we had a problem writing the file */
fclose(fp);
png_destroy_write_struct(&png_ptr, &info_ptr);
return (ERROR);
}
/* One of the following I/O initialization functions is REQUIRED */
#ifdef streams /* I/O initialization method 1 */
/* Set up the output control if you are using standard C streams */
png_init_io(png_ptr, fp);
#else no_streams /* I/O initialization method 2 */
/* If you are using replacement write functions, instead of calling
* png_init_io() here you would call
*/
png_set_write_fn(png_ptr, (void *)user_io_ptr, user_write_fn,
user_IO_flush_function);
/* where user_io_ptr is a structure you want available to the callbacks */
#endif no_streams /* Only use one initialization method */
#ifdef hilevel
/* This is the easy way. Use it if you already have all the
* image info living in the structure. You could "|" many
* PNG_TRANSFORM flags into the png_transforms integer here.
*/
png_write_png(png_ptr, info_ptr, png_transforms, NULL);
#else
/* This is the hard way */
/* Set the image information here. Width and height are up to 2^31,
* bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
* the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
* PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
* or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or
* PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
* currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
*/
png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, PNG_COLOR_TYPE_???,
PNG_INTERLACE_????, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
/* Set the palette if there is one. REQUIRED for indexed-color images */
palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH
* png_sizeof(png_color));
/* ... Set palette colors ... */
png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH);
/* You must not free palette here, because png_set_PLTE only makes a link to
* the palette that you malloced. Wait until you are about to destroy
* the png structure.
*/
/* Optional significant bit (sBIT) chunk */
png_color_8 sig_bit;
/* If we are dealing with a grayscale image then */
sig_bit.gray = true_bit_depth;
/* Otherwise, if we are dealing with a color image then */
sig_bit.red = true_red_bit_depth;
sig_bit.green = true_green_bit_depth;
sig_bit.blue = true_blue_bit_depth;
/* If the image has an alpha channel then */
sig_bit.alpha = true_alpha_bit_depth;
png_set_sBIT(png_ptr, info_ptr, &sig_bit);
/* Optional gamma chunk is strongly suggested if you have any guess
* as to the correct gamma of the image.
*/
png_set_gAMA(png_ptr, info_ptr, gamma);
/* Optionally write comments into the image */
text_ptr[0].key = "Title";
text_ptr[0].text = "Mona Lisa";
text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
text_ptr[1].key = "Author";
text_ptr[1].text = "Leonardo DaVinci";
text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;
text_ptr[2].key = "Description";
text_ptr[2].text = "<long text>";
text_ptr[2].compression = PNG_TEXT_COMPRESSION_zTXt;
#ifdef PNG_iTXt_SUPPORTED
text_ptr[0].lang = NULL;
text_ptr[0].lang_key = NULL;
text_ptr[1].lang = NULL;
text_ptr[1].lang_key = NULL;
text_ptr[2].lang = NULL;
text_ptr[2].lang_key = NULL;
#endif
png_set_text(png_ptr, info_ptr, text_ptr, 3);
/* Other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs */
/* Note that if sRGB is present the gAMA and cHRM chunks must be ignored
* on read and, if your application chooses to write them, they must
* be written in accordance with the sRGB profile
*/
/* Write the file header information. REQUIRED */
png_write_info(png_ptr, info_ptr);
/* If you want, you can write the info in two steps, in case you need to
* write your private chunk ahead of PLTE:
*
* png_write_info_before_PLTE(write_ptr, write_info_ptr);
* write_my_chunk();
* png_write_info(png_ptr, info_ptr);
*
* However, given the level of known- and unknown-chunk support in 1.2.0
* and up, this should no longer be necessary.
*/
/* Once we write out the header, the compression type on the text
* chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or
* PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again
* at the end.
*/
/* Set up the transformations you want. Note that these are
* all optional. Only call them if you want them.
*/
/* Invert monochrome pixels */
png_set_invert_mono(png_ptr);
/* Shift the pixels up to a legal bit depth and fill in
* as appropriate to correctly scale the image.
*/
png_set_shift(png_ptr, &sig_bit);
/* Pack pixels into bytes */
png_set_packing(png_ptr);
/* Swap location of alpha bytes from ARGB to RGBA */
png_set_swap_alpha(png_ptr);
/* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into
* RGB (4 channels -> 3 channels). The second parameter is not used.
*/
png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
/* Flip BGR pixels to RGB */
png_set_bgr(png_ptr);
/* Swap bytes of 16-bit files to most significant byte first */
png_set_swap(png_ptr);
/* Swap bits of 1, 2, 4 bit packed pixel formats */
png_set_packswap(png_ptr);
/* Turn on interlace handling if you are not using png_write_image() */
if (interlacing)
number_passes = png_set_interlace_handling(png_ptr);
else
number_passes = 1;
/* The easiest way to write the image (you may have a different memory
* layout, however, so choose what fits your needs best). You need to
* use the first method if you aren't handling interlacing yourself.
*/
png_uint_32 k, height, width;
png_byte image[height][width*bytes_per_pixel];
png_bytep row_pointers[height];
if (height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
png_error (png_ptr, "Image is too tall to process in memory");
for (k = 0; k < height; k++)
row_pointers[k] = image + k*width*bytes_per_pixel;
/* One of the following output methods is REQUIRED */
#ifdef entire /* Write out the entire image data in one call */
png_write_image(png_ptr, row_pointers);
/* The other way to write the image - deal with interlacing */
#else no_entire /* Write out the image data by one or more scanlines */
/* The number of passes is either 1 for non-interlaced images,
* or 7 for interlaced images.
*/
for (pass = 0; pass < number_passes; pass++)
{
/* Write a few rows at a time. */
png_write_rows(png_ptr, &row_pointers[first_row], number_of_rows);
/* If you are only writing one row at a time, this works */
for (y = 0; y < height; y++)
png_write_rows(png_ptr, &row_pointers[y], 1);
}
#endif no_entire /* Use only one output method */
/* You can write optional chunks like tEXt, zTXt, and tIME at the end
* as well. Shouldn't be necessary in 1.2.0 and up as all the public
* chunks are supported and you can use png_set_unknown_chunks() to
* register unknown chunks into the info structure to be written out.
*/
/* It is REQUIRED to call this to finish writing the rest of the file */
png_write_end(png_ptr, info_ptr);
#endif hilevel
/* If you png_malloced a palette, free it here (don't free info_ptr->palette,
* as recommended in versions 1.0.5m and earlier of this example; if
* libpng mallocs info_ptr->palette, libpng will free it). If you
* allocated it with malloc() instead of png_malloc(), use free() instead
* of png_free().
*/
png_free(png_ptr, palette);
palette = NULL;
/* Similarly, if you png_malloced any data that you passed in with
* png_set_something(), such as a hist or trans array, free it here,
* when you can be sure that libpng is through with it.
*/
png_free(png_ptr, trans);
trans = NULL;
/* Whenever you use png_free() it is a good idea to set the pointer to
* NULL in case your application inadvertently tries to png_free() it
* again. When png_free() sees a NULL it returns without action, thus
* avoiding the double-free security problem.
*/
/* Clean up after the write, and free any memory allocated */
png_destroy_write_struct(&png_ptr, &info_ptr);
/* Close the file */
fclose(fp);
/* That's it */
return (OK);
}
#endif /* if 0 */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

157
src/libpng/pngdebug.h Normal file
View File

@ -0,0 +1,157 @@
/* pngdebug.h - Debugging macros for libpng, also used in pngtest.c
*
* Copyright (c) 1998-2011 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.)
*
* Last changed in libpng 1.5.0 [January 6, 2011]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*/
/* Define PNG_DEBUG at compile time for debugging information. Higher
* numbers for PNG_DEBUG mean more debugging information. This has
* only been added since version 0.95 so it is not implemented throughout
* libpng yet, but more support will be added as needed.
*
* png_debug[1-2]?(level, message ,arg{0-2})
* Expands to a statement (either a simple expression or a compound
* do..while(0) statement) that outputs a message with parameter
* substitution if PNG_DEBUG is defined to 2 or more. If PNG_DEBUG
* is undefined, 0 or 1 every png_debug expands to a simple expression
* (actually ((void)0)).
*
* level: level of detail of message, starting at 0. A level 'n'
* message is preceded by 'n' tab characters (not implemented
* on Microsoft compilers unless PNG_DEBUG_FILE is also
* defined, to allow debug DLL compilation with no standard IO).
* message: a printf(3) style text string. A trailing '\n' is added
* to the message.
* arg: 0 to 2 arguments for printf(3) style substitution in message.
*/
#ifndef PNGDEBUG_H
#define PNGDEBUG_H
/* These settings control the formatting of messages in png.c and pngerror.c */
/* Moved to pngdebug.h at 1.5.0 */
# ifndef PNG_LITERAL_SHARP
# define PNG_LITERAL_SHARP 0x23
# endif
# ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET
# define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b
# endif
# ifndef PNG_LITERAL_RIGHT_SQUARE_BRACKET
# define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5d
# endif
# ifndef PNG_STRING_NEWLINE
# define PNG_STRING_NEWLINE "\n"
# endif
#ifdef PNG_DEBUG
# if (PNG_DEBUG > 0)
# if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER)
# include <crtdbg.h>
# if (PNG_DEBUG > 1)
# ifndef _DEBUG
# define _DEBUG
# endif
# ifndef png_debug
# define png_debug(l,m) _RPT0(_CRT_WARN,m PNG_STRING_NEWLINE)
# endif
# ifndef png_debug1
# define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m PNG_STRING_NEWLINE,p1)
# endif
# ifndef png_debug2
# define png_debug2(l,m,p1,p2) \
_RPT2(_CRT_WARN,m PNG_STRING_NEWLINE,p1,p2)
# endif
# endif
# else /* PNG_DEBUG_FILE || !_MSC_VER */
# ifndef PNG_STDIO_SUPPORTED
# include <stdio.h> /* not included yet */
# endif
# ifndef PNG_DEBUG_FILE
# define PNG_DEBUG_FILE stderr
# endif /* PNG_DEBUG_FILE */
# if (PNG_DEBUG > 1)
/* Note: ["%s"m PNG_STRING_NEWLINE] probably does not work on
* non-ISO compilers
*/
# ifdef __STDC__
# ifndef png_debug
# define png_debug(l,m) \
do { \
int num_tabs=l; \
fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
(num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \
} while (0)
# endif
# ifndef png_debug1
# define png_debug1(l,m,p1) \
do { \
int num_tabs=l; \
fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
(num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \
} while (0)
# endif
# ifndef png_debug2
# define png_debug2(l,m,p1,p2) \
do { \
int num_tabs=l; \
fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
(num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \
} while (0)
# endif
# else /* __STDC __ */
# ifndef png_debug
# define png_debug(l,m) \
do { \
int num_tabs=l; \
char format[256]; \
snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
(num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
m,PNG_STRING_NEWLINE); \
fprintf(PNG_DEBUG_FILE,format); \
} while (0)
# endif
# ifndef png_debug1
# define png_debug1(l,m,p1) \
do { \
int num_tabs=l; \
char format[256]; \
snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
(num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
m,PNG_STRING_NEWLINE); \
fprintf(PNG_DEBUG_FILE,format,p1); \
} while (0)
# endif
# ifndef png_debug2
# define png_debug2(l,m,p1,p2) \
do { \
int num_tabs=l; \
char format[256]; \
snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
(num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
m,PNG_STRING_NEWLINE); \
fprintf(PNG_DEBUG_FILE,format,p1,p2); \
} while (0)
# endif
# endif /* __STDC __ */
# endif /* (PNG_DEBUG > 1) */
# endif /* _MSC_VER */
# endif /* (PNG_DEBUG > 0) */
#endif /* PNG_DEBUG */
#ifndef png_debug
# define png_debug(l, m) ((void)0)
#endif
#ifndef png_debug1
# define png_debug1(l, m, p1) ((void)0)
#endif
#ifndef png_debug2
# define png_debug2(l, m, p1, p2) ((void)0)
#endif
#endif /* PNGDEBUG_H */

View File

@ -1,8 +1,8 @@
/* pngerror.c - stub functions for i/o and memory allocation /* pngerror.c - stub functions for i/o and memory allocation
* *
* Last changed in libpng 1.4.0 [January 3, 2010] * Last changed in libpng 1.5.1 [February 3, 2011]
* Copyright (c) 1998-2010 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
@ -16,14 +16,13 @@
* at each function. * at each function.
*/ */
#define PNG_NO_PEDANTIC_WARNINGS
#include "png.h"
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
#include "pngpriv.h" #include "pngpriv.h"
static void /* PRIVATE */ #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
png_default_error PNGARG((png_structp png_ptr,
png_const_charp error_message)) PNG_NORETURN; static PNG_FUNCTION(void, png_default_error,PNGARG((png_structp png_ptr,
png_const_charp error_message)),PNG_NORETURN);
#ifdef PNG_WARNINGS_SUPPORTED #ifdef PNG_WARNINGS_SUPPORTED
static void /* PRIVATE */ static void /* PRIVATE */
png_default_warning PNGARG((png_structp png_ptr, png_default_warning PNGARG((png_structp png_ptr,
@ -36,8 +35,8 @@ png_default_warning PNGARG((png_structp png_ptr,
* to replace the error function at run-time. * to replace the error function at run-time.
*/ */
#ifdef PNG_ERROR_TEXT_SUPPORTED #ifdef PNG_ERROR_TEXT_SUPPORTED
void PNGAPI PNG_FUNCTION(void,PNGAPI
png_error(png_structp png_ptr, png_const_charp error_message) png_error,(png_structp png_ptr, png_const_charp error_message),PNG_NORETURN)
{ {
#ifdef PNG_ERROR_NUMBERS_SUPPORTED #ifdef PNG_ERROR_NUMBERS_SUPPORTED
char msg[16]; char msg[16];
@ -53,6 +52,7 @@ png_error(png_structp png_ptr, png_const_charp error_message)
for (offset = 1; offset<15; offset++) for (offset = 1; offset<15; offset++)
if (error_message[offset] == ' ') if (error_message[offset] == ' ')
break; break;
if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
{ {
int i; int i;
@ -61,9 +61,11 @@ png_error(png_structp png_ptr, png_const_charp error_message)
msg[i - 1] = '\0'; msg[i - 1] = '\0';
error_message = msg; error_message = msg;
} }
else else
error_message += offset; error_message += offset;
} }
else else
{ {
if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
@ -84,8 +86,8 @@ png_error(png_structp png_ptr, png_const_charp error_message)
png_default_error(png_ptr, error_message); png_default_error(png_ptr, error_message);
} }
#else #else
void PNGAPI PNG_FUNCTION(void,PNGAPI
png_err(png_structp png_ptr) png_err,(png_structp png_ptr),PNG_NORETURN)
{ {
if (png_ptr != NULL && png_ptr->error_fn != NULL) if (png_ptr != NULL && png_ptr->error_fn != NULL)
(*(png_ptr->error_fn))(png_ptr, '\0'); (*(png_ptr->error_fn))(png_ptr, '\0');
@ -169,6 +171,7 @@ png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
buffer[iout++] = png_digit[c & 0x0f]; buffer[iout++] = png_digit[c & 0x0f];
buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET; buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET;
} }
else else
{ {
buffer[iout++] = (png_byte)c; buffer[iout++] = (png_byte)c;
@ -177,6 +180,7 @@ png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
if (error_message == NULL) if (error_message == NULL)
buffer[iout] = '\0'; buffer[iout] = '\0';
else else
{ {
buffer[iout++] = ':'; buffer[iout++] = ':';
@ -185,22 +189,24 @@ png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
buffer[iout + PNG_MAX_ERROR_TEXT - 1] = '\0'; buffer[iout + PNG_MAX_ERROR_TEXT - 1] = '\0';
} }
} }
#endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */
#ifdef PNG_READ_SUPPORTED #if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
void PNGAPI PNG_FUNCTION(void,PNGAPI
png_chunk_error(png_structp png_ptr, png_const_charp error_message) png_chunk_error,(png_structp png_ptr, png_const_charp error_message),
PNG_NORETURN)
{ {
char msg[18+PNG_MAX_ERROR_TEXT]; char msg[18+PNG_MAX_ERROR_TEXT];
if (png_ptr == NULL) if (png_ptr == NULL)
png_error(png_ptr, error_message); png_error(png_ptr, error_message);
else else
{ {
png_format_buffer(png_ptr, msg, error_message); png_format_buffer(png_ptr, msg, error_message);
png_error(png_ptr, msg); png_error(png_ptr, msg);
} }
} }
#endif /* PNG_READ_SUPPORTED */ #endif /* PNG_READ_SUPPORTED && PNG_ERROR_TEXT_SUPPORTED */
#endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */
#ifdef PNG_WARNINGS_SUPPORTED #ifdef PNG_WARNINGS_SUPPORTED
void PNGAPI void PNGAPI
@ -209,6 +215,7 @@ png_chunk_warning(png_structp png_ptr, png_const_charp warning_message)
char msg[18+PNG_MAX_ERROR_TEXT]; char msg[18+PNG_MAX_ERROR_TEXT];
if (png_ptr == NULL) if (png_ptr == NULL)
png_warning(png_ptr, warning_message); png_warning(png_ptr, warning_message);
else else
{ {
png_format_buffer(png_ptr, msg, warning_message); png_format_buffer(png_ptr, msg, warning_message);
@ -224,12 +231,35 @@ png_chunk_benign_error(png_structp png_ptr, png_const_charp error_message)
{ {
if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
png_chunk_warning(png_ptr, error_message); png_chunk_warning(png_ptr, error_message);
else else
png_chunk_error(png_ptr, error_message); png_chunk_error(png_ptr, error_message);
} }
#endif #endif
#endif /* PNG_READ_SUPPORTED */ #endif /* PNG_READ_SUPPORTED */
#ifdef PNG_ERROR_TEXT_SUPPORTED
#ifdef PNG_FLOATING_POINT_SUPPORTED
PNG_FUNCTION(void,
png_fixed_error,(png_structp png_ptr, png_const_charp name),PNG_NORETURN)
{
# define fixed_message "fixed point overflow in "
# define fixed_message_ln ((sizeof fixed_message)-1)
int iin;
char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT];
png_memcpy(msg, fixed_message, fixed_message_ln);
iin = 0;
if (name != NULL) while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0)
{
msg[fixed_message_ln + iin] = name[iin];
++iin;
}
msg[fixed_message_ln + iin] = 0;
png_error(png_ptr, msg);
}
#endif
#endif
#ifdef PNG_SETJMP_SUPPORTED #ifdef PNG_SETJMP_SUPPORTED
/* This API only exists if ANSI-C style error handling is used, /* This API only exists if ANSI-C style error handling is used,
* otherwise it is necessary for png_default_error to be overridden. * otherwise it is necessary for png_default_error to be overridden.
@ -242,7 +272,7 @@ png_set_longjmp_fn(png_structp png_ptr, png_longjmp_ptr longjmp_fn,
return NULL; return NULL;
png_ptr->longjmp_fn = longjmp_fn; png_ptr->longjmp_fn = longjmp_fn;
return &png_ptr->jmpbuf; return &png_ptr->png_jmpbuf;
} }
#endif #endif
@ -251,8 +281,9 @@ png_set_longjmp_fn(png_structp png_ptr, png_longjmp_ptr longjmp_fn,
* function is used by default, or if the program supplies NULL for the * function is used by default, or if the program supplies NULL for the
* error function pointer in png_set_error_fn(). * error function pointer in png_set_error_fn().
*/ */
static void /* PRIVATE */ static PNG_FUNCTION(void /* PRIVATE */,
png_default_error(png_structp png_ptr, png_const_charp error_message) png_default_error,(png_structp png_ptr, png_const_charp error_message),
PNG_NORETURN)
{ {
#ifdef PNG_CONSOLE_IO_SUPPORTED #ifdef PNG_CONSOLE_IO_SUPPORTED
#ifdef PNG_ERROR_NUMBERS_SUPPORTED #ifdef PNG_ERROR_NUMBERS_SUPPORTED
@ -267,6 +298,7 @@ png_default_error(png_structp png_ptr, png_const_charp error_message)
if (error_message[offset] == ' ') if (error_message[offset] == ' ')
break; break;
} }
if ((offset > 1) && (offset < 15)) if ((offset > 1) && (offset < 15))
{ {
error_number[offset - 1] = '\0'; error_number[offset - 1] = '\0';
@ -274,6 +306,7 @@ png_default_error(png_structp png_ptr, png_const_charp error_message)
error_number, error_message + offset + 1); error_number, error_message + offset + 1);
fprintf(stderr, PNG_STRING_NEWLINE); fprintf(stderr, PNG_STRING_NEWLINE);
} }
else else
{ {
fprintf(stderr, "libpng error: %s, offset=%d", fprintf(stderr, "libpng error: %s, offset=%d",
@ -288,26 +321,32 @@ png_default_error(png_structp png_ptr, png_const_charp error_message)
fprintf(stderr, PNG_STRING_NEWLINE); fprintf(stderr, PNG_STRING_NEWLINE);
} }
#endif #endif
#ifndef PNG_CONSOLE_IO_SUPPORTED
PNG_UNUSED(error_message) /* Make compiler happy */
#endif
png_longjmp(png_ptr, 1);
}
PNG_FUNCTION(void,PNGAPI
png_longjmp,(png_structp png_ptr, int val),PNG_NORETURN)
{
#ifdef PNG_SETJMP_SUPPORTED #ifdef PNG_SETJMP_SUPPORTED
if (png_ptr && png_ptr->longjmp_fn) if (png_ptr && png_ptr->longjmp_fn)
{ {
# ifdef USE_FAR_KEYWORD # ifdef USE_FAR_KEYWORD
{ {
jmp_buf jmpbuf; jmp_buf png_jmpbuf;
png_memcpy(jmpbuf, png_ptr->jmpbuf, png_sizeof(jmp_buf)); png_memcpy(png_jmpbuf, png_ptr->png_jmpbuf, png_sizeof(jmp_buf));
png_ptr->longjmp_fn(jmpbuf, 1); png_ptr->longjmp_fn(png_jmpbuf, val);
} }
# else # else
png_ptr->longjmp_fn(png_ptr->jmpbuf, 1); png_ptr->longjmp_fn(png_ptr->png_jmpbuf, val);
# endif # endif
} }
#endif #endif
/* Here if not setjmp support or if png_ptr is null. */ /* Here if not setjmp support or if png_ptr is null. */
PNG_ABORT(); PNG_ABORT();
#ifndef PNG_CONSOLE_IO_SUPPORTED
error_message = error_message; /* Make compiler happy */
#endif
} }
#ifdef PNG_WARNINGS_SUPPORTED #ifdef PNG_WARNINGS_SUPPORTED
@ -331,6 +370,7 @@ png_default_warning(png_structp png_ptr, png_const_charp warning_message)
if (warning_message[offset] == ' ') if (warning_message[offset] == ' ')
break; break;
} }
if ((offset > 1) && (offset < 15)) if ((offset > 1) && (offset < 15))
{ {
warning_number[offset + 1] = '\0'; warning_number[offset + 1] = '\0';
@ -338,6 +378,7 @@ png_default_warning(png_structp png_ptr, png_const_charp warning_message)
warning_number, warning_message + offset); warning_number, warning_message + offset);
fprintf(stderr, PNG_STRING_NEWLINE); fprintf(stderr, PNG_STRING_NEWLINE);
} }
else else
{ {
fprintf(stderr, "libpng warning: %s", fprintf(stderr, "libpng warning: %s",
@ -347,21 +388,22 @@ png_default_warning(png_structp png_ptr, png_const_charp warning_message)
} }
else else
# endif # endif
{ {
fprintf(stderr, "libpng warning: %s", warning_message); fprintf(stderr, "libpng warning: %s", warning_message);
fprintf(stderr, PNG_STRING_NEWLINE); fprintf(stderr, PNG_STRING_NEWLINE);
} }
#else #else
warning_message = warning_message; /* Make compiler happy */ PNG_UNUSED(warning_message) /* Make compiler happy */
#endif #endif
png_ptr = png_ptr; /* Make compiler happy */ PNG_UNUSED(png_ptr) /* Make compiler happy */
} }
#endif /* PNG_WARNINGS_SUPPORTED */ #endif /* PNG_WARNINGS_SUPPORTED */
/* This function is called when the application wants to use another method /* This function is called when the application wants to use another method
* of handling errors and warnings. Note that the error function MUST NOT * of handling errors and warnings. Note that the error function MUST NOT
* return to the calling routine or serious problems will occur. The return * return to the calling routine or serious problems will occur. The return
* method used in the default routine calls longjmp(png_ptr->jmpbuf, 1) * method used in the default routine calls longjmp(png_ptr->png_jmpbuf, 1)
*/ */
void PNGAPI void PNGAPI
png_set_error_fn(png_structp png_ptr, png_voidp error_ptr, png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
@ -369,6 +411,7 @@ png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
{ {
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
png_ptr->error_ptr = error_ptr; png_ptr->error_ptr = error_ptr;
png_ptr->error_fn = error_fn; png_ptr->error_fn = error_fn;
png_ptr->warning_fn = warning_fn; png_ptr->warning_fn = warning_fn;
@ -380,10 +423,11 @@ png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
* pointer before png_write_destroy and png_read_destroy are called. * pointer before png_write_destroy and png_read_destroy are called.
*/ */
png_voidp PNGAPI png_voidp PNGAPI
png_get_error_ptr(png_structp png_ptr) png_get_error_ptr(png_const_structp png_ptr)
{ {
if (png_ptr == NULL) if (png_ptr == NULL)
return NULL; return NULL;
return ((png_voidp)png_ptr->error_ptr); return ((png_voidp)png_ptr->error_ptr);
} }
@ -395,7 +439,8 @@ png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode)
if (png_ptr != NULL) if (png_ptr != NULL)
{ {
png_ptr->flags &= png_ptr->flags &=
((~(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode); ((~(PNG_FLAG_STRIP_ERROR_NUMBERS |
PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
} }
} }
#endif #endif

File diff suppressed because it is too large Load Diff

270
src/libpng/pnginfo.h Normal file
View File

@ -0,0 +1,270 @@
/* pnginfo.h - header file for PNG reference library
*
* Copyright (c) 1998-2011 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.)
*
* Last changed in libpng 1.5.0 [January 6, 2011]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*/
/* png_info is a structure that holds the information in a PNG file so
* that the application can find out the characteristics of the image.
* If you are reading the file, this structure will tell you what is
* in the PNG file. If you are writing the file, fill in the information
* you want to put into the PNG file, using png_set_*() functions, then
* call png_write_info().
*
* The names chosen should be very close to the PNG specification, so
* consult that document for information about the meaning of each field.
*
* With libpng < 0.95, it was only possible to directly set and read the
* the values in the png_info_struct, which meant that the contents and
* order of the values had to remain fixed. With libpng 0.95 and later,
* however, there are now functions that abstract the contents of
* png_info_struct from the application, so this makes it easier to use
* libpng with dynamic libraries, and even makes it possible to use
* libraries that don't have all of the libpng ancillary chunk-handing
* functionality. In libpng-1.5.0 this was moved into a separate private
* file that is not visible to applications.
*
* The following members may have allocated storage attached that should be
* cleaned up before the structure is discarded: palette, trans, text,
* pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile,
* splt_palettes, scal_unit, row_pointers, and unknowns. By default, these
* are automatically freed when the info structure is deallocated, if they were
* allocated internally by libpng. This behavior can be changed by means
* of the png_data_freer() function.
*
* More allocation details: all the chunk-reading functions that
* change these members go through the corresponding png_set_*
* functions. A function to clear these members is available: see
* png_free_data(). The png_set_* functions do not depend on being
* able to point info structure members to any of the storage they are
* passed (they make their own copies), EXCEPT that the png_set_text
* functions use the same storage passed to them in the text_ptr or
* itxt_ptr structure argument, and the png_set_rows and png_set_unknowns
* functions do not make their own copies.
*/
#ifndef PNGINFO_H
#define PNGINFO_H
struct png_info_def
{
/* the following are necessary for every PNG file */
png_uint_32 width; /* width of image in pixels (from IHDR) */
png_uint_32 height; /* height of image in pixels (from IHDR) */
png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */
png_size_t rowbytes; /* bytes needed to hold an untransformed row */
png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */
png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */
png_uint_16 num_trans; /* number of transparent palette color (tRNS) */
png_byte bit_depth; /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */
png_byte color_type; /* see PNG_COLOR_TYPE_ below (from IHDR) */
/* The following three should have been named *_method not *_type */
png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */
png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */
png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
/* The following is informational only on read, and not used on writes. */
png_byte channels; /* number of data channels per pixel (1, 2, 3, 4) */
png_byte pixel_depth; /* number of bits per pixel */
png_byte spare_byte; /* to align the data, and for future use */
png_byte signature[8]; /* magic bytes read by libpng from start of file */
/* The rest of the data is optional. If you are reading, check the
* valid field to see if the information in these are valid. If you
* are writing, set the valid field to those chunks you want written,
* and initialize the appropriate fields below.
*/
#if defined(PNG_gAMA_SUPPORTED)
/* The gAMA chunk describes the gamma characteristics of the system
* on which the image was created, normally in the range [1.0, 2.5].
* Data is valid if (valid & PNG_INFO_gAMA) is non-zero.
*/
png_fixed_point gamma;
#endif
#ifdef PNG_sRGB_SUPPORTED
/* GR-P, 0.96a */
/* Data valid if (valid & PNG_INFO_sRGB) non-zero. */
png_byte srgb_intent; /* sRGB rendering intent [0, 1, 2, or 3] */
#endif
#ifdef PNG_TEXT_SUPPORTED
/* The tEXt, and zTXt chunks contain human-readable textual data in
* uncompressed, compressed, and optionally compressed forms, respectively.
* The data in "text" is an array of pointers to uncompressed,
* null-terminated C strings. Each chunk has a keyword that describes the
* textual data contained in that chunk. Keywords are not required to be
* unique, and the text string may be empty. Any number of text chunks may
* be in an image.
*/
int num_text; /* number of comments read or comments to write */
int max_text; /* current size of text array */
png_textp text; /* array of comments read or comments to write */
#endif /* PNG_TEXT_SUPPORTED */
#ifdef PNG_tIME_SUPPORTED
/* The tIME chunk holds the last time the displayed image data was
* modified. See the png_time struct for the contents of this struct.
*/
png_time mod_time;
#endif
#ifdef PNG_sBIT_SUPPORTED
/* The sBIT chunk specifies the number of significant high-order bits
* in the pixel data. Values are in the range [1, bit_depth], and are
* only specified for the channels in the pixel data. The contents of
* the low-order bits is not specified. Data is valid if
* (valid & PNG_INFO_sBIT) is non-zero.
*/
png_color_8 sig_bit; /* significant bits in color channels */
#endif
#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \
defined(PNG_READ_BACKGROUND_SUPPORTED)
/* The tRNS chunk supplies transparency data for paletted images and
* other image types that don't need a full alpha channel. There are
* "num_trans" transparency values for a paletted image, stored in the
* same order as the palette colors, starting from index 0. Values
* for the data are in the range [0, 255], ranging from fully transparent
* to fully opaque, respectively. For non-paletted images, there is a
* single color specified that should be treated as fully transparent.
* Data is valid if (valid & PNG_INFO_tRNS) is non-zero.
*/
png_bytep trans; /* alpha values for paletted image */
png_bytep trans_alpha; /* alpha values for paletted image */
png_color_16 trans_color; /* transparent color for non-palette image */
#endif
#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
/* The bKGD chunk gives the suggested image background color if the
* display program does not have its own background color and the image
* is needs to composited onto a background before display. The colors
* in "background" are normally in the same color space/depth as the
* pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero.
*/
png_color_16 background;
#endif
#ifdef PNG_oFFs_SUPPORTED
/* The oFFs chunk gives the offset in "offset_unit_type" units rightwards
* and downwards from the top-left corner of the display, page, or other
* application-specific co-ordinate space. See the PNG_OFFSET_ defines
* below for the unit types. Valid if (valid & PNG_INFO_oFFs) non-zero.
*/
png_int_32 x_offset; /* x offset on page */
png_int_32 y_offset; /* y offset on page */
png_byte offset_unit_type; /* offset units type */
#endif
#ifdef PNG_pHYs_SUPPORTED
/* The pHYs chunk gives the physical pixel density of the image for
* display or printing in "phys_unit_type" units (see PNG_RESOLUTION_
* defines below). Data is valid if (valid & PNG_INFO_pHYs) is non-zero.
*/
png_uint_32 x_pixels_per_unit; /* horizontal pixel density */
png_uint_32 y_pixels_per_unit; /* vertical pixel density */
png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
#endif
#ifdef PNG_hIST_SUPPORTED
/* The hIST chunk contains the relative frequency or importance of the
* various palette entries, so that a viewer can intelligently select a
* reduced-color palette, if required. Data is an array of "num_palette"
* values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST)
* is non-zero.
*/
png_uint_16p hist;
#endif
#ifdef PNG_cHRM_SUPPORTED
/* The cHRM chunk describes the CIE color characteristics of the monitor
* on which the PNG was created. This data allows the viewer to do gamut
* mapping of the input image to ensure that the viewer sees the same
* colors in the image as the creator. Values are in the range
* [0.0, 0.8]. Data valid if (valid & PNG_INFO_cHRM) non-zero.
*/
png_fixed_point x_white;
png_fixed_point y_white;
png_fixed_point x_red;
png_fixed_point y_red;
png_fixed_point x_green;
png_fixed_point y_green;
png_fixed_point x_blue;
png_fixed_point y_blue;
#endif
#ifdef PNG_pCAL_SUPPORTED
/* The pCAL chunk describes a transformation between the stored pixel
* values and original physical data values used to create the image.
* The integer range [0, 2^bit_depth - 1] maps to the floating-point
* range given by [pcal_X0, pcal_X1], and are further transformed by a
* (possibly non-linear) transformation function given by "pcal_type"
* and "pcal_params" into "pcal_units". Please see the PNG_EQUATION_
* defines below, and the PNG-Group's PNG extensions document for a
* complete description of the transformations and how they should be
* implemented, and for a description of the ASCII parameter strings.
* Data values are valid if (valid & PNG_INFO_pCAL) non-zero.
*/
png_charp pcal_purpose; /* pCAL chunk description string */
png_int_32 pcal_X0; /* minimum value */
png_int_32 pcal_X1; /* maximum value */
png_charp pcal_units; /* Latin-1 string giving physical units */
png_charpp pcal_params; /* ASCII strings containing parameter values */
png_byte pcal_type; /* equation type (see PNG_EQUATION_ below) */
png_byte pcal_nparams; /* number of parameters given in pcal_params */
#endif
/* New members added in libpng-1.0.6 */
png_uint_32 free_me; /* flags items libpng is responsible for freeing */
#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) || \
defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
/* Storage for unknown chunks that the library doesn't recognize. */
png_unknown_chunkp unknown_chunks;
int unknown_chunks_num;
#endif
#ifdef PNG_iCCP_SUPPORTED
/* iCCP chunk data. */
png_charp iccp_name; /* profile name */
png_bytep iccp_profile; /* International Color Consortium profile data */
png_uint_32 iccp_proflen; /* ICC profile data length */
png_byte iccp_compression; /* Always zero */
#endif
#ifdef PNG_sPLT_SUPPORTED
/* Data on sPLT chunks (there may be more than one). */
png_sPLT_tp splt_palettes;
png_uint_32 splt_palettes_num;
#endif
#ifdef PNG_sCAL_SUPPORTED
/* The sCAL chunk describes the actual physical dimensions of the
* subject matter of the graphic. The chunk contains a unit specification
* a byte value, and two ASCII strings representing floating-point
* values. The values are width and height corresponsing to one pixel
* in the image. Data values are valid if (valid & PNG_INFO_sCAL) is
* non-zero.
*/
png_byte scal_unit; /* unit of physical scale */
png_charp scal_s_width; /* string containing height */
png_charp scal_s_height; /* string containing width */
#endif
#ifdef PNG_INFO_IMAGE_SUPPORTED
/* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS)
non-zero */
/* Data valid if (valid & PNG_INFO_IDAT) non-zero */
png_bytepp row_pointers; /* the image bits */
#endif
};
#endif /* PNGINFO_H */

174
src/libpng/pnglibconf.h Normal file
View File

@ -0,0 +1,174 @@
/* pnglibconf.h - library build configuration */
/* libpng version 1.5.0 - January 6, 2011 */
/* Copyright (c) 1998-2011 Glenn Randers-Pehrson */
/* This code is released under the libpng license. */
/* For conditions of distribution and use, see the disclaimer */
/* and license in png.h */
/* pnglibconf.h */
/* Machine generated file: DO NOT EDIT */
/* Derived from: scripts/pnglibconf.dfa */
#ifndef PNGLCONF_H
#define PNGLCONF_H
/* settings */
#define PNG_ZBUF_SIZE 8192
#define PNG_QUANTIZE_GREEN_BITS 5
#define PNG_DEFAULT_READ_MACROS 1
#define PNG_USER_CHUNK_CACHE_MAX 0
#define PNG_USER_WIDTH_MAX 1000000L
#define PNG_sCAL_PRECISION 5
#define PNG_API_RULE 0
#define PNG_GAMMA_THRESHOLD_FIXED 5000
#define PNG_COST_SHIFT 3
#define PNG_WEIGHT_SHIFT 8
#define PNG_USER_HEIGHT_MAX 1000000L
#define PNG_QUANTIZE_RED_BITS 5
#define PNG_MAX_GAMMA_8 11
#define PNG_CALLOC_SUPPORTED
#define PNG_QUANTIZE_BLUE_BITS 5
#define PNG_USER_CHUNK_MALLOC_MAX 0
/* end of settings */
/* options */
#define PNG_WARNINGS_SUPPORTED
#define PNG_INFO_IMAGE_SUPPORTED
#define PNG_READ_SUPPORTED
#define PNG_SETJMP_SUPPORTED
#define PNG_READ_QUANTIZE_SUPPORTED
#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
#define PNG_POINTER_INDEXING_SUPPORTED
//#define PNG_MNG_FEATURES_SUPPORTED
#define PNG_INCH_CONVERSIONS_SUPPORTED
#define PNG_IO_STATE_SUPPORTED
#define PNG_FLOATING_ARITHMETIC_SUPPORTED
#define PNG_FIXED_POINT_SUPPORTED
#define PNG_WRITE_SUPPORTED
/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/
#define PNG_STDIO_SUPPORTED
#define PNG_FLOATING_POINT_SUPPORTED
//#define PNG_PROGRESSIVE_READ_SUPPORTED
#define PNG_READ_16BIT_SUPPORTED
#define PNG_WRITE_INTERLACING_SUPPORTED
#define PNG_READ_INT_FUNCTIONS_SUPPORTED
#define PNG_READ_COMPOSITE_NODIV_SUPPORTED
#define PNG_USER_LIMITS_SUPPORTED
#define PNG_SEQUENTIAL_READ_SUPPORTED
#define PNG_CONSOLE_IO_SUPPORTED
/*#undef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED*/
#define PNG_ALIGN_MEMORY_SUPPORTED
#define PNG_BENIGN_ERRORS_SUPPORTED
#define PNG_EASY_ACCESS_SUPPORTED
#define PNG_USER_MEM_SUPPORTED
#define PNG_WRITE_TRANSFORMS_SUPPORTED
#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
#define PNG_READ_sCAL_SUPPORTED
#define PNG_READ_INTERLACING_SUPPORTED
#define PNG_READ_TRANSFORMS_SUPPORTED
#define PNG_WRITE_PACK_SUPPORTED
#define PNG_ERROR_TEXT_SUPPORTED
#define PNG_READ_pHYs_SUPPORTED
#define PNG_WRITE_USER_TRANSFORM_SUPPORTED
#define PNG_READ_STRIP_ALPHA_SUPPORTED
#define PNG_READ_OPT_PLTE_SUPPORTED
#define PNG_WRITE_16BIT_SUPPORTED
#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_READ_oFFs_SUPPORTED
#define PNG_READ_16_TO_8_SUPPORTED
#define PNG_READ_GRAY_TO_RGB_SUPPORTED
#define PNG_READ_SWAP_SUPPORTED
#define PNG_READ_SHIFT_SUPPORTED
#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED
#define PNG_READ_PACKSWAP_SUPPORTED
#define PNG_READ_USER_TRANSFORM_SUPPORTED
#define PNG_WRITE_BGR_SUPPORTED
#define PNG_READ_bKGD_SUPPORTED
#define PNG_READ_sRGB_SUPPORTED
#define PNG_WRITE_SWAP_SUPPORTED
#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_READ_hIST_SUPPORTED
#define PNG_READ_TEXT_SUPPORTED
#define PNG_WRITE_SWAP_ALPHA_SUPPORTED
#define PNG_TIME_RFC1123_SUPPORTED
#define PNG_READ_cHRM_SUPPORTED
#define PNG_READ_tRNS_SUPPORTED
#define PNG_READ_BACKGROUND_SUPPORTED
#define PNG_WRITE_INVERT_SUPPORTED
#define PNG_WRITE_FLUSH_SUPPORTED
#define PNG_READ_FILLER_SUPPORTED
#define PNG_READ_tEXt_SUPPORTED
#define PNG_READ_pCAL_SUPPORTED
#define PNG_READ_sPLT_SUPPORTED
#define PNG_READ_SWAP_ALPHA_SUPPORTED
#define PNG_SET_USER_LIMITS_SUPPORTED
#define PNG_WRITE_FILTER_SUPPORTED
#define PNG_USER_TRANSFORM_INFO_SUPPORTED
#define PNG_READ_INVERT_ALPHA_SUPPORTED
#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
#define PNG_WRITE_SHIFT_SUPPORTED
#define PNG_READ_tIME_SUPPORTED
#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
#define PNG_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_WRITE_FILLER_SUPPORTED
#define PNG_WRITE_tIME_SUPPORTED
#define PNG_READ_BGR_SUPPORTED
#define PNG_READ_EXPAND_16_SUPPORTED
#define PNG_WRITE_INVERT_ALPHA_SUPPORTED
#define PNG_READ_zTXt_SUPPORTED
#define PNG_READ_RGB_TO_GRAY_SUPPORTED
#define PNG_READ_GAMMA_SUPPORTED
#define PNG_16BIT_SUPPORTED
#define PNG_CONVERT_tIME_SUPPORTED
#define PNG_USER_TRANSFORM_PTR_SUPPORTED
#define PNG_READ_PACK_SUPPORTED
#define PNG_WRITE_PACKSWAP_SUPPORTED
#define PNG_READ_sBIT_SUPPORTED
#define PNG_SET_CHUNK_CACHE_LIMIT_SUPPORTED
#define PNG_READ_iCCP_SUPPORTED
#define PNG_READ_gAMA_SUPPORTED
#define PNG_READ_INVERT_SUPPORTED
#define PNG_WRITE_sBIT_SUPPORTED
#define PNG_READ_USER_CHUNKS_SUPPORTED
#define PNG_WRITE_iCCP_SUPPORTED
#define PNG_READ_EXPAND_SUPPORTED
#define PNG_WRITE_sCAL_SUPPORTED
#define PNG_WRITE_gAMA_SUPPORTED
#define PNG_WRITE_pHYs_SUPPORTED
#define PNG_READ_iTXt_SUPPORTED
#define PNG_WRITE_oFFs_SUPPORTED
#define PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
#define PNG_tIME_SUPPORTED
#define PNG_USER_CHUNKS_SUPPORTED
#define PNG_WRITE_bKGD_SUPPORTED
#define PNG_WRITE_sRGB_SUPPORTED
#define PNG_WRITE_hIST_SUPPORTED
#define PNG_WRITE_TEXT_SUPPORTED
#define PNG_WRITE_cHRM_SUPPORTED
#define PNG_WRITE_tRNS_SUPPORTED
#define PNG_WRITE_tEXt_SUPPORTED
#define PNG_WRITE_pCAL_SUPPORTED
#define PNG_WRITE_sPLT_SUPPORTED
#define PNG_sBIT_SUPPORTED
#define PNG_iCCP_SUPPORTED
#define PNG_gAMA_SUPPORTED
#define PNG_sCAL_SUPPORTED
#define PNG_pHYs_SUPPORTED
#define PNG_oFFs_SUPPORTED
#define PNG_WRITE_zTXt_SUPPORTED
#define PNG_bKGD_SUPPORTED
#define PNG_sRGB_SUPPORTED
#define PNG_TEXT_SUPPORTED
#define PNG_hIST_SUPPORTED
#define PNG_cHRM_SUPPORTED
#define PNG_tRNS_SUPPORTED
#define PNG_tEXt_SUPPORTED
#define PNG_pCAL_SUPPORTED
#define PNG_sPLT_SUPPORTED
#define PNG_WRITE_iTXt_SUPPORTED
#define PNG_SAVE_INT_32_SUPPORTED
#define PNG_CHECK_cHRM_SUPPORTED
#define PNG_zTXt_SUPPORTED
#define PNG_iTXt_SUPPORTED
/* end of options */
#endif /* PNGLCONF_H */

View File

@ -1,8 +1,8 @@
/* pngmem.c - stub functions for memory allocation /* pngmem.c - stub functions for memory allocation
* *
* Last changed in libpng 1.4.2 [May 6, 2010] * Last changed in libpng 1.5.1 [February 3, 2011]
* Copyright (c) 1998-2010 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
@ -17,27 +17,27 @@
* identify the replacement functions. * identify the replacement functions.
*/ */
#define PNG_NO_PEDANTIC_WARNINGS
#include "png.h"
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
#include "pngpriv.h" #include "pngpriv.h"
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
/* Borland DOS special memory handler */ /* Borland DOS special memory handler */
#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
/* If you change this, be sure to change the one in png.h also */ /* If you change this, be sure to change the one in png.h also */
/* Allocate memory for a png_struct. The malloc and memset can be replaced /* Allocate memory for a png_struct. The malloc and memset can be replaced
by a single call to calloc() if this is thought to improve performance. */ by a single call to calloc() if this is thought to improve performance. */
png_voidp /* PRIVATE */ PNG_FUNCTION(png_voidp /* PRIVATE */,
png_create_struct(int type) png_create_struct,(int type),PNG_ALLOCATED)
{ {
# ifdef PNG_USER_MEM_SUPPORTED # ifdef PNG_USER_MEM_SUPPORTED
return (png_create_struct_2(type, NULL, NULL)); return (png_create_struct_2(type, NULL, NULL));
} }
/* Alternate version of png_create_struct, for use with user-defined malloc. */ /* Alternate version of png_create_struct, for use with user-defined malloc. */
png_voidp /* PRIVATE */ PNG_FUNCTION(png_voidp /* PRIVATE */,
png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr) png_create_struct_2,(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr),
PNG_ALLOCATED)
{ {
# endif /* PNG_USER_MEM_SUPPORTED */ # endif /* PNG_USER_MEM_SUPPORTED */
png_size_t size; png_size_t size;
@ -45,8 +45,10 @@ png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
if (type == PNG_STRUCT_INFO) if (type == PNG_STRUCT_INFO)
size = png_sizeof(png_info); size = png_sizeof(png_info);
else if (type == PNG_STRUCT_PNG) else if (type == PNG_STRUCT_PNG)
size = png_sizeof(png_struct); size = png_sizeof(png_struct);
else else
return (png_get_copyright(NULL)); return (png_get_copyright(NULL));
@ -58,11 +60,13 @@ png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
png_ptr->mem_ptr=mem_ptr; png_ptr->mem_ptr=mem_ptr;
struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size); struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size);
} }
else else
# endif /* PNG_USER_MEM_SUPPORTED */ # endif /* PNG_USER_MEM_SUPPORTED */
struct_ptr = (png_voidp)farmalloc(size); struct_ptr = (png_voidp)farmalloc(size);
if (struct_ptr != NULL) if (struct_ptr != NULL)
png_memset(struct_ptr, 0, size); png_memset(struct_ptr, 0, size);
return (struct_ptr); return (struct_ptr);
} }
@ -91,6 +95,7 @@ png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
(*(free_fn))(png_ptr, struct_ptr); (*(free_fn))(png_ptr, struct_ptr);
return; return;
} }
# endif /* PNG_USER_MEM_SUPPORTED */ # endif /* PNG_USER_MEM_SUPPORTED */
farfree (struct_ptr); farfree (struct_ptr);
} }
@ -115,19 +120,21 @@ png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
* result, we would be truncating potentially larger memory requests * result, we would be truncating potentially larger memory requests
* (which should cause a fatal error) and introducing major problems. * (which should cause a fatal error) and introducing major problems.
*/ */
png_voidp PNGAPI PNG_FUNCTION(png_voidp,PNGAPI
png_calloc(png_structp png_ptr, png_alloc_size_t size) png_calloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
{ {
png_voidp ret; png_voidp ret;
ret = (png_malloc(png_ptr, size)); ret = (png_malloc(png_ptr, size));
if (ret != NULL) if (ret != NULL)
png_memset(ret,0,(png_size_t)size); png_memset(ret,0,(png_size_t)size);
return (ret); return (ret);
} }
png_voidp PNGAPI PNG_FUNCTION(png_voidp,PNGAPI
png_malloc(png_structp png_ptr, png_alloc_size_t size) png_malloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
{ {
png_voidp ret; png_voidp ret;
@ -137,15 +144,18 @@ png_malloc(png_structp png_ptr, png_alloc_size_t size)
# ifdef PNG_USER_MEM_SUPPORTED # ifdef PNG_USER_MEM_SUPPORTED
if (png_ptr->malloc_fn != NULL) if (png_ptr->malloc_fn != NULL)
ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size)); ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
else else
ret = (png_malloc_default(png_ptr, size)); ret = (png_malloc_default(png_ptr, size));
if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out of memory"); png_error(png_ptr, "Out of memory");
return (ret); return (ret);
} }
png_voidp PNGAPI PNG_FUNCTION(png_voidp,PNGAPI
png_malloc_default(png_structp png_ptr, png_alloc_size_t size) png_malloc_default,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
{ {
png_voidp ret; png_voidp ret;
# endif /* PNG_USER_MEM_SUPPORTED */ # endif /* PNG_USER_MEM_SUPPORTED */
@ -159,11 +169,13 @@ png_malloc_default(png_structp png_ptr, png_alloc_size_t size)
png_warning(png_ptr, "Cannot Allocate > 64K"); png_warning(png_ptr, "Cannot Allocate > 64K");
ret = NULL; ret = NULL;
} }
else else
# endif # endif
if (size != (size_t)size) if (size != (size_t)size)
ret = NULL; ret = NULL;
else if (size == (png_uint_32)65536L) else if (size == (png_uint_32)65536L)
{ {
if (png_ptr->offset_table == NULL) if (png_ptr->offset_table == NULL)
@ -186,10 +198,13 @@ png_malloc_default(png_structp png_ptr, png_alloc_size_t size)
if (png_ptr->zlib_window_bits > 14) if (png_ptr->zlib_window_bits > 14)
num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14)); num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
else else
num_blocks = 1; num_blocks = 1;
if (png_ptr->zlib_mem_level >= 7) if (png_ptr->zlib_mem_level >= 7)
num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7)); num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
else else
num_blocks++; num_blocks++;
@ -202,6 +217,7 @@ png_malloc_default(png_structp png_ptr, png_alloc_size_t size)
# ifndef PNG_USER_MEM_SUPPORTED # ifndef PNG_USER_MEM_SUPPORTED
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out Of Memory"); /* Note "O", "M" */ png_error(png_ptr, "Out Of Memory"); /* Note "O", "M" */
else else
png_warning(png_ptr, "Out Of Memory"); png_warning(png_ptr, "Out Of Memory");
# endif # endif
@ -214,6 +230,7 @@ png_malloc_default(png_structp png_ptr, png_alloc_size_t size)
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, png_error(png_ptr,
"Farmalloc didn't return normalized pointer"); "Farmalloc didn't return normalized pointer");
else else
png_warning(png_ptr, png_warning(png_ptr,
"Farmalloc didn't return normalized pointer"); "Farmalloc didn't return normalized pointer");
@ -230,6 +247,7 @@ png_malloc_default(png_structp png_ptr, png_alloc_size_t size)
# ifndef PNG_USER_MEM_SUPPORTED # ifndef PNG_USER_MEM_SUPPORTED
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out Of memory"); /* Note "O", "m" */ png_error(png_ptr, "Out Of memory"); /* Note "O", "m" */
else else
png_warning(png_ptr, "Out Of memory"); png_warning(png_ptr, "Out Of memory");
# endif # endif
@ -242,6 +260,7 @@ png_malloc_default(png_structp png_ptr, png_alloc_size_t size)
hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L); hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */ hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */
} }
for (i = 0; i < num_blocks; i++) for (i = 0; i < num_blocks; i++)
{ {
png_ptr->offset_table_ptr[i] = (png_bytep)hptr; png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
@ -259,6 +278,7 @@ png_malloc_default(png_structp png_ptr, png_alloc_size_t size)
# ifndef PNG_USER_MEM_SUPPORTED # ifndef PNG_USER_MEM_SUPPORTED
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out of Memory"); /* Note "o" and "M" */ png_error(png_ptr, "Out of Memory"); /* Note "o" and "M" */
else else
png_warning(png_ptr, "Out of Memory"); png_warning(png_ptr, "Out of Memory");
# endif # endif
@ -267,6 +287,7 @@ png_malloc_default(png_structp png_ptr, png_alloc_size_t size)
ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++]; ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
} }
else else
ret = farmalloc(size); ret = farmalloc(size);
@ -275,6 +296,7 @@ png_malloc_default(png_structp png_ptr, png_alloc_size_t size)
{ {
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out of memory"); /* Note "o" and "m" */ png_error(png_ptr, "Out of memory"); /* Note "o" and "m" */
else else
png_warning(png_ptr, "Out of memory"); /* Note "o" and "m" */ png_warning(png_ptr, "Out of memory"); /* Note "o" and "m" */
} }
@ -299,6 +321,7 @@ png_free(png_structp png_ptr, png_voidp ptr)
(*(png_ptr->free_fn))(png_ptr, ptr); (*(png_ptr->free_fn))(png_ptr, ptr);
return; return;
} }
else else
png_free_default(png_ptr, ptr); png_free_default(png_ptr, ptr);
} }
@ -334,18 +357,16 @@ png_free_default(png_structp png_ptr, png_voidp ptr)
} }
if (ptr != NULL) if (ptr != NULL)
{
farfree(ptr); farfree(ptr);
} }
}
#else /* Not the Borland DOS special memory handler */ #else /* Not the Borland DOS special memory handler */
/* Allocate memory for a png_struct or a png_info. The malloc and /* Allocate memory for a png_struct or a png_info. The malloc and
memset can be replaced by a single call to calloc() if this is thought memset can be replaced by a single call to calloc() if this is thought
to improve performance noticably. */ to improve performance noticably. */
png_voidp /* PRIVATE */ PNG_FUNCTION(png_voidp /* PRIVATE */,
png_create_struct(int type) png_create_struct,(int type),PNG_ALLOCATED)
{ {
# ifdef PNG_USER_MEM_SUPPORTED # ifdef PNG_USER_MEM_SUPPORTED
return (png_create_struct_2(type, NULL, NULL)); return (png_create_struct_2(type, NULL, NULL));
@ -354,8 +375,9 @@ png_create_struct(int type)
/* Allocate memory for a png_struct or a png_info. The malloc and /* Allocate memory for a png_struct or a png_info. The malloc and
memset can be replaced by a single call to calloc() if this is thought memset can be replaced by a single call to calloc() if this is thought
to improve performance noticably. */ to improve performance noticably. */
png_voidp /* PRIVATE */ PNG_FUNCTION(png_voidp /* PRIVATE */,
png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr) png_create_struct_2,(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr),
PNG_ALLOCATED)
{ {
# endif /* PNG_USER_MEM_SUPPORTED */ # endif /* PNG_USER_MEM_SUPPORTED */
png_size_t size; png_size_t size;
@ -363,8 +385,10 @@ png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
if (type == PNG_STRUCT_INFO) if (type == PNG_STRUCT_INFO)
size = png_sizeof(png_info); size = png_sizeof(png_info);
else if (type == PNG_STRUCT_PNG) else if (type == PNG_STRUCT_PNG)
size = png_sizeof(png_struct); size = png_sizeof(png_struct);
else else
return (NULL); return (NULL);
@ -375,8 +399,10 @@ png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
png_structp png_ptr = &dummy_struct; png_structp png_ptr = &dummy_struct;
png_ptr->mem_ptr=mem_ptr; png_ptr->mem_ptr=mem_ptr;
struct_ptr = (*(malloc_fn))(png_ptr, size); struct_ptr = (*(malloc_fn))(png_ptr, size);
if (struct_ptr != NULL) if (struct_ptr != NULL)
png_memset(struct_ptr, 0, size); png_memset(struct_ptr, 0, size);
return (struct_ptr); return (struct_ptr);
} }
# endif /* PNG_USER_MEM_SUPPORTED */ # endif /* PNG_USER_MEM_SUPPORTED */
@ -390,6 +416,7 @@ png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
struct_ptr = (png_voidp)malloc(size); struct_ptr = (png_voidp)malloc(size);
# endif # endif
# endif # endif
if (struct_ptr != NULL) if (struct_ptr != NULL)
png_memset(struct_ptr, 0, size); png_memset(struct_ptr, 0, size);
@ -425,11 +452,14 @@ png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
# endif /* PNG_USER_MEM_SUPPORTED */ # endif /* PNG_USER_MEM_SUPPORTED */
# if defined(__TURBOC__) && !defined(__FLAT__) # if defined(__TURBOC__) && !defined(__FLAT__)
farfree(struct_ptr); farfree(struct_ptr);
# else # else
# if defined(_MSC_VER) && defined(MAXSEG_64K) # if defined(_MSC_VER) && defined(MAXSEG_64K)
hfree(struct_ptr); hfree(struct_ptr);
# else # else
free(struct_ptr); free(struct_ptr);
# endif # endif
# endif # endif
} }
@ -442,19 +472,21 @@ png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
* have the ability to do that. * have the ability to do that.
*/ */
png_voidp PNGAPI PNG_FUNCTION(png_voidp,PNGAPI
png_calloc(png_structp png_ptr, png_alloc_size_t size) png_calloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
{ {
png_voidp ret; png_voidp ret;
ret = (png_malloc(png_ptr, size)); ret = (png_malloc(png_ptr, size));
if (ret != NULL) if (ret != NULL)
png_memset(ret,0,(png_size_t)size); png_memset(ret,0,(png_size_t)size);
return (ret); return (ret);
} }
png_voidp PNGAPI PNG_FUNCTION(png_voidp,PNGAPI
png_malloc(png_structp png_ptr, png_alloc_size_t size) png_malloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
{ {
png_voidp ret; png_voidp ret;
@ -464,15 +496,18 @@ png_malloc(png_structp png_ptr, png_alloc_size_t size)
if (png_ptr->malloc_fn != NULL) if (png_ptr->malloc_fn != NULL)
ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size)); ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
else else
ret = (png_malloc_default(png_ptr, size)); ret = (png_malloc_default(png_ptr, size));
if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out of Memory"); png_error(png_ptr, "Out of Memory");
return (ret); return (ret);
} }
png_voidp PNGAPI PNG_FUNCTION(png_voidp,PNGAPI
png_malloc_default(png_structp png_ptr, png_alloc_size_t size) png_malloc_default,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
{ {
png_voidp ret; png_voidp ret;
# endif /* PNG_USER_MEM_SUPPORTED */ # endif /* PNG_USER_MEM_SUPPORTED */
@ -486,6 +521,7 @@ png_malloc_default(png_structp png_ptr, png_alloc_size_t size)
# ifndef PNG_USER_MEM_SUPPORTED # ifndef PNG_USER_MEM_SUPPORTED
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Cannot Allocate > 64K"); png_error(png_ptr, "Cannot Allocate > 64K");
else else
# endif # endif
return NULL; return NULL;
@ -494,19 +530,25 @@ png_malloc_default(png_structp png_ptr, png_alloc_size_t size)
/* Check for overflow */ /* Check for overflow */
# if defined(__TURBOC__) && !defined(__FLAT__) # if defined(__TURBOC__) && !defined(__FLAT__)
if (size != (unsigned long)size) if (size != (unsigned long)size)
ret = NULL; ret = NULL;
else else
ret = farmalloc(size); ret = farmalloc(size);
# else # else
# if defined(_MSC_VER) && defined(MAXSEG_64K) # if defined(_MSC_VER) && defined(MAXSEG_64K)
if (size != (unsigned long)size) if (size != (unsigned long)size)
ret = NULL; ret = NULL;
else else
ret = halloc(size, 1); ret = halloc(size, 1);
# else # else
if (size != (size_t)size) if (size != (size_t)size)
ret = NULL; ret = NULL;
else else
ret = malloc((size_t)size); ret = malloc((size_t)size);
# endif # endif
@ -535,9 +577,11 @@ png_free(png_structp png_ptr, png_voidp ptr)
(*(png_ptr->free_fn))(png_ptr, ptr); (*(png_ptr->free_fn))(png_ptr, ptr);
return; return;
} }
else else
png_free_default(png_ptr, ptr); png_free_default(png_ptr, ptr);
} }
void PNGAPI void PNGAPI
png_free_default(png_structp png_ptr, png_voidp ptr) png_free_default(png_structp png_ptr, png_voidp ptr)
{ {
@ -548,15 +592,17 @@ png_free_default(png_structp png_ptr, png_voidp ptr)
# if defined(__TURBOC__) && !defined(__FLAT__) # if defined(__TURBOC__) && !defined(__FLAT__)
farfree(ptr); farfree(ptr);
# else # else
# if defined(_MSC_VER) && defined(MAXSEG_64K) # if defined(_MSC_VER) && defined(MAXSEG_64K)
hfree(ptr); hfree(ptr);
# else # else
free(ptr); free(ptr);
# endif # endif
# endif # endif
} }
#endif /* Not Borland DOS special memory handler */ #endif /* Not Borland DOS special memory handler */
/* This function was added at libpng version 1.2.3. The png_malloc_warn() /* This function was added at libpng version 1.2.3. The png_malloc_warn()
@ -564,8 +610,8 @@ png_free_default(png_structp png_ptr, png_voidp ptr)
* instead of issuing a png_error, if it fails to allocate the requested * instead of issuing a png_error, if it fails to allocate the requested
* memory. * memory.
*/ */
png_voidp PNGAPI PNG_FUNCTION(png_voidp,PNGAPI
png_malloc_warn(png_structp png_ptr, png_alloc_size_t size) png_malloc_warn,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
{ {
png_voidp ptr; png_voidp ptr;
png_uint_32 save_flags; png_uint_32 save_flags;
@ -601,10 +647,11 @@ png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
* pointer before png_write_destroy and png_read_destroy are called. * pointer before png_write_destroy and png_read_destroy are called.
*/ */
png_voidp PNGAPI png_voidp PNGAPI
png_get_mem_ptr(png_structp png_ptr) png_get_mem_ptr(png_const_structp png_ptr)
{ {
if (png_ptr == NULL) if (png_ptr == NULL)
return (NULL); return (NULL);
return ((png_voidp)png_ptr->mem_ptr); return ((png_voidp)png_ptr->mem_ptr);
} }
#endif /* PNG_USER_MEM_SUPPORTED */ #endif /* PNG_USER_MEM_SUPPORTED */

View File

@ -1,8 +1,8 @@
/* pngpread.c - read a png file in push mode /* pngpread.c - read a png file in push mode
* *
* Last changed in libpng 1.4.3 [June 26, 2010] * Last changed in libpng 1.5.2 [March 31, 2011]
* Copyright (c) 1998-2010 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
@ -11,11 +11,10 @@
* and license in png.h * and license in png.h
*/ */
#define PNG_NO_PEDANTIC_WARNINGS
#include "png.h"
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
#include "pngpriv.h" #include "pngpriv.h"
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
/* Push model modes */ /* Push model modes */
#define PNG_READ_SIG_MODE 0 #define PNG_READ_SIG_MODE 0
#define PNG_READ_CHUNK_MODE 1 #define PNG_READ_CHUNK_MODE 1
@ -42,6 +41,64 @@ png_process_data(png_structp png_ptr, png_infop info_ptr,
} }
} }
png_size_t PNGAPI
png_process_data_pause(png_structp png_ptr, int save)
{
if (png_ptr != NULL)
{
/* It's easiest for the caller if we do the save, then the caller doesn't
* have to supply the same data again:
*/
if (save)
png_push_save_buffer(png_ptr);
else
{
/* This includes any pending saved bytes: */
png_size_t remaining = png_ptr->buffer_size;
png_ptr->buffer_size = 0;
/* So subtract the saved buffer size, unless all the data
* is actually 'saved', in which case we just return 0
*/
if (png_ptr->save_buffer_size < remaining)
return remaining - png_ptr->save_buffer_size;
}
}
return 0;
}
png_uint_32 PNGAPI
png_process_data_skip(png_structp png_ptr)
{
png_uint_32 remaining = 0;
if (png_ptr != NULL && png_ptr->process_mode == PNG_SKIP_MODE &&
png_ptr->skip_length > 0)
{
/* At the end of png_process_data the buffer size must be 0 (see the loop
* above) so we can detect a broken call here:
*/
if (png_ptr->buffer_size != 0)
png_error(png_ptr,
"png_process_data_skip called inside png_process_data");
/* If is impossible for there to be a saved buffer at this point -
* otherwise we could not be in SKIP mode. This will also happen if
* png_process_skip is called inside png_process_data (but only very
* rarely.)
*/
if (png_ptr->save_buffer_size != 0)
png_error(png_ptr, "png_process_data_skip called with saved data");
remaining = png_ptr->skip_length;
png_ptr->skip_length = 0;
png_ptr->process_mode = PNG_READ_CHUNK_MODE;
}
return remaining;
}
/* What we do with the incoming data depends on what we were previously /* What we do with the incoming data depends on what we were previously
* doing before we ran out of data... * doing before we ran out of data...
*/ */
@ -135,6 +192,7 @@ png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
if (num_checked < 4 && if (num_checked < 4 &&
png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
png_error(png_ptr, "Not a PNG file"); png_error(png_ptr, "Not a PNG file");
else else
png_error(png_ptr, "PNG file corrupted by ASCII conversion"); png_error(png_ptr, "PNG file corrupted by ASCII conversion");
} }
@ -582,32 +640,45 @@ png_push_crc_finish(png_structp png_ptr)
{ {
if (png_ptr->skip_length && png_ptr->save_buffer_size) if (png_ptr->skip_length && png_ptr->save_buffer_size)
{ {
png_size_t save_size; png_size_t save_size = png_ptr->save_buffer_size;
png_uint_32 skip_length = png_ptr->skip_length;
/* We want the smaller of 'skip_length' and 'save_buffer_size', but
* they are of different types and we don't know which variable has the
* fewest bits. Carefully select the smaller and cast it to the type of
* the larger - this cannot overflow. Do not cast in the following test
* - it will break on either 16 or 64 bit platforms.
*/
if (skip_length < save_size)
save_size = (png_size_t)skip_length;
if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
save_size = (png_size_t)png_ptr->skip_length;
else else
save_size = png_ptr->save_buffer_size; skip_length = (png_uint_32)save_size;
png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
png_ptr->skip_length -= save_size; png_ptr->skip_length -= skip_length;
png_ptr->buffer_size -= save_size; png_ptr->buffer_size -= save_size;
png_ptr->save_buffer_size -= save_size; png_ptr->save_buffer_size -= save_size;
png_ptr->save_buffer_ptr += save_size; png_ptr->save_buffer_ptr += save_size;
} }
if (png_ptr->skip_length && png_ptr->current_buffer_size) if (png_ptr->skip_length && png_ptr->current_buffer_size)
{ {
png_size_t save_size; png_size_t save_size = png_ptr->current_buffer_size;
png_uint_32 skip_length = png_ptr->skip_length;
/* We want the smaller of 'skip_length' and 'current_buffer_size', here,
* the same problem exists as above and the same solution.
*/
if (skip_length < save_size)
save_size = (png_size_t)skip_length;
if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
save_size = (png_size_t)png_ptr->skip_length;
else else
save_size = png_ptr->current_buffer_size; skip_length = (png_uint_32)save_size;
png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
png_ptr->skip_length -= save_size; png_ptr->skip_length -= skip_length;
png_ptr->buffer_size -= save_size; png_ptr->buffer_size -= save_size;
png_ptr->current_buffer_size -= save_size; png_ptr->current_buffer_size -= save_size;
png_ptr->current_buffer_ptr += save_size; png_ptr->current_buffer_ptr += save_size;
@ -625,7 +696,7 @@ png_push_crc_finish(png_structp png_ptr)
} }
} }
void PNGAPI void PNGCBAPI
png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
{ {
png_bytep ptr; png_bytep ptr;
@ -640,6 +711,7 @@ png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
if (length < png_ptr->save_buffer_size) if (length < png_ptr->save_buffer_size)
save_size = length; save_size = length;
else else
save_size = png_ptr->save_buffer_size; save_size = png_ptr->save_buffer_size;
@ -702,11 +774,13 @@ png_push_save_buffer(png_structp png_ptr)
old_buffer = png_ptr->save_buffer; old_buffer = png_ptr->save_buffer;
png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr, png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,
(png_size_t)new_max); (png_size_t)new_max);
if (png_ptr->save_buffer == NULL) if (png_ptr->save_buffer == NULL)
{ {
png_free(png_ptr, old_buffer); png_free(png_ptr, old_buffer);
png_error(png_ptr, "Insufficient memory for save_buffer"); png_error(png_ptr, "Insufficient memory for save_buffer");
} }
png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size); png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
png_free(png_ptr, old_buffer); png_free(png_ptr, old_buffer);
png_ptr->save_buffer_max = new_max; png_ptr->save_buffer_max = new_max;
@ -755,8 +829,10 @@ png_push_read_IDAT(png_structp png_ptr)
if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
{ {
png_ptr->process_mode = PNG_READ_CHUNK_MODE; png_ptr->process_mode = PNG_READ_CHUNK_MODE;
if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
png_error(png_ptr, "Not enough compressed data"); png_error(png_ptr, "Not enough compressed data");
return; return;
} }
@ -764,48 +840,52 @@ png_push_read_IDAT(png_structp png_ptr)
} }
if (png_ptr->idat_size && png_ptr->save_buffer_size) if (png_ptr->idat_size && png_ptr->save_buffer_size)
{ {
png_size_t save_size; png_size_t save_size = png_ptr->save_buffer_size;
png_uint_32 idat_size = png_ptr->idat_size;
if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size) /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
{ * are of different types and we don't know which variable has the fewest
save_size = (png_size_t)png_ptr->idat_size; * bits. Carefully select the smaller and cast it to the type of the
* larger - this cannot overflow. Do not cast in the following test - it
* will break on either 16 or 64 bit platforms.
*/
if (idat_size < save_size)
save_size = (png_size_t)idat_size;
/* Check for overflow */
if ((png_uint_32)save_size != png_ptr->idat_size)
png_error(png_ptr, "save_size overflowed in pngpread");
}
else else
save_size = png_ptr->save_buffer_size; idat_size = (png_uint_32)save_size;
png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size); png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
png_ptr->idat_size -= save_size; png_ptr->idat_size -= idat_size;
png_ptr->buffer_size -= save_size; png_ptr->buffer_size -= save_size;
png_ptr->save_buffer_size -= save_size; png_ptr->save_buffer_size -= save_size;
png_ptr->save_buffer_ptr += save_size; png_ptr->save_buffer_ptr += save_size;
} }
if (png_ptr->idat_size && png_ptr->current_buffer_size) if (png_ptr->idat_size && png_ptr->current_buffer_size)
{ {
png_size_t save_size; png_size_t save_size = png_ptr->current_buffer_size;
png_uint_32 idat_size = png_ptr->idat_size;
if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size) /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
{ * are of different types and we don't know which variable has the fewest
save_size = (png_size_t)png_ptr->idat_size; * bits. Carefully select the smaller and cast it to the type of the
* larger - this cannot overflow.
*/
if (idat_size < save_size)
save_size = (png_size_t)idat_size;
/* Check for overflow */
if ((png_uint_32)save_size != png_ptr->idat_size)
png_error(png_ptr, "save_size overflowed in pngpread");
}
else else
save_size = png_ptr->current_buffer_size; idat_size = (png_uint_32)save_size;
png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size); png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
png_ptr->idat_size -= save_size; png_ptr->idat_size -= idat_size;
png_ptr->buffer_size -= save_size; png_ptr->buffer_size -= save_size;
png_ptr->current_buffer_size -= save_size; png_ptr->current_buffer_size -= save_size;
png_ptr->current_buffer_ptr += save_size; png_ptr->current_buffer_ptr += save_size;
@ -848,7 +928,7 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
int ret; int ret;
/* We have data for zlib, but we must check that zlib /* We have data for zlib, but we must check that zlib
* has somewhere to put the results. It doesn't matter * has someplace to put the results. It doesn't matter
* if we don't expect any results -- it may be the input * if we don't expect any results -- it may be the input
* data is just the LZ end code. * data is just the LZ end code.
*/ */
@ -857,15 +937,16 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
png_ptr->zstream.avail_out = png_ptr->zstream.avail_out =
(uInt) PNG_ROWBYTES(png_ptr->pixel_depth, (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
png_ptr->iwidth) + 1; png_ptr->iwidth) + 1;
png_ptr->zstream.next_out = png_ptr->row_buf; png_ptr->zstream.next_out = png_ptr->row_buf;
} }
/* Using Z_SYNC_FLUSH here means that an unterminated /* Using Z_SYNC_FLUSH here means that an unterminated
* LZ stream can still be handled (a stream with a missing * LZ stream (a stream with a missing end code) can still
* end code), otherwise (Z_NO_FLUSH) a future zlib * be handled, otherwise (Z_NO_FLUSH) a future zlib
* implementation might defer output and, therefore, * implementation might defer output and therefore
* change the current behavior. (See comments in inflate.c * change the current behavior (see comments in inflate.c
* for why this doesn't happen at present with zlib 1.2.5.) * for why this doesn't happen at present with zlib 1.2.5).
*/ */
ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH); ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
@ -881,6 +962,7 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
if (png_ptr->row_number >= png_ptr->num_rows || if (png_ptr->row_number >= png_ptr->num_rows ||
png_ptr->pass > 6) png_ptr->pass > 6)
png_warning(png_ptr, "Truncated compressed data in IDAT"); png_warning(png_ptr, "Truncated compressed data in IDAT");
else else
png_error(png_ptr, "Decompression error in IDAT"); png_error(png_ptr, "Decompression error in IDAT");
@ -901,6 +983,7 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
/* Extra data. */ /* Extra data. */
png_warning(png_ptr, "Extra compressed data in IDAT"); png_warning(png_ptr, "Extra compressed data in IDAT");
png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
/* Do no more processing; skip the unprocessed /* Do no more processing; skip the unprocessed
* input check below. * input check below.
*/ */
@ -922,7 +1005,7 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
* after the zlib end code. * after the zlib end code.
*/ */
if (png_ptr->zstream.avail_in > 0) if (png_ptr->zstream.avail_in > 0)
png_warning(png_ptr, "Extra compression data"); png_warning(png_ptr, "Extra compression data in IDAT");
} }
void /* PRIVATE */ void /* PRIVATE */
@ -943,7 +1026,7 @@ png_push_process_row(png_structp png_ptr)
png_memcpy(png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1); png_memcpy(png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1);
if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA)) if (png_ptr->transformations)
png_do_read_transformations(png_ptr); png_do_read_transformations(png_ptr);
#ifdef PNG_READ_INTERLACING_SUPPORTED #ifdef PNG_READ_INTERLACING_SUPPORTED
@ -1162,8 +1245,8 @@ png_read_push_finish_row(png_structp png_ptr)
if (png_ptr->interlaced) if (png_ptr->interlaced)
{ {
png_ptr->row_number = 0; png_ptr->row_number = 0;
png_memset(png_ptr->prev_row, 0, png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
png_ptr->rowbytes + 1);
do do
{ {
png_ptr->pass++; png_ptr->pass++;
@ -1203,8 +1286,9 @@ png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
{ {
if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
{ {
PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
png_error(png_ptr, "Out of place tEXt"); png_error(png_ptr, "Out of place tEXt");
info_ptr = info_ptr; /* To quiet some compiler warnings */ /*NOT REACHED*/
} }
#ifdef PNG_MAX_MALLOC_64K #ifdef PNG_MAX_MALLOC_64K
@ -1272,14 +1356,12 @@ png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
if (text < key + png_ptr->current_text_size) if (text < key + png_ptr->current_text_size)
text++; text++;
text_ptr = (png_textp)png_malloc(png_ptr, text_ptr = (png_textp)png_malloc(png_ptr, png_sizeof(png_text));
png_sizeof(png_text));
text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
text_ptr->key = key; text_ptr->key = key;
#ifdef PNG_iTXt_SUPPORTED text_ptr->itxt_length = 0;
text_ptr->lang = NULL; text_ptr->lang = NULL;
text_ptr->lang_key = NULL; text_ptr->lang_key = NULL;
#endif
text_ptr->text = text; text_ptr->text = text;
ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
@ -1301,8 +1383,9 @@ png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
{ {
if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
{ {
PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
png_error(png_ptr, "Out of place zTXt"); png_error(png_ptr, "Out of place zTXt");
info_ptr = info_ptr; /* To quiet some compiler warnings */ /*NOT REACHED*/
} }
#ifdef PNG_MAX_MALLOC_64K #ifdef PNG_MAX_MALLOC_64K
@ -1407,6 +1490,7 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
png_free(png_ptr, text); png_free(png_ptr, text);
return; return;
} }
if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END) if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
{ {
if (text == NULL) if (text == NULL)
@ -1425,6 +1509,7 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
*(text + text_size) = '\0'; *(text + text_size) = '\0';
} }
else else
{ {
png_charp tmp; png_charp tmp;
@ -1443,6 +1528,7 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out; text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
*(text + text_size) = '\0'; *(text + text_size) = '\0';
} }
if (ret != Z_STREAM_END) if (ret != Z_STREAM_END)
{ {
png_ptr->zstream.next_out = png_ptr->zbuf; png_ptr->zstream.next_out = png_ptr->zbuf;
@ -1478,10 +1564,9 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
png_sizeof(png_text)); png_sizeof(png_text));
text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt; text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
text_ptr->key = key; text_ptr->key = key;
#ifdef PNG_iTXt_SUPPORTED text_ptr->itxt_length = 0;
text_ptr->lang = NULL; text_ptr->lang = NULL;
text_ptr->lang_key = NULL; text_ptr->lang_key = NULL;
#endif
text_ptr->text = text; text_ptr->text = text;
ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
@ -1502,8 +1587,9 @@ png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
{ {
if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
{ {
PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
png_error(png_ptr, "Out of place iTXt"); png_error(png_ptr, "Out of place iTXt");
info_ptr = info_ptr; /* To quiet some compiler warnings */ /*NOT REACHED*/
} }
#ifdef PNG_MAX_MALLOC_64K #ifdef PNG_MAX_MALLOC_64K
@ -1544,6 +1630,7 @@ png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
png_ptr->current_text_left -= text_size; png_ptr->current_text_left -= text_size;
png_ptr->current_text_ptr += text_size; png_ptr->current_text_ptr += text_size;
} }
if (!(png_ptr->current_text_left)) if (!(png_ptr->current_text_left))
{ {
png_textp text_ptr; png_textp text_ptr;
@ -1638,7 +1725,7 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
#endif #endif
png_chunk_error(png_ptr, "unknown critical chunk"); png_chunk_error(png_ptr, "unknown critical chunk");
info_ptr = info_ptr; /* To quiet some compiler warnings */ PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
} }
#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
@ -1728,8 +1815,8 @@ png_push_have_row(png_structp png_ptr, png_bytep row)
} }
void PNGAPI void PNGAPI
png_progressive_combine_row(png_structp png_ptr, png_progressive_combine_row (png_structp png_ptr, png_bytep old_row,
png_bytep old_row, png_bytep new_row) png_const_bytep new_row)
{ {
PNG_CONST int FARDATA png_pass_dsp_mask[7] = PNG_CONST int FARDATA png_pass_dsp_mask[7] =
{0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
@ -1757,7 +1844,7 @@ png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
} }
png_voidp PNGAPI png_voidp PNGAPI
png_get_progressive_ptr(png_structp png_ptr) png_get_progressive_ptr(png_const_structp png_ptr)
{ {
if (png_ptr == NULL) if (png_ptr == NULL)
return (NULL); return (NULL);

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
/* pngread.c - read a PNG file /* pngread.c - read a PNG file
* *
* Last changed in libpng 1.4.5 [December 9, 2010] * Last changed in libpng 1.5.2 [March 31, 2011]
* Copyright (c) 1998-2010 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
@ -14,16 +14,14 @@
* read a PNG file or stream. * read a PNG file or stream.
*/ */
#define PNG_NO_PEDANTIC_WARNINGS
#include "png.h"
#ifdef PNG_READ_SUPPORTED
#include "pngpriv.h" #include "pngpriv.h"
#ifdef PNG_READ_SUPPORTED
/* Create a PNG structure for reading, and allocate any memory needed. */ /* Create a PNG structure for reading, and allocate any memory needed. */
png_structp PNGAPI PNG_FUNCTION(png_structp,PNGAPI
png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr, png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
png_error_ptr error_fn, png_error_ptr warn_fn) png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)
{ {
#ifdef PNG_USER_MEM_SUPPORTED #ifdef PNG_USER_MEM_SUPPORTED
@ -34,10 +32,10 @@ png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr,
/* Alternate create PNG structure for reading, and allocate any memory /* Alternate create PNG structure for reading, and allocate any memory
* needed. * needed.
*/ */
png_structp PNGAPI PNG_FUNCTION(png_structp,PNGAPI
png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
png_malloc_ptr malloc_fn, png_free_ptr free_fn) png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
{ {
#endif /* PNG_USER_MEM_SUPPORTED */ #endif /* PNG_USER_MEM_SUPPORTED */
@ -49,7 +47,7 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
#ifdef PNG_SETJMP_SUPPORTED #ifdef PNG_SETJMP_SUPPORTED
#ifdef USE_FAR_KEYWORD #ifdef USE_FAR_KEYWORD
jmp_buf jmpbuf; jmp_buf png_jmpbuf;
#endif #endif
#endif #endif
@ -70,10 +68,12 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
#ifdef PNG_USER_LIMITS_SUPPORTED #ifdef PNG_USER_LIMITS_SUPPORTED
png_ptr->user_width_max = PNG_USER_WIDTH_MAX; png_ptr->user_width_max = PNG_USER_WIDTH_MAX;
png_ptr->user_height_max = PNG_USER_HEIGHT_MAX; png_ptr->user_height_max = PNG_USER_HEIGHT_MAX;
# ifdef PNG_USER_CHUNK_CACHE_MAX # ifdef PNG_USER_CHUNK_CACHE_MAX
/* Added at libpng-1.2.43 and 1.4.0 */ /* Added at libpng-1.2.43 and 1.4.0 */
png_ptr->user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX; png_ptr->user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
# endif # endif
# ifdef PNG_SET_USER_CHUNK_MALLOC_MAX # ifdef PNG_SET_USER_CHUNK_MALLOC_MAX
/* Added at libpng-1.2.43 and 1.4.1 */ /* Added at libpng-1.2.43 and 1.4.1 */
png_ptr->user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX; png_ptr->user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;
@ -85,13 +85,13 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
encounter a png_error() will longjmp here. Since the jmpbuf is encounter a png_error() will longjmp here. Since the jmpbuf is
then meaningless we abort instead of returning. */ then meaningless we abort instead of returning. */
#ifdef USE_FAR_KEYWORD #ifdef USE_FAR_KEYWORD
if (setjmp(jmpbuf)) if (setjmp(png_jmpbuf))
#else #else
if (setjmp(png_jmpbuf(png_ptr))) /* Sets longjmp to match setjmp */ if (setjmp(png_jmpbuf(png_ptr))) /* Sets longjmp to match setjmp */
#endif #endif
PNG_ABORT(); PNG_ABORT();
#ifdef USE_FAR_KEYWORD #ifdef USE_FAR_KEYWORD
png_memcpy(png_jmpbuf(png_ptr), jmpbuf, png_sizeof(jmp_buf)); png_memcpy(png_jmpbuf(png_ptr), png_jmpbuf, png_sizeof(jmp_buf));
#endif #endif
#endif /* PNG_SETJMP_SUPPORTED */ #endif /* PNG_SETJMP_SUPPORTED */
@ -104,12 +104,14 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
if (user_png_ver) if (user_png_ver)
{ {
i = 0; i = 0;
do do
{ {
if (user_png_ver[i] != png_libpng_ver[i]) if (user_png_ver[i] != png_libpng_ver[i])
png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
} while (png_libpng_ver[i++]); } while (png_libpng_ver[i++]);
} }
else else
png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
@ -125,25 +127,24 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
(user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) || (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
(user_png_ver[0] == '0' && user_png_ver[2] < '9')) (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
{ {
#ifdef PNG_STDIO_SUPPORTED #ifdef PNG_CONSOLE_IO_SUPPORTED
char msg[80]; char msg[80];
if (user_png_ver) if (user_png_ver)
{ {
png_snprintf(msg, 80, png_snprintf2(msg, 80,
"Application was compiled with png.h from libpng-%.20s", "Application built with libpng-%.20s"
user_png_ver); " but running with %.20s",
png_warning(png_ptr, msg); user_png_ver,
}
png_snprintf(msg, 80,
"Application is running with png.c from libpng-%.20s",
png_libpng_ver); png_libpng_ver);
png_warning(png_ptr, msg); png_warning(png_ptr, msg);
}
#else
png_warning(png_ptr,
"Incompatible libpng version in application and library");
#endif #endif
#ifdef PNG_ERROR_NUMBERS_SUPPORTED #ifdef PNG_ERROR_NUMBERS_SUPPORTED
png_ptr->flags = 0; png_ptr->flags = 0;
#endif #endif
png_warning(png_ptr,
"Incompatible libpng version in application and library");
png_cleanup_needed = 1; png_cleanup_needed = 1;
} }
@ -153,11 +154,12 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
{ {
/* Initialize zbuf - compression buffer */ /* Initialize zbuf - compression buffer */
png_ptr->zbuf_size = PNG_ZBUF_SIZE; png_ptr->zbuf_size = PNG_ZBUF_SIZE;
png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, png_ptr->zbuf_size);
png_ptr->zbuf_size);
if (png_ptr->zbuf == NULL) if (png_ptr->zbuf == NULL)
png_cleanup_needed = 1; png_cleanup_needed = 1;
} }
png_ptr->zstream.zalloc = png_zalloc; png_ptr->zstream.zalloc = png_zalloc;
png_ptr->zstream.zfree = png_zfree; png_ptr->zstream.zfree = png_zfree;
png_ptr->zstream.opaque = (voidpf)png_ptr; png_ptr->zstream.opaque = (voidpf)png_ptr;
@ -166,12 +168,24 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
{ {
switch (inflateInit(&png_ptr->zstream)) switch (inflateInit(&png_ptr->zstream))
{ {
case Z_OK: /* Do nothing */ break; case Z_OK:
break; /* Do nothing */
case Z_MEM_ERROR: case Z_MEM_ERROR:
case Z_STREAM_ERROR: png_warning(png_ptr, "zlib memory error"); png_warning(png_ptr, "zlib memory error");
png_cleanup_needed = 1; break; png_cleanup_needed = 1;
case Z_VERSION_ERROR: png_warning(png_ptr, "zlib version error"); break;
png_cleanup_needed = 1; break;
case Z_STREAM_ERROR:
png_warning(png_ptr, "zlib stream error");
png_cleanup_needed = 1;
break;
case Z_VERSION_ERROR:
png_warning(png_ptr, "zlib version error");
png_cleanup_needed = 1;
break;
default: png_warning(png_ptr, "Unknown zlib error"); default: png_warning(png_ptr, "Unknown zlib error");
png_cleanup_needed = 1; png_cleanup_needed = 1;
} }
@ -290,33 +304,42 @@ png_read_info(png_structp png_ptr, png_infop info_ptr)
if (!png_memcmp(chunk_name, png_IHDR, 4)) if (!png_memcmp(chunk_name, png_IHDR, 4))
png_handle_IHDR(png_ptr, info_ptr, length); png_handle_IHDR(png_ptr, info_ptr, length);
else if (!png_memcmp(chunk_name, png_IEND, 4)) else if (!png_memcmp(chunk_name, png_IEND, 4))
png_handle_IEND(png_ptr, info_ptr, length); png_handle_IEND(png_ptr, info_ptr, length);
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
else if (png_handle_as_unknown(png_ptr, chunk_name)) else if (png_handle_as_unknown(png_ptr, chunk_name))
{ {
if (!png_memcmp(chunk_name, png_IDAT, 4)) if (!png_memcmp(chunk_name, png_IDAT, 4))
png_ptr->mode |= PNG_HAVE_IDAT; png_ptr->mode |= PNG_HAVE_IDAT;
png_handle_unknown(png_ptr, info_ptr, length); png_handle_unknown(png_ptr, info_ptr, length);
if (!png_memcmp(chunk_name, png_PLTE, 4)) if (!png_memcmp(chunk_name, png_PLTE, 4))
png_ptr->mode |= PNG_HAVE_PLTE; png_ptr->mode |= PNG_HAVE_PLTE;
else if (!png_memcmp(chunk_name, png_IDAT, 4)) else if (!png_memcmp(chunk_name, png_IDAT, 4))
{ {
if (!(png_ptr->mode & PNG_HAVE_IHDR)) if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before IDAT"); png_error(png_ptr, "Missing IHDR before IDAT");
else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
!(png_ptr->mode & PNG_HAVE_PLTE)) !(png_ptr->mode & PNG_HAVE_PLTE))
png_error(png_ptr, "Missing PLTE before IDAT"); png_error(png_ptr, "Missing PLTE before IDAT");
break; break;
} }
} }
#endif #endif
else if (!png_memcmp(chunk_name, png_PLTE, 4)) else if (!png_memcmp(chunk_name, png_PLTE, 4))
png_handle_PLTE(png_ptr, info_ptr, length); png_handle_PLTE(png_ptr, info_ptr, length);
else if (!png_memcmp(chunk_name, png_IDAT, 4)) else if (!png_memcmp(chunk_name, png_IDAT, 4))
{ {
if (!(png_ptr->mode & PNG_HAVE_IHDR)) if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before IDAT"); png_error(png_ptr, "Missing IHDR before IDAT");
else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
!(png_ptr->mode & PNG_HAVE_PLTE)) !(png_ptr->mode & PNG_HAVE_PLTE))
png_error(png_ptr, "Missing PLTE before IDAT"); png_error(png_ptr, "Missing PLTE before IDAT");
@ -325,74 +348,92 @@ png_read_info(png_structp png_ptr, png_infop info_ptr)
png_ptr->mode |= PNG_HAVE_IDAT; png_ptr->mode |= PNG_HAVE_IDAT;
break; break;
} }
#ifdef PNG_READ_bKGD_SUPPORTED #ifdef PNG_READ_bKGD_SUPPORTED
else if (!png_memcmp(chunk_name, png_bKGD, 4)) else if (!png_memcmp(chunk_name, png_bKGD, 4))
png_handle_bKGD(png_ptr, info_ptr, length); png_handle_bKGD(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_cHRM_SUPPORTED #ifdef PNG_READ_cHRM_SUPPORTED
else if (!png_memcmp(chunk_name, png_cHRM, 4)) else if (!png_memcmp(chunk_name, png_cHRM, 4))
png_handle_cHRM(png_ptr, info_ptr, length); png_handle_cHRM(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_gAMA_SUPPORTED #ifdef PNG_READ_gAMA_SUPPORTED
else if (!png_memcmp(chunk_name, png_gAMA, 4)) else if (!png_memcmp(chunk_name, png_gAMA, 4))
png_handle_gAMA(png_ptr, info_ptr, length); png_handle_gAMA(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_hIST_SUPPORTED #ifdef PNG_READ_hIST_SUPPORTED
else if (!png_memcmp(chunk_name, png_hIST, 4)) else if (!png_memcmp(chunk_name, png_hIST, 4))
png_handle_hIST(png_ptr, info_ptr, length); png_handle_hIST(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_oFFs_SUPPORTED #ifdef PNG_READ_oFFs_SUPPORTED
else if (!png_memcmp(chunk_name, png_oFFs, 4)) else if (!png_memcmp(chunk_name, png_oFFs, 4))
png_handle_oFFs(png_ptr, info_ptr, length); png_handle_oFFs(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_pCAL_SUPPORTED #ifdef PNG_READ_pCAL_SUPPORTED
else if (!png_memcmp(chunk_name, png_pCAL, 4)) else if (!png_memcmp(chunk_name, png_pCAL, 4))
png_handle_pCAL(png_ptr, info_ptr, length); png_handle_pCAL(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_sCAL_SUPPORTED #ifdef PNG_READ_sCAL_SUPPORTED
else if (!png_memcmp(chunk_name, png_sCAL, 4)) else if (!png_memcmp(chunk_name, png_sCAL, 4))
png_handle_sCAL(png_ptr, info_ptr, length); png_handle_sCAL(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_pHYs_SUPPORTED #ifdef PNG_READ_pHYs_SUPPORTED
else if (!png_memcmp(chunk_name, png_pHYs, 4)) else if (!png_memcmp(chunk_name, png_pHYs, 4))
png_handle_pHYs(png_ptr, info_ptr, length); png_handle_pHYs(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_sBIT_SUPPORTED #ifdef PNG_READ_sBIT_SUPPORTED
else if (!png_memcmp(chunk_name, png_sBIT, 4)) else if (!png_memcmp(chunk_name, png_sBIT, 4))
png_handle_sBIT(png_ptr, info_ptr, length); png_handle_sBIT(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_sRGB_SUPPORTED #ifdef PNG_READ_sRGB_SUPPORTED
else if (!png_memcmp(chunk_name, png_sRGB, 4)) else if (!png_memcmp(chunk_name, png_sRGB, 4))
png_handle_sRGB(png_ptr, info_ptr, length); png_handle_sRGB(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_iCCP_SUPPORTED #ifdef PNG_READ_iCCP_SUPPORTED
else if (!png_memcmp(chunk_name, png_iCCP, 4)) else if (!png_memcmp(chunk_name, png_iCCP, 4))
png_handle_iCCP(png_ptr, info_ptr, length); png_handle_iCCP(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_sPLT_SUPPORTED #ifdef PNG_READ_sPLT_SUPPORTED
else if (!png_memcmp(chunk_name, png_sPLT, 4)) else if (!png_memcmp(chunk_name, png_sPLT, 4))
png_handle_sPLT(png_ptr, info_ptr, length); png_handle_sPLT(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_tEXt_SUPPORTED #ifdef PNG_READ_tEXt_SUPPORTED
else if (!png_memcmp(chunk_name, png_tEXt, 4)) else if (!png_memcmp(chunk_name, png_tEXt, 4))
png_handle_tEXt(png_ptr, info_ptr, length); png_handle_tEXt(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_tIME_SUPPORTED #ifdef PNG_READ_tIME_SUPPORTED
else if (!png_memcmp(chunk_name, png_tIME, 4)) else if (!png_memcmp(chunk_name, png_tIME, 4))
png_handle_tIME(png_ptr, info_ptr, length); png_handle_tIME(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_tRNS_SUPPORTED #ifdef PNG_READ_tRNS_SUPPORTED
else if (!png_memcmp(chunk_name, png_tRNS, 4)) else if (!png_memcmp(chunk_name, png_tRNS, 4))
png_handle_tRNS(png_ptr, info_ptr, length); png_handle_tRNS(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_zTXt_SUPPORTED #ifdef PNG_READ_zTXt_SUPPORTED
else if (!png_memcmp(chunk_name, png_zTXt, 4)) else if (!png_memcmp(chunk_name, png_zTXt, 4))
png_handle_zTXt(png_ptr, info_ptr, length); png_handle_zTXt(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_iTXt_SUPPORTED #ifdef PNG_READ_iTXt_SUPPORTED
else if (!png_memcmp(chunk_name, png_iTXt, 4)) else if (!png_memcmp(chunk_name, png_iTXt, 4))
png_handle_iTXt(png_ptr, info_ptr, length); png_handle_iTXt(png_ptr, info_ptr, length);
#endif #endif
else else
png_handle_unknown(png_ptr, info_ptr, length); png_handle_unknown(png_ptr, info_ptr, length);
} }
@ -407,11 +448,14 @@ png_read_update_info(png_structp png_ptr, png_infop info_ptr)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
png_read_start_row(png_ptr); png_read_start_row(png_ptr);
else else
png_warning(png_ptr, png_warning(png_ptr,
"Ignoring extra png_read_update_info() call; row buffer not reallocated"); "Ignoring extra png_read_update_info() call;"
" row buffer not reallocated");
png_read_transform_info(png_ptr, info_ptr); png_read_transform_info(png_ptr, info_ptr);
} }
@ -429,8 +473,13 @@ png_start_read_image(png_structp png_ptr)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
png_read_start_row(png_ptr); png_read_start_row(png_ptr);
else
png_warning(png_ptr,
"Ignoring extra png_start_read_image() call;"
" row buffer not reallocated");
} }
#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
@ -439,9 +488,11 @@ void PNGAPI
png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
{ {
PNG_IDAT; PNG_IDAT;
#ifdef PNG_READ_INTERLACING_SUPPORTED
PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
0xff}; 0xff};
PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}; PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
#endif
int ret; int ret;
if (png_ptr == NULL) if (png_ptr == NULL)
@ -452,6 +503,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
png_read_start_row(png_ptr); png_read_start_row(png_ptr);
if (png_ptr->row_number == 0 && png_ptr->pass == 0) if (png_ptr->row_number == 0 && png_ptr->pass == 0)
{ {
/* Check for transforms that have been set but were defined out */ /* Check for transforms that have been set but were defined out */
@ -459,27 +511,33 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
if (png_ptr->transformations & PNG_INVERT_MONO) if (png_ptr->transformations & PNG_INVERT_MONO)
png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined"); png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined");
#endif #endif
#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED) #if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
if (png_ptr->transformations & PNG_FILLER) if (png_ptr->transformations & PNG_FILLER)
png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined"); png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined");
#endif #endif
#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ #if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
!defined(PNG_READ_PACKSWAP_SUPPORTED) !defined(PNG_READ_PACKSWAP_SUPPORTED)
if (png_ptr->transformations & PNG_PACKSWAP) if (png_ptr->transformations & PNG_PACKSWAP)
png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined"); png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined");
#endif #endif
#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED) #if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
if (png_ptr->transformations & PNG_PACK) if (png_ptr->transformations & PNG_PACK)
png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined"); png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined");
#endif #endif
#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) #if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
if (png_ptr->transformations & PNG_SHIFT) if (png_ptr->transformations & PNG_SHIFT)
png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined"); png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined");
#endif #endif
#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED) #if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
if (png_ptr->transformations & PNG_BGR) if (png_ptr->transformations & PNG_BGR)
png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined"); png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined");
#endif #endif
#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED) #if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
if (png_ptr->transformations & PNG_SWAP_BYTES) if (png_ptr->transformations & PNG_SWAP_BYTES)
png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined"); png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined");
@ -509,6 +567,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
if (dsp_row != NULL) if (dsp_row != NULL)
png_combine_row(png_ptr, dsp_row, png_combine_row(png_ptr, dsp_row,
png_pass_dsp_mask[png_ptr->pass]); png_pass_dsp_mask[png_ptr->pass]);
png_read_finish_row(png_ptr); png_read_finish_row(png_ptr);
return; return;
} }
@ -520,6 +579,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
if (dsp_row != NULL && (png_ptr->row_number & 4)) if (dsp_row != NULL && (png_ptr->row_number & 4))
png_combine_row(png_ptr, dsp_row, png_combine_row(png_ptr, dsp_row,
png_pass_dsp_mask[png_ptr->pass]); png_pass_dsp_mask[png_ptr->pass]);
png_read_finish_row(png_ptr); png_read_finish_row(png_ptr);
return; return;
} }
@ -531,6 +591,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
if (dsp_row != NULL) if (dsp_row != NULL)
png_combine_row(png_ptr, dsp_row, png_combine_row(png_ptr, dsp_row,
png_pass_dsp_mask[png_ptr->pass]); png_pass_dsp_mask[png_ptr->pass]);
png_read_finish_row(png_ptr); png_read_finish_row(png_ptr);
return; return;
} }
@ -542,17 +603,18 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
if (dsp_row != NULL && (png_ptr->row_number & 2)) if (dsp_row != NULL && (png_ptr->row_number & 2))
png_combine_row(png_ptr, dsp_row, png_combine_row(png_ptr, dsp_row,
png_pass_dsp_mask[png_ptr->pass]); png_pass_dsp_mask[png_ptr->pass]);
png_read_finish_row(png_ptr); png_read_finish_row(png_ptr);
return; return;
} }
break; break;
case 5: case 5:
if ((png_ptr->row_number & 1) || png_ptr->width < 2) if ((png_ptr->row_number & 1) || png_ptr->width < 2)
{ {
if (dsp_row != NULL) if (dsp_row != NULL)
png_combine_row(png_ptr, dsp_row, png_combine_row(png_ptr, dsp_row,
png_pass_dsp_mask[png_ptr->pass]); png_pass_dsp_mask[png_ptr->pass]);
png_read_finish_row(png_ptr); png_read_finish_row(png_ptr);
return; return;
} }
@ -577,6 +639,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
png_ptr->zstream.avail_out = png_ptr->zstream.avail_out =
(uInt)(PNG_ROWBYTES(png_ptr->pixel_depth, (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth,
png_ptr->iwidth) + 1); png_ptr->iwidth) + 1);
do do
{ {
if (!(png_ptr->zstream.avail_in)) if (!(png_ptr->zstream.avail_in))
@ -597,7 +660,9 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
(png_size_t)png_ptr->zstream.avail_in); (png_size_t)png_ptr->zstream.avail_in);
png_ptr->idat_size -= png_ptr->zstream.avail_in; png_ptr->idat_size -= png_ptr->zstream.avail_in;
} }
ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
if (ret == Z_STREAM_END) if (ret == Z_STREAM_END)
{ {
if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in || if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
@ -607,6 +672,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
break; break;
} }
if (ret != Z_OK) if (ret != Z_OK)
png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
"Decompression error"); "Decompression error");
@ -638,7 +704,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
#endif #endif
if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA)) if (png_ptr->transformations)
png_do_read_transformations(png_ptr); png_do_read_transformations(png_ptr);
#ifdef PNG_READ_INTERLACING_SUPPORTED #ifdef PNG_READ_INTERLACING_SUPPORTED
@ -654,17 +720,18 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
png_do_read_interlace(png_ptr); png_do_read_interlace(png_ptr);
if (dsp_row != NULL) if (dsp_row != NULL)
png_combine_row(png_ptr, dsp_row, png_combine_row(png_ptr, dsp_row, png_pass_dsp_mask[png_ptr->pass]);
png_pass_dsp_mask[png_ptr->pass]);
if (row != NULL) if (row != NULL)
png_combine_row(png_ptr, row, png_combine_row(png_ptr, row, png_pass_mask[png_ptr->pass]);
png_pass_mask[png_ptr->pass]);
} }
else else
#endif #endif
{ {
if (row != NULL) if (row != NULL)
png_combine_row(png_ptr, row, 0xff); png_combine_row(png_ptr, row, 0xff);
if (dsp_row != NULL) if (dsp_row != NULL)
png_combine_row(png_ptr, dsp_row, 0xff); png_combine_row(png_ptr, dsp_row, 0xff);
} }
@ -712,6 +779,7 @@ png_read_rows(png_structp png_ptr, png_bytepp row,
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
rp = row; rp = row;
dp = display_row; dp = display_row;
if (rp != NULL && dp != NULL) if (rp != NULL && dp != NULL)
@ -722,6 +790,7 @@ png_read_rows(png_structp png_ptr, png_bytepp row,
png_read_row(png_ptr, rptr, dptr); png_read_row(png_ptr, rptr, dptr);
} }
else if (rp != NULL) else if (rp != NULL)
for (i = 0; i < num_rows; i++) for (i = 0; i < num_rows; i++)
{ {
@ -729,6 +798,7 @@ png_read_rows(png_structp png_ptr, png_bytepp row,
png_read_row(png_ptr, rptr, NULL); png_read_row(png_ptr, rptr, NULL);
rp++; rp++;
} }
else if (dp != NULL) else if (dp != NULL)
for (i = 0; i < num_rows; i++) for (i = 0; i < num_rows; i++)
{ {
@ -765,17 +835,40 @@ png_read_image(png_structp png_ptr, png_bytepp image)
return; return;
#ifdef PNG_READ_INTERLACING_SUPPORTED #ifdef PNG_READ_INTERLACING_SUPPORTED
if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
{
pass = png_set_interlace_handling(png_ptr); pass = png_set_interlace_handling(png_ptr);
/* And make sure transforms are initialized. */
png_start_read_image(png_ptr);
}
else
{
if (png_ptr->interlaced && !(png_ptr->transformations & PNG_INTERLACE))
{
/* Caller called png_start_read_image or png_read_update_info without
* first turning on the PNG_INTERLACE transform. We can fix this here,
* but the caller should do it!
*/
png_warning(png_ptr, "Interlace handling should be turned on when "
"using png_read_image");
/* Make sure this is set correctly */
png_ptr->num_rows = png_ptr->height;
}
/* Obtain the pass number, which also turns on the PNG_INTERLACE flag in
* the above error case.
*/
pass = png_set_interlace_handling(png_ptr);
}
#else #else
if (png_ptr->interlaced) if (png_ptr->interlaced)
png_error(png_ptr, png_error(png_ptr,
"Cannot read interlaced image -- interlace handler disabled"); "Cannot read interlaced image -- interlace handler disabled");
pass = 1; pass = 1;
#endif #endif
image_height=png_ptr->height; image_height=png_ptr->height;
png_ptr->num_rows = image_height; /* Make sure this is set correctly */
for (j = 0; j < pass; j++) for (j = 0; j < pass; j++)
{ {
@ -801,6 +894,7 @@ png_read_end(png_structp png_ptr, png_infop info_ptr)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */ png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
do do
@ -865,8 +959,10 @@ png_read_end(png_structp png_ptr, png_infop info_ptr)
if (!png_memcmp(chunk_name, png_IHDR, 4)) if (!png_memcmp(chunk_name, png_IHDR, 4))
png_handle_IHDR(png_ptr, info_ptr, length); png_handle_IHDR(png_ptr, info_ptr, length);
else if (!png_memcmp(chunk_name, png_IEND, 4)) else if (!png_memcmp(chunk_name, png_IEND, 4))
png_handle_IEND(png_ptr, info_ptr, length); png_handle_IEND(png_ptr, info_ptr, length);
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
else if (png_handle_as_unknown(png_ptr, chunk_name)) else if (png_handle_as_unknown(png_ptr, chunk_name))
{ {
@ -880,6 +976,7 @@ png_read_end(png_structp png_ptr, png_infop info_ptr)
png_ptr->mode |= PNG_HAVE_PLTE; png_ptr->mode |= PNG_HAVE_PLTE;
} }
#endif #endif
else if (!png_memcmp(chunk_name, png_IDAT, 4)) else if (!png_memcmp(chunk_name, png_IDAT, 4))
{ {
/* Zero length IDATs are legal after the last IDAT has been /* Zero length IDATs are legal after the last IDAT has been
@ -887,78 +984,97 @@ png_read_end(png_structp png_ptr, png_infop info_ptr)
*/ */
if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
png_benign_error(png_ptr, "Too many IDATs found"); png_benign_error(png_ptr, "Too many IDATs found");
png_crc_finish(png_ptr, length); png_crc_finish(png_ptr, length);
} }
else if (!png_memcmp(chunk_name, png_PLTE, 4)) else if (!png_memcmp(chunk_name, png_PLTE, 4))
png_handle_PLTE(png_ptr, info_ptr, length); png_handle_PLTE(png_ptr, info_ptr, length);
#ifdef PNG_READ_bKGD_SUPPORTED #ifdef PNG_READ_bKGD_SUPPORTED
else if (!png_memcmp(chunk_name, png_bKGD, 4)) else if (!png_memcmp(chunk_name, png_bKGD, 4))
png_handle_bKGD(png_ptr, info_ptr, length); png_handle_bKGD(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_cHRM_SUPPORTED #ifdef PNG_READ_cHRM_SUPPORTED
else if (!png_memcmp(chunk_name, png_cHRM, 4)) else if (!png_memcmp(chunk_name, png_cHRM, 4))
png_handle_cHRM(png_ptr, info_ptr, length); png_handle_cHRM(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_gAMA_SUPPORTED #ifdef PNG_READ_gAMA_SUPPORTED
else if (!png_memcmp(chunk_name, png_gAMA, 4)) else if (!png_memcmp(chunk_name, png_gAMA, 4))
png_handle_gAMA(png_ptr, info_ptr, length); png_handle_gAMA(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_hIST_SUPPORTED #ifdef PNG_READ_hIST_SUPPORTED
else if (!png_memcmp(chunk_name, png_hIST, 4)) else if (!png_memcmp(chunk_name, png_hIST, 4))
png_handle_hIST(png_ptr, info_ptr, length); png_handle_hIST(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_oFFs_SUPPORTED #ifdef PNG_READ_oFFs_SUPPORTED
else if (!png_memcmp(chunk_name, png_oFFs, 4)) else if (!png_memcmp(chunk_name, png_oFFs, 4))
png_handle_oFFs(png_ptr, info_ptr, length); png_handle_oFFs(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_pCAL_SUPPORTED #ifdef PNG_READ_pCAL_SUPPORTED
else if (!png_memcmp(chunk_name, png_pCAL, 4)) else if (!png_memcmp(chunk_name, png_pCAL, 4))
png_handle_pCAL(png_ptr, info_ptr, length); png_handle_pCAL(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_sCAL_SUPPORTED #ifdef PNG_READ_sCAL_SUPPORTED
else if (!png_memcmp(chunk_name, png_sCAL, 4)) else if (!png_memcmp(chunk_name, png_sCAL, 4))
png_handle_sCAL(png_ptr, info_ptr, length); png_handle_sCAL(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_pHYs_SUPPORTED #ifdef PNG_READ_pHYs_SUPPORTED
else if (!png_memcmp(chunk_name, png_pHYs, 4)) else if (!png_memcmp(chunk_name, png_pHYs, 4))
png_handle_pHYs(png_ptr, info_ptr, length); png_handle_pHYs(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_sBIT_SUPPORTED #ifdef PNG_READ_sBIT_SUPPORTED
else if (!png_memcmp(chunk_name, png_sBIT, 4)) else if (!png_memcmp(chunk_name, png_sBIT, 4))
png_handle_sBIT(png_ptr, info_ptr, length); png_handle_sBIT(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_sRGB_SUPPORTED #ifdef PNG_READ_sRGB_SUPPORTED
else if (!png_memcmp(chunk_name, png_sRGB, 4)) else if (!png_memcmp(chunk_name, png_sRGB, 4))
png_handle_sRGB(png_ptr, info_ptr, length); png_handle_sRGB(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_iCCP_SUPPORTED #ifdef PNG_READ_iCCP_SUPPORTED
else if (!png_memcmp(chunk_name, png_iCCP, 4)) else if (!png_memcmp(chunk_name, png_iCCP, 4))
png_handle_iCCP(png_ptr, info_ptr, length); png_handle_iCCP(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_sPLT_SUPPORTED #ifdef PNG_READ_sPLT_SUPPORTED
else if (!png_memcmp(chunk_name, png_sPLT, 4)) else if (!png_memcmp(chunk_name, png_sPLT, 4))
png_handle_sPLT(png_ptr, info_ptr, length); png_handle_sPLT(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_tEXt_SUPPORTED #ifdef PNG_READ_tEXt_SUPPORTED
else if (!png_memcmp(chunk_name, png_tEXt, 4)) else if (!png_memcmp(chunk_name, png_tEXt, 4))
png_handle_tEXt(png_ptr, info_ptr, length); png_handle_tEXt(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_tIME_SUPPORTED #ifdef PNG_READ_tIME_SUPPORTED
else if (!png_memcmp(chunk_name, png_tIME, 4)) else if (!png_memcmp(chunk_name, png_tIME, 4))
png_handle_tIME(png_ptr, info_ptr, length); png_handle_tIME(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_tRNS_SUPPORTED #ifdef PNG_READ_tRNS_SUPPORTED
else if (!png_memcmp(chunk_name, png_tRNS, 4)) else if (!png_memcmp(chunk_name, png_tRNS, 4))
png_handle_tRNS(png_ptr, info_ptr, length); png_handle_tRNS(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_zTXt_SUPPORTED #ifdef PNG_READ_zTXt_SUPPORTED
else if (!png_memcmp(chunk_name, png_zTXt, 4)) else if (!png_memcmp(chunk_name, png_zTXt, 4))
png_handle_zTXt(png_ptr, info_ptr, length); png_handle_zTXt(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_iTXt_SUPPORTED #ifdef PNG_READ_iTXt_SUPPORTED
else if (!png_memcmp(chunk_name, png_iTXt, 4)) else if (!png_memcmp(chunk_name, png_iTXt, 4))
png_handle_iTXt(png_ptr, info_ptr, length); png_handle_iTXt(png_ptr, info_ptr, length);
#endif #endif
else else
png_handle_unknown(png_ptr, info_ptr, length); png_handle_unknown(png_ptr, info_ptr, length);
} while (!(png_ptr->mode & PNG_HAVE_IEND)); } while (!(png_ptr->mode & PNG_HAVE_IEND));
@ -1065,31 +1181,38 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr,
png_free(png_ptr, png_ptr->big_row_buf); png_free(png_ptr, png_ptr->big_row_buf);
png_free(png_ptr, png_ptr->prev_row); png_free(png_ptr, png_ptr->prev_row);
png_free(png_ptr, png_ptr->chunkdata); png_free(png_ptr, png_ptr->chunkdata);
#ifdef PNG_READ_QUANTIZE_SUPPORTED #ifdef PNG_READ_QUANTIZE_SUPPORTED
png_free(png_ptr, png_ptr->palette_lookup); png_free(png_ptr, png_ptr->palette_lookup);
png_free(png_ptr, png_ptr->quantize_index); png_free(png_ptr, png_ptr->quantize_index);
#endif #endif
#ifdef PNG_READ_GAMMA_SUPPORTED #ifdef PNG_READ_GAMMA_SUPPORTED
png_free(png_ptr, png_ptr->gamma_table); png_free(png_ptr, png_ptr->gamma_table);
#endif #endif
#ifdef PNG_READ_BACKGROUND_SUPPORTED #ifdef PNG_READ_BACKGROUND_SUPPORTED
png_free(png_ptr, png_ptr->gamma_from_1); png_free(png_ptr, png_ptr->gamma_from_1);
png_free(png_ptr, png_ptr->gamma_to_1); png_free(png_ptr, png_ptr->gamma_to_1);
#endif #endif
if (png_ptr->free_me & PNG_FREE_PLTE) if (png_ptr->free_me & PNG_FREE_PLTE)
png_zfree(png_ptr, png_ptr->palette); png_zfree(png_ptr, png_ptr->palette);
png_ptr->free_me &= ~PNG_FREE_PLTE; png_ptr->free_me &= ~PNG_FREE_PLTE;
#if defined(PNG_tRNS_SUPPORTED) || \ #if defined(PNG_tRNS_SUPPORTED) || \
defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
if (png_ptr->free_me & PNG_FREE_TRNS) if (png_ptr->free_me & PNG_FREE_TRNS)
png_free(png_ptr, png_ptr->trans_alpha); png_free(png_ptr, png_ptr->trans_alpha);
png_ptr->free_me &= ~PNG_FREE_TRNS; png_ptr->free_me &= ~PNG_FREE_TRNS;
#endif #endif
#ifdef PNG_READ_hIST_SUPPORTED #ifdef PNG_READ_hIST_SUPPORTED
if (png_ptr->free_me & PNG_FREE_HIST) if (png_ptr->free_me & PNG_FREE_HIST)
png_free(png_ptr, png_ptr->hist); png_free(png_ptr, png_ptr->hist);
png_ptr->free_me &= ~PNG_FREE_HIST; png_ptr->free_me &= ~PNG_FREE_HIST;
#endif #endif
#ifdef PNG_READ_GAMMA_SUPPORTED #ifdef PNG_READ_GAMMA_SUPPORTED
if (png_ptr->gamma_16_table != NULL) if (png_ptr->gamma_16_table != NULL)
{ {
@ -1101,6 +1224,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr,
} }
png_free(png_ptr, png_ptr->gamma_16_table); png_free(png_ptr, png_ptr->gamma_16_table);
} }
#ifdef PNG_READ_BACKGROUND_SUPPORTED #ifdef PNG_READ_BACKGROUND_SUPPORTED
if (png_ptr->gamma_16_from_1 != NULL) if (png_ptr->gamma_16_from_1 != NULL)
{ {
@ -1124,11 +1248,13 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr,
} }
#endif #endif
#endif #endif
#ifdef PNG_TIME_RFC1123_SUPPORTED #ifdef PNG_TIME_RFC1123_SUPPORTED
png_free(png_ptr, png_ptr->time_buffer); png_free(png_ptr, png_ptr->time_buffer);
#endif #endif
inflateEnd(&png_ptr->zstream); inflateEnd(&png_ptr->zstream);
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
png_free(png_ptr, png_ptr->save_buffer); png_free(png_ptr, png_ptr->save_buffer);
#endif #endif
@ -1143,7 +1269,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr,
* being used again. * being used again.
*/ */
#ifdef PNG_SETJMP_SUPPORTED #ifdef PNG_SETJMP_SUPPORTED
png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf)); png_memcpy(tmp_jmp, png_ptr->png_jmpbuf, png_sizeof(jmp_buf));
#endif #endif
error_fn = png_ptr->error_fn; error_fn = png_ptr->error_fn;
@ -1163,7 +1289,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr,
#endif #endif
#ifdef PNG_SETJMP_SUPPORTED #ifdef PNG_SETJMP_SUPPORTED
png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf)); png_memcpy(png_ptr->png_jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
#endif #endif
} }
@ -1173,6 +1299,7 @@ png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
{ {
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
png_ptr->read_row_fn = read_row_fn; png_ptr->read_row_fn = read_row_fn;
} }
@ -1186,7 +1313,7 @@ png_read_png(png_structp png_ptr, png_infop info_ptr,
{ {
int row; int row;
if (png_ptr == NULL) if (png_ptr == NULL || info_ptr == NULL)
return; return;
/* png_read_info() gives us all of the information from the /* png_read_info() gives us all of the information from the
@ -1268,44 +1395,44 @@ png_read_png(png_structp png_ptr, png_infop info_ptr,
#endif #endif
#ifdef PNG_READ_BGR_SUPPORTED #ifdef PNG_READ_BGR_SUPPORTED
/* Flip the RGB pixels to BGR (or RGBA to BGRA) /* Flip the RGB pixels to BGR (or RGBA to BGRA) */
*/
if (transforms & PNG_TRANSFORM_BGR) if (transforms & PNG_TRANSFORM_BGR)
png_set_bgr(png_ptr); png_set_bgr(png_ptr);
#endif #endif
#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
/* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
*/
if (transforms & PNG_TRANSFORM_SWAP_ALPHA) if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
png_set_swap_alpha(png_ptr); png_set_swap_alpha(png_ptr);
#endif #endif
#ifdef PNG_READ_SWAP_SUPPORTED #ifdef PNG_READ_SWAP_SUPPORTED
/* Swap bytes of 16 bit files to least significant byte first /* Swap bytes of 16 bit files to least significant byte first */
*/
if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
png_set_swap(png_ptr); png_set_swap(png_ptr);
#endif #endif
/* Added at libpng-1.2.41 */ /* Added at libpng-1.2.41 */
#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
/* Invert the alpha channel from opacity to transparency /* Invert the alpha channel from opacity to transparency */
*/
if (transforms & PNG_TRANSFORM_INVERT_ALPHA) if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
png_set_invert_alpha(png_ptr); png_set_invert_alpha(png_ptr);
#endif #endif
/* Added at libpng-1.2.41 */ /* Added at libpng-1.2.41 */
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
/* Expand grayscale image to RGB /* Expand grayscale image to RGB */
*/
if (transforms & PNG_TRANSFORM_GRAY_TO_RGB) if (transforms & PNG_TRANSFORM_GRAY_TO_RGB)
png_set_gray_to_rgb(png_ptr); png_set_gray_to_rgb(png_ptr);
#endif #endif
/* We don't handle adding filler bytes */ /* We don't handle adding filler bytes */
/* We use png_read_image and rely on that for interlace handling, but we also
* call png_read_update_info therefore must turn on interlace handling now:
*/
(void)png_set_interlace_handling(png_ptr);
/* Optional call to gamma correct and add the background to the palette /* Optional call to gamma correct and add the background to the palette
* and update info structure. REQUIRED if you are expecting libpng to * and update info structure. REQUIRED if you are expecting libpng to
* update the palette for you (i.e., you selected such a transform above). * update the palette for you (i.e., you selected such a transform above).
@ -1337,8 +1464,8 @@ png_read_png(png_structp png_ptr, png_infop info_ptr,
/* Read rest of file, and get additional chunks in info_ptr - REQUIRED */ /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
png_read_end(png_ptr, info_ptr); png_read_end(png_ptr, info_ptr);
transforms = transforms; /* Quiet compiler warnings */ PNG_UNUSED(transforms) /* Quiet compiler warnings */
params = params; PNG_UNUSED(params)
} }
#endif /* PNG_INFO_IMAGE_SUPPORTED */ #endif /* PNG_INFO_IMAGE_SUPPORTED */

View File

@ -1,8 +1,8 @@
/* pngrio.c - functions for data input /* pngrio.c - functions for data input
* *
* Last changed in libpng 1.4.5 [December 9, 2010] * Last changed in libpng 1.5.0 [January 6, 2011]
* Copyright (c) 1998-2010 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
@ -18,11 +18,10 @@
* libpng use it at run time with png_set_read_fn(...). * libpng use it at run time with png_set_read_fn(...).
*/ */
#define PNG_NO_PEDANTIC_WARNINGS
#include "png.h"
#ifdef PNG_READ_SUPPORTED
#include "pngpriv.h" #include "pngpriv.h"
#ifdef PNG_READ_SUPPORTED
/* Read the data from whatever input you are using. The default routine /* Read the data from whatever input you are using. The default routine
* reads from a file pointer. Note that this routine sometimes gets called * reads from a file pointer. Note that this routine sometimes gets called
* with very small lengths, so you should implement some kind of simple * with very small lengths, so you should implement some kind of simple
@ -36,6 +35,7 @@ png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
if (png_ptr->read_data_fn != NULL) if (png_ptr->read_data_fn != NULL)
(*(png_ptr->read_data_fn))(png_ptr, data, length); (*(png_ptr->read_data_fn))(png_ptr, data, length);
else else
png_error(png_ptr, "Call to NULL read function"); png_error(png_ptr, "Call to NULL read function");
} }
@ -47,13 +47,14 @@ png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
* than changing the library. * than changing the library.
*/ */
# ifndef USE_FAR_KEYWORD # ifndef USE_FAR_KEYWORD
void PNGAPI void PNGCBAPI
png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{ {
png_size_t check; png_size_t check;
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
/* fread() returns 0 on error, so it is OK to store this in a png_size_t /* fread() returns 0 on error, so it is OK to store this in a png_size_t
* instead of an int, which is what fread() actually returns. * instead of an int, which is what fread() actually returns.
*/ */
@ -71,7 +72,7 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
#define NEAR_BUF_SIZE 1024 #define NEAR_BUF_SIZE 1024
#define MIN(a,b) (a <= b ? a : b) #define MIN(a,b) (a <= b ? a : b)
static void PNGAPI static void PNGCBAPI
png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{ {
png_size_t check; png_size_t check;
@ -80,33 +81,41 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
/* Check if data really is near. If so, use usual code. */ /* Check if data really is near. If so, use usual code. */
n_data = (png_byte *)CVT_PTR_NOCHECK(data); n_data = (png_byte *)CVT_PTR_NOCHECK(data);
io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr); io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
if ((png_bytep)n_data == data) if ((png_bytep)n_data == data)
{ {
check = fread(n_data, 1, length, io_ptr); check = fread(n_data, 1, length, io_ptr);
} }
else else
{ {
png_byte buf[NEAR_BUF_SIZE]; png_byte buf[NEAR_BUF_SIZE];
png_size_t read, remaining, err; png_size_t read, remaining, err;
check = 0; check = 0;
remaining = length; remaining = length;
do do
{ {
read = MIN(NEAR_BUF_SIZE, remaining); read = MIN(NEAR_BUF_SIZE, remaining);
err = fread(buf, 1, read, io_ptr); err = fread(buf, 1, read, io_ptr);
png_memcpy(data, buf, read); /* copy far buffer to near buffer */ png_memcpy(data, buf, read); /* copy far buffer to near buffer */
if (err != read) if (err != read)
break; break;
else else
check += err; check += err;
data += read; data += read;
remaining -= read; remaining -= read;
} }
while (remaining != 0); while (remaining != 0);
} }
if ((png_uint_32)check != (png_uint_32)length) if ((png_uint_32)check != (png_uint_32)length)
png_error(png_ptr, "read Error"); png_error(png_ptr, "read Error");
} }
@ -117,9 +126,12 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
* for libpng if standard C streams aren't being used. * for libpng if standard C streams aren't being used.
* *
* This function takes as its arguments: * This function takes as its arguments:
*
* png_ptr - pointer to a png input data structure * png_ptr - pointer to a png input data structure
*
* io_ptr - pointer to user supplied structure containing info about * io_ptr - pointer to user supplied structure containing info about
* the input functions. May be NULL. * the input functions. May be NULL.
*
* read_data_fn - pointer to a new input function that takes as its * read_data_fn - pointer to a new input function that takes as its
* arguments a pointer to a png_struct, a pointer to * arguments a pointer to a png_struct, a pointer to
* a location where input data can be stored, and a 32-bit * a location where input data can be stored, and a 32-bit
@ -135,11 +147,13 @@ png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
{ {
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
png_ptr->io_ptr = io_ptr; png_ptr->io_ptr = io_ptr;
#ifdef PNG_STDIO_SUPPORTED #ifdef PNG_STDIO_SUPPORTED
if (read_data_fn != NULL) if (read_data_fn != NULL)
png_ptr->read_data_fn = read_data_fn; png_ptr->read_data_fn = read_data_fn;
else else
png_ptr->read_data_fn = png_default_read_data; png_ptr->read_data_fn = png_default_read_data;
#else #else
@ -151,9 +165,8 @@ png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
{ {
png_ptr->write_data_fn = NULL; png_ptr->write_data_fn = NULL;
png_warning(png_ptr, png_warning(png_ptr,
"It's an error to set both read_data_fn and write_data_fn in the "); "Can't set both read_data_fn and write_data_fn in the"
png_warning(png_ptr, " same structure");
"same structure. Resetting write_data_fn to NULL");
} }
#ifdef PNG_WRITE_FLUSH_SUPPORTED #ifdef PNG_WRITE_FLUSH_SUPPORTED

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

308
src/libpng/pngstruct.h Normal file
View File

@ -0,0 +1,308 @@
/* pngstruct.h - header file for PNG reference library
*
* Copyright (c) 1998-2011 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.)
*
* Last changed in libpng 1.5.0 [January 6, 2011]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*/
/* The structure that holds the information to read and write PNG files.
* The only people who need to care about what is inside of this are the
* people who will be modifying the library for their own special needs.
* It should NOT be accessed directly by an application.
*/
#ifndef PNGSTRUCT_H
#define PNGSTRUCT_H
/* zlib.h defines the structure z_stream, an instance of which is included
* in this structure and is required for decompressing the LZ compressed
* data in PNG files.
*/
#include "zlib.h"
struct png_struct_def
{
#ifdef PNG_SETJMP_SUPPORTED
jmp_buf png_jmpbuf; /* used in png_error */
png_longjmp_ptr longjmp_fn;/* setjmp non-local goto function. */
#endif
png_error_ptr error_fn; /* function for printing errors and aborting */
png_error_ptr warning_fn; /* function for printing warnings */
png_voidp error_ptr; /* user supplied struct for error functions */
png_rw_ptr write_data_fn; /* function for writing output data */
png_rw_ptr read_data_fn; /* function for reading input data */
png_voidp io_ptr; /* ptr to application struct for I/O functions */
#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
png_user_transform_ptr read_user_transform_fn; /* user read transform */
#endif
#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
png_user_transform_ptr write_user_transform_fn; /* user write transform */
#endif
/* These were added in libpng-1.0.2 */
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
png_voidp user_transform_ptr; /* user supplied struct for user transform */
png_byte user_transform_depth; /* bit depth of user transformed pixels */
png_byte user_transform_channels; /* channels in user transformed pixels */
#endif
#endif
png_uint_32 mode; /* tells us where we are in the PNG file */
png_uint_32 flags; /* flags indicating various things to libpng */
png_uint_32 transformations; /* which transformations to perform */
z_stream zstream; /* pointer to decompression structure (below) */
png_bytep zbuf; /* buffer for zlib */
uInt zbuf_size; /* size of zbuf (typically 65536) */
int zlib_level; /* holds zlib compression level */
int zlib_method; /* holds zlib compression method */
int zlib_window_bits; /* holds zlib compression window bits */
int zlib_mem_level; /* holds zlib compression memory level */
int zlib_strategy; /* holds zlib compression strategy */
png_uint_32 width; /* width of image in pixels */
png_uint_32 height; /* height of image in pixels */
png_uint_32 num_rows; /* number of rows in current pass */
png_uint_32 usr_width; /* width of row at start of write */
png_size_t rowbytes; /* size of row in bytes */
png_uint_32 iwidth; /* width of current interlaced row in pixels */
png_uint_32 row_number; /* current row in interlace pass */
png_bytep prev_row; /* buffer to save previous (unfiltered) row */
png_bytep row_buf; /* buffer to save current (unfiltered) row */
png_bytep sub_row; /* buffer to save "sub" row when filtering */
png_bytep up_row; /* buffer to save "up" row when filtering */
png_bytep avg_row; /* buffer to save "avg" row when filtering */
png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */
png_row_info row_info; /* used for transformation routines */
png_uint_32 idat_size; /* current IDAT size for read */
png_uint_32 crc; /* current chunk CRC value */
png_colorp palette; /* palette from the input file */
png_uint_16 num_palette; /* number of color entries in palette */
png_uint_16 num_trans; /* number of transparency values */
png_byte chunk_name[5]; /* null-terminated name of current chunk */
png_byte compression; /* file compression type (always 0) */
png_byte filter; /* file filter type (always 0) */
png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
png_byte pass; /* current interlace pass (0 - 6) */
png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */
png_byte color_type; /* color type of file */
png_byte bit_depth; /* bit depth of file */
png_byte usr_bit_depth; /* bit depth of users row */
png_byte pixel_depth; /* number of bits per pixel */
png_byte channels; /* number of channels in file */
png_byte usr_channels; /* channels at start of write */
png_byte sig_bytes; /* magic bytes read/written from start of file */
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
png_uint_16 filler; /* filler bytes for pixel expansion */
#endif
#ifdef PNG_bKGD_SUPPORTED
png_byte background_gamma_type;
png_fixed_point background_gamma;
png_color_16 background; /* background color in screen gamma space */
#ifdef PNG_READ_GAMMA_SUPPORTED
png_color_16 background_1; /* background normalized to gamma 1.0 */
#endif
#endif /* PNG_bKGD_SUPPORTED */
#ifdef PNG_WRITE_FLUSH_SUPPORTED
png_flush_ptr output_flush_fn; /* Function for flushing output */
png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */
png_uint_32 flush_rows; /* number of rows written since last flush */
#endif
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
int gamma_shift; /* number of "insignificant" bits in 16-bit gamma */
png_fixed_point gamma; /* file gamma value */
png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */
#endif
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
png_bytep gamma_table; /* gamma table for 8-bit depth files */
png_bytep gamma_from_1; /* converts from 1.0 to screen */
png_bytep gamma_to_1; /* converts from file to 1.0 */
png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */
png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */
png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */
#endif
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED)
png_color_8 sig_bit; /* significant bits in each available channel */
#endif
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
png_color_8 shift; /* shift for significant bit tranformation */
#endif
#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
|| defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
png_bytep trans_alpha; /* alpha values for paletted files */
png_color_16 trans_color; /* transparent color for non-paletted files */
#endif
png_read_status_ptr read_row_fn; /* called after each row is decoded */
png_write_status_ptr write_row_fn; /* called after each row is encoded */
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
png_progressive_info_ptr info_fn; /* called after header data fully read */
png_progressive_row_ptr row_fn; /* called after a prog. row is decoded */
png_progressive_end_ptr end_fn; /* called after image is complete */
png_bytep save_buffer_ptr; /* current location in save_buffer */
png_bytep save_buffer; /* buffer for previously read data */
png_bytep current_buffer_ptr; /* current location in current_buffer */
png_bytep current_buffer; /* buffer for recently used data */
png_uint_32 push_length; /* size of current input chunk */
png_uint_32 skip_length; /* bytes to skip in input data */
png_size_t save_buffer_size; /* amount of data now in save_buffer */
png_size_t save_buffer_max; /* total size of save_buffer */
png_size_t buffer_size; /* total amount of available input data */
png_size_t current_buffer_size; /* amount of data now in current_buffer */
int process_mode; /* what push library is currently doing */
int cur_palette; /* current push library palette index */
# ifdef PNG_TEXT_SUPPORTED
png_size_t current_text_size; /* current size of text input data */
png_size_t current_text_left; /* how much text left to read in input */
png_charp current_text; /* current text chunk buffer */
png_charp current_text_ptr; /* current location in current_text */
# endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_TEXT_SUPPORTED */
#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
/* For the Borland special 64K segment handler */
png_bytepp offset_table_ptr;
png_bytep offset_table;
png_uint_16 offset_table_number;
png_uint_16 offset_table_count;
png_uint_16 offset_table_count_free;
#endif
#ifdef PNG_READ_QUANTIZE_SUPPORTED
png_bytep palette_lookup; /* lookup table for quantizing */
png_bytep quantize_index; /* index translation for palette files */
#endif
#if defined(PNG_READ_QUANTIZE_SUPPORTED) || defined(PNG_hIST_SUPPORTED)
png_uint_16p hist; /* histogram */
#endif
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
png_byte heuristic_method; /* heuristic for row filter selection */
png_byte num_prev_filters; /* number of weights for previous rows */
png_bytep prev_filters; /* filter type(s) of previous row(s) */
png_uint_16p filter_weights; /* weight(s) for previous line(s) */
png_uint_16p inv_filter_weights; /* 1/weight(s) for previous line(s) */
png_uint_16p filter_costs; /* relative filter calculation cost */
png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */
#endif
#ifdef PNG_TIME_RFC1123_SUPPORTED
png_charp time_buffer; /* String to hold RFC 1123 time text */
#endif
/* New members added in libpng-1.0.6 */
png_uint_32 free_me; /* flags items libpng is responsible for freeing */
#ifdef PNG_USER_CHUNKS_SUPPORTED
png_voidp user_chunk_ptr;
png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */
#endif
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
int num_chunk_list;
png_bytep chunk_list;
#endif
/* New members added in libpng-1.0.3 */
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
png_byte rgb_to_gray_status;
/* These were changed from png_byte in libpng-1.0.6 */
png_uint_16 rgb_to_gray_red_coeff;
png_uint_16 rgb_to_gray_green_coeff;
png_uint_16 rgb_to_gray_blue_coeff;
#endif
/* New member added in libpng-1.0.4 (renamed in 1.0.9) */
#if defined(PNG_MNG_FEATURES_SUPPORTED) || \
defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
/* Changed from png_byte to png_uint_32 at version 1.2.0 */
png_uint_32 mng_features_permitted;
#endif
/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */
#ifdef PNG_MNG_FEATURES_SUPPORTED
png_byte filter_type;
#endif
/* New members added in libpng-1.2.0 */
/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
#ifdef PNG_USER_MEM_SUPPORTED
png_voidp mem_ptr; /* user supplied struct for mem functions */
png_malloc_ptr malloc_fn; /* function for allocating memory */
png_free_ptr free_fn; /* function for freeing memory */
#endif
/* New member added in libpng-1.0.13 and 1.2.0 */
png_bytep big_row_buf; /* buffer to save current (unfiltered) row */
#ifdef PNG_READ_QUANTIZE_SUPPORTED
/* The following three members were added at version 1.0.14 and 1.2.4 */
png_bytep quantize_sort; /* working sort array */
png_bytep index_to_palette; /* where the original index currently is
in the palette */
png_bytep palette_to_index; /* which original index points to this
palette color */
#endif
/* New members added in libpng-1.0.16 and 1.2.6 */
png_byte compression_type;
#ifdef PNG_USER_LIMITS_SUPPORTED
png_uint_32 user_width_max;
png_uint_32 user_height_max;
/* Added in libpng-1.4.0: Total number of sPLT, text, and unknown
* chunks that can be stored (0 means unlimited).
*/
png_uint_32 user_chunk_cache_max;
/* Total memory that a zTXt, sPLT, iTXt, iCCP, or unknown chunk
* can occupy when decompressed. 0 means unlimited.
*/
png_alloc_size_t user_chunk_malloc_max;
#endif
/* New member added in libpng-1.0.25 and 1.2.17 */
#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
/* Storage for unknown chunk that the library doesn't recognize. */
png_unknown_chunk unknown_chunk;
#endif
/* New members added in libpng-1.2.26 */
png_size_t old_big_row_buf_size;
png_size_t old_prev_row_size;
/* New member added in libpng-1.2.30 */
png_charp chunkdata; /* buffer for reading chunk data */
#ifdef PNG_IO_STATE_SUPPORTED
/* New member added in libpng-1.4.0 */
png_uint_32 io_state;
#endif
};
#endif /* PNGSTRUCT_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
/* pngtrans.c - transforms the data in a row (used by both readers and writers) /* pngtrans.c - transforms the data in a row (used by both readers and writers)
* *
* Last changed in libpng 1.4.2 [April 29, 2010] * Last changed in libpng 1.5.2 [March 31, 2011]
* Copyright (c) 1998-2010 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
@ -11,11 +11,10 @@
* and license in png.h * and license in png.h
*/ */
#define PNG_NO_PEDANTIC_WARNINGS
#include "png.h"
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
#include "pngpriv.h" #include "pngpriv.h"
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
/* Turn on BGR-to-RGB mapping */ /* Turn on BGR-to-RGB mapping */
void PNGAPI void PNGAPI
@ -25,6 +24,7 @@ png_set_bgr(png_structp png_ptr)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
png_ptr->transformations |= PNG_BGR; png_ptr->transformations |= PNG_BGR;
} }
#endif #endif
@ -38,6 +38,7 @@ png_set_swap(png_structp png_ptr)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
if (png_ptr->bit_depth == 16) if (png_ptr->bit_depth == 16)
png_ptr->transformations |= PNG_SWAP_BYTES; png_ptr->transformations |= PNG_SWAP_BYTES;
} }
@ -52,6 +53,7 @@ png_set_packing(png_structp png_ptr)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
if (png_ptr->bit_depth < 8) if (png_ptr->bit_depth < 8)
{ {
png_ptr->transformations |= PNG_PACK; png_ptr->transformations |= PNG_PACK;
@ -69,6 +71,7 @@ png_set_packswap(png_structp png_ptr)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
if (png_ptr->bit_depth < 8) if (png_ptr->bit_depth < 8)
png_ptr->transformations |= PNG_PACKSWAP; png_ptr->transformations |= PNG_PACKSWAP;
} }
@ -76,12 +79,13 @@ png_set_packswap(png_structp png_ptr)
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
void PNGAPI void PNGAPI
png_set_shift(png_structp png_ptr, png_color_8p true_bits) png_set_shift(png_structp png_ptr, png_const_color_8p true_bits)
{ {
png_debug(1, "in png_set_shift"); png_debug(1, "in png_set_shift");
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
png_ptr->transformations |= PNG_SHIFT; png_ptr->transformations |= PNG_SHIFT;
png_ptr->shift = *true_bits; png_ptr->shift = *true_bits;
} }
@ -117,10 +121,13 @@ png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
png_ptr->transformations |= PNG_FILLER; png_ptr->transformations |= PNG_FILLER;
png_ptr->filler = (png_uint_16)filler; png_ptr->filler = (png_uint_16)filler;
if (filler_loc == PNG_FILLER_AFTER) if (filler_loc == PNG_FILLER_AFTER)
png_ptr->flags |= PNG_FLAG_FILLER_AFTER; png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
else else
png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER; png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
@ -135,7 +142,7 @@ png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
} }
/* Also I added this in libpng-1.0.2a (what happens when we expand /* Also I added this in libpng-1.0.2a (what happens when we expand
* a less-than-8-bit grayscale to GA? */ * a less-than-8-bit grayscale to GA?) */
if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8) if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
{ {
@ -151,6 +158,7 @@ png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
png_set_filler(png_ptr, filler, filler_loc); png_set_filler(png_ptr, filler, filler_loc);
png_ptr->transformations |= PNG_ADD_ALPHA; png_ptr->transformations |= PNG_ADD_ALPHA;
} }
@ -166,6 +174,7 @@ png_set_swap_alpha(png_structp png_ptr)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
png_ptr->transformations |= PNG_SWAP_ALPHA; png_ptr->transformations |= PNG_SWAP_ALPHA;
} }
#endif #endif
@ -179,6 +188,7 @@ png_set_invert_alpha(png_structp png_ptr)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
png_ptr->transformations |= PNG_INVERT_ALPHA; png_ptr->transformations |= PNG_INVERT_ALPHA;
} }
#endif #endif
@ -191,6 +201,7 @@ png_set_invert_mono(png_structp png_ptr)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
png_ptr->transformations |= PNG_INVERT_MONO; png_ptr->transformations |= PNG_INVERT_MONO;
} }
@ -206,8 +217,8 @@ png_do_invert(png_row_infop row_info, png_bytep row)
if (row_info->color_type == PNG_COLOR_TYPE_GRAY) if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
{ {
png_bytep rp = row; png_bytep rp = row;
png_uint_32 i; png_size_t i;
png_uint_32 istop = row_info->rowbytes; png_size_t istop = row_info->rowbytes;
for (i = 0; i < istop; i++) for (i = 0; i < istop; i++)
{ {
@ -215,12 +226,13 @@ png_do_invert(png_row_infop row_info, png_bytep row)
rp++; rp++;
} }
} }
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
row_info->bit_depth == 8) row_info->bit_depth == 8)
{ {
png_bytep rp = row; png_bytep rp = row;
png_uint_32 i; png_size_t i;
png_uint_32 istop = row_info->rowbytes; png_size_t istop = row_info->rowbytes;
for (i = 0; i < istop; i += 2) for (i = 0; i < istop; i += 2)
{ {
@ -228,12 +240,14 @@ png_do_invert(png_row_infop row_info, png_bytep row)
rp += 2; rp += 2;
} }
} }
#ifdef PNG_16BIT_SUPPORTED
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
row_info->bit_depth == 16) row_info->bit_depth == 16)
{ {
png_bytep rp = row; png_bytep rp = row;
png_uint_32 i; png_size_t i;
png_uint_32 istop = row_info->rowbytes; png_size_t istop = row_info->rowbytes;
for (i = 0; i < istop; i += 4) for (i = 0; i < istop; i += 4)
{ {
@ -242,9 +256,11 @@ png_do_invert(png_row_infop row_info, png_bytep row)
rp += 4; rp += 4;
} }
} }
#endif
} }
#endif #endif
#ifdef PNG_16BIT_SUPPORTED
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
/* Swaps byte order on 16 bit depth images */ /* Swaps byte order on 16 bit depth images */
void /* PRIVATE */ void /* PRIVATE */
@ -252,8 +268,7 @@ png_do_swap(png_row_infop row_info, png_bytep row)
{ {
png_debug(1, "in png_do_swap"); png_debug(1, "in png_do_swap");
if ( if (row_info->bit_depth == 16)
row_info->bit_depth == 16)
{ {
png_bytep rp = row; png_bytep rp = row;
png_uint_32 i; png_uint_32 i;
@ -268,6 +283,7 @@ png_do_swap(png_row_infop row_info, png_bytep row)
} }
} }
#endif #endif
#endif
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
static PNG_CONST png_byte onebppswaptable[256] = { static PNG_CONST png_byte onebppswaptable[256] = {
@ -381,19 +397,22 @@ png_do_packswap(png_row_infop row_info, png_bytep row)
{ {
png_debug(1, "in png_do_packswap"); png_debug(1, "in png_do_packswap");
if ( if (row_info->bit_depth < 8)
row_info->bit_depth < 8)
{ {
png_bytep rp, end, table; png_bytep rp;
png_const_bytep end, table;
end = row + row_info->rowbytes; end = row + row_info->rowbytes;
if (row_info->bit_depth == 1) if (row_info->bit_depth == 1)
table = (png_bytep)onebppswaptable; table = onebppswaptable;
else if (row_info->bit_depth == 2) else if (row_info->bit_depth == 2)
table = (png_bytep)twobppswaptable; table = twobppswaptable;
else if (row_info->bit_depth == 4) else if (row_info->bit_depth == 4)
table = (png_bytep)fourbppswaptable; table = fourbppswaptable;
else else
return; return;
@ -405,158 +424,115 @@ png_do_packswap(png_row_infop row_info, png_bytep row)
#if defined(PNG_WRITE_FILLER_SUPPORTED) || \ #if defined(PNG_WRITE_FILLER_SUPPORTED) || \
defined(PNG_READ_STRIP_ALPHA_SUPPORTED) defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
/* Remove filler or alpha byte(s) */ /* Remove a channel - this used to be 'png_do_strip_filler' but it used a
* somewhat weird combination of flags to determine what to do. All the calls
* to png_do_strip_filler are changed in 1.5.2 to call this instead with the
* correct arguments.
*
* The routine isn't general - the channel must be the channel at the start or
* end (not in the middle) of each pixel.
*/
void /* PRIVATE */ void /* PRIVATE */
png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags) png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
{ {
png_debug(1, "in png_do_strip_filler"); png_bytep sp = row; /* source pointer */
png_bytep dp = row; /* destination pointer */
png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */
{ /* At the start sp will point to the first byte to copy and dp to where
png_bytep sp=row; * it is copied to. ep always points just beyond the end of the row, so
png_bytep dp=row; * the loop simply copies (channels-1) channels until sp reaches ep.
png_uint_32 row_width=row_info->width; */
png_uint_32 i; /* GA, GX, XG cases */
if (row_info->channels == 2)
if ((row_info->color_type == PNG_COLOR_TYPE_RGB ||
(row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
(flags & PNG_FLAG_STRIP_ALPHA))) &&
row_info->channels == 4)
{ {
if (row_info->bit_depth == 8) if (row_info->bit_depth == 8)
{ {
/* This converts from RGBX or RGBA to RGB */ if (at_start) /* Skip initial filler */
if (flags & PNG_FLAG_FILLER_AFTER) ++sp;
{ else /* Skip initial channels and, for sp, the filler */
dp+=3; sp+=4; sp += 2, ++dp;
for (i = 1; i < row_width; i++)
{
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
sp++;
}
}
/* This converts from XRGB or ARGB to RGB */
else
{
for (i = 0; i < row_width; i++)
{
sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
}
}
row_info->pixel_depth = 24;
row_info->rowbytes = row_width * 3;
}
else /* if (row_info->bit_depth == 16) */
{
if (flags & PNG_FLAG_FILLER_AFTER)
{
/* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
sp += 8; dp += 6;
for (i = 1; i < row_width; i++)
{
/* This could be (although png_memcpy is probably slower):
png_memcpy(dp, sp, 6);
sp += 8;
dp += 6;
*/
*dp++ = *sp++; /* For a 1 pixel wide image there is nothing to do */
*dp++ = *sp++; while (sp < ep)
*dp++ = *sp++; *dp++ = *sp, sp += 2;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
sp += 2;
}
}
else
{
/* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
for (i = 0; i < row_width; i++)
{
/* This could be (although png_memcpy is probably slower):
png_memcpy(dp, sp, 6);
sp += 8;
dp += 6;
*/
sp+=2;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
}
}
row_info->pixel_depth = 48;
row_info->rowbytes = row_width * 6;
}
row_info->channels = 3;
}
else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY ||
(row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
(flags & PNG_FLAG_STRIP_ALPHA))) &&
row_info->channels == 2)
{
if (row_info->bit_depth == 8)
{
/* This converts from GX or GA to G */
if (flags & PNG_FLAG_FILLER_AFTER)
{
for (i = 0; i < row_width; i++)
{
*dp++ = *sp++;
sp++;
}
}
/* This converts from XG or AG to G */
else
{
for (i = 0; i < row_width; i++)
{
sp++;
*dp++ = *sp++;
}
}
row_info->pixel_depth = 8; row_info->pixel_depth = 8;
row_info->rowbytes = row_width;
} }
else /* if (row_info->bit_depth == 16) */
else if (row_info->bit_depth == 16)
{ {
if (flags & PNG_FLAG_FILLER_AFTER) if (at_start)
{
/* This converts from GGXX or GGAA to GG */
sp += 4; dp += 2;
for (i = 1; i < row_width; i++)
{
*dp++ = *sp++;
*dp++ = *sp++;
sp += 2; sp += 2;
}
}
else else
{ sp += 4, dp += 2;
/* This converts from XXGG or AAGG to GG */
for (i = 0; i < row_width; i++) while (sp < ep)
{ *dp++ = *sp++, *dp++ = *sp, sp += 3;
sp += 2;
*dp++ = *sp++;
*dp++ = *sp++;
}
}
row_info->pixel_depth = 16; row_info->pixel_depth = 16;
row_info->rowbytes = row_width * 2;
} }
else
return; /* bad bit depth */
row_info->channels = 1; row_info->channels = 1;
/* Finally fix the color type if it records an alpha channel */
if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
row_info->color_type = PNG_COLOR_TYPE_GRAY;
} }
if (flags & PNG_FLAG_STRIP_ALPHA)
row_info->color_type &= ~PNG_COLOR_MASK_ALPHA; /* RGBA, RGBX, XRGB cases */
else if (row_info->channels == 4)
{
if (row_info->bit_depth == 8)
{
if (at_start) /* Skip initial filler */
++sp;
else /* Skip initial channels and, for sp, the filler */
sp += 4, dp += 3;
/* Note that the loop adds 3 to dp and 4 to sp each time. */
while (sp < ep)
*dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2;
row_info->pixel_depth = 24;
} }
else if (row_info->bit_depth == 16)
{
if (at_start)
sp += 2;
else
sp += 8, dp += 6;
while (sp < ep)
{
/* Copy 6 bytes, skip 2 */
*dp++ = *sp++, *dp++ = *sp++;
*dp++ = *sp++, *dp++ = *sp++;
*dp++ = *sp++, *dp++ = *sp, sp += 3;
}
row_info->pixel_depth = 48;
}
else
return; /* bad bit depth */
row_info->channels = 3;
/* Finally fix the color type if it records an alpha channel */
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
row_info->color_type = PNG_COLOR_TYPE_RGB;
}
else
return; /* The filler channel has gone already */
/* Fix the rowbytes value. */
row_info->rowbytes = dp-row;
} }
#endif #endif
@ -567,8 +543,7 @@ png_do_bgr(png_row_infop row_info, png_bytep row)
{ {
png_debug(1, "in png_do_bgr"); png_debug(1, "in png_do_bgr");
if ( if ((row_info->color_type & PNG_COLOR_MASK_COLOR))
(row_info->color_type & PNG_COLOR_MASK_COLOR))
{ {
png_uint_32 row_width = row_info->width; png_uint_32 row_width = row_info->width;
if (row_info->bit_depth == 8) if (row_info->bit_depth == 8)
@ -585,6 +560,7 @@ png_do_bgr(png_row_infop row_info, png_bytep row)
*(rp + 2) = save; *(rp + 2) = save;
} }
} }
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{ {
png_bytep rp; png_bytep rp;
@ -598,6 +574,8 @@ png_do_bgr(png_row_infop row_info, png_bytep row)
} }
} }
} }
#ifdef PNG_16BIT_SUPPORTED
else if (row_info->bit_depth == 16) else if (row_info->bit_depth == 16)
{ {
if (row_info->color_type == PNG_COLOR_TYPE_RGB) if (row_info->color_type == PNG_COLOR_TYPE_RGB)
@ -615,6 +593,7 @@ png_do_bgr(png_row_infop row_info, png_bytep row)
*(rp + 5) = save; *(rp + 5) = save;
} }
} }
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{ {
png_bytep rp; png_bytep rp;
@ -631,12 +610,14 @@ png_do_bgr(png_row_infop row_info, png_bytep row)
} }
} }
} }
#endif
} }
} }
#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */ #endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
void PNGAPI void PNGAPI
png_set_user_transform_info(png_structp png_ptr, png_voidp png_set_user_transform_info(png_structp png_ptr, png_voidp
user_transform_ptr, int user_transform_depth, int user_transform_channels) user_transform_ptr, int user_transform_depth, int user_transform_channels)
@ -645,33 +626,49 @@ png_set_user_transform_info(png_structp png_ptr, png_voidp
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
png_ptr->user_transform_ptr = user_transform_ptr; png_ptr->user_transform_ptr = user_transform_ptr;
png_ptr->user_transform_depth = (png_byte)user_transform_depth; png_ptr->user_transform_depth = (png_byte)user_transform_depth;
png_ptr->user_transform_channels = (png_byte)user_transform_channels; png_ptr->user_transform_channels = (png_byte)user_transform_channels;
#else
if (user_transform_ptr || user_transform_depth || user_transform_channels)
png_warning(png_ptr,
"This version of libpng does not support user transform info");
#endif
} }
#endif
/* This function returns a pointer to the user_transform_ptr associated with /* This function returns a pointer to the user_transform_ptr associated with
* the user transform functions. The application should free any memory * the user transform functions. The application should free any memory
* associated with this pointer before png_write_destroy and png_read_destroy * associated with this pointer before png_write_destroy and png_read_destroy
* are called. * are called.
*/ */
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
png_voidp PNGAPI png_voidp PNGAPI
png_get_user_transform_ptr(png_structp png_ptr) png_get_user_transform_ptr(png_const_structp png_ptr)
{ {
if (png_ptr == NULL) if (png_ptr == NULL)
return (NULL); return (NULL);
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
return ((png_voidp)png_ptr->user_transform_ptr); return ((png_voidp)png_ptr->user_transform_ptr);
#else
return (NULL);
#endif
} }
#endif
#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
png_uint_32 PNGAPI
png_get_current_row_number(png_const_structp png_ptr)
{
/* See the comments in png.h - this is the sub-image row when reading and
* interlaced image.
*/
if (png_ptr != NULL)
return png_ptr->row_number;
return PNG_UINT_32_MAX; /* help the app not to fail silently */
}
png_byte PNGAPI
png_get_current_pass_number(png_const_structp png_ptr)
{
if (png_ptr != NULL)
return png_ptr->pass;
return 8; /* invalid */
}
#endif /* PNG_USER_TRANSFORM_INFO_SUPPORTED */
#endif /* PNG_READ_USER_TRANSFORM_SUPPORTED || #endif /* PNG_READ_USER_TRANSFORM_SUPPORTED ||
PNG_WRITE_USER_TRANSFORM_SUPPORTED */ PNG_WRITE_USER_TRANSFORM_SUPPORTED */
#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */

View File

@ -1,8 +1,8 @@
/* pngwio.c - functions for data output /* pngwio.c - functions for data output
* *
* Last changed in libpng 1.4.0 [January 3, 2010] * Last changed in libpng 1.5.0 [January 6, 2011]
* Copyright (c) 1998-2010 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
@ -18,11 +18,10 @@
* them at run time with png_set_write_fn(...). * them at run time with png_set_write_fn(...).
*/ */
#define PNG_NO_PEDANTIC_WARNINGS
#include "png.h"
#ifdef PNG_WRITE_SUPPORTED
#include "pngpriv.h" #include "pngpriv.h"
#ifdef PNG_WRITE_SUPPORTED
/* Write the data to whatever output you are using. The default routine /* Write the data to whatever output you are using. The default routine
* writes to a file pointer. Note that this routine sometimes gets called * writes to a file pointer. Note that this routine sometimes gets called
* with very small lengths, so you should implement some kind of simple * with very small lengths, so you should implement some kind of simple
@ -31,10 +30,12 @@
*/ */
void /* PRIVATE */ void /* PRIVATE */
png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) png_write_data(png_structp png_ptr, png_const_bytep data, png_size_t length)
{ {
/* NOTE: write_data_fn must not change the buffer! */
if (png_ptr->write_data_fn != NULL ) if (png_ptr->write_data_fn != NULL )
(*(png_ptr->write_data_fn))(png_ptr, data, length); (*(png_ptr->write_data_fn))(png_ptr, (png_bytep)data, length);
else else
png_error(png_ptr, "Call to NULL write function"); png_error(png_ptr, "Call to NULL write function");
} }
@ -46,14 +47,16 @@ png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
* than changing the library. * than changing the library.
*/ */
#ifndef USE_FAR_KEYWORD #ifndef USE_FAR_KEYWORD
void PNGAPI void PNGCBAPI
png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
{ {
png_uint_32 check; png_size_t check;
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr)); check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
if (check != length) if (check != length)
png_error(png_ptr, "Write Error"); png_error(png_ptr, "Write Error");
} }
@ -66,7 +69,7 @@ png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
#define NEAR_BUF_SIZE 1024 #define NEAR_BUF_SIZE 1024
#define MIN(a,b) (a <= b ? a : b) #define MIN(a,b) (a <= b ? a : b)
void PNGAPI void PNGCBAPI
png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
{ {
png_uint_32 check; png_uint_32 check;
@ -75,24 +78,29 @@ png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
/* Check if data really is near. If so, use usual code. */ /* Check if data really is near. If so, use usual code. */
near_data = (png_byte *)CVT_PTR_NOCHECK(data); near_data = (png_byte *)CVT_PTR_NOCHECK(data);
io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr); io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
if ((png_bytep)near_data == data) if ((png_bytep)near_data == data)
{ {
check = fwrite(near_data, 1, length, io_ptr); check = fwrite(near_data, 1, length, io_ptr);
} }
else else
{ {
png_byte buf[NEAR_BUF_SIZE]; png_byte buf[NEAR_BUF_SIZE];
png_size_t written, remaining, err; png_size_t written, remaining, err;
check = 0; check = 0;
remaining = length; remaining = length;
do do
{ {
written = MIN(NEAR_BUF_SIZE, remaining); written = MIN(NEAR_BUF_SIZE, remaining);
png_memcpy(buf, data, written); /* Copy far buffer to near buffer */ png_memcpy(buf, data, written); /* Copy far buffer to near buffer */
err = fwrite(buf, 1, written, io_ptr); err = fwrite(buf, 1, written, io_ptr);
if (err != written) if (err != written)
break; break;
@ -104,6 +112,7 @@ png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
} }
while (remaining != 0); while (remaining != 0);
} }
if (check != length) if (check != length)
png_error(png_ptr, "Write Error"); png_error(png_ptr, "Write Error");
} }
@ -124,12 +133,14 @@ png_flush(png_structp png_ptr)
} }
# ifdef PNG_STDIO_SUPPORTED # ifdef PNG_STDIO_SUPPORTED
void PNGAPI void PNGCBAPI
png_default_flush(png_structp png_ptr) png_default_flush(png_structp png_ptr)
{ {
png_FILE_p io_ptr; png_FILE_p io_ptr;
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr)); io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
fflush(io_ptr); fflush(io_ptr);
} }
@ -186,11 +197,13 @@ png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
#ifdef PNG_WRITE_FLUSH_SUPPORTED #ifdef PNG_WRITE_FLUSH_SUPPORTED
# ifdef PNG_STDIO_SUPPORTED # ifdef PNG_STDIO_SUPPORTED
if (output_flush_fn != NULL) if (output_flush_fn != NULL)
png_ptr->output_flush_fn = output_flush_fn; png_ptr->output_flush_fn = output_flush_fn;
else else
png_ptr->output_flush_fn = png_default_flush; png_ptr->output_flush_fn = png_default_flush;
# else # else
png_ptr->output_flush_fn = output_flush_fn; png_ptr->output_flush_fn = output_flush_fn;
# endif # endif
@ -200,10 +213,10 @@ png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
if (png_ptr->read_data_fn != NULL) if (png_ptr->read_data_fn != NULL)
{ {
png_ptr->read_data_fn = NULL; png_ptr->read_data_fn = NULL;
png_warning(png_ptr, png_warning(png_ptr,
"Attempted to set both read_data_fn and write_data_fn in"); "Can't set both read_data_fn and write_data_fn in the"
png_warning(png_ptr, " same structure");
"the same structure. Resetting read_data_fn to NULL");
} }
} }

View File

@ -1,8 +1,8 @@
/* pngwrite.c - general routines to write a PNG file /* pngwrite.c - general routines to write a PNG file
* *
* Last changed in libpng 1.4.0 [January 3, 2010] * Last changed in libpng 1.5.1 [February 3, 2011]
* Copyright (c) 1998-2010 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
@ -11,12 +11,10 @@
* and license in png.h * and license in png.h
*/ */
/* Get internal access to png.h */
#define PNG_NO_PEDANTIC_WARNINGS
#include "png.h"
#ifdef PNG_WRITE_SUPPORTED
#include "pngpriv.h" #include "pngpriv.h"
#ifdef PNG_WRITE_SUPPORTED
/* Writes all the PNG information. This is the suggested way to use the /* Writes all the PNG information. This is the suggested way to use the
* library. If you have a new chunk to add, make a function to write it, * library. If you have a new chunk to add, make a function to write it,
* and put it in the correct location here. If you want the chunk written * and put it in the correct location here. If you want the chunk written
@ -33,10 +31,12 @@ png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr)
if (png_ptr == NULL || info_ptr == NULL) if (png_ptr == NULL || info_ptr == NULL)
return; return;
if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
{ {
/* Write PNG signature */ /* Write PNG signature */
png_write_sig(png_ptr); png_write_sig(png_ptr);
#ifdef PNG_MNG_FEATURES_SUPPORTED #ifdef PNG_MNG_FEATURES_SUPPORTED
if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) && \ if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) && \
(png_ptr->mng_features_permitted)) (png_ptr->mng_features_permitted))
@ -45,6 +45,7 @@ png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr)
png_ptr->mng_features_permitted = 0; png_ptr->mng_features_permitted = 0;
} }
#endif #endif
/* Write IHDR information. */ /* Write IHDR information. */
png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height, png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type, info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,
@ -59,24 +60,17 @@ png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr)
*/ */
#ifdef PNG_WRITE_gAMA_SUPPORTED #ifdef PNG_WRITE_gAMA_SUPPORTED
if (info_ptr->valid & PNG_INFO_gAMA) if (info_ptr->valid & PNG_INFO_gAMA)
{ png_write_gAMA_fixed(png_ptr, info_ptr->gamma);
# ifdef PNG_FLOATING_POINT_SUPPORTED
png_write_gAMA(png_ptr, info_ptr->gamma);
#else
#ifdef PNG_FIXED_POINT_SUPPORTED
png_write_gAMA_fixed(png_ptr, info_ptr->int_gamma);
# endif
#endif
}
#endif #endif
#ifdef PNG_WRITE_sRGB_SUPPORTED #ifdef PNG_WRITE_sRGB_SUPPORTED
if (info_ptr->valid & PNG_INFO_sRGB) if (info_ptr->valid & PNG_INFO_sRGB)
png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent); png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent);
#endif #endif
#ifdef PNG_WRITE_iCCP_SUPPORTED #ifdef PNG_WRITE_iCCP_SUPPORTED
if (info_ptr->valid & PNG_INFO_iCCP) if (info_ptr->valid & PNG_INFO_iCCP)
png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE, png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE,
info_ptr->iccp_profile, (int)info_ptr->iccp_proflen); (png_charp)info_ptr->iccp_profile, (int)info_ptr->iccp_proflen);
#endif #endif
#ifdef PNG_WRITE_sBIT_SUPPORTED #ifdef PNG_WRITE_sBIT_SUPPORTED
if (info_ptr->valid & PNG_INFO_sBIT) if (info_ptr->valid & PNG_INFO_sBIT)
@ -84,24 +78,13 @@ png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr)
#endif #endif
#ifdef PNG_WRITE_cHRM_SUPPORTED #ifdef PNG_WRITE_cHRM_SUPPORTED
if (info_ptr->valid & PNG_INFO_cHRM) if (info_ptr->valid & PNG_INFO_cHRM)
{ png_write_cHRM_fixed(png_ptr,
#ifdef PNG_FLOATING_POINT_SUPPORTED
png_write_cHRM(png_ptr,
info_ptr->x_white, info_ptr->y_white, info_ptr->x_white, info_ptr->y_white,
info_ptr->x_red, info_ptr->y_red, info_ptr->x_red, info_ptr->y_red,
info_ptr->x_green, info_ptr->y_green, info_ptr->x_green, info_ptr->y_green,
info_ptr->x_blue, info_ptr->y_blue); info_ptr->x_blue, info_ptr->y_blue);
#else
# ifdef PNG_FIXED_POINT_SUPPORTED
png_write_cHRM_fixed(png_ptr,
info_ptr->int_x_white, info_ptr->int_y_white,
info_ptr->int_x_red, info_ptr->int_y_red,
info_ptr->int_x_green, info_ptr->int_y_green,
info_ptr->int_x_blue, info_ptr->int_y_blue);
# endif
#endif
}
#endif #endif
#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
if (info_ptr->unknown_chunks_num) if (info_ptr->unknown_chunks_num)
{ {
@ -114,6 +97,7 @@ png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr)
up++) up++)
{ {
int keep = png_handle_as_unknown(png_ptr, up->name); int keep = png_handle_as_unknown(png_ptr, up->name);
if (keep != PNG_HANDLE_CHUNK_NEVER && if (keep != PNG_HANDLE_CHUNK_NEVER &&
up->location && !(up->location & PNG_HAVE_PLTE) && up->location && !(up->location & PNG_HAVE_PLTE) &&
!(up->location & PNG_HAVE_IDAT) && !(up->location & PNG_HAVE_IDAT) &&
@ -122,6 +106,7 @@ png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr)
{ {
if (up->size == 0) if (up->size == 0)
png_warning(png_ptr, "Writing zero-length unknown chunk"); png_warning(png_ptr, "Writing zero-length unknown chunk");
png_write_chunk(png_ptr, up->name, up->data, up->size); png_write_chunk(png_ptr, up->name, up->data, up->size);
} }
} }
@ -148,6 +133,7 @@ png_write_info(png_structp png_ptr, png_infop info_ptr)
if (info_ptr->valid & PNG_INFO_PLTE) if (info_ptr->valid & PNG_INFO_PLTE)
png_write_PLTE(png_ptr, info_ptr->palette, png_write_PLTE(png_ptr, info_ptr->palette,
(png_uint_32)info_ptr->num_palette); (png_uint_32)info_ptr->num_palette);
else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
png_error(png_ptr, "Valid palette required for paletted images"); png_error(png_ptr, "Valid palette required for paletted images");
@ -161,7 +147,8 @@ png_write_info(png_structp png_ptr, png_infop info_ptr)
{ {
int j; int j;
for (j = 0; j<(int)info_ptr->num_trans; j++) for (j = 0; j<(int)info_ptr->num_trans; j++)
info_ptr->trans_alpha[j] = (png_byte)(255 - info_ptr->trans_alpha[j]); info_ptr->trans_alpha[j] =
(png_byte)(255 - info_ptr->trans_alpha[j]);
} }
#endif #endif
png_write_tRNS(png_ptr, info_ptr->trans_alpha, &(info_ptr->trans_color), png_write_tRNS(png_ptr, info_ptr->trans_alpha, &(info_ptr->trans_color),
@ -172,15 +159,18 @@ png_write_info(png_structp png_ptr, png_infop info_ptr)
if (info_ptr->valid & PNG_INFO_bKGD) if (info_ptr->valid & PNG_INFO_bKGD)
png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type); png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
#endif #endif
#ifdef PNG_WRITE_hIST_SUPPORTED #ifdef PNG_WRITE_hIST_SUPPORTED
if (info_ptr->valid & PNG_INFO_hIST) if (info_ptr->valid & PNG_INFO_hIST)
png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette); png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
#endif #endif
#ifdef PNG_WRITE_oFFs_SUPPORTED #ifdef PNG_WRITE_oFFs_SUPPORTED
if (info_ptr->valid & PNG_INFO_oFFs) if (info_ptr->valid & PNG_INFO_oFFs)
png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset, png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset,
info_ptr->offset_unit_type); info_ptr->offset_unit_type);
#endif #endif
#ifdef PNG_WRITE_pCAL_SUPPORTED #ifdef PNG_WRITE_pCAL_SUPPORTED
if (info_ptr->valid & PNG_INFO_pCAL) if (info_ptr->valid & PNG_INFO_pCAL)
png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0, png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0,
@ -188,22 +178,10 @@ png_write_info(png_structp png_ptr, png_infop info_ptr)
info_ptr->pcal_units, info_ptr->pcal_params); info_ptr->pcal_units, info_ptr->pcal_params);
#endif #endif
#ifdef PNG_sCAL_SUPPORTED
if (info_ptr->valid & PNG_INFO_sCAL)
#ifdef PNG_WRITE_sCAL_SUPPORTED #ifdef PNG_WRITE_sCAL_SUPPORTED
#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) if (info_ptr->valid & PNG_INFO_sCAL)
png_write_sCAL(png_ptr, (int)info_ptr->scal_unit,
info_ptr->scal_pixel_width, info_ptr->scal_pixel_height);
#else /* !FLOATING_POINT */
#ifdef PNG_FIXED_POINT_SUPPORTED
png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit, png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit,
info_ptr->scal_s_width, info_ptr->scal_s_height); info_ptr->scal_s_width, info_ptr->scal_s_height);
#endif /* FIXED_POINT */
#endif /* FLOATING_POINT */
#else /* !WRITE_sCAL */
png_warning(png_ptr,
"png_write_sCAL not supported; sCAL chunk not written");
#endif /* WRITE_sCAL */
#endif /* sCAL */ #endif /* sCAL */
#ifdef PNG_WRITE_pHYs_SUPPORTED #ifdef PNG_WRITE_pHYs_SUPPORTED
@ -249,6 +227,7 @@ png_write_info(png_structp png_ptr, png_infop info_ptr)
/* Mark this chunk as written */ /* Mark this chunk as written */
info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
} }
/* If we want a compressed text chunk */ /* If we want a compressed text chunk */
else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt) else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt)
{ {
@ -263,6 +242,7 @@ png_write_info(png_structp png_ptr, png_infop info_ptr)
/* Mark this chunk as written */ /* Mark this chunk as written */
info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
} }
else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
{ {
#ifdef PNG_WRITE_tEXt_SUPPORTED #ifdef PNG_WRITE_tEXt_SUPPORTED
@ -317,6 +297,7 @@ png_write_end(png_structp png_ptr, png_infop info_ptr)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
if (!(png_ptr->mode & PNG_HAVE_IDAT)) if (!(png_ptr->mode & PNG_HAVE_IDAT))
png_error(png_ptr, "No IDATs written into file"); png_error(png_ptr, "No IDATs written into file");
@ -331,6 +312,7 @@ png_write_end(png_structp png_ptr, png_infop info_ptr)
if ((info_ptr->valid & PNG_INFO_tIME) && if ((info_ptr->valid & PNG_INFO_tIME) &&
!(png_ptr->mode & PNG_WROTE_tIME)) !(png_ptr->mode & PNG_WROTE_tIME))
png_write_tIME(png_ptr, &(info_ptr->mod_time)); png_write_tIME(png_ptr, &(info_ptr->mod_time));
#endif #endif
#ifdef PNG_WRITE_TEXT_SUPPORTED #ifdef PNG_WRITE_TEXT_SUPPORTED
/* Loop through comment chunks */ /* Loop through comment chunks */
@ -355,6 +337,7 @@ png_write_end(png_structp png_ptr, png_infop info_ptr)
/* Mark this chunk as written */ /* Mark this chunk as written */
info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
} }
else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt) else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
{ {
#ifdef PNG_WRITE_zTXt_SUPPORTED #ifdef PNG_WRITE_zTXt_SUPPORTED
@ -368,6 +351,7 @@ png_write_end(png_structp png_ptr, png_infop info_ptr)
/* Mark this chunk as written */ /* Mark this chunk as written */
info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
} }
else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
{ {
#ifdef PNG_WRITE_tEXt_SUPPORTED #ifdef PNG_WRITE_tEXt_SUPPORTED
@ -428,7 +412,7 @@ png_write_end(png_structp png_ptr, png_infop info_ptr)
#ifdef PNG_CONVERT_tIME_SUPPORTED #ifdef PNG_CONVERT_tIME_SUPPORTED
/* "tm" structure is not supported on WindowsCE */ /* "tm" structure is not supported on WindowsCE */
void PNGAPI void PNGAPI
png_convert_from_struct_tm(png_timep ptime, struct tm FAR * ttime) png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm FAR * ttime)
{ {
png_debug(1, "in png_convert_from_struct_tm"); png_debug(1, "in png_convert_from_struct_tm");
@ -453,9 +437,9 @@ png_convert_from_time_t(png_timep ptime, time_t ttime)
#endif #endif
/* Initialize png_ptr structure, and allocate any memory needed */ /* Initialize png_ptr structure, and allocate any memory needed */
png_structp PNGAPI PNG_FUNCTION(png_structp,PNGAPI
png_create_write_struct(png_const_charp user_png_ver, png_voidp error_ptr, png_create_write_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
png_error_ptr error_fn, png_error_ptr warn_fn) png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)
{ {
#ifdef PNG_USER_MEM_SUPPORTED #ifdef PNG_USER_MEM_SUPPORTED
return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn, return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn,
@ -463,10 +447,12 @@ png_create_write_struct(png_const_charp user_png_ver, png_voidp error_ptr,
} }
/* Alternate initialize png_ptr structure, and allocate any memory needed */ /* Alternate initialize png_ptr structure, and allocate any memory needed */
png_structp PNGAPI static void png_reset_filter_heuristics(png_structp png_ptr); /* forward decl */
png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
PNG_FUNCTION(png_structp,PNGAPI
png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
png_malloc_ptr malloc_fn, png_free_ptr free_fn) png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
{ {
#endif /* PNG_USER_MEM_SUPPORTED */ #endif /* PNG_USER_MEM_SUPPORTED */
volatile int png_cleanup_needed = 0; volatile int png_cleanup_needed = 0;
@ -476,7 +462,7 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
png_structp png_ptr; png_structp png_ptr;
#ifdef PNG_SETJMP_SUPPORTED #ifdef PNG_SETJMP_SUPPORTED
#ifdef USE_FAR_KEYWORD #ifdef USE_FAR_KEYWORD
jmp_buf jmpbuf; jmp_buf png_jmpbuf;
#endif #endif
#endif #endif
int i; int i;
@ -503,12 +489,12 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
encounter a png_error() will longjmp here. Since the jmpbuf is encounter a png_error() will longjmp here. Since the jmpbuf is
then meaningless we abort instead of returning. */ then meaningless we abort instead of returning. */
#ifdef USE_FAR_KEYWORD #ifdef USE_FAR_KEYWORD
if (setjmp(jmpbuf)) if (setjmp(png_jmpbuf))
#else #else
if (setjmp(png_jmpbuf(png_ptr))) /* sets longjmp to match setjmp */ if (setjmp(png_jmpbuf(png_ptr))) /* sets longjmp to match setjmp */
#endif #endif
#ifdef USE_FAR_KEYWORD #ifdef USE_FAR_KEYWORD
png_memcpy(png_jmpbuf(png_ptr), jmpbuf, png_sizeof(jmp_buf)); png_memcpy(png_jmpbuf(png_ptr), png_jmpbuf, png_sizeof(jmp_buf));
#endif #endif
PNG_ABORT(); PNG_ABORT();
#endif #endif
@ -539,31 +525,32 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
(user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) || (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
(user_png_ver[0] == '0' && user_png_ver[2] < '9')) (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
{ {
#ifdef PNG_STDIO_SUPPORTED #ifdef PNG_CONSOLE_IO_SUPPORTED
char msg[80]; char msg[80];
if (user_png_ver) if (user_png_ver)
{ {
png_snprintf(msg, 80, png_snprintf2(msg, 80,
"Application was compiled with png.h from libpng-%.20s", "Application built with libpng-%.20s"
user_png_ver); " but running with %.20s",
png_warning(png_ptr, msg); user_png_ver,
}
png_snprintf(msg, 80,
"Application is running with png.c from libpng-%.20s",
png_libpng_ver); png_libpng_ver);
png_warning(png_ptr, msg); png_warning(png_ptr, msg);
}
#else
png_warning(png_ptr,
"Incompatible libpng version in application and library");
#endif #endif
#ifdef PNG_ERROR_NUMBERS_SUPPORTED #ifdef PNG_ERROR_NUMBERS_SUPPORTED
png_ptr->flags = 0; png_ptr->flags = 0;
#endif #endif
png_warning(png_ptr,
"Incompatible libpng version in application and library");
png_cleanup_needed = 1; png_cleanup_needed = 1;
} }
} }
/* Initialize zbuf - compression buffer */ /* Initialize zbuf - compression buffer */
png_ptr->zbuf_size = PNG_ZBUF_SIZE; png_ptr->zbuf_size = PNG_ZBUF_SIZE;
if (!png_cleanup_needed) if (!png_cleanup_needed)
{ {
png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr,
@ -571,6 +558,7 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
if (png_ptr->zbuf == NULL) if (png_ptr->zbuf == NULL)
png_cleanup_needed = 1; png_cleanup_needed = 1;
} }
if (png_cleanup_needed) if (png_cleanup_needed)
{ {
/* Clean up PNG structure and deallocate any memory. */ /* Clean up PNG structure and deallocate any memory. */
@ -588,8 +576,7 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
png_set_write_fn(png_ptr, NULL, NULL, NULL); png_set_write_fn(png_ptr, NULL, NULL, NULL);
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT, png_reset_filter_heuristics(png_ptr);
1, NULL, NULL);
#endif #endif
return (png_ptr); return (png_ptr);
@ -656,12 +643,12 @@ png_write_image(png_structp png_ptr, png_bytepp image)
/* Called by user to write a row of image data */ /* Called by user to write a row of image data */
void PNGAPI void PNGAPI
png_write_row(png_structp png_ptr, png_bytep row) png_write_row(png_structp png_ptr, png_const_bytep row)
{ {
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
png_debug2(1, "in png_write_row (row %ld, pass %d)", png_debug2(1, "in png_write_row (row %u, pass %d)",
png_ptr->row_number, png_ptr->pass); png_ptr->row_number, png_ptr->pass);
/* Initialize transformations and other stuff if first time */ /* Initialize transformations and other stuff if first time */
@ -677,6 +664,7 @@ png_write_row(png_structp png_ptr, png_bytep row)
if (png_ptr->transformations & PNG_INVERT_MONO) if (png_ptr->transformations & PNG_INVERT_MONO)
png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined"); png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined");
#endif #endif
#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED) #if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED)
if (png_ptr->transformations & PNG_FILLER) if (png_ptr->transformations & PNG_FILLER)
png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined"); png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined");
@ -687,18 +675,22 @@ png_write_row(png_structp png_ptr, png_bytep row)
png_warning(png_ptr, png_warning(png_ptr,
"PNG_WRITE_PACKSWAP_SUPPORTED is not defined"); "PNG_WRITE_PACKSWAP_SUPPORTED is not defined");
#endif #endif
#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED) #if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED)
if (png_ptr->transformations & PNG_PACK) if (png_ptr->transformations & PNG_PACK)
png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined"); png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined");
#endif #endif
#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED) #if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED)
if (png_ptr->transformations & PNG_SHIFT) if (png_ptr->transformations & PNG_SHIFT)
png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined"); png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined");
#endif #endif
#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED) #if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED)
if (png_ptr->transformations & PNG_BGR) if (png_ptr->transformations & PNG_BGR)
png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined"); png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined");
#endif #endif
#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED) #if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED)
if (png_ptr->transformations & PNG_SWAP_BYTES) if (png_ptr->transformations & PNG_SWAP_BYTES)
png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined"); png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined");
@ -720,6 +712,7 @@ png_write_row(png_structp png_ptr, png_bytep row)
return; return;
} }
break; break;
case 1: case 1:
if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
{ {
@ -727,6 +720,7 @@ png_write_row(png_structp png_ptr, png_bytep row)
return; return;
} }
break; break;
case 2: case 2:
if ((png_ptr->row_number & 0x07) != 4) if ((png_ptr->row_number & 0x07) != 4)
{ {
@ -734,6 +728,7 @@ png_write_row(png_structp png_ptr, png_bytep row)
return; return;
} }
break; break;
case 3: case 3:
if ((png_ptr->row_number & 0x03) || png_ptr->width < 3) if ((png_ptr->row_number & 0x03) || png_ptr->width < 3)
{ {
@ -741,6 +736,7 @@ png_write_row(png_structp png_ptr, png_bytep row)
return; return;
} }
break; break;
case 4: case 4:
if ((png_ptr->row_number & 0x03) != 2) if ((png_ptr->row_number & 0x03) != 2)
{ {
@ -748,6 +744,7 @@ png_write_row(png_structp png_ptr, png_bytep row)
return; return;
} }
break; break;
case 5: case 5:
if ((png_ptr->row_number & 0x01) || png_ptr->width < 2) if ((png_ptr->row_number & 0x01) || png_ptr->width < 2)
{ {
@ -755,6 +752,7 @@ png_write_row(png_structp png_ptr, png_bytep row)
return; return;
} }
break; break;
case 6: case 6:
if (!(png_ptr->row_number & 0x01)) if (!(png_ptr->row_number & 0x01))
{ {
@ -762,6 +760,9 @@ png_write_row(png_structp png_ptr, png_bytep row)
return; return;
} }
break; break;
default: /* error: ignore it */
break;
} }
} }
#endif #endif
@ -778,11 +779,12 @@ png_write_row(png_structp png_ptr, png_bytep row)
png_ptr->row_info.width); png_ptr->row_info.width);
png_debug1(3, "row_info->color_type = %d", png_ptr->row_info.color_type); png_debug1(3, "row_info->color_type = %d", png_ptr->row_info.color_type);
png_debug1(3, "row_info->width = %lu", png_ptr->row_info.width); png_debug1(3, "row_info->width = %u", png_ptr->row_info.width);
png_debug1(3, "row_info->channels = %d", png_ptr->row_info.channels); png_debug1(3, "row_info->channels = %d", png_ptr->row_info.channels);
png_debug1(3, "row_info->bit_depth = %d", png_ptr->row_info.bit_depth); png_debug1(3, "row_info->bit_depth = %d", png_ptr->row_info.bit_depth);
png_debug1(3, "row_info->pixel_depth = %d", png_ptr->row_info.pixel_depth); png_debug1(3, "row_info->pixel_depth = %d", png_ptr->row_info.pixel_depth);
png_debug1(3, "row_info->rowbytes = %lu", png_ptr->row_info.rowbytes); png_debug1(3, "row_info->rowbytes = %lu",
(unsigned long)png_ptr->row_info.rowbytes);
/* Copy user's row into buffer, leaving room for filter byte. */ /* Copy user's row into buffer, leaving room for filter byte. */
png_memcpy(png_ptr->row_buf + 1, row, png_ptr->row_info.rowbytes); png_memcpy(png_ptr->row_buf + 1, row, png_ptr->row_info.rowbytes);
@ -841,6 +843,7 @@ png_set_flush(png_structp png_ptr, int nrows)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
png_ptr->flush_dist = (nrows < 0 ? 0 : nrows); png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
} }
@ -854,6 +857,7 @@ png_write_flush(png_structp png_ptr)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
/* We have already written out all of the data */ /* We have already written out all of the data */
if (png_ptr->row_number >= png_ptr->num_rows) if (png_ptr->row_number >= png_ptr->num_rows)
return; return;
@ -871,6 +875,7 @@ png_write_flush(png_structp png_ptr)
{ {
if (png_ptr->zstream.msg != NULL) if (png_ptr->zstream.msg != NULL)
png_error(png_ptr, png_ptr->zstream.msg); png_error(png_ptr, png_ptr->zstream.msg);
else else
png_error(png_ptr, "zlib error"); png_error(png_ptr, "zlib error");
} }
@ -878,8 +883,7 @@ png_write_flush(png_structp png_ptr)
if (!(png_ptr->zstream.avail_out)) if (!(png_ptr->zstream.avail_out))
{ {
/* Write the IDAT and reset the zlib output buffer */ /* Write the IDAT and reset the zlib output buffer */
png_write_IDAT(png_ptr, png_ptr->zbuf, png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
png_ptr->zbuf_size);
png_ptr->zstream.next_out = png_ptr->zbuf; png_ptr->zstream.next_out = png_ptr->zbuf;
png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
wrote_IDAT = 1; wrote_IDAT = 1;
@ -1006,16 +1010,15 @@ png_write_destroy(png_structp png_ptr)
#endif #endif
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
png_free(png_ptr, png_ptr->prev_filters); /* Use this to save a little code space, it doesn't free the filter_costs */
png_free(png_ptr, png_ptr->filter_weights); png_reset_filter_heuristics(png_ptr);
png_free(png_ptr, png_ptr->inv_filter_weights);
png_free(png_ptr, png_ptr->filter_costs); png_free(png_ptr, png_ptr->filter_costs);
png_free(png_ptr, png_ptr->inv_filter_costs); png_free(png_ptr, png_ptr->inv_filter_costs);
#endif #endif
#ifdef PNG_SETJMP_SUPPORTED #ifdef PNG_SETJMP_SUPPORTED
/* Reset structure */ /* Reset structure */
png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf)); png_memcpy(tmp_jmp, png_ptr->png_jmpbuf, png_sizeof(jmp_buf));
#endif #endif
error_fn = png_ptr->error_fn; error_fn = png_ptr->error_fn;
@ -1035,7 +1038,7 @@ png_write_destroy(png_structp png_ptr)
#endif #endif
#ifdef PNG_SETJMP_SUPPORTED #ifdef PNG_SETJMP_SUPPORTED
png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf)); png_memcpy(png_ptr->png_jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
#endif #endif
} }
@ -1047,10 +1050,12 @@ png_set_filter(png_structp png_ptr, int method, int filters)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
#ifdef PNG_MNG_FEATURES_SUPPORTED #ifdef PNG_MNG_FEATURES_SUPPORTED
if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
(method == PNG_INTRAPIXEL_DIFFERENCING)) (method == PNG_INTRAPIXEL_DIFFERENCING))
method = PNG_FILTER_TYPE_BASE; method = PNG_FILTER_TYPE_BASE;
#endif #endif
if (method == PNG_FILTER_TYPE_BASE) if (method == PNG_FILTER_TYPE_BASE)
{ {
@ -1063,18 +1068,25 @@ png_set_filter(png_structp png_ptr, int method, int filters)
#endif /* PNG_WRITE_FILTER_SUPPORTED */ #endif /* PNG_WRITE_FILTER_SUPPORTED */
case PNG_FILTER_VALUE_NONE: case PNG_FILTER_VALUE_NONE:
png_ptr->do_filter = PNG_FILTER_NONE; break; png_ptr->do_filter = PNG_FILTER_NONE; break;
#ifdef PNG_WRITE_FILTER_SUPPORTED #ifdef PNG_WRITE_FILTER_SUPPORTED
case PNG_FILTER_VALUE_SUB: case PNG_FILTER_VALUE_SUB:
png_ptr->do_filter = PNG_FILTER_SUB; break; png_ptr->do_filter = PNG_FILTER_SUB; break;
case PNG_FILTER_VALUE_UP: case PNG_FILTER_VALUE_UP:
png_ptr->do_filter = PNG_FILTER_UP; break; png_ptr->do_filter = PNG_FILTER_UP; break;
case PNG_FILTER_VALUE_AVG: case PNG_FILTER_VALUE_AVG:
png_ptr->do_filter = PNG_FILTER_AVG; break; png_ptr->do_filter = PNG_FILTER_AVG; break;
case PNG_FILTER_VALUE_PAETH: case PNG_FILTER_VALUE_PAETH:
png_ptr->do_filter = PNG_FILTER_PAETH; break; png_ptr->do_filter = PNG_FILTER_PAETH; break;
default: png_ptr->do_filter = (png_byte)filters; break;
default:
png_ptr->do_filter = (png_byte)filters; break;
#else #else
default: png_warning(png_ptr, "Unknown row filter for method 0"); default:
png_warning(png_ptr, "Unknown row filter for method 0");
#endif /* PNG_WRITE_FILTER_SUPPORTED */ #endif /* PNG_WRITE_FILTER_SUPPORTED */
} }
@ -1102,8 +1114,10 @@ png_set_filter(png_structp png_ptr, int method, int filters)
if (png_ptr->prev_row == NULL) if (png_ptr->prev_row == NULL)
{ {
png_warning(png_ptr, "Can't add Up filter after starting"); png_warning(png_ptr, "Can't add Up filter after starting");
png_ptr->do_filter &= ~PNG_FILTER_UP; png_ptr->do_filter = (png_byte)(png_ptr->do_filter &
~PNG_FILTER_UP);
} }
else else
{ {
png_ptr->up_row = (png_bytep)png_malloc(png_ptr, png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
@ -1117,8 +1131,10 @@ png_set_filter(png_structp png_ptr, int method, int filters)
if (png_ptr->prev_row == NULL) if (png_ptr->prev_row == NULL)
{ {
png_warning(png_ptr, "Can't add Average filter after starting"); png_warning(png_ptr, "Can't add Average filter after starting");
png_ptr->do_filter &= ~PNG_FILTER_AVG; png_ptr->do_filter = (png_byte)(png_ptr->do_filter &
~PNG_FILTER_AVG);
} }
else else
{ {
png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
@ -1135,6 +1151,7 @@ png_set_filter(png_structp png_ptr, int method, int filters)
png_warning(png_ptr, "Can't add Paeth filter after starting"); png_warning(png_ptr, "Can't add Paeth filter after starting");
png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH); png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH);
} }
else else
{ {
png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
@ -1160,40 +1177,59 @@ png_set_filter(png_structp png_ptr, int method, int filters)
* better compression. * better compression.
*/ */
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* GRR 970116 */ #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* GRR 970116 */
void PNGAPI /* Convenience reset API. */
png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, static void
int num_weights, png_doublep filter_weights, png_reset_filter_heuristics(png_structp png_ptr)
png_doublep filter_costs) {
/* Clear out any old values in the 'weights' - this must be done because if
* the app calls set_filter_heuristics multiple times with different
* 'num_weights' values we would otherwise potentially have wrong sized
* arrays.
*/
png_ptr->num_prev_filters = 0;
png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED;
if (png_ptr->prev_filters != NULL)
{
png_bytep old = png_ptr->prev_filters;
png_ptr->prev_filters = NULL;
png_free(png_ptr, old);
}
if (png_ptr->filter_weights != NULL)
{
png_uint_16p old = png_ptr->filter_weights;
png_ptr->filter_weights = NULL;
png_free(png_ptr, old);
}
if (png_ptr->inv_filter_weights != NULL)
{
png_uint_16p old = png_ptr->inv_filter_weights;
png_ptr->inv_filter_weights = NULL;
png_free(png_ptr, old);
}
/* Leave the filter_costs - this array is fixed size. */
}
static int
png_init_filter_heuristics(png_structp png_ptr, int heuristic_method,
int num_weights)
{
if (png_ptr == NULL)
return 0;
/* Clear out the arrays */
png_reset_filter_heuristics(png_ptr);
/* Check arguments; the 'reset' function makes the correct settings for the
* unweighted case, but we must handle the weight case by initializing the
* arrays for the caller.
*/
if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
{ {
int i; int i;
png_debug(1, "in png_set_filter_heuristics");
if (png_ptr == NULL)
return;
if (heuristic_method >= PNG_FILTER_HEURISTIC_LAST)
{
png_warning(png_ptr, "Unknown filter heuristic method");
return;
}
if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT)
{
heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED;
}
if (num_weights < 0 || filter_weights == NULL ||
heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED)
{
num_weights = 0;
}
png_ptr->num_prev_filters = (png_byte)num_weights;
png_ptr->heuristic_method = (png_byte)heuristic_method;
if (num_weights > 0) if (num_weights > 0)
{
if (png_ptr->prev_filters == NULL)
{ {
png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr, png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr,
(png_uint_32)(png_sizeof(png_byte) * num_weights)); (png_uint_32)(png_sizeof(png_byte) * num_weights));
@ -1203,37 +1239,21 @@ png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
{ {
png_ptr->prev_filters[i] = 255; png_ptr->prev_filters[i] = 255;
} }
}
if (png_ptr->filter_weights == NULL)
{
png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr, png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr,
(png_uint_32)(png_sizeof(png_uint_16) * num_weights)); (png_uint_32)(png_sizeof(png_uint_16) * num_weights));
png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr, png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr,
(png_uint_32)(png_sizeof(png_uint_16) * num_weights)); (png_uint_32)(png_sizeof(png_uint_16) * num_weights));
for (i = 0; i < num_weights; i++)
{
png_ptr->inv_filter_weights[i] =
png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
}
}
for (i = 0; i < num_weights; i++) for (i = 0; i < num_weights; i++)
{
if (filter_weights[i] < 0.0)
{ {
png_ptr->inv_filter_weights[i] = png_ptr->inv_filter_weights[i] =
png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
} }
else
{ /* Safe to set this now */
png_ptr->inv_filter_weights[i] = png_ptr->num_prev_filters = (png_byte)num_weights;
(png_uint_16)((double)PNG_WEIGHT_FACTOR*filter_weights[i]+0.5);
png_ptr->filter_weights[i] =
(png_uint_16)((double)PNG_WEIGHT_FACTOR/filter_weights[i]+0.5);
}
}
} }
/* If, in the future, there are other filter methods, this would /* If, in the future, there are other filter methods, this would
@ -1246,12 +1266,122 @@ png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr, png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr,
(png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
}
for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
{ {
png_ptr->inv_filter_costs[i] = png_ptr->inv_filter_costs[i] =
png_ptr->filter_costs[i] = PNG_COST_FACTOR; png_ptr->filter_costs[i] = PNG_COST_FACTOR;
} }
/* All the arrays are inited, safe to set this: */
png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_WEIGHTED;
/* Return the 'ok' code. */
return 1;
}
else if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT ||
heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED)
{
return 1;
}
else
{
png_warning(png_ptr, "Unknown filter heuristic method");
return 0;
}
}
/* Provide floating and fixed point APIs */
#ifdef PNG_FLOATING_POINT_SUPPORTED
void PNGAPI
png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
int num_weights, png_const_doublep filter_weights,
png_const_doublep filter_costs)
{
png_debug(1, "in png_set_filter_heuristics");
/* The internal API allocates all the arrays and ensures that the elements of
* those arrays are set to the default value.
*/
if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights))
return;
/* If using the weighted method copy in the weights. */
if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
{
int i;
for (i = 0; i < num_weights; i++)
{
if (filter_weights[i] <= 0.0)
{
png_ptr->inv_filter_weights[i] =
png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
}
else
{
png_ptr->inv_filter_weights[i] =
(png_uint_16)(PNG_WEIGHT_FACTOR*filter_weights[i]+.5);
png_ptr->filter_weights[i] =
(png_uint_16)(PNG_WEIGHT_FACTOR/filter_weights[i]+.5);
}
}
/* Here is where we set the relative costs of the different filters. We
* should take the desired compression level into account when setting
* the costs, so that Paeth, for instance, has a high relative cost at low
* compression levels, while it has a lower relative cost at higher
* compression settings. The filter types are in order of increasing
* relative cost, so it would be possible to do this with an algorithm.
*/
for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) if (filter_costs[i] >= 1.0)
{
png_ptr->inv_filter_costs[i] =
(png_uint_16)(PNG_COST_FACTOR / filter_costs[i] + .5);
png_ptr->filter_costs[i] =
(png_uint_16)(PNG_COST_FACTOR * filter_costs[i] + .5);
}
}
}
#endif /* FLOATING_POINT */
#ifdef PNG_FIXED_POINT_SUPPORTED
void PNGAPI
png_set_filter_heuristics_fixed(png_structp png_ptr, int heuristic_method,
int num_weights, png_const_fixed_point_p filter_weights,
png_const_fixed_point_p filter_costs)
{
png_debug(1, "in png_set_filter_heuristics_fixed");
/* The internal API allocates all the arrays and ensures that the elements of
* those arrays are set to the default value.
*/
if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights))
return;
/* If using the weighted method copy in the weights. */
if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
{
int i;
for (i = 0; i < num_weights; i++)
{
if (filter_weights[i] <= 0)
{
png_ptr->inv_filter_weights[i] =
png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
}
else
{
png_ptr->inv_filter_weights[i] = (png_uint_16)
((PNG_WEIGHT_FACTOR*filter_weights[i]+PNG_FP_HALF)/PNG_FP_1);
png_ptr->filter_weights[i] = (png_uint_16)((PNG_WEIGHT_FACTOR*
PNG_FP_1+(filter_weights[i]/2))/filter_weights[i]);
}
} }
/* Here is where we set the relative costs of the different filters. We /* Here is where we set the relative costs of the different filters. We
@ -1262,21 +1392,27 @@ png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
* relative cost, so it would be possible to do this with an algorithm. * relative cost, so it would be possible to do this with an algorithm.
*/ */
for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
if (filter_costs[i] >= PNG_FP_1)
{ {
if (filter_costs == NULL || filter_costs[i] < 0.0) png_uint_32 tmp;
{
png_ptr->inv_filter_costs[i] = /* Use a 32 bit unsigned temporary here because otherwise the
png_ptr->filter_costs[i] = PNG_COST_FACTOR; * intermediate value will be a 32 bit *signed* integer (ANSI rules)
} * and this will get the wrong answer on division.
else if (filter_costs[i] >= 1.0) */
{ tmp = PNG_COST_FACTOR*PNG_FP_1 + (filter_costs[i]/2);
png_ptr->inv_filter_costs[i] = tmp /= filter_costs[i];
(png_uint_16)((double)PNG_COST_FACTOR / filter_costs[i] + 0.5);
png_ptr->filter_costs[i] = png_ptr->inv_filter_costs[i] = (png_uint_16)tmp;
(png_uint_16)((double)PNG_COST_FACTOR * filter_costs[i] + 0.5);
tmp = PNG_COST_FACTOR * filter_costs[i] + PNG_FP_HALF;
tmp /= PNG_FP_1;
png_ptr->filter_costs[i] = (png_uint_16)tmp;
} }
} }
} }
#endif /* FIXED_POINT */
#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ #endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
void PNGAPI void PNGAPI
@ -1286,6 +1422,7 @@ png_set_compression_level(png_structp png_ptr, int level)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL; png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL;
png_ptr->zlib_level = level; png_ptr->zlib_level = level;
} }
@ -1297,6 +1434,7 @@ png_set_compression_mem_level(png_structp png_ptr, int mem_level)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL; png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL;
png_ptr->zlib_mem_level = mem_level; png_ptr->zlib_mem_level = mem_level;
} }
@ -1308,6 +1446,7 @@ png_set_compression_strategy(png_structp png_ptr, int strategy)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY; png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY;
png_ptr->zlib_strategy = strategy; png_ptr->zlib_strategy = strategy;
} }
@ -1317,10 +1456,13 @@ png_set_compression_window_bits(png_structp png_ptr, int window_bits)
{ {
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
if (window_bits > 15) if (window_bits > 15)
png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
else if (window_bits < 8) else if (window_bits < 8)
png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); png_warning(png_ptr, "Only compression windows >= 256 supported by PNG");
#ifndef WBITS_8_OK #ifndef WBITS_8_OK
/* Avoid libpng bug with 256-byte windows */ /* Avoid libpng bug with 256-byte windows */
if (window_bits == 8) if (window_bits == 8)
@ -1328,6 +1470,7 @@ png_set_compression_window_bits(png_structp png_ptr, int window_bits)
png_warning(png_ptr, "Compression window is being reset to 512"); png_warning(png_ptr, "Compression window is being reset to 512");
window_bits = 9; window_bits = 9;
} }
#endif #endif
png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS; png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS;
png_ptr->zlib_window_bits = window_bits; png_ptr->zlib_window_bits = window_bits;
@ -1340,8 +1483,10 @@ png_set_compression_method(png_structp png_ptr, int method)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
if (method != 8) if (method != 8)
png_warning(png_ptr, "Only compression method 8 is supported by PNG"); png_warning(png_ptr, "Only compression method 8 is supported by PNG");
png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD; png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD;
png_ptr->zlib_method = method; png_ptr->zlib_method = method;
} }
@ -1351,6 +1496,7 @@ png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn)
{ {
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
png_ptr->write_row_fn = write_row_fn; png_ptr->write_row_fn = write_row_fn;
} }
@ -1363,6 +1509,7 @@ png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
png_ptr->transformations |= PNG_USER_TRANSFORM; png_ptr->transformations |= PNG_USER_TRANSFORM;
png_ptr->write_user_transform_fn = write_user_transform_fn; png_ptr->write_user_transform_fn = write_user_transform_fn;
} }
@ -1413,6 +1560,7 @@ png_write_png(png_structp png_ptr, png_infop info_ptr,
/* Pack XRGB/RGBX/ARGB/RGBA into * RGB (4 channels -> 3 channels) */ /* Pack XRGB/RGBX/ARGB/RGBA into * RGB (4 channels -> 3 channels) */
if (transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) if (transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER)
png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
else if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) else if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE)
png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
#endif #endif
@ -1450,8 +1598,8 @@ png_write_png(png_structp png_ptr, png_infop info_ptr,
/* It is REQUIRED to call this to finish writing the rest of the file */ /* It is REQUIRED to call this to finish writing the rest of the file */
png_write_end(png_ptr, info_ptr); png_write_end(png_ptr, info_ptr);
transforms = transforms; /* Quiet compiler warnings */ PNG_UNUSED(transforms) /* Quiet compiler warnings */
params = params; PNG_UNUSED(params)
} }
#endif #endif
#endif /* PNG_WRITE_SUPPORTED */ #endif /* PNG_WRITE_SUPPORTED */

View File

@ -1,8 +1,8 @@
/* pngwtran.c - transforms the data in a row for PNG writers /* pngwtran.c - transforms the data in a row for PNG writers
* *
* Last changed in libpng 1.4.1 [February 25, 2010] * Last changed in libpng 1.5.2 [March 31, 2011]
* Copyright (c) 1998-2010 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
@ -11,11 +11,10 @@
* and license in png.h * and license in png.h
*/ */
#define PNG_NO_PEDANTIC_WARNINGS
#include "png.h"
#ifdef PNG_WRITE_SUPPORTED
#include "pngpriv.h" #include "pngpriv.h"
#ifdef PNG_WRITE_SUPPORTED
/* Transform the data according to the user's wishes. The order of /* Transform the data according to the user's wishes. The order of
* transformations is significant. * transformations is significant.
*/ */
@ -35,48 +34,57 @@ png_do_write_transformations(png_structp png_ptr)
(png_ptr, /* png_ptr */ (png_ptr, /* png_ptr */
&(png_ptr->row_info), /* row_info: */ &(png_ptr->row_info), /* row_info: */
/* png_uint_32 width; width of row */ /* png_uint_32 width; width of row */
/* png_uint_32 rowbytes; number of bytes in row */ /* png_size_t rowbytes; number of bytes in row */
/* png_byte color_type; color type of pixels */ /* png_byte color_type; color type of pixels */
/* png_byte bit_depth; bit depth of samples */ /* png_byte bit_depth; bit depth of samples */
/* png_byte channels; number of channels (1-4) */ /* png_byte channels; number of channels (1-4) */
/* png_byte pixel_depth; bits per pixel (depth*channels) */ /* png_byte pixel_depth; bits per pixel (depth*channels) */
png_ptr->row_buf + 1); /* start of pixel data for row */ png_ptr->row_buf + 1); /* start of pixel data for row */
#endif #endif
#ifdef PNG_WRITE_FILLER_SUPPORTED #ifdef PNG_WRITE_FILLER_SUPPORTED
if (png_ptr->transformations & PNG_FILLER) if (png_ptr->transformations & PNG_FILLER)
png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, png_do_strip_channel(&(png_ptr->row_info), png_ptr->row_buf + 1,
png_ptr->flags); !(png_ptr->flags & PNG_FILLER_AFTER));
#endif #endif
#ifdef PNG_WRITE_PACKSWAP_SUPPORTED #ifdef PNG_WRITE_PACKSWAP_SUPPORTED
if (png_ptr->transformations & PNG_PACKSWAP) if (png_ptr->transformations & PNG_PACKSWAP)
png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif #endif
#ifdef PNG_WRITE_PACK_SUPPORTED #ifdef PNG_WRITE_PACK_SUPPORTED
if (png_ptr->transformations & PNG_PACK) if (png_ptr->transformations & PNG_PACK)
png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1, png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
(png_uint_32)png_ptr->bit_depth); (png_uint_32)png_ptr->bit_depth);
#endif #endif
#ifdef PNG_WRITE_SWAP_SUPPORTED #ifdef PNG_WRITE_SWAP_SUPPORTED
if (png_ptr->transformations & PNG_SWAP_BYTES) if (png_ptr->transformations & PNG_SWAP_BYTES)
png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif #endif
#ifdef PNG_WRITE_SHIFT_SUPPORTED #ifdef PNG_WRITE_SHIFT_SUPPORTED
if (png_ptr->transformations & PNG_SHIFT) if (png_ptr->transformations & PNG_SHIFT)
png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1, png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
&(png_ptr->shift)); &(png_ptr->shift));
#endif #endif
#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
if (png_ptr->transformations & PNG_SWAP_ALPHA) if (png_ptr->transformations & PNG_SWAP_ALPHA)
png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif #endif
#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
if (png_ptr->transformations & PNG_INVERT_ALPHA) if (png_ptr->transformations & PNG_INVERT_ALPHA)
png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif #endif
#ifdef PNG_WRITE_BGR_SUPPORTED #ifdef PNG_WRITE_BGR_SUPPORTED
if (png_ptr->transformations & PNG_BGR) if (png_ptr->transformations & PNG_BGR)
png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif #endif
#ifdef PNG_WRITE_INVERT_SUPPORTED #ifdef PNG_WRITE_INVERT_SUPPORTED
if (png_ptr->transformations & PNG_INVERT_MONO) if (png_ptr->transformations & PNG_INVERT_MONO)
png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
@ -114,9 +122,12 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
{ {
if (*sp != 0) if (*sp != 0)
v |= mask; v |= mask;
sp++; sp++;
if (mask > 1) if (mask > 1)
mask >>= 1; mask >>= 1;
else else
{ {
mask = 0x80; mask = 0x80;
@ -125,10 +136,13 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
v = 0; v = 0;
} }
} }
if (mask != 0x80) if (mask != 0x80)
*dp = (png_byte)v; *dp = (png_byte)v;
break; break;
} }
case 2: case 2:
{ {
png_bytep sp, dp; png_bytep sp, dp;
@ -140,12 +154,14 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
dp = row; dp = row;
shift = 6; shift = 6;
v = 0; v = 0;
for (i = 0; i < row_width; i++) for (i = 0; i < row_width; i++)
{ {
png_byte value; png_byte value;
value = (png_byte)(*sp & 0x03); value = (png_byte)(*sp & 0x03);
v |= (value << shift); v |= (value << shift);
if (shift == 0) if (shift == 0)
{ {
shift = 6; shift = 6;
@ -153,14 +169,19 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
dp++; dp++;
v = 0; v = 0;
} }
else else
shift -= 2; shift -= 2;
sp++; sp++;
} }
if (shift != 6) if (shift != 6)
*dp = (png_byte)v; *dp = (png_byte)v;
break; break;
} }
case 4: case 4:
{ {
png_bytep sp, dp; png_bytep sp, dp;
@ -172,6 +193,7 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
dp = row; dp = row;
shift = 4; shift = 4;
v = 0; v = 0;
for (i = 0; i < row_width; i++) for (i = 0; i < row_width; i++)
{ {
png_byte value; png_byte value;
@ -186,19 +208,23 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
dp++; dp++;
v = 0; v = 0;
} }
else else
shift -= 4; shift -= 4;
sp++; sp++;
} }
if (shift != 4) if (shift != 4)
*dp = (png_byte)v; *dp = (png_byte)v;
break; break;
} }
default: default:
break; break;
} }
row_info->bit_depth = (png_byte)bit_depth; row_info->bit_depth = (png_byte)bit_depth;
row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels); row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
@ -216,12 +242,12 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
* data to 0 to 15. * data to 0 to 15.
*/ */
void /* PRIVATE */ void /* PRIVATE */
png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth) png_do_shift(png_row_infop row_info, png_bytep row,
png_const_color_8p bit_depth)
{ {
png_debug(1, "in png_do_shift"); png_debug(1, "in png_do_shift");
if ( if (row_info->color_type != PNG_COLOR_TYPE_PALETTE)
row_info->color_type != PNG_COLOR_TYPE_PALETTE)
{ {
int shift_start[4], shift_dec[4]; int shift_start[4], shift_dec[4];
int channels = 0; int channels = 0;
@ -231,19 +257,23 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
shift_start[channels] = row_info->bit_depth - bit_depth->red; shift_start[channels] = row_info->bit_depth - bit_depth->red;
shift_dec[channels] = bit_depth->red; shift_dec[channels] = bit_depth->red;
channels++; channels++;
shift_start[channels] = row_info->bit_depth - bit_depth->green; shift_start[channels] = row_info->bit_depth - bit_depth->green;
shift_dec[channels] = bit_depth->green; shift_dec[channels] = bit_depth->green;
channels++; channels++;
shift_start[channels] = row_info->bit_depth - bit_depth->blue; shift_start[channels] = row_info->bit_depth - bit_depth->blue;
shift_dec[channels] = bit_depth->blue; shift_dec[channels] = bit_depth->blue;
channels++; channels++;
} }
else else
{ {
shift_start[channels] = row_info->bit_depth - bit_depth->gray; shift_start[channels] = row_info->bit_depth - bit_depth->gray;
shift_dec[channels] = bit_depth->gray; shift_dec[channels] = bit_depth->gray;
channels++; channels++;
} }
if (row_info->color_type & PNG_COLOR_MASK_ALPHA) if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
{ {
shift_start[channels] = row_info->bit_depth - bit_depth->alpha; shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
@ -255,14 +285,16 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
if (row_info->bit_depth < 8) if (row_info->bit_depth < 8)
{ {
png_bytep bp = row; png_bytep bp = row;
png_uint_32 i; png_size_t i;
png_byte mask; png_byte mask;
png_uint_32 row_bytes = row_info->rowbytes; png_size_t row_bytes = row_info->rowbytes;
if (bit_depth->gray == 1 && row_info->bit_depth == 2) if (bit_depth->gray == 1 && row_info->bit_depth == 2)
mask = 0x55; mask = 0x55;
else if (row_info->bit_depth == 4 && bit_depth->gray == 3) else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
mask = 0x11; mask = 0x11;
else else
mask = 0xff; mask = 0xff;
@ -273,15 +305,18 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
v = *bp; v = *bp;
*bp = 0; *bp = 0;
for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0]) for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
{ {
if (j > 0) if (j > 0)
*bp |= (png_byte)((v << j) & 0xff); *bp |= (png_byte)((v << j) & 0xff);
else else
*bp |= (png_byte)((v >> (-j)) & mask); *bp |= (png_byte)((v >> (-j)) & mask);
} }
} }
} }
else if (row_info->bit_depth == 8) else if (row_info->bit_depth == 8)
{ {
png_bytep bp = row; png_bytep bp = row;
@ -297,15 +332,18 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
v = *bp; v = *bp;
*bp = 0; *bp = 0;
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
{ {
if (j > 0) if (j > 0)
*bp |= (png_byte)((v << j) & 0xff); *bp |= (png_byte)((v << j) & 0xff);
else else
*bp |= (png_byte)((v >> (-j)) & 0xff); *bp |= (png_byte)((v >> (-j)) & 0xff);
} }
} }
} }
else else
{ {
png_bytep bp; png_bytep bp;
@ -320,10 +358,12 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1)); v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
value = 0; value = 0;
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
{ {
if (j > 0) if (j > 0)
value |= (png_uint_16)((v << j) & (png_uint_16)0xffff); value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
else else
value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff); value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
} }
@ -344,12 +384,13 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
{ {
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{ {
/* This converts from ARGB to RGBA */
if (row_info->bit_depth == 8) if (row_info->bit_depth == 8)
{ {
/* This converts from ARGB to RGBA */
png_bytep sp, dp; png_bytep sp, dp;
png_uint_32 i; png_uint_32 i;
png_uint_32 row_width = row_info->width; png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++) for (i = 0, sp = dp = row; i < row_width; i++)
{ {
png_byte save = *(sp++); png_byte save = *(sp++);
@ -359,9 +400,11 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
*(dp++) = save; *(dp++) = save;
} }
} }
/* This converts from AARRGGBB to RRGGBBAA */
#ifdef PNG_WRITE_16BIT_SUPPORTED
else else
{ {
/* This converts from AARRGGBB to RRGGBBAA */
png_bytep sp, dp; png_bytep sp, dp;
png_uint_32 i; png_uint_32 i;
png_uint_32 row_width = row_info->width; png_uint_32 row_width = row_info->width;
@ -381,12 +424,14 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
*(dp++) = save[1]; *(dp++) = save[1];
} }
} }
#endif /* PNG_WRITE_16BIT_SUPPORTED */
} }
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
{ {
/* This converts from AG to GA */
if (row_info->bit_depth == 8) if (row_info->bit_depth == 8)
{ {
/* This converts from AG to GA */
png_bytep sp, dp; png_bytep sp, dp;
png_uint_32 i; png_uint_32 i;
png_uint_32 row_width = row_info->width; png_uint_32 row_width = row_info->width;
@ -398,9 +443,11 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
*(dp++) = save; *(dp++) = save;
} }
} }
/* This converts from AAGG to GGAA */
#ifdef PNG_WRITE_16BIT_SUPPORTED
else else
{ {
/* This converts from AAGG to GGAA */
png_bytep sp, dp; png_bytep sp, dp;
png_uint_32 i; png_uint_32 i;
png_uint_32 row_width = row_info->width; png_uint_32 row_width = row_info->width;
@ -416,6 +463,7 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
*(dp++) = save[1]; *(dp++) = save[1];
} }
} }
#endif /* PNG_WRITE_16BIT_SUPPORTED */
} }
} }
} }
@ -430,12 +478,13 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
{ {
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{ {
/* This inverts the alpha channel in RGBA */
if (row_info->bit_depth == 8) if (row_info->bit_depth == 8)
{ {
/* This inverts the alpha channel in RGBA */
png_bytep sp, dp; png_bytep sp, dp;
png_uint_32 i; png_uint_32 i;
png_uint_32 row_width = row_info->width; png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++) for (i = 0, sp = dp = row; i < row_width; i++)
{ {
/* Does nothing /* Does nothing
@ -447,9 +496,11 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
*(dp++) = (png_byte)(255 - *(sp++)); *(dp++) = (png_byte)(255 - *(sp++));
} }
} }
/* This inverts the alpha channel in RRGGBBAA */
#ifdef PNG_WRITE_16BIT_SUPPORTED
else else
{ {
/* This inverts the alpha channel in RRGGBBAA */
png_bytep sp, dp; png_bytep sp, dp;
png_uint_32 i; png_uint_32 i;
png_uint_32 row_width = row_info->width; png_uint_32 row_width = row_info->width;
@ -469,12 +520,14 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
*(dp++) = (png_byte)(255 - *(sp++)); *(dp++) = (png_byte)(255 - *(sp++));
} }
} }
#endif /* PNG_WRITE_16BIT_SUPPORTED */
} }
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
{ {
/* This inverts the alpha channel in GA */
if (row_info->bit_depth == 8) if (row_info->bit_depth == 8)
{ {
/* This inverts the alpha channel in GA */
png_bytep sp, dp; png_bytep sp, dp;
png_uint_32 i; png_uint_32 i;
png_uint_32 row_width = row_info->width; png_uint_32 row_width = row_info->width;
@ -485,9 +538,11 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
*(dp++) = (png_byte)(255 - *(sp++)); *(dp++) = (png_byte)(255 - *(sp++));
} }
} }
/* This inverts the alpha channel in GGAA */
#ifdef PNG_WRITE_16BIT_SUPPORTED
else else
{ {
/* This inverts the alpha channel in GGAA */
png_bytep sp, dp; png_bytep sp, dp;
png_uint_32 i; png_uint_32 i;
png_uint_32 row_width = row_info->width; png_uint_32 row_width = row_info->width;
@ -503,6 +558,7 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
*(dp++) = (png_byte)(255 - *(sp++)); *(dp++) = (png_byte)(255 - *(sp++));
} }
} }
#endif /* PNG_WRITE_16BIT_SUPPORTED */
} }
} }
} }
@ -515,8 +571,7 @@ png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
{ {
png_debug(1, "in png_do_write_intrapixel"); png_debug(1, "in png_do_write_intrapixel");
if ( if ((row_info->color_type & PNG_COLOR_MASK_COLOR))
(row_info->color_type & PNG_COLOR_MASK_COLOR))
{ {
int bytes_per_pixel; int bytes_per_pixel;
png_uint_32 row_width = row_info->width; png_uint_32 row_width = row_info->width;
@ -527,8 +582,10 @@ png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
if (row_info->color_type == PNG_COLOR_TYPE_RGB) if (row_info->color_type == PNG_COLOR_TYPE_RGB)
bytes_per_pixel = 3; bytes_per_pixel = 3;
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
bytes_per_pixel = 4; bytes_per_pixel = 4;
else else
return; return;
@ -538,6 +595,8 @@ png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
*(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff); *(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff);
} }
} }
#ifdef PNG_WRITE_16BIT_SUPPORTED
else if (row_info->bit_depth == 16) else if (row_info->bit_depth == 16)
{ {
png_bytep rp; png_bytep rp;
@ -545,8 +604,10 @@ png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
if (row_info->color_type == PNG_COLOR_TYPE_RGB) if (row_info->color_type == PNG_COLOR_TYPE_RGB)
bytes_per_pixel = 6; bytes_per_pixel = 6;
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
bytes_per_pixel = 8; bytes_per_pixel = 8;
else else
return; return;
@ -563,6 +624,7 @@ png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
*(rp + 5) = (png_byte)(blue & 0xff); *(rp + 5) = (png_byte)(blue & 0xff);
} }
} }
#endif /* PNG_WRITE_16BIT_SUPPORTED */
} }
} }
#endif /* PNG_MNG_FEATURES_SUPPORTED */ #endif /* PNG_MNG_FEATURES_SUPPORTED */

File diff suppressed because it is too large Load Diff