First pass at adding libpng functionality directly into Stella,

similar to the recent Zlib addition.  This is required for the
RomListWidget, which currently doesn't parse valid PNG files
that are generated outside Stella (in particular, those that
have been optimized and use row filtering).


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2044 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2010-06-11 15:38:17 +00:00
parent cd34147f5e
commit ec1d3c6e10
23 changed files with 28404 additions and 0 deletions

38
src/common/PNGLibrary.cxx Normal file
View File

@ -0,0 +1,38 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2010 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id$
//============================================================================
#include "PNGLibrary.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PNGLibrary::PNGLibrary(const string& filename)
: myFilename(filename)
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PNGLibrary::~PNGLibrary()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const uInt8*
PNGLibrary::readImage(uInt32& width, uInt32& height, StringList& text)
{
return 0;
}

59
src/common/PNGLibrary.hxx Normal file
View File

@ -0,0 +1,59 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2010 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id$
//============================================================================
#ifndef PNGLIBRARY_HXX
#define PNGLIBRARY_HXX
#include <png.h>
#include "bspf.hxx"
#include "StringList.hxx"
/**
This class implements a thin wrapper around the libpng library, and
abstracts all the irrelevant details other loading and saving an
actual image.
@author Stephen Anthony
*/
class PNGLibrary
{
public:
/** Access a PNG image with the given filename. */
PNGLibrary(const string& filename);
~PNGLibrary();
/**
Read a PNG image from the previously specified file.
@param width The width of the image that was read
@param height The height of the image that was read
@param text Any tEXt chunks that were present in the input file
@return On success, a buffer containing image data, otherwise
an exception is thrown. Note that the caller IS NOT
responsible for deleting the buffer array.
*/
const uInt8* readImage(uInt32& width, uInt32& height, StringList& text);
private:
string myFilename;
};
#endif

841
src/libpng/example.c Normal file
View File

