Imported from libpng-0.82.tar
This commit is contained in:
parent
51f0eb4584
commit
0f71645dfe
48
example.c
48
example.c
@ -79,9 +79,19 @@ void read_png(char *file_name)
|
|||||||
png_info_init(info_ptr);
|
png_info_init(info_ptr);
|
||||||
png_read_init(png_ptr);
|
png_read_init(png_ptr);
|
||||||
|
|
||||||
/* set up the input control */
|
/* set up the input control for the default input and message functions.
|
||||||
|
* If we were to replace both the input and message functions we don't
|
||||||
|
* need to call png_init_io first. */
|
||||||
png_init_io(png_ptr, fp);
|
png_init_io(png_ptr, fp);
|
||||||
|
|
||||||
|
/* if you are using replacement read functions, here you would call */
|
||||||
|
io_ptr = (user_io_struct *)malloc(sizeof(user_io_struct));
|
||||||
|
png_set_read_fn(png_ptr, (void *)io_ptr, user_read_fn);
|
||||||
|
|
||||||
|
/* if you are using replacement message functions, here you would call */
|
||||||
|
msg_ptr = (user_msg_struct *)malloc(sizeof(user_msg_struct));
|
||||||
|
png_set_read_fn(png_ptr, (void *)msg_ptr, user_error_fn, user_warning_fn);
|
||||||
|
|
||||||
/* read the file information */
|
/* read the file information */
|
||||||
png_read_info(png_ptr, info_ptr);
|
png_read_info(png_ptr, info_ptr);
|
||||||
|
|
||||||
@ -146,8 +156,7 @@ void read_png(char *file_name)
|
|||||||
png_set_invert(png_ptr);
|
png_set_invert(png_ptr);
|
||||||
|
|
||||||
/* shift the pixels down to their true bit depth */
|
/* shift the pixels down to their true bit depth */
|
||||||
if (info_ptr->valid & PNG_INFO_sBIT &&
|
if (info_ptr->valid & PNG_INFO_sBIT)
|
||||||
info_ptr->bit_depth > info_ptr->sig_bit)
|
|
||||||
png_set_shift(png_ptr, &(info_ptr->sig_bit));
|
png_set_shift(png_ptr, &(info_ptr->sig_bit));
|
||||||
|
|
||||||
/* pack pixels into bytes */
|
/* pack pixels into bytes */
|
||||||
@ -212,6 +221,11 @@ void read_png(char *file_name)
|
|||||||
in info_ptr */
|
in info_ptr */
|
||||||
png_read_end(png_ptr, info_ptr);
|
png_read_end(png_ptr, info_ptr);
|
||||||
|
|
||||||
|
/* if you had allocated any memory structures for custom input or
|
||||||
|
messaging routines you need to free them before png_read_destroy */
|
||||||
|
free(png_get_io_ptr(png_ptr));
|
||||||
|
free(png_get_msg_ptr(png_ptr));
|
||||||
|
|
||||||
/* clean up after the read, and free any memory allocated */
|
/* clean up after the read, and free any memory allocated */
|
||||||
png_read_destroy(png_ptr, info_ptr, (png_info *)0);
|
png_read_destroy(png_ptr, info_ptr, (png_info *)0);
|
||||||
|
|
||||||
@ -269,9 +283,19 @@ void write_png(char *file_name, ... other image information ...)
|
|||||||
png_info_init(info_ptr);
|
png_info_init(info_ptr);
|
||||||
png_write_init(png_ptr);
|
png_write_init(png_ptr);
|
||||||
|
|
||||||
/* set up the output control */
|
/* set up the output control for the default output and message functions.
|
||||||
|
* If we were to replace both the output and message functions we don't
|
||||||
|
* need to call png_init_io first. */
|
||||||
png_init_io(png_ptr, fp);
|
png_init_io(png_ptr, fp);
|
||||||
|
|
||||||
|
/* if you are using replacement write functions, here you would call */
|
||||||
|
io_ptr = (user_io_struct *)malloc(sizeof(user_io_struct));
|
||||||
|
png_set_write_fn(png_ptr, (void *)io_ptr, user_write_fn, user_flush_fn);
|
||||||
|
|
||||||
|
/* if you are using replacement message functions, here you would call */
|
||||||
|
msg_ptr = (user_msg_struct *)malloc(sizeof(user_msg_struct));
|
||||||
|
png_set_read_fn(png_ptr, (void *)msg_ptr, user_error_fn, user_warning_fn);
|
||||||
|
|
||||||
/* set the file information here */
|
/* set the file information here */
|
||||||
info_ptr->width = ;
|
info_ptr->width = ;
|
||||||
info_ptr->height = ;
|
info_ptr->height = ;
|
||||||
@ -285,9 +309,16 @@ void write_png(char *file_name, ... other image information ...)
|
|||||||
|
|
||||||
/* optional significant bit chunk */
|
/* optional significant bit chunk */
|
||||||
info_ptr->valid |= PNG_INFO_sBIT;
|
info_ptr->valid |= PNG_INFO_sBIT;
|
||||||
info_ptr->sig_bit = true_bit_depth;
|
/* if we are dealing with a grayscale image then */
|
||||||
|
info_ptr->sig_bit.gray = true_bit_depth;
|
||||||
|
/* otherwise, if we are dealing with a color image then */
|
||||||
|
info_ptr->sig_bit.red = true_red_bit_depth;
|
||||||
|
info_ptr->sig_bit.green = true_green_bit_depth;
|
||||||
|
info_ptr->sig_bit.blue = true_blue_bit_depth;
|
||||||
|
/* if the image has an alpha channel then */
|
||||||
|
info_ptr->sig_bit.alpha = true_alpha_bit_depth;
|
||||||
|
|
||||||
/* optional gamma chunk */
|
/* optional gamma chunk is a good idea if you can write one */
|
||||||
info_ptr->valid |= PNG_INFO_gAMA;
|
info_ptr->valid |= PNG_INFO_gAMA;
|
||||||
info_ptr->gamma = gamma;
|
info_ptr->gamma = gamma;
|
||||||
|
|
||||||
@ -347,6 +378,11 @@ void write_png(char *file_name, ... other image information ...)
|
|||||||
/* write the rest of the file */
|
/* write the rest of the file */
|
||||||
png_write_end(png_ptr, info_ptr);
|
png_write_end(png_ptr, info_ptr);
|
||||||
|
|
||||||
|
/* if you had allocated any memory structures for custom output or
|
||||||
|
messaging routines you need to free them before png_write_destroy */
|
||||||
|
free(png_get_io_ptr(png_ptr));
|
||||||
|
free(png_get_msg_ptr(png_ptr));
|
||||||
|
|
||||||
/* clean up after the write, and free any memory allocated */
|
/* clean up after the write, and free any memory allocated */
|
||||||
png_write_destroy(png_ptr);
|
png_write_destroy(png_ptr);
|
||||||
|
|
||||||
|
250
libpng.txt
250
libpng.txt
@ -45,22 +45,22 @@ The structures:
|
|||||||
There are two main structures that are important to libpng, png_struct
|
There are two main structures that are important to libpng, png_struct
|
||||||
and png_info. The first, png_struct, is an internal structure that
|
and png_info. The first, png_struct, is an internal structure that
|
||||||
will not, for the most part, be used by the general user except as
|
will not, for the most part, be used by the general user except as
|
||||||
the first variable passed to every png function call.
|
the first variable passed to every PNG function call.
|
||||||
|
|
||||||
The png_info structure is designed to provide information about the
|
The png_info structure is designed to provide information about the
|
||||||
png file. All of it's fields are intended to be examined or modified
|
png file. All of it's fields are intended to be examined or modified
|
||||||
by the user. See png.h for a good description of the png_info fields.
|
by the user. See png.h for a good description of the png_info fields.
|
||||||
|
|
||||||
And while I'm on the topic, make sure you include the png header file:
|
And while I'm on the topic, make sure you include the PNG header file:
|
||||||
|
|
||||||
#include <png.h>
|
#include <png.h>
|
||||||
|
|
||||||
Checking PNG files:
|
Checking PNG files:
|
||||||
|
|
||||||
Libpng provides a simple check to see if a file is a png file. To
|
Libpng provides a simple check to see if a file is a PNG file. To
|
||||||
use it, pass in the first 1 to 8 bytes of the file, and it will return
|
use it, pass in the first 1 to 8 bytes of the file, and it will return
|
||||||
true or false (1 or 0) depending on whether the bytes could be part
|
true or false (1 or 0) depending on whether the bytes could be part
|
||||||
of a png file. Of course, the more bytes you pass in, the greater
|
of a PNG file. Of course, the more bytes you pass in, the greater
|
||||||
the accuracy of the prediction.
|
the accuracy of the prediction.
|
||||||
|
|
||||||
fread(header, 1, number, fp);
|
fread(header, 1, number, fp);
|
||||||
@ -95,6 +95,11 @@ much to undo.
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
If you are not using the standard IO functions to do input and
|
||||||
|
output, and/or not using stderr for your output messages, you will
|
||||||
|
have the ability to change the functions that libpng uses once
|
||||||
|
you have allocated the libpng data structures below.
|
||||||
|
|
||||||
After you have these structures, you will need to set up the
|
After you have these structures, you will need to set up the
|
||||||
error handling. When libpng encounters an error, it expects to
|
error handling. When libpng encounters an error, it expects to
|
||||||
longjmp back to your routine. Therefore, you will need to call
|
longjmp back to your routine. Therefore, you will need to call
|
||||||
@ -103,10 +108,11 @@ read the file from different routines, you will need to update
|
|||||||
the jmpbuf field every time you enter a new routine that will
|
the jmpbuf field every time you enter a new routine that will
|
||||||
call a png_ function. See your documentation of setjmp/longjmp
|
call a png_ function. See your documentation of setjmp/longjmp
|
||||||
for your compiler for more information on setjmp/longjmp. See
|
for your compiler for more information on setjmp/longjmp. See
|
||||||
the discussion on png error handling in the Customizing Libpng
|
the discussion on libpng error handling in the Customizing Libpng
|
||||||
section below for more information on the png error handling.
|
section below for more information on how to change the behaviour
|
||||||
If an error occurs, and libpng longjmp's back to your setjmp,
|
of libpng error handling. If an error occurs, and libpng longjmp's
|
||||||
you will want to call png_read_destroy() to free any memory.
|
back to your setjmp, you will want to call png_read_destroy() to
|
||||||
|
free any memory.
|
||||||
|
|
||||||
if (setjmp(png_ptr->jmpbuf))
|
if (setjmp(png_ptr->jmpbuf))
|
||||||
{
|
{
|
||||||
@ -132,9 +138,8 @@ would be bad.
|
|||||||
Now you need to set up the input code. The default for libpng is
|
Now you need to set up the input code. The default for libpng is
|
||||||
to use the C function fread(). If you use this, you will need to
|
to use the C function fread(). If you use this, you will need to
|
||||||
pass a valid FILE * in the function png_init_io(). Be sure that
|
pass a valid FILE * in the function png_init_io(). Be sure that
|
||||||
the file is opened in binary mode. If you wish to handle reading
|
the file is opened in binary mode. Otherwise, you should see the
|
||||||
data in another way, see the discussion on png i/o handling in the
|
section below on Customizing libpng I/O functions.
|
||||||
Customizing Libpng section below.
|
|
||||||
|
|
||||||
png_init_io(png_ptr, fp);
|
png_init_io(png_ptr, fp);
|
||||||
|
|
||||||
@ -159,7 +164,7 @@ to read the file. Some of the more important parts of the png_info are:
|
|||||||
PNG_INFO_<chunk name> define.
|
PNG_INFO_<chunk name> define.
|
||||||
palette and num_palette - the palette for the file
|
palette and num_palette - the palette for the file
|
||||||
gamma - the gamma the file is written at
|
gamma - the gamma the file is written at
|
||||||
sig_bit and sig_bit_number - the number of significant bits
|
sig_bit - the number of significant bits for red, green, blue, grey, alpha
|
||||||
trans, trans_values, and number_trans - transparency info
|
trans, trans_values, and number_trans - transparency info
|
||||||
hist - histogram of palette
|
hist - histogram of palette
|
||||||
text and num_text - text comments in the file.
|
text and num_text - text comments in the file.
|
||||||
@ -174,14 +179,26 @@ suggested keywords, there is no requirement to restrict the use
|
|||||||
to these strings. There is a requirement to have at least one
|
to these strings. There is a requirement to have at least one
|
||||||
character for a keyword. It is strongly suggested that keywords
|
character for a keyword. It is strongly suggested that keywords
|
||||||
be sensible to humans (that's the point), so don't use abbreviations.
|
be sensible to humans (that's the point), so don't use abbreviations.
|
||||||
See the png specification for more details. There is no requirement
|
Some suggested keywords for tEXT (or zTXt) chunks are:
|
||||||
to have text after the keyword on tEXt chunks. However, you must
|
|
||||||
have text after the keyword on zTXt chunks, as only the text gets
|
|
||||||
compressed, and compressing nothing will result in an error.
|
|
||||||
|
|
||||||
There is no maximum length on the keyword, and nothing
|
Title Short (one line) title or caption for image
|
||||||
prevents you from duplicating the keyword. The text field is an
|
Author Name of image's creator
|
||||||
array of png_text structures, each holding pointer to a keyword
|
Copyright Copyright notice (possibly long)
|
||||||
|
Description Description of image (possibly long)
|
||||||
|
Software Software used to create the image
|
||||||
|
Disclaimer Legal disclaimer (possibly long)
|
||||||
|
Warning Warning of nature of content
|
||||||
|
Source Device used to create the image
|
||||||
|
Comment Miscellaneous comment; conversion from GIF comment
|
||||||
|
Created When the image or source file was created
|
||||||
|
|
||||||
|
There is no requirement to have text after the keyword on tEXt chunks.
|
||||||
|
However, you must have text after the keyword on zTXt chunks, as only
|
||||||
|
the text gets compressed, and compressing nothing will result in an error.
|
||||||
|
|
||||||
|
The maximum length of the keyword is limited to 80 characters. It is
|
||||||
|
possible to use the same keyword any number of times. The text field
|
||||||
|
is an array of png_text structures, each holding pointer to a keyword
|
||||||
and a pointer to a text string. Only the text string may be null.
|
and a pointer to a text string. Only the text string may be null.
|
||||||
The keyword/text pairs are put into the array in the order that
|
The keyword/text pairs are put into the array in the order that
|
||||||
they are received. However, some or all of the text chunks may be
|
they are received. However, some or all of the text chunks may be
|
||||||
@ -200,7 +217,7 @@ check to see if it has data that it can do somthing with, you should
|
|||||||
make sure to only enable a transformation if it will be valid for
|
make sure to only enable a transformation if it will be valid for
|
||||||
the data. For example, don't swap red and blue on grayscale data.
|
the data. For example, don't swap red and blue on grayscale data.
|
||||||
|
|
||||||
This transforms bit depths of less then 8 to 8 bits, changes paletted
|
This transforms bit depths of less than 8 to 8 bits, changes paletted
|
||||||
images to rgb, and adds an alpha channel if there is transparency
|
images to rgb, and adds an alpha channel if there is transparency
|
||||||
information in a tRNS chunk. This is probably most useful on grayscale
|
information in a tRNS chunk. This is probably most useful on grayscale
|
||||||
images with bit depths of 2 or 4 and tRNS chunks.
|
images with bit depths of 2 or 4 and tRNS chunks.
|
||||||
@ -239,7 +256,8 @@ This handles gamma transformations of the data. Pass both the file
|
|||||||
gamma and the desired screen gamma. If the file does not have a
|
gamma and the desired screen gamma. If the file does not have a
|
||||||
gamma value, you can pass one anyway if you wish. Note that file
|
gamma value, you can pass one anyway if you wish. Note that file
|
||||||
gammas are inverted from screen gammas. See the discussions on
|
gammas are inverted from screen gammas. See the discussions on
|
||||||
gamma in the PNG specification for more information.
|
gamma in the PNG specification for more information. It is strongly
|
||||||
|
reccommended that viewers support gamma correction.
|
||||||
|
|
||||||
if (info_ptr->valid & PNG_INFO_gAMA)
|
if (info_ptr->valid & PNG_INFO_gAMA)
|
||||||
png_set_gamma(png_ptr, screen_gamma, info_ptr->gamma);
|
png_set_gamma(png_ptr, screen_gamma, info_ptr->gamma);
|
||||||
@ -506,9 +524,11 @@ setjmp and pass the jmpbuf field of your png_struct. If you
|
|||||||
write the file from different routines, you will need to update
|
write the file from different routines, you will need to update
|
||||||
the jmpbuf field every time you enter a new routine that will
|
the jmpbuf field every time you enter a new routine that will
|
||||||
call a png_ function. See your documentation of setjmp/longjmp
|
call a png_ function. See your documentation of setjmp/longjmp
|
||||||
for your compiler for more information on setjmp/longjmp. See
|
for your compiler for more information on setjmp/longjmp. If you
|
||||||
the discussion on png error handling in the Customizing Libpng
|
don't want to use stderr for error output, or you want to use a
|
||||||
section below for more information on the png error handling.
|
method other than setjmp()/longjmp() to handle errors, see the
|
||||||
|
Customizing Libpng section below for more information on libpng
|
||||||
|
error handling.
|
||||||
|
|
||||||
if (setjmp(png_ptr->jmpbuf))
|
if (setjmp(png_ptr->jmpbuf))
|
||||||
{
|
{
|
||||||
@ -535,7 +555,7 @@ Now you need to set up the input code. The default for libpng is
|
|||||||
to use the C function fwrite(). If you use this, you will need to
|
to use the C function fwrite(). If you use this, you will need to
|
||||||
pass a valid FILE * in the function png_init_io(). Be sure that
|
pass a valid FILE * in the function png_init_io(). Be sure that
|
||||||
the file is opened in binary mode. If you wish to handle writing
|
the file is opened in binary mode. If you wish to handle writing
|
||||||
data in another way, see the discussion on png i/o handling in the
|
data in another way, see the discussion on PNG I/O handling in the
|
||||||
Customizing Libpng section below.
|
Customizing Libpng section below.
|
||||||
|
|
||||||
png_init_io(png_ptr, fp);
|
png_init_io(png_ptr, fp);
|
||||||
@ -543,7 +563,7 @@ Customizing Libpng section below.
|
|||||||
You now have the option of modifying how the compression library
|
You now have the option of modifying how the compression library
|
||||||
will run. The following functions are mainly for testing, but
|
will run. The following functions are mainly for testing, but
|
||||||
may be useful in certain special cases, like if you need to
|
may be useful in certain special cases, like if you need to
|
||||||
write png files extremely fast and are willing to give up some
|
write PNG files extremely fast and are willing to give up some
|
||||||
compression, or if you want to get the maximum possible compression
|
compression, or if you want to get the maximum possible compression
|
||||||
at the expense of slower writing. If you have no special needs
|
at the expense of slower writing. If you have no special needs
|
||||||
in this area, let the library do what it wants, as it has been
|
in this area, let the library do what it wants, as it has been
|
||||||
@ -553,12 +573,34 @@ See the compression library for more details.
|
|||||||
/* turn on or off filtering (1 or 0) */
|
/* turn on or off filtering (1 or 0) */
|
||||||
png_set_filtering(png_struct *png_ptr, 1);
|
png_set_filtering(png_struct *png_ptr, 1);
|
||||||
|
|
||||||
|
/* compression level (0 - none, 6 - default, 9 - maximum) */
|
||||||
png_set_compression_level(png_ptr, Z_DEFAULT_COMPRESSION);
|
png_set_compression_level(png_ptr, Z_DEFAULT_COMPRESSION);
|
||||||
png_set_compression_mem_level(png_ptr, 8);
|
png_set_compression_mem_level(png_ptr, 8);
|
||||||
png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY);
|
png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY);
|
||||||
png_set_compression_window_bits(png_ptr, 15);
|
png_set_compression_window_bits(png_ptr, 15);
|
||||||
png_set_compression_method(png_ptr, 8);
|
png_set_compression_method(png_ptr, 8);
|
||||||
|
|
||||||
|
It is possible to have libpng flush any pending output, either manually,
|
||||||
|
or automatically after a certain number of lines have been written. To
|
||||||
|
flush the output stream a single time call:
|
||||||
|
|
||||||
|
png_write_flush(png_ptr);
|
||||||
|
|
||||||
|
and to have libpng flush the output stream after a certain number of
|
||||||
|
scanlines have been written, call:
|
||||||
|
|
||||||
|
png_set_flush(png_ptr, nrows);
|
||||||
|
|
||||||
|
Note that the distance between rows is from the last time png_write_flush
|
||||||
|
was called, or the first row of the image if it has never been called.
|
||||||
|
So if you write 50 lines, and then png_set_flush 25, it will flush the
|
||||||
|
output on the next scanline, and on line 75, unless png_write_flush is
|
||||||
|
called earlier. If nrows is too small (less than about 10 lines) the
|
||||||
|
image compression may decrease dramatically (although this may be
|
||||||
|
acceptable for real-time applications). Infrequent flushing will only
|
||||||
|
degrade the compression performance by a few percent over images that
|
||||||
|
do not use flushing.
|
||||||
|
|
||||||
You now need to fill in the png_info structure with all the data
|
You now need to fill in the png_info structure with all the data
|
||||||
you wish to write before the actual image. Note that the only thing
|
you wish to write before the actual image. Note that the only thing
|
||||||
you are allowed to write after the image is the text chunks and the
|
you are allowed to write after the image is the text chunks and the
|
||||||
@ -581,7 +623,7 @@ parts of the png_info are:
|
|||||||
appropriate PNG_INFO_<chunk name> define.
|
appropriate PNG_INFO_<chunk name> define.
|
||||||
palette and num_palette - the palette for the file
|
palette and num_palette - the palette for the file
|
||||||
gamma - the gamma the file is written at
|
gamma - the gamma the file is written at
|
||||||
sig_bit and sig_bit_number - the number of significant bits
|
sig_bit - the number of significant bits for red, green, blue, grey, alpha
|
||||||
trans, trans_values, and number_trans - transparency info
|
trans, trans_values, and number_trans - transparency info
|
||||||
hist - histogram of palette
|
hist - histogram of palette
|
||||||
text and num_text - text comments in the file.
|
text and num_text - text comments in the file.
|
||||||
@ -614,13 +656,20 @@ you can leave off the text string on non-compressed pairs.
|
|||||||
Compressed pairs must have a text string, as only the text string
|
Compressed pairs must have a text string, as only the text string
|
||||||
is compressed anyway, so the compression would be meaningless.
|
is compressed anyway, so the compression would be meaningless.
|
||||||
|
|
||||||
PNG supports modification time via the png_time structure. Two
|
PNG supports MODIFICATION time via the png_time structure. Two
|
||||||
conversion routines are proved, png_convert_from_time_t() for
|
conversion routines are proved, png_convert_from_time_t() for
|
||||||
time_t and png_convert_from_struct_tm() for struct tm. The
|
time_t and png_convert_from_struct_tm() for struct tm. The
|
||||||
time_t routine uses gmtime(). You don't have to use either of
|
time_t routine uses gmtime(). You don't have to use either of
|
||||||
these, but if you wish to fill in the png_time structure directly,
|
these, but if you wish to fill in the png_time structure directly,
|
||||||
you should provide the time in universal time (GMT) if possible
|
you should provide the time in universal time (GMT) if possible
|
||||||
instead of your local time.
|
instead of your local time. Note that the year number is the full
|
||||||
|
year number (ie 1995 rather than 95).
|
||||||
|
|
||||||
|
Since the CREATION time of an image is somewhat ambiguous, it is not
|
||||||
|
sensible to store an exact time like the tIME chunk above (ie when was
|
||||||
|
a scanned photo of neanderthal art created?). However, a text chunk
|
||||||
|
with a "Created" keyword can hold this information, in a form which is
|
||||||
|
useful (ie "Painted circa 40000 BC, photographed 1971, scanned 1996").
|
||||||
|
|
||||||
You are now ready to write all the file information up to the actual
|
You are now ready to write all the file information up to the actual
|
||||||
image data. You do this with a call to png_write_info().
|
image data. You do this with a call to png_write_info().
|
||||||
@ -782,29 +831,43 @@ standard things like memory allocation, input/output, and error handling.
|
|||||||
The second deals with more complicated things like adding new chunks,
|
The second deals with more complicated things like adding new chunks,
|
||||||
adding new transformations, and generally changing how libpng works.
|
adding new transformations, and generally changing how libpng works.
|
||||||
|
|
||||||
All of the memory allocation, input/output, and error handling in libpng
|
All of the memory allocation in libpng is done in pngmem.c. Memory
|
||||||
goes through the routines in pngstub.c. The file as plenty of comments
|
allocation is done through the functions png_large_malloc(), png_malloc(),
|
||||||
describing each function and how it expects to work, so I will just
|
png_realloc(), png_large_free(), and png_free(). These currently just
|
||||||
summarize here. See pngstub.c for more details.
|
call the standard C functions. The large functions must handle at least
|
||||||
|
64K, but they don't have to handle more then that. If your pointers can't
|
||||||
|
access more then 64K at a time, you will want to set MAXSEG_64K in zlib.h.
|
||||||
|
|
||||||
Memory allocation is done through the functions png_large_malloc(),
|
Since it is unlikely that the method of handling memory allocation on a
|
||||||
png_malloc(), png_realloc(), png_large_free(), and png_free().
|
platform will change between applications, these functions must be modified
|
||||||
These currently just call the standard C functions. The large
|
or replaced to change their behaviour. If you only need to add new tests or
|
||||||
functions must handle exactly 64K, but they don't have to handle
|
flags to have the compiler choose the correct function calls, please forward
|
||||||
more then that. If your pointers can't access more then 64K at a
|
these changes to the libpng author, so they can be added into the library
|
||||||
time, you will want to set MAXSEG_64K in zlib.h.
|
for the benefit of others.
|
||||||
|
|
||||||
Input/Output in libpng is done throught png_read() and png_write(), which
|
All of the input/output, and error handling in libpng go through the
|
||||||
currently just call fread() and fwrite(). The FILE * is stored in
|
routines in pngio.c by default. The file has plenty of comments describing
|
||||||
png_struct, and is initialized via png_init_io(). If you wish to change
|
each function and how it expects to work. It is possible to supply different
|
||||||
this, make the appropriate changes in pngstub.c and png.h. Make sure you
|
I/O and error handling methods at run time with the png_set_msg_fn(),
|
||||||
change the function prototype for png_init_io() if you are no longer
|
png_set_read_fn(), and png_set_write_fn() calls.
|
||||||
using a FILE *.
|
|
||||||
|
|
||||||
Error handling in libpng is done through png_error() and png_warning().
|
Input/Output in libpng is done throught png_read_data() and png_write_data(),
|
||||||
Errors handled through png_error() are fatal, meaning that png_error()
|
which currently just call fread() and fwrite(). The error and warning
|
||||||
should never return to it's caller. Currently, this is handled via
|
functions png_error() and png_warning() use stderr to output any messages,
|
||||||
setjmp() and longjmp(), but you could change this to do things like
|
and png_error() uses longjmp to return from an error. These default
|
||||||
|
functions are set by via png_init_io().
|
||||||
|
|
||||||
|
If you wish to change some or all of these functions, it is possible to
|
||||||
|
do so at runtime, and without modifying the libpng library code. The
|
||||||
|
application must supply replacement functions which have the same arguments
|
||||||
|
and are functionally equivalent to the default functions. If you are
|
||||||
|
replacing both the I/O and message functions, the call to png_init_io()
|
||||||
|
is not needed.
|
||||||
|
|
||||||
|
Error handling in libpng is done through png_error() and png_warning() by
|
||||||
|
default. Errors handled through png_error() are fatal, meaning that
|
||||||
|
png_error() should never return to it's caller. Currently, this is handled
|
||||||
|
via setjmp() and longjmp(), but you could change this to do things like
|
||||||
exit() if you should wish. Similarly, both png_error() and png_warning()
|
exit() if you should wish. Similarly, both png_error() and png_warning()
|
||||||
print a message on stderr, but that can also be changed. The motivation
|
print a message on stderr, but that can also be changed. The motivation
|
||||||
behind using setjmp() and longjmp() is the C++ throw and catch exception
|
behind using setjmp() and longjmp() is the C++ throw and catch exception
|
||||||
@ -815,6 +878,71 @@ a longjmp, so the user may want to be careful about doing anything after
|
|||||||
setjmp returns non zero besides returning itself. Consult your compiler
|
setjmp returns non zero besides returning itself. Consult your compiler
|
||||||
documentation for more details.
|
documentation for more details.
|
||||||
|
|
||||||
|
The replacement message functions should have parameters as follows:
|
||||||
|
|
||||||
|
void user_error_fn(png_struct png_ptr, char *error_msg);
|
||||||
|
void user_warning_fn(png_struct png_ptr, char *warning_msg);
|
||||||
|
|
||||||
|
These functions can be attached to a PNG stream with a call
|
||||||
|
|
||||||
|
png_set_msg_fn(png_ptr, msg_ptr, user_error_fn, user_warning_fn);
|
||||||
|
|
||||||
|
If NULL is supplied for user_error_fn, then the error function will not
|
||||||
|
print any error messages, and will return via longjmp(png_ptr->jmpbuf,1) to
|
||||||
|
the last location setjmp(png_ptr->jmpbuf) was previously called. If NULL is
|
||||||
|
supplied for user_warning_fn then no warning messages will be printed.
|
||||||
|
|
||||||
|
In order to make it possible to have multiple PNG files open at the same
|
||||||
|
time, the replacement message functions should not modify any global
|
||||||
|
variables. In order to have any message information available to the
|
||||||
|
libpng streams, there is a pointer available to for a user variable or
|
||||||
|
structure. If more than one variable or structure of needs to be kept
|
||||||
|
with each stream, then you must create a structure which holds all the
|
||||||
|
relevant data. The pointer to this data is set in the initial png_set_msg_fn
|
||||||
|
call, and can be accessed with:
|
||||||
|
|
||||||
|
msg_ptr = (user_msg_type *)png_get_msg_ptr(png_ptr);
|
||||||
|
|
||||||
|
The replacement I/O functions should have prototypes as follows:
|
||||||
|
|
||||||
|
void user_read_data(png_struct *png_ptr,png_bytef *data,png_uint_32 length);
|
||||||
|
void user_write_data(png_struct *png_ptr,png_bytef *data,png_uint_32 length);
|
||||||
|
|
||||||
|
where the routine will read or write "length" bytes into or out of "data".
|
||||||
|
If the routines are unable to read or write the correct number of bytes, they
|
||||||
|
should call (*(png_ptr->error_fn))(png_ptr, "Error message"); to abort.
|
||||||
|
|
||||||
|
void user_output_flush(png_struct *png_ptr);
|
||||||
|
|
||||||
|
will flush any data from the buffer used by the output device. Note that
|
||||||
|
the flush function is purely to output any data being stored by the write
|
||||||
|
function, and has no control over any data buffered inside the compressor.
|
||||||
|
|
||||||
|
These functions can be attached to a PNG stream by calling one of
|
||||||
|
|
||||||
|
png_set_read_fn(png_ptr, io_ptr, user_read_data);
|
||||||
|
png_set_write_fn(png_ptr, io_ptr, user_write_data, user_output_flush);
|
||||||
|
|
||||||
|
You should only call one of these two functions for a single PNG stream.
|
||||||
|
It is a fatal error to read from a write stream, and vice-versa. If the
|
||||||
|
output method you are using does not buffer any data, or you have chosen
|
||||||
|
not to compile libpng with PNG_WRITE_FLUSH_SUPPORTED, NULL may be supplied
|
||||||
|
instead of a function name for user_output_flush, and an empty function will
|
||||||
|
be used. Note that even if the output method being used does not buffer
|
||||||
|
output, during compression data is buffered by the compressor. If an
|
||||||
|
application wants to guarantee that all pending output data has been written,
|
||||||
|
it should call png_write_flush, which will flush the compression buffers,
|
||||||
|
and in turn call the user_output_flush function.
|
||||||
|
|
||||||
|
As with the message functions, the replacement I/O functions should not
|
||||||
|
modify any global variables. Therse is a separate pointer available to for
|
||||||
|
an I/O variable or structure. If more than one variable or structure of
|
||||||
|
needs to be kept with each stream, then you must create a structure which
|
||||||
|
holds all the relevant data. The pointer to this data is set in the initial
|
||||||
|
set_xxx_fn call, and can be accessed with:
|
||||||
|
|
||||||
|
io_ptr = (user_io_type *)png_get_io_ptr(png_ptr);
|
||||||
|
|
||||||
If you need to read or write custom chunks, you will need to get deeper
|
If you need to read or write custom chunks, you will need to get deeper
|
||||||
into the libpng code. First, read the PNG specification, and have
|
into the libpng code. First, read the PNG specification, and have
|
||||||
a first level of understanding of how it works. Pay particular
|
a first level of understanding of how it works. Pay particular
|
||||||
@ -822,7 +950,9 @@ attention to the sections that describe chunk names, and look
|
|||||||
at how other chunks were designed, so you can do things similar.
|
at how other chunks were designed, so you can do things similar.
|
||||||
Second, check out the sections of libpng that read and write chunks.
|
Second, check out the sections of libpng that read and write chunks.
|
||||||
Try to find a chunk that is similar to yours, and copy off of it.
|
Try to find a chunk that is similar to yours, and copy off of it.
|
||||||
More details can be found in the comments inside the code.
|
More details can be found in the comments inside the code. If you are
|
||||||
|
truly ambitious, you can modify the libpng code to handle unknown chunks
|
||||||
|
in a general way and send the code to the libpng author.
|
||||||
|
|
||||||
If you wish to write your own transformation for the data, look
|
If you wish to write your own transformation for the data, look
|
||||||
through the part of the code that does the transformations, and check
|
through the part of the code that does the transformations, and check
|
||||||
@ -833,8 +963,8 @@ itself.
|
|||||||
|
|
||||||
Configuring for 16 bit platforms:
|
Configuring for 16 bit platforms:
|
||||||
|
|
||||||
You will probably need to change the png__large_malloc() and
|
You will probably need to change the png_large_malloc() and
|
||||||
png_large_free() routines in pngstub.c, as these are requred
|
png_large_free() routines in pngmem.c, as these are required
|
||||||
to allocate 64K. Also, you will want to look into zconf.h to tell
|
to allocate 64K. Also, you will want to look into zconf.h to tell
|
||||||
zlib (and thus libpng) that it cannot allocate more then 64K at a
|
zlib (and thus libpng) that it cannot allocate more then 64K at a
|
||||||
time. Even if you can, the memory won't be accessable. So limit zlib
|
time. Even if you can, the memory won't be accessable. So limit zlib
|
||||||
@ -842,11 +972,12 @@ and libpng to 64K by defining MAXSEG_64K.
|
|||||||
|
|
||||||
Configuring for gui/windowing platforms:
|
Configuring for gui/windowing platforms:
|
||||||
|
|
||||||
You will need to change the error message display in png_error() and
|
You will need to supply new message display functions for png_error() and
|
||||||
png_warning() to display a message instead of fprinting it to stderr.
|
png_warning() (through png_set_message_fn() to display a message in a window
|
||||||
You may want to write a single function to do this and call it something
|
instead of fprinting it to stderr. You may want to write a single function
|
||||||
like png_message(). On some compliers, you may have to change the
|
to do this and call it something like png_message() (although the error
|
||||||
memory allocators (png_malloc, etc.).
|
function should still call longjmp or otherwise handle the error without
|
||||||
|
returning).
|
||||||
|
|
||||||
Configuring for compiler xxx:
|
Configuring for compiler xxx:
|
||||||
|
|
||||||
@ -858,9 +989,9 @@ files in libpng proper only include png.h.
|
|||||||
|
|
||||||
Removing unwanted object code:
|
Removing unwanted object code:
|
||||||
|
|
||||||
There are a bunch of #define's in png.h that control what parts of
|
There are a bunch of #define's in pngconf.h that control what parts of
|
||||||
libpng are compiled. All the defines end in _SUPPORT. If you are
|
libpng are compiled. All the defines end in _SUPPORT. If you are
|
||||||
not using an ability, you can change the #define to #undef and
|
never going to use an ability, you can change the #define to #undef and
|
||||||
save yourself code and data space. All the reading and writing
|
save yourself code and data space. All the reading and writing
|
||||||
specific code are in seperate files, so the linker should only grab
|
specific code are in seperate files, so the linker should only grab
|
||||||
the files it needs. However, if you want to make sure, or if you
|
the files it needs. However, if you want to make sure, or if you
|
||||||
@ -868,4 +999,3 @@ are building a stand alone library, all the reading files start with
|
|||||||
pngr and all the writing files start with pngw. The files that
|
pngr and all the writing files start with pngw. The files that
|
||||||
don't match either (like png.c, pngtrans.c, etc.) are used for
|
don't match either (like png.c, pngtrans.c, etc.) are used for
|
||||||
both reading and writing, and always need to be included.
|
both reading and writing, and always need to be included.
|
||||||
|
|
||||||
|
190
lpfaq.txt
Normal file
190
lpfaq.txt
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
libpng FAQ - August 20, 1995
|
||||||
|
|
||||||
|
Maintainer:
|
||||||
|
|
||||||
|
Guy Eric Schalnat: schalnat@group42.com CompuServe: 75501,1625
|
||||||
|
|
||||||
|
|
||||||
|
Contents:
|
||||||
|
|
||||||
|
1) General Questions
|
||||||
|
1.1) How official is this FAQ?
|
||||||
|
1.2) How often is this FAQ posted?
|
||||||
|
1.3) Where can I get this FAQ, libpng, zlib, the PNG
|
||||||
|
specification, test images, etc.?
|
||||||
|
1.4) How ready is libpng?
|
||||||
|
1.5) How portable is libpng?
|
||||||
|
1.6) When will libpng be out of Beta?
|
||||||
|
1.7) What remains to be done in libpng for the 1.0 release?
|
||||||
|
1.8) Can I help?
|
||||||
|
1.9) Why don't you answer your mail?
|
||||||
|
|
||||||
|
2) Libpng questions
|
||||||
|
2.1) Does the order of functions calls matter?
|
||||||
|
2.2) When I try to read/write a png image, it doesn't work.
|
||||||
|
2.3) Do I have to start with example.c?
|
||||||
|
2.4) What things should I be careful of?
|
||||||
|
2.5) Why doesn't example.c compile?
|
||||||
|
|
||||||
|
3) Critical Patches
|
||||||
|
No known bugs (for now :-).
|
||||||
|
|
||||||
|
4) Non-critical patches
|
||||||
|
No known bugs (for now :-).
|
||||||
|
|
||||||
|
|
||||||
|
Questions:
|
||||||
|
|
||||||
|
1) General Questions
|
||||||
|
|
||||||
|
1.1) How official is this FAQ?
|
||||||
|
|
||||||
|
As it was written by the author of libpng (that's me :), it's
|
||||||
|
about offical as one can get. However, it is not ready for
|
||||||
|
prime time yet, as libpng is still in beta, and thus its
|
||||||
|
users are of the sort that are willing to deal with beta
|
||||||
|
software. Thus, I assume all of you reading this have a
|
||||||
|
basic familiarity with PNG, libpng, and C programming. I'll
|
||||||
|
write a basic section for libpng later, as well as some quick
|
||||||
|
stuff on PNG itself (but this will not be the PNG FAQ. I just
|
||||||
|
don't have that kind of time).
|
||||||
|
|
||||||
|
1.2) How often is this FAQ posted?
|
||||||
|
|
||||||
|
As often as events warrant. I doubt it'll get stale, and as
|
||||||
|
it is not (and may never be) actually posted to a newsgroup,
|
||||||
|
I feel no need to make monthy postings.
|
||||||
|
|
||||||
|
1.3) Where can I get this FAQ, libpng, zlib, the PNG
|
||||||
|
specification, test images, etc.?
|
||||||
|
|
||||||
|
Everything should be at ftp://ftp.uu.net/graphics/png and
|
||||||
|
mirror sites. On CompuServe, it should be at GO GRAPHSUPPORT
|
||||||
|
in the Png Development library (lib 20). Failing that, try
|
||||||
|
my ftp site at ftp://ftp.group42.com/pub/png or web site at
|
||||||
|
http://www.group42.com/ If you have trouble getting to these,
|
||||||
|
the numerical address is 204.94.158.25
|
||||||
|
|
||||||
|
1.4) How ready is libpng?
|
||||||
|
|
||||||
|
In its current incarnation (0.8), it still may have a few bugs.
|
||||||
|
I think I got all of the bugs this time, but one never knows.
|
||||||
|
Also, the dithering currently in libpng is horrid, so that
|
||||||
|
needs work. Finally, I have yet to implement medium model
|
||||||
|
support.
|
||||||
|
|
||||||
|
1.5) How portable is libpng?
|
||||||
|
|
||||||
|
As portable as I can make it. It needs int's of at least
|
||||||
|
16 bits, and longs of at least 32 bits. It has not been
|
||||||
|
tried for char's larger then 8 bits. It should support
|
||||||
|
any reasonable K&R C compiler, as well as any ANSI C
|
||||||
|
compiler. The most you should need to do is change the
|
||||||
|
includes in pngconf.h. So far, I know of no compiler in use
|
||||||
|
that libpng will not compile on.
|
||||||
|
|
||||||
|
1.6) When will libpng be out of Beta?
|
||||||
|
|
||||||
|
That depends on my workload here. I'm writing libpng for
|
||||||
|
free, which generates tons of good will, but doesn't help
|
||||||
|
put food on the table, so there are times I just can't do
|
||||||
|
any real work on it. There is still some work to be done
|
||||||
|
(see question 1.7), so don't expect the official version
|
||||||
|
before September (and that may be pushing it). I'll try
|
||||||
|
to get the next (last?) beta version out my early
|
||||||
|
September. Be warned, I always seem to take twice as
|
||||||
|
long as I think I will.
|
||||||
|
|
||||||
|
1.7) What remains to be done in libpng for the 1.0 release?
|
||||||
|
|
||||||
|
Add Tim Wegner's medium memory model support. (Thanks, Tim).
|
||||||
|
Improve the dithering.
|
||||||
|
Rewrite libpng.txt, and comment the code better.
|
||||||
|
Test with a final zlib.
|
||||||
|
|
||||||
|
1.8) Can I help?
|
||||||
|
|
||||||
|
Sweet words. The most helpful thing you can do for the
|
||||||
|
1.0 release is help testing on your compiler. After this
|
||||||
|
release, though, there is a large list of things that ought
|
||||||
|
to be done to make libpng be more full featured. We'll
|
||||||
|
talk about this later, as I don't want to add tons of new
|
||||||
|
code until after 1.0 gets out the door. Please send me
|
||||||
|
any makefile changes and/or other changes needed to support
|
||||||
|
your compiler (with a #ifdef for the code changes).
|
||||||
|
|
||||||
|
If any of you are good at technical writing, take a look at
|
||||||
|
libpng.txt and correct it (or rewrite it) as necessary. I
|
||||||
|
am not a writer, I'm a programmer. It shows.
|
||||||
|
|
||||||
|
1.9) Why don't you answer your mail?
|
||||||
|
|
||||||
|
I've been busy. I'm sorry about that, and I've got to get
|
||||||
|
into the habit of at least replying that I got the message.
|
||||||
|
Also, some of you have sent me problems that I haven't gotten
|
||||||
|
back to you yet. If it is still a problem, you may want to
|
||||||
|
give me a short message and remind me that I need to look into
|
||||||
|
it. Libpng is being tested by more people than I dared hope
|
||||||
|
(which is a good thing), and I was unprepared to deal with so
|
||||||
|
many problems so soon.
|
||||||
|
|
||||||
|
|
||||||
|
2) Libpng questions
|
||||||
|
|
||||||
|
2.1) Does the order of functions calls matter?
|
||||||
|
|
||||||
|
In general, yes. If you stick with the order I used in libpng.txt
|
||||||
|
and example.c, you should be safe. Be warned, however, that I
|
||||||
|
messed up the order of png_set_interlace_handling(). It needs
|
||||||
|
to be called *before* png_start_read_image(), not after. Oops.
|
||||||
|
The exceptions to this rule are all the png_set ... calls.
|
||||||
|
They can be done in any order, but they all have to be done
|
||||||
|
in the area indicated by libpng.txt/example.c.
|
||||||
|
|
||||||
|
2.2) When I try to read/write a png image, it doesn't work.
|
||||||
|
|
||||||
|
Does zlib's test program work (example.c)? Does libpng's test
|
||||||
|
program work (testpng.c)? Have you installed the patches at
|
||||||
|
the end of this FAQ? After all that, if the problem continues,
|
||||||
|
e-mail me, and we'll try to fix it. If you don't have much
|
||||||
|
programming experience, be patient about the fix. Code
|
||||||
|
fragments help, as do *small* images (uuencoded please). If
|
||||||
|
I don't get back to you right away, give me some time. Thanks.
|
||||||
|
|
||||||
|
2.3) Do I have to start with example.c?
|
||||||
|
|
||||||
|
No, but most people have had much better luck doing that. Seems
|
||||||
|
I didn't explain things well in libpng.txt, so things are not
|
||||||
|
intuitive to people (which could be an api design problem also).
|
||||||
|
Sometime in the future, we'll revisit the api design, and try
|
||||||
|
to make it easier to use. I'll rewrite libpng.txt before the
|
||||||
|
1.0 release.
|
||||||
|
|
||||||
|
2.4) What things should I be careful of?
|
||||||
|
|
||||||
|
The main gotcha is calling png_read_init() before png_info_init().
|
||||||
|
Also, always make sure you have a correct setjmp buffer. That's
|
||||||
|
all I can think of for now.
|
||||||
|
|
||||||
|
2.5) Why doesn't example.c compile?
|
||||||
|
|
||||||
|
I wrote example.c as a staring point for using libpng. It doesn't
|
||||||
|
compile because I don't know how you want to do things like allocating
|
||||||
|
memory to hold the image, so I left that code out. If you go in and
|
||||||
|
finish it up, it should work fine. The file pngtest.c gives a
|
||||||
|
very simple example of reading and writing png files.
|
||||||
|
|
||||||
|
|
||||||
|
3) Critical Patches
|
||||||
|
|
||||||
|
No known bugs (for now :-).
|
||||||
|
|
||||||
|
|
||||||
|
4) Non-critical patches
|
||||||
|
|
||||||
|
No known bugs (for now :-).
|
||||||
|
|
||||||
|
|
||||||
|
That's it so far as I know. If I missed something, yell.
|
||||||
|
|
||||||
|
-Guy
|
14
makefile
14
makefile
@ -2,25 +2,26 @@
|
|||||||
# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
|
# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
|
||||||
# For conditions of distribution and use, see copyright notice in png.h
|
# For conditions of distribution and use, see copyright notice in png.h
|
||||||
|
|
||||||
CC=cc
|
CC=gcc
|
||||||
CFLAGS=-I../zlib -O
|
CFLAGS=-I../zlib -O2 -Wall -ansi -pedantic
|
||||||
LDFLAGS=-L. -L../zlib/ -lpng -lz -lm
|
LDFLAGS=-L. -L../zlib/ -lpng -lz -lm
|
||||||
|
|
||||||
#RANLIB=ranlib
|
RANLIB=ranlib
|
||||||
RANLIB=echo
|
#RANLIB=echo
|
||||||
|
|
||||||
# where make install puts libpng.a and png.h
|
# where make install puts libpng.a and png.h
|
||||||
prefix=/usr/local
|
prefix=/home/munet-d2/sun/local
|
||||||
|
|
||||||
OBJS = png.o pngrcb.o pngrutil.o pngtrans.o pngwutil.o \
|
OBJS = png.o pngrcb.o pngrutil.o pngtrans.o pngwutil.o \
|
||||||
pngread.o pngio.o pngwrite.o pngrtran.o pngwtran.o \
|
pngread.o pngio.o pngwrite.o pngrtran.o pngwtran.o \
|
||||||
pngmem.o pngerror.o
|
pngmem.o
|
||||||
|
|
||||||
all: libpng.a pngtest
|
all: libpng.a pngtest
|
||||||
|
|
||||||
libpng.a: $(OBJS)
|
libpng.a: $(OBJS)
|
||||||
ar rc $@ $(OBJS)
|
ar rc $@ $(OBJS)
|
||||||
$(RANLIB) $@
|
$(RANLIB) $@
|
||||||
|
rcp libpng.a vlsi:bin/lib/libpng.a
|
||||||
|
|
||||||
pngtest: pngtest.o libpng.a
|
pngtest: pngtest.o libpng.a
|
||||||
$(CC) -o pngtest $(CCFLAGS) pngtest.o $(LDFLAGS)
|
$(CC) -o pngtest $(CCFLAGS) pngtest.o $(LDFLAGS)
|
||||||
@ -44,7 +45,6 @@ clean:
|
|||||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||||
|
|
||||||
png.o: png.h pngconf.h
|
png.o: png.h pngconf.h
|
||||||
pngerror.o: png.h pngconf.h
|
|
||||||
pngio.o: png.h pngconf.h
|
pngio.o: png.h pngconf.h
|
||||||
pngmem.o: png.h pngconf.h
|
pngmem.o: png.h pngconf.h
|
||||||
pngrcb.o: png.h pngconf.h
|
pngrcb.o: png.h pngconf.h
|
||||||
|
98
png.h
98
png.h
@ -267,7 +267,19 @@ typedef struct png_row_info_struct
|
|||||||
The only people who need to care about what is inside of this are the
|
The only people who need to care about what is inside of this are the
|
||||||
people who will be modifying the library for their own special needs.
|
people who will be modifying the library for their own special needs.
|
||||||
*/
|
*/
|
||||||
typedef struct png_struct_def
|
typedef struct png_struct_def png_struct;
|
||||||
|
typedef png_struct FAR png_structf;
|
||||||
|
|
||||||
|
/* These are the function types for the I/O functions, and the functions which
|
||||||
|
* modify the default I/O functions to user I/O functions. The png_msg_ptr
|
||||||
|
* type should match that of user supplied warning and error functions, while
|
||||||
|
* the png_rw_ptr type should match that of the user read/write data functions.
|
||||||
|
*/
|
||||||
|
typedef void (*png_msg_ptr) PNGARG((png_struct *, char *));
|
||||||
|
typedef void (*png_rw_ptr) PNGARG((png_struct *, png_bytef *, png_uint_32));
|
||||||
|
typedef void (*png_flush_ptr) PNGARG((png_struct *));
|
||||||
|
|
||||||
|
struct png_struct_def
|
||||||
{
|
{
|
||||||
jmp_buf jmpbuf; /* used in png_error */
|
jmp_buf jmpbuf; /* used in png_error */
|
||||||
png_byte mode; /* used to determine where we are in the png file */
|
png_byte mode; /* used to determine where we are in the png file */
|
||||||
@ -314,6 +326,10 @@ typedef struct png_struct_def
|
|||||||
png_uint_32 width; /* width of file */
|
png_uint_32 width; /* width of file */
|
||||||
png_uint_32 height; /* height of file */
|
png_uint_32 height; /* height of file */
|
||||||
png_uint_32 num_rows; /* number of rows in current pass */
|
png_uint_32 num_rows; /* number of rows in current pass */
|
||||||
|
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
|
||||||
|
png_uint_32 flush_dist; /* how many rows apart to flush, 0 for no flush */
|
||||||
|
png_uint_32 flush_rows; /* number of rows written since last flush */
|
||||||
|
#endif /* PNG_WRITE_FLUSH_SUPPORTED */
|
||||||
png_uint_32 rowbytes; /* size of row in bytes */
|
png_uint_32 rowbytes; /* size of row in bytes */
|
||||||
png_uint_32 usr_width; /* width of row at start of write */
|
png_uint_32 usr_width; /* width of row at start of write */
|
||||||
png_uint_32 iwidth; /* interlaced width */
|
png_uint_32 iwidth; /* interlaced width */
|
||||||
@ -322,13 +338,14 @@ typedef struct png_struct_def
|
|||||||
png_uint_32 idat_size; /* current idat size for read */
|
png_uint_32 idat_size; /* current idat size for read */
|
||||||
png_uint_32 zbuf_size; /* size of zbuf */
|
png_uint_32 zbuf_size; /* size of zbuf */
|
||||||
png_color *palette; /* files palette */
|
png_color *palette; /* files palette */
|
||||||
|
png_uint_32 do_free; /* flags indicating if libpng should free memory */
|
||||||
#if defined(PNG_READ_DITHER_SUPPORTED)
|
#if defined(PNG_READ_DITHER_SUPPORTED)
|
||||||
png_bytef *palette_lookup; /* lookup table for dithering */
|
png_bytef *palette_lookup; /* lookup table for dithering */
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
|
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
|
||||||
png_byte *gamma_table; /* gamma table for 8 bit depth files */
|
png_byte *gamma_table; /* gamma table for 8 bit depth files */
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
|
#if defined(PNG_READ_GAMMA_SUPPORTED)
|
||||||
png_byte *gamma_from_1; /* converts from 1.0 to screen */
|
png_byte *gamma_from_1; /* converts from 1.0 to screen */
|
||||||
png_byte *gamma_to_1; /* converts from file to 1.0 */
|
png_byte *gamma_to_1; /* converts from file to 1.0 */
|
||||||
#endif
|
#endif
|
||||||
@ -363,7 +380,7 @@ typedef struct png_struct_def
|
|||||||
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
|
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
|
||||||
png_color_8 shift; /* shift for significant bit tranformation */
|
png_color_8 shift; /* shift for significant bit tranformation */
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_GAMMA_SUPPORTED)
|
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined (PNG_READ_sBIT_SUPPORTED)
|
||||||
png_color_8 sig_bit; /* significant bits in file */
|
png_color_8 sig_bit; /* significant bits in file */
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
|
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
|
||||||
@ -375,10 +392,17 @@ typedef struct png_struct_def
|
|||||||
#endif
|
#endif
|
||||||
png_row_info row_info; /* used for transformation routines */
|
png_row_info row_info; /* used for transformation routines */
|
||||||
z_stream zstream_struct; /* decompression structure */
|
z_stream zstream_struct; /* decompression structure */
|
||||||
FILE *fp; /* used for png_read and png_write */
|
FILE *fp; /* used for default png_read and png_write */
|
||||||
} png_struct;
|
png_msg_ptr error_fn; /* Function for printing errors and aborting */
|
||||||
|
png_msg_ptr warning_fn; /* Function for printing warnings */
|
||||||
typedef png_struct FAR png_structf;
|
png_rw_ptr write_data_fn; /* Function for writing output data */
|
||||||
|
png_rw_ptr read_data_fn; /* Function for reading input data */
|
||||||
|
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
|
||||||
|
png_flush_ptr output_flush_fn;/* Function for flushing output */
|
||||||
|
#endif /* PNG_WRITE_FLUSH_SUPPORTED */
|
||||||
|
void *io_ptr; /* Pointer to user supplied struct for I/O functions */
|
||||||
|
void *msg_ptr; /* Pointer to user supplied struct for message functions */
|
||||||
|
};
|
||||||
|
|
||||||
/* Here are the function definitions most commonly used. This is not
|
/* Here are the function definitions most commonly used. This is not
|
||||||
the place to find out how to use libpng. See libpng.txt for the
|
the place to find out how to use libpng. See libpng.txt for the
|
||||||
@ -403,7 +427,7 @@ extern void png_write_info PNGARG((png_struct *png_ptr, png_info *info));
|
|||||||
/* read the information before the actual image data. */
|
/* read the information before the actual image data. */
|
||||||
extern void png_read_info PNGARG((png_struct *png_ptr, png_info *info));
|
extern void png_read_info PNGARG((png_struct *png_ptr, png_info *info));
|
||||||
|
|
||||||
#if defined(PNG_READ_tIME_SUPPORTED)
|
#if defined(PNG_WRITE_tIME_SUPPORTED)
|
||||||
/* convert from a struct tm to png_time */
|
/* convert from a struct tm to png_time */
|
||||||
extern void png_convert_from_struct_tm PNGARG((png_time *ptime,
|
extern void png_convert_from_struct_tm PNGARG((png_time *ptime,
|
||||||
struct tm *ttime));
|
struct tm *ttime));
|
||||||
@ -500,6 +524,14 @@ extern void png_set_gamma PNGARG((png_struct *png_ptr, double screen_gamma,
|
|||||||
double default_file_gamma));
|
double default_file_gamma));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
|
||||||
|
/* Set how many lines between output flushes - 0 for no flushing */
|
||||||
|
extern void png_set_flush PNGARG((png_struct *png_ptr, int nrows));
|
||||||
|
|
||||||
|
/* Flush the current PNG output buffer */
|
||||||
|
extern void png_write_flush PNGARG((png_struct *png_ptr));
|
||||||
|
#endif /* PNG_WRITE_FLUSH_SUPPORTED */
|
||||||
|
|
||||||
/* optional update palette with requested transformations */
|
/* optional update palette with requested transformations */
|
||||||
extern void png_start_read_image PNGARG((png_struct *png_ptr));
|
extern void png_start_read_image PNGARG((png_struct *png_ptr));
|
||||||
|
|
||||||
@ -570,21 +602,8 @@ extern void png_set_compression_window_bits PNGARG((png_struct *png_ptr,
|
|||||||
extern void png_set_compression_method PNGARG((png_struct *png_ptr,
|
extern void png_set_compression_method PNGARG((png_struct *png_ptr,
|
||||||
int method));
|
int method));
|
||||||
|
|
||||||
/* These next functions are stubs of typical c functions for input/output,
|
/* These next functions are prototypes of the functions libpng uses for
|
||||||
memory, and error handling. They are in the file pngstub.c, and are
|
memory allocation. */
|
||||||
set up to be easily modified for users that need to. See the file
|
|
||||||
pngstub.c for more information */
|
|
||||||
|
|
||||||
/* Write the data to whatever output you are using. */
|
|
||||||
extern void png_write_data PNGARG((png_struct *png_ptr, png_bytef *data,
|
|
||||||
png_uint_32 length));
|
|
||||||
|
|
||||||
/* Read data from whatever input you are using */
|
|
||||||
extern void png_read_data PNGARG((png_struct *png_ptr, png_bytef *data,
|
|
||||||
png_uint_32 length));
|
|
||||||
|
|
||||||
/* Initialize the input/output for the png file. */
|
|
||||||
extern void png_init_io PNGARG((png_struct *png_ptr, FILE *fp));
|
|
||||||
|
|
||||||
/* Allocate memory in larger chunks. */
|
/* Allocate memory in larger chunks. */
|
||||||
extern voidpf png_large_malloc PNGARG((png_structf *png_ptr, png_uint_32 size));
|
extern voidpf png_large_malloc PNGARG((png_structf *png_ptr, png_uint_32 size));
|
||||||
@ -602,12 +621,32 @@ extern void *png_realloc PNGARG((png_struct *png_ptr, void *ptr,
|
|||||||
/* free's a pointer allocated by png_malloc() */
|
/* free's a pointer allocated by png_malloc() */
|
||||||
extern void png_free PNGARG((png_struct *png_ptr, void *ptr));
|
extern void png_free PNGARG((png_struct *png_ptr, void *ptr));
|
||||||
|
|
||||||
/* Fatal error in libpng - can't continue */
|
/* Initialize the I/O and message handling for the png file to the defaults. */
|
||||||
extern void png_error PNGARG((png_structf *png_ptr, char *error));
|
extern void png_init_io PNGARG((png_struct *png_ptr, FILE *fp));
|
||||||
|
|
||||||
/* Non-fatal error in libpng. Can continue, but may have a problem. */
|
/* Replace the error message and abort, and warning functions with user
|
||||||
extern void png_warning PNGARG((png_struct *png_ptr, char *message));
|
supplied functions. If no messages are to be printed, NULL can be
|
||||||
|
supplied for error_fn and warning_fn, although error_fn will still do
|
||||||
|
a longjmp to the last setjmp location. */
|
||||||
|
extern void png_set_msg_fn PNGARG((png_struct *png_ptr, void *msg_ptr,
|
||||||
|
png_msg_ptr error_fn, png_msg_ptr warning_fn));
|
||||||
|
|
||||||
|
/* Return the user pointer associated with the message functions */
|
||||||
|
extern void *png_get_msg_ptr PNGARG((png_struct *png_ptr));
|
||||||
|
|
||||||
|
/* Replace the default data output functions with a user supplied one(s).
|
||||||
|
If buffered output is not used, then output_flush_fn can be set to NULL.
|
||||||
|
if PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time
|
||||||
|
output_flush_fn will be ignored (but must be supplied for compatability). */
|
||||||
|
extern void png_set_write_fn PNGARG((png_struct *png_ptr, void *io_ptr,
|
||||||
|
png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn));
|
||||||
|
|
||||||
|
/* Replace the default data input function with a user supplied one. */
|
||||||
|
extern void png_set_read_fn PNGARG((png_struct *png_ptr, void *io_ptr,
|
||||||
|
png_rw_ptr read_data_fn));
|
||||||
|
|
||||||
|
/* Return the user pointer associated with the I/O functions */
|
||||||
|
extern void *png_get_io_ptr PNGARG((png_struct *png_ptr));
|
||||||
|
|
||||||
/* These next functions are used internally in the code. If you use
|
/* These next functions are used internally in the code. If you use
|
||||||
them, make sure you read and understand the png spec. More information
|
them, make sure you read and understand the png spec. More information
|
||||||
@ -646,6 +685,11 @@ extern void png_warning PNGARG((png_struct *png_ptr, char *message));
|
|||||||
#define PNG_GRAY_TO_RGB 0x2000
|
#define PNG_GRAY_TO_RGB 0x2000
|
||||||
#define PNG_FILLER 0x4000
|
#define PNG_FILLER 0x4000
|
||||||
|
|
||||||
|
/* defines for memory alloced by libpng which should be freed */
|
||||||
|
#define PNG_FREE_TRANS 0x0001
|
||||||
|
#define PNG_FREE_HIST 0x0002
|
||||||
|
#define PNG_FREE_PALETTE 0x0004
|
||||||
|
|
||||||
/* save typing and make code easier to understand */
|
/* save typing and make code easier to understand */
|
||||||
#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
|
#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
|
||||||
abs((int)((c1).green) - (int)((c2).green)) + \
|
abs((int)((c1).green) - (int)((c2).green)) + \
|
||||||
|
10
pngchang.txt
10
pngchang.txt
@ -55,6 +55,16 @@ version 0.8
|
|||||||
put all the configurable stuff in pngconf.h
|
put all the configurable stuff in pngconf.h
|
||||||
enabled png_set_shift to work with paletted images on read
|
enabled png_set_shift to work with paletted images on read
|
||||||
added png_read_update_info() - updates info structure with transformations
|
added png_read_update_info() - updates info structure with transformations
|
||||||
|
version 0.81
|
||||||
|
added support for medium memory model
|
||||||
|
version 0.82
|
||||||
|
added ability to flush output stream automatically or manually
|
||||||
|
added ability to change I/O and error functions dynamically
|
||||||
|
moved pngerror.c into pngio.c to make all the default functions static
|
||||||
|
when freeing memory in png_read_destroy don't free memory we didn't allocate
|
||||||
|
added warnings when reading blocks of incorrect length
|
||||||
|
limit tEXt and zTXt keywords to 80 chars
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
Unless this gets smaller then the size of a row (compressed),
|
Unless this gets smaller then the size of a row (compressed),
|
||||||
it should not make much difference how big this is. */
|
it should not make much difference how big this is. */
|
||||||
|
|
||||||
#define PNG_ZBUF_SIZE 8192
|
#define PNG_ZBUF_SIZE 32768
|
||||||
|
|
||||||
/* While libpng currently uses zlib for it's compression, it has been designed
|
/* While libpng currently uses zlib for it's compression, it has been designed
|
||||||
to stand on it's own. Towards this end, there are two defines that are
|
to stand on it's own. Towards this end, there are two defines that are
|
||||||
@ -166,6 +166,7 @@
|
|||||||
#define PNG_WRITE_SWAP_SUPPORTED
|
#define PNG_WRITE_SWAP_SUPPORTED
|
||||||
#define PNG_WRITE_INVERT_SUPPORTED
|
#define PNG_WRITE_INVERT_SUPPORTED
|
||||||
#define PNG_WRITE_FILLER_SUPPORTED
|
#define PNG_WRITE_FILLER_SUPPORTED
|
||||||
|
#define PNG_WRITE_FLUSH_SUPPORTED
|
||||||
|
|
||||||
/* any chunks you are not interested in, you can undef here. The
|
/* any chunks you are not interested in, you can undef here. The
|
||||||
ones that allocate memory may be expecially important (hIST,
|
ones that allocate memory may be expecially important (hIST,
|
||||||
|
46
pngerror.c
46
pngerror.c
@ -1,46 +0,0 @@
|
|||||||
|
|
||||||
/* pngstub.c - stub functions for i/o and memory allocation
|
|
||||||
|
|
||||||
libpng 1.0 beta 2 - version 0.81
|
|
||||||
For conditions of distribution and use, see copyright notice in png.h
|
|
||||||
Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc.
|
|
||||||
August 24, 1995
|
|
||||||
|
|
||||||
This file provides a location for all error handling. Users which
|
|
||||||
need special error handling are expected to modify the code in this
|
|
||||||
file to meet their needs. See the instructions at each function. */
|
|
||||||
|
|
||||||
#define PNG_INTERNAL
|
|
||||||
#include "png.h"
|
|
||||||
|
|
||||||
/* This function is called whenever there is an error. Replace with
|
|
||||||
however you wish to handle the error. Note that this function
|
|
||||||
MUST NOT return, or the program will crash */
|
|
||||||
void
|
|
||||||
png_error(png_structf *png_ptr, char *message)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "libpng error: %s\n", message);
|
|
||||||
#ifdef USE_FAR_KEYWORD
|
|
||||||
{
|
|
||||||
jmp_buf jmpbuf;
|
|
||||||
png_memcpy(jmpbuf,png_ptr->jmpbuf,sizeof(jmp_buf));
|
|
||||||
longjmp(jmpbuf, 1);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
longjmp(png_ptr->jmpbuf, 1);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This function is called when there is a warning, but the library
|
|
||||||
thinks it can continue anyway. You don't have to do anything here
|
|
||||||
if you don't want to. In the default configuration, png_ptr is
|
|
||||||
not used, but it is passed in case it may be useful. */
|
|
||||||
void
|
|
||||||
png_warning(png_struct *png_ptr, char *message)
|
|
||||||
{
|
|
||||||
if (!png_ptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
fprintf(stderr, "libpng warning: %s\n", message);
|
|
||||||
}
|
|
||||||
|
|
307
pngio.c
307
pngio.c
@ -1,32 +1,31 @@
|
|||||||
|
|
||||||
/* pngstub.c - stub functions for i/o and memory allocation
|
/* pngio.c - default functions for data I/O and error/warning messages
|
||||||
|
|
||||||
libpng 1.0 beta 2 - version 0.81
|
libpng 1.0 beta 3 - version 0.82
|
||||||
For conditions of distribution and use, see copyright notice in png.h
|
For conditions of distribution and use, see copyright notice in png.h
|
||||||
Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc.
|
Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc.
|
||||||
August 24, 1995
|
Some portions Copyright (C) 1995 Andreas Dilger
|
||||||
|
Sept 24, 1995
|
||||||
|
|
||||||
This file provides a location for all input/output. Users which need
|
This file provides a location for all input/output. Users which need
|
||||||
special handling are expected to modify the code in this file to meet
|
special handling are expected to write functions which have the same
|
||||||
their needs. See the instructions at each function. */
|
arguments as these, and perform similar functions, but possibly have
|
||||||
|
different I/O 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(...) or png_set_read_fn(...), etc */
|
||||||
|
|
||||||
#define PNG_INTERNAL
|
|
||||||
#include "png.h"
|
#include "png.h"
|
||||||
|
|
||||||
|
|
||||||
/* Write the data to whatever output you are using. The default
|
/* Write the data to whatever output you are using. The default
|
||||||
routine writes to a file pointer. If you need to write to something
|
routine writes to a file pointer. If you need to write to something
|
||||||
else, this is the place to do it. We suggest saving the old code
|
else, this is a good example of how to do it. Note that this routine
|
||||||
for future use, possibly in a #define. Note that this routine sometimes
|
sometimes gets called with very small lengths, so you should implement
|
||||||
gets called with very small lengths, so you should implement some kind
|
some kind of simple buffering if you are using unbuffered writes. This
|
||||||
of simple buffering if you are using unbuffered writes. This should
|
should never be asked to write more then 64K on a 16 bit machine. The
|
||||||
never be asked to write more then 64K on a 16 bit machine. The cast
|
cast to png_size_t is there for insurance. */
|
||||||
to png_size_t is there for insurance, but if you are having problems
|
|
||||||
with it, you can take it out. Just be sure to cast length to whatever
|
|
||||||
fwrite needs in that spot if you don't have a function prototype for
|
|
||||||
it. */
|
|
||||||
|
|
||||||
#ifndef USE_FAR_KEYWORD
|
#ifndef USE_FAR_KEYWORD
|
||||||
void
|
static void
|
||||||
png_write_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length)
|
png_write_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length)
|
||||||
{
|
{
|
||||||
png_uint_32 check;
|
png_uint_32 check;
|
||||||
@ -34,7 +33,7 @@ png_write_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length)
|
|||||||
check = fwrite(data, 1, (png_size_t)length, png_ptr->fp);
|
check = fwrite(data, 1, (png_size_t)length, png_ptr->fp);
|
||||||
if (check != length)
|
if (check != length)
|
||||||
{
|
{
|
||||||
png_error(png_ptr, "Write Error");
|
(*(png_ptr->error_fn))(png_ptr, "Write error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -51,7 +50,7 @@ png_write_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length)
|
|||||||
#include <dos.h>
|
#include <dos.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
static void
|
||||||
png_write_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length)
|
png_write_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length)
|
||||||
{
|
{
|
||||||
png_uint_32 check;
|
png_uint_32 check;
|
||||||
@ -92,25 +91,22 @@ png_write_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length)
|
|||||||
}
|
}
|
||||||
if (check != length)
|
if (check != length)
|
||||||
{
|
{
|
||||||
png_error(png_ptr, "Write Error");
|
(*(png_ptr->error_fn))(png_ptr, "Write error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Read the data from whatever input you are using. The default
|
/* Read the data from whatever input you are using. The default
|
||||||
routine reads from a file pointer. If you need to read from something
|
routine reads from a file pointer. If you need to read from something
|
||||||
else, this is the place to do it. We suggest saving the old code
|
else, this is a good example of how to do it. Note that this routine
|
||||||
for future use. Note that this routine sometimes gets called with
|
sometimes gets called with very small lengths, so you should implement
|
||||||
very small lengths, so you should implement some kind of simple
|
some kind of simple buffering if you are using unbuffered reads. This
|
||||||
buffering if you are using unbuffered reads. This should
|
should never be asked to read more then 64K on a 16 bit machine. The
|
||||||
never be asked to read more then 64K on a 16 bit machine. The cast
|
cast to png_size_t is there for insurance. */
|
||||||
to png_size_t is there for insurance, but if you are having problems
|
|
||||||
with it, you can take it out. Just be sure to cast length to whatever
|
|
||||||
fread needs in that spot if you don't have a function prototype for
|
|
||||||
it. */
|
|
||||||
#ifndef USE_FAR_KEYWORD
|
#ifndef USE_FAR_KEYWORD
|
||||||
void
|
static void
|
||||||
png_read_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length)
|
png_read_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length)
|
||||||
{
|
{
|
||||||
png_uint_32 check;
|
png_uint_32 check;
|
||||||
@ -118,11 +114,11 @@ png_read_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length)
|
|||||||
check = fread(data, 1, (size_t)length, png_ptr->fp);
|
check = fread(data, 1, (size_t)length, png_ptr->fp);
|
||||||
if (check != length)
|
if (check != length)
|
||||||
{
|
{
|
||||||
png_error(png_ptr, "Read Error");
|
(*(png_ptr->error_fn))(png_ptr, "Read error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void
|
static void
|
||||||
png_read_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length)
|
png_read_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length)
|
||||||
{
|
{
|
||||||
png_uint_32 check;
|
png_uint_32 check;
|
||||||
@ -163,18 +159,253 @@ png_read_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length)
|
|||||||
}
|
}
|
||||||
if (check != length)
|
if (check != length)
|
||||||
{
|
{
|
||||||
png_error(png_ptr, "read Error");
|
(*(png_ptr->error_fn))(png_ptr, "Read error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Initialize the input/output for the png file. If you change
|
|
||||||
the read and write routines, you will probably need to change
|
/* This function does nothing, and is used for the write function on
|
||||||
this routine (or write your own). If you change the parameters
|
a read, and vice-versa. It is an error if this function is
|
||||||
of this routine, remember to change png.h also. */
|
actually called. */
|
||||||
|
static void
|
||||||
|
png_empty_rw(png_struct *png_ptr, png_bytef *data, png_uint_32 length)
|
||||||
|
{
|
||||||
|
if (png_ptr->read_data_fn == png_empty_rw)
|
||||||
|
{
|
||||||
|
(*(png_ptr->error_fn))(png_ptr, "Invalid read on a write device");
|
||||||
|
}
|
||||||
|
else /* if (png_ptr->write_data_fn == png_empty_rw) */
|
||||||
|
{
|
||||||
|
(*(png_ptr->error_fn))(png_ptr, "Invalid write on a read device");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
|
||||||
|
/* This function does nothing, and is supplied for user I/O functions which
|
||||||
|
do not do any buffering. This function is set when NULL is supplied for
|
||||||
|
the flush function pointer. */
|
||||||
|
static void
|
||||||
|
png_empty_flush(png_struct *png_ptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Write out any remaining output that is stored in the output buffers.
|
||||||
|
If you supply a new write routine, you will probably need to supply a
|
||||||
|
replacement for this routine as well. */
|
||||||
|
static void
|
||||||
|
png_output_flush(png_struct *png_ptr)
|
||||||
|
{
|
||||||
|
fflush(png_ptr->fp);
|
||||||
|
}
|
||||||
|
#endif /* PNG_WRITE_FLUSH_SUPPORTED */
|
||||||
|
|
||||||
|
|
||||||
|
/* This function does nothing, and is called if the user supplies null
|
||||||
|
when setting the error function. */
|
||||||
|
static void
|
||||||
|
png_empty_error(png_structf *png_ptr, char *message)
|
||||||
|
{
|
||||||
|
#ifdef USE_FAR_KEYWORD
|
||||||
|
{
|
||||||
|
jmp_buf jmpbuf;
|
||||||
|
png_memcpy(jmpbuf,png_ptr->jmpbuf,sizeof(jmp_buf));
|
||||||
|
longjmp(jmpbuf, 1);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
longjmp(png_ptr->jmpbuf, 1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This function is called whenever there is an error. Replace with a
|
||||||
|
function you wish to handle the error. Note that this function
|
||||||
|
MUST NOT return, or the program will crash. To be consistent with
|
||||||
|
the examples for the library and this function, you could call
|
||||||
|
longjmp(pnt_ptr->jmpbuf) to return to the program at the location of
|
||||||
|
the last setjmp(png_ptr->jmpbuf) after an error. */
|
||||||
|
static void
|
||||||
|
png_error(png_structf *png_ptr, char *message)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "libpng error: %s\n", message);
|
||||||
|
|
||||||
|
png_empty_error(png_ptr, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This function does nothing, and is called if the user supplies null
|
||||||
|
when setting the warning function. */
|
||||||
|
static void
|
||||||
|
png_empty_warning(png_struct *png_ptr, char *message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This function is called when there is a warning, but the library
|
||||||
|
thinks it can continue anyway. You don't have to do anything here
|
||||||
|
if you don't want to. In the default configuration, png_ptr is
|
||||||
|
not used, but it is passed in case it may be useful. */
|
||||||
|
static void
|
||||||
|
png_warning(png_struct *png_ptr, char *message)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "libpng warning: %s\n", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This function allows the application to supply new output functions for
|
||||||
|
libpng if standard C streams aren't being used. The new write function
|
||||||
|
should call (*(png_ptr->error_fn))("Error message") to exit and output
|
||||||
|
any fatal error messages if it cannot output the correct number of bytes.
|
||||||
|
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 which takes as its
|
||||||
|
arguments a pointer to a png_struct, a pointer to
|
||||||
|
data to be written, and a 32-bit unsigned int which is
|
||||||
|
the number of bytes to be written. The new write
|
||||||
|
function should call (*(png_ptr->error_fn))("Error msg")
|
||||||
|
to exit and output any fatal error messages.
|
||||||
|
flush_data_fn - pointer to a new flush function which 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 ouput, this parameter can be NULL. 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. */
|
||||||
|
void
|
||||||
|
png_set_write_fn(png_struct *png_ptr, void *io_ptr, png_rw_ptr write_data_fn,
|
||||||
|
png_flush_ptr output_flush_fn)
|
||||||
|
{
|
||||||
|
png_ptr->io_ptr = io_ptr;
|
||||||
|
|
||||||
|
if (write_data_fn == NULL)
|
||||||
|
{
|
||||||
|
(*(png_ptr->error_fn))(png_ptr, "NULL write function pointer given");
|
||||||
|
}
|
||||||
|
|
||||||
|
png_ptr->write_data_fn = write_data_fn;
|
||||||
|
|
||||||
|
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
|
||||||
|
if (output_flush_fn == NULL)
|
||||||
|
{
|
||||||
|
png_ptr->output_flush_fn = png_empty_flush;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
png_ptr->output_flush_fn = output_flush_fn;
|
||||||
|
}
|
||||||
|
#endif /* PNG_WRITE_FLUSH_SUPPORTED */
|
||||||
|
|
||||||
|
/* It is an error to write to a read device */
|
||||||
|
png_ptr->read_data_fn = png_empty_rw;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This function allows the application to supply a new input function
|
||||||
|
for libpng if standard C streams aren't being used. The new read function
|
||||||
|
should call (*(png_ptr->error_fn))("Error message") to exit and output
|
||||||
|
any fatal error messages if the desired number of bytes is not available.
|
||||||
|
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 which takes as it's
|
||||||
|
arguments a pointer to a png_struct, a pointer to
|
||||||
|
a location where input data can be stored, and a 32-bit
|
||||||
|
unsigned int which is the number of bytes to be read. */
|
||||||
|
void
|
||||||
|
png_set_read_fn(png_struct *png_ptr, void *io_ptr, png_rw_ptr read_data_fn)
|
||||||
|
{
|
||||||
|
png_ptr->io_ptr = io_ptr;
|
||||||
|
|
||||||
|
if (read_data_fn == NULL)
|
||||||
|
{
|
||||||
|
(*(png_ptr->error_fn))(png_ptr, "NULL read function pointer given");
|
||||||
|
}
|
||||||
|
png_ptr->read_data_fn = read_data_fn;
|
||||||
|
|
||||||
|
/* It is an error to write to a read device */
|
||||||
|
png_ptr->write_data_fn = png_empty_rw;
|
||||||
|
|
||||||
|
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
|
||||||
|
png_ptr->output_flush_fn = png_empty_flush;
|
||||||
|
#endif /* PNG_WRITE_FLUSH_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 and png_read_destroy are called. */
|
||||||
|
void *
|
||||||
|
png_get_io_ptr(png_struct *png_ptr)
|
||||||
|
{
|
||||||
|
return png_ptr->io_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
error return method used in the default routine calls
|
||||||
|
longjmp(png_ptr->jmpbuf, 1), or exits if setjmp(png_ptr->jmpbuf) has never
|
||||||
|
been called. */
|
||||||
|
void
|
||||||
|
png_set_msg_fn(png_struct *png_ptr, void *msg_ptr, png_msg_ptr error_fn,
|
||||||
|
png_msg_ptr warning_fn)
|
||||||
|
{
|
||||||
|
png_ptr->msg_ptr = msg_ptr;
|
||||||
|
|
||||||
|
if (error_fn == NULL)
|
||||||
|
{
|
||||||
|
png_ptr->error_fn = png_empty_error;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
png_ptr->error_fn = error_fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (warning_fn == NULL)
|
||||||
|
{
|
||||||
|
png_ptr->warning_fn = png_empty_warning;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
png_ptr->warning_fn = warning_fn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This function returns a pointer to the msg_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. */
|
||||||
|
void *
|
||||||
|
png_get_msg_ptr(png_struct *png_ptr)
|
||||||
|
{
|
||||||
|
return png_ptr->msg_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Initialize the default input/output functions for the png file.
|
||||||
|
If you change the read, write or message routines, can call
|
||||||
|
either png_set_read_fn(...), png_set_write_fn(...), etc. to change
|
||||||
|
individual functions after a call to png_init_io(...). You can also
|
||||||
|
call one of png_set_read_fn(...) or png_set_write_fn(...), AND
|
||||||
|
png_set_msg_fn(...) instead of png_init_io(...) if you aren't using
|
||||||
|
any of the default libpng functions. */
|
||||||
void
|
void
|
||||||
png_init_io(png_struct *png_ptr, FILE *fp)
|
png_init_io(png_struct *png_ptr, FILE *fp)
|
||||||
{
|
{
|
||||||
png_ptr->fp = fp;
|
png_ptr->fp = fp;
|
||||||
}
|
png_ptr->error_fn = png_error;
|
||||||
|
png_ptr->warning_fn = png_warning;
|
||||||
|
png_ptr->write_data_fn = png_write_data;
|
||||||
|
png_ptr->read_data_fn = png_read_data;
|
||||||
|
|
||||||
|
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
|
||||||
|
png_ptr->output_flush_fn = png_output_flush;
|
||||||
|
#endif /* PNG_WRITE_FLUSH_SUPPORTED */
|
||||||
|
}
|
||||||
|
22
pngmem.c
22
pngmem.c
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
/* pngstub.c - stub functions for i/o and memory allocation
|
/* pngmem.c - stub functions for memory allocation
|
||||||
|
|
||||||
libpng 1.0 beta 2 - version 0.81
|
libpng 1.0 beta 2 - version 0.81
|
||||||
For conditions of distribution and use, see copyright notice in png.h
|
For conditions of distribution and use, see copyright notice in png.h
|
||||||
@ -61,7 +61,7 @@ png_large_malloc(png_structf *png_ptr, png_uint_32 size)
|
|||||||
|
|
||||||
#ifdef PNG_MAX_MALLOC_64K
|
#ifdef PNG_MAX_MALLOC_64K
|
||||||
if (size > (png_uint_32)65536L)
|
if (size > (png_uint_32)65536L)
|
||||||
png_error(png_ptr, "Cannot Allocate > 64K");
|
(*(png_ptr->error_fn))(png_ptr, "Cannot Allocate > 64K");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __TURBOC__
|
#ifdef __TURBOC__
|
||||||
@ -99,11 +99,11 @@ png_large_malloc(png_structf *png_ptr, png_uint_32 size)
|
|||||||
num_save_array = 1;
|
num_save_array = 1;
|
||||||
save_array = malloc(num_save_array * sizeof (borland_seg));
|
save_array = malloc(num_save_array * sizeof (borland_seg));
|
||||||
if (!save_array)
|
if (!save_array)
|
||||||
png_error(png_ptr, "Out of Memory 1");
|
(*(png_ptr->error_fn))(png_ptr, "Out of Memory 1");
|
||||||
save_array->mem_ptr = farmalloc(
|
save_array->mem_ptr = farmalloc(
|
||||||
(unsigned long)(NUM_SEG) * 65536L + 65532L);
|
(unsigned long)(NUM_SEG) * 65536L + 65532L);
|
||||||
if (!save_array->mem_ptr)
|
if (!save_array->mem_ptr)
|
||||||
png_error(png_ptr, "Out of Memory 2");
|
(*(png_ptr->error_fn))(png_ptr, "Out of Memory 2");
|
||||||
offset = (unsigned long)(ret);
|
offset = (unsigned long)(ret);
|
||||||
offset &= 0xffffL;
|
offset &= 0xffffL;
|
||||||
ptr = save_array->mem_ptr;
|
ptr = save_array->mem_ptr;
|
||||||
@ -141,11 +141,11 @@ png_large_malloc(png_structf *png_ptr, png_uint_32 size)
|
|||||||
save_array = realloc(save_array,
|
save_array = realloc(save_array,
|
||||||
(num_save_array + 1) * sizeof (borland_seg));
|
(num_save_array + 1) * sizeof (borland_seg));
|
||||||
if (!save_array)
|
if (!save_array)
|
||||||
png_error(png_ptr, "Out of Memory 3");
|
(*(png_ptr->error_fn))(png_ptr, "Out of Memory 3");
|
||||||
save_array[num_save_array].mem_ptr = farmalloc(
|
save_array[num_save_array].mem_ptr = farmalloc(
|
||||||
(unsigned long)(NUM_SEG) * 65536L + 65532L);
|
(unsigned long)(NUM_SEG) * 65536L + 65532L);
|
||||||
if (!save_array[num_save_array].mem_ptr)
|
if (!save_array[num_save_array].mem_ptr)
|
||||||
png_error(png_ptr, "Out of Memory 4");
|
(*(png_ptr->error_fn))(png_ptr, "Out of Memory 4");
|
||||||
offset = (unsigned long)(ret);
|
offset = (unsigned long)(ret);
|
||||||
offset &= 0xffffL;
|
offset &= 0xffffL;
|
||||||
ptr = save_array[num_save_array].mem_ptr;
|
ptr = save_array[num_save_array].mem_ptr;
|
||||||
@ -180,7 +180,7 @@ png_large_malloc(png_structf *png_ptr, png_uint_32 size)
|
|||||||
|
|
||||||
if (ret == NULL)
|
if (ret == NULL)
|
||||||
{
|
{
|
||||||
png_error(png_ptr, "Out of Memory");
|
(*(png_ptr->error_fn))(png_ptr, "Out of Memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -259,14 +259,14 @@ png_malloc(png_struct *png_ptr, png_uint_32 size)
|
|||||||
|
|
||||||
#ifdef PNG_MAX_MALLOC_64K
|
#ifdef PNG_MAX_MALLOC_64K
|
||||||
if (size > (png_uint_32)65536L)
|
if (size > (png_uint_32)65536L)
|
||||||
png_error(png_ptr, "Cannot Allocate > 64K");
|
(*(png_ptr->error_fn))(png_ptr, "Cannot Allocate > 64K");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = malloc((png_size_t)size);
|
ret = malloc((png_size_t)size);
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
{
|
||||||
png_error(png_ptr, "Out of Memory 6");
|
(*(png_ptr->error_fn))(png_ptr, "Out of Memory 6");
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -285,14 +285,14 @@ png_realloc(png_struct *png_ptr, void *ptr, png_uint_32 size,
|
|||||||
|
|
||||||
#ifdef PNG_MAX_MALLOC_64K
|
#ifdef PNG_MAX_MALLOC_64K
|
||||||
if (size > (png_uint_32)65536L)
|
if (size > (png_uint_32)65536L)
|
||||||
png_error(png_ptr, "Cannot Allocate > 64K");
|
(*(png_ptr->error_fn))(png_ptr, "Cannot Allocate > 64K");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = realloc(ptr, (png_size_t)size);
|
ret = realloc(ptr, (png_size_t)size);
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
{
|
||||||
png_error(png_ptr, "Out of Memory 7");
|
(*(png_ptr->error_fn))(png_ptr, "Out of Memory 7");
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
126
pngread.c
126
pngread.c
@ -38,22 +38,22 @@ png_read_info(png_struct *png_ptr, png_info *info)
|
|||||||
png_byte chunk_start[8];
|
png_byte chunk_start[8];
|
||||||
png_uint_32 length;
|
png_uint_32 length;
|
||||||
|
|
||||||
png_read_data(png_ptr, chunk_start, 8);
|
(*(png_ptr->read_data_fn))(png_ptr, chunk_start, 8);
|
||||||
if (memcmp(chunk_start, png_sig, 8))
|
if (memcmp(chunk_start, png_sig, 8))
|
||||||
png_error(png_ptr, "Not a Png File");
|
(*(png_ptr->error_fn))(png_ptr, "Not a PNG File");
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
png_uint_32 crc;
|
png_uint_32 crc;
|
||||||
|
|
||||||
png_read_data(png_ptr, chunk_start, 8);
|
(*(png_ptr->read_data_fn))(png_ptr, chunk_start, 8);
|
||||||
length = png_get_uint_32(chunk_start);
|
length = png_get_uint_32(chunk_start);
|
||||||
png_reset_crc(png_ptr);
|
png_reset_crc(png_ptr);
|
||||||
png_calculate_crc(png_ptr, chunk_start + 4, 4);
|
png_calculate_crc(png_ptr, chunk_start + 4, 4);
|
||||||
if (!memcmp(chunk_start + 4, png_IHDR, 4))
|
if (!memcmp(chunk_start + 4, png_IHDR, 4))
|
||||||
{
|
{
|
||||||
if (png_ptr->mode != PNG_BEFORE_IHDR)
|
if (png_ptr->mode != PNG_BEFORE_IHDR)
|
||||||
png_error(png_ptr, "Out of Place IHDR");
|
(*(png_ptr->error_fn))(png_ptr, "Out of Place IHDR");
|
||||||
|
|
||||||
png_handle_IHDR(png_ptr, info, length);
|
png_handle_IHDR(png_ptr, info, length);
|
||||||
png_ptr->mode = PNG_HAVE_IHDR;
|
png_ptr->mode = PNG_HAVE_IHDR;
|
||||||
@ -61,7 +61,7 @@ png_read_info(png_struct *png_ptr, png_info *info)
|
|||||||
else if (!memcmp(chunk_start + 4, png_PLTE, 4))
|
else if (!memcmp(chunk_start + 4, png_PLTE, 4))
|
||||||
{
|
{
|
||||||
if (png_ptr->mode != PNG_HAVE_IHDR)
|
if (png_ptr->mode != PNG_HAVE_IHDR)
|
||||||
png_error(png_ptr, "Missing IHDR");
|
(*(png_ptr->error_fn))(png_ptr, "Missing IHDR");
|
||||||
|
|
||||||
#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
|
#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
|
||||||
if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
|
if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
|
||||||
@ -82,13 +82,13 @@ png_read_info(png_struct *png_ptr, png_info *info)
|
|||||||
}
|
}
|
||||||
else if (!memcmp(chunk_start + 4, png_IEND, 4))
|
else if (!memcmp(chunk_start + 4, png_IEND, 4))
|
||||||
{
|
{
|
||||||
png_error(png_ptr, "No Image in File");
|
(*(png_ptr->error_fn))(png_ptr, "No Image in File");
|
||||||
}
|
}
|
||||||
#if defined(PNG_READ_gAMA_SUPPORTED)
|
#if defined(PNG_READ_gAMA_SUPPORTED)
|
||||||
else if (!memcmp(chunk_start + 4, png_gAMA, 4))
|
else if (!memcmp(chunk_start + 4, png_gAMA, 4))
|
||||||
{
|
{
|
||||||
if (png_ptr->mode != PNG_HAVE_IHDR)
|
if (png_ptr->mode != PNG_HAVE_IHDR)
|
||||||
png_error(png_ptr, "Out of Place PLTE");
|
(*(png_ptr->error_fn))(png_ptr, "Out of Place PLTE");
|
||||||
|
|
||||||
png_handle_gAMA(png_ptr, info, length);
|
png_handle_gAMA(png_ptr, info, length);
|
||||||
}
|
}
|
||||||
@ -97,7 +97,7 @@ png_read_info(png_struct *png_ptr, png_info *info)
|
|||||||
else if (!memcmp(chunk_start + 4, png_sBIT, 4))
|
else if (!memcmp(chunk_start + 4, png_sBIT, 4))
|
||||||
{
|
{
|
||||||
if (png_ptr->mode != PNG_HAVE_IHDR)
|
if (png_ptr->mode != PNG_HAVE_IHDR)
|
||||||
png_error(png_ptr, "Out of Place sBIT");
|
(*(png_ptr->error_fn))(png_ptr, "Out of Place sBIT");
|
||||||
|
|
||||||
png_handle_sBIT(png_ptr, info, length);
|
png_handle_sBIT(png_ptr, info, length);
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ png_read_info(png_struct *png_ptr, png_info *info)
|
|||||||
else if (!memcmp(chunk_start + 4, png_cHRM, 4))
|
else if (!memcmp(chunk_start + 4, png_cHRM, 4))
|
||||||
{
|
{
|
||||||
if (png_ptr->mode != PNG_HAVE_IHDR)
|
if (png_ptr->mode != PNG_HAVE_IHDR)
|
||||||
png_error(png_ptr, "Out of Place cHRM");
|
(*(png_ptr->error_fn))(png_ptr, "Out of Place cHRM");
|
||||||
|
|
||||||
png_handle_cHRM(png_ptr, info, length);
|
png_handle_cHRM(png_ptr, info, length);
|
||||||
}
|
}
|
||||||
@ -116,7 +116,7 @@ png_read_info(png_struct *png_ptr, png_info *info)
|
|||||||
{
|
{
|
||||||
if (png_ptr->mode != PNG_HAVE_IHDR &&
|
if (png_ptr->mode != PNG_HAVE_IHDR &&
|
||||||
png_ptr->mode != PNG_HAVE_PLTE)
|
png_ptr->mode != PNG_HAVE_PLTE)
|
||||||
png_error(png_ptr, "Out of Place tRNS");
|
(*(png_ptr->error_fn))(png_ptr, "Out of Place tRNS");
|
||||||
|
|
||||||
png_handle_tRNS(png_ptr, info, length);
|
png_handle_tRNS(png_ptr, info, length);
|
||||||
}
|
}
|
||||||
@ -126,7 +126,7 @@ png_read_info(png_struct *png_ptr, png_info *info)
|
|||||||
{
|
{
|
||||||
if (png_ptr->mode != PNG_HAVE_IHDR &&
|
if (png_ptr->mode != PNG_HAVE_IHDR &&
|
||||||
png_ptr->mode != PNG_HAVE_PLTE)
|
png_ptr->mode != PNG_HAVE_PLTE)
|
||||||
png_error(png_ptr, "Out of Place bKGD");
|
(*(png_ptr->error_fn))(png_ptr, "Out of Place bKGD");
|
||||||
|
|
||||||
png_handle_bKGD(png_ptr, info, length);
|
png_handle_bKGD(png_ptr, info, length);
|
||||||
}
|
}
|
||||||
@ -135,7 +135,7 @@ png_read_info(png_struct *png_ptr, png_info *info)
|
|||||||
else if (!memcmp(chunk_start + 4, png_hIST, 4))
|
else if (!memcmp(chunk_start + 4, png_hIST, 4))
|
||||||
{
|
{
|
||||||
if (png_ptr->mode != PNG_HAVE_PLTE)
|
if (png_ptr->mode != PNG_HAVE_PLTE)
|
||||||
png_error(png_ptr, "Out of Place hIST");
|
(*(png_ptr->error_fn))(png_ptr, "Out of Place hIST");
|
||||||
|
|
||||||
png_handle_hIST(png_ptr, info, length);
|
png_handle_hIST(png_ptr, info, length);
|
||||||
}
|
}
|
||||||
@ -145,7 +145,7 @@ png_read_info(png_struct *png_ptr, png_info *info)
|
|||||||
{
|
{
|
||||||
if (png_ptr->mode != PNG_HAVE_IHDR &&
|
if (png_ptr->mode != PNG_HAVE_IHDR &&
|
||||||
png_ptr->mode != PNG_HAVE_PLTE)
|
png_ptr->mode != PNG_HAVE_PLTE)
|
||||||
png_error(png_ptr, "Out of Place pHYs");
|
(*(png_ptr->error_fn))(png_ptr, "Out of Place pHYs");
|
||||||
|
|
||||||
png_handle_pHYs(png_ptr, info, length);
|
png_handle_pHYs(png_ptr, info, length);
|
||||||
}
|
}
|
||||||
@ -155,7 +155,7 @@ png_read_info(png_struct *png_ptr, png_info *info)
|
|||||||
{
|
{
|
||||||
if (png_ptr->mode != PNG_HAVE_IHDR &&
|
if (png_ptr->mode != PNG_HAVE_IHDR &&
|
||||||
png_ptr->mode != PNG_HAVE_PLTE)
|
png_ptr->mode != PNG_HAVE_PLTE)
|
||||||
png_error(png_ptr, "Out of Place oFFs");
|
(*(png_ptr->error_fn))(png_ptr, "Out of Place oFFs");
|
||||||
|
|
||||||
png_handle_oFFs(png_ptr, info, length);
|
png_handle_oFFs(png_ptr, info, length);
|
||||||
}
|
}
|
||||||
@ -165,7 +165,7 @@ png_read_info(png_struct *png_ptr, png_info *info)
|
|||||||
{
|
{
|
||||||
if (png_ptr->mode == PNG_BEFORE_IHDR ||
|
if (png_ptr->mode == PNG_BEFORE_IHDR ||
|
||||||
png_ptr->mode == PNG_AFTER_IEND)
|
png_ptr->mode == PNG_AFTER_IEND)
|
||||||
png_error(png_ptr, "Out of Place tIME");
|
(*(png_ptr->error_fn))(png_ptr, "Out of Place tIME");
|
||||||
|
|
||||||
png_handle_tIME(png_ptr, info, length);
|
png_handle_tIME(png_ptr, info, length);
|
||||||
}
|
}
|
||||||
@ -175,7 +175,7 @@ png_read_info(png_struct *png_ptr, png_info *info)
|
|||||||
{
|
{
|
||||||
if (png_ptr->mode == PNG_BEFORE_IHDR ||
|
if (png_ptr->mode == PNG_BEFORE_IHDR ||
|
||||||
png_ptr->mode == PNG_AFTER_IEND)
|
png_ptr->mode == PNG_AFTER_IEND)
|
||||||
png_error(png_ptr, "Out of Place tEXt");
|
(*(png_ptr->error_fn))(png_ptr, "Out of Place tEXt");
|
||||||
|
|
||||||
png_handle_tEXt(png_ptr, info, length);
|
png_handle_tEXt(png_ptr, info, length);
|
||||||
}
|
}
|
||||||
@ -185,7 +185,7 @@ png_read_info(png_struct *png_ptr, png_info *info)
|
|||||||
{
|
{
|
||||||
if (png_ptr->mode == PNG_BEFORE_IHDR ||
|
if (png_ptr->mode == PNG_BEFORE_IHDR ||
|
||||||
png_ptr->mode == PNG_AFTER_IEND)
|
png_ptr->mode == PNG_AFTER_IEND)
|
||||||
png_error(png_ptr, "Out of Place zTXt");
|
(*(png_ptr->error_fn))(png_ptr, "Out of Place zTXt");
|
||||||
|
|
||||||
png_handle_zTXt(png_ptr, info, length);
|
png_handle_zTXt(png_ptr, info, length);
|
||||||
}
|
}
|
||||||
@ -193,15 +193,15 @@ png_read_info(png_struct *png_ptr, png_info *info)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((chunk_start[4] & 0x20) == 0)
|
if ((chunk_start[4] & 0x20) == 0)
|
||||||
png_error(png_ptr, "Unknown Critical Chunk");
|
(*(png_ptr->error_fn))(png_ptr, "Unknown Critical Chunk");
|
||||||
|
|
||||||
png_crc_skip(png_ptr, length);
|
png_crc_skip(png_ptr, length);
|
||||||
}
|
}
|
||||||
png_read_data(png_ptr, chunk_start, 4);
|
(*(png_ptr->read_data_fn))(png_ptr, chunk_start, 4);
|
||||||
crc = png_get_uint_32(chunk_start);
|
crc = png_get_uint_32(chunk_start);
|
||||||
if (((crc ^ 0xffffffffL) & 0xffffffffL) !=
|
if (((crc ^ 0xffffffffL) & 0xffffffffL) !=
|
||||||
(png_ptr->crc & 0xffffffffL))
|
(png_ptr->crc & 0xffffffffL))
|
||||||
png_error(png_ptr, "Bad CRC value");
|
(*(png_ptr->error_fn))(png_ptr, "Bad CRC value");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,7 +310,7 @@ png_read_row(png_struct *png_ptr, png_bytef *row, png_byte *dsp_row)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (png_ptr->mode != PNG_HAVE_IDAT)
|
if (png_ptr->mode != PNG_HAVE_IDAT)
|
||||||
png_error(png_ptr, "invalid attempt to read row data");
|
(*(png_ptr->error_fn))(png_ptr, "Invalid attempt to read row data");
|
||||||
|
|
||||||
png_ptr->zstream->next_out = png_ptr->row_buf;
|
png_ptr->zstream->next_out = png_ptr->row_buf;
|
||||||
png_ptr->zstream->avail_out = (uInt)png_ptr->irowbytes;
|
png_ptr->zstream->avail_out = (uInt)png_ptr->irowbytes;
|
||||||
@ -323,19 +323,19 @@ png_read_row(png_struct *png_ptr, png_bytef *row, png_byte *dsp_row)
|
|||||||
png_byte buf[4];
|
png_byte buf[4];
|
||||||
png_uint_32 crc;
|
png_uint_32 crc;
|
||||||
|
|
||||||
png_read_data(png_ptr, buf, 4);
|
(*(png_ptr->read_data_fn))(png_ptr, buf, 4);
|
||||||
crc = png_get_uint_32(buf);
|
crc = png_get_uint_32(buf);
|
||||||
if (((crc ^ 0xffffffffL) & 0xffffffffL) !=
|
if (((crc ^ 0xffffffffL) & 0xffffffffL) !=
|
||||||
(png_ptr->crc & 0xffffffffL))
|
(png_ptr->crc & 0xffffffffL))
|
||||||
png_error(png_ptr, "Bad CRC value");
|
(*(png_ptr->error_fn))(png_ptr, "Bad CRC value");
|
||||||
|
|
||||||
png_read_data(png_ptr, buf, 4);
|
(*(png_ptr->read_data_fn))(png_ptr, buf, 4);
|
||||||
png_ptr->idat_size = png_get_uint_32(buf);
|
png_ptr->idat_size = png_get_uint_32(buf);
|
||||||
png_reset_crc(png_ptr);
|
png_reset_crc(png_ptr);
|
||||||
|
|
||||||
png_crc_read(png_ptr, buf, 4);
|
png_crc_read(png_ptr, buf, 4);
|
||||||
if (memcmp(buf, png_IDAT, 4))
|
if (memcmp(buf, png_IDAT, 4))
|
||||||
png_error(png_ptr, "Not enough image data");
|
(*(png_ptr->error_fn))(png_ptr, "Not enough image data");
|
||||||
|
|
||||||
}
|
}
|
||||||
png_ptr->zstream->avail_in = (uInt)png_ptr->zbuf_size;
|
png_ptr->zstream->avail_in = (uInt)png_ptr->zbuf_size;
|
||||||
@ -350,12 +350,12 @@ png_read_row(png_struct *png_ptr, png_bytef *row, png_byte *dsp_row)
|
|||||||
{
|
{
|
||||||
if (png_ptr->zstream->avail_out || png_ptr->zstream->avail_in ||
|
if (png_ptr->zstream->avail_out || png_ptr->zstream->avail_in ||
|
||||||
png_ptr->idat_size)
|
png_ptr->idat_size)
|
||||||
png_error(png_ptr, "Extra compressed data");
|
(*(png_ptr->warning_fn))(png_ptr, "Extra compressed data");
|
||||||
png_ptr->mode = PNG_AT_LAST_IDAT;
|
png_ptr->mode = PNG_AT_LAST_IDAT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ret != Z_OK)
|
if (ret != Z_OK)
|
||||||
png_error(png_ptr, "Compression Error");
|
(*(png_ptr->error_fn))(png_ptr, "Compression Error");
|
||||||
|
|
||||||
} while (png_ptr->zstream->avail_out);
|
} while (png_ptr->zstream->avail_out);
|
||||||
|
|
||||||
@ -448,6 +448,7 @@ png_read_rows(png_struct *png_ptr, png_bytef **row,
|
|||||||
dptr = *dp;
|
dptr = *dp;
|
||||||
else
|
else
|
||||||
dptr = NULL;
|
dptr = NULL;
|
||||||
|
|
||||||
png_read_row(png_ptr, rptr, dptr);
|
png_read_row(png_ptr, rptr, dptr);
|
||||||
if (row)
|
if (row)
|
||||||
rp++;
|
rp++;
|
||||||
@ -491,70 +492,70 @@ png_read_end(png_struct *png_ptr, png_info *info)
|
|||||||
png_uint_32 length;
|
png_uint_32 length;
|
||||||
png_uint_32 crc;
|
png_uint_32 crc;
|
||||||
|
|
||||||
png_read_data(png_ptr, chunk_start, 4);
|
(*(png_ptr->read_data_fn))(png_ptr, chunk_start, 4);
|
||||||
crc = png_get_uint_32(chunk_start);
|
crc = png_get_uint_32(chunk_start);
|
||||||
if (((crc ^ 0xffffffffL) & 0xffffffffL) !=
|
if (((crc ^ 0xffffffffL) & 0xffffffffL) !=
|
||||||
(png_ptr->crc & 0xffffffffL))
|
(png_ptr->crc & 0xffffffffL))
|
||||||
png_error(png_ptr, "Bad CRC value");
|
(*(png_ptr->error_fn))(png_ptr, "Bad CRC value");
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
png_read_data(png_ptr, chunk_start, 8);
|
(*(png_ptr->read_data_fn))(png_ptr, chunk_start, 8);
|
||||||
length = png_get_uint_32(chunk_start);
|
length = png_get_uint_32(chunk_start);
|
||||||
png_reset_crc(png_ptr);
|
png_reset_crc(png_ptr);
|
||||||
png_calculate_crc(png_ptr, chunk_start + 4, 4);
|
png_calculate_crc(png_ptr, chunk_start + 4, 4);
|
||||||
|
|
||||||
if (!memcmp(chunk_start + 4, png_IHDR, 4))
|
if (!memcmp(chunk_start + 4, png_IHDR, 4))
|
||||||
{
|
{
|
||||||
png_error(png_ptr, "invalid chunk after IDAT");
|
(*(png_ptr->error_fn))(png_ptr, "Invalid chunk after IDAT");
|
||||||
}
|
}
|
||||||
else if (!memcmp(chunk_start + 4, png_PLTE, 4))
|
else if (!memcmp(chunk_start + 4, png_PLTE, 4))
|
||||||
{
|
{
|
||||||
png_error(png_ptr, "invalid chunk after IDAT");
|
(*(png_ptr->error_fn))(png_ptr, "Invalid chunk after IDAT");
|
||||||
}
|
}
|
||||||
else if (!memcmp(chunk_start + 4, png_gAMA, 4))
|
else if (!memcmp(chunk_start + 4, png_gAMA, 4))
|
||||||
{
|
{
|
||||||
png_error(png_ptr, "invalid chunk after IDAT");
|
(*(png_ptr->error_fn))(png_ptr, "Invalid chunk after IDAT");
|
||||||
}
|
}
|
||||||
else if (!memcmp(chunk_start + 4, png_sBIT, 4))
|
else if (!memcmp(chunk_start + 4, png_sBIT, 4))
|
||||||
{
|
{
|
||||||
png_error(png_ptr, "invalid chunk after IDAT");
|
(*(png_ptr->error_fn))(png_ptr, "Invalid chunk after IDAT");
|
||||||
}
|
}
|
||||||
else if (!memcmp(chunk_start + 4, png_cHRM, 4))
|
else if (!memcmp(chunk_start + 4, png_cHRM, 4))
|
||||||
{
|
{
|
||||||
png_error(png_ptr, "invalid chunk after IDAT");
|
(*(png_ptr->error_fn))(png_ptr, "Invalid chunk after IDAT");
|
||||||
}
|
}
|
||||||
else if (!memcmp(chunk_start + 4, png_tRNS, 4))
|
else if (!memcmp(chunk_start + 4, png_tRNS, 4))
|
||||||
{
|
{
|
||||||
png_error(png_ptr, "invalid chunk after IDAT");
|
(*(png_ptr->error_fn))(png_ptr, "Invalid chunk after IDAT");
|
||||||
}
|
}
|
||||||
else if (!memcmp(chunk_start + 4, png_bKGD, 4))
|
else if (!memcmp(chunk_start + 4, png_bKGD, 4))
|
||||||
{
|
{
|
||||||
png_error(png_ptr, "invalid chunk after IDAT");
|
(*(png_ptr->error_fn))(png_ptr, "Invalid chunk after IDAT");
|
||||||
}
|
}
|
||||||
else if (!memcmp(chunk_start + 4, png_hIST, 4))
|
else if (!memcmp(chunk_start + 4, png_hIST, 4))
|
||||||
{
|
{
|
||||||
png_error(png_ptr, "invalid chunk after IDAT");
|
(*(png_ptr->error_fn))(png_ptr, "Invalid chunk after IDAT");
|
||||||
}
|
}
|
||||||
else if (!memcmp(chunk_start + 4, png_IDAT, 4))
|
else if (!memcmp(chunk_start + 4, png_IDAT, 4))
|
||||||
{
|
{
|
||||||
if (length > 0 || png_ptr->mode != PNG_AT_LAST_IDAT)
|
if (length > 0 || png_ptr->mode != PNG_AT_LAST_IDAT)
|
||||||
png_error(png_ptr, "too many IDAT's found");
|
(*(png_ptr->error_fn))(png_ptr, "Too many IDAT's found");
|
||||||
}
|
}
|
||||||
else if (!memcmp(chunk_start + 4, png_pHYs, 4))
|
else if (!memcmp(chunk_start + 4, png_pHYs, 4))
|
||||||
{
|
{
|
||||||
png_error(png_ptr, "invalid chunk after IDAT");
|
(*(png_ptr->error_fn))(png_ptr, "Invalid chunk after IDAT");
|
||||||
}
|
}
|
||||||
else if (!memcmp(chunk_start + 4, png_oFFs, 4))
|
else if (!memcmp(chunk_start + 4, png_oFFs, 4))
|
||||||
{
|
{
|
||||||
png_error(png_ptr, "invalid chunk after IDAT");
|
(*(png_ptr->error_fn))(png_ptr, "Invalid chunk after IDAT");
|
||||||
}
|
}
|
||||||
#if defined(PNG_READ_tIME_SUPPORTED)
|
#if defined(PNG_READ_tIME_SUPPORTED)
|
||||||
else if (!memcmp(chunk_start + 4, png_tIME, 4))
|
else if (!memcmp(chunk_start + 4, png_tIME, 4))
|
||||||
{
|
{
|
||||||
if (png_ptr->mode == PNG_BEFORE_IHDR ||
|
if (png_ptr->mode == PNG_BEFORE_IHDR ||
|
||||||
png_ptr->mode == PNG_AFTER_IEND)
|
png_ptr->mode == PNG_AFTER_IEND)
|
||||||
png_error(png_ptr, "Out of Place tIME");
|
(*(png_ptr->error_fn))(png_ptr, "Out of Place tIME");
|
||||||
|
|
||||||
if (info)
|
if (info)
|
||||||
png_handle_tIME(png_ptr, info, length);
|
png_handle_tIME(png_ptr, info, length);
|
||||||
@ -567,7 +568,7 @@ png_read_end(png_struct *png_ptr, png_info *info)
|
|||||||
{
|
{
|
||||||
if (png_ptr->mode == PNG_BEFORE_IHDR ||
|
if (png_ptr->mode == PNG_BEFORE_IHDR ||
|
||||||
png_ptr->mode == PNG_AFTER_IEND)
|
png_ptr->mode == PNG_AFTER_IEND)
|
||||||
png_error(png_ptr, "Out of Place tEXt");
|
(*(png_ptr->error_fn))(png_ptr, "Out of Place tEXt");
|
||||||
|
|
||||||
if (info)
|
if (info)
|
||||||
png_handle_tEXt(png_ptr, info, length);
|
png_handle_tEXt(png_ptr, info, length);
|
||||||
@ -580,7 +581,7 @@ png_read_end(png_struct *png_ptr, png_info *info)
|
|||||||
{
|
{
|
||||||
if (png_ptr->mode == PNG_BEFORE_IHDR ||
|
if (png_ptr->mode == PNG_BEFORE_IHDR ||
|
||||||
png_ptr->mode == PNG_AFTER_IEND)
|
png_ptr->mode == PNG_AFTER_IEND)
|
||||||
png_error(png_ptr, "Out of Place zTXt");
|
(*(png_ptr->error_fn))(png_ptr, "Out of Place zTXt");
|
||||||
|
|
||||||
if (info)
|
if (info)
|
||||||
png_handle_zTXt(png_ptr, info, length);
|
png_handle_zTXt(png_ptr, info, length);
|
||||||
@ -594,16 +595,25 @@ png_read_end(png_struct *png_ptr, png_info *info)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((chunk_start[4] & 0x20) == 0)
|
char msg[80];
|
||||||
png_error(png_ptr, "Unknown Critical Chunk");
|
|
||||||
|
|
||||||
|
if ((chunk_start[4] & 0x20) == 0)
|
||||||
|
{
|
||||||
|
png_strcpy(msg,"Unknown critical chunk ");
|
||||||
|
png_memcpy(msg + strlen(msg), chunk_start + 4,4);
|
||||||
|
(*(png_ptr->error_fn))(png_ptr, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
png_strcpy(msg,"Unknown extension chunk ");
|
||||||
|
png_memcpy(msg + strlen(msg), chunk_start + 4,4);
|
||||||
|
(*(png_ptr->warning_fn))(png_ptr, msg);
|
||||||
png_crc_skip(png_ptr, length);
|
png_crc_skip(png_ptr, length);
|
||||||
}
|
}
|
||||||
png_read_data(png_ptr, chunk_start, 4);
|
(*(png_ptr->read_data_fn))(png_ptr, chunk_start, 4);
|
||||||
crc = png_get_uint_32(chunk_start);
|
crc = png_get_uint_32(chunk_start);
|
||||||
if (((crc ^ 0xffffffffL) & 0xffffffffL) !=
|
if (((crc ^ 0xffffffffL) & 0xffffffffL) !=
|
||||||
(png_ptr->crc & 0xffffffffL))
|
(png_ptr->crc & 0xffffffffL))
|
||||||
png_error(png_ptr, "Bad CRC value");
|
(*(png_ptr->error_fn))(png_ptr, "Bad CRC value");
|
||||||
if (png_ptr->mode == PNG_AT_LAST_IDAT)
|
if (png_ptr->mode == PNG_AT_LAST_IDAT)
|
||||||
png_ptr->mode = PNG_AFTER_IDAT;
|
png_ptr->mode = PNG_AFTER_IDAT;
|
||||||
} while (png_ptr->mode != PNG_AFTER_IEND);
|
} while (png_ptr->mode != PNG_AFTER_IEND);
|
||||||
@ -618,19 +628,19 @@ png_read_destroy(png_struct *png_ptr, png_info *info, png_info *end_info)
|
|||||||
|
|
||||||
if (info)
|
if (info)
|
||||||
{
|
{
|
||||||
/* I'm not sure I should be freeing this */
|
if (png_ptr->do_free & PNG_FREE_PALETTE)
|
||||||
if (info->palette != png_ptr->palette)
|
|
||||||
png_free(png_ptr, info->palette);
|
png_free(png_ptr, info->palette);
|
||||||
/* I'm not sure I should be freeing this */
|
|
||||||
#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_bKGD_SUPPORTED)
|
#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_bKGD_SUPPORTED)
|
||||||
if (info->trans != png_ptr->trans)
|
if (png_ptr->do_free & PNG_FREE_TRANS)
|
||||||
png_free(png_ptr, info->trans);
|
png_free(png_ptr, info->trans);
|
||||||
#endif
|
#endif
|
||||||
/* I'm not sure I should be freeing this */
|
|
||||||
#if defined(PNG_READ_hIST_SUPPORTED)
|
#if defined(PNG_READ_hIST_SUPPORTED)
|
||||||
if (info->hist != png_ptr->hist)
|
if (png_ptr->do_free & PNG_FREE_HIST)
|
||||||
png_free(png_ptr, info->hist);
|
png_free(png_ptr, info->hist);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
|
#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
|
||||||
for (i = 0; i < info->num_text; i++)
|
for (i = 0; i < info->num_text; i++)
|
||||||
{
|
{
|
||||||
@ -658,17 +668,21 @@ png_read_destroy(png_struct *png_ptr, png_info *info, png_info *end_info)
|
|||||||
png_large_free(png_ptr, png_ptr->zbuf);
|
png_large_free(png_ptr, png_ptr->zbuf);
|
||||||
png_large_free(png_ptr, png_ptr->row_buf);
|
png_large_free(png_ptr, png_ptr->row_buf);
|
||||||
png_large_free(png_ptr, png_ptr->prev_row);
|
png_large_free(png_ptr, png_ptr->prev_row);
|
||||||
|
|
||||||
#if defined(PNG_READ_DITHER_SUPPORTED)
|
#if defined(PNG_READ_DITHER_SUPPORTED)
|
||||||
png_large_free(png_ptr, png_ptr->palette_lookup);
|
png_large_free(png_ptr, png_ptr->palette_lookup);
|
||||||
png_free(png_ptr, png_ptr->dither_index);
|
png_free(png_ptr, png_ptr->dither_index);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_READ_GAMMA_SUPPORTED)
|
#if defined(PNG_READ_GAMMA_SUPPORTED)
|
||||||
png_free(png_ptr, png_ptr->gamma_table);
|
png_free(png_ptr, png_ptr->gamma_table);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
|
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
|
||||||
png_free(png_ptr, png_ptr->gamma_from_1);
|
png_free(png_ptr, png_ptr->gamma_from_1);
|
||||||
png_free(png_ptr, png_ptr->gamma_to_1);
|
png_free(png_ptr, png_ptr->gamma_to_1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_READ_GAMMA_SUPPORTED)
|
#if defined(PNG_READ_GAMMA_SUPPORTED)
|
||||||
if (png_ptr->gamma_16_table)
|
if (png_ptr->gamma_16_table)
|
||||||
{
|
{
|
||||||
@ -678,6 +692,7 @@ png_read_destroy(png_struct *png_ptr, png_info *info, png_info *end_info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
|
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
|
||||||
png_free(png_ptr, png_ptr->gamma_16_table);
|
png_free(png_ptr, png_ptr->gamma_16_table);
|
||||||
if (png_ptr->gamma_16_from_1)
|
if (png_ptr->gamma_16_from_1)
|
||||||
@ -697,12 +712,15 @@ png_read_destroy(png_struct *png_ptr, png_info *info, png_info *end_info)
|
|||||||
}
|
}
|
||||||
png_free(png_ptr, png_ptr->gamma_16_to_1);
|
png_free(png_ptr, png_ptr->gamma_16_to_1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
|
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
|
||||||
png_free(png_ptr, png_ptr->trans);
|
png_free(png_ptr, png_ptr->trans);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_READ_DITHER_SUPPORTED)
|
#if defined(PNG_READ_DITHER_SUPPORTED)
|
||||||
png_free(png_ptr, png_ptr->hist);
|
png_free(png_ptr, png_ptr->hist);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!png_ptr->user_palette)
|
if (!png_ptr->user_palette)
|
||||||
png_free(png_ptr, png_ptr->palette);
|
png_free(png_ptr, png_ptr->palette);
|
||||||
|
|
||||||
|
49
pngrtran.c
49
pngrtran.c
@ -572,7 +572,7 @@ png_init_read_transformations(png_struct *png_ptr)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_READ_SHIFT_SUPPORTED)
|
#if defined(PNG_READ_SHIFT_SUPPORTED) && defined(PNG_READ_sBIT_SUPPORTED)
|
||||||
if ((png_ptr->transformations & PNG_SHIFT) &&
|
if ((png_ptr->transformations & PNG_SHIFT) &&
|
||||||
png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
|
png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
|
||||||
{
|
{
|
||||||
@ -876,19 +876,33 @@ png_do_unshift(png_row_info *row_info, png_bytef *row,
|
|||||||
channels = 0;
|
channels = 0;
|
||||||
if (row_info->color_type & PNG_COLOR_MASK_COLOR)
|
if (row_info->color_type & PNG_COLOR_MASK_COLOR)
|
||||||
{
|
{
|
||||||
shift[channels++] = row_info->bit_depth - sig_bits->red;
|
shift[channels++] = row_info->bit_depth - sig_bits->red < 0 ?
|
||||||
shift[channels++] = row_info->bit_depth - sig_bits->green;
|
0 : row_info->bit_depth - sig_bits->red;
|
||||||
shift[channels++] = row_info->bit_depth - sig_bits->blue;
|
shift[channels++] = row_info->bit_depth - sig_bits->green < 0 ?
|
||||||
|
0 : row_info->bit_depth - sig_bits->green;
|
||||||
|
shift[channels++] = row_info->bit_depth - sig_bits->blue < 0 ?
|
||||||
|
0 : row_info->bit_depth - sig_bits->blue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
shift[channels++] = row_info->bit_depth - sig_bits->gray;
|
shift[channels++] = row_info->bit_depth - sig_bits->gray < 0 ?
|
||||||
|
0 : row_info->bit_depth - sig_bits->gray;
|
||||||
}
|
}
|
||||||
if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
|
if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
|
||||||
{
|
{
|
||||||
shift[channels++] = row_info->bit_depth - sig_bits->alpha;
|
shift[channels++] = row_info->bit_depth - sig_bits->alpha < 0 ?
|
||||||
|
0 : row_info->bit_depth - sig_bits->alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
value = 1;
|
||||||
|
|
||||||
|
for (i = 0; i < channels; i++)
|
||||||
|
{
|
||||||
|
if (shift[i] != 0) value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value == 1) return;
|
||||||
|
|
||||||
switch (row_info->bit_depth)
|
switch (row_info->bit_depth)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
@ -905,6 +919,7 @@ png_do_unshift(png_row_info *row_info, png_bytef *row,
|
|||||||
case 4:
|
case 4:
|
||||||
{
|
{
|
||||||
png_byte mask;
|
png_byte mask;
|
||||||
|
|
||||||
mask = (png_byte)(((int)0xf0 >> shift[0]) & (int)0xf0) |
|
mask = (png_byte)(((int)0xf0 >> shift[0]) & (int)0xf0) |
|
||||||
((int)0xf >> shift[0]);
|
((int)0xf >> shift[0]);
|
||||||
for (bp = row, i = 0;
|
for (bp = row, i = 0;
|
||||||
@ -957,17 +972,15 @@ png_do_unshift(png_row_info *row_info, png_bytef *row,
|
|||||||
void
|
void
|
||||||
png_do_chop(png_row_info *row_info, png_bytef *row)
|
png_do_chop(png_row_info *row_info, png_bytef *row)
|
||||||
{
|
{
|
||||||
png_bytef *sp, *dp;
|
|
||||||
png_uint_32 i;
|
|
||||||
if (row && row_info && row_info->bit_depth == 16)
|
if (row && row_info && row_info->bit_depth == 16)
|
||||||
{
|
{
|
||||||
sp = row + 2;
|
png_bytef *sp = row, *dp = row;
|
||||||
dp = row + 1;
|
png_uint_32 i;
|
||||||
for (i = 1; i < row_info->width * row_info->channels; i++)
|
|
||||||
|
for (i = 0; i < row_info->width * row_info->channels; i++)
|
||||||
{
|
{
|
||||||
*dp = *sp;
|
*dp++ = ((((*sp << 8 | *(sp + 1)) - *sp) + 0x7F) >> 8) & 0xFF;
|
||||||
sp += 2;
|
sp += 2;
|
||||||
dp++;
|
|
||||||
}
|
}
|
||||||
row_info->bit_depth = 8;
|
row_info->bit_depth = 8;
|
||||||
row_info->pixel_depth = 8 * row_info->channels;
|
row_info->pixel_depth = 8 * row_info->channels;
|
||||||
@ -1147,6 +1160,7 @@ png_build_grayscale_palette(int bit_depth, png_color *palette)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
num_palette = 0;
|
num_palette = 0;
|
||||||
|
color_inc = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2002,7 +2016,7 @@ png_do_background(png_row_info *row_info, png_bytef *row,
|
|||||||
you do this after you deal with the trasparency issue on grayscale
|
you do this after you deal with the trasparency issue on grayscale
|
||||||
or rgb images. If your bit depth is 8, use gamma_table, if it is 16,
|
or rgb images. If your bit depth is 8, use gamma_table, if it is 16,
|
||||||
use gamma_16_table and gamma_shift. Build these with
|
use gamma_16_table and gamma_shift. Build these with
|
||||||
build_gamma_table(). If your bit depth < 8, gamma correct a
|
build_gamma_table(). If your bit depth <= 8, gamma correct a
|
||||||
palette, not the data. */
|
palette, not the data. */
|
||||||
void
|
void
|
||||||
png_do_gamma(png_row_info *row_info, png_bytef *row,
|
png_do_gamma(png_row_info *row_info, png_bytef *row,
|
||||||
@ -2623,8 +2637,9 @@ png_build_gamma_table(png_struct *png_ptr)
|
|||||||
{
|
{
|
||||||
double g;
|
double g;
|
||||||
int i, j, shift, num;
|
int i, j, shift, num;
|
||||||
int sig_bit;
|
|
||||||
png_uint_32 ig;
|
png_uint_32 ig;
|
||||||
|
#if defined(PNG_READ_sBIT_SUPPORTED)
|
||||||
|
int sig_bit;
|
||||||
|
|
||||||
if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
|
if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
|
||||||
{
|
{
|
||||||
@ -2642,6 +2657,7 @@ png_build_gamma_table(png_struct *png_ptr)
|
|||||||
if (sig_bit > 0)
|
if (sig_bit > 0)
|
||||||
shift = 16 - sig_bit;
|
shift = 16 - sig_bit;
|
||||||
else
|
else
|
||||||
|
#endif /* PNG_READ_sBIT_SUPPORTED */
|
||||||
shift = 0;
|
shift = 0;
|
||||||
|
|
||||||
if (png_ptr->transformations & PNG_16_TO_8)
|
if (png_ptr->transformations & PNG_16_TO_8)
|
||||||
@ -2685,8 +2701,7 @@ png_build_gamma_table(png_struct *png_ptr)
|
|||||||
max = (png_uint_32)(fin * (double)(num << 8));
|
max = (png_uint_32)(fin * (double)(num << 8));
|
||||||
while (last <= max)
|
while (last <= max)
|
||||||
{
|
{
|
||||||
png_ptr->gamma_16_table[(int)(last >> 8)]
|
png_ptr->gamma_16_table[(int)(last >> 8)][(int)(last & 0xff)] =
|
||||||
[(int)(last & 0xff)] =
|
|
||||||
(png_uint_16)i | ((png_uint_16)i << 8);
|
(png_uint_16)i | ((png_uint_16)i << 8);
|
||||||
last++;
|
last++;
|
||||||
}
|
}
|
||||||
|
94
pngrutil.c
94
pngrutil.c
@ -40,7 +40,7 @@ png_get_uint_16(png_byte *buf)
|
|||||||
void
|
void
|
||||||
png_crc_read(png_struct *png_ptr, png_bytef *buf, png_uint_32 length)
|
png_crc_read(png_struct *png_ptr, png_bytef *buf, png_uint_32 length)
|
||||||
{
|
{
|
||||||
png_read_data(png_ptr, buf, length);
|
(*(png_ptr->read_data_fn))(png_ptr, buf, length);
|
||||||
png_calculate_crc(png_ptr, buf, length);
|
png_calculate_crc(png_ptr, buf, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,12 +52,12 @@ png_crc_skip(png_struct *png_ptr, png_uint_32 length)
|
|||||||
|
|
||||||
for (i = length; i > png_ptr->zbuf_size; i -= png_ptr->zbuf_size)
|
for (i = length; i > png_ptr->zbuf_size; i -= png_ptr->zbuf_size)
|
||||||
{
|
{
|
||||||
png_read_data(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
|
(*(png_ptr->read_data_fn))(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
|
||||||
png_calculate_crc(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
|
png_calculate_crc(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
|
||||||
}
|
}
|
||||||
if (i)
|
if (i)
|
||||||
{
|
{
|
||||||
png_read_data(png_ptr, png_ptr->zbuf, i);
|
(*(png_ptr->read_data_fn))(png_ptr, png_ptr->zbuf, i);
|
||||||
png_calculate_crc(png_ptr, png_ptr->zbuf, i);
|
png_calculate_crc(png_ptr, png_ptr->zbuf, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,7 +73,7 @@ png_handle_IHDR(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
|
|
||||||
/* check the length */
|
/* check the length */
|
||||||
if (length != 13)
|
if (length != 13)
|
||||||
png_error(png_ptr, "Invalid IHDR chunk");
|
(*(png_ptr->error_fn))(png_ptr, "Invalid IHDR chunk");
|
||||||
|
|
||||||
png_crc_read(png_ptr, buf, 13);
|
png_crc_read(png_ptr, buf, 13);
|
||||||
|
|
||||||
@ -87,36 +87,36 @@ png_handle_IHDR(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
|
|
||||||
/* check for width and height valid values */
|
/* check for width and height valid values */
|
||||||
if (width == 0 || height == 0)
|
if (width == 0 || height == 0)
|
||||||
png_error(png_ptr, "Invalid Width or Height Found");
|
(*(png_ptr->error_fn))(png_ptr, "Invalid Width or Height Found");
|
||||||
|
|
||||||
/* check other values */
|
/* check other values */
|
||||||
if (bit_depth != 1 && bit_depth != 2 &&
|
if (bit_depth != 1 && bit_depth != 2 &&
|
||||||
bit_depth != 4 && bit_depth != 8 &&
|
bit_depth != 4 && bit_depth != 8 &&
|
||||||
bit_depth != 16)
|
bit_depth != 16)
|
||||||
png_error(png_ptr, "Invalid Bit Depth Found");
|
(*(png_ptr->error_fn))(png_ptr, "Invalid Bit Depth Found");
|
||||||
|
|
||||||
if (color_type < 0 || color_type == 1 ||
|
if (color_type < 0 || color_type == 1 ||
|
||||||
color_type == 5 || color_type > 6)
|
color_type == 5 || color_type > 6)
|
||||||
png_error(png_ptr, "Invalid Color Type Found");
|
(*(png_ptr->error_fn))(png_ptr, "Invalid Color Type Found");
|
||||||
|
|
||||||
if (color_type == PNG_COLOR_TYPE_PALETTE &&
|
if (color_type == PNG_COLOR_TYPE_PALETTE &&
|
||||||
bit_depth == 16)
|
bit_depth == 16)
|
||||||
png_error(png_ptr, "Found Invalid Color Type and Bit Depth Combination");
|
(*(png_ptr->error_fn))(png_ptr, "Found Invalid Color Type and Bit Depth Combination");
|
||||||
|
|
||||||
if ((color_type == PNG_COLOR_TYPE_RGB ||
|
if ((color_type == PNG_COLOR_TYPE_RGB ||
|
||||||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
|
color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
|
||||||
color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
|
color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
|
||||||
bit_depth < 8)
|
bit_depth < 8)
|
||||||
png_error(png_ptr, "Found Invalid Color Type and Bit Depth Combination");
|
(*(png_ptr->error_fn))(png_ptr, "Found Invalid Color Type and Bit Depth Combination");
|
||||||
|
|
||||||
if (interlace_type > 1)
|
if (interlace_type > 1)
|
||||||
png_error(png_ptr, "Found Invalid Interlace Value");
|
(*(png_ptr->error_fn))(png_ptr, "Found Unsupported Interlace Value");
|
||||||
|
|
||||||
if (compression_type > 0)
|
if (compression_type > 0)
|
||||||
png_error(png_ptr, "Found Invalid Compression Value");
|
(*(png_ptr->error_fn))(png_ptr, "Found Unsupported Compression Value");
|
||||||
|
|
||||||
if (filter_type > 0)
|
if (filter_type > 0)
|
||||||
png_error(png_ptr, "Found Invalid Filter Value");
|
(*(png_ptr->error_fn))(png_ptr, "Found Unsupported Filter Value");
|
||||||
|
|
||||||
/* set internal variables */
|
/* set internal variables */
|
||||||
png_ptr->width = width;
|
png_ptr->width = width;
|
||||||
@ -160,10 +160,12 @@ png_handle_PLTE(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
png_color *palette;
|
png_color *palette;
|
||||||
|
|
||||||
if (length % 3)
|
if (length % 3)
|
||||||
png_error(png_ptr, "Invalid Palette Chunk");
|
(*(png_ptr->error_fn))(png_ptr, "Invalid Palette Chunk");
|
||||||
|
|
||||||
num = (int)length / 3;
|
num = (int)length / 3;
|
||||||
palette = (png_color *)png_malloc(png_ptr, num * sizeof (png_color));
|
palette = (png_color *)png_malloc(png_ptr, num * sizeof (png_color));
|
||||||
|
png_ptr->do_free |= PNG_FREE_PALETTE;
|
||||||
|
|
||||||
for (i = 0; i < num; i++)
|
for (i = 0; i < num; i++)
|
||||||
{
|
{
|
||||||
png_byte buf[3];
|
png_byte buf[3];
|
||||||
@ -189,6 +191,7 @@ png_handle_gAMA(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
|
|
||||||
if (length != 4)
|
if (length != 4)
|
||||||
{
|
{
|
||||||
|
(*(png_ptr->warning_fn))(png_ptr,"Incorrect gAMA chunk length");
|
||||||
png_crc_skip(png_ptr, length);
|
png_crc_skip(png_ptr, length);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -210,6 +213,7 @@ void
|
|||||||
png_handle_sBIT(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
png_handle_sBIT(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
||||||
{
|
{
|
||||||
int slen;
|
int slen;
|
||||||
|
register int index = 0;
|
||||||
png_byte buf[4];
|
png_byte buf[4];
|
||||||
|
|
||||||
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
|
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
|
||||||
@ -219,6 +223,7 @@ png_handle_sBIT(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
|
|
||||||
if (length != (png_uint_32)slen)
|
if (length != (png_uint_32)slen)
|
||||||
{
|
{
|
||||||
|
(*(png_ptr->warning_fn))(png_ptr, "Incorrect sBIT chunk length");
|
||||||
png_crc_skip(png_ptr, length);
|
png_crc_skip(png_ptr, length);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -226,16 +231,28 @@ png_handle_sBIT(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
png_crc_read(png_ptr, buf, length);
|
png_crc_read(png_ptr, buf, length);
|
||||||
if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
|
if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
|
||||||
{
|
{
|
||||||
png_ptr->sig_bit.red = buf[0];
|
png_ptr->sig_bit.red = buf[index++];
|
||||||
png_ptr->sig_bit.green = buf[1];
|
png_ptr->sig_bit.green = buf[index++];
|
||||||
png_ptr->sig_bit.blue = buf[2];
|
png_ptr->sig_bit.blue = buf[index++];
|
||||||
png_ptr->sig_bit.alpha = buf[3];
|
png_ptr->sig_bit.gray = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
png_ptr->sig_bit.red = 0;
|
||||||
|
png_ptr->sig_bit.green = 0;
|
||||||
|
png_ptr->sig_bit.blue = 0;
|
||||||
png_ptr->sig_bit.gray = buf[0];
|
png_ptr->sig_bit.gray = buf[0];
|
||||||
png_ptr->sig_bit.alpha = buf[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)
|
||||||
|
{
|
||||||
|
png_ptr->sig_bit.alpha = buf[index++];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
png_ptr->sig_bit.alpha = 0;
|
||||||
|
}
|
||||||
|
|
||||||
png_read_sBIT(png_ptr, info, &(png_ptr->sig_bit));
|
png_read_sBIT(png_ptr, info, &(png_ptr->sig_bit));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -250,6 +267,7 @@ png_handle_cHRM(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
|
|
||||||
if (length != 32)
|
if (length != 32)
|
||||||
{
|
{
|
||||||
|
(*(png_ptr->warning_fn))(png_ptr, "Incorrect cHRM chunk length");
|
||||||
png_crc_skip(png_ptr, length);
|
png_crc_skip(png_ptr, length);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -299,11 +317,13 @@ png_handle_tRNS(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
{
|
{
|
||||||
if (length > png_ptr->num_palette)
|
if (length > png_ptr->num_palette)
|
||||||
{
|
{
|
||||||
|
(*(png_ptr->warning_fn))(png_ptr, "Incorrect tRNS chunk length");
|
||||||
png_crc_skip(png_ptr, length);
|
png_crc_skip(png_ptr, length);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
png_ptr->trans = png_malloc(png_ptr, length);
|
png_ptr->trans = png_malloc(png_ptr, length);
|
||||||
|
png_ptr->do_free |= PNG_FREE_TRANS;
|
||||||
png_crc_read(png_ptr, png_ptr->trans, length);
|
png_crc_read(png_ptr, png_ptr->trans, length);
|
||||||
png_ptr->num_trans = (int)length;
|
png_ptr->num_trans = (int)length;
|
||||||
}
|
}
|
||||||
@ -313,6 +333,7 @@ png_handle_tRNS(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
|
|
||||||
if (length != 6)
|
if (length != 6)
|
||||||
{
|
{
|
||||||
|
(*(png_ptr->warning_fn))(png_ptr, "Incorrect tRNS chunk length");
|
||||||
png_crc_skip(png_ptr, length);
|
png_crc_skip(png_ptr, length);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -329,6 +350,7 @@ png_handle_tRNS(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
|
|
||||||
if (length != 2)
|
if (length != 2)
|
||||||
{
|
{
|
||||||
|
(*(png_ptr->warning_fn))(png_ptr, "Incorrect tRNS chunk length");
|
||||||
png_crc_skip(png_ptr, length);
|
png_crc_skip(png_ptr, length);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -338,7 +360,7 @@ png_handle_tRNS(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
png_ptr->trans_values.gray = png_get_uint_16(buf);
|
png_ptr->trans_values.gray = png_get_uint_16(buf);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
png_error(png_ptr, "Invalid tRNS chunk");
|
(*(png_ptr->error_fn))(png_ptr, "Invalid tRNS chunk");
|
||||||
|
|
||||||
png_read_tRNS(png_ptr, info, png_ptr->trans, png_ptr->num_trans,
|
png_read_tRNS(png_ptr, info, png_ptr->trans, png_ptr->num_trans,
|
||||||
&(png_ptr->trans_values));
|
&(png_ptr->trans_values));
|
||||||
@ -361,6 +383,7 @@ png_handle_bKGD(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
|
|
||||||
if (length != (png_uint_32)truelen)
|
if (length != (png_uint_32)truelen)
|
||||||
{
|
{
|
||||||
|
(*(png_ptr->warning_fn))(png_ptr, "Incorrect bKGD chunk length");
|
||||||
png_crc_skip(png_ptr, length);
|
png_crc_skip(png_ptr, length);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -389,12 +412,15 @@ png_handle_hIST(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
|
|
||||||
if (length != 2 * png_ptr->num_palette)
|
if (length != 2 * png_ptr->num_palette)
|
||||||
{
|
{
|
||||||
|
(*(png_ptr->warning_fn))(png_ptr, "Incorrect hIST chunk length");
|
||||||
png_crc_skip(png_ptr, length);
|
png_crc_skip(png_ptr, length);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
num = (int)length / 2;
|
num = (int)length / 2;
|
||||||
png_ptr->hist = png_malloc(png_ptr, num * sizeof (png_uint_16));
|
png_ptr->hist = png_malloc(png_ptr, num * sizeof (png_uint_16));
|
||||||
|
png_ptr->do_free |= PNG_FREE_HIST;
|
||||||
|
|
||||||
for (i = 0; i < num; i++)
|
for (i = 0; i < num; i++)
|
||||||
{
|
{
|
||||||
png_byte buf[2];
|
png_byte buf[2];
|
||||||
@ -416,6 +442,7 @@ png_handle_pHYs(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
|
|
||||||
if (length != 9)
|
if (length != 9)
|
||||||
{
|
{
|
||||||
|
(*(png_ptr->warning_fn))(png_ptr, "Incorrect pHYS chunk length");
|
||||||
png_crc_skip(png_ptr, length);
|
png_crc_skip(png_ptr, length);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -439,6 +466,7 @@ png_handle_oFFs(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
|
|
||||||
if (length != 9)
|
if (length != 9)
|
||||||
{
|
{
|
||||||
|
(*(png_ptr->warning_fn))(png_ptr, "Incorrect oFFs chunk length");
|
||||||
png_crc_skip(png_ptr, length);
|
png_crc_skip(png_ptr, length);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -461,6 +489,7 @@ png_handle_tIME(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
|
|
||||||
if (length != 7)
|
if (length != 7)
|
||||||
{
|
{
|
||||||
|
(*(png_ptr->warning_fn))(png_ptr, "Incorrect tIME chunk length");
|
||||||
png_crc_skip(png_ptr, length);
|
png_crc_skip(png_ptr, length);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -509,7 +538,7 @@ png_handle_zTXt(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
{
|
{
|
||||||
charf *key;
|
charf *key;
|
||||||
charf *text;
|
charf *text;
|
||||||
int ret;
|
int ret = Z_STREAM_END;
|
||||||
png_uint_32 text_size, key_size;
|
png_uint_32 text_size, key_size;
|
||||||
|
|
||||||
text = NULL;
|
text = NULL;
|
||||||
@ -524,6 +553,7 @@ png_handle_zTXt(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
/* zTXt can't have zero text */
|
/* zTXt can't have zero text */
|
||||||
if (text == key + (png_size_t)length)
|
if (text == key + (png_size_t)length)
|
||||||
{
|
{
|
||||||
|
(*(png_ptr->warning_fn))(png_ptr, "Zero length zTXt chunk");
|
||||||
png_large_free(png_ptr, key);
|
png_large_free(png_ptr, key);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -552,6 +582,10 @@ png_handle_zTXt(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
ret = inflate(png_ptr->zstream, Z_PARTIAL_FLUSH);
|
ret = inflate(png_ptr->zstream, Z_PARTIAL_FLUSH);
|
||||||
if (ret != Z_OK && ret != Z_STREAM_END)
|
if (ret != Z_OK && ret != Z_STREAM_END)
|
||||||
{
|
{
|
||||||
|
if (png_ptr->zstream->msg)
|
||||||
|
(*(png_ptr->warning_fn))(png_ptr,png_ptr->zstream->msg);
|
||||||
|
else
|
||||||
|
(*(png_ptr->warning_fn))(png_ptr,"zTXt decompression error");
|
||||||
inflateReset(png_ptr->zstream);
|
inflateReset(png_ptr->zstream);
|
||||||
png_ptr->zstream->avail_in = 0;
|
png_ptr->zstream->avail_in = 0;
|
||||||
png_large_free(png_ptr, key);
|
png_large_free(png_ptr, key);
|
||||||
@ -1104,19 +1138,19 @@ png_read_finish_row(png_struct *png_ptr)
|
|||||||
png_byte buf[4];
|
png_byte buf[4];
|
||||||
png_uint_32 crc;
|
png_uint_32 crc;
|
||||||
|
|
||||||
png_read_data(png_ptr, buf, 4);
|
(*(png_ptr->read_data_fn))(png_ptr, buf, 4);
|
||||||
crc = png_get_uint_32(buf);
|
crc = png_get_uint_32(buf);
|
||||||
if (((crc ^ 0xffffffffL) & 0xffffffffL) !=
|
if (((crc ^ 0xffffffffL) & 0xffffffffL) !=
|
||||||
(png_ptr->crc & 0xffffffffL))
|
(png_ptr->crc & 0xffffffffL))
|
||||||
png_error(png_ptr, "Bad CRC value");
|
(*(png_ptr->error_fn))(png_ptr, "Bad CRC value");
|
||||||
|
|
||||||
png_read_data(png_ptr, buf, 4);
|
(*(png_ptr->read_data_fn))(png_ptr, buf, 4);
|
||||||
png_ptr->idat_size = png_get_uint_32(buf);
|
png_ptr->idat_size = png_get_uint_32(buf);
|
||||||
png_reset_crc(png_ptr);
|
png_reset_crc(png_ptr);
|
||||||
|
|
||||||
png_crc_read(png_ptr, buf, 4);
|
png_crc_read(png_ptr, buf, 4);
|
||||||
if (memcmp(buf, png_IDAT, 4))
|
if (memcmp(buf, png_IDAT, 4))
|
||||||
png_error(png_ptr, "Not enough image data");
|
(*(png_ptr->error_fn))(png_ptr, "Not enough image data");
|
||||||
|
|
||||||
}
|
}
|
||||||
png_ptr->zstream->avail_in = (uInt)png_ptr->zbuf_size;
|
png_ptr->zstream->avail_in = (uInt)png_ptr->zbuf_size;
|
||||||
@ -1131,22 +1165,22 @@ png_read_finish_row(png_struct *png_ptr)
|
|||||||
{
|
{
|
||||||
if (!(png_ptr->zstream->avail_out) || png_ptr->zstream->avail_in ||
|
if (!(png_ptr->zstream->avail_out) || png_ptr->zstream->avail_in ||
|
||||||
png_ptr->idat_size)
|
png_ptr->idat_size)
|
||||||
png_error(png_ptr, "Extra compressed data");
|
(*(png_ptr->warning_fn))(png_ptr, "Extra compressed data");
|
||||||
png_ptr->mode = PNG_AT_LAST_IDAT;
|
png_ptr->mode = PNG_AT_LAST_IDAT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ret != Z_OK)
|
if (ret != Z_OK)
|
||||||
png_error(png_ptr, "Compression Error");
|
(*(png_ptr->error_fn))(png_ptr, "Compression Error");
|
||||||
|
|
||||||
if (!(png_ptr->zstream->avail_out))
|
if (!(png_ptr->zstream->avail_out))
|
||||||
png_error(png_ptr, "Extra compressed data");
|
(*(png_ptr->error_fn))(png_ptr, "Extra compressed data");
|
||||||
|
|
||||||
} while (1);
|
} while (1);
|
||||||
png_ptr->zstream->avail_out = 0;
|
png_ptr->zstream->avail_out = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (png_ptr->idat_size || png_ptr->zstream->avail_in)
|
if (png_ptr->idat_size || png_ptr->zstream->avail_in)
|
||||||
png_error(png_ptr, "Extra compression data");
|
(*(png_ptr->warning_fn))(png_ptr, "Extra compression data");
|
||||||
|
|
||||||
inflateReset(png_ptr->zstream);
|
inflateReset(png_ptr->zstream);
|
||||||
|
|
||||||
@ -1258,13 +1292,13 @@ png_read_start_row(png_struct *png_ptr)
|
|||||||
1 + ((max_pixel_depth + 7) >> 3);
|
1 + ((max_pixel_depth + 7) >> 3);
|
||||||
#ifdef PNG_MAX_MALLOC_64K
|
#ifdef PNG_MAX_MALLOC_64K
|
||||||
if (rowbytes > 65536L)
|
if (rowbytes > 65536L)
|
||||||
png_error(png_ptr, "This image requires a row greater then 64KB");
|
(*(png_ptr->error_fn))(png_ptr, "This image requires a row greater then 64KB");
|
||||||
#endif
|
#endif
|
||||||
png_ptr->row_buf = (png_bytef *)png_large_malloc(png_ptr, rowbytes);
|
png_ptr->row_buf = (png_bytef *)png_large_malloc(png_ptr, rowbytes);
|
||||||
|
|
||||||
#ifdef PNG_MAX_MALLOC_64K
|
#ifdef PNG_MAX_MALLOC_64K
|
||||||
if (png_ptr->rowbytes + 1 > 65536L)
|
if (png_ptr->rowbytes + 1 > 65536L)
|
||||||
png_error(png_ptr, "This image requires a row greater then 64KB");
|
(*(png_ptr->error_fn))(png_ptr, "This image requires a row greater then 64KB");
|
||||||
#endif
|
#endif
|
||||||
png_ptr->prev_row = png_large_malloc(png_ptr,
|
png_ptr->prev_row = png_large_malloc(png_ptr,
|
||||||
png_ptr->rowbytes + 1);
|
png_ptr->rowbytes + 1);
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
/* input and output filenames */
|
/* input and output filenames */
|
||||||
char inname[] = "pngtest.png";
|
char inname[] = "pngtest.png";
|
||||||
char outname[] = "pngout.png";
|
char outname[] = "testout.png";
|
||||||
|
|
||||||
png_struct read_ptr;
|
png_struct read_ptr;
|
||||||
png_struct write_ptr;
|
png_struct write_ptr;
|
||||||
@ -79,10 +79,10 @@ int main()
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
png_read_init(&read_ptr);
|
|
||||||
png_write_init(&write_ptr);
|
|
||||||
png_info_init(&info_ptr);
|
png_info_init(&info_ptr);
|
||||||
png_info_init(&end_info);
|
png_info_init(&end_info);
|
||||||
|
png_read_init(&read_ptr);
|
||||||
|
png_write_init(&write_ptr);
|
||||||
|
|
||||||
png_init_io(&read_ptr, fpin);
|
png_init_io(&read_ptr, fpin);
|
||||||
png_init_io(&write_ptr, fpout);
|
png_init_io(&write_ptr, fpout);
|
||||||
@ -97,6 +97,9 @@ int main()
|
|||||||
if (info_ptr.color_type & 4)
|
if (info_ptr.color_type & 4)
|
||||||
channels++;
|
channels++;
|
||||||
|
|
||||||
|
png_set_flush(&write_ptr, 20);
|
||||||
|
png_set_compression_level(&write_ptr, 9);
|
||||||
|
|
||||||
rowbytes = ((info_ptr.width * info_ptr.bit_depth * channels + 7) >> 3);
|
rowbytes = ((info_ptr.width * info_ptr.bit_depth * channels + 7) >> 3);
|
||||||
row_buf = (png_byte *)malloc((size_t)rowbytes);
|
row_buf = (png_byte *)malloc((size_t)rowbytes);
|
||||||
if (!row_buf)
|
if (!row_buf)
|
||||||
|
107
pngwrite.c
107
pngwrite.c
@ -57,25 +57,30 @@ png_write_info(png_struct *png_ptr, png_info *info)
|
|||||||
if (info->valid & PNG_INFO_bKGD)
|
if (info->valid & PNG_INFO_bKGD)
|
||||||
png_write_bKGD(png_ptr, &(info->background), info->color_type);
|
png_write_bKGD(png_ptr, &(info->background), info->color_type);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_WRITE_hIST_SUPPORTED)
|
#if defined(PNG_WRITE_hIST_SUPPORTED)
|
||||||
if (info->valid & PNG_INFO_hIST)
|
if (info->valid & PNG_INFO_hIST)
|
||||||
png_write_hIST(png_ptr, info->hist, info->num_palette);
|
png_write_hIST(png_ptr, info->hist, info->num_palette);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_WRITE_pHYs_SUPPORTED)
|
#if defined(PNG_WRITE_pHYs_SUPPORTED)
|
||||||
if (info->valid & PNG_INFO_pHYs)
|
if (info->valid & PNG_INFO_pHYs)
|
||||||
png_write_pHYs(png_ptr, info->x_pixels_per_unit,
|
png_write_pHYs(png_ptr, info->x_pixels_per_unit,
|
||||||
info->y_pixels_per_unit, info->phys_unit_type);
|
info->y_pixels_per_unit, info->phys_unit_type);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_WRITE_oFFs_SUPPORTED)
|
#if defined(PNG_WRITE_oFFs_SUPPORTED)
|
||||||
if (info->valid & PNG_INFO_oFFs)
|
if (info->valid & PNG_INFO_oFFs)
|
||||||
png_write_oFFs(png_ptr, info->x_offset, info->y_offset,
|
png_write_oFFs(png_ptr, info->x_offset, info->y_offset,
|
||||||
info->offset_unit_type);
|
info->offset_unit_type);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_WRITE_tIME_SUPPORTED)
|
#if defined(PNG_WRITE_tIME_SUPPORTED)
|
||||||
if (info->valid & PNG_INFO_tIME)
|
if (info->valid & PNG_INFO_tIME)
|
||||||
png_write_tIME(png_ptr, &(info->mod_time));
|
png_write_tIME(png_ptr, &(info->mod_time));
|
||||||
/* Check to see if we need to write text chunks */
|
/* Check to see if we need to write text chunks */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
|
#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
|
||||||
if (info->num_text)
|
if (info->num_text)
|
||||||
{
|
{
|
||||||
@ -84,6 +89,12 @@ png_write_info(png_struct *png_ptr, png_info *info)
|
|||||||
/* loop through the text chunks */
|
/* loop through the text chunks */
|
||||||
for (i = 0; i < info->num_text; i++)
|
for (i = 0; i < info->num_text; i++)
|
||||||
{
|
{
|
||||||
|
if (strlen(info->text[i].key) > 80)
|
||||||
|
{
|
||||||
|
(*(png_ptr->warning_fn))(png_ptr,"tEXt keyword more than 80 chars");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* if chunk is compressed */
|
/* if chunk is compressed */
|
||||||
if (info->text[i].compression >= 0)
|
if (info->text[i].compression >= 0)
|
||||||
{
|
{
|
||||||
@ -104,7 +115,8 @@ png_write_info(png_struct *png_ptr, png_info *info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* PNG_WRITE_tEXt_SUPPORTED || PNG_WRITE_zTXt_SUPPORTED */
|
||||||
|
png_ptr->mode = PNG_HAVE_IHDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* writes the end of the png file. If you don't want to write comments or
|
/* writes the end of the png file. If you don't want to write comments or
|
||||||
@ -114,6 +126,9 @@ png_write_info(png_struct *png_ptr, png_info *info)
|
|||||||
void
|
void
|
||||||
png_write_end(png_struct *png_ptr, png_info *info)
|
png_write_end(png_struct *png_ptr, png_info *info)
|
||||||
{
|
{
|
||||||
|
if (info && png_ptr->mode == PNG_AFTER_IEND)
|
||||||
|
return;
|
||||||
|
|
||||||
/* see if user wants us to write information chunks */
|
/* see if user wants us to write information chunks */
|
||||||
if (info)
|
if (info)
|
||||||
{
|
{
|
||||||
@ -122,6 +137,7 @@ png_write_end(png_struct *png_ptr, png_info *info)
|
|||||||
if (info->valid & PNG_INFO_tIME)
|
if (info->valid & PNG_INFO_tIME)
|
||||||
png_write_tIME(png_ptr, &(info->mod_time));
|
png_write_tIME(png_ptr, &(info->mod_time));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
|
#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
|
||||||
/* check to see if we need to write comment chunks */
|
/* check to see if we need to write comment chunks */
|
||||||
if (info->num_text)
|
if (info->num_text)
|
||||||
@ -151,10 +167,12 @@ png_write_end(png_struct *png_ptr, png_info *info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* PNG_WRITE_tEXt_SUPPORTED || PNG_WRITE_zTXt_SUPPORTED */
|
||||||
}
|
}
|
||||||
/* write end of png file */
|
/* write end of png file */
|
||||||
png_write_IEND(png_ptr);
|
png_write_IEND(png_ptr);
|
||||||
|
|
||||||
|
png_ptr->mode = PNG_AFTER_IEND;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(PNG_WRITE_tIME_SUPPORTED)
|
#if defined(PNG_WRITE_tIME_SUPPORTED)
|
||||||
@ -177,7 +195,7 @@ png_convert_from_time_t(png_time *ptime, time_t ttime)
|
|||||||
tbuf = gmtime(&ttime);
|
tbuf = gmtime(&ttime);
|
||||||
png_convert_from_struct_tm(ptime, tbuf);
|
png_convert_from_struct_tm(ptime, tbuf);
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* PNG_WRITE_tIME_SUPPORTED */
|
||||||
|
|
||||||
/* initialize png structure, and allocate any memory needed */
|
/* initialize png structure, and allocate any memory needed */
|
||||||
void
|
void
|
||||||
@ -243,11 +261,13 @@ void
|
|||||||
png_write_row(png_struct *png_ptr, png_bytef *row)
|
png_write_row(png_struct *png_ptr, png_bytef *row)
|
||||||
{
|
{
|
||||||
/* initialize transformations and other stuff if first time */
|
/* initialize transformations and other stuff if first time */
|
||||||
if (png_ptr->row_number == 0 && png_ptr->pass == 0)
|
if (png_ptr->mode < PNG_HAVE_IDAT)
|
||||||
{
|
{
|
||||||
png_write_start_row(png_ptr);
|
png_write_start_row(png_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
png_ptr->mode = PNG_HAVE_IDAT;
|
||||||
|
|
||||||
#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
|
#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
|
||||||
/* if interlaced and not interested in row, return */
|
/* if interlaced and not interested in row, return */
|
||||||
if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
|
if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
|
||||||
@ -305,7 +325,7 @@ png_write_row(png_struct *png_ptr, png_bytef *row)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* PNG_WRITE_INTERLACE_SUPPORTED */
|
||||||
|
|
||||||
/* set up row info for transformations */
|
/* set up row info for transformations */
|
||||||
png_ptr->row_info.color_type = png_ptr->color_type;
|
png_ptr->row_info.color_type = png_ptr->color_type;
|
||||||
@ -334,7 +354,7 @@ png_write_row(png_struct *png_ptr, png_bytef *row)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* PNG_WRITE_INTERLACE_SUPPORTED */
|
||||||
|
|
||||||
/* handle other transformations */
|
/* handle other transformations */
|
||||||
if (png_ptr->transformations)
|
if (png_ptr->transformations)
|
||||||
@ -367,6 +387,7 @@ png_write_row(png_struct *png_ptr, png_bytef *row)
|
|||||||
/* set up the zlib input buffer */
|
/* set up the zlib input buffer */
|
||||||
png_ptr->zstream->next_in = png_ptr->row_buf;
|
png_ptr->zstream->next_in = png_ptr->row_buf;
|
||||||
png_ptr->zstream->avail_in = (uInt)png_ptr->row_info.rowbytes + 1;
|
png_ptr->zstream->avail_in = (uInt)png_ptr->row_info.rowbytes + 1;
|
||||||
|
|
||||||
/* repeat until we have compressed all the data */
|
/* repeat until we have compressed all the data */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -378,9 +399,9 @@ png_write_row(png_struct *png_ptr, png_bytef *row)
|
|||||||
if (ret != Z_OK)
|
if (ret != Z_OK)
|
||||||
{
|
{
|
||||||
if (png_ptr->zstream->msg)
|
if (png_ptr->zstream->msg)
|
||||||
png_error(png_ptr, png_ptr->zstream->msg);
|
(*(png_ptr->error_fn))(png_ptr, png_ptr->zstream->msg);
|
||||||
else
|
else
|
||||||
png_error(png_ptr, "zlib error");
|
(*(png_ptr->error_fn))(png_ptr, "zlib error");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* see if it is time to write another IDAT */
|
/* see if it is time to write another IDAT */
|
||||||
@ -396,8 +417,77 @@ png_write_row(png_struct *png_ptr, png_bytef *row)
|
|||||||
|
|
||||||
/* finish row - updates counters and flushes zlib if last row */
|
/* finish row - updates counters and flushes zlib if last row */
|
||||||
png_write_finish_row(png_ptr);
|
png_write_finish_row(png_ptr);
|
||||||
|
|
||||||
|
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
|
||||||
|
png_ptr->flush_rows++;
|
||||||
|
|
||||||
|
if (png_ptr->flush_dist > 0 &&
|
||||||
|
png_ptr->flush_rows >= png_ptr->flush_dist)
|
||||||
|
{
|
||||||
|
png_write_flush(png_ptr);
|
||||||
|
}
|
||||||
|
#endif /* PNG_WRITE_FLUSH_SUPPORTED */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
|
||||||
|
/* Set the automatic flush interval or 0 to turn flushing off */
|
||||||
|
void
|
||||||
|
png_set_flush(png_struct *png_ptr, int nrows)
|
||||||
|
{
|
||||||
|
png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* flush the current output buffers now */
|
||||||
|
void
|
||||||
|
png_write_flush(png_struct *png_ptr)
|
||||||
|
{
|
||||||
|
char wrote_IDAT;
|
||||||
|
|
||||||
|
if (png_ptr->mode != PNG_HAVE_IDAT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* compress the data */
|
||||||
|
ret = deflate(png_ptr->zstream, Z_SYNC_FLUSH);
|
||||||
|
wrote_IDAT = 0;
|
||||||
|
|
||||||
|
/* check for compression errors */
|
||||||
|
if (ret != Z_OK)
|
||||||
|
{
|
||||||
|
if (png_ptr->zstream->msg)
|
||||||
|
(*(png_ptr->error_fn))(png_ptr, png_ptr->zstream->msg);
|
||||||
|
else
|
||||||
|
(*(png_ptr->error_fn))(png_ptr, "zlib error");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!png_ptr->zstream->avail_out)
|
||||||
|
{
|
||||||
|
/* write the IDAT and reset the zlib output buffer */
|
||||||
|
png_write_IDAT(png_ptr, png_ptr->zbuf,
|
||||||
|
png_ptr->zbuf_size);
|
||||||
|
png_ptr->zstream->next_out = png_ptr->zbuf;
|
||||||
|
png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
|
||||||
|
wrote_IDAT = 1;
|
||||||
|
}
|
||||||
|
} while(wrote_IDAT == 1);
|
||||||
|
|
||||||
|
/* If there is any data left to be output, write it into a new IDAT */
|
||||||
|
if (png_ptr->zbuf_size != png_ptr->zstream->avail_out)
|
||||||
|
{
|
||||||
|
/* write the IDAT and reset the zlib output buffer */
|
||||||
|
png_write_IDAT(png_ptr, png_ptr->zbuf,
|
||||||
|
png_ptr->zbuf_size - png_ptr->zstream->avail_out);
|
||||||
|
png_ptr->zstream->next_out = png_ptr->zbuf;
|
||||||
|
png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
|
||||||
|
}
|
||||||
|
png_ptr->flush_rows = 0;
|
||||||
|
(*(png_ptr->output_flush_fn))(png_ptr);
|
||||||
|
}
|
||||||
|
#endif /* PNG_WRITE_FLUSH_SUPPORTED */
|
||||||
|
|
||||||
/* free any memory used in png struct */
|
/* free any memory used in png struct */
|
||||||
void
|
void
|
||||||
png_write_destroy(png_struct *png_ptr)
|
png_write_destroy(png_struct *png_ptr)
|
||||||
@ -416,6 +506,7 @@ png_write_destroy(png_struct *png_ptr)
|
|||||||
png_memset(png_ptr, 0, sizeof (png_struct));
|
png_memset(png_ptr, 0, sizeof (png_struct));
|
||||||
png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
|
png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
png_set_filtering(png_struct *png_ptr, int filter)
|
png_set_filtering(png_struct *png_ptr, int filter)
|
||||||
{
|
{
|
||||||
|
29
pngwutil.c
29
pngwutil.c
@ -39,7 +39,7 @@ png_write_uint_32(png_struct *png_ptr, png_uint_32 i)
|
|||||||
buf[1] = (png_byte)((i >> 16) & 0xff);
|
buf[1] = (png_byte)((i >> 16) & 0xff);
|
||||||
buf[2] = (png_byte)((i >> 8) & 0xff);
|
buf[2] = (png_byte)((i >> 8) & 0xff);
|
||||||
buf[3] = (png_byte)(i & 0xff);
|
buf[3] = (png_byte)(i & 0xff);
|
||||||
png_write_data(png_ptr, buf, 4);
|
(*(png_ptr->write_data_fn))(png_ptr, buf, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write a 16 bit number */
|
/* write a 16 bit number */
|
||||||
@ -50,7 +50,7 @@ png_write_uint_16(png_struct *png_ptr, png_uint_16 i)
|
|||||||
|
|
||||||
buf[0] = (png_byte)((i >> 8) & 0xff);
|
buf[0] = (png_byte)((i >> 8) & 0xff);
|
||||||
buf[1] = (png_byte)(i & 0xff);
|
buf[1] = (png_byte)(i & 0xff);
|
||||||
png_write_data(png_ptr, buf, 2);
|
(*(png_ptr->write_data_fn))(png_ptr, buf, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write a png chunk all at once. The type is an array of ASCII characters
|
/* Write a png chunk all at once. The type is an array of ASCII characters
|
||||||
@ -68,7 +68,7 @@ png_write_chunk(png_struct *png_ptr, png_byte *type,
|
|||||||
/* write length */
|
/* write length */
|
||||||
png_write_uint_32(png_ptr, length);
|
png_write_uint_32(png_ptr, length);
|
||||||
/* write chunk name */
|
/* write chunk name */
|
||||||
png_write_data(png_ptr, type, (png_uint_32)4);
|
(*(png_ptr->write_data_fn))(png_ptr, type, (png_uint_32)4);
|
||||||
/* reset the crc and run the chunk name over it */
|
/* reset the crc and run the chunk name over it */
|
||||||
png_reset_crc(png_ptr);
|
png_reset_crc(png_ptr);
|
||||||
png_calculate_crc(png_ptr, type, (png_uint_32)4);
|
png_calculate_crc(png_ptr, type, (png_uint_32)4);
|
||||||
@ -76,7 +76,7 @@ png_write_chunk(png_struct *png_ptr, png_byte *type,
|
|||||||
if (length)
|
if (length)
|
||||||
{
|
{
|
||||||
png_calculate_crc(png_ptr, data, length);
|
png_calculate_crc(png_ptr, data, length);
|
||||||
png_write_data(png_ptr, data, length);
|
(*(png_ptr->write_data_fn))(png_ptr, data, length);
|
||||||
}
|
}
|
||||||
/* write the crc */
|
/* write the crc */
|
||||||
png_write_uint_32(png_ptr, ~png_ptr->crc);
|
png_write_uint_32(png_ptr, ~png_ptr->crc);
|
||||||
@ -92,7 +92,7 @@ png_write_chunk_start(png_struct *png_ptr, png_byte *type,
|
|||||||
/* write the length */
|
/* write the length */
|
||||||
png_write_uint_32(png_ptr, total_length);
|
png_write_uint_32(png_ptr, total_length);
|
||||||
/* write the chunk name */
|
/* write the chunk name */
|
||||||
png_write_data(png_ptr, type, (png_uint_32)4);
|
(*(png_ptr->write_data_fn))(png_ptr, type, (png_uint_32)4);
|
||||||
/* reset the crc and run it over the chunk name */
|
/* reset the crc and run it over the chunk name */
|
||||||
png_reset_crc(png_ptr);
|
png_reset_crc(png_ptr);
|
||||||
png_calculate_crc(png_ptr, type, (png_uint_32)4);
|
png_calculate_crc(png_ptr, type, (png_uint_32)4);
|
||||||
@ -109,7 +109,7 @@ png_write_chunk_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length)
|
|||||||
if (length)
|
if (length)
|
||||||
{
|
{
|
||||||
png_calculate_crc(png_ptr, data, length);
|
png_calculate_crc(png_ptr, data, length);
|
||||||
png_write_data(png_ptr, data, length);
|
(*(png_ptr->write_data_fn))(png_ptr, data, length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ void
|
|||||||
png_write_sig(png_struct *png_ptr)
|
png_write_sig(png_struct *png_ptr)
|
||||||
{
|
{
|
||||||
/* write the 8 byte signature */
|
/* write the 8 byte signature */
|
||||||
png_write_data(png_ptr, png_sig, (png_uint_32)8);
|
(*(png_ptr->write_data_fn))(png_ptr, png_sig, (png_uint_32)8);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write the IHDR chunk, and update the png_struct with the necessary
|
/* Write the IHDR chunk, and update the png_struct with the necessary
|
||||||
@ -462,9 +462,9 @@ png_write_zTXt(png_struct *png_ptr, charf *key, charf *text,
|
|||||||
{
|
{
|
||||||
/* error */
|
/* error */
|
||||||
if (png_ptr->zstream->msg)
|
if (png_ptr->zstream->msg)
|
||||||
png_error(png_ptr, png_ptr->zstream->msg);
|
(*(png_ptr->error_fn))(png_ptr, png_ptr->zstream->msg);
|
||||||
else
|
else
|
||||||
png_error(png_ptr, "zlib error");
|
(*(png_ptr->error_fn))(png_ptr, "zlib error");
|
||||||
}
|
}
|
||||||
/* check to see if we need more room */
|
/* check to see if we need more room */
|
||||||
if (!png_ptr->zstream->avail_out && png_ptr->zstream->avail_in)
|
if (!png_ptr->zstream->avail_out && png_ptr->zstream->avail_in)
|
||||||
@ -508,9 +508,9 @@ png_write_zTXt(png_struct *png_ptr, charf *key, charf *text,
|
|||||||
{
|
{
|
||||||
/* we got an error */
|
/* we got an error */
|
||||||
if (png_ptr->zstream->msg)
|
if (png_ptr->zstream->msg)
|
||||||
png_error(png_ptr, png_ptr->zstream->msg);
|
(*(png_ptr->error_fn))(png_ptr, png_ptr->zstream->msg);
|
||||||
else
|
else
|
||||||
png_error(png_ptr, "zlib error");
|
(*(png_ptr->error_fn))(png_ptr, "zlib error");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check to see if we need more room */
|
/* check to see if we need more room */
|
||||||
@ -689,7 +689,7 @@ png_write_finish_row(png_struct *png_ptr)
|
|||||||
/* next row */
|
/* next row */
|
||||||
png_ptr->row_number++;
|
png_ptr->row_number++;
|
||||||
/* see if we are done */
|
/* see if we are done */
|
||||||
if (png_ptr->row_number < png_ptr->num_rows)
|
if (png_ptr->row_number < png_ptr->num_rows || png_ptr->mode > PNG_HAVE_IDAT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* if interlaced, go to next pass */
|
/* if interlaced, go to next pass */
|
||||||
@ -740,9 +740,9 @@ png_write_finish_row(png_struct *png_ptr)
|
|||||||
if (ret != Z_OK && ret != Z_STREAM_END)
|
if (ret != Z_OK && ret != Z_STREAM_END)
|
||||||
{
|
{
|
||||||
if (png_ptr->zstream->msg)
|
if (png_ptr->zstream->msg)
|
||||||
png_error(png_ptr, png_ptr->zstream->msg);
|
(*(png_ptr->error_fn))(png_ptr, png_ptr->zstream->msg);
|
||||||
else
|
else
|
||||||
png_error(png_ptr, "zlib error");
|
(*(png_ptr->error_fn))(png_ptr, "zlib error");
|
||||||
}
|
}
|
||||||
/* check to see if we need more room */
|
/* check to see if we need more room */
|
||||||
if (!png_ptr->zstream->avail_out && ret == Z_OK)
|
if (!png_ptr->zstream->avail_out && ret == Z_OK)
|
||||||
@ -761,6 +761,7 @@ png_write_finish_row(png_struct *png_ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
deflateReset(png_ptr->zstream);
|
deflateReset(png_ptr->zstream);
|
||||||
|
png_ptr->mode = PNG_AFTER_IDAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
|
#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
|
||||||
|
Reference in New Issue
Block a user