From 6d76471acd6ee528f21458658ccf4aff330e0357 Mon Sep 17 00:00:00 2001 From: Guy Schalnat Date: Tue, 19 Dec 1995 03:22:19 -0600 Subject: [PATCH] Imported from libpng-0.85.tar --- build.bat | 2 + example.c | 193 +++++--- libpng.txt | 543 +++++++++++----------- lpfaq.txt | 190 -------- makefile | 15 +- png.c | 88 ++-- png.h | 932 ++++++++++++++++++++++---------------- pngchang.txt | 16 +- pngconf.h | 124 +++++- pngerror.c | 99 ++++ pngio.c | 453 ++++++++----------- pngmem.c | 274 ++---------- pngpread.c | 1214 ++++++++++++++++++++++++++++++++++++++++++++++++++ pngrcb.c | 68 +-- pngread.c | 346 +++++++------- pngrtran.c | 379 ++++++++-------- pngrutil.c | 253 +++++------ pngtest.c | 26 +- pngtodo.txt | 11 +- pngtrans.c | 40 +- pngwrite.c | 240 +++++----- pngwtran.c | 45 +- pngwutil.c | 237 +++++----- readme.txt | 41 +- 24 files changed, 3505 insertions(+), 2324 deletions(-) create mode 100644 build.bat delete mode 100644 lpfaq.txt create mode 100644 pngerror.c create mode 100644 pngpread.c diff --git a/build.bat b/build.bat new file mode 100644 index 00000000..ec34b6f0 --- /dev/null +++ b/build.bat @@ -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 diff --git a/example.c b/example.c index 4a830acb..d6fd805b 100644 --- a/example.c +++ b/example.c @@ -15,7 +15,7 @@ #include /* 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); diff --git a/libpng.txt b/libpng.txt index 05bf711d..dc2338b7 100644 --- a/libpng.txt +++ b/libpng.txt @@ -1,9 +1,9 @@ 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 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 (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 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 -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 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. -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 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 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 -the accuracy of the prediction. +of a png file. Of course, the more bytes you pass in, the greater +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); - is_png = png_check_sig(header, number); + fread(header, 1, number, fp); + is_png = png_check_sig(header, number); 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 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 to spare. Of course, you will want to check if malloc returns NULL. - png_struct *png_ptr = malloc(sizeof (png_struct)); - if (!png_ptr) - return; - png_info *info_ptr = malloc(sizeof (png_info)); - if (!info_ptr) - { - free(png_ptr); - return; - } + png_structp png_ptr = malloc(sizeof (png_struct)); + if (!png_ptr) + return; + png_infop info_ptr = malloc(sizeof (png_info)); + if (!info_ptr) + { + free(png_ptr); + return; + } 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 much to undo. - FILE *fp = fopen(file_name, "rb"); - if (!fp) - { - free(png_ptr); - free(info_ptr); - 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. + FILE *fp = fopen(file_name, "rb"); + if (!fp) + { + free(png_ptr); + free(info_ptr); + return; + } After you have these structures, you will need to set up the 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 call a png_ function. See your documentation of setjmp/longjmp for your compiler for more information on setjmp/longjmp. See -the discussion on libpng error handling in the Customizing Libpng -section below for more information on how to change the behaviour -of libpng error handling. If an error occurs, and libpng longjmp's -back to your setjmp, you will want to call png_read_destroy() to -free any memory. +the discussion on png error handling in the Customizing Libpng +section below for more information on the png error handling. +If an error occurs, and libpng longjmp's back to your setjmp, +you will want to call png_read_destroy() to free any memory. - 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); - fclose(fp); - return; - } + 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); + fclose(fp); + return; + } Next, you will need to call png_read_init() and png_info_init(). 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 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 -the file is opened in binary mode. Otherwise, you should see the -section below on Customizing libpng I/O functions. +the file is opened in binary mode. If you wish to handle reading +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 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 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 bit_depth - holds the bit depth of one of the image channels 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 pixel_depth - bits per pixel rowbytes - number of bytes needed to hold a row - interlace_type - currently 0 for none, 1 for interlaced - valid - this details which optional chunks were found in the file - to see if a chunk was present, OR valid with the appropriate + interlace_type - currently 0 for none, 1 for interlaced + valid - this details which optional chunks were found in the file + to see if a chunk was present, OR valid with the appropriate PNG_INFO_ define. palette and num_palette - the palette for the file 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 hist - histogram of palette 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 character for a keyword. It is strongly suggested that keywords 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 - Author Name of image's creator - Copyright Copyright notice (possibly long) - Description Description of image (possibly long) - Software Software used to create the image - Disclaimer Legal disclaimer (possibly long) - Warning Warning of nature of content - Source Device used to create the image - Comment Miscellaneous comment; conversion from GIF comment - Created When the image or source file was created - -There is no requirement to have text after the keyword on tEXt chunks. -However, you must have text after the keyword on zTXt chunks, as only -the text gets compressed, and compressing nothing will result in an error. - -The maximum length of the keyword is limited to 80 characters. It is -possible to use the same keyword any number of times. The text field -is an array of png_text structures, each holding pointer to a keyword +Keywords are restricted to 80 characters without leading or trailing +spaces, but spaces are allowed within the keyword Nothing +prevents you from duplicating the keyword. 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. 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 @@ -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 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 information in a tRNS chunk. This is probably most useful on grayscale images with bit depths of 2 or 4 and tRNS chunks. if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 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) 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 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) png_set_backgrond(png_ptr, &(info_ptr->background), - PNG_GAMMA_FILE, 1, 1.0); + PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); else 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 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 gammas are inverted from screen gammas. See the discussions on -gamma in the PNG specification for more information. It is strongly -reccommended that viewers support gamma correction. +gamma in the PNG specification for more information. if (info_ptr->valid & PNG_INFO_gAMA) png_set_gamma(png_ptr, screen_gamma, info_ptr->gamma); - else - png_set_gamma(png_ptr, screen_gamma, 0.45); + else + png_set_gamma(png_ptr, screen_gamma, 0.45); 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. @@ -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 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) 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); else { - png_color std_color_cube[MAX_SCREEN_COLORS] = + png_color std_color_cube[MAX_SCREEN_COLORS] = { ... 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. 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); 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 || 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 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 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 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 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 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: - void *row_pointers[height]; + png_bytep row_pointers[height]; 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 row_pointers: - char *row_pointers = row; + png_bytep row_pointers = row; 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 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 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. +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: 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 to spare. - png_struct *png_ptr = malloc(sizeof (png_struct)); - if (!png_ptr) - return; - png_info *info_ptr = malloc(sizeof (png_info)); - if (!info_ptr) + png_structp png_ptr = malloc(sizeof (png_struct)); + if (!png_ptr) + return; + png_infop info_ptr = malloc(sizeof (png_info)); + if (!info_ptr) { free(png_ptr); return; @@ -513,7 +626,7 @@ much to undo. if (!fp) { free(png_ptr); - free(info_ptr); + free(info_ptr); 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 the jmpbuf field every time you enter a new routine that will call a png_ function. See your documentation of setjmp/longjmp -for your compiler for more information on setjmp/longjmp. If you -don't want to use stderr for error output, or you want to use a -method other than setjmp()/longjmp() to handle errors, see the -Customizing Libpng section below for more information on libpng -error handling. +for your compiler for more information on setjmp/longjmp. See +the discussion on png error handling in the Customizing Libpng +section below for more information on the png error handling. if (setjmp(png_ptr->jmpbuf)) { 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. */ free(png_ptr); free(info_ptr); - fclose(fp); + fclose(fp); 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 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 -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. 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 will run. The following functions are mainly for testing, but 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 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 @@ -571,36 +682,14 @@ carefully tuned to deliver the best speed/compression ratio. See the compression library for more details. /* 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_strategy(png_ptr, Z_DEFAULT_STRATEGY); png_set_compression_window_bits(png_ptr, 15); 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 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 @@ -613,7 +702,7 @@ parts of the png_info are: width - holds the width of the file height - holds the height of the file 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 interlace_type - currently 0 for none, 1 for interlaced valid - this describes which optional chunks to write to the @@ -623,7 +712,7 @@ parts of the png_info are: appropriate PNG_INFO_ define. palette and num_palette - the palette for the file 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 hist - histogram of palette 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 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 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 these, but if you wish to fill in the png_time structure directly, you should provide the time in universal time (GMT) if possible -instead of your local time. Note that the year number is the full -year number (ie 1995 rather than 95). - -Since the CREATION time of an image is somewhat ambiguous, it is not -sensible to store an exact time like the tIME chunk above (ie when was -a scanned photo of neanderthal art created?). However, a text chunk -with a "Created" keyword can hold this information, in a form which is -useful (ie "Painted circa 40000 BC, photographed 1971, scanned 1996"). +instead of your local time. 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(). - 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 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 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. 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: - void *row_pointers[height]; + png_bytef *row_pointers[height]; 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 row_pointers: - char *row_pointers = row; + png_bytep row_pointers = row; 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 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: @@ -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, adding new transformations, and generally changing how libpng works. -All of the memory allocation in libpng is done in pngmem.c. Memory -allocation is done through the functions png_large_malloc(), png_malloc(), -png_realloc(), png_large_free(), and png_free(). These currently just -call the standard C functions. The large functions must handle at least -64K, but they don't have to handle more then that. If your pointers can't -access more then 64K at a time, you will want to set MAXSEG_64K in zlib.h. +All of the memory allocation, input/output, and error handling in libpng +goes through callbacks which are user setable. The default routines +are in pngerror.c, pngmem.c, and pngio.c. To change these functions, +call the approprate fn function. -Since it is unlikely that the method of handling memory allocation on a -platform will change between applications, these functions must be modified -or replaced to change their behaviour. If you only need to add new tests or -flags to have the compiler choose the correct function calls, please forward -these changes to the libpng author, so they can be added into the library -for the benefit of others. +Memory allocation is done through the functions png_large_malloc(), +png_malloc(), png_realloc(), png_large_free(), and png_free(). +These currently just call the standard C functions. The large +functions must handle exactly 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. -All of the input/output, and error handling in libpng go through the -routines in pngio.c by default. The file has plenty of comments describing -each function and how it expects to work. It is possible to supply different -I/O and error handling methods at run time with the png_set_msg_fn(), -png_set_read_fn(), and png_set_write_fn() calls. +Input/Output in libpng is done throught png_read() and png_write(), which +currently just call fread() and fwrite(). The FILE * is stored in +png_struct, and is initialized via png_init_io(). If you wish to change +this, the library supplies callbacks that you can set through the +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(), -which currently just call fread() and fwrite(). The error and warning -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(). + png_set_read_fn(png_structp png_ptr, voidp io_ptr, + png_rw_ptr read_data_fn) -If you wish to change some or all of these functions, it is possible to -do so at runtime, and without modifying the libpng library code. The -application must supply replacement functions which have the same arguments -and are functionally equivalent to the default functions. If you are -replacing both the I/O and message functions, the call to png_init_io() -is not needed. + png_set_write_fn(png_structp png_ptr, voidp io_ptr, + png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn); -Error handling in libpng is done through png_error() and png_warning() by -default. Errors handled through png_error() are fatal, meaning that -png_error() should never return to it's caller. Currently, this is handled -via setjmp() and longjmp(), but you could change this to do things like + voidp io_ptr = png_get_io_ptr(png_ptr); + +Note that you can pass NULL for the flush function if you are not doing +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() 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 @@ -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 a longjmp, so the user may want to be careful about doing anything after 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); - 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); + png_voidp msg_ptr = png_get_msg_ptr(png_ptr); 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 @@ -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. 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. -More details can be found in the comments inside the code. If you are -truly ambitious, you can modify the libpng code to handle unknown chunks -in a general way and send the code to the libpng author. +More details can be found in the comments inside the code. If you wish to write your own transformation for the data, look through the part of the code that does the transformations, and check @@ -963,21 +983,32 @@ itself. Configuring for 16 bit platforms: -You will probably need to change the png_large_malloc() and -png_large_free() routines in pngmem.c, as these are required +You will may need to change the png_large_malloc() and +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 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 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: -You will need to supply new message display functions for png_error() and -png_warning() (through png_set_message_fn() to display a message in a window -instead of fprinting it to stderr. You may want to write a single function -to do this and call it something like png_message() (although the error -function should still call longjmp or otherwise handle the error without -returning). +You will need to change the error message display in png_error() and +png_warning() to display a message instead of fprinting it to stderr. +You may want to write a single function to do this and call it something +like png_message(). On some compliers, you may have to change the +memory allocators (png_malloc, etc.). + Configuring for compiler xxx: @@ -989,13 +1020,15 @@ files in libpng proper only include png.h. 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 -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 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 are building a stand alone library, all the reading files start with 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 -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 + diff --git a/lpfaq.txt b/lpfaq.txt deleted file mode 100644 index 11b95e3b..00000000 --- a/lpfaq.txt +++ /dev/null @@ -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 diff --git a/makefile b/makefile index 96e19c66..b7d7c269 100644 --- a/makefile +++ b/makefile @@ -2,26 +2,25 @@ # Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc. # For conditions of distribution and use, see copyright notice in png.h -CC=gcc -CFLAGS=-I../zlib -O2 -Wall -ansi -pedantic +CC=cc +CFLAGS=-I../zlib -O LDFLAGS=-L. -L../zlib/ -lpng -lz -lm -RANLIB=ranlib -#RANLIB=echo +#RANLIB=ranlib +RANLIB=echo # 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 \ pngread.o pngio.o pngwrite.o pngrtran.o pngwtran.o \ - pngmem.o + pngmem.o pngerror.o pngpread.o all: libpng.a pngtest libpng.a: $(OBJS) ar rc $@ $(OBJS) $(RANLIB) $@ - rcp libpng.a vlsi:bin/lib/libpng.a pngtest: pngtest.o libpng.a $(CC) -o pngtest $(CCFLAGS) pngtest.o $(LDFLAGS) @@ -45,6 +44,7 @@ clean: # DO NOT DELETE THIS LINE -- make depend depends on it. png.o: png.h pngconf.h +pngerror.o: png.h pngconf.h pngio.o: png.h pngconf.h pngmem.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 pngwtran.o: png.h pngconf.h pngwutil.o: png.h pngconf.h +pngpread.o: png.h pngconf.h diff --git a/png.c b/png.c index d0afd9a9..a6600cf8 100644 --- a/png.c +++ b/png.c @@ -1,10 +1,10 @@ /* 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 Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. - August 24, 1995 + December 19, 1995 */ #define PNG_INTERNAL @@ -13,123 +13,127 @@ /* version information for c files. This better match the version 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. */ -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, add a string holding the name here. If you want to make the code portable to EBCDIC machines, use ASCII numbers, not characters. */ -png_byte png_IHDR[4] = { 73, 72, 68, 82}; -png_byte png_IDAT[4] = { 73, 68, 65, 84}; -png_byte png_IEND[4] = { 73, 69, 78, 68}; -png_byte png_PLTE[4] = { 80, 76, 84, 69}; +png_byte FARDATA png_IHDR[4] = { 73, 72, 68, 82}; +png_byte FARDATA png_IDAT[4] = { 73, 68, 65, 84}; +png_byte FARDATA png_IEND[4] = { 73, 69, 78, 68}; +png_byte FARDATA png_PLTE[4] = { 80, 76, 84, 69}; #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* 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 */ -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 */ -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 */ -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 */ /* this is not currently used - if you need it, uncomment it here and 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 */ /* this is not currently used - if you need it, uncomment it here and 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 */ -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 */ -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 -png_check_sig(png_byte *sig, int num) +png_check_sig(png_bytep sig, int num) { - if (num > 8) + if (num > 8) num = 8; if (num < 1) return 0; - return (!memcmp(sig, png_sig, num)); + return (!png_memcmp(sig, png_sig, num)); } /* Function to allocate memory for zlib. */ voidpf png_zalloc(voidpf png_ptr, uInt items, uInt size) { - return ((voidpf)png_large_malloc((png_struct FAR *)png_ptr, - (png_uint_32)items * (png_uint_32)size)); + voidp * ptr; + + 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 */ void 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 in case crc is > 32 bits to leave the top bits 0 */ void -png_reset_crc(png_struct *png_ptr) +png_reset_crc(png_structp png_ptr) { /* set crc to all 1's */ png_ptr->crc = 0xffffffffL; } /* Note: the crc code below was copied from the sample code in the - PNG spec, with appropriate modifications made to ensure the - variables are large enough */ + PNG spec, with appropriate modifications made to ensure the + variables are large enough */ /* 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(). @@ -161,10 +165,10 @@ make_crc_table(void) initialized to all 1's, and the transmitted value is the 1's complement of the final running crc. */ 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_bytef *p; + png_bytep p; png_uint_32 n; c = crc; @@ -178,7 +182,7 @@ update_crc(png_uint_32 crc, png_bytef *buf, png_uint_32 len) 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); 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 need this, put huge here and above. */ 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_ptr->crc = update_crc(png_ptr->crc, ptr, length); } void -png_info_init(png_info *info) +png_info_init(png_infop info) { /* set everything to 0 */ - memset(info, 0, sizeof (png_info)); + png_memset(info, 0, sizeof (png_info)); } diff --git a/png.h b/png.h index f359e34e..35e20cc0 100644 --- a/png.h +++ b/png.h @@ -1,12 +1,12 @@ /* png.h - header file for png reference library - libpng 1.0 beta 2 - version 0.81 - August 24, 1995 + libpng 1.0 beta 2 - version 0.85 + December 19, 1995 Note: This is a beta version. It reads and writes valid files on the platforms I have, but it has had limited portability - testing. Furthermore, you will probably have to modify the + testing. Furthermore, you will may have to modify the includes below to get it to work on your system, and you may have to supply the correct compiler flags in the makefile. Read the readme.txt for more information, and how to contact @@ -16,7 +16,7 @@ See readme.txt for more information Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. - Contributing Authors: + Contributing Authors: Dave Martindale Guy Eric Schalnat Paul Schmidt @@ -34,16 +34,16 @@ to the following restrictions: 1. The origin of this source code must not be misrepresented. 2. Altered versions must be plainly marked as such and must not be - misrepresented as being the original source. - 3. This Copyright notice may not be removed or altered from any source or - altered source distribution. + misrepresented as being the original source. + 3. This Copyright notice may not be removed or altered from any source or + altered source distribution. - The Contributing Authors and Group 42, Inc. specifically permit, without - fee, and encourage the use of this source code as a component to - supporting the PNG file format in commercial products. If you use this - source code in a product, acknowledgment is not required but would be - appreciated. - */ + The Contributing Authors and Group 42, Inc. specifically permit, without + fee, and encourage the use of this source code as a component to + supporting the PNG file format in commercial products. If you use this + source code in a product, acknowledgment is not required but would be + appreciated. + */ #ifndef _PNG_H #define _PNG_H @@ -63,14 +63,14 @@ the functions most users will use. The third section describes the stub files that users will most likely need to change. The last section contains functions used internally by the code. - */ + */ /* version information for png.h - this should match the version number in png.c */ -#define PNG_LIBPNG_VER_STRING "0.81" -/* careful here. I wanted to use 081, but that would be octal. Version +#define PNG_LIBPNG_VER_STRING "0.85" +/* careful here. I wanted to use 085, but that would be octal. Version 1.0 will be 100 here, etc. */ -#define PNG_LIBPNG_VER 81 +#define PNG_LIBPNG_VER 85 /* variables defined in png.c - only it needs to define PNG_NO_EXTERN */ #ifndef PNG_NO_EXTERN @@ -83,15 +83,17 @@ extern char png_libpng_ver[]; exact size) is not important, although the size of the fields need to be png_byte or png_uint_16 (as defined below). While png_color_8 and png_color_16 have more fields then they need, they are never used in - arrays, so the size isn't that important. I thought about using + arrays, so the size isn't that important. I thought about using unions, but it looked too clumsy, so I left it. If you're using C++, you can union red, index, and gray, if you really want too. */ typedef struct png_color_struct { - png_byte red; + png_byte red; png_byte green; png_byte blue; } png_color; +typedef png_color FAR * png_colorp; +typedef png_color FAR * FAR * png_colorpp; typedef struct png_color_16_struct { @@ -99,8 +101,10 @@ typedef struct png_color_16_struct png_uint_16 red; /* for use in red green blue files */ png_uint_16 green; png_uint_16 blue; - png_uint_16 gray; /* for use in grayscale files */ + png_uint_16 gray; /* for use in grayscale files */ } png_color_16; +typedef png_color_16 FAR * png_color_16p; +typedef png_color_16 FAR * FAR * png_color_16pp; typedef struct png_color_8_struct { @@ -110,16 +114,20 @@ typedef struct png_color_8_struct png_byte gray; /* for use in grayscale files */ png_byte alpha; /* for alpha channel files */ } png_color_8; +typedef png_color_8 FAR * png_color_8p; +typedef png_color_8 FAR * FAR * png_color_8pp; /* png_text holds the text in a png file, and whether they are compressed or not. If compression is -1, the text is not compressed. */ typedef struct png_text_struct { int compression; /* compression value, -1 if uncompressed */ - charf *key; /* keyword */ - charf *text; /* comment */ - png_uint_32 text_length; /* length of text field */ + png_charp key; /* keyword */ + png_charp text; /* comment */ + png_uint_32 text_length; /* length of text field */ } png_text; +typedef png_text FAR * png_textp; +typedef png_text FAR * FAR * png_textpp; /* png_time is a way to hold the time in an machine independent way. Two conversions are provided, both from time_t and struct tm. There @@ -133,8 +141,10 @@ typedef struct png_time_struct png_byte day; /* day of month, 1 - 31 */ png_byte hour; /* hour of day, 0 - 23 */ png_byte minute; /* minute of hour, 0 - 59 */ - png_byte second; /* second of minute, 0 - 60 (for leap seconds) */ + png_byte second; /* second of minute, 0 - 60 (for leap seconds) */ } png_time; +typedef png_time FAR * png_timep; +typedef png_time FAR * FAR * png_timepp; /* png_info is a structure that holds the information in a png file. If you are reading the file, This structure will tell you what is @@ -145,12 +155,12 @@ typedef struct png_time_struct about the meaning of each field. */ typedef struct png_info_struct { - /* the following are necessary for every png file */ + /* the following are necessary for every png file */ png_uint_32 width; /* with of file */ png_uint_32 height; /* height of file */ png_byte bit_depth; /* 1, 2, 4, 8, or 16 */ - png_byte color_type; /* use the PNG_COLOR_TYPE_ defines */ - png_byte compression_type; /* must be 0 */ + png_byte color_type; /* use the PNG_COLOR_TYPE_ defines */ + png_byte compression_type; /* must be 0 */ png_byte filter_type; /* must be 0 */ png_byte interlace_type; /* 0 for non-interlaced, 1 for interlaced */ png_uint_32 valid; /* the PNG_INFO_ defines, OR'd together */ @@ -163,15 +173,15 @@ typedef struct png_info_struct /* the rest are optional. If you are reading, check the valid field to see if the information in these are valid. If you are writing, set the valid field to those chunks you want - written, and initialize the appropriate fields below */ + written, and initialize the appropriate fields below */ #if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED) float gamma; /* gamma value of file, if gAMA chunk is valid */ #endif #if defined(PNG_READ_sBIT_SUPPORTED) || defined(PNG_WRITE_sBIT_SUPPORTED) - png_color_8 sig_bit; /* significant bits */ + png_color_8 sig_bit; /* significant bits */ #endif #if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED) - float x_white; /* cHRM chunk values */ + float x_white; /* cHRM chunk values */ float y_white; float x_red; float y_red; @@ -180,22 +190,22 @@ typedef struct png_info_struct float x_blue; float y_blue; #endif - png_color *palette; /* palette of file */ - png_uint_16 num_palette; /* number of values in palette */ + png_colorp palette; /* palette of file */ + png_uint_16 num_palette; /* number of values in palette */ png_uint_16 num_trans; /* number of trans values */ #if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED) - png_byte *trans; /* tRNS values for palette image */ - png_color_16 trans_values; /* tRNS values for non-palette image */ + png_bytep trans; /* tRNS values for palette image */ + png_color_16 trans_values; /* tRNS values for non-palette image */ #endif #if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED) - png_color_16 background; /* background color of image */ + png_color_16 background; /* background color of image */ #endif #if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED) - png_uint_16 *hist; /* histogram of palette usage */ + png_uint_16p hist; /* histogram of palette usage */ #endif #if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED) - png_uint_32 x_pixels_per_unit; /* x resolution */ + png_uint_32 x_pixels_per_unit; /* x resolution */ png_uint_32 y_pixels_per_unit; /* y resolution */ png_byte phys_unit_type; /* resolution type */ #endif @@ -208,12 +218,14 @@ typedef struct png_info_struct png_time mod_time; /* modification time */ #endif #if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \ - defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) - int num_text; /* number of comments */ + defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) + int num_text; /* number of comments */ int max_text; /* size of text array */ - png_text *text; /* array of comments */ + png_textp text; /* array of comments */ #endif } png_info; +typedef png_info FAR * png_infop; +typedef png_info FAR * FAR * png_infopp; #define PNG_RESOLUTION_UNKNOWN 0 #define PNG_RESOLUTION_METER 1 @@ -238,7 +250,7 @@ typedef struct png_info_struct #define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA) /* These determine if a chunks information is present in a read operation, or - if the chunk should be written in a write operation. */ + if the chunk should be written in a write operation. */ #define PNG_INFO_gAMA 0x0001 #define PNG_INFO_sBIT 0x0002 #define PNG_INFO_cHRM 0x0004 @@ -250,129 +262,170 @@ typedef struct png_info_struct #define PNG_INFO_oFFs 0x0100 #define PNG_INFO_tIME 0x0200 +/* these determine if a function in the info needs freed */ +#define PNG_FREE_PALETTE 0x0001 +#define PNG_FREE_HIST 0x0002 + /* this is used for the transformation routines, as some of them - change these values for the row. It also should enable using + change these values for the row. It also should enable using the routines for other uses. */ typedef struct png_row_info_struct { - png_uint_32 width; /* width of row */ - png_uint_32 rowbytes; /* number of bytes in row */ - png_byte color_type; /* color type of row */ - png_byte bit_depth; /* bit depth of row */ - png_byte channels; /* number of channels (1, 2, 3, or 4) */ - png_byte pixel_depth; /* bits per pixel (depth * channels) */ + png_uint_32 width; /* width of row */ + png_uint_32 rowbytes; /* number of bytes in row */ + png_byte color_type; /* color type of row */ + png_byte bit_depth; /* bit depth of row */ + png_byte channels; /* number of channels (1, 2, 3, or 4) */ + png_byte pixel_depth; /* bits per pixel (depth * channels) */ } png_row_info; -/* The structure that holds the information to read and write png files. - The only people who need to care about what is inside of this are the - people who will be modifying the library for their own special needs. - */ -typedef struct png_struct_def png_struct; -typedef png_struct FAR png_structf; +typedef png_row_info FAR * png_row_infop; +typedef png_row_info FAR * FAR * png_row_infopp; /* These are the function types for the I/O functions, and the functions which * modify the default I/O functions to user I/O functions. The png_msg_ptr * type should match that of user supplied warning and error functions, while * the png_rw_ptr type should match that of the user read/write data functions. */ -typedef void (*png_msg_ptr) PNGARG((png_struct *, char *)); -typedef void (*png_rw_ptr) PNGARG((png_struct *, png_bytef *, png_uint_32)); -typedef void (*png_flush_ptr) PNGARG((png_struct *)); +typedef struct png_struct_def png_struct; +typedef png_struct FAR * png_structp; -struct png_struct_def +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +typedef void (*png_msg_ptr) PNGARG((png_structp, png_const_charp)); +typedef void (*png_rw_ptr) PNGARG((png_structp, png_bytep, png_uint_32)); +typedef void (*png_flush_ptr) PNGARG((png_structp)); +typedef void (*png_progressive_info_ptr) PNGARG((png_structp, png_infop)); +typedef void (*png_progressive_end_ptr) PNGARG((png_structp, png_infop)); +typedef void (*png_progressive_row_ptr) PNGARG((png_structp, png_bytep, + png_uint_32, int)); +#endif + +/* The structure that holds the information to read and write png files. + The only people who need to care about what is inside of this are the + people who will be modifying the library for their own special needs. + */ + +typedef struct png_struct_def { - jmp_buf jmpbuf; /* used in png_error */ - png_byte mode; /* used to determine where we are in the png file */ + jmp_buf jmpbuf; /* used in png_error */ + png_byte mode; /* used to determine where we are in the png file */ + png_byte read_mode; png_byte color_type; /* color type of file */ png_byte bit_depth; /* bit depth of file */ png_byte interlaced; /* interlace type of file */ png_byte compession; /* compression type of file */ png_byte filter; /* filter type */ - png_byte channels; /* number of channels in file */ + png_byte channels; /* number of channels in file */ png_byte pixel_depth; /* number of bits per pixel */ png_byte usr_bit_depth; /* bit depth of users row */ png_byte usr_channels; /* channels at start of write */ #if defined(PNG_READ_GAMMA_SUPPORTED) png_byte gamma_shift; /* amount of shift for 16 bit gammas */ #endif - png_byte pass; /* current pass (0 - 6) */ + png_byte pass; /* current pass (0 - 6) */ png_byte row_init; /* 1 if png_read_start_row() has been called */ #if defined(PNG_READ_BACKGROUND_SUPPORTED) - png_byte background_gamma_type; + png_byte background_gamma_type; png_byte background_expand; #endif png_byte zlib_finished; png_byte user_palette; #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) png_byte filler; - png_byte filler_loc; + png_byte filler_loc; +#endif + png_byte zlib_custom_level; /* one if custom compression level */ + png_byte zlib_custom_method; /* one if custom compression method */ + png_byte zlib_custom_window_bits; /* one if custom compression window bits */ + png_byte zlib_custom_mem_level; /* one if custom compression memory level */ + png_byte zlib_custom_strategy; /* one if custom compression strategy */ + png_byte do_filter; /* one if filtering, zero if not */ + png_byte do_custom_filter; /* one if filtering, zero if not */ +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + png_byte have_chunk_header; #endif - png_byte zlib_custom_level; /* one if custom compression level */ - png_byte zlib_custom_method; /* one if custom compression method */ - png_byte zlib_custom_window_bits; /* one if custom compression window bits */ - png_byte zlib_custom_mem_level; /* one if custom compression memory level */ - png_byte zlib_custom_strategy; /* one if custom compression strategy */ - png_byte do_filter; /* one if filtering, zero if not */ - png_byte do_custom_filter; /* one if filtering, zero if not */ png_uint_16 num_palette; /* number of entries in palette */ png_uint_16 num_trans; /* number of transparency values */ int zlib_level; /* holds zlib compression level */ int zlib_method; /* holds zlib compression method */ - int zlib_window_bits; /* holds zlib compression window bits */ + int zlib_window_bits; /* holds zlib compression window bits */ int zlib_mem_level; /* holds zlib compression memory level */ - int zlib_strategy; /* holds zlib compression strategy */ - png_uint_32 transformations; /* which transformations to perform */ - png_uint_32 crc; /* current crc value */ - png_uint_32 width; /* width of file */ - png_uint_32 height; /* height of file */ - png_uint_32 num_rows; /* number of rows in current pass */ -#if defined(PNG_WRITE_FLUSH_SUPPORTED) - png_uint_32 flush_dist; /* how many rows apart to flush, 0 for no flush */ - png_uint_32 flush_rows; /* number of rows written since last flush */ -#endif /* PNG_WRITE_FLUSH_SUPPORTED */ - png_uint_32 rowbytes; /* size of row in bytes */ - png_uint_32 usr_width; /* width of row at start of write */ - png_uint_32 iwidth; /* interlaced width */ + int zlib_strategy; /* holds zlib compression strategy */ +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + int process_mode; + int cur_palette; +#endif + png_uint_32 transformations; /* which transformations to perform */ + png_uint_32 crc; /* current crc value */ + png_uint_32 width; /* width of file */ + png_uint_32 height; /* height of file */ + png_uint_32 num_rows; /* number of rows in current pass */ + png_uint_32 rowbytes; /* size of row in bytes */ + png_uint_32 usr_width; /* width of row at start of write */ + png_uint_32 iwidth; /* interlaced width */ png_uint_32 irowbytes; /* interlaced rowbytes */ png_uint_32 row_number; /* current row in pass */ - png_uint_32 idat_size; /* current idat size for read */ - png_uint_32 zbuf_size; /* size of zbuf */ - png_color *palette; /* files palette */ - png_uint_32 do_free; /* flags indicating if libpng should free memory */ + png_uint_32 idat_size; /* current idat size for read */ + png_uint_32 zbuf_size; /* size of zbuf */ + png_uint_32 do_free; /* flags indicating if libpng should free memory */ +#if defined(PNG_WRITE_FLUSH_SUPPORTED) + png_uint_32 flush_dist; /* how many rows apart to flush, 0 for no flush */ + png_uint_32 flush_rows; /* number of rows written since last flush */ +#endif /* PNG_WRITE_FLUSH_SUPPORTED */ +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + png_uint_32 push_length; + png_uint_32 skip_length; + png_uint_32 save_buffer_size; + png_uint_32 save_buffer_max; + png_uint_32 buffer_size; + png_uint_32 current_buffer_size; +#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED) + png_uint_32 current_text_size; + png_uint_32 current_text_left; + png_charp current_text; + png_charp current_text_ptr; +#endif + png_byte push_chunk_name[4]; + png_bytep save_buffer_ptr; + png_bytep save_buffer; + png_bytep current_buffer_ptr; + png_bytep current_buffer; +#endif + png_colorp palette; /* files palette */ #if defined(PNG_READ_DITHER_SUPPORTED) - png_bytef *palette_lookup; /* lookup table for dithering */ + png_bytep palette_lookup; /* lookup table for dithering */ #endif #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - png_byte *gamma_table; /* gamma table for 8 bit depth files */ -#endif -#if defined(PNG_READ_GAMMA_SUPPORTED) - png_byte *gamma_from_1; /* converts from 1.0 to screen */ - png_byte *gamma_to_1; /* converts from file to 1.0 */ + png_bytep gamma_table; /* gamma table for 8 bit depth files */ #endif #if defined(PNG_READ_BACKGROUND_SUPPORTED) - png_byte *trans; /* transparency values for paletted files */ + png_bytep gamma_from_1; /* converts from 1.0 to screen */ + png_bytep gamma_to_1; /* converts from file to 1.0 */ +#endif +#if defined(PNG_READ_BACKGROUND_SUPPORTED) + png_bytep trans; /* transparency values for paletted files */ #endif #if defined(PNG_READ_DITHER_SUPPORTED) - png_byte *dither_index; /* index translation for palette files */ + png_bytep dither_index; /* index translation for palette files */ #endif #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - png_uint_16 **gamma_16_table; /* gamma table for 16 bit depth files */ + png_uint_16pp gamma_16_table; /* gamma table for 16 bit depth files */ #endif #if defined(PNG_READ_BACKGROUND_SUPPORTED) - png_uint_16 **gamma_16_from_1; /* converts from 1.0 to screen */ - png_uint_16 **gamma_16_to_1; /* converts from file to 1.0 */ + png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */ + png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */ #endif #if defined(PNG_READ_DITHER_SUPPORTED) - png_uint_16 *hist; /* histogram */ + png_uint_16p hist; /* histogram */ #endif - png_bytef *zbuf; /* buffer for zlib */ - png_bytef *row_buf; /* row buffer */ - png_bytef *prev_row; /* previous row */ - png_bytef *save_row; /* place to save row before filtering */ - z_stream *zstream; /* pointer to decompression structure (below) */ + png_bytep zbuf; /* buffer for zlib */ + png_bytep row_buf; /* row buffer */ + png_bytep prev_row; /* previous row */ + png_bytep save_row; /* place to save row before filtering */ + z_stream * zstream; /* pointer to decompression structure (below) */ #if defined(PNG_READ_GAMMA_SUPPORTED) - float gamma; /* file gamma value */ - float display_gamma; /* display gamma value */ + float gamma; /* file gamma value */ + float display_gamma; /* display gamma value */ #endif #if defined(PNG_READ_BACKGROUND_SUPPORTED) float background_gamma; @@ -381,114 +434,121 @@ struct png_struct_def png_color_8 shift; /* shift for significant bit tranformation */ #endif #if defined(PNG_READ_GAMMA_SUPPORTED) || defined (PNG_READ_sBIT_SUPPORTED) - png_color_8 sig_bit; /* significant bits in file */ + png_color_8 sig_bit; /* significant bits in file */ #endif #if defined(PNG_READ_BACKGROUND_SUPPORTED) png_color_16 trans_values; /* transparency values for non-paletted files */ - png_color_16 background; /* background color, gamma corrected for screen */ + png_color_16 background; /* background color, gamma corrected for screen */ #if defined(PNG_READ_GAMMA_SUPPORTED) png_color_16 background_1; /* background normalized to gamma 1.0 */ #endif #endif png_row_info row_info; /* used for transformation routines */ - z_stream zstream_struct; /* decompression structure */ - FILE *fp; /* used for default png_read and png_write */ - png_msg_ptr error_fn; /* Function for printing errors and aborting */ - png_msg_ptr warning_fn; /* Function for printing warnings */ - png_rw_ptr write_data_fn; /* Function for writing output data */ - png_rw_ptr read_data_fn; /* Function for reading input data */ + FILE *fp; /* used for default png_read and png_write */ + png_msg_ptr error_fn; /* Function for printing errors and aborting */ + png_msg_ptr warning_fn; /* Function for printing warnings */ + png_rw_ptr write_data_fn; /* Function for writing output data */ + png_rw_ptr read_data_fn; /* Function for reading input data */ #if defined(PNG_WRITE_FLUSH_SUPPORTED) - png_flush_ptr output_flush_fn;/* Function for flushing output */ + png_flush_ptr output_flush_fn;/* Function for flushing output */ #endif /* PNG_WRITE_FLUSH_SUPPORTED */ - void *io_ptr; /* Pointer to user supplied struct for I/O functions */ - void *msg_ptr; /* Pointer to user supplied struct for message functions */ +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + png_progressive_info_ptr info_fn; + png_progressive_row_ptr row_fn; + png_progressive_end_ptr end_fn; + png_voidp push_ptr; +#endif + png_voidp io_ptr; /* Pointer to user supplied struct for I/O functions */ + png_voidp msg_ptr; /* Pointer to user supplied struct for message functions */ }; +typedef png_struct FAR * FAR * png_structpp; + /* Here are the function definitions most commonly used. This is not - the place to find out how to use libpng. See libpng.txt for the - full explanation, see example.c for the summary. This just provides - a simple one line of the use of each function. */ + the place to find out how to use libpng. See libpng.txt for the + full explanation, see example.c for the summary. This just provides + a simple one line of the use of each function. */ /* check the first 1 - 8 bytes to see if it is a png file */ -extern int png_check_sig PNGARG((png_byte *sig, int num)); +extern int png_check_sig PNGARG((png_bytep sig, int num)); /* initialize png structure for reading, and allocate any memory needed */ -extern void png_read_init PNGARG((png_struct *png_ptr)); +extern void png_read_init PNGARG((png_structp png_ptr)); /* initialize png structure for writing, and allocate any memory needed */ -extern void png_write_init PNGARG((png_struct *png_ptr)); +extern void png_write_init PNGARG((png_structp png_ptr)); /* initialize the info structure */ -extern void png_info_init PNGARG((png_info *info)); +extern void png_info_init PNGARG((png_infop info)); /* Writes all the png information before the image. */ -extern void png_write_info PNGARG((png_struct *png_ptr, png_info *info)); +extern void png_write_info PNGARG((png_structp png_ptr, png_infop info)); /* read the information before the actual image data. */ -extern void png_read_info PNGARG((png_struct *png_ptr, png_info *info)); +extern void png_read_info PNGARG((png_structp png_ptr, png_infop info)); #if defined(PNG_WRITE_tIME_SUPPORTED) /* convert from a struct tm to png_time */ -extern void png_convert_from_struct_tm PNGARG((png_time *ptime, - struct tm *ttime)); +extern void png_convert_from_struct_tm PNGARG((png_timep ptime, + struct tm FAR * ttime)); /*SJT: struct tm FAR *tttime ??? */ /* convert from time_t to png_time. Uses gmtime() */ -extern void png_convert_from_time_t PNGARG((png_time *ptime, time_t ttime)); +extern void png_convert_from_time_t PNGARG((png_timep ptime, time_t ttime)); #endif #if defined(PNG_READ_EXPAND_SUPPORTED) /* Expand the data to 24 bit RGB, or 8 bit Grayscale, with alpha if necessary. */ -extern void png_set_expand PNGARG((png_struct *png_ptr)); +extern void png_set_expand PNGARG((png_structp png_ptr)); #endif #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) /* Use blue, green, red order for pixels. */ -extern void png_set_bgr PNGARG((png_struct *png_ptr)); +extern void png_set_bgr PNGARG((png_structp png_ptr)); #endif #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) #define PNG_FILLER_BEFORE 0 #define PNG_FILLER_AFTER 1 /* Add a filler byte to rgb images. */ -extern void png_set_filler PNGARG((png_struct *png_ptr, int filler, +extern void png_set_filler PNGARG((png_structp png_ptr, int filler, int filler_loc)); /* old ways of doing this, still supported through 1.x for backwards compatability, but not suggested */ /* Add a filler byte to rgb images after the colors. */ -extern void png_set_rgbx PNGARG((png_struct *png_ptr)); +extern void png_set_rgbx PNGARG((png_structp png_ptr)); /* Add a filler byte to rgb images before the colors. */ -extern void png_set_xrgb PNGARG((png_struct *png_ptr)); +extern void png_set_xrgb PNGARG((png_structp png_ptr)); #endif #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) /* Swap bytes in 16 bit depth files. */ -extern void png_set_swap PNGARG((png_struct *png_ptr)); +extern void png_set_swap PNGARG((png_structp png_ptr)); #endif #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) /* Use 1 byte per pixel in 1, 2, or 4 bit depth files. */ -extern void png_set_packing PNGARG((png_struct *png_ptr)); +extern void png_set_packing PNGARG((png_structp png_ptr)); #endif #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) /* Converts files to legal bit depths. */ -extern void png_set_shift PNGARG((png_struct *png_ptr, - png_color_8 *true_bits)); +extern void png_set_shift PNGARG((png_structp png_ptr, + png_color_8p true_bits)); #endif #if defined(PNG_READ_INTERLACING_SUPPORTED) || \ defined(PNG_WRITE_INTERLACING_SUPPORTED) /* Have the code handle the interlacing. Returns the number of passes. */ -extern int png_set_interlace_handling PNGARG((png_struct *png_ptr)); +extern int png_set_interlace_handling PNGARG((png_structp png_ptr)); #endif #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) /* Invert monocrome files */ -extern void png_set_invert_mono PNGARG((png_struct *png_ptr)); +extern void png_set_invert_mono PNGARG((png_structp png_ptr)); #endif #if defined(PNG_READ_BACKGROUND_SUPPORTED) @@ -497,156 +557,181 @@ extern void png_set_invert_mono PNGARG((png_struct *png_ptr)); #define PNG_BACKGROUND_GAMMA_FILE 1 #define PNG_BACKGROUND_GAMMA_UNIQUE 2 #define PNG_BACKGROUND_GAMMA_UNKNOWN 3 -extern void png_set_background PNGARG((png_struct *png_ptr, - png_color_16 *background_color, int background_gamma_code, +extern void png_set_background PNGARG((png_structp png_ptr, + png_color_16p background_color, int background_gamma_code, int need_expand, double background_gamma)); #endif #if defined(PNG_READ_16_TO_8_SUPPORTED) /* strip the second byte of information from a 16 bit depth file. */ -extern void png_set_strip_16 PNGARG((png_struct *png_ptr)); +extern void png_set_strip_16 PNGARG((png_structp png_ptr)); #endif -#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) +#if defined(PNG_GRAY_TO_RGB_SUPPORTED) /* convert a grayscale file into rgb. */ -extern void png_set_gray_to_rgb PNGARG((png_struct *png_ptr)); +extern void png_set_gray_to_rgb PNGARG((png_structp png_ptr)); #endif #if defined(PNG_READ_DITHER_SUPPORTED) /* Turn on dithering, and reduce the palette to the number of colors available. */ -extern void png_set_dither PNGARG((png_struct *png_ptr, png_color *palette, - int num_palette, int maximum_colors, png_uint_16 *histogram, int full_dither)); +extern void png_set_dither PNGARG((png_structp png_ptr, png_colorp palette, + int num_palette, int maximum_colors, png_uint_16p histogram, + int full_dither)); #endif #if defined(PNG_READ_GAMMA_SUPPORTED) /* Handle gamma correction. */ -extern void png_set_gamma PNGARG((png_struct *png_ptr, double screen_gamma, +extern void png_set_gamma PNGARG((png_structp png_ptr, double screen_gamma, double default_file_gamma)); #endif #if defined(PNG_WRITE_FLUSH_SUPPORTED) /* Set how many lines between output flushes - 0 for no flushing */ -extern void png_set_flush PNGARG((png_struct *png_ptr, int nrows)); +extern void png_set_flush PNGARG((png_structp png_ptr, int nrows)); /* Flush the current PNG output buffer */ -extern void png_write_flush PNGARG((png_struct *png_ptr)); +extern void png_write_flush PNGARG((png_structp png_ptr)); #endif /* PNG_WRITE_FLUSH_SUPPORTED */ /* optional update palette with requested transformations */ -extern void png_start_read_image PNGARG((png_struct *png_ptr)); +extern void png_start_read_image PNGARG((png_structp png_ptr)); /* optional call to update the users info structure */ -extern void png_read_update_info PNGARG((png_struct *png_ptr, - png_info *info_ptr)); +extern void png_read_update_info PNGARG((png_structp png_ptr, + png_infop info_ptr)); /* read a one or more rows of image data.*/ -extern void png_read_rows PNGARG((png_struct *png_ptr, - png_bytef **row, - png_byte **display_row, png_uint_32 num_rows)); +extern void png_read_rows PNGARG((png_structp png_ptr, + png_bytepp row, + png_bytepp display_row, png_uint_32 num_rows)); /* read a row of data.*/ -extern void png_read_row PNGARG((png_struct *png_ptr, - png_bytef *row, - png_byte *display_row)); +extern void png_read_row PNGARG((png_structp png_ptr, + png_bytep row, + png_bytep display_row)); /* read the whole image into memory at once. */ -extern void png_read_image PNGARG((png_struct *png_ptr, - png_bytef **image)); +extern void png_read_image PNGARG((png_structp png_ptr, + png_bytepp image)); /* write a row of image data */ -extern void png_write_row PNGARG((png_struct *png_ptr, - png_bytef *row)); +extern void png_write_row PNGARG((png_structp png_ptr, + png_bytep row)); /* write a few rows of image data */ -extern void png_write_rows PNGARG((png_struct *png_ptr, - png_bytef **row, +extern void png_write_rows PNGARG((png_structp png_ptr, + png_bytepp row, png_uint_32 num_rows)); /* write the image data */ -extern void png_write_image PNGARG((png_struct *png_ptr, png_bytef **image)); +extern void png_write_image PNGARG((png_structp png_ptr, png_bytepp image)); /* writes the end of the png file. */ -extern void png_write_end PNGARG((png_struct *png_ptr, png_info *info)); +extern void png_write_end PNGARG((png_structp png_ptr, png_infop info)); /* read the end of the png file. */ -extern void png_read_end PNGARG((png_struct *png_ptr, png_info *info)); +extern void png_read_end PNGARG((png_structp png_ptr, png_infop info)); /* free all memory used by the read */ -extern void png_read_destroy PNGARG((png_struct *png_ptr, png_info *info, - png_info *end_info)); +extern void png_read_destroy PNGARG((png_structp png_ptr, png_infop info, + png_infop end_info)); /* free any memory used in png struct */ -extern void png_write_destroy PNGARG((png_struct *png_ptr)); +extern void png_write_destroy PNGARG((png_structp png_ptr)); /* These functions give the user control over the filtering and compression libraries used by zlib. These functions are mainly useful for testing, as the defaults should work with most users. - Those users who are tight on memory, or are wanting faster + Those users who are tight on memory, or are wanting faster performance at the expense of compression can modify them. See the compression library header file for an explination of these functions */ -extern void png_set_filtering PNGARG((png_struct *png_ptr, int filter)); +extern void png_set_filtering PNGARG((png_structp png_ptr, int filter)); -extern void png_set_compression_level PNGARG((png_struct *png_ptr, +extern void png_set_compression_level PNGARG((png_structp png_ptr, int level)); -extern void png_set_compression_mem_level PNGARG((png_struct *png_ptr, +extern void png_set_compression_mem_level PNGARG((png_structp png_ptr, int mem_level)); -extern void png_set_compression_strategy PNGARG((png_struct *png_ptr, +extern void png_set_compression_strategy PNGARG((png_structp png_ptr, int strategy)); -extern void png_set_compression_window_bits PNGARG((png_struct *png_ptr, +extern void png_set_compression_window_bits PNGARG((png_structp png_ptr, int window_bits)); -extern void png_set_compression_method PNGARG((png_struct *png_ptr, +extern void png_set_compression_method PNGARG((png_structp png_ptr, int method)); -/* These next functions are prototypes of the functions libpng uses for - memory allocation. */ +/* These next functions are stubs of typical c functions for input/output, + memory, and error handling. They are in the file pngstub.c, and are + set up to be easily modified for users that need to. See the file + pngstub.c for more information */ -/* Allocate memory in larger chunks. */ -extern voidpf png_large_malloc PNGARG((png_structf *png_ptr, png_uint_32 size)); +/* Write the data to whatever output you are using. */ +extern void png_write_data PNGARG((png_structp png_ptr, png_bytep data, + png_uint_32 length)); + +/* Read data from whatever input you are using */ +extern void png_read_data PNGARG((png_structp png_ptr, png_bytep data, + png_uint_32 length)); + +/* Initialize the input/output for the png file. */ +extern void png_init_io PNGARG((png_structp png_ptr, FILE *fp)); + +/* Replace the error message and abort, and warning functions with user + supplied functions. If no messages are to be printed, NULL can be + supplied for error_fn and warning_fn, although error_fn will still do + a longjmp to the last setjmp location. */ +extern void png_set_message_fn PNGARG((png_structp png_ptr, png_voidp msg_ptr, + png_msg_ptr error_fn, png_msg_ptr warning_fn)); + +/* Return the user pointer associated with the message functions */ +extern png_voidp png_get_msg_ptr PNGARG((png_structp png_ptr)); + +/* Replace the default data output functions with a user supplied one(s). + If buffered output is not used, then output_flush_fn can be set to NULL. + if PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time + output_flush_fn will be ignored (and thus can be NULL). */ +extern void png_set_write_fn PNGARG((png_structp png_ptr, png_voidp io_ptr, + png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); + +/* Replace the default data input function with a user supplied one. */ +extern void png_set_read_fn PNGARG((png_structp png_ptr, void *io_ptr, + png_rw_ptr read_data_fn)); + +/* Return the user pointer associated with the I/O functions */ +extern png_voidp png_get_io_ptr PNGARG((png_structp png_ptr)); + +/* Replace the default push model read functions */ +extern void png_set_push_fn PNGARG((png_structp png_ptr, png_voidp push_ptr, + png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, + png_progressive_end_ptr end_fn)); + +/* returns the user pointer assiciated with the push read functions */ +extern void * png_get_progressive_ptr PNGARG((png_structp png_ptr)); + +extern png_voidp png_large_malloc PNGARG((png_structp png_ptr, + png_uint_32 size)); /* free's a pointer allocated by png_large_malloc() */ -extern void png_large_free PNGARG((png_structf *png_ptr, voidpf ptr)); +extern void png_large_free PNGARG((png_structp png_ptr, png_voidp ptr)); /* Allocate memory. */ -extern void *png_malloc PNGARG((png_struct *png_ptr, png_uint_32 size)); +extern png_voidp png_malloc PNGARG((png_structp png_ptr, png_uint_32 size)); /* Reallocate memory. */ -extern void *png_realloc PNGARG((png_struct *png_ptr, void *ptr, +extern png_voidp png_realloc PNGARG((png_structp png_ptr, png_voidp ptr, png_uint_32 size, png_uint_32 old_size)); /* free's a pointer allocated by png_malloc() */ -extern void png_free PNGARG((png_struct *png_ptr, void *ptr)); +extern void png_free PNGARG((png_structp png_ptr, png_voidp ptr)); -/* Initialize the I/O and message handling for the png file to the defaults. */ -extern void png_init_io PNGARG((png_struct *png_ptr, FILE *fp)); +/* Fatal error in libpng - can't continue */ +extern void png_error PNGARG((png_structp png_ptr, png_const_charp error)); -/* Replace the error message and abort, and warning functions with user - supplied functions. If no messages are to be printed, NULL can be - supplied for error_fn and warning_fn, although error_fn will still do - a longjmp to the last setjmp location. */ -extern void png_set_msg_fn PNGARG((png_struct *png_ptr, void *msg_ptr, - png_msg_ptr error_fn, png_msg_ptr warning_fn)); - -/* Return the user pointer associated with the message functions */ -extern void *png_get_msg_ptr PNGARG((png_struct *png_ptr)); - -/* Replace the default data output functions with a user supplied one(s). - If buffered output is not used, then output_flush_fn can be set to NULL. - if PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time - output_flush_fn will be ignored (but must be supplied for compatability). */ -extern void png_set_write_fn PNGARG((png_struct *png_ptr, void *io_ptr, - png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); - -/* Replace the default data input function with a user supplied one. */ -extern void png_set_read_fn PNGARG((png_struct *png_ptr, void *io_ptr, - png_rw_ptr read_data_fn)); - -/* Return the user pointer associated with the I/O functions */ -extern void *png_get_io_ptr PNGARG((png_struct *png_ptr)); +/* Non-fatal error in libpng. Can continue, but may have a problem. */ +extern void png_warning PNGARG((png_structp png_ptr, png_const_charp message)); /* These next functions are used internally in the code. If you use them, make sure you read and understand the png spec. More information @@ -668,6 +753,22 @@ extern void *png_get_io_ptr PNGARG((png_struct *png_ptr)); #define PNG_AFTER_IDAT 5 #define PNG_AFTER_IEND 6 +/* push model modes */ +#define PNG_READ_SIG_MODE 0 +#define PNG_READ_CHUNK_MODE 1 +#define PNG_READ_IDAT_MODE 2 +#define PNG_READ_PLTE_MODE 3 +#define PNG_READ_END_MODE 4 +#define PNG_SKIP_MODE 5 +#define PNG_READ_tEXt_MODE 6 +#define PNG_READ_zTXt_MODE 7 +#define PNG_READ_DONE_MODE 8 +#define PNG_ERROR_MODE 9 + +/* read modes */ +#define PNG_READ_PULL_MODE 0 +#define PNG_READ_PUSH_MODE 1 + /* defines for the transformations the png library does on the image data */ #define PNG_BGR 0x0001 #define PNG_INTERLACE 0x0002 @@ -685,11 +786,6 @@ extern void *png_get_io_ptr PNGARG((png_struct *png_ptr)); #define PNG_GRAY_TO_RGB 0x2000 #define PNG_FILLER 0x4000 -/* defines for memory alloced by libpng which should be freed */ -#define PNG_FREE_TRANS 0x0001 -#define PNG_FREE_HIST 0x0002 -#define PNG_FREE_PALETTE 0x0004 - /* save typing and make code easier to understand */ #define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \ abs((int)((c1).green) - (int)((c2).green)) + \ @@ -705,54 +801,54 @@ extern char png_libpng_ver[]; /* constant strings for known chunk types. If you need to add a chunk, add a string holding the name here. See png.c for more details */ -extern png_byte png_IHDR[]; -extern png_byte png_IDAT[]; -extern png_byte png_IEND[]; -extern png_byte png_PLTE[]; +extern png_byte FARDATA png_IHDR[]; +extern png_byte FARDATA png_IDAT[]; +extern png_byte FARDATA png_IEND[]; +extern png_byte FARDATA png_PLTE[]; #if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED) -extern png_byte png_gAMA[]; +extern png_byte FARDATA png_gAMA[]; #endif #if defined(PNG_READ_sBIT_SUPPORTED) || defined(PNG_WRITE_sBIT_SUPPORTED) -extern png_byte png_sBIT[]; +extern png_byte FARDATA png_sBIT[]; #endif #if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED) -extern png_byte png_cHRM[]; +extern png_byte FARDATA png_cHRM[]; #endif #if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED) -extern png_byte png_tRNS[]; +extern png_byte FARDATA png_tRNS[]; #endif #if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED) -extern png_byte png_bKGD[]; +extern png_byte FARDATA png_bKGD[]; #endif #if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED) -extern png_byte png_hIST[]; +extern png_byte FARDATA png_hIST[]; #endif #if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) -extern png_byte png_tEXt[]; +extern png_byte FARDATA png_tEXt[]; #endif #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) -extern png_byte png_zTXt[]; +extern png_byte FARDATA png_zTXt[]; #endif #if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED) -extern png_byte png_pHYs[]; +extern png_byte FARDATA png_pHYs[]; #endif #if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED) -extern png_byte png_oFFs[]; +extern png_byte FARDATA png_oFFs[]; #endif #if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED) -extern png_byte png_tIME[]; +extern png_byte FARDATA png_tIME[]; #endif /* Structures to facilitate easy interlacing. See png.c for more details */ -extern int png_pass_start[]; -extern int png_pass_inc[]; -extern int png_pass_ystart[]; -extern int png_pass_yinc[]; +extern int FARDATA png_pass_start[]; +extern int FARDATA png_pass_inc[]; +extern int FARDATA png_pass_ystart[]; +extern int FARDATA png_pass_yinc[]; /* these are not currently used. If you need them, see png.c -extern int png_pass_width[]; -extern int png_pass_height[]; +extern int FARDATA png_pass_width[]; +extern int FARDATA png_pass_height[]; */ -extern int png_pass_mask[]; -extern int png_pass_dsp_mask[]; +extern int FARDATA png_pass_mask[]; +extern int FARDATA png_pass_dsp_mask[]; #endif /* PNG_NO_EXTERN */ @@ -763,389 +859,453 @@ extern voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size)); extern void png_zfree PNGARG((voidpf png_ptr, voidpf ptr)); /* reset the crc variable */ -extern void png_reset_crc PNGARG((png_struct *png_ptr)); +extern void png_reset_crc PNGARG((png_structp png_ptr)); /* calculate the crc over a section of data. Note that while we are passing in a 32 bit value for length, on 16 bit machines, you would need to use huge pointers to access all that data. See the code in png.c for more information. */ -extern void png_calculate_crc PNGARG((png_struct *png_ptr, png_bytef *ptr, - png_uint_32 length)); +extern void png_calculate_crc PNGARG((png_structp png_ptr, png_bytep ptr, + png_uint_32 length)); + +/* default error and warning functions if user doesn't supply them */ +extern void png_default_warning PNGARG((png_structp png_ptr, png_const_charp message)); +extern void png_default_error PNGARG((png_structp png_ptr, png_const_charp error)); +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +extern void png_flush PNGARG((png_struct *png_ptr)); +extern void png_default_flush PNGARG((png_struct *png_ptr)); +#endif /* place a 32 bit number into a buffer in png byte order. We work - with unsigned numbers for convenience, you may have to cast - signed numbers (if you use any, most png data is unsigned). */ -extern void png_save_uint_32 PNGARG((png_byte *buf, png_uint_32 i)); + with unsigned numbers for convenience, you may have to cast + signed numbers (if you use any, most png data is unsigned). */ +extern void png_save_uint_32 PNGARG((png_bytep buf, png_uint_32 i)); /* place a 16 bit number into a buffer in png byte order */ -extern void png_save_uint_16 PNGARG((png_byte *buf, png_uint_16 i)); +extern void png_save_uint_16 PNGARG((png_bytep buf, png_uint_16 i)); /* write a 32 bit number */ -extern void png_write_uint_32 PNGARG((png_struct *png_ptr, png_uint_32 i)); +extern void png_write_uint_32 PNGARG((png_structp png_ptr, png_uint_32 i)); /* write a 16 bit number */ -extern void png_write_uint_16 PNGARG((png_struct *png_ptr, png_uint_16 i)); +extern void png_write_uint_16 PNGARG((png_structp png_ptr, png_uint_16 i)); /* Write a png chunk. */ -extern void png_write_chunk PNGARG((png_struct *png_ptr, png_byte *type, - png_bytef *data, png_uint_32 length)); +extern void png_write_chunk PNGARG((png_structp png_ptr, png_bytep type, + png_bytep data, png_uint_32 length)); /* Write the start of a png chunk. */ -extern void png_write_chunk_start PNGARG((png_struct *png_ptr, png_byte *type, - png_uint_32 total_length)); +extern void png_write_chunk_start PNGARG((png_structp png_ptr, png_bytep type, + png_uint_32 total_length)); /* write the data of a png chunk started with png_write_chunk_start(). */ -extern void png_write_chunk_data PNGARG((png_struct *png_ptr, png_bytef *data, - png_uint_32 length)); +extern void png_write_chunk_data PNGARG((png_structp png_ptr, png_bytep data, + png_uint_32 length)); /* finish a chunk started with png_write_chunk_start() */ -extern void png_write_chunk_end PNGARG((png_struct *png_ptr)); +extern void png_write_chunk_end PNGARG((png_structp png_ptr)); /* simple function to write the signiture */ -extern void png_write_sig PNGARG((png_struct *png_ptr)); +extern void png_write_sig PNGARG((png_structp png_ptr)); /* write various chunks */ /* Write the IHDR chunk, and update the png_struct with the necessary - information. */ -extern void png_write_IHDR PNGARG((png_struct *png_ptr, png_uint_32 width, - png_uint_32 height, - int bit_depth, int color_type, int compression_type, int filter_type, - int interlace_type)); + information. */ +extern void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width, + png_uint_32 height, + int bit_depth, int color_type, int compression_type, int filter_type, + int interlace_type)); -extern void png_write_PLTE PNGARG((png_struct *png_ptr, png_color *palette, - int number)); +extern void png_write_PLTE PNGARG((png_structp png_ptr, png_colorp palette, + int number)); -extern void png_write_IDAT PNGARG((png_struct *png_ptr, png_bytef *data, - png_uint_32 length)); +extern void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data, + png_uint_32 length)); -extern void png_write_IEND PNGARG((png_struct *png_ptr)); +extern void png_write_IEND PNGARG((png_structp png_ptr)); #if defined(PNG_WRITE_gAMA_SUPPORTED) -extern void png_write_gAMA PNGARG((png_struct *png_ptr, float gamma)); +extern void png_write_gAMA PNGARG((png_structp png_ptr, double gamma)); #endif #if defined(PNG_WRITE_sBIT_SUPPORTED) -extern void png_write_sBIT PNGARG((png_struct *png_ptr, png_color_8 *sbit, - int color_type)); +extern void png_write_sBIT PNGARG((png_structp png_ptr, png_color_8p sbit, + int color_type)); #endif #if defined(PNG_WRITE_cHRM_SUPPORTED) -extern void png_write_cHRM PNGARG((png_struct *png_ptr, - float white_x, float white_y, - float red_x, float red_y, float green_x, float green_y, - float blue_x, float blue_y)); +extern void png_write_cHRM PNGARG((png_structp png_ptr, + double white_x, double white_y, + double red_x, double red_y, double green_x, double green_y, + double blue_x, double blue_y)); #endif #if defined(PNG_WRITE_tRNS_SUPPORTED) -extern void png_write_tRNS PNGARG((png_struct *png_ptr, png_byte *trans, - png_color_16 *values, int number, int color_type)); +extern void png_write_tRNS PNGARG((png_structp png_ptr, png_bytep trans, + png_color_16p values, int number, int color_type)); #endif #if defined(PNG_WRITE_bKGD_SUPPORTED) -extern void png_write_bKGD PNGARG((png_struct *png_ptr, png_color_16 *values, +extern void png_write_bKGD PNGARG((png_structp png_ptr, png_color_16p values, int color_type)); #endif #if defined(PNG_WRITE_hIST_SUPPORTED) -extern void png_write_hIST PNGARG((png_struct *png_ptr, png_uint_16 *hist, - int number)); +extern void png_write_hIST PNGARG((png_structp png_ptr, png_uint_16p hist, + int number)); #endif #if defined(PNG_WRITE_tEXt_SUPPORTED) -extern void png_write_tEXt PNGARG((png_struct *png_ptr, charf *key, - charf *text, png_uint_32 text_len)); +extern void png_write_tEXt PNGARG((png_structp png_ptr, png_charp key, + png_charp text, png_uint_32 text_len)); #endif #if defined(PNG_WRITE_zTXt_SUPPORTED) -extern void png_write_zTXt PNGARG((png_struct *png_ptr, charf *key, - charf *text, png_uint_32 text_len, int compression)); +extern void png_write_zTXt PNGARG((png_structp png_ptr, png_charp key, + png_charp text, png_uint_32 text_len, int compression)); #endif #if defined(PNG_WRITE_pHYs_SUPPORTED) -extern void png_write_pHYs PNGARG((png_struct *png_ptr, - png_uint_32 x_pixels_per_unit, - png_uint_32 y_pixels_per_unit, - int unit_type)); +extern void png_write_pHYs PNGARG((png_structp png_ptr, + png_uint_32 x_pixels_per_unit, + png_uint_32 y_pixels_per_unit, + int unit_type)); #endif #if defined(PNG_WRITE_oFFs_SUPPORTED) -extern void png_write_oFFs PNGARG((png_struct *png_ptr, - png_uint_32 x_offset, +extern void png_write_oFFs PNGARG((png_structp png_ptr, + png_uint_32 x_offset, png_uint_32 y_offset, int unit_type)); #endif #if defined(PNG_WRITE_tIME_SUPPORTED) -extern void png_write_tIME PNGARG((png_struct *png_ptr, png_time *mod_time)); +extern void png_write_tIME PNGARG((png_structp png_ptr, png_timep mod_time)); #endif /* Internal use only. Called when finished processing a row of data */ -extern void png_write_finish_row PNGARG((png_struct *png_ptr)); +extern void png_write_finish_row PNGARG((png_structp png_ptr)); /* Internal use only. Called before first row of data */ -extern void png_write_start_row PNGARG((png_struct *png_ptr)); +extern void png_write_start_row PNGARG((png_structp png_ptr)); /* callbacks for png chunks */ -extern void png_read_IHDR PNGARG((png_struct *png_ptr, png_info *info, +extern void png_read_IHDR PNGARG((png_structp png_ptr, png_infop info, 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)); -extern void png_read_PLTE PNGARG((png_struct *png_ptr, png_info *info, - png_color *palette, int num)); +extern void png_read_PLTE PNGARG((png_structp png_ptr, png_infop info, + png_colorp palette, int num)); #if defined(PNG_READ_gAMA_SUPPORTED) -extern void png_read_gAMA PNGARG((png_struct *png_ptr, png_info *info, - float gamma)); +extern void png_read_gAMA PNGARG((png_structp png_ptr, png_infop info, + double gamma)); #endif #if defined(PNG_READ_sBIT_SUPPORTED) -extern void png_read_sBIT PNGARG((png_struct *png_ptr, png_info *info, - png_color_8 *sig_bit)); +extern void png_read_sBIT PNGARG((png_structp png_ptr, png_infop info, + png_color_8p sig_bit)); #endif #if defined(PNG_READ_cHRM_SUPPORTED) -extern void png_read_cHRM PNGARG((png_struct *png_ptr, png_info *info, - float white_x, float white_y, float red_x, float red_y, - float green_x, float green_y, float blue_x, float blue_y)); +extern void png_read_cHRM PNGARG((png_structp png_ptr, png_infop info, + double white_x, double white_y, double red_x, double red_y, + double green_x, double green_y, double blue_x, double blue_y)); #endif #if defined(PNG_READ_tRNS_SUPPORTED) -extern void png_read_tRNS PNGARG((png_struct *png_ptr, png_info *info, - png_byte *trans, int num_trans, png_color_16 *trans_values)); +extern void png_read_tRNS PNGARG((png_structp png_ptr, png_infop info, + png_bytep trans, int num_trans, png_color_16p trans_values)); #endif #if defined(PNG_READ_bKGD_SUPPORTED) -extern void png_read_bKGD PNGARG((png_struct *png_ptr, png_info *info, - png_color_16 *background)); +extern void png_read_bKGD PNGARG((png_structp png_ptr, png_infop info, + png_color_16p background)); #endif #if defined(PNG_READ_hIST_SUPPORTED) -extern void png_read_hIST PNGARG((png_struct *png_ptr, png_info *info, - png_uint_16 *hist)); +extern void png_read_hIST PNGARG((png_structp png_ptr, png_infop info, + png_uint_16p hist)); #endif #if defined(PNG_READ_pHYs_SUPPORTED) -extern void png_read_pHYs PNGARG((png_struct *png_ptr, png_info *info, - png_uint_32 res_x, png_uint_32 res_y, int unit_type)); +extern void png_read_pHYs PNGARG((png_structp png_ptr, png_infop info, + png_uint_32 res_x, png_uint_32 res_y, int unit_type)); #endif #if defined(PNG_READ_oFFs_SUPPORTED) -extern void png_read_oFFs PNGARG((png_struct *png_ptr, png_info *info, - png_uint_32 offset_x, png_uint_32 offset_y, int unit_type)); +extern void png_read_oFFs PNGARG((png_structp png_ptr, png_infop info, + png_uint_32 offset_x, png_uint_32 offset_y, int unit_type)); #endif #if defined(PNG_READ_tIME_SUPPORTED) -extern void png_read_tIME PNGARG((png_struct *png_ptr, png_info *info, - png_time *mod_time)); +extern void png_read_tIME PNGARG((png_structp png_ptr, png_infop info, + png_timep mod_time)); #endif #if defined(PNG_READ_tEXt_SUPPORTED) -extern void png_read_tEXt PNGARG((png_struct *png_ptr, png_info *info, - charf *key, charf *text, png_uint_32 text_len)); +extern void png_read_tEXt PNGARG((png_structp png_ptr, png_infop info, + png_charp key, png_charp text, png_uint_32 text_len)); #endif #if defined(PNG_READ_zTXt_SUPPORTED) -extern void png_read_zTXt PNGARG((png_struct *png_ptr, png_info *info, - charf *key, charf *text, png_uint_32 text_len, int compression)); +extern void png_read_zTXt PNGARG((png_structp png_ptr, png_infop info, + png_charp key, png_charp text, png_uint_32 text_len, int compression)); #endif #if defined(PNG_READ_GAMMA_SUPPORTED) void -png_build_gamma_table PNGARG((png_struct *png_ptr)); +png_build_gamma_table PNGARG((png_structp png_ptr)); #endif /* combine a row of data, dealing with alpha, etc. if requested */ -extern void png_combine_row PNGARG((png_struct *png_ptr, png_bytef *row, +extern void png_combine_row PNGARG((png_structp png_ptr, png_bytep row, int mask)); #if defined(PNG_READ_INTERLACING_SUPPORTED) /* expand an interlaced row */ -extern void png_do_read_interlace PNGARG((png_row_info *row_info, - png_bytef *row, int pass)); +extern void png_do_read_interlace PNGARG((png_row_infop row_info, + png_bytep row, int pass)); #endif #if defined(PNG_WRITE_INTERLACING_SUPPORTED) /* grab pixels out of a row for an interlaced pass */ -extern void png_do_write_interlace PNGARG((png_row_info *row_info, - png_bytef *row, int pass)); +extern void png_do_write_interlace PNGARG((png_row_infop row_info, + png_bytep row, int pass)); #endif /* unfilter a row */ -extern void png_read_filter_row PNGARG((png_row_info *row_info, - png_bytef *row, png_bytef *prev_row, int filter)); +extern void png_read_filter_row PNGARG((png_row_infop row_info, + png_bytep row, png_bytep prev_row, int filter)); /* filter a row, and place the correct filter byte in the row */ -extern void png_write_filter_row PNGARG((png_row_info *row_info, - png_bytef *row, png_bytef *prev_row)); +extern void png_write_filter_row PNGARG((png_row_infop row_info, + png_bytep row, png_bytep prev_row)); /* finish a row while reading, dealing with interlacing passes, etc. */ -extern void png_read_finish_row PNGARG((png_struct *png_ptr)); +extern void png_read_finish_row PNGARG((png_structp png_ptr)); /* initialize the row buffers, etc. */ -extern void png_read_start_row PNGARG((png_struct *png_ptr)); +extern void png_read_start_row PNGARG((png_structp png_ptr)); /* optional call to update the users info structure */ -extern void png_read_transform_info PNGARG((png_struct *png_ptr, - png_info *info_ptr)); +extern void png_read_transform_info PNGARG((png_structp png_ptr, + png_infop info_ptr)); /* these are the functions that do the transformations */ #if defined(PNG_READ_FILLER_SUPPORTED) -extern void png_do_read_filler PNGARG((png_row_info *row_info, - png_bytef *row, png_byte filler, png_byte filler_loc)); +extern void png_do_read_filler PNGARG((png_row_infop row_info, + png_bytep row, png_byte filler, png_byte filler_loc)); #endif #if defined(PNG_WRITE_FILLER_SUPPORTED) -extern void png_do_write_filler PNGARG((png_row_info *row_info, - png_bytef *row, png_byte filler_loc)); +extern void png_do_write_filler PNGARG((png_row_infop row_info, + png_bytep row, png_byte filler_loc)); #endif #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) -extern void png_do_swap PNGARG((png_row_info *row_info, png_bytef *row)); +extern void png_do_swap PNGARG((png_row_infop row_info, png_bytep row)); #endif #if defined(PNG_READ_PACK_SUPPORTED) -extern void png_do_unpack PNGARG((png_row_info *row_info, png_bytef *row)); +extern void png_do_unpack PNGARG((png_row_infop row_info, png_bytep row)); #endif #if defined(PNG_READ_SHIFT_SUPPORTED) -extern void png_do_unshift PNGARG((png_row_info *row_info, png_bytef *row, - png_color_8 *sig_bits)); +extern void png_do_unshift PNGARG((png_row_infop row_info, png_bytep row, + png_color_8p sig_bits)); #endif #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) -extern void png_do_invert PNGARG((png_row_info *row_info, png_bytef *row)); +extern void png_do_invert PNGARG((png_row_infop row_info, png_bytep row)); #endif #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) -extern void png_do_gray_to_rgb PNGARG((png_row_info *row_info, - png_bytef *row)); +extern void png_do_gray_to_rgb PNGARG((png_row_infop row_info, + png_bytep row)); #endif #if defined(PNG_READ_16_TO_8_SUPPORTED) -extern void png_do_chop PNGARG((png_row_info *row_info, png_bytef *row)); +extern void png_do_chop PNGARG((png_row_infop row_info, png_bytep row)); #endif #if defined(PNG_READ_DITHER_SUPPORTED) -extern void png_do_dither PNGARG((png_row_info *row_info, - png_bytef *row, png_byte *palette_lookup, png_byte *dither_lookup)); +extern void png_do_dither PNGARG((png_row_infop row_info, + png_bytep row, png_bytep palette_lookup, png_bytep dither_lookup)); #endif #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) -extern void png_do_bgr PNGARG((png_row_info *row_info, png_bytef *row)); +extern void png_do_bgr PNGARG((png_row_infop row_info, png_bytep row)); #endif #if defined(PNG_WRITE_PACK_SUPPORTED) -extern void png_do_pack PNGARG((png_row_info *row_info, - png_bytef *row, png_byte bit_depth)); +extern void png_do_pack PNGARG((png_row_infop row_info, + png_bytep row, png_byte bit_depth)); #endif #if defined(PNG_WRITE_SHIFT_SUPPORTED) -extern void png_do_shift PNGARG((png_row_info *row_info, png_bytef *row, - png_color_8 *bit_depth)); +extern void png_do_shift PNGARG((png_row_infop row_info, png_bytep row, + png_color_8p bit_depth)); #endif #if defined(PNG_READ_BACKGROUND_SUPPORTED) -extern void png_do_background PNGARG((png_row_info *row_info, png_bytef *row, - png_color_16 *trans_values, png_color_16 *background, - png_color_16 *background_1, - png_byte *gamma_table, png_byte *gamma_from_1, png_byte *gamma_to_1, - png_uint_16 **gamma_16, png_uint_16 **gamma_16_from_1, - png_uint_16 **gamma_16_to_1, int gamma_shift)); +extern void png_do_background PNGARG((png_row_infop row_info, png_bytep row, + png_color_16p trans_values, png_color_16p background, + png_color_16p background_1, + png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1, + png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1, + png_uint_16pp gamma_16_to_1, int gamma_shift)); #endif #if defined(PNG_READ_GAMMA_SUPPORTED) -extern void png_do_gamma PNGARG((png_row_info *row_info, png_bytef *row, - png_byte *gamma_table, png_uint_16 **gamma_16_table, +extern void png_do_gamma PNGARG((png_row_infop row_info, png_bytep row, + png_bytep gamma_table, png_uint_16pp gamma_16_table, int gamma_shift)); #endif #if defined(PNG_READ_EXPAND_SUPPORTED) -extern void png_do_expand_palette PNGARG((png_row_info *row_info, - png_bytef *row, png_color *palette, png_byte *trans, int num_trans)); -extern void png_do_expand PNGARG((png_row_info *row_info, - png_bytef *row, png_color_16 *trans_value)); +extern void png_do_expand_palette PNGARG((png_row_infop row_info, + png_bytep row, png_colorp palette, png_bytep trans, int num_trans)); +extern void png_do_expand PNGARG((png_row_infop row_info, + png_bytep row, png_color_16p trans_value)); #endif /* unpack 16 and 32 bit values from a string */ -extern png_uint_32 png_get_uint_32 PNGARG((png_byte *buf)); -extern png_uint_16 png_get_uint_16 PNGARG((png_byte *buf)); +extern png_uint_32 png_get_uint_32 PNGARG((png_bytep buf)); +extern png_uint_16 png_get_uint_16 PNGARG((png_bytep buf)); /* read bytes into buf, and update png_ptr->crc */ -extern void png_crc_read PNGARG((png_struct *png_ptr, png_bytef *buf, +extern void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf, png_uint_32 length)); /* skip length bytes, and update png_ptr->crc */ -extern void png_crc_skip PNGARG((png_struct *png_ptr, png_uint_32 length)); +extern void png_crc_skip PNGARG((png_structp png_ptr, png_uint_32 length)); /* the following decodes the appropriate chunks, and does error correction, then calls the appropriate callback for the chunk if it is valid */ /* decode the IHDR chunk */ -extern void png_handle_IHDR PNGARG((png_struct *png_ptr, png_info *info, - png_uint_32 length)); -extern void png_handle_PLTE PNGARG((png_struct *png_ptr, png_info *info, +extern void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info, + png_uint_32 length)); +extern void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info, png_uint_32 length)); #if defined(PNG_READ_gAMA_SUPPORTED) -extern void png_handle_gAMA PNGARG((png_struct *png_ptr, png_info *info, +extern void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info, png_uint_32 length)); #endif #if defined(PNG_READ_sBIT_SUPPORTED) -extern void png_handle_sBIT PNGARG((png_struct *png_ptr, png_info *info, +extern void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info, png_uint_32 length)); #endif #if defined(PNG_READ_cHRM_SUPPORTED) -extern void png_handle_cHRM PNGARG((png_struct *png_ptr, png_info *info, +extern void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info, png_uint_32 length)); #endif #if defined(PNG_READ_tRNS_SUPPORTED) -extern void png_handle_tRNS PNGARG((png_struct *png_ptr, png_info *info, +extern void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info, png_uint_32 length)); #endif #if defined(PNG_READ_bKGD_SUPPORTED) -extern void png_handle_bKGD PNGARG((png_struct *png_ptr, png_info *info, +extern void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info, png_uint_32 length)); #endif #if defined(PNG_READ_hIST_SUPPORTED) -extern void png_handle_hIST PNGARG((png_struct *png_ptr, png_info *info, +extern void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info, png_uint_32 length)); #endif #if defined(PNG_READ_pHYs_SUPPORTED) -extern void png_handle_pHYs PNGARG((png_struct *png_ptr, png_info *info, +extern void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info, png_uint_32 length)); #endif #if defined(PNG_READ_oFFs_SUPPORTED) -extern void png_handle_oFFs PNGARG((png_struct *png_ptr, png_info *info, +extern void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info, png_uint_32 length)); #endif #if defined(PNG_READ_tIME_SUPPORTED) -extern void png_handle_tIME PNGARG((png_struct *png_ptr, png_info *info, +extern void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info, png_uint_32 length)); #endif #if defined(PNG_READ_tEXt_SUPPORTED) -extern void png_handle_tEXt PNGARG((png_struct *png_ptr, png_info *info, +extern void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info, png_uint_32 length)); #endif #if defined(PNG_READ_zTXt_SUPPORTED) -extern void png_handle_zTXt PNGARG((png_struct *png_ptr, png_info *info, +extern void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info, png_uint_32 length)); #endif /* handle the transformations for reading and writing */ -extern void png_do_read_transformations PNGARG((png_struct *png_ptr)); -extern void png_do_write_transformations PNGARG((png_struct *png_ptr)); +extern void png_do_read_transformations PNGARG((png_structp png_ptr)); +extern void png_do_write_transformations PNGARG((png_structp png_ptr)); -extern void png_init_read_transformations PNGARG((png_struct *png_ptr)); +extern void png_init_read_transformations PNGARG((png_structp png_ptr)); +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +extern void png_push_read_chunk PNGARG((png_structp png_ptr, png_infop info)); +extern void png_push_read_sig PNGARG((png_structp png_ptr)); +extern void png_push_check_crc PNGARG((png_structp png_ptr)); +extern void png_push_crc_skip PNGARG((png_structp png_ptr, png_uint_32 length)); +extern void png_push_skip PNGARG((png_structp png_ptr)); +extern void png_push_fill_buffer PNGARG((png_structp png_ptr, png_bytep buffer, + png_uint_32 length)); +extern void png_push_save_buffer PNGARG((png_structp png_ptr)); +extern void png_push_restore_buffer PNGARG((png_structp png_ptr, png_bytep buffer, + png_uint_32 buffer_length)); +extern void png_push_read_idat PNGARG((png_structp png_ptr)); +extern void png_process_IDAT_data PNGARG((png_structp png_ptr, + png_bytep buffer, png_uint_32 buffer_length)); +extern void png_push_process_row PNGARG((png_structp png_ptr)); +extern void png_push_handle_PLTE PNGARG((png_structp png_ptr, + png_infop info, png_uint_32 length)); +extern void png_push_read_plte PNGARG((png_structp png_ptr, png_infop info)); +extern void png_push_handle_tRNS PNGARG((png_structp png_ptr, png_infop info, + png_uint_32 length)); +extern void png_push_handle_hIST PNGARG((png_structp png_ptr, png_infop info, + png_uint_32 length)); +extern void png_push_handle_tEXt PNGARG((png_structp png_ptr, png_infop info, + png_uint_32 length)); +extern void png_push_handle_zTXt PNGARG((png_structp png_ptr, png_infop info, + png_uint_32 length)); +extern void png_push_have_info PNGARG((png_structp png_ptr, png_infop info)); +extern void png_push_have_end PNGARG((png_structp png_ptr, png_infop info)); +extern void png_push_have_row PNGARG((png_structp png_ptr, png_bytep row)); +extern void png_push_read_end PNGARG((png_structp png_ptr, png_infop info)); +extern void png_process_some_data PNGARG((png_structp png_ptr, + png_infop info)); +extern void png_read_push_finish_row PNGARG((png_structp png_ptr)); +#if defined(PNG_READ_tEXt_SUPPORTED) +extern void png_push_handle_tEXt PNGARG((png_structp png_ptr, png_infop info, + png_uint_32 length)); +extern void png_push_read_text PNGARG((png_structp png_ptr, png_infop info)); +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) +extern void png_push_handle_zTXt PNGARG((png_structp png_ptr, png_infop info, + png_uint_32 length)); +extern void png_push_read_ztxt PNGARG((png_structp png_ptr, png_infop info)); +#endif + +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ #endif /* PNG_INTERNAL */ +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +extern void png_process_data PNGARG((png_structp png_ptr, png_infop info, + png_bytep buffer, png_uint_32 buffer_size)); +extern void png_set_progressive_read_fn PNGARG((png_structp png_ptr, + png_voidp progressive_ptr, + png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, + png_progressive_end_ptr end_fn)); +extern void png_progressive_combine_row PNGARG((png_structp png_ptr, + png_bytep old_row, png_bytep new_row)); +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + /* do not put anything past this line */ #endif /* _PNG_H */ diff --git a/pngchang.txt b/pngchang.txt index 0b99e20f..6715e74d 100644 --- a/pngchang.txt +++ b/pngchang.txt @@ -56,15 +56,11 @@ version 0.8 enabled png_set_shift to work with paletted images on read added png_read_update_info() - updates info structure with transformations version 0.81 - added support for medium memory model -version 0.82 - added ability to flush output stream automatically or manually - added ability to change I/O and error functions dynamically - moved pngerror.c into pngio.c to make all the default functions static - when freeing memory in png_read_destroy don't free memory we didn't allocate - added warnings when reading blocks of incorrect length - limit tEXt and zTXt keywords to 80 chars - - + incorporated Tim Wegner's medium model code (thanks, Tim) +version 0.85 + added more medium model code (almost everythings a far) + added i/o, error, and memory callback functions + fixed some bugs (16 bit, 4 bit interlaced, etc.) + added first run progressive reader (barely tested) diff --git a/pngconf.h b/pngconf.h index 98917b46..81a95ec2 100644 --- a/pngconf.h +++ b/pngconf.h @@ -1,10 +1,10 @@ /* 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 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 @@ -27,7 +27,7 @@ Unless this gets smaller then the size of a row (compressed), 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 to stand on it's own. Towards this end, there are two defines that are @@ -48,6 +48,14 @@ #define PNG_MAX_ALLOC_64K #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 prototypes. If your compiler does not handle function prototypes, define this macro. I've always been able to use _NO_PROTO as the @@ -60,7 +68,7 @@ #else #ifdef _NO_PROTO -#define PNGARG(arglist) +#define PNGARG(arglist) () #else #define PNGARG(arglist) arglist #endif /* _NO_PROTO */ @@ -129,6 +137,19 @@ #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 from the library that you will not be using. I wish I 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 */ - +#define PNG_PROGRESSIVE_READ_SUPPORTED #define PNG_READ_INTERLACING_SUPPORTED #define PNG_READ_EXPAND_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) */ typedef size_t png_size_t; -/* The following is needed for medium model support. It cannot be in the - PNG_INTERNAL section. Needs modification for other compilers besides +/* The following is needed for medium model support. It cannot be in the + PNG_INTERNAL section. Needs modification for other compilers besides MSC. Model independent support declares all arrays that might be very 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 changes that are needed. Most of the far keyword changes are hidden inside typedefs with suffix "f". Tim Wegner */ -#if defined(FAR) && defined(M_I86MM) /* MSC Medium model */ -# define USE_FAR_KEYWORD +/* SJT: Separate compiler dependencies */ +/* SJT: problem here is that zlib.h always defines FAR */ +#ifdef __BORLANDC__ +#if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__) +#define LDATA 1 #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 #endif +/* SJT: At this point FAR is always defined */ + +/* not used anymore, but kept for compatability */ typedef unsigned char FAR png_bytef; +/* SJT: */ +#ifndef FARDATA +#define FARDATA +#endif + /* 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 that are passed far data must be model independent. */ #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_strlen _fstrlen # define png_strcmp _fstrcmp +# define png_memcmp _fmemcmp /* SJT: added */ # define png_memcpy _fmemcpy # define png_memset _fmemset #else /* use the usual functions */ @@ -247,11 +349,11 @@ typedef unsigned char FAR png_bytef; # define png_strcat strcat # define png_strlen strlen # define png_strcmp strcmp +# define png_memcmp memcmp /* SJT: added */ # define png_memcpy memcpy # define png_memset memset #endif /* End of memory model independent support */ - #endif /* PNGCONF_H */ diff --git a/pngerror.c b/pngerror.c new file mode 100644 index 00000000..1ea22217 --- /dev/null +++ b/pngerror.c @@ -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; +} + + + diff --git a/pngio.c b/pngio.c index 3a0eff89..f73c3b7c 100644 --- a/pngio.c +++ b/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 Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. - Some portions Copyright (C) 1995 Andreas Dilger - Sept 24, 1995 + December 19, 1995 This file provides a location for all input/output. Users which need - special handling are expected to write functions which have the same - arguments as these, and perform similar functions, but possibly have - different I/O methods. Note that you shouldn't change these functions, - but rather write replacement functions and then change them at run - time with png_set_write_fn(...) or png_set_read_fn(...), etc */ + special handling are expected to write functions which have the same + arguments as these, and perform similar functions, but possibly have + different I/O methods. Note that you shouldn't change these functions, + but rather write replacement functions and then change them at run + time with png_set_write_fn(...) or png_set_read_fn(...), etc */ +#define PNG_INTERNAL #include "png.h" - /* Write the data to whatever output you are using. The default 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 - sometimes gets called with very small lengths, so you should implement - some kind of simple buffering if you are using unbuffered writes. This - should never be asked to write more then 64K on a 16 bit machine. The - cast to png_size_t is there for insurance. */ + 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 + 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 + 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 -static void -png_write_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length) +void +png_default_write_data(png_structp png_ptr, png_bytep data, png_uint_32 length) { png_uint_32 check; check = fwrite(data, 1, (png_size_t)length, png_ptr->fp); 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 can't handle far buffers in the medium and small models, we have to copy - the data. + the data. */ #define NEAR_BUF_SIZE 1024 @@ -50,93 +59,114 @@ png_write_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length) #include #endif -static void -png_write_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length) +void +png_default_write_data(png_structp png_ptr, png_bytep data, png_uint_32 length) { png_uint_32 check; png_byte *n_data; - + /* Check if data really is near. If so, use usual code. */ #ifdef _MSC_VER - /* do it this way just to quiet warning */ - FP_OFF(n_data) = FP_OFF(data); - if(FP_SEG(n_data) == FP_SEG(data)) + /* do it this way just to quiet warning */ + FP_OFF(n_data) = FP_OFF(data); + if (FP_SEG(n_data) == FP_SEG(data)) #else - /* this works in MSC also but with lost segment warning */ - n_data = (png_byte *)data; - if((png_bytef *)n_data == data) -#endif + /* this works in MSC also but with lost segment warning */ + n_data = (png_byte *)data; + if ((png_bytep)n_data == data) +#endif { check = fwrite(n_data, 1, (png_size_t)length, png_ptr->fp); } - else + else { png_byte buf[NEAR_BUF_SIZE]; png_size_t written, remaining, err; check = 0; remaining = (png_size_t)length; - do - { - written = MIN(NEAR_BUF_SIZE,remaining); - png_memcpy(buf,data,written); /* copy far buffer to near buffer */ + do + { + written = MIN(NEAR_BUF_SIZE, remaining); + png_memcpy(buf, data, written); /* copy far buffer to near buffer */ err = fwrite(buf, 1, written, png_ptr->fp); - if(err != written) + if (err != written) break; - else - check += err; + else + check += err; data += written; remaining -= written; } - while(remaining != 0); - } - if (check != length) - { - (*(png_ptr->error_fn))(png_ptr, "Write error"); - } + while (remaining != 0); + } + if (check != length) + { + png_error(png_ptr, "Write Error"); + } } #endif - /* Read the data from whatever input you are using. The default 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 - sometimes gets called with very small lengths, so you should implement - some kind of simple buffering if you are using unbuffered reads. This - should never be asked to read more then 64K on a 16 bit machine. The - cast to png_size_t is there for insurance. */ + else, this is the place to do it. We suggest saving the old code + for future use. Note that this routine sometimes gets called with + very small lengths, so you should implement some kind of simple + buffering if you are using unbuffered reads. This should + never be asked to read more then 64K on a 16 bit machine. 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 -static void -png_read_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length) +void +png_default_read_data(png_structp png_ptr, png_bytep data, png_uint_32 length) { png_uint_32 check; check = fread(data, 1, (size_t)length, png_ptr->fp); if (check != length) { - (*(png_ptr->error_fn))(png_ptr, "Read error"); + png_error(png_ptr, "Read Error"); } } #else -static void -png_read_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length) +void +png_default_read_data(png_structp png_ptr, png_bytep data, png_uint_32 length) { png_uint_32 check; png_byte *n_data; - + /* Check if data really is near. If so, use usual code. */ #ifdef _MSC_VER /* do it this way just to quiet warning */ - FP_OFF(n_data) = FP_OFF(data); - if(FP_SEG(n_data) == FP_SEG(data)) + FP_OFF(n_data) = FP_OFF(data); + if (FP_SEG(n_data) == FP_SEG(data)) #else /* this works in MSC also but with lost segment warning */ - n_data = (png_byte *)data; - if((png_bytef *)n_data == data) -#endif + n_data = (png_byte *)data; + if ((PNG_BYTEP )n_data == data) +#endif { check = fread(n_data, 1, (size_t)length, png_ptr->fp); - } + } else { 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; do { - read = MIN(NEAR_BUF_SIZE,remaining); + read = MIN(NEAR_BUF_SIZE, remaining); 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) break; else - check += err; + check += err; data += read; - remaining -= read; - } - while(remaining != 0); - } - if (check != length) - { - (*(png_ptr->error_fn))(png_ptr, "Read error"); - } + remaining -= read; + } + while (remaining != 0); + } + if (check != length) + { + png_error(png_ptr, "read Error"); + } } #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) -/* This function does nothing, and is supplied for user I/O functions which - do not do any buffering. This function is set when NULL is supplied for - the flush function pointer. */ -static void -png_empty_flush(png_struct *png_ptr) +void +png_flush(png_struct *png_ptr) { + if (png_ptr->output_flush_fn) + (*(png_ptr->output_flush_fn))(png_ptr); } - -/* Write out any remaining output that is stored in the output buffers. - If you supply a new write routine, you will probably need to supply a - replacement for this routine as well. */ -static void -png_output_flush(png_struct *png_ptr) +void +png_default_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 -} - - -/* This function is called whenever there is an error. Replace with a - function you wish to handle the error. Note that this function - MUST NOT return, or the program will crash. To be consistent with - the examples for the library and this function, you could call - longjmp(pnt_ptr->jmpbuf) to return to the program at the location of - the last setjmp(png_ptr->jmpbuf) after an error. */ -static void -png_error(png_structf *png_ptr, char *message) -{ - fprintf(stderr, "libpng error: %s\n", message); - - png_empty_error(png_ptr, message); -} - - -/* This function does nothing, and is called if the user supplies null - when setting the warning function. */ -static void -png_empty_warning(png_struct *png_ptr, char *message) -{ -} - - -/* This function is called when there is a warning, but the library - thinks it can continue anyway. You don't have to do anything here - if you don't want to. In the default configuration, png_ptr is - not used, but it is passed in case it may be useful. */ -static void -png_warning(png_struct *png_ptr, char *message) -{ - fprintf(stderr, "libpng warning: %s\n", message); -} - /* This function allows the application to supply new output functions for - libpng if standard C streams aren't being used. The new write function - should call (*(png_ptr->error_fn))("Error message") to exit and output - any fatal error messages if it cannot output the correct number of bytes. - This function takes as its arguments: - png_ptr - pointer to a png output data structure - io_ptr - pointer to user supplied structure containing info about - the output functions. May be NULL. - write_data_fn - pointer to a new output function which takes as its - arguments a pointer to a png_struct, a pointer to - data to be written, and a 32-bit unsigned int which is - the number of bytes to be written. The new write - function should call (*(png_ptr->error_fn))("Error msg") - to exit and output any fatal error messages. - flush_data_fn - pointer to a new flush function which takes as its - arguments a pointer to a png_struct. After a call to - the flush function, there should be no data in any buffers - or pending transmission. If the output method doesn't do - any buffering of ouput, this parameter can be NULL. If - PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng - compile time, output_flush_fn will be ignored, although - it must be supplied for compatibility. */ + libpng if standard C streams aren't being used. + + This function takes as its arguments: + png_ptr - pointer to a png output data structure + io_ptr - pointer to user supplied structure containing info about + the output functions. May be NULL. + write_data_fn - pointer to a new output function which takes as its + arguments a pointer to a png_struct, a pointer to + data to be written, and a 32-bit unsigned int which is + the number of bytes to be written. The new write + function should call (*(png_ptr->error_fn))("Error msg") + to exit and output any fatal error messages. + flush_data_fn - pointer to a new flush function which takes as its + arguments a pointer to a png_struct. After a call to + the flush function, there should be no data in any buffers + or pending transmission. If the output method doesn't do + any buffering of ouput, this parameter can be NULL. If + PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng + compile time, output_flush_fn will be ignored, although + it must be supplied for compatibility. */ void -png_set_write_fn(png_struct *png_ptr, void *io_ptr, png_rw_ptr write_data_fn, - png_flush_ptr output_flush_fn) +png_set_write_fn(png_structp png_ptr, png_voidp io_ptr, png_rw_ptr write_data_fn, + png_flush_ptr output_flush_fn) { - png_ptr->io_ptr = io_ptr; + png_ptr->io_ptr = io_ptr; - if (write_data_fn == NULL) - { - (*(png_ptr->error_fn))(png_ptr, "NULL write function pointer given"); - } - - png_ptr->write_data_fn = write_data_fn; + if (write_data_fn) + png_ptr->write_data_fn = write_data_fn; + else + png_ptr->write_data_fn = png_default_write_data; #if defined(PNG_WRITE_FLUSH_SUPPORTED) - if (output_flush_fn == NULL) - { - png_ptr->output_flush_fn = png_empty_flush; - } - else - { - png_ptr->output_flush_fn = output_flush_fn; - } + if (output_flush_fn == NULL) + png_ptr->output_flush_fn = png_default_flush; + else + png_ptr->output_flush_fn = output_flush_fn; #endif /* PNG_WRITE_FLUSH_SUPPORTED */ - /* It is an error to write to a read device */ - png_ptr->read_data_fn = png_empty_rw; + /* It is an error to read while writing a png file */ + png_ptr->read_data_fn = NULL; } /* This function allows the application to supply a new input function - for libpng if standard C streams aren't being used. The new read function - should call (*(png_ptr->error_fn))("Error message") to exit and output - any fatal error messages if the desired number of bytes is not available. - This function takes as its arguments: - png_ptr - pointer to a png input data structure - io_ptr - pointer to user supplied structure containing info about - the input functions. May be NULL. - read_data_fn - pointer to a new input function which takes as it's - arguments a pointer to a png_struct, a pointer to - a location where input data can be stored, and a 32-bit - unsigned int which is the number of bytes to be read. */ + for libpng if standard C streams aren't being used. + + This function takes as its arguments: + png_ptr - pointer to a png input data structure + io_ptr - pointer to user supplied structure containing info about + the input functions. May be NULL. + read_data_fn - pointer to a new input function which takes as it's + arguments a pointer to a png_struct, a pointer to + a location where input data can be stored, and a 32-bit + unsigned int which is the number of bytes to be read. */ void png_set_read_fn(png_struct *png_ptr, void *io_ptr, png_rw_ptr read_data_fn) { - png_ptr->io_ptr = io_ptr; + png_ptr->io_ptr = io_ptr; - if (read_data_fn == NULL) - { - (*(png_ptr->error_fn))(png_ptr, "NULL read function pointer given"); - } - png_ptr->read_data_fn = read_data_fn; + if (read_data_fn) + png_ptr->read_data_fn = read_data_fn; + else + png_ptr->read_data_fn = png_default_read_data; - /* It is an error to write to a read device */ - png_ptr->write_data_fn = png_empty_rw; + /* It is an error to write to a read device */ + png_ptr->write_data_fn = NULL; #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 */ } /* This function returns a pointer to the io_ptr associated with the user - functions. The application should free any memory associated with this - pointer before png_write_destroy and png_read_destroy are called. */ + functions. The application should free any memory associated with this + pointer before png_write_destroy and png_read_destroy are called. */ void * png_get_io_ptr(png_struct *png_ptr) { - return png_ptr->io_ptr; + return png_ptr->io_ptr; } - -/* This function is called when the application wants to use another - method of handling errors and warnings. Note that the error function must - NOT return to the calling routine or serious problems will occur. The - error return method used in the default routine calls - longjmp(png_ptr->jmpbuf, 1), or exits if setjmp(png_ptr->jmpbuf) has never - been called. */ +/* Initialize the input/output for the png file. If you change + the read and write routines, you will probably need to change + this routine (or write your own). If you change the parameters + of this routine, remember to change png.h also. */ void -png_set_msg_fn(png_struct *png_ptr, void *msg_ptr, png_msg_ptr error_fn, - png_msg_ptr warning_fn) +png_init_io(png_structp png_ptr, FILE *fp) { - png_ptr->msg_ptr = msg_ptr; - - if (error_fn == NULL) - { - png_ptr->error_fn = png_empty_error; - } - else - { - png_ptr->error_fn = error_fn; - } - - if (warning_fn == NULL) - { - png_ptr->warning_fn = png_empty_warning; - } - else - { - png_ptr->warning_fn = warning_fn; - } + png_ptr->fp = fp; + png_ptr->read_data_fn = png_default_read_data; + png_ptr->write_data_fn = png_default_write_data; +#ifdef PNG_WRITE_FLUSH_SUPPORTED + png_ptr->output_flush_fn = png_default_flush; +#endif } - -/* 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 */ -} diff --git a/pngmem.c b/pngmem.c index 2ae261e7..d3ee01c7 100644 --- a/pngmem.c +++ b/pngmem.c @@ -1,13 +1,13 @@ /* 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 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 - 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. */ #define PNG_INTERNAL @@ -19,168 +19,28 @@ need to allocate exactly 64K, so whatever you call here must 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 */ -#define NUM_SEG 4 -typedef struct borland_seg_struct +png_voidp +png_large_malloc(png_structp png_ptr, png_uint_32 size) { - void *mem_ptr; - 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; + png_voidp ret; if (!png_ptr || !size) - return ((void *)0); + return ((voidp)0); #ifdef PNG_MAX_MALLOC_64K if (size > (png_uint_32)65536L) - (*(png_ptr->error_fn))(png_ptr, "Cannot Allocate > 64K"); + png_error(png_ptr, "Cannot Allocate > 64K"); #endif -#ifdef __TURBOC__ -# if defined(__WIN32__) || defined(__FLAT__) - ret = malloc(size); -# else - - 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 +#if defined(__TURBOC__) && !defined(__FLAT__) + ret = farmalloc(size); +#else + ret = malloc(size); #endif if (ret == NULL) { - (*(png_ptr->error_fn))(png_ptr, "Out of Memory"); + png_error(png_ptr, "Out of Memory"); } 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 is needed. If ptr is NULL, return without taking any action. */ void -png_large_free(png_structf *png_ptr, voidpf ptr) +png_large_free(png_structp png_ptr, png_voidp ptr) { if (!png_ptr) - return; + return; - if (ptr != (void *)0) + if (ptr != NULL) { -#ifdef __TURBOC__ -# if defined(__WIN32__) || defined(__FLAT__) - 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 +#if defined(__TURBOC__) && !defined(__FLAT__) + farfree(ptr); #else -# ifdef _MSC_VER - hfree(ptr); -# else - free(ptr); -# endif + free(ptr); #endif } } + /* 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 * -png_malloc(png_struct *png_ptr, png_uint_32 size) +png_malloc(png_structp png_ptr, png_uint_32 size) { void *ret; if (!png_ptr || !size) + { return ((void *)0); + } #ifdef PNG_MAX_MALLOC_64K if (size > (png_uint_32)65536L) - (*(png_ptr->error_fn))(png_ptr, "Cannot Allocate > 64K"); + png_error(png_ptr, "Cannot Allocate > 64K"); #endif + 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; } /* Reallocate memory. This will not get near 64K on a - even marginally reasonable file. */ + even marginally reasonable file. */ void * -png_realloc(png_struct *png_ptr, void *ptr, png_uint_32 size, - png_uint_32 old_size) +png_realloc(png_structp png_ptr, void * ptr, png_uint_32 size, + png_uint_32 old_size) { - void *ret; + void *ret; - if (!png_ptr || !old_size || !ptr || !size) - return ((void *)0); + if (!png_ptr || !old_size || !ptr || !size) + return ((void *)0); #ifdef PNG_MAX_MALLOC_64K - if (size > (png_uint_32)65536L) - (*(png_ptr->error_fn))(png_ptr, "Cannot Allocate > 64K"); + if (size > (png_uint_32)65536L) + png_error(png_ptr, "Cannot Allocate > 64K"); #endif - ret = realloc(ptr, (png_size_t)size); + ret = realloc(ptr, (png_size_t)size); - if (!ret) - { - (*(png_ptr->error_fn))(png_ptr, "Out of Memory 7"); - } + if (!ret) + { + png_error(png_ptr, "Out of Memory 7"); + } - return ret; + return ret; } /* free a pointer allocated by png_malloc(). In the default configuration, png_ptr is not used, but is passed incase it is needed. If ptr is NULL, return without taking any action. */ void -png_free(png_struct *png_ptr, void *ptr) +png_free(png_structp png_ptr, void * ptr) { - if (!png_ptr) - return; + if (!png_ptr) + return; - if (ptr != (void *)0) - free(ptr); + if (ptr != (void *)0) + free(ptr); } + diff --git a/pngpread.c b/pngpread.c new file mode 100644 index 00000000..6369f6e7 --- /dev/null +++ b/pngpread.c @@ -0,0 +1,1214 @@ + +/* pngpread.c - read a png file in push mode + + 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 + */ + +#define PNG_INTERNAL +#include "png.h" + +void +png_process_data(png_structp png_ptr, png_infop info, + png_bytep buffer, png_uint_32 buffer_size) +{ + png_push_restore_buffer(png_ptr, buffer, buffer_size); + + while (png_ptr->buffer_size) + { + png_process_some_data(png_ptr, info); + } +} + +void +png_process_some_data(png_structp png_ptr, png_infop info) +{ + switch (png_ptr->process_mode) + { + case PNG_READ_SIG_MODE: + { + png_push_read_sig(png_ptr); + break; + } + case PNG_READ_CHUNK_MODE: + { + png_push_read_chunk(png_ptr, info); + break; + } + case PNG_READ_IDAT_MODE: + { + png_push_read_idat(png_ptr); + break; + } + case PNG_READ_PLTE_MODE: + { + png_push_read_plte(png_ptr, info); + break; + } +#if defined(PNG_READ_tEXt_SUPPORTED) + case PNG_READ_tEXt_MODE: + { + png_push_read_text(png_ptr, info); + break; + } +#endif + case PNG_READ_END_MODE: + { + png_push_read_end(png_ptr, info); + break; + } + case PNG_SKIP_MODE: + { + png_push_skip(png_ptr); + break; + } + default: + { + png_ptr->buffer_size = 0; + break; + } + } +} + +void +png_push_read_sig(png_structp png_ptr) +{ + png_byte sig[8]; + + if (png_ptr->buffer_size < 8) + { + png_push_save_buffer(png_ptr); + return; + } + + png_push_fill_buffer(png_ptr, sig, 8); + + if (png_check_sig(sig, 8)) + { + png_ptr->process_mode = PNG_READ_CHUNK_MODE; + } + else + { + png_error(png_ptr, "Not a PNG file"); + } +} + +void +png_push_read_chunk(png_structp png_ptr, png_infop info) +{ + if (!png_ptr->have_chunk_header) + { + png_byte chunk_start[8]; + + if (png_ptr->buffer_size < 8) + { + png_push_save_buffer(png_ptr); + return; + } + + png_push_fill_buffer(png_ptr, chunk_start, 8); + png_ptr->push_length = png_get_uint_32(chunk_start); + memcpy(png_ptr->push_chunk_name, chunk_start + 4, 4); + png_ptr->have_chunk_header = 1; + png_reset_crc(png_ptr); + png_calculate_crc(png_ptr, chunk_start + 4, 4); + } + + if (!png_memcmp(png_ptr->push_chunk_name, png_IHDR, 4)) + { + if (png_ptr->mode != PNG_BEFORE_IHDR) + png_error(png_ptr, "Out of Place IHDR"); + + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + png_handle_IHDR(png_ptr, info, png_ptr->push_length); + png_push_check_crc(png_ptr); + png_ptr->mode = PNG_HAVE_IHDR; + } + else if (!png_memcmp(png_ptr->push_chunk_name, png_PLTE, 4)) + { + if (png_ptr->mode != PNG_HAVE_IHDR) + png_error(png_ptr, "Missing IHDR"); + +#if !defined(PNG_READ_OPT_PLTE_SUPPORTED) + if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) + png_push_crc_skip(png_ptr, length); + else +#else + { + png_push_handle_PLTE(png_ptr, info, png_ptr->push_length); + } +#endif + png_ptr->mode = PNG_HAVE_PLTE; + } + else if (!png_memcmp(png_ptr->push_chunk_name, png_IDAT, 4)) + { + png_ptr->idat_size = png_ptr->push_length; + png_ptr->mode = PNG_HAVE_IDAT; + png_ptr->process_mode = PNG_READ_IDAT_MODE; + png_push_have_info(png_ptr, info); + png_ptr->zstream->avail_out = (uInt)png_ptr->irowbytes; + png_ptr->zstream->next_out = png_ptr->row_buf; + return; + } + else if (!png_memcmp(png_ptr->push_chunk_name, png_IEND, 4)) + { + png_error(png_ptr, "No Image in File"); + } +#if defined(PNG_READ_gAMA_SUPPORTED) + else if (!png_memcmp(png_ptr->push_chunk_name, png_gAMA, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + if (png_ptr->mode != PNG_HAVE_IHDR) + png_error(png_ptr, "Out of Place PLTE"); + + png_handle_gAMA(png_ptr, info, png_ptr->push_length); + png_push_check_crc(png_ptr); + } +#endif +#if defined(PNG_READ_sBIT_SUPPORTED) + else if (!png_memcmp(png_ptr->push_chunk_name, png_sBIT, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + if (png_ptr->mode != PNG_HAVE_IHDR) + png_error(png_ptr, "Out of Place sBIT"); + + png_handle_sBIT(png_ptr, info, png_ptr->push_length); + png_push_check_crc(png_ptr); + } +#endif +#if defined(PNG_READ_cHRM_SUPPORTED) + else if (!png_memcmp(png_ptr->push_chunk_name, png_cHRM, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + if (png_ptr->mode != PNG_HAVE_IHDR) + png_error(png_ptr, "Out of Place cHRM"); + + png_handle_cHRM(png_ptr, info, png_ptr->push_length); + png_push_check_crc(png_ptr); + } +#endif +#if defined(PNG_READ_tRNS_SUPPORTED) + else if (!png_memcmp(png_ptr->push_chunk_name, png_tRNS, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + if (png_ptr->mode != PNG_HAVE_IHDR && + png_ptr->mode != PNG_HAVE_PLTE) + png_error(png_ptr, "Out of Place tRNS"); + + png_handle_tRNS(png_ptr, info, png_ptr->push_length); + png_push_check_crc(png_ptr); + } +#endif +#if defined(PNG_READ_bKGD_SUPPORTED) + else if (!png_memcmp(png_ptr->push_chunk_name, png_bKGD, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + if (png_ptr->mode != PNG_HAVE_IHDR && + png_ptr->mode != PNG_HAVE_PLTE) + png_error(png_ptr, "Out of Place bKGD"); + + png_handle_bKGD(png_ptr, info, png_ptr->push_length); + png_push_check_crc(png_ptr); + } +#endif +#if defined(PNG_READ_hIST_SUPPORTED) + else if (!png_memcmp(png_ptr->push_chunk_name, png_hIST, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + if (png_ptr->mode != PNG_HAVE_PLTE) + png_error(png_ptr, "Out of Place hIST"); + + png_handle_hIST(png_ptr, info, png_ptr->push_length); + png_push_check_crc(png_ptr); + } +#endif +#if defined(PNG_READ_pHYs_SUPPORTED) + else if (!png_memcmp(png_ptr->push_chunk_name, png_pHYs, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + if (png_ptr->mode != PNG_HAVE_IHDR && + png_ptr->mode != PNG_HAVE_PLTE) + png_error(png_ptr, "Out of Place pHYs"); + + png_handle_pHYs(png_ptr, info, png_ptr->push_length); + png_push_check_crc(png_ptr); + } +#endif +#if defined(PNG_READ_oFFs_SUPPORTED) + else if (!png_memcmp(png_ptr->push_chunk_name, png_oFFs, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + if (png_ptr->mode != PNG_HAVE_IHDR && + png_ptr->mode != PNG_HAVE_PLTE) + png_error(png_ptr, "Out of Place oFFs"); + + png_handle_oFFs(png_ptr, info, png_ptr->push_length); + png_push_check_crc(png_ptr); + } +#endif +#if defined(PNG_READ_tIME_SUPPORTED) + else if (!png_memcmp(png_ptr->push_chunk_name, png_tIME, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + if (png_ptr->mode == PNG_BEFORE_IHDR || + png_ptr->mode == PNG_AFTER_IEND) + png_error(png_ptr, "Out of Place tIME"); + + png_handle_tIME(png_ptr, info, png_ptr->push_length); + png_push_check_crc(png_ptr); + } +#endif +#if defined(PNG_READ_tEXt_SUPPORTED) + else if (!png_memcmp(png_ptr->push_chunk_name, png_tEXt, 4)) + { + if (png_ptr->mode == PNG_BEFORE_IHDR || + png_ptr->mode == PNG_AFTER_IEND) + png_error(png_ptr, "Out of Place tEXt"); + + png_push_handle_tEXt(png_ptr, info, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) + else if (!png_memcmp(png_ptr->push_chunk_name, png_zTXt, 4)) + { + if (png_ptr->mode == PNG_BEFORE_IHDR || + png_ptr->mode == PNG_AFTER_IEND) + png_error(png_ptr, "Out of Place zTXt"); + + png_push_handle_zTXt(png_ptr, info, png_ptr->push_length); + } +#endif + else + { + if ((png_ptr->push_chunk_name[0] & 0x20) == 0) + png_error(png_ptr, "Unknown Critical Chunk"); + + png_push_crc_skip(png_ptr, png_ptr->push_length); + } + png_ptr->have_chunk_header = 0; +} + +void +png_push_check_crc(png_structp png_ptr) +{ + png_byte crc_buf[4]; + png_uint_32 crc; + + png_push_fill_buffer(png_ptr, crc_buf, 4); + crc = png_get_uint_32(crc_buf); + if (((crc ^ 0xffffffffL) & 0xffffffffL) != + (png_ptr->crc & 0xffffffffL)) + png_error(png_ptr, "Bad CRC value"); +} + +void +png_push_crc_skip(png_structp png_ptr, png_uint_32 length) +{ + png_ptr->process_mode = PNG_SKIP_MODE; + png_ptr->skip_length = length; +} + +void +png_push_skip(png_structp png_ptr) +{ + if (png_ptr->skip_length && png_ptr->save_buffer_size) + { + png_uint_32 save_size; + + if (png_ptr->skip_length < png_ptr->save_buffer_size) + save_size = png_ptr->skip_length; + else + save_size = png_ptr->save_buffer_size; + + png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); + + png_ptr->skip_length -= save_size; + png_ptr->buffer_size -= save_size; + png_ptr->save_buffer_size -= save_size; + png_ptr->save_buffer_ptr += save_size; + } + if (png_ptr->skip_length && png_ptr->current_buffer_size) + { + png_uint_32 save_size; + + if (png_ptr->skip_length < png_ptr->current_buffer_size) + save_size = png_ptr->skip_length; + else + save_size = png_ptr->current_buffer_size; + + png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); + + png_ptr->skip_length -= save_size; + png_ptr->buffer_size -= save_size; + png_ptr->current_buffer_size -= save_size; + png_ptr->current_buffer_ptr += save_size; + } + if (!png_ptr->skip_length && png_ptr->buffer_size >= 4) + { + png_push_check_crc(png_ptr); + png_ptr->process_mode = PNG_READ_CHUNK_MODE; + } +} + +void +png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, + png_uint_32 length) +{ + png_byte * ptr; + + ptr = buffer; + if (png_ptr->save_buffer_size) + { + png_uint_32 save_size; + + if (length < png_ptr->save_buffer_size) + save_size = length; + else + save_size = png_ptr->save_buffer_size; + + memcpy(ptr, png_ptr->save_buffer_ptr, save_size); + length -= save_size; + ptr += save_size; + png_ptr->buffer_size -= save_size; + png_ptr->save_buffer_size -= save_size; + png_ptr->save_buffer_ptr += save_size; + } + if (length && png_ptr->current_buffer_size) + { + png_uint_32 save_size; + + if (length < png_ptr->current_buffer_size) + save_size = length; + else + save_size = png_ptr->current_buffer_size; + + memcpy(ptr, png_ptr->current_buffer_ptr, save_size); + png_ptr->buffer_size -= save_size; + png_ptr->current_buffer_size -= save_size; + png_ptr->current_buffer_ptr += save_size; + } +} + +void +png_push_save_buffer(png_structp png_ptr) +{ + if (png_ptr->save_buffer_size) + { + if (png_ptr->save_buffer_ptr != png_ptr->save_buffer) + { + int i; + png_byte * sp; + png_byte * dp; + + for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer; + i < png_ptr->save_buffer_size; + i++, sp++, dp++) + { + *dp = *sp; + } + } + } + if (png_ptr->save_buffer_size + png_ptr->current_buffer_size > + png_ptr->save_buffer_max) + { + int new_max; + png_byte * old_buffer; + + new_max = png_ptr->save_buffer_size + + png_ptr->current_buffer_size + 256; + old_buffer = png_ptr->save_buffer; + png_ptr->save_buffer = (png_byte *) + png_large_malloc(png_ptr, new_max); + memcpy(png_ptr->save_buffer, old_buffer, + png_ptr->save_buffer_size); + png_large_free(png_ptr, old_buffer); + png_ptr->save_buffer_max = new_max; + } + if (png_ptr->current_buffer_size) + { + memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size, + png_ptr->current_buffer_ptr, png_ptr->current_buffer_size); + png_ptr->save_buffer_size += png_ptr->current_buffer_size; + png_ptr->current_buffer_size = 0; + } + png_ptr->save_buffer_ptr = png_ptr->save_buffer; + png_ptr->buffer_size = 0; +} + +void +png_push_restore_buffer(png_structp png_ptr, png_bytep buffer, + png_uint_32 buffer_length) +{ + png_ptr->current_buffer = buffer; + png_ptr->current_buffer_size = buffer_length; + png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size; + png_ptr->current_buffer_ptr = png_ptr->current_buffer; +} + +void +png_push_read_idat(png_structp png_ptr) +{ + if (!png_ptr->have_chunk_header) + { + png_byte chunk_start[8]; + + if (png_ptr->buffer_size < 8) + { + png_push_save_buffer(png_ptr); + return; + } + + png_push_fill_buffer(png_ptr, chunk_start, 8); + png_ptr->push_length = png_get_uint_32(chunk_start); + memcpy(png_ptr->push_chunk_name, chunk_start + 4, 4); + png_ptr->have_chunk_header = 1; + png_reset_crc(png_ptr); + png_calculate_crc(png_ptr, chunk_start + 4, 4); + if (png_memcmp(png_ptr->push_chunk_name, png_IDAT, 4)) + { + png_ptr->process_mode = PNG_READ_END_MODE; + if (!png_ptr->zlib_finished) + png_error(png_ptr, "Not enough compressed data"); + return; + } + + png_ptr->idat_size = png_ptr->push_length; + } + if (png_ptr->idat_size && png_ptr->save_buffer_size) + { + png_uint_32 save_size; + + if (png_ptr->idat_size < png_ptr->save_buffer_size) + save_size = png_ptr->idat_size; + else + save_size = png_ptr->save_buffer_size; + + png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); + png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size); + + png_ptr->idat_size -= save_size; + png_ptr->buffer_size -= save_size; + png_ptr->save_buffer_size -= save_size; + png_ptr->save_buffer_ptr += save_size; + } + if (png_ptr->idat_size && png_ptr->current_buffer_size) + { + png_uint_32 save_size; + + if (png_ptr->idat_size < png_ptr->current_buffer_size) + save_size = png_ptr->idat_size; + else + save_size = png_ptr->current_buffer_size; + + png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); + png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size); + + png_ptr->idat_size -= save_size; + png_ptr->buffer_size -= save_size; + png_ptr->current_buffer_size -= save_size; + png_ptr->current_buffer_ptr += save_size; + } + if (!png_ptr->idat_size && png_ptr->buffer_size >= 4) + { + png_push_check_crc(png_ptr); + png_ptr->have_chunk_header = 0; + } +} + +void +png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, + png_uint_32 buffer_length) +{ + int ret; + + if (png_ptr->zlib_finished && buffer_length) + png_error(png_ptr, "Extra compression data"); + + png_ptr->zstream->next_in = buffer; + png_ptr->zstream->avail_in = (uInt)buffer_length; + do + { + ret = inflate(png_ptr->zstream, Z_PARTIAL_FLUSH); + if (ret == Z_STREAM_END) + { + if (png_ptr->zstream->avail_in) + png_error(png_ptr, "Extra compressed data"); + if (!png_ptr->zstream->avail_out) + { + png_push_process_row(png_ptr); + } + png_ptr->mode = PNG_AT_LAST_IDAT; + png_ptr->zlib_finished = 1; + break; + } + if (ret != Z_OK) + png_error(png_ptr, "Compression Error"); + if (!(png_ptr->zstream->avail_out)) + { + png_push_process_row(png_ptr); + png_ptr->zstream->avail_out = (uInt)png_ptr->irowbytes; + png_ptr->zstream->next_out = png_ptr->row_buf; + } + + } while (png_ptr->zstream->avail_in); +} + +void +png_push_process_row(png_structp png_ptr) +{ + png_ptr->row_info.color_type = png_ptr->color_type; + png_ptr->row_info.width = png_ptr->iwidth; + png_ptr->row_info.channels = png_ptr->channels; + png_ptr->row_info.bit_depth = png_ptr->bit_depth; + png_ptr->row_info.pixel_depth = png_ptr->pixel_depth; + png_ptr->row_info.rowbytes = ((png_ptr->row_info.width * + (png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3); + + if (png_ptr->row_buf[0]) + png_read_filter_row(&(png_ptr->row_info), + png_ptr->row_buf + 1, png_ptr->prev_row + 1, + (int)(png_ptr->row_buf[0])); + + png_memcpy(png_ptr->prev_row, png_ptr->row_buf, (png_size_t)png_ptr->rowbytes + 1); + + if (png_ptr->transformations) + png_do_read_transformations(png_ptr); + +#if defined(PNG_READ_INTERLACING_SUPPORTED) + /* blow up interlaced rows to full size */ + if (png_ptr->interlaced && + (png_ptr->transformations & PNG_INTERLACE)) + { + if (png_ptr->pass < 6) + png_do_read_interlace(&(png_ptr->row_info), + png_ptr->row_buf + 1, png_ptr->pass); + + switch (png_ptr->pass) + { + case 0: + { + int i; + for (i = 0; i < 8 && png_ptr->pass == 0; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + break; + } + case 1: + { + int i; + for (i = 0; i < 8 && png_ptr->pass == 1; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + if (png_ptr->pass == 2) + { + for (i = 0; i < 4 && png_ptr->pass == 2; i++) + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + } + break; + } + case 2: + { + int i; + for (i = 0; i < 4 && png_ptr->pass == 2; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + for (i = 0; i < 4 && png_ptr->pass == 2; i++) + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + break; + } + case 3: + { + int i; + for (i = 0; i < 4 && png_ptr->pass == 3; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + if (png_ptr->pass == 4) + { + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + } + break; + } + case 4: + { + int i; + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + break; + } + case 5: + { + int i; + for (i = 0; i < 2 && png_ptr->pass == 5; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + if (png_ptr->pass == 6) + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + break; + } + case 6: + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + if (png_ptr->pass != 6) + break; + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + } + } + else +#endif + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } +} + +void +png_read_push_finish_row(png_structp png_ptr) +{ + png_ptr->row_number++; + if (png_ptr->row_number < png_ptr->num_rows) + return; + + if (png_ptr->interlaced) + { + png_ptr->row_number = 0; + png_memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1); + do + { + png_ptr->pass++; + if (png_ptr->pass >= 7) + break; + png_ptr->iwidth = (png_ptr->width + + png_pass_inc[png_ptr->pass] - 1 - + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; + png_ptr->irowbytes = ((png_ptr->iwidth * + png_ptr->pixel_depth + 7) >> 3) + 1; + if (!(png_ptr->transformations & PNG_INTERLACE)) + { + png_ptr->num_rows = (png_ptr->height + + png_pass_yinc[png_ptr->pass] - 1 - + png_pass_ystart[png_ptr->pass]) / + png_pass_yinc[png_ptr->pass]; + if (!(png_ptr->num_rows)) + continue; + } + if (png_ptr->transformations & PNG_INTERLACE) + break; + } while (png_ptr->iwidth == 0); + } +} + + +void +png_push_handle_PLTE(png_structp png_ptr, png_infop info, png_uint_32 length) +{ + if (length % 3) + png_error(png_ptr, "Invalid Palette Chunk"); + + png_ptr->num_palette = length / 3; + png_ptr->cur_palette = 0; + png_ptr->palette = (png_colorp)png_malloc(png_ptr, + png_ptr->num_palette * sizeof (png_color)); + png_ptr->process_mode = PNG_READ_PLTE_MODE; +} + +void +png_push_read_plte(png_structp png_ptr, png_infop info) +{ + while (png_ptr->cur_palette < png_ptr->num_palette && + png_ptr->buffer_size >= 3) + { + png_byte buf[3]; + png_push_fill_buffer(png_ptr, buf, 3); + png_calculate_crc(png_ptr, buf, 3); + + /* don't depend upon png_color being any order */ + png_ptr->palette[png_ptr->cur_palette].red = buf[0]; + png_ptr->palette[png_ptr->cur_palette].green = buf[1]; + png_ptr->palette[png_ptr->cur_palette].blue = buf[2]; + png_ptr->cur_palette++; + } + if (png_ptr->cur_palette == png_ptr->num_palette && + png_ptr->buffer_size >= 4) + { + png_push_check_crc(png_ptr); + png_read_PLTE(png_ptr, info, png_ptr->palette, png_ptr->num_palette); + png_ptr->process_mode = PNG_READ_CHUNK_MODE; + } + else + { + png_push_save_buffer(png_ptr); + } +} + +#if defined(PNG_READ_tEXt_SUPPORTED) +void +png_push_handle_tEXt(png_structp png_ptr, png_infop info, + png_uint_32 length) +{ + png_ptr->current_text = (png_charp)png_large_malloc(png_ptr, length + 1); + png_ptr->current_text[(png_size_t)length] = '\0'; + png_ptr->current_text_ptr = png_ptr->current_text; + png_ptr->current_text_size = length; + png_ptr->current_text_left = length; + png_ptr->process_mode = PNG_READ_tEXt_MODE; +} + +void +png_push_read_text(png_structp png_ptr, png_infop info) +{ + if (png_ptr->buffer_size && png_ptr->current_text_left) + { + png_uint_32 text_size; + + if (png_ptr->buffer_size < png_ptr->current_text_left) + text_size = png_ptr->buffer_size; + else + text_size = png_ptr->current_text_left; + png_push_fill_buffer(png_ptr, png_ptr->current_text_ptr, text_size); + png_calculate_crc(png_ptr, png_ptr->current_text_ptr, text_size); + png_ptr->current_text_left -= text_size; + png_ptr->current_text_ptr += text_size; + } + if (!(png_ptr->current_text_left) && png_ptr->buffer_size >= 4) + { + png_charp text; + png_charp key; + + png_push_check_crc(png_ptr); + + key = png_ptr->current_text; + png_ptr->current_text = 0; + + for (text = key; *text; text++) + /* empty loop */ ; + + if (text != key + (png_size_t)png_ptr->current_text_size) + text++; + + png_read_tEXt(png_ptr, info, key, text, + png_ptr->current_text_size - (text - key)); + png_ptr->process_mode = PNG_READ_CHUNK_MODE; + } +} +#endif + +#if defined(PNG_READ_zTXt_SUPPORTED) +void +png_push_handle_zTXt(png_structp png_ptr, png_infop info, + png_uint_32 length) +{ + png_ptr->current_text = (png_charp)png_large_malloc(png_ptr, length + 1); + png_ptr->current_text[(png_size_t)length] = '\0'; + png_ptr->current_text_ptr = png_ptr->current_text; + png_ptr->current_text_size = length; + png_ptr->current_text_left = length; + png_ptr->process_mode = PNG_READ_zTXt_MODE; +} + +void +png_push_read_ztxt(png_structp png_ptr, png_infop info) +{ + if (png_ptr->buffer_size && png_ptr->current_text_left) + { + png_uint_32 text_size; + + if (png_ptr->buffer_size < png_ptr->current_text_left) + text_size = png_ptr->buffer_size; + else + text_size = png_ptr->current_text_left; + png_push_fill_buffer(png_ptr, png_ptr->current_text_ptr, text_size); + png_calculate_crc(png_ptr, png_ptr->current_text_ptr, text_size); + png_ptr->current_text_left -= text_size; + png_ptr->current_text_ptr += text_size; + } + if (!(png_ptr->current_text_left) && png_ptr->buffer_size >= 4) + { + png_charp text; + png_charp key; + int ret; + png_uint_32 text_size, key_size; + + png_push_check_crc(png_ptr); + + key = png_ptr->current_text; + png_ptr->current_text = 0; + + text = NULL; + + for (text = key; *text; text++) + /* empty loop */ ; + + /* zTXt can't have zero text */ + if (text == key + (png_size_t)png_ptr->current_text_size) + { + png_large_free(png_ptr, key); + return; + } + + text++; + + if (*text) /* check compression byte */ + { + png_large_free(png_ptr, key); + return; + } + + text++; + + png_ptr->zstream->next_in = (png_bytep )text; + png_ptr->zstream->avail_in = (uInt)(png_ptr->current_text_size - + (text - key)); + png_ptr->zstream->next_out = png_ptr->zbuf; + png_ptr->zstream->avail_out = (png_size_t)png_ptr->zbuf_size; + + key_size = text - key; + text_size = 0; + text = NULL; + + while (png_ptr->zstream->avail_in) + { + ret = inflate(png_ptr->zstream, Z_PARTIAL_FLUSH); + if (ret != Z_OK && ret != Z_STREAM_END) + { + inflateReset(png_ptr->zstream); + png_ptr->zstream->avail_in = 0; + png_large_free(png_ptr, key); + png_large_free(png_ptr, text); + return; + } + if (!png_ptr->zstream->avail_out || ret == Z_STREAM_END) + { + if (!text) + { + text = (png_charp)png_malloc(png_ptr, + png_ptr->zbuf_size - png_ptr->zstream->avail_out + + key_size + 1); + png_memcpy(text + (png_size_t)key_size, png_ptr->zbuf, + (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream->avail_out)); + png_memcpy(text, key, (png_size_t)key_size); + text_size = key_size + (png_size_t)png_ptr->zbuf_size - + png_ptr->zstream->avail_out; + *(text + (png_size_t)text_size) = '\0'; + } + else + { + png_charp tmp; + + tmp = text; + text = png_large_malloc(png_ptr, text_size + + png_ptr->zbuf_size - png_ptr->zstream->avail_out + 1); + png_memcpy(text, tmp, (png_size_t)text_size); + png_large_free(png_ptr, tmp); + png_memcpy(text + (png_size_t)text_size, png_ptr->zbuf, + (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream->avail_out)); + text_size += png_ptr->zbuf_size - png_ptr->zstream->avail_out; + *(text + (png_size_t)text_size) = '\0'; + } + if (ret != Z_STREAM_END) + { + png_ptr->zstream->next_out = png_ptr->zbuf; + png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size; + } + } + else + { + break; + } + + if (ret == Z_STREAM_END) + break; + } + + inflateReset(png_ptr->zstream); + png_ptr->zstream->avail_in = 0; + + if (ret != Z_STREAM_END) + { + png_large_free(png_ptr, key); + png_large_free(png_ptr, text); + return; + } + + png_large_free(png_ptr, key); + key = text; + text += (png_size_t)key_size; + text_size -= key_size; + + png_read_zTXt(png_ptr, info, key, text, text_size, 0); + } +} +#endif + +void +png_push_have_info(png_structp png_ptr, png_infop info) +{ + if (png_ptr->info_fn) + (*(png_ptr->info_fn))(png_ptr, info); +} + +void +png_push_have_end(png_structp png_ptr, png_infop info) +{ + if (png_ptr->end_fn) + (*(png_ptr->end_fn))(png_ptr, info); +} + +void +png_push_have_row(png_structp png_ptr, png_bytep row) +{ + if (png_ptr->row_fn) + (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number, + (int)png_ptr->pass); +} + +png_voidp +png_get_progressive_ptr(png_structp png_ptr) +{ + return png_ptr->push_ptr; +} + +void +png_push_read_end(png_structp png_ptr, png_infop info) +{ + if (!png_ptr->have_chunk_header) + { + png_byte chunk_start[8]; + + if (png_ptr->buffer_size < 8) + { + png_push_save_buffer(png_ptr); + return; + } + + png_push_fill_buffer(png_ptr, chunk_start, 8); + png_ptr->push_length = png_get_uint_32(chunk_start); + memcpy(png_ptr->push_chunk_name, chunk_start + 4, 4); + png_ptr->have_chunk_header = 1; + png_reset_crc(png_ptr); + png_calculate_crc(png_ptr, chunk_start + 4, 4); + } + + if (!png_memcmp(png_ptr->push_chunk_name, png_IHDR, 4)) + { + png_error(png_ptr, "invalid chunk after IDAT"); + } + else if (!png_memcmp(png_ptr->push_chunk_name, png_PLTE, 4)) + { + png_error(png_ptr, "invalid chunk after IDAT"); + } + else if (!png_memcmp(png_ptr->push_chunk_name, png_IDAT, 4)) + { + if (png_ptr->push_length > 0 || png_ptr->mode != PNG_AT_LAST_IDAT) + png_error(png_ptr, "too many IDAT's found"); + } + else if (!png_memcmp(png_ptr->push_chunk_name, png_IEND, 4)) + { + if (png_ptr->push_length) + png_error(png_ptr, "Invalid IEND chunk"); + png_push_check_crc(png_ptr); + png_ptr->mode = PNG_AFTER_IEND; + png_ptr->process_mode = PNG_READ_DONE_MODE; + png_push_have_end(png_ptr, info); + } +#if defined(PNG_READ_gAMA_SUPPORTED) + else if (!png_memcmp(png_ptr->push_chunk_name, png_gAMA, 4)) + { + png_error(png_ptr, "invalid chunk after IDAT"); + } +#endif +#if defined(PNG_READ_sBIT_SUPPORTED) + else if (!png_memcmp(png_ptr->push_chunk_name, png_sBIT, 4)) + { + png_error(png_ptr, "invalid chunk after IDAT"); + } +#endif +#if defined(PNG_READ_cHRM_SUPPORTED) + else if (!png_memcmp(png_ptr->push_chunk_name, png_cHRM, 4)) + { + png_error(png_ptr, "invalid chunk after IDAT"); + } +#endif +#if defined(PNG_READ_tRNS_SUPPORTED) + else if (!png_memcmp(png_ptr->push_chunk_name, png_tRNS, 4)) + { + png_error(png_ptr, "invalid chunk after IDAT"); + } +#endif +#if defined(PNG_READ_bKGD_SUPPORTED) + else if (!png_memcmp(png_ptr->push_chunk_name, png_bKGD, 4)) + { + png_error(png_ptr, "invalid chunk after IDAT"); + } +#endif +#if defined(PNG_READ_hIST_SUPPORTED) + else if (!png_memcmp(png_ptr->push_chunk_name, png_hIST, 4)) + { + png_error(png_ptr, "invalid chunk after IDAT"); + } +#endif +#if defined(PNG_READ_pHYs_SUPPORTED) + else if (!png_memcmp(png_ptr->push_chunk_name, png_pHYs, 4)) + { + png_error(png_ptr, "invalid chunk after IDAT"); + } +#endif +#if defined(PNG_READ_oFFs_SUPPORTED) + else if (!png_memcmp(png_ptr->push_chunk_name, png_oFFs, 4)) + { + png_error(png_ptr, "invalid chunk after IDAT"); + } +#endif +#if defined(PNG_READ_tIME_SUPPORTED) + else if (!png_memcmp(png_ptr->push_chunk_name, png_tIME, 4)) + { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } + + if (png_ptr->mode == PNG_BEFORE_IHDR || + png_ptr->mode == PNG_AFTER_IEND) + png_error(png_ptr, "Out of Place tIME"); + + png_handle_tIME(png_ptr, info, png_ptr->push_length); + png_push_check_crc(png_ptr); + } +#endif +#if defined(PNG_READ_tEXt_SUPPORTED) + else if (!png_memcmp(png_ptr->push_chunk_name, png_tEXt, 4)) + { + if (png_ptr->mode == PNG_BEFORE_IHDR || + png_ptr->mode == PNG_AFTER_IEND) + png_error(png_ptr, "Out of Place tEXt"); + + png_push_handle_tEXt(png_ptr, info, png_ptr->push_length); + } +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) + else if (!png_memcmp(png_ptr->push_chunk_name, png_zTXt, 4)) + { + if (png_ptr->mode == PNG_BEFORE_IHDR || + png_ptr->mode == PNG_AFTER_IEND) + png_error(png_ptr, "Out of Place zTXt"); + + png_push_handle_zTXt(png_ptr, info, png_ptr->push_length); + } +#endif + else + { + if ((png_ptr->push_chunk_name[0] & 0x20) == 0) + png_error(png_ptr, "Unknown Critical Chunk"); + + png_push_crc_skip(png_ptr, png_ptr->push_length); + } + if (png_ptr->mode == PNG_AT_LAST_IDAT) + png_ptr->mode = PNG_AFTER_IDAT; + png_ptr->have_chunk_header = 0; +} + +void +png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr, + png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, + png_progressive_end_ptr end_fn) +{ + png_ptr->info_fn = info_fn; + png_ptr->row_fn = row_fn; + png_ptr->push_ptr = progressive_ptr; + png_ptr->end_fn = end_fn; + png_ptr->read_mode = PNG_READ_PUSH_MODE; +} + +void +png_progressive_combine_row (png_structp png_ptr, + png_bytep old_row, png_bytep new_row) +{ + png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]); +} + diff --git a/pngrcb.c b/pngrcb.c index ba1fe143..5ea16cea 100644 --- a/pngrcb.c +++ b/pngrcb.c @@ -1,16 +1,16 @@ /* 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 Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. - August 24, 1995 + December 19, 1995 */ #define PNG_INTERNAL #include "png.h" 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, int color_type, int compression_type, int filter_type, int interlace_type) @@ -24,7 +24,7 @@ png_read_IHDR(png_struct *png_ptr, png_info *info, info->color_type = color_type; info->compression_type = compression_type; info->filter_type = filter_type; - info->interlace_type = interlace_type; + info->interlace_type = interlace_type; if (info->color_type == PNG_COLOR_TYPE_PALETTE) info->channels = 1; else if (info->color_type & PNG_COLOR_MASK_COLOR) @@ -38,8 +38,8 @@ png_read_IHDR(png_struct *png_ptr, png_info *info, } void -png_read_PLTE(png_struct *png_ptr, png_info *info, - png_color *palette, int num) +png_read_PLTE(png_structp png_ptr, png_infop info, + png_colorp palette, int num) { if (!png_ptr || !info) return; @@ -51,7 +51,7 @@ png_read_PLTE(png_struct *png_ptr, png_info *info, #if defined(PNG_READ_gAMA_SUPPORTED) 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) return; @@ -63,22 +63,22 @@ png_read_gAMA(png_struct *png_ptr, png_info *info, float gamma) #if defined(PNG_READ_sBIT_SUPPORTED) void -png_read_sBIT(png_struct *png_ptr, png_info *info, - png_color_8 *sig_bit) +png_read_sBIT(png_structp png_ptr, png_infop info, + png_color_8p sig_bit) { if (!png_ptr || !info) 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; } #endif #if defined(PNG_READ_cHRM_SUPPORTED) void -png_read_cHRM(png_struct *png_ptr, png_info *info, - float white_x, float white_y, float red_x, float red_y, - float green_x, float green_y, float blue_x, float blue_y) +png_read_cHRM(png_structp png_ptr, png_infop info, + double white_x, double white_y, double red_x, double red_y, + double green_x, double green_y, double blue_x, double blue_y) { if (!png_ptr || !info) return; @@ -97,8 +97,8 @@ png_read_cHRM(png_struct *png_ptr, png_info *info, #if defined(PNG_READ_tRNS_SUPPORTED) void -png_read_tRNS(png_struct *png_ptr, png_info *info, - png_byte *trans, int num_trans, png_color_16 *trans_values) +png_read_tRNS(png_structp png_ptr, png_infop info, + png_bytep trans, int num_trans, png_color_16p trans_values) { if (!png_ptr || !info) return; @@ -109,7 +109,7 @@ png_read_tRNS(png_struct *png_ptr, png_info *info, } else { - memcpy(&(info->trans_values), trans_values, + png_memcpy(&(info->trans_values), trans_values, sizeof(png_color_16)); } 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) void -png_read_bKGD(png_struct *png_ptr, png_info *info, - png_color_16 *background) +png_read_bKGD(png_structp png_ptr, png_infop info, + png_color_16p background) { if (!png_ptr || !info) return; - memcpy(&(info->background), background, sizeof(png_color_16)); + png_memcpy(&(info->background), background, sizeof(png_color_16)); info->valid |= PNG_INFO_bKGD; } #endif #if defined(PNG_READ_hIST_SUPPORTED) 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) 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) 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) { if (!png_ptr || !info) @@ -159,7 +159,7 @@ png_read_pHYs(png_struct *png_ptr, png_info *info, #if defined(PNG_READ_oFFs_SUPPORTED) 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) { if (!png_ptr || !info) @@ -174,26 +174,26 @@ png_read_oFFs(png_struct *png_ptr, png_info *info, #if defined(PNG_READ_tIME_SUPPORTED) void -png_read_tIME(png_struct *png_ptr, png_info *info, - png_time *mod_time) +png_read_tIME(png_structp png_ptr, png_infop info, + png_timep mod_time) { if (!png_ptr || !info) 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; } #endif #if defined(PNG_READ_zTXt_SUPPORTED) void -png_read_zTXt(png_struct *png_ptr, png_info *info, - charf *key, charf *text, png_uint_32 text_len, int compression) +png_read_zTXt(png_structp png_ptr, png_infop info, + png_charp key, png_charp text, png_uint_32 text_len, int compression) { if (!png_ptr || !info) return; - if (info->max_text <= info->num_text) + if (info->max_text <= info->num_text) { if (info->text) { @@ -201,15 +201,15 @@ png_read_zTXt(png_struct *png_ptr, png_info *info, old_max = info->max_text; 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->max_text * sizeof (png_text), - old_max * sizeof (png_text)); + old_max * sizeof (png_text)); } else { 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->num_text = 0; } @@ -225,13 +225,13 @@ png_read_zTXt(png_struct *png_ptr, png_info *info, #if defined(PNG_READ_tEXt_SUPPORTED) void -png_read_tEXt(png_struct *png_ptr, png_info *info, - charf *key, charf *text, png_uint_32 text_len) +png_read_tEXt(png_structp png_ptr, png_infop info, + png_charp key, png_charp text, png_uint_32 text_len) { if (!png_ptr || !info) return; - png_read_zTXt(png_ptr, info, key, text, text_len, -1); + png_read_zTXt(png_ptr, info, key, text, text_len, -1); } #endif diff --git a/pngread.c b/pngread.c index b3749e5f..3dc71903 100644 --- a/pngread.c +++ b/pngread.c @@ -1,10 +1,10 @@ /* 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 Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. - August 24, 1995 + December 19, 1995 */ #define PNG_INTERNAL @@ -12,56 +12,67 @@ /* initialize png structure for reading, and allocate any memory needed */ 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_memset(png_ptr, 0, sizeof (png_struct)); - png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf)); + png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf)); + error_fn = png_ptr->error_fn; + 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 = png_large_malloc(png_ptr, png_ptr->zbuf_size); - png_ptr->zstream = &(png_ptr->zstream_struct); - png_ptr->zstream->zalloc = png_zalloc; + png_ptr->zstream = (z_stream *)png_malloc(png_ptr, sizeof (z_stream)); + png_ptr->zstream->zalloc = png_zalloc; png_ptr->zstream->zfree = png_zfree; 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->avail_out = (uInt)png_ptr->zbuf_size; } /* read the information before the actual image data. */ 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_uint_32 length; - (*(png_ptr->read_data_fn))(png_ptr, chunk_start, 8); - if (memcmp(chunk_start, png_sig, 8)) - (*(png_ptr->error_fn))(png_ptr, "Not a PNG File"); + png_read_data(png_ptr, chunk_start, 8); + if (png_memcmp(chunk_start, png_sig, 8)) + png_error(png_ptr, "Not a Png File"); while (1) { 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); png_reset_crc(png_ptr); 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) - (*(png_ptr->error_fn))(png_ptr, "Out of Place IHDR"); + if (png_ptr->mode != PNG_BEFORE_IHDR) + png_error(png_ptr, "Out of Place IHDR"); png_handle_IHDR(png_ptr, info, length); 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) - (*(png_ptr->error_fn))(png_ptr, "Missing IHDR"); + png_error(png_ptr, "Missing IHDR"); #if !defined(PNG_READ_OPT_PLTE_SUPPORTED) if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) @@ -70,122 +81,122 @@ png_read_info(png_struct *png_ptr, png_info *info) #else { png_handle_PLTE(png_ptr, info, length); - } + } #endif 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->mode = PNG_HAVE_IDAT; 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) - 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) - (*(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); } #endif #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) - (*(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); } #endif #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) - (*(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); } #endif #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 && 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); } #endif #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->error_fn))(png_ptr, "Out of Place bKGD"); + png_error(png_ptr, "Out of Place bKGD"); png_handle_bKGD(png_ptr, info, length); } #endif #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) - (*(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); } #endif #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 && 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); } #endif #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 && 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); } #endif #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 || 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); } #endif #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 || 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); - } + } #endif #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 || 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); } @@ -193,21 +204,21 @@ png_read_info(png_struct *png_ptr, png_info *info) else { 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_ptr->read_data_fn))(png_ptr, chunk_start, 4); + png_read_data(png_ptr, chunk_start, 4); crc = png_get_uint_32(chunk_start); if (((crc ^ 0xffffffffL) & 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 */ 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)) 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. If the user doesn't call this, we will do it ourselves. */ void -png_start_read_image(png_struct *png_ptr) +png_start_read_image(png_structp png_ptr) { if (!(png_ptr->row_init)) png_read_start_row(png_ptr); } 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; 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) png_combine_row(png_ptr, dsp_row, png_pass_dsp_mask[png_ptr->pass]); - png_read_finish_row(png_ptr); + png_read_finish_row(png_ptr); return; } 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 (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_read_finish_row(png_ptr); return; @@ -280,7 +291,7 @@ png_read_row(png_struct *png_ptr, png_bytef *row, png_byte *dsp_row) break; case 4: if ((png_ptr->row_number & 3) != 2) - { + { if (dsp_row && (png_ptr->row_number & 2)) png_combine_row(png_ptr, dsp_row, 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; } break; - case 6: + case 6: if (!(png_ptr->row_number & 1)) { 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 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->avail_out = (uInt)png_ptr->irowbytes; do { - if (!(png_ptr->zstream->avail_in)) + if (!(png_ptr->zstream->avail_in)) { while (!png_ptr->idat_size) { png_byte buf[4]; 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); if (((crc ^ 0xffffffffL) & 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_reset_crc(png_ptr); png_crc_read(png_ptr, buf, 4); - if (memcmp(buf, png_IDAT, 4)) - (*(png_ptr->error_fn))(png_ptr, "Not enough image data"); + if (png_memcmp(buf, png_IDAT, 4)) + png_error(png_ptr, "Not enough image data"); } 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_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 (png_ptr->zstream->avail_out || png_ptr->zstream->avail_in || 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; - break; + break; } if (ret != Z_OK) - (*(png_ptr->error_fn))(png_ptr, "Compression Error"); + png_error(png_ptr, "Compression Error"); } 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_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_ptr->row_buf + 1, png_ptr->prev_row + 1, (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, and png_set_interlace_handling() has been called, the rows need to 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 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 @@ -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 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 - be ignored, so pass NULL to it. */ + be ignored, so pass NULL to it. */ + void -png_read_rows(png_struct *png_ptr, png_bytef **row, - png_byte **display_row, png_uint_32 num_rows) +png_read_rows(png_structp png_ptr, png_bytepp row, + png_bytepp display_row, png_uint_32 num_rows) { - png_uint_32 i; - png_bytef **rp; - png_byte **dp; + png_uint_32 i; + png_bytepp rp; + png_bytepp dp; rp = row; dp = display_row; for (i = 0; i < num_rows; i++) { - png_bytef *rptr; - png_byte *dptr; + png_bytep rptr; + png_bytep dptr; if (rp) rptr = *rp; @@ -448,10 +460,9 @@ png_read_rows(png_struct *png_ptr, png_bytef **row, dptr = *dp; else dptr = NULL; - png_read_row(png_ptr, rptr, dptr); - if (row) - rp++; + if (row) + rp++; if (display_row) 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 an image for each pass of a interlaced image, use png_read_rows() */ 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; int pass, j; - png_bytef **rp; + png_bytepp rp; pass = png_set_interlace_handling(png_ptr); 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 or time information at the end of the file, if info is not NULL. */ 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_uint_32 length; 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); if (((crc ^ 0xffffffffL) & 0xffffffffL) != (png_ptr->crc & 0xffffffffL)) - (*(png_ptr->error_fn))(png_ptr, "Bad CRC value"); + png_error(png_ptr, "Bad CRC value"); 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); png_reset_crc(png_ptr); 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)) - { - (*(png_ptr->error_fn))(png_ptr, "Invalid chunk after IDAT"); - } - else if (!memcmp(chunk_start + 4, png_IDAT, 4)) + else if (!png_memcmp(chunk_start + 4, png_IDAT, 4)) { 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) - 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 || 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) - png_handle_tIME(png_ptr, info, length); + png_handle_tIME(png_ptr, info, length); else png_crc_skip(png_ptr, length); } #endif #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 || 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) png_handle_tEXt(png_ptr, info, length); @@ -577,11 +588,11 @@ png_read_end(png_struct *png_ptr, png_info *info) } #endif #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 || 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) 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); } #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; } else - { - char msg[80]; - + { if ((chunk_start[4] & 0x20) == 0) - { - png_strcpy(msg,"Unknown critical chunk "); - png_memcpy(msg + strlen(msg), chunk_start + 4,4); - (*(png_ptr->error_fn))(png_ptr, msg); - } + png_error(png_ptr, "Unknown Critical Chunk"); - 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_ptr->read_data_fn))(png_ptr, chunk_start, 4); + png_read_data(png_ptr, chunk_start, 4); crc = png_get_uint_32(chunk_start); if (((crc ^ 0xffffffffL) & 0xffffffffL) != (png_ptr->crc & 0xffffffffL)) - (*(png_ptr->error_fn))(png_ptr, "Bad CRC value"); - if (png_ptr->mode == PNG_AT_LAST_IDAT) + png_error(png_ptr, "Bad CRC value"); + if (png_ptr->mode == PNG_AT_LAST_IDAT) png_ptr->mode = PNG_AFTER_IDAT; } while (png_ptr->mode != PNG_AFTER_IEND); } /* free all memory used by the read */ 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; jmp_buf tmp_jmp; if (info) - { - if (png_ptr->do_free & PNG_FREE_PALETTE) - png_free(png_ptr, info->palette); - + { + if (png_ptr->do_free & PNG_FREE_PALETTE) + png_free(png_ptr, info->palette); #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_bKGD_SUPPORTED) - if (png_ptr->do_free & PNG_FREE_TRANS) - png_free(png_ptr, info->trans); + if (png_ptr->do_free & PNG_FREE_PALETTE) + png_free(png_ptr, info->trans); #endif - #if defined(PNG_READ_hIST_SUPPORTED) - if (png_ptr->do_free & PNG_FREE_HIST) - png_free(png_ptr, info->hist); + if (png_ptr->do_free & PNG_FREE_HIST) + png_free(png_ptr, info->hist); #endif - #if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED) - for (i = 0; i < info->num_text; i++) - { - png_large_free(png_ptr, info->text[i].key); - } + for (i = 0; i < info->num_text; i++) + { + png_large_free(png_ptr, info->text[i].key); + } - png_free(png_ptr, info->text); + png_free(png_ptr, info->text); #endif - png_memset(info, 0, sizeof(png_info)); - } + png_memset(info, 0, sizeof(png_info)); + } if (end_info) { #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); @@ -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->row_buf); png_large_free(png_ptr, png_ptr->prev_row); - #if defined(PNG_READ_DITHER_SUPPORTED) png_large_free(png_ptr, png_ptr->palette_lookup); png_free(png_ptr, png_ptr->dither_index); #endif - #if defined(PNG_READ_GAMMA_SUPPORTED) - png_free(png_ptr, png_ptr->gamma_table); + png_free(png_ptr, png_ptr->gamma_table); #endif - #if defined(PNG_READ_BACKGROUND_SUPPORTED) png_free(png_ptr, png_ptr->gamma_from_1); png_free(png_ptr, png_ptr->gamma_to_1); #endif - #if defined(PNG_READ_GAMMA_SUPPORTED) 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]); } - } + } #endif - #if defined(PNG_READ_BACKGROUND_SUPPORTED) png_free(png_ptr, png_ptr->gamma_16_table); if (png_ptr->gamma_16_from_1) - { + { for (i = 0; i < (1 << (8 - png_ptr->gamma_shift)); 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); #endif - #if defined(PNG_READ_BACKGROUND_SUPPORTED) png_free(png_ptr, png_ptr->trans); #endif - #if defined(PNG_READ_DITHER_SUPPORTED) - png_free(png_ptr, png_ptr->hist); + png_free(png_ptr, png_ptr->hist); #endif + if (!png_ptr->user_palette) + png_free(png_ptr, png_ptr->palette); - if (!png_ptr->user_palette) - png_free(png_ptr, png_ptr->palette); - - inflateEnd(png_ptr->zstream); - - png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf)); - png_memset(png_ptr, 0, sizeof (png_struct)); - png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf)); + inflateEnd(png_ptr->zstream); + png_free(png_ptr, png_ptr->zstream); +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + png_free(png_ptr, png_ptr->save_buffer); +#endif + png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf)); + png_memset(png_ptr, 0, sizeof (png_struct)); + png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf)); } diff --git a/pngrtran.c b/pngrtran.c index 893e80bf..aad816f4 100644 --- a/pngrtran.c +++ b/pngrtran.c @@ -1,10 +1,10 @@ /* 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 Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. - August 20, 1995 + December 19, 1995 */ #define PNG_INTERNAL @@ -13,8 +13,8 @@ #if defined(PNG_READ_BACKGROUND_SUPPORTED) /* handle alpha and tRNS via a background color */ void -png_set_background(png_struct *png_ptr, - png_color_16 *background_color, int background_gamma_code, +png_set_background(png_structp png_ptr, + png_color_16p background_color, int background_gamma_code, int need_expand, double background_gamma) { png_ptr->transformations |= PNG_BACKGROUND; @@ -29,7 +29,7 @@ png_set_background(png_struct *png_ptr, #if defined(PNG_READ_16_TO_8_SUPPORTED) /* strip 16 bit depth files to 8 bit depth */ void -png_set_strip_16(png_struct *png_ptr) +png_set_strip_16(png_structp png_ptr) { 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 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 right; -} dsort; +} png_dsort; +typedef png_dsort FAR * png_dsortp; +typedef png_dsort FAR * FAR * png_dsortpp; void -png_set_dither(png_struct *png_ptr, png_color *palette, - int num_palette, int maximum_colors, png_uint_16 *histogram, +png_set_dither(png_structp png_ptr, png_colorp palette, + int num_palette, int maximum_colors, png_uint_16p histogram, int full_dither) { png_ptr->transformations |= PNG_DITHER; @@ -60,7 +63,7 @@ png_set_dither(png_struct *png_ptr, png_color *palette, { 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)); for (i = 0; i < num_palette; 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 */ int i; - png_byte *sort; + png_bytep sort; /* 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 */ for (i = 0; i < num_palette; i++) @@ -200,16 +203,16 @@ png_set_dither(png_struct *png_ptr, png_color *palette, int i; int max_d; int num_new_palette; - dsort **hash; - png_byte *index_to_palette; + png_dsortpp hash; + png_bytep index_to_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 */ /* 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)); - palette_to_index = (png_byte *)png_malloc(png_ptr, + palette_to_index = (png_bytep)png_malloc(png_ptr, num_palette * sizeof (png_byte)); /* initialize the sort array */ @@ -219,10 +222,10 @@ png_set_dither(png_struct *png_ptr, png_color *palette, 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++) - hash[i] = (dsort *)0; -/* png_memset(hash, 0, 769 * sizeof (dsort *)); */ + hash[i] = (png_dsortp)0; +/* png_memset(hash, 0, 769 * sizeof (png_dsortp)); */ num_new_palette = num_palette; @@ -246,13 +249,13 @@ png_set_dither(png_struct *png_ptr, png_color *palette, { int d; - d = PNG_COLOR_DIST(palette[i], palette[j]); + d = PNG_COLOR_DIST(palette[i], palette[j]); 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->left = i; t->right = j; @@ -265,7 +268,7 @@ png_set_dither(png_struct *png_ptr, png_color *palette, { if (hash[i]) { - dsort *p; + png_dsortp p; 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]) { - dsort *p; + png_dsortp p; p = hash[i]; while (p) { - dsort *t; + png_dsortp t; t = p->next; png_free(png_ptr, p); @@ -348,7 +351,7 @@ png_set_dither(png_struct *png_ptr, png_color *palette, num_palette = maximum_colors; } if (!(png_ptr->palette)) - { + { png_ptr->palette = palette; png_ptr->user_palette = 1; } @@ -359,22 +362,22 @@ png_set_dither(png_struct *png_ptr, png_color *palette, int i; int total_bits, num_red, num_green, num_blue; png_uint_32 num_entries; - png_bytef *distance; + png_bytep distance; 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_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); - 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_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_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; 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)); 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); index_g = index_r | (ig << PNG_DITHER_BLUE_BITS); for (ib = 0; ib < num_blue; ib++) - { + { int index, db, dmax, d; 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 @@ -428,7 +431,7 @@ png_set_dither(png_struct *png_ptr, png_color *palette, #if defined(PNG_READ_GAMMA_SUPPORTED) /* transform the image from the file_gamma to the screen_gamma */ void -png_set_gamma(png_struct *png_ptr, double screen_gamma, +png_set_gamma(png_structp png_ptr, double screen_gamma, double file_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 to alpha channels */ void -png_set_expand(png_struct *png_ptr) +png_set_expand(png_structp png_ptr) { png_ptr->transformations |= PNG_EXPAND; } @@ -450,7 +453,7 @@ png_set_expand(png_struct *png_ptr) #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) 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; } @@ -459,7 +462,7 @@ png_set_gray_to_rgb(png_struct *png_ptr) /* initialize everything needed for the read. This includes modifying the palette */ void -png_init_read_transformations(png_struct *png_ptr) +png_init_read_transformations(png_structp png_ptr) { int color_type; @@ -474,7 +477,7 @@ png_init_read_transformations(png_struct *png_ptr) (png_ptr->transformations & PNG_BACKGROUND) && png_ptr->background_expand) /* (!(png_ptr->transformations & PNG_BACKGROUND) || - png_ptr->background_expand)) */ + png_ptr->background_expand)) */ { /* expand background chunk. While this may not be the fastest way to do this, it only happens once @@ -492,7 +495,7 @@ png_init_read_transformations(png_struct *png_ptr) break; } } - if (color_type == PNG_COLOR_TYPE_PALETTE && + if (color_type == PNG_COLOR_TYPE_PALETTE && (png_ptr->transformations & PNG_BACKGROUND) && png_ptr->background_expand) { @@ -523,12 +526,12 @@ png_init_read_transformations(png_struct *png_ptr) { 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; gs = 1.0; switch (png_ptr->background_gamma_type) - { + { case PNG_BACKGROUND_GAMMA_SCREEN: g = (png_ptr->display_gamma); gs = 1.0; @@ -544,9 +547,9 @@ png_init_read_transformations(png_struct *png_ptr) 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); png_ptr->background_1.green = (png_uint_16)(pow( (double)png_ptr->background.green / m, g) * m + .5); @@ -562,9 +565,9 @@ png_init_read_transformations(png_struct *png_ptr) else { 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( - (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 -#if defined(PNG_READ_SHIFT_SUPPORTED) && defined(PNG_READ_sBIT_SUPPORTED) +#if defined(PNG_READ_SHIFT_SUPPORTED) if ((png_ptr->transformations & PNG_SHIFT) && - png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + color_type == PNG_COLOR_TYPE_PALETTE) { png_uint_16 i; int sr, sg, sb; @@ -582,7 +585,7 @@ png_init_read_transformations(png_struct *png_ptr) sr = 8 - png_ptr->sig_bit.red; if (sr < 0 || sr > 8) sr = 0; - sg = 8 - png_ptr->sig_bit.green; + sg = 8 - png_ptr->sig_bit.green; if (sg < 0 || sg > 8) sg = 0; 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 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 -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 ((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) { 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) info_ptr->bit_depth = 8; 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 ((png_ptr->transformations & PNG_16_TO_8) && info_ptr->bit_depth == 16) - info_ptr->bit_depth = 8; + info_ptr->bit_depth = 8; #endif #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; #endif - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) info_ptr->channels = 1; else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) 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 decide how it fits in with the other transformations here */ void -png_do_read_transformations(png_struct *png_ptr) +png_do_read_transformations(png_structp png_ptr) { #if defined(PNG_READ_EXPAND_SUPPORTED) if ((png_ptr->transformations & PNG_EXPAND) && @@ -690,7 +693,7 @@ png_do_read_transformations(png_struct *png_ptr) { if (png_ptr->num_trans) png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, - &(png_ptr->trans_values)); + &(png_ptr->trans_values)); else png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, NULL); @@ -724,16 +727,16 @@ png_do_read_transformations(png_struct *png_ptr) #if defined(PNG_READ_DITHER_SUPPORTED) 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->palette_lookup, + png_ptr->palette_lookup, png_ptr->dither_index); } #endif #if defined(PNG_READ_INVERT_SUPPORTED) 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 #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 (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 #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 png_do_shift() after this. */ 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; - png_bytef *sp, *dp; - png_uint_32 i; + png_bytep sp, dp; + png_uint_32 i; 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; sp--; - } + } else 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); 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++) { *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 the values back to 0 through 31 */ void -png_do_unshift(png_row_info *row_info, png_bytef *row, - png_color_8 *sig_bits) +png_do_unshift(png_row_infop row_info, png_bytep row, + png_color_8p sig_bits) { - png_bytef *bp; + png_bytep bp; png_uint_16 value; png_uint_32 i; if (row && row_info && sig_bits && @@ -876,34 +879,33 @@ png_do_unshift(png_row_info *row_info, png_bytef *row, channels = 0; if (row_info->color_type & PNG_COLOR_MASK_COLOR) { - shift[channels++] = row_info->bit_depth - sig_bits->red < 0 ? - 0 : row_info->bit_depth - sig_bits->red; - shift[channels++] = row_info->bit_depth - sig_bits->green < 0 ? - 0 : row_info->bit_depth - sig_bits->green; - shift[channels++] = row_info->bit_depth - sig_bits->blue < 0 ? - 0 : row_info->bit_depth - sig_bits->blue; + shift[channels++] = row_info->bit_depth - sig_bits->red; + shift[channels++] = row_info->bit_depth - sig_bits->green; + shift[channels++] = row_info->bit_depth - sig_bits->blue; } else { - shift[channels++] = row_info->bit_depth - sig_bits->gray < 0 ? - 0 : row_info->bit_depth - sig_bits->gray; + shift[channels++] = row_info->bit_depth - sig_bits->gray; } if (row_info->color_type & PNG_COLOR_MASK_ALPHA) { - shift[channels++] = row_info->bit_depth - sig_bits->alpha < 0 ? - 0 : row_info->bit_depth - sig_bits->alpha; - } + shift[channels++] = row_info->bit_depth - sig_bits->alpha; + } - value = 1; + value = 0; - for (i = 0; i < channels; i++) - { - if (shift[i] != 0) value = 0; - } + for (i = 0; i < channels; i++) + { + 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: { @@ -919,8 +921,7 @@ png_do_unshift(png_row_info *row_info, png_bytef *row, case 4: { 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]); for (bp = row, i = 0; i < row_info->rowbytes; @@ -938,7 +939,7 @@ png_do_unshift(png_row_info *row_info, png_bytef *row, { int c; - for (c = 0; c < row_info->channels; c++, bp++) + for (c = 0; c < row_info->channels; c++, bp++) { *bp >>= shift[c]; } @@ -956,7 +957,7 @@ png_do_unshift(png_row_info *row_info, png_bytef *row, { value = (*bp << 8) + *(bp + 1); value >>= shift[c]; - *bp = value >> 8; + *bp = value >> 8; *(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) /* chop rows of bit depth 16 down to 8 */ 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; - png_uint_32 i; - + sp = row; + dp = row; for (i = 0; i < row_info->width * row_info->channels; i++) { - *dp++ = ((((*sp << 8 | *(sp + 1)) - *sp) + 0x7F) >> 8) & 0xFF; - sp += 2; + *dp = *sp; +/* 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->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) /* add filler byte */ 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_bytef *sp, *dp; + png_bytep sp, dp; png_uint_32 i; if (row && row_info && row_info->color_type == 2 && 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) /* expand grayscale files to rgb, with or without alpha */ 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; + if (row && row_info && row_info->bit_depth >= 8 && !(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 of code. */ 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 color_inc; @@ -1160,7 +1169,6 @@ png_build_grayscale_palette(int bit_depth, png_color *palette) break; default: num_palette = 0; - color_inc = 0; break; } @@ -1174,7 +1182,7 @@ png_build_grayscale_palette(int bit_depth, png_color *palette) #if defined(PNG_READ_DITHER_SUPPORTED) void -png_correct_palette(png_struct *png_ptr, png_color *palette, +png_correct_palette(png_structp png_ptr, png_colorp palette, int num_palette) { 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 appropriate). note that paletted files are taken care of elsewhere */ void -png_do_background(png_row_info *row_info, png_bytef *row, - png_color_16 *trans_values, png_color_16 *background, - png_color_16 *background_1, - png_byte *gamma_table, png_byte *gamma_from_1, png_byte *gamma_to_1, - png_uint_16 **gamma_16, png_uint_16 **gamma_16_from_1, - png_uint_16 **gamma_16_to_1, int gamma_shift) +png_do_background(png_row_infop row_info, png_bytep row, + png_color_16p trans_values, png_color_16p background, + png_color_16p background_1, + png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1, + png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1, + png_uint_16pp gamma_16_to_1, int gamma_shift) { - png_bytef *sp, *dp; + png_bytep sp, dp; png_uint_32 i; + int shift; if (row && row_info && background && (!(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 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 - 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. */ void -png_do_gamma(png_row_info *row_info, png_bytef *row, - png_byte *gamma_table, png_uint_16 **gamma_16_table, +png_do_gamma(png_row_infop row_info, png_bytep row, + png_bytep gamma_table, png_uint_16pp gamma_16_table, int gamma_shift) { - png_bytef *sp; + png_bytep sp; png_uint_32 i; + if (row && row_info && ((row_info->bit_depth <= 8 && gamma_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 upon whether you supply trans and num_trans */ void -png_do_expand_palette(png_row_info *row_info, png_bytef *row, - png_color *palette, - png_byte *trans, int num_trans) +png_do_expand_palette(png_row_infop row_info, png_bytep row, + png_colorp palette, + png_bytep trans, int num_trans) { int shift, value; - png_bytef *sp, *dp; + png_bytep sp, dp; png_uint_32 i; + if (row && row_info && row_info->color_type == PNG_COLOR_TYPE_PALETTE) { 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 - transparency value is supplied, an alpha channel is built. */ + transparency value is supplied, an alpha channel is built. */ void -png_do_expand(png_row_info *row_info, png_bytef *row, - png_color_16 *trans_value) +png_do_expand(png_row_infop row_info, png_bytep row, + png_color_16p trans_value) { int shift, value; - png_bytef *sp, *dp; + png_bytep sp, dp; png_uint_32 i; + if (row && row_info) { 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-- = *sp--; } - } + } else if (row_info->bit_depth == 16) { 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-- = *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; 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 - 0) == trans_value->blue) *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++) { 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 - 3) << 8)) == trans_value->green) && (((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--; } } @@ -2499,11 +2511,12 @@ png_do_expand(png_row_info *row_info, png_bytef *row, #if defined(PNG_READ_DITHER_SUPPORTED) void -png_do_dither(png_row_info *row_info, png_bytef *row, - png_byte *palette_lookup, png_byte *dither_lookup) +png_do_dither(png_row_infop row_info, png_bytep row, + png_bytep palette_lookup, png_bytep dither_lookup) { - png_bytef *sp, *dp; + png_bytep sp, dp; png_uint_32 i; + if (row && row_info) { 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)) << (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) | (((g >> (8 - PNG_DITHER_GREEN_BITS)) & - ((1 << PNG_DITHER_GREEN_BITS) - 1)) << + ((1 << PNG_DITHER_GREEN_BITS) - 1)) << (PNG_DITHER_BLUE_BITS)) | ((b >> (8 - PNG_DITHER_BLUE_BITS)) & ((1 << PNG_DITHER_BLUE_BITS) - 1)); @@ -2556,7 +2569,7 @@ png_do_dither(png_row_info *row_info, png_bytef *row, sp++; 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)) | (((g >> (8 - PNG_DITHER_GREEN_BITS)) & ((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 && dither_lookup && row_info->bit_depth == 8) - { + { sp = row; 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}; void -png_build_gamma_table(png_struct *png_ptr) +png_build_gamma_table(png_structp png_ptr) { 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); - png_ptr->gamma_table = (png_byte *)png_malloc(png_ptr, + png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr, (png_uint_32)256); for (i = 0; i < 256; i++) @@ -2612,7 +2625,7 @@ png_build_gamma_table(png_struct *png_ptr) { 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); 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); - 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); for (i = 0; i < 256; i++) @@ -2633,16 +2646,15 @@ png_build_gamma_table(png_struct *png_ptr) } } } - else + else { double g; - int i, j, shift, num; - png_uint_32 ig; -#if defined(PNG_READ_sBIT_SUPPORTED) - int sig_bit; + int i, j, shift, num; + int sig_bit; + png_uint_32 ig; if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) - { + { sig_bit = (int)png_ptr->sig_bit.red; if ((int)png_ptr->sig_bit.green > sig_bit) sig_bit = png_ptr->sig_bit.green; @@ -2652,13 +2664,12 @@ png_build_gamma_table(png_struct *png_ptr) else { sig_bit = (int)png_ptr->sig_bit.gray; - } + } if (sig_bit > 0) shift = 16 - sig_bit; else -#endif /* PNG_READ_sBIT_SUPPORTED */ - shift = 0; + shift = 0; 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); } - if (shift > 8) + if (shift > 8) shift = 8; if (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); - png_ptr->gamma_16_table = (png_uint_16 **)png_malloc(png_ptr, - num * sizeof (png_uint_16 *)); + png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr, + num * sizeof (png_uint_16p )); if ((png_ptr->transformations & PNG_16_TO_8) && !(png_ptr->transformations & PNG_BACKGROUND)) { - double fin, fout; - png_uint_32 last, max; + double fin, fout; + png_uint_32 last, max; for (i = 0; i < num; i++) { - png_ptr->gamma_16_table[i] = (png_uint_16 *)png_malloc(png_ptr, - 256 * sizeof (png_uint_16)); + png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr, + 256 * sizeof (png_uint_16)); } - g = 1.0 / g; - last = 0; - for (i = 0; i < 256; i++) - { - fout = ((double)i + 0.5) / 256.0; - fin = pow(fout, g); - max = (png_uint_32)(fin * (double)(num << 8)); - while (last <= max) - { - png_ptr->gamma_16_table[(int)(last >> 8)][(int)(last & 0xff)] = - (png_uint_16)i | ((png_uint_16)i << 8); + g = 1.0 / g; + last = 0; + for (i = 0; i < 256; i++) + { + fout = ((double)i + 0.5) / 256.0; + fin = pow(fout, g); + max = (png_uint_32)(fin * (double)(num << 8)); + while (last <= max) + { + png_ptr->gamma_16_table[(int)(last & 0xff) >> shift] + [(int)(last >> (8 - shift))] = + (png_uint_16)i | ((png_uint_16)i << 8); last++; } - } - while (last < (num << 8)) - { - png_ptr->gamma_16_table[(int)(last >> 8)][(int)(last & 0xff)] = - (png_uint_16)65535L; - last++; - } + } + while (last < ((png_uint_32)num << 8)) + { + png_ptr->gamma_16_table[(int)(last & 0xff) >> shift] + [(int)(last >> (8 - shift))] = + (png_uint_16)65535L; + last++; + } } else { 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)); ig = (((png_uint_32)i * @@ -2735,12 +2748,12 @@ png_build_gamma_table(png_struct *png_ptr) { g = 1.0 / (png_ptr->gamma); - png_ptr->gamma_16_to_1 = (png_uint_16 **)png_malloc(png_ptr, - num * sizeof (png_uint_16 *)); + png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr, + num * sizeof (png_uint_16p )); 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)); ig = (((png_uint_32)i * @@ -2754,12 +2767,12 @@ png_build_gamma_table(png_struct *png_ptr) } g = 1.0 / (png_ptr->display_gamma); - png_ptr->gamma_16_from_1 = (png_uint_16 **)png_malloc(png_ptr, - num * sizeof (png_uint_16 *)); + png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr, + num * sizeof (png_uint_16p)); 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)); ig = (((png_uint_32)i * diff --git a/pngrutil.c b/pngrutil.c index 4800e8e2..2bbd427d 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -1,10 +1,10 @@ /* 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 Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. - August 24, 1995 + December 19, 1995 */ #define PNG_INTERNAL @@ -12,7 +12,7 @@ /* grab an uint 32 from a buffer */ png_uint_32 -png_get_uint_32(png_byte *buf) +png_get_uint_32(png_bytep buf) { png_uint_32 i; @@ -26,11 +26,11 @@ png_get_uint_32(png_byte *buf) /* grab an uint 16 from a buffer */ png_uint_16 -png_get_uint_16(png_byte *buf) +png_get_uint_16(png_bytep buf) { png_uint_16 i; - i = ((png_uint_16)(*buf) << 8) + + i = ((png_uint_16)(*buf) << 8) + (png_uint_16)(*(buf + 1)); return i; @@ -38,33 +38,33 @@ png_get_uint_16(png_byte *buf) /* read data, and run it through the crc */ 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); } /* skip data, but calcuate the crc anyway */ 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; 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); } 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); } } /* read and check the IDHR chunk */ 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_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 */ 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); @@ -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 */ 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 */ if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && bit_depth != 8 && 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 || 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) - (*(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 || color_type == PNG_COLOR_TYPE_GRAY_ALPHA || color_type == PNG_COLOR_TYPE_RGB_ALPHA) && 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) - (*(png_ptr->error_fn))(png_ptr, "Found Unsupported Interlace Value"); + png_error(png_ptr, "Found Invalid Interlace Value"); 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) - (*(png_ptr->error_fn))(png_ptr, "Found Unsupported Filter Value"); + png_error(png_ptr, "Found Invalid Filter Value"); /* set internal variables */ 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 */ 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; - png_color *palette; + png_colorp palette; if (length % 3) - (*(png_ptr->error_fn))(png_ptr, "Invalid Palette Chunk"); + png_error(png_ptr, "Invalid Palette Chunk"); num = (int)length / 3; - palette = (png_color *)png_malloc(png_ptr, num * sizeof (png_color)); - png_ptr->do_free |= PNG_FREE_PALETTE; - + palette = (png_colorp)png_malloc(png_ptr, num * sizeof (png_color)); for (i = 0; i < num; i++) { 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) 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; float gamma; @@ -191,7 +189,6 @@ png_handle_gAMA(png_struct *png_ptr, png_info *info, png_uint_32 length) if (length != 4) { - (*(png_ptr->warning_fn))(png_ptr,"Incorrect gAMA chunk length"); png_crc_skip(png_ptr, length); 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); /* check for zero gamma */ if (!igamma) - return; + return; gamma = (float)igamma / (float)100000.0; 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) 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; - register int index = 0; png_byte buf[4]; if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) slen = 3; else - slen = png_ptr->channels; + slen = png_ptr->channels; if (length != (png_uint_32)slen) { - (*(png_ptr->warning_fn))(png_ptr, "Incorrect sBIT chunk length"); png_crc_skip(png_ptr, length); 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); if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) { - png_ptr->sig_bit.red = buf[index++]; - png_ptr->sig_bit.green = buf[index++]; - png_ptr->sig_bit.blue = buf[index++]; - png_ptr->sig_bit.gray = 0; + png_ptr->sig_bit.red = buf[0]; + png_ptr->sig_bit.green = buf[1]; + png_ptr->sig_bit.blue = buf[2]; + png_ptr->sig_bit.alpha = buf[3]; } else { - png_ptr->sig_bit.red = 0; - png_ptr->sig_bit.green = 0; - png_ptr->sig_bit.blue = 0; - png_ptr->sig_bit.gray = buf[0]; + png_ptr->sig_bit.gray = buf[0]; + png_ptr->sig_bit.alpha = buf[1]; } - - if (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) - { - png_ptr->sig_bit.alpha = buf[index++]; - } - else - { - png_ptr->sig_bit.alpha = 0; - } - png_read_sBIT(png_ptr, info, &(png_ptr->sig_bit)); } #endif #if defined(PNG_READ_cHRM_SUPPORTED) 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_uint_32 v; @@ -267,9 +250,8 @@ png_handle_cHRM(png_struct *png_ptr, png_info *info, png_uint_32 length) if (length != 32) { - (*(png_ptr->warning_fn))(png_ptr, "Incorrect cHRM chunk length"); png_crc_skip(png_ptr, length); - return; + return; } 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; 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 #if defined(PNG_READ_tRNS_SUPPORTED) 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 (length > png_ptr->num_palette) { - (*(png_ptr->warning_fn))(png_ptr, "Incorrect tRNS chunk length"); png_crc_skip(png_ptr, length); return; } - png_ptr->trans = png_malloc(png_ptr, length); - png_ptr->do_free |= PNG_FREE_TRANS; + png_ptr->trans = (png_bytep)png_malloc(png_ptr, 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) { @@ -333,7 +313,6 @@ png_handle_tRNS(png_struct *png_ptr, png_info *info, png_uint_32 length) if (length != 6) { - (*(png_ptr->warning_fn))(png_ptr, "Incorrect tRNS chunk length"); png_crc_skip(png_ptr, length); return; } @@ -350,7 +329,6 @@ png_handle_tRNS(png_struct *png_ptr, png_info *info, png_uint_32 length) if (length != 2) { - (*(png_ptr->warning_fn))(png_ptr, "Incorrect tRNS chunk length"); png_crc_skip(png_ptr, length); 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); } 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_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) 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; 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) { - (*(png_ptr->warning_fn))(png_ptr, "Incorrect bKGD chunk length"); png_crc_skip(png_ptr, length); 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) 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; if (length != 2 * png_ptr->num_palette) { - (*(png_ptr->warning_fn))(png_ptr, "Incorrect hIST chunk length"); png_crc_skip(png_ptr, length); return; } num = (int)length / 2; - png_ptr->hist = png_malloc(png_ptr, num * sizeof (png_uint_16)); - png_ptr->do_free |= PNG_FREE_HIST; - + png_ptr->hist = (png_uint_16p)png_malloc(png_ptr, + num * sizeof (png_uint_16)); for (i = 0; i < num; i++) { 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) 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_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) { - (*(png_ptr->warning_fn))(png_ptr, "Incorrect pHYS chunk length"); png_crc_skip(png_ptr, length); return; - } + } 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) 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_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) { - (*(png_ptr->warning_fn))(png_ptr, "Incorrect oFFs chunk length"); png_crc_skip(png_ptr, length); 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) 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_time mod_time; if (length != 7) { - (*(png_ptr->warning_fn))(png_ptr, "Incorrect tIME chunk length"); png_crc_skip(png_ptr, length); 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.day = buf[3]; 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); } @@ -510,16 +482,16 @@ png_handle_tIME(png_struct *png_ptr, png_info *info, png_uint_32 length) #if defined(PNG_READ_tEXt_SUPPORTED) /* note: this does not correctly handle chunks that are > 64K */ 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; - charf *text; + png_charp key; + png_charp text; text = NULL; - key = (charf *)png_large_malloc(png_ptr, length + 1); - png_crc_read(png_ptr, (png_bytef *)key, length); - key[(png_size_t)length] = '\0'; + key = (png_charp )png_large_malloc(png_ptr, length + 1); + png_crc_read(png_ptr, (png_bytep )key, length); + key[(png_size_t)length] = '\0'; for (text = key; *text; text++) /* 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) /* note: this does not correctly handle chunks that are > 64K compressed */ 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; - charf *text; - int ret = Z_STREAM_END; + png_charp key; + png_charp text; + int ret; png_uint_32 text_size, key_size; text = NULL; 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'; 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 */ if (text == key + (png_size_t)length) { - (*(png_ptr->warning_fn))(png_ptr, "Zero length zTXt chunk"); png_large_free(png_ptr, key); return; } @@ -568,7 +539,7 @@ png_handle_zTXt(png_struct *png_ptr, png_info *info, png_uint_32 length) 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->next_out = png_ptr->zbuf; 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) { - 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 (png_ptr->zstream->msg) - (*(png_ptr->warning_fn))(png_ptr,png_ptr->zstream->msg); - else - (*(png_ptr->warning_fn))(png_ptr,"zTXt decompression error"); - inflateReset(png_ptr->zstream); + inflateReset(png_ptr->zstream); png_ptr->zstream->avail_in = 0; png_large_free(png_ptr, key); 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) { - text = png_malloc(png_ptr, + text = (png_charp)png_malloc(png_ptr, png_ptr->zbuf_size - png_ptr->zstream->avail_out + key_size + 1); 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 { - charf *tmp; + png_charp tmp; tmp = text; 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; } - inflateReset(png_ptr->zstream); + inflateReset(png_ptr->zstream); png_ptr->zstream->avail_in = 0; 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. */ void -png_combine_row(png_struct *png_ptr, png_bytef *row, +png_combine_row(png_structp png_ptr, png_bytep row, int mask) { if (mask == 0xff) @@ -681,8 +648,8 @@ png_combine_row(png_struct *png_ptr, png_bytef *row, { case 1: { - png_bytef *sp; - png_bytef *dp; + png_bytep sp; + png_bytep dp; int m; int shift; png_uint_32 i; @@ -719,8 +686,8 @@ png_combine_row(png_struct *png_ptr, png_bytef *row, } case 2: { - png_bytef *sp; - png_bytef *dp; + png_bytep sp; + png_bytep dp; int m; int shift; png_uint_32 i; @@ -756,8 +723,8 @@ png_combine_row(png_struct *png_ptr, png_bytef *row, } case 4: { - png_bytef *sp; - png_bytef *dp; + png_bytep sp; + png_bytep dp; int m; int shift; png_uint_32 i; @@ -793,8 +760,8 @@ png_combine_row(png_struct *png_ptr, png_bytef *row, } default: { - png_bytef *sp; - png_bytef *dp; + png_bytep sp; + png_bytep dp; png_uint_32 i; int pixel_bytes, m; @@ -826,7 +793,7 @@ png_combine_row(png_struct *png_ptr, png_bytef *row, #if defined(PNG_READ_INTERLACING_SUPPORTED) 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) { @@ -838,7 +805,7 @@ png_do_read_interlace(png_row_info *row_info, png_bytef *row, int pass) { case 1: { - png_bytef *sp, *dp; + png_bytep sp, dp; int sshift, dshift; png_byte v; png_uint_32 i; @@ -875,7 +842,7 @@ png_do_read_interlace(png_row_info *row_info, png_bytef *row, int pass) } case 2: { - png_bytef *sp, *dp; + png_bytep sp, dp; int sshift, dshift; png_byte v; 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: { - png_bytef *sp, *dp; + png_bytep sp, dp; int sshift, dshift; png_byte v; png_uint_32 i; @@ -948,7 +915,7 @@ png_do_read_interlace(png_row_info *row_info, png_bytef *row, int pass) } default: { - png_bytef *sp, *dp; + png_bytep sp, dp; png_byte v[8]; png_uint_32 i; int j; @@ -979,8 +946,8 @@ png_do_read_interlace(png_row_info *row_info, png_bytef *row, int pass) #endif void -png_read_filter_row(png_row_info *row_info, png_bytef *row, - png_bytef *prev_row, int filter) +png_read_filter_row(png_row_infop row_info, png_bytep row, + png_bytep prev_row, int filter) { switch (filter) { @@ -990,8 +957,8 @@ png_read_filter_row(png_row_info *row_info, png_bytef *row, { png_uint_32 i; int bpp; - png_bytef *rp; - png_bytef *lp; + png_bytep rp; + png_bytep lp; bpp = (row_info->pixel_depth + 7) / 8; 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: { png_uint_32 i; - png_bytef *rp; - png_bytef *pp; + png_bytep rp; + png_bytep pp; for (i = 0, rp = row, pp = prev_row; 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; int bpp; - png_bytef *rp; - png_bytef *pp; - png_bytef *lp; + png_bytep rp; + png_bytep pp; + png_bytep lp; bpp = (row_info->pixel_depth + 7) / 8; 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; png_uint_32 i; - png_bytef *rp; - png_bytef *pp; - png_bytef *lp; - png_bytef *cp; + png_bytep rp; + png_bytep pp; + png_bytep lp; + png_bytep cp; bpp = (row_info->pixel_depth + 7) / 8; 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 -png_read_finish_row(png_struct *png_ptr) +png_read_finish_row(png_structp png_ptr) { png_ptr->row_number++; 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_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); if (((crc ^ 0xffffffffL) & 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_reset_crc(png_ptr); png_crc_read(png_ptr, buf, 4); - if (memcmp(buf, png_IDAT, 4)) - (*(png_ptr->error_fn))(png_ptr, "Not enough image data"); + if (png_memcmp(buf, png_IDAT, 4)) + png_error(png_ptr, "Not enough image data"); } 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_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 (!(png_ptr->zstream->avail_out) || png_ptr->zstream->avail_in || 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; break; } if (ret != Z_OK) - (*(png_ptr->error_fn))(png_ptr, "Compression Error"); + png_error(png_ptr, "Compression Error"); if (!(png_ptr->zstream->avail_out)) - (*(png_ptr->error_fn))(png_ptr, "Extra compressed data"); + png_error(png_ptr, "Extra compressed data"); } while (1); png_ptr->zstream->avail_out = 0; } 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); @@ -1188,7 +1155,7 @@ png_read_finish_row(png_struct *png_ptr) } void -png_read_start_row(png_struct *png_ptr) +png_read_start_row(png_structp png_ptr) { int max_pixel_depth; png_uint_32 rowbytes; @@ -1292,13 +1259,13 @@ png_read_start_row(png_struct *png_ptr) 1 + ((max_pixel_depth + 7) >> 3); #ifdef PNG_MAX_MALLOC_64K 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 - 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 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 png_ptr->prev_row = png_large_malloc(png_ptr, png_ptr->rowbytes + 1); diff --git a/pngtest.c b/pngtest.c index 6a92f365..59ce6ec4 100644 --- a/pngtest.c +++ b/pngtest.c @@ -15,11 +15,12 @@ #endif /* 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 */ char inname[] = "pngtest.png"; -char outname[] = "testout.png"; +char outname[] = "pngout.png"; png_struct read_ptr; png_struct write_ptr; @@ -31,12 +32,12 @@ char inbuf[256], outbuf[256]; int main() { FILE *fpin, *fpout; - png_byte *row_buf; + png_bytep row_buf; png_uint_32 rowbytes; png_uint_32 y; 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); @@ -79,10 +80,10 @@ int main() return 1; } - png_info_init(&info_ptr); - png_info_init(&end_info); png_read_init(&read_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(&write_ptr, fpout); @@ -97,15 +98,12 @@ int main() if (info_ptr.color_type & 4) 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); - row_buf = (png_byte *)malloc((size_t)rowbytes); + row_buf = (png_bytep )malloc((size_t)rowbytes); if (!row_buf) { 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); fclose(fpin); fclose(fpout); @@ -126,8 +124,8 @@ int main() { for (y = 0; y < info_ptr.height; y++) { - png_read_rows(&read_ptr, (png_bytef **)&row_buf, (png_bytef **)0, 1); - png_write_rows(&write_ptr, (png_bytef **)&row_buf, 1); + png_read_rows(&read_ptr, (png_bytepp )&row_buf, (png_bytepp )0, 1); + png_write_rows(&write_ptr, (png_bytepp )&row_buf, 1); } } @@ -140,7 +138,7 @@ int main() fclose(fpin); fclose(fpout); - free(row_buf); + free((void *)row_buf); fpin = fopen(inname, "rb"); diff --git a/pngtodo.txt b/pngtodo.txt index de444938..ff7e1fe3 100644 --- a/pngtodo.txt +++ b/pngtodo.txt @@ -1,18 +1,15 @@ pngtodo.txt - list of things to do for libpng for 0.9 - medium memory model - improved dithering? + improved dithering + final bug fixes + cHRM transformation -for 1.1 - push reader - -for 1.1 or later +after 1.0 overlaying one image on top of another optional palette creation histogram creation text conversion between different code types - cHRM transformation support for other chunks being defined (sCAl, the gIF series, and others that people come up with). pull writer diff --git a/pngtrans.c b/pngtrans.c index 83a42829..73d0694a 100644 --- a/pngtrans.c +++ b/pngtrans.c @@ -2,10 +2,10 @@ /* pngtrans.c - transforms the data in a row 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 Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. - August 24, 1995 + December 19, 1995 */ #define PNG_INTERNAL @@ -14,7 +14,7 @@ #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) /* turn on bgr to rgb mapping */ void -png_set_bgr(png_struct *png_ptr) +png_set_bgr(png_structp png_ptr) { 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) /* turn on 16 bit byte swapping */ void -png_set_swap(png_struct *png_ptr) +png_set_swap(png_structp png_ptr) { if (png_ptr->bit_depth == 16) 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) /* turn on pixel packing */ void -png_set_packing(png_struct *png_ptr) +png_set_packing(png_structp png_ptr) { 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) 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->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) int -png_set_interlace_handling(png_struct *png_ptr) +png_set_interlace_handling(png_structp png_ptr) { 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) 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->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 */ void -png_set_rgbx(png_struct *png_ptr) +png_set_rgbx(png_structp png_ptr) { png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); } void -png_set_xrgb(png_struct *png_ptr) +png_set_xrgb(png_structp png_ptr) { 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) void -png_set_invert_mono(png_struct *png_ptr) +png_set_invert_mono(png_structp png_ptr) { png_ptr->transformations |= PNG_INVERT_MONO; } /* invert monocrome grayscale data */ 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 && row_info->color_type == PNG_COLOR_TYPE_GRAY) { - png_bytef *rp; + png_bytep rp; png_uint_32 i; 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) /* swaps byte order on 16 bit depth images */ 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) { - png_bytef *rp; + png_bytep rp; png_byte t; 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) /* swaps red and blue */ 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_info->color_type == 2 && row_info->bit_depth == 8) { - png_bytef *rp; + png_bytep rp; png_byte t; 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) { - png_bytef *rp; + png_bytep rp; png_byte t; 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) { - png_bytef *rp; + png_bytep rp; png_byte t[2]; 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) { - png_bytef *rp; + png_bytep rp; png_byte t[2]; png_uint_32 i; diff --git a/pngwrite.c b/pngwrite.c index 50ea96b7..453d5cf2 100644 --- a/pngwrite.c +++ b/pngwrite.c @@ -1,10 +1,10 @@ /* 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 Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. - August 24, 1995 + December 19, 1995 */ /* get internal access to png.h */ @@ -16,12 +16,12 @@ 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(). 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. If you have long comments, I suggest writing them in png_write_end(), and compressing them. */ 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 */ /* write IHDR information. */ @@ -57,30 +57,25 @@ png_write_info(png_struct *png_ptr, png_info *info) if (info->valid & PNG_INFO_bKGD) png_write_bKGD(png_ptr, &(info->background), info->color_type); #endif - #if defined(PNG_WRITE_hIST_SUPPORTED) if (info->valid & PNG_INFO_hIST) png_write_hIST(png_ptr, info->hist, info->num_palette); #endif - #if defined(PNG_WRITE_pHYs_SUPPORTED) if (info->valid & PNG_INFO_pHYs) png_write_pHYs(png_ptr, info->x_pixels_per_unit, info->y_pixels_per_unit, info->phys_unit_type); #endif - #if defined(PNG_WRITE_oFFs_SUPPORTED) if (info->valid & PNG_INFO_oFFs) png_write_oFFs(png_ptr, info->x_offset, info->y_offset, info->offset_unit_type); #endif - #if defined(PNG_WRITE_tIME_SUPPORTED) if (info->valid & PNG_INFO_tIME) png_write_tIME(png_ptr, &(info->mod_time)); /* Check to see if we need to write text chunks */ #endif - #if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) if (info->num_text) { @@ -89,17 +84,11 @@ png_write_info(png_struct *png_ptr, png_info *info) /* loop through the text chunks */ 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 (info->text[i].compression >= 0) { #if defined(PNG_WRITE_zTXt_SUPPORTED) - /* write compressed chunk */ + /* write compressed chunk */ png_write_zTXt(png_ptr, info->text[i].key, info->text[i].text, info->text[i].text_length, info->text[i].compression); @@ -110,13 +99,12 @@ png_write_info(png_struct *png_ptr, png_info *info) #if defined(PNG_WRITE_tEXt_SUPPORTED) /* write uncompressed chunk */ 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 /* PNG_WRITE_tEXt_SUPPORTED || PNG_WRITE_zTXt_SUPPORTED */ - png_ptr->mode = PNG_HAVE_IHDR; +#endif } /* 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 comments, I suggest writing them here, and compressing them. */ 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 */ if (info) { @@ -137,7 +122,6 @@ png_write_end(png_struct *png_ptr, png_info *info) if (info->valid & PNG_INFO_tIME) png_write_tIME(png_ptr, &(info->mod_time)); #endif - #if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) /* check to see if we need to write comment chunks */ if (info->num_text) @@ -146,7 +130,7 @@ png_write_end(png_struct *png_ptr, png_info *info) /* loop through comment chunks */ for (i = 0; i < info->num_text; i++) - { + { /* check to see if comment is to be compressed */ 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, info->text[i].text, info->text[i].text_length); #endif - } + } } } -#endif /* PNG_WRITE_tEXt_SUPPORTED || PNG_WRITE_zTXt_SUPPORTED */ +#endif } /* write end of png file */ png_write_IEND(png_ptr); - - png_ptr->mode = PNG_AFTER_IEND; } #if defined(PNG_WRITE_tIME_SUPPORTED) 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->month = ttime->tm_mon + 1; - ptime->day = ttime->tm_mday; - ptime->hour = ttime->tm_hour; - ptime->minute = ttime->tm_min; - ptime->second = ttime->tm_sec; + ptime->year = 1900 + ttime->tm_year; + ptime->month = ttime->tm_mon + 1; + ptime->day = ttime->tm_mday; + ptime->hour = ttime->tm_hour; + ptime->minute = ttime->tm_min; + ptime->second = ttime->tm_sec; } 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; tbuf = gmtime(&ttime); png_convert_from_struct_tm(ptime, tbuf); } -#endif /* PNG_WRITE_tIME_SUPPORTED */ +#endif /* initialize png structure, and allocate any memory needed */ void -png_write_init(png_struct *png_ptr) +png_write_init(png_structp png_ptr) { 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 */ - png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf)); - /* reset all variables to 0 */ - png_memset(png_ptr, 0, sizeof (png_struct)); - /* restore jump buffer */ + /* save jump buffer and error functions */ + png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf)); + error_fn = png_ptr->error_fn; + warning_fn = png_ptr->warning_fn; + 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_ptr->error_fn = error_fn; + png_ptr->warning_fn = warning_fn; + png_ptr->msg_ptr = msg_ptr; /* initialize zbuf - compression buffer */ 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, either you will have to write the 7 sub images, or, if you have called png_set_interlace_handling(), you will have to - "write" the image seven times */ + "write" the image seven times */ 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 i; /* row counter */ - png_bytef **rp; /* row pointer */ + png_bytepp rp; /* row pointer */ /* loop through the rows */ 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 if you are writing an interlaced image. */ 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 */ 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, 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 */ 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 */ - if (png_ptr->mode < PNG_HAVE_IDAT) + if (png_ptr->row_number == 0 && png_ptr->pass == 0) { png_write_start_row(png_ptr); } - png_ptr->mode = PNG_HAVE_IDAT; - #if defined(PNG_WRITE_INTERLACING_SUPPORTED) /* if interlaced and not interested in row, return */ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) { switch (png_ptr->pass) { - case 0: + case 0: if (png_ptr->row_number & 7) { 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) { png_write_finish_row(png_ptr); - return; + return; } break; case 3: @@ -310,7 +300,7 @@ png_write_row(png_struct *png_ptr, png_bytef *row) } break; 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); return; @@ -325,10 +315,10 @@ png_write_row(png_struct *png_ptr, png_bytef *row) break; } } -#endif /* PNG_WRITE_INTERLACE_SUPPORTED */ +#endif /* 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.channels = png_ptr->usr_channels; 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_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 ... */ if (!(png_ptr->row_info.width)) { @@ -354,7 +344,7 @@ png_write_row(png_struct *png_ptr, png_bytef *row) return; } } -#endif /* PNG_WRITE_INTERLACE_SUPPORTED */ +#endif /* handle other transformations */ if (png_ptr->transformations) @@ -364,7 +354,7 @@ png_write_row(png_struct *png_ptr, png_bytef *row) if (png_ptr->do_filter) { /* 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); /* 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 */ { /* scope limiter */ - png_bytef *tptr; + png_bytep tptr; tptr = png_ptr->prev_row; png_ptr->prev_row = png_ptr->save_row; @@ -382,12 +372,11 @@ png_write_row(png_struct *png_ptr, png_bytef *row) } else /* set filter row to "none" */ - png_ptr->row_buf[0] = 0; + png_ptr->row_buf[0] = 0; /* set up the zlib input buffer */ png_ptr->zstream->next_in = png_ptr->row_buf; png_ptr->zstream->avail_in = (uInt)png_ptr->row_info.rowbytes + 1; - /* repeat until we have compressed all the data */ do { @@ -399,9 +388,9 @@ png_write_row(png_struct *png_ptr, png_bytef *row) if (ret != Z_OK) { if (png_ptr->zstream->msg) - (*(png_ptr->error_fn))(png_ptr, png_ptr->zstream->msg); - else - (*(png_ptr->error_fn))(png_ptr, "zlib error"); + png_error(png_ptr, png_ptr->zstream->msg); + else + png_error(png_ptr, "zlib error"); } /* 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 */ } while (png_ptr->zstream->avail_in); - /* finish row - updates counters and flushes zlib if last row */ - png_write_finish_row(png_ptr); + /* finish row - updates counters and flushes zlib if last row */ + png_write_finish_row(png_ptr); #if defined(PNG_WRITE_FLUSH_SUPPORTED) - png_ptr->flush_rows++; + png_ptr->flush_rows++; - if (png_ptr->flush_dist > 0 && - png_ptr->flush_rows >= png_ptr->flush_dist) - { - png_write_flush(png_ptr); - } + if (png_ptr->flush_dist > 0 && + png_ptr->flush_rows >= png_ptr->flush_dist) + { + png_write_flush(png_ptr); + } #endif /* PNG_WRITE_FLUSH_SUPPORTED */ } @@ -434,68 +423,70 @@ png_write_row(png_struct *png_ptr, png_bytef *row) void 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 */ void png_write_flush(png_struct *png_ptr) { - char wrote_IDAT; + int wrote_IDAT; - if (png_ptr->mode != PNG_HAVE_IDAT) - return; + if (png_ptr->mode != PNG_HAVE_IDAT) + return; - do - { - int ret; + do + { + int ret; - /* compress the data */ - ret = deflate(png_ptr->zstream, Z_SYNC_FLUSH); - wrote_IDAT = 0; + /* compress the data */ + ret = deflate(png_ptr->zstream, Z_SYNC_FLUSH); + wrote_IDAT = 0; - /* check for compression errors */ - if (ret != Z_OK) - { - if (png_ptr->zstream->msg) - (*(png_ptr->error_fn))(png_ptr, png_ptr->zstream->msg); - else - (*(png_ptr->error_fn))(png_ptr, "zlib error"); - } + /* check for compression errors */ + if (ret != Z_OK) + { + if (png_ptr->zstream->msg) + png_error(png_ptr, png_ptr->zstream->msg); + else + png_error(png_ptr, "zlib error"); + } - if (!png_ptr->zstream->avail_out) - { - /* write the IDAT and reset the zlib output buffer */ - png_write_IDAT(png_ptr, png_ptr->zbuf, - png_ptr->zbuf_size); - png_ptr->zstream->next_out = png_ptr->zbuf; - png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size; - wrote_IDAT = 1; - } - } while(wrote_IDAT == 1); + if (!png_ptr->zstream->avail_out) + { + /* write the IDAT and reset the zlib output buffer */ + png_write_IDAT(png_ptr, png_ptr->zbuf, + png_ptr->zbuf_size); + png_ptr->zstream->next_out = png_ptr->zbuf; + png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size; + wrote_IDAT = 1; + } + } while(wrote_IDAT == 1); - /* If there is any data left to be output, write it into a new IDAT */ - if (png_ptr->zbuf_size != png_ptr->zstream->avail_out) - { - /* write the IDAT and reset the zlib output buffer */ - png_write_IDAT(png_ptr, png_ptr->zbuf, - png_ptr->zbuf_size - png_ptr->zstream->avail_out); - png_ptr->zstream->next_out = png_ptr->zbuf; - png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size; - } - png_ptr->flush_rows = 0; - (*(png_ptr->output_flush_fn))(png_ptr); + /* If there is any data left to be output, write it into a new IDAT */ + if (png_ptr->zbuf_size != png_ptr->zstream->avail_out) + { + /* write the IDAT and reset the zlib output buffer */ + png_write_IDAT(png_ptr, png_ptr->zbuf, + png_ptr->zbuf_size - png_ptr->zstream->avail_out); + png_ptr->zstream->next_out = png_ptr->zbuf; + png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size; + } + png_ptr->flush_rows = 0; + png_flush(png_ptr); } #endif /* PNG_WRITE_FLUSH_SUPPORTED */ + /* free any memory used in png struct */ 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 */ - deflateEnd(png_ptr->zstream); + deflateEnd(png_ptr->zstream); + png_free(png_ptr, png_ptr->zstream); /* free our memory. png_free checks NULL for us. */ png_large_free(png_ptr, png_ptr->zbuf); 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_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf)); } - 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_filter = filter; } 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_level = level; } 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_mem_level = mem_level; + png_ptr->zlib_mem_level = mem_level; } 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_strategy = strategy; } 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_window_bits = window_bits; } 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_method = method; diff --git a/pngwtran.c b/pngwtran.c index acbd0c21..c0961545 100644 --- a/pngwtran.c +++ b/pngwtran.c @@ -1,10 +1,10 @@ /* 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 Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. - August 24, 1995 + December 19, 1995 */ #define PNG_INTERNAL @@ -13,10 +13,10 @@ /* transform the data according to the users wishes. The order of transformations is significant. */ void -png_do_write_transformations(png_struct *png_ptr) +png_do_write_transformations(png_structp png_ptr) { #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_ptr->filler_loc); #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 should be 1 (this only happens on grayscale and paletted images) */ 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 && 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: { - png_bytef *sp; - png_bytef *dp; - int mask; - png_int_32 i; + png_bytep sp; + png_bytep dp; + int mask; + png_int_32 i; int v; sp = row; @@ -79,7 +79,7 @@ png_do_pack(png_row_info *row_info, png_bytef *row, png_byte bit_depth) { mask = 0x80; *dp = v; - dp++; + dp++; v = 0; } } @@ -89,8 +89,8 @@ png_do_pack(png_row_info *row_info, png_bytef *row, png_byte bit_depth) } case 2: { - png_bytef *sp; - png_bytef *dp; + png_bytep sp; + png_bytep dp; int shift; png_int_32 i; int v; @@ -121,8 +121,8 @@ png_do_pack(png_row_info *row_info, png_bytef *row, png_byte bit_depth) } case 4: { - png_bytef *sp; - png_bytef *dp; + png_bytep sp; + png_bytep dp; int shift; png_int_32 i; 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 data to 0 to 15. */ 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 && 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 */ if (row_info->bit_depth < 8) { - png_bytef *bp; + png_bytep bp; png_uint_32 i; int j; 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) { - png_bytef *bp; + png_bytep bp; png_uint_32 i; int j; @@ -262,7 +262,7 @@ png_do_shift(png_row_info *row_info, png_bytef *row, png_color_8 *bit_depth) } else { - png_bytef *bp; + png_bytep bp; png_uint_32 i; 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 /* remove filler byte */ 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) { 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) { - png_bytef *sp, *dp; + png_bytep sp, dp; + png_uint_32 i; 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 { - png_bytef *sp, *dp; + png_bytep sp, dp; 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++) { diff --git a/pngwutil.c b/pngwutil.c index c34d94ac..d1f834f7 100644 --- a/pngwutil.c +++ b/pngwutil.c @@ -1,10 +1,10 @@ /* 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 Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. - August 24, 1995 + December 19, 1995 */ #define PNG_INTERNAL #include "png.h" @@ -13,7 +13,7 @@ with unsigned numbers for convenience, you may have to cast signed numbers (if you use any, most png data is unsigned). */ 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[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 */ 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[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 */ 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]; @@ -39,18 +39,18 @@ png_write_uint_32(png_struct *png_ptr, png_uint_32 i) buf[1] = (png_byte)((i >> 16) & 0xff); buf[2] = (png_byte)((i >> 8) & 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 */ 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]; buf[0] = (png_byte)((i >> 8) & 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 @@ -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() functions instead. */ void -png_write_chunk(png_struct *png_ptr, png_byte *type, - png_bytef *data, png_uint_32 length) +png_write_chunk(png_structp png_ptr, png_bytep type, + png_bytep data, png_uint_32 length) { /* write length */ png_write_uint_32(png_ptr, length); /* 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 */ png_reset_crc(png_ptr); 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) { 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 */ 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 passing in png_write_chunk_data() */ 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) { /* write the length */ png_write_uint_32(png_ptr, total_length); /* 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 */ png_reset_crc(png_ptr); 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 given to png_write_chunk_start() */ 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 */ if (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() */ void -png_write_chunk_end(png_struct *png_ptr) +png_write_chunk_end(png_structp png_ptr) { /* write the 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 */ void -png_write_sig(png_struct *png_ptr) +png_write_sig(png_structp png_ptr) { /* 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 information. Note that the rest of this code depends upon this information being correct. */ 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 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 */ png_ptr->usr_width = png_ptr->width; 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 */ - 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 */ - 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->zfree = png_zfree; 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 structure. */ 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; - png_color *pal_ptr; + png_colorp pal_ptr; png_byte buf[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 */ 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); } /* write an IEND chunk */ 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); } @@ -257,7 +257,7 @@ png_write_IEND(png_struct *png_ptr) #if defined(PNG_WRITE_gAMA_SUPPORTED) /* write a gAMA chunk */ void -png_write_gAMA(png_struct *png_ptr, float gamma) +png_write_gAMA(png_structp png_ptr, double gamma) { png_uint_32 igamma; png_byte buf[4]; @@ -272,12 +272,12 @@ png_write_gAMA(png_struct *png_ptr, float gamma) #if defined(PNG_WRITE_sBIT_SUPPORTED) /* write the sBIT chunk */ 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]; 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) { 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) /* write the cHRM chunk */ void -png_write_cHRM(png_struct *png_ptr, float white_x, float white_y, - float red_x, float red_y, float green_x, float green_y, - float blue_x, float blue_y) +png_write_cHRM ( png_structp png_ptr, double white_x, double white_y, + double red_x, double red_y, double green_x, double green_y, + double blue_x, double blue_y) { png_uint_32 itemp; 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) /* write the tRNS chunk */ 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) { 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) /* write the background chunk */ 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]; @@ -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); } else - { + { png_save_uint_16(buf, back->gray); 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) /* write the histogram */ 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; 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)); 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_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) /* write a tEXt chunk */ 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) { int key_len; @@ -417,11 +417,11 @@ png_write_tEXt(png_struct *png_ptr, charf *key, charf *text, key_len = png_strlen(key); /* make sure we count the 0 after the key */ 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 */ - 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) - 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); } #endif @@ -429,13 +429,13 @@ png_write_tEXt(png_struct *png_ptr, charf *key, charf *text, #if defined(PNG_WRITE_zTXt_SUPPORTED) /* write a compressed chunk */ 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) { int key_len; char buf[1]; 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 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->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 { /* compress the data */ - ret = deflate(png_ptr->zstream, Z_NO_FLUSH); + ret = deflate(png_ptr->zstream, Z_NO_FLUSH); if (ret != Z_OK) { /* error */ if (png_ptr->zstream->msg) - (*(png_ptr->error_fn))(png_ptr, png_ptr->zstream->msg); + png_error(png_ptr, png_ptr->zstream->msg); else - (*(png_ptr->error_fn))(png_ptr, "zlib error"); + png_error(png_ptr, "zlib error"); } /* check to see if we need more room */ if (!png_ptr->zstream->avail_out && png_ptr->zstream->avail_in) { /* make sure the output array has room */ if (num_output_ptr >= max_output_ptr) - { + { png_uint_32 old_max; old_max = max_output_ptr; max_output_ptr = num_output_ptr + 4; if (output_ptr) - output_ptr = png_realloc(png_ptr, output_ptr, - max_output_ptr * sizeof (char *), - old_max * sizeof (char *)); + output_ptr = (png_charpp)png_realloc(png_ptr, output_ptr, + max_output_ptr * sizeof (png_charpp), + old_max * sizeof (png_charp)); else - output_ptr = png_malloc(png_ptr, - max_output_ptr * sizeof (char *)); + output_ptr = (png_charpp)png_malloc(png_ptr, + max_output_ptr * sizeof (png_charp)); } /* 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 */ } while (png_ptr->zstream->avail_in); - /* finish the compression */ + /* finish the compression */ do { /* 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) { /* we got an error */ if (png_ptr->zstream->msg) - (*(png_ptr->error_fn))(png_ptr, png_ptr->zstream->msg); + png_error(png_ptr, png_ptr->zstream->msg); else - (*(png_ptr->error_fn))(png_ptr, "zlib error"); + png_error(png_ptr, "zlib error"); } /* check to see if we need more room */ if (!png_ptr->zstream->avail_out && ret == Z_OK) { /* 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; old_max = max_output_ptr; max_output_ptr = num_output_ptr + 4; if (output_ptr) - output_ptr = png_realloc(png_ptr, output_ptr, - max_output_ptr * sizeof (char *), - old_max * sizeof (char *)); + output_ptr = (png_charpp)png_realloc(png_ptr, output_ptr, + max_output_ptr * sizeof (png_charp), + old_max * sizeof (png_charp)); else - output_ptr = png_malloc(png_ptr, - max_output_ptr * sizeof (char *)); + output_ptr = (png_charpp)png_malloc(png_ptr, + max_output_ptr * sizeof (png_charp)); } /* save off the data */ output_ptr[num_output_ptr] = png_large_malloc(png_ptr, 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); num_output_ptr++; @@ -546,7 +546,7 @@ png_write_zTXt(png_struct *png_ptr, charf *key, charf *text, } while (ret != Z_STREAM_END); /* 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) text_len += (png_uint_32)(png_ptr->zbuf_size - 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_uint_32)(key_len + text_len + 2)); /* 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; /* 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 */ for (i = 0; i < num_output_ptr; i++) { - png_write_chunk_data(png_ptr, (png_bytef *)output_ptr[i], png_ptr->zbuf_size); - png_large_free(png_ptr, output_ptr[i]); + png_write_chunk_data(png_ptr, (png_bytep )output_ptr[i], png_ptr->zbuf_size); + png_large_free(png_ptr, output_ptr[i]); } if (max_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); /* reset zlib for another zTXt or the image data */ - deflateReset(png_ptr->zstream); + deflateReset(png_ptr->zstream); } #endif #if defined(PNG_WRITE_pHYs_SUPPORTED) /* write the pHYs chunk */ 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, 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) /* write the oFFs chunk */ 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, 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() or png_convert_from_time_t(), or fill in the structure yourself */ 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]; @@ -635,26 +635,26 @@ png_write_tIME(png_struct *png_ptr, png_time *mod_time) /* initializes the row writing capability of libpng */ void -png_write_start_row(png_struct *png_ptr) +png_write_start_row(png_structp png_ptr) { /* 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_bit_depth * - png_ptr->width) >> 3) + 1); + png_ptr->width + 7) >> 3) + 1); /* set up filtering buffers, if filtering */ 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_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_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 (png_ptr->interlaced) + if (png_ptr->interlaced) { if (!(png_ptr->transformations & PNG_INTERLACE)) { @@ -672,7 +672,7 @@ png_write_start_row(png_struct *png_ptr) } } else - { + { png_ptr->num_rows = png_ptr->height; 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 */ void -png_write_finish_row(png_struct *png_ptr) +png_write_finish_row(png_structp png_ptr) { int ret; /* next row */ png_ptr->row_number++; /* see if we are done */ - if (png_ptr->row_number < png_ptr->num_rows || png_ptr->mode > PNG_HAVE_IDAT) - return; + if (png_ptr->row_number < png_ptr->num_rows) + return; /* if interlaced, go to next pass */ if (png_ptr->interlaced) @@ -708,7 +708,7 @@ png_write_finish_row(png_struct *png_ptr) png_ptr->pass++; if (png_ptr->pass >= 7) break; - png_ptr->usr_width = (png_ptr->width + + png_ptr->usr_width = (png_ptr->width + png_pass_inc[png_ptr->pass] - 1 - png_pass_start[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) 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 (png_ptr->pass < 7) + if (png_ptr->pass < 7) return; } @@ -735,16 +735,16 @@ png_write_finish_row(png_struct *png_ptr) do { /* tell the compressor we are done */ - ret = deflate(png_ptr->zstream, Z_FINISH); + ret = deflate(png_ptr->zstream, Z_FINISH); /* check for an error */ if (ret != Z_OK && ret != Z_STREAM_END) { if (png_ptr->zstream->msg) - (*(png_ptr->error_fn))(png_ptr, png_ptr->zstream->msg); + png_error(png_ptr, png_ptr->zstream->msg); 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) { 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); - png_ptr->mode = PNG_AFTER_IDAT; } #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. */ 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) */ if (row && row_info && pass < 6) { /* each pixel depth is handled seperately */ switch (row_info->pixel_depth) - { + { case 1: { - png_bytef *sp; - png_bytef *dp; + png_bytep sp; + png_bytep dp; int shift; int d; 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]) { 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); if (shift == 0) @@ -817,9 +816,9 @@ png_do_write_interlace(png_row_info *row_info, png_bytef *row, int pass) break; } case 2: - { - png_bytef *sp; - png_bytef *dp; + { + png_bytep sp; + png_bytep dp; int shift; int d; int value; @@ -851,9 +850,9 @@ png_do_write_interlace(png_row_info *row_info, png_bytef *row, int pass) } case 4: { - png_bytef *sp; - png_bytef *dp; - int shift; + png_bytep sp; + png_bytep dp; + int shift; int d; int value; 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) { - shift = 4; + shift = 4; *dp++ = d; d = 0; } @@ -884,12 +883,12 @@ png_do_write_interlace(png_row_info *row_info, png_bytef *row, int pass) } default: { - png_bytef *sp; - png_bytef *dp; + png_bytep sp; + png_bytep dp; png_uint_32 i; int pixel_bytes; - /* start at the beginning */ + /* start at the beginning */ dp = row; /* find out how many bytes each pixel takes up */ 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 */ dp += pixel_bytes; } - break; + break; } } /* 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 first byte for the filter byte. */ void -png_write_filter_row(png_row_info *row_info, png_bytef *row, - png_bytef *prev_row) +png_write_filter_row(png_row_infop row_info, png_bytep row, + png_bytep prev_row) { int minf, bpp; png_uint_32 i, v; 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 */ 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. */ 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; 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; - /* check none filter */ + /* check none filter */ v = *rp; if (v < 128) s0 += v; @@ -997,7 +996,7 @@ png_write_filter_row(png_row_info *row_info, png_bytef *row, /* check up filter */ v = (png_byte)(((int)*rp - (int)*pp) & 0xff); - if (v < 128) + if (v < 128) s2 += v; else s2 += 256 - v; @@ -1015,7 +1014,7 @@ png_write_filter_row(png_row_info *row_info, png_bytef *row, c = *cp; a = *lp; p = a + b - c; - pa = abs(p - a); + pa = abs(p - a); pb = abs(p - b); pc = abs(p - c); @@ -1051,7 +1050,7 @@ png_write_filter_row(png_row_info *row_info, png_bytef *row, if (s3 < mins) { - mins = s3; + mins = s3; minf = 3; } @@ -1069,7 +1068,7 @@ png_write_filter_row(png_row_info *row_info, png_bytef *row, { /* sub filter */ 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; i < row_info->rowbytes; i++, rp--, lp--) { @@ -1087,7 +1086,7 @@ png_write_filter_row(png_row_info *row_info, png_bytef *row, break; /* avg filter */ case 3: - for (i = row_info->rowbytes, + for (i = row_info->rowbytes, rp = 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; @@ -1105,7 +1104,7 @@ png_write_filter_row(png_row_info *row_info, png_bytef *row, case 4: for (i = 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, cp = prev_row + (png_size_t)row_info->rowbytes - bpp; 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; } p = a + b - c; - pa = abs(p - a); + pa = abs(p - a); pb = abs(p - b); pc = abs(p - c); diff --git a/readme.txt b/readme.txt index f1800a41..b0274551 100644 --- a/readme.txt +++ b/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 -of the stuff I want to before the final 1.0 version. Remaining -to do are the medium memory model support (which I'll put in -as soon as we test this version), better dithering, and any bug -fixes and makefile/include additions. I expect a third (and -perhaps final) beta after zlib is officially 1.0. +This is a bug fix for the second beta version of libpng 1.0, and +a first try at a progressive (push) reader. It hasn't been +tested very much, but I'm not going to have time to test it for +a few days, and I wanted to give an advanced look at the +progressive reader to everyone. Please report bugs back +(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 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. -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 usage information and restrictions (what little they are) on libpng, see png.h. For a description on using zlib (the compression library