@ -0,0 +1,841 @@
#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:
*/
/* Check if row_num is in bounds. */
if ((row_num >= 0) && (row_num < height))
{
/* 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 */

918
src/libpng/png.c Normal file
View File

@ -0,0 +1,918 @@
/* png.c - location for general purpose libpng functions
*
* Last changed in libpng 1.4.2 [May 6, 2010]
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*/
#define PNG_NO_EXTERN
#define PNG_NO_PEDANTIC_WARNINGS
#include "png.h"
#include "pngpriv.h"
/* Generate a compiler error if there is an old png.h in the search path. */
typedef version_1_4_2 Your_png_h_is_not_version_1_4_2;
/* Version information for C files. This had better match the version
* string defined in png.h.
*/
/* Tells libpng that we have already handled the first "num_bytes" bytes
* of the PNG file signature. If the PNG data is embedded into another
* stream we can set num_bytes = 8 so that libpng will not attempt to read
* or write any of the magic bytes before it starts on the IHDR.
*/
#ifdef PNG_READ_SUPPORTED
void PNGAPI
png_set_sig_bytes(png_structp png_ptr, int num_bytes)
{
png_debug(1, "in png_set_sig_bytes");
if (png_ptr == NULL)
return;
if (num_bytes > 8)
png_error(png_ptr, "Too many bytes for PNG signature");
png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
}
/* Checks whether the supplied bytes match the PNG signature. We allow
* checking less than the full 8-byte signature so that those apps that
* already read the first few bytes of a file to determine the file type
* can simply check the remaining bytes for extra assurance. Returns
* an integer less than, equal to, or greater than zero if sig is found,
* respectively, to be less than, to match, or be greater than the correct
* PNG signature (this is the same behaviour as strcmp, memcmp, etc).
*/
int PNGAPI
png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check)
{
png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
if (num_to_check > 8)
num_to_check = 8;
else if (num_to_check < 1)
return (-1);
if (start > 7)
return (-1);
if (start + num_to_check > 8)
num_to_check = 8 - start;
return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check)));
}
#endif /* PNG_READ_SUPPORTED */
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
/* Function to allocate memory for zlib and clear it to 0. */
voidpf /* PRIVATE */
png_zalloc(voidpf png_ptr, uInt items, uInt size)
{
png_voidp ptr;
png_structp p=(png_structp)png_ptr;
png_uint_32 save_flags=p->flags;
png_alloc_size_t num_bytes;
if (png_ptr == NULL)
return (NULL);
if (items > PNG_UINT_32_MAX/size)
{
png_warning (p, "Potential overflow in png_zalloc()");
return (NULL);
}
num_bytes = (png_alloc_size_t)items * size;
p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes);
p->flags=save_flags;
return ((voidpf)ptr);
}
/* Function to free memory for zlib */
void /* PRIVATE */
png_zfree(voidpf png_ptr, voidpf ptr)
{
png_free((png_structp)png_ptr, (png_voidp)ptr);
}
/* Reset the CRC variable to 32 bits of 1's. Care must be taken
* in case CRC is > 32 bits to leave the top bits 0.
*/
void /* PRIVATE */
png_reset_crc(png_structp png_ptr)
{
png_ptr->crc = crc32(0, Z_NULL, 0);
}
/* Calculate the CRC over a section of data. We can only pass as
* much data to this routine as the largest single buffer size. We
* also check that this data will actually be used before going to the
* trouble of calculating it.
*/
void /* PRIVATE */
png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)
{
int need_crc = 1;
if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
{
if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
(PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
need_crc = 0;
}
else /* critical */
{
if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
need_crc = 0;
}
if (need_crc)
png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length);
}
/* Allocate the memory for an info_struct for the application. We don't
* really need the png_ptr, but it could potentially be useful in the
* future. This should be used in favour of malloc(png_sizeof(png_info))
* and png_info_init() so that applications that want to use a shared
* libpng don't have to be recompiled if png_info changes size.
*/
png_infop PNGAPI
png_create_info_struct(png_structp png_ptr)
{
png_infop info_ptr;
png_debug(1, "in png_create_info_struct");
if (png_ptr == NULL)
return (NULL);
#ifdef PNG_USER_MEM_SUPPORTED
info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO,
png_ptr->malloc_fn, png_ptr->mem_ptr);
#else
info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
#endif
if (info_ptr != NULL)
png_info_init_3(&info_ptr, png_sizeof(png_info));
return (info_ptr);
}
/* This function frees the memory associated with a single info struct.
* Normally, one would use either png_destroy_read_struct() or
* png_destroy_write_struct() to free an info struct, but this may be
* useful for some applications.
*/
void PNGAPI
png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
{
png_infop info_ptr = NULL;
png_debug(1, "in png_destroy_info_struct");
if (png_ptr == NULL)
return;
if (info_ptr_ptr != NULL)
info_ptr = *info_ptr_ptr;
if (info_ptr != NULL)
{
png_info_destroy(png_ptr, info_ptr);
#ifdef PNG_USER_MEM_SUPPORTED
png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn,
png_ptr->mem_ptr);
#else
png_destroy_struct((png_voidp)info_ptr);
#endif
*info_ptr_ptr = NULL;
}
}
/* Initialize the info structure. This is now an internal function (0.89)
* and applications using it are urged to use png_create_info_struct()
* instead.
*/
void PNGAPI
png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size)
{
png_infop info_ptr = *ptr_ptr;
png_debug(1, "in png_info_init_3");
if (info_ptr == NULL)
return;
if (png_sizeof(png_info) > png_info_struct_size)
{
png_destroy_struct(info_ptr);
info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
*ptr_ptr = info_ptr;
}
/* Set everything to 0 */
png_memset(info_ptr, 0, png_sizeof(png_info));
}
void PNGAPI
png_data_freer(png_structp png_ptr, png_infop info_ptr,
int freer, png_uint_32 mask)
{
png_debug(1, "in png_data_freer");
if (png_ptr == NULL || info_ptr == NULL)
return;
if (freer == PNG_DESTROY_WILL_FREE_DATA)
info_ptr->free_me |= mask;
else if (freer == PNG_USER_WILL_FREE_DATA)
info_ptr->free_me &= ~mask;
else
png_warning(png_ptr,
"Unknown freer parameter in png_data_freer");
}
void PNGAPI
png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask,
int num)
{
png_debug(1, "in png_free_data");
if (png_ptr == NULL || info_ptr == NULL)
return;
#ifdef PNG_TEXT_SUPPORTED
/* Free text item num or (if num == -1) all text items */
if ((mask & PNG_FREE_TEXT) & info_ptr->free_me)
{
if (num != -1)
{
if (info_ptr->text && info_ptr->text[num].key)
{
png_free(png_ptr, info_ptr->text[num].key);
info_ptr->text[num].key = NULL;
}
}
else
{
int i;
for (i = 0; i < info_ptr->num_text; i++)
png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i);
png_free(png_ptr, info_ptr->text);
info_ptr->text = NULL;
info_ptr->num_text=0;
}
}
#endif
#ifdef PNG_tRNS_SUPPORTED
/* Free any tRNS entry */
if ((mask & PNG_FREE_TRNS) & info_ptr->free_me)
{
png_free(png_ptr, info_ptr->trans_alpha);
info_ptr->trans_alpha = NULL;
info_ptr->valid &= ~PNG_INFO_tRNS;
}
#endif
#ifdef PNG_sCAL_SUPPORTED
/* Free any sCAL entry */
if ((mask & PNG_FREE_SCAL) & info_ptr->free_me)
{
#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
png_free(png_ptr, info_ptr->scal_s_width);
png_free(png_ptr, info_ptr->scal_s_height);
info_ptr->scal_s_width = NULL;
info_ptr->scal_s_height = NULL;
#endif
info_ptr->valid &= ~PNG_INFO_sCAL;
}
#endif
#ifdef PNG_pCAL_SUPPORTED
/* Free any pCAL entry */
if ((mask & PNG_FREE_PCAL) & info_ptr->free_me)
{
png_free(png_ptr, info_ptr->pcal_purpose);
png_free(png_ptr, info_ptr->pcal_units);
info_ptr->pcal_purpose = NULL;
info_ptr->pcal_units = NULL;
if (info_ptr->pcal_params != NULL)
{
int i;
for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
{
png_free(png_ptr, info_ptr->pcal_params[i]);
info_ptr->pcal_params[i] = NULL;
}
png_free(png_ptr, info_ptr->pcal_params);
info_ptr->pcal_params = NULL;
}
info_ptr->valid &= ~PNG_INFO_pCAL;
}
#endif
#ifdef PNG_iCCP_SUPPORTED
/* Free any iCCP entry */
if ((mask & PNG_FREE_ICCP) & info_ptr->free_me)
{
png_free(png_ptr, info_ptr->iccp_name);
png_free(png_ptr, info_ptr->iccp_profile);
info_ptr->iccp_name = NULL;
info_ptr->iccp_profile = NULL;
info_ptr->valid &= ~PNG_INFO_iCCP;
}
#endif
#ifdef PNG_sPLT_SUPPORTED
/* Free a given sPLT entry, or (if num == -1) all sPLT entries */
if ((mask & PNG_FREE_SPLT) & info_ptr->free_me)
{
if (num != -1)
{
if (info_ptr->splt_palettes)
{
png_free(png_ptr, info_ptr->splt_palettes[num].name);
png_free(png_ptr, info_ptr->splt_palettes[num].entries);
info_ptr->splt_palettes[num].name = NULL;
info_ptr->splt_palettes[num].entries = NULL;
}
}
else
{
if (info_ptr->splt_palettes_num)
{
int i;
for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i);
png_free(png_ptr, info_ptr->splt_palettes);
info_ptr->splt_palettes = NULL;
info_ptr->splt_palettes_num = 0;
}
info_ptr->valid &= ~PNG_INFO_sPLT;
}
}
#endif
#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
if (png_ptr->unknown_chunk.data)
{
png_free(png_ptr, png_ptr->unknown_chunk.data);
png_ptr->unknown_chunk.data = NULL;
}
if ((mask & PNG_FREE_UNKN) & info_ptr->free_me)
{
if (num != -1)
{
if (info_ptr->unknown_chunks)
{
png_free(png_ptr, info_ptr->unknown_chunks[num].data);
info_ptr->unknown_chunks[num].data = NULL;
}
}
else
{
int i;
if (info_ptr->unknown_chunks_num)
{
for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++)
png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i);
png_free(png_ptr, info_ptr->unknown_chunks);
info_ptr->unknown_chunks = NULL;
info_ptr->unknown_chunks_num = 0;
}
}
}
#endif
#ifdef PNG_hIST_SUPPORTED
/* Free any hIST entry */
if ((mask & PNG_FREE_HIST) & info_ptr->free_me)
{
png_free(png_ptr, info_ptr->hist);
info_ptr->hist = NULL;
info_ptr->valid &= ~PNG_INFO_hIST;
}
#endif
/* Free any PLTE entry that was internally allocated */
if ((mask & PNG_FREE_PLTE) & info_ptr->free_me)
{
png_zfree(png_ptr, info_ptr->palette);
info_ptr->palette = NULL;
info_ptr->valid &= ~PNG_INFO_PLTE;
info_ptr->num_palette = 0;
}
#ifdef PNG_INFO_IMAGE_SUPPORTED
/* Free any image bits attached to the info structure */
if ((mask & PNG_FREE_ROWS) & info_ptr->free_me)
{
if (info_ptr->row_pointers)
{
int row;
for (row = 0; row < (int)info_ptr->height; row++)
{
png_free(png_ptr, info_ptr->row_pointers[row]);
info_ptr->row_pointers[row] = NULL;
}
png_free(png_ptr, info_ptr->row_pointers);
info_ptr->row_pointers = NULL;
}
info_ptr->valid &= ~PNG_INFO_IDAT;
}
#endif
if (num == -1)
info_ptr->free_me &= ~mask;
else
info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL);
}
/* This is an internal routine to free any memory that the info struct is
* pointing to before re-using it or freeing the struct itself. Recall
* that png_free() checks for NULL pointers for us.
*/
void /* PRIVATE */
png_info_destroy(png_structp png_ptr, png_infop info_ptr)
{
png_debug(1, "in png_info_destroy");
png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
if (png_ptr->num_chunk_list)
{
png_free(png_ptr, png_ptr->chunk_list);
png_ptr->chunk_list = NULL;
png_ptr->num_chunk_list = 0;
}
#endif
png_info_init_3(&info_ptr, png_sizeof(png_info));
}
#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
/* This function returns a pointer to the io_ptr associated with the user
* functions. The application should free any memory associated with this
* pointer before png_write_destroy() or png_read_destroy() are called.
*/
png_voidp PNGAPI
png_get_io_ptr(png_structp png_ptr)
{
if (png_ptr == NULL)
return (NULL);
return (png_ptr->io_ptr);
}
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
#ifdef PNG_STDIO_SUPPORTED
/* Initialize the default input/output functions for the PNG file. If you
* use your own read or write routines, you can call either png_set_read_fn()
* or png_set_write_fn() instead of png_init_io(). If you have defined
* PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't
* necessarily available.
*/
void PNGAPI
png_init_io(png_structp png_ptr, png_FILE_p fp)
{
png_debug(1, "in png_init_io");
if (png_ptr == NULL)
return;
png_ptr->io_ptr = (png_voidp)fp;
}
#endif
#ifdef PNG_TIME_RFC1123_SUPPORTED
/* Convert the supplied time into an RFC 1123 string suitable for use in
* a "Creation Time" or other text-based time string.
*/
png_charp PNGAPI
png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
{
static PNG_CONST char short_months[12][4] =
{"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
if (png_ptr == NULL)
return (NULL);
if (png_ptr->time_buffer == NULL)
{
png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29*
png_sizeof(char)));
}
#ifdef USE_FAR_KEYWORD
{
char near_time_buf[29];
png_snprintf6(near_time_buf, 29, "%d %s %d %02d:%02d:%02d +0000",
ptime->day % 32, short_months[(ptime->month - 1) % 12],
ptime->year, ptime->hour % 24, ptime->minute % 60,
ptime->second % 61);
png_memcpy(png_ptr->time_buffer, near_time_buf,
29*png_sizeof(char));
}
#else
png_snprintf6(png_ptr->time_buffer, 29, "%d %s %d %02d:%02d:%02d +0000",
ptime->day % 32, short_months[(ptime->month - 1) % 12],
ptime->year, ptime->hour % 24, ptime->minute % 60,
ptime->second % 61);
#endif
return ((png_charp)png_ptr->time_buffer);
}
#endif /* PNG_TIME_RFC1123_SUPPORTED */
#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
png_charp PNGAPI
png_get_copyright(png_structp png_ptr)
{
png_ptr = png_ptr; /* Silence compiler warning about unused png_ptr */
#ifdef PNG_STRING_COPYRIGHT
return PNG_STRING_COPYRIGHT
#else
#ifdef __STDC__
return ((png_charp) PNG_STRING_NEWLINE \
"libpng version 1.4.2 - May 6, 2010" PNG_STRING_NEWLINE \
"Copyright (c) 1998-2010 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
"Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
"Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
PNG_STRING_NEWLINE);
#else
return ((png_charp) "libpng version 1.4.2 - May 6, 2010\
Copyright (c) 1998-2010 Glenn Randers-Pehrson\
Copyright (c) 1996-1997 Andreas Dilger\
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.");
#endif
#endif
}
/* The following return the library version as a short string in the
* format 1.0.0 through 99.99.99zz. To get the version of *.h files
* used with your application, print out PNG_LIBPNG_VER_STRING, which
* is defined in png.h.
* Note: now there is no difference between png_get_libpng_ver() and
* png_get_header_ver(). Due to the version_nn_nn_nn typedef guard,
* it is guaranteed that png.c uses the correct version of png.h.
*/
png_charp PNGAPI
png_get_libpng_ver(png_structp png_ptr)
{
/* Version of *.c files used when building libpng */
png_ptr = png_ptr; /* Silence compiler warning about unused png_ptr */
return ((png_charp) PNG_LIBPNG_VER_STRING);
}
png_charp PNGAPI
png_get_header_ver(png_structp png_ptr)
{
/* Version of *.h files used when building libpng */
png_ptr = png_ptr; /* Silence compiler warning about unused png_ptr */
return ((png_charp) PNG_LIBPNG_VER_STRING);
}
png_charp PNGAPI
png_get_header_version(png_structp png_ptr)
{
/* Returns longer string containing both version and date */
png_ptr = png_ptr; /* Silence compiler warning about unused png_ptr */
#ifdef __STDC__
return ((png_charp) PNG_HEADER_VERSION_STRING
#ifndef PNG_READ_SUPPORTED
" (NO READ SUPPORT)"
#endif
PNG_STRING_NEWLINE);
#else
return ((png_charp) PNG_HEADER_VERSION_STRING);
#endif
}
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
int PNGAPI
png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name)
{
/* Check chunk_name and return "keep" value if it's on the list, else 0 */
int i;
png_bytep p;
if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list<=0)
return 0;
p = png_ptr->chunk_list + png_ptr->num_chunk_list*5 - 5;
for (i = png_ptr->num_chunk_list; i; i--, p -= 5)
if (!png_memcmp(chunk_name, p, 4))
return ((int)*(p + 4));
return 0;
}
#endif
#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
#ifdef PNG_READ_SUPPORTED
/* This function, added to libpng-1.0.6g, is untested. */
int PNGAPI
png_reset_zstream(png_structp png_ptr)
{
if (png_ptr == NULL)
return Z_STREAM_ERROR;
return (inflateReset(&png_ptr->zstream));
}
#endif /* PNG_READ_SUPPORTED */
/* This function was added to libpng-1.0.7 */
png_uint_32 PNGAPI
png_access_version_number(void)
{
/* Version of *.c files used when building libpng */
return((png_uint_32) PNG_LIBPNG_VER);
}
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
#ifdef PNG_SIZE_T
/* Added at libpng version 1.2.6 */
PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size));
png_size_t PNGAPI
png_convert_size(size_t size)
{
if (size > (png_size_t)-1)
PNG_ABORT(); /* We haven't got access to png_ptr, so no png_error() */
return ((png_size_t)size);
}
#endif /* PNG_SIZE_T */
/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */
#ifdef PNG_cHRM_SUPPORTED
#ifdef PNG_CHECK_cHRM_SUPPORTED
/*
* Multiply two 32-bit numbers, V1 and V2, using 32-bit
* arithmetic, to produce a 64 bit result in the HI/LO words.
*
* A B
* x C D
* ------
* AD || BD
* AC || CB || 0
*
* where A and B are the high and low 16-bit words of V1,
* C and D are the 16-bit words of V2, AD is the product of
* A and D, and X || Y is (X << 16) + Y.
*/
void /* PRIVATE */
png_64bit_product (long v1, long v2, unsigned long *hi_product,
unsigned long *lo_product)
{
int a, b, c, d;
long lo, hi, x, y;
a = (v1 >> 16) & 0xffff;
b = v1 & 0xffff;
c = (v2 >> 16) & 0xffff;
d = v2 & 0xffff;
lo = b * d; /* BD */
x = a * d + c * b; /* AD + CB */
y = ((lo >> 16) & 0xffff) + x;
lo = (lo & 0xffff) | ((y & 0xffff) << 16);
hi = (y >> 16) & 0xffff;
hi += a * c; /* AC */
*hi_product = (unsigned long)hi;
*lo_product = (unsigned long)lo;
}
int /* PRIVATE */
png_check_cHRM_fixed(png_structp png_ptr,
png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
png_fixed_point blue_x, png_fixed_point blue_y)
{
int ret = 1;
unsigned long xy_hi,xy_lo,yx_hi,yx_lo;
png_debug(1, "in function png_check_cHRM_fixed");
if (png_ptr == NULL)
return 0;
if (white_x < 0 || white_y <= 0 ||
red_x < 0 || red_y < 0 ||
green_x < 0 || green_y < 0 ||
blue_x < 0 || blue_y < 0)
{
png_warning(png_ptr,
"Ignoring attempt to set negative chromaticity value");
ret = 0;
}
if (white_x > (png_fixed_point) PNG_UINT_31_MAX ||
white_y > (png_fixed_point) PNG_UINT_31_MAX ||
red_x > (png_fixed_point) PNG_UINT_31_MAX ||
red_y > (png_fixed_point) PNG_UINT_31_MAX ||
green_x > (png_fixed_point) PNG_UINT_31_MAX ||
green_y > (png_fixed_point) PNG_UINT_31_MAX ||
blue_x > (png_fixed_point) PNG_UINT_31_MAX ||
blue_y > (png_fixed_point) PNG_UINT_31_MAX )
{
png_warning(png_ptr,
"Ignoring attempt to set chromaticity value exceeding 21474.83");
ret = 0;
}
if (white_x > 100000L - white_y)
{
png_warning(png_ptr, "Invalid cHRM white point");
ret = 0;
}
if (red_x > 100000L - red_y)
{
png_warning(png_ptr, "Invalid cHRM red point");
ret = 0;
}
if (green_x > 100000L - green_y)
{
png_warning(png_ptr, "Invalid cHRM green point");
ret = 0;
}
if (blue_x > 100000L - blue_y)
{
png_warning(png_ptr, "Invalid cHRM blue point");
ret = 0;
}
png_64bit_product(green_x - red_x, blue_y - red_y, &xy_hi, &xy_lo);
png_64bit_product(green_y - red_y, blue_x - red_x, &yx_hi, &yx_lo);
if (xy_hi == yx_hi && xy_lo == yx_lo)
{
png_warning(png_ptr,
"Ignoring attempt to set cHRM RGB triangle with zero area");
ret = 0;
}
return ret;
}
#endif /* PNG_CHECK_cHRM_SUPPORTED */
#endif /* PNG_cHRM_SUPPORTED */
void /* PRIVATE */
png_check_IHDR(png_structp png_ptr,
png_uint_32 width, png_uint_32 height, int bit_depth,
int color_type, int interlace_type, int compression_type,
int filter_type)
{
int error = 0;
/* Check for width and height valid values */
if (width == 0)
{
png_warning(png_ptr, "Image width is zero in IHDR");
error = 1;
}
if (height == 0)
{
png_warning(png_ptr, "Image height is zero in IHDR");
error = 1;
}
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
if (width > png_ptr->user_width_max || width > PNG_USER_WIDTH_MAX)
#else
if (width > PNG_USER_WIDTH_MAX)
#endif
{
png_warning(png_ptr, "Image width exceeds user limit in IHDR");
error = 1;
}
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
if (height > png_ptr->user_height_max || height > PNG_USER_HEIGHT_MAX)
#else
if (height > PNG_USER_HEIGHT_MAX)
#endif
{
png_warning(png_ptr, "Image height exceeds user limit in IHDR");
error = 1;
}
if (width > PNG_UINT_31_MAX)
{
png_warning(png_ptr, "Invalid image width in IHDR");
error = 1;
}
if ( height > PNG_UINT_31_MAX)
{
png_warning(png_ptr, "Invalid image height in IHDR");
error = 1;
}
if ( width > (PNG_UINT_32_MAX
>> 3) /* 8-byte RGBA pixels */
- 64 /* bigrowbuf hack */
- 1 /* filter byte */
- 7*8 /* rounding of width to multiple of 8 pixels */
- 8) /* extra max_pixel_depth pad */
png_warning(png_ptr, "Width is too large for libpng to process pixels");
/* Check other values */
if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
bit_depth != 8 && bit_depth != 16)
{
png_warning(png_ptr, "Invalid bit depth in IHDR");
error = 1;
}
if (color_type < 0 || color_type == 1 ||
color_type == 5 || color_type > 6)
{
png_warning(png_ptr, "Invalid color type in IHDR");
error = 1;
}
if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
((color_type == PNG_COLOR_TYPE_RGB ||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
{
png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR");
error = 1;
}
if (interlace_type >= PNG_INTERLACE_LAST)
{
png_warning(png_ptr, "Unknown interlace method in IHDR");
error = 1;
}
if (compression_type != PNG_COMPRESSION_TYPE_BASE)
{
png_warning(png_ptr, "Unknown compression method in IHDR");
error = 1;
}
#ifdef PNG_MNG_FEATURES_SUPPORTED
/* Accept filter_method 64 (intrapixel differencing) only if
* 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
* 2. Libpng did not read a PNG signature (this filter_method is only
* used in PNG datastreams that are embedded in MNG datastreams) and
* 3. The application called png_permit_mng_features with a mask that
* included PNG_FLAG_MNG_FILTER_64 and
* 4. The filter_method is 64 and
* 5. The color_type is RGB or RGBA
*/
if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) &&
png_ptr->mng_features_permitted)
png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
if (filter_type != PNG_FILTER_TYPE_BASE)
{
if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
(filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&
(color_type == PNG_COLOR_TYPE_RGB ||
color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
{
png_warning(png_ptr, "Unknown filter method in IHDR");
error = 1;
}
if (png_ptr->mode & PNG_HAVE_PNG_SIGNATURE)
{
png_warning(png_ptr, "Invalid filter method in IHDR");
error = 1;
}
}
#else
if (filter_type != PNG_FILTER_TYPE_BASE)
{
png_warning(png_ptr, "Unknown filter method in IHDR");
error = 1;
}
#endif
if (error == 1)
png_error(png_ptr, "Invalid IHDR data");
}
#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */

2698
src/libpng/png.h Normal file

File diff suppressed because it is too large Load Diff

1525
src/libpng/pngconf.h Normal file

File diff suppressed because it is too large Load Diff

402
src/libpng/pngerror.c Normal file
View File

@ -0,0 +1,402 @@
/* pngerror.c - stub functions for i/o and memory allocation
*
* Last changed in libpng 1.4.0 [January 3, 2010]
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*
* This file provides a location for all error handling. Users who
* need special error handling are expected to write replacement functions
* and use png_set_error_fn() to use those functions. See the instructions
* at each function.
*/
#define PNG_NO_PEDANTIC_WARNINGS
#include "png.h"
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
#include "pngpriv.h"
static void /* PRIVATE */
png_default_error PNGARG((png_structp png_ptr,
png_const_charp error_message)) PNG_NORETURN;
#ifdef PNG_WARNINGS_SUPPORTED
static void /* PRIVATE */
png_default_warning PNGARG((png_structp png_ptr,
png_const_charp warning_message));
#endif /* PNG_WARNINGS_SUPPORTED */
/* This function is called whenever there is a fatal error. This function
* should not be changed. If there is a need to handle errors differently,
* you should supply a replacement error function and use png_set_error_fn()
* to replace the error function at run-time.
*/
#ifdef PNG_ERROR_TEXT_SUPPORTED
void PNGAPI
png_error(png_structp png_ptr, png_const_charp error_message)
{
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
char msg[16];
if (png_ptr != NULL)
{
if (png_ptr->flags&
(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
{
if (*error_message == PNG_LITERAL_SHARP)
{
/* Strip "#nnnn " from beginning of error message. */
int offset;
for (offset = 1; offset<15; offset++)
if (error_message[offset] == ' ')
break;
if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
{
int i;
for (i = 0; i < offset - 1; i++)
msg[i] = error_message[i + 1];
msg[i - 1] = '\0';
error_message = msg;
}
else
error_message += offset;
}
else
{
if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
{
msg[0] = '0';
msg[1] = '\0';
error_message = msg;
}
}
}
}
#endif
if (png_ptr != NULL && png_ptr->error_fn != NULL)
(*(png_ptr->error_fn))(png_ptr, error_message);
/* If the custom handler doesn't exist, or if it returns,
use the default handler, which will not return. */
png_default_error(png_ptr, error_message);
}
#else
void PNGAPI
png_err(png_structp png_ptr)
{
if (png_ptr != NULL && png_ptr->error_fn != NULL)
(*(png_ptr->error_fn))(png_ptr, '\0');
/* If the custom handler doesn't exist, or if it returns,
use the default handler, which will not return. */
png_default_error(png_ptr, '\0');
}
#endif /* PNG_ERROR_TEXT_SUPPORTED */
#ifdef PNG_WARNINGS_SUPPORTED
/* This function is called whenever there is a non-fatal error. This function
* should not be changed. If there is a need to handle warnings differently,
* you should supply a replacement warning function and use
* png_set_error_fn() to replace the warning function at run-time.
*/
void PNGAPI
png_warning(png_structp png_ptr, png_const_charp warning_message)
{
int offset = 0;
if (png_ptr != NULL)
{
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
if (png_ptr->flags&
(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
#endif
{
if (*warning_message == PNG_LITERAL_SHARP)
{
for (offset = 1; offset < 15; offset++)
if (warning_message[offset] == ' ')
break;
}
}
}
if (png_ptr != NULL && png_ptr->warning_fn != NULL)
(*(png_ptr->warning_fn))(png_ptr, warning_message + offset);
else
png_default_warning(png_ptr, warning_message + offset);
}
#endif /* PNG_WARNINGS_SUPPORTED */
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
void PNGAPI
png_benign_error(png_structp png_ptr, png_const_charp error_message)
{
if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
png_warning(png_ptr, error_message);
else
png_error(png_ptr, error_message);
}
#endif
/* These utilities are used internally to build an error message that relates
* to the current chunk. The chunk name comes from png_ptr->chunk_name,
* this is used to prefix the message. The message is limited in length
* to 63 bytes, the name characters are output as hex digits wrapped in []
* if the character is invalid.
*/
#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
static PNG_CONST char png_digit[16] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F'
};
#define PNG_MAX_ERROR_TEXT 64
#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED)
static void /* PRIVATE */
png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
error_message)
{
int iout = 0, iin = 0;
while (iin < 4)
{
int c = png_ptr->chunk_name[iin++];
if (isnonalpha(c))
{
buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET;
buffer[iout++] = png_digit[(c & 0xf0) >> 4];
buffer[iout++] = png_digit[c & 0x0f];
buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET;
}
else
{
buffer[iout++] = (png_byte)c;
}
}
if (error_message == NULL)
buffer[iout] = '\0';
else
{
buffer[iout++] = ':';
buffer[iout++] = ' ';
png_memcpy(buffer + iout, error_message, PNG_MAX_ERROR_TEXT);
buffer[iout + PNG_MAX_ERROR_TEXT - 1] = '\0';
}
}
#ifdef PNG_READ_SUPPORTED
void PNGAPI
png_chunk_error(png_structp png_ptr, png_const_charp error_message)
{
char msg[18+PNG_MAX_ERROR_TEXT];
if (png_ptr == NULL)
png_error(png_ptr, error_message);
else
{
png_format_buffer(png_ptr, msg, error_message);
png_error(png_ptr, msg);
}
}
#endif /* PNG_READ_SUPPORTED */
#endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */
#ifdef PNG_WARNINGS_SUPPORTED
void PNGAPI
png_chunk_warning(png_structp png_ptr, png_const_charp warning_message)
{
char msg[18+PNG_MAX_ERROR_TEXT];
if (png_ptr == NULL)
png_warning(png_ptr, warning_message);
else
{
png_format_buffer(png_ptr, msg, warning_message);
png_warning(png_ptr, msg);
}
}
#endif /* PNG_WARNINGS_SUPPORTED */
#ifdef PNG_READ_SUPPORTED
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
void PNGAPI
png_chunk_benign_error(png_structp png_ptr, png_const_charp error_message)
{
if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
png_chunk_warning(png_ptr, error_message);
else
png_chunk_error(png_ptr, error_message);
}
#endif
#endif /* PNG_READ_SUPPORTED */
#ifdef PNG_SETJMP_SUPPORTED
/* This API only exists if ANSI-C style error handling is used,
* otherwise it is necessary for png_default_error to be overridden.
*/
jmp_buf* PNGAPI
png_set_longjmp_fn(png_structp png_ptr, png_longjmp_ptr longjmp_fn,
size_t jmp_buf_size)
{
if (png_ptr == NULL || jmp_buf_size != png_sizeof(jmp_buf))
return NULL;
png_ptr->longjmp_fn = longjmp_fn;
return &png_ptr->jmpbuf;
}
#endif
/* This is the default error handling function. Note that replacements for
* this function MUST NOT RETURN, or the program will likely crash. This
* function is used by default, or if the program supplies NULL for the
* error function pointer in png_set_error_fn().
*/
static void /* PRIVATE */
png_default_error(png_structp png_ptr, png_const_charp error_message)
{
#ifdef PNG_CONSOLE_IO_SUPPORTED
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
if (*error_message == PNG_LITERAL_SHARP)
{
/* Strip "#nnnn " from beginning of error message. */
int offset;
char error_number[16];
for (offset = 0; offset<15; offset++)
{
error_number[offset] = error_message[offset + 1];
if (error_message[offset] == ' ')
break;
}
if ((offset > 1) && (offset < 15))
{
error_number[offset - 1] = '\0';
fprintf(stderr, "libpng error no. %s: %s",
error_number, error_message + offset + 1);
fprintf(stderr, PNG_STRING_NEWLINE);
}
else
{
fprintf(stderr, "libpng error: %s, offset=%d",
error_message, offset);
fprintf(stderr, PNG_STRING_NEWLINE);
}
}
else
#endif
{
fprintf(stderr, "libpng error: %s", error_message);
fprintf(stderr, PNG_STRING_NEWLINE);
}
#endif
#ifdef PNG_SETJMP_SUPPORTED
if (png_ptr && png_ptr->longjmp_fn)
{
# ifdef USE_FAR_KEYWORD
{
jmp_buf jmpbuf;
png_memcpy(jmpbuf, png_ptr->jmpbuf, png_sizeof(jmp_buf));
png_ptr->longjmp_fn(jmpbuf, 1);
}
# else
png_ptr->longjmp_fn(png_ptr->jmpbuf, 1);
# endif
}
#endif
/* Here if not setjmp support or if png_ptr is null. */
PNG_ABORT();
#ifndef PNG_CONSOLE_IO_SUPPORTED
error_message = error_message; /* Make compiler happy */
#endif
}
#ifdef PNG_WARNINGS_SUPPORTED
/* This function is called when there is a warning, but the library thinks
* it can continue anyway. Replacement functions don't have to do anything
* here if you don't want them to. In the default configuration, png_ptr is
* not used, but it is passed in case it may be useful.
*/
static void /* PRIVATE */
png_default_warning(png_structp png_ptr, png_const_charp warning_message)
{
#ifdef PNG_CONSOLE_IO_SUPPORTED
# ifdef PNG_ERROR_NUMBERS_SUPPORTED
if (*warning_message == PNG_LITERAL_SHARP)
{
int offset;
char warning_number[16];
for (offset = 0; offset < 15; offset++)
{
warning_number[offset] = warning_message[offset + 1];
if (warning_message[offset] == ' ')
break;
}
if ((offset > 1) && (offset < 15))
{
warning_number[offset + 1] = '\0';
fprintf(stderr, "libpng warning no. %s: %s",
warning_number, warning_message + offset);
fprintf(stderr, PNG_STRING_NEWLINE);
}
else
{
fprintf(stderr, "libpng warning: %s",
warning_message);
fprintf(stderr, PNG_STRING_NEWLINE);
}
}
else
# endif
{
fprintf(stderr, "libpng warning: %s", warning_message);
fprintf(stderr, PNG_STRING_NEWLINE);
}
#else
warning_message = warning_message; /* Make compiler happy */
#endif
png_ptr = png_ptr; /* Make compiler happy */
}
#endif /* PNG_WARNINGS_SUPPORTED */
/* This function is called when the application wants to use another method
* of handling errors and warnings. Note that the error function MUST NOT
* return to the calling routine or serious problems will occur. The return
* method used in the default routine calls longjmp(png_ptr->jmpbuf, 1)
*/
void PNGAPI
png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
png_error_ptr error_fn, png_error_ptr warning_fn)
{
if (png_ptr == NULL)
return;
png_ptr->error_ptr = error_ptr;
png_ptr->error_fn = error_fn;
png_ptr->warning_fn = warning_fn;
}
/* This function returns a pointer to the error_ptr associated with the user
* functions. The application should free any memory associated with this
* pointer before png_write_destroy and png_read_destroy are called.
*/
png_voidp PNGAPI
png_get_error_ptr(png_structp png_ptr)
{
if (png_ptr == NULL)
return NULL;
return ((png_voidp)png_ptr->error_ptr);
}
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
void PNGAPI
png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode)
{
if (png_ptr != NULL)
{
png_ptr->flags &=
((~(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
}
}
#endif
#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */

925
src/libpng/pngget.c Normal file
View File

@ -0,0 +1,925 @@
/* pngget.c - retrieval of values from info struct
*
* Last changed in libpng 1.4.2 [May 6, 2010]
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* 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"
png_uint_32 PNGAPI
png_get_valid(png_structp png_ptr, png_infop info_ptr, png_uint_32 flag)
{
if (png_ptr != NULL && info_ptr != NULL)
return(info_ptr->valid & flag);
else
return(0);
}
png_size_t PNGAPI
png_get_rowbytes(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
return(info_ptr->rowbytes);
else
return(0);
}
#ifdef PNG_INFO_IMAGE_SUPPORTED
png_bytepp PNGAPI
png_get_rows(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
return(info_ptr->row_pointers);
else
return(0);
}
#endif
#ifdef PNG_EASY_ACCESS_SUPPORTED
/* Easy access to info, added in libpng-0.99 */
png_uint_32 PNGAPI
png_get_image_width(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->width;
return (0);
}
png_uint_32 PNGAPI
png_get_image_height(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->height;
return (0);
}
png_byte PNGAPI
png_get_bit_depth(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->bit_depth;
return (0);
}
png_byte PNGAPI
png_get_color_type(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->color_type;
return (0);
}
png_byte PNGAPI
png_get_filter_type(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->filter_type;
return (0);
}
png_byte PNGAPI
png_get_interlace_type(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->interlace_type;
return (0);
}
png_byte PNGAPI
png_get_compression_type(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->compression_type;
return (0);
}
png_uint_32 PNGAPI
png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
#ifdef PNG_pHYs_SUPPORTED
if (info_ptr->valid & PNG_INFO_pHYs)
{
png_debug1(1, "in %s retrieval function", "png_get_x_pixels_per_meter");
if (info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
return (0);
else
return (info_ptr->x_pixels_per_unit);
}
#else
return (0);
#endif
return (0);
}
png_uint_32 PNGAPI
png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
#ifdef PNG_pHYs_SUPPORTED
if (info_ptr->valid & PNG_INFO_pHYs)
{
png_debug1(1, "in %s retrieval function", "png_get_y_pixels_per_meter");
if (info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
return (0);
else
return (info_ptr->y_pixels_per_unit);
}
#else
return (0);
#endif
return (0);
}
png_uint_32 PNGAPI
png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
#ifdef PNG_pHYs_SUPPORTED
if (info_ptr->valid & PNG_INFO_pHYs)
{
png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter");
if (info_ptr->phys_unit_type != PNG_RESOLUTION_METER ||
info_ptr->x_pixels_per_unit != info_ptr->y_pixels_per_unit)
return (0);
else
return (info_ptr->x_pixels_per_unit);
}
#else
return (0);
#endif
return (0);
}
#ifdef PNG_FLOATING_POINT_SUPPORTED
float PNGAPI
png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
#ifdef PNG_pHYs_SUPPORTED
if (info_ptr->valid & PNG_INFO_pHYs)
{
png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio");
if (info_ptr->x_pixels_per_unit == 0)
return ((float)0.0);
else
return ((float)((float)info_ptr->y_pixels_per_unit
/(float)info_ptr->x_pixels_per_unit));
}
#else
return (0.0);
#endif
return ((float)0.0);
}
#endif
png_int_32 PNGAPI
png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
#ifdef PNG_oFFs_SUPPORTED
if (info_ptr->valid & PNG_INFO_oFFs)
{
png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns");
if (info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
return (0);
else
return (info_ptr->x_offset);
}
#else
return (0);
#endif
return (0);
}
png_int_32 PNGAPI
png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
#ifdef PNG_oFFs_SUPPORTED
if (info_ptr->valid & PNG_INFO_oFFs)
{
png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns");
if (info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
return (0);
else
return (info_ptr->y_offset);
}
#else
return (0);
#endif
return (0);
}
png_int_32 PNGAPI
png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
#ifdef PNG_oFFs_SUPPORTED
if (info_ptr->valid & PNG_INFO_oFFs)
{
png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns");
if (info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
return (0);
else
return (info_ptr->x_offset);
}
#else
return (0);
#endif
return (0);
}
png_int_32 PNGAPI
png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
#ifdef PNG_oFFs_SUPPORTED
if (info_ptr->valid & PNG_INFO_oFFs)
{
png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns");
if (info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
return (0);
else
return (info_ptr->y_offset);
}
#else
return (0);
#endif
return (0);
}
#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED)
png_uint_32 PNGAPI
png_get_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
{
return ((png_uint_32)((float)png_get_pixels_per_meter(png_ptr, info_ptr)
*.0254 +.5));
}
png_uint_32 PNGAPI
png_get_x_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
{
return ((png_uint_32)((float)png_get_x_pixels_per_meter(png_ptr, info_ptr)
*.0254 +.5));
}
png_uint_32 PNGAPI
png_get_y_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
{
return ((png_uint_32)((float)png_get_y_pixels_per_meter(png_ptr, info_ptr)
*.0254 +.5));
}
float PNGAPI
png_get_x_offset_inches(png_structp png_ptr, png_infop info_ptr)
{
return ((float)png_get_x_offset_microns(png_ptr, info_ptr)
*.00003937);
}
float PNGAPI
png_get_y_offset_inches(png_structp png_ptr, png_infop info_ptr)
{
return ((float)png_get_y_offset_microns(png_ptr, info_ptr)
*.00003937);
}
#ifdef PNG_pHYs_SUPPORTED
png_uint_32 PNGAPI
png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr,
png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
{
png_uint_32 retval = 0;
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
{
png_debug1(1, "in %s retrieval function", "pHYs");
if (res_x != NULL)
{
*res_x = info_ptr->x_pixels_per_unit;
retval |= PNG_INFO_pHYs;
}
if (res_y != NULL)
{
*res_y = info_ptr->y_pixels_per_unit;
retval |= PNG_INFO_pHYs;
}
if (unit_type != NULL)
{
*unit_type = (int)info_ptr->phys_unit_type;
retval |= PNG_INFO_pHYs;
if (*unit_type == 1)
{
if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50);
if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50);
}
}
}
return (retval);
}
#endif /* PNG_pHYs_SUPPORTED */
#endif /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */
/* png_get_channels really belongs in here, too, but it's been around longer */
#endif /* PNG_EASY_ACCESS_SUPPORTED */
png_byte PNGAPI
png_get_channels(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
return(info_ptr->channels);
else
return (0);
}
png_bytep PNGAPI
png_get_signature(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
return(info_ptr->signature);
else
return (NULL);
}
#ifdef PNG_bKGD_SUPPORTED
png_uint_32 PNGAPI
png_get_bKGD(png_structp png_ptr, png_infop info_ptr,
png_color_16p *background)
{
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)
&& background != NULL)
{
png_debug1(1, "in %s retrieval function", "bKGD");
*background = &(info_ptr->background);
return (PNG_INFO_bKGD);
}
return (0);
}
#endif
#ifdef PNG_cHRM_SUPPORTED
#ifdef PNG_FLOATING_POINT_SUPPORTED
png_uint_32 PNGAPI
png_get_cHRM(png_structp png_ptr, png_infop info_ptr,
double *white_x, double *white_y, double *red_x, double *red_y,
double *green_x, double *green_y, double *blue_x, double *blue_y)
{
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
{
png_debug1(1, "in %s retrieval function", "cHRM");
if (white_x != NULL)
*white_x = (double)info_ptr->x_white;
if (white_y != NULL)
*white_y = (double)info_ptr->y_white;
if (red_x != NULL)
*red_x = (double)info_ptr->x_red;
if (red_y != NULL)
*red_y = (double)info_ptr->y_red;
if (green_x != NULL)
*green_x = (double)info_ptr->x_green;
if (green_y != NULL)
*green_y = (double)info_ptr->y_green;
if (blue_x != NULL)
*blue_x = (double)info_ptr->x_blue;
if (blue_y != NULL)
*blue_y = (double)info_ptr->y_blue;
return (PNG_INFO_cHRM);
}
return (0);
}
#endif
#ifdef PNG_FIXED_POINT_SUPPORTED
png_uint_32 PNGAPI
png_get_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x,
png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y,
png_fixed_point *blue_x, png_fixed_point *blue_y)
{
png_debug1(1, "in %s retrieval function", "cHRM");
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
{
if (white_x != NULL)
*white_x = info_ptr->int_x_white;
if (white_y != NULL)
*white_y = info_ptr->int_y_white;
if (red_x != NULL)
*red_x = info_ptr->int_x_red;
if (red_y != NULL)
*red_y = info_ptr->int_y_red;
if (green_x != NULL)
*green_x = info_ptr->int_x_green;
if (green_y != NULL)
*green_y = info_ptr->int_y_green;
if (blue_x != NULL)
*blue_x = info_ptr->int_x_blue;
if (blue_y != NULL)
*blue_y = info_ptr->int_y_blue;
return (PNG_INFO_cHRM);
}
return (0);
}
#endif
#endif
#ifdef PNG_gAMA_SUPPORTED
#ifdef PNG_FLOATING_POINT_SUPPORTED
png_uint_32 PNGAPI
png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma)
{
png_debug1(1, "in %s retrieval function", "gAMA");
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
&& file_gamma != NULL)
{
*file_gamma = (double)info_ptr->gamma;
return (PNG_INFO_gAMA);
}
return (0);
}
#endif
#ifdef PNG_FIXED_POINT_SUPPORTED
png_uint_32 PNGAPI
png_get_gAMA_fixed(png_structp png_ptr, png_infop info_ptr,
png_fixed_point *int_file_gamma)
{
png_debug1(1, "in %s retrieval function", "gAMA");
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
&& int_file_gamma != NULL)
{
*int_file_gamma = info_ptr->int_gamma;
return (PNG_INFO_gAMA);
}
return (0);
}
#endif
#endif
#ifdef PNG_sRGB_SUPPORTED
png_uint_32 PNGAPI
png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent)
{
png_debug1(1, "in %s retrieval function", "sRGB");
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)
&& file_srgb_intent != NULL)
{
*file_srgb_intent = (int)info_ptr->srgb_intent;
return (PNG_INFO_sRGB);
}
return (0);
}
#endif
#ifdef PNG_iCCP_SUPPORTED
png_uint_32 PNGAPI
png_get_iCCP(png_structp png_ptr, png_infop info_ptr,
png_charpp name, int *compression_type,
png_charpp profile, png_uint_32 *proflen)
{
png_debug1(1, "in %s retrieval function", "iCCP");
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)
&& name != NULL && profile != NULL && proflen != NULL)
{
*name = info_ptr->iccp_name;
*profile = info_ptr->iccp_profile;
/* Compression_type is a dummy so the API won't have to change
* if we introduce multiple compression types later.
*/
*proflen = (int)info_ptr->iccp_proflen;
*compression_type = (int)info_ptr->iccp_compression;
return (PNG_INFO_iCCP);
}
return (0);
}
#endif
#ifdef PNG_sPLT_SUPPORTED
png_uint_32 PNGAPI
png_get_sPLT(png_structp png_ptr, png_infop info_ptr,
png_sPLT_tpp spalettes)
{
if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
{
*spalettes = info_ptr->splt_palettes;
return ((png_uint_32)info_ptr->splt_palettes_num);
}
return (0);
}
#endif
#ifdef PNG_hIST_SUPPORTED
png_uint_32 PNGAPI
png_get_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist)
{
png_debug1(1, "in %s retrieval function", "hIST");
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)
&& hist != NULL)
{
*hist = info_ptr->hist;
return (PNG_INFO_hIST);
}
return (0);
}
#endif
png_uint_32 PNGAPI
png_get_IHDR(png_structp png_ptr, png_infop info_ptr,
png_uint_32 *width, png_uint_32 *height, int *bit_depth,
int *color_type, int *interlace_type, int *compression_type,
int *filter_type)
{
png_debug1(1, "in %s retrieval function", "IHDR");
if (png_ptr == NULL || info_ptr == NULL || width == NULL ||
height == NULL || bit_depth == NULL || color_type == NULL)
return (0);
*width = info_ptr->width;
*height = info_ptr->height;
*bit_depth = info_ptr->bit_depth;
*color_type = info_ptr->color_type;
if (compression_type != NULL)
*compression_type = info_ptr->compression_type;
if (filter_type != NULL)
*filter_type = info_ptr->filter_type;
if (interlace_type != NULL)
*interlace_type = info_ptr->interlace_type;
/* This is redundant if we can be sure that the info_ptr values were all
* assigned in png_set_IHDR(). We do the check anyhow in case an
* application has ignored our advice not to mess with the members
* of info_ptr directly.
*/
png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height,
info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
info_ptr->compression_type, info_ptr->filter_type);
return (1);
}
#ifdef PNG_oFFs_SUPPORTED
png_uint_32 PNGAPI
png_get_oFFs(png_structp png_ptr, png_infop info_ptr,
png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
{
png_debug1(1, "in %s retrieval function", "oFFs");
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)
&& offset_x != NULL && offset_y != NULL && unit_type != NULL)
{
*offset_x = info_ptr->x_offset;
*offset_y = info_ptr->y_offset;
*unit_type = (int)info_ptr->offset_unit_type;
return (PNG_INFO_oFFs);
}
return (0);
}
#endif
#ifdef PNG_pCAL_SUPPORTED
png_uint_32 PNGAPI
png_get_pCAL(png_structp png_ptr, png_infop info_ptr,
png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
png_charp *units, png_charpp *params)
{
png_debug1(1, "in %s retrieval function", "pCAL");
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)
&& purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
nparams != NULL && units != NULL && params != NULL)
{
*purpose = info_ptr->pcal_purpose;
*X0 = info_ptr->pcal_X0;
*X1 = info_ptr->pcal_X1;
*type = (int)info_ptr->pcal_type;
*nparams = (int)info_ptr->pcal_nparams;
*units = info_ptr->pcal_units;
*params = info_ptr->pcal_params;
return (PNG_INFO_pCAL);
}
return (0);
}
#endif
#ifdef PNG_sCAL_SUPPORTED
#ifdef PNG_FLOATING_POINT_SUPPORTED
png_uint_32 PNGAPI
png_get_sCAL(png_structp png_ptr, png_infop info_ptr,
int *unit, double *width, double *height)
{
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_sCAL))
{
*unit = info_ptr->scal_unit;
*width = info_ptr->scal_pixel_width;
*height = info_ptr->scal_pixel_height;
return (PNG_INFO_sCAL);
}
return(0);
}
#else
#ifdef PNG_FIXED_POINT_SUPPORTED
png_uint_32 PNGAPI
png_get_sCAL_s(png_structp png_ptr, png_infop info_ptr,
int *unit, png_charpp width, png_charpp height)
{
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_sCAL))
{
*unit = info_ptr->scal_unit;
*width = info_ptr->scal_s_width;
*height = info_ptr->scal_s_height;
return (PNG_INFO_sCAL);
}
return(0);
}
#endif
#endif
#endif
#ifdef PNG_pHYs_SUPPORTED
png_uint_32 PNGAPI
png_get_pHYs(png_structp png_ptr, png_infop info_ptr,
png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
{
png_uint_32 retval = 0;
png_debug1(1, "in %s retrieval function", "pHYs");
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_pHYs))
{
if (res_x != NULL)
{
*res_x = info_ptr->x_pixels_per_unit;
retval |= PNG_INFO_pHYs;
}
if (res_y != NULL)
{
*res_y = info_ptr->y_pixels_per_unit;
retval |= PNG_INFO_pHYs;
}
if (unit_type != NULL)
{
*unit_type = (int)info_ptr->phys_unit_type;
retval |= PNG_INFO_pHYs;
}
}
return (retval);
}
#endif
png_uint_32 PNGAPI
png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette,
int *num_palette)
{
png_debug1(1, "in %s retrieval function", "PLTE");
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE)
&& palette != NULL)
{
*palette = info_ptr->palette;
*num_palette = info_ptr->num_palette;
png_debug1(3, "num_palette = %d", *num_palette);
return (PNG_INFO_PLTE);
}
return (0);
}
#ifdef PNG_sBIT_SUPPORTED
png_uint_32 PNGAPI
png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit)
{
png_debug1(1, "in %s retrieval function", "sBIT");
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)
&& sig_bit != NULL)
{
*sig_bit = &(info_ptr->sig_bit);
return (PNG_INFO_sBIT);
}
return (0);
}
#endif
#ifdef PNG_TEXT_SUPPORTED
png_uint_32 PNGAPI
png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr,
int *num_text)
{
if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
{
png_debug1(1, "in %s retrieval function",
(png_ptr->chunk_name[0] == '\0' ? "text"
: (png_const_charp)png_ptr->chunk_name));
if (text_ptr != NULL)
*text_ptr = info_ptr->text;
if (num_text != NULL)
*num_text = info_ptr->num_text;
return ((png_uint_32)info_ptr->num_text);
}
if (num_text != NULL)
*num_text = 0;
return(0);
}
#endif
#ifdef PNG_tIME_SUPPORTED
png_uint_32 PNGAPI
png_get_tIME(png_structp png_ptr, png_infop info_ptr, png_timep *mod_time)
{
png_debug1(1, "in %s retrieval function", "tIME");
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)
&& mod_time != NULL)
{
*mod_time = &(info_ptr->mod_time);
return (PNG_INFO_tIME);
}
return (0);
}
#endif
#ifdef PNG_tRNS_SUPPORTED
png_uint_32 PNGAPI
png_get_tRNS(png_structp png_ptr, png_infop info_ptr,
png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)
{
png_uint_32 retval = 0;
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
{
png_debug1(1, "in %s retrieval function", "tRNS");
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
{
if (trans_alpha != NULL)
{
*trans_alpha = info_ptr->trans_alpha;
retval |= PNG_INFO_tRNS;
}
if (trans_color != NULL)
*trans_color = &(info_ptr->trans_color);
}
else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
{
if (trans_color != NULL)
{
*trans_color = &(info_ptr->trans_color);
retval |= PNG_INFO_tRNS;
}
if (trans_alpha != NULL)
*trans_alpha = NULL;
}
if (num_trans != NULL)
{
*num_trans = info_ptr->num_trans;
retval |= PNG_INFO_tRNS;
}
}
return (retval);
}
#endif
#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
png_uint_32 PNGAPI
png_get_unknown_chunks(png_structp png_ptr, png_infop info_ptr,
png_unknown_chunkpp unknowns)
{
if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)
{
*unknowns = info_ptr->unknown_chunks;
return ((png_uint_32)info_ptr->unknown_chunks_num);
}
return (0);
}
#endif
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
png_byte PNGAPI
png_get_rgb_to_gray_status (png_structp png_ptr)
{
return (png_byte)(png_ptr? png_ptr->rgb_to_gray_status : 0);
}
#endif
#ifdef PNG_USER_CHUNKS_SUPPORTED
png_voidp PNGAPI
png_get_user_chunk_ptr(png_structp png_ptr)
{
return (png_ptr? png_ptr->user_chunk_ptr : NULL);
}
#endif
png_size_t PNGAPI
png_get_compression_buffer_size(png_structp png_ptr)
{
return (png_ptr ? png_ptr->zbuf_size : 0L);
}
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
/* These functions were added to libpng 1.2.6 and were enabled
* by default in libpng-1.4.0 */
png_uint_32 PNGAPI
png_get_user_width_max (png_structp png_ptr)
{
return (png_ptr? png_ptr->user_width_max : 0);
}
png_uint_32 PNGAPI
png_get_user_height_max (png_structp png_ptr)
{
return (png_ptr? png_ptr->user_height_max : 0);
}
/* This function was added to libpng 1.4.0 */
png_uint_32 PNGAPI
png_get_chunk_cache_max (png_structp png_ptr)
{
return (png_ptr? png_ptr->user_chunk_cache_max : 0);
}
/* This function was added to libpng 1.4.1 */
png_alloc_size_t PNGAPI
png_get_chunk_malloc_max (png_structp png_ptr)
{
return (png_ptr?
png_ptr->user_chunk_malloc_max : 0);
}
#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
/* These functions were added to libpng 1.4.0 */
#ifdef PNG_IO_STATE_SUPPORTED
png_uint_32 PNGAPI
png_get_io_state (png_structp png_ptr)
{
return png_ptr->io_state;
}
png_bytep PNGAPI
png_get_io_chunk_name (png_structp png_ptr)
{
return png_ptr->chunk_name;
}
#endif /* ?PNG_IO_STATE_SUPPORTED */
#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */

