Imported from libpng-0.85.tar

This commit is contained in:
Guy Schalnat
1995-12-19 03:22:19 -06:00
committed by Glenn Randers-Pehrson
parent 0f71645dfe
commit 6d76471acd
24 changed files with 3505 additions and 2324 deletions

193
example.c
View File

@@ -15,7 +15,7 @@
#include <png.h>
/* 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;
char buf[8];
@@ -40,8 +40,8 @@ int check_png(char *file_name)
void read_png(char *file_name)
{
FILE *fp;
png_struct *png_ptr;
png_info *info_ptr;
png_structp png_ptr;
png_infop info_ptr;
/* open the file */
fp = fopen(file_name, "rb");
@@ -79,19 +79,9 @@ void read_png(char *file_name)
png_info_init(info_ptr);
png_read_init(png_ptr);
/* set up the input control for the default input and message functions.
* If we were to replace both the input and message functions we don't
* need to call png_init_io first. */
/* set up the input control */
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 */
png_read_info(png_ptr, info_ptr);
@@ -117,10 +107,10 @@ void read_png(char *file_name)
if (info_ptr->valid & PNG_INFO_bKGD)
png_set_background(png_ptr, &(info_ptr->background),
PNG_GAMMA_FILE, 1, 1.0);
else
png_set_background(png_ptr, &my_background,
PNG_GAMMA_SCREEN, 0, 1.0);
PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
else
png_set_background(png_ptr, &my_background,
PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
/* tell libpng to handle the gamma conversion for you */
if (info_ptr->valid & PNG_INFO_gAMA)
@@ -156,7 +146,8 @@ void read_png(char *file_name)
png_set_invert(png_ptr);
/* 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));
/* pack pixels into bytes */
@@ -193,7 +184,7 @@ void read_png(char *file_name)
of png_info. */
/* the easiest way to read the image */
png_bytef *row_pointers[height];
png_bytep row_pointers[height];
png_read_image(png_ptr, row_pointers);
/* 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 */
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);
}
@@ -221,13 +212,8 @@ void read_png(char *file_name)
in 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 */
png_read_destroy(png_ptr, info_ptr, (png_info *)0);
png_read_destroy(png_ptr, info_ptr, (png_infop)0);
/* free the structures */
free(png_ptr);
@@ -240,12 +226,129 @@ void read_png(char *file_name)
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 */
void write_png(char *file_name, ... other image information ...)
{
FILE *fp;
png_struct *png_ptr;
png_info *info_ptr;
png_structp png_ptr;
png_infop info_ptr;
/* open the file */
fp = fopen(file_name, "wb");
@@ -283,19 +386,9 @@ void write_png(char *file_name, ... other image information ...)
png_info_init(info_ptr);
png_write_init(png_ptr);
/* set up the output control for the default output and message functions.
* If we were to replace both the output and message functions we don't
* need to call png_init_io first. */
/* set up the output control */
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 */
info_ptr->width = ;
info_ptr->height = ;
@@ -309,16 +402,9 @@ void write_png(char *file_name, ... other image information ...)
/* optional significant bit chunk */
info_ptr->valid |= PNG_INFO_sBIT;
/* if we are dealing with a grayscale image then */
info_ptr->sig_bit.gray = true_bit_depth;
/* otherwise, if we are dealing with a color image then */
info_ptr->sig_bit.red = true_red_bit_depth;
info_ptr->sig_bit.green = true_green_bit_depth;
info_ptr->sig_bit.blue = true_blue_bit_depth;
/* if the image has an alpha channel then */
info_ptr->sig_bit.alpha = true_alpha_bit_depth;
info_ptr->sig_bit = true_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->gamma = gamma;
@@ -357,7 +443,7 @@ void write_png(char *file_name, ... other image information ...)
number_passes = 1;
/* the easiest way to write the image */
png_bytef *row_pointers[height];
png_bytep row_pointers[height];
png_write_image(png_ptr, row_pointers);
/* 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 */
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);
}
}
@@ -378,11 +464,6 @@ void write_png(char *file_name, ... other image information ...)
/* write the rest of the file */
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 */
png_write_destroy(png_ptr);