mirror of
https://git.code.sf.net/p/libpng/code.git
synced 2025-07-10 18:04:09 +02:00
Imported from libpng-0.88.tar
This commit is contained in:
committed by
Glenn Randers-Pehrson
parent
4ee97b0891
commit
b2e01bd505
240
example.c
240
example.c
@@ -40,7 +40,7 @@ int check_png(char * file_name)
|
||||
void read_png(char *file_name)
|
||||
{
|
||||
FILE *fp;
|
||||
png_structp png_ptr;
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
|
||||
/* open the file */
|
||||
@@ -82,18 +82,18 @@ void read_png(char *file_name)
|
||||
/* set up the input control if you are using standard C streams */
|
||||
png_init_io(png_ptr, fp);
|
||||
|
||||
/* if you are using replacement read functions, here you would call */
|
||||
png_set_read_fn(png_ptr, (void *)io_ptr, user_read_fn);
|
||||
/* where io_ptr is a structure you want available to the callbacks */
|
||||
/* if you are using replacement read functions, here you would call */
|
||||
png_set_read_fn(png_ptr, (void *)io_ptr, user_read_fn);
|
||||
/* where io_ptr is a structure you want available to the callbacks */
|
||||
|
||||
/* if you are using replacement message functions, here you would call */
|
||||
png_set_message_fn(png_ptr, (void *)msg_ptr, user_error_fn, user_warning_fn);
|
||||
/* where msg_ptr is a structure you want available to the callbacks */
|
||||
/* if you are using replacement message functions, here you would call */
|
||||
png_set_message_fn(png_ptr, (void *)msg_ptr, user_error_fn, user_warning_fn);
|
||||
/* where msg_ptr is a structure you want available to the callbacks */
|
||||
|
||||
/* read the file information */
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
/* read the file information */
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
|
||||
/* set up the transformations you want. Note that these are
|
||||
/* set up the transformations you want. Note that these are
|
||||
all optional. Only call them if you want them */
|
||||
|
||||
/* expand paletted colors into true rgb */
|
||||
@@ -110,14 +110,14 @@ void read_png(char *file_name)
|
||||
png_set_expand(png_ptr);
|
||||
|
||||
/* Set the background color to draw transparent and alpha
|
||||
images over */
|
||||
images over */
|
||||
png_color_16 my_background;
|
||||
|
||||
if (info_ptr->valid & PNG_INFO_bKGD)
|
||||
png_set_background(png_ptr, &(info_ptr->background),
|
||||
PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
|
||||
else
|
||||
png_set_background(png_ptr, &my_background,
|
||||
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 */
|
||||
@@ -128,7 +128,7 @@ void read_png(char *file_name)
|
||||
|
||||
/* tell libpng to strip 16 bit depth files down to 8 bits */
|
||||
if (info_ptr->bit_depth == 16)
|
||||
png_set_strip_16(png_ptr);
|
||||
png_set_strip_16(png_ptr);
|
||||
|
||||
/* dither rgb files down to 8 bit palettes & reduce palettes
|
||||
to the number of colors available on your screen */
|
||||
@@ -146,7 +146,7 @@ void read_png(char *file_name)
|
||||
png_set_dither(png_ptr, std_color_cube, MAX_SCREEN_COLORS,
|
||||
MAX_SCREEN_COLORS, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* invert monocrome files */
|
||||
if (info_ptr->bit_depth == 1 &&
|
||||
@@ -164,7 +164,7 @@ void read_png(char *file_name)
|
||||
|
||||
/* flip the rgb pixels to bgr */
|
||||
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);
|
||||
|
||||
/* swap bytes of 16 bit files to least significant bit first */
|
||||
@@ -182,7 +182,7 @@ void read_png(char *file_name)
|
||||
else
|
||||
number_passes = 1;
|
||||
|
||||
/* optional call to update palette with transformations */
|
||||
/* optional call to update palette with transformations */
|
||||
png_start_read_image(png_ptr);
|
||||
|
||||
/* optional call to update the info structure */
|
||||
@@ -200,7 +200,7 @@ void read_png(char *file_name)
|
||||
for (pass = 0; pass < number_passes; pass++)
|
||||
{
|
||||
/* Read the image using the "sparkle" effect. */
|
||||
png_read_rows(png_ptr, row_pointers, NULL, number_of_rows);
|
||||
png_read_rows(png_ptr, row_pointers, NULL, number_of_rows);
|
||||
|
||||
/* If you are only reading on row at a time, this works */
|
||||
for (y = 0; y < height; y++)
|
||||
@@ -218,7 +218,7 @@ void read_png(char *file_name)
|
||||
|
||||
/* read the rest of the file, getting any additional chunks
|
||||
in info_ptr */
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
|
||||
/* clean up after the read, and free any memory allocated */
|
||||
png_read_destroy(png_ptr, info_ptr, (png_infop)0);
|
||||
@@ -237,126 +237,126 @@ void read_png(char *file_name)
|
||||
/* progressively read a file */
|
||||
|
||||
/* these will normally not be global unless you are only
|
||||
reading in one image at a time */
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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);
|
||||
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);
|
||||
/* 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;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
/* 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. */
|
||||
/* 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)
|
||||
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.
|
||||
/* 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: */
|
||||
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);
|
||||
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. */
|
||||
/* 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.
|
||||
/* 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. */
|
||||
Most people won't do much here, perhaps setting a flag that
|
||||
marks the image as finished. */
|
||||
}
|
||||
|
||||
/* write a png file */
|
||||
void write_png(char *file_name, ... other image information ...)
|
||||
{
|
||||
FILE *fp;
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
|
||||
/* open the file */
|
||||
fp = fopen(file_name, "wb");
|
||||
@@ -380,7 +380,7 @@ void write_png(char *file_name, ... other image information ...)
|
||||
}
|
||||
|
||||
/* set error handling */
|
||||
if (setjmp(png_ptr->jmpbuf))
|
||||
if (setjmp(png_ptr->jmpbuf))
|
||||
{
|
||||
png_write_destroy(png_ptr);
|
||||
fclose(fp);
|
||||
@@ -397,15 +397,15 @@ void write_png(char *file_name, ... other image information ...)
|
||||
/* set up the output control if you are using standard C streams */
|
||||
png_init_io(png_ptr, fp);
|
||||
|
||||
/* if you are using replacement write functions, here you would call */
|
||||
png_set_write_fn(png_ptr, (void *)io_ptr, user_write_fn, user_flush_fn);
|
||||
/* where io_ptr is a structure you want available to the callbacks */
|
||||
/* if you are using replacement write functions, here you would call */
|
||||
png_set_write_fn(png_ptr, (void *)io_ptr, user_write_fn, user_flush_fn);
|
||||
/* where io_ptr is a structure you want available to the callbacks */
|
||||
|
||||
/* if you are using replacement message functions, here you would call */
|
||||
png_set_message_fn(png_ptr, (void *)msg_ptr, user_error_fn, user_warning_fn);
|
||||
/* where msg_ptr is a structure you want available to the callbacks */
|
||||
/* if you are using replacement message functions, here you would call */
|
||||
png_set_message_fn(png_ptr, (void *)msg_ptr, user_error_fn, user_warning_fn);
|
||||
/* where msg_ptr is a structure you want available to the callbacks */
|
||||
|
||||
/* set the file information here */
|
||||
/* set the file information here */
|
||||
info_ptr->width = ;
|
||||
info_ptr->height = ;
|
||||
etc.
|
||||
@@ -418,18 +418,18 @@ 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 */
|
||||
/* if we are dealing with a grayscale image then */
|
||||
info_ptr->sig_bit.gray = true_bit_depth;
|
||||
/* otherwise, if we are dealing with a color image then */
|
||||
info_ptr->sig_bit.red = true_red_bit_depth;
|
||||
info_ptr->sig_bit.green = true_green_bit_depth;
|
||||
info_ptr->sig_bit.blue = true_blue_bit_depth;
|
||||
/* if the image has an alpha channel then */
|
||||
info_ptr->sig_bit.alpha = true_alpha_bit_depth;
|
||||
|
||||
/* optional gamma chunk is strongly suggested if you have any guess
|
||||
as to the correct gamma of the image */
|
||||
info_ptr->valid |= PNG_INFO_gAMA;
|
||||
/* optional gamma chunk is strongly suggested if you have any guess
|
||||
as to the correct gamma of the image */
|
||||
info_ptr->valid |= PNG_INFO_gAMA;
|
||||
info_ptr->gamma = gamma;
|
||||
|
||||
/* other optional chunks */
|
||||
|
||||
Reference in New Issue
Block a user