611
src/libpng/pngmem.c Normal file
View File

@ -0,0 +1,611 @@
/* pngmem.c - stub functions for memory allocation
*
* Last changed in libpng 1.4.2 [May 6, 2010]
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*
* This file provides a location for all memory allocation. Users who
* need special memory handling are expected to supply replacement
* functions for png_malloc() and png_free(), and to use
* png_create_read_struct_2() and png_create_write_struct_2() to
* identify the replacement functions.
*/
#define PNG_NO_PEDANTIC_WARNINGS
#include "png.h"
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
#include "pngpriv.h"
/* Borland DOS special memory handler */
#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
/* 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
by a single call to calloc() if this is thought to improve performance. */
png_voidp /* PRIVATE */
png_create_struct(int type)
{
#ifdef PNG_USER_MEM_SUPPORTED
return (png_create_struct_2(type, NULL, NULL));
}
/* Alternate version of png_create_struct, for use with user-defined malloc. */
png_voidp /* PRIVATE */
png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
{
#endif /* PNG_USER_MEM_SUPPORTED */
png_size_t size;
png_voidp struct_ptr;
if (type == PNG_STRUCT_INFO)
size = png_sizeof(png_info);
else if (type == PNG_STRUCT_PNG)
size = png_sizeof(png_struct);
else
return (png_get_copyright(NULL));
#ifdef PNG_USER_MEM_SUPPORTED
if (malloc_fn != NULL)
{
png_struct dummy_struct;
png_structp png_ptr = &dummy_struct;
png_ptr->mem_ptr=mem_ptr;
struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size);
}
else
#endif /* PNG_USER_MEM_SUPPORTED */
struct_ptr = (png_voidp)farmalloc(size);
if (struct_ptr != NULL)
png_memset(struct_ptr, 0, size);
return (struct_ptr);
}
/* Free memory allocated by a png_create_struct() call */
void /* PRIVATE */
png_destroy_struct(png_voidp struct_ptr)
{
#ifdef PNG_USER_MEM_SUPPORTED
png_destroy_struct_2(struct_ptr, NULL, NULL);
}
/* Free memory allocated by a png_create_struct() call */
void /* PRIVATE */
png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
png_voidp mem_ptr)
{
#endif
if (struct_ptr != NULL)
{
#ifdef PNG_USER_MEM_SUPPORTED
if (free_fn != NULL)
{
png_struct dummy_struct;
png_structp png_ptr = &dummy_struct;
png_ptr->mem_ptr=mem_ptr;
(*(free_fn))(png_ptr, struct_ptr);
return;
}
#endif /* PNG_USER_MEM_SUPPORTED */
farfree (struct_ptr);
}
}
/* Allocate memory. For reasonable files, size should never exceed
* 64K. However, zlib may allocate more then 64K if you don't tell
* it not to. See zconf.h and png.h for more information. zlib does
* need to allocate exactly 64K, so whatever you call here must
* have the ability to do that.
*
* Borland seems to have a problem in DOS mode for exactly 64K.
* It gives you a segment with an offset of 8 (perhaps to store its
* memory stuff). zlib doesn't like this at all, so we have to
* detect and deal with it. This code should not be needed in
* Windows or OS/2 modes, and only in 16 bit mode. This code has
* been updated by Alexander Lehmann for version 0.89 to waste less
* memory.
*
* Note that we can't use png_size_t for the "size" declaration,
* since on some systems a png_size_t is a 16-bit quantity, and as a
* result, we would be truncating potentially larger memory requests
* (which should cause a fatal error) and introducing major problems.
*/
png_voidp PNGAPI
png_calloc(png_structp png_ptr, png_alloc_size_t size)
{
png_voidp ret;
ret = (png_malloc(png_ptr, size));
if (ret != NULL)
png_memset(ret,0,(png_size_t)size);
return (ret);
}
png_voidp PNGAPI
png_malloc(png_structp png_ptr, png_alloc_size_t size)
{
png_voidp ret;
if (png_ptr == NULL || size == 0)
return (NULL);
#ifdef PNG_USER_MEM_SUPPORTED
if (png_ptr->malloc_fn != NULL)
ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
else
ret = (png_malloc_default(png_ptr, size));
if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out of memory");
return (ret);
}
png_voidp PNGAPI
png_malloc_default(png_structp png_ptr, png_alloc_size_t size)
{
png_voidp ret;
#endif /* PNG_USER_MEM_SUPPORTED */
if (png_ptr == NULL || size == 0)
return (NULL);
#ifdef PNG_MAX_MALLOC_64K
if (size > (png_uint_32)65536L)
{
png_warning(png_ptr, "Cannot Allocate > 64K");
ret = NULL;
}
else
#endif
if (size != (size_t)size)
ret = NULL;
else if (size == (png_uint_32)65536L)
{
if (png_ptr->offset_table == NULL)
{
/* Try to see if we need to do any of this fancy stuff */
ret = farmalloc(size);
if (ret == NULL || ((png_size_t)ret & 0xffff))
{
int num_blocks;
png_uint_32 total_size;
png_bytep table;
int i;
png_byte huge * hptr;
if (ret != NULL)
{
farfree(ret);
ret = NULL;
}
if (png_ptr->zlib_window_bits > 14)
num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
else
num_blocks = 1;
if (png_ptr->zlib_mem_level >= 7)
num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
else
num_blocks++;
total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
table = farmalloc(total_size);
if (table == NULL)
{
#ifndef PNG_USER_MEM_SUPPORTED
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out Of Memory"); /* Note "O", "M" */
else
png_warning(png_ptr, "Out Of Memory");
#endif
return (NULL);
}
if ((png_size_t)table & 0xfff0)
{
#ifndef PNG_USER_MEM_SUPPORTED
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr,
"Farmalloc didn't return normalized pointer");
else
png_warning(png_ptr,
"Farmalloc didn't return normalized pointer");
#endif
return (NULL);
}
png_ptr->offset_table = table;
png_ptr->offset_table_ptr = farmalloc(num_blocks *
png_sizeof(png_bytep));
if (png_ptr->offset_table_ptr == NULL)
{
#ifndef PNG_USER_MEM_SUPPORTED
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out Of memory"); /* Note "O", "m" */
else
png_warning(png_ptr, "Out Of memory");
#endif
return (NULL);
}
hptr = (png_byte huge *)table;
if ((png_size_t)hptr & 0xf)
{
hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */
}
for (i = 0; i < num_blocks; i++)
{
png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */
}
png_ptr->offset_table_number = num_blocks;
png_ptr->offset_table_count = 0;
png_ptr->offset_table_count_free = 0;
}
}
if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
{
#ifndef PNG_USER_MEM_SUPPORTED
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out of Memory"); /* Note "o" and "M" */
else
png_warning(png_ptr, "Out of Memory");
#endif
return (NULL);
}
ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
}
else
ret = farmalloc(size);
#ifndef PNG_USER_MEM_SUPPORTED
if (ret == NULL)
{
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out of memory"); /* Note "o" and "m" */
else
png_warning(png_ptr, "Out of memory"); /* Note "o" and "m" */
}
#endif
return (ret);
}
/* Free a pointer allocated by png_malloc(). In the default
* configuration, png_ptr is not used, but is passed in case it
* is needed. If ptr is NULL, return without taking any action.
*/
void PNGAPI
png_free(png_structp png_ptr, png_voidp ptr)
{
if (png_ptr == NULL || ptr == NULL)
return;
#ifdef PNG_USER_MEM_SUPPORTED
if (png_ptr->free_fn != NULL)
{
(*(png_ptr->free_fn))(png_ptr, ptr);
return;
}
else
png_free_default(png_ptr, ptr);
}
void PNGAPI
png_free_default(png_structp png_ptr, png_voidp ptr)
{
#endif /* PNG_USER_MEM_SUPPORTED */
if (png_ptr == NULL || ptr == NULL)
return;
if (png_ptr->offset_table != NULL)
{
int i;
for (i = 0; i < png_ptr->offset_table_count; i++)
{
if (ptr == png_ptr->offset_table_ptr[i])
{
ptr = NULL;
png_ptr->offset_table_count_free++;
break;
}
}
if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
{
farfree(png_ptr->offset_table);
farfree(png_ptr->offset_table_ptr);
png_ptr->offset_table = NULL;
png_ptr->offset_table_ptr = NULL;
}
}
if (ptr != NULL)
{
farfree(ptr);
}
}
#else /* Not the Borland DOS special memory handler */
/* 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
to improve performance noticably. */
png_voidp /* PRIVATE */
png_create_struct(int type)
{
#ifdef PNG_USER_MEM_SUPPORTED
return (png_create_struct_2(type, NULL, NULL));
}
/* 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
to improve performance noticably. */
png_voidp /* PRIVATE */
png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
{
#endif /* PNG_USER_MEM_SUPPORTED */
png_size_t size;
png_voidp struct_ptr;
if (type == PNG_STRUCT_INFO)
size = png_sizeof(png_info);
else if (type == PNG_STRUCT_PNG)
size = png_sizeof(png_struct);
else
return (NULL);
#ifdef PNG_USER_MEM_SUPPORTED
if (malloc_fn != NULL)
{
png_struct dummy_struct;
png_structp png_ptr = &dummy_struct;
png_ptr->mem_ptr=mem_ptr;
struct_ptr = (*(malloc_fn))(png_ptr, size);
if (struct_ptr != NULL)
png_memset(struct_ptr, 0, size);
return (struct_ptr);
}
#endif /* PNG_USER_MEM_SUPPORTED */
#if defined(__TURBOC__) && !defined(__FLAT__)
struct_ptr = (png_voidp)farmalloc(size);
#else
# if defined(_MSC_VER) && defined(MAXSEG_64K)
struct_ptr = (png_voidp)halloc(size, 1);
# else
struct_ptr = (png_voidp)malloc(size);
# endif
#endif
if (struct_ptr != NULL)
png_memset(struct_ptr, 0, size);
return (struct_ptr);
}
/* Free memory allocated by a png_create_struct() call */
void /* PRIVATE */
png_destroy_struct(png_voidp struct_ptr)
{
#ifdef PNG_USER_MEM_SUPPORTED
png_destroy_struct_2(struct_ptr, NULL, NULL);
}
/* Free memory allocated by a png_create_struct() call */
void /* PRIVATE */
png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
png_voidp mem_ptr)
{
#endif /* PNG_USER_MEM_SUPPORTED */
if (struct_ptr != NULL)
{
#ifdef PNG_USER_MEM_SUPPORTED
if (free_fn != NULL)
{
png_struct dummy_struct;
png_structp png_ptr = &dummy_struct;
png_ptr->mem_ptr=mem_ptr;
(*(free_fn))(png_ptr, struct_ptr);
return;
}
#endif /* PNG_USER_MEM_SUPPORTED */
#if defined(__TURBOC__) && !defined(__FLAT__)
farfree(struct_ptr);
#else
# if defined(_MSC_VER) && defined(MAXSEG_64K)
hfree(struct_ptr);
# else
free(struct_ptr);
# endif
#endif
}
}
/* Allocate memory. For reasonable files, size should never exceed
* 64K. However, zlib may allocate more then 64K if you don't tell
* it not to. See zconf.h and png.h for more information. zlib does
* need to allocate exactly 64K, so whatever you call here must
* have the ability to do that.
*/
png_voidp PNGAPI
png_calloc(png_structp png_ptr, png_alloc_size_t size)
{
png_voidp ret;
ret = (png_malloc(png_ptr, size));
if (ret != NULL)
png_memset(ret,0,(png_size_t)size);
return (ret);
}
png_voidp PNGAPI
png_malloc(png_structp png_ptr, png_alloc_size_t size)
{
png_voidp ret;
#ifdef PNG_USER_MEM_SUPPORTED
if (png_ptr == NULL || size == 0)
return (NULL);
if (png_ptr->malloc_fn != NULL)
ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
else
ret = (png_malloc_default(png_ptr, size));
if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out of Memory");
return (ret);
}
png_voidp PNGAPI
png_malloc_default(png_structp png_ptr, png_alloc_size_t size)
{
png_voidp ret;
#endif /* PNG_USER_MEM_SUPPORTED */
if (png_ptr == NULL || size == 0)
return (NULL);
#ifdef PNG_MAX_MALLOC_64K
if (size > (png_uint_32)65536L)
{
#ifndef PNG_USER_MEM_SUPPORTED
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Cannot Allocate > 64K");
else
#endif
return NULL;
}
#endif
/* Check for overflow */
#if defined(__TURBOC__) && !defined(__FLAT__)
if (size != (unsigned long)size)
ret = NULL;
else
ret = farmalloc(size);
#else
# if defined(_MSC_VER) && defined(MAXSEG_64K)
if (size != (unsigned long)size)
ret = NULL;
else
ret = halloc(size, 1);
# else
if (size != (size_t)size)
ret = NULL;
else
ret = malloc((size_t)size);
# endif
#endif
#ifndef PNG_USER_MEM_SUPPORTED
if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out of Memory");
#endif
return (ret);
}
/* Free a pointer allocated by png_malloc(). If ptr is NULL, return
* without taking any action.
*/
void PNGAPI
png_free(png_structp png_ptr, png_voidp ptr)
{
if (png_ptr == NULL || ptr == NULL)
return;
#ifdef PNG_USER_MEM_SUPPORTED
if (png_ptr->free_fn != NULL)
{
(*(png_ptr->free_fn))(png_ptr, ptr);
return;
}
else
png_free_default(png_ptr, ptr);
}
void PNGAPI
png_free_default(png_structp png_ptr, png_voidp ptr)
{
if (png_ptr == NULL || ptr == NULL)
return;
#endif /* PNG_USER_MEM_SUPPORTED */
#if defined(__TURBOC__) && !defined(__FLAT__)
farfree(ptr);
#else
# if defined(_MSC_VER) && defined(MAXSEG_64K)
hfree(ptr);
# else
free(ptr);
# endif
#endif
}
#endif /* Not Borland DOS special memory handler */
/* This function was added at libpng version 1.2.3. The png_malloc_warn()
* function will set up png_malloc() to issue a png_warning and return NULL
* instead of issuing a png_error, if it fails to allocate the requested
* memory.
*/
png_voidp PNGAPI
png_malloc_warn(png_structp png_ptr, png_alloc_size_t size)
{
png_voidp ptr;
png_uint_32 save_flags;
if (png_ptr == NULL)
return (NULL);
save_flags = png_ptr->flags;
png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
ptr = (png_voidp)png_malloc((png_structp)png_ptr, size);
png_ptr->flags=save_flags;
return(ptr);
}
#ifdef PNG_USER_MEM_SUPPORTED
/* This function is called when the application wants to use another method
* of allocating and freeing memory.
*/
void PNGAPI
png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
malloc_fn, png_free_ptr free_fn)
{
if (png_ptr != NULL)
{
png_ptr->mem_ptr = mem_ptr;
png_ptr->malloc_fn = malloc_fn;
png_ptr->free_fn = free_fn;
}
}
/* This function returns a pointer to the mem_ptr associated with the user
* functions. The application should free any memory associated with this
* pointer before png_write_destroy and png_read_destroy are called.
*/
png_voidp PNGAPI
png_get_mem_ptr(png_structp png_ptr)
{
if (png_ptr == NULL)
return (NULL);
return ((png_voidp)png_ptr->mem_ptr);
}
#endif /* PNG_USER_MEM_SUPPORTED */
#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */

