diff --git a/ansi2knr.c b/ansi2knr.c deleted file mode 100644 index 39242154..00000000 --- a/ansi2knr.c +++ /dev/null @@ -1,488 +0,0 @@ -/* Copyright (C) 1989, 1991, 1993 Aladdin Enterprises. All rights reserved. */ - -/* ansi2knr.c */ -/* Convert ANSI function declarations to K&R syntax */ - -/* -ansi2knr is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY. No author or distributor accepts responsibility -to anyone for the consequences of using it or for whether it serves any -particular purpose or works at all, unless he says so in writing. Refer -to the GNU General Public License for full details. - -Everyone is granted permission to copy, modify and redistribute -ansi2knr, but only under the conditions described in the GNU -General Public License. A copy of this license is supposed to have been -given to you along with ansi2knr so you can know your rights and -responsibilities. It should be in a file named COPYING. Among other -things, the copyright notice and this notice must be preserved on all -copies. -*/ - -/* ----------- Here is the GNU GPL file COPYING, referred to above ---------- ------ These terms do NOT apply to the JPEG software itself; see README ------ - - GHOSTSCRIPT GENERAL PUBLIC LICENSE - (Clarified 11 Feb 1988) - - Copyright (C) 1988 Richard M. Stallman - Everyone is permitted to copy and distribute verbatim copies of this - license, but changing it is not allowed. You can also use this wording - to make the terms for other programs. - - The license agreements of most software companies keep you at the -mercy of those companies. By contrast, our general public license is -intended to give everyone the right to share Ghostscript. To make sure -that you get the rights we want you to have, we need to make -restrictions that forbid anyone to deny you these rights or to ask you -to surrender the rights. Hence this license agreement. - - Specifically, we want to make sure that you have the right to give -away copies of Ghostscript, that you receive source code or else can get -it if you want it, that you can change Ghostscript or use pieces of it -in new free programs, and that you know you can do these things. - - To make sure that everyone has such rights, we have to forbid you to -deprive anyone else of these rights. For example, if you distribute -copies of Ghostscript, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must tell them their rights. - - Also, for our own protection, we must make certain that everyone finds -out that there is no warranty for Ghostscript. If Ghostscript is -modified by someone else and passed on, we want its recipients to know -that what they have is not what we distributed, so that any problems -introduced by others will not reflect on our reputation. - - Therefore we (Richard M. Stallman and the Free Software Foundation, -Inc.) make the following terms which say what you must do to be allowed -to distribute or change Ghostscript. - - - COPYING POLICIES - - 1. You may copy and distribute verbatim copies of Ghostscript source -code as you receive it, in any medium, provided that you conspicuously -and appropriately publish on each copy a valid copyright and license -notice "Copyright (C) 1989 Aladdin Enterprises. All rights reserved. -Distributed by Free Software Foundation, Inc." (or with whatever year is -appropriate); keep intact the notices on all files that refer to this -License Agreement and to the absence of any warranty; and give any other -recipients of the Ghostscript program a copy of this License Agreement -along with the program. You may charge a distribution fee for the -physical act of transferring a copy. - - 2. You may modify your copy or copies of Ghostscript or any portion of -it, and copy and distribute such modifications under the terms of -Paragraph 1 above, provided that you also do the following: - - a) cause the modified files to carry prominent notices stating - that you changed the files and the date of any change; and - - b) cause the whole of any work that you distribute or publish, - that in whole or in part contains or is a derivative of Ghostscript - or any part thereof, to be licensed at no charge to all third - parties on terms identical to those contained in this License - Agreement (except that you may choose to grant more extensive - warranty protection to some or all third parties, at your option). - - c) You may charge a distribution fee for the physical act of - transferring a copy, and you may at your option offer warranty - protection in exchange for a fee. - -Mere aggregation of another unrelated program with this program (or its -derivative) on a volume of a storage or distribution medium does not bring -the other program under the scope of these terms. - - 3. You may copy and distribute Ghostscript (or a portion or derivative -of it, under Paragraph 2) in object code or executable form under the -terms of Paragraphs 1 and 2 above provided that you also do one of the -following: - - a) accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of - Paragraphs 1 and 2 above; or, - - b) accompany it with a written offer, valid for at least three - years, to give any third party free (except for a nominal - shipping charge) a complete machine-readable copy of the - corresponding source code, to be distributed under the terms of - Paragraphs 1 and 2 above; or, - - c) accompany it with the information you received as to where the - corresponding source code may be obtained. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form alone.) - -For an executable file, complete source code means all the source code for -all modules it contains; but, as a special exception, it need not include -source code for modules which are standard libraries that accompany the -operating system on which the executable file runs. - - 4. You may not copy, sublicense, distribute or transfer Ghostscript -except as expressly provided under this License Agreement. Any attempt -otherwise to copy, sublicense, distribute or transfer Ghostscript is -void and your rights to use the program under this License agreement -shall be automatically terminated. However, parties who have received -computer software programs from you with this License Agreement will not -have their licenses terminated so long as such parties remain in full -compliance. - - 5. If you wish to incorporate parts of Ghostscript into other free -programs whose distribution conditions are different, write to the Free -Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not -yet worked out a simple rule that can be stated here, but we will often -permit this. We will be guided by the two goals of preserving the free -status of all derivatives of our free software and of promoting the -sharing and reuse of software. - -Your comments and suggestions about our licensing policies and our -software are welcome! Please contact the Free Software Foundation, -Inc., 675 Mass Ave, Cambridge, MA 02139, or call (617) 876-3296. - - NO WARRANTY - - BECAUSE GHOSTSCRIPT IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY -NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT -WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, RICHARD -M. STALLMAN, ALADDIN ENTERPRISES, L. PETER DEUTSCH, AND/OR OTHER PARTIES -PROVIDE GHOSTSCRIPT "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER -EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE -ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF GHOSTSCRIPT IS WITH -YOU. SHOULD GHOSTSCRIPT PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL -NECESSARY SERVICING, REPAIR OR CORRECTION. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M. -STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., L. PETER DEUTSCH, ALADDIN -ENTERPRISES, AND/OR ANY OTHER PARTY WHO MAY MODIFY AND REDISTRIBUTE -GHOSTSCRIPT AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING -ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE -(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED -INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A FAILURE OF THE -PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) GHOSTSCRIPT, EVEN IF YOU -HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM -BY ANY OTHER PARTY. - --------------------- End of file COPYING ------------------------------ -*/ - - -#include -#include - -#ifdef BSD -#include -#else -#ifdef VMS - extern int strlen(), strncmp(); -#else -#include -#endif -#endif - -/* malloc and free should be declared in stdlib.h, */ -/* but if you've got a K&R compiler, they probably aren't. */ -#ifdef MSDOS -#include -#else -#ifdef VMS - extern char *malloc(); - extern void free(); -#else - extern char *malloc(); - extern int free(); -#endif -#endif - -/* Usage: - ansi2knr input_file [output_file] - * If no output_file is supplied, output goes to stdout. - * There are no error messages. - * - * ansi2knr recognizes functions by seeing a non-keyword identifier - * at the left margin, followed by a left parenthesis, - * with a right parenthesis as the last character on the line. - * It will recognize a multi-line header provided that the last character - * of the last line of the header is a right parenthesis, - * and no intervening line ends with a left brace or a semicolon. - * These algorithms ignore whitespace and comments, except that - * the function name must be the first thing on the line. - * The following constructs will confuse it: - * - Any other construct that starts at the left margin and - * follows the above syntax (such as a macro or function call). - * - Macros that tinker with the syntax of the function header. - */ - -/* Scanning macros */ -#define isidchar(ch) (isalnum(ch) || (ch) == '_') -#define isidfirstchar(ch) (isalpha(ch) || (ch) == '_') - -/* Forward references */ -char *skipspace(); -int writeblanks(); -int test1(); -int convert1(); - -/* The main program */ -main(argc, argv) - int argc; - char *argv[]; -{ FILE *in, *out; -#define bufsize 5000 /* arbitrary size */ - char *buf; - char *line; - switch ( argc ) - { - default: - printf("Usage: ansi2knr input_file [output_file]\n"); - exit(0); - case 2: - out = stdout; break; - case 3: - out = fopen(argv[2], "w"); - if ( out == NULL ) - { fprintf(stderr, "Cannot open %s\n", argv[2]); - exit(1); - } - } - in = fopen(argv[1], "r"); - if ( in == NULL ) - { fprintf(stderr, "Cannot open %s\n", argv[1]); - exit(1); - } - fprintf(out, "#line 1 \"%s\"\n", argv[1]); - buf = malloc(bufsize); - line = buf; - while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL ) - { switch ( test1(buf) ) - { - case 1: /* a function */ - convert1(buf, out); - break; - case -1: /* maybe the start of a function */ - line = buf + strlen(buf); - if ( line != buf + (bufsize - 1) ) /* overflow check */ - continue; - /* falls through */ - default: /* not a function */ - fputs(buf, out); - break; - } - line = buf; - } - if ( line != buf ) fputs(buf, out); - free(buf); - fclose(out); - fclose(in); - return 0; -} - -/* Skip over space and comments, in either direction. */ -char * -skipspace(p, dir) - register char *p; - register int dir; /* 1 for forward, -1 for backward */ -{ for ( ; ; ) - { while ( isspace(*p) ) p += dir; - if ( !(*p == '/' && p[dir] == '*') ) break; - p += dir; p += dir; - while ( !(*p == '*' && p[dir] == '/') ) - { if ( *p == 0 ) return p; /* multi-line comment?? */ - p += dir; - } - p += dir; p += dir; - } - return p; -} - -/* - * Write blanks over part of a string. - */ -int -writeblanks(start, end) - char *start; - char *end; -{ char *p; - for ( p = start; p < end; p++ ) *p = ' '; - return 0; -} - -/* - * Test whether the string in buf is a function definition. - * The string may contain and/or end with a newline. - * Return as follows: - * 0 - definitely not a function definition; - * 1 - definitely a function definition; - * -1 - may be the beginning of a function definition, - * append another line and look again. - */ -int -test1(buf) - char *buf; -{ register char *p = buf; - char *bend; - char *endfn; - int contin; - if ( !isidfirstchar(*p) ) - return 0; /* no name at left margin */ - bend = skipspace(buf + strlen(buf) - 1, -1); - switch ( *bend ) - { - case ')': contin = 1; break; - case '{': - case ';': return 0; /* not a function */ - default: contin = -1; - } - while ( isidchar(*p) ) p++; - endfn = p; - p = skipspace(p, 1); - if ( *p++ != '(' ) - return 0; /* not a function */ - p = skipspace(p, 1); - if ( *p == ')' ) - return 0; /* no parameters */ - /* Check that the apparent function name isn't a keyword. */ - /* We only need to check for keywords that could be followed */ - /* by a left parenthesis (which, unfortunately, is most of them). */ - { static char *words[] = - { "asm", "auto", "case", "char", "const", "double", - "extern", "float", "for", "if", "int", "long", - "register", "return", "short", "signed", "sizeof", - "static", "switch", "typedef", "unsigned", - "void", "volatile", "while", 0 - }; - char **key = words; - char *kp; - int len = endfn - buf; - while ( (kp = *key) != 0 ) - { if ( strlen(kp) == len && !strncmp(kp, buf, len) ) - return 0; /* name is a keyword */ - key++; - } - } - return contin; -} - -int -convert1(buf, out) - char *buf; - FILE *out; -{ char *endfn; - register char *p; - char **breaks; - unsigned num_breaks = 2; /* for testing */ - char **btop; - char **bp; - char **ap; - /* Pre-ANSI implementations don't agree on whether strchr */ - /* is called strchr or index, so we open-code it here. */ - for ( endfn = buf; *(endfn++) != '('; ) ; -top: p = endfn; - breaks = (char **)malloc(sizeof(char *) * num_breaks * 2); - if ( breaks == 0 ) - { /* Couldn't allocate break table, give up */ - fprintf(stderr, "Unable to allocate break table!\n"); - fputs(buf, out); - return -1; - } - btop = breaks + num_breaks * 2 - 2; - bp = breaks; - /* Parse the argument list */ - do - { int level = 0; - char *end = NULL; - if ( bp >= btop ) - { /* Filled up break table. */ - /* Allocate a bigger one and start over. */ - free((char *)breaks); - num_breaks <<= 1; - goto top; - } - *bp++ = p; - /* Find the end of the argument */ - for ( ; end == NULL; p++ ) - { switch(*p) - { - case ',': if ( !level ) end = p; break; - case '(': level++; break; - case ')': if ( --level < 0 ) end = p; break; - case '/': p = skipspace(p, 1) - 1; break; - default: ; - } - } - p--; /* back up over terminator */ - /* Find the name being declared. */ - /* This is complicated because of procedure and */ - /* array modifiers. */ - for ( ; ; ) - { p = skipspace(p - 1, -1); - switch ( *p ) - { - case ']': /* skip array dimension(s) */ - case ')': /* skip procedure args OR name */ - { int level = 1; - while ( level ) - switch ( *--p ) - { - case ']': case ')': level++; break; - case '[': case '(': level--; break; - case '/': p = skipspace(p, -1) + 1; break; - default: ; - } - } - if ( *p == '(' && *skipspace(p + 1, 1) == '*' ) - { /* We found the name being declared */ - while ( !isidfirstchar(*p) ) - p = skipspace(p, 1) + 1; - goto found; - } - break; - default: goto found; - } - } -found: if ( *p == '.' && p[-1] == '.' && p[-2] == '.' ) - { p++; - if ( bp == breaks + 1 ) /* sole argument */ - writeblanks(breaks[0], p); - else - writeblanks(bp[-1] - 1, p); - bp--; - } - else - { while ( isidchar(*p) ) p--; - *bp++ = p+1; - } - p = end; - } - while ( *p++ == ',' ); - *bp = p; - /* Make a special check for 'void' arglist */ - if ( bp == breaks+2 ) - { p = skipspace(breaks[0], 1); - if ( !strncmp(p, "void", 4) ) - { p = skipspace(p+4, 1); - if ( p == breaks[2] - 1 ) - { bp = breaks; /* yup, pretend arglist is empty */ - writeblanks(breaks[0], p + 1); - } - } - } - /* Put out the function name */ - p = buf; - while ( p != endfn ) putc(*p, out), p++; - /* Put out the declaration */ - for ( ap = breaks+1; ap < bp; ap += 2 ) - { p = *ap; - while ( isidchar(*p) ) putc(*p, out), p++; - if ( ap < bp - 1 ) fputs(", ", out); - } - fputs(") ", out); - /* Put out the argument declarations */ - for ( ap = breaks+2; ap <= bp; ap += 2 ) (*ap)[-1] = ';'; - fputs(breaks[0], out); - free((char *)breaks); - return 0; -} diff --git a/example.c b/example.c index 830f26da..61e03577 100644 --- a/example.c +++ b/example.c @@ -6,6 +6,10 @@ designed to be a starting point of an implementation. This is not officially part of libpng, and therefore does not require a copyright notice. + + This file does not currently compile, because it is missing + certain parts, like allocating memory to hold an image. + You will have to supply these parts to get it to compile. */ #include @@ -81,15 +85,11 @@ void read_png(char *file_name) /* read the file information */ png_read_info(png_ptr, info_ptr); - /* allocate the memory to hold the image using the fields - of png_info. */ - /* set up the transformations you want. Note that these are all optional. Only call them if you want them */ /* expand paletted colors into true rgb */ - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - info_ptr->bit_depth < 8) + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr); /* expand grayscale images to the full 8 bits */ @@ -163,26 +163,32 @@ void read_png(char *file_name) if (info_ptr->bit_depth == 16) png_set_swap(png_ptr); - /* add a filler byte to store rgb files as rgbx */ + /* add a filler byte to rgb files */ if (info_ptr->bit_depth == 8 && info_ptr->color_type == PNG_COLOR_TYPE_RGB) - png_set_rgbx(png_ptr); + png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); - /* optional call to update palette with transformations */ - png_start_read_image(png_ptr); - - /* the easiest way to read the image */ - void *row_pointers[height]; - png_read_image(png_ptr, row_pointers); - - /* the other way to read images - deal with interlacing */ - - /* turn on interlace handling */ + /* turn on interlace handling if you are not using png_read_image() */ if (info_ptr->interlace_type) number_passes = png_set_interlace_handling(png_ptr); else number_passes = 1; + /* optional call to update palette with transformations */ + png_start_read_image(png_ptr); + + /* optional call to update the info structure */ + png_read_update_info(png_ptr, info_ptr); + + /* allocate the memory to hold the image using the fields + of png_info. */ + + /* the easiest way to read the image */ + png_bytef *row_pointers[height]; + png_read_image(png_ptr, row_pointers); + + /* the other way to read images - deal with interlacing */ + for (pass = 0; pass < number_passes; pass++) { /* Read the image using the "sparkle" effect. */ @@ -191,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++) { - char *row_pointers = row[y]; + png_bytef *row_pointers = row[y]; png_read_rows(png_ptr, &row_pointers, NULL, 1); } @@ -309,21 +315,22 @@ void write_png(char *file_name, ... other image information ...) /* swap bytes of 16 bit files to most significant bit first */ png_set_swap(png_ptr); - /* get rid of filler bytes, pack rgb into 3 bytes */ - png_set_rgbx(png_ptr); + /* get rid of filler bytes, pack rgb into 3 bytes. The + filler number is not used. */ + png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); - /* the easiest way to write the image */ - void *row_pointers[height]; - png_write_image(png_ptr, row_pointers); - - /* the other way to write the image - deal with interlacing */ - - /* turn on interlace handling */ + /* turn on interlace handling if you are not using png_write_image() */ if (interlacing) number_passes = png_set_interlace_handling(png_ptr); else number_passes = 1; + /* the easiest way to write the image */ + png_bytef *row_pointers[height]; + png_write_image(png_ptr, row_pointers); + + /* the other way to write the image - deal with interlacing */ + for (pass = 0; pass < number_passes; pass++) { /* Write a few rows at a time. */ @@ -332,7 +339,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++) { - char *row_pointers = row[y]; + png_bytef *row_pointers = row[y]; png_write_rows(png_ptr, &row_pointers, 1); } } diff --git a/libpng.txt b/libpng.txt index 4ddd1c1a..cf6979b0 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 1 - version 0.71 + libpng 1.0 beta 2 - version 0.8 For conditions of distribution and use, see copyright notice in png.h Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. - June 26, 1995 + August 20, 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 @@ -325,17 +325,21 @@ PC's store them, for example), call this: png_set_swap(png_ptr); PNG files store rgb pixels packed into 3 bytes. If you would rather -pack them into 4 bytes, with the filler byte last, call this: +pack them into 4 bytes, call this: if (info_ptr->bit_depth == 8 && info_ptr->color_type == PNG_COLOR_TYPE_RGB) - png_set_rgbx(png_ptr); + png_set_filler(png_ptr, filler_byte, PNG_FILLER_BEFORE); -If you need the filler byte first, call this: +where filler_byte is the number to fill with, and the location is +either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whether +you want the filler before the rgb or after. - if (info_ptr->bit_depth == 8 && - info_ptr->color_type == PNG_COLOR_TYPE_RGB) - png_set_xrgb(png_ptr); +Finally, if you need the interlacing as discussed below, call +this here: + + if (info_ptr->interlace_type) + number_passes = png_set_interlace_handling(png_ptr); After setting the transformations, you can update your palette by calling png_start_read_image(). This function is provided for those @@ -345,7 +349,22 @@ before it reads the first row. png_start_read_image(png_ptr); -That's it for the transformations. Now you can read the image data. +If you want, libpng will update your png_info structure to reflect +any transformations you've requested with this call. This is most +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); + +After you call png_read_update_info(), you can allocate any +memory you need to hold the image. As the actual allocation +varies among applications, no example will be given. If you +are allocating one large chunk, you may find it useful to +build an array of pointers to each row, as it will be needed +for some of the functions below. + +After you've allocated memory, you can read the image data. The simplest way to do this is in one function call. If you are allocating enough memory to hold the whole image, you can just call png_read_image() and libpng will read in all the image data @@ -399,7 +418,7 @@ call png_read_rows() the correct number of times to read in all seven images. See the PNG specification for more details on the interlacing scheme. -If you want libpng to expand the images, call this: +If you want libpng to expand the images, call this above: if (info_ptr->interlace_type) number_passes = png_set_interlace_handling(png_ptr); @@ -521,6 +540,25 @@ Customizing Libpng section below. png_init_io(png_ptr, fp); +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 +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 +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_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); + 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 @@ -600,14 +638,13 @@ 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. PNG files store rgb pixels packed into 3 bytes. If you would rather -supply the pixels as 4 bytes per pixel, with the filler byte last, -call this: +supply the pixels as 4 bytes per pixel, call this: - png_set_rgbx(png_ptr); + png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); -If your filler byte goes first, call this: - - png_set_xrgb(png_ptr); +where the 0 is not used for writing, and the location is either +PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whether you +want the filler before the rgb or after. PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as they can, resulting in, for example, 8 pixels per byte for 1 bit files. @@ -819,3 +856,16 @@ needed outside libpng are protected by the PNG_INTERNAL definition, which is only defined for those routines inside libpng itself. The files in libpng proper only include png.h. +Removing unwanted object code: + +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 +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. + diff --git a/makefile b/makefile index 5d3da0f0..82c5f266 100644 --- a/makefile +++ b/makefile @@ -2,18 +2,19 @@ # 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 -O3 -LDFLAGS=-L. -L../zlib/ -lpng -lgz -lm +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=/usr/local OBJS = png.o pngrcb.o pngrutil.o pngtrans.o pngwutil.o \ - pngread.o pngstub.o pngwrite.o pngrtran.o pngwtran.o + pngread.o pngio.o pngwrite.o pngrtran.o pngwtran.o \ + pngmem.o pngerror.o all: libpng.a pngtest @@ -22,13 +23,18 @@ libpng.a: $(OBJS) $(RANLIB) $@ pngtest: pngtest.o libpng.a - cc -o pngtest $(CCFLAGS) pngtest.o $(LDFLAGS) + $(CC) -o pngtest $(CCFLAGS) pngtest.o $(LDFLAGS) + +test: pngtest + ./pngtest install: libpng.a -@mkdir $(prefix)/include -@mkdir $(prefix)/lib cp png.h $(prefix)/include + cp pngconf.h $(prefix)/include chmod 644 $(prefix)/include/png.h + chmod 644 $(prefix)/include/pngconf.h cp libpng.a $(prefix)/lib chmod 644 $(prefix)/lib/libpng.a @@ -37,13 +43,16 @@ clean: # DO NOT DELETE THIS LINE -- make depend depends on it. -pngrcb.o: png.h -pngread.o: png.h -pngrtran.o: png.h -pngrutil.o: png.h -pngstub.o: png.h -pngtest.o: png.h -pngtrans.o: png.h -pngwrite.o: png.h -pngwtran.o: png.h -pngwutil.o: png.h +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 +pngread.o: png.h pngconf.h +pngrtran.o: png.h pngconf.h +pngrutil.o: png.h pngconf.h +pngtest.o: png.h pngconf.h +pngtrans.o: png.h pngconf.h +pngwrite.o: png.h pngconf.h +pngwtran.o: png.h pngconf.h +pngwutil.o: png.h pngconf.h diff --git a/makefile.knr b/makefile.knr deleted file mode 100644 index 5eb0b79a..00000000 --- a/makefile.knr +++ /dev/null @@ -1,61 +0,0 @@ -# makefile for libpng -# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc. -# For conditions of distribution and use, see copyright notice in png.h - -CC=cc -CFLAGS=-I../zlib -O -LDFLAGS=-L. -L../zlib/ -lpng -lgz -lm -# flags for ansi2knr -ANSI2KNRFLAGS= - -RANLIB=ranlib -#RANLIB=echo - -# where make install puts libpng.a and png.h -prefix=/usr/local - -OBJS = png.o pngrcb.o pngrutil.o pngtrans.o pngwutil.o \ - pngread.o pngstub.o pngwrite.o pngrtran.o pngwtran.o - -all: ansi2knr libpng.a pngtest - -# general rule to allow ansi2knr to work -.c.o: - ./ansi2knr $*.c T$*.c - $(CC) $(CFLAGS) -c T$*.c - rm -f T$*.c $*.o - mv T$*.o $*.o - -ansi2knr: ansi2knr.c - $(CC) $(CFLAGS) $(ANSI2KNRFLAGS) -o ansi2knr ansi2knr.c - -libpng.a: ansi2knr $(OBJS) - ar rc $@ $(OBJS) - $(RANLIB) $@ - -pngtest: pngtest.o libpng.a ansi2knr - cc -o pngtest $(CCFLAGS) pngtest.o $(LDFLAGS) - -install: libpng.a - -@mkdir $(prefix)/include - -@mkdir $(prefix)/lib - cp png.h $(prefix)/include - chmod 644 $(prefix)/include/png.h - cp libpng.a $(prefix)/lib - chmod 644 $(prefix)/lib/libpng.a - -clean: - rm -f *.o libpng.a pngtest pngout.png ansi2knr - -# DO NOT DELETE THIS LINE -- make depend depends on it. - -pngrcb.o: png.h -pngread.o: png.h -pngrtran.o: png.h -pngrutil.o: png.h -pngstub.o: png.h -pngtest.o: png.h -pngtrans.o: png.h -pngwrite.o: png.h -pngwtran.o: png.h -pngwutil.o: png.h diff --git a/makefile.mip b/makefile.mip deleted file mode 100644 index ea41c611..00000000 --- a/makefile.mip +++ /dev/null @@ -1,50 +0,0 @@ -# makefile for libpng -# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc. -# For conditions of distribution and use, see copyright notice in png.h - -CC=cc -CFLAGS=-I../zlib -O -systype sysv -DSYSV -w -Dmips -#CFLAGS=-O -LDFLAGS=-L. -L../zlib/ -lpng -lgz -lm - -#RANLIB=ranlib -RANLIB=echo - -# where make install puts libpng.a and png.h -prefix=/usr/local - -OBJS = png.o pngrcb.o pngrutil.o pngtrans.o pngwutil.o \ - pngread.o pngstub.o pngwrite.o pngrtran.o pngwtran.o - -all: libpng.a pngtest - -libpng.a: $(OBJS) - ar rc $@ $(OBJS) - $(RANLIB) $@ - -pngtest: pngtest.o libpng.a - cc -o pngtest $(CCFLAGS) pngtest.o $(LDFLAGS) - -install: libpng.a - -@mkdir $(prefix)/include - -@mkdir $(prefix)/lib - cp png.h $(prefix)/include - chmod 644 $(prefix)/include/png.h - cp libpng.a $(prefix)/lib - chmod 644 $(prefix)/lib/libpng.a - -clean: - rm -f *.o libpng.a pngtest pngout.png - -# DO NOT DELETE THIS LINE -- make depend depends on it. - -pngrcb.o: png.h -pngread.o: png.h -pngrtran.o: png.h -pngrutil.o: png.h -pngstub.o: png.h -pngtest.o: png.h -pngtrans.o: png.h -pngwrite.o: png.h -pngwtran.o: png.h -pngwutil.o: png.h diff --git a/makefile.std b/makefile.std deleted file mode 100644 index 1613e909..00000000 --- a/makefile.std +++ /dev/null @@ -1,49 +0,0 @@ -# makefile for libpng -# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc. -# For conditions of distribution and use, see copyright notice in png.h - -CC=cc -CFLAGS=-I../zlib -O -LDFLAGS=-L. -L../zlib/ -lpng -lgz -lm - -#RANLIB=ranlib -RANLIB=echo - -# where make install puts libpng.a and png.h -prefix=/usr/local - -OBJS = png.o pngrcb.o pngrutil.o pngtrans.o pngwutil.o \ - pngread.o pngstub.o pngwrite.o pngrtran.o pngwtran.o - -all: libpng.a pngtest - -libpng.a: $(OBJS) - ar rc $@ $(OBJS) - $(RANLIB) $@ - -pngtest: pngtest.o libpng.a - cc -o pngtest $(CCFLAGS) pngtest.o $(LDFLAGS) - -install: libpng.a - -@mkdir $(prefix)/include - -@mkdir $(prefix)/lib - cp png.h $(prefix)/include - chmod 644 $(prefix)/include/png.h - cp libpng.a $(prefix)/lib - chmod 644 $(prefix)/lib/libpng.a - -clean: - rm -f *.o libpng.a pngtest pngout.png - -# DO NOT DELETE THIS LINE -- make depend depends on it. - -pngrcb.o: png.h -pngread.o: png.h -pngrtran.o: png.h -pngrutil.o: png.h -pngstub.o: png.h -pngtest.o: png.h -pngtrans.o: png.h -pngwrite.o: png.h -pngwtran.o: png.h -pngwutil.o: png.h diff --git a/png.c b/png.c index d65d7c64..d0afd9a9 100644 --- a/png.c +++ b/png.c @@ -1,16 +1,20 @@ /* png.c - location for general purpose png functions - libpng 1.0 beta 1 - version 0.71 + libpng 1.0 beta 2 - version 0.81 For conditions of distribution and use, see copyright notice in png.h Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. - June 26, 1995 + August 24, 1995 */ #define PNG_INTERNAL #define PNG_NO_EXTERN #include "png.h" +/* version information for c files. This better match the version + string defined in png.h */ +char png_libpng_ver[] = "0.81"; + /* place to hold the signiture string for a png file. */ png_byte png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10}; @@ -21,17 +25,39 @@ 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}; +#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED) png_byte 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}; +#endif +#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED) png_byte 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}; +#endif +#if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED) png_byte 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}; +#endif +#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) png_byte 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}; +#endif +#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED) png_byte 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}; +#endif +#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED) png_byte png_tIME[4] = {116, 73, 77, 69}; +#endif /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ @@ -78,18 +104,18 @@ png_check_sig(png_byte *sig, int num) } /* Function to allocate memory for zlib. */ -voidp -png_zalloc(voidp png_ptr, uInt items, uInt size) +voidpf +png_zalloc(voidpf png_ptr, uInt items, uInt size) { - return ((voidp)png_large_malloc((png_struct *)png_ptr, + return ((voidpf)png_large_malloc((png_struct FAR *)png_ptr, (png_uint_32)items * (png_uint_32)size)); } /* function to free memory for zlib */ void -png_zfree(voidp png_ptr, voidp ptr) +png_zfree(voidpf png_ptr, voidpf ptr) { - png_large_free((png_struct *)png_ptr, (void *)ptr); + png_large_free((png_struct FAR *)png_ptr, (voidpf)ptr); } /* reset the crc variable to 32 bits of 1's. Care must be taken @@ -135,10 +161,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_byte *buf, png_uint_32 len) +update_crc(png_uint_32 crc, png_bytef *buf, png_uint_32 len) { png_uint_32 c; - png_byte *p; + png_bytef *p; png_uint_32 n; c = crc; @@ -163,10 +189,15 @@ update_crc(png_uint_32 crc, png_byte *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_byte *ptr, +png_calculate_crc(png_struct *png_ptr, png_bytef *ptr, png_uint_32 length) { png_ptr->crc = update_crc(png_ptr->crc, ptr, length); } - +void +png_info_init(png_info *info) +{ + /* set everything to 0 */ + memset(info, 0, sizeof (png_info)); +} diff --git a/png.h b/png.h index b0fc8e58..62c9d2d8 100644 --- a/png.h +++ b/png.h @@ -1,7 +1,8 @@ /* png.h - header file for png reference library - libpng 1.0 beta 1 - version 0.71 - June 26, 1995 + + libpng 1.0 beta 2 - version 0.81 + August 24, 1995 Note: This is a beta version. It reads and writes valid files on the platforms I have, but it has had limited portability @@ -16,7 +17,10 @@ Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. Contributing Authors: + Dave Martindale Guy Eric Schalnat + Paul Schmidt + Tim Wegner The PNG Reference Library is supplied "AS IS". The Contributing Authors and Group 42, Inc. disclaim all warranties, expressed or implied, @@ -49,153 +53,39 @@ with some code to build around. This file is useful for looking at the actual function definitions and structure components. */ -/* This file is arranged in several sections. The first section contains - all the definitions for libpng. The second section details 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. - - Any machine specific code is near the front of this file, so if you - are configuring libpng for a machine, you may want to read the section - starting here down to where it starts to typedef png_color, png_text, - and png_info */ - -/* this is the size of the compression buffer, and thus the size of - an IDAT chunk. Make this whatever size you feel is best for your - machine. One of these will be allocated per png_struct. When this - is full, it writes the data to the disk, and does some other - calculations. Making this an extreamly small size will slow - the library down, but you may want to experiment to determine - where it becomes significant, if you are concerned with memory - usage. Note that zlib allocates at least 32Kb also. For readers, - this describes the size of the buffer available to read the data in. - 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 8192; - /* include the compression library's header */ #include "zlib.h" -/* 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 - used to help portability between machines. To make it simpler to - setup libpng on a machine, this currently uses zlib's definitions, so - any changes should be made in zlib. Libpng will check zlib's settings - and adjust it's own accordingly. */ +/* include all user configurable info */ +#include "pngconf.h" -/* if you are running on a machine where you cannot allocate more then - 64K of memory, uncomment this. While libpng will not normally need - that much memory in a chunk (unless you load up a very large file), - zlib needs to know how big of a chunk it can use, and libpng thus - makes sure to check any memory allocation to verify it will fit - into memory. -#define PNG_MAX_ALLOC_64K -*/ -#ifdef MAXSEG_64K -#define PNG_MAX_ALLOC_64K +/* This file is arranged in several sections. The first section details + 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 + 1.0 will be 100 here, etc. */ +#define PNG_LIBPNG_VER 81 + +/* variables defined in png.c - only it needs to define PNG_NO_EXTERN */ +#ifndef PNG_NO_EXTERN +/* version information for c files, stored in png.c. This better match + the version above. */ +extern char png_libpng_ver[]; #endif -/* 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 - indicator, but you may need to drag the empty declaration out in - front of here, or change the ifdef to suit your own needs. */ -#ifndef PNGARG - -#ifdef __P -#define PNGARG(arglist) __P(arglist) -#else - -#ifdef _NO_PROTO -#define PNGARG(arglist) -#else -#define PNGARG(arglist) arglist -#endif /* _NO_PROTO */ - -#endif /* __P(arglist) */ - -#endif /* PNGARG */ - -/* enough people need this for various reasons to include it here */ -#include -/* need the time information for reading tIME chunks */ -#include - -/* for FILE. If you are not using standard io, you don't need this */ -#include - -/* include setjmp.h for error handling */ -#include - -/* other defines for things like memory and the like can go here. These - are the only files included in libpng, so if you need to change them, - change them here. They are only included if PNG_INTERNAL is defined. */ -#ifdef PNG_INTERNAL -#include -#include -#ifdef BSD -#include -#else -#include -#endif -#include - -/* other defines specific to compilers can go here. Try to keep - them inside an appropriate ifdef/endif pair for portability */ - -/* for some reason, Borland C++ defines memcmp, etc. in mem.h, not - stdlib.h like it should (I think). Or perhaps this is a C++ - feature */ -#ifdef __TURBOC__ -#include -#include "alloc.h" -#endif - -#ifdef _MSC_VER -#include -#endif - -/* this controls how fine the dithering gets. As this allocates - a largish chunk of memory (32K), those who are not as concerned - with dithering quality can decrease some or all of these */ -#define PNG_DITHER_RED_BITS 5 -#define PNG_DITHER_GREEN_BITS 5 -#define PNG_DITHER_BLUE_BITS 5 - -/* this controls how fine the gamma correction becomes when you - are only interested in 8 bits anyway. Increasing this value - results in more memory being used, and more pow() functions - being called to fill in the gamma tables. Don't get this - value less then 8, and even that may not work (I haven't tested - it). */ - -#define PNG_MAX_GAMMA_8 11 - -#endif /* PNG_INTERNAL */ - -/* some typedefs to get us started. These should be safe on most of the - common platforms. The typedefs should be at least as large - as the numbers suggest (a png_uint_32 must be at least 32 bits long), - but they don't have to be exactly that size. */ - -typedef unsigned long png_uint_32; -typedef long png_int_32; -typedef unsigned short png_uint_16; -typedef short png_int_16; -typedef unsigned char png_byte; - -/* this is usually size_t. it is typedef'ed just in case you need it to - change (I'm not sure if you will or not, so I thought I'd be safe) */ -typedef size_t png_size_t; - /* three color definitions. The order of the red, green, and blue, (and the 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 unions, but it looked too clumsy, so I left it. If you're using C++, - you can union red, index, and gray, if you want. */ + you can union red, index, and gray, if you really want too. */ typedef struct png_color_struct { png_byte red; @@ -226,8 +116,8 @@ typedef struct png_color_8_struct typedef struct png_text_struct { int compression; /* compression value, -1 if uncompressed */ - char *key; /* keyword */ - char *text; /* comment */ + charf *key; /* keyword */ + charf *text; /* comment */ png_uint_32 text_length; /* length of text field */ } png_text; @@ -239,6 +129,7 @@ typedef struct png_time_struct { png_uint_16 year; /* full year, as in, 1995 */ png_byte month; /* month of year, 1 - 12 */ + png_byte day; /* day of month, 1 - 31 */ png_byte hour; /* hour of day, 0 - 23 */ png_byte minute; /* minute of hour, 0 - 59 */ @@ -267,13 +158,19 @@ typedef struct png_info_struct writes */ png_byte channels; /* number of channels of data per pixel */ png_byte pixel_depth; /* number of bits per pixel */ + png_uint_32 rowbytes; /* bytes needed for untransformed row */ /* 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 */ +#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 */ +#endif +#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED) float x_white; /* cHRM chunk values */ float y_white; float x_red; @@ -282,23 +179,40 @@ typedef struct png_info_struct float y_green; float x_blue; float y_blue; +#endif png_color *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_uint_16 num_trans; /* number of trans values */ 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 */ +#endif +#if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED) png_uint_16 *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 y_pixels_per_unit; /* y resolution */ png_byte phys_unit_type; /* resolution type */ +#endif +#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED) png_uint_32 x_offset; /* x offset on page */ png_uint_32 y_offset; /* y offset on page */ png_byte offset_unit_type; /* offset units type */ +#endif +#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED) 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 */ int max_text; /* size of text array */ png_text *text; /* array of comments */ +#endif } png_info; #define PNG_RESOLUTION_UNKNOWN 0 @@ -366,15 +280,35 @@ typedef struct png_struct_def 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 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_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; +#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_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 */ @@ -388,34 +322,63 @@ typedef struct png_struct_def png_uint_32 idat_size; /* current idat size for read */ png_uint_32 zbuf_size; /* size of zbuf */ png_color *palette; /* files palette */ - png_byte *palette_lookup; /* lookup table for dithering */ +#if defined(PNG_READ_DITHER_SUPPORTED) + png_bytef *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_BACKGROUND_SUPPORTED) png_byte *gamma_from_1; /* converts from 1.0 to screen */ png_byte *gamma_to_1; /* converts from file to 1.0 */ +#endif +#if defined(PNG_READ_BACKGROUND_SUPPORTED) png_byte *trans; /* transparency values for paletted files */ +#endif +#if defined(PNG_READ_DITHER_SUPPORTED) png_byte *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 */ +#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 */ +#endif +#if defined(PNG_READ_DITHER_SUPPORTED) png_uint_16 *hist; /* histogram */ - png_byte *zbuf; /* buffer for zlib */ - png_byte *row_buf; /* row buffer */ - png_byte *prev_row; /* previous row */ - png_byte *save_row; /* place to save row before filtering */ +#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) */ +#if defined(PNG_READ_GAMMA_SUPPORTED) float gamma; /* file gamma value */ float display_gamma; /* display gamma value */ +#endif +#if defined(PNG_READ_BACKGROUND_SUPPORTED) float background_gamma; +#endif +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) png_color_8 shift; /* shift for significant bit tranformation */ +#endif +#if defined(PNG_READ_GAMMA_SUPPORTED) 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 */ +#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 png_read and png_write */ } png_struct; +typedef png_struct FAR png_structf; /* 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 @@ -440,42 +403,71 @@ extern void png_write_info PNGARG((png_struct *png_ptr, png_info *info)); /* read the information before the actual image data. */ extern void png_read_info PNGARG((png_struct *png_ptr, png_info *info)); +#if defined(PNG_READ_tIME_SUPPORTED) /* convert from a struct tm to png_time */ extern void png_convert_from_struct_tm PNGARG((png_time *ptime, struct tm *ttime)); /* convert from time_t to png_time. Uses gmtime() */ extern void png_convert_from_time_t PNGARG((png_time *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)); +#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)); +#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, + 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)); /* Add a filler byte to rgb images before the colors. */ extern void png_set_xrgb PNGARG((png_struct *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)); +#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)); +#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)); +#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)); +#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)); +#endif +#if defined(PNG_READ_BACKGROUND_SUPPORTED) /* Handle alpha and tRNS by replacing with a background color. */ #define PNG_BACKGROUND_GAMMA_SCREEN 0 #define PNG_BACKGROUND_GAMMA_FILE 1 @@ -483,50 +475,63 @@ extern void png_set_invert_mono PNGARG((png_struct *png_ptr)); #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, - int need_expand, float background_gamma)); + 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)); +#endif +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) /* convert a grayscale file into rgb. */ extern void png_set_gray_to_rgb PNGARG((png_struct *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)); +#endif +#if defined(PNG_READ_GAMMA_SUPPORTED) /* Handle gamma correction. */ -extern void png_set_gamma PNGARG((png_struct *png_ptr, float screen_gamma, - float default_file_gamma)); +extern void png_set_gamma PNGARG((png_struct *png_ptr, double screen_gamma, + double default_file_gamma)); +#endif /* optional update palette with requested transformations */ -void png_start_read_image PNGARG((png_struct *png_ptr)); +extern void png_start_read_image PNGARG((png_struct *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)); /* read a one or more rows of image data.*/ extern void png_read_rows PNGARG((png_struct *png_ptr, - png_byte **row, + png_bytef **row, png_byte **display_row, png_uint_32 num_rows)); /* read a row of data.*/ extern void png_read_row PNGARG((png_struct *png_ptr, - png_byte *row, + png_bytef *row, png_byte *display_row)); /* read the whole image into memory at once. */ extern void png_read_image PNGARG((png_struct *png_ptr, - png_byte **image)); + png_bytef **image)); /* write a row of image data */ extern void png_write_row PNGARG((png_struct *png_ptr, - png_byte *row)); + png_bytef *row)); /* write a few rows of image data */ extern void png_write_rows PNGARG((png_struct *png_ptr, - png_byte **row, + png_bytef **row, png_uint_32 num_rows)); /* write the image data */ -extern void png_write_image PNGARG((png_struct *png_ptr, png_byte **image)); +extern void png_write_image PNGARG((png_struct *png_ptr, png_bytef **image)); /* writes the end of the png file. */ extern void png_write_end PNGARG((png_struct *png_ptr, png_info *info)); @@ -541,6 +546,29 @@ extern void png_read_destroy PNGARG((png_struct *png_ptr, png_info *info, /* free any memory used in png struct */ extern void png_write_destroy PNGARG((png_struct *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 + 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_compression_level PNGARG((png_struct *png_ptr, + int level)); + +extern void png_set_compression_mem_level PNGARG((png_struct *png_ptr, + int mem_level)); + +extern void png_set_compression_strategy PNGARG((png_struct *png_ptr, + int strategy)); + +extern void png_set_compression_window_bits PNGARG((png_struct *png_ptr, + int window_bits)); + +extern void png_set_compression_method PNGARG((png_struct *png_ptr, + int method)); /* 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 @@ -548,34 +576,34 @@ extern void png_write_destroy PNGARG((png_struct *png_ptr)); pngstub.c for more information */ /* Write the data to whatever output you are using. */ -extern void png_write_data PNGARG((png_struct *png_ptr, png_byte *data, +extern void png_write_data PNGARG((png_struct *png_ptr, png_bytef *data, png_uint_32 length)); /* Read data from whatever input you are using */ -extern void png_read_data PNGARG((png_struct *png_ptr, png_byte *data, +extern void png_read_data PNGARG((png_struct *png_ptr, png_bytef *data, png_uint_32 length)); /* Initialize the input/output for the png file. */ extern void png_init_io PNGARG((png_struct *png_ptr, FILE *fp)); /* Allocate memory in larger chunks. */ -extern void *png_large_malloc PNGARG((png_struct *png_ptr, png_uint_32 size)); +extern voidpf png_large_malloc PNGARG((png_structf *png_ptr, png_uint_32 size)); /* free's a pointer allocated by png_large_malloc() */ -extern void png_large_free PNGARG((png_struct *png_ptr, void *ptr)); +extern void png_large_free PNGARG((png_structf *png_ptr, voidpf ptr)); /* Allocate memory. */ extern void *png_malloc PNGARG((png_struct *png_ptr, png_uint_32 size)); /* Reallocate memory. */ extern void *png_realloc PNGARG((png_struct *png_ptr, void *ptr, - png_uint_32 size)); + 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)); /* Fatal error in libpng - can't continue */ -extern void png_error PNGARG((png_struct *png_ptr, char *error)); +extern void png_error PNGARG((png_structf *png_ptr, char *error)); /* Non-fatal error in libpng. Can continue, but may have a problem. */ extern void png_warning PNGARG((png_struct *png_ptr, char *message)); @@ -616,6 +644,7 @@ extern void png_warning PNGARG((png_struct *png_ptr, char *message)); #define PNG_EXPAND 0x0800 #define PNG_GAMMA 0x1000 #define PNG_GRAY_TO_RGB 0x2000 +#define PNG_FILLER 0x4000 /* save typing and make code easier to understand */ #define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \ @@ -627,23 +656,48 @@ extern void png_warning PNGARG((png_struct *png_ptr, char *message)); /* place to hold the signiture string for a png file. */ extern png_byte png_sig[]; +/* version information for c files, stored in png.c. */ +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[]; +#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED) extern png_byte png_gAMA[]; +#endif +#if defined(PNG_READ_sBIT_SUPPORTED) || defined(PNG_WRITE_sBIT_SUPPORTED) extern png_byte png_sBIT[]; +#endif +#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED) extern png_byte png_cHRM[]; +#endif +#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED) extern png_byte png_tRNS[]; +#endif +#if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED) extern png_byte png_bKGD[]; +#endif +#if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED) extern png_byte png_hIST[]; +#endif +#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) extern png_byte png_tEXt[]; +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) extern png_byte png_zTXt[]; +#endif +#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED) extern png_byte png_pHYs[]; +#endif +#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED) extern png_byte png_oFFs[]; +#endif +#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED) extern png_byte png_tIME[]; +#endif /* Structures to facilitate easy interlacing. See png.c for more details */ extern int png_pass_start[]; extern int png_pass_inc[]; @@ -659,10 +713,10 @@ extern int png_pass_dsp_mask[]; #endif /* PNG_NO_EXTERN */ /* Function to allocate memory for zlib. */ -extern voidp png_zalloc PNGARG((voidp png_ptr, uInt items, uInt size)); +extern voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size)); /* function to free memory for zlib */ -extern void png_zfree PNGARG((voidp png_ptr, voidp ptr)); +extern void png_zfree PNGARG((voidpf png_ptr, voidpf ptr)); /* reset the crc variable */ extern void png_reset_crc PNGARG((png_struct *png_ptr)); @@ -671,7 +725,7 @@ extern void png_reset_crc PNGARG((png_struct *png_ptr)); 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_byte *ptr, +extern void png_calculate_crc PNGARG((png_struct *png_ptr, png_bytef *ptr, png_uint_32 length)); /* place a 32 bit number into a buffer in png byte order. We work @@ -690,14 +744,14 @@ extern void png_write_uint_16 PNGARG((png_struct *png_ptr, png_uint_16 i)); /* Write a png chunk. */ extern void png_write_chunk PNGARG((png_struct *png_ptr, png_byte *type, - png_byte *data, png_uint_32 length)); + png_bytef *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)); /* 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_byte *data, +extern void png_write_chunk_data PNGARG((png_struct *png_ptr, png_bytef *data, png_uint_32 length)); /* finish a chunk started with png_write_chunk_start() */ @@ -718,47 +772,69 @@ extern void png_write_IHDR PNGARG((png_struct *png_ptr, png_uint_32 width, extern void png_write_PLTE PNGARG((png_struct *png_ptr, png_color *palette, int number)); -extern void png_write_IDAT PNGARG((png_struct *png_ptr, png_byte *data, +extern void png_write_IDAT PNGARG((png_struct *png_ptr, png_bytef *data, png_uint_32 length)); extern void png_write_IEND PNGARG((png_struct *png_ptr)); +#if defined(PNG_WRITE_gAMA_SUPPORTED) extern void png_write_gAMA PNGARG((png_struct *png_ptr, float 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)); +#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)); +#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)); +#endif +#if defined(PNG_WRITE_bKGD_SUPPORTED) extern void png_write_bKGD PNGARG((png_struct *png_ptr, png_color_16 *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)); +#endif -extern void png_write_tEXt PNGARG((png_struct *png_ptr, char *key, - char *text, png_uint_32 text_len)); +#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)); +#endif -extern void png_write_zTXt PNGARG((png_struct *png_ptr, char *key, - char *text, png_uint_32 text_len, int compression)); +#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)); +#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)); +#endif +#if defined(PNG_WRITE_oFFs_SUPPORTED) extern void png_write_oFFs PNGARG((png_struct *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)); +#endif /* Internal use only. Called when finished processing a row of data */ extern void png_write_finish_row PNGARG((png_struct *png_ptr)); @@ -771,100 +847,185 @@ extern void png_read_IHDR PNGARG((png_struct *png_ptr, png_info *info, 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_read_PLTE PNGARG((png_struct *png_ptr, png_info *info, png_color *palette, int num)); + +#if defined(PNG_READ_gAMA_SUPPORTED) extern void png_read_gAMA PNGARG((png_struct *png_ptr, png_info *info, float 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)); +#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)); +#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)); +#endif + +#if defined(PNG_READ_bKGD_SUPPORTED) extern void png_read_bKGD PNGARG((png_struct *png_ptr, png_info *info, png_color_16 *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)); +#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)); +#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)); +#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_tEXt PNGARG((png_struct *png_ptr, png_info *info, - char *key, char *text, png_uint_32 text_len)); -extern void png_read_zTXt PNGARG((png_struct *png_ptr, png_info *info, - char *key, char *text, png_uint_32 text_len, int compression)); +#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)); +#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)); +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) void png_build_gamma_table PNGARG((png_struct *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_byte *row, +extern void png_combine_row PNGARG((png_struct *png_ptr, png_bytef *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_byte *row, int pass)); + png_bytef *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_byte *row, int pass)); + png_bytef *row, int pass)); +#endif /* unfilter a row */ extern void png_read_filter_row PNGARG((png_row_info *row_info, - png_byte *row, png_byte *prev_row, int filter)); + png_bytef *row, png_bytef *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_byte *row, png_byte *prev_row)); + png_bytef *row, png_bytef *prev_row)); /* finish a row while reading, dealing with interlacing passes, etc. */ extern void png_read_finish_row PNGARG((png_struct *png_ptr)); /* initialize the row buffers, etc. */ extern void png_read_start_row PNGARG((png_struct *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)); /* these are the functions that do the transformations */ -extern void png_do_read_rgbx PNGARG((png_row_info *row_info, - png_byte *row)); -extern void png_do_write_rgbx PNGARG((png_row_info *row_info, - png_byte *row)); -extern void png_do_read_xrgb PNGARG((png_row_info *row_info, - png_byte *row)); -extern void png_do_write_xrgb PNGARG((png_row_info *row_info, - png_byte *row)); -extern void png_do_swap PNGARG((png_row_info *row_info, png_byte *row)); -extern void png_do_unpack PNGARG((png_row_info *row_info, png_byte *row)); -extern void png_do_unshift PNGARG((png_row_info *row_info, png_byte *row, +#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)); +#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)); +#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)); +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) +extern void png_do_unpack PNGARG((png_row_info *row_info, png_bytef *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_invert PNGARG((png_row_info *row_info, png_byte *row)); +#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)); +#endif + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) extern void png_do_gray_to_rgb PNGARG((png_row_info *row_info, - png_byte *row)); -extern void png_do_chop PNGARG((png_row_info *row_info, png_byte *row)); + png_bytef *row)); +#endif + +#if defined(PNG_READ_16_TO_8_SUPPORTED) +extern void png_do_chop PNGARG((png_row_info *row_info, png_bytef *row)); +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) extern void png_do_dither PNGARG((png_row_info *row_info, - png_byte *row, png_byte *palette_lookup, png_byte *dither_lookup)); -extern void png_do_bgr PNGARG((png_row_info *row_info, png_byte *row)); + png_bytef *row, png_byte *palette_lookup, png_byte *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)); +#endif + +#if defined(PNG_WRITE_PACK_SUPPORTED) extern void png_do_pack PNGARG((png_row_info *row_info, - png_byte *row, png_byte bit_depth)); -extern void png_do_shift PNGARG((png_row_info *row_info, png_byte *row, + png_bytef *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_background PNGARG((png_row_info *row_info, png_byte *row, +#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_gamma PNGARG((png_row_info *row_info, png_byte *row, +#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, int gamma_shift)); +#endif + +#if defined(PNG_READ_EXPAND_SUPPORTED) extern void png_do_expand_palette PNGARG((png_row_info *row_info, - png_byte *row, png_color *palette, png_byte *trans, int num_trans)); + png_bytef *row, png_color *palette, png_byte *trans, int num_trans)); extern void png_do_expand PNGARG((png_row_info *row_info, - png_byte *row, png_color_16 *trans_value)); + png_bytef *row, png_color_16 *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)); /* read bytes into buf, and update png_ptr->crc */ -extern void png_crc_read PNGARG((png_struct *png_ptr, png_byte *buf, +extern void png_crc_read PNGARG((png_struct *png_ptr, png_bytef *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)); @@ -877,28 +1038,60 @@ 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, png_uint_32 length)); +#if defined(PNG_READ_gAMA_SUPPORTED) extern void png_handle_gAMA PNGARG((png_struct *png_ptr, png_info *info, png_uint_32 length)); -extern void png_handle_sBIT PNGARG((png_struct *png_ptr, png_info *info, +#endif + +#if defined(PNG_READ_sBIT_SUPPORTED) +extern void png_handle_sBIT PNGARG((png_struct *png_ptr, png_info *info, png_uint_32 length)); -extern void png_handle_cHRM PNGARG((png_struct *png_ptr, png_info *info, +#endif + +#if defined(PNG_READ_cHRM_SUPPORTED) +extern void png_handle_cHRM PNGARG((png_struct *png_ptr, png_info *info, png_uint_32 length)); -extern void png_handle_tRNS PNGARG((png_struct *png_ptr, png_info *info, +#endif + +#if defined(PNG_READ_tRNS_SUPPORTED) +extern void png_handle_tRNS PNGARG((png_struct *png_ptr, png_info *info, png_uint_32 length)); -extern void png_handle_bKGD PNGARG((png_struct *png_ptr, png_info *info, +#endif + +#if defined(PNG_READ_bKGD_SUPPORTED) +extern void png_handle_bKGD PNGARG((png_struct *png_ptr, png_info *info, png_uint_32 length)); -extern void png_handle_hIST PNGARG((png_struct *png_ptr, png_info *info, +#endif + +#if defined(PNG_READ_hIST_SUPPORTED) +extern void png_handle_hIST PNGARG((png_struct *png_ptr, png_info *info, png_uint_32 length)); -extern void png_handle_pHYs PNGARG((png_struct *png_ptr, png_info *info, +#endif + +#if defined(PNG_READ_pHYs_SUPPORTED) +extern void png_handle_pHYs PNGARG((png_struct *png_ptr, png_info *info, png_uint_32 length)); -extern void png_handle_oFFs PNGARG((png_struct *png_ptr, png_info *info, +#endif + +#if defined(PNG_READ_oFFs_SUPPORTED) +extern void png_handle_oFFs PNGARG((png_struct *png_ptr, png_info *info, png_uint_32 length)); -extern void png_handle_tIME PNGARG((png_struct *png_ptr, png_info *info, +#endif + +#if defined(PNG_READ_tIME_SUPPORTED) +extern void png_handle_tIME PNGARG((png_struct *png_ptr, png_info *info, png_uint_32 length)); -extern void png_handle_tEXt PNGARG((png_struct *png_ptr, png_info *info, +#endif + +#if defined(PNG_READ_tEXt_SUPPORTED) +extern void png_handle_tEXt PNGARG((png_struct *png_ptr, png_info *info, png_uint_32 length)); -extern void png_handle_zTXt PNGARG((png_struct *png_ptr, png_info *info, +#endif + +#if defined(PNG_READ_zTXt_SUPPORTED) +extern void png_handle_zTXt PNGARG((png_struct *png_ptr, png_info *info, png_uint_32 length)); +#endif /* handle the transformations for reading and writing */ extern void png_do_read_transformations PNGARG((png_struct *png_ptr)); @@ -911,3 +1104,4 @@ extern void png_init_read_transformations PNGARG((png_struct *png_ptr)); /* do not put anything past this line */ #endif /* _PNG_H */ + diff --git a/pngchang.txt b/pngchang.txt index 878a2f81..4eff6532 100644 --- a/pngchang.txt +++ b/pngchang.txt @@ -40,5 +40,21 @@ version 0.7 version 0.71 changed pngtest.png for zlib 0.93 fixed error in libpng.txt and example.c +version 0.8 + cleaned up some bugs + added png_set_filler() + split up pngstub.c into pngmem.c, pngio.c, and pngerror.c + added #define's to remove unwanted code + moved png_info_init() to png.c + added old_size into png_realloc() + added functions to manually set filtering and compression info + changed compression parameters based on image type + optimized filter selection code + added version info + changed external functions passing floats to doubles (k&r problems?) + put all the configurable stuff in pngconf.h + enabled png_set_shift to work with paletted images on read + added png_read_update_info() - updates info structure with transformations + diff --git a/pngconf.h b/pngconf.h new file mode 100644 index 00000000..5cfdcc92 --- /dev/null +++ b/pngconf.h @@ -0,0 +1,256 @@ + +/* pngconf.c - machine configurable file for libpng + + libpng 1.0 beta 2 - version 0.81 + For conditions of distribution and use, see copyright notice in png.h + Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. + August 24, 1995 + */ + +/* Any machine specific code is near the front of this file, so if you + are configuring libpng for a machine, you may want to read the section + starting here down to where it starts to typedef png_color, png_text, + and png_info */ + +#ifndef PNGCONF_H +#define PNGCONF_H + +/* this is the size of the compression buffer, and thus the size of + an IDAT chunk. Make this whatever size you feel is best for your + machine. One of these will be allocated per png_struct. When this + is full, it writes the data to the disk, and does some other + calculations. Making this an extreamly small size will slow + the library down, but you may want to experiment to determine + where it becomes significant, if you are concerned with memory + usage. Note that zlib allocates at least 32Kb also. For readers, + this describes the size of the buffer available to read the data in. + 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 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 + used to help portability between machines. To make it simpler to + setup libpng on a machine, this currently uses zlib's definitions, so + any changes should be made in zlib. Libpng will check zlib's settings + and adjust it's own accordingly. */ + +/* if you are running on a machine where you cannot allocate more then + 64K of memory, uncomment this. While libpng will not normally need + that much memory in a chunk (unless you load up a very large file), + zlib needs to know how big of a chunk it can use, and libpng thus + makes sure to check any memory allocation to verify it will fit + into memory. +#define PNG_MAX_ALLOC_64K +*/ +#ifdef MAXSEG_64K +#define PNG_MAX_ALLOC_64K +#endif + +/* 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 + indicator, but you may need to drag the empty declaration out in + front of here, or change the ifdef to suit your own needs. */ +#ifndef PNGARG + +#ifdef OF +#define PNGARG(arglist) OF(arglist) +#else + +#ifdef _NO_PROTO +#define PNGARG(arglist) +#else +#define PNGARG(arglist) arglist +#endif /* _NO_PROTO */ + +#endif /* OF */ + +#endif /* PNGARG */ + +/* enough people need this for various reasons to include it here */ +#ifndef MACOS +#include +#endif +/* need the time information for reading tIME chunks */ +#include + +/* for FILE. If you are not using standard io, you don't need this */ +#include + +/* include setjmp.h for error handling */ +#include + +#ifdef BSD +#include +#else +#include +#endif + +/* other defines for things like memory and the like can go here. These + are the only files included in libpng, so if you need to change them, + change them here. They are only included if PNG_INTERNAL is defined. */ +#ifdef PNG_INTERNAL +#include +#include +#include + +/* other defines specific to compilers can go here. Try to keep + them inside an appropriate ifdef/endif pair for portability */ + +/* for some reason, Borland C++ defines memcmp, etc. in mem.h, not + stdlib.h like it should (I think). Or perhaps this is a C++ + feature */ +#ifdef __TURBOC__ +#include +#include "alloc.h" +#endif + +#ifdef _MSC_VER +#include +#endif + +/* this controls how fine the dithering gets. As this allocates + a largish chunk of memory (32K), those who are not as concerned + with dithering quality can decrease some or all of these */ +#define PNG_DITHER_RED_BITS 5 +#define PNG_DITHER_GREEN_BITS 5 +#define PNG_DITHER_BLUE_BITS 5 + +/* this controls how fine the gamma correction becomes when you + are only interested in 8 bits anyway. Increasing this value + results in more memory being used, and more pow() functions + being called to fill in the gamma tables. Don't get this + value less then 8, and even that may not work (I haven't tested + it). */ + +#define PNG_MAX_GAMMA_8 11 + +#endif /* PNG_INTERNAL */ + +/* 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 + that without making it seriously hard on the users. So + if you are not using an ability, change the #define to + and #undef, and that part of the library will not be + compiled. If your linker can't find a function, you + may want to make sure the ability is defined here. + Some of these depend upon some others being defined. + I haven't figured out all the interactions here, so + you may have to experiment awhile to get everything + to compile. + */ + +/* Any transformations you will not be using can be undef'ed here */ + +#define PNG_READ_INTERLACING_SUPPORTED +#define PNG_READ_EXPAND_SUPPORTED +#define PNG_READ_SHIFT_SUPPORTED +#define PNG_READ_PACK_SUPPORTED +#define PNG_READ_BGR_SUPPORTED +#define PNG_READ_SWAP_SUPPORTED +#define PNG_READ_INVERT_SUPPORTED +#define PNG_READ_DITHER_SUPPORTED +#define PNG_READ_BACKGROUND_SUPPORTED +#define PNG_READ_16_TO_8_SUPPORTED +#define PNG_READ_FILLER_SUPPORTED +#define PNG_READ_GAMMA_SUPPORTED +#define PNG_READ_GRAY_TO_RGB_SUPPORTED + +#define PNG_WRITE_INTERLACING_SUPPORTED +#define PNG_WRITE_SHIFT_SUPPORTED +#define PNG_WRITE_PACK_SUPPORTED +#define PNG_WRITE_BGR_SUPPORTED +#define PNG_WRITE_SWAP_SUPPORTED +#define PNG_WRITE_INVERT_SUPPORTED +#define PNG_WRITE_FILLER_SUPPORTED + +/* any chunks you are not interested in, you can undef here. The + ones that allocate memory may be expecially important (hIST, + tEXt, zTXt, tRNS) Others will just save time and make png_info + smaller. OPT_PLTE only disables the optional palette in RGB + and RGB Alpha images. */ + +#define PNG_READ_gAMA_SUPPORTED +#define PNG_READ_sBIT_SUPPORTED +#define PNG_READ_cHRM_SUPPORTED +#define PNG_READ_tRNS_SUPPORTED +#define PNG_READ_bKGD_SUPPORTED +#define PNG_READ_hIST_SUPPORTED +#define PNG_READ_pHYs_SUPPORTED +#define PNG_READ_oFFs_SUPPORTED +#define PNG_READ_tIME_SUPPORTED +#define PNG_READ_tEXt_SUPPORTED +#define PNG_READ_zTXt_SUPPORTED +#define PNG_READ_OPT_PLTE_SUPPORTED + +#define PNG_WRITE_gAMA_SUPPORTED +#define PNG_WRITE_sBIT_SUPPORTED +#define PNG_WRITE_cHRM_SUPPORTED +#define PNG_WRITE_tRNS_SUPPORTED +#define PNG_WRITE_bKGD_SUPPORTED +#define PNG_WRITE_hIST_SUPPORTED +#define PNG_WRITE_pHYs_SUPPORTED +#define PNG_WRITE_oFFs_SUPPORTED +#define PNG_WRITE_tIME_SUPPORTED +#define PNG_WRITE_tEXt_SUPPORTED +#define PNG_WRITE_zTXt_SUPPORTED + +/* some typedefs to get us started. These should be safe on most of the + common platforms. The typedefs should be at least as large + as the numbers suggest (a png_uint_32 must be at least 32 bits long), + but they don't have to be exactly that size. */ + +typedef unsigned long png_uint_32; +typedef long png_int_32; +typedef unsigned short png_uint_16; +typedef short png_int_16; +typedef unsigned char png_byte; + +/* this is usually size_t. it is typedef'ed just in case you need it to + 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 + 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 + 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 +#else +# define FAR +#endif + +typedef unsigned char FAR png_bytef; + +/* End medium model changes to be in zconf.h */ + +/* 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 */ +# define png_strcpy _fstrcpy +# define png_strcat _fstrcat +# define png_strlen _fstrlen +# define png_strcmp _fstrcmp +# define png_memcpy _fmemcpy +# define png_memset _fmemset +#else /* use the usual functions */ +# define png_strcpy strcpy +# define png_strcat strcat +# define png_strlen strlen +# define png_strcmp strcmp +# 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..2bfef52c --- /dev/null +++ b/pngerror.c @@ -0,0 +1,46 @@ + +/* pngstub.c - stub functions for i/o and memory allocation + + libpng 1.0 beta 2 - version 0.81 + For conditions of distribution and use, see copyright notice in png.h + Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. + August 24, 1995 + + This file provides a location for all error handling. Users which + need special error handling are expected to modify the code in this + file to meet their needs. See the instructions at each function. */ + +#define PNG_INTERNAL +#include "png.h" + +/* This function is called whenever there is an error. Replace with + however you wish to handle the error. Note that this function + MUST NOT return, or the program will crash */ +void +png_error(png_structf *png_ptr, char *message) +{ + fprintf(stderr, "libpng error: %s\n", message); +#ifdef USE_FAR_KEYWORD + { + jmp_buf jmpbuf; + png_memcpy(jmpbuf,png_ptr->jmpbuf,sizeof(jmp_buf)); + longjmp(jmpbuf, 1); + } +#else + longjmp(png_ptr->jmpbuf, 1); +#endif +} + +/* This function is called when there is a warning, but the library + thinks it can continue anyway. You don't have to do anything here + if you don't want to. In the default configuration, png_ptr is + not used, but it is passed in case it may be useful. */ +void +png_warning(png_struct *png_ptr, char *message) +{ + if (!png_ptr) + return; + + fprintf(stderr, "libpng warning: %s\n", message); +} + diff --git a/pngio.c b/pngio.c new file mode 100644 index 00000000..6c11c75a --- /dev/null +++ b/pngio.c @@ -0,0 +1,180 @@ + +/* pngstub.c - stub functions for i/o and memory allocation + + libpng 1.0 beta 2 - version 0.81 + For conditions of distribution and use, see copyright notice in png.h + Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. + August 24, 1995 + + This file provides a location for all input/output. Users which need + special 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" + +/* 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 the place to do it. We suggest saving the old code + for future use, possibly in a #define. 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, but if you are having problems + with it, you can take it out. Just be sure to cast length to whatever + fwrite needs in that spot if you don't have a function prototype for + it. */ + +#ifndef USE_FAR_KEYWORD +void +png_write_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length) +{ + png_uint_32 check; + + check = fwrite(data, 1, (png_size_t)length, png_ptr->fp); + if (check != length) + { + png_error(png_ptr, "Write Error"); + } +} +#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. +*/ + +#define NEAR_BUF_SIZE 1024 +#define MIN(a,b) (a <= b ? a : b) + +#ifdef _MSC_VER +/* for FP_OFF */ +#include +#endif + +void +png_write_data(png_struct *png_ptr, png_bytef *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)) +#else + /* this works in MSC also but with lost segment warning */ + n_data = (png_byte *)data; + if((png_bytef *)n_data == data) +#endif + { + check = fwrite(n_data, 1, (png_size_t)length, png_ptr->fp); + } + 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 */ + err = fwrite(buf, 1, written, png_ptr->fp); + if(err != written) + break; + else + check += err; + data += written; + remaining -= written; + } + 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 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. */ +#ifndef USE_FAR_KEYWORD +void +png_read_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length) +{ + png_uint_32 check; + + check = fread(data, 1, (size_t)length, png_ptr->fp); + if (check != length) + { + png_error(png_ptr, "Read Error"); + } +} +#else +void +png_read_data(png_struct *png_ptr, png_bytef *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)) +#else + /* this works in MSC also but with lost segment warning */ + n_data = (png_byte *)data; + if((png_bytef *)n_data == data) +#endif + { + check = fread(n_data, 1, (size_t)length, png_ptr->fp); + } + else + { + png_byte buf[NEAR_BUF_SIZE]; + png_size_t read, remaining, err; + check = 0; + remaining = (png_size_t)length; + do + { + 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 */ + if(err != read) + break; + else + check += err; + data += read; + remaining -= read; + } + while(remaining != 0); + } + if (check != length) + { + png_error(png_ptr, "read Error"); + } +} +#endif + +/* 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_init_io(png_struct *png_ptr, FILE *fp) +{ + png_ptr->fp = fp; +} + diff --git a/pngstub.c b/pngmem.c similarity index 62% rename from pngstub.c rename to pngmem.c index 6ae1469e..c115e4c7 100644 --- a/pngstub.c +++ b/pngmem.c @@ -1,75 +1,18 @@ /* pngstub.c - stub functions for i/o and memory allocation - libpng 1.0 beta 1 - version 0.71 + libpng 1.0 beta 2 - version 0.81 For conditions of distribution and use, see copyright notice in png.h Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. - June 26, 1995 + August 24, 1995 - This file provides a location for all input/output, memory location, - and error handling. Users which need special handling in these areas - are expected to modify the code in this file to meet their needs. See - the instructions at each function. */ + This file provides a location for all memory allocation. Users which + 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 #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 the place to do it. We suggest saving the old code - for future use, possibly in a #define. 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, but if you are having problems - with it, you can take it out. Just be sure to cast length to whatever - fwrite needs in that spot if you don't have a function prototype for - it. */ -void -png_write_data(png_struct *png_ptr, png_byte *data, png_uint_32 length) -{ - png_uint_32 check; - - check = fwrite(data, 1, (png_size_t)length, png_ptr->fp); - if (check != length) - { - png_error(png_ptr, "Write Error"); - } -} - -/* 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 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_struct *png_ptr, png_byte *data, png_uint_32 length) -{ - png_uint_32 check; - - check = fread(data, 1, (size_t)length, png_ptr->fp); - if (check != length) - { - png_error(png_ptr, "Read Error"); - } -} - -/* 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_init_io(png_struct *png_ptr, FILE *fp) -{ - png_ptr->fp = fp; -} - /* Allocate memory. For reasonable files, size should never exceed 64K. However, zlib may allocate more then 64K if you don't tell it not to. See zconf.h and png.h for more information. zlib does @@ -89,6 +32,7 @@ png_init_io(png_struct *png_ptr, FILE *fp) */ #ifdef __TURBOC__ #ifndef __WIN32__ +#ifndef __FLAT__ /* NUM_SEG is the number of segments allocated at once */ #define NUM_SEG 4 @@ -104,13 +48,16 @@ borland_seg *save_array; int num_save_array; int max_save_array; +#endif #endif #endif -void * -png_large_malloc(png_struct *png_ptr, png_uint_32 size) +voidpf +png_large_malloc(png_structf *png_ptr, png_uint_32 size) { - void *ret; + voidpf ret; + if (!png_ptr || !size) + return ((void *)0); #ifdef PNG_MAX_MALLOC_64K if (size > (png_uint_32)65536L) @@ -118,8 +65,8 @@ png_large_malloc(png_struct *png_ptr, png_uint_32 size) #endif #ifdef __TURBOC__ -# ifdef __WIN32__ - ret = farmalloc(size); +# if defined(__WIN32__) || defined(__FLAT__) + ret = malloc(size); # else if (size == 65536L) @@ -152,11 +99,11 @@ png_large_malloc(png_struct *png_ptr, png_uint_32 size) num_save_array = 1; save_array = malloc(num_save_array * sizeof (borland_seg)); if (!save_array) - png_error(png_ptr, "Out of Memory"); + png_error(png_ptr, "Out of Memory 1"); save_array->mem_ptr = farmalloc( - (unsigned long)(NUM_SEG) * 65536L + 65528L); + (unsigned long)(NUM_SEG) * 65536L + 65532L); if (!save_array->mem_ptr) - png_error(png_ptr, "Out of Memory"); + png_error(png_ptr, "Out of Memory 2"); offset = (unsigned long)(ret); offset &= 0xffffL; ptr = save_array->mem_ptr; @@ -194,11 +141,11 @@ png_large_malloc(png_struct *png_ptr, png_uint_32 size) save_array = realloc(save_array, (num_save_array + 1) * sizeof (borland_seg)); if (!save_array) - png_error(png_ptr, "Out of Memory"); + png_error(png_ptr, "Out of Memory 3"); save_array[num_save_array].mem_ptr = farmalloc( - (unsigned long)(NUM_SEG) * 65536L + 65528L); + (unsigned long)(NUM_SEG) * 65536L + 65532L); if (!save_array[num_save_array].mem_ptr) - png_error(png_ptr, "Out of Memory"); + png_error(png_ptr, "Out of Memory 4"); offset = (unsigned long)(ret); offset &= 0xffffL; ptr = save_array[num_save_array].mem_ptr; @@ -231,7 +178,7 @@ png_large_malloc(png_struct *png_ptr, png_uint_32 size) # endif #endif - if (!ret) + if (ret == NULL) { png_error(png_ptr, "Out of Memory"); } @@ -243,7 +190,7 @@ png_large_malloc(png_struct *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_struct *png_ptr, void *ptr) +png_large_free(png_structf *png_ptr, voidpf ptr) { if (!png_ptr) return; @@ -251,7 +198,10 @@ png_large_free(png_struct *png_ptr, void *ptr) if (ptr != (void *)0) { #ifdef __TURBOC__ -# ifndef __WIN32__ +# if defined(__WIN32__) || defined(__FLAT__) + if (ptr) + free(ptr); +# else int i, j; for (i = 0; i < num_save_array; i++) @@ -260,14 +210,13 @@ png_large_free(png_struct *png_ptr, void *ptr) { if (ptr == save_array[i].seg_ptr[j]) { -printf("freeing pointer: i, j: %d, %d\n", i, j); save_array[i].seg_used[j] = 0; ptr = 0; save_array[i].num_used--; if (!save_array[i].num_used) { int k; -printf("freeing array: %d\n", i); + num_save_array--; farfree(save_array[i].mem_ptr); for (k = i; k < num_save_array; k++) @@ -285,9 +234,9 @@ printf("freeing array: %d\n", i); break; } -# endif if (ptr) farfree(ptr); +# endif #else # ifdef _MSC_VER hfree(ptr); @@ -305,7 +254,7 @@ png_malloc(png_struct *png_ptr, png_uint_32 size) { void *ret; - if (!png_ptr) + if (!png_ptr || !size) return ((void *)0); #ifdef PNG_MAX_MALLOC_64K @@ -317,7 +266,7 @@ png_malloc(png_struct *png_ptr, png_uint_32 size) if (!ret) { - png_error(png_ptr, "Out of Memory"); + png_error(png_ptr, "Out of Memory 6"); } return ret; @@ -326,11 +275,12 @@ png_malloc(png_struct *png_ptr, png_uint_32 size) /* Reallocate memory. This will not get near 64K on a even marginally reasonable file. */ void * -png_realloc(png_struct *png_ptr, void *ptr, png_uint_32 size) +png_realloc(png_struct *png_ptr, void *ptr, png_uint_32 size, + png_uint_32 old_size) { void *ret; - if (!png_ptr) + if (!png_ptr || !old_size || !ptr || !size) return ((void *)0); #ifdef PNG_MAX_MALLOC_64K @@ -342,7 +292,7 @@ png_realloc(png_struct *png_ptr, void *ptr, png_uint_32 size) if (!ret) { - png_error(png_ptr, "Out of Memory"); + png_error(png_ptr, "Out of Memory 7"); } return ret; @@ -361,27 +311,3 @@ png_free(png_struct *png_ptr, void *ptr) free(ptr); } -/* 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_struct *png_ptr, char *message) -{ - fprintf(stderr, "libpng error: %s\n", message); - - longjmp(png_ptr->jmpbuf, 1); -} - -/* This function is called when there is a warning, but the library - thinks it can continue anyway. You don't have to do anything here - if you don't want to. In the default configuration, png_ptr is - not used, but it is passed in case it may be useful. */ -void -png_warning(png_struct *png_ptr, char *message) -{ - if (!png_ptr) - return; - - fprintf(stderr, "libpng warning: %s\n", message); -} - diff --git a/pngrcb.c b/pngrcb.c index 50b43014..ba1fe143 100644 --- a/pngrcb.c +++ b/pngrcb.c @@ -1,9 +1,9 @@ /* pngrcb.c - callbacks while reading a png file - libpng 1.0 beta 1 - version 0.71 + libpng 1.0 beta 2 - version 0.81 For conditions of distribution and use, see copyright notice in png.h Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. - June 26, 1995 + August 24, 1995 */ #define PNG_INTERNAL @@ -49,6 +49,7 @@ png_read_PLTE(png_struct *png_ptr, png_info *info, info->valid |= PNG_INFO_PLTE; } +#if defined(PNG_READ_gAMA_SUPPORTED) void png_read_gAMA(png_struct *png_ptr, png_info *info, float gamma) { @@ -58,7 +59,9 @@ png_read_gAMA(png_struct *png_ptr, png_info *info, float gamma) info->gamma = gamma; info->valid |= PNG_INFO_gAMA; } +#endif +#if defined(PNG_READ_sBIT_SUPPORTED) void png_read_sBIT(png_struct *png_ptr, png_info *info, png_color_8 *sig_bit) @@ -69,7 +72,9 @@ png_read_sBIT(png_struct *png_ptr, png_info *info, 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, @@ -88,7 +93,9 @@ png_read_cHRM(png_struct *png_ptr, png_info *info, info->y_blue = blue_y; info->valid |= PNG_INFO_cHRM; } +#endif +#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) @@ -108,7 +115,9 @@ png_read_tRNS(png_struct *png_ptr, png_info *info, info->num_trans = num_trans; info->valid |= PNG_INFO_tRNS; } +#endif +#if defined(PNG_READ_bKGD_SUPPORTED) void png_read_bKGD(png_struct *png_ptr, png_info *info, png_color_16 *background) @@ -119,7 +128,9 @@ png_read_bKGD(png_struct *png_ptr, png_info *info, 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) { @@ -129,7 +140,9 @@ png_read_hIST(png_struct *png_ptr, png_info *info, png_uint_16 *hist) info->hist = hist; info->valid |= PNG_INFO_hIST; } +#endif +#if defined(PNG_READ_pHYs_SUPPORTED) void png_read_pHYs(png_struct *png_ptr, png_info *info, png_uint_32 res_x, png_uint_32 res_y, int unit_type) @@ -142,7 +155,9 @@ png_read_pHYs(png_struct *png_ptr, png_info *info, info->phys_unit_type = unit_type; info->valid |= PNG_INFO_pHYs; } +#endif +#if defined(PNG_READ_oFFs_SUPPORTED) void png_read_oFFs(png_struct *png_ptr, png_info *info, png_uint_32 offset_x, png_uint_32 offset_y, int unit_type) @@ -155,7 +170,9 @@ png_read_oFFs(png_struct *png_ptr, png_info *info, info->offset_unit_type = unit_type; info->valid |= PNG_INFO_oFFs; } +#endif +#if defined(PNG_READ_tIME_SUPPORTED) void png_read_tIME(png_struct *png_ptr, png_info *info, png_time *mod_time) @@ -166,10 +183,12 @@ png_read_tIME(png_struct *png_ptr, png_info *info, 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, - char *key, char *text, png_uint_32 text_len, int compression) + charf *key, charf *text, png_uint_32 text_len, int compression) { if (!png_ptr || !info) return; @@ -178,10 +197,14 @@ png_read_zTXt(png_struct *png_ptr, png_info *info, { if (info->text) { + png_uint_32 old_max; + + old_max = info->max_text; info->max_text = info->num_text + 16; info->text = (png_text *)png_realloc(png_ptr, info->text, - info->max_text * sizeof (png_text)); + info->max_text * sizeof (png_text), + old_max * sizeof (png_text)); } else { @@ -198,15 +221,17 @@ png_read_zTXt(png_struct *png_ptr, png_info *info, info->text[info->num_text].compression = compression; info->num_text++; } +#endif +#if defined(PNG_READ_tEXt_SUPPORTED) void png_read_tEXt(png_struct *png_ptr, png_info *info, - char *key, char *text, png_uint_32 text_len) + charf *key, charf *text, png_uint_32 text_len) { if (!png_ptr || !info) return; png_read_zTXt(png_ptr, info, key, text, text_len, -1); } - +#endif diff --git a/pngread.c b/pngread.c index e1afee66..37ac3c28 100644 --- a/pngread.c +++ b/pngread.c @@ -1,10 +1,10 @@ /* pngread.c - read a png file - libpng 1.0 beta 1 - version 0.71 + libpng 1.0 beta 2 - version 0.81 For conditions of distribution and use, see copyright notice in png.h Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. - June 26, 1995 + August 24, 1995 */ #define PNG_INTERNAL @@ -16,9 +16,9 @@ png_read_init(png_struct *png_ptr) { jmp_buf tmp_jmp; - memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf)); - memset(png_ptr, 0, sizeof (png_struct)); - memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf)); + 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_ptr->zbuf_size = PNG_ZBUF_SIZE; png_ptr->zbuf = png_large_malloc(png_ptr, png_ptr->zbuf_size); @@ -63,9 +63,28 @@ png_read_info(png_struct *png_ptr, png_info *info) if (png_ptr->mode != PNG_HAVE_IHDR) png_error(png_ptr, "Missing IHDR"); - png_handle_PLTE(png_ptr, info, length); +#if !defined(PNG_READ_OPT_PLTE_SUPPORTED) + if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) + png_crc_skip(png_ptr, length); + else +#else + { + png_handle_PLTE(png_ptr, info, length); + } +#endif png_ptr->mode = PNG_HAVE_PLTE; } + else if (!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)) + { + png_error(png_ptr, "No Image in File"); + } +#if defined(PNG_READ_gAMA_SUPPORTED) else if (!memcmp(chunk_start + 4, png_gAMA, 4)) { if (png_ptr->mode != PNG_HAVE_IHDR) @@ -73,6 +92,8 @@ png_read_info(png_struct *png_ptr, png_info *info) png_handle_gAMA(png_ptr, info, length); } +#endif +#if defined(PNG_READ_sBIT_SUPPORTED) else if (!memcmp(chunk_start + 4, png_sBIT, 4)) { if (png_ptr->mode != PNG_HAVE_IHDR) @@ -80,6 +101,8 @@ png_read_info(png_struct *png_ptr, png_info *info) png_handle_sBIT(png_ptr, info, length); } +#endif +#if defined(PNG_READ_cHRM_SUPPORTED) else if (!memcmp(chunk_start + 4, png_cHRM, 4)) { if (png_ptr->mode != PNG_HAVE_IHDR) @@ -87,6 +110,8 @@ png_read_info(png_struct *png_ptr, png_info *info) png_handle_cHRM(png_ptr, info, length); } +#endif +#if defined(PNG_READ_tRNS_SUPPORTED) else if (!memcmp(chunk_start + 4, png_tRNS, 4)) { if (png_ptr->mode != PNG_HAVE_IHDR && @@ -95,6 +120,8 @@ png_read_info(png_struct *png_ptr, png_info *info) png_handle_tRNS(png_ptr, info, length); } +#endif +#if defined(PNG_READ_bKGD_SUPPORTED) else if (!memcmp(chunk_start + 4, png_bKGD, 4)) { if (png_ptr->mode != PNG_HAVE_IHDR && @@ -103,6 +130,8 @@ png_read_info(png_struct *png_ptr, png_info *info) png_handle_bKGD(png_ptr, info, length); } +#endif +#if defined(PNG_READ_hIST_SUPPORTED) else if (!memcmp(chunk_start + 4, png_hIST, 4)) { if (png_ptr->mode != PNG_HAVE_PLTE) @@ -110,12 +139,8 @@ png_read_info(png_struct *png_ptr, png_info *info) png_handle_hIST(png_ptr, info, length); } - else if (!memcmp(chunk_start + 4, png_IDAT, 4)) - { - png_ptr->idat_size = length; - png_ptr->mode = PNG_HAVE_IDAT; - break; - } +#endif +#if defined(PNG_READ_pHYs_SUPPORTED) else if (!memcmp(chunk_start + 4, png_pHYs, 4)) { if (png_ptr->mode != PNG_HAVE_IHDR && @@ -124,6 +149,8 @@ png_read_info(png_struct *png_ptr, png_info *info) png_handle_pHYs(png_ptr, info, length); } +#endif +#if defined(PNG_READ_oFFs_SUPPORTED) else if (!memcmp(chunk_start + 4, png_oFFs, 4)) { if (png_ptr->mode != PNG_HAVE_IHDR && @@ -132,6 +159,8 @@ png_read_info(png_struct *png_ptr, png_info *info) png_handle_oFFs(png_ptr, info, length); } +#endif +#if defined(PNG_READ_tIME_SUPPORTED) else if (!memcmp(chunk_start + 4, png_tIME, 4)) { if (png_ptr->mode == PNG_BEFORE_IHDR || @@ -140,6 +169,8 @@ png_read_info(png_struct *png_ptr, png_info *info) png_handle_tIME(png_ptr, info, length); } +#endif +#if defined(PNG_READ_tEXt_SUPPORTED) else if (!memcmp(chunk_start + 4, png_tEXt, 4)) { if (png_ptr->mode == PNG_BEFORE_IHDR || @@ -148,6 +179,8 @@ png_read_info(png_struct *png_ptr, png_info *info) png_handle_tEXt(png_ptr, info, length); } +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) else if (!memcmp(chunk_start + 4, png_zTXt, 4)) { if (png_ptr->mode == PNG_BEFORE_IHDR || @@ -156,13 +189,10 @@ png_read_info(png_struct *png_ptr, png_info *info) png_handle_zTXt(png_ptr, info, length); } - else if (!memcmp(chunk_start + 4, png_IEND, 4)) - { - png_error(png_ptr, "No Image in File"); - } +#endif else { - if (isupper(chunk_start[4])) + if ((chunk_start[4] & 0x20) == 0) png_error(png_ptr, "Unknown Critical Chunk"); png_crc_skip(png_ptr, length); @@ -175,6 +205,15 @@ png_read_info(png_struct *png_ptr, png_info *info) } } +/* optional call to update the users info structure */ +void +png_read_update_info(png_struct *png_ptr, png_info *info_ptr) +{ + if (!(png_ptr->row_init)) + png_read_start_row(png_ptr); + png_read_transform_info(png_ptr, info_ptr); +} + /* initialize palette, background, etc, after transformations are set, but before any reading takes place. This allows the user to obtail a gamma corrected palette, for example. @@ -182,17 +221,18 @@ png_read_info(png_struct *png_ptr, png_info *info) void png_start_read_image(png_struct *png_ptr) { - png_read_start_row(png_ptr); + if (!(png_ptr->row_init)) + png_read_start_row(png_ptr); } void -png_read_row(png_struct *png_ptr, png_byte *row, png_byte *dsp_row) +png_read_row(png_struct *png_ptr, png_bytef *row, png_byte *dsp_row) { int ret; - if (!(png_ptr->row_init)) png_read_start_row(png_ptr); +#if defined(PNG_READ_INTERLACING_SUPPORTED) /* if interlaced and we do not need a new row, combine row and return */ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) { @@ -267,6 +307,7 @@ png_read_row(png_struct *png_ptr, png_byte *row, png_byte *dsp_row) break; } } +#endif if (png_ptr->mode != PNG_HAVE_IDAT) png_error(png_ptr, "invalid attempt to read row data"); @@ -334,11 +375,12 @@ png_read_row(png_struct *png_ptr, png_byte *row, png_byte *dsp_row) png_ptr->row_buf + 1, png_ptr->prev_row + 1, (int)(png_ptr->row_buf[0])); - memcpy(png_ptr->prev_row, png_ptr->row_buf, (png_size_t)png_ptr->rowbytes + 1); + 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)) @@ -355,6 +397,7 @@ png_read_row(png_struct *png_ptr, png_byte *row, png_byte *dsp_row) png_pass_mask[png_ptr->pass]); } else +#endif { if (row) png_combine_row(png_ptr, row, 0xff); @@ -383,18 +426,18 @@ png_read_row(png_struct *png_ptr, png_byte *row, png_byte *dsp_row) not called png_set_interlace_handling(), the display_row buffer will be ignored, so pass NULL to it. */ void -png_read_rows(png_struct *png_ptr, png_byte **row, +png_read_rows(png_struct *png_ptr, png_bytef **row, png_byte **display_row, png_uint_32 num_rows) { png_uint_32 i; - png_byte **rp; + png_bytef **rp; png_byte **dp; rp = row; dp = display_row; for (i = 0; i < num_rows; i++) { - png_byte *rptr; + png_bytef *rptr; png_byte *dptr; if (rp) @@ -420,11 +463,11 @@ png_read_rows(png_struct *png_ptr, png_byte **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_byte **image) +png_read_image(png_struct *png_ptr, png_bytef **image) { png_uint_32 i; int pass, j; - png_byte **rp; + png_bytef **rp; pass = png_set_interlace_handling(png_ptr); for (j = 0; j < pass; j++) @@ -506,6 +549,7 @@ png_read_end(png_struct *png_ptr, png_info *info) { png_error(png_ptr, "invalid chunk after IDAT"); } +#if defined(PNG_READ_tIME_SUPPORTED) else if (!memcmp(chunk_start + 4, png_tIME, 4)) { if (png_ptr->mode == PNG_BEFORE_IHDR || @@ -517,6 +561,8 @@ png_read_end(png_struct *png_ptr, png_info *info) else png_crc_skip(png_ptr, length); } +#endif +#if defined(PNG_READ_tEXt_SUPPORTED) else if (!memcmp(chunk_start + 4, png_tEXt, 4)) { if (png_ptr->mode == PNG_BEFORE_IHDR || @@ -528,6 +574,8 @@ png_read_end(png_struct *png_ptr, png_info *info) else png_crc_skip(png_ptr, length); } +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) else if (!memcmp(chunk_start + 4, png_zTXt, 4)) { if (png_ptr->mode == PNG_BEFORE_IHDR || @@ -539,13 +587,14 @@ png_read_end(png_struct *png_ptr, png_info *info) else png_crc_skip(png_ptr, length); } +#endif else if (!memcmp(chunk_start + 4, png_IEND, 4)) { png_ptr->mode = PNG_AFTER_IEND; } else { - if (isupper(chunk_start[4])) + if ((chunk_start[4] & 0x20) == 0) png_error(png_ptr, "Unknown Critical Chunk"); png_crc_skip(png_ptr, length); @@ -569,40 +618,58 @@ png_read_destroy(png_struct *png_ptr, png_info *info, png_info *end_info) if (info) { +/* I'm not sure I should be freeing this */ if (info->palette != png_ptr->palette) png_free(png_ptr, info->palette); +/* I'm not sure I should be freeing this */ +#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_bKGD_SUPPORTED) if (info->trans != png_ptr->trans) png_free(png_ptr, info->trans); +#endif +/* I'm not sure I should be freeing this */ +#if defined(PNG_READ_hIST_SUPPORTED) if (info->hist != png_ptr->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); } png_free(png_ptr, info->text); - memset(info, 0, sizeof(png_info)); +#endif + 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++) { png_large_free(png_ptr, end_info->text[i].key); } png_free(png_ptr, end_info->text); - memset(end_info, 0, sizeof(png_info)); +#endif + png_memset(end_info, 0, sizeof(png_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); +#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) { for (i = 0; i < (1 << (8 - png_ptr->gamma_shift)); i++) @@ -610,6 +677,8 @@ 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) { @@ -627,16 +696,20 @@ png_read_destroy(png_struct *png_ptr, png_info *info, png_info *end_info) } } 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); +#endif if (!png_ptr->user_palette) png_free(png_ptr, png_ptr->palette); inflateEnd(png_ptr->zstream); - memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf)); - memset(png_ptr, 0, sizeof (png_struct)); - memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf)); + 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 0aa3b47f..d291a33b 100644 --- a/pngrtran.c +++ b/pngrtran.c @@ -1,36 +1,41 @@ /* pngrtran.c - transforms the data in a row for png readers - libpng 1.0 beta 1 - version 0.71 + libpng 1.0 beta 2 - version 0.8 For conditions of distribution and use, see copyright notice in png.h Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. - June 26, 1995 + August 20, 1995 */ #define PNG_INTERNAL #include "png.h" +#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, - int need_expand, float background_gamma) + int need_expand, double background_gamma) { png_ptr->transformations |= PNG_BACKGROUND; - memcpy(&(png_ptr->background), background_color, + png_memcpy(&(png_ptr->background), background_color, sizeof(png_color_16)); - png_ptr->background_gamma = background_gamma; + png_ptr->background_gamma = (float)background_gamma; png_ptr->background_gamma_type = background_gamma_code; png_ptr->background_expand = need_expand; } +#endif +#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_ptr->transformations |= PNG_16_TO_8; } +#endif +#if defined(PNG_READ_DITHER_SUPPORTED) /* dither file to 8 bit. Supply a palette, the current number of elements in the palette, the maximum number of elements allowed, and a histogram, if possible. If the current number @@ -217,7 +222,7 @@ png_set_dither(png_struct *png_ptr, png_color *palette, hash = (dsort **)png_malloc(png_ptr, 769 * sizeof (dsort *)); for (i = 0; i < 769; i++) hash[i] = (dsort *)0; -/* memset(hash, 0, 769 * sizeof (dsort *)); */ +/* png_memset(hash, 0, 769 * sizeof (dsort *)); */ num_new_palette = num_palette; @@ -354,7 +359,7 @@ 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_byte *distance; + png_bytef *distance; total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS; @@ -364,15 +369,15 @@ png_set_dither(png_struct *png_ptr, png_color *palette, num_blue = (1 << PNG_DITHER_BLUE_BITS); num_entries = ((png_uint_32)1 << total_bits); - png_ptr->palette_lookup = (png_byte *)png_large_malloc(png_ptr, + png_ptr->palette_lookup = (png_bytef *)png_large_malloc(png_ptr, (png_size_t)num_entries * sizeof (png_byte)); - memset(png_ptr->palette_lookup, 0, (png_size_t)num_entries * sizeof (png_byte)); + png_memset(png_ptr->palette_lookup, 0, (png_size_t)num_entries * sizeof (png_byte)); - distance = (png_byte *)png_large_malloc(png_ptr, + distance = (png_bytef *)png_large_malloc(png_ptr, (png_size_t)num_entries * sizeof (png_byte)); - memset(distance, 0xff, (png_size_t)num_entries * sizeof (png_byte)); + png_memset(distance, 0xff, (png_size_t)num_entries * sizeof (png_byte)); for (i = 0; i < num_palette; i++) { @@ -417,67 +422,22 @@ png_set_dither(png_struct *png_ptr, png_color *palette, png_large_free(png_ptr, distance); } -#ifdef oldway - d = TABLE_COLOR_DISTANCE(index, palette[i]); - dt = TABLE_DISTANCE(index); - if (d < dt) - png_ptr->palette_lookup[index] = i; - - for (ir = r + 1, index2 = index; ir < num_red; ir++) - { - index2 += (1 << (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)); - d = RGB_COLOR_DISTANCE(r, g, b, palette[i]); - dt = TABLE_DISTANCE(index2); - if (d < dt) - png_ptr->palette_lookup[index2] = i; - else - break; - } - - - - i = 0; - for (ir = 0; ir < num_red; ir++) - { - r = (ir * 255) / (num_red - 1); - for (ig = 0; ig < num_green; ig++) - { - g = (ig * 255) / (num_green - 1); - for (ib = 0; ib < num_blue; ib++) - { - int min_d, j, k, d; - - b = (ib * 255) / (num_blue - 1); - min_d = 1024; - k = 0; - for (j = 0; j < png_ptr->num_palette; j++) - { - d = abs(r - (int)png_ptr->palette[j].red) + - abs(g - (int)png_ptr->palette[j].green) + - abs(b - (int)png_ptr->palette[j].blue); - if (d < min_d) - { - min_d = d; - k = j; - } - } - png_ptr->palette_lookup[i++] = k; - } - } - } -#endif } +#endif +#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, float screen_gamma, - float file_gamma) +png_set_gamma(png_struct *png_ptr, double screen_gamma, + double file_gamma) { png_ptr->transformations |= PNG_GAMMA; - png_ptr->gamma = file_gamma; - png_ptr->display_gamma = screen_gamma; + png_ptr->gamma = (float)file_gamma; + png_ptr->display_gamma = (float)screen_gamma; } +#endif +#if defined(PNG_READ_EXPAND_SUPPORTED) /* expand paletted images to rgb, expand grayscale images of less then 8 bit depth to 8 bit depth, and expand tRNS chunks to alpha channels */ @@ -486,12 +446,15 @@ png_set_expand(png_struct *png_ptr) { png_ptr->transformations |= PNG_EXPAND; } +#endif +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) void png_set_gray_to_rgb(png_struct *png_ptr) { png_ptr->transformations |= PNG_GRAY_TO_RGB; } +#endif /* initialize everything needed for the read. This includes modifying the palette */ @@ -502,12 +465,16 @@ png_init_read_transformations(png_struct *png_ptr) color_type = png_ptr->color_type; +#if defined(PNG_READ_EXPAND_SUPPORTED) && \ + defined(PNG_READ_BACKGROUND_SUPPORTED) if (png_ptr->transformations & PNG_EXPAND) { if (color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth < 8 && - (!(png_ptr->transformations & PNG_BACKGROUND) || - png_ptr->background_expand)) + (png_ptr->transformations & PNG_BACKGROUND) && + png_ptr->background_expand) +/* (!(png_ptr->transformations & PNG_BACKGROUND) || + png_ptr->background_expand)) */ { /* expand background chunk. While this may not be the fastest way to do this, it only happens once @@ -539,11 +506,16 @@ png_init_read_transformations(png_struct *png_ptr) color_type = PNG_COLOR_TYPE_RGB; } } +#endif +#if defined(PNG_READ_BACKGROUND_SUPPORTED) png_ptr->background_1 = png_ptr->background; +#endif +#if defined(PNG_READ_GAMMA_SUPPORTED) if (png_ptr->transformations & PNG_GAMMA) { png_build_gamma_table(png_ptr); +#if defined(PNG_READ_BACKGROUND_SUPPORTED) if ((png_ptr->transformations & PNG_BACKGROUND) && (color_type != PNG_COLOR_TYPE_PALETTE)) { @@ -596,7 +568,109 @@ png_init_read_transformations(png_struct *png_ptr) } } } +#endif } +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) + if ((png_ptr->transformations & PNG_SHIFT) && + png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + png_uint_16 i; + int sr, sg, sb; + + sr = 8 - png_ptr->sig_bit.red; + if (sr < 0 || sr > 8) + sr = 0; + sg = 8 - png_ptr->sig_bit.green; + if (sg < 0 || sg > 8) + sg = 0; + sb = 8 - png_ptr->sig_bit.blue; + if (sb < 0 || sb > 8) + sb = 0; + for (i = 0; i < png_ptr->num_palette; i++) + { + png_ptr->palette[i].red >>= sr; + png_ptr->palette[i].green >>= sg; + png_ptr->palette[i].blue >>= sb; + } + } +#endif +} + +/* 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 */ +void +png_read_transform_info(png_struct *png_ptr, png_info *info_ptr) +{ +#if defined(PNG_READ_EXPAND_SUPPORTED) + if ((png_ptr->transformations & PNG_EXPAND) && + info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (png_ptr->num_trans) + info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA; + else + info_ptr->color_type = PNG_COLOR_TYPE_RGB; + info_ptr->bit_depth = 8; + info_ptr->num_trans = 0; + } + else if (png_ptr->transformations & PNG_EXPAND) + { + if (png_ptr->num_trans) + info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; + if (info_ptr->bit_depth < 8) + info_ptr->bit_depth = 8; + info_ptr->num_trans = 0; + } +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) + if (png_ptr->transformations & PNG_BACKGROUND) + { + info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; + info_ptr->num_trans = 0; + info_ptr->background = png_ptr->background; + } +#endif + +#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; +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) + if (png_ptr->transformations & PNG_DITHER) + { + if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || + (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && + png_ptr->palette_lookup && info_ptr->bit_depth == 8) + { + info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; + } + } +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) + if ((png_ptr->transformations & PNG_PACK) && info_ptr->bit_depth < 8) + info_ptr->bit_depth = 8; +#endif + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) + if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && + !(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) + info_ptr->channels = 1; + else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) + info_ptr->channels = 3; + else + info_ptr->channels = 1; + if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) + info_ptr->channels++; + info_ptr->pixel_depth = info_ptr->channels * info_ptr->bit_depth; + info_ptr->rowbytes = ((info_ptr->width * info_ptr->pixel_depth + 7) >> 3); } /* transform the row. The order of transformations is significant, @@ -605,6 +679,7 @@ png_init_read_transformations(png_struct *png_ptr) void png_do_read_transformations(png_struct *png_ptr) { +#if defined(PNG_READ_EXPAND_SUPPORTED) if ((png_ptr->transformations & PNG_EXPAND) && png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE) { @@ -620,6 +695,9 @@ png_do_read_transformations(png_struct *png_ptr) png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, NULL); } +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) if (png_ptr->transformations & PNG_BACKGROUND) png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1, &(png_ptr->trans_values), &(png_ptr->background), @@ -628,53 +706,88 @@ png_do_read_transformations(png_struct *png_ptr) png_ptr->gamma_to_1, png_ptr->gamma_16_table, png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1, png_ptr->gamma_shift); - else if (png_ptr->transformations & PNG_GAMMA) +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) + if ((png_ptr->transformations & PNG_GAMMA) && + !(png_ptr->transformations & PNG_BACKGROUND)) png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr->gamma_table, png_ptr->gamma_16_table, png_ptr->gamma_shift); +#endif + +#if defined(PNG_READ_16_TO_8_SUPPORTED) if (png_ptr->transformations & PNG_16_TO_8) png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) if (png_ptr->transformations & PNG_DITHER) - png_do_dither(&(png_ptr->row_info), png_ptr->row_buf + 1, - png_ptr->palette_lookup, png_ptr->dither_index); + { + png_do_dither((png_row_info *)&(png_ptr->row_info), + png_ptr->row_buf + 1, + 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); +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) if (png_ptr->transformations & PNG_SHIFT) png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1, &(png_ptr->shift)); +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) if (png_ptr->transformations & PNG_PACK) png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) if (png_ptr->transformations & PNG_BGR) png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) if (png_ptr->transformations & PNG_GRAY_TO_RGB) png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_SWAP_SUPPORTED) if (png_ptr->transformations & PNG_SWAP_BYTES) png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); - if (png_ptr->transformations & PNG_RGBA) - png_do_read_rgbx(&(png_ptr->row_info), png_ptr->row_buf + 1); - if (png_ptr->transformations & PNG_XRGB) - png_do_read_xrgb(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_FILLER_SUPPORTED) + if (png_ptr->transformations & PNG_FILLER) + png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, + png_ptr->filler, png_ptr->filler_loc); +#endif } +#if defined(PNG_READ_PACK_SUPPORTED) /* unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, without changing the actual values. Thus, if you had a row with a bit depth of 1, you would end up with bytes that only contained 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_byte *row) +png_do_unpack(png_row_info *row_info, png_bytef *row) { + int shift; + png_bytef *sp, *dp; + png_uint_32 i; + if (row && row_info && row_info->bit_depth < 8) { switch (row_info->bit_depth) { case 1: { - png_byte *sp; - png_byte *dp; - int shift; - png_uint_32 i; - sp = row + (png_size_t)((row_info->width - 1) >> 3); dp = row + (png_size_t)row_info->width - 1; shift = 7 - (int)((row_info->width + 7) & 7); @@ -695,10 +808,6 @@ png_do_unpack(png_row_info *row_info, png_byte *row) } case 2: { - png_byte *sp; - png_byte *dp; - int shift; - png_uint_32 i; sp = row + (png_size_t)((row_info->width - 1) >> 2); dp = row + (png_size_t)row_info->width - 1; @@ -720,11 +829,6 @@ png_do_unpack(png_row_info *row_info, png_byte *row) } case 4: { - png_byte *sp; - png_byte *dp; - int shift; - png_uint_32 i; - 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); @@ -749,16 +853,22 @@ png_do_unpack(png_row_info *row_info, png_byte *row) row_info->rowbytes = row_info->width * row_info->channels; } } +#endif +#if defined(PNG_READ_SHIFT_SUPPORTED) /* reverse the effects of png_do_shift. This routine merely shifts the pixels back to their significant bits values. Thus, if you have 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_byte *row, +png_do_unshift(png_row_info *row_info, png_bytef *row, png_color_8 *sig_bits) { - if (row && row_info && sig_bits) + png_bytef *bp; + png_uint_16 value; + png_uint_32 i; + if (row && row_info && sig_bits && + row_info->color_type != PNG_COLOR_TYPE_PALETTE) { int shift[4]; int channels; @@ -783,9 +893,6 @@ png_do_unshift(png_row_info *row_info, png_byte *row, { case 2: { - png_byte *bp; - png_uint_32 i; - for (bp = row, i = 0; i < row_info->rowbytes; i++, bp++) @@ -797,9 +904,7 @@ png_do_unshift(png_row_info *row_info, png_byte *row, } case 4: { - png_byte *bp, mask; - png_uint_32 i; - + png_byte mask; mask = (png_byte)(((int)0xf0 >> shift[0]) & (int)0xf0) | ((int)0xf >> shift[0]); for (bp = row, i = 0; @@ -813,9 +918,6 @@ png_do_unshift(png_row_info *row_info, png_byte *row, } case 8: { - png_byte *bp; - png_uint_32 i; - for (bp = row, i = 0; i < row_info->width; i++) { @@ -830,10 +932,6 @@ png_do_unshift(png_row_info *row_info, png_byte *row, } case 16: { - png_byte *bp; - png_uint_16 value; - png_uint_32 i; - for (bp = row, i = 0; i < row_info->width; i++) { @@ -852,16 +950,17 @@ png_do_unshift(png_row_info *row_info, png_byte *row, } } } +#endif +#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_byte *row) +png_do_chop(png_row_info *row_info, png_bytef *row) { + png_bytef *sp, *dp; + png_uint_32 i; if (row && row_info && row_info->bit_depth == 16) { - png_byte *sp, *dp; - png_uint_32 i; - sp = row + 2; dp = row + 1; for (i = 1; i < row_info->width * row_info->channels; i++) @@ -875,64 +974,63 @@ png_do_chop(png_row_info *row_info, png_byte *row) row_info->rowbytes = row_info->width * row_info->channels; } } +#endif -/* add filler byte after rgb */ +#if defined(PNG_READ_FILLER_SUPPORTED) +/* add filler byte */ void -png_do_read_rgbx(png_row_info *row_info, png_byte *row) +png_do_read_filler(png_row_info *row_info, png_bytef *row, + png_byte filler, png_byte filler_loc) { + png_bytef *sp, *dp; + png_uint_32 i; if (row && row_info && row_info->color_type == 2 && row_info->bit_depth == 8) { - png_byte *sp, *dp; - png_uint_32 i; - - for (i = 1, sp = row + (png_size_t)row_info->width * 3, - dp = row + (png_size_t)row_info->width * 4; - i < row_info->width; - i++) + if (filler_loc == PNG_FILLER_AFTER) { - *(--dp) = 0xff; - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); + for (i = 1, sp = row + (png_size_t)row_info->width * 3, + dp = row + (png_size_t)row_info->width * 4; + i < row_info->width; + i++) + { + *(--dp) = filler; + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + } + *(--dp) = filler; + row_info->channels = 4; + row_info->pixel_depth = 32; + row_info->rowbytes = row_info->width * 4; + } + else + { + for (i = 0, sp = row + (png_size_t)row_info->width * 3, + dp = row + (png_size_t)row_info->width * 4; + i < row_info->width; + i++) + { + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = filler; + } + row_info->channels = 4; + row_info->pixel_depth = 32; + row_info->rowbytes = row_info->width * 4; } - *(--dp) = 0xff; - row_info->channels = 4; - row_info->pixel_depth = 32; - row_info->rowbytes = row_info->width * 4; - } -} - -/* add filler byte before rgb */ -void -png_do_read_xrgb(png_row_info *row_info, png_byte *row) -{ - if (row && row_info && row_info->color_type == 2 && - row_info->bit_depth == 8) - { - png_byte *sp, *dp; - png_uint_32 i; - - for (i = 0, sp = row + (png_size_t)row_info->width * 3, - dp = row + (png_size_t)row_info->width * 4; - i < row_info->width; - i++) - { - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = 0xff; - } - row_info->channels = 4; - row_info->pixel_depth = 32; - row_info->rowbytes = row_info->width * 4; } } +#endif +#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_byte *row) +png_do_gray_to_rgb(png_row_info *row_info, png_bytef *row) { + png_bytef *sp, *dp; + png_uint_32 i; if (row && row_info && row_info->bit_depth >= 8 && !(row_info->color_type & PNG_COLOR_MASK_COLOR)) { @@ -940,9 +1038,6 @@ png_do_gray_to_rgb(png_row_info *row_info, png_byte *row) { if (row_info->bit_depth == 8) { - png_byte *sp, *dp; - png_uint_32 i; - for (i = 0, sp = row + (png_size_t)row_info->width - 1, dp = row + (png_size_t)row_info->width * 3 - 1; i < row_info->width; @@ -956,9 +1051,6 @@ png_do_gray_to_rgb(png_row_info *row_info, png_byte *row) } else { - png_byte *sp, *dp; - png_uint_32 i; - for (i = 0, sp = row + (png_size_t)row_info->width * 2 - 1, dp = row + (png_size_t)row_info->width * 6 - 1; i < row_info->width; @@ -979,9 +1071,6 @@ png_do_gray_to_rgb(png_row_info *row_info, png_byte *row) { if (row_info->bit_depth == 8) { - png_byte *sp, *dp; - png_uint_32 i; - for (i = 0, sp = row + (png_size_t)row_info->width * 2 - 1, dp = row + (png_size_t)row_info->width * 4 - 1; i < row_info->width; @@ -996,9 +1085,6 @@ png_do_gray_to_rgb(png_row_info *row_info, png_byte *row) } else { - png_byte *sp, *dp; - png_uint_32 i; - for (i = 0, sp = row + (png_size_t)row_info->width * 4 - 1, dp = row + (png_size_t)row_info->width * 8 - 1; i < row_info->width; @@ -1024,6 +1110,7 @@ png_do_gray_to_rgb(png_row_info *row_info, png_byte *row) row_info->pixel_depth + 7) >> 3); } } +#endif /* build a grayscale palette. Palette is assumed to be 1 << bit_depth large of png_color. This lets grayscale images be treated as @@ -1071,6 +1158,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, int num_palette) @@ -1235,18 +1323,23 @@ png_correct_palette(png_struct *png_ptr, png_color *palette, } } } +#endif +#if defined(PNG_READ_BACKGROUND_SUPPORTED) /* replace any alpha or transparency with the supplied background color. 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_byte *row, +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_bytef *sp, *dp; + png_uint_32 i; + int shift; if (row && row_info && background && (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) || (row_info->color_type != PNG_COLOR_TYPE_PALETTE && @@ -1260,10 +1353,6 @@ png_do_background(png_row_info *row_info, png_byte *row, { case 1: { - png_byte *sp; - int shift; - png_uint_32 i; - sp = row; shift = 7; for (i = 0; i < row_info->width; i++) @@ -1286,10 +1375,6 @@ png_do_background(png_row_info *row_info, png_byte *row, } case 2: { - png_byte *sp; - int shift; - png_uint_32 i; - sp = row; shift = 6; for (i = 0; i < row_info->width; i++) @@ -1312,10 +1397,6 @@ png_do_background(png_row_info *row_info, png_byte *row, } case 4: { - png_byte *sp; - int shift; - png_uint_32 i; - sp = row + 1; shift = 4; for (i = 0; i < row_info->width; i++) @@ -1338,10 +1419,9 @@ png_do_background(png_row_info *row_info, png_byte *row, } case 8: { +#if defined(PNG_READ_GAMMA_SUPPORTED) if (gamma_table) { - png_byte *sp; - png_uint_32 i; for (i = 0, sp = row; i < row_info->width; i++, sp++) @@ -1357,10 +1437,8 @@ png_do_background(png_row_info *row_info, png_byte *row, } } else +#endif { - png_byte *sp; - png_uint_32 i; - for (i = 0, sp = row; i < row_info->width; i++, sp++) { @@ -1374,11 +1452,9 @@ png_do_background(png_row_info *row_info, png_byte *row, } case 16: { +#if defined(PNG_READ_GAMMA_SUPPORTED) if (gamma_16) { - png_byte *sp; - png_uint_32 i; - for (i = 0, sp = row; i < row_info->width; i++, sp += 2) { @@ -1401,10 +1477,8 @@ png_do_background(png_row_info *row_info, png_byte *row, } } else +#endif { - png_byte *sp; - png_uint_32 i; - for (i = 0, sp = row; i < row_info->width; i++, sp += 2) { @@ -1428,11 +1502,9 @@ png_do_background(png_row_info *row_info, png_byte *row, { if (row_info->bit_depth == 8) { +#if defined(PNG_READ_GAMMA_SUPPORTED) if (gamma_table) { - png_byte *sp; - png_uint_32 i; - for (i = 0, sp = row; i < row_info->width; i++, sp += 3) { @@ -1453,10 +1525,8 @@ png_do_background(png_row_info *row_info, png_byte *row, } } else +#endif { - png_byte *sp; - png_uint_32 i; - for (i = 0, sp = row; i < row_info->width; i++, sp += 3) { @@ -1473,11 +1543,9 @@ png_do_background(png_row_info *row_info, png_byte *row, } else if (row_info->bit_depth == 16) { +#if defined(PNG_READ_GAMMA_SUPPORTED) if (gamma_16) { - png_byte *sp; - png_uint_32 i; - for (i = 0, sp = row; i < row_info->width; i++, sp += 6) { @@ -1519,10 +1587,8 @@ png_do_background(png_row_info *row_info, png_byte *row, } } else +#endif { - png_byte *sp; - png_uint_32 i; - for (i = 0, sp = row; i < row_info->width; i++, sp += 6) { @@ -1556,11 +1622,9 @@ png_do_background(png_row_info *row_info, png_byte *row, { case 8: { +#if defined(PNG_READ_GAMMA_SUPPORTED) if (gamma_to_1 && gamma_from_1 && gamma_table) { - png_byte *sp, *dp; - png_uint_32 i; - for (i = 0, sp = row, dp = row; i < row_info->width; i++, sp += 2, dp++) @@ -1589,10 +1653,8 @@ png_do_background(png_row_info *row_info, png_byte *row, } } else +#endif { - png_byte *sp, *dp; - png_uint_32 i; - for (i = 0, sp = row, dp = row; i < row_info->width; i++, sp += 2, dp++) @@ -1620,11 +1682,9 @@ png_do_background(png_row_info *row_info, png_byte *row, } case 16: { +#if defined(PNG_READ_GAMMA_SUPPORTED) if (gamma_16 && gamma_16_from_1 && gamma_16_to_1) { - png_byte *sp, *dp; - png_uint_32 i; - for (i = 0, sp = row, dp = row; i < row_info->width; i++, sp += 4, dp += 2) @@ -1655,8 +1715,8 @@ png_do_background(png_row_info *row_info, png_byte *row, *(sp + 1) >> gamma_shift][*sp]; v = (g * (png_uint_32)a + (png_uint_32)background_1->gray * - (png_uint_32)((png_uint_16)65535 - a) + - (png_uint_16)32767) / (png_uint_16)65535; + (png_uint_32)((png_uint_16)65535L - a) + + (png_uint_16)32767) / (png_uint_16)65535L; v = gamma_16_from_1[(size_t)( (v & 0xff) >> gamma_shift)][(size_t)(v >> 8)]; *dp = (png_byte)((v >> 8) & 0xff); @@ -1665,10 +1725,8 @@ png_do_background(png_row_info *row_info, png_byte *row, } } else +#endif { - png_byte *sp, *dp; - png_uint_32 i; - for (i = 0, sp = row, dp = row; i < row_info->width; i++, sp += 4, dp += 2) @@ -1679,7 +1737,7 @@ png_do_background(png_row_info *row_info, png_byte *row, (png_uint_16)(*(sp + 3)); if (a == (png_uint_16)0xffff) { - memcpy(dp, sp, 2); + png_memcpy(dp, sp, 2); } else if (a == 0) { @@ -1694,8 +1752,8 @@ png_do_background(png_row_info *row_info, png_byte *row, (png_uint_32)(*(sp + 1)); v = (g * (png_uint_32)a + (png_uint_32)background_1->gray * - (png_uint_32)((png_uint_16)65535 - a) + - (png_uint_16)32767) / (png_uint_16)65535; + (png_uint_32)((png_uint_16)65535L - a) + + (png_uint_16)32767) / (png_uint_16)65535L; *dp = (png_byte)((v >> 8) & 0xff); *(dp + 1) = (png_byte)(v & 0xff); } @@ -1710,11 +1768,9 @@ png_do_background(png_row_info *row_info, png_byte *row, { if (row_info->bit_depth == 8) { +#if defined(PNG_READ_GAMMA_SUPPORTED) if (gamma_to_1 && gamma_from_1 && gamma_table) { - png_byte *sp, *dp; - png_uint_32 i; - for (i = 0, sp = row, dp = row; i < row_info->width; i++, sp += 4, dp += 3) @@ -1757,10 +1813,8 @@ png_do_background(png_row_info *row_info, png_byte *row, } } else +#endif { - png_byte *sp, *dp; - png_uint_32 i; - for (i = 0, sp = row, dp = row; i < row_info->width; i++, sp += 4, dp += 3) @@ -1797,11 +1851,9 @@ png_do_background(png_row_info *row_info, png_byte *row, } else if (row_info->bit_depth == 16) { +#if defined(PNG_READ_GAMMA_SUPPORTED) if (gamma_16 && gamma_16_from_1 && gamma_16_to_1) { - png_byte *sp, *dp; - png_uint_32 i; - for (i = 0, sp = row, dp = row; i < row_info->width; i++, sp += 8, dp += 6) @@ -1844,8 +1896,8 @@ png_do_background(png_row_info *row_info, png_byte *row, *(sp + 1) >> gamma_shift][*sp]; v = (v * (png_uint_32)a + (png_uint_32)background->red * - (png_uint_32)((png_uint_16)65535 - a) + - (png_uint_16)32767) / (png_uint_16)65535; + (png_uint_32)((png_uint_16)65535L - a) + + (png_uint_16)32767) / (png_uint_16)65535L; v = gamma_16_from_1[(size_t)( (v & 0xff) >> gamma_shift)][(size_t)(v >> 8)]; *dp = (png_byte)((v >> 8) & 0xff); @@ -1854,8 +1906,8 @@ png_do_background(png_row_info *row_info, png_byte *row, *(sp + 3) >> gamma_shift][*(sp + 2)]; v = (v * (png_uint_32)a + (png_uint_32)background->green * - (png_uint_32)((png_uint_16)65535 - a) + - (png_uint_16)32767) / (png_uint_16)65535; + (png_uint_32)((png_uint_16)65535L - a) + + (png_uint_16)32767) / (png_uint_16)65535L; v = gamma_16_from_1[(size_t)( (v & 0xff) >> gamma_shift)][(size_t)(v >> 8)]; *(dp + 2) = (png_byte)((v >> 8) & 0xff); @@ -1864,8 +1916,8 @@ png_do_background(png_row_info *row_info, png_byte *row, *(sp + 5) >> gamma_shift][*(sp + 4)]; v = (v * (png_uint_32)a + (png_uint_32)background->blue * - (png_uint_32)((png_uint_16)65535 - a) + - (png_uint_16)32767) / (png_uint_16)65535; + (png_uint_32)((png_uint_16)65535L - a) + + (png_uint_16)32767) / (png_uint_16)65535L; v = gamma_16_from_1[(size_t)( (v & 0xff) >> gamma_shift)][(size_t)(v >> 8)]; *(dp + 4) = (png_byte)((v >> 8) & 0xff); @@ -1874,10 +1926,8 @@ png_do_background(png_row_info *row_info, png_byte *row, } } else +#endif { - png_byte *sp, *dp; - png_uint_32 i; - for (i = 0, sp = row, dp = row; i < row_info->width; i++, sp += 8, dp += 6) @@ -1888,7 +1938,7 @@ png_do_background(png_row_info *row_info, png_byte *row, (png_uint_16)(*(sp + 7)); if (a == (png_uint_16)0xffff) { - memcpy(dp, sp, 6); + png_memcpy(dp, sp, 6); } else if (a == 0) { @@ -1911,20 +1961,20 @@ png_do_background(png_row_info *row_info, png_byte *row, (png_uint_32)(*(sp + 5)); v = (r * (png_uint_32)a + (png_uint_32)background->red * - (png_uint_32)((png_uint_32)65535 - a) + - (png_uint_32)32767) / (png_uint_32)65535; + (png_uint_32)((png_uint_32)65535L - a) + + (png_uint_32)32767) / (png_uint_32)65535L; *dp = (png_byte)((v >> 8) & 0xff); *(dp + 1) = (png_byte)(v & 0xff); v = (g * (png_uint_32)a + (png_uint_32)background->green * - (png_uint_32)((png_uint_32)65535 - a) + - (png_uint_32)32767) / (png_uint_32)65535; + (png_uint_32)((png_uint_32)65535L - a) + + (png_uint_32)32767) / (png_uint_32)65535L; *(dp + 2) = (png_byte)((v >> 8) & 0xff); *(dp + 3) = (png_byte)(v & 0xff); v = (b * (png_uint_32)a + (png_uint_32)background->blue * - (png_uint_32)((png_uint_32)65535 - a) + - (png_uint_32)32767) / (png_uint_32)65535; + (png_uint_32)((png_uint_32)65535L - a) + + (png_uint_32)32767) / (png_uint_32)65535L; *(dp + 4) = (png_byte)((v >> 8) & 0xff); *(dp + 5) = (png_byte)(v & 0xff); } @@ -1945,7 +1995,9 @@ png_do_background(png_row_info *row_info, png_byte *row, } } } +#endif +#if defined(PNG_READ_GAMMA_SUPPORTED) /* gamma correct the image, avoiding the alpha channel. Make sure 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, @@ -1953,10 +2005,12 @@ png_do_background(png_row_info *row_info, png_byte *row, 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_byte *row, +png_do_gamma(png_row_info *row_info, png_bytef *row, png_byte *gamma_table, png_uint_16 **gamma_16_table, int gamma_shift) { + png_bytef *sp; + png_uint_32 i; if (row && row_info && ((row_info->bit_depth <= 8 && gamma_table) || (row_info->bit_depth == 16 && gamma_16_table))) { @@ -1966,9 +2020,6 @@ png_do_gamma(png_row_info *row_info, png_byte *row, { if (row_info->bit_depth == 8) { - png_byte *sp; - png_uint_32 i; - for (i = 0, sp = row; i < row_info->width; i++) { @@ -1982,9 +2033,6 @@ png_do_gamma(png_row_info *row_info, png_byte *row, } else if (row_info->bit_depth == 16) { - png_byte *sp; - png_uint_32 i; - for (i = 0, sp = row; i < row_info->width; i++) { @@ -2013,9 +2061,6 @@ png_do_gamma(png_row_info *row_info, png_byte *row, { if (row_info->bit_depth == 8) { - png_byte *sp; - png_uint_32 i; - for (i = 0, sp = row; i < row_info->width; i++) { @@ -2030,9 +2075,6 @@ png_do_gamma(png_row_info *row_info, png_byte *row, } else if (row_info->bit_depth == 16) { - png_byte *sp; - png_uint_32 i; - for (i = 0, sp = row; i < row_info->width; i++) { @@ -2061,9 +2103,6 @@ png_do_gamma(png_row_info *row_info, png_byte *row, { if (row_info->bit_depth == 8) { - png_byte *sp; - png_uint_32 i; - for (i = 0, sp = row; i < row_info->width; i++) { @@ -2074,9 +2113,6 @@ png_do_gamma(png_row_info *row_info, png_byte *row, } else if (row_info->bit_depth == 16) { - png_byte *sp; - png_uint_32 i; - for (i = 0, sp = row; i < row_info->width; i++) { @@ -2095,9 +2131,6 @@ png_do_gamma(png_row_info *row_info, png_byte *row, { if (row_info->bit_depth == 8) { - png_byte *sp; - png_uint_32 i; - for (i = 0, sp = row; i < row_info->width; i++) { @@ -2107,9 +2140,6 @@ png_do_gamma(png_row_info *row_info, png_byte *row, } else if (row_info->bit_depth == 16) { - png_byte *sp; - png_uint_32 i; - for (i = 0, sp = row; i < row_info->width; i++) { @@ -2127,14 +2157,19 @@ png_do_gamma(png_row_info *row_info, png_byte *row, } } } +#endif +#if defined(PNG_READ_EXPAND_SUPPORTED) /* 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_byte *row, +png_do_expand_palette(png_row_info *row_info, png_bytef *row, png_color *palette, png_byte *trans, int num_trans) { + int shift, value; + png_bytef *sp, *dp; + png_uint_32 i; if (row && row_info && row_info->color_type == PNG_COLOR_TYPE_PALETTE) { if (row_info->bit_depth < 8) @@ -2143,11 +2178,6 @@ png_do_expand_palette(png_row_info *row_info, png_byte *row, { case 1: { - png_byte *sp; - png_byte *dp; - int shift; - png_uint_32 i; - sp = row + (png_size_t)((row_info->width - 1) >> 3); dp = row + (png_size_t)row_info->width - 1; shift = 7 - (int)((row_info->width + 7) & 7); @@ -2171,11 +2201,6 @@ png_do_expand_palette(png_row_info *row_info, png_byte *row, } case 2: { - png_byte *sp; - png_byte *dp; - int shift, value; - png_uint_32 i; - sp = row + (png_size_t)((row_info->width - 1) >> 2); dp = row + (png_size_t)row_info->width - 1; shift = (int)((3 - ((row_info->width + 3) & 3)) << 1); @@ -2197,11 +2222,6 @@ png_do_expand_palette(png_row_info *row_info, png_byte *row, } case 4: { - png_byte *sp; - png_byte *dp; - int shift, value; - png_uint_32 i; - sp = row + (png_size_t)((row_info->width - 1) >> 1); dp = row + (png_size_t)row_info->width - 1; shift = (int)((row_info->width & 1) << 2); @@ -2232,9 +2252,6 @@ png_do_expand_palette(png_row_info *row_info, png_byte *row, { if (trans) { - png_byte *sp, *dp; - png_uint_32 i; - sp = row + (png_size_t)row_info->width - 1; dp = row + (png_size_t)(row_info->width << 2) - 1; @@ -2257,9 +2274,6 @@ png_do_expand_palette(png_row_info *row_info, png_byte *row, } else { - png_byte *sp, *dp; - png_uint_32 i; - sp = row + (png_size_t)row_info->width - 1; dp = row + (png_size_t)(row_info->width * 3) - 1; @@ -2285,9 +2299,12 @@ png_do_expand_palette(png_row_info *row_info, png_byte *row, /* if the bit depth < 8, it is expanded to 8. Also, if the transparency value is supplied, an alpha channel is built. */ void -png_do_expand(png_row_info *row_info, png_byte *row, +png_do_expand(png_row_info *row_info, png_bytef *row, png_color_16 *trans_value) { + int shift, value; + png_bytef *sp, *dp; + png_uint_32 i; if (row && row_info) { if (row_info->color_type == PNG_COLOR_TYPE_GRAY && @@ -2297,11 +2314,6 @@ png_do_expand(png_row_info *row_info, png_byte *row, { case 1: { - png_byte *sp; - png_byte *dp; - int shift; - png_uint_32 i; - sp = row + (png_size_t)((row_info->width - 1) >> 3); dp = row + (png_size_t)row_info->width - 1; shift = 7 - (int)((row_info->width + 7) & 7); @@ -2325,11 +2337,6 @@ png_do_expand(png_row_info *row_info, png_byte *row, } case 2: { - png_byte *sp; - png_byte *dp; - int shift, value; - png_uint_32 i; - sp = row + (png_size_t)((row_info->width - 1) >> 2); dp = row + (png_size_t)row_info->width - 1; shift = (int)((3 - ((row_info->width + 3) & 3)) << 1); @@ -2352,11 +2359,6 @@ png_do_expand(png_row_info *row_info, png_byte *row, } case 4: { - png_byte *sp; - png_byte *dp; - int shift, value; - png_uint_32 i; - 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)) << 2); @@ -2385,9 +2387,6 @@ png_do_expand(png_row_info *row_info, png_byte *row, { if (row_info->bit_depth == 8) { - png_byte *sp, *dp; - png_uint_32 i; - sp = row + (png_size_t)row_info->width - 1; dp = row + (png_size_t)(row_info->width << 1) - 1; for (i = 0; i < row_info->width; i++) @@ -2401,9 +2400,6 @@ png_do_expand(png_row_info *row_info, png_byte *row, } else if (row_info->bit_depth == 16) { - png_byte *sp, *dp; - png_uint_32 i; - sp = row + (png_size_t)row_info->rowbytes - 1; dp = row + (png_size_t)(row_info->rowbytes << 1) - 1; for (i = 0; i < row_info->width; i++) @@ -2433,9 +2429,6 @@ png_do_expand(png_row_info *row_info, png_byte *row, { if (row_info->bit_depth == 8) { - png_byte *sp, *dp; - png_uint_32 i; - sp = row + (png_size_t)row_info->rowbytes - 1; dp = row + (png_size_t)(row_info->width << 2) - 1; for (i = 0; i < row_info->width; i++) @@ -2453,9 +2446,6 @@ png_do_expand(png_row_info *row_info, png_byte *row, } else if (row_info->bit_depth == 16) { - png_byte *sp, *dp; - png_uint_32 i; - sp = row + (png_size_t)row_info->rowbytes - 1; dp = row + (png_size_t)(row_info->width << 3) - 1; for (i = 0; i < row_info->width; i++) @@ -2491,20 +2481,21 @@ png_do_expand(png_row_info *row_info, png_byte *row, } } } +#endif +#if defined(PNG_READ_DITHER_SUPPORTED) void -png_do_dither(png_row_info *row_info, png_byte *row, +png_do_dither(png_row_info *row_info, png_bytef *row, png_byte *palette_lookup, png_byte *dither_lookup) { + png_bytef *sp, *dp; + png_uint_32 i; if (row && row_info) { if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup && row_info->bit_depth == 8) { int r, g, b, p; - png_byte *sp, *dp; - png_uint_32 i; - sp = row; dp = row; for (i = 0; i < row_info->width; i++) @@ -2541,9 +2532,6 @@ png_do_dither(png_row_info *row_info, png_byte *row, palette_lookup && row_info->bit_depth == 8) { int r, g, b, p; - png_byte *sp, *dp; - png_uint_32 i; - sp = row; dp = row; for (i = 0; i < row_info->width; i++) @@ -2573,9 +2561,6 @@ png_do_dither(png_row_info *row_info, png_byte *row, else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && dither_lookup && row_info->bit_depth == 8) { - png_byte *sp; - png_uint_32 i; - sp = row; for (i = 0; i < row_info->width; i++, sp++) { @@ -2584,7 +2569,9 @@ png_do_dither(png_row_info *row_info, png_byte *row, } } } +#endif +#if defined(PNG_READ_GAMMA_SUPPORTED) static int png_gamma_shift[] = {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0}; @@ -2707,7 +2694,7 @@ png_build_gamma_table(png_struct *png_ptr) while (last < (num << 8)) { png_ptr->gamma_16_table[(int)(last >> 8)][(int)(last & 0xff)] = - (png_uint_16)65535; + (png_uint_16)65535L; last++; } } @@ -2772,3 +2759,5 @@ png_build_gamma_table(png_struct *png_ptr) } } } +#endif + diff --git a/pngrutil.c b/pngrutil.c index 83a2973d..c1ab51dc 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -1,10 +1,10 @@ /* pngrutil.c - utilities to read a png file - libpng 1.0 beta 1 - version 0.71 + libpng 1.0 beta 2 - version 0.81 For conditions of distribution and use, see copyright notice in png.h Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. - June 26, 1995 + August 24, 1995 */ #define PNG_INTERNAL @@ -38,7 +38,7 @@ png_get_uint_16(png_byte *buf) /* read data, and run it through the crc */ void -png_crc_read(png_struct *png_ptr, png_byte *buf, png_uint_32 length) +png_crc_read(png_struct *png_ptr, png_bytef *buf, png_uint_32 length) { png_read_data(png_ptr, buf, length); png_calculate_crc(png_ptr, buf, length); @@ -179,6 +179,7 @@ png_handle_PLTE(png_struct *png_ptr, png_info *info, png_uint_32 length) png_read_PLTE(png_ptr, info, palette, num); } +#if defined(PNG_READ_gAMA_SUPPORTED) void png_handle_gAMA(png_struct *png_ptr, png_info *info, png_uint_32 length) { @@ -202,7 +203,9 @@ png_handle_gAMA(png_struct *png_ptr, png_info *info, png_uint_32 length) png_read_gAMA(png_ptr, info, gamma); png_ptr->gamma = gamma; } +#endif +#if defined(PNG_READ_sBIT_SUPPORTED) void png_handle_sBIT(png_struct *png_ptr, png_info *info, png_uint_32 length) { @@ -235,7 +238,9 @@ png_handle_sBIT(png_struct *png_ptr, png_info *info, png_uint_32 length) } 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) { @@ -284,7 +289,9 @@ png_handle_cHRM(png_struct *png_ptr, png_info *info, png_uint_32 length) png_read_cHRM(png_ptr, info, 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) { @@ -336,7 +343,9 @@ png_handle_tRNS(png_struct *png_ptr, png_info *info, png_uint_32 length) png_read_tRNS(png_ptr, info, png_ptr->trans, png_ptr->num_trans, &(png_ptr->trans_values)); } +#endif +#if defined(PNG_READ_bKGD_SUPPORTED) void png_handle_bKGD(png_struct *png_ptr, png_info *info, png_uint_32 length) { @@ -370,7 +379,9 @@ png_handle_bKGD(png_struct *png_ptr, png_info *info, png_uint_32 length) png_read_bKGD(png_ptr, info, &(png_ptr->background)); } +#endif +#if defined(PNG_READ_hIST_SUPPORTED) void png_handle_hIST(png_struct *png_ptr, png_info *info, png_uint_32 length) { @@ -393,7 +404,9 @@ png_handle_hIST(png_struct *png_ptr, png_info *info, png_uint_32 length) } png_read_hIST(png_ptr, info, png_ptr->hist); } +#endif +#if defined(PNG_READ_pHYs_SUPPORTED) void png_handle_pHYs(png_struct *png_ptr, png_info *info, png_uint_32 length) { @@ -414,7 +427,9 @@ png_handle_pHYs(png_struct *png_ptr, png_info *info, png_uint_32 length) unit_type = buf[8]; png_read_pHYs(png_ptr, info, res_x, res_y, unit_type); } +#endif +#if defined(PNG_READ_oFFs_SUPPORTED) void png_handle_oFFs(png_struct *png_ptr, png_info *info, png_uint_32 length) { @@ -435,7 +450,9 @@ png_handle_oFFs(png_struct *png_ptr, png_info *info, png_uint_32 length) unit_type = buf[8]; png_read_oFFs(png_ptr, info, offset_x, offset_y, unit_type); } +#endif +#if defined(PNG_READ_tIME_SUPPORTED) void png_handle_tIME(png_struct *png_ptr, png_info *info, png_uint_32 length) { @@ -459,17 +476,20 @@ png_handle_tIME(png_struct *png_ptr, png_info *info, png_uint_32 length) png_read_tIME(png_ptr, info, &mod_time); } +#endif +#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) { - char *key, *text; + charf *key; + charf *text; text = NULL; - key = (char *)png_large_malloc(png_ptr, length + 1); - png_crc_read(png_ptr, (png_byte *)key, length); + key = (charf *)png_large_malloc(png_ptr, length + 1); + png_crc_read(png_ptr, (png_bytef *)key, length); key[(png_size_t)length] = '\0'; for (text = key; *text; text++) @@ -480,19 +500,22 @@ png_handle_tEXt(png_struct *png_ptr, png_info *info, png_uint_32 length) png_read_tEXt(png_ptr, info, key, text, length - (text - key)); } +#endif +#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) { - char *key, *text; + charf *key; + charf *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_byte *)key, length); + png_crc_read(png_ptr, (png_bytef *)key, length); key[(png_size_t)length] = '\0'; for (text = key; *text; text++) @@ -515,7 +538,7 @@ png_handle_zTXt(png_struct *png_ptr, png_info *info, png_uint_32 length) text++; - png_ptr->zstream->next_in = (png_byte *)text; + png_ptr->zstream->next_in = (png_bytef *)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; @@ -542,23 +565,23 @@ png_handle_zTXt(png_struct *png_ptr, png_info *info, png_uint_32 length) text = png_malloc(png_ptr, png_ptr->zbuf_size - png_ptr->zstream->avail_out + key_size + 1); - memcpy(text + (png_size_t)key_size, png_ptr->zbuf, + png_memcpy(text + (png_size_t)key_size, png_ptr->zbuf, (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream->avail_out)); - memcpy(text, key, (png_size_t)key_size); + 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 { - char *tmp; + charf *tmp; tmp = text; text = png_large_malloc(png_ptr, text_size + png_ptr->zbuf_size - png_ptr->zstream->avail_out + 1); - memcpy(text, tmp, (png_size_t)text_size); + png_memcpy(text, tmp, (png_size_t)text_size); png_large_free(png_ptr, tmp); - memcpy(text + (png_size_t)text_size, png_ptr->zbuf, + 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'; @@ -595,6 +618,7 @@ png_handle_zTXt(png_struct *png_ptr, png_info *info, png_uint_32 length) png_read_zTXt(png_ptr, info, key, text, text_size, 0); } +#endif /* Combines the row recently read in with the previous row. This routine takes care of alpha and transparency if requested. @@ -608,12 +632,12 @@ 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_byte *row, +png_combine_row(png_struct *png_ptr, png_bytef *row, int mask) { if (mask == 0xff) { - memcpy(row, png_ptr->row_buf + 1, + png_memcpy(row, png_ptr->row_buf + 1, (png_size_t)((png_ptr->width * png_ptr->row_info.pixel_depth + 7) >> 3)); } @@ -623,8 +647,8 @@ png_combine_row(png_struct *png_ptr, png_byte *row, { case 1: { - png_byte *sp; - png_byte *dp; + png_bytef *sp; + png_bytef *dp; int m; int shift; png_uint_32 i; @@ -661,8 +685,8 @@ png_combine_row(png_struct *png_ptr, png_byte *row, } case 2: { - png_byte *sp; - png_byte *dp; + png_bytef *sp; + png_bytef *dp; int m; int shift; png_uint_32 i; @@ -698,8 +722,8 @@ png_combine_row(png_struct *png_ptr, png_byte *row, } case 4: { - png_byte *sp; - png_byte *dp; + png_bytef *sp; + png_bytef *dp; int m; int shift; png_uint_32 i; @@ -735,8 +759,8 @@ png_combine_row(png_struct *png_ptr, png_byte *row, } default: { - png_byte *sp; - png_byte *dp; + png_bytef *sp; + png_bytef *dp; png_uint_32 i; int pixel_bytes, m; @@ -749,7 +773,7 @@ png_combine_row(png_struct *png_ptr, png_byte *row, { if (m & mask) { - memcpy(dp, sp, pixel_bytes); + png_memcpy(dp, sp, pixel_bytes); } sp += pixel_bytes; @@ -766,8 +790,9 @@ png_combine_row(png_struct *png_ptr, png_byte *row, } } +#if defined(PNG_READ_INTERLACING_SUPPORTED) void -png_do_read_interlace(png_row_info *row_info, png_byte *row, int pass) +png_do_read_interlace(png_row_info *row_info, png_bytef *row, int pass) { if (row && row_info) { @@ -779,7 +804,7 @@ png_do_read_interlace(png_row_info *row_info, png_byte *row, int pass) { case 1: { - png_byte *sp, *dp; + png_bytef *sp, *dp; int sshift, dshift; png_byte v; png_uint_32 i; @@ -816,7 +841,7 @@ png_do_read_interlace(png_row_info *row_info, png_byte *row, int pass) } case 2: { - png_byte *sp, *dp; + png_bytef *sp, *dp; int sshift, dshift; png_byte v; png_uint_32 i, j; @@ -852,7 +877,7 @@ png_do_read_interlace(png_row_info *row_info, png_byte *row, int pass) } case 4: { - png_byte *sp, *dp; + png_bytef *sp, *dp; int sshift, dshift; png_byte v; png_uint_32 i; @@ -889,7 +914,7 @@ png_do_read_interlace(png_row_info *row_info, png_byte *row, int pass) } default: { - png_byte *sp, *dp; + png_bytef *sp, *dp; png_byte v[8]; png_uint_32 i; int j; @@ -901,10 +926,10 @@ png_do_read_interlace(png_row_info *row_info, png_byte *row, int pass) dp = row + (png_size_t)((final_width - 1) * pixel_bytes); for (i = row_info->width; i; i--) { - memcpy(v, sp, pixel_bytes); + png_memcpy(v, sp, pixel_bytes); for (j = 0; j < png_pass_inc[pass]; j++) { - memcpy(dp, v, pixel_bytes); + png_memcpy(dp, v, pixel_bytes); dp -= pixel_bytes; } sp -= pixel_bytes; @@ -917,10 +942,11 @@ png_do_read_interlace(png_row_info *row_info, png_byte *row, int pass) (png_uint_32)row_info->pixel_depth + 7) >> 3); } } +#endif void -png_read_filter_row(png_row_info *row_info, png_byte *row, - png_byte *prev_row, int filter) +png_read_filter_row(png_row_info *row_info, png_bytef *row, + png_bytef *prev_row, int filter) { switch (filter) { @@ -930,8 +956,8 @@ png_read_filter_row(png_row_info *row_info, png_byte *row, { png_uint_32 i; int bpp; - png_byte *rp; - png_byte *lp; + png_bytef *rp; + png_bytef *lp; bpp = (row_info->pixel_depth + 7) / 8; for (i = (png_uint_32)bpp, rp = row + bpp, lp = row; @@ -944,8 +970,8 @@ png_read_filter_row(png_row_info *row_info, png_byte *row, case 2: { png_uint_32 i; - png_byte *rp; - png_byte *pp; + png_bytef *rp; + png_bytef *pp; for (i = 0, rp = row, pp = prev_row; i < row_info->rowbytes; i++, rp++, pp++) @@ -958,9 +984,9 @@ png_read_filter_row(png_row_info *row_info, png_byte *row, { png_uint_32 i; int bpp; - png_byte *rp; - png_byte *pp; - png_byte *lp; + png_bytef *rp; + png_bytef *pp; + png_bytef *lp; bpp = (row_info->pixel_depth + 7) / 8; for (i = 0, rp = row, pp = prev_row; @@ -980,10 +1006,10 @@ png_read_filter_row(png_row_info *row_info, png_byte *row, { int bpp; png_uint_32 i; - png_byte *rp; - png_byte *pp; - png_byte *lp; - png_byte *cp; + png_bytef *rp; + png_bytef *pp; + png_bytef *lp; + png_bytef *cp; bpp = (row_info->pixel_depth + 7) / 8; for (i = 0, rp = row, pp = prev_row, @@ -1033,7 +1059,7 @@ png_read_finish_row(png_struct *png_ptr) if (png_ptr->interlaced) { png_ptr->row_number = 0; - memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1); + png_memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1); do { png_ptr->pass++; @@ -1054,6 +1080,8 @@ png_read_finish_row(png_struct *png_ptr) if (!(png_ptr->num_rows)) continue; } + if (png_ptr->transformations & PNG_INTERLACE) + break; } while (png_ptr->iwidth == 0); if (png_ptr->pass < 7) @@ -1157,11 +1185,14 @@ png_read_start_row(png_struct *png_ptr) max_pixel_depth = png_ptr->pixel_depth; +#if defined(PNG_READ_PACK_SUPPORTED) if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8) { max_pixel_depth = 8; } +#endif +#if defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_PACK_SUPPORTED) if (png_ptr->transformations & (PNG_EXPAND | PNG_PACK)) { if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) @@ -1187,13 +1218,17 @@ png_read_start_row(png_struct *png_ptr) } } } +#endif - if (png_ptr->transformations & PNG_RGBA) +#if defined(PNG_READ_FILLER_SUPPORTED) + if (png_ptr->transformations & (PNG_FILLER)) { if (max_pixel_depth < 32) max_pixel_depth = 32; } +#endif +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) if (png_ptr->transformations & PNG_GRAY_TO_RGB) { if ((png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) || @@ -1212,6 +1247,7 @@ png_read_start_row(png_struct *png_ptr) max_pixel_depth = 48; } } +#endif /* align the width on the next larger 8 pixels. Mainly used for interlacing */ @@ -1224,7 +1260,7 @@ png_read_start_row(png_struct *png_ptr) if (rowbytes > 65536L) png_error(png_ptr, "This image requires a row greater then 64KB"); #endif - png_ptr->row_buf = (png_byte *)png_large_malloc(png_ptr, rowbytes); + png_ptr->row_buf = (png_bytef *)png_large_malloc(png_ptr, rowbytes); #ifdef PNG_MAX_MALLOC_64K if (png_ptr->rowbytes + 1 > 65536L) @@ -1233,11 +1269,8 @@ png_read_start_row(png_struct *png_ptr) png_ptr->prev_row = png_large_malloc(png_ptr, png_ptr->rowbytes + 1); - memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1); + png_memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1); png_ptr->row_init = 1; - - /* if we have to do any modifications of values for the transformations, - do them here */ } diff --git a/pngtest.c b/pngtest.c index ba60b134..15697797 100644 --- a/pngtest.c +++ b/pngtest.c @@ -1,9 +1,9 @@ /* pngtest.c - a simple test program to test libpng - libpng 1.0 beta 1 - version 0.71 + libpng 1.0 beta 2 - version 0.81 For conditions of distribution and use, see copyright notice in png.h Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. - June 26, 1995 + August 24, 1995 */ #include @@ -38,19 +38,29 @@ int main() row_buf = (png_byte *)0; + fprintf(STDERR, "Testing libpng version %s\n", PNG_LIBPNG_VER_STRING); + + if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING)) + { + fprintf(STDERR, + "Warning: versions are different between png.h and png.c\n"); + fprintf(STDERR, " png.h version: %s\n", PNG_LIBPNG_VER_STRING); + fprintf(STDERR, " png.c version: %s\n\n", png_libpng_ver); + } + fpin = fopen(inname, "rb"); if (!fpin) { fprintf(STDERR, "Could not find input file %s\n", inname); - return -1; + return 1; } fpout = fopen(outname, "wb"); - if (!fpin) + if (!fpout) { fprintf(STDERR, "could not open output file %s\n", outname); fclose(fpin); - return -1; + return 1; } if (setjmp(read_ptr.jmpbuf)) @@ -58,7 +68,7 @@ int main() fprintf(STDERR, "libpng read error\n"); fclose(fpin); fclose(fpout); - return -1; + return 1; } if (setjmp(write_ptr.jmpbuf)) @@ -66,7 +76,7 @@ int main() fprintf(STDERR, "libpng write error\n"); fclose(fpin); fclose(fpout); - return -1; + return 1; } png_read_init(&read_ptr); @@ -96,7 +106,7 @@ int main() png_write_destroy(&write_ptr); fclose(fpin); fclose(fpout); - return -1; + return 1; } if (info_ptr.interlace_type) @@ -113,8 +123,8 @@ int main() { for (y = 0; y < info_ptr.height; y++) { - png_read_rows(&read_ptr, &row_buf, (png_byte **)0, 1); - png_write_rows(&write_ptr, &row_buf, 1); + png_read_rows(&read_ptr, (png_bytef **)&row_buf, (png_bytef **)0, 1); + png_write_rows(&write_ptr, (png_bytef **)&row_buf, 1); } } @@ -134,7 +144,7 @@ int main() if (!fpin) { fprintf(STDERR, "could not find file %s\n", inname); - return -1; + return 1; } fpout = fopen(outname, "rb"); @@ -142,7 +152,7 @@ int main() { fprintf(STDERR, "could not find file %s\n", outname); fclose(fpin); - return -1; + return 1; } while (1) @@ -157,7 +167,7 @@ int main() fprintf(STDERR, "files are of a different size\n"); fclose(fpin); fclose(fpout); - return -1; + return 1; } if (!num_in) @@ -168,7 +178,7 @@ int main() fprintf(STDERR, "files are different\n"); fclose(fpin); fclose(fpout); - return -1; + return 1; } } @@ -178,3 +188,4 @@ int main() return 0; } + diff --git a/pngtest.png b/pngtest.png index 67506634..43485ec2 100644 Binary files a/pngtest.png and b/pngtest.png differ diff --git a/pngtodo.txt b/pngtodo.txt index b52a3aaa..de444938 100644 --- a/pngtodo.txt +++ b/pngtodo.txt @@ -1,7 +1,13 @@ pngtodo.txt - list of things to do for libpng - allow user to #define out unused transformations - medium memory model support +for 0.9 + medium memory model + improved dithering? + +for 1.1 + push reader + +for 1.1 or later overlaying one image on top of another optional palette creation histogram creation @@ -9,14 +15,13 @@ pngtodo.txt - list of things to do for libpng cHRM transformation support for other chunks being defined (sCAl, the gIF series, and others that people come up with). - push reader pull writer better dithering keep up with public chunks other compression libraries more exotic interlace handling - better filtering + better filtering (counting huffman bits? filter type inertia?) C++ wrapper - other languages + other languages (pascal, for one) comments of > 64K diff --git a/pngtrans.c b/pngtrans.c index 02b00bcb..83a42829 100644 --- a/pngtrans.c +++ b/pngtrans.c @@ -2,22 +2,25 @@ /* pngtrans.c - transforms the data in a row routines used by both readers and writers - libpng 1.0 beta 1 - version 0.71 + libpng 1.0 beta 2 - version 0.81 For conditions of distribution and use, see copyright notice in png.h Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. - June 26, 1995 + August 24, 1995 */ #define PNG_INTERNAL #include "png.h" +#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_ptr->transformations |= PNG_BGR; } +#endif +#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) @@ -25,7 +28,9 @@ png_set_swap(png_struct *png_ptr) if (png_ptr->bit_depth == 16) png_ptr->transformations |= PNG_SWAP_BYTES; } +#endif +#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) /* turn on pixel packing */ void png_set_packing(png_struct *png_ptr) @@ -36,14 +41,18 @@ png_set_packing(png_struct *png_ptr) png_ptr->usr_bit_depth = 8; } } +#endif +#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_ptr->transformations |= PNG_SHIFT; png_ptr->shift = *true_bits; } +#endif +#if defined(PNG_READ_INTERLACING_SUPPORTED) || defined(PNG_WRITE_INTERLACING_SUPPORTED) int png_set_interlace_handling(png_struct *png_ptr) { @@ -55,25 +64,35 @@ png_set_interlace_handling(png_struct *png_ptr) return 1; } +#endif +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) void -png_set_rgbx(png_struct *png_ptr) +png_set_filler(png_struct *png_ptr, int filler, int filler_loc) { - png_ptr->transformations |= PNG_RGBA; + png_ptr->transformations |= PNG_FILLER; + png_ptr->filler = (png_byte)filler; + png_ptr->filler_loc = (png_byte)filler_loc; if (png_ptr->color_type == PNG_COLOR_TYPE_RGB && png_ptr->bit_depth == 8) png_ptr->usr_channels = 4; } +/* old functions kept around for compatability purposes */ +void +png_set_rgbx(png_struct *png_ptr) +{ + png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); +} + void png_set_xrgb(png_struct *png_ptr) { - png_ptr->transformations |= PNG_XRGB; - if (png_ptr->color_type == PNG_COLOR_TYPE_RGB && - png_ptr->bit_depth == 8) - png_ptr->usr_channels = 4; + png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE); } +#endif +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) void png_set_invert_mono(png_struct *png_ptr) { @@ -82,12 +101,12 @@ png_set_invert_mono(png_struct *png_ptr) /* invert monocrome grayscale data */ void -png_do_invert(png_row_info *row_info, png_byte *row) +png_do_invert(png_row_info *row_info, png_bytef *row) { if (row && row_info && row_info->bit_depth == 1 && row_info->color_type == PNG_COLOR_TYPE_GRAY) { - png_byte *rp; + png_bytef *rp; png_uint_32 i; for (i = 0, rp = row; @@ -98,14 +117,17 @@ png_do_invert(png_row_info *row_info, png_byte *row) } } } +#endif +#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_byte *row) +png_do_swap(png_row_info *row_info, png_bytef *row) { if (row && row_info && row_info->bit_depth == 16) { - png_byte *rp, t; + png_bytef *rp; + png_byte t; png_uint_32 i; for (i = 0, rp = row; @@ -118,16 +140,19 @@ png_do_swap(png_row_info *row_info, png_byte *row) } } } +#endif +#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_byte *row) +png_do_bgr(png_row_info *row_info, png_bytef *row) { if (row && row_info && (row_info->color_type & 2)) { if (row_info->color_type == 2 && row_info->bit_depth == 8) { - png_byte *rp, t; + png_bytef *rp; + png_byte t; png_uint_32 i; for (i = 0, rp = row; @@ -141,7 +166,8 @@ png_do_bgr(png_row_info *row_info, png_byte *row) } else if (row_info->color_type == 6 && row_info->bit_depth == 8) { - png_byte *rp, t; + png_bytef *rp; + png_byte t; png_uint_32 i; for (i = 0, rp = row; @@ -155,7 +181,8 @@ png_do_bgr(png_row_info *row_info, png_byte *row) } else if (row_info->color_type == 2 && row_info->bit_depth == 16) { - png_byte *rp, t[2]; + png_bytef *rp; + png_byte t[2]; png_uint_32 i; for (i = 0, rp = row; @@ -172,7 +199,8 @@ png_do_bgr(png_row_info *row_info, png_byte *row) } else if (row_info->color_type == 6 && row_info->bit_depth == 16) { - png_byte *rp, t[2]; + png_bytef *rp; + png_byte t[2]; png_uint_32 i; for (i = 0, rp = row; @@ -189,4 +217,5 @@ png_do_bgr(png_row_info *row_info, png_byte *row) } } } +#endif diff --git a/pngwrite.c b/pngwrite.c index ac7e22f6..2e2e3718 100644 --- a/pngwrite.c +++ b/pngwrite.c @@ -1,10 +1,10 @@ /* pngwrite.c - general routines to write a png file - libpng 1.0 beta 1 - version 0.71 + libpng 1.0 beta 2 - version 0.81 For conditions of distribution and use, see copyright notice in png.h Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. - June 26, 1995 + August 24, 1995 */ /* get internal access to png.h */ @@ -30,34 +30,53 @@ png_write_info(png_struct *png_ptr, png_info *info) info->interlace_type); /* the rest of these check to see if the valid field has the appropriate flag set, and if it does, writes the chunk. */ +#if defined(PNG_WRITE_gAMA_SUPPORTED) if (info->valid & PNG_INFO_gAMA) png_write_gAMA(png_ptr, info->gamma); +#endif +#if defined(PNG_WRITE_sBIT_SUPPORTED) if (info->valid & PNG_INFO_sBIT) png_write_sBIT(png_ptr, &(info->sig_bit), info->color_type); +#endif +#if defined(PNG_WRITE_cHRM_SUPPORTED) if (info->valid & PNG_INFO_cHRM) png_write_cHRM(png_ptr, info->x_white, info->y_white, info->x_red, info->y_red, info->x_green, info->y_green, info->x_blue, info->y_blue); +#endif if (info->valid & PNG_INFO_PLTE) png_write_PLTE(png_ptr, info->palette, info->num_palette); +#if defined(PNG_WRITE_tRNS_SUPPORTED) if (info->valid & PNG_INFO_tRNS) png_write_tRNS(png_ptr, info->trans, &(info->trans_values), info->num_trans, info->color_type); +#endif +#if defined(PNG_WRITE_bKGD_SUPPORTED) 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) { int i; /* local counter */ @@ -68,19 +87,24 @@ png_write_info(png_struct *png_ptr, png_info *info) /* if chunk is compressed */ if (info->text[i].compression >= 0) { +#if defined(PNG_WRITE_zTXt_SUPPORTED) /* 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); +#endif } else { +#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); +#endif } } } +#endif } /* writes the end of the png file. If you don't want to write comments or @@ -93,9 +117,12 @@ png_write_end(png_struct *png_ptr, png_info *info) /* see if user wants us to write information chunks */ if (info) { +#if defined(PNG_WRITE_tIME_SUPPORTED) /* check to see if user has supplied a time chunk */ 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) { @@ -107,32 +134,30 @@ png_write_end(png_struct *png_ptr, png_info *info) /* check to see if comment is to be compressed */ if (info->text[i].compression >= 0) { +#if defined(PNG_WRITE_zTXt_SUPPORTED) /* 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); +#endif } else { +#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); +#endif } } } +#endif } /* write end of png file */ png_write_IEND(png_ptr); } -/* initialize the info structure */ -void -png_info_init(png_info *info) -{ - /* set everything to 0 */ - memset(info, 0, sizeof (png_info)); -} - +#if defined(PNG_WRITE_tIME_SUPPORTED) void png_convert_from_struct_tm(png_time *ptime, struct tm *ttime) { @@ -152,6 +177,7 @@ png_convert_from_time_t(png_time *ptime, time_t ttime) tbuf = gmtime(&ttime); png_convert_from_struct_tm(ptime, tbuf); } +#endif /* initialize png structure, and allocate any memory needed */ void @@ -160,23 +186,15 @@ png_write_init(png_struct *png_ptr) jmp_buf tmp_jmp; /* to save current jump buffer */ /* save jump buffer */ - memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf)); + png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf)); /* reset all variables to 0 */ - memset(png_ptr, 0, sizeof (png_struct)); + png_memset(png_ptr, 0, sizeof (png_struct)); /* restore jump buffer */ - memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf)); + png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf)); /* initialize zbuf - compression buffer */ png_ptr->zbuf_size = PNG_ZBUF_SIZE; png_ptr->zbuf = png_large_malloc(png_ptr, png_ptr->zbuf_size); - /* initialize zlib */ - png_ptr->zstream = &(png_ptr->zstream_struct); - png_ptr->zstream->zalloc = png_zalloc; - png_ptr->zstream->zfree = png_zfree; - png_ptr->zstream->opaque = (voidp)png_ptr; - deflateInit(png_ptr->zstream, Z_BEST_COMPRESSION); - png_ptr->zstream->next_out = png_ptr->zbuf; - png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size; } /* write a few rows of image data. If the image is interlaced, @@ -184,11 +202,11 @@ png_write_init(png_struct *png_ptr) have called png_set_interlace_handling(), you will have to "write" the image seven times */ void -png_write_rows(png_struct *png_ptr, png_byte **row, +png_write_rows(png_struct *png_ptr, png_bytef **row, png_uint_32 num_rows) { png_uint_32 i; /* row counter */ - png_byte **rp; /* row pointer */ + png_bytef **rp; /* row pointer */ /* loop through the rows */ for (i = 0, rp = row; i < num_rows; i++, rp++) @@ -200,11 +218,11 @@ png_write_rows(png_struct *png_ptr, png_byte **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_byte **image) +png_write_image(png_struct *png_ptr, png_bytef **image) { png_uint_32 i; /* row index */ int pass, num_pass; /* pass variables */ - png_byte **rp; /* points to current row */ + png_bytef **rp; /* points to current row */ /* intialize interlace handling. If image is not interlaced, this will set pass to 1 */ @@ -222,7 +240,7 @@ png_write_image(png_struct *png_ptr, png_byte **image) /* write a row of image data */ void -png_write_row(png_struct *png_ptr, png_byte *row) +png_write_row(png_struct *png_ptr, png_bytef *row) { /* initialize transformations and other stuff if first time */ if (png_ptr->row_number == 0 && png_ptr->pass == 0) @@ -230,6 +248,7 @@ png_write_row(png_struct *png_ptr, png_byte *row) png_write_start_row(png_ptr); } +#if defined(PNG_WRITE_INTERLACING_SUPPORTED) /* if interlaced and not interested in row, return */ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) { @@ -286,6 +305,7 @@ png_write_row(png_struct *png_ptr, png_byte *row) break; } } +#endif /* set up row info for transformations */ png_ptr->row_info.color_type = png_ptr->color_type; @@ -298,8 +318,9 @@ png_write_row(png_struct *png_ptr, png_byte *row) (png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3); /* copy users row into buffer, leaving room for filter byte */ - memcpy(png_ptr->row_buf + 1, row, (png_size_t)png_ptr->row_info.rowbytes); + png_memcpy(png_ptr->row_buf + 1, row, (png_size_t)png_ptr->row_info.rowbytes); +#if defined(PNG_WRITE_INTERLACING_SUPPORTED) /* handle interlacing */ if (png_ptr->interlaced && png_ptr->pass < 6 && (png_ptr->transformations & PNG_INTERLACE)) @@ -313,16 +334,17 @@ png_write_row(png_struct *png_ptr, png_byte *row) return; } } +#endif /* handle other transformations */ if (png_ptr->transformations) png_do_write_transformations(png_ptr); /* filter rows that have been proved to help */ - if (png_ptr->bit_depth >= 8 && png_ptr->color_type != 3) + if (png_ptr->do_filter) { /* save row to previous row */ - 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 */ @@ -331,7 +353,7 @@ png_write_row(png_struct *png_ptr, png_byte *row) /* trade saved pointer and prev pointer so next row references are correctly */ { /* scope limiter */ - png_byte *tptr; + png_bytef *tptr; tptr = png_ptr->prev_row; png_ptr->prev_row = png_ptr->save_row; @@ -345,17 +367,6 @@ png_write_row(png_struct *png_ptr, png_byte *row) /* 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; - -#ifdef zlibinout -/* temp zlib problem */ -{ - extern FILE *fpzlibin; - - fwrite(png_ptr->row_buf, 1, png_ptr->zstream->avail_in, fpzlibin); -} -/* end temp zlib problem */ -#endif - /* repeat until we have compressed all the data */ do { @@ -401,8 +412,49 @@ png_write_destroy(png_struct *png_ptr) png_large_free(png_ptr, png_ptr->prev_row); png_large_free(png_ptr, png_ptr->save_row); /* reset structure */ - memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf)); - memset(png_ptr, 0, sizeof (png_struct)); - memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf)); + 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)); +} +void +png_set_filtering(png_struct *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_ptr->zlib_custom_level = 1; + png_ptr->zlib_level = level; +} + +void +png_set_compression_mem_level(png_struct *png_ptr, int mem_level) +{ + png_ptr->zlib_custom_mem_level = 1; + png_ptr->zlib_mem_level = mem_level; +} + +void +png_set_compression_strategy(png_struct *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_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_ptr->zlib_custom_method = 1; + png_ptr->zlib_method = method; } diff --git a/pngwtran.c b/pngwtran.c index 7423ade3..acbd0c21 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 1 - version 0.71 + libpng 1.0 beta 2 - version 0.81 For conditions of distribution and use, see copyright notice in png.h Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. - June 26, 1995 + August 24, 1995 */ #define PNG_INTERNAL @@ -15,29 +15,41 @@ void png_do_write_transformations(png_struct *png_ptr) { +#if defined(PNG_WRITE_FILLER_SUPPORTED) if (png_ptr->transformations & PNG_RGBA) - png_do_write_rgbx(&(png_ptr->row_info), png_ptr->row_buf + 1); - if (png_ptr->transformations & PNG_XRGB) - png_do_write_xrgb(&(png_ptr->row_info), png_ptr->row_buf + 1); + png_do_write_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, + png_ptr->filler_loc); +#endif +#if defined(PNG_WRITE_PACK_SUPPORTED) if (png_ptr->transformations & PNG_PACK) png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr->bit_depth); +#endif +#if defined(PNG_WRITE_SHIFT_SUPPORTED) if (png_ptr->transformations & PNG_SHIFT) png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1, &(png_ptr->shift)); +#endif +#if defined(PNG_WRITE_SWAP_SUPPORTED) if (png_ptr->transformations & PNG_SWAP_BYTES) png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif +#if defined(PNG_WRITE_BGR_SUPPORTED) if (png_ptr->transformations & PNG_BGR) png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif +#if defined(PNG_WRITE_INVERT_SUPPORTED) if (png_ptr->transformations & PNG_INVERT_MONO) png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif } +#if defined(PNG_WRITE_PACK_SUPPORTED) /* pack pixels into bytes. Pass the true bit depth in bit_depth. The 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_byte *row, png_byte bit_depth) +png_do_pack(png_row_info *row_info, png_bytef *row, png_byte bit_depth) { if (row_info && row && row_info->bit_depth == 8 && row_info->channels == 1) @@ -46,8 +58,8 @@ png_do_pack(png_row_info *row_info, png_byte *row, png_byte bit_depth) { case 1: { - png_byte *sp; - png_byte *dp; + png_bytef *sp; + png_bytef *dp; int mask; png_int_32 i; int v; @@ -77,8 +89,8 @@ png_do_pack(png_row_info *row_info, png_byte *row, png_byte bit_depth) } case 2: { - png_byte *sp; - png_byte *dp; + png_bytef *sp; + png_bytef *dp; int shift; png_int_32 i; int v; @@ -109,8 +121,8 @@ png_do_pack(png_row_info *row_info, png_byte *row, png_byte bit_depth) } case 4: { - png_byte *sp; - png_byte *dp; + png_bytef *sp; + png_bytef *dp; int shift; png_int_32 i; int v; @@ -148,7 +160,9 @@ png_do_pack(png_row_info *row_info, png_byte *row, png_byte bit_depth) ((row_info->width * row_info->pixel_depth + 7) >> 3); } } +#endif +#if defined(PNG_WRITE_SHIFT_SUPPORTED) /* shift pixel values to take advantage of whole range. Pass the true number of bits in bit_depth. The row should be packed according to row_info->bit_depth. Thus, if you had a row of @@ -156,7 +170,7 @@ png_do_pack(png_row_info *row_info, png_byte *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_byte *row, png_color_8 *bit_depth) +png_do_shift(png_row_info *row_info, png_bytef *row, png_color_8 *bit_depth) { if (row && row_info && row_info->color_type != PNG_COLOR_TYPE_PALETTE) @@ -193,7 +207,7 @@ png_do_shift(png_row_info *row_info, png_byte *row, png_color_8 *bit_depth) /* with low row dephts, could only be grayscale, so one channel */ if (row_info->bit_depth < 8) { - png_byte *bp; + png_bytef *bp; png_uint_32 i; int j; png_byte mask; @@ -222,7 +236,7 @@ png_do_shift(png_row_info *row_info, png_byte *row, png_color_8 *bit_depth) } else if (row_info->bit_depth == 8) { - png_byte *bp; + png_bytef *bp; png_uint_32 i; int j; @@ -248,7 +262,7 @@ png_do_shift(png_row_info *row_info, png_byte *row, png_color_8 *bit_depth) } else { - png_byte *bp; + png_bytef *bp; png_uint_32 i; int j; @@ -278,54 +292,54 @@ png_do_shift(png_row_info *row_info, png_byte *row, png_color_8 *bit_depth) } } } +#endif -/* remove filler byte after rgb */ +#ifdef PNG_WRITE_FILLER_SUPPORTED +/* remove filler byte */ void -png_do_write_rgbx(png_row_info *row_info, png_byte *row) +png_do_write_filler(png_row_info *row_info, png_bytef *row, + png_byte filler_loc) { if (row && row_info && row_info->color_type == PNG_COLOR_TYPE_RGB && row_info->bit_depth == 8) { - png_byte *sp, *dp; - png_uint_32 i; - - for (i = 1, sp = row + 4, dp = row + 3; - i < row_info->width; - i++) + if (filler_loc == PNG_FILLER_AFTER) { - *dp++ = *sp++; - *dp++ = *sp++; - *dp++ = *sp++; - sp++; + png_bytef *sp, *dp; + png_uint_32 i; + + for (i = 1, sp = row + 4, dp = row + 3; + i < row_info->width; + i++) + { + *dp++ = *sp++; + *dp++ = *sp++; + *dp++ = *sp++; + sp++; + } + row_info->channels = 3; + row_info->pixel_depth = 24; + row_info->rowbytes = row_info->width * 3; + } + else + { + png_bytef *sp, *dp; + png_uint_32 i; + + for (i = 1, sp = row + 4, dp = row + 3; + i < row_info->width; + i++) + { + sp++; + *dp++ = *sp++; + *dp++ = *sp++; + *dp++ = *sp++; + } + row_info->channels = 3; + row_info->pixel_depth = 24; + row_info->rowbytes = row_info->width * 3; } - row_info->channels = 3; - row_info->pixel_depth = 24; - row_info->rowbytes = row_info->width * 3; - } -} - -/* remove filler byte before rgb */ -void -png_do_write_xrgb(png_row_info *row_info, png_byte *row) -{ - if (row && row_info && row_info->color_type == PNG_COLOR_TYPE_RGB && - row_info->bit_depth == 8) - { - png_byte *sp, *dp; - png_uint_32 i; - - for (i = 0, sp = row, dp = row; - i < row_info->width; - i++) - { - sp++; - *dp++ = *sp++; - *dp++ = *sp++; - *dp++ = *sp++; - } - row_info->channels = 3; - row_info->pixel_depth = 24; - row_info->rowbytes = row_info->width * 3; } } +#endif diff --git a/pngwutil.c b/pngwutil.c index 89743d75..f92ca1f7 100644 --- a/pngwutil.c +++ b/pngwutil.c @@ -1,10 +1,10 @@ /* pngwutil.c - utilities to write a png file - libpng 1.0 beta 1 - version 0.71 + libpng 1.0 beta 2 - version 0.81 For conditions of distribution and use, see copyright notice in png.h Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc. - June 26, 1995 + August 24, 1995 */ #define PNG_INTERNAL #include "png.h" @@ -63,7 +63,7 @@ png_write_uint_16(png_struct *png_ptr, png_uint_16 i) functions instead. */ void png_write_chunk(png_struct *png_ptr, png_byte *type, - png_byte *data, png_uint_32 length) + png_bytef *data, png_uint_32 length) { /* write length */ png_write_uint_32(png_ptr, length); @@ -103,7 +103,7 @@ 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_byte *data, png_uint_32 length) +png_write_chunk_data(png_struct *png_ptr, png_bytef *data, png_uint_32 length) { /* write the data, and run the crc over it */ if (length) @@ -178,7 +178,43 @@ png_write_IHDR(png_struct *png_ptr, png_uint_32 width, png_uint_32 height, 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->zalloc = png_zalloc; + png_ptr->zstream->zfree = png_zfree; + png_ptr->zstream->opaque = (voidp)png_ptr; + if (!png_ptr->do_custom_filter) + { + if (png_ptr->color_type == 3 || png_ptr->bit_depth < 8) + png_ptr->do_filter = 0; + else + png_ptr->do_filter = 1; + } + if (!png_ptr->zlib_custom_strategy) + { + if (png_ptr->do_filter) + png_ptr->zlib_strategy = Z_FILTERED; + else + png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY; + } + if (!png_ptr->zlib_custom_level) + png_ptr->zlib_level = Z_DEFAULT_COMPRESSION; + if (!png_ptr->zlib_custom_mem_level) + png_ptr->zlib_mem_level = 8; + if (!png_ptr->zlib_custom_window_bits) + png_ptr->zlib_window_bits = 15; + if (!png_ptr->zlib_custom_method) + png_ptr->zlib_method = 8; + deflateInit2(png_ptr->zstream, png_ptr->zlib_level, + png_ptr->zlib_method, + png_ptr->zlib_window_bits, + png_ptr->zlib_mem_level, + png_ptr->zlib_strategy); + png_ptr->zstream->next_out = png_ptr->zbuf; + png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size; + } /* write the palette. We are careful not to trust png_color to be in the @@ -206,18 +242,8 @@ 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_byte *data, png_uint_32 length) +png_write_IDAT(png_struct *png_ptr, png_bytef *data, png_uint_32 length) { -#ifdef zlibinout -/* temp zlib problem */ -{ - extern FILE *fpzlibout; - - fwrite(data, 1, length, fpzlibout); -} -/* end temp zlib problem */ -#endif - png_write_chunk(png_ptr, png_IDAT, data, length); } @@ -228,6 +254,7 @@ png_write_IEND(png_struct *png_ptr) png_write_chunk(png_ptr, png_IEND, NULL, (png_uint_32)0); } +#if defined(PNG_WRITE_gAMA_SUPPORTED) /* write a gAMA chunk */ void png_write_gAMA(png_struct *png_ptr, float gamma) @@ -240,7 +267,9 @@ png_write_gAMA(png_struct *png_ptr, float gamma) png_save_uint_32(buf, igamma); png_write_chunk(png_ptr, png_gAMA, buf, (png_uint_32)4); } +#endif +#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) @@ -269,7 +298,9 @@ png_write_sBIT(png_struct *png_ptr, png_color_8 *sbit, int color_type) png_write_chunk(png_ptr, png_sBIT, buf, (png_uint_32)size); } +#endif +#if defined(PNG_WRITE_cHRM_SUPPORTED) /* write the cHRM chunk */ void png_write_cHRM(png_struct *png_ptr, float white_x, float white_y, @@ -298,7 +329,9 @@ png_write_cHRM(png_struct *png_ptr, float white_x, float white_y, png_save_uint_32(buf + 28, itemp); png_write_chunk(png_ptr, png_cHRM, buf, (png_uint_32)32); } +#endif +#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, @@ -326,7 +359,9 @@ png_write_tRNS(png_struct *png_ptr, png_byte *trans, png_color_16 *tran, png_write_chunk(png_ptr, png_tRNS, buf, (png_uint_32)6); } } +#endif +#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) @@ -351,7 +386,9 @@ 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)2); } } +#endif +#if defined(PNG_WRITE_hIST_SUPPORTED) /* write the histogram */ void png_write_hIST(png_struct *png_ptr, png_uint_16 *hist, int number) @@ -367,38 +404,42 @@ png_write_hIST(png_struct *png_ptr, png_uint_16 *hist, int number) } png_write_chunk_end(png_ptr); } +#endif +#if defined(PNG_WRITE_tEXt_SUPPORTED) /* write a tEXt chunk */ void -png_write_tEXt(png_struct *png_ptr, char *key, char *text, +png_write_tEXt(png_struct *png_ptr, charf *key, charf *text, png_uint_32 text_len) { int key_len; - key_len = strlen(key); + 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)); /* key has an 0 at the end. How nice */ - png_write_chunk_data(png_ptr, (png_byte *)key, (png_uint_32)(key_len + 1)); + png_write_chunk_data(png_ptr, (png_bytef *)key, (png_uint_32)(key_len + 1)); if (text && text_len) - png_write_chunk_data(png_ptr, (png_byte *)text, (png_uint_32)text_len); + png_write_chunk_data(png_ptr, (png_bytef *)text, (png_uint_32)text_len); png_write_chunk_end(png_ptr); } +#endif +#if defined(PNG_WRITE_zTXt_SUPPORTED) /* write a compressed chunk */ void -png_write_zTXt(png_struct *png_ptr, char *key, char *text, +png_write_zTXt(png_struct *png_ptr, charf *key, charf *text, png_uint_32 text_len, int compression) { int key_len; char buf[1]; int i, ret; - char **output_ptr = NULL; /* array of pointers to output */ + charf **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 */ - key_len = strlen(key); + key_len = png_strlen(key); /* we can't write the chunk until we find out how much data we have, which means we need to run the compresser first, and save the @@ -408,9 +449,9 @@ png_write_zTXt(png_struct *png_ptr, char *key, char *text, /* set up the compression buffers */ png_ptr->zstream->avail_in = (uInt)text_len; - png_ptr->zstream->next_in = (Byte *)text; + png_ptr->zstream->next_in = (Bytef *)text; png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size; - png_ptr->zstream->next_out = (Byte *)png_ptr->zbuf; + png_ptr->zstream->next_out = (Bytef *)png_ptr->zbuf; /* this is the same compression loop as in png_write_row() */ do @@ -431,10 +472,14 @@ png_write_zTXt(png_struct *png_ptr, char *key, char *text, /* 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 *)); + max_output_ptr * sizeof (char *), + old_max * sizeof (char *)); else output_ptr = png_malloc(png_ptr, max_output_ptr * sizeof (char *)); @@ -443,7 +488,7 @@ png_write_zTXt(png_struct *png_ptr, char *key, char *text, /* save the data */ output_ptr[num_output_ptr] = png_large_malloc(png_ptr, png_ptr->zbuf_size); - 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++; @@ -474,10 +519,14 @@ png_write_zTXt(png_struct *png_ptr, char *key, char *text, /* check to make sure our 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 *)); + max_output_ptr * sizeof (char *), + old_max * sizeof (char *)); else output_ptr = png_malloc(png_ptr, max_output_ptr * sizeof (char *)); @@ -486,7 +535,7 @@ png_write_zTXt(png_struct *png_ptr, char *key, char *text, /* save off the data */ output_ptr[num_output_ptr] = png_large_malloc(png_ptr, png_ptr->zbuf_size); - 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++; @@ -506,7 +555,7 @@ png_write_zTXt(png_struct *png_ptr, char *key, char *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_byte *)key, (png_uint_32)(key_len + 1)); + png_write_chunk_data(png_ptr, (png_bytef *)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); @@ -514,7 +563,7 @@ png_write_zTXt(png_struct *png_ptr, char *key, char *text, /* write saved output buffers, if any */ for (i = 0; i < num_output_ptr; i++) { - png_write_chunk_data(png_ptr, (png_byte *)output_ptr[i], png_ptr->zbuf_size); + png_write_chunk_data(png_ptr, (png_bytef *)output_ptr[i], png_ptr->zbuf_size); png_large_free(png_ptr, output_ptr[i]); } if (max_output_ptr) @@ -527,11 +576,11 @@ png_write_zTXt(png_struct *png_ptr, char *key, char *text, png_write_chunk_end(png_ptr); /* reset zlib for another zTXt or the image data */ -/* deflateReset(png_ptr->zstream); */ - deflateEnd(png_ptr->zstream); - deflateInit(png_ptr->zstream, -1); + 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, @@ -546,7 +595,9 @@ png_write_pHYs(png_struct *png_ptr, png_uint_32 x_pixels_per_unit, png_write_chunk(png_ptr, png_pHYs, buf, (png_uint_32)9); } +#endif +#if defined(PNG_WRITE_oFFs_SUPPORTED) /* write the oFFs chunk */ void png_write_oFFs(png_struct *png_ptr, png_uint_32 x_offset, @@ -561,9 +612,11 @@ png_write_oFFs(png_struct *png_ptr, png_uint_32 x_offset, png_write_chunk(png_ptr, png_oFFs, buf, (png_uint_32)9); } +#endif -/* two time chunks are given. This chunk assumes you have a gmtime() - function. If you don't have that, use the other tIME function */ +#if defined(PNG_WRITE_tIME_SUPPORTED) +/* 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) { @@ -578,25 +631,26 @@ png_write_tIME(png_struct *png_ptr, png_time *mod_time) png_write_chunk(png_ptr, png_tIME, buf, (png_uint_32)7); } +#endif /* initializes the row writing capability of libpng */ void png_write_start_row(png_struct *png_ptr) { /* set up row buffer */ - png_ptr->row_buf = (png_byte *)png_large_malloc(png_ptr, + png_ptr->row_buf = (png_bytef *)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); /* set up filtering buffers, if filtering */ - if (png_ptr->bit_depth >= 8 && png_ptr->color_type != 3) + if (png_ptr->do_filter) { - png_ptr->prev_row = (png_byte *)png_large_malloc(png_ptr, + png_ptr->prev_row = (png_bytef *)png_large_malloc(png_ptr, png_ptr->rowbytes + 1); - memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1); - png_ptr->save_row = (png_byte *)png_large_malloc(png_ptr, + 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->rowbytes + 1); - memset(png_ptr->save_row, 0, (png_size_t)png_ptr->rowbytes + 1); + png_memset(png_ptr->save_row, 0, (png_size_t)png_ptr->rowbytes + 1); } /* if interlaced, we need to set up width and height of pass */ @@ -662,13 +716,15 @@ png_write_finish_row(png_struct *png_ptr) png_pass_yinc[png_ptr->pass] - 1 - png_pass_ystart[png_ptr->pass]) / png_pass_yinc[png_ptr->pass]; + if (png_ptr->transformations & PNG_INTERLACE) + break; } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0); } /* reset filter row */ if (png_ptr->prev_row) - memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1); + png_memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1); /* if we have more data to get, go get it */ if (png_ptr->pass < 7) return; @@ -704,12 +760,10 @@ png_write_finish_row(png_struct *png_ptr) png_ptr->zstream->avail_out); } -/* deflateReset(png_ptr->zstream); */ - deflateEnd(png_ptr->zstream); - deflateInit(png_ptr->zstream, -1); - + deflateReset(png_ptr->zstream); } +#if defined(PNG_WRITE_INTERLACING_SUPPORTED) /* pick out the correct pixels for the interlace pass. The basic idea here is to go through the row with a source @@ -719,7 +773,7 @@ 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_byte *row, int pass) +png_do_write_interlace(png_row_info *row_info, png_bytef *row, int pass) { /* we don't have to do anything on the last pass (6) */ if (row && row_info && pass < 6) @@ -729,8 +783,8 @@ png_do_write_interlace(png_row_info *row_info, png_byte *row, int pass) { case 1: { - png_byte *sp; - png_byte *dp; + png_bytef *sp; + png_bytef *dp; int shift; int d; int value; @@ -763,8 +817,8 @@ png_do_write_interlace(png_row_info *row_info, png_byte *row, int pass) } case 2: { - png_byte *sp; - png_byte *dp; + png_bytef *sp; + png_bytef *dp; int shift; int d; int value; @@ -796,8 +850,8 @@ png_do_write_interlace(png_row_info *row_info, png_byte *row, int pass) } case 4: { - png_byte *sp; - png_byte *dp; + png_bytef *sp; + png_bytef *dp; int shift; int d; int value; @@ -829,8 +883,8 @@ png_do_write_interlace(png_row_info *row_info, png_byte *row, int pass) } default: { - png_byte *sp; - png_byte *dp; + png_bytef *sp; + png_bytef *dp; png_uint_32 i; int pixel_bytes; @@ -848,7 +902,7 @@ png_do_write_interlace(png_row_info *row_info, png_byte *row, int pass) sp = row + (png_size_t)(i * pixel_bytes); /* move the pixel */ if (dp != sp) - memcpy(dp, sp, pixel_bytes); + png_memcpy(dp, sp, pixel_bytes); /* next pixel */ dp += pixel_bytes; } @@ -865,17 +919,18 @@ png_do_write_interlace(png_row_info *row_info, png_byte *row, int pass) } } +#endif /* 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_byte *row, - png_byte *prev_row) +png_write_filter_row(png_row_info *row_info, png_bytef *row, + png_bytef *prev_row) { int minf, bpp; png_uint_32 i, v; - png_uint_32 s, mins; - png_byte *rp, *pp, *cp, *lp; + png_uint_32 s0, s1, s2, s3, s4, mins; + png_bytef *rp, *pp, *cp, *lp; /* find out how many bytes offset each pixel is */ bpp = (row_info->pixel_depth + 7) / 8; @@ -885,95 +940,79 @@ png_write_filter_row(png_row_info *row_info, png_byte *row, /* the prediction method we use is to find which method provides the smallest value when summing the abs of the distances from zero using anything >= 128 as negitive numbers. */ - for (i = 0, s = 0, rp = row + 1; i < row_info->rowbytes; i++, rp++) + s0 = s1 = s2 = s3 = s4 = 0; + + 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++) { + /* check none filter */ v = *rp; if (v < 128) - s += v; + s0 += v; else - s += 256 - (png_int_32)v; - } + s0 += 256 - v; - mins = s; - minf = 0; - - /* check sub filter */ - for (i = 0, s = 0, rp = row + 1, lp = row + 1 - bpp; - i < row_info->rowbytes; i++, rp++, lp++) - { - if (i >= bpp) - v = (png_byte)(((int)*rp - (int)*lp) & 0xff); - else - v = *rp; - - if (v < 128) - s += v; - else - s += 256 - v; - } - - if (s < mins) - { - mins = s; - minf = 1; - } - - /* check up filter */ - for (i = 0, s = 0, rp = row + 1, pp = prev_row + 1; - i < row_info->rowbytes; i++, rp++, pp++) - { + /* check up filter */ v = (png_byte)(((int)*rp - (int)*pp) & 0xff); if (v < 128) - s += v; + s2 += v; else - s += 256 - v; - } + s2 += 256 - v; - if (s < mins) - { - mins = s; - minf = 2; - } - - /* check avg filter */ - for (i = 0, s = 0, rp = row + 1, pp = prev_row + 1, lp = row + 1 - bpp; - i < row_info->rowbytes; i++, rp++, pp++, lp++) - { - if (i >= bpp) - v = (png_byte)(((int)*rp - (((int)*pp + (int)*lp) / 2)) & 0xff); - else - v = (png_byte)(((int)*rp - ((int)*pp / 2)) & 0xff); + /* check avg filter */ + v = (png_byte)(((int)*rp - ((int)*pp / 2)) & 0xff); if (v < 128) - s += v; + s3 += v; else - s += 256 - v; + s3 += 256 - v; } - if (s < mins) - { - mins = s; - minf = 3; - } + /* some filters are same until we get past bpp */ + s1 = s0; + s4 = s2; - /* check paeth filter */ - for (i = 0, s = 0, rp = row + 1, pp = prev_row + 1, lp = row + 1 - bpp, - cp = prev_row + 1 - bpp; - i < row_info->rowbytes; i++, rp++, pp++, lp++, cp++) + for (; i < row_info->rowbytes; i++, rp++, pp++, lp++, cp++) { int a, b, c, pa, pb, pc, p; - b = *pp; - if (i >= bpp) - { - c = *cp; - a = *lp; - } + /* check none filter */ + v = *rp; + if (v < 128) + s0 += v; else - { - a = c = 0; - } + s0 += 256 - v; + + /* check sub filter */ + v = (png_byte)(((int)*rp - (int)*lp) & 0xff); + + if (v < 128) + s1 += v; + else + s1 += 256 - v; + + /* check up filter */ + v = (png_byte)(((int)*rp - (int)*pp) & 0xff); + + if (v < 128) + s2 += v; + else + s2 += 256 - v; + + /* check avg filter */ + v = (png_byte)(((int)*rp - (((int)*pp + (int)*lp) / 2)) & 0xff); + + if (v < 128) + s3 += v; + else + s3 += 256 - v; + + /* check paeth filter */ + b = *pp; + c = *cp; + a = *lp; p = a + b - c; pa = abs(p - a); pb = abs(p - b); @@ -989,14 +1028,35 @@ png_write_filter_row(png_row_info *row_info, png_byte *row, v = (png_byte)(((int)*rp - p) & 0xff); if (v < 128) - s += v; + s4 += v; else - s += 256 - v; + s4 += 256 - v; } - if (s < mins) + mins = s0; + minf = 0; + + if (s1 < mins) { - mins = s; + mins = s1; + minf = 1; + } + + if (s2 < mins) + { + mins = s2; + minf = 2; + } + + if (s3 < mins) + { + mins = s3; + minf = 3; + } + + if (s4 < mins) + { + mins = s4; minf = 4; } @@ -1078,3 +1138,4 @@ png_write_filter_row(png_row_info *row_info, png_byte *row, break; } } + diff --git a/readme.txt b/readme.txt index 3ca55c55..f1800a41 100644 --- a/readme.txt +++ b/readme.txt @@ -1,25 +1,40 @@ -readme.txt - for libpng 0.71 +readme.txt - for libpng 0.8 -This is the first beta version of libpng 1.0. By beta, I mean that -all the code for 1.0 is there, and it works on all the machines -I have running all the tests I have devised. However, there is -always one more bug (at least), and I don't have many #define's in -the code (yet) for various platforms that I do not have. Also, I'd -like to see if I can get the code to compile with as few warnings -as possible. Finally, as people use my code, they may have -suggestions for additions that will make pnglib easier to port. +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. + +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 used by libpng) and zlib's restrictions, see zlib.h -I have included a make file, but you will probably have to modify it -for your own needs. I'm using Borland C++, running large memory -model on Windows 3.11, but it should work on almost anything. Support -for medium memory model is planned, but is not in 1.0 (probably in 1.1). +I have included a general makefile, but you may have to modify it +for your own needs. -You will need zlib 0.93 to run this. zlib is a compression +You will need zlib 0.95 or later to run this. zlib is a compression library that is useful for more things then just png files. If you need a compression library, check out zlib.h @@ -32,10 +47,10 @@ be available at the same place you picked up libpng. If it is not there, try ftp.uu.net in the /graphics/png directory. This code is currently being archived at ftp.uu.net in the -/graphics/png directory, and at ftp.group42.com in the /pub/png -directory, and on CompuServe, Lib 20 (PNG) at GO GRAPHSUP. -If you can't find it in any of those places, e-mail me, and I'll -tell you where it is. +/graphics/png directory, and at ftp.group42.com (204.94.158.25) +in the /pub/png directory, and on CompuServe, Lib 20 (PNG SUPPORT) +at GO GRAPHSUP. If you can't find it in any of those places, +e-mail me, and I'll help you find it. If you have any code changes, requests, problems, etc., please e-mail them to me. Also, I'd appreciate any make files or project files, @@ -50,7 +65,7 @@ fix. Please mention "libpng" somewhere in the subject line. Thanks. You can reach me at: -internet: schalnat&group42.com +internet: schalnat@group42.com CompuServe: 75501,1625 Please do not send me general questions about PNG. Send them to @@ -63,7 +78,7 @@ and ...". If in doubt, send questions to me. I'll bounce them to others, if necessary. Please do not send suggestions on how to change PNG. We have -been discussing PNG for 6 months now, and it is official and +been discussing PNG for 9 months now, and it is official and finished. If you have suggestions for libpng, however, I'll gladly listen. Even if your suggestion is not used for version 1.0, it may be used later. @@ -75,5 +90,5 @@ Good luck, and happy coding. Internet: schalnat@group42.com CompuServe: 75501,1625 Web: www.group42.com - FTP: ftp.group42.com + FTP: ftp.group42.com (204.94.158.25)