Imported from libpng-0.85.tar
This commit is contained in:
parent
0f71645dfe
commit
6d76471acd
2
build.bat
Normal file
2
build.bat
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
make -fmakefile.bor -B -DMODEL=m %1 %2 %3 libpng >buildm.out
|
||||||
|
make -fmakefile.bor -B -DMODEL=l %1 %2 %3 libpng >buildl.out
|
193
example.c
193
example.c
@ -15,7 +15,7 @@
|
|||||||
#include <png.h>
|
#include <png.h>
|
||||||
|
|
||||||
/* check to see if a file is a png file using png_check_sig() */
|
/* check to see if a file is a png file using png_check_sig() */
|
||||||
int check_png(char *file_name)
|
int check_png(char * file_name)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char buf[8];
|
char buf[8];
|
||||||
@ -40,8 +40,8 @@ int check_png(char *file_name)
|
|||||||
void read_png(char *file_name)
|
void read_png(char *file_name)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
png_struct *png_ptr;
|
png_structp png_ptr;
|
||||||
png_info *info_ptr;
|
png_infop info_ptr;
|
||||||
|
|
||||||
/* open the file */
|
/* open the file */
|
||||||
fp = fopen(file_name, "rb");
|
fp = fopen(file_name, "rb");
|
||||||
@ -79,19 +79,9 @@ 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 for the default input and message functions.
|
/* set up the input control */
|
||||||
* 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);
|
||||||
|
|
||||||
@ -117,10 +107,10 @@ void read_png(char *file_name)
|
|||||||
|
|
||||||
if (info_ptr->valid & PNG_INFO_bKGD)
|
if (info_ptr->valid & PNG_INFO_bKGD)
|
||||||
png_set_background(png_ptr, &(info_ptr->background),
|
png_set_background(png_ptr, &(info_ptr->background),
|
||||||
PNG_GAMMA_FILE, 1, 1.0);
|
PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
|
||||||
else
|
else
|
||||||
png_set_background(png_ptr, &my_background,
|
png_set_background(png_ptr, &my_background,
|
||||||
PNG_GAMMA_SCREEN, 0, 1.0);
|
PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
|
||||||
|
|
||||||
/* tell libpng to handle the gamma conversion for you */
|
/* tell libpng to handle the gamma conversion for you */
|
||||||
if (info_ptr->valid & PNG_INFO_gAMA)
|
if (info_ptr->valid & PNG_INFO_gAMA)
|
||||||
@ -156,7 +146,8 @@ 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 */
|
||||||
@ -193,7 +184,7 @@ void read_png(char *file_name)
|
|||||||
of png_info. */
|
of png_info. */
|
||||||
|
|
||||||
/* the easiest way to read the image */
|
/* the easiest way to read the image */
|
||||||
png_bytef *row_pointers[height];
|
png_bytep row_pointers[height];
|
||||||
png_read_image(png_ptr, row_pointers);
|
png_read_image(png_ptr, row_pointers);
|
||||||
|
|
||||||
/* the other way to read images - deal with interlacing */
|
/* the other way to read images - deal with interlacing */
|
||||||
@ -206,7 +197,7 @@ void read_png(char *file_name)
|
|||||||
/* If you are only reading on row at a time, this works */
|
/* If you are only reading on row at a time, this works */
|
||||||
for (y = 0; y < height; y++)
|
for (y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
png_bytef *row_pointers = row[y];
|
png_bytep row_pointers = row[y];
|
||||||
png_read_rows(png_ptr, &row_pointers, NULL, 1);
|
png_read_rows(png_ptr, &row_pointers, NULL, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,13 +212,8 @@ 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_infop)0);
|
||||||
|
|
||||||
/* free the structures */
|
/* free the structures */
|
||||||
free(png_ptr);
|
free(png_ptr);
|
||||||
@ -240,12 +226,129 @@ void read_png(char *file_name)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* progressively read a file */
|
||||||
|
|
||||||
|
/* these will normally not be global unless you are only
|
||||||
|
reading in one image at a time */
|
||||||
|
png_structp png_ptr;
|
||||||
|
png_infop info_ptr;
|
||||||
|
|
||||||
|
int
|
||||||
|
initialize_png_reader()
|
||||||
|
{
|
||||||
|
png_ptr = malloc(sizeof (png_struct));
|
||||||
|
if (!png_ptr)
|
||||||
|
return -1;
|
||||||
|
info_ptr = malloc(sizeof (png_info));
|
||||||
|
if (!info_ptr)
|
||||||
|
{
|
||||||
|
free(png_ptr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setjmp(png_ptr->jmpbuf))
|
||||||
|
{
|
||||||
|
png_read_destroy(png_ptr, info_ptr, (png_info *)0);
|
||||||
|
/* free pointers before returning, if necessary */
|
||||||
|
free(png_ptr);
|
||||||
|
free(info_ptr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
png_info_init(info_ptr);
|
||||||
|
png_read_init(png_ptr);
|
||||||
|
|
||||||
|
/* this one's new. You will need to provide all three
|
||||||
|
function callbacks, even if you aren't using them all.
|
||||||
|
You can put a void pointer in place of the NULL, and
|
||||||
|
retrieve the pointer from inside the callbacks using
|
||||||
|
the function png_get_msg_ptr(png_ptr); */
|
||||||
|
png_set_progressive_read_fn(png_ptr, NULL,
|
||||||
|
info_callback, row_callback, end_callback);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
process_data(png_bytep buffer, png_uint_32 length)
|
||||||
|
{
|
||||||
|
if (setjmp(png_ptr->jmpbuf))
|
||||||
|
{
|
||||||
|
png_read_destroy(png_ptr, info_ptr, (png_info *)0);
|
||||||
|
free(png_ptr);
|
||||||
|
free(info_ptr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this one's new also. Simply give it a chunk of data
|
||||||
|
from the file stream (in order, of course). On Segmented
|
||||||
|
machines, don't give it any more then 64K. The library
|
||||||
|
seems to run fine with sizes of 4K, although you can give
|
||||||
|
it much less if necessary (I assume you can give it chunks
|
||||||
|
of 1 byte, but I haven't tried less then 256 bytes yet).
|
||||||
|
When this function returns, you may want to display any
|
||||||
|
rows that were generated in the row callback. */
|
||||||
|
png_process_data(png_ptr, info_ptr, buffer, length);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
info_callback(png_structp png_ptr, png_infop info)
|
||||||
|
{
|
||||||
|
/* do any setup here, including setting any of the transformations
|
||||||
|
mentioned in the Reading PNG files section. For now, you _must_
|
||||||
|
call either png_start_read_image() or png_read_update_info()
|
||||||
|
after all the transformations are set (even if you don't set
|
||||||
|
any). You may start getting rows before png_process_data()
|
||||||
|
returns, so this is your last chance to prepare for that. */
|
||||||
|
}
|
||||||
|
|
||||||
|
row_callback(png_structp png_ptr, png_bytep new_row,
|
||||||
|
png_uint_32 row_num, int pass)
|
||||||
|
{
|
||||||
|
/* this function is called for every row in the image. If the
|
||||||
|
image is interlacing, and you turned on the interlace handler,
|
||||||
|
this function will be called for every row in every pass.
|
||||||
|
Some of these rows will not be changed from the previous pass.
|
||||||
|
When the row is not changed, the new_row variable will be NULL.
|
||||||
|
The rows and passes are called in order, so you don't really
|
||||||
|
need the row_num and pass, but I'm supplying them because it
|
||||||
|
may make your life easier.
|
||||||
|
|
||||||
|
For the non-NULL rows of interlaced images, you must call
|
||||||
|
png_progressive_combine_row() passing in the row and the
|
||||||
|
old row. You can call this function for NULL rows (it will
|
||||||
|
just return) and for non-interlaced images (it just does the
|
||||||
|
memcpy for you) if it will make the code easier. Thus, you
|
||||||
|
can just do this for all cases: */
|
||||||
|
|
||||||
|
png_progressive_combine_row(png_ptr, old_row, new_row);
|
||||||
|
|
||||||
|
/* where old_row is what was displayed for previous rows. Note
|
||||||
|
that the first pass (pass == 0 really) will completely cover
|
||||||
|
the old row, so the rows do not have to be initialized. After
|
||||||
|
the first pass (and only for interlaced images), you will have
|
||||||
|
to pass the current row, and the function will combine the
|
||||||
|
old row and the new row. */
|
||||||
|
}
|
||||||
|
|
||||||
|
end_callback(png_structp png_ptr, png_infop info)
|
||||||
|
{
|
||||||
|
/* this function is called when the whole image has been read,
|
||||||
|
including any chunks after the image (up to and including
|
||||||
|
the IEND). You will usually have the same info chunk as you
|
||||||
|
had in the header, although some data may have been added
|
||||||
|
to the comments and time fields.
|
||||||
|
|
||||||
|
Most people won't do much here, perhaps setting a flag that
|
||||||
|
marks the image as finished. */
|
||||||
|
}
|
||||||
|
|
||||||
/* write a png file */
|
/* write a png file */
|
||||||
void write_png(char *file_name, ... other image information ...)
|
void write_png(char *file_name, ... other image information ...)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
png_struct *png_ptr;
|
png_structp png_ptr;
|
||||||
png_info *info_ptr;
|
png_infop info_ptr;
|
||||||
|
|
||||||
/* open the file */
|
/* open the file */
|
||||||
fp = fopen(file_name, "wb");
|
fp = fopen(file_name, "wb");
|
||||||
@ -283,19 +386,9 @@ 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 for the default output and message functions.
|
/* set up the output control */
|
||||||
* 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 = ;
|
||||||
@ -309,16 +402,9 @@ 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;
|
||||||
/* if we are dealing with a grayscale image then */
|
info_ptr->sig_bit = true_bit_depth;
|
||||||
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 is a good idea if you can write one */
|
/* optional gamma chunk */
|
||||||
info_ptr->valid |= PNG_INFO_gAMA;
|
info_ptr->valid |= PNG_INFO_gAMA;
|
||||||
info_ptr->gamma = gamma;
|
info_ptr->gamma = gamma;
|
||||||
|
|
||||||
@ -357,7 +443,7 @@ void write_png(char *file_name, ... other image information ...)
|
|||||||
number_passes = 1;
|
number_passes = 1;
|
||||||
|
|
||||||
/* the easiest way to write the image */
|
/* the easiest way to write the image */
|
||||||
png_bytef *row_pointers[height];
|
png_bytep row_pointers[height];
|
||||||
png_write_image(png_ptr, row_pointers);
|
png_write_image(png_ptr, row_pointers);
|
||||||
|
|
||||||
/* the other way to write the image - deal with interlacing */
|
/* the other way to write the image - deal with interlacing */
|
||||||
@ -370,7 +456,7 @@ void write_png(char *file_name, ... other image information ...)
|
|||||||
/* If you are only writing one row at a time, this works */
|
/* If you are only writing one row at a time, this works */
|
||||||
for (y = 0; y < height; y++)
|
for (y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
png_bytef *row_pointers = row[y];
|
png_bytep row_pointers = row[y];
|
||||||
png_write_rows(png_ptr, &row_pointers, 1);
|
png_write_rows(png_ptr, &row_pointers, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -378,11 +464,6 @@ 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);
|
||||||
|
|
||||||
|
543
libpng.txt
543
libpng.txt
@ -1,9 +1,9 @@
|
|||||||
libpng.txt - a description on how to use and modify libpng
|
libpng.txt - a description on how to use and modify libpng
|
||||||
|
|
||||||
libpng 1.0 beta 2 - version 0.8
|
libpng 1.0 beta 2 - version 0.85
|
||||||
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 20, 1995
|
December 19, 1995
|
||||||
|
|
||||||
This file describes how to use and modify the PNG reference library
|
This file describes how to use and modify the PNG reference library
|
||||||
(known as libpng) for your own use. There are four sections to this
|
(known as libpng) for your own use. There are four sections to this
|
||||||
@ -45,60 +45,60 @@ 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. If you pass in more then eight bytes,
|
||||||
|
libpng will only look at the first eight bytes.
|
||||||
|
|
||||||
fread(header, 1, number, fp);
|
fread(header, 1, number, fp);
|
||||||
is_png = png_check_sig(header, number);
|
is_png = png_check_sig(header, number);
|
||||||
|
|
||||||
Reading PNG files:
|
Reading PNG files:
|
||||||
|
|
||||||
|
This section covers reading png files row by row. Progressive reading
|
||||||
|
is covered in the next section (although you still need to read this
|
||||||
|
section, as much of the information is still needed).
|
||||||
|
|
||||||
The first thing you need to do while reading a PNG file is to allocate
|
The first thing you need to do while reading a PNG file is to allocate
|
||||||
and initialize png_struct and png_info. As these are both large, you
|
and initialize png_struct and png_info. As these are both large, you
|
||||||
may not want to store these on the stack, unless you have stack space
|
may not want to store these on the stack, unless you have stack space
|
||||||
to spare. Of course, you will want to check if malloc returns NULL.
|
to spare. Of course, you will want to check if malloc returns NULL.
|
||||||
|
|
||||||
png_struct *png_ptr = malloc(sizeof (png_struct));
|
png_structp png_ptr = malloc(sizeof (png_struct));
|
||||||
if (!png_ptr)
|
if (!png_ptr)
|
||||||
return;
|
return;
|
||||||
png_info *info_ptr = malloc(sizeof (png_info));
|
png_infop info_ptr = malloc(sizeof (png_info));
|
||||||
if (!info_ptr)
|
if (!info_ptr)
|
||||||
{
|
{
|
||||||
free(png_ptr);
|
free(png_ptr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
You may also want to do any i/o initialization here, before
|
You may also want to do any i/o initialization here, before
|
||||||
you get into libpng, so if it doesn't work, you don't have
|
you get into libpng, so if it doesn't work, you don't have
|
||||||
much to undo.
|
much to undo.
|
||||||
|
|
||||||
FILE *fp = fopen(file_name, "rb");
|
FILE *fp = fopen(file_name, "rb");
|
||||||
if (!fp)
|
if (!fp)
|
||||||
{
|
{
|
||||||
free(png_ptr);
|
free(png_ptr);
|
||||||
free(info_ptr);
|
free(info_ptr);
|
||||||
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
|
||||||
@ -108,21 +108,20 @@ 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 libpng error handling in the Customizing Libpng
|
the discussion on png error handling in the Customizing Libpng
|
||||||
section below for more information on how to change the behaviour
|
section below for more information on the png error handling.
|
||||||
of libpng error handling. If an error occurs, and libpng longjmp's
|
If an error occurs, and libpng longjmp's back to your setjmp,
|
||||||
back to your setjmp, you will want to call png_read_destroy() to
|
you will want to call png_read_destroy() to free any memory.
|
||||||
free any memory.
|
|
||||||
|
|
||||||
if (setjmp(png_ptr->jmpbuf))
|
if (setjmp(png_ptr->jmpbuf))
|
||||||
{
|
{
|
||||||
png_read_destroy(png_ptr, info_ptr, (png_info *)0);
|
png_read_destroy(png_ptr, info_ptr, (png_info *)0);
|
||||||
/* free pointers before returning, if necessary */
|
/* free pointers before returning, if necessary */
|
||||||
free(png_ptr);
|
free(png_ptr);
|
||||||
free(info_ptr);
|
free(info_ptr);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Next, you will need to call png_read_init() and png_info_init().
|
Next, you will need to call png_read_init() and png_info_init().
|
||||||
These functions make sure all the fields are initialized to useful
|
These functions make sure all the fields are initialized to useful
|
||||||
@ -138,10 +137,11 @@ 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. Otherwise, you should see the
|
the file is opened in binary mode. If you wish to handle reading
|
||||||
section below on Customizing libpng I/O functions.
|
data in another way, see the discussion on png i/o handling in the
|
||||||
|
Customizing Libpng section below.
|
||||||
|
|
||||||
png_init_io(png_ptr, fp);
|
png_init_io(png_ptr, fp);
|
||||||
|
|
||||||
You are now ready to read all the file information up to the actual
|
You are now ready to read all the file information up to the actual
|
||||||
image data. You do this with a call to png_read_info().
|
image data. You do this with a call to png_read_info().
|
||||||
@ -150,7 +150,7 @@ image data. You do this with a call to png_read_info().
|
|||||||
|
|
||||||
The png_info structure is now filled in with all the data necessary
|
The png_info structure is now filled in with all the data necessary
|
||||||
to read the file. Some of the more important parts of the png_info are:
|
to read the file. Some of the more important parts of the png_info are:
|
||||||
width - holds the width of the file
|
width - holds the width of the file
|
||||||
height - holds the height of the file
|
height - holds the height of the file
|
||||||
bit_depth - holds the bit depth of one of the image channels
|
bit_depth - holds the bit depth of one of the image channels
|
||||||
color_type - describes the channels and what they mean
|
color_type - describes the channels and what they mean
|
||||||
@ -158,13 +158,13 @@ to read the file. Some of the more important parts of the png_info are:
|
|||||||
channels - number of channels of info for the color type
|
channels - number of channels of info for the color type
|
||||||
pixel_depth - bits per pixel
|
pixel_depth - bits per pixel
|
||||||
rowbytes - number of bytes needed to hold a row
|
rowbytes - number of bytes needed to hold a row
|
||||||
interlace_type - currently 0 for none, 1 for interlaced
|
interlace_type - currently 0 for none, 1 for interlaced
|
||||||
valid - this details which optional chunks were found in the file
|
valid - this details which optional chunks were found in the file
|
||||||
to see if a chunk was present, OR valid with the appropriate
|
to see if a chunk was present, OR valid with the appropriate
|
||||||
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 - the number of significant bits for red, green, blue, grey, alpha
|
sig_bit and sig_bit_number - the number of significant bits
|
||||||
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.
|
||||||
@ -179,26 +179,13 @@ 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.
|
||||||
Some suggested keywords for tEXT (or zTXt) chunks are:
|
See the png specification for more details. There is no requirement
|
||||||
|
to have text after the keyword.
|
||||||
|
|
||||||
Title Short (one line) title or caption for image
|
Keywords are restricted to 80 characters without leading or trailing
|
||||||
Author Name of image's creator
|
spaces, but spaces are allowed within the keyword Nothing
|
||||||
Copyright Copyright notice (possibly long)
|
prevents you from duplicating the keyword. The text field is an
|
||||||
Description Description of image (possibly long)
|
array of png_text structures, each holding pointer to a keyword
|
||||||
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
|
||||||
@ -217,16 +204,16 @@ 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 than 8 to 8 bits, changes paletted
|
This transforms bit depths of less then 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.
|
||||||
|
|
||||||
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
|
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
|
||||||
info_ptr->bit_depth < 8)
|
info_ptr->bit_depth < 8)
|
||||||
png_set_expand(png_ptr);
|
png_set_expand(png_ptr);
|
||||||
|
|
||||||
if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
|
if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
|
||||||
info_ptr->bit_depth < 8)
|
info_ptr->bit_depth < 8)
|
||||||
png_set_expand(png_ptr);
|
png_set_expand(png_ptr);
|
||||||
|
|
||||||
@ -243,26 +230,25 @@ If you are modifying the color data with png_set_expand(), you must
|
|||||||
indicate whether the background needs to be expanded. See the
|
indicate whether the background needs to be expanded. See the
|
||||||
function definition in png.h for more details.
|
function definition in png.h for more details.
|
||||||
|
|
||||||
png_color_16 my_background;
|
png_color_16 my_background;
|
||||||
|
|
||||||
if (info_ptr->valid & PNG_INFO_bKGD)
|
if (info_ptr->valid & PNG_INFO_bKGD)
|
||||||
png_set_backgrond(png_ptr, &(info_ptr->background),
|
png_set_backgrond(png_ptr, &(info_ptr->background),
|
||||||
PNG_GAMMA_FILE, 1, 1.0);
|
PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
|
||||||
else
|
else
|
||||||
png_set_background(png_ptr, &my_background,
|
png_set_background(png_ptr, &my_background,
|
||||||
PNG_GAMMA_SCREEN, 0, 1.0);
|
PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
|
||||||
|
|
||||||
This handles gamma transformations of the data. Pass both the file
|
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. It is strongly
|
gamma in the PNG specification for more information.
|
||||||
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);
|
||||||
else
|
else
|
||||||
png_set_gamma(png_ptr, screen_gamma, 0.45);
|
png_set_gamma(png_ptr, screen_gamma, 0.45);
|
||||||
|
|
||||||
PNG can have files with 16 bits per channel. If you only can handle
|
PNG can have files with 16 bits per channel. If you only can handle
|
||||||
8 bits per channel, this will strip the pixels down to 8 bit.
|
8 bits per channel, this will strip the pixels down to 8 bit.
|
||||||
@ -281,7 +267,7 @@ will fit into maximum_colors. If there is an histogram, it will
|
|||||||
use it to make intelligent choises when reducing the palette. If
|
use it to make intelligent choises when reducing the palette. If
|
||||||
there is no histogram, it may not do a good job.
|
there is no histogram, it may not do a good job.
|
||||||
|
|
||||||
if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
|
if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
|
||||||
{
|
{
|
||||||
if (info_ptr->valid & PNG_INFO_PLTE)
|
if (info_ptr->valid & PNG_INFO_PLTE)
|
||||||
png_set_dither(png_ptr, info_ptr->palette,
|
png_set_dither(png_ptr, info_ptr->palette,
|
||||||
@ -289,7 +275,7 @@ there is no histogram, it may not do a good job.
|
|||||||
info_ptr->histogram);
|
info_ptr->histogram);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
png_color std_color_cube[MAX_SCREEN_COLORS] =
|
png_color std_color_cube[MAX_SCREEN_COLORS] =
|
||||||
{ ... colors ... };
|
{ ... colors ... };
|
||||||
|
|
||||||
png_set_dither(png_ptr, std_color_cube, MAX_SCREEN_COLORS,
|
png_set_dither(png_ptr, std_color_cube, MAX_SCREEN_COLORS,
|
||||||
@ -325,7 +311,7 @@ PNG files store 3 color pixels in red, green, blue order. If you would
|
|||||||
rather have the pixels as blue, green, red, call this.
|
rather have the pixels as blue, green, red, call this.
|
||||||
|
|
||||||
if (info_ptr->color_type == PNG_COLOR_TYPE_RGB ||
|
if (info_ptr->color_type == PNG_COLOR_TYPE_RGB ||
|
||||||
info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||||
png_set_bgr(png_ptr);
|
png_set_bgr(png_ptr);
|
||||||
|
|
||||||
For some uses, you may want a grayscale image to be represented as
|
For some uses, you may want a grayscale image to be represented as
|
||||||
@ -333,7 +319,7 @@ rgb. If you need this, call this:
|
|||||||
|
|
||||||
if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY ||
|
if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY ||
|
||||||
info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||||
png_set_gray_to_rgb(png_ptr);
|
png_set_gray_to_rgb(png_ptr);
|
||||||
|
|
||||||
PNG files store 16 bit pixels in network byte order (most significant
|
PNG files store 16 bit pixels in network byte order (most significant
|
||||||
bit first). If you would rather store them the other way, (the way
|
bit first). If you would rather store them the other way, (the way
|
||||||
@ -365,7 +351,7 @@ who need an updated palette before they read the image data. If you
|
|||||||
don't call this function, the library will automatically call it
|
don't call this function, the library will automatically call it
|
||||||
before it reads the first row.
|
before it reads the first row.
|
||||||
|
|
||||||
png_start_read_image(png_ptr);
|
png_start_read_image(png_ptr);
|
||||||
|
|
||||||
If you want, libpng will update your png_info structure to reflect
|
If you want, libpng will update your png_info structure to reflect
|
||||||
any transformations you've requested with this call. This is most
|
any transformations you've requested with this call. This is most
|
||||||
@ -373,7 +359,7 @@ useful to update the info structures rowbytes field, so you can
|
|||||||
use it to allocate your image memory. This function calls
|
use it to allocate your image memory. This function calls
|
||||||
png_start_read_image(), so you don't have to call both of them.
|
png_start_read_image(), so you don't have to call both of them.
|
||||||
|
|
||||||
png_read_update_info(png_ptr, info_ptr);
|
png_read_update_info(png_ptr, info_ptr);
|
||||||
|
|
||||||
After you call png_read_update_info(), you can allocate any
|
After you call png_read_update_info(), you can allocate any
|
||||||
memory you need to hold the image. As the actual allocation
|
memory you need to hold the image. As the actual allocation
|
||||||
@ -397,7 +383,7 @@ times, or any of that other stuff necessary with png_read_rows().
|
|||||||
|
|
||||||
where row_pointers is:
|
where row_pointers is:
|
||||||
|
|
||||||
void *row_pointers[height];
|
png_bytep row_pointers[height];
|
||||||
|
|
||||||
You can point to void or char or whatever you use for pixels.
|
You can point to void or char or whatever you use for pixels.
|
||||||
|
|
||||||
@ -412,7 +398,7 @@ row_pointers is the same as in the png_read_image() call.
|
|||||||
If you are just calling one row at a time, you can do this for
|
If you are just calling one row at a time, you can do this for
|
||||||
row_pointers:
|
row_pointers:
|
||||||
|
|
||||||
char *row_pointers = row;
|
png_bytep row_pointers = row;
|
||||||
|
|
||||||
png_read_rows(png_ptr, &row_pointers, NULL, 1);
|
png_read_rows(png_ptr, &row_pointers, NULL, 1);
|
||||||
|
|
||||||
@ -460,7 +446,7 @@ rows between calls. You can change the locations of the data, just
|
|||||||
not the data. Each pass only writes the pixels appropriate for that
|
not the data. Each pass only writes the pixels appropriate for that
|
||||||
pass, and assumes the data from previous passes is still valid.
|
pass, and assumes the data from previous passes is still valid.
|
||||||
|
|
||||||
png_read_rows(png_ptr, row_pointers, NULL, number_of_rows);
|
png_read_rows(png_ptr, row_pointers, NULL, number_of_rows);
|
||||||
|
|
||||||
If you only want the first effect (the rectangles), do the same as
|
If you only want the first effect (the rectangles), do the same as
|
||||||
before except pass the row buffer in the third parameter, and leave
|
before except pass the row buffer in the third parameter, and leave
|
||||||
@ -484,6 +470,133 @@ read or write. For a more compact example of reading a PNG image,
|
|||||||
see the file example.c.
|
see the file example.c.
|
||||||
|
|
||||||
|
|
||||||
|
Reading PNG files progressively:
|
||||||
|
|
||||||
|
The progressive reader is slightly different then the non-progressive
|
||||||
|
reader. Instead of calling png_read_info(), png_read_rows(), and
|
||||||
|
png_read_end(), you make one call to png_process_data(), which calls
|
||||||
|
callbacks when it has the info, a row, or the end of the image. You
|
||||||
|
set up these callbacks with png_set_progressive_read_fn(). You don't
|
||||||
|
have to worry about the input/output functions of libpng, as you are
|
||||||
|
giving the library the data directly in png_process_data(). I will
|
||||||
|
assume that you have read the second on reading PNG files above,
|
||||||
|
so I will only highlight the differences (although I will show
|
||||||
|
all of the code).
|
||||||
|
|
||||||
|
png_structp png_ptr;
|
||||||
|
png_infop info_ptr;
|
||||||
|
|
||||||
|
int
|
||||||
|
initialize_png_reader()
|
||||||
|
{
|
||||||
|
png_ptr = malloc(sizeof (png_struct));
|
||||||
|
if (!png_ptr)
|
||||||
|
return -1;
|
||||||
|
info_ptr = malloc(sizeof (png_info));
|
||||||
|
if (!info_ptr)
|
||||||
|
{
|
||||||
|
free(png_ptr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setjmp(png_ptr->jmpbuf))
|
||||||
|
{
|
||||||
|
png_read_destroy(png_ptr, info_ptr, (png_info *)0);
|
||||||
|
/* free pointers before returning, if necessary */
|
||||||
|
free(png_ptr);
|
||||||
|
free(info_ptr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
png_info_init(info_ptr);
|
||||||
|
png_read_init(png_ptr);
|
||||||
|
|
||||||
|
/* this one's new. You will need to provide all three
|
||||||
|
function callbacks, even if you aren't using them all.
|
||||||
|
You can put a void pointer in place of the NULL, and
|
||||||
|
retrieve the pointer from inside the callbacks using
|
||||||
|
the function png_get_progressive_ptr(png_ptr); */
|
||||||
|
png_set_progressive_read_fn(png_ptr, NULL,
|
||||||
|
info_callback, row_callback, end_callback);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
process_data(png_bytep buffer, png_uint_32 length)
|
||||||
|
{
|
||||||
|
if (setjmp(png_ptr->jmpbuf))
|
||||||
|
{
|
||||||
|
png_read_destroy(png_ptr, info_ptr, (png_info *)0);
|
||||||
|
free(png_ptr);
|
||||||
|
free(info_ptr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this one's new also. Simply give it a chunk of data
|
||||||
|
from the file stream (in order, of course). On Segmented
|
||||||
|
machines, don't give it any more then 64K. The library
|
||||||
|
seems to run fine with sizes of 4K, although you can give
|
||||||
|
it much less if necessary (I assume you can give it chunks
|
||||||
|
of 1 byte, but I haven't tried less then 256 bytes yet).
|
||||||
|
When this function returns, you may want to display any
|
||||||
|
rows that were generated in the row callback. */
|
||||||
|
png_process_data(png_ptr, info_ptr, buffer, length);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
info_callback(png_structp png_ptr, png_infop info)
|
||||||
|
{
|
||||||
|
do any setup here, including setting any of the transformations
|
||||||
|
mentioned in the Reading PNG files section. For now, you _must_
|
||||||
|
call either png_start_read_image() or png_read_update_info()
|
||||||
|
after all the transformations are set (even if you don't set
|
||||||
|
any). You may start getting rows before png_process_data()
|
||||||
|
returns, so this is your last chance to prepare for that.
|
||||||
|
}
|
||||||
|
|
||||||
|
row_callback(png_structp png_ptr, png_bytep new_row,
|
||||||
|
png_uint_32 row_num, int pass)
|
||||||
|
{
|
||||||
|
this function is called for every row in the image. If the
|
||||||
|
image is interlacing, and you turned on the interlace handler,
|
||||||
|
this function will be called for every row in every pass.
|
||||||
|
Some of these rows will not be changed from the previous pass.
|
||||||
|
When the row is not changed, the new_row variable will be NULL.
|
||||||
|
The rows and passes are called in order, so you don't really
|
||||||
|
need the row_num and pass, but I'm supplying them because it
|
||||||
|
may make your life easier.
|
||||||
|
|
||||||
|
For the non-NULL rows of interlaced images, you must call
|
||||||
|
png_progressive_combine_row() passing in the row and the
|
||||||
|
old row. You can call this function for NULL rows (it will
|
||||||
|
just return) and for non-interlaced images (it just does the
|
||||||
|
memcpy for you) if it will make the code easier. Thus, you
|
||||||
|
can just do this for all cases:
|
||||||
|
|
||||||
|
png_progressive_combine_row(png_ptr, old_row, new_row);
|
||||||
|
|
||||||
|
where old_row is what was displayed for previous rows. Note
|
||||||
|
that the first pass (pass == 0 really) will completely cover
|
||||||
|
the old row, so the rows do not have to be initialized. After
|
||||||
|
the first pass (and only for interlaced images), you will have
|
||||||
|
to pass the current row, and the function will combine the
|
||||||
|
old row and the new row.
|
||||||
|
}
|
||||||
|
|
||||||
|
end_callback(png_structp png_ptr, png_infop info)
|
||||||
|
{
|
||||||
|
this function is called when the whole image has been read,
|
||||||
|
including any chunks after the image (up to and including
|
||||||
|
the IEND). You will usually have the same info chunk as you
|
||||||
|
had in the header, although some data may have been added
|
||||||
|
to the comments and time fields.
|
||||||
|
|
||||||
|
Most people won't do much here, perhaps setting a flag that
|
||||||
|
marks the image as finished.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Writing PNG files:
|
Writing PNG files:
|
||||||
|
|
||||||
Much of this is very similar to reading. However, everything of
|
Much of this is very similar to reading. However, everything of
|
||||||
@ -495,11 +608,11 @@ and initialize png_struct and png_info. As these are both large, you
|
|||||||
may not want to store these on the stack, unless you have stack space
|
may not want to store these on the stack, unless you have stack space
|
||||||
to spare.
|
to spare.
|
||||||
|
|
||||||
png_struct *png_ptr = malloc(sizeof (png_struct));
|
png_structp png_ptr = malloc(sizeof (png_struct));
|
||||||
if (!png_ptr)
|
if (!png_ptr)
|
||||||
return;
|
return;
|
||||||
png_info *info_ptr = malloc(sizeof (png_info));
|
png_infop info_ptr = malloc(sizeof (png_info));
|
||||||
if (!info_ptr)
|
if (!info_ptr)
|
||||||
{
|
{
|
||||||
free(png_ptr);
|
free(png_ptr);
|
||||||
return;
|
return;
|
||||||
@ -513,7 +626,7 @@ much to undo.
|
|||||||
if (!fp)
|
if (!fp)
|
||||||
{
|
{
|
||||||
free(png_ptr);
|
free(png_ptr);
|
||||||
free(info_ptr);
|
free(info_ptr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -524,20 +637,18 @@ 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. If you
|
for your compiler for more information on setjmp/longjmp. See
|
||||||
don't want to use stderr for error output, or you want to use a
|
the discussion on png error handling in the Customizing Libpng
|
||||||
method other than setjmp()/longjmp() to handle errors, see the
|
section below for more information on the png error handling.
|
||||||
Customizing Libpng section below for more information on libpng
|
|
||||||
error handling.
|
|
||||||
|
|
||||||
if (setjmp(png_ptr->jmpbuf))
|
if (setjmp(png_ptr->jmpbuf))
|
||||||
{
|
{
|
||||||
png_write_destroy(png_ptr);
|
png_write_destroy(png_ptr);
|
||||||
/* free pointers before returning. Make sure you clean up
|
/* free pointers before returning. Make sure you clean up
|
||||||
anything else you've done. */
|
anything else you've done. */
|
||||||
free(png_ptr);
|
free(png_ptr);
|
||||||
free(info_ptr);
|
free(info_ptr);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -555,7 +666,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);
|
||||||
@ -563,7 +674,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
|
||||||
@ -571,36 +682,14 @@ carefully tuned to deliver the best speed/compression ratio.
|
|||||||
See the compression library for more details.
|
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_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
|
||||||
@ -613,7 +702,7 @@ parts of the png_info are:
|
|||||||
width - holds the width of the file
|
width - holds the width of the file
|
||||||
height - holds the height of the file
|
height - holds the height of the file
|
||||||
bit_depth - holds the bit depth of one of the image channels
|
bit_depth - holds the bit depth of one of the image channels
|
||||||
color_type - describes the channels and what they mean
|
color_type - describes the channels and what they mean
|
||||||
see the PNG_COLOR_TYPE_ defines for more information
|
see the PNG_COLOR_TYPE_ defines for more information
|
||||||
interlace_type - currently 0 for none, 1 for interlaced
|
interlace_type - currently 0 for none, 1 for interlaced
|
||||||
valid - this describes which optional chunks to write to the
|
valid - this describes which optional chunks to write to the
|
||||||
@ -623,7 +712,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 - the number of significant bits for red, green, blue, grey, alpha
|
sig_bit and sig_bit_number - the number of significant bits
|
||||||
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.
|
||||||
@ -656,25 +745,18 @@ 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. Note that the year number is the full
|
instead of your local time.
|
||||||
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().
|
||||||
|
|
||||||
png_write_info(png_ptr, info_ptr);
|
png_write_info(png_ptr, info_ptr);
|
||||||
|
|
||||||
After you've read the file information, you can set up the library to
|
After you've read the file information, you can set up the library to
|
||||||
handle any special transformations of the image data. The various
|
handle any special transformations of the image data. The various
|
||||||
@ -746,7 +828,7 @@ PNG files describe moncrome as black is zero and white is one. If you
|
|||||||
would rather supply the pixels with this reversed (black is one and
|
would rather supply the pixels with this reversed (black is one and
|
||||||
white is zero), call this:
|
white is zero), call this:
|
||||||
|
|
||||||
png_set_invert(png_ptr);
|
png_set_invert(png_ptr);
|
||||||
|
|
||||||
That's it for the transformations. Now you can write the image data.
|
That's it for the transformations. Now you can write the image data.
|
||||||
The simplest way to do this is in one function call. If have the
|
The simplest way to do this is in one function call. If have the
|
||||||
@ -760,7 +842,7 @@ times, or any of that other stuff necessary with png_write_rows().
|
|||||||
|
|
||||||
where row_pointers is:
|
where row_pointers is:
|
||||||
|
|
||||||
void *row_pointers[height];
|
png_bytef *row_pointers[height];
|
||||||
|
|
||||||
You can point to void or char or whatever you use for pixels.
|
You can point to void or char or whatever you use for pixels.
|
||||||
|
|
||||||
@ -775,7 +857,7 @@ row_pointers is the same as in the png_write_image() call.
|
|||||||
If you are just calling one row at a time, you can do this for
|
If you are just calling one row at a time, you can do this for
|
||||||
row_pointers:
|
row_pointers:
|
||||||
|
|
||||||
char *row_pointers = row;
|
png_bytep row_pointers = row;
|
||||||
|
|
||||||
png_write_rows(png_ptr, &row_pointers, 1);
|
png_write_rows(png_ptr, &row_pointers, 1);
|
||||||
|
|
||||||
@ -811,7 +893,7 @@ pass the an appropriately filled png_info pointer. If you
|
|||||||
are not interested, you can pass NULL. Be careful that you don't
|
are not interested, you can pass NULL. Be careful that you don't
|
||||||
write the same text or time chunks here as you did in png_write_info().
|
write the same text or time chunks here as you did in png_write_info().
|
||||||
|
|
||||||
png_write_end(png_ptr, info_ptr);
|
png_write_end(png_ptr, info_ptr);
|
||||||
|
|
||||||
When you are done, you can free all memory used by libpng like this:
|
When you are done, you can free all memory used by libpng like this:
|
||||||
|
|
||||||
@ -831,43 +913,41 @@ 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 in libpng is done in pngmem.c. Memory
|
All of the memory allocation, input/output, and error handling in libpng
|
||||||
allocation is done through the functions png_large_malloc(), png_malloc(),
|
goes through callbacks which are user setable. The default routines
|
||||||
png_realloc(), png_large_free(), and png_free(). These currently just
|
are in pngerror.c, pngmem.c, and pngio.c. To change these functions,
|
||||||
call the standard C functions. The large functions must handle at least
|
call the approprate fn function.
|
||||||
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.
|
|
||||||
|
|
||||||
Since it is unlikely that the method of handling memory allocation on a
|
Memory allocation is done through the functions png_large_malloc(),
|
||||||
platform will change between applications, these functions must be modified
|
png_malloc(), png_realloc(), png_large_free(), and png_free().
|
||||||
or replaced to change their behaviour. If you only need to add new tests or
|
These currently just call the standard C functions. The large
|
||||||
flags to have the compiler choose the correct function calls, please forward
|
functions must handle exactly 64K, but they don't have to handle
|
||||||
these changes to the libpng author, so they can be added into the library
|
more then that. If your pointers can't access more then 64K at a
|
||||||
for the benefit of others.
|
time, you will want to set MAXSEG_64K in zlib.h.
|
||||||
|
|
||||||
All of the input/output, and error handling in libpng go through the
|
Input/Output in libpng is done throught png_read() and png_write(), which
|
||||||
routines in pngio.c by default. The file has plenty of comments describing
|
currently just call fread() and fwrite(). The FILE * is stored in
|
||||||
each function and how it expects to work. It is possible to supply different
|
png_struct, and is initialized via png_init_io(). If you wish to change
|
||||||
I/O and error handling methods at run time with the png_set_msg_fn(),
|
this, the library supplies callbacks that you can set through the
|
||||||
png_set_read_fn(), and png_set_write_fn() calls.
|
function png_set_read_fn() and png_set_write_fn(). These functions
|
||||||
|
also provide a void pointer that can be retrieved via the function
|
||||||
|
png_get_io_ptr(). For example:
|
||||||
|
|
||||||
Input/Output in libpng is done throught png_read_data() and png_write_data(),
|
png_set_read_fn(png_structp png_ptr, voidp io_ptr,
|
||||||
which currently just call fread() and fwrite(). The error and warning
|
png_rw_ptr read_data_fn)
|
||||||
functions png_error() and png_warning() use stderr to output any messages,
|
|
||||||
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
|
png_set_write_fn(png_structp png_ptr, voidp io_ptr,
|
||||||
do so at runtime, and without modifying the libpng library code. The
|
png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn);
|
||||||
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
|
voidp io_ptr = png_get_io_ptr(png_ptr);
|
||||||
default. Errors handled through png_error() are fatal, meaning that
|
|
||||||
png_error() should never return to it's caller. Currently, this is handled
|
Note that you can pass NULL for the flush function if you are not doing
|
||||||
via setjmp() and longjmp(), but you could change this to do things like
|
flushing.
|
||||||
|
|
||||||
|
Error handling in libpng is done through png_error() and png_warning().
|
||||||
|
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
|
||||||
@ -876,72 +956,14 @@ is no need to check every return code of every function call. However,
|
|||||||
there are some uncertainties about the status of local variables after
|
there are some uncertainties about the status of local variables after
|
||||||
a longjmp, so the user may want to be careful about doing anything after
|
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. If you wish to change this behavior,
|
||||||
|
you will need to set up your own message callbacks. You do this like
|
||||||
|
the io callbacks above.
|
||||||
|
|
||||||
The replacement message functions should have parameters as follows:
|
png_set_message_fn(png_structp png_ptr, png_voidp msg_ptr,
|
||||||
|
png_msg_ptr error_fn, png_msg_ptr warning_fn);
|
||||||
|
|
||||||
void user_error_fn(png_struct png_ptr, char *error_msg);
|
png_voidp msg_ptr = png_get_msg_ptr(png_ptr);
|
||||||
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
|
||||||
@ -950,9 +972,7 @@ 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. If you are
|
More details can be found in the comments inside the code.
|
||||||
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
|
||||||
@ -963,21 +983,32 @@ itself.
|
|||||||
|
|
||||||
Configuring for 16 bit platforms:
|
Configuring for 16 bit platforms:
|
||||||
|
|
||||||
You will probably need to change the png_large_malloc() and
|
You will may need to change the png_large_malloc() and
|
||||||
png_large_free() routines in pngmem.c, as these are required
|
png_large_free() routines in pngmem.c, as these are requred
|
||||||
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
|
||||||
and libpng to 64K by defining MAXSEG_64K.
|
and libpng to 64K by defining MAXSEG_64K.
|
||||||
|
|
||||||
|
Configuring for Medium Model:
|
||||||
|
|
||||||
|
Libpng's support for medium model has been tested on most of the popular
|
||||||
|
complers. Make sure MAXSEG_64K get's defined, USE_FAR_KEYWORD get's
|
||||||
|
defined, and FAR get's defined to far in pngconf.h, and you should be
|
||||||
|
all set. Everything in the library (except for zlib's structure) is
|
||||||
|
expecting far data. You must use the typedefs with the p or pp on
|
||||||
|
the end for pointers (or at least look at them and be careful). Make
|
||||||
|
note that the row's of data are defined as png_bytepp which is a
|
||||||
|
unsigned char far * far *
|
||||||
|
|
||||||
Configuring for gui/windowing platforms:
|
Configuring for gui/windowing platforms:
|
||||||
|
|
||||||
You will need to supply new message display functions for png_error() and
|
You will need to change the error message display in png_error() and
|
||||||
png_warning() (through png_set_message_fn() to display a message in a window
|
png_warning() to display a message instead of fprinting it to stderr.
|
||||||
instead of fprinting it to stderr. You may want to write a single function
|
You may want to write a single function to do this and call it something
|
||||||
to do this and call it something like png_message() (although the error
|
like png_message(). On some compliers, you may have to change the
|
||||||
function should still call longjmp or otherwise handle the error without
|
memory allocators (png_malloc, etc.).
|
||||||
returning).
|
|
||||||
|
|
||||||
Configuring for compiler xxx:
|
Configuring for compiler xxx:
|
||||||
|
|
||||||
@ -989,13 +1020,15 @@ files in libpng proper only include png.h.
|
|||||||
|
|
||||||
Removing unwanted object code:
|
Removing unwanted object code:
|
||||||
|
|
||||||
There are a bunch of #define's in pngconf.h that control what parts of
|
There are a bunch of #define's in png.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
|
||||||
never going to use an ability, you can change the #define to #undef and
|
not using 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
|
||||||
are building a stand alone library, all the reading files start with
|
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. The
|
||||||
|
progressive reader is in pngpread.c
|
||||||
|
|
||||||
|
190
lpfaq.txt
190
lpfaq.txt
@ -1,190 +0,0 @@
|
|||||||
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
|
|
15
makefile
15
makefile
@ -2,26 +2,25 @@
|
|||||||
# 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=gcc
|
CC=cc
|
||||||
CFLAGS=-I../zlib -O2 -Wall -ansi -pedantic
|
CFLAGS=-I../zlib -O
|
||||||
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=/home/munet-d2/sun/local
|
prefix=/usr/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
|
pngmem.o pngerror.o pngpread.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)
|
||||||
@ -45,6 +44,7 @@ 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
|
||||||
@ -56,3 +56,4 @@ pngtrans.o: png.h pngconf.h
|
|||||||
pngwrite.o: png.h pngconf.h
|
pngwrite.o: png.h pngconf.h
|
||||||
pngwtran.o: png.h pngconf.h
|
pngwtran.o: png.h pngconf.h
|
||||||
pngwutil.o: png.h pngconf.h
|
pngwutil.o: png.h pngconf.h
|
||||||
|
pngpread.o: png.h pngconf.h
|
||||||
|
88
png.c
88
png.c
@ -1,10 +1,10 @@
|
|||||||
|
|
||||||
/* png.c - location for general purpose png functions
|
/* png.c - location for general purpose png functions
|
||||||
|
|
||||||
libpng 1.0 beta 2 - version 0.81
|
libpng 1.0 beta 2 - version 0.85
|
||||||
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
|
December 19, 1995
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PNG_INTERNAL
|
#define PNG_INTERNAL
|
||||||
@ -13,123 +13,127 @@
|
|||||||
|
|
||||||
/* version information for c files. This better match the version
|
/* version information for c files. This better match the version
|
||||||
string defined in png.h */
|
string defined in png.h */
|
||||||
char png_libpng_ver[] = "0.81";
|
char FARDATA png_libpng_ver[] = "0.85";
|
||||||
|
|
||||||
/* place to hold the signiture string for a png file. */
|
/* place to hold the signiture string for a png file. */
|
||||||
png_byte png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
|
png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
|
||||||
|
|
||||||
/* constant strings for known chunk types. If you need to add a chunk,
|
/* constant strings for known chunk types. If you need to add a chunk,
|
||||||
add a string holding the name here. If you want to make the code
|
add a string holding the name here. If you want to make the code
|
||||||
portable to EBCDIC machines, use ASCII numbers, not characters. */
|
portable to EBCDIC machines, use ASCII numbers, not characters. */
|
||||||
png_byte png_IHDR[4] = { 73, 72, 68, 82};
|
png_byte FARDATA png_IHDR[4] = { 73, 72, 68, 82};
|
||||||
png_byte png_IDAT[4] = { 73, 68, 65, 84};
|
png_byte FARDATA png_IDAT[4] = { 73, 68, 65, 84};
|
||||||
png_byte png_IEND[4] = { 73, 69, 78, 68};
|
png_byte FARDATA png_IEND[4] = { 73, 69, 78, 68};
|
||||||
png_byte png_PLTE[4] = { 80, 76, 84, 69};
|
png_byte FARDATA png_PLTE[4] = { 80, 76, 84, 69};
|
||||||
#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED)
|
#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED)
|
||||||
png_byte png_gAMA[4] = {103, 65, 77, 65};
|
png_byte FARDATA png_gAMA[4] = {103, 65, 77, 65};
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_sBIT_SUPPORTED) || defined(PNG_WRITE_sBIT_SUPPORTED)
|
#if defined(PNG_READ_sBIT_SUPPORTED) || defined(PNG_WRITE_sBIT_SUPPORTED)
|
||||||
png_byte png_sBIT[4] = {115, 66, 73, 84};
|
png_byte FARDATA png_sBIT[4] = {115, 66, 73, 84};
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
|
#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
|
||||||
png_byte png_cHRM[4] = { 99, 72, 82, 77};
|
png_byte FARDATA png_cHRM[4] = { 99, 72, 82, 77};
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED)
|
#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED)
|
||||||
png_byte png_tRNS[4] = {116, 82, 78, 83};
|
png_byte FARDATA png_tRNS[4] = {116, 82, 78, 83};
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED)
|
#if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED)
|
||||||
png_byte png_bKGD[4] = { 98, 75, 71, 68};
|
png_byte FARDATA png_bKGD[4] = { 98, 75, 71, 68};
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED)
|
#if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED)
|
||||||
png_byte png_hIST[4] = {104, 73, 83, 84};
|
png_byte FARDATA png_hIST[4] = {104, 73, 83, 84};
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED)
|
#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED)
|
||||||
png_byte png_tEXt[4] = {116, 69, 88, 116};
|
png_byte FARDATA png_tEXt[4] = {116, 69, 88, 116};
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
|
#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
|
||||||
png_byte png_zTXt[4] = {122, 84, 88, 116};
|
png_byte FARDATA png_zTXt[4] = {122, 84, 88, 116};
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
|
#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
|
||||||
png_byte png_pHYs[4] = {112, 72, 89, 115};
|
png_byte FARDATA png_pHYs[4] = {112, 72, 89, 115};
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
|
#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
|
||||||
png_byte png_oFFs[4] = {111, 70, 70, 115};
|
png_byte FARDATA png_oFFs[4] = {111, 70, 70, 115};
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED)
|
#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED)
|
||||||
png_byte png_tIME[4] = {116, 73, 77, 69};
|
png_byte FARDATA png_tIME[4] = {116, 73, 77, 69};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
|
/* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
|
||||||
|
|
||||||
/* start of interlace block */
|
/* start of interlace block */
|
||||||
int png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
|
int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
|
||||||
|
|
||||||
/* offset to next interlace block */
|
/* offset to next interlace block */
|
||||||
int png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
|
int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
|
||||||
|
|
||||||
/* start of interlace block in the y direction */
|
/* start of interlace block in the y direction */
|
||||||
int png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
|
int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
|
||||||
|
|
||||||
/* offset to next interlace block in the y direction */
|
/* offset to next interlace block in the y direction */
|
||||||
int png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
|
int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
|
||||||
|
|
||||||
/* width of interlace block */
|
/* width of interlace block */
|
||||||
/* this is not currently used - if you need it, uncomment it here and
|
/* this is not currently used - if you need it, uncomment it here and
|
||||||
in png.h
|
in png.h
|
||||||
int png_pass_width[] = {8, 4, 4, 2, 2, 1, 1};
|
int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* height of interlace block */
|
/* height of interlace block */
|
||||||
/* this is not currently used - if you need it, uncomment it here and
|
/* this is not currently used - if you need it, uncomment it here and
|
||||||
in png.h
|
in png.h
|
||||||
int png_pass_height[] = {8, 8, 4, 4, 4, 2, 2, 1};
|
int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* mask to determine which pixels are valid in a pass */
|
/* mask to determine which pixels are valid in a pass */
|
||||||
int png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
|
int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
|
||||||
|
|
||||||
/* mask to determine which pixels to overwrite while displaying */
|
/* mask to determine which pixels to overwrite while displaying */
|
||||||
int png_pass_dsp_mask[] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
|
int FARDATA png_pass_dsp_mask[] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
png_check_sig(png_byte *sig, int num)
|
png_check_sig(png_bytep sig, int num)
|
||||||
{
|
{
|
||||||
if (num > 8)
|
if (num > 8)
|
||||||
num = 8;
|
num = 8;
|
||||||
if (num < 1)
|
if (num < 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return (!memcmp(sig, png_sig, num));
|
return (!png_memcmp(sig, png_sig, num));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function to allocate memory for zlib. */
|
/* Function to allocate memory for zlib. */
|
||||||
voidpf
|
voidpf
|
||||||
png_zalloc(voidpf png_ptr, uInt items, uInt size)
|
png_zalloc(voidpf png_ptr, uInt items, uInt size)
|
||||||
{
|
{
|
||||||
return ((voidpf)png_large_malloc((png_struct FAR *)png_ptr,
|
voidp * ptr;
|
||||||
(png_uint_32)items * (png_uint_32)size));
|
|
||||||
|
ptr = ((voidp)png_large_malloc((png_structp)png_ptr,
|
||||||
|
(png_uint_32)items * (png_uint_32)size));
|
||||||
|
png_memset(ptr, 0, (png_uint_32)items * (png_uint_32)size);
|
||||||
|
return (voidpf)(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* function to free memory for zlib */
|
/* function to free memory for zlib */
|
||||||
void
|
void
|
||||||
png_zfree(voidpf png_ptr, voidpf ptr)
|
png_zfree(voidpf png_ptr, voidpf ptr)
|
||||||
{
|
{
|
||||||
png_large_free((png_struct FAR *)png_ptr, (voidpf)ptr);
|
png_large_free((png_structp)png_ptr, (voidp)ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reset the crc variable to 32 bits of 1's. Care must be taken
|
/* reset the crc variable to 32 bits of 1's. Care must be taken
|
||||||
in case crc is > 32 bits to leave the top bits 0 */
|
in case crc is > 32 bits to leave the top bits 0 */
|
||||||
void
|
void
|
||||||
png_reset_crc(png_struct *png_ptr)
|
png_reset_crc(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
/* set crc to all 1's */
|
/* set crc to all 1's */
|
||||||
png_ptr->crc = 0xffffffffL;
|
png_ptr->crc = 0xffffffffL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note: the crc code below was copied from the sample code in the
|
/* Note: the crc code below was copied from the sample code in the
|
||||||
PNG spec, with appropriate modifications made to ensure the
|
PNG spec, with appropriate modifications made to ensure the
|
||||||
variables are large enough */
|
variables are large enough */
|
||||||
|
|
||||||
/* table of crc's of all 8-bit messages. If you wish to png_malloc this
|
/* table of crc's of all 8-bit messages. If you wish to png_malloc this
|
||||||
table, turn this into a pointer, and png_malloc it in make_crc_table().
|
table, turn this into a pointer, and png_malloc it in make_crc_table().
|
||||||
@ -161,10 +165,10 @@ make_crc_table(void)
|
|||||||
initialized to all 1's, and the transmitted value is the 1's complement
|
initialized to all 1's, and the transmitted value is the 1's complement
|
||||||
of the final running crc. */
|
of the final running crc. */
|
||||||
static png_uint_32
|
static png_uint_32
|
||||||
update_crc(png_uint_32 crc, png_bytef *buf, png_uint_32 len)
|
update_crc(png_uint_32 crc, png_bytep buf, png_uint_32 len)
|
||||||
{
|
{
|
||||||
png_uint_32 c;
|
png_uint_32 c;
|
||||||
png_bytef *p;
|
png_bytep p;
|
||||||
png_uint_32 n;
|
png_uint_32 n;
|
||||||
|
|
||||||
c = crc;
|
c = crc;
|
||||||
@ -178,7 +182,7 @@ update_crc(png_uint_32 crc, png_bytef *buf, png_uint_32 len)
|
|||||||
|
|
||||||
if (n > 0) do
|
if (n > 0) do
|
||||||
{
|
{
|
||||||
c = crc_table[(png_byte)((c ^ (*p++)) & 0xff)] ^ (c >> 8);
|
c = crc_table[(png_byte)((c ^ (*p++)) & 0xff)] ^ (c >> 8);
|
||||||
} while (--n);
|
} while (--n);
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
@ -189,15 +193,15 @@ update_crc(png_uint_32 crc, png_bytef *buf, png_uint_32 len)
|
|||||||
would need to use huge pointers to access all that data. If you
|
would need to use huge pointers to access all that data. If you
|
||||||
need this, put huge here and above. */
|
need this, put huge here and above. */
|
||||||
void
|
void
|
||||||
png_calculate_crc(png_struct *png_ptr, png_bytef *ptr,
|
png_calculate_crc(png_structp png_ptr, png_bytep ptr,
|
||||||
png_uint_32 length)
|
png_uint_32 length)
|
||||||
{
|
{
|
||||||
png_ptr->crc = update_crc(png_ptr->crc, ptr, length);
|
png_ptr->crc = update_crc(png_ptr->crc, ptr, length);
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
png_info_init(png_info *info)
|
png_info_init(png_infop info)
|
||||||
{
|
{
|
||||||
/* set everything to 0 */
|
/* set everything to 0 */
|
||||||
memset(info, 0, sizeof (png_info));
|
png_memset(info, 0, sizeof (png_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
pngchang.txt
16
pngchang.txt
@ -56,15 +56,11 @@ version 0.8
|
|||||||
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
|
version 0.81
|
||||||
added support for medium memory model
|
incorporated Tim Wegner's medium model code (thanks, Tim)
|
||||||
version 0.82
|
version 0.85
|
||||||
added ability to flush output stream automatically or manually
|
added more medium model code (almost everythings a far)
|
||||||
added ability to change I/O and error functions dynamically
|
added i/o, error, and memory callback functions
|
||||||
moved pngerror.c into pngio.c to make all the default functions static
|
fixed some bugs (16 bit, 4 bit interlaced, etc.)
|
||||||
when freeing memory in png_read_destroy don't free memory we didn't allocate
|
added first run progressive reader (barely tested)
|
||||||
added warnings when reading blocks of incorrect length
|
|
||||||
limit tEXt and zTXt keywords to 80 chars
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
124
pngconf.h
124
pngconf.h
@ -1,10 +1,10 @@
|
|||||||
|
|
||||||
/* pngconf.c - machine configurable file for libpng
|
/* pngconf.c - machine configurable file for libpng
|
||||||
|
|
||||||
libpng 1.0 beta 2 - version 0.81
|
libpng 1.0 beta 2 - version 0.85
|
||||||
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
|
December 19, 1995
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Any machine specific code is near the front of this file, so if you
|
/* Any machine specific code is near the front of this file, so if you
|
||||||
@ -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 32768
|
#define PNG_ZBUF_SIZE 8192
|
||||||
|
|
||||||
/* 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
|
||||||
@ -48,6 +48,14 @@
|
|||||||
#define PNG_MAX_ALLOC_64K
|
#define PNG_MAX_ALLOC_64K
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* this protects us against compilers which run on a windowing system
|
||||||
|
and thus don't have or would rather us not use the stdio types:
|
||||||
|
stdin, stdout, and stderr. The only one currently used is stderr
|
||||||
|
in png_error() and png_warning(). #defining PNG_NO_STDIO will
|
||||||
|
prevent these from being compiled and used. */
|
||||||
|
|
||||||
|
/* #define PNG_NO_STDIO */
|
||||||
|
|
||||||
/* this macro protects us against machines that don't have function
|
/* this macro protects us against machines that don't have function
|
||||||
prototypes. If your compiler does not handle function prototypes,
|
prototypes. If your compiler does not handle function prototypes,
|
||||||
define this macro. I've always been able to use _NO_PROTO as the
|
define this macro. I've always been able to use _NO_PROTO as the
|
||||||
@ -60,7 +68,7 @@
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
#ifdef _NO_PROTO
|
#ifdef _NO_PROTO
|
||||||
#define PNGARG(arglist)
|
#define PNGARG(arglist) ()
|
||||||
#else
|
#else
|
||||||
#define PNGARG(arglist) arglist
|
#define PNGARG(arglist) arglist
|
||||||
#endif /* _NO_PROTO */
|
#endif /* _NO_PROTO */
|
||||||
@ -129,6 +137,19 @@
|
|||||||
|
|
||||||
#endif /* PNG_INTERNAL */
|
#endif /* PNG_INTERNAL */
|
||||||
|
|
||||||
|
/* the following uses const char * instead of char * for error
|
||||||
|
and warning message functions, so some compilers won't complain.
|
||||||
|
If you want to use const, define PNG_USE_CONST here. It is not
|
||||||
|
normally defined to make configuration easier, as it is not a
|
||||||
|
critical part of the code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef PNG_USE_CONST
|
||||||
|
# define PNG_CONST const
|
||||||
|
#else
|
||||||
|
# define PNG_CONST
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The following defines give you the ability to remove code
|
/* The following defines give you the ability to remove code
|
||||||
from the library that you will not be using. I wish I
|
from the library that you will not be using. I wish I
|
||||||
could figure out how to automate this, but I can't do
|
could figure out how to automate this, but I can't do
|
||||||
@ -144,7 +165,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Any transformations you will not be using can be undef'ed here */
|
/* Any transformations you will not be using can be undef'ed here */
|
||||||
|
#define PNG_PROGRESSIVE_READ_SUPPORTED
|
||||||
#define PNG_READ_INTERLACING_SUPPORTED
|
#define PNG_READ_INTERLACING_SUPPORTED
|
||||||
#define PNG_READ_EXPAND_SUPPORTED
|
#define PNG_READ_EXPAND_SUPPORTED
|
||||||
#define PNG_READ_SHIFT_SUPPORTED
|
#define PNG_READ_SHIFT_SUPPORTED
|
||||||
@ -214,25 +235,105 @@ typedef unsigned char png_byte;
|
|||||||
change (I'm not sure if you will or not, so I thought I'd be safe) */
|
change (I'm not sure if you will or not, so I thought I'd be safe) */
|
||||||
typedef size_t png_size_t;
|
typedef size_t png_size_t;
|
||||||
|
|
||||||
/* The following is needed for medium model support. It cannot be in the
|
/* The following is needed for medium model support. It cannot be in the
|
||||||
PNG_INTERNAL section. Needs modification for other compilers besides
|
PNG_INTERNAL section. Needs modification for other compilers besides
|
||||||
MSC. Model independent support declares all arrays that might be very
|
MSC. Model independent support declares all arrays that might be very
|
||||||
large using the far keyword. The Zlib version used must also support
|
large using the far keyword. The Zlib version used must also support
|
||||||
model independent data. As of version Zlib .95, the necessary changes
|
model independent data. As of version Zlib .95, the necessary changes
|
||||||
have been made in Zlib. The USE_FAR_KEYWORD define triggers other
|
have been made in Zlib. The USE_FAR_KEYWORD define triggers other
|
||||||
changes that are needed. Most of the far keyword changes are hidden
|
changes that are needed. Most of the far keyword changes are hidden
|
||||||
inside typedefs with suffix "f". Tim Wegner */
|
inside typedefs with suffix "f". Tim Wegner */
|
||||||
|
|
||||||
#if defined(FAR) && defined(M_I86MM) /* MSC Medium model */
|
/* SJT: Separate compiler dependencies */
|
||||||
# define USE_FAR_KEYWORD
|
/* SJT: problem here is that zlib.h always defines FAR */
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
#if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
|
||||||
|
#define LDATA 1
|
||||||
#else
|
#else
|
||||||
|
#define LDATA 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(__WIN32__) && !defined(__FLAT__)
|
||||||
|
#define PNG_MAX_MALLOC_64K
|
||||||
|
#if (LDATA != 1)
|
||||||
|
#ifndef FAR
|
||||||
|
#define FAR __far
|
||||||
|
#endif
|
||||||
|
#define USE_FAR_KEYWORD
|
||||||
|
#endif /* LDATA != 1 */
|
||||||
|
|
||||||
|
/* SJT: Possibly useful for moving data out of default segment.
|
||||||
|
Uncomment it if you want. Could also define FARDATA as const
|
||||||
|
if your compiler supports it.
|
||||||
|
# define FARDATA FAR
|
||||||
|
*/
|
||||||
|
#endif /* __WIN32__, __FLAT__ */
|
||||||
|
|
||||||
|
#endif /* __BORLANDC__ */
|
||||||
|
|
||||||
|
|
||||||
|
/* SJT: Suggest testing for specific compiler first before
|
||||||
|
testing for FAR. The Watcom compiler defines both __MEDIUM__
|
||||||
|
and M_I86MM, making reliance oncertain keywords suspect
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* MSC Medium model */
|
||||||
|
#if defined(FAR)
|
||||||
|
# if defined(M_I86MM)
|
||||||
|
# define USE_FAR_KEYWORD
|
||||||
|
# define FARDATA FAR /* SJT: added */
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* SJT: default case */
|
||||||
|
#ifndef FAR
|
||||||
# define FAR
|
# define FAR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* SJT: At this point FAR is always defined */
|
||||||
|
|
||||||
|
/* not used anymore, but kept for compatability */
|
||||||
typedef unsigned char FAR png_bytef;
|
typedef unsigned char FAR png_bytef;
|
||||||
|
|
||||||
|
/* SJT: */
|
||||||
|
#ifndef FARDATA
|
||||||
|
#define FARDATA
|
||||||
|
#endif
|
||||||
|
|
||||||
/* End medium model changes to be in zconf.h */
|
/* End medium model changes to be in zconf.h */
|
||||||
|
|
||||||
|
/* SJT: More typedefs */
|
||||||
|
typedef void FAR * png_voidp;
|
||||||
|
|
||||||
|
|
||||||
|
/* SJT: Add typedefs for pointers */
|
||||||
|
typedef png_byte FAR * png_bytep;
|
||||||
|
typedef png_uint_32 FAR * png_uint_32p;
|
||||||
|
typedef png_int_32 FAR * png_int_32p;
|
||||||
|
typedef png_uint_16 FAR * png_uint_16p;
|
||||||
|
typedef png_int_16 FAR * png_int_16p;
|
||||||
|
typedef PNG_CONST char FAR * png_const_charp;
|
||||||
|
typedef char FAR * png_charp;
|
||||||
|
|
||||||
|
/* SJT: Pointers to pointers; i.e. arrays */
|
||||||
|
typedef png_byte FAR * FAR * png_bytepp;
|
||||||
|
typedef png_uint_32 FAR * FAR * png_uint_32pp;
|
||||||
|
typedef png_int_32 FAR * FAR * png_int_32pp;
|
||||||
|
typedef png_uint_16 FAR * FAR * png_uint_16pp;
|
||||||
|
typedef png_int_16 FAR * FAR * png_int_16pp;
|
||||||
|
typedef PNG_CONST char FAR * FAR * png_const_charpp;
|
||||||
|
typedef char FAR * FAR * png_charpp;
|
||||||
|
|
||||||
|
|
||||||
|
/* SJT: libpng typedefs for types in zlib. If Zlib changes
|
||||||
|
or another compression library is used, then change these.
|
||||||
|
Eliminates need to change all the source files.
|
||||||
|
*/
|
||||||
|
typedef charf * png_zcharp;
|
||||||
|
typedef charf * FAR * png_zcharpp;
|
||||||
|
typedef z_stream * png_zstreamp; /* zlib won't accept far z_stream */
|
||||||
|
|
||||||
|
|
||||||
/* User may want to use these so not in PNG_INTERNAL. Any library functions
|
/* User may want to use these so not in PNG_INTERNAL. Any library functions
|
||||||
that are passed far data must be model independent. */
|
that are passed far data must be model independent. */
|
||||||
#if defined(USE_FAR_KEYWORD) /* memory model independent fns */
|
#if defined(USE_FAR_KEYWORD) /* memory model independent fns */
|
||||||
@ -240,6 +341,7 @@ typedef unsigned char FAR png_bytef;
|
|||||||
# define png_strcat _fstrcat
|
# define png_strcat _fstrcat
|
||||||
# define png_strlen _fstrlen
|
# define png_strlen _fstrlen
|
||||||
# define png_strcmp _fstrcmp
|
# define png_strcmp _fstrcmp
|
||||||
|
# define png_memcmp _fmemcmp /* SJT: added */
|
||||||
# define png_memcpy _fmemcpy
|
# define png_memcpy _fmemcpy
|
||||||
# define png_memset _fmemset
|
# define png_memset _fmemset
|
||||||
#else /* use the usual functions */
|
#else /* use the usual functions */
|
||||||
@ -247,11 +349,11 @@ typedef unsigned char FAR png_bytef;
|
|||||||
# define png_strcat strcat
|
# define png_strcat strcat
|
||||||
# define png_strlen strlen
|
# define png_strlen strlen
|
||||||
# define png_strcmp strcmp
|
# define png_strcmp strcmp
|
||||||
|
# define png_memcmp memcmp /* SJT: added */
|
||||||
# define png_memcpy memcpy
|
# define png_memcpy memcpy
|
||||||
# define png_memset memset
|
# define png_memset memset
|
||||||
#endif
|
#endif
|
||||||
/* End of memory model independent support */
|
/* End of memory model independent support */
|
||||||
|
|
||||||
|
|
||||||
#endif /* PNGCONF_H */
|
#endif /* PNGCONF_H */
|
||||||
|
|
||||||
|
99
pngerror.c
Normal file
99
pngerror.c
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
|
||||||
|
/* pngerror.c - stub functions for i/o and memory allocation
|
||||||
|
|
||||||
|
libpng 1.0 beta 2 - version 0.85
|
||||||
|
For conditions of distribution and use, see copyright notice in png.h
|
||||||
|
Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc.
|
||||||
|
December 19, 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_structp png_ptr, png_const_charp message)
|
||||||
|
{
|
||||||
|
if (png_ptr->error_fn)
|
||||||
|
(*(png_ptr->error_fn))(png_ptr, message);
|
||||||
|
|
||||||
|
/* if the following returns or doesn't exist, use the default function,
|
||||||
|
which will not return */
|
||||||
|
png_default_error(png_ptr, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
png_warning(png_structp png_ptr, png_const_charp message)
|
||||||
|
{
|
||||||
|
if (png_ptr->warning_fn)
|
||||||
|
(*(png_ptr->warning_fn))(png_ptr, message);
|
||||||
|
else
|
||||||
|
png_default_warning(png_ptr, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
png_default_error(png_structp png_ptr, png_const_charp message)
|
||||||
|
{
|
||||||
|
#ifndef PNG_NO_STDIO
|
||||||
|
fprintf(stderr, "libpng error: %s\n", message);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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_default_warning(png_structp png_ptr, png_const_charp message)
|
||||||
|
{
|
||||||
|
if (!png_ptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#ifndef PNG_NO_STDIO
|
||||||
|
fprintf(stderr, "libpng warning: %s\n", message);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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) */
|
||||||
|
void
|
||||||
|
png_set_message_fn(png_structp png_ptr, png_voidp msg_ptr, png_msg_ptr error_fn,
|
||||||
|
png_msg_ptr warning_fn)
|
||||||
|
{
|
||||||
|
png_ptr->msg_ptr = msg_ptr;
|
||||||
|
|
||||||
|
png_ptr->error_fn = error_fn;
|
||||||
|
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. */
|
||||||
|
png_voidp
|
||||||
|
png_get_msg_ptr(png_structp png_ptr)
|
||||||
|
{
|
||||||
|
return png_ptr->msg_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
453
pngio.c
453
pngio.c
@ -1,45 +1,54 @@
|
|||||||
|
|
||||||
/* pngio.c - default functions for data I/O and error/warning messages
|
/* pngstub.c - stub functions for i/o and memory allocation
|
||||||
|
|
||||||
libpng 1.0 beta 3 - version 0.82
|
libpng 1.0 beta 2 - version 0.85
|
||||||
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.
|
||||||
Some portions Copyright (C) 1995 Andreas Dilger
|
December 19, 1995
|
||||||
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 write functions which have the same
|
special handling are expected to write functions which have the same
|
||||||
arguments as these, and perform similar functions, but possibly have
|
arguments as these, and perform similar functions, but possibly have
|
||||||
different I/O methods. Note that you shouldn't change these functions,
|
different I/O methods. Note that you shouldn't change these functions,
|
||||||
but rather write replacement functions and then change them at run
|
but rather write replacement functions and then change them at run
|
||||||
time with png_set_write_fn(...) or png_set_read_fn(...), etc */
|
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 a good example of how to do it. Note that this routine
|
else, this is a good example of how to do it. Note that this routine
|
||||||
sometimes gets called with very small lengths, so you should implement
|
sometimes gets called with very small lengths, so you should implement
|
||||||
some kind of simple buffering if you are using unbuffered writes. This
|
some kind of simple buffering if you are using unbuffered writes. This
|
||||||
should never be asked to write more then 64K on a 16 bit machine. The
|
should never be asked to write more then 64K on a 16 bit machine. The
|
||||||
cast to png_size_t is there for insurance. */
|
cast to png_size_t is there for insurance. */
|
||||||
|
|
||||||
|
void
|
||||||
|
png_write_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
|
||||||
|
{
|
||||||
|
if (png_ptr->write_data_fn)
|
||||||
|
(*(png_ptr->write_data_fn))(png_ptr, data, length);
|
||||||
|
else
|
||||||
|
png_error(png_ptr, "Call to NULL write function");
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef USE_FAR_KEYWORD
|
#ifndef USE_FAR_KEYWORD
|
||||||
static void
|
void
|
||||||
png_write_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length)
|
png_default_write_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
|
||||||
{
|
{
|
||||||
png_uint_32 check;
|
png_uint_32 check;
|
||||||
|
|
||||||
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_ptr->error_fn))(png_ptr, "Write error");
|
png_error(png_ptr, "Write Error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* this is the model-independent version. Since the standard I/O library
|
/* this is the model-independent version. Since the standard I/O library
|
||||||
can't handle far buffers in the medium and small models, we have to copy
|
can't handle far buffers in the medium and small models, we have to copy
|
||||||
the data.
|
the data.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define NEAR_BUF_SIZE 1024
|
#define NEAR_BUF_SIZE 1024
|
||||||
@ -50,93 +59,114 @@ png_write_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length)
|
|||||||
#include <dos.h>
|
#include <dos.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
void
|
||||||
png_write_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length)
|
png_default_write_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
|
||||||
{
|
{
|
||||||
png_uint_32 check;
|
png_uint_32 check;
|
||||||
png_byte *n_data;
|
png_byte *n_data;
|
||||||
|
|
||||||
/* Check if data really is near. If so, use usual code. */
|
/* Check if data really is near. If so, use usual code. */
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
/* do it this way just to quiet warning */
|
/* do it this way just to quiet warning */
|
||||||
FP_OFF(n_data) = FP_OFF(data);
|
FP_OFF(n_data) = FP_OFF(data);
|
||||||
if(FP_SEG(n_data) == FP_SEG(data))
|
if (FP_SEG(n_data) == FP_SEG(data))
|
||||||
#else
|
#else
|
||||||
/* this works in MSC also but with lost segment warning */
|
/* this works in MSC also but with lost segment warning */
|
||||||
n_data = (png_byte *)data;
|
n_data = (png_byte *)data;
|
||||||
if((png_bytef *)n_data == data)
|
if ((png_bytep)n_data == data)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
check = fwrite(n_data, 1, (png_size_t)length, png_ptr->fp);
|
check = fwrite(n_data, 1, (png_size_t)length, png_ptr->fp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
png_byte buf[NEAR_BUF_SIZE];
|
png_byte buf[NEAR_BUF_SIZE];
|
||||||
png_size_t written, remaining, err;
|
png_size_t written, remaining, err;
|
||||||
check = 0;
|
check = 0;
|
||||||
remaining = (png_size_t)length;
|
remaining = (png_size_t)length;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
written = MIN(NEAR_BUF_SIZE,remaining);
|
written = MIN(NEAR_BUF_SIZE, remaining);
|
||||||
png_memcpy(buf,data,written); /* copy far buffer to near buffer */
|
png_memcpy(buf, data, written); /* copy far buffer to near buffer */
|
||||||
err = fwrite(buf, 1, written, png_ptr->fp);
|
err = fwrite(buf, 1, written, png_ptr->fp);
|
||||||
if(err != written)
|
if (err != written)
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
check += err;
|
check += err;
|
||||||
data += written;
|
data += written;
|
||||||
remaining -= written;
|
remaining -= written;
|
||||||
}
|
}
|
||||||
while(remaining != 0);
|
while (remaining != 0);
|
||||||
}
|
}
|
||||||
if (check != length)
|
if (check != length)
|
||||||
{
|
{
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Write error");
|
png_error(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 a good example of how to do it. Note that this routine
|
else, this is the place to do it. We suggest saving the old code
|
||||||
sometimes gets called with very small lengths, so you should implement
|
for future use. Note that this routine sometimes gets called with
|
||||||
some kind of simple buffering if you are using unbuffered reads. This
|
very small lengths, so you should implement some kind of simple
|
||||||
should never be asked to read more then 64K on a 16 bit machine. The
|
buffering if you are using unbuffered reads. This should
|
||||||
cast to png_size_t is there for insurance. */
|
never be asked to read more then 64K on a 16 bit machine. The cast
|
||||||
|
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. */
|
||||||
|
void
|
||||||
|
png_read_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
|
||||||
|
{
|
||||||
|
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
|
||||||
|
if (png_ptr->read_mode == PNG_READ_PUSH_MODE)
|
||||||
|
{
|
||||||
|
png_push_fill_buffer(png_ptr, data, length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (png_ptr->read_data_fn)
|
||||||
|
(*(png_ptr->read_data_fn))(png_ptr, data, length);
|
||||||
|
else
|
||||||
|
png_error(png_ptr, "Call to NULL read function");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef USE_FAR_KEYWORD
|
#ifndef USE_FAR_KEYWORD
|
||||||
static void
|
void
|
||||||
png_read_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length)
|
png_default_read_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
|
||||||
{
|
{
|
||||||
png_uint_32 check;
|
png_uint_32 check;
|
||||||
|
|
||||||
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_ptr->error_fn))(png_ptr, "Read error");
|
png_error(png_ptr, "Read Error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static void
|
void
|
||||||
png_read_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length)
|
png_default_read_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
|
||||||
{
|
{
|
||||||
png_uint_32 check;
|
png_uint_32 check;
|
||||||
png_byte *n_data;
|
png_byte *n_data;
|
||||||
|
|
||||||
/* Check if data really is near. If so, use usual code. */
|
/* Check if data really is near. If so, use usual code. */
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
/* do it this way just to quiet warning */
|
/* do it this way just to quiet warning */
|
||||||
FP_OFF(n_data) = FP_OFF(data);
|
FP_OFF(n_data) = FP_OFF(data);
|
||||||
if(FP_SEG(n_data) == FP_SEG(data))
|
if (FP_SEG(n_data) == FP_SEG(data))
|
||||||
#else
|
#else
|
||||||
/* this works in MSC also but with lost segment warning */
|
/* this works in MSC also but with lost segment warning */
|
||||||
n_data = (png_byte *)data;
|
n_data = (png_byte *)data;
|
||||||
if((png_bytef *)n_data == data)
|
if ((PNG_BYTEP )n_data == data)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
check = fread(n_data, 1, (size_t)length, png_ptr->fp);
|
check = fread(n_data, 1, (size_t)length, png_ptr->fp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
png_byte buf[NEAR_BUF_SIZE];
|
png_byte buf[NEAR_BUF_SIZE];
|
||||||
@ -145,267 +175,136 @@ png_read_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length)
|
|||||||
remaining = (png_size_t)length;
|
remaining = (png_size_t)length;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
read = MIN(NEAR_BUF_SIZE,remaining);
|
read = MIN(NEAR_BUF_SIZE, remaining);
|
||||||
err = fread(buf, 1, read, png_ptr->fp);
|
err = fread(buf, 1, read, png_ptr->fp);
|
||||||
png_memcpy(data,buf,read); /* copy far buffer to near buffer */
|
png_memcpy(data, buf, read); /* copy far buffer to near buffer */
|
||||||
if(err != read)
|
if(err != read)
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
check += err;
|
check += err;
|
||||||
data += read;
|
data += read;
|
||||||
remaining -= read;
|
remaining -= read;
|
||||||
}
|
}
|
||||||
while(remaining != 0);
|
while (remaining != 0);
|
||||||
}
|
}
|
||||||
if (check != length)
|
if (check != length)
|
||||||
{
|
{
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Read error");
|
png_error(png_ptr, "read Error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* This function does nothing, and is used for the write function on
|
|
||||||
a read, and vice-versa. It is an error if this function is
|
|
||||||
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)
|
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
|
||||||
/* This function does nothing, and is supplied for user I/O functions which
|
void
|
||||||
do not do any buffering. This function is set when NULL is supplied for
|
png_flush(png_struct *png_ptr)
|
||||||
the flush function pointer. */
|
|
||||||
static void
|
|
||||||
png_empty_flush(png_struct *png_ptr)
|
|
||||||
{
|
{
|
||||||
|
if (png_ptr->output_flush_fn)
|
||||||
|
(*(png_ptr->output_flush_fn))(png_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
/* Write out any remaining output that is stored in the output buffers.
|
png_default_flush(png_struct *png_ptr)
|
||||||
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);
|
if (png_ptr->fp)
|
||||||
|
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
|
#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
|
/* This function allows the application to supply new output functions for
|
||||||
libpng if standard C streams aren't being used. The new write function
|
libpng if standard C streams aren't being used.
|
||||||
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:
|
||||||
This function takes as its arguments:
|
png_ptr - pointer to a png output data structure
|
||||||
png_ptr - pointer to a png output data structure
|
io_ptr - pointer to user supplied structure containing info about
|
||||||
io_ptr - pointer to user supplied structure containing info about
|
the output functions. May be NULL.
|
||||||
the output functions. May be NULL.
|
write_data_fn - pointer to a new output function which takes as its
|
||||||
write_data_fn - pointer to a new output function which takes as its
|
arguments a pointer to a png_struct, a pointer to
|
||||||
arguments a pointer to a png_struct, a pointer to
|
data to be written, and a 32-bit unsigned int which is
|
||||||
data to be written, and a 32-bit unsigned int which is
|
the number of bytes to be written. The new write
|
||||||
the number of bytes to be written. The new write
|
function should call (*(png_ptr->error_fn))("Error msg")
|
||||||
function should call (*(png_ptr->error_fn))("Error msg")
|
to exit and output any fatal error messages.
|
||||||
to exit and output any fatal error messages.
|
flush_data_fn - pointer to a new flush function which takes as its
|
||||||
flush_data_fn - pointer to a new flush function which takes as its
|
arguments a pointer to a png_struct. After a call to
|
||||||
arguments a pointer to a png_struct. After a call to
|
the flush function, there should be no data in any buffers
|
||||||
the flush function, there should be no data in any buffers
|
or pending transmission. If the output method doesn't do
|
||||||
or pending transmission. If the output method doesn't do
|
any buffering of ouput, this parameter can be NULL. If
|
||||||
any buffering of ouput, this parameter can be NULL. If
|
PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng
|
||||||
PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng
|
compile time, output_flush_fn will be ignored, although
|
||||||
compile time, output_flush_fn will be ignored, although
|
it must be supplied for compatibility. */
|
||||||
it must be supplied for compatibility. */
|
|
||||||
void
|
void
|
||||||
png_set_write_fn(png_struct *png_ptr, void *io_ptr, png_rw_ptr write_data_fn,
|
png_set_write_fn(png_structp png_ptr, png_voidp io_ptr, png_rw_ptr write_data_fn,
|
||||||
png_flush_ptr output_flush_fn)
|
png_flush_ptr output_flush_fn)
|
||||||
{
|
{
|
||||||
png_ptr->io_ptr = io_ptr;
|
png_ptr->io_ptr = io_ptr;
|
||||||
|
|
||||||
if (write_data_fn == NULL)
|
if (write_data_fn)
|
||||||
{
|
png_ptr->write_data_fn = write_data_fn;
|
||||||
(*(png_ptr->error_fn))(png_ptr, "NULL write function pointer given");
|
else
|
||||||
}
|
png_ptr->write_data_fn = png_default_write_data;
|
||||||
|
|
||||||
png_ptr->write_data_fn = write_data_fn;
|
|
||||||
|
|
||||||
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
|
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
|
||||||
if (output_flush_fn == NULL)
|
if (output_flush_fn == NULL)
|
||||||
{
|
png_ptr->output_flush_fn = png_default_flush;
|
||||||
png_ptr->output_flush_fn = png_empty_flush;
|
else
|
||||||
}
|
png_ptr->output_flush_fn = output_flush_fn;
|
||||||
else
|
|
||||||
{
|
|
||||||
png_ptr->output_flush_fn = output_flush_fn;
|
|
||||||
}
|
|
||||||
#endif /* PNG_WRITE_FLUSH_SUPPORTED */
|
#endif /* PNG_WRITE_FLUSH_SUPPORTED */
|
||||||
|
|
||||||
/* It is an error to write to a read device */
|
/* It is an error to read while writing a png file */
|
||||||
png_ptr->read_data_fn = png_empty_rw;
|
png_ptr->read_data_fn = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This function allows the application to supply a new input function
|
/* 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
|
for libpng if standard C streams aren't being used.
|
||||||
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:
|
||||||
This function takes as its arguments:
|
png_ptr - pointer to a png input data structure
|
||||||
png_ptr - pointer to a png input data structure
|
io_ptr - pointer to user supplied structure containing info about
|
||||||
io_ptr - pointer to user supplied structure containing info about
|
the input functions. May be NULL.
|
||||||
the input functions. May be NULL.
|
read_data_fn - pointer to a new input function which takes as it's
|
||||||
read_data_fn - pointer to a new input function which takes as it's
|
arguments a pointer to a png_struct, a pointer to
|
||||||
arguments a pointer to a png_struct, a pointer to
|
a location where input data can be stored, and a 32-bit
|
||||||
a location where input data can be stored, and a 32-bit
|
unsigned int which is the number of bytes to be read. */
|
||||||
unsigned int which is the number of bytes to be read. */
|
|
||||||
void
|
void
|
||||||
png_set_read_fn(png_struct *png_ptr, void *io_ptr, png_rw_ptr read_data_fn)
|
png_set_read_fn(png_struct *png_ptr, void *io_ptr, png_rw_ptr read_data_fn)
|
||||||
{
|
{
|
||||||
png_ptr->io_ptr = io_ptr;
|
png_ptr->io_ptr = io_ptr;
|
||||||
|
|
||||||
if (read_data_fn == NULL)
|
if (read_data_fn)
|
||||||
{
|
png_ptr->read_data_fn = read_data_fn;
|
||||||
(*(png_ptr->error_fn))(png_ptr, "NULL read function pointer given");
|
else
|
||||||
}
|
png_ptr->read_data_fn = png_default_read_data;
|
||||||
png_ptr->read_data_fn = read_data_fn;
|
|
||||||
|
|
||||||
/* It is an error to write to a read device */
|
/* It is an error to write to a read device */
|
||||||
png_ptr->write_data_fn = png_empty_rw;
|
png_ptr->write_data_fn = NULL;
|
||||||
|
|
||||||
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
|
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
|
||||||
png_ptr->output_flush_fn = png_empty_flush;
|
png_ptr->output_flush_fn = NULL;
|
||||||
#endif /* PNG_WRITE_FLUSH_SUPPORTED */
|
#endif /* PNG_WRITE_FLUSH_SUPPORTED */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This function returns a pointer to the io_ptr associated with the user
|
/* This function returns a pointer to the io_ptr associated with the user
|
||||||
functions. The application should free any memory associated with this
|
functions. The application should free any memory associated with this
|
||||||
pointer before png_write_destroy and png_read_destroy are called. */
|
pointer before png_write_destroy and png_read_destroy are called. */
|
||||||
void *
|
void *
|
||||||
png_get_io_ptr(png_struct *png_ptr)
|
png_get_io_ptr(png_struct *png_ptr)
|
||||||
{
|
{
|
||||||
return png_ptr->io_ptr;
|
return png_ptr->io_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize the input/output for the png file. If you change
|
||||||
/* This function is called when the application wants to use another
|
the read and write routines, you will probably need to change
|
||||||
method of handling errors and warnings. Note that the error function must
|
this routine (or write your own). If you change the parameters
|
||||||
NOT return to the calling routine or serious problems will occur. The
|
of this routine, remember to change png.h also. */
|
||||||
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
|
void
|
||||||
png_set_msg_fn(png_struct *png_ptr, void *msg_ptr, png_msg_ptr error_fn,
|
png_init_io(png_structp png_ptr, FILE *fp)
|
||||||
png_msg_ptr warning_fn)
|
|
||||||
{
|
{
|
||||||
png_ptr->msg_ptr = msg_ptr;
|
png_ptr->fp = fp;
|
||||||
|
png_ptr->read_data_fn = png_default_read_data;
|
||||||
if (error_fn == NULL)
|
png_ptr->write_data_fn = png_default_write_data;
|
||||||
{
|
#ifdef PNG_WRITE_FLUSH_SUPPORTED
|
||||||
png_ptr->error_fn = png_empty_error;
|
png_ptr->output_flush_fn = png_default_flush;
|
||||||
}
|
#endif
|
||||||
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
|
|
||||||
png_init_io(png_struct *png_ptr, FILE *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 */
|
|
||||||
}
|
|
||||||
|
274
pngmem.c
274
pngmem.c
@ -1,13 +1,13 @@
|
|||||||
|
|
||||||
/* pngmem.c - stub functions for memory allocation
|
/* pngmem.c - stub functions for memory allocation
|
||||||
|
|
||||||
libpng 1.0 beta 2 - version 0.81
|
libpng 1.0 beta 2 - version 0.85
|
||||||
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
|
December 19, 1995
|
||||||
|
|
||||||
This file provides a location for all memory allocation. Users which
|
This file provides a location for all memory allocation. Users which
|
||||||
need special memory handling are expected to modify the code in this file
|
need special memory handling are expected to modify the code in this file
|
||||||
to meet their needs. See the instructions at each function. */
|
to meet their needs. See the instructions at each function. */
|
||||||
|
|
||||||
#define PNG_INTERNAL
|
#define PNG_INTERNAL
|
||||||
@ -19,168 +19,28 @@
|
|||||||
need to allocate exactly 64K, so whatever you call here must
|
need to allocate exactly 64K, so whatever you call here must
|
||||||
have the ability to do that. */
|
have the ability to do that. */
|
||||||
|
|
||||||
/* Borland compilers have this habit of not giving you 64K chunks
|
|
||||||
that start on the segment in DOS mode. This has not been observed
|
|
||||||
in Windows, and of course it doesn't matter in 32 bit mode, as there
|
|
||||||
are no segments. Now libpng doesn't need that much memory normally,
|
|
||||||
but zlib does, so we have to normalize it, if necessary. It would be
|
|
||||||
better if zlib worked in less then 64K, but it doesn't, so we
|
|
||||||
have to deal with it. Truely, we are misusing farmalloc here,
|
|
||||||
as it is designed for use with huge pointers, which don't care
|
|
||||||
about segments. So we allocate a large amount of memory, and
|
|
||||||
divvy off segments when needed.
|
|
||||||
*/
|
|
||||||
#ifdef __TURBOC__
|
|
||||||
#ifndef __WIN32__
|
|
||||||
#ifndef __FLAT__
|
|
||||||
|
|
||||||
/* NUM_SEG is the number of segments allocated at once */
|
png_voidp
|
||||||
#define NUM_SEG 4
|
png_large_malloc(png_structp png_ptr, png_uint_32 size)
|
||||||
typedef struct borland_seg_struct
|
|
||||||
{
|
{
|
||||||
void *mem_ptr;
|
png_voidp ret;
|
||||||
void *seg_ptr[NUM_SEG];
|
|
||||||
int seg_used[NUM_SEG];
|
|
||||||
int num_used;
|
|
||||||
} borland_seg;
|
|
||||||
|
|
||||||
borland_seg *save_array;
|
|
||||||
int num_save_array;
|
|
||||||
int max_save_array;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
voidpf
|
|
||||||
png_large_malloc(png_structf *png_ptr, png_uint_32 size)
|
|
||||||
{
|
|
||||||
voidpf ret;
|
|
||||||
if (!png_ptr || !size)
|
if (!png_ptr || !size)
|
||||||
return ((void *)0);
|
return ((voidp)0);
|
||||||
|
|
||||||
#ifdef PNG_MAX_MALLOC_64K
|
#ifdef PNG_MAX_MALLOC_64K
|
||||||
if (size > (png_uint_32)65536L)
|
if (size > (png_uint_32)65536L)
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Cannot Allocate > 64K");
|
png_error(png_ptr, "Cannot Allocate > 64K");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __TURBOC__
|
#if defined(__TURBOC__) && !defined(__FLAT__)
|
||||||
# if defined(__WIN32__) || defined(__FLAT__)
|
ret = farmalloc(size);
|
||||||
ret = malloc(size);
|
#else
|
||||||
# else
|
ret = malloc(size);
|
||||||
|
|
||||||
if (size == 65536L)
|
|
||||||
{
|
|
||||||
unsigned long offset;
|
|
||||||
if (!save_array)
|
|
||||||
{
|
|
||||||
ret = farmalloc(size);
|
|
||||||
offset = (unsigned long)(ret);
|
|
||||||
offset &= 0xffffL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ret = (void *)0;
|
|
||||||
}
|
|
||||||
if (save_array || offset)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
farfree(ret);
|
|
||||||
ret = (void *)0;
|
|
||||||
|
|
||||||
if (!save_array)
|
|
||||||
{
|
|
||||||
unsigned long offset;
|
|
||||||
png_byte huge *ptr;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
num_save_array = 1;
|
|
||||||
save_array = malloc(num_save_array * sizeof (borland_seg));
|
|
||||||
if (!save_array)
|
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Out of Memory 1");
|
|
||||||
save_array->mem_ptr = farmalloc(
|
|
||||||
(unsigned long)(NUM_SEG) * 65536L + 65532L);
|
|
||||||
if (!save_array->mem_ptr)
|
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Out of Memory 2");
|
|
||||||
offset = (unsigned long)(ret);
|
|
||||||
offset &= 0xffffL;
|
|
||||||
ptr = save_array->mem_ptr;
|
|
||||||
if (offset)
|
|
||||||
ptr += 65536L - offset;
|
|
||||||
for (i = 0; i < NUM_SEG; i++, ptr += 65536L)
|
|
||||||
{
|
|
||||||
save_array->seg_ptr[i] = ptr;
|
|
||||||
save_array->seg_used[i] = 0;
|
|
||||||
}
|
|
||||||
save_array->num_used = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < num_save_array; i++)
|
|
||||||
{
|
|
||||||
for (j = 0; j < NUM_SEG; j++)
|
|
||||||
{
|
|
||||||
if (!save_array[i].seg_used[j])
|
|
||||||
{
|
|
||||||
ret = save_array[i].seg_ptr[j];
|
|
||||||
save_array[i].seg_used[j] = 1;
|
|
||||||
save_array[i].num_used++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
{
|
|
||||||
unsigned long offset;
|
|
||||||
png_byte huge *ptr;
|
|
||||||
|
|
||||||
save_array = realloc(save_array,
|
|
||||||
(num_save_array + 1) * sizeof (borland_seg));
|
|
||||||
if (!save_array)
|
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Out of Memory 3");
|
|
||||||
save_array[num_save_array].mem_ptr = farmalloc(
|
|
||||||
(unsigned long)(NUM_SEG) * 65536L + 65532L);
|
|
||||||
if (!save_array[num_save_array].mem_ptr)
|
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Out of Memory 4");
|
|
||||||
offset = (unsigned long)(ret);
|
|
||||||
offset &= 0xffffL;
|
|
||||||
ptr = save_array[num_save_array].mem_ptr;
|
|
||||||
if (offset)
|
|
||||||
ptr += 65536L - offset;
|
|
||||||
for (i = 0; i < NUM_SEG; i++, ptr += 65536L)
|
|
||||||
{
|
|
||||||
save_array[num_save_array].seg_ptr[i] = ptr;
|
|
||||||
save_array[num_save_array].seg_used[i] = 0;
|
|
||||||
}
|
|
||||||
ret = save_array[num_save_array].seg_ptr[0];
|
|
||||||
save_array[num_save_array].seg_used[0] = 1;
|
|
||||||
save_array[num_save_array].num_used = 1;
|
|
||||||
num_save_array++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ret = farmalloc(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
# endif /* __WIN32__ */
|
|
||||||
#else /* __TURBOC__ */
|
|
||||||
# ifdef _MSC_VER
|
|
||||||
ret = halloc(size, 1);
|
|
||||||
# else
|
|
||||||
/* everybody else, so normal malloc should do it. */
|
|
||||||
ret = malloc(size);
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ret == NULL)
|
if (ret == NULL)
|
||||||
{
|
{
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Out of Memory");
|
png_error(png_ptr, "Out of Memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -190,124 +50,88 @@ png_large_malloc(png_structf *png_ptr, png_uint_32 size)
|
|||||||
configuration, png_ptr is not used, but is passed in case it
|
configuration, png_ptr is not used, but is passed in case it
|
||||||
is needed. If ptr is NULL, return without taking any action. */
|
is needed. If ptr is NULL, return without taking any action. */
|
||||||
void
|
void
|
||||||
png_large_free(png_structf *png_ptr, voidpf ptr)
|
png_large_free(png_structp png_ptr, png_voidp ptr)
|
||||||
{
|
{
|
||||||
if (!png_ptr)
|
if (!png_ptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ptr != (void *)0)
|
if (ptr != NULL)
|
||||||
{
|
{
|
||||||
#ifdef __TURBOC__
|
#if defined(__TURBOC__) && !defined(__FLAT__)
|
||||||
# if defined(__WIN32__) || defined(__FLAT__)
|
farfree(ptr);
|
||||||
if (ptr)
|
|
||||||
free(ptr);
|
|
||||||
# else
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
for (i = 0; i < num_save_array; i++)
|
|
||||||
{
|
|
||||||
for (j = 0; j < NUM_SEG; j++)
|
|
||||||
{
|
|
||||||
if (ptr == save_array[i].seg_ptr[j])
|
|
||||||
{
|
|
||||||
save_array[i].seg_used[j] = 0;
|
|
||||||
ptr = 0;
|
|
||||||
save_array[i].num_used--;
|
|
||||||
if (!save_array[i].num_used)
|
|
||||||
{
|
|
||||||
int k;
|
|
||||||
|
|
||||||
num_save_array--;
|
|
||||||
farfree(save_array[i].mem_ptr);
|
|
||||||
for (k = i; k < num_save_array; k++)
|
|
||||||
save_array[k] = save_array[k + 1];
|
|
||||||
if (!num_save_array)
|
|
||||||
{
|
|
||||||
free(save_array);
|
|
||||||
save_array = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!ptr)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ptr)
|
|
||||||
farfree(ptr);
|
|
||||||
# endif
|
|
||||||
#else
|
#else
|
||||||
# ifdef _MSC_VER
|
free(ptr);
|
||||||
hfree(ptr);
|
|
||||||
# else
|
|
||||||
free(ptr);
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Allocate memory. This is called for smallish blocks only It
|
/* Allocate memory. This is called for smallish blocks only It
|
||||||
should not get anywhere near 64K. */
|
should not get anywhere near 64K. On segmented machines, this
|
||||||
|
must come from the local heap (for zlib). */
|
||||||
void *
|
void *
|
||||||
png_malloc(png_struct *png_ptr, png_uint_32 size)
|
png_malloc(png_structp png_ptr, png_uint_32 size)
|
||||||
{
|
{
|
||||||
void *ret;
|
void *ret;
|
||||||
|
|
||||||
if (!png_ptr || !size)
|
if (!png_ptr || !size)
|
||||||
|
{
|
||||||
return ((void *)0);
|
return ((void *)0);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef PNG_MAX_MALLOC_64K
|
#ifdef PNG_MAX_MALLOC_64K
|
||||||
if (size > (png_uint_32)65536L)
|
if (size > (png_uint_32)65536L)
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Cannot Allocate > 64K");
|
png_error(png_ptr, "Cannot Allocate > 64K");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ret = malloc((png_size_t)size);
|
ret = malloc((png_size_t)size);
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
{
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Out of Memory 6");
|
png_error(png_ptr, "Out of Memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reallocate memory. This will not get near 64K on a
|
/* Reallocate memory. This will not get near 64K on a
|
||||||
even marginally reasonable file. */
|
even marginally reasonable file. */
|
||||||
void *
|
void *
|
||||||
png_realloc(png_struct *png_ptr, void *ptr, png_uint_32 size,
|
png_realloc(png_structp png_ptr, void * ptr, png_uint_32 size,
|
||||||
png_uint_32 old_size)
|
png_uint_32 old_size)
|
||||||
{
|
{
|
||||||
void *ret;
|
void *ret;
|
||||||
|
|
||||||
if (!png_ptr || !old_size || !ptr || !size)
|
if (!png_ptr || !old_size || !ptr || !size)
|
||||||
return ((void *)0);
|
return ((void *)0);
|
||||||
|
|
||||||
#ifdef PNG_MAX_MALLOC_64K
|
#ifdef PNG_MAX_MALLOC_64K
|
||||||
if (size > (png_uint_32)65536L)
|
if (size > (png_uint_32)65536L)
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Cannot Allocate > 64K");
|
png_error(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_ptr->error_fn))(png_ptr, "Out of Memory 7");
|
png_error(png_ptr, "Out of Memory 7");
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free a pointer allocated by png_malloc(). In the default
|
/* free a pointer allocated by png_malloc(). In the default
|
||||||
configuration, png_ptr is not used, but is passed incase it
|
configuration, png_ptr is not used, but is passed incase it
|
||||||
is needed. If ptr is NULL, return without taking any action. */
|
is needed. If ptr is NULL, return without taking any action. */
|
||||||
void
|
void
|
||||||
png_free(png_struct *png_ptr, void *ptr)
|
png_free(png_structp png_ptr, void * ptr)
|
||||||
{
|
{
|
||||||
if (!png_ptr)
|
if (!png_ptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ptr != (void *)0)
|
if (ptr != (void *)0)
|
||||||
free(ptr);
|
free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
1214
pngpread.c
Normal file
1214
pngpread.c
Normal file
File diff suppressed because it is too large
Load Diff
68
pngrcb.c
68
pngrcb.c
@ -1,16 +1,16 @@
|
|||||||
/* pngrcb.c - callbacks while reading a png file
|
/* pngrcb.c - callbacks while reading a png file
|
||||||
|
|
||||||
libpng 1.0 beta 2 - version 0.81
|
libpng 1.0 beta 2 - version 0.85
|
||||||
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
|
December 19, 1995
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PNG_INTERNAL
|
#define PNG_INTERNAL
|
||||||
#include "png.h"
|
#include "png.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
png_read_IHDR(png_struct *png_ptr, png_info *info,
|
png_read_IHDR(png_structp png_ptr, png_infop info,
|
||||||
png_uint_32 width, png_uint_32 height, int bit_depth,
|
png_uint_32 width, png_uint_32 height, int bit_depth,
|
||||||
int color_type, int compression_type, int filter_type,
|
int color_type, int compression_type, int filter_type,
|
||||||
int interlace_type)
|
int interlace_type)
|
||||||
@ -24,7 +24,7 @@ png_read_IHDR(png_struct *png_ptr, png_info *info,
|
|||||||
info->color_type = color_type;
|
info->color_type = color_type;
|
||||||
info->compression_type = compression_type;
|
info->compression_type = compression_type;
|
||||||
info->filter_type = filter_type;
|
info->filter_type = filter_type;
|
||||||
info->interlace_type = interlace_type;
|
info->interlace_type = interlace_type;
|
||||||
if (info->color_type == PNG_COLOR_TYPE_PALETTE)
|
if (info->color_type == PNG_COLOR_TYPE_PALETTE)
|
||||||
info->channels = 1;
|
info->channels = 1;
|
||||||
else if (info->color_type & PNG_COLOR_MASK_COLOR)
|
else if (info->color_type & PNG_COLOR_MASK_COLOR)
|
||||||
@ -38,8 +38,8 @@ png_read_IHDR(png_struct *png_ptr, png_info *info,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
png_read_PLTE(png_struct *png_ptr, png_info *info,
|
png_read_PLTE(png_structp png_ptr, png_infop info,
|
||||||
png_color *palette, int num)
|
png_colorp palette, int num)
|
||||||
{
|
{
|
||||||
if (!png_ptr || !info)
|
if (!png_ptr || !info)
|
||||||
return;
|
return;
|
||||||
@ -51,7 +51,7 @@ png_read_PLTE(png_struct *png_ptr, png_info *info,
|
|||||||
|
|
||||||
#if defined(PNG_READ_gAMA_SUPPORTED)
|
#if defined(PNG_READ_gAMA_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_read_gAMA(png_struct *png_ptr, png_info *info, float gamma)
|
png_read_gAMA(png_structp png_ptr, png_infop info, double gamma)
|
||||||
{
|
{
|
||||||
if (!png_ptr || !info)
|
if (!png_ptr || !info)
|
||||||
return;
|
return;
|
||||||
@ -63,22 +63,22 @@ png_read_gAMA(png_struct *png_ptr, png_info *info, float gamma)
|
|||||||
|
|
||||||
#if defined(PNG_READ_sBIT_SUPPORTED)
|
#if defined(PNG_READ_sBIT_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_read_sBIT(png_struct *png_ptr, png_info *info,
|
png_read_sBIT(png_structp png_ptr, png_infop info,
|
||||||
png_color_8 *sig_bit)
|
png_color_8p sig_bit)
|
||||||
{
|
{
|
||||||
if (!png_ptr || !info)
|
if (!png_ptr || !info)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
memcpy(&(info->sig_bit), sig_bit, sizeof (png_color_8));
|
png_memcpy(&(info->sig_bit), sig_bit, sizeof (png_color_8));
|
||||||
info->valid |= PNG_INFO_sBIT;
|
info->valid |= PNG_INFO_sBIT;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_READ_cHRM_SUPPORTED)
|
#if defined(PNG_READ_cHRM_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_read_cHRM(png_struct *png_ptr, png_info *info,
|
png_read_cHRM(png_structp png_ptr, png_infop info,
|
||||||
float white_x, float white_y, float red_x, float red_y,
|
double white_x, double white_y, double red_x, double red_y,
|
||||||
float green_x, float green_y, float blue_x, float blue_y)
|
double green_x, double green_y, double blue_x, double blue_y)
|
||||||
{
|
{
|
||||||
if (!png_ptr || !info)
|
if (!png_ptr || !info)
|
||||||
return;
|
return;
|
||||||
@ -97,8 +97,8 @@ png_read_cHRM(png_struct *png_ptr, png_info *info,
|
|||||||
|
|
||||||
#if defined(PNG_READ_tRNS_SUPPORTED)
|
#if defined(PNG_READ_tRNS_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_read_tRNS(png_struct *png_ptr, png_info *info,
|
png_read_tRNS(png_structp png_ptr, png_infop info,
|
||||||
png_byte *trans, int num_trans, png_color_16 *trans_values)
|
png_bytep trans, int num_trans, png_color_16p trans_values)
|
||||||
{
|
{
|
||||||
if (!png_ptr || !info)
|
if (!png_ptr || !info)
|
||||||
return;
|
return;
|
||||||
@ -109,7 +109,7 @@ png_read_tRNS(png_struct *png_ptr, png_info *info,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy(&(info->trans_values), trans_values,
|
png_memcpy(&(info->trans_values), trans_values,
|
||||||
sizeof(png_color_16));
|
sizeof(png_color_16));
|
||||||
}
|
}
|
||||||
info->num_trans = num_trans;
|
info->num_trans = num_trans;
|
||||||
@ -119,20 +119,20 @@ png_read_tRNS(png_struct *png_ptr, png_info *info,
|
|||||||
|
|
||||||
#if defined(PNG_READ_bKGD_SUPPORTED)
|
#if defined(PNG_READ_bKGD_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_read_bKGD(png_struct *png_ptr, png_info *info,
|
png_read_bKGD(png_structp png_ptr, png_infop info,
|
||||||
png_color_16 *background)
|
png_color_16p background)
|
||||||
{
|
{
|
||||||
if (!png_ptr || !info)
|
if (!png_ptr || !info)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
memcpy(&(info->background), background, sizeof(png_color_16));
|
png_memcpy(&(info->background), background, sizeof(png_color_16));
|
||||||
info->valid |= PNG_INFO_bKGD;
|
info->valid |= PNG_INFO_bKGD;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_READ_hIST_SUPPORTED)
|
#if defined(PNG_READ_hIST_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_read_hIST(png_struct *png_ptr, png_info *info, png_uint_16 *hist)
|
png_read_hIST(png_structp png_ptr, png_infop info, png_uint_16p hist)
|
||||||
{
|
{
|
||||||
if (!png_ptr || !info)
|
if (!png_ptr || !info)
|
||||||
return;
|
return;
|
||||||
@ -144,7 +144,7 @@ png_read_hIST(png_struct *png_ptr, png_info *info, png_uint_16 *hist)
|
|||||||
|
|
||||||
#if defined(PNG_READ_pHYs_SUPPORTED)
|
#if defined(PNG_READ_pHYs_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_read_pHYs(png_struct *png_ptr, png_info *info,
|
png_read_pHYs(png_structp png_ptr, png_infop info,
|
||||||
png_uint_32 res_x, png_uint_32 res_y, int unit_type)
|
png_uint_32 res_x, png_uint_32 res_y, int unit_type)
|
||||||
{
|
{
|
||||||
if (!png_ptr || !info)
|
if (!png_ptr || !info)
|
||||||
@ -159,7 +159,7 @@ png_read_pHYs(png_struct *png_ptr, png_info *info,
|
|||||||
|
|
||||||
#if defined(PNG_READ_oFFs_SUPPORTED)
|
#if defined(PNG_READ_oFFs_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_read_oFFs(png_struct *png_ptr, png_info *info,
|
png_read_oFFs(png_structp png_ptr, png_infop info,
|
||||||
png_uint_32 offset_x, png_uint_32 offset_y, int unit_type)
|
png_uint_32 offset_x, png_uint_32 offset_y, int unit_type)
|
||||||
{
|
{
|
||||||
if (!png_ptr || !info)
|
if (!png_ptr || !info)
|
||||||
@ -174,26 +174,26 @@ png_read_oFFs(png_struct *png_ptr, png_info *info,
|
|||||||
|
|
||||||
#if defined(PNG_READ_tIME_SUPPORTED)
|
#if defined(PNG_READ_tIME_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_read_tIME(png_struct *png_ptr, png_info *info,
|
png_read_tIME(png_structp png_ptr, png_infop info,
|
||||||
png_time *mod_time)
|
png_timep mod_time)
|
||||||
{
|
{
|
||||||
if (!png_ptr || !info)
|
if (!png_ptr || !info)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
memcpy(&(info->mod_time), mod_time, sizeof (png_time));
|
png_memcpy(&(info->mod_time), mod_time, sizeof (png_time));
|
||||||
info->valid |= PNG_INFO_tIME;
|
info->valid |= PNG_INFO_tIME;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_READ_zTXt_SUPPORTED)
|
#if defined(PNG_READ_zTXt_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_read_zTXt(png_struct *png_ptr, png_info *info,
|
png_read_zTXt(png_structp png_ptr, png_infop info,
|
||||||
charf *key, charf *text, png_uint_32 text_len, int compression)
|
png_charp key, png_charp text, png_uint_32 text_len, int compression)
|
||||||
{
|
{
|
||||||
if (!png_ptr || !info)
|
if (!png_ptr || !info)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (info->max_text <= info->num_text)
|
if (info->max_text <= info->num_text)
|
||||||
{
|
{
|
||||||
if (info->text)
|
if (info->text)
|
||||||
{
|
{
|
||||||
@ -201,15 +201,15 @@ png_read_zTXt(png_struct *png_ptr, png_info *info,
|
|||||||
|
|
||||||
old_max = info->max_text;
|
old_max = info->max_text;
|
||||||
info->max_text = info->num_text + 16;
|
info->max_text = info->num_text + 16;
|
||||||
info->text = (png_text *)png_realloc(png_ptr,
|
info->text = (png_textp)png_realloc(png_ptr,
|
||||||
info->text,
|
info->text,
|
||||||
info->max_text * sizeof (png_text),
|
info->max_text * sizeof (png_text),
|
||||||
old_max * sizeof (png_text));
|
old_max * sizeof (png_text));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
info->max_text = info->num_text + 16;
|
info->max_text = info->num_text + 16;
|
||||||
info->text = (png_text *)png_malloc(png_ptr,
|
info->text = (png_textp)png_malloc(png_ptr,
|
||||||
info->max_text * sizeof (png_text));
|
info->max_text * sizeof (png_text));
|
||||||
info->num_text = 0;
|
info->num_text = 0;
|
||||||
}
|
}
|
||||||
@ -225,13 +225,13 @@ png_read_zTXt(png_struct *png_ptr, png_info *info,
|
|||||||
|
|
||||||
#if defined(PNG_READ_tEXt_SUPPORTED)
|
#if defined(PNG_READ_tEXt_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_read_tEXt(png_struct *png_ptr, png_info *info,
|
png_read_tEXt(png_structp png_ptr, png_infop info,
|
||||||
charf *key, charf *text, png_uint_32 text_len)
|
png_charp key, png_charp text, png_uint_32 text_len)
|
||||||
{
|
{
|
||||||
if (!png_ptr || !info)
|
if (!png_ptr || !info)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
png_read_zTXt(png_ptr, info, key, text, text_len, -1);
|
png_read_zTXt(png_ptr, info, key, text, text_len, -1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
346
pngread.c
346
pngread.c
@ -1,10 +1,10 @@
|
|||||||
|
|
||||||
/* pngread.c - read a png file
|
/* pngread.c - read a png file
|
||||||
|
|
||||||
libpng 1.0 beta 2 - version 0.81
|
libpng 1.0 beta 2 - version 0.85
|
||||||
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
|
December 19, 1995
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PNG_INTERNAL
|
#define PNG_INTERNAL
|
||||||
@ -12,56 +12,67 @@
|
|||||||
|
|
||||||
/* initialize png structure for reading, and allocate any memory needed */
|
/* initialize png structure for reading, and allocate any memory needed */
|
||||||
void
|
void
|
||||||
png_read_init(png_struct *png_ptr)
|
png_read_init(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
jmp_buf tmp_jmp;
|
jmp_buf tmp_jmp;
|
||||||
|
png_msg_ptr error_fn;
|
||||||
|
png_msg_ptr warning_fn;
|
||||||
|
png_voidp msg_ptr;
|
||||||
|
|
||||||
png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
|
png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
|
||||||
png_memset(png_ptr, 0, sizeof (png_struct));
|
error_fn = png_ptr->error_fn;
|
||||||
png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
|
warning_fn = png_ptr->warning_fn;
|
||||||
|
msg_ptr = png_ptr->msg_ptr;
|
||||||
|
|
||||||
|
png_memset(png_ptr, 0, sizeof (png_struct));
|
||||||
|
|
||||||
|
png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
|
||||||
|
png_ptr->error_fn = error_fn;
|
||||||
|
png_ptr->warning_fn = warning_fn;
|
||||||
|
png_ptr->msg_ptr = msg_ptr;
|
||||||
|
|
||||||
png_ptr->zbuf_size = PNG_ZBUF_SIZE;
|
png_ptr->zbuf_size = PNG_ZBUF_SIZE;
|
||||||
png_ptr->zbuf = png_large_malloc(png_ptr, png_ptr->zbuf_size);
|
png_ptr->zbuf = png_large_malloc(png_ptr, png_ptr->zbuf_size);
|
||||||
png_ptr->zstream = &(png_ptr->zstream_struct);
|
png_ptr->zstream = (z_stream *)png_malloc(png_ptr, sizeof (z_stream));
|
||||||
png_ptr->zstream->zalloc = png_zalloc;
|
png_ptr->zstream->zalloc = png_zalloc;
|
||||||
png_ptr->zstream->zfree = png_zfree;
|
png_ptr->zstream->zfree = png_zfree;
|
||||||
png_ptr->zstream->opaque = (voidp)png_ptr;
|
png_ptr->zstream->opaque = (voidp)png_ptr;
|
||||||
inflateInit(png_ptr->zstream);
|
inflateInit(png_ptr->zstream);
|
||||||
png_ptr->zstream->next_out = png_ptr->zbuf;
|
png_ptr->zstream->next_out = png_ptr->zbuf;
|
||||||
png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
|
png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read the information before the actual image data. */
|
/* read the information before the actual image data. */
|
||||||
void
|
void
|
||||||
png_read_info(png_struct *png_ptr, png_info *info)
|
png_read_info(png_structp png_ptr, png_infop info)
|
||||||
{
|
{
|
||||||
png_byte chunk_start[8];
|
png_byte chunk_start[8];
|
||||||
png_uint_32 length;
|
png_uint_32 length;
|
||||||
|
|
||||||
(*(png_ptr->read_data_fn))(png_ptr, chunk_start, 8);
|
png_read_data(png_ptr, chunk_start, 8);
|
||||||
if (memcmp(chunk_start, png_sig, 8))
|
if (png_memcmp(chunk_start, png_sig, 8))
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Not a PNG File");
|
png_error(png_ptr, "Not a Png File");
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
png_uint_32 crc;
|
png_uint_32 crc;
|
||||||
|
|
||||||
(*(png_ptr->read_data_fn))(png_ptr, chunk_start, 8);
|
png_read_data(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 (!png_memcmp(chunk_start + 4, png_IHDR, 4))
|
||||||
{
|
{
|
||||||
if (png_ptr->mode != PNG_BEFORE_IHDR)
|
if (png_ptr->mode != PNG_BEFORE_IHDR)
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Out of Place IHDR");
|
png_error(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;
|
||||||
}
|
}
|
||||||
else if (!memcmp(chunk_start + 4, png_PLTE, 4))
|
else if (!png_memcmp(chunk_start + 4, png_PLTE, 4))
|
||||||
{
|
{
|
||||||
if (png_ptr->mode != PNG_HAVE_IHDR)
|
if (png_ptr->mode != PNG_HAVE_IHDR)
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Missing IHDR");
|
png_error(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)
|
||||||
@ -70,122 +81,122 @@ png_read_info(png_struct *png_ptr, png_info *info)
|
|||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
png_handle_PLTE(png_ptr, info, length);
|
png_handle_PLTE(png_ptr, info, length);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
png_ptr->mode = PNG_HAVE_PLTE;
|
png_ptr->mode = PNG_HAVE_PLTE;
|
||||||
}
|
}
|
||||||
else if (!memcmp(chunk_start + 4, png_IDAT, 4))
|
else if (!png_memcmp(chunk_start + 4, png_IDAT, 4))
|
||||||
{
|
{
|
||||||
png_ptr->idat_size = length;
|
png_ptr->idat_size = length;
|
||||||
png_ptr->mode = PNG_HAVE_IDAT;
|
png_ptr->mode = PNG_HAVE_IDAT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (!memcmp(chunk_start + 4, png_IEND, 4))
|
else if (!png_memcmp(chunk_start + 4, png_IEND, 4))
|
||||||
{
|
{
|
||||||
(*(png_ptr->error_fn))(png_ptr, "No Image in File");
|
png_error(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 (!png_memcmp(chunk_start + 4, png_gAMA, 4))
|
||||||
{
|
{
|
||||||
if (png_ptr->mode != PNG_HAVE_IHDR)
|
if (png_ptr->mode != PNG_HAVE_IHDR)
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Out of Place PLTE");
|
png_error(png_ptr, "Out of Place PLTE");
|
||||||
|
|
||||||
png_handle_gAMA(png_ptr, info, length);
|
png_handle_gAMA(png_ptr, info, length);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_sBIT_SUPPORTED)
|
#if defined(PNG_READ_sBIT_SUPPORTED)
|
||||||
else if (!memcmp(chunk_start + 4, png_sBIT, 4))
|
else if (!png_memcmp(chunk_start + 4, png_sBIT, 4))
|
||||||
{
|
{
|
||||||
if (png_ptr->mode != PNG_HAVE_IHDR)
|
if (png_ptr->mode != PNG_HAVE_IHDR)
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Out of Place sBIT");
|
png_error(png_ptr, "Out of Place sBIT");
|
||||||
|
|
||||||
png_handle_sBIT(png_ptr, info, length);
|
png_handle_sBIT(png_ptr, info, length);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_cHRM_SUPPORTED)
|
#if defined(PNG_READ_cHRM_SUPPORTED)
|
||||||
else if (!memcmp(chunk_start + 4, png_cHRM, 4))
|
else if (!png_memcmp(chunk_start + 4, png_cHRM, 4))
|
||||||
{
|
{
|
||||||
if (png_ptr->mode != PNG_HAVE_IHDR)
|
if (png_ptr->mode != PNG_HAVE_IHDR)
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Out of Place cHRM");
|
png_error(png_ptr, "Out of Place cHRM");
|
||||||
|
|
||||||
png_handle_cHRM(png_ptr, info, length);
|
png_handle_cHRM(png_ptr, info, length);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_tRNS_SUPPORTED)
|
#if defined(PNG_READ_tRNS_SUPPORTED)
|
||||||
else if (!memcmp(chunk_start + 4, png_tRNS, 4))
|
else if (!png_memcmp(chunk_start + 4, png_tRNS, 4))
|
||||||
{
|
{
|
||||||
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_ptr->error_fn))(png_ptr, "Out of Place tRNS");
|
png_error(png_ptr, "Out of Place tRNS");
|
||||||
|
|
||||||
png_handle_tRNS(png_ptr, info, length);
|
png_handle_tRNS(png_ptr, info, length);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_bKGD_SUPPORTED)
|
#if defined(PNG_READ_bKGD_SUPPORTED)
|
||||||
else if (!memcmp(chunk_start + 4, png_bKGD, 4))
|
else if (!png_memcmp(chunk_start + 4, png_bKGD, 4))
|
||||||
{
|
{
|
||||||
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_ptr->error_fn))(png_ptr, "Out of Place bKGD");
|
png_error(png_ptr, "Out of Place bKGD");
|
||||||
|
|
||||||
png_handle_bKGD(png_ptr, info, length);
|
png_handle_bKGD(png_ptr, info, length);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_hIST_SUPPORTED)
|
#if defined(PNG_READ_hIST_SUPPORTED)
|
||||||
else if (!memcmp(chunk_start + 4, png_hIST, 4))
|
else if (!png_memcmp(chunk_start + 4, png_hIST, 4))
|
||||||
{
|
{
|
||||||
if (png_ptr->mode != PNG_HAVE_PLTE)
|
if (png_ptr->mode != PNG_HAVE_PLTE)
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Out of Place hIST");
|
png_error(png_ptr, "Out of Place hIST");
|
||||||
|
|
||||||
png_handle_hIST(png_ptr, info, length);
|
png_handle_hIST(png_ptr, info, length);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_pHYs_SUPPORTED)
|
#if defined(PNG_READ_pHYs_SUPPORTED)
|
||||||
else if (!memcmp(chunk_start + 4, png_pHYs, 4))
|
else if (!png_memcmp(chunk_start + 4, png_pHYs, 4))
|
||||||
{
|
{
|
||||||
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_ptr->error_fn))(png_ptr, "Out of Place pHYs");
|
png_error(png_ptr, "Out of Place pHYs");
|
||||||
|
|
||||||
png_handle_pHYs(png_ptr, info, length);
|
png_handle_pHYs(png_ptr, info, length);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_oFFs_SUPPORTED)
|
#if defined(PNG_READ_oFFs_SUPPORTED)
|
||||||
else if (!memcmp(chunk_start + 4, png_oFFs, 4))
|
else if (!png_memcmp(chunk_start + 4, png_oFFs, 4))
|
||||||
{
|
{
|
||||||
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_ptr->error_fn))(png_ptr, "Out of Place oFFs");
|
png_error(png_ptr, "Out of Place oFFs");
|
||||||
|
|
||||||
png_handle_oFFs(png_ptr, info, length);
|
png_handle_oFFs(png_ptr, info, length);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_tIME_SUPPORTED)
|
#if defined(PNG_READ_tIME_SUPPORTED)
|
||||||
else if (!memcmp(chunk_start + 4, png_tIME, 4))
|
else if (!png_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_ptr->error_fn))(png_ptr, "Out of Place tIME");
|
png_error(png_ptr, "Out of Place tIME");
|
||||||
|
|
||||||
png_handle_tIME(png_ptr, info, length);
|
png_handle_tIME(png_ptr, info, length);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_tEXt_SUPPORTED)
|
#if defined(PNG_READ_tEXt_SUPPORTED)
|
||||||
else if (!memcmp(chunk_start + 4, png_tEXt, 4))
|
else if (!png_memcmp(chunk_start + 4, png_tEXt, 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_ptr->error_fn))(png_ptr, "Out of Place tEXt");
|
png_error(png_ptr, "Out of Place tEXt");
|
||||||
|
|
||||||
png_handle_tEXt(png_ptr, info, length);
|
png_handle_tEXt(png_ptr, info, length);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_zTXt_SUPPORTED)
|
#if defined(PNG_READ_zTXt_SUPPORTED)
|
||||||
else if (!memcmp(chunk_start + 4, png_zTXt, 4))
|
else if (!png_memcmp(chunk_start + 4, png_zTXt, 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_ptr->error_fn))(png_ptr, "Out of Place zTXt");
|
png_error(png_ptr, "Out of Place zTXt");
|
||||||
|
|
||||||
png_handle_zTXt(png_ptr, info, length);
|
png_handle_zTXt(png_ptr, info, length);
|
||||||
}
|
}
|
||||||
@ -193,21 +204,21 @@ 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_ptr->error_fn))(png_ptr, "Unknown Critical Chunk");
|
png_error(png_ptr, "Unknown Critical Chunk");
|
||||||
|
|
||||||
png_crc_skip(png_ptr, length);
|
png_crc_skip(png_ptr, length);
|
||||||
}
|
}
|
||||||
(*(png_ptr->read_data_fn))(png_ptr, chunk_start, 4);
|
png_read_data(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_ptr->error_fn))(png_ptr, "Bad CRC value");
|
png_error(png_ptr, "Bad CRC value");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* optional call to update the users info structure */
|
/* optional call to update the users info structure */
|
||||||
void
|
void
|
||||||
png_read_update_info(png_struct *png_ptr, png_info *info_ptr)
|
png_read_update_info(png_structp png_ptr, png_infop info_ptr)
|
||||||
{
|
{
|
||||||
if (!(png_ptr->row_init))
|
if (!(png_ptr->row_init))
|
||||||
png_read_start_row(png_ptr);
|
png_read_start_row(png_ptr);
|
||||||
@ -219,14 +230,14 @@ png_read_update_info(png_struct *png_ptr, png_info *info_ptr)
|
|||||||
the user to obtail a gamma corrected palette, for example.
|
the user to obtail a gamma corrected palette, for example.
|
||||||
If the user doesn't call this, we will do it ourselves. */
|
If the user doesn't call this, we will do it ourselves. */
|
||||||
void
|
void
|
||||||
png_start_read_image(png_struct *png_ptr)
|
png_start_read_image(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
if (!(png_ptr->row_init))
|
if (!(png_ptr->row_init))
|
||||||
png_read_start_row(png_ptr);
|
png_read_start_row(png_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
png_read_row(png_struct *png_ptr, png_bytef *row, png_byte *dsp_row)
|
png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
if (!(png_ptr->row_init))
|
if (!(png_ptr->row_init))
|
||||||
@ -244,7 +255,7 @@ png_read_row(png_struct *png_ptr, png_bytef *row, png_byte *dsp_row)
|
|||||||
if (dsp_row)
|
if (dsp_row)
|
||||||
png_combine_row(png_ptr, dsp_row,
|
png_combine_row(png_ptr, dsp_row,
|
||||||
png_pass_dsp_mask[png_ptr->pass]);
|
png_pass_dsp_mask[png_ptr->pass]);
|
||||||
png_read_finish_row(png_ptr);
|
png_read_finish_row(png_ptr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -262,7 +273,7 @@ png_read_row(png_struct *png_ptr, png_bytef *row, png_byte *dsp_row)
|
|||||||
if ((png_ptr->row_number & 7) != 4)
|
if ((png_ptr->row_number & 7) != 4)
|
||||||
{
|
{
|
||||||
if (dsp_row && (png_ptr->row_number & 4))
|
if (dsp_row && (png_ptr->row_number & 4))
|
||||||
png_combine_row(png_ptr, dsp_row,
|
png_combine_row(png_ptr, dsp_row,
|
||||||
png_pass_dsp_mask[png_ptr->pass]);
|
png_pass_dsp_mask[png_ptr->pass]);
|
||||||
png_read_finish_row(png_ptr);
|
png_read_finish_row(png_ptr);
|
||||||
return;
|
return;
|
||||||
@ -280,7 +291,7 @@ png_read_row(png_struct *png_ptr, png_bytef *row, png_byte *dsp_row)
|
|||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
if ((png_ptr->row_number & 3) != 2)
|
if ((png_ptr->row_number & 3) != 2)
|
||||||
{
|
{
|
||||||
if (dsp_row && (png_ptr->row_number & 2))
|
if (dsp_row && (png_ptr->row_number & 2))
|
||||||
png_combine_row(png_ptr, dsp_row,
|
png_combine_row(png_ptr, dsp_row,
|
||||||
png_pass_dsp_mask[png_ptr->pass]);
|
png_pass_dsp_mask[png_ptr->pass]);
|
||||||
@ -298,7 +309,7 @@ png_read_row(png_struct *png_ptr, png_bytef *row, png_byte *dsp_row)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
if (!(png_ptr->row_number & 1))
|
if (!(png_ptr->row_number & 1))
|
||||||
{
|
{
|
||||||
png_read_finish_row(png_ptr);
|
png_read_finish_row(png_ptr);
|
||||||
@ -310,32 +321,32 @@ 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_ptr->error_fn))(png_ptr, "Invalid attempt to read row data");
|
png_error(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;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (!(png_ptr->zstream->avail_in))
|
if (!(png_ptr->zstream->avail_in))
|
||||||
{
|
{
|
||||||
while (!png_ptr->idat_size)
|
while (!png_ptr->idat_size)
|
||||||
{
|
{
|
||||||
png_byte buf[4];
|
png_byte buf[4];
|
||||||
png_uint_32 crc;
|
png_uint_32 crc;
|
||||||
|
|
||||||
(*(png_ptr->read_data_fn))(png_ptr, buf, 4);
|
png_read_data(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_ptr->error_fn))(png_ptr, "Bad CRC value");
|
png_error(png_ptr, "Bad CRC value");
|
||||||
|
|
||||||
(*(png_ptr->read_data_fn))(png_ptr, buf, 4);
|
png_read_data(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 (png_memcmp(buf, png_IDAT, 4))
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Not enough image data");
|
png_error(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;
|
||||||
@ -345,17 +356,17 @@ png_read_row(png_struct *png_ptr, png_bytef *row, png_byte *dsp_row)
|
|||||||
png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream->avail_in);
|
png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream->avail_in);
|
||||||
png_ptr->idat_size -= png_ptr->zstream->avail_in;
|
png_ptr->idat_size -= png_ptr->zstream->avail_in;
|
||||||
}
|
}
|
||||||
ret = inflate(png_ptr->zstream, Z_PARTIAL_FLUSH);
|
ret = inflate(png_ptr->zstream, Z_PARTIAL_FLUSH);
|
||||||
if (ret == Z_STREAM_END)
|
if (ret == Z_STREAM_END)
|
||||||
{
|
{
|
||||||
if (png_ptr->zstream->avail_out || png_ptr->zstream->avail_in ||
|
if (png_ptr->zstream->avail_out || png_ptr->zstream->avail_in ||
|
||||||
png_ptr->idat_size)
|
png_ptr->idat_size)
|
||||||
(*(png_ptr->warning_fn))(png_ptr, "Extra compressed data");
|
png_error(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_ptr->error_fn))(png_ptr, "Compression Error");
|
png_error(png_ptr, "Compression Error");
|
||||||
|
|
||||||
} while (png_ptr->zstream->avail_out);
|
} while (png_ptr->zstream->avail_out);
|
||||||
|
|
||||||
@ -370,7 +381,7 @@ png_read_row(png_struct *png_ptr, png_bytef *row, png_byte *dsp_row)
|
|||||||
png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
|
png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
|
||||||
(png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
|
(png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
|
||||||
|
|
||||||
if (png_ptr->row_buf[0])
|
if (png_ptr->row_buf[0])
|
||||||
png_read_filter_row(&(png_ptr->row_info),
|
png_read_filter_row(&(png_ptr->row_info),
|
||||||
png_ptr->row_buf + 1, png_ptr->prev_row + 1,
|
png_ptr->row_buf + 1, png_ptr->prev_row + 1,
|
||||||
(int)(png_ptr->row_buf[0]));
|
(int)(png_ptr->row_buf[0]));
|
||||||
@ -410,7 +421,7 @@ png_read_row(png_struct *png_ptr, png_bytef *row, png_byte *dsp_row)
|
|||||||
/* read a one or more rows of image data. If the image is interlaced,
|
/* read a one or more rows of image data. If the image is interlaced,
|
||||||
and png_set_interlace_handling() has been called, the rows need to
|
and png_set_interlace_handling() has been called, the rows need to
|
||||||
to contain the contents of the rows from the previous pass. If
|
to contain the contents of the rows from the previous pass. If
|
||||||
the image has alpha or transparency, and png_handle_alpha() has been
|
the image has alpha or transparency, and png_handle_alpha() has been
|
||||||
called, the rows contents must be initialized to the contents of the
|
called, the rows contents must be initialized to the contents of the
|
||||||
screen. row holds the actual image, and pixels are placed in it
|
screen. row holds the actual image, and pixels are placed in it
|
||||||
as they arrive. If the image is displayed after each pass, it will
|
as they arrive. If the image is displayed after each pass, it will
|
||||||
@ -424,21 +435,22 @@ png_read_row(png_struct *png_ptr, png_bytef *row, png_byte *dsp_row)
|
|||||||
rows. In this case, you do not have to provide a display_rows buffer
|
rows. In this case, you do not have to provide a display_rows buffer
|
||||||
also, but you may. If the image is not interlaced, or if you have
|
also, but you may. If the image is not interlaced, or if you have
|
||||||
not called png_set_interlace_handling(), the display_row buffer will
|
not called png_set_interlace_handling(), the display_row buffer will
|
||||||
be ignored, so pass NULL to it. */
|
be ignored, so pass NULL to it. */
|
||||||
|
|
||||||
void
|
void
|
||||||
png_read_rows(png_struct *png_ptr, png_bytef **row,
|
png_read_rows(png_structp png_ptr, png_bytepp row,
|
||||||
png_byte **display_row, png_uint_32 num_rows)
|
png_bytepp display_row, png_uint_32 num_rows)
|
||||||
{
|
{
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
png_bytef **rp;
|
png_bytepp rp;
|
||||||
png_byte **dp;
|
png_bytepp dp;
|
||||||
|
|
||||||
rp = row;
|
rp = row;
|
||||||
dp = display_row;
|
dp = display_row;
|
||||||
for (i = 0; i < num_rows; i++)
|
for (i = 0; i < num_rows; i++)
|
||||||
{
|
{
|
||||||
png_bytef *rptr;
|
png_bytep rptr;
|
||||||
png_byte *dptr;
|
png_bytep dptr;
|
||||||
|
|
||||||
if (rp)
|
if (rp)
|
||||||
rptr = *rp;
|
rptr = *rp;
|
||||||
@ -448,10 +460,9 @@ 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++;
|
||||||
if (display_row)
|
if (display_row)
|
||||||
dp++;
|
dp++;
|
||||||
}
|
}
|
||||||
@ -464,11 +475,11 @@ png_read_rows(png_struct *png_ptr, png_bytef **row,
|
|||||||
You only need to call this function once. If you desire to have
|
You only need to call this function once. If you desire to have
|
||||||
an image for each pass of a interlaced image, use png_read_rows() */
|
an image for each pass of a interlaced image, use png_read_rows() */
|
||||||
void
|
void
|
||||||
png_read_image(png_struct *png_ptr, png_bytef **image)
|
png_read_image(png_structp png_ptr, png_bytepp image)
|
||||||
{
|
{
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
int pass, j;
|
int pass, j;
|
||||||
png_bytef **rp;
|
png_bytepp rp;
|
||||||
|
|
||||||
pass = png_set_interlace_handling(png_ptr);
|
pass = png_set_interlace_handling(png_ptr);
|
||||||
for (j = 0; j < pass; j++)
|
for (j = 0; j < pass; j++)
|
||||||
@ -486,89 +497,89 @@ png_read_image(png_struct *png_ptr, png_bytef **image)
|
|||||||
file, will verify the end is accurate, and will read any comments
|
file, will verify the end is accurate, and will read any comments
|
||||||
or time information at the end of the file, if info is not NULL. */
|
or time information at the end of the file, if info is not NULL. */
|
||||||
void
|
void
|
||||||
png_read_end(png_struct *png_ptr, png_info *info)
|
png_read_end(png_structp png_ptr, png_infop info)
|
||||||
{
|
{
|
||||||
png_byte chunk_start[8];
|
png_byte chunk_start[8];
|
||||||
png_uint_32 length;
|
png_uint_32 length;
|
||||||
png_uint_32 crc;
|
png_uint_32 crc;
|
||||||
|
|
||||||
(*(png_ptr->read_data_fn))(png_ptr, chunk_start, 4);
|
png_read_data(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_ptr->error_fn))(png_ptr, "Bad CRC value");
|
png_error(png_ptr, "Bad CRC value");
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
(*(png_ptr->read_data_fn))(png_ptr, chunk_start, 8);
|
png_read_data(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 (!png_memcmp(chunk_start + 4, png_IHDR, 4))
|
||||||
{
|
{
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Invalid chunk after IDAT");
|
png_error(png_ptr, "invalid chunk after IDAT");
|
||||||
}
|
}
|
||||||
else if (!memcmp(chunk_start + 4, png_PLTE, 4))
|
else if (!png_memcmp(chunk_start + 4, png_PLTE, 4))
|
||||||
{
|
{
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Invalid chunk after IDAT");
|
png_error(png_ptr, "invalid chunk after IDAT");
|
||||||
}
|
}
|
||||||
else if (!memcmp(chunk_start + 4, png_gAMA, 4))
|
else if (!png_memcmp(chunk_start + 4, png_gAMA, 4))
|
||||||
{
|
{
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Invalid chunk after IDAT");
|
png_error(png_ptr, "invalid chunk after IDAT");
|
||||||
}
|
}
|
||||||
else if (!memcmp(chunk_start + 4, png_sBIT, 4))
|
else if (!png_memcmp(chunk_start + 4, png_sBIT, 4))
|
||||||
{
|
{
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Invalid chunk after IDAT");
|
png_error(png_ptr, "invalid chunk after IDAT");
|
||||||
}
|
}
|
||||||
else if (!memcmp(chunk_start + 4, png_cHRM, 4))
|
else if (!png_memcmp(chunk_start + 4, png_cHRM, 4))
|
||||||
|
{
|
||||||
|
png_error(png_ptr, "invalid chunk after IDAT");
|
||||||
|
}
|
||||||
|
else if (!png_memcmp(chunk_start + 4, png_tRNS, 4))
|
||||||
{
|
{
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Invalid chunk after IDAT");
|
png_error(png_ptr, "invalid chunk after IDAT");
|
||||||
}
|
}
|
||||||
else if (!memcmp(chunk_start + 4, png_tRNS, 4))
|
else if (!png_memcmp(chunk_start + 4, png_bKGD, 4))
|
||||||
{
|
{
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Invalid chunk after IDAT");
|
png_error(png_ptr, "invalid chunk after IDAT");
|
||||||
}
|
}
|
||||||
else if (!memcmp(chunk_start + 4, png_bKGD, 4))
|
else if (!png_memcmp(chunk_start + 4, png_hIST, 4))
|
||||||
{
|
{
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Invalid chunk after IDAT");
|
png_error(png_ptr, "invalid chunk after IDAT");
|
||||||
}
|
}
|
||||||
else if (!memcmp(chunk_start + 4, png_hIST, 4))
|
else if (!png_memcmp(chunk_start + 4, png_IDAT, 4))
|
||||||
{
|
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Invalid chunk after IDAT");
|
|
||||||
}
|
|
||||||
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_ptr->error_fn))(png_ptr, "Too many IDAT's found");
|
png_error(png_ptr, "too many IDAT's found");
|
||||||
}
|
}
|
||||||
else if (!memcmp(chunk_start + 4, png_pHYs, 4))
|
else if (!png_memcmp(chunk_start + 4, png_pHYs, 4))
|
||||||
{
|
{
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Invalid chunk after IDAT");
|
png_error(png_ptr, "invalid chunk after IDAT");
|
||||||
}
|
}
|
||||||
else if (!memcmp(chunk_start + 4, png_oFFs, 4))
|
else if (!png_memcmp(chunk_start + 4, png_oFFs, 4))
|
||||||
{
|
{
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Invalid chunk after IDAT");
|
png_error(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 (!png_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_ptr->error_fn))(png_ptr, "Out of Place tIME");
|
png_error(png_ptr, "Out of Place tIME");
|
||||||
|
|
||||||
if (info)
|
if (info)
|
||||||
png_handle_tIME(png_ptr, info, length);
|
png_handle_tIME(png_ptr, info, length);
|
||||||
else
|
else
|
||||||
png_crc_skip(png_ptr, length);
|
png_crc_skip(png_ptr, length);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_tEXt_SUPPORTED)
|
#if defined(PNG_READ_tEXt_SUPPORTED)
|
||||||
else if (!memcmp(chunk_start + 4, png_tEXt, 4))
|
else if (!png_memcmp(chunk_start + 4, png_tEXt, 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_ptr->error_fn))(png_ptr, "Out of Place tEXt");
|
png_error(png_ptr, "Out of Place tEXt");
|
||||||
|
|
||||||
if (info)
|
if (info)
|
||||||
png_handle_tEXt(png_ptr, info, length);
|
png_handle_tEXt(png_ptr, info, length);
|
||||||
@ -577,11 +588,11 @@ png_read_end(png_struct *png_ptr, png_info *info)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(PNG_READ_zTXt_SUPPORTED)
|
#if defined(PNG_READ_zTXt_SUPPORTED)
|
||||||
else if (!memcmp(chunk_start + 4, png_zTXt, 4))
|
else if (!png_memcmp(chunk_start + 4, png_zTXt, 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_ptr->error_fn))(png_ptr, "Out of Place zTXt");
|
png_error(png_ptr, "Out of Place zTXt");
|
||||||
|
|
||||||
if (info)
|
if (info)
|
||||||
png_handle_zTXt(png_ptr, info, length);
|
png_handle_zTXt(png_ptr, info, length);
|
||||||
@ -589,75 +600,63 @@ png_read_end(png_struct *png_ptr, png_info *info)
|
|||||||
png_crc_skip(png_ptr, length);
|
png_crc_skip(png_ptr, length);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (!memcmp(chunk_start + 4, png_IEND, 4))
|
else if (!png_memcmp(chunk_start + 4, png_IEND, 4))
|
||||||
{
|
{
|
||||||
png_ptr->mode = PNG_AFTER_IEND;
|
png_ptr->mode = PNG_AFTER_IEND;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char msg[80];
|
|
||||||
|
|
||||||
if ((chunk_start[4] & 0x20) == 0)
|
if ((chunk_start[4] & 0x20) == 0)
|
||||||
{
|
png_error(png_ptr, "Unknown Critical Chunk");
|
||||||
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_ptr->read_data_fn))(png_ptr, chunk_start, 4);
|
png_read_data(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_ptr->error_fn))(png_ptr, "Bad CRC value");
|
png_error(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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free all memory used by the read */
|
/* free all memory used by the read */
|
||||||
void
|
void
|
||||||
png_read_destroy(png_struct *png_ptr, png_info *info, png_info *end_info)
|
png_read_destroy(png_structp png_ptr, png_infop info, png_infop end_info)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
jmp_buf tmp_jmp;
|
jmp_buf tmp_jmp;
|
||||||
|
|
||||||
if (info)
|
if (info)
|
||||||
{
|
{
|
||||||
if (png_ptr->do_free & PNG_FREE_PALETTE)
|
if (png_ptr->do_free & PNG_FREE_PALETTE)
|
||||||
png_free(png_ptr, info->palette);
|
png_free(png_ptr, info->palette);
|
||||||
|
|
||||||
#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_bKGD_SUPPORTED)
|
#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_bKGD_SUPPORTED)
|
||||||
if (png_ptr->do_free & PNG_FREE_TRANS)
|
if (png_ptr->do_free & PNG_FREE_PALETTE)
|
||||||
png_free(png_ptr, info->trans);
|
png_free(png_ptr, info->trans);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_READ_hIST_SUPPORTED)
|
#if defined(PNG_READ_hIST_SUPPORTED)
|
||||||
if (png_ptr->do_free & PNG_FREE_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++)
|
||||||
{
|
{
|
||||||
png_large_free(png_ptr, info->text[i].key);
|
png_large_free(png_ptr, info->text[i].key);
|
||||||
}
|
}
|
||||||
|
|
||||||
png_free(png_ptr, info->text);
|
png_free(png_ptr, info->text);
|
||||||
#endif
|
#endif
|
||||||
png_memset(info, 0, sizeof(png_info));
|
png_memset(info, 0, sizeof(png_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (end_info)
|
if (end_info)
|
||||||
{
|
{
|
||||||
#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 < end_info->num_text; i++)
|
for (i = 0; i < end_info->num_text; i++)
|
||||||
{
|
{
|
||||||
png_large_free(png_ptr, end_info->text[i].key);
|
png_large_free(png_ptr, end_info->text[i].key);
|
||||||
}
|
}
|
||||||
|
|
||||||
png_free(png_ptr, end_info->text);
|
png_free(png_ptr, end_info->text);
|
||||||
@ -668,21 +667,17 @@ 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)
|
||||||
{
|
{
|
||||||
@ -690,15 +685,14 @@ png_read_destroy(png_struct *png_ptr, png_info *info, png_info *end_info)
|
|||||||
{
|
{
|
||||||
png_free(png_ptr, png_ptr->gamma_16_table[i]);
|
png_free(png_ptr, png_ptr->gamma_16_table[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#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)
|
||||||
{
|
{
|
||||||
for (i = 0; i < (1 << (8 - png_ptr->gamma_shift)); i++)
|
for (i = 0; i < (1 << (8 - png_ptr->gamma_shift)); i++)
|
||||||
{
|
{
|
||||||
png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
|
png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -709,25 +703,25 @@ png_read_destroy(png_struct *png_ptr, png_info *info, png_info *end_info)
|
|||||||
{
|
{
|
||||||
png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
|
png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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)
|
||||||
|
png_free(png_ptr, png_ptr->palette);
|
||||||
|
|
||||||
if (!png_ptr->user_palette)
|
inflateEnd(png_ptr->zstream);
|
||||||
png_free(png_ptr, png_ptr->palette);
|
png_free(png_ptr, png_ptr->zstream);
|
||||||
|
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
|
||||||
inflateEnd(png_ptr->zstream);
|
png_free(png_ptr, png_ptr->save_buffer);
|
||||||
|
#endif
|
||||||
png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
|
png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
|
||||||
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
379
pngrtran.c
379
pngrtran.c
@ -1,10 +1,10 @@
|
|||||||
|
|
||||||
/* pngrtran.c - transforms the data in a row for png readers
|
/* pngrtran.c - transforms the data in a row for png readers
|
||||||
|
|
||||||
libpng 1.0 beta 2 - version 0.8
|
libpng 1.0 beta 2 - version 0.85
|
||||||
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 20, 1995
|
December 19, 1995
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PNG_INTERNAL
|
#define PNG_INTERNAL
|
||||||
@ -13,8 +13,8 @@
|
|||||||
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
|
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
|
||||||
/* handle alpha and tRNS via a background color */
|
/* handle alpha and tRNS via a background color */
|
||||||
void
|
void
|
||||||
png_set_background(png_struct *png_ptr,
|
png_set_background(png_structp png_ptr,
|
||||||
png_color_16 *background_color, int background_gamma_code,
|
png_color_16p background_color, int background_gamma_code,
|
||||||
int need_expand, double background_gamma)
|
int need_expand, double background_gamma)
|
||||||
{
|
{
|
||||||
png_ptr->transformations |= PNG_BACKGROUND;
|
png_ptr->transformations |= PNG_BACKGROUND;
|
||||||
@ -29,7 +29,7 @@ png_set_background(png_struct *png_ptr,
|
|||||||
#if defined(PNG_READ_16_TO_8_SUPPORTED)
|
#if defined(PNG_READ_16_TO_8_SUPPORTED)
|
||||||
/* strip 16 bit depth files to 8 bit depth */
|
/* strip 16 bit depth files to 8 bit depth */
|
||||||
void
|
void
|
||||||
png_set_strip_16(png_struct *png_ptr)
|
png_set_strip_16(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
png_ptr->transformations |= PNG_16_TO_8;
|
png_ptr->transformations |= PNG_16_TO_8;
|
||||||
}
|
}
|
||||||
@ -42,16 +42,19 @@ png_set_strip_16(png_struct *png_ptr)
|
|||||||
is greater then the maximum number, the palette will be
|
is greater then the maximum number, the palette will be
|
||||||
modified to fit in the maximum number */
|
modified to fit in the maximum number */
|
||||||
|
|
||||||
typedef struct dsort_struct
|
|
||||||
|
typedef struct png_dsort_struct
|
||||||
{
|
{
|
||||||
struct dsort_struct *next;
|
struct png_dsort_struct FAR * next;
|
||||||
png_byte left;
|
png_byte left;
|
||||||
png_byte right;
|
png_byte right;
|
||||||
} dsort;
|
} png_dsort;
|
||||||
|
typedef png_dsort FAR * png_dsortp;
|
||||||
|
typedef png_dsort FAR * FAR * png_dsortpp;
|
||||||
|
|
||||||
void
|
void
|
||||||
png_set_dither(png_struct *png_ptr, png_color *palette,
|
png_set_dither(png_structp png_ptr, png_colorp palette,
|
||||||
int num_palette, int maximum_colors, png_uint_16 *histogram,
|
int num_palette, int maximum_colors, png_uint_16p histogram,
|
||||||
int full_dither)
|
int full_dither)
|
||||||
{
|
{
|
||||||
png_ptr->transformations |= PNG_DITHER;
|
png_ptr->transformations |= PNG_DITHER;
|
||||||
@ -60,7 +63,7 @@ png_set_dither(png_struct *png_ptr, png_color *palette,
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
png_ptr->dither_index = png_malloc(png_ptr,
|
png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
|
||||||
num_palette * sizeof (png_byte));
|
num_palette * sizeof (png_byte));
|
||||||
for (i = 0; i < num_palette; i++)
|
for (i = 0; i < num_palette; i++)
|
||||||
png_ptr->dither_index[i] = i;
|
png_ptr->dither_index[i] = i;
|
||||||
@ -74,10 +77,10 @@ png_set_dither(png_struct *png_ptr, png_color *palette,
|
|||||||
perhaps not the best solution, but good enough */
|
perhaps not the best solution, but good enough */
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
png_byte *sort;
|
png_bytep sort;
|
||||||
|
|
||||||
/* initialize an array to sort colors */
|
/* initialize an array to sort colors */
|
||||||
sort = (png_byte *)png_malloc(png_ptr, num_palette * sizeof (png_byte));
|
sort = (png_bytep)png_malloc(png_ptr, num_palette * sizeof (png_byte));
|
||||||
|
|
||||||
/* initialize the sort array */
|
/* initialize the sort array */
|
||||||
for (i = 0; i < num_palette; i++)
|
for (i = 0; i < num_palette; i++)
|
||||||
@ -200,16 +203,16 @@ png_set_dither(png_struct *png_ptr, png_color *palette,
|
|||||||
int i;
|
int i;
|
||||||
int max_d;
|
int max_d;
|
||||||
int num_new_palette;
|
int num_new_palette;
|
||||||
dsort **hash;
|
png_dsortpp hash;
|
||||||
png_byte *index_to_palette;
|
png_bytep index_to_palette;
|
||||||
/* where the original index currently is in the palette */
|
/* where the original index currently is in the palette */
|
||||||
png_byte *palette_to_index;
|
png_bytep palette_to_index;
|
||||||
/* which original index points to this palette color */
|
/* which original index points to this palette color */
|
||||||
|
|
||||||
/* initialize palette index arrays */
|
/* initialize palette index arrays */
|
||||||
index_to_palette = (png_byte *)png_malloc(png_ptr,
|
index_to_palette = (png_bytep)png_malloc(png_ptr,
|
||||||
num_palette * sizeof (png_byte));
|
num_palette * sizeof (png_byte));
|
||||||
palette_to_index = (png_byte *)png_malloc(png_ptr,
|
palette_to_index = (png_bytep)png_malloc(png_ptr,
|
||||||
num_palette * sizeof (png_byte));
|
num_palette * sizeof (png_byte));
|
||||||
|
|
||||||
/* initialize the sort array */
|
/* initialize the sort array */
|
||||||
@ -219,10 +222,10 @@ png_set_dither(png_struct *png_ptr, png_color *palette,
|
|||||||
palette_to_index[i] = i;
|
palette_to_index[i] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
hash = (dsort **)png_malloc(png_ptr, 769 * sizeof (dsort *));
|
hash = (png_dsortpp)png_malloc(png_ptr, 769 * sizeof (png_dsortp));
|
||||||
for (i = 0; i < 769; i++)
|
for (i = 0; i < 769; i++)
|
||||||
hash[i] = (dsort *)0;
|
hash[i] = (png_dsortp)0;
|
||||||
/* png_memset(hash, 0, 769 * sizeof (dsort *)); */
|
/* png_memset(hash, 0, 769 * sizeof (png_dsortp)); */
|
||||||
|
|
||||||
num_new_palette = num_palette;
|
num_new_palette = num_palette;
|
||||||
|
|
||||||
@ -246,13 +249,13 @@ png_set_dither(png_struct *png_ptr, png_color *palette,
|
|||||||
{
|
{
|
||||||
int d;
|
int d;
|
||||||
|
|
||||||
d = PNG_COLOR_DIST(palette[i], palette[j]);
|
d = PNG_COLOR_DIST(palette[i], palette[j]);
|
||||||
|
|
||||||
if (d <= max_d)
|
if (d <= max_d)
|
||||||
{
|
{
|
||||||
dsort *t;
|
png_dsortp t;
|
||||||
|
|
||||||
t = png_malloc(png_ptr, sizeof (dsort));
|
t = png_malloc(png_ptr, sizeof (png_dsort));
|
||||||
t->next = hash[d];
|
t->next = hash[d];
|
||||||
t->left = i;
|
t->left = i;
|
||||||
t->right = j;
|
t->right = j;
|
||||||
@ -265,7 +268,7 @@ png_set_dither(png_struct *png_ptr, png_color *palette,
|
|||||||
{
|
{
|
||||||
if (hash[i])
|
if (hash[i])
|
||||||
{
|
{
|
||||||
dsort *p;
|
png_dsortp p;
|
||||||
|
|
||||||
for (p = hash[i]; p; p = p->next)
|
for (p = hash[i]; p; p = p->next)
|
||||||
{
|
{
|
||||||
@ -325,12 +328,12 @@ png_set_dither(png_struct *png_ptr, png_color *palette,
|
|||||||
{
|
{
|
||||||
if (hash[i])
|
if (hash[i])
|
||||||
{
|
{
|
||||||
dsort *p;
|
png_dsortp p;
|
||||||
|
|
||||||
p = hash[i];
|
p = hash[i];
|
||||||
while (p)
|
while (p)
|
||||||
{
|
{
|
||||||
dsort *t;
|
png_dsortp t;
|
||||||
|
|
||||||
t = p->next;
|
t = p->next;
|
||||||
png_free(png_ptr, p);
|
png_free(png_ptr, p);
|
||||||
@ -348,7 +351,7 @@ png_set_dither(png_struct *png_ptr, png_color *palette,
|
|||||||
num_palette = maximum_colors;
|
num_palette = maximum_colors;
|
||||||
}
|
}
|
||||||
if (!(png_ptr->palette))
|
if (!(png_ptr->palette))
|
||||||
{
|
{
|
||||||
png_ptr->palette = palette;
|
png_ptr->palette = palette;
|
||||||
png_ptr->user_palette = 1;
|
png_ptr->user_palette = 1;
|
||||||
}
|
}
|
||||||
@ -359,22 +362,22 @@ png_set_dither(png_struct *png_ptr, png_color *palette,
|
|||||||
int i;
|
int i;
|
||||||
int total_bits, num_red, num_green, num_blue;
|
int total_bits, num_red, num_green, num_blue;
|
||||||
png_uint_32 num_entries;
|
png_uint_32 num_entries;
|
||||||
png_bytef *distance;
|
png_bytep distance;
|
||||||
|
|
||||||
total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
|
total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
|
||||||
PNG_DITHER_BLUE_BITS;
|
PNG_DITHER_BLUE_BITS;
|
||||||
|
|
||||||
num_red = (1 << PNG_DITHER_RED_BITS);
|
num_red = (1 << PNG_DITHER_RED_BITS);
|
||||||
num_green = (1 << PNG_DITHER_GREEN_BITS);
|
num_green = (1 << PNG_DITHER_GREEN_BITS);
|
||||||
num_blue = (1 << PNG_DITHER_BLUE_BITS);
|
num_blue = (1 << PNG_DITHER_BLUE_BITS);
|
||||||
num_entries = ((png_uint_32)1 << total_bits);
|
num_entries = ((png_uint_32)1 << total_bits);
|
||||||
|
|
||||||
png_ptr->palette_lookup = (png_bytef *)png_large_malloc(png_ptr,
|
png_ptr->palette_lookup = (png_bytep )png_large_malloc(png_ptr,
|
||||||
(png_size_t)num_entries * sizeof (png_byte));
|
(png_size_t)num_entries * sizeof (png_byte));
|
||||||
|
|
||||||
png_memset(png_ptr->palette_lookup, 0, (png_size_t)num_entries * sizeof (png_byte));
|
png_memset(png_ptr->palette_lookup, 0, (png_size_t)num_entries * sizeof (png_byte));
|
||||||
|
|
||||||
distance = (png_bytef *)png_large_malloc(png_ptr,
|
distance = (png_bytep )png_large_malloc(png_ptr,
|
||||||
(png_size_t)num_entries * sizeof (png_byte));
|
(png_size_t)num_entries * sizeof (png_byte));
|
||||||
|
|
||||||
png_memset(distance, 0xff, (png_size_t)num_entries * sizeof (png_byte));
|
png_memset(distance, 0xff, (png_size_t)num_entries * sizeof (png_byte));
|
||||||
@ -384,7 +387,7 @@ png_set_dither(png_struct *png_ptr, png_color *palette,
|
|||||||
int r, g, b, ir, ig, ib;
|
int r, g, b, ir, ig, ib;
|
||||||
|
|
||||||
r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
|
r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
|
||||||
g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
|
g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
|
||||||
b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
|
b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
|
||||||
|
|
||||||
for (ir = 0; ir < num_red; ir++)
|
for (ir = 0; ir < num_red; ir++)
|
||||||
@ -402,7 +405,7 @@ png_set_dither(png_struct *png_ptr, png_color *palette,
|
|||||||
dm = ((dr > dg) ? dr : dg);
|
dm = ((dr > dg) ? dr : dg);
|
||||||
index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
|
index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
|
||||||
for (ib = 0; ib < num_blue; ib++)
|
for (ib = 0; ib < num_blue; ib++)
|
||||||
{
|
{
|
||||||
int index, db, dmax, d;
|
int index, db, dmax, d;
|
||||||
|
|
||||||
index = index_g | ib;
|
index = index_g | ib;
|
||||||
@ -420,7 +423,7 @@ png_set_dither(png_struct *png_ptr, png_color *palette,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
png_large_free(png_ptr, distance);
|
png_large_free(png_ptr, distance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -428,7 +431,7 @@ png_set_dither(png_struct *png_ptr, png_color *palette,
|
|||||||
#if defined(PNG_READ_GAMMA_SUPPORTED)
|
#if defined(PNG_READ_GAMMA_SUPPORTED)
|
||||||
/* transform the image from the file_gamma to the screen_gamma */
|
/* transform the image from the file_gamma to the screen_gamma */
|
||||||
void
|
void
|
||||||
png_set_gamma(png_struct *png_ptr, double screen_gamma,
|
png_set_gamma(png_structp png_ptr, double screen_gamma,
|
||||||
double file_gamma)
|
double file_gamma)
|
||||||
{
|
{
|
||||||
png_ptr->transformations |= PNG_GAMMA;
|
png_ptr->transformations |= PNG_GAMMA;
|
||||||
@ -442,7 +445,7 @@ png_set_gamma(png_struct *png_ptr, double screen_gamma,
|
|||||||
less then 8 bit depth to 8 bit depth, and expand tRNS chunks
|
less then 8 bit depth to 8 bit depth, and expand tRNS chunks
|
||||||
to alpha channels */
|
to alpha channels */
|
||||||
void
|
void
|
||||||
png_set_expand(png_struct *png_ptr)
|
png_set_expand(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
png_ptr->transformations |= PNG_EXPAND;
|
png_ptr->transformations |= PNG_EXPAND;
|
||||||
}
|
}
|
||||||
@ -450,7 +453,7 @@ png_set_expand(png_struct *png_ptr)
|
|||||||
|
|
||||||
#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
|
#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_set_gray_to_rgb(png_struct *png_ptr)
|
png_set_gray_to_rgb(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
png_ptr->transformations |= PNG_GRAY_TO_RGB;
|
png_ptr->transformations |= PNG_GRAY_TO_RGB;
|
||||||
}
|
}
|
||||||
@ -459,7 +462,7 @@ png_set_gray_to_rgb(png_struct *png_ptr)
|
|||||||
/* initialize everything needed for the read. This includes modifying
|
/* initialize everything needed for the read. This includes modifying
|
||||||
the palette */
|
the palette */
|
||||||
void
|
void
|
||||||
png_init_read_transformations(png_struct *png_ptr)
|
png_init_read_transformations(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
int color_type;
|
int color_type;
|
||||||
|
|
||||||
@ -474,7 +477,7 @@ png_init_read_transformations(png_struct *png_ptr)
|
|||||||
(png_ptr->transformations & PNG_BACKGROUND) &&
|
(png_ptr->transformations & PNG_BACKGROUND) &&
|
||||||
png_ptr->background_expand)
|
png_ptr->background_expand)
|
||||||
/* (!(png_ptr->transformations & PNG_BACKGROUND) ||
|
/* (!(png_ptr->transformations & PNG_BACKGROUND) ||
|
||||||
png_ptr->background_expand)) */
|
png_ptr->background_expand)) */
|
||||||
{
|
{
|
||||||
/* expand background chunk. While this may not be
|
/* expand background chunk. While this may not be
|
||||||
the fastest way to do this, it only happens once
|
the fastest way to do this, it only happens once
|
||||||
@ -492,7 +495,7 @@ png_init_read_transformations(png_struct *png_ptr)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (color_type == PNG_COLOR_TYPE_PALETTE &&
|
if (color_type == PNG_COLOR_TYPE_PALETTE &&
|
||||||
(png_ptr->transformations & PNG_BACKGROUND) &&
|
(png_ptr->transformations & PNG_BACKGROUND) &&
|
||||||
png_ptr->background_expand)
|
png_ptr->background_expand)
|
||||||
{
|
{
|
||||||
@ -523,12 +526,12 @@ png_init_read_transformations(png_struct *png_ptr)
|
|||||||
{
|
{
|
||||||
double g, gs, m;
|
double g, gs, m;
|
||||||
|
|
||||||
m = (double)((png_uint_32)1 << png_ptr->bit_depth);
|
m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
|
||||||
g = 1.0;
|
g = 1.0;
|
||||||
gs = 1.0;
|
gs = 1.0;
|
||||||
|
|
||||||
switch (png_ptr->background_gamma_type)
|
switch (png_ptr->background_gamma_type)
|
||||||
{
|
{
|
||||||
case PNG_BACKGROUND_GAMMA_SCREEN:
|
case PNG_BACKGROUND_GAMMA_SCREEN:
|
||||||
g = (png_ptr->display_gamma);
|
g = (png_ptr->display_gamma);
|
||||||
gs = 1.0;
|
gs = 1.0;
|
||||||
@ -544,9 +547,9 @@ png_init_read_transformations(png_struct *png_ptr)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
|
if (color_type & PNG_COLOR_MASK_COLOR)
|
||||||
{
|
{
|
||||||
png_ptr->background_1.red = (png_uint_16)(pow(
|
png_ptr->background_1.red = (png_uint_16)(pow(
|
||||||
(double)png_ptr->background.red / m, g) * m + .5);
|
(double)png_ptr->background.red / m, g) * m + .5);
|
||||||
png_ptr->background_1.green = (png_uint_16)(pow(
|
png_ptr->background_1.green = (png_uint_16)(pow(
|
||||||
(double)png_ptr->background.green / m, g) * m + .5);
|
(double)png_ptr->background.green / m, g) * m + .5);
|
||||||
@ -562,9 +565,9 @@ png_init_read_transformations(png_struct *png_ptr)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
png_ptr->background_1.gray = (png_uint_16)(pow(
|
png_ptr->background_1.gray = (png_uint_16)(pow(
|
||||||
(double)png_ptr->background.gray / m, g) * m + .5);
|
(double)png_ptr->background.gray / m, g) * m + .5);
|
||||||
png_ptr->background.gray = (png_uint_16)(pow(
|
png_ptr->background.gray = (png_uint_16)(pow(
|
||||||
(double)png_ptr->background.gray / m, gs) * m + .5);
|
(double)png_ptr->background.gray / m, gs) * m + .5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -572,9 +575,9 @@ png_init_read_transformations(png_struct *png_ptr)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_READ_SHIFT_SUPPORTED) && defined(PNG_READ_sBIT_SUPPORTED)
|
#if defined(PNG_READ_SHIFT_SUPPORTED)
|
||||||
if ((png_ptr->transformations & PNG_SHIFT) &&
|
if ((png_ptr->transformations & PNG_SHIFT) &&
|
||||||
png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
|
color_type == PNG_COLOR_TYPE_PALETTE)
|
||||||
{
|
{
|
||||||
png_uint_16 i;
|
png_uint_16 i;
|
||||||
int sr, sg, sb;
|
int sr, sg, sb;
|
||||||
@ -582,7 +585,7 @@ png_init_read_transformations(png_struct *png_ptr)
|
|||||||
sr = 8 - png_ptr->sig_bit.red;
|
sr = 8 - png_ptr->sig_bit.red;
|
||||||
if (sr < 0 || sr > 8)
|
if (sr < 0 || sr > 8)
|
||||||
sr = 0;
|
sr = 0;
|
||||||
sg = 8 - png_ptr->sig_bit.green;
|
sg = 8 - png_ptr->sig_bit.green;
|
||||||
if (sg < 0 || sg > 8)
|
if (sg < 0 || sg > 8)
|
||||||
sg = 0;
|
sg = 0;
|
||||||
sb = 8 - png_ptr->sig_bit.blue;
|
sb = 8 - png_ptr->sig_bit.blue;
|
||||||
@ -600,9 +603,9 @@ png_init_read_transformations(png_struct *png_ptr)
|
|||||||
|
|
||||||
/* modify the info structure to reflect the transformations. The
|
/* modify the info structure to reflect the transformations. The
|
||||||
info should be updated so a png file could be written with it,
|
info should be updated so a png file could be written with it,
|
||||||
assuming the transformations result in valid png data */
|
assuming the transformations result in valid png data */
|
||||||
void
|
void
|
||||||
png_read_transform_info(png_struct *png_ptr, png_info *info_ptr)
|
png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
|
||||||
{
|
{
|
||||||
#if defined(PNG_READ_EXPAND_SUPPORTED)
|
#if defined(PNG_READ_EXPAND_SUPPORTED)
|
||||||
if ((png_ptr->transformations & PNG_EXPAND) &&
|
if ((png_ptr->transformations & PNG_EXPAND) &&
|
||||||
@ -618,7 +621,7 @@ png_read_transform_info(png_struct *png_ptr, png_info *info_ptr)
|
|||||||
else if (png_ptr->transformations & PNG_EXPAND)
|
else if (png_ptr->transformations & PNG_EXPAND)
|
||||||
{
|
{
|
||||||
if (png_ptr->num_trans)
|
if (png_ptr->num_trans)
|
||||||
info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
|
info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
|
||||||
if (info_ptr->bit_depth < 8)
|
if (info_ptr->bit_depth < 8)
|
||||||
info_ptr->bit_depth = 8;
|
info_ptr->bit_depth = 8;
|
||||||
info_ptr->num_trans = 0;
|
info_ptr->num_trans = 0;
|
||||||
@ -636,7 +639,7 @@ png_read_transform_info(png_struct *png_ptr, png_info *info_ptr)
|
|||||||
|
|
||||||
#if defined(PNG_READ_16_TO_8_SUPPORTED)
|
#if defined(PNG_READ_16_TO_8_SUPPORTED)
|
||||||
if ((png_ptr->transformations & PNG_16_TO_8) && info_ptr->bit_depth == 16)
|
if ((png_ptr->transformations & PNG_16_TO_8) && info_ptr->bit_depth == 16)
|
||||||
info_ptr->bit_depth = 8;
|
info_ptr->bit_depth = 8;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_READ_DITHER_SUPPORTED)
|
#if defined(PNG_READ_DITHER_SUPPORTED)
|
||||||
@ -661,7 +664,7 @@ png_read_transform_info(png_struct *png_ptr, png_info *info_ptr)
|
|||||||
!(info_ptr->color_type & PNG_COLOR_MASK_COLOR))
|
!(info_ptr->color_type & PNG_COLOR_MASK_COLOR))
|
||||||
info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
|
info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
|
||||||
#endif
|
#endif
|
||||||
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
|
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
|
||||||
info_ptr->channels = 1;
|
info_ptr->channels = 1;
|
||||||
else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
|
else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
|
||||||
info_ptr->channels = 3;
|
info_ptr->channels = 3;
|
||||||
@ -677,7 +680,7 @@ png_read_transform_info(png_struct *png_ptr, png_info *info_ptr)
|
|||||||
and is very touchy. If you add a transformation, take care to
|
and is very touchy. If you add a transformation, take care to
|
||||||
decide how it fits in with the other transformations here */
|
decide how it fits in with the other transformations here */
|
||||||
void
|
void
|
||||||
png_do_read_transformations(png_struct *png_ptr)
|
png_do_read_transformations(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
#if defined(PNG_READ_EXPAND_SUPPORTED)
|
#if defined(PNG_READ_EXPAND_SUPPORTED)
|
||||||
if ((png_ptr->transformations & PNG_EXPAND) &&
|
if ((png_ptr->transformations & PNG_EXPAND) &&
|
||||||
@ -690,7 +693,7 @@ png_do_read_transformations(png_struct *png_ptr)
|
|||||||
{
|
{
|
||||||
if (png_ptr->num_trans)
|
if (png_ptr->num_trans)
|
||||||
png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
|
png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
|
||||||
&(png_ptr->trans_values));
|
&(png_ptr->trans_values));
|
||||||
else
|
else
|
||||||
png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
|
png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
|
||||||
NULL);
|
NULL);
|
||||||
@ -724,16 +727,16 @@ png_do_read_transformations(png_struct *png_ptr)
|
|||||||
#if defined(PNG_READ_DITHER_SUPPORTED)
|
#if defined(PNG_READ_DITHER_SUPPORTED)
|
||||||
if (png_ptr->transformations & PNG_DITHER)
|
if (png_ptr->transformations & PNG_DITHER)
|
||||||
{
|
{
|
||||||
png_do_dither((png_row_info *)&(png_ptr->row_info),
|
png_do_dither((png_row_infop)&(png_ptr->row_info),
|
||||||
png_ptr->row_buf + 1,
|
png_ptr->row_buf + 1,
|
||||||
png_ptr->palette_lookup,
|
png_ptr->palette_lookup,
|
||||||
png_ptr->dither_index);
|
png_ptr->dither_index);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_READ_INVERT_SUPPORTED)
|
#if defined(PNG_READ_INVERT_SUPPORTED)
|
||||||
if (png_ptr->transformations & PNG_INVERT_MONO)
|
if (png_ptr->transformations & PNG_INVERT_MONO)
|
||||||
png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
|
png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_READ_SHIFT_SUPPORTED)
|
#if defined(PNG_READ_SHIFT_SUPPORTED)
|
||||||
@ -744,7 +747,7 @@ png_do_read_transformations(png_struct *png_ptr)
|
|||||||
|
|
||||||
#if defined(PNG_READ_PACK_SUPPORTED)
|
#if defined(PNG_READ_PACK_SUPPORTED)
|
||||||
if (png_ptr->transformations & PNG_PACK)
|
if (png_ptr->transformations & PNG_PACK)
|
||||||
png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
|
png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_READ_BGR_SUPPORTED)
|
#if defined(PNG_READ_BGR_SUPPORTED)
|
||||||
@ -776,11 +779,11 @@ png_do_read_transformations(png_struct *png_ptr)
|
|||||||
the numbers 0 or 1. If you would rather they contain 0 and 255, use
|
the numbers 0 or 1. If you would rather they contain 0 and 255, use
|
||||||
png_do_shift() after this. */
|
png_do_shift() after this. */
|
||||||
void
|
void
|
||||||
png_do_unpack(png_row_info *row_info, png_bytef *row)
|
png_do_unpack(png_row_infop row_info, png_bytep row)
|
||||||
{
|
{
|
||||||
int shift;
|
int shift;
|
||||||
png_bytef *sp, *dp;
|
png_bytep sp, dp;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
|
|
||||||
if (row && row_info && row_info->bit_depth < 8)
|
if (row && row_info && row_info->bit_depth < 8)
|
||||||
{
|
{
|
||||||
@ -798,7 +801,7 @@ png_do_unpack(png_row_info *row_info, png_bytef *row)
|
|||||||
{
|
{
|
||||||
shift = 0;
|
shift = 0;
|
||||||
sp--;
|
sp--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
shift++;
|
shift++;
|
||||||
|
|
||||||
@ -831,7 +834,7 @@ png_do_unpack(png_row_info *row_info, png_bytef *row)
|
|||||||
{
|
{
|
||||||
sp = row + (png_size_t)((row_info->width - 1) >> 1);
|
sp = row + (png_size_t)((row_info->width - 1) >> 1);
|
||||||
dp = row + (png_size_t)row_info->width - 1;
|
dp = row + (png_size_t)row_info->width - 1;
|
||||||
shift = (int)((1 - ((row_info->width + 1) & 1)) << 4);
|
shift = (int)((1 - ((row_info->width + 1) & 1)) << 2);
|
||||||
for (i = 0; i < row_info->width; i++)
|
for (i = 0; i < row_info->width; i++)
|
||||||
{
|
{
|
||||||
*dp = (*sp >> shift) & 0xf;
|
*dp = (*sp >> shift) & 0xf;
|
||||||
@ -861,10 +864,10 @@ png_do_unpack(png_row_info *row_info, png_bytef *row)
|
|||||||
a row of bit depth 8, but only 5 are significant, this will shift
|
a row of bit depth 8, but only 5 are significant, this will shift
|
||||||
the values back to 0 through 31 */
|
the values back to 0 through 31 */
|
||||||
void
|
void
|
||||||
png_do_unshift(png_row_info *row_info, png_bytef *row,
|
png_do_unshift(png_row_infop row_info, png_bytep row,
|
||||||
png_color_8 *sig_bits)
|
png_color_8p sig_bits)
|
||||||
{
|
{
|
||||||
png_bytef *bp;
|
png_bytep bp;
|
||||||
png_uint_16 value;
|
png_uint_16 value;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
if (row && row_info && sig_bits &&
|
if (row && row_info && sig_bits &&
|
||||||
@ -876,34 +879,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 < 0 ?
|
shift[channels++] = row_info->bit_depth - sig_bits->red;
|
||||||
0 : row_info->bit_depth - sig_bits->red;
|
shift[channels++] = row_info->bit_depth - sig_bits->green;
|
||||||
shift[channels++] = row_info->bit_depth - sig_bits->green < 0 ?
|
shift[channels++] = row_info->bit_depth - sig_bits->blue;
|
||||||
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 < 0 ?
|
shift[channels++] = row_info->bit_depth - sig_bits->gray;
|
||||||
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 < 0 ?
|
shift[channels++] = row_info->bit_depth - sig_bits->alpha;
|
||||||
0 : row_info->bit_depth - sig_bits->alpha;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
value = 1;
|
value = 0;
|
||||||
|
|
||||||
for (i = 0; i < channels; i++)
|
for (i = 0; i < channels; i++)
|
||||||
{
|
{
|
||||||
if (shift[i] != 0) value = 0;
|
if (shift[i] <= 0)
|
||||||
}
|
shift[i] = 0;
|
||||||
|
else
|
||||||
|
value = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (value == 1) return;
|
if (!value)
|
||||||
|
return;
|
||||||
|
|
||||||
switch (row_info->bit_depth)
|
switch (row_info->bit_depth)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
@ -919,8 +921,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;
|
||||||
i < row_info->rowbytes;
|
i < row_info->rowbytes;
|
||||||
@ -938,7 +939,7 @@ png_do_unshift(png_row_info *row_info, png_bytef *row,
|
|||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
for (c = 0; c < row_info->channels; c++, bp++)
|
for (c = 0; c < row_info->channels; c++, bp++)
|
||||||
{
|
{
|
||||||
*bp >>= shift[c];
|
*bp >>= shift[c];
|
||||||
}
|
}
|
||||||
@ -956,7 +957,7 @@ png_do_unshift(png_row_info *row_info, png_bytef *row,
|
|||||||
{
|
{
|
||||||
value = (*bp << 8) + *(bp + 1);
|
value = (*bp << 8) + *(bp + 1);
|
||||||
value >>= shift[c];
|
value >>= shift[c];
|
||||||
*bp = value >> 8;
|
*bp = value >> 8;
|
||||||
*(bp + 1) = value & 0xff;
|
*(bp + 1) = value & 0xff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -970,17 +971,24 @@ png_do_unshift(png_row_info *row_info, png_bytef *row,
|
|||||||
#if defined(PNG_READ_16_TO_8_SUPPORTED)
|
#if defined(PNG_READ_16_TO_8_SUPPORTED)
|
||||||
/* chop rows of bit depth 16 down to 8 */
|
/* chop rows of bit depth 16 down to 8 */
|
||||||
void
|
void
|
||||||
png_do_chop(png_row_info *row_info, png_bytef *row)
|
png_do_chop(png_row_infop row_info, png_bytep row)
|
||||||
{
|
{
|
||||||
if (row && row_info && row_info->bit_depth == 16)
|
png_bytep sp, dp;
|
||||||
|
png_uint_32 i;
|
||||||
|
if (row && row_info && row_info->bit_depth == 16)
|
||||||
{
|
{
|
||||||
png_bytef *sp = row, *dp = row;
|
sp = row;
|
||||||
png_uint_32 i;
|
dp = row;
|
||||||
|
|
||||||
for (i = 0; i < row_info->width * row_info->channels; i++)
|
for (i = 0; i < row_info->width * row_info->channels; i++)
|
||||||
{
|
{
|
||||||
*dp++ = ((((*sp << 8 | *(sp + 1)) - *sp) + 0x7F) >> 8) & 0xFF;
|
*dp = *sp;
|
||||||
sp += 2;
|
/* not yet, as I'm afraid of overflow here
|
||||||
|
*dp = ((((((png_uint_16)(*sp) << 8)) |
|
||||||
|
(png_uint_16)((*(sp + 1) - *sp) & 0xff) +
|
||||||
|
0x7f) >> 8) & 0xff);
|
||||||
|
*/
|
||||||
|
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;
|
||||||
@ -992,10 +1000,10 @@ png_do_chop(png_row_info *row_info, png_bytef *row)
|
|||||||
#if defined(PNG_READ_FILLER_SUPPORTED)
|
#if defined(PNG_READ_FILLER_SUPPORTED)
|
||||||
/* add filler byte */
|
/* add filler byte */
|
||||||
void
|
void
|
||||||
png_do_read_filler(png_row_info *row_info, png_bytef *row,
|
png_do_read_filler(png_row_infop row_info, png_bytep row,
|
||||||
png_byte filler, png_byte filler_loc)
|
png_byte filler, png_byte filler_loc)
|
||||||
{
|
{
|
||||||
png_bytef *sp, *dp;
|
png_bytep sp, dp;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
if (row && row_info && row_info->color_type == 2 &&
|
if (row && row_info && row_info->color_type == 2 &&
|
||||||
row_info->bit_depth == 8)
|
row_info->bit_depth == 8)
|
||||||
@ -1040,10 +1048,11 @@ png_do_read_filler(png_row_info *row_info, png_bytef *row,
|
|||||||
#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
|
#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
|
||||||
/* expand grayscale files to rgb, with or without alpha */
|
/* expand grayscale files to rgb, with or without alpha */
|
||||||
void
|
void
|
||||||
png_do_gray_to_rgb(png_row_info *row_info, png_bytef *row)
|
png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
|
||||||
{
|
{
|
||||||
png_bytef *sp, *dp;
|
png_bytep sp, dp;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
|
|
||||||
if (row && row_info && row_info->bit_depth >= 8 &&
|
if (row && row_info && row_info->bit_depth >= 8 &&
|
||||||
!(row_info->color_type & PNG_COLOR_MASK_COLOR))
|
!(row_info->color_type & PNG_COLOR_MASK_COLOR))
|
||||||
{
|
{
|
||||||
@ -1130,7 +1139,7 @@ png_do_gray_to_rgb(png_row_info *row_info, png_bytef *row)
|
|||||||
paletted. Most useful for gamma correction and simplification
|
paletted. Most useful for gamma correction and simplification
|
||||||
of code. */
|
of code. */
|
||||||
void
|
void
|
||||||
png_build_grayscale_palette(int bit_depth, png_color *palette)
|
png_build_grayscale_palette(int bit_depth, png_colorp palette)
|
||||||
{
|
{
|
||||||
int num_palette;
|
int num_palette;
|
||||||
int color_inc;
|
int color_inc;
|
||||||
@ -1160,7 +1169,6 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1174,7 +1182,7 @@ png_build_grayscale_palette(int bit_depth, png_color *palette)
|
|||||||
|
|
||||||
#if defined(PNG_READ_DITHER_SUPPORTED)
|
#if defined(PNG_READ_DITHER_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_correct_palette(png_struct *png_ptr, png_color *palette,
|
png_correct_palette(png_structp png_ptr, png_colorp palette,
|
||||||
int num_palette)
|
int num_palette)
|
||||||
{
|
{
|
||||||
if ((png_ptr->transformations & (PNG_GAMMA)) &&
|
if ((png_ptr->transformations & (PNG_GAMMA)) &&
|
||||||
@ -1344,15 +1352,16 @@ png_correct_palette(png_struct *png_ptr, png_color *palette,
|
|||||||
background is the color (in rgb or grey or palette index, as
|
background is the color (in rgb or grey or palette index, as
|
||||||
appropriate). note that paletted files are taken care of elsewhere */
|
appropriate). note that paletted files are taken care of elsewhere */
|
||||||
void
|
void
|
||||||
png_do_background(png_row_info *row_info, png_bytef *row,
|
png_do_background(png_row_infop row_info, png_bytep row,
|
||||||
png_color_16 *trans_values, png_color_16 *background,
|
png_color_16p trans_values, png_color_16p background,
|
||||||
png_color_16 *background_1,
|
png_color_16p background_1,
|
||||||
png_byte *gamma_table, png_byte *gamma_from_1, png_byte *gamma_to_1,
|
png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
|
||||||
png_uint_16 **gamma_16, png_uint_16 **gamma_16_from_1,
|
png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
|
||||||
png_uint_16 **gamma_16_to_1, int gamma_shift)
|
png_uint_16pp gamma_16_to_1, int gamma_shift)
|
||||||
{
|
{
|
||||||
png_bytef *sp, *dp;
|
png_bytep sp, dp;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
|
|
||||||
int shift;
|
int shift;
|
||||||
if (row && row_info && background &&
|
if (row && row_info && background &&
|
||||||
(!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
|
(!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
|
||||||
@ -2016,15 +2025,16 @@ 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_infop row_info, png_bytep row,
|
||||||
png_byte *gamma_table, png_uint_16 **gamma_16_table,
|
png_bytep gamma_table, png_uint_16pp gamma_16_table,
|
||||||
int gamma_shift)
|
int gamma_shift)
|
||||||
{
|
{
|
||||||
png_bytef *sp;
|
png_bytep sp;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
|
|
||||||
if (row && row_info && ((row_info->bit_depth <= 8 && gamma_table) ||
|
if (row && row_info && ((row_info->bit_depth <= 8 && gamma_table) ||
|
||||||
(row_info->bit_depth == 16 && gamma_16_table)))
|
(row_info->bit_depth == 16 && gamma_16_table)))
|
||||||
{
|
{
|
||||||
@ -2177,13 +2187,14 @@ png_do_gamma(png_row_info *row_info, png_bytef *row,
|
|||||||
/* expands a palette row to an rgb or rgba row depending
|
/* expands a palette row to an rgb or rgba row depending
|
||||||
upon whether you supply trans and num_trans */
|
upon whether you supply trans and num_trans */
|
||||||
void
|
void
|
||||||
png_do_expand_palette(png_row_info *row_info, png_bytef *row,
|
png_do_expand_palette(png_row_infop row_info, png_bytep row,
|
||||||
png_color *palette,
|
png_colorp palette,
|
||||||
png_byte *trans, int num_trans)
|
png_bytep trans, int num_trans)
|
||||||
{
|
{
|
||||||
int shift, value;
|
int shift, value;
|
||||||
png_bytef *sp, *dp;
|
png_bytep sp, dp;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
|
|
||||||
if (row && row_info && row_info->color_type == PNG_COLOR_TYPE_PALETTE)
|
if (row && row_info && row_info->color_type == PNG_COLOR_TYPE_PALETTE)
|
||||||
{
|
{
|
||||||
if (row_info->bit_depth < 8)
|
if (row_info->bit_depth < 8)
|
||||||
@ -2311,14 +2322,15 @@ png_do_expand_palette(png_row_info *row_info, png_bytef *row,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* if the bit depth < 8, it is expanded to 8. Also, if the
|
/* if the bit depth < 8, it is expanded to 8. Also, if the
|
||||||
transparency value is supplied, an alpha channel is built. */
|
transparency value is supplied, an alpha channel is built. */
|
||||||
void
|
void
|
||||||
png_do_expand(png_row_info *row_info, png_bytef *row,
|
png_do_expand(png_row_infop row_info, png_bytep row,
|
||||||
png_color_16 *trans_value)
|
png_color_16p trans_value)
|
||||||
{
|
{
|
||||||
int shift, value;
|
int shift, value;
|
||||||
png_bytef *sp, *dp;
|
png_bytep sp, dp;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
|
|
||||||
if (row && row_info)
|
if (row && row_info)
|
||||||
{
|
{
|
||||||
if (row_info->color_type == PNG_COLOR_TYPE_GRAY &&
|
if (row_info->color_type == PNG_COLOR_TYPE_GRAY &&
|
||||||
@ -2411,7 +2423,7 @@ png_do_expand(png_row_info *row_info, png_bytef *row,
|
|||||||
*dp-- = 0xff;
|
*dp-- = 0xff;
|
||||||
*dp-- = *sp--;
|
*dp-- = *sp--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (row_info->bit_depth == 16)
|
else if (row_info->bit_depth == 16)
|
||||||
{
|
{
|
||||||
sp = row + (png_size_t)row_info->rowbytes - 1;
|
sp = row + (png_size_t)row_info->rowbytes - 1;
|
||||||
@ -2429,7 +2441,7 @@ png_do_expand(png_row_info *row_info, png_bytef *row,
|
|||||||
*dp-- = 0xff;
|
*dp-- = 0xff;
|
||||||
*dp-- = 0xff;
|
*dp-- = 0xff;
|
||||||
}
|
}
|
||||||
*dp-- = *sp--;
|
*dp-- = *sp--;
|
||||||
*dp-- = *sp--;
|
*dp-- = *sp--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2447,7 +2459,7 @@ png_do_expand(png_row_info *row_info, png_bytef *row,
|
|||||||
dp = row + (png_size_t)(row_info->width << 2) - 1;
|
dp = row + (png_size_t)(row_info->width << 2) - 1;
|
||||||
for (i = 0; i < row_info->width; i++)
|
for (i = 0; i < row_info->width; i++)
|
||||||
{
|
{
|
||||||
if (*(sp - 2) == trans_value->red &&
|
if (*(sp - 2) == trans_value->red &&
|
||||||
*(sp - 1) == trans_value->green &&
|
*(sp - 1) == trans_value->green &&
|
||||||
*(sp - 0) == trans_value->blue)
|
*(sp - 0) == trans_value->blue)
|
||||||
*dp-- = 0;
|
*dp-- = 0;
|
||||||
@ -2465,7 +2477,7 @@ png_do_expand(png_row_info *row_info, png_bytef *row,
|
|||||||
for (i = 0; i < row_info->width; i++)
|
for (i = 0; i < row_info->width; i++)
|
||||||
{
|
{
|
||||||
if ((((png_uint_16)*(sp - 4) |
|
if ((((png_uint_16)*(sp - 4) |
|
||||||
((png_uint_16)*(sp - 5) << 8)) == trans_value->red) &&
|
((png_uint_16)*(sp - 5) << 8)) == trans_value->red) &&
|
||||||
(((png_uint_16)*(sp - 2) |
|
(((png_uint_16)*(sp - 2) |
|
||||||
((png_uint_16)*(sp - 3) << 8)) == trans_value->green) &&
|
((png_uint_16)*(sp - 3) << 8)) == trans_value->green) &&
|
||||||
(((png_uint_16)*(sp - 0) |
|
(((png_uint_16)*(sp - 0) |
|
||||||
@ -2483,7 +2495,7 @@ png_do_expand(png_row_info *row_info, png_bytef *row,
|
|||||||
*dp-- = *sp--;
|
*dp-- = *sp--;
|
||||||
*dp-- = *sp--;
|
*dp-- = *sp--;
|
||||||
*dp-- = *sp--;
|
*dp-- = *sp--;
|
||||||
*dp-- = *sp--;
|
*dp-- = *sp--;
|
||||||
*dp-- = *sp--;
|
*dp-- = *sp--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2499,11 +2511,12 @@ png_do_expand(png_row_info *row_info, png_bytef *row,
|
|||||||
|
|
||||||
#if defined(PNG_READ_DITHER_SUPPORTED)
|
#if defined(PNG_READ_DITHER_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_do_dither(png_row_info *row_info, png_bytef *row,
|
png_do_dither(png_row_infop row_info, png_bytep row,
|
||||||
png_byte *palette_lookup, png_byte *dither_lookup)
|
png_bytep palette_lookup, png_bytep dither_lookup)
|
||||||
{
|
{
|
||||||
png_bytef *sp, *dp;
|
png_bytep sp, dp;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
|
|
||||||
if (row && row_info)
|
if (row && row_info)
|
||||||
{
|
{
|
||||||
if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
|
if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
|
||||||
@ -2529,7 +2542,7 @@ png_do_dither(png_row_info *row_info, png_bytef *row,
|
|||||||
((1 << PNG_DITHER_RED_BITS) - 1)) <<
|
((1 << PNG_DITHER_RED_BITS) - 1)) <<
|
||||||
(PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
|
(PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
|
||||||
(((g >> (8 - PNG_DITHER_GREEN_BITS)) &
|
(((g >> (8 - PNG_DITHER_GREEN_BITS)) &
|
||||||
((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
|
((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
|
||||||
(PNG_DITHER_BLUE_BITS)) |
|
(PNG_DITHER_BLUE_BITS)) |
|
||||||
((b >> (8 - PNG_DITHER_BLUE_BITS)) &
|
((b >> (8 - PNG_DITHER_BLUE_BITS)) &
|
||||||
((1 << PNG_DITHER_BLUE_BITS) - 1));
|
((1 << PNG_DITHER_BLUE_BITS) - 1));
|
||||||
@ -2556,7 +2569,7 @@ png_do_dither(png_row_info *row_info, png_bytef *row,
|
|||||||
sp++;
|
sp++;
|
||||||
|
|
||||||
p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
|
p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
|
||||||
((1 << PNG_DITHER_RED_BITS) - 1)) <<
|
((1 << PNG_DITHER_RED_BITS) - 1)) <<
|
||||||
(PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
|
(PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
|
||||||
(((g >> (8 - PNG_DITHER_GREEN_BITS)) &
|
(((g >> (8 - PNG_DITHER_GREEN_BITS)) &
|
||||||
((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
|
((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
|
||||||
@ -2574,7 +2587,7 @@ png_do_dither(png_row_info *row_info, png_bytef *row,
|
|||||||
}
|
}
|
||||||
else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
|
else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
|
||||||
dither_lookup && row_info->bit_depth == 8)
|
dither_lookup && row_info->bit_depth == 8)
|
||||||
{
|
{
|
||||||
sp = row;
|
sp = row;
|
||||||
for (i = 0; i < row_info->width; i++, sp++)
|
for (i = 0; i < row_info->width; i++, sp++)
|
||||||
{
|
{
|
||||||
@ -2590,7 +2603,7 @@ static int png_gamma_shift[] =
|
|||||||
{0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0};
|
{0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0};
|
||||||
|
|
||||||
void
|
void
|
||||||
png_build_gamma_table(png_struct *png_ptr)
|
png_build_gamma_table(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
if (png_ptr->bit_depth <= 8)
|
if (png_ptr->bit_depth <= 8)
|
||||||
{
|
{
|
||||||
@ -2599,7 +2612,7 @@ png_build_gamma_table(png_struct *png_ptr)
|
|||||||
|
|
||||||
g = 1.0 / (png_ptr->gamma * png_ptr->display_gamma);
|
g = 1.0 / (png_ptr->gamma * png_ptr->display_gamma);
|
||||||
|
|
||||||
png_ptr->gamma_table = (png_byte *)png_malloc(png_ptr,
|
png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
|
||||||
(png_uint_32)256);
|
(png_uint_32)256);
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
@ -2612,7 +2625,7 @@ png_build_gamma_table(png_struct *png_ptr)
|
|||||||
{
|
{
|
||||||
g = 1.0 / (png_ptr->gamma);
|
g = 1.0 / (png_ptr->gamma);
|
||||||
|
|
||||||
png_ptr->gamma_to_1 = (png_byte *)png_malloc(png_ptr,
|
png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
|
||||||
(png_uint_32)256);
|
(png_uint_32)256);
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
@ -2623,7 +2636,7 @@ png_build_gamma_table(png_struct *png_ptr)
|
|||||||
|
|
||||||
g = 1.0 / (png_ptr->display_gamma);
|
g = 1.0 / (png_ptr->display_gamma);
|
||||||
|
|
||||||
png_ptr->gamma_from_1 = (png_byte *)png_malloc(png_ptr,
|
png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
|
||||||
(png_uint_32)256);
|
(png_uint_32)256);
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
@ -2633,16 +2646,15 @@ png_build_gamma_table(png_struct *png_ptr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
double g;
|
double g;
|
||||||
int i, j, shift, num;
|
int i, j, shift, num;
|
||||||
png_uint_32 ig;
|
int sig_bit;
|
||||||
#if defined(PNG_READ_sBIT_SUPPORTED)
|
png_uint_32 ig;
|
||||||
int sig_bit;
|
|
||||||
|
|
||||||
if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
|
if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
|
||||||
{
|
{
|
||||||
sig_bit = (int)png_ptr->sig_bit.red;
|
sig_bit = (int)png_ptr->sig_bit.red;
|
||||||
if ((int)png_ptr->sig_bit.green > sig_bit)
|
if ((int)png_ptr->sig_bit.green > sig_bit)
|
||||||
sig_bit = png_ptr->sig_bit.green;
|
sig_bit = png_ptr->sig_bit.green;
|
||||||
@ -2652,13 +2664,12 @@ png_build_gamma_table(png_struct *png_ptr)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
sig_bit = (int)png_ptr->sig_bit.gray;
|
sig_bit = (int)png_ptr->sig_bit.gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
@ -2666,58 +2677,60 @@ png_build_gamma_table(png_struct *png_ptr)
|
|||||||
shift = (16 - PNG_MAX_GAMMA_8);
|
shift = (16 - PNG_MAX_GAMMA_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shift > 8)
|
if (shift > 8)
|
||||||
shift = 8;
|
shift = 8;
|
||||||
if (shift < 0)
|
if (shift < 0)
|
||||||
shift = 0;
|
shift = 0;
|
||||||
|
|
||||||
png_ptr->gamma_shift = shift;
|
png_ptr->gamma_shift = shift;
|
||||||
|
|
||||||
num = (1 << (8 - shift));
|
num = (1 << (8 - shift));
|
||||||
|
|
||||||
g = 1.0 / (png_ptr->gamma * png_ptr->display_gamma);
|
g = 1.0 / (png_ptr->gamma * png_ptr->display_gamma);
|
||||||
|
|
||||||
png_ptr->gamma_16_table = (png_uint_16 **)png_malloc(png_ptr,
|
png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr,
|
||||||
num * sizeof (png_uint_16 *));
|
num * sizeof (png_uint_16p ));
|
||||||
|
|
||||||
if ((png_ptr->transformations & PNG_16_TO_8) &&
|
if ((png_ptr->transformations & PNG_16_TO_8) &&
|
||||||
!(png_ptr->transformations & PNG_BACKGROUND))
|
!(png_ptr->transformations & PNG_BACKGROUND))
|
||||||
{
|
{
|
||||||
double fin, fout;
|
double fin, fout;
|
||||||
png_uint_32 last, max;
|
png_uint_32 last, max;
|
||||||
|
|
||||||
for (i = 0; i < num; i++)
|
for (i = 0; i < num; i++)
|
||||||
{
|
{
|
||||||
png_ptr->gamma_16_table[i] = (png_uint_16 *)png_malloc(png_ptr,
|
png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
|
||||||
256 * sizeof (png_uint_16));
|
256 * sizeof (png_uint_16));
|
||||||
}
|
}
|
||||||
|
|
||||||
g = 1.0 / g;
|
g = 1.0 / g;
|
||||||
last = 0;
|
last = 0;
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
fout = ((double)i + 0.5) / 256.0;
|
fout = ((double)i + 0.5) / 256.0;
|
||||||
fin = pow(fout, g);
|
fin = pow(fout, g);
|
||||||
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)][(int)(last & 0xff)] =
|
png_ptr->gamma_16_table[(int)(last & 0xff) >> shift]
|
||||||
(png_uint_16)i | ((png_uint_16)i << 8);
|
[(int)(last >> (8 - shift))] =
|
||||||
|
(png_uint_16)i | ((png_uint_16)i << 8);
|
||||||
last++;
|
last++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (last < (num << 8))
|
while (last < ((png_uint_32)num << 8))
|
||||||
{
|
{
|
||||||
png_ptr->gamma_16_table[(int)(last >> 8)][(int)(last & 0xff)] =
|
png_ptr->gamma_16_table[(int)(last & 0xff) >> shift]
|
||||||
(png_uint_16)65535L;
|
[(int)(last >> (8 - shift))] =
|
||||||
last++;
|
(png_uint_16)65535L;
|
||||||
}
|
last++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (i = 0; i < num; i++)
|
for (i = 0; i < num; i++)
|
||||||
{
|
{
|
||||||
png_ptr->gamma_16_table[i] = (png_uint_16 *)png_malloc(png_ptr,
|
png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
|
||||||
256 * sizeof (png_uint_16));
|
256 * sizeof (png_uint_16));
|
||||||
|
|
||||||
ig = (((png_uint_32)i *
|
ig = (((png_uint_32)i *
|
||||||
@ -2735,12 +2748,12 @@ png_build_gamma_table(png_struct *png_ptr)
|
|||||||
{
|
{
|
||||||
g = 1.0 / (png_ptr->gamma);
|
g = 1.0 / (png_ptr->gamma);
|
||||||
|
|
||||||
png_ptr->gamma_16_to_1 = (png_uint_16 **)png_malloc(png_ptr,
|
png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr,
|
||||||
num * sizeof (png_uint_16 *));
|
num * sizeof (png_uint_16p ));
|
||||||
|
|
||||||
for (i = 0; i < num; i++)
|
for (i = 0; i < num; i++)
|
||||||
{
|
{
|
||||||
png_ptr->gamma_16_to_1[i] = (png_uint_16 *)png_malloc(png_ptr,
|
png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
|
||||||
256 * sizeof (png_uint_16));
|
256 * sizeof (png_uint_16));
|
||||||
|
|
||||||
ig = (((png_uint_32)i *
|
ig = (((png_uint_32)i *
|
||||||
@ -2754,12 +2767,12 @@ png_build_gamma_table(png_struct *png_ptr)
|
|||||||
}
|
}
|
||||||
g = 1.0 / (png_ptr->display_gamma);
|
g = 1.0 / (png_ptr->display_gamma);
|
||||||
|
|
||||||
png_ptr->gamma_16_from_1 = (png_uint_16 **)png_malloc(png_ptr,
|
png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr,
|
||||||
num * sizeof (png_uint_16 *));
|
num * sizeof (png_uint_16p));
|
||||||
|
|
||||||
for (i = 0; i < num; i++)
|
for (i = 0; i < num; i++)
|
||||||
{
|
{
|
||||||
png_ptr->gamma_16_from_1[i] = (png_uint_16 *)png_malloc(png_ptr,
|
png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
|
||||||
256 * sizeof (png_uint_16));
|
256 * sizeof (png_uint_16));
|
||||||
|
|
||||||
ig = (((png_uint_32)i *
|
ig = (((png_uint_32)i *
|
||||||
|
253
pngrutil.c
253
pngrutil.c
@ -1,10 +1,10 @@
|
|||||||
|
|
||||||
/* pngrutil.c - utilities to read a png file
|
/* pngrutil.c - utilities to read a png file
|
||||||
|
|
||||||
libpng 1.0 beta 2 - version 0.81
|
libpng 1.0 beta 2 - version 0.85
|
||||||
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
|
December 19, 1995
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PNG_INTERNAL
|
#define PNG_INTERNAL
|
||||||
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
/* grab an uint 32 from a buffer */
|
/* grab an uint 32 from a buffer */
|
||||||
png_uint_32
|
png_uint_32
|
||||||
png_get_uint_32(png_byte *buf)
|
png_get_uint_32(png_bytep buf)
|
||||||
{
|
{
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
|
|
||||||
@ -26,11 +26,11 @@ png_get_uint_32(png_byte *buf)
|
|||||||
|
|
||||||
/* grab an uint 16 from a buffer */
|
/* grab an uint 16 from a buffer */
|
||||||
png_uint_16
|
png_uint_16
|
||||||
png_get_uint_16(png_byte *buf)
|
png_get_uint_16(png_bytep buf)
|
||||||
{
|
{
|
||||||
png_uint_16 i;
|
png_uint_16 i;
|
||||||
|
|
||||||
i = ((png_uint_16)(*buf) << 8) +
|
i = ((png_uint_16)(*buf) << 8) +
|
||||||
(png_uint_16)(*(buf + 1));
|
(png_uint_16)(*(buf + 1));
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
@ -38,33 +38,33 @@ png_get_uint_16(png_byte *buf)
|
|||||||
|
|
||||||
/* read data, and run it through the crc */
|
/* read data, and run it through the crc */
|
||||||
void
|
void
|
||||||
png_crc_read(png_struct *png_ptr, png_bytef *buf, png_uint_32 length)
|
png_crc_read(png_structp png_ptr, png_bytep buf, png_uint_32 length)
|
||||||
{
|
{
|
||||||
(*(png_ptr->read_data_fn))(png_ptr, buf, length);
|
png_read_data(png_ptr, buf, length);
|
||||||
png_calculate_crc(png_ptr, buf, length);
|
png_calculate_crc(png_ptr, buf, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skip data, but calcuate the crc anyway */
|
/* skip data, but calcuate the crc anyway */
|
||||||
void
|
void
|
||||||
png_crc_skip(png_struct *png_ptr, png_uint_32 length)
|
png_crc_skip(png_structp png_ptr, png_uint_32 length)
|
||||||
{
|
{
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
|
|
||||||
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_ptr->read_data_fn))(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
|
png_read_data(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_ptr->read_data_fn))(png_ptr, png_ptr->zbuf, i);
|
png_read_data(png_ptr, png_ptr->zbuf, i);
|
||||||
png_calculate_crc(png_ptr, png_ptr->zbuf, i);
|
png_calculate_crc(png_ptr, png_ptr->zbuf, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read and check the IDHR chunk */
|
/* read and check the IDHR chunk */
|
||||||
void
|
void
|
||||||
png_handle_IHDR(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
png_handle_IHDR(png_structp png_ptr, png_infop info, png_uint_32 length)
|
||||||
{
|
{
|
||||||
png_byte buf[13];
|
png_byte buf[13];
|
||||||
png_uint_32 width, height;
|
png_uint_32 width, height;
|
||||||
@ -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_ptr->error_fn))(png_ptr, "Invalid IHDR chunk");
|
png_error(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_ptr->error_fn))(png_ptr, "Invalid Width or Height Found");
|
png_error(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_ptr->error_fn))(png_ptr, "Invalid Bit Depth Found");
|
png_error(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_ptr->error_fn))(png_ptr, "Invalid Color Type Found");
|
png_error(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_ptr->error_fn))(png_ptr, "Found Invalid Color Type and Bit Depth Combination");
|
png_error(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_ptr->error_fn))(png_ptr, "Found Invalid Color Type and Bit Depth Combination");
|
png_error(png_ptr, "Found Invalid Color Type and Bit Depth Combination");
|
||||||
|
|
||||||
if (interlace_type > 1)
|
if (interlace_type > 1)
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Found Unsupported Interlace Value");
|
png_error(png_ptr, "Found Invalid Interlace Value");
|
||||||
|
|
||||||
if (compression_type > 0)
|
if (compression_type > 0)
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Found Unsupported Compression Value");
|
png_error(png_ptr, "Found Invalid Compression Value");
|
||||||
|
|
||||||
if (filter_type > 0)
|
if (filter_type > 0)
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Found Unsupported Filter Value");
|
png_error(png_ptr, "Found Invalid Filter Value");
|
||||||
|
|
||||||
/* set internal variables */
|
/* set internal variables */
|
||||||
png_ptr->width = width;
|
png_ptr->width = width;
|
||||||
@ -154,18 +154,16 @@ png_handle_IHDR(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
|
|
||||||
/* read and check the palette */
|
/* read and check the palette */
|
||||||
void
|
void
|
||||||
png_handle_PLTE(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
png_handle_PLTE(png_structp png_ptr, png_infop info, png_uint_32 length)
|
||||||
{
|
{
|
||||||
int num, i;
|
int num, i;
|
||||||
png_color *palette;
|
png_colorp palette;
|
||||||
|
|
||||||
if (length % 3)
|
if (length % 3)
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Invalid Palette Chunk");
|
png_error(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_colorp)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];
|
||||||
@ -183,7 +181,7 @@ png_handle_PLTE(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
|
|
||||||
#if defined(PNG_READ_gAMA_SUPPORTED)
|
#if defined(PNG_READ_gAMA_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_handle_gAMA(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
png_handle_gAMA(png_structp png_ptr, png_infop info, png_uint_32 length)
|
||||||
{
|
{
|
||||||
png_uint_32 igamma;
|
png_uint_32 igamma;
|
||||||
float gamma;
|
float gamma;
|
||||||
@ -191,7 +189,6 @@ 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;
|
||||||
}
|
}
|
||||||
@ -200,7 +197,7 @@ png_handle_gAMA(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
igamma = png_get_uint_32(buf);
|
igamma = png_get_uint_32(buf);
|
||||||
/* check for zero gamma */
|
/* check for zero gamma */
|
||||||
if (!igamma)
|
if (!igamma)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gamma = (float)igamma / (float)100000.0;
|
gamma = (float)igamma / (float)100000.0;
|
||||||
png_read_gAMA(png_ptr, info, gamma);
|
png_read_gAMA(png_ptr, info, gamma);
|
||||||
@ -210,20 +207,18 @@ png_handle_gAMA(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
|
|
||||||
#if defined(PNG_READ_sBIT_SUPPORTED)
|
#if defined(PNG_READ_sBIT_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_handle_sBIT(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
png_handle_sBIT(png_structp png_ptr, png_infop 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)
|
||||||
slen = 3;
|
slen = 3;
|
||||||
else
|
else
|
||||||
slen = png_ptr->channels;
|
slen = png_ptr->channels;
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
@ -231,35 +226,23 @@ 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[index++];
|
png_ptr->sig_bit.red = buf[0];
|
||||||
png_ptr->sig_bit.green = buf[index++];
|
png_ptr->sig_bit.green = buf[1];
|
||||||
png_ptr->sig_bit.blue = buf[index++];
|
png_ptr->sig_bit.blue = buf[2];
|
||||||
png_ptr->sig_bit.gray = 0;
|
png_ptr->sig_bit.alpha = buf[3];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
png_ptr->sig_bit.red = 0;
|
png_ptr->sig_bit.gray = buf[0];
|
||||||
png_ptr->sig_bit.green = 0;
|
png_ptr->sig_bit.alpha = buf[1];
|
||||||
png_ptr->sig_bit.blue = 0;
|
|
||||||
png_ptr->sig_bit.gray = buf[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
#if defined(PNG_READ_cHRM_SUPPORTED)
|
#if defined(PNG_READ_cHRM_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_handle_cHRM(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
png_handle_cHRM(png_structp png_ptr, png_infop info, png_uint_32 length)
|
||||||
{
|
{
|
||||||
png_byte buf[4];
|
png_byte buf[4];
|
||||||
png_uint_32 v;
|
png_uint_32 v;
|
||||||
@ -267,9 +250,8 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
png_crc_read(png_ptr, buf, 4);
|
png_crc_read(png_ptr, buf, 4);
|
||||||
@ -305,27 +287,25 @@ png_handle_cHRM(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
blue_y = (float)v / (float)100000.0;
|
blue_y = (float)v / (float)100000.0;
|
||||||
|
|
||||||
png_read_cHRM(png_ptr, info,
|
png_read_cHRM(png_ptr, info,
|
||||||
white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
|
white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_READ_tRNS_SUPPORTED)
|
#if defined(PNG_READ_tRNS_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_handle_tRNS(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
png_handle_tRNS(png_structp png_ptr, png_infop info, png_uint_32 length)
|
||||||
{
|
{
|
||||||
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
|
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
|
||||||
{
|
{
|
||||||
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_bytep)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;
|
||||||
}
|
}
|
||||||
else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
|
else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
|
||||||
{
|
{
|
||||||
@ -333,7 +313,6 @@ 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;
|
||||||
}
|
}
|
||||||
@ -350,7 +329,6 @@ 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;
|
||||||
}
|
}
|
||||||
@ -360,7 +338,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_ptr->error_fn))(png_ptr, "Invalid tRNS chunk");
|
png_error(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));
|
||||||
@ -369,7 +347,7 @@ png_handle_tRNS(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
|
|
||||||
#if defined(PNG_READ_bKGD_SUPPORTED)
|
#if defined(PNG_READ_bKGD_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_handle_bKGD(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
png_handle_bKGD(png_structp png_ptr, png_infop info, png_uint_32 length)
|
||||||
{
|
{
|
||||||
int truelen;
|
int truelen;
|
||||||
png_byte buf[6];
|
png_byte buf[6];
|
||||||
@ -383,7 +361,6 @@ 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;
|
||||||
}
|
}
|
||||||
@ -406,21 +383,19 @@ png_handle_bKGD(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
|
|
||||||
#if defined(PNG_READ_hIST_SUPPORTED)
|
#if defined(PNG_READ_hIST_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_handle_hIST(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
png_handle_hIST(png_structp png_ptr, png_infop info, png_uint_32 length)
|
||||||
{
|
{
|
||||||
int num, i;
|
int num, i;
|
||||||
|
|
||||||
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_uint_16p)png_malloc(png_ptr,
|
||||||
png_ptr->do_free |= PNG_FREE_HIST;
|
num * sizeof (png_uint_16));
|
||||||
|
|
||||||
for (i = 0; i < num; i++)
|
for (i = 0; i < num; i++)
|
||||||
{
|
{
|
||||||
png_byte buf[2];
|
png_byte buf[2];
|
||||||
@ -434,7 +409,7 @@ png_handle_hIST(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
|
|
||||||
#if defined(PNG_READ_pHYs_SUPPORTED)
|
#if defined(PNG_READ_pHYs_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_handle_pHYs(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
png_handle_pHYs(png_structp png_ptr, png_infop info, png_uint_32 length)
|
||||||
{
|
{
|
||||||
png_byte buf[9];
|
png_byte buf[9];
|
||||||
png_uint_32 res_x, res_y;
|
png_uint_32 res_x, res_y;
|
||||||
@ -442,10 +417,9 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
png_crc_read(png_ptr, buf, 9);
|
png_crc_read(png_ptr, buf, 9);
|
||||||
|
|
||||||
@ -458,7 +432,7 @@ png_handle_pHYs(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
|
|
||||||
#if defined(PNG_READ_oFFs_SUPPORTED)
|
#if defined(PNG_READ_oFFs_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_handle_oFFs(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
png_handle_oFFs(png_structp png_ptr, png_infop info, png_uint_32 length)
|
||||||
{
|
{
|
||||||
png_byte buf[9];
|
png_byte buf[9];
|
||||||
png_uint_32 offset_x, offset_y;
|
png_uint_32 offset_x, offset_y;
|
||||||
@ -466,7 +440,6 @@ 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;
|
||||||
}
|
}
|
||||||
@ -482,14 +455,13 @@ png_handle_oFFs(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
|
|
||||||
#if defined(PNG_READ_tIME_SUPPORTED)
|
#if defined(PNG_READ_tIME_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_handle_tIME(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
png_handle_tIME(png_structp png_ptr, png_infop info, png_uint_32 length)
|
||||||
{
|
{
|
||||||
png_byte buf[7];
|
png_byte buf[7];
|
||||||
png_time mod_time;
|
png_time mod_time;
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
@ -501,7 +473,7 @@ png_handle_tIME(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
mod_time.hour = buf[4];
|
mod_time.hour = buf[4];
|
||||||
mod_time.day = buf[3];
|
mod_time.day = buf[3];
|
||||||
mod_time.month = buf[2];
|
mod_time.month = buf[2];
|
||||||
mod_time.year = png_get_uint_16(buf);
|
mod_time.year = png_get_uint_16(buf);
|
||||||
|
|
||||||
png_read_tIME(png_ptr, info, &mod_time);
|
png_read_tIME(png_ptr, info, &mod_time);
|
||||||
}
|
}
|
||||||
@ -510,16 +482,16 @@ png_handle_tIME(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
#if defined(PNG_READ_tEXt_SUPPORTED)
|
#if defined(PNG_READ_tEXt_SUPPORTED)
|
||||||
/* note: this does not correctly handle chunks that are > 64K */
|
/* note: this does not correctly handle chunks that are > 64K */
|
||||||
void
|
void
|
||||||
png_handle_tEXt(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
png_handle_tEXt(png_structp png_ptr, png_infop info, png_uint_32 length)
|
||||||
{
|
{
|
||||||
charf *key;
|
png_charp key;
|
||||||
charf *text;
|
png_charp text;
|
||||||
|
|
||||||
text = NULL;
|
text = NULL;
|
||||||
|
|
||||||
key = (charf *)png_large_malloc(png_ptr, length + 1);
|
key = (png_charp )png_large_malloc(png_ptr, length + 1);
|
||||||
png_crc_read(png_ptr, (png_bytef *)key, length);
|
png_crc_read(png_ptr, (png_bytep )key, length);
|
||||||
key[(png_size_t)length] = '\0';
|
key[(png_size_t)length] = '\0';
|
||||||
|
|
||||||
for (text = key; *text; text++)
|
for (text = key; *text; text++)
|
||||||
/* empty loop */ ;
|
/* empty loop */ ;
|
||||||
@ -534,17 +506,17 @@ png_handle_tEXt(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
#if defined(PNG_READ_zTXt_SUPPORTED)
|
#if defined(PNG_READ_zTXt_SUPPORTED)
|
||||||
/* note: this does not correctly handle chunks that are > 64K compressed */
|
/* note: this does not correctly handle chunks that are > 64K compressed */
|
||||||
void
|
void
|
||||||
png_handle_zTXt(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
png_handle_zTXt(png_structp png_ptr, png_infop info, png_uint_32 length)
|
||||||
{
|
{
|
||||||
charf *key;
|
png_charp key;
|
||||||
charf *text;
|
png_charp text;
|
||||||
int ret = Z_STREAM_END;
|
int ret;
|
||||||
png_uint_32 text_size, key_size;
|
png_uint_32 text_size, key_size;
|
||||||
|
|
||||||
text = NULL;
|
text = NULL;
|
||||||
|
|
||||||
key = png_large_malloc(png_ptr, length + 1);
|
key = png_large_malloc(png_ptr, length + 1);
|
||||||
png_crc_read(png_ptr, (png_bytef *)key, length);
|
png_crc_read(png_ptr, (png_bytep )key, length);
|
||||||
key[(png_size_t)length] = '\0';
|
key[(png_size_t)length] = '\0';
|
||||||
|
|
||||||
for (text = key; *text; text++)
|
for (text = key; *text; text++)
|
||||||
@ -553,7 +525,6 @@ 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;
|
||||||
}
|
}
|
||||||
@ -568,7 +539,7 @@ png_handle_zTXt(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
|
|
||||||
text++;
|
text++;
|
||||||
|
|
||||||
png_ptr->zstream->next_in = (png_bytef *)text;
|
png_ptr->zstream->next_in = (png_bytep )text;
|
||||||
png_ptr->zstream->avail_in = (uInt)(length - (text - key));
|
png_ptr->zstream->avail_in = (uInt)(length - (text - key));
|
||||||
png_ptr->zstream->next_out = png_ptr->zbuf;
|
png_ptr->zstream->next_out = png_ptr->zbuf;
|
||||||
png_ptr->zstream->avail_out = (png_size_t)png_ptr->zbuf_size;
|
png_ptr->zstream->avail_out = (png_size_t)png_ptr->zbuf_size;
|
||||||
@ -579,14 +550,10 @@ png_handle_zTXt(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
|
|
||||||
while (png_ptr->zstream->avail_in)
|
while (png_ptr->zstream->avail_in)
|
||||||
{
|
{
|
||||||
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)
|
inflateReset(png_ptr->zstream);
|
||||||
(*(png_ptr->warning_fn))(png_ptr,png_ptr->zstream->msg);
|
|
||||||
else
|
|
||||||
(*(png_ptr->warning_fn))(png_ptr,"zTXt decompression error");
|
|
||||||
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);
|
||||||
png_large_free(png_ptr, text);
|
png_large_free(png_ptr, text);
|
||||||
@ -596,7 +563,7 @@ png_handle_zTXt(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
{
|
{
|
||||||
if (!text)
|
if (!text)
|
||||||
{
|
{
|
||||||
text = png_malloc(png_ptr,
|
text = (png_charp)png_malloc(png_ptr,
|
||||||
png_ptr->zbuf_size - png_ptr->zstream->avail_out +
|
png_ptr->zbuf_size - png_ptr->zstream->avail_out +
|
||||||
key_size + 1);
|
key_size + 1);
|
||||||
png_memcpy(text + (png_size_t)key_size, png_ptr->zbuf,
|
png_memcpy(text + (png_size_t)key_size, png_ptr->zbuf,
|
||||||
@ -608,7 +575,7 @@ png_handle_zTXt(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
charf *tmp;
|
png_charp tmp;
|
||||||
|
|
||||||
tmp = text;
|
tmp = text;
|
||||||
text = png_large_malloc(png_ptr, text_size +
|
text = png_large_malloc(png_ptr, text_size +
|
||||||
@ -635,7 +602,7 @@ png_handle_zTXt(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
inflateReset(png_ptr->zstream);
|
inflateReset(png_ptr->zstream);
|
||||||
png_ptr->zstream->avail_in = 0;
|
png_ptr->zstream->avail_in = 0;
|
||||||
|
|
||||||
if (ret != Z_STREAM_END)
|
if (ret != Z_STREAM_END)
|
||||||
@ -666,7 +633,7 @@ png_handle_zTXt(png_struct *png_ptr, png_info *info, png_uint_32 length)
|
|||||||
you want all pixels to be combined, pass 0xff (255) in mask.
|
you want all pixels to be combined, pass 0xff (255) in mask.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
png_combine_row(png_struct *png_ptr, png_bytef *row,
|
png_combine_row(png_structp png_ptr, png_bytep row,
|
||||||
int mask)
|
int mask)
|
||||||
{
|
{
|
||||||
if (mask == 0xff)
|
if (mask == 0xff)
|
||||||
@ -681,8 +648,8 @@ png_combine_row(png_struct *png_ptr, png_bytef *row,
|
|||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
png_bytef *sp;
|
png_bytep sp;
|
||||||
png_bytef *dp;
|
png_bytep dp;
|
||||||
int m;
|
int m;
|
||||||
int shift;
|
int shift;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
@ -719,8 +686,8 @@ png_combine_row(png_struct *png_ptr, png_bytef *row,
|
|||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
png_bytef *sp;
|
png_bytep sp;
|
||||||
png_bytef *dp;
|
png_bytep dp;
|
||||||
int m;
|
int m;
|
||||||
int shift;
|
int shift;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
@ -756,8 +723,8 @@ png_combine_row(png_struct *png_ptr, png_bytef *row,
|
|||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
{
|
{
|
||||||
png_bytef *sp;
|
png_bytep sp;
|
||||||
png_bytef *dp;
|
png_bytep dp;
|
||||||
int m;
|
int m;
|
||||||
int shift;
|
int shift;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
@ -793,8 +760,8 @@ png_combine_row(png_struct *png_ptr, png_bytef *row,
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
png_bytef *sp;
|
png_bytep sp;
|
||||||
png_bytef *dp;
|
png_bytep dp;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
int pixel_bytes, m;
|
int pixel_bytes, m;
|
||||||
|
|
||||||
@ -826,7 +793,7 @@ png_combine_row(png_struct *png_ptr, png_bytef *row,
|
|||||||
|
|
||||||
#if defined(PNG_READ_INTERLACING_SUPPORTED)
|
#if defined(PNG_READ_INTERLACING_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_do_read_interlace(png_row_info *row_info, png_bytef *row, int pass)
|
png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass)
|
||||||
{
|
{
|
||||||
if (row && row_info)
|
if (row && row_info)
|
||||||
{
|
{
|
||||||
@ -838,7 +805,7 @@ png_do_read_interlace(png_row_info *row_info, png_bytef *row, int pass)
|
|||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
png_bytef *sp, *dp;
|
png_bytep sp, dp;
|
||||||
int sshift, dshift;
|
int sshift, dshift;
|
||||||
png_byte v;
|
png_byte v;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
@ -875,7 +842,7 @@ png_do_read_interlace(png_row_info *row_info, png_bytef *row, int pass)
|
|||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
png_bytef *sp, *dp;
|
png_bytep sp, dp;
|
||||||
int sshift, dshift;
|
int sshift, dshift;
|
||||||
png_byte v;
|
png_byte v;
|
||||||
png_uint_32 i, j;
|
png_uint_32 i, j;
|
||||||
@ -911,7 +878,7 @@ png_do_read_interlace(png_row_info *row_info, png_bytef *row, int pass)
|
|||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
{
|
{
|
||||||
png_bytef *sp, *dp;
|
png_bytep sp, dp;
|
||||||
int sshift, dshift;
|
int sshift, dshift;
|
||||||
png_byte v;
|
png_byte v;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
@ -948,7 +915,7 @@ png_do_read_interlace(png_row_info *row_info, png_bytef *row, int pass)
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
png_bytef *sp, *dp;
|
png_bytep sp, dp;
|
||||||
png_byte v[8];
|
png_byte v[8];
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
int j;
|
int j;
|
||||||
@ -979,8 +946,8 @@ png_do_read_interlace(png_row_info *row_info, png_bytef *row, int pass)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
png_read_filter_row(png_row_info *row_info, png_bytef *row,
|
png_read_filter_row(png_row_infop row_info, png_bytep row,
|
||||||
png_bytef *prev_row, int filter)
|
png_bytep prev_row, int filter)
|
||||||
{
|
{
|
||||||
switch (filter)
|
switch (filter)
|
||||||
{
|
{
|
||||||
@ -990,8 +957,8 @@ png_read_filter_row(png_row_info *row_info, png_bytef *row,
|
|||||||
{
|
{
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
int bpp;
|
int bpp;
|
||||||
png_bytef *rp;
|
png_bytep rp;
|
||||||
png_bytef *lp;
|
png_bytep lp;
|
||||||
|
|
||||||
bpp = (row_info->pixel_depth + 7) / 8;
|
bpp = (row_info->pixel_depth + 7) / 8;
|
||||||
for (i = (png_uint_32)bpp, rp = row + bpp, lp = row;
|
for (i = (png_uint_32)bpp, rp = row + bpp, lp = row;
|
||||||
@ -1004,8 +971,8 @@ png_read_filter_row(png_row_info *row_info, png_bytef *row,
|
|||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
png_bytef *rp;
|
png_bytep rp;
|
||||||
png_bytef *pp;
|
png_bytep pp;
|
||||||
|
|
||||||
for (i = 0, rp = row, pp = prev_row;
|
for (i = 0, rp = row, pp = prev_row;
|
||||||
i < row_info->rowbytes; i++, rp++, pp++)
|
i < row_info->rowbytes; i++, rp++, pp++)
|
||||||
@ -1018,9 +985,9 @@ png_read_filter_row(png_row_info *row_info, png_bytef *row,
|
|||||||
{
|
{
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
int bpp;
|
int bpp;
|
||||||
png_bytef *rp;
|
png_bytep rp;
|
||||||
png_bytef *pp;
|
png_bytep pp;
|
||||||
png_bytef *lp;
|
png_bytep lp;
|
||||||
|
|
||||||
bpp = (row_info->pixel_depth + 7) / 8;
|
bpp = (row_info->pixel_depth + 7) / 8;
|
||||||
for (i = 0, rp = row, pp = prev_row;
|
for (i = 0, rp = row, pp = prev_row;
|
||||||
@ -1040,10 +1007,10 @@ png_read_filter_row(png_row_info *row_info, png_bytef *row,
|
|||||||
{
|
{
|
||||||
int bpp;
|
int bpp;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
png_bytef *rp;
|
png_bytep rp;
|
||||||
png_bytef *pp;
|
png_bytep pp;
|
||||||
png_bytef *lp;
|
png_bytep lp;
|
||||||
png_bytef *cp;
|
png_bytep cp;
|
||||||
|
|
||||||
bpp = (row_info->pixel_depth + 7) / 8;
|
bpp = (row_info->pixel_depth + 7) / 8;
|
||||||
for (i = 0, rp = row, pp = prev_row,
|
for (i = 0, rp = row, pp = prev_row,
|
||||||
@ -1084,7 +1051,7 @@ png_read_filter_row(png_row_info *row_info, png_bytef *row,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
png_read_finish_row(png_struct *png_ptr)
|
png_read_finish_row(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
png_ptr->row_number++;
|
png_ptr->row_number++;
|
||||||
if (png_ptr->row_number < png_ptr->num_rows)
|
if (png_ptr->row_number < png_ptr->num_rows)
|
||||||
@ -1138,19 +1105,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_ptr->read_data_fn))(png_ptr, buf, 4);
|
png_read_data(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_ptr->error_fn))(png_ptr, "Bad CRC value");
|
png_error(png_ptr, "Bad CRC value");
|
||||||
|
|
||||||
(*(png_ptr->read_data_fn))(png_ptr, buf, 4);
|
png_read_data(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 (png_memcmp(buf, png_IDAT, 4))
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Not enough image data");
|
png_error(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;
|
||||||
@ -1160,27 +1127,27 @@ png_read_finish_row(png_struct *png_ptr)
|
|||||||
png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream->avail_in);
|
png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream->avail_in);
|
||||||
png_ptr->idat_size -= png_ptr->zstream->avail_in;
|
png_ptr->idat_size -= png_ptr->zstream->avail_in;
|
||||||
}
|
}
|
||||||
ret = inflate(png_ptr->zstream, Z_PARTIAL_FLUSH);
|
ret = inflate(png_ptr->zstream, Z_PARTIAL_FLUSH);
|
||||||
if (ret == Z_STREAM_END)
|
if (ret == Z_STREAM_END)
|
||||||
{
|
{
|
||||||
if (!(png_ptr->zstream->avail_out) || png_ptr->zstream->avail_in ||
|
if (!(png_ptr->zstream->avail_out) || png_ptr->zstream->avail_in ||
|
||||||
png_ptr->idat_size)
|
png_ptr->idat_size)
|
||||||
(*(png_ptr->warning_fn))(png_ptr, "Extra compressed data");
|
png_error(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_ptr->error_fn))(png_ptr, "Compression Error");
|
png_error(png_ptr, "Compression Error");
|
||||||
|
|
||||||
if (!(png_ptr->zstream->avail_out))
|
if (!(png_ptr->zstream->avail_out))
|
||||||
(*(png_ptr->error_fn))(png_ptr, "Extra compressed data");
|
png_error(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_ptr->warning_fn))(png_ptr, "Extra compression data");
|
png_error(png_ptr, "Extra compression data");
|
||||||
|
|
||||||
inflateReset(png_ptr->zstream);
|
inflateReset(png_ptr->zstream);
|
||||||
|
|
||||||
@ -1188,7 +1155,7 @@ png_read_finish_row(png_struct *png_ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
png_read_start_row(png_struct *png_ptr)
|
png_read_start_row(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
int max_pixel_depth;
|
int max_pixel_depth;
|
||||||
png_uint_32 rowbytes;
|
png_uint_32 rowbytes;
|
||||||
@ -1292,13 +1259,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_ptr->error_fn))(png_ptr, "This image requires a row greater then 64KB");
|
png_error(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_bytep )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_ptr->error_fn))(png_ptr, "This image requires a row greater then 64KB");
|
png_error(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);
|
||||||
|
26
pngtest.c
26
pngtest.c
@ -15,11 +15,12 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* defined so I can write to a file on gui/windowing platforms */
|
/* defined so I can write to a file on gui/windowing platforms */
|
||||||
#define STDERR stderr
|
/* #define STDERR stderr */
|
||||||
|
#define STDERR stdout /* for DOS */
|
||||||
|
|
||||||
/* input and output filenames */
|
/* input and output filenames */
|
||||||
char inname[] = "pngtest.png";
|
char inname[] = "pngtest.png";
|
||||||
char outname[] = "testout.png";
|
char outname[] = "pngout.png";
|
||||||
|
|
||||||
png_struct read_ptr;
|
png_struct read_ptr;
|
||||||
png_struct write_ptr;
|
png_struct write_ptr;
|
||||||
@ -31,12 +32,12 @@ char inbuf[256], outbuf[256];
|
|||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
FILE *fpin, *fpout;
|
FILE *fpin, *fpout;
|
||||||
png_byte *row_buf;
|
png_bytep row_buf;
|
||||||
png_uint_32 rowbytes;
|
png_uint_32 rowbytes;
|
||||||
png_uint_32 y;
|
png_uint_32 y;
|
||||||
int channels, num_pass, pass;
|
int channels, num_pass, pass;
|
||||||
|
|
||||||
row_buf = (png_byte *)0;
|
row_buf = (png_bytep )0;
|
||||||
|
|
||||||
fprintf(STDERR, "Testing libpng version %s\n", PNG_LIBPNG_VER_STRING);
|
fprintf(STDERR, "Testing libpng version %s\n", PNG_LIBPNG_VER_STRING);
|
||||||
|
|
||||||
@ -79,10 +80,10 @@ int main()
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
png_info_init(&info_ptr);
|
|
||||||
png_info_init(&end_info);
|
|
||||||
png_read_init(&read_ptr);
|
png_read_init(&read_ptr);
|
||||||
png_write_init(&write_ptr);
|
png_write_init(&write_ptr);
|
||||||
|
png_info_init(&info_ptr);
|
||||||
|
png_info_init(&end_info);
|
||||||
|
|
||||||
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,15 +98,12 @@ 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_bytep )malloc((size_t)rowbytes);
|
||||||
if (!row_buf)
|
if (!row_buf)
|
||||||
{
|
{
|
||||||
fprintf(STDERR, "no memory to allocate row buffer\n");
|
fprintf(STDERR, "no memory to allocate row buffer\n");
|
||||||
png_read_destroy(&read_ptr, &info_ptr, (png_info *)0);
|
png_read_destroy(&read_ptr, &info_ptr, (png_infop )0);
|
||||||
png_write_destroy(&write_ptr);
|
png_write_destroy(&write_ptr);
|
||||||
fclose(fpin);
|
fclose(fpin);
|
||||||
fclose(fpout);
|
fclose(fpout);
|
||||||
@ -126,8 +124,8 @@ int main()
|
|||||||
{
|
{
|
||||||
for (y = 0; y < info_ptr.height; y++)
|
for (y = 0; y < info_ptr.height; y++)
|
||||||
{
|
{
|
||||||
png_read_rows(&read_ptr, (png_bytef **)&row_buf, (png_bytef **)0, 1);
|
png_read_rows(&read_ptr, (png_bytepp )&row_buf, (png_bytepp )0, 1);
|
||||||
png_write_rows(&write_ptr, (png_bytef **)&row_buf, 1);
|
png_write_rows(&write_ptr, (png_bytepp )&row_buf, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,7 +138,7 @@ int main()
|
|||||||
fclose(fpin);
|
fclose(fpin);
|
||||||
fclose(fpout);
|
fclose(fpout);
|
||||||
|
|
||||||
free(row_buf);
|
free((void *)row_buf);
|
||||||
|
|
||||||
fpin = fopen(inname, "rb");
|
fpin = fopen(inname, "rb");
|
||||||
|
|
||||||
|
11
pngtodo.txt
11
pngtodo.txt
@ -1,18 +1,15 @@
|
|||||||
pngtodo.txt - list of things to do for libpng
|
pngtodo.txt - list of things to do for libpng
|
||||||
|
|
||||||
for 0.9
|
for 0.9
|
||||||
medium memory model
|
improved dithering
|
||||||
improved dithering?
|
final bug fixes
|
||||||
|
cHRM transformation
|
||||||
|
|
||||||
for 1.1
|
after 1.0
|
||||||
push reader
|
|
||||||
|
|
||||||
for 1.1 or later
|
|
||||||
overlaying one image on top of another
|
overlaying one image on top of another
|
||||||
optional palette creation
|
optional palette creation
|
||||||
histogram creation
|
histogram creation
|
||||||
text conversion between different code types
|
text conversion between different code types
|
||||||
cHRM transformation
|
|
||||||
support for other chunks being defined (sCAl, the gIF series,
|
support for other chunks being defined (sCAl, the gIF series,
|
||||||
and others that people come up with).
|
and others that people come up with).
|
||||||
pull writer
|
pull writer
|
||||||
|
40
pngtrans.c
40
pngtrans.c
@ -2,10 +2,10 @@
|
|||||||
/* pngtrans.c - transforms the data in a row
|
/* pngtrans.c - transforms the data in a row
|
||||||
routines used by both readers and writers
|
routines used by both readers and writers
|
||||||
|
|
||||||
libpng 1.0 beta 2 - version 0.81
|
libpng 1.0 beta 2 - version 0.85
|
||||||
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
|
December 19, 1995
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PNG_INTERNAL
|
#define PNG_INTERNAL
|
||||||
@ -14,7 +14,7 @@
|
|||||||
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
|
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
|
||||||
/* turn on bgr to rgb mapping */
|
/* turn on bgr to rgb mapping */
|
||||||
void
|
void
|
||||||
png_set_bgr(png_struct *png_ptr)
|
png_set_bgr(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
png_ptr->transformations |= PNG_BGR;
|
png_ptr->transformations |= PNG_BGR;
|
||||||
}
|
}
|
||||||
@ -23,7 +23,7 @@ png_set_bgr(png_struct *png_ptr)
|
|||||||
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
|
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
|
||||||
/* turn on 16 bit byte swapping */
|
/* turn on 16 bit byte swapping */
|
||||||
void
|
void
|
||||||
png_set_swap(png_struct *png_ptr)
|
png_set_swap(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
if (png_ptr->bit_depth == 16)
|
if (png_ptr->bit_depth == 16)
|
||||||
png_ptr->transformations |= PNG_SWAP_BYTES;
|
png_ptr->transformations |= PNG_SWAP_BYTES;
|
||||||
@ -33,7 +33,7 @@ png_set_swap(png_struct *png_ptr)
|
|||||||
#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
|
#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
|
||||||
/* turn on pixel packing */
|
/* turn on pixel packing */
|
||||||
void
|
void
|
||||||
png_set_packing(png_struct *png_ptr)
|
png_set_packing(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
if (png_ptr->bit_depth < 8)
|
if (png_ptr->bit_depth < 8)
|
||||||
{
|
{
|
||||||
@ -45,7 +45,7 @@ png_set_packing(png_struct *png_ptr)
|
|||||||
|
|
||||||
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
|
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_set_shift(png_struct *png_ptr, png_color_8 *true_bits)
|
png_set_shift(png_structp png_ptr, png_color_8p true_bits)
|
||||||
{
|
{
|
||||||
png_ptr->transformations |= PNG_SHIFT;
|
png_ptr->transformations |= PNG_SHIFT;
|
||||||
png_ptr->shift = *true_bits;
|
png_ptr->shift = *true_bits;
|
||||||
@ -54,7 +54,7 @@ png_set_shift(png_struct *png_ptr, png_color_8 *true_bits)
|
|||||||
|
|
||||||
#if defined(PNG_READ_INTERLACING_SUPPORTED) || defined(PNG_WRITE_INTERLACING_SUPPORTED)
|
#if defined(PNG_READ_INTERLACING_SUPPORTED) || defined(PNG_WRITE_INTERLACING_SUPPORTED)
|
||||||
int
|
int
|
||||||
png_set_interlace_handling(png_struct *png_ptr)
|
png_set_interlace_handling(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
if (png_ptr->interlaced)
|
if (png_ptr->interlaced)
|
||||||
{
|
{
|
||||||
@ -68,7 +68,7 @@ png_set_interlace_handling(png_struct *png_ptr)
|
|||||||
|
|
||||||
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
|
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_set_filler(png_struct *png_ptr, int filler, int filler_loc)
|
png_set_filler(png_structp png_ptr, int filler, int filler_loc)
|
||||||
{
|
{
|
||||||
png_ptr->transformations |= PNG_FILLER;
|
png_ptr->transformations |= PNG_FILLER;
|
||||||
png_ptr->filler = (png_byte)filler;
|
png_ptr->filler = (png_byte)filler;
|
||||||
@ -80,13 +80,13 @@ png_set_filler(png_struct *png_ptr, int filler, int filler_loc)
|
|||||||
|
|
||||||
/* old functions kept around for compatability purposes */
|
/* old functions kept around for compatability purposes */
|
||||||
void
|
void
|
||||||
png_set_rgbx(png_struct *png_ptr)
|
png_set_rgbx(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
|
png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
png_set_xrgb(png_struct *png_ptr)
|
png_set_xrgb(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE);
|
png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE);
|
||||||
}
|
}
|
||||||
@ -94,19 +94,19 @@ png_set_xrgb(png_struct *png_ptr)
|
|||||||
|
|
||||||
#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
|
#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
|
||||||
void
|
void
|
||||||
png_set_invert_mono(png_struct *png_ptr)
|
png_set_invert_mono(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
png_ptr->transformations |= PNG_INVERT_MONO;
|
png_ptr->transformations |= PNG_INVERT_MONO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* invert monocrome grayscale data */
|
/* invert monocrome grayscale data */
|
||||||
void
|
void
|
||||||
png_do_invert(png_row_info *row_info, png_bytef *row)
|
png_do_invert(png_row_infop row_info, png_bytep row)
|
||||||
{
|
{
|
||||||
if (row && row_info && row_info->bit_depth == 1 &&
|
if (row && row_info && row_info->bit_depth == 1 &&
|
||||||
row_info->color_type == PNG_COLOR_TYPE_GRAY)
|
row_info->color_type == PNG_COLOR_TYPE_GRAY)
|
||||||
{
|
{
|
||||||
png_bytef *rp;
|
png_bytep rp;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
|
|
||||||
for (i = 0, rp = row;
|
for (i = 0, rp = row;
|
||||||
@ -122,11 +122,11 @@ png_do_invert(png_row_info *row_info, png_bytef *row)
|
|||||||
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
|
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
|
||||||
/* swaps byte order on 16 bit depth images */
|
/* swaps byte order on 16 bit depth images */
|
||||||
void
|
void
|
||||||
png_do_swap(png_row_info *row_info, png_bytef *row)
|
png_do_swap(png_row_infop row_info, png_bytep row)
|
||||||
{
|
{
|
||||||
if (row && row_info && row_info->bit_depth == 16)
|
if (row && row_info && row_info->bit_depth == 16)
|
||||||
{
|
{
|
||||||
png_bytef *rp;
|
png_bytep rp;
|
||||||
png_byte t;
|
png_byte t;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
|
|
||||||
@ -145,13 +145,13 @@ png_do_swap(png_row_info *row_info, png_bytef *row)
|
|||||||
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
|
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
|
||||||
/* swaps red and blue */
|
/* swaps red and blue */
|
||||||
void
|
void
|
||||||
png_do_bgr(png_row_info *row_info, png_bytef *row)
|
png_do_bgr(png_row_infop row_info, png_bytep row)
|
||||||
{
|
{
|
||||||
if (row && row_info && (row_info->color_type & 2))
|
if (row && row_info && (row_info->color_type & 2))
|
||||||
{
|
{
|
||||||
if (row_info->color_type == 2 && row_info->bit_depth == 8)
|
if (row_info->color_type == 2 && row_info->bit_depth == 8)
|
||||||
{
|
{
|
||||||
png_bytef *rp;
|
png_bytep rp;
|
||||||
png_byte t;
|
png_byte t;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
|
|
||||||
@ -166,7 +166,7 @@ png_do_bgr(png_row_info *row_info, png_bytef *row)
|
|||||||
}
|
}
|
||||||
else if (row_info->color_type == 6 && row_info->bit_depth == 8)
|
else if (row_info->color_type == 6 && row_info->bit_depth == 8)
|
||||||
{
|
{
|
||||||
png_bytef *rp;
|
png_bytep rp;
|
||||||
png_byte t;
|
png_byte t;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ png_do_bgr(png_row_info *row_info, png_bytef *row)
|
|||||||
}
|
}
|
||||||
else if (row_info->color_type == 2 && row_info->bit_depth == 16)
|
else if (row_info->color_type == 2 && row_info->bit_depth == 16)
|
||||||
{
|
{
|
||||||
png_bytef *rp;
|
png_bytep rp;
|
||||||
png_byte t[2];
|
png_byte t[2];
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
|
|
||||||
@ -199,7 +199,7 @@ png_do_bgr(png_row_info *row_info, png_bytef *row)
|
|||||||
}
|
}
|
||||||
else if (row_info->color_type == 6 && row_info->bit_depth == 16)
|
else if (row_info->color_type == 6 && row_info->bit_depth == 16)
|
||||||
{
|
{
|
||||||
png_bytef *rp;
|
png_bytep rp;
|
||||||
png_byte t[2];
|
png_byte t[2];
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
|
|
||||||
|
240
pngwrite.c
240
pngwrite.c
@ -1,10 +1,10 @@
|
|||||||
|
|
||||||
/* pngwrite.c - general routines to write a png file
|
/* pngwrite.c - general routines to write a png file
|
||||||
|
|
||||||
libpng 1.0 beta 2 - version 0.81
|
libpng 1.0 beta 2 - version 0.85
|
||||||
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
|
December 19, 1995
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* get internal access to png.h */
|
/* get internal access to png.h */
|
||||||
@ -16,12 +16,12 @@
|
|||||||
write it, and put it in the correct location here. If you want
|
write it, and put it in the correct location here. If you want
|
||||||
the chunk written after the image data, put it in png_write_end().
|
the chunk written after the image data, put it in png_write_end().
|
||||||
I strongly encurage you to supply a PNG_INFO_ flag, and check
|
I strongly encurage you to supply a PNG_INFO_ flag, and check
|
||||||
info->valid before writing the chunk, as that will keep the code
|
info->valid before writing the chunk, as that will keep the code
|
||||||
from breaking if you want to just write a plain png file.
|
from breaking if you want to just write a plain png file.
|
||||||
If you have long comments, I suggest writing them in png_write_end(),
|
If you have long comments, I suggest writing them in png_write_end(),
|
||||||
and compressing them. */
|
and compressing them. */
|
||||||
void
|
void
|
||||||
png_write_info(png_struct *png_ptr, png_info *info)
|
png_write_info(png_structp png_ptr, png_infop info)
|
||||||
{
|
{
|
||||||
png_write_sig(png_ptr); /* write PNG signature */
|
png_write_sig(png_ptr); /* write PNG signature */
|
||||||
/* write IHDR information. */
|
/* write IHDR information. */
|
||||||
@ -57,30 +57,25 @@ 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)
|
||||||
{
|
{
|
||||||
@ -89,17 +84,11 @@ 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)
|
||||||
{
|
{
|
||||||
#if defined(PNG_WRITE_zTXt_SUPPORTED)
|
#if defined(PNG_WRITE_zTXt_SUPPORTED)
|
||||||
/* write compressed chunk */
|
/* write compressed chunk */
|
||||||
png_write_zTXt(png_ptr, info->text[i].key,
|
png_write_zTXt(png_ptr, info->text[i].key,
|
||||||
info->text[i].text, info->text[i].text_length,
|
info->text[i].text, info->text[i].text_length,
|
||||||
info->text[i].compression);
|
info->text[i].compression);
|
||||||
@ -110,13 +99,12 @@ png_write_info(png_struct *png_ptr, png_info *info)
|
|||||||
#if defined(PNG_WRITE_tEXt_SUPPORTED)
|
#if defined(PNG_WRITE_tEXt_SUPPORTED)
|
||||||
/* write uncompressed chunk */
|
/* write uncompressed chunk */
|
||||||
png_write_tEXt(png_ptr, info->text[i].key,
|
png_write_tEXt(png_ptr, info->text[i].key,
|
||||||
info->text[i].text, info->text[i].text_length);
|
info->text[i].text, info->text[i].text_length);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* PNG_WRITE_tEXt_SUPPORTED || PNG_WRITE_zTXt_SUPPORTED */
|
#endif
|
||||||
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
|
||||||
@ -124,11 +112,8 @@ png_write_info(png_struct *png_ptr, png_info *info)
|
|||||||
in png_write_info(), do not write them again here. If you have long
|
in png_write_info(), do not write them again here. If you have long
|
||||||
comments, I suggest writing them here, and compressing them. */
|
comments, I suggest writing them here, and compressing them. */
|
||||||
void
|
void
|
||||||
png_write_end(png_struct *png_ptr, png_info *info)
|
png_write_end(png_structp png_ptr, png_infop 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)
|
||||||
{
|
{
|
||||||
@ -137,7 +122,6 @@ 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)
|
||||||
@ -146,7 +130,7 @@ png_write_end(png_struct *png_ptr, png_info *info)
|
|||||||
|
|
||||||
/* loop through comment chunks */
|
/* loop through comment chunks */
|
||||||
for (i = 0; i < info->num_text; i++)
|
for (i = 0; i < info->num_text; i++)
|
||||||
{
|
{
|
||||||
/* check to see if comment is to be compressed */
|
/* check to see if comment is to be compressed */
|
||||||
if (info->text[i].compression >= 0)
|
if (info->text[i].compression >= 0)
|
||||||
{
|
{
|
||||||
@ -164,51 +148,59 @@ png_write_end(png_struct *png_ptr, png_info *info)
|
|||||||
png_write_tEXt(png_ptr, info->text[i].key,
|
png_write_tEXt(png_ptr, info->text[i].key,
|
||||||
info->text[i].text, info->text[i].text_length);
|
info->text[i].text, info->text[i].text_length);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* PNG_WRITE_tEXt_SUPPORTED || PNG_WRITE_zTXt_SUPPORTED */
|
#endif
|
||||||
}
|
}
|
||||||
/* 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)
|
||||||
void
|
void
|
||||||
png_convert_from_struct_tm(png_time *ptime, struct tm *ttime)
|
png_convert_from_struct_tm(png_timep ptime, struct tm FAR * ttime)
|
||||||
{
|
{
|
||||||
ptime->year = 1900 + ttime->tm_year;
|
ptime->year = 1900 + ttime->tm_year;
|
||||||
ptime->month = ttime->tm_mon + 1;
|
ptime->month = ttime->tm_mon + 1;
|
||||||
ptime->day = ttime->tm_mday;
|
ptime->day = ttime->tm_mday;
|
||||||
ptime->hour = ttime->tm_hour;
|
ptime->hour = ttime->tm_hour;
|
||||||
ptime->minute = ttime->tm_min;
|
ptime->minute = ttime->tm_min;
|
||||||
ptime->second = ttime->tm_sec;
|
ptime->second = ttime->tm_sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
png_convert_from_time_t(png_time *ptime, time_t ttime)
|
png_convert_from_time_t(png_timep ptime, time_t ttime)
|
||||||
{
|
{
|
||||||
struct tm *tbuf;
|
struct tm *tbuf;
|
||||||
|
|
||||||
tbuf = gmtime(&ttime);
|
tbuf = gmtime(&ttime);
|
||||||
png_convert_from_struct_tm(ptime, tbuf);
|
png_convert_from_struct_tm(ptime, tbuf);
|
||||||
}
|
}
|
||||||
#endif /* PNG_WRITE_tIME_SUPPORTED */
|
#endif
|
||||||
|
|
||||||
/* initialize png structure, and allocate any memory needed */
|
/* initialize png structure, and allocate any memory needed */
|
||||||
void
|
void
|
||||||
png_write_init(png_struct *png_ptr)
|
png_write_init(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
jmp_buf tmp_jmp; /* to save current jump buffer */
|
jmp_buf tmp_jmp; /* to save current jump buffer */
|
||||||
|
png_msg_ptr error_fn;
|
||||||
|
png_msg_ptr warning_fn;
|
||||||
|
png_voidp msg_ptr;
|
||||||
|
|
||||||
/* save jump buffer */
|
/* save jump buffer and error functions */
|
||||||
png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
|
png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
|
||||||
/* reset all variables to 0 */
|
error_fn = png_ptr->error_fn;
|
||||||
png_memset(png_ptr, 0, sizeof (png_struct));
|
warning_fn = png_ptr->warning_fn;
|
||||||
/* restore jump buffer */
|
msg_ptr = png_ptr->msg_ptr;
|
||||||
|
|
||||||
|
/* reset all variables to 0 */
|
||||||
|
png_memset(png_ptr, 0, sizeof (png_struct));
|
||||||
|
/* restore jump buffer and error functions */
|
||||||
png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
|
png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
|
||||||
|
png_ptr->error_fn = error_fn;
|
||||||
|
png_ptr->warning_fn = warning_fn;
|
||||||
|
png_ptr->msg_ptr = msg_ptr;
|
||||||
|
|
||||||
/* initialize zbuf - compression buffer */
|
/* initialize zbuf - compression buffer */
|
||||||
png_ptr->zbuf_size = PNG_ZBUF_SIZE;
|
png_ptr->zbuf_size = PNG_ZBUF_SIZE;
|
||||||
@ -218,13 +210,13 @@ png_write_init(png_struct *png_ptr)
|
|||||||
/* write a few rows of image data. If the image is interlaced,
|
/* write a few rows of image data. If the image is interlaced,
|
||||||
either you will have to write the 7 sub images, or, if you
|
either you will have to write the 7 sub images, or, if you
|
||||||
have called png_set_interlace_handling(), you will have to
|
have called png_set_interlace_handling(), you will have to
|
||||||
"write" the image seven times */
|
"write" the image seven times */
|
||||||
void
|
void
|
||||||
png_write_rows(png_struct *png_ptr, png_bytef **row,
|
png_write_rows(png_structp png_ptr, png_bytepp row,
|
||||||
png_uint_32 num_rows)
|
png_uint_32 num_rows)
|
||||||
{
|
{
|
||||||
png_uint_32 i; /* row counter */
|
png_uint_32 i; /* row counter */
|
||||||
png_bytef **rp; /* row pointer */
|
png_bytepp rp; /* row pointer */
|
||||||
|
|
||||||
/* loop through the rows */
|
/* loop through the rows */
|
||||||
for (i = 0, rp = row; i < num_rows; i++, rp++)
|
for (i = 0, rp = row; i < num_rows; i++, rp++)
|
||||||
@ -236,11 +228,11 @@ png_write_rows(png_struct *png_ptr, png_bytef **row,
|
|||||||
/* write the image. You only need to call this function once, even
|
/* write the image. You only need to call this function once, even
|
||||||
if you are writing an interlaced image. */
|
if you are writing an interlaced image. */
|
||||||
void
|
void
|
||||||
png_write_image(png_struct *png_ptr, png_bytef **image)
|
png_write_image(png_structp png_ptr, png_bytepp image)
|
||||||
{
|
{
|
||||||
png_uint_32 i; /* row index */
|
png_uint_32 i; /* row index */
|
||||||
int pass, num_pass; /* pass variables */
|
int pass, num_pass; /* pass variables */
|
||||||
png_bytef **rp; /* points to current row */
|
png_bytepp rp; /* points to current row */
|
||||||
|
|
||||||
/* intialize interlace handling. If image is not interlaced,
|
/* intialize interlace handling. If image is not interlaced,
|
||||||
this will set pass to 1 */
|
this will set pass to 1 */
|
||||||
@ -258,23 +250,21 @@ png_write_image(png_struct *png_ptr, png_bytef **image)
|
|||||||
|
|
||||||
/* write a row of image data */
|
/* write a row of image data */
|
||||||
void
|
void
|
||||||
png_write_row(png_struct *png_ptr, png_bytef *row)
|
png_write_row(png_structp png_ptr, png_bytep row)
|
||||||
{
|
{
|
||||||
/* initialize transformations and other stuff if first time */
|
/* initialize transformations and other stuff if first time */
|
||||||
if (png_ptr->mode < PNG_HAVE_IDAT)
|
if (png_ptr->row_number == 0 && png_ptr->pass == 0)
|
||||||
{
|
{
|
||||||
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))
|
||||||
{
|
{
|
||||||
switch (png_ptr->pass)
|
switch (png_ptr->pass)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
if (png_ptr->row_number & 7)
|
if (png_ptr->row_number & 7)
|
||||||
{
|
{
|
||||||
png_write_finish_row(png_ptr);
|
png_write_finish_row(png_ptr);
|
||||||
@ -292,7 +282,7 @@ png_write_row(png_struct *png_ptr, png_bytef *row)
|
|||||||
if ((png_ptr->row_number & 7) != 4)
|
if ((png_ptr->row_number & 7) != 4)
|
||||||
{
|
{
|
||||||
png_write_finish_row(png_ptr);
|
png_write_finish_row(png_ptr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
@ -310,7 +300,7 @@ png_write_row(png_struct *png_ptr, png_bytef *row)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
if ((png_ptr->row_number & 1) || png_ptr->width < 2)
|
if ((png_ptr->row_number & 1) || png_ptr->width < 2)
|
||||||
{
|
{
|
||||||
png_write_finish_row(png_ptr);
|
png_write_finish_row(png_ptr);
|
||||||
return;
|
return;
|
||||||
@ -325,10 +315,10 @@ png_write_row(png_struct *png_ptr, png_bytef *row)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* PNG_WRITE_INTERLACE_SUPPORTED */
|
#endif
|
||||||
|
|
||||||
/* 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;
|
||||||
png_ptr->row_info.width = png_ptr->usr_width;
|
png_ptr->row_info.width = png_ptr->usr_width;
|
||||||
png_ptr->row_info.channels = png_ptr->usr_channels;
|
png_ptr->row_info.channels = png_ptr->usr_channels;
|
||||||
png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth;
|
png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth;
|
||||||
@ -346,7 +336,7 @@ png_write_row(png_struct *png_ptr, png_bytef *row)
|
|||||||
(png_ptr->transformations & PNG_INTERLACE))
|
(png_ptr->transformations & PNG_INTERLACE))
|
||||||
{
|
{
|
||||||
png_do_write_interlace(&(png_ptr->row_info),
|
png_do_write_interlace(&(png_ptr->row_info),
|
||||||
png_ptr->row_buf + 1, png_ptr->pass);
|
png_ptr->row_buf + 1, png_ptr->pass);
|
||||||
/* this should always get caught above, but still ... */
|
/* this should always get caught above, but still ... */
|
||||||
if (!(png_ptr->row_info.width))
|
if (!(png_ptr->row_info.width))
|
||||||
{
|
{
|
||||||
@ -354,7 +344,7 @@ png_write_row(png_struct *png_ptr, png_bytef *row)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* PNG_WRITE_INTERLACE_SUPPORTED */
|
#endif
|
||||||
|
|
||||||
/* handle other transformations */
|
/* handle other transformations */
|
||||||
if (png_ptr->transformations)
|
if (png_ptr->transformations)
|
||||||
@ -364,7 +354,7 @@ png_write_row(png_struct *png_ptr, png_bytef *row)
|
|||||||
if (png_ptr->do_filter)
|
if (png_ptr->do_filter)
|
||||||
{
|
{
|
||||||
/* save row to previous row */
|
/* save row to previous row */
|
||||||
png_memcpy(png_ptr->save_row, png_ptr->row_buf,
|
png_memcpy(png_ptr->save_row, png_ptr->row_buf,
|
||||||
(png_size_t)png_ptr->row_info.rowbytes + 1);
|
(png_size_t)png_ptr->row_info.rowbytes + 1);
|
||||||
|
|
||||||
/* filter row */
|
/* filter row */
|
||||||
@ -373,7 +363,7 @@ png_write_row(png_struct *png_ptr, png_bytef *row)
|
|||||||
|
|
||||||
/* trade saved pointer and prev pointer so next row references are correctly */
|
/* trade saved pointer and prev pointer so next row references are correctly */
|
||||||
{ /* scope limiter */
|
{ /* scope limiter */
|
||||||
png_bytef *tptr;
|
png_bytep tptr;
|
||||||
|
|
||||||
tptr = png_ptr->prev_row;
|
tptr = png_ptr->prev_row;
|
||||||
png_ptr->prev_row = png_ptr->save_row;
|
png_ptr->prev_row = png_ptr->save_row;
|
||||||
@ -382,12 +372,11 @@ png_write_row(png_struct *png_ptr, png_bytef *row)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* set filter row to "none" */
|
/* set filter row to "none" */
|
||||||
png_ptr->row_buf[0] = 0;
|
png_ptr->row_buf[0] = 0;
|
||||||
|
|
||||||
/* 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
|
||||||
{
|
{
|
||||||
@ -399,9 +388,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_ptr->error_fn))(png_ptr, png_ptr->zstream->msg);
|
png_error(png_ptr, png_ptr->zstream->msg);
|
||||||
else
|
else
|
||||||
(*(png_ptr->error_fn))(png_ptr, "zlib error");
|
png_error(png_ptr, "zlib error");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* see if it is time to write another IDAT */
|
/* see if it is time to write another IDAT */
|
||||||
@ -415,17 +404,17 @@ png_write_row(png_struct *png_ptr, png_bytef *row)
|
|||||||
/* repeat until all data has been compressed */
|
/* repeat until all data has been compressed */
|
||||||
} while (png_ptr->zstream->avail_in);
|
} while (png_ptr->zstream->avail_in);
|
||||||
|
|
||||||
/* 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)
|
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
|
||||||
png_ptr->flush_rows++;
|
png_ptr->flush_rows++;
|
||||||
|
|
||||||
if (png_ptr->flush_dist > 0 &&
|
if (png_ptr->flush_dist > 0 &&
|
||||||
png_ptr->flush_rows >= png_ptr->flush_dist)
|
png_ptr->flush_rows >= png_ptr->flush_dist)
|
||||||
{
|
{
|
||||||
png_write_flush(png_ptr);
|
png_write_flush(png_ptr);
|
||||||
}
|
}
|
||||||
#endif /* PNG_WRITE_FLUSH_SUPPORTED */
|
#endif /* PNG_WRITE_FLUSH_SUPPORTED */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,68 +423,70 @@ png_write_row(png_struct *png_ptr, png_bytef *row)
|
|||||||
void
|
void
|
||||||
png_set_flush(png_struct *png_ptr, int nrows)
|
png_set_flush(png_struct *png_ptr, int nrows)
|
||||||
{
|
{
|
||||||
png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
|
png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* flush the current output buffers now */
|
/* flush the current output buffers now */
|
||||||
void
|
void
|
||||||
png_write_flush(png_struct *png_ptr)
|
png_write_flush(png_struct *png_ptr)
|
||||||
{
|
{
|
||||||
char wrote_IDAT;
|
int wrote_IDAT;
|
||||||
|
|
||||||
if (png_ptr->mode != PNG_HAVE_IDAT)
|
if (png_ptr->mode != PNG_HAVE_IDAT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* compress the data */
|
/* compress the data */
|
||||||
ret = deflate(png_ptr->zstream, Z_SYNC_FLUSH);
|
ret = deflate(png_ptr->zstream, Z_SYNC_FLUSH);
|
||||||
wrote_IDAT = 0;
|
wrote_IDAT = 0;
|
||||||
|
|
||||||
/* check for compression errors */
|
/* check for compression errors */
|
||||||
if (ret != Z_OK)
|
if (ret != Z_OK)
|
||||||
{
|
{
|
||||||
if (png_ptr->zstream->msg)
|
if (png_ptr->zstream->msg)
|
||||||
(*(png_ptr->error_fn))(png_ptr, png_ptr->zstream->msg);
|
png_error(png_ptr, png_ptr->zstream->msg);
|
||||||
else
|
else
|
||||||
(*(png_ptr->error_fn))(png_ptr, "zlib error");
|
png_error(png_ptr, "zlib error");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!png_ptr->zstream->avail_out)
|
if (!png_ptr->zstream->avail_out)
|
||||||
{
|
{
|
||||||
/* write the IDAT and reset the zlib output buffer */
|
/* write the IDAT and reset the zlib output buffer */
|
||||||
png_write_IDAT(png_ptr, png_ptr->zbuf,
|
png_write_IDAT(png_ptr, png_ptr->zbuf,
|
||||||
png_ptr->zbuf_size);
|
png_ptr->zbuf_size);
|
||||||
png_ptr->zstream->next_out = png_ptr->zbuf;
|
png_ptr->zstream->next_out = png_ptr->zbuf;
|
||||||
png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
|
png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
|
||||||
wrote_IDAT = 1;
|
wrote_IDAT = 1;
|
||||||
}
|
}
|
||||||
} while(wrote_IDAT == 1);
|
} while(wrote_IDAT == 1);
|
||||||
|
|
||||||
/* If there is any data left to be output, write it into a new IDAT */
|
/* 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)
|
if (png_ptr->zbuf_size != png_ptr->zstream->avail_out)
|
||||||
{
|
{
|
||||||
/* write the IDAT and reset the zlib output buffer */
|
/* write the IDAT and reset the zlib output buffer */
|
||||||
png_write_IDAT(png_ptr, png_ptr->zbuf,
|
png_write_IDAT(png_ptr, png_ptr->zbuf,
|
||||||
png_ptr->zbuf_size - png_ptr->zstream->avail_out);
|
png_ptr->zbuf_size - png_ptr->zstream->avail_out);
|
||||||
png_ptr->zstream->next_out = png_ptr->zbuf;
|
png_ptr->zstream->next_out = png_ptr->zbuf;
|
||||||
png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
|
png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
|
||||||
}
|
}
|
||||||
png_ptr->flush_rows = 0;
|
png_ptr->flush_rows = 0;
|
||||||
(*(png_ptr->output_flush_fn))(png_ptr);
|
png_flush(png_ptr);
|
||||||
}
|
}
|
||||||
#endif /* PNG_WRITE_FLUSH_SUPPORTED */
|
#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_structp png_ptr)
|
||||||
{
|
{
|
||||||
jmp_buf tmp_jmp; /* save jump buffer */
|
jmp_buf tmp_jmp; /* save jump buffer */
|
||||||
|
|
||||||
/* free any memory zlib uses */
|
/* free any memory zlib uses */
|
||||||
deflateEnd(png_ptr->zstream);
|
deflateEnd(png_ptr->zstream);
|
||||||
|
png_free(png_ptr, png_ptr->zstream);
|
||||||
/* free our memory. png_free checks NULL for us. */
|
/* free our memory. png_free checks NULL for us. */
|
||||||
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);
|
||||||
@ -506,44 +497,43 @@ 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_structp png_ptr, int filter)
|
||||||
{
|
{
|
||||||
png_ptr->do_custom_filter = 1;
|
png_ptr->do_custom_filter = 1;
|
||||||
png_ptr->do_filter = filter;
|
png_ptr->do_filter = filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
png_set_compression_level(png_struct *png_ptr, int level)
|
png_set_compression_level(png_structp png_ptr, int level)
|
||||||
{
|
{
|
||||||
png_ptr->zlib_custom_level = 1;
|
png_ptr->zlib_custom_level = 1;
|
||||||
png_ptr->zlib_level = level;
|
png_ptr->zlib_level = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
png_set_compression_mem_level(png_struct *png_ptr, int mem_level)
|
png_set_compression_mem_level(png_structp png_ptr, int mem_level)
|
||||||
{
|
{
|
||||||
png_ptr->zlib_custom_mem_level = 1;
|
png_ptr->zlib_custom_mem_level = 1;
|
||||||
png_ptr->zlib_mem_level = mem_level;
|
png_ptr->zlib_mem_level = mem_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
png_set_compression_strategy(png_struct *png_ptr, int strategy)
|
png_set_compression_strategy(png_structp png_ptr, int strategy)
|
||||||
{
|
{
|
||||||
png_ptr->zlib_custom_strategy = 1;
|
png_ptr->zlib_custom_strategy = 1;
|
||||||
png_ptr->zlib_strategy = strategy;
|
png_ptr->zlib_strategy = strategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
png_set_compression_window_bits(png_struct *png_ptr, int window_bits)
|
png_set_compression_window_bits(png_structp png_ptr, int window_bits)
|
||||||
{
|
{
|
||||||
png_ptr->zlib_custom_window_bits = 1;
|
png_ptr->zlib_custom_window_bits = 1;
|
||||||
png_ptr->zlib_window_bits = window_bits;
|
png_ptr->zlib_window_bits = window_bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
png_set_compression_method(png_struct *png_ptr, int method)
|
png_set_compression_method(png_structp png_ptr, int method)
|
||||||
{
|
{
|
||||||
png_ptr->zlib_custom_method = 1;
|
png_ptr->zlib_custom_method = 1;
|
||||||
png_ptr->zlib_method = method;
|
png_ptr->zlib_method = method;
|
||||||
|
45
pngwtran.c
45
pngwtran.c
@ -1,10 +1,10 @@
|
|||||||
|
|
||||||
/* pngwtran.c - transforms the data in a row for png writers
|
/* pngwtran.c - transforms the data in a row for png writers
|
||||||
|
|
||||||
libpng 1.0 beta 2 - version 0.81
|
libpng 1.0 beta 2 - version 0.85
|
||||||
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
|
December 19, 1995
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PNG_INTERNAL
|
#define PNG_INTERNAL
|
||||||
@ -13,10 +13,10 @@
|
|||||||
/* transform the data according to the users wishes. The order of
|
/* transform the data according to the users wishes. The order of
|
||||||
transformations is significant. */
|
transformations is significant. */
|
||||||
void
|
void
|
||||||
png_do_write_transformations(png_struct *png_ptr)
|
png_do_write_transformations(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
#if defined(PNG_WRITE_FILLER_SUPPORTED)
|
#if defined(PNG_WRITE_FILLER_SUPPORTED)
|
||||||
if (png_ptr->transformations & PNG_RGBA)
|
if (png_ptr->transformations & PNG_FILLER)
|
||||||
png_do_write_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
|
png_do_write_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
|
||||||
png_ptr->filler_loc);
|
png_ptr->filler_loc);
|
||||||
#endif
|
#endif
|
||||||
@ -49,7 +49,7 @@ png_do_write_transformations(png_struct *png_ptr)
|
|||||||
row_info bit depth should be 8 (one pixel per byte). The channels
|
row_info bit depth should be 8 (one pixel per byte). The channels
|
||||||
should be 1 (this only happens on grayscale and paletted images) */
|
should be 1 (this only happens on grayscale and paletted images) */
|
||||||
void
|
void
|
||||||
png_do_pack(png_row_info *row_info, png_bytef *row, png_byte bit_depth)
|
png_do_pack(png_row_infop row_info, png_bytep row, png_byte bit_depth)
|
||||||
{
|
{
|
||||||
if (row_info && row && row_info->bit_depth == 8 &&
|
if (row_info && row && row_info->bit_depth == 8 &&
|
||||||
row_info->channels == 1)
|
row_info->channels == 1)
|
||||||
@ -58,10 +58,10 @@ png_do_pack(png_row_info *row_info, png_bytef *row, png_byte bit_depth)
|
|||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
png_bytef *sp;
|
png_bytep sp;
|
||||||
png_bytef *dp;
|
png_bytep dp;
|
||||||
int mask;
|
int mask;
|
||||||
png_int_32 i;
|
png_int_32 i;
|
||||||
int v;
|
int v;
|
||||||
|
|
||||||
sp = row;
|
sp = row;
|
||||||
@ -79,7 +79,7 @@ png_do_pack(png_row_info *row_info, png_bytef *row, png_byte bit_depth)
|
|||||||
{
|
{
|
||||||
mask = 0x80;
|
mask = 0x80;
|
||||||
*dp = v;
|
*dp = v;
|
||||||
dp++;
|
dp++;
|
||||||
v = 0;
|
v = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,8 +89,8 @@ png_do_pack(png_row_info *row_info, png_bytef *row, png_byte bit_depth)
|
|||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
png_bytef *sp;
|
png_bytep sp;
|
||||||
png_bytef *dp;
|
png_bytep dp;
|
||||||
int shift;
|
int shift;
|
||||||
png_int_32 i;
|
png_int_32 i;
|
||||||
int v;
|
int v;
|
||||||
@ -121,8 +121,8 @@ png_do_pack(png_row_info *row_info, png_bytef *row, png_byte bit_depth)
|
|||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
{
|
{
|
||||||
png_bytef *sp;
|
png_bytep sp;
|
||||||
png_bytef *dp;
|
png_bytep dp;
|
||||||
int shift;
|
int shift;
|
||||||
png_int_32 i;
|
png_int_32 i;
|
||||||
int v;
|
int v;
|
||||||
@ -170,7 +170,7 @@ png_do_pack(png_row_info *row_info, png_bytef *row, png_byte bit_depth)
|
|||||||
would pass 3 as bit_depth, and this routine would translate the
|
would pass 3 as bit_depth, and this routine would translate the
|
||||||
data to 0 to 15. */
|
data to 0 to 15. */
|
||||||
void
|
void
|
||||||
png_do_shift(png_row_info *row_info, png_bytef *row, png_color_8 *bit_depth)
|
png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
|
||||||
{
|
{
|
||||||
if (row && row_info &&
|
if (row && row_info &&
|
||||||
row_info->color_type != PNG_COLOR_TYPE_PALETTE)
|
row_info->color_type != PNG_COLOR_TYPE_PALETTE)
|
||||||
@ -207,7 +207,7 @@ png_do_shift(png_row_info *row_info, png_bytef *row, png_color_8 *bit_depth)
|
|||||||
/* with low row dephts, could only be grayscale, so one channel */
|
/* with low row dephts, could only be grayscale, so one channel */
|
||||||
if (row_info->bit_depth < 8)
|
if (row_info->bit_depth < 8)
|
||||||
{
|
{
|
||||||
png_bytef *bp;
|
png_bytep bp;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
int j;
|
int j;
|
||||||
png_byte mask;
|
png_byte mask;
|
||||||
@ -236,7 +236,7 @@ png_do_shift(png_row_info *row_info, png_bytef *row, png_color_8 *bit_depth)
|
|||||||
}
|
}
|
||||||
else if (row_info->bit_depth == 8)
|
else if (row_info->bit_depth == 8)
|
||||||
{
|
{
|
||||||
png_bytef *bp;
|
png_bytep bp;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
@ -262,7 +262,7 @@ png_do_shift(png_row_info *row_info, png_bytef *row, png_color_8 *bit_depth)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
png_bytef *bp;
|
png_bytep bp;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
@ -297,7 +297,7 @@ png_do_shift(png_row_info *row_info, png_bytef *row, png_color_8 *bit_depth)
|
|||||||
#ifdef PNG_WRITE_FILLER_SUPPORTED
|
#ifdef PNG_WRITE_FILLER_SUPPORTED
|
||||||
/* remove filler byte */
|
/* remove filler byte */
|
||||||
void
|
void
|
||||||
png_do_write_filler(png_row_info *row_info, png_bytef *row,
|
png_do_write_filler(png_row_infop row_info, png_bytep row,
|
||||||
png_byte filler_loc)
|
png_byte filler_loc)
|
||||||
{
|
{
|
||||||
if (row && row_info && row_info->color_type == PNG_COLOR_TYPE_RGB &&
|
if (row && row_info && row_info->color_type == PNG_COLOR_TYPE_RGB &&
|
||||||
@ -305,7 +305,8 @@ png_do_write_filler(png_row_info *row_info, png_bytef *row,
|
|||||||
{
|
{
|
||||||
if (filler_loc == PNG_FILLER_AFTER)
|
if (filler_loc == PNG_FILLER_AFTER)
|
||||||
{
|
{
|
||||||
png_bytef *sp, *dp;
|
png_bytep sp, dp;
|
||||||
|
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
|
|
||||||
for (i = 1, sp = row + 4, dp = row + 3;
|
for (i = 1, sp = row + 4, dp = row + 3;
|
||||||
@ -323,10 +324,10 @@ png_do_write_filler(png_row_info *row_info, png_bytef *row,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
png_bytef *sp, *dp;
|
png_bytep sp, dp;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
|
|
||||||
for (i = 1, sp = row + 4, dp = row + 3;
|
for (i = 0, sp = row, dp = row;
|
||||||
i < row_info->width;
|
i < row_info->width;
|
||||||
i++)
|
i++)
|
||||||
{
|
{
|
||||||
|
237
pngwutil.c
237
pngwutil.c
@ -1,10 +1,10 @@
|
|||||||
|
|
||||||
/* pngwutil.c - utilities to write a png file
|
/* pngwutil.c - utilities to write a png file
|
||||||
|
|
||||||
libpng 1.0 beta 2 - version 0.81
|
libpng 1.0 beta 2 - version 0.85
|
||||||
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
|
December 19, 1995
|
||||||
*/
|
*/
|
||||||
#define PNG_INTERNAL
|
#define PNG_INTERNAL
|
||||||
#include "png.h"
|
#include "png.h"
|
||||||
@ -13,7 +13,7 @@
|
|||||||
with unsigned numbers for convenience, you may have to cast
|
with unsigned numbers for convenience, you may have to cast
|
||||||
signed numbers (if you use any, most png data is unsigned). */
|
signed numbers (if you use any, most png data is unsigned). */
|
||||||
void
|
void
|
||||||
png_save_uint_32(png_byte *buf, png_uint_32 i)
|
png_save_uint_32(png_bytep buf, png_uint_32 i)
|
||||||
{
|
{
|
||||||
buf[0] = (png_byte)((i >> 24) & 0xff);
|
buf[0] = (png_byte)((i >> 24) & 0xff);
|
||||||
buf[1] = (png_byte)((i >> 16) & 0xff);
|
buf[1] = (png_byte)((i >> 16) & 0xff);
|
||||||
@ -23,7 +23,7 @@ png_save_uint_32(png_byte *buf, png_uint_32 i)
|
|||||||
|
|
||||||
/* place a 16 bit number into a buffer in png byte order */
|
/* place a 16 bit number into a buffer in png byte order */
|
||||||
void
|
void
|
||||||
png_save_uint_16(png_byte *buf, png_uint_16 i)
|
png_save_uint_16(png_bytep buf, 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);
|
||||||
@ -31,7 +31,7 @@ png_save_uint_16(png_byte *buf, png_uint_16 i)
|
|||||||
|
|
||||||
/* write a 32 bit number */
|
/* write a 32 bit number */
|
||||||
void
|
void
|
||||||
png_write_uint_32(png_struct *png_ptr, png_uint_32 i)
|
png_write_uint_32(png_structp png_ptr, png_uint_32 i)
|
||||||
{
|
{
|
||||||
png_byte buf[4];
|
png_byte buf[4];
|
||||||
|
|
||||||
@ -39,18 +39,18 @@ 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_ptr->write_data_fn))(png_ptr, buf, 4);
|
png_write_data(png_ptr, buf, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write a 16 bit number */
|
/* write a 16 bit number */
|
||||||
void
|
void
|
||||||
png_write_uint_16(png_struct *png_ptr, png_uint_16 i)
|
png_write_uint_16(png_structp png_ptr, png_uint_16 i)
|
||||||
{
|
{
|
||||||
png_byte buf[2];
|
png_byte buf[2];
|
||||||
|
|
||||||
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_ptr->write_data_fn))(png_ptr, buf, 2);
|
png_write_data(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
|
||||||
@ -62,13 +62,13 @@ png_write_uint_16(png_struct *png_ptr, png_uint_16 i)
|
|||||||
png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
|
png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
|
||||||
functions instead. */
|
functions instead. */
|
||||||
void
|
void
|
||||||
png_write_chunk(png_struct *png_ptr, png_byte *type,
|
png_write_chunk(png_structp png_ptr, png_bytep type,
|
||||||
png_bytef *data, png_uint_32 length)
|
png_bytep data, png_uint_32 length)
|
||||||
{
|
{
|
||||||
/* 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_ptr->write_data_fn))(png_ptr, type, (png_uint_32)4);
|
png_write_data(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_ptr->write_data_fn))(png_ptr, data, length);
|
png_write_data(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);
|
||||||
@ -86,13 +86,13 @@ png_write_chunk(png_struct *png_ptr, png_byte *type,
|
|||||||
The total_length is the sum of the lengths of all the data you will be
|
The total_length is the sum of the lengths of all the data you will be
|
||||||
passing in png_write_chunk_data() */
|
passing in png_write_chunk_data() */
|
||||||
void
|
void
|
||||||
png_write_chunk_start(png_struct *png_ptr, png_byte *type,
|
png_write_chunk_start(png_structp png_ptr, png_bytep type,
|
||||||
png_uint_32 total_length)
|
png_uint_32 total_length)
|
||||||
{
|
{
|
||||||
/* 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_ptr->write_data_fn))(png_ptr, type, (png_uint_32)4);
|
png_write_data(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);
|
||||||
@ -103,19 +103,19 @@ png_write_chunk_start(png_struct *png_ptr, png_byte *type,
|
|||||||
sum of the lengths from these calls *must* add up to the total_length
|
sum of the lengths from these calls *must* add up to the total_length
|
||||||
given to png_write_chunk_start() */
|
given to png_write_chunk_start() */
|
||||||
void
|
void
|
||||||
png_write_chunk_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length)
|
png_write_chunk_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
|
||||||
{
|
{
|
||||||
/* write the data, and run the crc over it */
|
/* write the data, and run the crc over it */
|
||||||
if (length)
|
if (length)
|
||||||
{
|
{
|
||||||
png_calculate_crc(png_ptr, data, length);
|
png_calculate_crc(png_ptr, data, length);
|
||||||
(*(png_ptr->write_data_fn))(png_ptr, data, length);
|
png_write_data(png_ptr, data, length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* finish a chunk started with png_write_chunk_start() */
|
/* finish a chunk started with png_write_chunk_start() */
|
||||||
void
|
void
|
||||||
png_write_chunk_end(png_struct *png_ptr)
|
png_write_chunk_end(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
/* write the crc */
|
/* write the crc */
|
||||||
png_write_uint_32(png_ptr, ~png_ptr->crc);
|
png_write_uint_32(png_ptr, ~png_ptr->crc);
|
||||||
@ -123,17 +123,17 @@ png_write_chunk_end(png_struct *png_ptr)
|
|||||||
|
|
||||||
/* simple function to write the signature */
|
/* simple function to write the signature */
|
||||||
void
|
void
|
||||||
png_write_sig(png_struct *png_ptr)
|
png_write_sig(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
/* write the 8 byte signature */
|
/* write the 8 byte signature */
|
||||||
(*(png_ptr->write_data_fn))(png_ptr, png_sig, (png_uint_32)8);
|
png_write_data(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
|
||||||
information. Note that the rest of this code depends upon this
|
information. Note that the rest of this code depends upon this
|
||||||
information being correct. */
|
information being correct. */
|
||||||
void
|
void
|
||||||
png_write_IHDR(png_struct *png_ptr, png_uint_32 width, png_uint_32 height,
|
png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
|
||||||
int bit_depth, int color_type, int compression_type, int filter_type,
|
int bit_depth, int color_type, int compression_type, int filter_type,
|
||||||
int interlace_type)
|
int interlace_type)
|
||||||
{
|
{
|
||||||
@ -175,13 +175,13 @@ png_write_IHDR(png_struct *png_ptr, png_uint_32 width, png_uint_32 height,
|
|||||||
/* set the usr info, so any transformations can modify it */
|
/* set the usr info, so any transformations can modify it */
|
||||||
png_ptr->usr_width = png_ptr->width;
|
png_ptr->usr_width = png_ptr->width;
|
||||||
png_ptr->usr_bit_depth = png_ptr->bit_depth;
|
png_ptr->usr_bit_depth = png_ptr->bit_depth;
|
||||||
png_ptr->usr_channels = png_ptr->channels;
|
png_ptr->usr_channels = png_ptr->channels;
|
||||||
|
|
||||||
/* write the chunk */
|
/* write the chunk */
|
||||||
png_write_chunk(png_ptr, png_IHDR, buf, (png_uint_32)13);
|
png_write_chunk(png_ptr, png_IHDR, buf, (png_uint_32)13);
|
||||||
|
|
||||||
/* initialize zlib with png info */
|
/* initialize zlib with png info */
|
||||||
png_ptr->zstream = &(png_ptr->zstream_struct);
|
png_ptr->zstream = (z_stream *)png_malloc(png_ptr, sizeof (z_stream));
|
||||||
png_ptr->zstream->zalloc = png_zalloc;
|
png_ptr->zstream->zalloc = png_zalloc;
|
||||||
png_ptr->zstream->zfree = png_zfree;
|
png_ptr->zstream->zfree = png_zfree;
|
||||||
png_ptr->zstream->opaque = (voidp)png_ptr;
|
png_ptr->zstream->opaque = (voidp)png_ptr;
|
||||||
@ -221,10 +221,10 @@ png_write_IHDR(png_struct *png_ptr, png_uint_32 width, png_uint_32 height,
|
|||||||
correct order for PNG, so people can redefine it to any convient
|
correct order for PNG, so people can redefine it to any convient
|
||||||
structure. */
|
structure. */
|
||||||
void
|
void
|
||||||
png_write_PLTE(png_struct *png_ptr, png_color *palette, int number)
|
png_write_PLTE(png_structp png_ptr, png_colorp palette, int number)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
png_color *pal_ptr;
|
png_colorp pal_ptr;
|
||||||
png_byte buf[3];
|
png_byte buf[3];
|
||||||
|
|
||||||
png_write_chunk_start(png_ptr, png_PLTE, number * 3);
|
png_write_chunk_start(png_ptr, png_PLTE, number * 3);
|
||||||
@ -242,14 +242,14 @@ png_write_PLTE(png_struct *png_ptr, png_color *palette, int number)
|
|||||||
|
|
||||||
/* write an IDAT chunk */
|
/* write an IDAT chunk */
|
||||||
void
|
void
|
||||||
png_write_IDAT(png_struct *png_ptr, png_bytef *data, png_uint_32 length)
|
png_write_IDAT(png_structp png_ptr, png_bytep data, png_uint_32 length)
|
||||||
{
|
{
|
||||||
png_write_chunk(png_ptr, png_IDAT, data, length);
|
png_write_chunk(png_ptr, png_IDAT, data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write an IEND chunk */
|
/* write an IEND chunk */
|
||||||
void
|
void
|
||||||
png_write_IEND(png_struct *png_ptr)
|
png_write_IEND(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
png_write_chunk(png_ptr, png_IEND, NULL, (png_uint_32)0);
|
png_write_chunk(png_ptr, png_IEND, NULL, (png_uint_32)0);
|
||||||
}
|
}
|
||||||
@ -257,7 +257,7 @@ png_write_IEND(png_struct *png_ptr)
|
|||||||
#if defined(PNG_WRITE_gAMA_SUPPORTED)
|
#if defined(PNG_WRITE_gAMA_SUPPORTED)
|
||||||
/* write a gAMA chunk */
|
/* write a gAMA chunk */
|
||||||
void
|
void
|
||||||
png_write_gAMA(png_struct *png_ptr, float gamma)
|
png_write_gAMA(png_structp png_ptr, double gamma)
|
||||||
{
|
{
|
||||||
png_uint_32 igamma;
|
png_uint_32 igamma;
|
||||||
png_byte buf[4];
|
png_byte buf[4];
|
||||||
@ -272,12 +272,12 @@ png_write_gAMA(png_struct *png_ptr, float gamma)
|
|||||||
#if defined(PNG_WRITE_sBIT_SUPPORTED)
|
#if defined(PNG_WRITE_sBIT_SUPPORTED)
|
||||||
/* write the sBIT chunk */
|
/* write the sBIT chunk */
|
||||||
void
|
void
|
||||||
png_write_sBIT(png_struct *png_ptr, png_color_8 *sbit, int color_type)
|
png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type)
|
||||||
{
|
{
|
||||||
png_byte buf[4];
|
png_byte buf[4];
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
/* make sure we don't depend upon the order of png_color_8 */
|
/* make sure we don't depend upon the order of PNG_COLOR_8 */
|
||||||
if (color_type & PNG_COLOR_MASK_COLOR)
|
if (color_type & PNG_COLOR_MASK_COLOR)
|
||||||
{
|
{
|
||||||
buf[0] = sbit->red;
|
buf[0] = sbit->red;
|
||||||
@ -303,9 +303,9 @@ png_write_sBIT(png_struct *png_ptr, png_color_8 *sbit, int color_type)
|
|||||||
#if defined(PNG_WRITE_cHRM_SUPPORTED)
|
#if defined(PNG_WRITE_cHRM_SUPPORTED)
|
||||||
/* write the cHRM chunk */
|
/* write the cHRM chunk */
|
||||||
void
|
void
|
||||||
png_write_cHRM(png_struct *png_ptr, float white_x, float white_y,
|
png_write_cHRM ( png_structp png_ptr, double white_x, double white_y,
|
||||||
float red_x, float red_y, float green_x, float green_y,
|
double red_x, double red_y, double green_x, double green_y,
|
||||||
float blue_x, float blue_y)
|
double blue_x, double blue_y)
|
||||||
{
|
{
|
||||||
png_uint_32 itemp;
|
png_uint_32 itemp;
|
||||||
png_byte buf[32];
|
png_byte buf[32];
|
||||||
@ -334,7 +334,7 @@ png_write_cHRM(png_struct *png_ptr, float white_x, float white_y,
|
|||||||
#if defined(PNG_WRITE_tRNS_SUPPORTED)
|
#if defined(PNG_WRITE_tRNS_SUPPORTED)
|
||||||
/* write the tRNS chunk */
|
/* write the tRNS chunk */
|
||||||
void
|
void
|
||||||
png_write_tRNS(png_struct *png_ptr, png_byte *trans, png_color_16 *tran,
|
png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran,
|
||||||
int num_trans, int color_type)
|
int num_trans, int color_type)
|
||||||
{
|
{
|
||||||
png_byte buf[6];
|
png_byte buf[6];
|
||||||
@ -364,7 +364,7 @@ png_write_tRNS(png_struct *png_ptr, png_byte *trans, png_color_16 *tran,
|
|||||||
#if defined(PNG_WRITE_bKGD_SUPPORTED)
|
#if defined(PNG_WRITE_bKGD_SUPPORTED)
|
||||||
/* write the background chunk */
|
/* write the background chunk */
|
||||||
void
|
void
|
||||||
png_write_bKGD(png_struct *png_ptr, png_color_16 *back, int color_type)
|
png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type)
|
||||||
{
|
{
|
||||||
png_byte buf[6];
|
png_byte buf[6];
|
||||||
|
|
||||||
@ -381,7 +381,7 @@ png_write_bKGD(png_struct *png_ptr, png_color_16 *back, int color_type)
|
|||||||
png_write_chunk(png_ptr, png_bKGD, buf, (png_uint_32)6);
|
png_write_chunk(png_ptr, png_bKGD, buf, (png_uint_32)6);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
png_save_uint_16(buf, back->gray);
|
png_save_uint_16(buf, back->gray);
|
||||||
png_write_chunk(png_ptr, png_bKGD, buf, (png_uint_32)2);
|
png_write_chunk(png_ptr, png_bKGD, buf, (png_uint_32)2);
|
||||||
}
|
}
|
||||||
@ -391,7 +391,7 @@ png_write_bKGD(png_struct *png_ptr, png_color_16 *back, int color_type)
|
|||||||
#if defined(PNG_WRITE_hIST_SUPPORTED)
|
#if defined(PNG_WRITE_hIST_SUPPORTED)
|
||||||
/* write the histogram */
|
/* write the histogram */
|
||||||
void
|
void
|
||||||
png_write_hIST(png_struct *png_ptr, png_uint_16 *hist, int number)
|
png_write_hIST(png_structp png_ptr, png_uint_16p hist, int number)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
png_byte buf[3];
|
png_byte buf[3];
|
||||||
@ -399,7 +399,7 @@ png_write_hIST(png_struct *png_ptr, png_uint_16 *hist, int number)
|
|||||||
png_write_chunk_start(png_ptr, png_hIST, (png_uint_32)(number * 2));
|
png_write_chunk_start(png_ptr, png_hIST, (png_uint_32)(number * 2));
|
||||||
for (i = 0; i < number; i++)
|
for (i = 0; i < number; i++)
|
||||||
{
|
{
|
||||||
png_save_uint_16(buf, hist[i]);
|
png_save_uint_16(buf, hist[i]);
|
||||||
png_write_chunk_data(png_ptr, buf, (png_uint_32)2);
|
png_write_chunk_data(png_ptr, buf, (png_uint_32)2);
|
||||||
}
|
}
|
||||||
png_write_chunk_end(png_ptr);
|
png_write_chunk_end(png_ptr);
|
||||||
@ -409,7 +409,7 @@ png_write_hIST(png_struct *png_ptr, png_uint_16 *hist, int number)
|
|||||||
#if defined(PNG_WRITE_tEXt_SUPPORTED)
|
#if defined(PNG_WRITE_tEXt_SUPPORTED)
|
||||||
/* write a tEXt chunk */
|
/* write a tEXt chunk */
|
||||||
void
|
void
|
||||||
png_write_tEXt(png_struct *png_ptr, charf *key, charf *text,
|
png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text,
|
||||||
png_uint_32 text_len)
|
png_uint_32 text_len)
|
||||||
{
|
{
|
||||||
int key_len;
|
int key_len;
|
||||||
@ -417,11 +417,11 @@ png_write_tEXt(png_struct *png_ptr, charf *key, charf *text,
|
|||||||
key_len = png_strlen(key);
|
key_len = png_strlen(key);
|
||||||
/* make sure we count the 0 after the key */
|
/* make sure we count the 0 after the key */
|
||||||
png_write_chunk_start(png_ptr, png_tEXt,
|
png_write_chunk_start(png_ptr, png_tEXt,
|
||||||
(png_uint_32)(key_len + text_len + 1));
|
(png_uint_32)(key_len + text_len + 1));
|
||||||
/* key has an 0 at the end. How nice */
|
/* key has an 0 at the end. How nice */
|
||||||
png_write_chunk_data(png_ptr, (png_bytef *)key, (png_uint_32)(key_len + 1));
|
png_write_chunk_data(png_ptr, (png_bytep )key, (png_uint_32)(key_len + 1));
|
||||||
if (text && text_len)
|
if (text && text_len)
|
||||||
png_write_chunk_data(png_ptr, (png_bytef *)text, (png_uint_32)text_len);
|
png_write_chunk_data(png_ptr, (png_bytep )text, (png_uint_32)text_len);
|
||||||
png_write_chunk_end(png_ptr);
|
png_write_chunk_end(png_ptr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -429,13 +429,13 @@ png_write_tEXt(png_struct *png_ptr, charf *key, charf *text,
|
|||||||
#if defined(PNG_WRITE_zTXt_SUPPORTED)
|
#if defined(PNG_WRITE_zTXt_SUPPORTED)
|
||||||
/* write a compressed chunk */
|
/* write a compressed chunk */
|
||||||
void
|
void
|
||||||
png_write_zTXt(png_struct *png_ptr, charf *key, charf *text,
|
png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text,
|
||||||
png_uint_32 text_len, int compression)
|
png_uint_32 text_len, int compression)
|
||||||
{
|
{
|
||||||
int key_len;
|
int key_len;
|
||||||
char buf[1];
|
char buf[1];
|
||||||
int i, ret;
|
int i, ret;
|
||||||
charf **output_ptr = NULL; /* array of pointers to output */
|
png_charpp output_ptr = NULL; /* array of pointers to output */
|
||||||
int num_output_ptr = 0; /* number of output pointers used */
|
int num_output_ptr = 0; /* number of output pointers used */
|
||||||
int max_output_ptr = 0; /* size of output_ptr */
|
int max_output_ptr = 0; /* size of output_ptr */
|
||||||
|
|
||||||
@ -453,36 +453,36 @@ png_write_zTXt(png_struct *png_ptr, charf *key, charf *text,
|
|||||||
png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
|
png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
|
||||||
png_ptr->zstream->next_out = (Bytef *)png_ptr->zbuf;
|
png_ptr->zstream->next_out = (Bytef *)png_ptr->zbuf;
|
||||||
|
|
||||||
/* this is the same compression loop as in png_write_row() */
|
/* this is the same compression loop as in png_write_row() */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
/* compress the data */
|
/* compress the data */
|
||||||
ret = deflate(png_ptr->zstream, Z_NO_FLUSH);
|
ret = deflate(png_ptr->zstream, Z_NO_FLUSH);
|
||||||
if (ret != Z_OK)
|
if (ret != Z_OK)
|
||||||
{
|
{
|
||||||
/* error */
|
/* error */
|
||||||
if (png_ptr->zstream->msg)
|
if (png_ptr->zstream->msg)
|
||||||
(*(png_ptr->error_fn))(png_ptr, png_ptr->zstream->msg);
|
png_error(png_ptr, png_ptr->zstream->msg);
|
||||||
else
|
else
|
||||||
(*(png_ptr->error_fn))(png_ptr, "zlib error");
|
png_error(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)
|
||||||
{
|
{
|
||||||
/* make sure the output array has room */
|
/* make sure the output array has room */
|
||||||
if (num_output_ptr >= max_output_ptr)
|
if (num_output_ptr >= max_output_ptr)
|
||||||
{
|
{
|
||||||
png_uint_32 old_max;
|
png_uint_32 old_max;
|
||||||
|
|
||||||
old_max = max_output_ptr;
|
old_max = max_output_ptr;
|
||||||
max_output_ptr = num_output_ptr + 4;
|
max_output_ptr = num_output_ptr + 4;
|
||||||
if (output_ptr)
|
if (output_ptr)
|
||||||
output_ptr = png_realloc(png_ptr, output_ptr,
|
output_ptr = (png_charpp)png_realloc(png_ptr, output_ptr,
|
||||||
max_output_ptr * sizeof (char *),
|
max_output_ptr * sizeof (png_charpp),
|
||||||
old_max * sizeof (char *));
|
old_max * sizeof (png_charp));
|
||||||
else
|
else
|
||||||
output_ptr = png_malloc(png_ptr,
|
output_ptr = (png_charpp)png_malloc(png_ptr,
|
||||||
max_output_ptr * sizeof (char *));
|
max_output_ptr * sizeof (png_charp));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* save the data */
|
/* save the data */
|
||||||
@ -499,43 +499,43 @@ png_write_zTXt(png_struct *png_ptr, charf *key, charf *text,
|
|||||||
/* continue until we don't have anymore to compress */
|
/* continue until we don't have anymore to compress */
|
||||||
} while (png_ptr->zstream->avail_in);
|
} while (png_ptr->zstream->avail_in);
|
||||||
|
|
||||||
/* finish the compression */
|
/* finish the compression */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
/* tell zlib we are finished */
|
/* tell zlib we are finished */
|
||||||
ret = deflate(png_ptr->zstream, Z_FINISH);
|
ret = deflate(png_ptr->zstream, Z_FINISH);
|
||||||
if (ret != Z_OK && ret != Z_STREAM_END)
|
if (ret != Z_OK && ret != Z_STREAM_END)
|
||||||
{
|
{
|
||||||
/* we got an error */
|
/* we got an error */
|
||||||
if (png_ptr->zstream->msg)
|
if (png_ptr->zstream->msg)
|
||||||
(*(png_ptr->error_fn))(png_ptr, png_ptr->zstream->msg);
|
png_error(png_ptr, png_ptr->zstream->msg);
|
||||||
else
|
else
|
||||||
(*(png_ptr->error_fn))(png_ptr, "zlib error");
|
png_error(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)
|
||||||
{
|
{
|
||||||
/* check to make sure our output array has room */
|
/* check to make sure our output array has room */
|
||||||
if (num_output_ptr >= max_output_ptr)
|
if (num_output_ptr >= max_output_ptr)
|
||||||
{
|
{
|
||||||
png_uint_32 old_max;
|
png_uint_32 old_max;
|
||||||
|
|
||||||
old_max = max_output_ptr;
|
old_max = max_output_ptr;
|
||||||
max_output_ptr = num_output_ptr + 4;
|
max_output_ptr = num_output_ptr + 4;
|
||||||
if (output_ptr)
|
if (output_ptr)
|
||||||
output_ptr = png_realloc(png_ptr, output_ptr,
|
output_ptr = (png_charpp)png_realloc(png_ptr, output_ptr,
|
||||||
max_output_ptr * sizeof (char *),
|
max_output_ptr * sizeof (png_charp),
|
||||||
old_max * sizeof (char *));
|
old_max * sizeof (png_charp));
|
||||||
else
|
else
|
||||||
output_ptr = png_malloc(png_ptr,
|
output_ptr = (png_charpp)png_malloc(png_ptr,
|
||||||
max_output_ptr * sizeof (char *));
|
max_output_ptr * sizeof (png_charp));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* save off the data */
|
/* save off the data */
|
||||||
output_ptr[num_output_ptr] = png_large_malloc(png_ptr,
|
output_ptr[num_output_ptr] = png_large_malloc(png_ptr,
|
||||||
png_ptr->zbuf_size);
|
png_ptr->zbuf_size);
|
||||||
png_memcpy(output_ptr[num_output_ptr], png_ptr->zbuf,
|
png_memcpy(output_ptr[num_output_ptr], png_ptr->zbuf,
|
||||||
(png_size_t)png_ptr->zbuf_size);
|
(png_size_t)png_ptr->zbuf_size);
|
||||||
num_output_ptr++;
|
num_output_ptr++;
|
||||||
|
|
||||||
@ -546,7 +546,7 @@ png_write_zTXt(png_struct *png_ptr, charf *key, charf *text,
|
|||||||
} while (ret != Z_STREAM_END);
|
} while (ret != Z_STREAM_END);
|
||||||
|
|
||||||
/* text length is number of buffers plus last buffer */
|
/* text length is number of buffers plus last buffer */
|
||||||
text_len = png_ptr->zbuf_size * num_output_ptr;
|
text_len = png_ptr->zbuf_size * num_output_ptr;
|
||||||
if (png_ptr->zstream->avail_out < png_ptr->zbuf_size)
|
if (png_ptr->zstream->avail_out < png_ptr->zbuf_size)
|
||||||
text_len += (png_uint_32)(png_ptr->zbuf_size -
|
text_len += (png_uint_32)(png_ptr->zbuf_size -
|
||||||
png_ptr->zstream->avail_out);
|
png_ptr->zstream->avail_out);
|
||||||
@ -555,16 +555,16 @@ png_write_zTXt(png_struct *png_ptr, charf *key, charf *text,
|
|||||||
png_write_chunk_start(png_ptr, png_zTXt,
|
png_write_chunk_start(png_ptr, png_zTXt,
|
||||||
(png_uint_32)(key_len + text_len + 2));
|
(png_uint_32)(key_len + text_len + 2));
|
||||||
/* write key */
|
/* write key */
|
||||||
png_write_chunk_data(png_ptr, (png_bytef *)key, (png_uint_32)(key_len + 1));
|
png_write_chunk_data(png_ptr, (png_bytep )key, (png_uint_32)(key_len + 1));
|
||||||
buf[0] = compression;
|
buf[0] = compression;
|
||||||
/* write compression */
|
/* write compression */
|
||||||
png_write_chunk_data(png_ptr, (png_byte *)buf, (png_uint_32)1);
|
png_write_chunk_data(png_ptr, (png_bytep )buf, (png_uint_32)1);
|
||||||
|
|
||||||
/* write saved output buffers, if any */
|
/* write saved output buffers, if any */
|
||||||
for (i = 0; i < num_output_ptr; i++)
|
for (i = 0; i < num_output_ptr; i++)
|
||||||
{
|
{
|
||||||
png_write_chunk_data(png_ptr, (png_bytef *)output_ptr[i], png_ptr->zbuf_size);
|
png_write_chunk_data(png_ptr, (png_bytep )output_ptr[i], png_ptr->zbuf_size);
|
||||||
png_large_free(png_ptr, output_ptr[i]);
|
png_large_free(png_ptr, output_ptr[i]);
|
||||||
}
|
}
|
||||||
if (max_output_ptr)
|
if (max_output_ptr)
|
||||||
png_free(png_ptr, output_ptr);
|
png_free(png_ptr, output_ptr);
|
||||||
@ -576,14 +576,14 @@ png_write_zTXt(png_struct *png_ptr, charf *key, charf *text,
|
|||||||
png_write_chunk_end(png_ptr);
|
png_write_chunk_end(png_ptr);
|
||||||
|
|
||||||
/* reset zlib for another zTXt or the image data */
|
/* reset zlib for another zTXt or the image data */
|
||||||
deflateReset(png_ptr->zstream);
|
deflateReset(png_ptr->zstream);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PNG_WRITE_pHYs_SUPPORTED)
|
#if defined(PNG_WRITE_pHYs_SUPPORTED)
|
||||||
/* write the pHYs chunk */
|
/* write the pHYs chunk */
|
||||||
void
|
void
|
||||||
png_write_pHYs(png_struct *png_ptr, png_uint_32 x_pixels_per_unit,
|
png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
|
||||||
png_uint_32 y_pixels_per_unit,
|
png_uint_32 y_pixels_per_unit,
|
||||||
int unit_type)
|
int unit_type)
|
||||||
{
|
{
|
||||||
@ -600,7 +600,7 @@ png_write_pHYs(png_struct *png_ptr, png_uint_32 x_pixels_per_unit,
|
|||||||
#if defined(PNG_WRITE_oFFs_SUPPORTED)
|
#if defined(PNG_WRITE_oFFs_SUPPORTED)
|
||||||
/* write the oFFs chunk */
|
/* write the oFFs chunk */
|
||||||
void
|
void
|
||||||
png_write_oFFs(png_struct *png_ptr, png_uint_32 x_offset,
|
png_write_oFFs(png_structp png_ptr, png_uint_32 x_offset,
|
||||||
png_uint_32 y_offset,
|
png_uint_32 y_offset,
|
||||||
int unit_type)
|
int unit_type)
|
||||||
{
|
{
|
||||||
@ -618,7 +618,7 @@ png_write_oFFs(png_struct *png_ptr, png_uint_32 x_offset,
|
|||||||
/* write the tIME chunk. Use either png_convert_from_struct_tm()
|
/* write the tIME chunk. Use either png_convert_from_struct_tm()
|
||||||
or png_convert_from_time_t(), or fill in the structure yourself */
|
or png_convert_from_time_t(), or fill in the structure yourself */
|
||||||
void
|
void
|
||||||
png_write_tIME(png_struct *png_ptr, png_time *mod_time)
|
png_write_tIME(png_structp png_ptr, png_timep mod_time)
|
||||||
{
|
{
|
||||||
png_byte buf[7];
|
png_byte buf[7];
|
||||||
|
|
||||||
@ -635,26 +635,26 @@ png_write_tIME(png_struct *png_ptr, png_time *mod_time)
|
|||||||
|
|
||||||
/* initializes the row writing capability of libpng */
|
/* initializes the row writing capability of libpng */
|
||||||
void
|
void
|
||||||
png_write_start_row(png_struct *png_ptr)
|
png_write_start_row(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
/* set up row buffer */
|
/* set up row buffer */
|
||||||
png_ptr->row_buf = (png_bytef *)png_large_malloc(png_ptr,
|
png_ptr->row_buf = (png_bytep )png_large_malloc(png_ptr,
|
||||||
(((png_uint_32)png_ptr->usr_channels *
|
(((png_uint_32)png_ptr->usr_channels *
|
||||||
(png_uint_32)png_ptr->usr_bit_depth *
|
(png_uint_32)png_ptr->usr_bit_depth *
|
||||||
png_ptr->width) >> 3) + 1);
|
png_ptr->width + 7) >> 3) + 1);
|
||||||
/* set up filtering buffers, if filtering */
|
/* set up filtering buffers, if filtering */
|
||||||
if (png_ptr->do_filter)
|
if (png_ptr->do_filter)
|
||||||
{
|
{
|
||||||
png_ptr->prev_row = (png_bytef *)png_large_malloc(png_ptr,
|
png_ptr->prev_row = (png_bytep )png_large_malloc(png_ptr,
|
||||||
png_ptr->rowbytes + 1);
|
png_ptr->rowbytes + 1);
|
||||||
png_memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1);
|
png_memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1);
|
||||||
png_ptr->save_row = (png_bytef *)png_large_malloc(png_ptr,
|
png_ptr->save_row = (png_bytep )png_large_malloc(png_ptr,
|
||||||
png_ptr->rowbytes + 1);
|
png_ptr->rowbytes + 1);
|
||||||
png_memset(png_ptr->save_row, 0, (png_size_t)png_ptr->rowbytes + 1);
|
png_memset(png_ptr->save_row, 0, (png_size_t)png_ptr->rowbytes + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if interlaced, we need to set up width and height of pass */
|
/* if interlaced, we need to set up width and height of pass */
|
||||||
if (png_ptr->interlaced)
|
if (png_ptr->interlaced)
|
||||||
{
|
{
|
||||||
if (!(png_ptr->transformations & PNG_INTERLACE))
|
if (!(png_ptr->transformations & PNG_INTERLACE))
|
||||||
{
|
{
|
||||||
@ -672,7 +672,7 @@ png_write_start_row(png_struct *png_ptr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
png_ptr->num_rows = png_ptr->height;
|
png_ptr->num_rows = png_ptr->height;
|
||||||
png_ptr->usr_width = png_ptr->width;
|
png_ptr->usr_width = png_ptr->width;
|
||||||
}
|
}
|
||||||
@ -682,15 +682,15 @@ png_write_start_row(png_struct *png_ptr)
|
|||||||
|
|
||||||
/* Internal use only. Called when finished processing a row of data */
|
/* Internal use only. Called when finished processing a row of data */
|
||||||
void
|
void
|
||||||
png_write_finish_row(png_struct *png_ptr)
|
png_write_finish_row(png_structp png_ptr)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* 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 || png_ptr->mode > PNG_HAVE_IDAT)
|
if (png_ptr->row_number < png_ptr->num_rows)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* if interlaced, go to next pass */
|
/* if interlaced, go to next pass */
|
||||||
if (png_ptr->interlaced)
|
if (png_ptr->interlaced)
|
||||||
@ -708,7 +708,7 @@ png_write_finish_row(png_struct *png_ptr)
|
|||||||
png_ptr->pass++;
|
png_ptr->pass++;
|
||||||
if (png_ptr->pass >= 7)
|
if (png_ptr->pass >= 7)
|
||||||
break;
|
break;
|
||||||
png_ptr->usr_width = (png_ptr->width +
|
png_ptr->usr_width = (png_ptr->width +
|
||||||
png_pass_inc[png_ptr->pass] - 1 -
|
png_pass_inc[png_ptr->pass] - 1 -
|
||||||
png_pass_start[png_ptr->pass]) /
|
png_pass_start[png_ptr->pass]) /
|
||||||
png_pass_inc[png_ptr->pass];
|
png_pass_inc[png_ptr->pass];
|
||||||
@ -726,7 +726,7 @@ png_write_finish_row(png_struct *png_ptr)
|
|||||||
if (png_ptr->prev_row)
|
if (png_ptr->prev_row)
|
||||||
png_memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1);
|
png_memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1);
|
||||||
/* if we have more data to get, go get it */
|
/* if we have more data to get, go get it */
|
||||||
if (png_ptr->pass < 7)
|
if (png_ptr->pass < 7)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -735,16 +735,16 @@ png_write_finish_row(png_struct *png_ptr)
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
/* tell the compressor we are done */
|
/* tell the compressor we are done */
|
||||||
ret = deflate(png_ptr->zstream, Z_FINISH);
|
ret = deflate(png_ptr->zstream, Z_FINISH);
|
||||||
/* check for an error */
|
/* check for an error */
|
||||||
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_ptr->error_fn))(png_ptr, png_ptr->zstream->msg);
|
png_error(png_ptr, png_ptr->zstream->msg);
|
||||||
else
|
else
|
||||||
(*(png_ptr->error_fn))(png_ptr, "zlib error");
|
png_error(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)
|
||||||
{
|
{
|
||||||
png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
|
png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
|
||||||
@ -761,7 +761,6 @@ 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)
|
||||||
@ -774,18 +773,18 @@ png_write_finish_row(png_struct *png_ptr)
|
|||||||
See the default: case for the easiest code to understand.
|
See the default: case for the easiest code to understand.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
png_do_write_interlace(png_row_info *row_info, png_bytef *row, int pass)
|
png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
|
||||||
{
|
{
|
||||||
/* we don't have to do anything on the last pass (6) */
|
/* we don't have to do anything on the last pass (6) */
|
||||||
if (row && row_info && pass < 6)
|
if (row && row_info && pass < 6)
|
||||||
{
|
{
|
||||||
/* each pixel depth is handled seperately */
|
/* each pixel depth is handled seperately */
|
||||||
switch (row_info->pixel_depth)
|
switch (row_info->pixel_depth)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
png_bytef *sp;
|
png_bytep sp;
|
||||||
png_bytef *dp;
|
png_bytep dp;
|
||||||
int shift;
|
int shift;
|
||||||
int d;
|
int d;
|
||||||
int value;
|
int value;
|
||||||
@ -799,7 +798,7 @@ png_do_write_interlace(png_row_info *row_info, png_bytef *row, int pass)
|
|||||||
i += png_pass_inc[pass])
|
i += png_pass_inc[pass])
|
||||||
{
|
{
|
||||||
sp = row + (png_size_t)(i >> 3);
|
sp = row + (png_size_t)(i >> 3);
|
||||||
value = (int)(*sp >> (7 - (int)(i & 7))) & 0x1;
|
value = (int)(*sp >> (7 - (int)(i & 7))) & 0x1;
|
||||||
d |= (value << shift);
|
d |= (value << shift);
|
||||||
|
|
||||||
if (shift == 0)
|
if (shift == 0)
|
||||||
@ -817,9 +816,9 @@ png_do_write_interlace(png_row_info *row_info, png_bytef *row, int pass)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
png_bytef *sp;
|
png_bytep sp;
|
||||||
png_bytef *dp;
|
png_bytep dp;
|
||||||
int shift;
|
int shift;
|
||||||
int d;
|
int d;
|
||||||
int value;
|
int value;
|
||||||
@ -851,9 +850,9 @@ png_do_write_interlace(png_row_info *row_info, png_bytef *row, int pass)
|
|||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
{
|
{
|
||||||
png_bytef *sp;
|
png_bytep sp;
|
||||||
png_bytef *dp;
|
png_bytep dp;
|
||||||
int shift;
|
int shift;
|
||||||
int d;
|
int d;
|
||||||
int value;
|
int value;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
@ -871,7 +870,7 @@ png_do_write_interlace(png_row_info *row_info, png_bytef *row, int pass)
|
|||||||
|
|
||||||
if (shift == 0)
|
if (shift == 0)
|
||||||
{
|
{
|
||||||
shift = 4;
|
shift = 4;
|
||||||
*dp++ = d;
|
*dp++ = d;
|
||||||
d = 0;
|
d = 0;
|
||||||
}
|
}
|
||||||
@ -884,12 +883,12 @@ png_do_write_interlace(png_row_info *row_info, png_bytef *row, int pass)
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
png_bytef *sp;
|
png_bytep sp;
|
||||||
png_bytef *dp;
|
png_bytep dp;
|
||||||
png_uint_32 i;
|
png_uint_32 i;
|
||||||
int pixel_bytes;
|
int pixel_bytes;
|
||||||
|
|
||||||
/* start at the beginning */
|
/* start at the beginning */
|
||||||
dp = row;
|
dp = row;
|
||||||
/* find out how many bytes each pixel takes up */
|
/* find out how many bytes each pixel takes up */
|
||||||
pixel_bytes = (row_info->pixel_depth >> 3);
|
pixel_bytes = (row_info->pixel_depth >> 3);
|
||||||
@ -907,7 +906,7 @@ png_do_write_interlace(png_row_info *row_info, png_bytef *row, int pass)
|
|||||||
/* next pixel */
|
/* next pixel */
|
||||||
dp += pixel_bytes;
|
dp += pixel_bytes;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* set new row width */
|
/* set new row width */
|
||||||
@ -925,13 +924,13 @@ png_do_write_interlace(png_row_info *row_info, png_bytef *row, int pass)
|
|||||||
/* this filters the row. Both row and prev_row have space at the
|
/* this filters the row. Both row and prev_row have space at the
|
||||||
first byte for the filter byte. */
|
first byte for the filter byte. */
|
||||||
void
|
void
|
||||||
png_write_filter_row(png_row_info *row_info, png_bytef *row,
|
png_write_filter_row(png_row_infop row_info, png_bytep row,
|
||||||
png_bytef *prev_row)
|
png_bytep prev_row)
|
||||||
{
|
{
|
||||||
int minf, bpp;
|
int minf, bpp;
|
||||||
png_uint_32 i, v;
|
png_uint_32 i, v;
|
||||||
png_uint_32 s0, s1, s2, s3, s4, mins;
|
png_uint_32 s0, s1, s2, s3, s4, mins;
|
||||||
png_bytef *rp, *pp, *cp, *lp;
|
png_bytep rp, pp, cp, lp;
|
||||||
|
|
||||||
/* find out how many bytes offset each pixel is */
|
/* find out how many bytes offset each pixel is */
|
||||||
bpp = (row_info->pixel_depth + 7) / 8;
|
bpp = (row_info->pixel_depth + 7) / 8;
|
||||||
@ -943,7 +942,7 @@ png_write_filter_row(png_row_info *row_info, png_bytef *row,
|
|||||||
zero using anything >= 128 as negitive numbers. */
|
zero using anything >= 128 as negitive numbers. */
|
||||||
s0 = s1 = s2 = s3 = s4 = 0;
|
s0 = s1 = s2 = s3 = s4 = 0;
|
||||||
|
|
||||||
for (i = 0, rp = row + 1, pp = prev_row + 1, lp = row + 1 - bpp,
|
for (i = 0, rp = row + 1, pp = prev_row + 1, lp = row + 1 - bpp,
|
||||||
cp = prev_row + 1 - bpp;
|
cp = prev_row + 1 - bpp;
|
||||||
i < bpp; i++, rp++, pp++, lp++, cp++)
|
i < bpp; i++, rp++, pp++, lp++, cp++)
|
||||||
{
|
{
|
||||||
@ -979,7 +978,7 @@ png_write_filter_row(png_row_info *row_info, png_bytef *row,
|
|||||||
{
|
{
|
||||||
int a, b, c, pa, pb, pc, p;
|
int a, b, c, pa, pb, pc, p;
|
||||||
|
|
||||||
/* check none filter */
|
/* check none filter */
|
||||||
v = *rp;
|
v = *rp;
|
||||||
if (v < 128)
|
if (v < 128)
|
||||||
s0 += v;
|
s0 += v;
|
||||||
@ -997,7 +996,7 @@ png_write_filter_row(png_row_info *row_info, png_bytef *row,
|
|||||||
/* check up filter */
|
/* check up filter */
|
||||||
v = (png_byte)(((int)*rp - (int)*pp) & 0xff);
|
v = (png_byte)(((int)*rp - (int)*pp) & 0xff);
|
||||||
|
|
||||||
if (v < 128)
|
if (v < 128)
|
||||||
s2 += v;
|
s2 += v;
|
||||||
else
|
else
|
||||||
s2 += 256 - v;
|
s2 += 256 - v;
|
||||||
@ -1015,7 +1014,7 @@ png_write_filter_row(png_row_info *row_info, png_bytef *row,
|
|||||||
c = *cp;
|
c = *cp;
|
||||||
a = *lp;
|
a = *lp;
|
||||||
p = a + b - c;
|
p = a + b - c;
|
||||||
pa = abs(p - a);
|
pa = abs(p - a);
|
||||||
pb = abs(p - b);
|
pb = abs(p - b);
|
||||||
pc = abs(p - c);
|
pc = abs(p - c);
|
||||||
|
|
||||||
@ -1051,7 +1050,7 @@ png_write_filter_row(png_row_info *row_info, png_bytef *row,
|
|||||||
|
|
||||||
if (s3 < mins)
|
if (s3 < mins)
|
||||||
{
|
{
|
||||||
mins = s3;
|
mins = s3;
|
||||||
minf = 3;
|
minf = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1069,7 +1068,7 @@ png_write_filter_row(png_row_info *row_info, png_bytef *row,
|
|||||||
{
|
{
|
||||||
/* sub filter */
|
/* sub filter */
|
||||||
case 1:
|
case 1:
|
||||||
for (i = bpp, rp = row + (png_size_t)row_info->rowbytes,
|
for (i = bpp, rp = row + (png_size_t)row_info->rowbytes,
|
||||||
lp = row + (png_size_t)row_info->rowbytes - bpp;
|
lp = row + (png_size_t)row_info->rowbytes - bpp;
|
||||||
i < row_info->rowbytes; i++, rp--, lp--)
|
i < row_info->rowbytes; i++, rp--, lp--)
|
||||||
{
|
{
|
||||||
@ -1087,7 +1086,7 @@ png_write_filter_row(png_row_info *row_info, png_bytef *row,
|
|||||||
break;
|
break;
|
||||||
/* avg filter */
|
/* avg filter */
|
||||||
case 3:
|
case 3:
|
||||||
for (i = row_info->rowbytes,
|
for (i = row_info->rowbytes,
|
||||||
rp = row + (png_size_t)row_info->rowbytes,
|
rp = row + (png_size_t)row_info->rowbytes,
|
||||||
pp = prev_row + (png_size_t)row_info->rowbytes,
|
pp = prev_row + (png_size_t)row_info->rowbytes,
|
||||||
lp = row + (png_size_t)row_info->rowbytes - bpp;
|
lp = row + (png_size_t)row_info->rowbytes - bpp;
|
||||||
@ -1105,7 +1104,7 @@ png_write_filter_row(png_row_info *row_info, png_bytef *row,
|
|||||||
case 4:
|
case 4:
|
||||||
for (i = row_info->rowbytes,
|
for (i = row_info->rowbytes,
|
||||||
rp = row + (png_size_t)row_info->rowbytes,
|
rp = row + (png_size_t)row_info->rowbytes,
|
||||||
pp = prev_row + (png_size_t)row_info->rowbytes,
|
pp = prev_row + (png_size_t)row_info->rowbytes,
|
||||||
lp = row + (png_size_t)row_info->rowbytes - bpp,
|
lp = row + (png_size_t)row_info->rowbytes - bpp,
|
||||||
cp = prev_row + (png_size_t)row_info->rowbytes - bpp;
|
cp = prev_row + (png_size_t)row_info->rowbytes - bpp;
|
||||||
i > 0; i--, rp--, lp--, pp--, cp--)
|
i > 0; i--, rp--, lp--, pp--, cp--)
|
||||||
@ -1123,7 +1122,7 @@ png_write_filter_row(png_row_info *row_info, png_bytef *row,
|
|||||||
a = c = 0;
|
a = c = 0;
|
||||||
}
|
}
|
||||||
p = a + b - c;
|
p = a + b - c;
|
||||||
pa = abs(p - a);
|
pa = abs(p - a);
|
||||||
pb = abs(p - b);
|
pb = abs(p - b);
|
||||||
pc = abs(p - c);
|
pc = abs(p - c);
|
||||||
|
|
||||||
|
41
readme.txt
41
readme.txt
@ -1,31 +1,28 @@
|
|||||||
readme.txt - for libpng 0.8
|
readme.txt - for libpng 0.85
|
||||||
|
|
||||||
This is the second beta version of libpng 1.0. I've updated most
|
This is a bug fix for the second beta version of libpng 1.0, and
|
||||||
of the stuff I want to before the final 1.0 version. Remaining
|
a first try at a progressive (push) reader. It hasn't been
|
||||||
to do are the medium memory model support (which I'll put in
|
tested very much, but I'm not going to have time to test it for
|
||||||
as soon as we test this version), better dithering, and any bug
|
a few days, and I wanted to give an advanced look at the
|
||||||
fixes and makefile/include additions. I expect a third (and
|
progressive reader to everyone. Please report bugs back
|
||||||
perhaps final) beta after zlib is officially 1.0.
|
(and fixes, if you find them), and I'll release a new version
|
||||||
|
in a week or two. Thanks.
|
||||||
|
|
||||||
|
I've implemented the callback functions for the error/warning
|
||||||
|
messages and the input/output. See the libpng.txt
|
||||||
|
for details. I've also added defines to support medium memory
|
||||||
|
models, so every type now has pointer defines. For example,
|
||||||
|
a pointer to the png_struct is now png_structp, while a double
|
||||||
|
pointer is now png_structpp. The old way should work, but I'll
|
||||||
|
be using the new way from now on in all my examples. Those of
|
||||||
|
you doing medium memory model or changing the error/warning
|
||||||
|
or input/output functions should try these and report back to
|
||||||
|
me any problems.
|
||||||
|
|
||||||
I've tried to incorporate all the changes and makefiles everyone
|
I've tried to incorporate all the changes and makefiles everyone
|
||||||
sent me. However, I may of lost some in the flood. If you sent
|
sent me. However, I may of lost some in the flood. If you sent
|
||||||
me a change and I didn't put it in, send it again. Sorry.
|
me a change and I didn't put it in, send it again. Sorry.
|
||||||
|
|
||||||
Updates from libpng 0.71 include a new transformation,
|
|
||||||
png_set_filler(), which replaces png_set_rgbx() and
|
|
||||||
png_set_xrgb(). The old functions will be supported for
|
|
||||||
awhile, but I'd suggest changing to the new function. Also,
|
|
||||||
I've added defines in png.h to remove unwanted code from the
|
|
||||||
compiled library. I've added a new field to png_realloc(), and
|
|
||||||
fixed various bugs. I've also split up pngstub.c into pngmem.c,
|
|
||||||
pngio.c, and pngerror.c, in case you need to just change some of
|
|
||||||
these. I've pulled pngconf.h out of png.h, so you don't have to
|
|
||||||
remake your changes every new release. I've added a function to
|
|
||||||
update the png_info structure after you're done setting up your
|
|
||||||
transformations (png_read_update_info()). The complete list of
|
|
||||||
changes is in pngchang.txt. Most of you won't be much affected
|
|
||||||
by any of this. Some of you will want to use the new features.
|
|
||||||
|
|
||||||
For a detailed description on using libpng, read libpng.txt. For
|
For a detailed description on using libpng, read libpng.txt. For
|
||||||
usage information and restrictions (what little they are) on libpng,
|
usage information and restrictions (what little they are) on libpng,
|
||||||
see png.h. For a description on using zlib (the compression library
|
see png.h. For a description on using zlib (the compression library
|
||||||
|
Reference in New Issue
Block a user