1727
src/libpng/pngpread.c Normal file

File diff suppressed because it is too large Load Diff

956
src/libpng/pngpriv.h Normal file
View File

@ -0,0 +1,956 @@
/* pngpriv.h - private declarations for use inside libpng
*
* libpng version 1.4.2 - May 6, 2010
* For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*/
/* The symbols declared in this file (including the functions declared
* as PNG_EXTERN) are PRIVATE. They are not part of the libpng public
* interface, and are not recommended for use by regular applications.
* Some of them may become public in the future; others may stay private,
* change in an incompatible way, or even disappear.
* Although the libpng users are not forbidden to include this header,
* they should be well aware of the issues that may arise from doing so.
*/
#ifndef PNGPRIV_H
#define PNGPRIV_H
#ifndef PNG_VERSION_INFO_ONLY
#include <stdlib.h>
/* The functions exported by PNG_EXTERN are internal functions, which
* aren't usually used outside the library (as far as I know), so it is
* debatable if they should be exported at all. In the future, when it
* is possible to have run-time registry of chunk-handling functions,
* some of these will be made available again.
#define PNG_EXTERN extern
*/
#define PNG_EXTERN
/* Other defines specific to compilers can go here. Try to keep
* them inside an appropriate ifdef/endif pair for portability.
*/
#ifdef PNG_FLOATING_POINT_SUPPORTED
# ifdef MACOS
/* We need to check that <math.h> hasn't already been included earlier
* as it seems it doesn't agree with <fp.h>, yet we should really use
* <fp.h> if possible.
*/
# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
# include <fp.h>
# endif
# else
# include <math.h>
# endif
# if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
/* Amiga SAS/C: We must include builtin FPU functions when compiling using
* MATH=68881
*/
# include <m68881.h>
# endif
#endif
/* Codewarrior on NT has linking problems without this. */
#if (defined(__MWERKS__) && defined(WIN32)) || defined(__STDC__)
# define PNG_ALWAYS_EXTERN
#endif
/* This provides the non-ANSI (far) memory allocation routines. */
#if defined(__TURBOC__) && defined(__MSDOS__)
# include <mem.h>
# include <alloc.h>
#endif
#if defined(WIN32) || defined(_Windows) || defined(_WINDOWS) || \
defined(_WIN32) || defined(__WIN32__)
# include <windows.h> /* defines _WINDOWS_ macro */
/* I have no idea why is this necessary... */
# ifdef _MSC_VER
# include <malloc.h>
# endif
#endif
/* Various modes of operation. Note that after an init, mode is set to
* zero automatically when the structure is created.
*/
#define PNG_HAVE_IHDR 0x01
#define PNG_HAVE_PLTE 0x02
#define PNG_HAVE_IDAT 0x04
#define PNG_AFTER_IDAT 0x08 /* Have complete zlib datastream */
#define PNG_HAVE_IEND 0x10
#define PNG_HAVE_gAMA 0x20
#define PNG_HAVE_cHRM 0x40
#define PNG_HAVE_sRGB 0x80
#define PNG_HAVE_CHUNK_HEADER 0x100
#define PNG_WROTE_tIME 0x200
#define PNG_WROTE_INFO_BEFORE_PLTE 0x400
#define PNG_BACKGROUND_IS_GRAY 0x800
#define PNG_HAVE_PNG_SIGNATURE 0x1000
#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
/* Flags for the transformations the PNG library does on the image data */
#define PNG_BGR 0x0001
#define PNG_INTERLACE 0x0002
#define PNG_PACK 0x0004
#define PNG_SHIFT 0x0008
#define PNG_SWAP_BYTES 0x0010
#define PNG_INVERT_MONO 0x0020
#define PNG_QUANTIZE 0x0040 /* formerly PNG_DITHER */
#define PNG_BACKGROUND 0x0080
#define PNG_BACKGROUND_EXPAND 0x0100
/* 0x0200 unused */
#define PNG_16_TO_8 0x0400
#define PNG_RGBA 0x0800
#define PNG_EXPAND 0x1000
#define PNG_GAMMA 0x2000
#define PNG_GRAY_TO_RGB 0x4000
#define PNG_FILLER 0x8000L
#define PNG_PACKSWAP 0x10000L
#define PNG_SWAP_ALPHA 0x20000L
#define PNG_STRIP_ALPHA 0x40000L
#define PNG_INVERT_ALPHA 0x80000L
#define PNG_USER_TRANSFORM 0x100000L
#define PNG_RGB_TO_GRAY_ERR 0x200000L
#define PNG_RGB_TO_GRAY_WARN 0x400000L
#define PNG_RGB_TO_GRAY 0x600000L /* two bits, RGB_TO_GRAY_ERR|WARN */
/* 0x800000L Unused */
#define PNG_ADD_ALPHA 0x1000000L /* Added to libpng-1.2.7 */
#define PNG_EXPAND_tRNS 0x2000000L /* Added to libpng-1.2.9 */
/* 0x4000000L unused */
/* 0x8000000L unused */
/* 0x10000000L unused */
/* 0x20000000L unused */
/* 0x40000000L unused */
/* Flags for png_create_struct */
#define PNG_STRUCT_PNG 0x0001
#define PNG_STRUCT_INFO 0x0002
/* Scaling factor for filter heuristic weighting calculations */
#define PNG_WEIGHT_SHIFT 8
#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT))
#define PNG_COST_SHIFT 3
#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT))
/* Flags for the png_ptr->flags rather than declaring a byte for each one */
#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001
#define PNG_FLAG_ZLIB_CUSTOM_LEVEL 0x0002
#define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL 0x0004
#define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS 0x0008
#define PNG_FLAG_ZLIB_CUSTOM_METHOD 0x0010
#define PNG_FLAG_ZLIB_FINISHED 0x0020
#define PNG_FLAG_ROW_INIT 0x0040
#define PNG_FLAG_FILLER_AFTER 0x0080
#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100
#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200
#define PNG_FLAG_CRC_CRITICAL_USE 0x0400
#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800
/* 0x1000 unused */
/* 0x2000 unused */
/* 0x4000 unused */
#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000L
#define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000L
#define PNG_FLAG_LIBRARY_MISMATCH 0x20000L
#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000L
#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000L
#define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000L
#define PNG_FLAG_ADD_ALPHA 0x200000L /* Added to libpng-1.2.8 */
#define PNG_FLAG_STRIP_ALPHA 0x400000L /* Added to libpng-1.2.8 */
#define PNG_FLAG_BENIGN_ERRORS_WARN 0x800000L /* Added to libpng-1.4.0 */
/* 0x1000000L unused */
/* 0x2000000L unused */
/* 0x4000000L unused */
/* 0x8000000L unused */
/* 0x10000000L unused */
/* 0x20000000L unused */
/* 0x40000000L unused */
#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
PNG_FLAG_CRC_ANCILLARY_NOWARN)
#define PNG_FLAG_CRC_CRITICAL_MASK (PNG_FLAG_CRC_CRITICAL_USE | \
PNG_FLAG_CRC_CRITICAL_IGNORE)
#define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \
PNG_FLAG_CRC_CRITICAL_MASK)
/* Save typing and make code easier to understand */
#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
abs((int)((c1).green) - (int)((c2).green)) + \
abs((int)((c1).blue) - (int)((c2).blue)))
/* Added to libpng-1.2.6 JB */
#define PNG_ROWBYTES(pixel_bits, width) \
((pixel_bits) >= 8 ? \
((png_size_t)(width) * (((png_size_t)(pixel_bits)) >> 3)) : \
(( ((png_size_t)(width) * ((png_size_t)(pixel_bits))) + 7) >> 3) )
/* PNG_OUT_OF_RANGE returns true if value is outside the range
* ideal-delta..ideal+delta. Each argument is evaluated twice.
* "ideal" and "delta" should be constants, normally simple
* integers, "value" a variable. Added to libpng-1.2.6 JB
*/
#define PNG_OUT_OF_RANGE(value, ideal, delta) \
( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) )
/* Constant strings for known chunk types. If you need to add a chunk,
* define the name here, and add an invocation of the macro wherever it's
* needed.
*/
#define PNG_IHDR PNG_CONST png_byte png_IHDR[5] = { 73, 72, 68, 82, '\0'}
#define PNG_IDAT PNG_CONST png_byte png_IDAT[5] = { 73, 68, 65, 84, '\0'}
#define PNG_IEND PNG_CONST png_byte png_IEND[5] = { 73, 69, 78, 68, '\0'}
#define PNG_PLTE PNG_CONST png_byte png_PLTE[5] = { 80, 76, 84, 69, '\0'}
#define PNG_bKGD PNG_CONST png_byte png_bKGD[5] = { 98, 75, 71, 68, '\0'}
#define PNG_cHRM PNG_CONST png_byte png_cHRM[5] = { 99, 72, 82, 77, '\0'}
#define PNG_gAMA PNG_CONST png_byte png_gAMA[5] = {103, 65, 77, 65, '\0'}
#define PNG_hIST PNG_CONST png_byte png_hIST[5] = {104, 73, 83, 84, '\0'}
#define PNG_iCCP PNG_CONST png_byte png_iCCP[5] = {105, 67, 67, 80, '\0'}
#define PNG_iTXt PNG_CONST png_byte png_iTXt[5] = {105, 84, 88, 116, '\0'}
#define PNG_oFFs PNG_CONST png_byte png_oFFs[5] = {111, 70, 70, 115, '\0'}
#define PNG_pCAL PNG_CONST png_byte png_pCAL[5] = {112, 67, 65, 76, '\0'}
#define PNG_sCAL PNG_CONST png_byte png_sCAL[5] = {115, 67, 65, 76, '\0'}
#define PNG_pHYs PNG_CONST png_byte png_pHYs[5] = {112, 72, 89, 115, '\0'}
#define PNG_sBIT PNG_CONST png_byte png_sBIT[5] = {115, 66, 73, 84, '\0'}
#define PNG_sPLT PNG_CONST png_byte png_sPLT[5] = {115, 80, 76, 84, '\0'}
#define PNG_sRGB PNG_CONST png_byte png_sRGB[5] = {115, 82, 71, 66, '\0'}
#define PNG_sTER PNG_CONST png_byte png_sTER[5] = {115, 84, 69, 82, '\0'}
#define PNG_tEXt PNG_CONST png_byte png_tEXt[5] = {116, 69, 88, 116, '\0'}
#define PNG_tIME PNG_CONST png_byte png_tIME[5] = {116, 73, 77, 69, '\0'}
#define PNG_tRNS PNG_CONST png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'}
#define PNG_zTXt PNG_CONST png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'}
/* Inhibit C++ name-mangling for libpng functions but not for system calls. */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* These functions are used internally in the code. They generally
* shouldn't be used unless you are writing code to add or replace some
* functionality in libpng. More information about most functions can
* be found in the files where the functions are located.
*/
/* Allocate memory for an internal libpng struct */
PNG_EXTERN png_voidp png_create_struct PNGARG((int type));
/* Free memory from internal libpng struct */
PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr));
PNG_EXTERN png_voidp png_create_struct_2 PNGARG((int type, png_malloc_ptr
malloc_fn, png_voidp mem_ptr));
PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr,
png_free_ptr free_fn, png_voidp mem_ptr));
/* Free any memory that info_ptr points to and reset struct. */
PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr,
png_infop info_ptr));
/* Function to allocate memory for zlib. PNGAPI is disallowed. */
PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size));
/* Function to free memory for zlib. PNGAPI is disallowed. */
PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr));
/* Next four functions are used internally as callbacks. PNGAPI is required
* but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3. */
PNG_EXTERN void PNGAPI png_default_read_data PNGARG((png_structp png_ptr,
png_bytep data, png_size_t length));
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
PNG_EXTERN void PNGAPI png_push_fill_buffer PNGARG((png_structp png_ptr,
png_bytep buffer, png_size_t length));
#endif
PNG_EXTERN void PNGAPI png_default_write_data PNGARG((png_structp png_ptr,
png_bytep data, png_size_t length));
#ifdef PNG_WRITE_FLUSH_SUPPORTED
#ifdef PNG_STDIO_SUPPORTED
PNG_EXTERN void PNGAPI png_default_flush PNGARG((png_structp png_ptr));
#endif
#endif
/* Reset the CRC variable */
PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr));
/* Write the "data" buffer to whatever output you are using */
PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, png_bytep data,
png_size_t length));
/* Read the chunk header (length + type name) */
PNG_EXTERN png_uint_32 png_read_chunk_header PNGARG((png_structp png_ptr));
/* Read data from whatever input you are using into the "data" buffer */
PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data,
png_size_t length));
/* Read bytes into buf, and update png_ptr->crc */
PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf,
png_size_t length));
/* Decompress data in a chunk that uses compression */
#if defined(PNG_zTXt_SUPPORTED) || defined(PNG_iTXt_SUPPORTED) || \
defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED)
PNG_EXTERN void png_decompress_chunk PNGARG((png_structp png_ptr,
int comp_type, png_size_t chunklength, png_size_t prefix_length,
png_size_t *data_length));
#endif
/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */
PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip));
/* Read the CRC from the file and compare it to the libpng calculated CRC */
PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr));
/* Calculate the CRC over a section of data. Note that we are only
* passing a maximum of 64K on systems that have this as a memory limit,
* since this is the maximum buffer size we can specify.
*/
PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, png_bytep ptr,
png_size_t length));
#ifdef PNG_WRITE_FLUSH_SUPPORTED
PNG_EXTERN void png_flush PNGARG((png_structp png_ptr));
#endif
/* Write various chunks */
/* Write the IHDR chunk, and update the png_struct with the necessary
* information.
*/
PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width,
png_uint_32 height,
int bit_depth, int color_type, int compression_method, int filter_method,
int interlace_method));
PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, png_colorp palette,
png_uint_32 num_pal));
PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data,
png_size_t length));
PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr));
#ifdef PNG_WRITE_gAMA_SUPPORTED
#ifdef PNG_FLOATING_POINT_SUPPORTED
PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma));
#endif
#ifdef PNG_FIXED_POINT_SUPPORTED
PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr,
png_fixed_point file_gamma));
#endif
#endif
#ifdef PNG_WRITE_sBIT_SUPPORTED
PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, png_color_8p sbit,
int color_type));
#endif
#ifdef PNG_WRITE_cHRM_SUPPORTED
#ifdef PNG_FLOATING_POINT_SUPPORTED
PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr,
double white_x, double white_y,
double red_x, double red_y, double green_x, double green_y,
double blue_x, double blue_y));
#endif
PNG_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr,
png_fixed_point int_white_x, png_fixed_point int_white_y,
png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
png_fixed_point int_blue_y));
#endif
#ifdef PNG_WRITE_sRGB_SUPPORTED
PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr,
int intent));
#endif
#ifdef PNG_WRITE_iCCP_SUPPORTED
PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr,
png_charp name, int compression_type,
png_charp profile, int proflen));
/* Note to maintainer: profile should be png_bytep */
#endif
#ifdef PNG_WRITE_sPLT_SUPPORTED
PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr,
png_sPLT_tp palette));
#endif
#ifdef PNG_WRITE_tRNS_SUPPORTED
PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, png_bytep trans,
png_color_16p values, int number, int color_type));
#endif
#ifdef PNG_WRITE_bKGD_SUPPORTED
PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr,
png_color_16p values, int color_type));
#endif
#ifdef PNG_WRITE_hIST_SUPPORTED
PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, png_uint_16p hist,
int num_hist));
#endif
#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr,
png_charp key, png_charpp new_key));
#endif
#ifdef PNG_WRITE_tEXt_SUPPORTED
PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_charp key,
png_charp text, png_size_t text_len));
#endif
#ifdef PNG_WRITE_zTXt_SUPPORTED
PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_charp key,
png_charp text, png_size_t text_len, int compression));
#endif
#ifdef PNG_WRITE_iTXt_SUPPORTED
PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr,
int compression, png_charp key, png_charp lang, png_charp lang_key,
png_charp text));
#endif
#ifdef PNG_TEXT_SUPPORTED /* Added at version 1.0.14 and 1.2.4 */
PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr,
png_infop info_ptr, png_textp text_ptr, int num_text));
#endif
#ifdef PNG_WRITE_oFFs_SUPPORTED
PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr,
png_int_32 x_offset, png_int_32 y_offset, int unit_type));
#endif
#ifdef PNG_WRITE_pCAL_SUPPORTED
PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose,
png_int_32 X0, png_int_32 X1, int type, int nparams,
png_charp units, png_charpp params));
#endif
#ifdef PNG_WRITE_pHYs_SUPPORTED
PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr,
png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit,
int unit_type));
#endif
#ifdef PNG_WRITE_tIME_SUPPORTED
PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr,
png_timep mod_time));
#endif
#ifdef PNG_WRITE_sCAL_SUPPORTED
#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)
PNG_EXTERN void png_write_sCAL PNGARG((png_structp png_ptr,
int unit, double width, double height));
#else
#ifdef PNG_FIXED_POINT_SUPPORTED
PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr,
int unit, png_charp width, png_charp height));
#endif
#endif
#endif
/* Called when finished processing a row of data */
PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr));
/* Internal use only. Called before first row of data */
PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr));
#ifdef PNG_READ_GAMMA_SUPPORTED
PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr,
png_byte bit_depth));
#endif
/* Combine a row of data, dealing with alpha, etc. if requested */
PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row,
int mask));
#ifdef PNG_READ_INTERLACING_SUPPORTED
/* Expand an interlaced row */
/* OLD pre-1.0.9 interface:
PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info,
png_bytep row, int pass, png_uint_32 transformations));
*/
PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr));
#endif
/* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
/* Grab pixels out of a row for an interlaced pass */
PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info,
png_bytep row, int pass));
#endif
/* Unfilter a row */
PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr,
png_row_infop row_info, png_bytep row, png_bytep prev_row, int filter));
/* Choose the best filter to use and filter the row data */
PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr,
png_row_infop row_info));
/* Write out the filtered row. */
PNG_EXTERN void png_write_filtered_row PNGARG((png_structp png_ptr,
png_bytep filtered_row));
/* Finish a row while reading, dealing with interlacing passes, etc. */
PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr));
/* Initialize the row buffers, etc. */
PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr));
/* Optional call to update the users info structure */
PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr,
png_infop info_ptr));
/* These are the functions that do the transformations */
#ifdef PNG_READ_FILLER_SUPPORTED
PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info,
png_bytep row, png_uint_32 filler, png_uint_32 flags));
#endif
#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info,
png_bytep row));
#endif
#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info,
png_bytep row));
#endif
#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info,
png_bytep row));
#endif
#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info,
png_bytep row));
#endif
#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
PNG_EXTERN void png_do_strip_filler PNGARG((png_row_infop row_info,
png_bytep row, png_uint_32 flags));
#endif
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info, png_bytep row));
#endif
#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \
defined(PNG_WRITE_PACKSWAP_SUPPORTED)
PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info, png_bytep row));
#endif
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, png_row_infop
row_info, png_bytep row));
#endif
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info,
png_bytep row));
#endif
#ifdef PNG_READ_PACK_SUPPORTED
PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, png_bytep row));
#endif
#ifdef PNG_READ_SHIFT_SUPPORTED
PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, png_bytep row,
png_color_8p sig_bits));
#endif
#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info, png_bytep row));
#endif
#ifdef PNG_READ_16_TO_8_SUPPORTED
PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, png_bytep row));
#endif
#ifdef PNG_READ_QUANTIZE_SUPPORTED
PNG_EXTERN void png_do_quantize PNGARG((png_row_infop row_info,
png_bytep row, png_bytep palette_lookup, png_bytep quantize_lookup));
# ifdef PNG_CORRECT_PALETTE_SUPPORTED
PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr,
png_colorp palette, int num_palette));
# endif
#endif
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info, png_bytep row));
#endif
#ifdef PNG_WRITE_PACK_SUPPORTED
PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info,
png_bytep row, png_uint_32 bit_depth));
#endif
#ifdef PNG_WRITE_SHIFT_SUPPORTED
PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, png_bytep row,
png_color_8p bit_depth));
#endif
#ifdef PNG_READ_BACKGROUND_SUPPORTED
#ifdef PNG_READ_GAMMA_SUPPORTED
PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row,
png_color_16p trans_color, png_color_16p background,
png_color_16p background_1,
png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
png_uint_16pp gamma_16_to_1, int gamma_shift));
#else
PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row,
png_color_16p trans_color, png_color_16p background));
#endif
#endif
#ifdef PNG_READ_GAMMA_SUPPORTED
PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, png_bytep row,
png_bytep gamma_table, png_uint_16pp gamma_16_table,
int gamma_shift));
#endif
#ifdef PNG_READ_EXPAND_SUPPORTED
PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info,
png_bytep row, png_colorp palette, png_bytep trans, int num_trans));
PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info,
png_bytep row, png_color_16p trans_value));
#endif
/* The following decodes the appropriate chunks, and does error correction,
* then calls the appropriate callback for the chunk if it is valid.
*/
/* Decode the IHDR chunk */
PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
#ifdef PNG_READ_bKGD_SUPPORTED
PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
#endif
#ifdef PNG_READ_cHRM_SUPPORTED
PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
#endif
#ifdef PNG_READ_gAMA_SUPPORTED
PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
#endif
#ifdef PNG_READ_hIST_SUPPORTED
PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
#endif
#ifdef PNG_READ_iCCP_SUPPORTED
extern void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
#endif /* PNG_READ_iCCP_SUPPORTED */
#ifdef PNG_READ_iTXt_SUPPORTED
PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
#endif
#ifdef PNG_READ_oFFs_SUPPORTED
PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
#endif
#ifdef PNG_READ_pCAL_SUPPORTED
PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
#endif
#ifdef PNG_READ_pHYs_SUPPORTED
PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
#endif
#ifdef PNG_READ_sBIT_SUPPORTED
PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
#endif
#ifdef PNG_READ_sCAL_SUPPORTED
PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
#endif
#ifdef PNG_READ_sPLT_SUPPORTED
extern void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
#endif /* PNG_READ_sPLT_SUPPORTED */
#ifdef PNG_READ_sRGB_SUPPORTED
PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
#endif
#ifdef PNG_READ_tEXt_SUPPORTED
PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
#endif
#ifdef PNG_READ_tIME_SUPPORTED
PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
#endif
#ifdef PNG_READ_tRNS_SUPPORTED
PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
#endif
#ifdef PNG_READ_zTXt_SUPPORTED
PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
#endif
PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr,
png_infop info_ptr, png_uint_32 length));
PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr,
png_bytep chunk_name));
/* Handle the transformations for reading and writing */
PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr));
PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr));
PNG_EXTERN void png_init_read_transformations PNGARG((png_structp png_ptr));
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr,
png_infop info_ptr));
PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr,
png_infop info_ptr));
PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr));
PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr,
png_uint_32 length));
PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr));
PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr));
PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr,
png_bytep buffer, png_size_t buffer_length));
PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr));
PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr,
png_bytep buffer, png_size_t buffer_length));
PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr));
PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr,
png_infop info_ptr, png_uint_32 length));
PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr,
png_infop info_ptr));
PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr,
png_infop info_ptr));
PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr, png_bytep row));
PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr,
png_infop info_ptr));
PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr,
png_infop info_ptr));
PNG_EXTERN void png_read_push_finish_row PNGARG((png_structp png_ptr));
#ifdef PNG_READ_tEXt_SUPPORTED
PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr,
png_infop info_ptr, png_uint_32 length));
PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr,
png_infop info_ptr));
#endif
#ifdef PNG_READ_zTXt_SUPPORTED
PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr,
png_infop info_ptr, png_uint_32 length));
PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr,
png_infop info_ptr));
#endif
#ifdef PNG_READ_iTXt_SUPPORTED
PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr,
png_infop info_ptr, png_uint_32 length));
PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr,
png_infop info_ptr));
#endif
#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
#ifdef PNG_MNG_FEATURES_SUPPORTED
PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info,
png_bytep row));
PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info,
png_bytep row));
#endif
/* Added at libpng version 1.4.0 */
#ifdef PNG_cHRM_SUPPORTED
PNG_EXTERN int png_check_cHRM_fixed PNGARG((png_structp png_ptr,
png_fixed_point int_white_x, png_fixed_point int_white_y,
png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
png_fixed_point int_blue_y));
#endif
#ifdef PNG_cHRM_SUPPORTED
#ifdef PNG_CHECK_cHRM_SUPPORTED
/* Added at libpng version 1.2.34 and 1.4.0 */
PNG_EXTERN void png_64bit_product PNGARG((long v1, long v2,
unsigned long *hi_product, unsigned long *lo_product));
#endif
#endif
/* Added at libpng version 1.4.0 */
PNG_EXTERN void png_check_IHDR PNGARG((png_structp png_ptr,
png_uint_32 width, png_uint_32 height, int bit_depth,
int color_type, int interlace_type, int compression_type,
int filter_type));
/* Free all memory used by the read (old method - NOT DLL EXPORTED) */
extern void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr,
png_infop end_info_ptr));
/* Free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */
extern void png_write_destroy PNGARG((png_structp png_ptr));
#ifdef USE_FAR_KEYWORD /* memory model conversion function */
extern void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr,
int check));
#endif /* USE_FAR_KEYWORD */
/* 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.
*/
#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_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) \
{ \
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":"")))); \
}
# endif
# ifndef png_debug1
# define png_debug1(l,m,p1) \
{ \
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); \
}
# endif
# ifndef png_debug2
# define png_debug2(l,m,p1,p2) \
{ \
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); \
}
# endif
# else /* __STDC __ */
# ifndef png_debug
# define png_debug(l,m) \
{ \
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); \
}
# endif
# ifndef png_debug1
# define png_debug1(l,m,p1) \
{ \
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); \
}
# endif
# ifndef png_debug2
# define png_debug2(l,m,p1,p2) \
{ \
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); \
}
# 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)
#endif
#ifndef png_debug1
#define png_debug1(l, m, p1)
#endif
#ifndef png_debug2
#define png_debug2(l, m, p1, p2)
#endif
/* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */
#ifdef __cplusplus
}
#endif
#endif /* PNG_VERSION_INFO_ONLY */
#endif /* PNGPRIV_H */

1361
src/libpng/pngread.c Normal file

File diff suppressed because it is too large Load Diff

163
src/libpng/pngrio.c Normal file
View File

@ -0,0 +1,163 @@
/* pngrio.c - functions for data input
*
* Last changed in libpng 1.4.1 [February 25, 2010]
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*
* This file provides a location for all input. Users who need
* special handling are expected to write a function that has the same
* arguments as this and performs a similar function, but that possibly
* has a different input method. Note that you shouldn't change this
* function, but rather write a replacement function and then make
* 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"
/* Read the data from whatever input you are using. The default routine
* reads from a file pointer. Note that this routine sometimes gets called
* with very small lengths, so you should implement some kind of simple
* buffering if you are using unbuffered reads. This should never be asked
* to read more then 64K on a 16 bit machine.
*/
void /* PRIVATE */
png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_debug1(4, "reading %d bytes", (int)length);
if (png_ptr->read_data_fn != NULL)
(*(png_ptr->read_data_fn))(png_ptr, data, length);
else
png_error(png_ptr, "Call to NULL read function");
}
#ifdef PNG_STDIO_SUPPORTED
/* This is the function that does the actual reading of data. If you are
* not reading from a standard C stream, you should create a replacement
* read_data function and use it at run time with png_set_read_fn(), rather
* than changing the library.
*/
#ifndef USE_FAR_KEYWORD
void PNGAPI
png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_size_t check;
if (png_ptr == NULL)
return;
/* 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.
*/
check = fread(data, 1, length, (png_FILE_p)png_ptr->io_ptr);
if (check != length)
png_error(png_ptr, "Read Error");
}
#else
/* This is the model-independent version. Since the standard I/O library
can't handle far buffers in the medium and small models, we have to copy
the data.
*/
#define NEAR_BUF_SIZE 1024
#define MIN(a,b) (a <= b ? a : b)
static void PNGAPI
png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_size_t check;
png_byte *n_data;
png_FILE_p io_ptr;
if (png_ptr == NULL)
return;
/* Check if data really is near. If so, use usual code. */
n_data = (png_byte *)CVT_PTR_NOCHECK(data);
io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
if ((png_bytep)n_data == data)
{
check = fread(n_data, 1, length, io_ptr);
}
else
{
png_byte buf[NEAR_BUF_SIZE];
png_size_t read, remaining, err;
check = 0;
remaining = length;
do
{
read = MIN(NEAR_BUF_SIZE, remaining);
err = fread(buf, 1, read, io_ptr);
png_memcpy(data, buf, read); /* copy far buffer to near buffer */
if (err != read)
break;
else
check += err;
data += read;
remaining -= read;
}
while (remaining != 0);
}
if ((png_uint_32)check != (png_uint_32)length)
png_error(png_ptr, "read Error");
}
#endif
#endif
/* This function allows the application to supply a new input function
* for libpng if standard C streams aren't being used.
*
* This function takes as its arguments:
* png_ptr - pointer to a png input data structure
* io_ptr - pointer to user supplied structure containing info about
* the input functions. May be NULL.
* read_data_fn - pointer to a new input function that takes as its
* arguments a pointer to a png_struct, a pointer to
* a location where input data can be stored, and a 32-bit
* unsigned int that is the number of bytes to be read.
* To exit and output any fatal error messages the new write
* function should call png_error(png_ptr, "Error msg").
* May be NULL, in which case libpng's default function will
* be used.
*/
void PNGAPI
png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
png_rw_ptr read_data_fn)
{
if (png_ptr == NULL)
return;
png_ptr->io_ptr = io_ptr;
#ifdef PNG_STDIO_SUPPORTED
if (read_data_fn != NULL)
png_ptr->read_data_fn = read_data_fn;
else
png_ptr->read_data_fn = png_default_read_data;
#else
png_ptr->read_data_fn = read_data_fn;
#endif
/* It is an error to write to a read device */
if (png_ptr->write_data_fn != NULL)
{
png_ptr->write_data_fn = NULL;
png_warning(png_ptr,
"It's an error to set both read_data_fn and write_data_fn in the ");
png_warning(png_ptr,
"same structure. Resetting write_data_fn to NULL");
}
#ifdef PNG_WRITE_FLUSH_SUPPORTED
png_ptr->output_flush_fn = NULL;
#endif
}
#endif /* PNG_READ_SUPPORTED */

4203
src/libpng/pngrtran.c Normal file

File diff suppressed because it is too large Load Diff

3365
src/libpng/pngrutil.c Normal file

File diff suppressed because it is too large Load Diff

1167
src/libpng/pngset.c Normal file

File diff suppressed because it is too large Load Diff

1630
src/libpng/pngtest.c Normal file

File diff suppressed because it is too large Load Diff

677
src/libpng/pngtrans.c Normal file
View File

@ -0,0 +1,677 @@
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
*
* Last changed in libpng 1.4.2 [April 29, 2010]
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* 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"
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
/* Turn on BGR-to-RGB mapping */
void PNGAPI
png_set_bgr(png_structp png_ptr)
{
png_debug(1, "in png_set_bgr");
if (png_ptr == NULL)
return;
png_ptr->transformations |= PNG_BGR;
}
#endif
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
/* Turn on 16 bit byte swapping */
void PNGAPI
png_set_swap(png_structp png_ptr)
{
png_debug(1, "in png_set_swap");
if (png_ptr == NULL)
return;
if (png_ptr->bit_depth == 16)
png_ptr->transformations |= PNG_SWAP_BYTES;
}
#endif
#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
/* Turn on pixel packing */
void PNGAPI
png_set_packing(png_structp png_ptr)
{
png_debug(1, "in png_set_packing");
if (png_ptr == NULL)
return;
if (png_ptr->bit_depth < 8)
{
png_ptr->transformations |= PNG_PACK;
png_ptr->usr_bit_depth = 8;
}
}
#endif
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
/* Turn on packed pixel swapping */
void PNGAPI
png_set_packswap(png_structp png_ptr)
{
png_debug(1, "in png_set_packswap");
if (png_ptr == NULL)
return;
if (png_ptr->bit_depth < 8)
png_ptr->transformations |= PNG_PACKSWAP;
}
#endif
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
void PNGAPI
png_set_shift(png_structp png_ptr, png_color_8p true_bits)
{
png_debug(1, "in png_set_shift");
if (png_ptr == NULL)
return;
png_ptr->transformations |= PNG_SHIFT;
png_ptr->shift = *true_bits;
}
#endif
#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
defined(PNG_WRITE_INTERLACING_SUPPORTED)
int PNGAPI
png_set_interlace_handling(png_structp png_ptr)
{
png_debug(1, "in png_set_interlace handling");
if (png_ptr && png_ptr->interlaced)
{
png_ptr->transformations |= PNG_INTERLACE;
return (7);
}
return (1);
}
#endif
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
/* Add a filler byte on read, or remove a filler or alpha byte on write.
* The filler type has changed in v0.95 to allow future 2-byte fillers
* for 48-bit input data, as well as to avoid problems with some compilers
* that don't like bytes as parameters.
*/
void PNGAPI
png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
{
png_debug(1, "in png_set_filler");
if (png_ptr == NULL)
return;
png_ptr->transformations |= PNG_FILLER;
png_ptr->filler = (png_uint_16)filler;
if (filler_loc == PNG_FILLER_AFTER)
png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
else
png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
/* This should probably go in the "do_read_filler" routine.
* I attempted to do that in libpng-1.0.1a but that caused problems
* so I restored it in libpng-1.0.2a
*/
if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
{
png_ptr->usr_channels = 4;
}
/* Also I added this in libpng-1.0.2a (what happens when we expand
* a less-than-8-bit grayscale to GA? */
if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
{
png_ptr->usr_channels = 2;
}
}
/* Added to libpng-1.2.7 */
void PNGAPI
png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
{
png_debug(1, "in png_set_add_alpha");
if (png_ptr == NULL)
return;
png_set_filler(png_ptr, filler, filler_loc);
png_ptr->transformations |= PNG_ADD_ALPHA;
}
#endif
#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
void PNGAPI
png_set_swap_alpha(png_structp png_ptr)
{
png_debug(1, "in png_set_swap_alpha");
if (png_ptr == NULL)
return;
png_ptr->transformations |= PNG_SWAP_ALPHA;
}
#endif
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
void PNGAPI
png_set_invert_alpha(png_structp png_ptr)
{
png_debug(1, "in png_set_invert_alpha");
if (png_ptr == NULL)
return;
png_ptr->transformations |= PNG_INVERT_ALPHA;
}
#endif
#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
void PNGAPI
png_set_invert_mono(png_structp png_ptr)
{
png_debug(1, "in png_set_invert_mono");
if (png_ptr == NULL)
return;
png_ptr->transformations |= PNG_INVERT_MONO;
}
/* Invert monochrome grayscale data */
void /* PRIVATE */
png_do_invert(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_invert");
/* This test removed from libpng version 1.0.13 and 1.2.0:
* if (row_info->bit_depth == 1 &&
*/
if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
{
png_bytep rp = row;
png_uint_32 i;
png_uint_32 istop = row_info->rowbytes;
for (i = 0; i < istop; i++)
{
*rp = (png_byte)(~(*rp));
rp++;
}
}
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
row_info->bit_depth == 8)
{
png_bytep rp = row;
png_uint_32 i;
png_uint_32 istop = row_info->rowbytes;
for (i = 0; i < istop; i+=2)
{
*rp = (png_byte)(~(*rp));
rp+=2;
}
}
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
row_info->bit_depth == 16)
{
png_bytep rp = row;
png_uint_32 i;
png_uint_32 istop = row_info->rowbytes;
for (i = 0; i < istop; i+=4)
{
*rp = (png_byte)(~(*rp));
*(rp+1) = (png_byte)(~(*(rp+1)));
rp+=4;
}
}
}
#endif
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
/* Swaps byte order on 16 bit depth images */
void /* PRIVATE */
png_do_swap(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_swap");
if (
row_info->bit_depth == 16)
{
png_bytep rp = row;
png_uint_32 i;
png_uint_32 istop= row_info->width * row_info->channels;
for (i = 0; i < istop; i++, rp += 2)
{
png_byte t = *rp;
*rp = *(rp + 1);
*(rp + 1) = t;
}
}
}
#endif
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
static PNG_CONST png_byte onebppswaptable[256] = {
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
};
static PNG_CONST png_byte twobppswaptable[256] = {
0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
};
static PNG_CONST png_byte fourbppswaptable[256] = {
0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
};
/* Swaps pixel packing order within bytes */
void /* PRIVATE */
png_do_packswap(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_packswap");
if (
row_info->bit_depth < 8)
{
png_bytep rp, end, table;
end = row + row_info->rowbytes;
if (row_info->bit_depth == 1)
table = (png_bytep)onebppswaptable;
else if (row_info->bit_depth == 2)
table = (png_bytep)twobppswaptable;
else if (row_info->bit_depth == 4)
table = (png_bytep)fourbppswaptable;
else
return;
for (rp = row; rp < end; rp++)
*rp = table[*rp];
}
}
#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
/* Remove filler or alpha byte(s) */
void /* PRIVATE */
png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
{
png_debug(1, "in png_do_strip_filler");
{
png_bytep sp=row;
png_bytep dp=row;
png_uint_32 row_width=row_info->width;
png_uint_32 i;
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)
{
/* This converts from RGBX or RGBA to RGB */
if (flags & PNG_FLAG_FILLER_AFTER)
{
dp+=3; sp+=4;
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++;
*dp++ = *sp++;
*dp++ = *sp++;
*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->rowbytes = row_width;
}
else /* if (row_info->bit_depth == 16) */
{
if (flags & PNG_FLAG_FILLER_AFTER)
{
/* 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;
}
}
else
{
/* This converts from XXGG or AAGG to GG */
for (i = 0; i < row_width; i++)
{
sp += 2;
*dp++ = *sp++;
*dp++ = *sp++;
}
}
row_info->pixel_depth = 16;
row_info->rowbytes = row_width * 2;
}
row_info->channels = 1;
}
if (flags & PNG_FLAG_STRIP_ALPHA)
row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
}
}
#endif
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
/* Swaps red and blue bytes within a pixel */
void /* PRIVATE */
png_do_bgr(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_bgr");
if (
(row_info->color_type & PNG_COLOR_MASK_COLOR))
{
png_uint_32 row_width = row_info->width;
if (row_info->bit_depth == 8)
{
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
{
png_bytep rp;
png_uint_32 i;
for (i = 0, rp = row; i < row_width; i++, rp += 3)
{
png_byte save = *rp;
*rp = *(rp + 2);
*(rp + 2) = save;
}
}
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{
png_bytep rp;
png_uint_32 i;
for (i = 0, rp = row; i < row_width; i++, rp += 4)
{
png_byte save = *rp;
*rp = *(rp + 2);
*(rp + 2) = save;
}
}
}
else if (row_info->bit_depth == 16)
{
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
{
png_bytep rp;
png_uint_32 i;
for (i = 0, rp = row; i < row_width; i++, rp += 6)
{
png_byte save = *rp;
*rp = *(rp + 4);
*(rp + 4) = save;
save = *(rp + 1);
*(rp + 1) = *(rp + 5);
*(rp + 5) = save;
}
}
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{
png_bytep rp;
png_uint_32 i;
for (i = 0, rp = row; i < row_width; i++, rp += 8)
{
png_byte save = *rp;
*rp = *(rp + 4);
*(rp + 4) = save;
save = *(rp + 1);
*(rp + 1) = *(rp + 5);
*(rp + 5) = save;
}
}
}
}
}
#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
void PNGAPI
png_set_user_transform_info(png_structp png_ptr, png_voidp
user_transform_ptr, int user_transform_depth, int user_transform_channels)
{
png_debug(1, "in png_set_user_transform_info");
if (png_ptr == NULL)
return;
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
png_ptr->user_transform_ptr = user_transform_ptr;
png_ptr->user_transform_depth = (png_byte)user_transform_depth;
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
}
/* This function returns a pointer to the user_transform_ptr associated with
* the user transform functions. The application should free any memory
* associated with this pointer before png_write_destroy and png_read_destroy
* are called.
*/
png_voidp PNGAPI
png_get_user_transform_ptr(png_structp png_ptr)
{
if (png_ptr == NULL)
return (NULL);
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
return ((png_voidp)png_ptr->user_transform_ptr);
#else
return (NULL);
#endif
}
#endif /* PNG_READ_USER_TRANSFORM_SUPPORTED ||
PNG_WRITE_USER_TRANSFORM_SUPPORTED */
#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */

241
src/libpng/pngwio.c Normal file
View File

@ -0,0 +1,241 @@
/* pngwio.c - functions for data output
*
* Last changed in libpng 1.4.0 [January 3, 2010]
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*
* This file provides a location for all output. Users who need
* special handling are expected to write functions that have the same
* arguments as these and perform similar functions, but that possibly
* use different output methods. Note that you shouldn't change these
* functions, but rather write replacement functions and then change
* them at run time with png_set_write_fn(...).
*/
#define PNG_NO_PEDANTIC_WARNINGS
#include "png.h"
#ifdef PNG_WRITE_SUPPORTED
#include "pngpriv.h"
/* Write the data to whatever output you are using. The default routine
* writes to a file pointer. Note that this routine sometimes gets called
* with very small lengths, so you should implement some kind of simple
* buffering if you are using unbuffered writes. This should never be asked
* to write more than 64K on a 16 bit machine.
*/
void /* PRIVATE */
png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
if (png_ptr->write_data_fn != NULL )
(*(png_ptr->write_data_fn))(png_ptr, data, length);
else
png_error(png_ptr, "Call to NULL write function");
}
#ifdef PNG_STDIO_SUPPORTED
/* This is the function that does the actual writing of data. If you are
* not writing to a standard C stream, you should create a replacement
* write_data function and use it at run time with png_set_write_fn(), rather
* than changing the library.
*/
#ifndef USE_FAR_KEYWORD
void PNGAPI
png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_uint_32 check;
if (png_ptr == NULL)
return;
check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
if (check != length)
png_error(png_ptr, "Write Error");
}
#else
/* This is the model-independent version. Since the standard I/O library
* can't handle far buffers in the medium and small models, we have to copy
* the data.
*/
#define NEAR_BUF_SIZE 1024
#define MIN(a,b) (a <= b ? a : b)
void PNGAPI
png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_uint_32 check;
png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
png_FILE_p io_ptr;
if (png_ptr == NULL)
return;
/* Check if data really is near. If so, use usual code. */
near_data = (png_byte *)CVT_PTR_NOCHECK(data);
io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
if ((png_bytep)near_data == data)
{
check = fwrite(near_data, 1, length, io_ptr);
}
else
{
png_byte buf[NEAR_BUF_SIZE];
png_size_t written, remaining, err;
check = 0;
remaining = length;
do
{
written = MIN(NEAR_BUF_SIZE, remaining);
png_memcpy(buf, data, written); /* Copy far buffer to near buffer */
err = fwrite(buf, 1, written, io_ptr);
if (err != written)
break;
else
check += err;
data += written;
remaining -= written;
}
while (remaining != 0);
}
if (check != length)
png_error(png_ptr, "Write Error");
}
#endif
#endif
/* This function is called to output any data pending writing (normally
* to disk). After png_flush is called, there should be no data pending
* writing in any buffers.
*/
#ifdef PNG_WRITE_FLUSH_SUPPORTED
void /* PRIVATE */
png_flush(png_structp png_ptr)
{
if (png_ptr->output_flush_fn != NULL)
(*(png_ptr->output_flush_fn))(png_ptr);
}
#ifdef PNG_STDIO_SUPPORTED
void PNGAPI
png_default_flush(png_structp png_ptr)
{
png_FILE_p io_ptr;
if (png_ptr == NULL)
return;
io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
fflush(io_ptr);
}
#endif
#endif
/* This function allows the application to supply new output functions for
* libpng if standard C streams aren't being used.
*
* This function takes as its arguments:
* png_ptr - pointer to a png output data structure
* io_ptr - pointer to user supplied structure containing info about
* the output functions. May be NULL.
* write_data_fn - pointer to a new output function that takes as its
* arguments a pointer to a png_struct, a pointer to
* data to be written, and a 32-bit unsigned int that is
* the number of bytes to be written. The new write
* function should call png_error(png_ptr, "Error msg")
* to exit and output any fatal error messages. May be
* NULL, in which case libpng's default function will
* be used.
* flush_data_fn - pointer to a new flush function that takes as its
* arguments a pointer to a png_struct. After a call to
* the flush function, there should be no data in any buffers
* or pending transmission. If the output method doesn't do
* any buffering of output, a function prototype must still be
* supplied although it doesn't have to do anything. If
* PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
* time, output_flush_fn will be ignored, although it must be
* supplied for compatibility. May be NULL, in which case
* libpng's default function will be used, if
* PNG_WRITE_FLUSH_SUPPORTED is defined. This is not
* a good idea if io_ptr does not point to a standard
* *FILE structure.
*/
void PNGAPI
png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
{
if (png_ptr == NULL)
return;
png_ptr->io_ptr = io_ptr;
#ifdef PNG_STDIO_SUPPORTED
if (write_data_fn != NULL)
png_ptr->write_data_fn = write_data_fn;
else
png_ptr->write_data_fn = png_default_write_data;
#else
png_ptr->write_data_fn = write_data_fn;
#endif
#ifdef PNG_WRITE_FLUSH_SUPPORTED
#ifdef PNG_STDIO_SUPPORTED
if (output_flush_fn != NULL)
png_ptr->output_flush_fn = output_flush_fn;
else
png_ptr->output_flush_fn = png_default_flush;
#else
png_ptr->output_flush_fn = output_flush_fn;
#endif
#endif /* PNG_WRITE_FLUSH_SUPPORTED */
/* It is an error to read while writing a png file */
if (png_ptr->read_data_fn != NULL)
{
png_ptr->read_data_fn = NULL;
png_warning(png_ptr,
"Attempted to set both read_data_fn and write_data_fn in");
png_warning(png_ptr,
"the same structure. Resetting read_data_fn to NULL");
}
}
#ifdef USE_FAR_KEYWORD
#ifdef _MSC_VER
void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check)
{
void *near_ptr;
void FAR *far_ptr;
FP_OFF(near_ptr) = FP_OFF(ptr);
far_ptr = (void FAR *)near_ptr;
if (check != 0)
if (FP_SEG(ptr) != FP_SEG(far_ptr))
png_error(png_ptr, "segment lost in conversion");
return(near_ptr);
}
# else
void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check)
{
void *near_ptr;
void FAR *far_ptr;
near_ptr = (void FAR *)ptr;
far_ptr = (void FAR *)near_ptr;
if (check != 0)
if (far_ptr != ptr)
png_error(png_ptr, "segment lost in conversion");
return(near_ptr);
}
# endif
# endif
#endif /* PNG_WRITE_SUPPORTED */

1457
src/libpng/pngwrite.c Normal file

File diff suppressed because it is too large Load Diff

566
src/libpng/pngwtran.c Normal file
View File

@ -0,0 +1,566 @@
/* pngwtran.c - transforms the data in a row for PNG writers
*
* Last changed in libpng 1.4.1 [February 25, 2010]
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*/
#define PNG_NO_PEDANTIC_WARNINGS
#include "png.h"
#ifdef PNG_WRITE_SUPPORTED
#include "pngpriv.h"
/* Transform the data according to the user's wishes. The order of
* transformations is significant.
*/
void /* PRIVATE */
png_do_write_transformations(png_structp png_ptr)
{
png_debug(1, "in png_do_write_transformations");
if (png_ptr == NULL)
return;
#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
if (png_ptr->transformations & PNG_USER_TRANSFORM)
if (png_ptr->write_user_transform_fn != NULL)
(*(png_ptr->write_user_transform_fn)) /* User write transform
function */
(png_ptr, /* png_ptr */
&(png_ptr->row_info), /* row_info: */
/* png_uint_32 width; width of row */
/* png_uint_32 rowbytes; number of bytes in row */
/* png_byte color_type; color type of pixels */
/* png_byte bit_depth; bit depth of samples */
/* png_byte channels; number of channels (1-4) */
/* png_byte pixel_depth; bits per pixel (depth*channels) */
png_ptr->row_buf + 1); /* start of pixel data for row */
#endif
#ifdef PNG_WRITE_FILLER_SUPPORTED
if (png_ptr->transformations & PNG_FILLER)
png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
png_ptr->flags);
#endif
#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
if (png_ptr->transformations & PNG_PACKSWAP)
png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
#ifdef PNG_WRITE_PACK_SUPPORTED
if (png_ptr->transformations & PNG_PACK)
png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
(png_uint_32)png_ptr->bit_depth);
#endif
#ifdef PNG_WRITE_SWAP_SUPPORTED
if (png_ptr->transformations & PNG_SWAP_BYTES)
png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
#ifdef PNG_WRITE_SHIFT_SUPPORTED
if (png_ptr->transformations & PNG_SHIFT)
png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
&(png_ptr->shift));
#endif
#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
if (png_ptr->transformations & PNG_SWAP_ALPHA)
png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
if (png_ptr->transformations & PNG_INVERT_ALPHA)
png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
#ifdef PNG_WRITE_BGR_SUPPORTED
if (png_ptr->transformations & PNG_BGR)
png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
#ifdef PNG_WRITE_INVERT_SUPPORTED
if (png_ptr->transformations & PNG_INVERT_MONO)
png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
}
#ifdef PNG_WRITE_PACK_SUPPORTED
/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
* row_info bit depth should be 8 (one pixel per byte). The channels
* should be 1 (this only happens on grayscale and paletted images).
*/
void /* PRIVATE */
png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
{
png_debug(1, "in png_do_pack");
if (row_info->bit_depth == 8 &&
row_info->channels == 1)
{
switch ((int)bit_depth)
{
case 1:
{
png_bytep sp, dp;
int mask, v;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
sp = row;
dp = row;
mask = 0x80;
v = 0;
for (i = 0; i < row_width; i++)
{
if (*sp != 0)
v |= mask;
sp++;
if (mask > 1)
mask >>= 1;
else
{
mask = 0x80;
*dp = (png_byte)v;
dp++;
v = 0;
}
}
if (mask != 0x80)
*dp = (png_byte)v;
break;
}
case 2:
{
png_bytep sp, dp;
int shift, v;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
sp = row;
dp = row;
shift = 6;
v = 0;
for (i = 0; i < row_width; i++)
{
png_byte value;
value = (png_byte)(*sp & 0x03);
v |= (value << shift);
if (shift == 0)
{
shift = 6;
*dp = (png_byte)v;
dp++;
v = 0;
}
else
shift -= 2;
sp++;
}
if (shift != 6)
*dp = (png_byte)v;
break;
}
case 4:
{
png_bytep sp, dp;
int shift, v;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
sp = row;
dp = row;
shift = 4;
v = 0;
for (i = 0; i < row_width; i++)
{
png_byte value;
value = (png_byte)(*sp & 0x0f);
v |= (value << shift);
if (shift == 0)
{
shift = 4;
*dp = (png_byte)v;
dp++;
v = 0;
}
else
shift -= 4;
sp++;
}
if (shift != 4)
*dp = (png_byte)v;
break;
}
}
row_info->bit_depth = (png_byte)bit_depth;
row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
row_info->width);
}
}
#endif
#ifdef PNG_WRITE_SHIFT_SUPPORTED
/* Shift pixel values to take advantage of whole range. Pass the
* true number of bits in bit_depth. The row should be packed
* according to row_info->bit_depth. Thus, if you had a row of
* bit depth 4, but the pixels only had values from 0 to 7, you
* would pass 3 as bit_depth, and this routine would translate the
* data to 0 to 15.
*/
void /* PRIVATE */
png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
{
png_debug(1, "in png_do_shift");
if (
row_info->color_type != PNG_COLOR_TYPE_PALETTE)
{
int shift_start[4], shift_dec[4];
int channels = 0;
if (row_info->color_type & PNG_COLOR_MASK_COLOR)
{
shift_start[channels] = row_info->bit_depth - bit_depth->red;
shift_dec[channels] = bit_depth->red;
channels++;
shift_start[channels] = row_info->bit_depth - bit_depth->green;
shift_dec[channels] = bit_depth->green;
channels++;
shift_start[channels] = row_info->bit_depth - bit_depth->blue;
shift_dec[channels] = bit_depth->blue;
channels++;
}
else
{
shift_start[channels] = row_info->bit_depth - bit_depth->gray;
shift_dec[channels] = bit_depth->gray;
channels++;
}
if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
{
shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
shift_dec[channels] = bit_depth->alpha;
channels++;
}
/* With low row depths, could only be grayscale, so one channel */
if (row_info->bit_depth < 8)
{
png_bytep bp = row;
png_uint_32 i;
png_byte mask;
png_uint_32 row_bytes = row_info->rowbytes;
if (bit_depth->gray == 1 && row_info->bit_depth == 2)
mask = 0x55;
else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
mask = 0x11;
else
mask = 0xff;
for (i = 0; i < row_bytes; i++, bp++)
{
png_uint_16 v;
int j;
v = *bp;
*bp = 0;
for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
{
if (j > 0)
*bp |= (png_byte)((v << j) & 0xff);
else
*bp |= (png_byte)((v >> (-j)) & mask);
}
}
}
else if (row_info->bit_depth == 8)
{
png_bytep bp = row;
png_uint_32 i;
png_uint_32 istop = channels * row_info->width;
for (i = 0; i < istop; i++, bp++)
{
png_uint_16 v;
int j;
int c = (int)(i%channels);
v = *bp;
*bp = 0;
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
{
if (j > 0)
*bp |= (png_byte)((v << j) & 0xff);
else
*bp |= (png_byte)((v >> (-j)) & 0xff);
}
}
}
else
{
png_bytep bp;
png_uint_32 i;
png_uint_32 istop = channels * row_info->width;
for (bp = row, i = 0; i < istop; i++)
{
int c = (int)(i%channels);
png_uint_16 value, v;
int j;
v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
value = 0;
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
{
if (j > 0)
value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
else
value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
}
*bp++ = (png_byte)(value >> 8);
*bp++ = (png_byte)(value & 0xff);
}
}
}
}
#endif
#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
void /* PRIVATE */
png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_write_swap_alpha");
{
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{
/* This converts from ARGB to RGBA */
if (row_info->bit_depth == 8)
{
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
png_byte save = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = save;
}
}
/* This converts from AARRGGBB to RRGGBBAA */
else
{
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
png_byte save[2];
save[0] = *(sp++);
save[1] = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = save[0];
*(dp++) = save[1];
}
}
}
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
{
/* This converts from AG to GA */
if (row_info->bit_depth == 8)
{
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
png_byte save = *(sp++);
*(dp++) = *(sp++);
*(dp++) = save;
}
}
/* This converts from AAGG to GGAA */
else
{
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
png_byte save[2];
save[0] = *(sp++);
save[1] = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = save[0];
*(dp++) = save[1];
}
}
}
}
}
#endif
#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
void /* PRIVATE */
png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_write_invert_alpha");
{
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{
/* This inverts the alpha channel in RGBA */
if (row_info->bit_depth == 8)
{
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
/* Does nothing
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*/
sp+=3; dp = sp;
*(dp++) = (png_byte)(255 - *(sp++));
}
}
/* This inverts the alpha channel in RRGGBBAA */
else
{
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
/* Does nothing
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*/
sp+=6; dp = sp;
*(dp++) = (png_byte)(255 - *(sp++));
*(dp++) = (png_byte)(255 - *(sp++));
}
}
}
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
{
/* This inverts the alpha channel in GA */
if (row_info->bit_depth == 8)
{
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
*(dp++) = *(sp++);
*(dp++) = (png_byte)(255 - *(sp++));
}
}
/* This inverts the alpha channel in GGAA */
else
{
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
/* Does nothing
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*/
sp+=2; dp = sp;
*(dp++) = (png_byte)(255 - *(sp++));
*(dp++) = (png_byte)(255 - *(sp++));
}
}
}
}
}
#endif
#ifdef PNG_MNG_FEATURES_SUPPORTED
/* Undoes intrapixel differencing */
void /* PRIVATE */
png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_write_intrapixel");
if (
(row_info->color_type & PNG_COLOR_MASK_COLOR))
{
int bytes_per_pixel;
png_uint_32 row_width = row_info->width;
if (row_info->bit_depth == 8)
{
png_bytep rp;
png_uint_32 i;
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
bytes_per_pixel = 3;
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
bytes_per_pixel = 4;
else
return;
for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
{
*(rp) = (png_byte)((*rp - *(rp+1))&0xff);
*(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff);
}
}
else if (row_info->bit_depth == 16)
{
png_bytep rp;
png_uint_32 i;
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
bytes_per_pixel = 6;
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
bytes_per_pixel = 8;
else
return;
for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
{
png_uint_32 s0 = (*(rp ) << 8) | *(rp+1);
png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3);
png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5);
png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL);
png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
*(rp ) = (png_byte)((red >> 8) & 0xff);
*(rp+1) = (png_byte)(red & 0xff);
*(rp+4) = (png_byte)((blue >> 8) & 0xff);
*(rp+5) = (png_byte)(blue & 0xff);
}
}
}
}
#endif /* PNG_MNG_FEATURES_SUPPORTED */
#endif /* PNG_WRITE_SUPPORTED */

2786
src/libpng/pngwutil.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -316,6 +316,26 @@
DCD56D390B247D920092F9F8 /* Cart4A50.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCD56D370B247D920092F9F8 /* Cart4A50.hxx */; };
DCD56D3C0B247DB40092F9F8 /* RectList.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCD56D3A0B247DB40092F9F8 /* RectList.cxx */; };
DCD56D3D0B247DB40092F9F8 /* RectList.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCD56D3B0B247DB40092F9F8 /* RectList.hxx */; };
DCD6FC7011C281ED005DA767 /* png.c in Sources */ = {isa = PBXBuildFile; fileRef = DCD6FC5D11C281ED005DA767 /* png.c */; };
DCD6FC7111C281ED005DA767 /* png.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD6FC5E11C281ED005DA767 /* png.h */; };
DCD6FC7211C281ED005DA767 /* pngconf.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD6FC5F11C281ED005DA767 /* pngconf.h */; };
DCD6FC7311C281ED005DA767 /* pngerror.c in Sources */ = {isa = PBXBuildFile; fileRef = DCD6FC6011C281ED005DA767 /* pngerror.c */; };
DCD6FC7411C281ED005DA767 /* pngget.c in Sources */ = {isa = PBXBuildFile; fileRef = DCD6FC6111C281ED005DA767 /* pngget.c */; };
DCD6FC7511C281ED005DA767 /* pngmem.c in Sources */ = {isa = PBXBuildFile; fileRef = DCD6FC6211C281ED005DA767 /* pngmem.c */; };
DCD6FC7611C281ED005DA767 /* pngpread.c in Sources */ = {isa = PBXBuildFile; fileRef = DCD6FC6311C281ED005DA767 /* pngpread.c */; };
DCD6FC7711C281ED005DA767 /* pngpriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD6FC6411C281ED005DA767 /* pngpriv.h */; };
DCD6FC7811C281ED005DA767 /* pngread.c in Sources */ = {isa = PBXBuildFile; fileRef = DCD6FC6511C281ED005DA767 /* pngread.c */; };
DCD6FC7911C281ED005DA767 /* pngrio.c in Sources */ = {isa = PBXBuildFile; fileRef = DCD6FC6611C281ED005DA767 /* pngrio.c */; };
DCD6FC7A11C281ED005DA767 /* pngrtran.c in Sources */ = {isa = PBXBuildFile; fileRef = DCD6FC6711C281ED005DA767 /* pngrtran.c */; };
DCD6FC7B11C281ED005DA767 /* pngrutil.c in Sources */ = {isa = PBXBuildFile; fileRef = DCD6FC6811C281ED005DA767 /* pngrutil.c */; };
DCD6FC7C11C281ED005DA767 /* pngset.c in Sources */ = {isa = PBXBuildFile; fileRef = DCD6FC6911C281ED005DA767 /* pngset.c */; };
DCD6FC7E11C281ED005DA767 /* pngtrans.c in Sources */ = {isa = PBXBuildFile; fileRef = DCD6FC6B11C281ED005DA767 /* pngtrans.c */; };
DCD6FC7F11C281ED005DA767 /* pngwio.c in Sources */ = {isa = PBXBuildFile; fileRef = DCD6FC6C11C281ED005DA767 /* pngwio.c */; };
DCD6FC8011C281ED005DA767 /* pngwrite.c in Sources */ = {isa = PBXBuildFile; fileRef = DCD6FC6D11C281ED005DA767 /* pngwrite.c */; };
DCD6FC8111C281ED005DA767 /* pngwtran.c in Sources */ = {isa = PBXBuildFile; fileRef = DCD6FC6E11C281ED005DA767 /* pngwtran.c */; };
DCD6FC8211C281ED005DA767 /* pngwutil.c in Sources */ = {isa = PBXBuildFile; fileRef = DCD6FC6F11C281ED005DA767 /* pngwutil.c */; };
DCD6FC9311C28C6F005DA767 /* PNGLibrary.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCD6FC9111C28C6F005DA767 /* PNGLibrary.cxx */; };
DCD6FC9411C28C6F005DA767 /* PNGLibrary.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCD6FC9211C28C6F005DA767 /* PNGLibrary.hxx */; };
DCE3BBF90C95CEDC00A671DF /* RomInfoWidget.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCE3BBF50C95CEDC00A671DF /* RomInfoWidget.cxx */; };
DCE3BBFA0C95CEDC00A671DF /* RomInfoWidget.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCE3BBF60C95CEDC00A671DF /* RomInfoWidget.hxx */; };
DCE6EB220DD9ADA00047AC28 /* TrackBall.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCE6EB200DD9ADA00047AC28 /* TrackBall.cxx */; };
@ -697,6 +717,26 @@
DCD56D370B247D920092F9F8 /* Cart4A50.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Cart4A50.hxx; path = ../emucore/Cart4A50.hxx; sourceTree = SOURCE_ROOT; };
DCD56D3A0B247DB40092F9F8 /* RectList.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = RectList.cxx; path = ../common/RectList.cxx; sourceTree = SOURCE_ROOT; };
DCD56D3B0B247DB40092F9F8 /* RectList.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = RectList.hxx; path = ../common/RectList.hxx; sourceTree = SOURCE_ROOT; };
DCD6FC5D11C281ED005DA767 /* png.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = png.c; path = ../libpng/png.c; sourceTree = SOURCE_ROOT; };
DCD6FC5E11C281ED005DA767 /* png.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = png.h; path = ../libpng/png.h; sourceTree = SOURCE_ROOT; };
DCD6FC5F11C281ED005DA767 /* pngconf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pngconf.h; path = ../libpng/pngconf.h; sourceTree = SOURCE_ROOT; };
DCD6FC6011C281ED005DA767 /* pngerror.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngerror.c; path = ../libpng/pngerror.c; sourceTree = SOURCE_ROOT; };
DCD6FC6111C281ED005DA767 /* pngget.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngget.c; path = ../libpng/pngget.c; sourceTree = SOURCE_ROOT; };
DCD6FC6211C281ED005DA767 /* pngmem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngmem.c; path = ../libpng/pngmem.c; sourceTree = SOURCE_ROOT; };
DCD6FC6311C281ED005DA767 /* pngpread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngpread.c; path = ../libpng/pngpread.c; sourceTree = SOURCE_ROOT; };
DCD6FC6411C281ED005DA767 /* pngpriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pngpriv.h; path = ../libpng/pngpriv.h; sourceTree = SOURCE_ROOT; };
DCD6FC6511C281ED005DA767 /* pngread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngread.c; path = ../libpng/pngread.c; sourceTree = SOURCE_ROOT; };
DCD6FC6611C281ED005DA767 /* pngrio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngrio.c; path = ../libpng/pngrio.c; sourceTree = SOURCE_ROOT; };
DCD6FC6711C281ED005DA767 /* pngrtran.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngrtran.c; path = ../libpng/pngrtran.c; sourceTree = SOURCE_ROOT; };
DCD6FC6811C281ED005DA767 /* pngrutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngrutil.c; path = ../libpng/pngrutil.c; sourceTree = SOURCE_ROOT; };
DCD6FC6911C281ED005DA767 /* pngset.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngset.c; path = ../libpng/pngset.c; sourceTree = SOURCE_ROOT; };
DCD6FC6B11C281ED005DA767 /* pngtrans.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngtrans.c; path = ../libpng/pngtrans.c; sourceTree = SOURCE_ROOT; };
DCD6FC6C11C281ED005DA767 /* pngwio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngwio.c; path = ../libpng/pngwio.c; sourceTree = SOURCE_ROOT; };
DCD6FC6D11C281ED005DA767 /* pngwrite.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngwrite.c; path = ../libpng/pngwrite.c; sourceTree = SOURCE_ROOT; };
DCD6FC6E11C281ED005DA767 /* pngwtran.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngwtran.c; path = ../libpng/pngwtran.c; sourceTree = SOURCE_ROOT; };
DCD6FC6F11C281ED005DA767 /* pngwutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pngwutil.c; path = ../libpng/pngwutil.c; sourceTree = SOURCE_ROOT; };
DCD6FC9111C28C6F005DA767 /* PNGLibrary.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PNGLibrary.cxx; path = ../common/PNGLibrary.cxx; sourceTree = SOURCE_ROOT; };
DCD6FC9211C28C6F005DA767 /* PNGLibrary.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = PNGLibrary.hxx; path = ../common/PNGLibrary.hxx; sourceTree = SOURCE_ROOT; };
DCE3BBF50C95CEDC00A671DF /* RomInfoWidget.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = RomInfoWidget.cxx; path = ../gui/RomInfoWidget.cxx; sourceTree = SOURCE_ROOT; };
DCE3BBF60C95CEDC00A671DF /* RomInfoWidget.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = RomInfoWidget.hxx; path = ../gui/RomInfoWidget.hxx; sourceTree = SOURCE_ROOT; };
DCE6EB200DD9ADA00047AC28 /* TrackBall.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TrackBall.cxx; path = ../emucore/TrackBall.cxx; sourceTree = SOURCE_ROOT; };
@ -799,6 +839,7 @@
2D605130089879BA00C6DE89 /* debugger */,
2D6050CC0898776500C6DE89 /* emucore */,
2D6050FA0898786C00C6DE89 /* gui */,
DCD6FC5A11C281A1005DA767 /* libpng */,
2D6050C60898771C00C6DE89 /* macosx */,
2D6050C90898774B00C6DE89 /* unix */,
2D60513708987A5400C6DE89 /* yacc */,
@ -881,6 +922,8 @@
2D733D62062893E7006265D9 /* FrameBufferSoft.hxx */,
DCB9DA5E0FCD527000B192F6 /* GLShaderProgs.hxx */,
2DDBEA0A0845700300812C11 /* mainSDL.cxx */,
DCD6FC9111C28C6F005DA767 /* PNGLibrary.cxx */,
DCD6FC9211C28C6F005DA767 /* PNGLibrary.hxx */,
DCD56D3A0B247DB40092F9F8 /* RectList.cxx */,
DCD56D3B0B247DB40092F9F8 /* RectList.hxx */,
DCF467B20F93993B00B25D7A /* SharedPtr.hxx */,
@ -1201,6 +1244,31 @@
name = cheat;
sourceTree = "<group>";
};
DCD6FC5A11C281A1005DA767 /* libpng */ = {
isa = PBXGroup;
children = (
DCD6FC5D11C281ED005DA767 /* png.c */,
DCD6FC5E11C281ED005DA767 /* png.h */,
DCD6FC5F11C281ED005DA767 /* pngconf.h */,
DCD6FC6011C281ED005DA767 /* pngerror.c */,
DCD6FC6111C281ED005DA767 /* pngget.c */,
DCD6FC6211C281ED005DA767 /* pngmem.c */,
DCD6FC6311C281ED005DA767 /* pngpread.c */,
DCD6FC6411C281ED005DA767 /* pngpriv.h */,
DCD6FC6511C281ED005DA767 /* pngread.c */,
DCD6FC6611C281ED005DA767 /* pngrio.c */,
DCD6FC6711C281ED005DA767 /* pngrtran.c */,
DCD6FC6811C281ED005DA767 /* pngrutil.c */,
DCD6FC6911C281ED005DA767 /* pngset.c */,
DCD6FC6B11C281ED005DA767 /* pngtrans.c */,
DCD6FC6C11C281ED005DA767 /* pngwio.c */,
DCD6FC6D11C281ED005DA767 /* pngwrite.c */,
DCD6FC6E11C281ED005DA767 /* pngwtran.c */,
DCD6FC6F11C281ED005DA767 /* pngwutil.c */,
);
name = libpng;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@ -1376,6 +1444,10 @@
DC6B2BA711037FF200F199A7 /* DiStella.hxx in Headers */,
DCD3F7C611340AAF00DBA3AE /* Genesis.hxx in Headers */,
DCAD60A91152F8BD00BC4184 /* CartDPCPlus.hxx in Headers */,
DCD6FC7111C281ED005DA767 /* png.h in Headers */,
DCD6FC7211C281ED005DA767 /* pngconf.h in Headers */,
DCD6FC7711C281ED005DA767 /* pngpriv.h in Headers */,
DCD6FC9411C28C6F005DA767 /* PNGLibrary.hxx in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1613,6 +1685,22 @@
DC6B2BA611037FF200F199A7 /* DiStella.cxx in Sources */,
DCD3F7C511340AAF00DBA3AE /* Genesis.cxx in Sources */,
DCAD60A81152F8BD00BC4184 /* CartDPCPlus.cxx in Sources */,
DCD6FC7011C281ED005DA767 /* png.c in Sources */,
DCD6FC7311C281ED005DA767 /* pngerror.c in Sources */,
DCD6FC7411C281ED005DA767 /* pngget.c in Sources */,
DCD6FC7511C281ED005DA767 /* pngmem.c in Sources */,
DCD6FC7611C281ED005DA767 /* pngpread.c in Sources */,
DCD6FC7811C281ED005DA767 /* pngread.c in Sources */,
DCD6FC7911C281ED005DA767 /* pngrio.c in Sources */,
DCD6FC7A11C281ED005DA767 /* pngrtran.c in Sources */,
DCD6FC7B11C281ED005DA767 /* pngrutil.c in Sources */,
DCD6FC7C11C281ED005DA767 /* pngset.c in Sources */,
DCD6FC7E11C281ED005DA767 /* pngtrans.c in Sources */,
DCD6FC7F11C281ED005DA767 /* pngwio.c in Sources */,
DCD6FC8011C281ED005DA767 /* pngwrite.c in Sources */,
DCD6FC8111C281ED005DA767 /* pngwtran.c in Sources */,
DCD6FC8211C281ED005DA767 /* pngwutil.c in Sources */,
DCD6FC9311C28C6F005DA767 /* PNGLibrary.cxx in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};