+++ /dev/null
-
-Libpng 1.0.3 - January 14, 1999
-
-This is a public release of libpng, intended for use in production codes.
-
-Changes since the previous public release (1.0.2):
-
-libpng-1.0.3:
-
- Replaced and extended code that was removed from png_set_filler() in 1.0.1a.
- Fixed a bug in png_do_filler() that made it fail to write filler bytes in
- the left-most pixel of each row (Kevin Bracey).
- Changed "static pngcharp tIME_string" to "static char tIME_string[30]"
- in pngtest.c (Duncan Simpson).
- Fixed a bug in pngtest.c that caused pngtest to try to write a tIME chunk
- even when no tIME chunk was present in the source file.
- Fixed a problem in pngrutil.c: gray_to_rgb didn't always work with 16-bit.
- Fixed a problem in png_read_push_finish_row(), which would not skip some
- passes that it should skip, for images that are less than 3 pixels high.
- Interchanged the order of calls to png_do_swap() and png_do_shift()
- in pngwtran.c (John Cromer).
- Added #ifdef PNG_DEBUG/#endif surrounding use of PNG_DEBUG in png.h .
- Changed "bad adaptive filter type" from error to warning in pngrutil.c .
- Fixed a documentation error about default filtering with 8-bit indexed-color.
- Separated the PNG_NO_STDIO macro into PNG_NO_STDIO and PNG_NO_CONSOLE_IO
- (L. Peter Deutsch).
- Added png_set_rgb_to_gray() and png_get_rgb_to_gray_status() functions.
- Added png_get_copyright() and png_get_header_version() functions.
- Revised comments on png_set_progressive_read_fn() in libpng.txt and example.c
- Added information about debugging in libpng.txt and libpng.3 .
- Changed "ln -sf" to "ln -s -f" in makefile.s2x, makefile.lnx, and makefile.sco.
- Removed lines after Dynamic Dependencies" in makefile.aco .
- Revised makefile.dec to make a shared library (Jeremie Petit).
- Removed trailing blanks from all files.
- Removed misplaced #endif and #ifdef PNG_NO_EXTERN near the end of png.h
- Added "if" tests to silence complaints about unused png_ptr in png.h and png.c
- Changed "check_if_png" function in example.c to return true (nonzero) if PNG.
- Changed libpng.txt to demonstrate png_sig_cmp() instead of png_check_sig()
- which is obsolete.
- Added makefile.hux, for Hewlett Packard HPUX 10.20 and 11.00 (Jim Rice)
- Added a statement of Y2K compliance in png.h, libpng.1, and Y2KINFO.
-
-Send comments/corrections/commendations to
-png-implement@dworkin.wustl.edu or to randeg@alumni.rpi.edu
-
-Glenn R-P
-
-Send comments/corrections/commendations to
-png-implement@dworkin.wustl.edu or to randeg@alumni.rpi.edu
-
-Glenn Randers-Pehrson
-libpng maintainer
-PNG Development Group
+++ /dev/null
-CHANGES - changes for libpng
-
-version 0.2
- added reader into png.h
- fixed small problems in stub file
-version 0.3
- added pull reader
- split up pngwrite.c to several files
- added pnglib.txt
- added example.c
- cleaned up writer, adding a few new tranformations
- fixed some bugs in writer
- interfaced with zlib 0.5
- added K&R support
- added check for 64 KB blocks for 16 bit machines
-version 0.4
- cleaned up code and commented code
- simplified time handling into png_time
- created png_color_16 and png_color_8 to handle color needs
- cleaned up color type defines
- fixed various bugs
- made various names more consistant
- interfaced with zlib 0.71
- cleaned up zTXt reader and writer (using zlib's Reset functions)
- split transformations into pngrtran.c and pngwtran.c
-version 0.5
- interfaced with zlib 0.8
- fixed many reading and writing bugs
- saved using 3 spaces instead of tabs
-version 0.6
- added png_large_malloc() and png_large_free()
- added png_size_t
- cleaned up some compiler warnings
- added png_start_read_image()
-version 0.7
- cleaned up lots of bugs
- finished dithering and other stuff
- added test program
- changed name from pnglib to libpng
-version 0.71 [June, 1995]
- 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
-version 0.81 [August, 1995]
- incorporated Tim Wegner's medium model code (thanks, Tim)
-version 0.82 [September, 1995]
- [unspecified changes]
-version 0.85 [December, 1995]
- added more medium model code (almost everything's a far)
- added i/o, error, and memory callback functions
- fixed some bugs (16 bit, 4 bit interlaced, etc.)
- added first run progressive reader (barely tested)
-version 0.86 [January, 1996]
- fixed bugs
- improved documentation
-version 0.87 [January, 1996]
- fixed medium model bugs
- fixed other bugs introduced in 0.85 and 0.86
- added some minor documentation
-version 0.88 [January, 1996]
- fixed progressive bugs
- replaced tabs with spaces
- cleaned up documentation
- added callbacks for read/write and warning/error functions
-version 0.89 [July, 1996]
- added new initialization API to make libpng work better with shared libs
- we now have png_create_read_struct(), png_create_write_struct(),
- png_create_info_struct(), png_destroy_read_struct(), and
- png_destroy_write_struct() instead of the separate calls to
- malloc and png_read_init(), png_info_init(), and png_write_init()
- changed warning/error callback functions to fix bug - this means you
- should use the new initialization API if you were using the old
- png_set_message_fn() calls, and that the old API no longer exists
- so that people are aware that they need to change their code
- changed filter selection API to allow selection of multiple filters
- since it didn't work in previous versions of libpng anyways
- optimized filter selection code
- fixed png_set_background() to allow using an arbitrary RGB color for
- paletted images
- fixed gamma and background correction for paletted images, so
- png_correct_palette is not needed unless you are correcting an
- external palette (you will need to #define PNG_CORRECT_PALETTE_SUPPORTED
- in pngconf.h) - if nobody uses this, it may disappear in the future.
- fixed bug with Borland 64K memory allocation (Alexander Lehmann)
- fixed bug in interlace handling (Smarasderagd, I think)
- added more error checking for writing and image to reduce invalid files
- separated read and write functions so that they won't both be linked
- into a binary when only reading or writing functionality is used
- new pngtest image also has interlacing and zTXt
- updated documentation to reflect new API
-version 0.90 [January, 1997]
- made CRC errors/warnings on critical and ancillary chunks configurable
- libpng will use the zlib CRC routines by (compile-time) default
- changed DOS small/medium model memory support - needs zlib 1.04 (Tim Wegner)
- added external C++ wrapper statements to png.h (Gilles Dauphin)
- allow PNG file to be read when some or all of file signature has already
- been read from the beginning of the stream. ****This affects the size
- of info_struct and invalidates all programs that use a shared libpng****
- fixed png_filler() declarations
- fixed? background color conversions
- fixed order of error function pointers to match documentation
- current chunk name is now available in png_struct to reduce the number
- of nearly identical error messages (will simplify multi-lingual
- support when available)
- try to get ready for unknown-chunk callback functions:
- - previously read critical chunks are flagged, so the chunk handling
- routines can determine if the chunk is in the right place
- - all chunk handling routines have the same prototypes, so we will
- be able to handle all chunks via a callback mechanism
- try to fix Linux "setjmp" buffer size problems
-version 0.95 [March, 1997]
- fixed bug in pngwutil.c allocating "up_row" twice and "avg_row" never
- fixed bug in PNG file signature compares when start != 0
- changed parameter type of png_set_filler(...filler...) from png_byte
- to png_uint_32
- added test for MACOS to ensure that both math.h and fp.h are not #included
- added macros for libpng to be compiled as a Windows DLL (Andreas Kupries)
- added "packswap" transformation, which changes the endianness of
- packed-pixel bytes (Kevin Bracey)
- added "strip_alpha" transformation, which removes the alpha channel of
- input images without using it (not neccesarily a good idea)
- added "swap_alpha" transformation, which puts the alpha channel in front
- of the color bytes instead of after
- removed all implicit variable tests which assume NULL == 0 (I think)
- changed several variables to "png_size_t" to show 16/32-bit limitations
- added new pCAL chunk read/write support
- added experimental filter selection weighting (Greg Roelofs)
- removed old png_set_rgbx() and png_set_xrgb() functions that have been
- obsolete for about 2 years now (use png_set_filler() instead)
- added macros to read 16- and 32-bit ints directly from buffer, to be
- used only on those systems that support it (namely PowerPC and 680x0)
- With some testing, this may become the default for MACOS/PPC systems.
- only calculate CRC on data if we are going to use it
- added macros for zTXt compression type PNG_zTXt_COMPRESSION_???
- added macros for simple libpng debugging output selectable at compile time
- removed PNG_READ_END_MODE in progressive reader (Smarasderagd)
- more description of info_struct in libpng.txt and png.h
- more instructions in example.c
- more chunk types tested in pngtest.c
- renamed pngrcb.c to pngset.c, and all png_read_<chunk> functions to be
- png_set_<chunk>. We now have corresponding png_get_<chunk>
- functions in pngget.c to get infomation in info_ptr. This isolates
- the application from the internal organization of png_info_struct
- (good for shared library implementations).
-version 0.96 [May, 1997]
- fixed serious bug with < 8bpp images introduced in 0.95
- fixed 256-color transparency bug (Greg Roelofs)
- fixed up documentation (Greg Roelofs, Laszlo Nyul)
- fixed "error" in pngconf.h for Linux setjmp() behaviour
- fixed DOS medium model support (Tim Wegner)
- fixed png_check_keyword() for case with error in static string text
- added read of CRC after IEND chunk for embedded PNGs (Laszlo Nyul)
- added typecasts to quiet compiler errors
- added more debugging info
-version 0.97 [January, 1998]
- removed PNG_USE_OWN_CRC capability
- relocated png_set_crc_action from pngrutil.c to pngrtran.c
- fixed typecasts of "new_key", etc. (Andreas Dilger)
- added RFC 1152 [sic] date support
- fixed bug in gamma handling of 4-bit grayscale
- added 2-bit grayscale gamma handling (Glenn R-P)
- added more typecasts. 65536L becomes (png_uint_32)65536L, etc. (Glenn R-P)
- minor corrections in libpng.txt
- added simple sRGB support (Glenn R-P)
- easier conditional compiling, e.g. define PNG_READ/WRITE_NOT_FULLY_SUPPORTED;
- all configurable options can be selected from command-line instead
- of having to edit pngconf.h (Glenn R-P)
- fixed memory leak in pngwrite.c (free info_ptr->text) (Glenn R-P)
- added more conditions for png_do_background, to avoid changing
- black pixels to background when a background is supplied and
- no pixels are transparent
- repaired PNG_NO_STDIO behaviour
- tested NODIV support and made it default behaviour (Greg Roelofs)
- added "-m" option and PNGTEST_DEBUG_MEMORY to pngtest (John Bowler)
- regularized version numbering scheme and bumped shared-library major
- version number to 2 to avoid problems with libpng 0.89 apps (Greg Roelofs)
-version 0.98 [January, 1998]
- cleaned up some typos in libpng.txt and in code documentation
- fixed memory leaks in pCAL chunk processing (Glenn R-P and John Bowler)
- cosmetic change "display_gamma" to "screen_gamma" in pngrtran.c
- changed recommendation about file_gamma for PC images to .51 from .45,
- in example.c and libpng.txt, added comments to distinguish between
- screen_gamma, viewing_gamma, and display_gamma.
- changed all references to RFC1152 to read RFC1123 and changed the
- PNG_TIME_RFC1152_SUPPORTED macro to PNG_TIME_RFC1123_SUPPORTED
- added png_invert_alpha capability (Glenn R-P -- suggestion by Jon Vincent)
- changed srgb_intent from png_byte to int to avoid compiler bugs
-version 0.99 [January 30, 1998]
- free info_ptr->text instead of end_info_ptr->text in pngread.c (John Bowler)
- fixed a longstanding "packswap" bug in pngtrans.c
- fixed some inconsistencies in pngconf.h that prevented compiling with
- PNG_READ_GAMMA_SUPPORTED and PNG_READ_hIST_SUPPORTED undefined
- fixed some typos and made other minor rearrangement of libpng.txt (Andreas)
- changed recommendation about file_gamma for PC images to .50 from .51 in
- example.c and libpng.txt, and changed file_gamma for sRGB images to .45
- added a number of functions to access information from the png structure
- png_get_image_height(), etc. (Glenn R-P, suggestion by Brad Pettit)
- added TARGET_MACOS similar to zlib-1.0.8
- define PNG_ALWAYS_EXTERN when __MWERKS__ && WIN32 are defined
- added type casting to all png_malloc() function calls
-version 0.99a [January 31, 1998]
- Added type casts and parentheses to all returns that return a value.(Tim W.)
-version 0.99b [February 4, 1998]
- Added type cast png_uint_32 on malloc function calls where needed.
- Changed type of num_hist from png_uint_32 to int (same as num_palette).
- Added checks for rowbytes overflow, in case png_size_t is less than 32 bits.
- Renamed makefile.elf to makefile.lnx.
-version 0.99c [February 7, 1998]
- More type casting. Removed erroneous overflow test in pngmem.c.
- Added png_buffered_memcpy() and png_buffered_memset(), apply them to rowbytes.
- Added UNIX manual pages libpng.3 (incorporating libpng.txt) and png.5.
-version 0.99d [February 11, 1998]
- Renamed "far_to_near()" "png_far_to_near()"
- Revised libpng.3
- Version 99c "buffered" operations didn't work as intended. Replaced them
- with png_memcpy_check() and png_memset_check().
- Added many "if (png_ptr == NULL) return" to quell compiler warnings about
- unused png_ptr, mostly in pngget.c and pngset.c.
- Check for overlength tRNS chunk present when indexed-color PLTE is read.
- Cleaned up spelling errors in libpng.3/libpng.txt
- Corrected a problem with png_get_tRNS() which returned undefined trans array
-version 0.99e [February 28, 1998]
- Corrected png_get_tRNS() again.
- Add parentheses for easier reading of pngget.c, fixed "||" should be "&&".
- Touched up example.c to make more of it compileable, although the entire
- file still can't be compiled (Willem van Schaik)
- Fixed a bug in png_do_shift() (Bryan Tsai)
- Added a space in png.h prototype for png_write_chunk_start()
- Replaced pngtest.png with one created with zlib 1.1.1
- Changed pngtest to report PASS even when file size is different (Jean-loup G.)
- Corrected some logic errors in png_do_invert_alpha() (Chris Patterson)
-version 0.99f [March 5, 1998]
- Corrected a bug in pngpread() introduced in version 99c (Kevin Bracey)
- Moved makefiles into a "scripts" directory, and added INSTALL instruction file
- Added makefile.os2 and pngos2.def (A. Zabolotny) and makefile.s2x (W. Sebok)
- Added pointers to "note on libpng versions" in makefile.lnx and README
- Added row callback feature when reading and writing nonprogressive rows
- and added a test of this feature in pngtest.c
- Added user transform callbacks, with test of the feature in pngtest.c
-version 0.99g [March 6, 1998, morning]
- Minor changes to pngtest.c to suppress compiler warnings.
- Removed "beta" language from documentation.
-version 0.99h [March 6, 1998, evening]
- Minor changes to previous minor changes to pngtest.c
- Changed PNG_READ_NOT_FULLY_SUPPORTED to PNG_READ_TRANSFORMS_NOT_SUPPORTED
- and added PNG_PROGRESSIVE_READ_NOT_SUPPORTED macro
-version 1.00 [March 7, 1998]
- Changed several typedefs in pngrutil.c
- Added makefile.wat (Pawel Mrochen), updated makefile.tc3 (Willem van Schaik)
- replaced "while(1)" with "for(;;)"
- added PNGARG() to prototypes in pngtest.c and removed some prototypes
- updated some of the makefiles (Tom Lane)
- changed some typedefs (s_start, etc.) in pngrutil.c
- fixed dimensions of "short_months" array in pngwrite.c
- Replaced ansi2knr.c with the one from jpeg-v6
-version 1.0.0 [March 8, 1998]
- Changed name from 1.00 to 1.0.0 (Adam Costello)
- Added smakefile.ppc (with SCOPTIONS.ppc) for Amiga PPC (Andreas Kleinert)
-version 1.0.0a [March 9, 1998]
- Fixed three bugs in pngrtran.c to make gamma+background handling consistent
- (Greg Roelofs)
- Changed format of the PNG_LIBPNG_VER integer to xyyzz instead of xyz
- for major, minor, and bugfix releases. This is 10001. (Adam Costello,
- Tom Lane)
- Make months range from 1-12 in png_convert_to_rfc1123
-version 1.0.0b [March 13, 1998]
- Quieted compiler complaints about two empty "for" loops in pngrutil.c
- Minor changes to makefile.s2x
- Removed #ifdef/#endif around a png_free() in pngread.c
-version 1.0.1 [March 14, 1998]
- Changed makefile.s2x to reduce security risk of using a relative pathname
- Fixed some typos in the documentation (Greg).
- Fixed a problem with value of "channels" returned by png_read_update_info()
-version 1.0.1a [April 21, 1998]
- Optimized Paeth calculations by replacing abs() function calls with intrinsics
- plus other loop optimizations. Improves avg decoding speed by about 20%.
- Commented out i386istic "align" compiler flags in makefile.lnx.
- Reduced the default warning level in some makefiles, to make them consistent.
- Removed references to IJG and JPEG in the ansi2knr.c copyright statement.
- Fixed a bug in png_do_strip_filler with XXRRGGBB => RRGGBB transformation.
- Added grayscale and 16-bit capability to png_do_read_filler().
- Fixed a bug in pngset.c, introduced in version 0.99c, that sets rowbytes
- too large when writing an image with bit_depth < 8 (Bob Dellaca).
- Corrected some bugs in the experimental weighted filtering heuristics.
- Moved a misplaced pngrutil code block that truncates tRNS if it has more
- than num_palette entries -- test was done before num_palette was defined.
- Fixed a png_convert_to_rfc1123() bug that converts day 31 to 0 (Steve Eddins).
- Changed compiler flags in makefile.wat for better optimization (Pawel Mrochen).
-version 1.0.1b [May 2, 1998]
- Relocated png_do_gray_to_rgb() within png_do_read_transformations() (Greg).
- Relocated the png_composite macros from pngrtran.c to png.h (Greg).
- Added makefile.sco (contributed by Mike Hopkirk).
- Fixed two bugs (missing definitions of "istop") introduced in libpng-1.0.1a.
- Fixed a bug in pngrtran.c that would set channels=5 under some circumstances.
- More work on the Paeth-filtering, achieving imperceptible speedup (A Kleinert).
- More work on loop optimization which may help when compiled with C++ compilers.
- Added warnings when people try to use transforms they've defined out.
- Collapsed 4 "i" and "c" loops into single "i" loops in pngrtran and pngwtran.
- Revised paragraph about png_set_expand() in libpng.txt and libpng.3 (Greg)
-version 1.0.1c [May 11, 1998]
- Fixed a bug in pngrtran.c (introduced in libpng-1.0.1a) where the masks for
- filler bytes should have been 0xff instead of 0xf.
- Added max_pixel_depth=32 in pngrutil.c when using FILLER with palette images.
- Moved PNG_WRITE_WEIGHTED_FILTER_SUPPORTED and PNG_WRITE_FLUSH_SUPPORTED
- out of the PNG_WRITE_TRANSFORMS_NOT_SUPPORTED block of pngconf.h
- Added "PNG_NO_WRITE_TRANSFORMS" etc., as alternatives for *_NOT_SUPPORTED,
- for consistency, in pngconf.h
- Added individual "ifndef PNG_NO_[CAPABILITY]" in pngconf.h to make it easier
- to remove unwanted capabilities via the compile line
- Made some corrections to grammar (which, it's) in documentation (Greg).
- Corrected example.c, use of row_pointers in png_write_image().
-version 1.0.1d [May 24, 1998]
- Corrected several statements that used side effects illegally in pngrutil.c
- and pngtrans.c, that were introduced in version 1.0.1b
- Revised png_read_rows() to avoid repeated if-testing for NULL (A Kleinert)
- More corrections to example.c, use of row_pointers in png_write_image()
- and png_read_rows().
- Added pngdll.mak and pngdef.pas to scripts directory, contributed by
- Bob Dellaca, to make a png32bd.dll with Borland C++ 4.5
- Fixed error in example.c with png_set_text: num_text is 3, not 2 (Guido V.)
- Changed several loops from count-down to count-up, for consistency.
-version 1.0.1e [June 6, 1998]
- Revised libpng.txt and libpng.3 description of png_set_read|write_fn(), and
- added warnings when people try to set png_read_fn and png_write_fn in
- the same structure.
- Added a test such that png_do_gamma will be done when num_trans==0
- for truecolor images that have defined a background. This corrects an
- error that was introduced in libpng-0.90 that can cause gamma processing
- to be skipped.
- Added tests in png.h to include "trans" and "trans_values" in structures
- when PNG_READ_BACKGROUND_SUPPORTED or PNG_READ_EXPAND_SUPPORTED is defined.
- Add png_free(png_ptr->time_buffer) in png_destroy_read_struct()
- Moved png_convert_to_rfc_1123() from pngwrite.c to png.c
- Added capability for user-provided malloc_fn() and free_fn() functions,
- and revised pngtest.c to demonstrate their use, replacing the
- PNGTEST_DEBUG_MEM feature.
- Added makefile.w32, for Microsoft C++ 4.0 and later (Tim Wegner).
-version 1.0.2 [June 14, 1998]
- Fixed two bugs in makefile.bor .
-version 1.0.2a [December 30, 1998]
- Replaced and extended code that was removed from png_set_filler() in 1.0.1a.
- Fixed a bug in png_do_filler() that made it fail to write filler bytes in
- the left-most pixel of each row (Kevin Bracey).
- Changed "static pngcharp tIME_string" to "static char tIME_string[30]"
- in pngtest.c (Duncan Simpson).
- Fixed a bug in pngtest.c that caused pngtest to try to write a tIME chunk
- even when no tIME chunk was present in the source file.
- Fixed a problem in pngrutil.c: gray_to_rgb didn't always work with 16-bit.
- Fixed a problem in png_read_push_finish_row(), which would not skip some
- passes that it should skip, for images that are less than 3 pixels high.
- Interchanged the order of calls to png_do_swap() and png_do_shift()
- in pngwtran.c (John Cromer).
- Added #ifdef PNG_DEBUG/#endif surrounding use of PNG_DEBUG in png.h .
- Changed "bad adaptive filter type" from error to warning in pngrutil.c .
- Fixed a documentation error about default filtering with 8-bit indexed-color.
- Separated the PNG_NO_STDIO macro into PNG_NO_STDIO and PNG_NO_CONSOLE_IO
- (L. Peter Deutsch).
- Added png_set_rgb_to_gray() and png_get_rgb_to_gray_status() functions.
- Added png_get_copyright() and png_get_header_version() functions.
- Revised comments on png_set_progressive_read_fn() in libpng.txt and example.c
- Added information about debugging in libpng.txt and libpng.3 .
- Changed "ln -sf" to "ln -s -f" in makefile.s2x, makefile.lnx, and makefile.sco.
- Removed lines after Dynamic Dependencies" in makefile.aco .
- Revised makefile.dec to make a shared library (Jeremie Petit).
- Removed trailing blanks from all files.
-version 1.0.2a [January 6, 1999]
- Removed misplaced #endif and #ifdef PNG_NO_EXTERN near the end of png.h
- Added "if" tests to silence complaints about unused png_ptr in png.h and png.c
- Changed "check_if_png" function in example.c to return true (nonzero) if PNG.
- Changed libpng.txt to demonstrate png_sig_cmp() instead of png_check_sig()
- which is obsolete.
-version 1.0.3 [January 14, 1999]
- Added makefile.hux, for Hewlett Packard HPUX 10.20 and 11.00 (Jim Rice)
- Added a statement of Y2K compliance in png.h, libpng.1, and Y2KINFO.
+++ /dev/null
-
-Installing libpng version 1.0.3 - January 14, 1999
-
-Before installing libpng, you must first install zlib. zlib
-can usually be found wherever you got libpng. zlib can be
-placed in another directory, at the same level as libpng.
-Note that your system might already have a preinstalled
-zlib, but you will still need to have access to the
-zlib.h and zconf.h include files that correspond to the
-version of zlib that's installed.
-
-You can rename the directories that you downloaded (they
-might be called "libpng-1.0.3" or "lpng103" and "zlib-1.1.3"
-or "zlib113") so that you have directories called "zlib" and "libpng".
-
-Your directory structure should look like this:
-
- .. (the parent directory)
- libpng (this directory)
- INSTALL (this file)
- README
- *.h
- *.c
- scripts
- makefile.*
- pngtest.png
- etc.
- zlib
- README
- *.h
- *.c
- contrib
- etc.
-
-First enter the zlib directory and follow the instructions
-in zlib/README. Then come back here and choose the
-appropriate makefile.sys in the scripts directory.
-The files that are presently available in the scripts directory
-include
-
- descrip.mms => VMS makefile for MMS or MMK
- makefile.std => Generic UNIX makefile
- makefile.knr => Archaic UNIX Makefile that converts files with ansi2knr
- makefile.dec => DEC Alpha UNIX makefile
- makefile.hux => HPUX (10.20 and 11.00) makefile
- makefile.sgi => Silicon Graphics IRIX makefile
- makefile.sun => Sun makefile
- makefile.s2x => Solaris 2.X makefile (gcc, creates libpng.so.2.1.0)
- makefile.lnx => Linux/ELF makefile (gcc, creates libpng.so.2.1.0)
- makefile.mip => MIPS makefile
- makefile.aco => Acorn makefile
- makefile.ama => Amiga makefile
- smakefile.ppc => AMIGA smakefile for SAS C V6.58/7.00 PPC compiler
- (Requires SCOPTIONS, copied from scripts/SCOPTIONS.ppc)
- makefile.atr => Atari makefile
- makefile.bor => Borland makefile
- build.bat => MS-DOS batch file for Borland compiler
- makefile.dj2 => DJGPP 2 makefile
- makefile.msc => Microsoft C makefile
- makefile.w32 => makefile for Microsoft Visual C++ 4.0 and later
- makefile.tc3 => Turbo C 3.0 makefile
- makefile.os2 => OS/2 Makefile (gcc and emx, requires pngos2.def)
- pngos2.def => OS/2 module definition file used by makefile.os2
- makefile.wat => Watcom 10a+ Makefile, 32-bit flat memory model
- makevms.com => VMS build script
- pngdll.mak => To make a png32bd.dll with Borland C++ 4.5
- pngdef.pas => Defines for a png32bd.dll with Borland C++ 4.5
-
-Copy the file (or files) that you need from the
-scripts directory into this directory, for example
-
- MSDOS example: copy scripts\makefile.msd makefile
- UNIX example: cp scripts/makefile.std makefile
-
-Read the makefile to see if you need to change any source or
-target directories to match your preferences.
-
-Then read pngconf.h to see if you want to make any configuration
-changes.
-
-Then just run "make test" which will create the libpng library in
-this directory and run a quick test that reads the "pngtest.png"
-file and writes a "pngout.png" file that should be identical to it.
-
-Most of the makefiles will allow you to run "make install" to
-put the library in its final resting place (if you want to
-do that, run "make install" in the zlib directory first if necessary).
-
-Further information can be found in the README and libpng.txt
-files, in the individual makefiles, and in png.h, and the manual
-pages libpng.3 and png.5.
+++ /dev/null
-README for libpng 1.0.3 - January 14, 1999 (shared library 2.1)
-See the note about version numbers near the top of png.h
-
-See INSTALL for instructions on how to install libpng.
-
-This is the first official release of libpng. Don't let the fact that
-it's the first release fool you. The libpng library has been in
-extensive use and testing for about two and a half years. However, it's
-finally gotten to the stage where there haven't been significant
-changes to the API in some time, and people have a bad feeling about
-libraries with versions < 1.0.
-
-****
-Note that some of the changes to the png_info structure render this
-version of the library binary incompatible with libpng-0.89 or
-earlier versions if you are using a shared library. The type of the
-"filler" parameter for png_set_filler() has changed from png_byte to
-png_uint_32, which will affect shared-library applications that use
-this function.
-
-To avoid problems with changes to the internals of png_info_struct,
-new APIs have been made available in 0.95 to avoid direct application
-access to info_ptr. These functions are the png_set_<chunk> and
-png_get_<chunk> functions. These functions should be used when
-accessing/storing the info_struct data, rather than manipulating it
-directly, to avoid such problems in the future.
-
-It is important to note that the APIs do not make current programs
-that access the info struct directly incompatible with the new
-library. However, it is strongly suggested that new programs use
-the new APIs (as shown in example.c), and older programs be converted
-to the new format, to facilitate upgrades in the future.
-****
-
-Additions since 0.90 include the ability to compile libpng as a
-Windows DLL, and new APIs for accessing data in the info struct.
-Experimental functions include the ability to set weighting and cost
-factors for row filter selection, direct reads of integers from buffers
-on big-endian processors that support misaligned data access, faster
-methods of doing alpha composition, and more accurate 16->8 bit color
-conversion.
-
-The additions since 0.89 include the ability to read from a PNG stream
-which has had some (or all) of the signature bytes read by the calling
-application. This also allows the reading of embedded PNG streams that
-do not have the PNG file signature. As well, it is now possible to set
-the library action on the detection of chunk CRC errors. It is possible
-to set different actions based on whether the CRC error occurred in a
-critical or an ancillary chunk.
-
-The changes made to the library, and bugs fixed are based on discussions
-on the PNG implementation mailing list <png-implement@dworking.wustl.edu>
-and not on material submitted to Guy.
-
-For a detailed description on using libpng, read libpng.txt. For
-examples of libpng in a program, see example.c and pngtest.c. 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 general makefile, as well as several machine and
-compiler specific ones, but you may have to modify one for your own needs.
-
-You should use zlib 1.0.4 or later to run this, but it MAY work with
-versions as old as zlib 0.95. Even so, there are bugs in older zlib
-versions which can cause the output of invalid compression streams for
-some images. You will definitely need zlib 1.0.4 or later if you are
-taking advantage of the MS-DOS "far" structure allocation for the small
-and medium memory models. You should also note that zlib is a
-compression library that is useful for more things than just PNG files.
-You can use zlib as a drop-in replacement for fread() and fwrite() if
-you are so inclined.
-
-zlib should be available at the same place that libpng is.
-If not, it should be at ftp.uu.net in /graphics/png
-Eventually, it will be at ftp.uu.net in /pub/archiving/zip/zlib
-
-You may also want a copy of the PNG specification. It is available
-as an RFC and a W3C Recommendation. Failing
-these resources you can 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 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,
-and any modifications you needed to make to get libpng to compile,
-along with a #define variable to tell what compiler/system you are on.
-If you needed to add transformations to libpng, or wish libpng would
-provide the image in a different way, drop me a note (and code, if
-possible), so I can consider supporting the transformation.
-Finally, if you get any warning messages when compiling libpng
-(note: not zlib), and they are easy to fix, I'd appreciate the
-fix. Please mention "libpng" somewhere in the subject line. Thanks.
-
-This release was created and will be supported by myself (of course
-based in a large way on Guy's and Andreas' earlier work), and the PNG group.
-
-randeg@alumni.rpi.edu
-png-implement@dworkin.wustl.edu
-
-You can't reach Guy, the original libpng author, at the addresses
-given in previous versions of this document. He and Andreas will read mail
-addressed to the png-implement list, however.
-
-Please do not send general questions about PNG. Send them to
-the address in the specification (png-group@w3.org). At the same
-time, please do not send libpng questions to that address, send them to me
-or to png-implement@dworkin.wustl.edu. I'll
-get them in the end anyway. If you have a question about something
-in the PNG specification that is related to using libpng, send it
-to me. Send me any questions that start with "I was using libpng,
-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 three years 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.
-
-Files in this distribution:
-
- CHANGES => Description of changes between libpng versions
- README => This file
- TODO => Things not implemented in the current library
- ansi2knr.1 => Manual page for ansi2knr
- ansi2knr.c => Converts files to K&R style function declarations
- build.bat => MS-DOS batch file for Borland compiler
- descrip.mms => VMS project file
- example.c => Example code for using libpng functions
- libpng.3 => manual page for libpng
- libpng.txt => Description of libpng and its functions
- libpngpf.3 => manual page for libpng's private functions
- png.5 => manual page for the PNG format
- png.c => Basic interface functions common to library
- png.h => Library function and interface declarations
- pngconf.h => System specific library configuration
- pngerror.c => Error/warning message I/O functions
- pngget.c => Functions for retrieving info from struct
- pngmem.c => Memory handling functions
- pngpread.c => Progressive reading functions
- pngread.c => Read data/helper high-level functions
- pngrio.c => Lowest-level data read I/O functions
- pngrtran.c => Read data transformation functions
- pngrutil.c => Read data utility functions
- pngset.c => Functions for storing data into the info_struct
- pngtest.c => Library test program
- pngtest.png => Library test sample image
- pngtrans.c => Common data transformation functions
- pngwio.c => Lowest-level write I/O functions
- pngwrite.c => High-level write functions
- pngwtran.c => Write data transformations
- pngwutil.c => Write utility functions
- scripts => Directory containing scripts for building libpng:
- descrip.mms => VMS makefile for MMS or MMK
- makefile.std => Generic UNIX makefile
- makefile.knr => Archaic UNIX Makefile that converts files with ansi2knr
- makefile.dec => DEC Alpha UNIX makefile
- makefile.hux => HPUX (10.20 and 11.00) makefile
- makefile.sgi => Silicon Graphics IRIX makefile
- makefile.sun => Sun makefile
- makefile.s2x => Solaris 2.X makefile (gcc, creates libpng.so.2.1.0)
- makefile.lnx => Linux/ELF makefile (gcc, creates libpng.so.2.1.0)
- makefile.mip => MIPS makefile
- makefile.aco => Acorn makefile
- makefile.ama => Amiga makefile
- smakefile.ppc => AMIGA smakefile for SAS C V6.58/7.00 PPC compiler
- (Requires SCOPTIONS, copied from scripts/SCOPTIONS.ppc)
- makefile.atr => Atari makefile
- makefile.bor => Borland makefile
- build.bat => MS-DOS batch file for Borland compiler
- makefile.dj2 => DJGPP 2 makefile
- makefile.msc => Microsoft C makefile
- makefile.w32 => makefile for Microsoft Visual C++ 4.0 and later
- makefile.tc3 => Turbo C 3.0 makefile
- makefile.os2 => OS/2 Makefile (gcc and emx, requires pngos2.def)
- makefile.wat => Watcom 10a+ Makefile, 32-bit flat memory model
- pngos2.def => OS/2 module definition file used by makefile.os2
- makevms.com => VMS build script
- pngdll.mak => To make a png32bd.dll with Borland C++ 4.5
- pngdef.pas => Defines for a png32bd.dll with Borland C++ 4.5
-
-Good luck, and happy coding.
-
--Glenn Randers-Pehrson
- Internet: randeg@alumni.rpi.edu
- Web: http://www.rpi.edu/~randeg/index.html
-
--Andreas Eric Dilger
- Internet: adilger@enel.ucalgary.ca
- Web: http://www-mddsp.enel.ucalgary.ca/People/adilger/
-
--Guy Eric Schalnat
- (formerly of Group 42, Inc)
- Internet: gschal@infinet.com
+++ /dev/null
-TODO - list of things to do for libpng:
-
-Final bug fixes.
-Fix problem with C++ and EXTERN "C".
-Better C++ wrapper/full C++ implementation?
-Keep up with public chunks.
-sPLT chunk handling.
-cHRM transformation.
-Support for application-defined chunk handlers.
-Improve setjmp/longjmp usage or remove it in favor of returning error codes.
-High-level API for reading images.
-Add "grayscale->palette" transformation and "palette->grayscale" detection.
-Color to gray transformation.
-Improved dithering.
-Multi-lingual error and warning message support.
-Complete sRGB transformation (presently it simply uses gamma=0.45455).
-Man pages for function calls.
-Better documentation.
-Better filter selection
- (counting huffman bits/precompression? filter inertia? filter costs?).
-Optional palette (sPLT) creation.
-Histogram creation.
-Text conversion between different code pages (Latin-1 -> Mac and DOS).
-Improve API by hiding the info_ptr.
+++ /dev/null
- Y2K compliance in libpng:
- =========================
-
- January 13, 1999
-
- Since the PNG Development group is an ad-hoc body, we can't make
- an official declaration.
-
- This is your unofficial assurance that libpng from version 0.81 and
- upward are Y2K compliant. It is my belief that earlier versions were
- also Y2K compliant.
-
- Libpng only has three year fields. One is a 2-byte unsigned integer
- that will hold years up to 65535. The other two hold the date in text
- format, and will hold years up to 9999.
-
- The integer is
- "png_uint_16 year" in png_time_struct.
-
- The strings are
- "png_charp time_buffer" in png_struct and
- "near_time_buffer", which is a local character string in png.c.
-
- There are seven time-related functions:
-
- png_convert_to_rfc_1123() in png.c
- (formerly png_convert_to_rfc_1152() in error)
- png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
- png_convert_from_time_t() in pngwrite.c
- png_get_tIME() in pngget.c
- png_handle_tIME() in pngrutil.c, called in pngread.c
- png_set_tIME() in pngset.c
- png_write_tIME() in pngwutil.c, called in pngwrite.c
-
- All appear to handle dates properly in a Y2K environment. The
- png_convert_from_time_t() function calls gmtime() to convert from system
- clock time, which returns (year - 1900), which we properly convert to
- the full 4-digit year. There is a possibility that applications using
- libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
- function, or incorrectly passing only a 2-digit year instead of
- "year - 1900" into the png_convert_from_struct_tm() function, but this
- is not under our control. The libpng documentation has always stated
- that it works with 4-digit years, and the APIs have been documented as
- such.
-
- The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned
- integer to hold the year, and can hold years as large as 65535.
-
-
- Glenn Randers-Pehrson
- libpng maintainer
- PNG Development Group
+++ /dev/null
-
-/* example.c - an example of using libpng */
-
-/* This is an example of how to use libpng to read and write PNG files.
- * The file libpng.txt is much more verbose then this. If you have not
- * read it, do so first. This was 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. For an example of a minimal
- * working PNG reader/writer, see pngtest.c, included in this distribution.
- */
-
-#include "png.h"
-
-/* Check to see if a file is a PNG file using png_sig_cmp(). png_sig_cmp()
- * returns zero if the image is a PNG and nonzero if it isn't a PNG.
- *
- * The function check_if_png() shown here, but not used, returns nonzero (true)
- * if the file can be opened and is a PNG, 0 (false) otherwise.
- *
- * If this call is successful, and you are going to keep the file open,
- * you should call png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); once
- * you have created the png_ptr, so that libpng knows your application
- * has read that many bytes from the start of the file. Make sure you
- * don't call png_set_sig_bytes() with more than 8 bytes read or give it
- * an incorrect number of bytes read, or you will either have read too
- * many bytes (your fault), or you are telling libpng to read the wrong
- * number of magic bytes (also your fault).
- *
- * Many applications already read the first 2 or 4 bytes from the start
- * of the image to determine the file type, so it would be easiest just
- * to pass the bytes to png_sig_cmp() or even skip that if you know
- * you have a PNG file, and call png_set_sig_bytes().
- */
-#define PNG_BYTES_TO_CHECK 4
-int check_if_png(char *file_name, FILE **fp)
-{
- char buf[PNG_BYTES_TO_CHECK];
-
- /* Open the prospective PNG file. */
- if ((*fp = fopen(file_name, "rb")) != NULL);
- return 0;
-
- /* Read in some of the signature bytes */
- if (fread(buf, 1, PNG_BYTES_TO_CHECK, *fp) != PNG_BYTES_TO_CHECK)
- return 0;
-
- /* Compare the first PNG_BYTES_TO_CHECK bytes of the signature.
- Return nonzero (true) if they match */
-
- return(!png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK));
-}
-
-/* Read a PNG file. You may want to return an error code if the read
- * fails (depending upon the failure). There are two "prototypes" given
- * here - one where we are given the filename, and we need to open the
- * file, and the other where we are given an open file (possibly with
- * some or all of the magic bytes read - see comments above).
- */
-#ifdef open_file /* prototype 1 */
-void read_png(char *file_name) /* We need to open the file */
-{
- png_structp png_ptr;
- png_infop info_ptr;
- unsigned int sig_read = 0;
- png_uint_32 width, height;
- int bit_depth, color_type, interlace_type;
- FILE *fp;
-
- if ((fp = fopen(file_name, "rb")) == NULL)
- return;
-#else no_open_file /* prototype 2 */
-void read_png(FILE *fp, unsigned int sig_read) /* file is already open */
-{
- png_structp png_ptr;
- png_infop info_ptr;
- png_uint_32 width, height;
- int bit_depth, color_type, interlace_type;
-#endif no_open_file /* only use one prototype! */
-
- /* Create and initialize the png_struct with the desired error handler
- * functions. If you want to use the default stderr and longjump method,
- * you can supply NULL for the last three parameters. We also supply the
- * the compiler header file version, so that we know if the application
- * was compiled with a compatible version of the library. REQUIRED
- */
- png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
- png_voidp user_error_ptr, user_error_fn, user_warning_fn);
-
- if (png_ptr == NULL)
- {
- fclose(fp);
- return;
- }
-
- /* Allocate/initialize the memory for image information. REQUIRED. */
- info_ptr = png_create_info_struct(png_ptr);
- if (info_ptr == NULL)
- {
- fclose(fp);
- png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
- return;
- }
-
- /* Set error handling if you are using the setjmp/longjmp method (this is
- * the normal method of doing things with libpng). REQUIRED unless you
- * set up your own error handlers in the png_create_read_struct() earlier.
- */
- if (setjmp(png_ptr->jmpbuf))
- {
- /* Free all of the memory associated with the png_ptr and info_ptr */
- png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
- fclose(fp);
- /* If we get here, we had a problem reading the file */
- return;
- }
-
- /* One of the following I/O initialization methods is REQUIRED */
-#ifdef streams /* PNG file I/O method 1 */
- /* Set up the input control if you are using standard C streams */
- png_init_io(png_ptr, fp);
-
-#else no_streams /* PNG file I/O method 2 */
- /* If you are using replacement read functions, instead of calling
- * png_init_io() here you would call:
- */
- png_set_read_fn(png_ptr, (void *)user_io_ptr, user_read_fn);
- /* where user_io_ptr is a structure you want available to the callbacks */
-#endif no_streams /* Use only one I/O method! */
-
- /* If we have already read some of the signature */
- png_set_sig_bytes(png_ptr, sig_read);
-
- /* The call to png_read_info() gives us all of the information from the
- * PNG file before the first IDAT (image data chunk). REQUIRED
- */
- png_read_info(png_ptr, info_ptr);
-
- png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
- &interlace_type, NULL, NULL);
-
-/**** Set up the data transformations you want. Note that these are all
- **** optional. Only call them if you want/need them. Many of the
- **** transformations only work on specific types of images, and many
- **** are mutually exclusive.
- ****/
-
- /* tell libpng to strip 16 bit/color files down to 8 bits/color */
- png_set_strip_16(png_ptr);
-
- /* Strip alpha bytes from the input data without combining with th
- * background (not recommended).
- */
- png_set_strip_alpha(png_ptr);
-
- /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
- * byte into separate bytes (useful for paletted and grayscale images).
- */
- png_set_packing(png_ptr);
-
- /* Change the order of packed pixels to least significant bit first
- * (not useful if you are using png_set_packing). */
- png_set_packswap(png_ptr);
-
- /* Expand paletted colors into true RGB triplets */
- if (color_type == PNG_COLOR_TYPE_PALETTE)
- png_set_expand(png_ptr);
-
- /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */
- if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
- png_set_expand(png_ptr);
-
- /* Expand paletted or RGB images with transparency to full alpha channels
- * so the data will be available as RGBA quartets.
- */
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
- png_set_expand(png_ptr);
-
- /* Set the background color to draw transparent and alpha images over.
- * It is possible to set the red, green, and blue components directly
- * for paletted images instead of supplying a palette index. Note that
- * even if the PNG file supplies a background, you are not required to
- * use it - you should use the (solid) application background if it has one.
- */
-
- png_color_16 my_background, *image_background;
-
- if (png_get_bKGD(png_ptr, info_ptr, &image_background))
- png_set_background(png_ptr, image_background,
- PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
- else
- png_set_background(png_ptr, &my_background,
- PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
-
- /* Some suggestions as to how to get a screen gamma value */
-
- /* Note that screen gamma is (display_gamma/viewing_gamma) */
- if (/* We have a user-defined screen gamma value */)
- {
- screen_gamma = user-defined screen_gamma;
- }
- /* This is one way that applications share the same screen gamma value */
- else if ((gamma_str = getenv("SCREEN_GAMMA")) != NULL)
- {
- screen_gamma = atof(gamma_str);
- }
- /* If we don't have another value */
- else
- {
- screen_gamma = 2.2; /* A good guess for a PC monitors in a dimly
- lit room */
- screen_gamma = 1.7 or 1.0; /* A good guess for Mac systems */
- }
-
- /* Tell libpng to handle the gamma conversion for you. The second call
- * is a good guess for PC generated images, but it should be configurable
- * by the user at run time by the user. It is strongly suggested that
- * your application support gamma correction.
- */
-
- int intent;
-
- if (png_get_sRGB(png_ptr, info_ptr, &intent))
- png_set_sRGB(png_ptr, intent, 0);
- else
- {
- double image_gamma;
- if (png_get_gAMA(png_ptr, info_ptr, &image_gamma))
- png_set_gamma(png_ptr, screen_gamma, image_gamma);
- else
- png_set_gamma(png_ptr, screen_gamma, 0.45455);
- }
-
- /* Dither RGB files down to 8 bit palette or reduce palettes
- * to the number of colors available on your screen.
- */
- if (color_type & PNG_COLOR_MASK_COLOR)
- {
- png_uint_32 num_palette;
- png_colorp palette;
-
- /* This reduces the image to the application supplied palette */
- if (/* we have our own palette */)
- {
- /* An array of colors to which the image should be dithered */
- png_color std_color_cube[MAX_SCREEN_COLORS];
-
- png_set_dither(png_ptr, std_color_cube, MAX_SCREEN_COLORS,
- MAX_SCREEN_COLORS, NULL, 0);
- }
- /* This reduces the image to the palette supplied in the file */
- else if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette))
- {
- png_color16p histogram;
-
- png_get_hIST(png_ptr, info_ptr, &histogram);
-
- png_set_dither(png_ptr, palette, num_palette,
- max_screen_colors, histogram, 0);
- }
- }
-
- /* invert monocrome files to have 0 as white and 1 as black */
- png_set_invert_mono(png_ptr);
-
- /* If you want to shift the pixel values from the range [0,255] or
- * [0,65535] to the original [0,7] or [0,31], or whatever range the
- * colors were originally in:
- */
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
- {
- png_color8p sig_bit;
-
- png_get_sBIT(png_ptr, info_ptr, &sig_bit);
- png_set_shift(png_ptr, sig_bit);
- }
-
- /* flip the RGB pixels to BGR (or RGBA to BGRA) */
- png_set_bgr(png_ptr);
-
- /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
- png_set_swap_alpha(png_ptr);
-
- /* swap bytes of 16 bit files to least significant byte first */
- png_set_swap(png_ptr);
-
- /* Add filler (or alpha) byte (before/after each RGB triplet) */
- png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
-
- /* Turn on interlace handling. REQUIRED if you are not using
- * png_read_image(). To see how to handle interlacing passes,
- * see the png_read_row() method below:
- */
- number_passes = png_set_interlace_handling(png_ptr);
-
- /* Optional call to gamma correct and add the background to the palette
- * and update info structure. REQUIRED if you are expecting libpng to
- * update the palette for you (ie you selected such a transform above).
- */
- png_read_update_info(png_ptr, info_ptr);
-
- /* Allocate the memory to hold the image using the fields of info_ptr. */
-
- /* The easiest way to read the image: */
- png_bytep row_pointers[height];
-
- for (row = 0; row < height; row++)
- {
- row_pointers[row] = malloc(png_get_rowbytes(png_ptr, info_ptr));
- }
-
- /* Now it's time to read the image. One of these methods is REQUIRED */
-#ifdef entire /* Read the entire image in one go */
- png_read_image(png_ptr, row_pointers);
-
-#else no_entire /* Read the image one or more scanlines at a time */
- /* The other way to read images - deal with interlacing: */
-
- for (pass = 0; pass < number_passes; pass++)
- {
-#ifdef single /* Read the image a single row at a time */
- for (y = 0; y < height; y++)
- {
- png_read_rows(png_ptr, &row_pointers[y], NULL, 1);
- }
-
-#else no_single /* Read the image several rows at a time */
- for (y = 0; y < height; y += number_of_rows)
- {
-#ifdef sparkle /* Read the image using the "sparkle" effect. */
- png_read_rows(png_ptr, &row_pointers[y], NULL, number_of_rows);
-
- png_read_rows(png_ptr, NULL, row_pointers[y], number_of_rows);
-#else no_sparkle /* Read the image using the "rectangle" effect */
- png_read_rows(png_ptr, NULL, &row_pointers[y], number_of_rows);
-#endif no_sparkle /* use only one of these two methods */
- }
-
- /* if you want to display the image after every pass, do
- so here */
-#endif no_single /* use only one of these two methods */
- }
-#endif no_entire /* use only one of these two methods */
-
- /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
- png_read_end(png_ptr, info_ptr);
-
- /* clean up after the read, and free any memory allocated - REQUIRED */
- png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
-
- /* close the file */
- fclose(fp);
-
- /* that's it */
- return;
-}
-
-/* progressively read a file */
-
-int
-initialize_png_reader(png_structp *png_ptr, png_infop *info_ptr)
-{
- /* Create and initialize the png_struct with the desired error handler
- * functions. If you want to use the default stderr and longjump method,
- * you can supply NULL for the last three parameters. We also check that
- * the library version is compatible in case we are using dynamically
- * linked libraries.
- */
- *png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
- png_voidp user_error_ptr, user_error_fn, user_warning_fn);
-
- if (*png_ptr == NULL)
- {
- *info_ptr = NULL;
- return ERROR;
- }
-
- *info_ptr = png_create_info_struct(png_ptr);
-
- if (*info_ptr == NULL)
- {
- png_destroy_read_struct(png_ptr, info_ptr, (png_infopp)NULL);
- return ERROR;
- }
-
- if (setjmp((*png_ptr)->jmpbuf))
- {
- png_destroy_read_struct(png_ptr, info_ptr, (png_infopp)NULL);
- return ERROR;
- }
-
- /* This one's new. You will need to provide all three
- * function callbacks, even if you aren't using them all.
- * If you aren't using all functions, you can specify NULL
- * parameters. Even when all three functions are NULL,
- * you need to call png_set_progressive_read_fn().
- * These functions shouldn't be dependent on global or
- * static variables if you are decoding several images
- * simultaneously. You should store stream specific data
- * in a separate struct, given as the second parameter,
- * and retrieve the pointer from inside the callbacks using
- * the function png_get_progressive_ptr(png_ptr).
- */
- png_set_progressive_read_fn(*png_ptr, (void *)stream_data,
- info_callback, row_callback, end_callback);
-
- return OK;
-}
-
-int
-process_data(png_structp *png_ptr, png_infop *info_ptr,
- png_bytep buffer, png_uint_32 length)
-{
- if (setjmp((*png_ptr)->jmpbuf))
- {
- /* Free the png_ptr and info_ptr memory on error */
- png_destroy_read_struct(png_ptr, info_ptr, (png_infopp)NULL);
- return ERROR;
- }
-
- /* This one's new also. Simply give it chunks of data as
- * they arrive from the data stream (in order, of course).
- * On Segmented machines, don't give it any more than 64K.
- * The library seems to run fine with sizes of 4K, although
- * you can give it much less if necessary (I assume you can
- * give it chunks of 1 byte, but I haven't tried with less
- * than 256 bytes yet). When this function returns, you may
- * want to display any rows that were generated in the row
- * callback, if you aren't already displaying them there.
- */
- png_process_data(*png_ptr, *info_ptr, buffer, length);
- return OK;
-}
-
-info_callback(png_structp png_ptr, png_infop info)
-{
-/* do any setup here, including setting any of the transformations
- * mentioned in the Reading PNG files section. For now, you _must_
- * call either png_start_read_image() or png_read_update_info()
- * after all the transformations are set (even if you don't set
- * any). You may start getting rows before png_process_data()
- * returns, so this is your last chance to prepare for that.
- */
-}
-
-row_callback(png_structp png_ptr, png_bytep new_row,
- png_uint_32 row_num, int pass)
-{
-/* this function is called for every row in the image. If the
- * image is interlacing, and you turned on the interlace handler,
- * this function will be called for every row in every pass.
- * Some of these rows will not be changed from the previous pass.
- * When the row is not changed, the new_row variable will be NULL.
- * The rows and passes are called in order, so you don't really
- * need the row_num and pass, but I'm supplying them because it
- * may make your life easier.
- *
- * For the non-NULL rows of interlaced images, you must call
- * png_progressive_combine_row() passing in the row and the
- * old row. You can call this function for NULL rows (it will
- * just return) and for non-interlaced images (it just does the
- * memcpy for you) if it will make the code easier. Thus, you
- * can just do this for all cases:
- */
-
- png_progressive_combine_row(png_ptr, old_row, new_row);
-
-/* where old_row is what was displayed for previous rows. Note
- * that the first pass (pass == 0 really) will completely cover
- * the old row, so the rows do not have to be initialized. After
- * the first pass (and only for interlaced images), you will have
- * to pass the current row, and the function will combine the
- * old row and the new row.
- */
-}
-
-end_callback(png_structp png_ptr, png_infop info)
-{
-/* this function is called when the whole image has been read,
- * including any chunks after the image (up to and including
- * the IEND). You will usually have the same info chunk as you
- * had in the header, although some data may have been added
- * to the comments and time fields.
- *
- * Most people won't do much here, perhaps setting a flag that
- * marks the image as finished.
- */
-}
-
-/* write a png file */
-void write_png(char *file_name /* , ... other image information ... */)
-{
- FILE *fp;
- png_structp png_ptr;
- png_infop info_ptr;
-
- /* open the file */
- fp = fopen(file_name, "wb");
- if (fp == NULL)
- return;
-
- /* Create and initialize the png_struct with the desired error handler
- * functions. If you want to use the default stderr and longjump method,
- * you can supply NULL for the last three parameters. We also check that
- * the library version is compatible with the one used at compile time,
- * in case we are using dynamically linked libraries. REQUIRED.
- */
- png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
- png_voidp user_error_ptr, user_error_fn, user_warning_fn);
-
- if (png_ptr == NULL)
- {
- fclose(fp);
- return;
- }
-
- /* Allocate/initialize the image information data. REQUIRED */
- info_ptr = png_create_info_struct(png_ptr);
- if (info_ptr == NULL)
- {
- fclose(fp);
- png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
- return;
- }
-
- /* Set error handling. REQUIRED if you aren't supplying your own
- * error hadnling functions in the png_create_write_struct() call.
- */
- if (setjmp(png_ptr->jmpbuf))
- {
- /* If we get here, we had a problem reading the file */
- fclose(fp);
- png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
- return;
- }
-
- /* One of the following I/O initialization functions is REQUIRED */
-#ifdef streams /* I/O initialization method 1 */
- /* set up the output control if you are using standard C streams */
- png_init_io(png_ptr, fp);
-#else no_streams /* I/O initialization method 2 */
- /* If you are using replacement read functions, instead of calling
- * png_init_io() here you would call */
- png_set_write_fn(png_ptr, (void *)user_io_ptr, user_write_fn,
- user_IO_flush_function);
- /* where user_io_ptr is a structure you want available to the callbacks */
-#endif no_streams /* only use one initialization method */
-
- /* Set the image information here. Width and height are up to 2^31,
- * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
- * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
- * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
- * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or
- * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
- * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
- */
- png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, PNG_COLOR_TYPE_???,
- PNG_INTERLACE_????, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
-
- /* set the palette if there is one. REQUIRED for indexed-color images */
- palette = (png_colorp)png_malloc(png_ptr, 256 * sizeof (png_color));
- /* ... set palette colors ... */
- png_set_PLTE(png_ptr, info_ptr, palette, 256);
-
- /* optional significant bit chunk */
- /* if we are dealing with a grayscale image then */
- sig_bit.gray = true_bit_depth;
- /* otherwise, if we are dealing with a color image then */
- sig_bit.red = true_red_bit_depth;
- sig_bit.green = true_green_bit_depth;
- sig_bit.blue = true_blue_bit_depth;
- /* if the image has an alpha channel then */
- sig_bit.alpha = true_alpha_bit_depth;
- png_set_sBIT(png_ptr, info_ptr, sig_bit);
-
-
- /* Optional gamma chunk is strongly suggested if you have any guess
- * as to the correct gamma of the image.
- */
- png_set_gAMA(png_ptr, info_ptr, gamma);
-
- /* Optionally write comments into the image */
- text_ptr[0].key = "Title";
- text_ptr[0].text = "Mona Lisa";
- text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
- text_ptr[1].key = "Author";
- text_ptr[1].text = "Leonardo DaVinci";
- text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;
- text_ptr[2].key = "Description";
- text_ptr[2].text = "<long text>";
- text_ptr[2].compression = PNG_TEXT_COMPRESSION_zTXt;
- png_set_text(png_ptr, info_ptr, text_ptr, 3);
-
- /* other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs, */
- /* note that if sRGB is present the cHRM chunk must be ignored
- * on read and must be written in accordance with the sRGB profile */
-
- /* Write the file header information. REQUIRED */
- png_write_info(png_ptr, info_ptr);
-
- /* Once we write out the header, the compression type on the text
- * chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or
- * PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again
- * at the end.
- */
-
- /* set up the transformations you want. Note that these are
- * all optional. Only call them if you want them.
- */
-
- /* invert monocrome pixels */
- png_set_invert_mono(png_ptr);
-
- /* Shift the pixels up to a legal bit depth and fill in
- * as appropriate to correctly scale the image.
- */
- png_set_shift(png_ptr, &sig_bit);
-
- /* pack pixels into bytes */
- png_set_packing(png_ptr);
-
- /* swap location of alpha bytes from ARGB to RGBA */
- png_set_swap_alpha(png_ptr);
-
- /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into
- * RGB (4 channels -> 3 channels). The second parameter is not used.
- */
- png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
-
- /* flip BGR pixels to RGB */
- png_set_bgr(png_ptr);
-
- /* swap bytes of 16-bit files to most significant byte first */
- png_set_swap(png_ptr);
-
- /* swap bits of 1, 2, 4 bit packed pixel formats */
- png_set_packswap(png_ptr);
-
- /* 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 (you may have a different memory
- * layout, however, so choose what fits your needs best). You need to
- * use the first method if you aren't handling interlacing yourself.
- */
- png_uint_32 k, height, width;
- png_byte image[height][width];
- png_bytep row_pointers[height];
- for (k = 0; k < height; k++)
- row_pointers[k] = image + k*width;
-
- /* One of the following output methods is REQUIRED */
-#ifdef entire /* write out the entire image data in one call */
- png_write_image(png_ptr, row_pointers);
-
- /* the other way to write the image - deal with interlacing */
-
-#else no_entire /* write out the image data by one or more scanlines */
- /* The number of passes is either 1 for non-interlaced images,
- * or 7 for interlaced images.
- */
- for (pass = 0; pass < number_passes; pass++)
- {
- /* Write a few rows at a time. */
- png_write_rows(png_ptr, &row_pointers[first_row], number_of_rows);
-
- /* If you are only writing one row at a time, this works */
- for (y = 0; y < height; y++)
- {
- png_write_rows(png_ptr, &row_pointers[y], 1);
- }
- }
-#endif no_entire /* use only one output method */
-
- /* You can write optional chunks like tEXt, zTXt, and tIME at the end
- * as well.
- */
-
- /* It is REQUIRED to call this to finish writing the rest of the file */
- png_write_end(png_ptr, info_ptr);
-
- /* if you malloced the palette, free it here */
- free(info_ptr->palette);
-
- /* if you allocated any text comments, free them here */
-
- /* clean up after the write, and free any memory allocated */
- png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
-
- /* close the file */
- fclose(fp);
-
- /* that's it */
- return;
-}
-
+++ /dev/null
-.TH LIBPNG 3 "January 14, 1999"
-.SH NAME
-libpng \- Portable Network Graphics (PNG) Reference Library 1.0.3 - January 14, 1999
-.SH SYNOPSIS
-
-#include <png.h>
-
-int png_check_sig (png_bytep sig, int num);
-
-void png_chunk_error (png_structp png_ptr, png_const_charp
-error);
-
-void png_chunk_warning (png_structp png_ptr, png_const_charp
-message);
-
-void png_convert_from_struct_tm (png_timep ptime, struct tm FAR
-* ttime);
-
-void png_convert_from_time_t (png_timep ptime, time_t ttime);
-
-png_charp png_convert_to_rfc1123 (png_structp png_ptr,
-png_timep ptime);
-
-png_infop png_create_info_struct (png_structp png_ptr);
-
-png_structp png_create_read_struct (png_const_charp
-user_png_ver, voidp error_ptr, png_error_ptr error_fn,
-png_error_ptr warn_fn);
-
-png_structp png_create_read_struct_2(png_const_charp user_png_ver,
-png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr
-warn_fn, png_voidp mem_ptr, png_malloc_ptr malloc_fn,
-png_free_ptr free_fn)
-
-png_structp png_create_write_struct (png_const_charp
-user_png_ver, voidp error_ptr, png_error_ptr error_fn,
-png_error_ptr warn_fn);
-
-png_structp png_create_write_struct_2(png_const_charp
-user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
-png_error_ptr warn_fn, png_voidp mem_ptr,
-png_malloc_ptr malloc_fn, png_free_ptr free_fn)
-
-int png_debug(int level, png_const_charp message)
-
-int png_debug1(int level, png_const_charp message, p1)
-
-int png_debug2(int level, png_const_charp message, p1, p2)
-
-void png_destroy_info_struct (png_structp png_ptr, png_infopp
-info_ptr_ptr);
-
-void png_destroy_read_struct (png_structpp png_ptr_ptr,
-png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr);
-
-void png_destroy_write_struct (png_structpp png_ptr_ptr,
-png_infopp info_ptr_ptr);
-
-void png_error (png_structp png_ptr, png_const_charp error);
-
-void png_free (png_structp png_ptr, png_voidp ptr);
-
-void png_free_default(png_structp png_ptr, png_voidp ptr)
-
-png_byte png_get_bit_depth (png_structp png_ptr, png_infop
-info_ptr);
-
-png_uint_32 png_get_bKGD (png_structp png_ptr, png_infop
-info_ptr, png_color_16p *background);
-
-png_byte png_get_channels (png_structp png_ptr, png_infop
-info_ptr);
-
-png_uint_32 png_get_cHRM (png_structp png_ptr, png_infop
-info_ptr, double *white_x, double *white_y, double *red_x,
-double *red_y, double *green_x, double *green_y, double
-*blue_x, double *blue_y);
-
-png_byte png_get_color_type (png_structp png_ptr, png_infop
-info_ptr);
-
-png_byte png_get_compression_type (png_structp png_ptr,
-png_infop info_ptr);
-
-png_byte png_get_copyright (png_structp png_ptr);
-
-png_voidp png_get_error_ptr (png_structp png_ptr);
-
-png_byte png_get_filter_type (png_structp png_ptr, png_infop
-info_ptr);
-
-png_uint_32 png_get_gAMA (png_structp png_ptr, png_infop
-info_ptr, double *file_gamma);
-
-png_byte png_get_header_version (png_structp png_ptr);
-
-png_uint_32 png_get_hIST (png_structp png_ptr, png_infop
-info_ptr, png_uint_16p *hist);
-
-png_uint_32 png_get_IHDR (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 *width, png_uint_32 *height, int
-*bit_depth, int *color_type, int *interlace_type, int
-*compression_type, int *filter_type);
-
-png_uint_32 png_get_image_height (png_structp png_ptr,
-png_infop info_ptr);
-
-png_uint_32 png_get_image_width (png_structp png_ptr, png_infop
-info_ptr);
-
-png_byte png_get_interlace_type (png_structp png_ptr, png_infop
-info_ptr);
-
-png_voidp png_get_io_ptr (png_structp png_ptr);
-
-png_voidp png_get_mem_ptr(png_structp png_ptr)
-
-png_uint_32 png_get_oFFs (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 *offset_x, png_uint_32 *offset_y, int
-*unit_type);
-
-png_uint_32 png_get_pCAL (png_structp png_ptr, png_infop
-info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1,
-int *type, int *nparams, png_charp *units, png_charpp *params);
-
-png_uint_32 png_get_pHYs (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int
-*unit_type);
-
-float png_get_pixel_aspect_ratio (png_structp png_ptr,
-png_infop info_ptr);
-
-png_uint_32 png_get_pixels_per_meter (png_structp png_ptr,
-png_infop info_ptr);
-
-png_voidp png_get_progressive_ptr (png_structp png_ptr);
-
-png_uint_32 png_get_PLTE (png_structp png_ptr, png_infop
-info_ptr, png_colorp *palette, int *num_palette);
-
-png_byte png_get_rgb_to_gray_status (png_structp png_ptr)
-
-png_uint_32 png_get_rowbytes (png_structp png_ptr, png_infop
-info_ptr);
-
-png_uint_32 png_get_sBIT (png_structp png_ptr, png_infop
-info_ptr, png_color_8p *sig_bit);
-
-png_bytep png_get_signature (png_structp png_ptr, png_infop
-info_ptr);
-
-png_uint_32 png_get_sRGB (png_structp png_ptr, png_infop
-info_ptr, int *intent);
-
-png_uint_32 png_get_text (png_structp png_ptr, png_infop
-info_ptr, png_textp *text_ptr, int *num_text);
-
-png_uint_32 png_get_tIME (png_structp png_ptr, png_infop
-info_ptr, png_timep *mod_time);
-
-png_uint_32 png_get_tRNS (png_structp png_ptr, png_infop
-info_ptr, png_bytep *trans, int *num_trans, png_color_16p
-*trans_values);
-
-png_uint_32 png_get_valid (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 flag);
-
-png_uint_32 png_get_x_offset_microns (png_structp png_ptr,
-png_infop info_ptr);
-
-png_uint_32 png_get_x_offset_pixels (png_structp png_ptr,
-png_infop info_ptr);
-
-png_uint_32 png_get_x_pixels_per_meter (png_structp png_ptr,
-png_infop info_ptr);
-
-png_uint_32 png_get_y_offset_microns (png_structp png_ptr,
-png_infop info_ptr);
-
-png_uint_32 png_get_y_offset_pixels (png_structp png_ptr,
-png_infop info_ptr);
-
-png_uint_32 png_get_y_pixels_per_meter (png_structp png_ptr,
-png_infop info_ptr);
-
-void png_info_init (png_infop info_ptr);
-
-void png_init_io (png_structp png_ptr, FILE *fp);
-
-png_voidp png_malloc (png_structp png_ptr, png_uint_32 size);
-
-png_voidp png_malloc_default(png_structp png_ptr,
-png_uint_32 size)
-
-voidp png_memcpy (png_voidp s1, png_voidp s2, png_size_t size);
-
-png_voidp png_memcpy_check (png_structp png_ptr, png_voidp s1,
-png_voidp s2, png_uint_32 size);
-
-voidp png_memset (png_voidp s1, int value, png_size_t size);
-
-png_voidp png_memset_check (png_structp png_ptr, png_voidp
-s1, int value, png_uint_32 size);
-
-void png_process_data (png_structp png_ptr, png_infop info_ptr,
-png_bytep buffer, png_size_t buffer_size);
-
-void png_progressive_combine_row (png_structp png_ptr,
-png_bytep old_row, png_bytep new_row);
-
-void png_read_destroy (png_structp png_ptr, png_infop info_ptr,
-png_infop end_info_ptr);
-
-void png_read_end (png_structp png_ptr, png_infop info_ptr);
-
-void png_read_image (png_structp png_ptr, png_bytepp image);
-
-void png_read_info (png_structp png_ptr, png_infop info_ptr);
-
-void png_read_row (png_structp png_ptr, png_bytep row,
-png_bytep display_row);
-
-void png_read_rows (png_structp png_ptr, png_bytepp row,
-png_bytepp display_row, png_uint_32 num_rows);
-
-void png_read_update_info (png_structp png_ptr, png_infop
-info_ptr);
-
-void png_set_background (png_structp png_ptr, png_color_16p
-background_color, int background_gamma_code, int need_expand,
-double background_gamma);
-
-void png_set_bgr (png_structp png_ptr);
-
-void png_set_bKGD (png_structp png_ptr, png_infop info_ptr,
-png_color_16p background);
-
-void png_set_cHRM (png_structp png_ptr, png_infop info_ptr,
-double white_x, double white_y, double red_x, double red_y,
-double green_x, double green_y, double blue_x, double blue_y);
-
-void png_set_compression_level (png_structp png_ptr, int
-level);
-
-void png_set_compression_mem_level (png_structp png_ptr, int
-mem_level);
-
-void png_set_compression_method (png_structp png_ptr, int
-method);
-
-void png_set_compression_strategy (png_structp png_ptr, int
-strategy);
-
-void png_set_compression_window_bits (png_structp png_ptr, int
-window_bits);
-
-void png_set_crc_action (png_structp png_ptr, int crit_action,
-int ancil_action);
-
-void png_set_dither (png_structp png_ptr, png_colorp palette,
-int num_palette, int maximum_colors, png_uint_16p histogram,
-int full_dither);
-
-void png_set_error_fn (png_structp png_ptr, png_voidp
-error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn);
-
-void png_set_expand (png_structp png_ptr);
-
-void png_set_filler (png_structp png_ptr, png_uint_32 filler,
-int flags);
-
-void png_set_filter (png_structp png_ptr, int method, int
-filters);
-
-void png_set_filter_heuristics (png_structp png_ptr, int
-heuristic_method, int num_weights, png_doublep filter_weights,
-png_doublep filter_costs);
-
-void png_set_flush (png_structp png_ptr, int nrows);
-
-void png_set_gamma (png_structp png_ptr, double screen_gamma,
-double default_file_gamma);
-
-void png_set_gAMA (png_structp png_ptr, png_infop info_ptr,
-double file_gamma);
-
-void png_set_gray_to_rgb (png_structp png_ptr);
-
-void png_set_hIST (png_structp png_ptr, png_infop info_ptr,
-png_uint_16p hist);
-
-int png_set_interlace_handling (png_structp png_ptr);
-
-void png_set_invert_alpha (png_structp png_ptr);
-
-void png_set_invert_mono (png_structp png_ptr);
-
-void png_set_IHDR (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 width, png_uint_32 height, int bit_depth, int
-color_type, int interlace_type, int compression_type, int
-filter_type);
-
-void png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr,
-png_malloc_ptr malloc_fn, png_free_ptr free_fn)
-
-void png_set_oFFs (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 offset_x, png_uint_32 offset_y, int unit_type);
-
-void png_set_packing (png_structp png_ptr);
-
-void png_set_packswap (png_structp png_ptr);
-
-void png_set_pCAL (png_structp png_ptr, png_infop info_ptr,
-png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int
-nparams, png_charp units, png_charpp params);
-
-void png_set_pHYs (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 res_x, png_uint_32 res_y, int unit_type);
-
-void png_set_progressive_read_fn (png_structp png_ptr,
-png_voidp progressive_ptr, png_progressive_info_ptr info_fn,
-png_progressive_row_ptr row_fn, png_progressive_end_ptr
-end_fn);
-
-void png_set_PLTE (png_structp png_ptr, png_infop info_ptr,
-png_colorp palette, int num_palette);
-
-void png_set_read_fn (png_structp png_ptr, png_voidp io_ptr,
-png_rw_ptr read_data_fn);
-
-void png_set_read_status_fn (png_structp png_ptr, png_read_status_ptr
-read_row_fn);
-
-void png_set_read_user_transform_fn (png_structp png_ptr,
-png_user_transform_ptr read_user_transform_fn);
-
-void png_set_rgb_to_gray (png_structp png_ptr, int error_action);
-
-void png_set_sBIT (png_structp png_ptr, png_infop info_ptr,
-png_color_8p sig_bit);
-
-void png_set_shift (png_structp png_ptr, png_color_8p
-true_bits);
-
-void png_set_sig_bytes (png_structp png_ptr, int num_bytes);
-
-void png_set_sRGB (png_structp png_ptr, png_infop info_ptr, int
-intent);
-
-void png_set_sRGB_gAMA_and_cHRM (png_structp png_ptr, png_infop
-info_ptr, int intent);
-
-void png_set_strip_16 (png_structp png_ptr);
-
-void png_set_strip_alpha (png_structp png_ptr);
-
-void png_set_swap (png_structp png_ptr);
-
-void png_set_swap_alpha (png_structp png_ptr);
-
-void png_set_text (png_structp png_ptr, png_infop info_ptr,
-png_textp text_ptr, int num_text);
-
-void png_set_tIME (png_structp png_ptr, png_infop info_ptr,
-png_timep mod_time);
-
-void png_set_tRNS (png_structp png_ptr, png_infop info_ptr,
-png_bytep trans, int num_trans, png_color_16p trans_values);
-
-void png_set_write_fn (png_structp png_ptr, png_voidp io_ptr,
-png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn);
-
-void png_set_write_status_fn (png_structp png_ptr, png_write_status_ptr
-write_row_fn);
-
-void png_set_write_user_transform_fn (png_structp png_ptr,
-png_user_transform_ptr write_user_transform_fn);
-
-int png_sig_cmp (png_bytep sig, png_size_t start, png_size_t
-num_to_check);
-
-void png_start_read_image (png_structp png_ptr);
-
-void png_warning (png_structp png_ptr, png_const_charp
-message);
-
-void png_write_chunk (png_structp png_ptr, png_bytep
-chunk_name, png_bytep data, png_size_t length);
-
-void png_write_chunk_data (png_structp png_ptr, png_bytep data,
-png_size_t length);
-
-void png_write_chunk_end (png_structp png_ptr);
-
-void png_write_chunk_start (png_structp png_ptr, png_bytep
-chunk_name, png_uint_32 length);
-
-void png_write_destroy (png_structp png_ptr);
-
-void png_write_destroy_info (png_infop info_ptr);
-
-void png_write_end (png_structp png_ptr, png_infop info_ptr);
-
-void png_write_flush (png_structp png_ptr);
-
-void png_write_image (png_structp png_ptr, png_bytepp image);
-
-void png_write_info (png_structp png_ptr, png_infop info_ptr);
-
-void png_write_row (png_structp png_ptr, png_bytep row);
-
-void png_write_rows (png_structp png_ptr, png_bytepp row,
-png_uint_32 num_rows);
-
-.SH DESCRIPTION
-The
-.I libpng
-library supports encoding, decoding, and various manipulations of
-the Portable Network Graphics (PNG) format image files. It uses the
-.IR zlib(3)
-compression library.
-Following is a copy of the libpng.txt file that accompanies libpng.
-.SH LIBPNG.TXT
-libpng.txt - A description on how to use and modify libpng
-
- libpng version 1.0.3 - January 14, 1999
- Updated and distributed by Glenn Randers-Pehrson
- <randeg@alumni.rpi.edu>
- Copyright (c) 1998, 1999 Glenn Randers-Pehrson
- For conditions of distribution and use, see copyright
- notice in png.h.
-
- based on:
-
- libpng 1.0 beta 6 version 0.96 May 28, 1997
- Updated and distributed by Andreas Dilger
- Copyright (c) 1996, 1997 Andreas Dilger
-
- libpng 1.0 beta 2 - version 0.88 January 26, 1996
- For conditions of distribution and use, see copyright
- notice in png.h. Copyright (c) 1995, 1996 Guy Eric
- Schalnat, Group 42, Inc.
-
- Updated/rewritten per request in the libpng FAQ
- Copyright (c) 1995 Frank J. T. Wojcik
- December 18, 1995 && January 20, 1996
-
-.SH I. Introduction
-
-This file describes how to use and modify the PNG reference library
-(known as libpng) for your own use. There are five sections to this
-file: introduction, structures, reading, writing, and modification and
-configuration notes for various special platforms. In addition to this
-file, example.c is a good starting point for using the library, as
-it is heavily commented and should include everything most people
-will need. We assume that libpng is already installed; see the
-INSTALL file for instructions on how to install libpng.
-
-Libpng was written as a companion to the PNG specification, as a way
-of reducing the amount of time and effort it takes to support the PNG
-file format in application programs. The PNG specification is available
-as RFC 2083 <ftp://ftp.uu.net/graphics/png/documents/> and as a
-W3C Recommendation <http://www.w3.org/TR/REC.png.html>. Some
-additional chunks are described in the special-purpose public chunks
-documents at <ftp://ftp.uu.net/graphics/png/documents/>. Other information
-about PNG, and the latest version of libpng, can be found at the PNG home
-page, <http://www.cdrom.com/pub/png/>.
-
-Most users will not have to modify the library significantly; advanced
-users may want to modify it more. All attempts were made to make it as
-complete as possible, while keeping the code easy to understand.
-Currently, this library only supports C. Support for other languages
-is being considered.
-
-Libpng has been designed to handle multiple sessions at one time,
-to be easily modifiable, to be portable to the vast majority of
-machines (ANSI, K&R, 16-, 32-, and 64-bit) available, and to be easy
-to use. The ultimate goal of libpng is to promote the acceptance of
-the PNG file format in whatever way possible. While there is still
-work to be done (see the TODO file), libpng should cover the
-majority of the needs of its users.
-
-Libpng uses zlib for its compression and decompression of PNG files.
-Further information about zlib, and the latest version of zlib, can
-be found at the zlib home page, <http://www.cdrom.com/pub/infozip/zlib/>.
-The zlib compression utility is a general purpose utility that is
-useful for more than PNG files, and can be used without libpng.
-See the documentation delivered with zlib for more details.
-You can usually find the source files for the zlib utility wherever you
-find the libpng source files.
-
-Libpng is thread safe, provided the threads are using different
-instances of the structures. Each thread should have its own
-png_struct and png_info instances, and thus its own image.
-Libpng does not protect itself against two threads using the
-same instance of a structure.
-
-
-.SH II. Structures
-
-There are two main structures that are important to libpng, png_struct
-and png_info. The first, png_struct, is an internal structure that
-will not, for the most part, be used by a user except as the first
-variable passed to every libpng function call.
-
-The png_info structure is designed to provide information about the
-PNG file. At one time, the fields of png_info were intended to be
-directly accessible to the user. However, this tended to cause problems
-with applications using dynamically loaded libraries, and as a result
-a set of interface functions for png_info was developed. The fields
-of png_info are still available for older applications, but it is
-suggested that applications use the new interfaces if at all possible.
-
-The png.h header file is an invaluable reference for programming with libpng.
-And while I'm on the topic, make sure you include the libpng header file:
-
-#include <png.h>
-
-.SH III. Reading
-
-Reading PNG files:
-
-We'll now walk you through the possible functions to call when reading
-in a PNG file, briefly explaining the syntax and purpose of each one.
-See example.c and png.h for more detail. While Progressive reading
-is covered in the next section, you will still need some of the
-functions discussed in this section to read a PNG file.
-
-You will want to do the I/O initialization(*) before you get into libpng,
-so if it doesn't work, you don't have much to undo. Of course, you
-will also want to insure that you are, in fact, dealing with a PNG
-file. Libpng provides a simple check to see if a file is a PNG file.
-To use it, pass in the first 1 to 8 bytes of the file, and it will
-return true or false (1 or 0) depending on whether the bytes could be
-part of a PNG file. Of course, the more bytes you pass in, the
-greater the accuracy of the prediction.
-
-If you are intending to keep the file pointer open for use in libpng,
-you must ensure you don't read more than 8 bytes from the beginning
-of the file, and you also have to make a call to png_set_sig_bytes_read()
-with the number of bytes you read from the beginning. Libpng will
-then only check the bytes (if any) that your program didn't read.
-
-(*): If you are not using the standard I/O functions, you will need
-to replace them with custom functions. See the discussion under
-Customizing libpng.
-
-
- FILE *fp = fopen(file_name, "rb");
- if (!fp)
- {
- return;
- }
- fread(header, 1, number, fp);
- is_png = !png_sig_cmp(header, 0, number);
- if (!is_png)
- {
- return;
- }
-
-
-Next, png_struct and png_info need to be allocated and initialized. In
-order to ensure that the size of these structures is correct even with a
-dynamically linked libpng, there are functions to initialize and
-allocate the structures. We also pass the library version, optional
-pointers to error handling functions, and a pointer to a data struct for
-use by the error functions, if necessary (the pointer and functions can
-be NULL if the default error handlers are to be used). See the section
-on Changes to Libpng below regarding the old initialization functions.
-
- png_structp png_ptr = png_create_read_struct
- (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
- user_error_fn, user_warning_fn);
- if (!png_ptr)
- return;
-
- png_infop info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr)
- {
- png_destroy_read_struct(&png_ptr,
- (png_infopp)NULL, (png_infopp)NULL);
- return;
- }
-
- png_infop end_info = png_create_info_struct(png_ptr);
- if (!end_info)
- {
- png_destroy_read_struct(&png_ptr, &info_ptr,
- (png_infopp)NULL);
- return;
- }
-
-If you want to use your own memory allocation routines,
-define PNG_USER_MEM_SUPPORTED and use
-png_create_read_struct_2() instead of png_create_read_struct():
-
- png_structp png_ptr = png_create_read_struct_2
- (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
- user_error_fn, user_warning_fn, (png_voidp)
- user_mem_ptr, user_malloc_fn, user_free_fn);
-
-The error handling routines passed to png_create_read_struct()
-and the memory alloc/free routines passed to png_create_struct_2()
-are only necessary if you are not using the libpng supplied error
-handling and memory alloc/free functions.
-
-When libpng encounters an error, it expects to longjmp back
-to your routine. Therefore, you will need to call setjmp and pass
-your png_ptr->jmpbuf. If you read the file from different
-routines, you will need to update the jmpbuf field every time you enter
-a new routine that will call a png_ function.
-
-See your documentation of setjmp/longjmp for your compiler for more
-handling in the Customizing Libpng section below for more information on
-the libpng error handling. If an error occurs, and libpng longjmp's
-back to your setjmp, you will want to call png_destroy_read_struct() to
-free any memory.
-
- if (setjmp(png_ptr->jmpbuf))
- {
- png_destroy_read_struct(&png_ptr, &info_ptr,
- &end_info);
- fclose(fp);
- return;
- }
-
-Now you need to set up the input code. The default for libpng is to
-use the C function fread(). If you use this, you will need to pass a
-valid FILE * in the function png_init_io(). Be sure that the file is
-opened in binary mode. If you wish to handle reading data in another
-way, you need not call the png_init_io() function, but you must then
-implement the libpng I/O methods discussed in the Customizing Libpng
-section below.
-
- png_init_io(png_ptr, fp);
-
-If you had previously opened the file and read any of the signature from
-the beginning in order to see if this was a PNG file, you need to let
-libpng know that there are some bytes missing from the start of the file.
-
- png_set_sig_bytes(png_ptr, number);
-
-At this point, you can set up a callback function that will be
-called after each row has been read, which you can use to control
-a progress meter or the like. It's demonstrated in pngtest.c.
-You must supply a function
-
- void read_row_callback(png_ptr, png_uint_32 row, int pass);
- {
- /* put your code here */
- }
-
-(You can give it another name that you like instead of "read_row_callback")
-
-To inform libpng about your function, use
-
- png_set_read_status_fn(png_ptr, read_row_callback);
-
-In PNG files, the alpha channel in an image is the level of opacity.
-If you need the alpha channel in an image to be the level of transparency
-instead of opacity, you can invert the alpha channel (or the tRNS chunk
-data) after it's read, so that 0 is fully opaque and 255 (in 8-bit or
-paletted images) or 65535 (in 16-bit images) is fully transparent, with
-
- png_set_invert_alpha(png_ptr);
-
-This has to appear here rather than later with the other transformations
-because the tRNS chunk data must be modified in the case of paletted images.
-If your image is not a paletted image, the tRNS data (which in such cases
-represents a single color to be rendered as transparent) won't be changed.
-
-Finally, you can write your own transformation function if none of
-the existing ones meets your needs. This is done by setting a callback
-with
-
- png_set_read_user_transform_fn(png_ptr,
- read_transform_fn);
-
-You must supply the function
-
- void read_transform_fn(png_ptr ptr, row_info_ptr
- row_info, png_bytep data)
-
-See pngtest.c for a working example. Your function will be called
-after all of the other transformations have been processed.
-
-You are now ready to read all the file information up to the actual
-image data. You do this with a call to png_read_info().
-
- png_read_info(png_ptr, info_ptr);
-
-Functions are used to get the information from the info_ptr:
-
- png_get_IHDR(png_ptr, info_ptr, &width, &height,
- &bit_depth, &color_type, &interlace_type,
- &compression_type, &filter_type);
-
- width - holds the width of the image
- in pixels (up to 2^31).
- height - holds the height of the image
- in pixels (up to 2^31).
- bit_depth - holds the bit depth of one of the
- image channels. (valid values are
- 1, 2, 4, 8, 16 and depend also on
- the color_type. See also
- significant bits (sBIT) below).
- color_type - describes which color/alpha channels
- are present.
- PNG_COLOR_TYPE_GRAY
- (bit depths 1, 2, 4, 8, 16)
- PNG_COLOR_TYPE_GRAY_ALPHA
- (bit depths 8, 16)
- PNG_COLOR_TYPE_PALETTE
- (bit depths 1, 2, 4, 8)
- PNG_COLOR_TYPE_RGB
- (bit_depths 8, 16)
- PNG_COLOR_TYPE_RGB_ALPHA
- (bit_depths 8, 16)
-
- PNG_COLOR_MASK_PALETTE
- PNG_COLOR_MASK_COLOR
- PNG_COLOR_MASK_ALPHA
-
- filter_type - (must be PNG_FILTER_TYPE_BASE
- for PNG 1.0)
- compression_type - (must be PNG_COMPRESSION_TYPE_BASE
- for PNG 1.0)
- interlace_type - (PNG_INTERLACE_NONE or
- PNG_INTERLACE_ADAM7)
- Any or all of interlace_type, compression_type, of
- filter_type can be
- NULL if you are not interested in their values.
-
- channels = png_get_channels(png_ptr, info_ptr);
- channels - number of channels of info for the
- color type (valid values are 1 (GRAY,
- PALETTE), 2 (GRAY_ALPHA), 3 (RGB),
- 4 (RGB_ALPHA or RGB + filler byte))
- rowbytes = png_get_rowbytes(png_ptr, info_ptr);
- rowbytes - number of bytes needed to hold a row
-
- signature = png_get_signature(png_ptr, info_ptr);
- signature - holds the signature read from the
- file (if any). The data is kept in
- the same offset it would be if the
- whole signature were read (i.e. if an
- application had already read in 4
- bytes of signature before starting
- libpng, the remaining 4 bytes would
- be in signature[4] through signature[7]
- (see png_set_sig_bytes())).
-
-
- width = png_get_image_width(png_ptr,
- info_ptr);
- height = png_get_image_height(png_ptr,
- info_ptr);
- bit_depth = png_get_bit_depth(png_ptr,
- info_ptr);
- color_type = png_get_color_type(png_ptr,
- info_ptr);
- filter_type = png_get_filter_type(png_ptr,
- info_ptr);
- compression_type = png_get_compression_type(png_ptr,
- info_ptr);
- interlace_type = png_get_interlace_type(png_ptr,
- info_ptr);
-
-
-These are also important, but their validity depends on whether the chunk
-has been read. The png_get_valid(png_ptr, info_ptr, PNG_INFO_<chunk>) and
-png_get_<chunk>(png_ptr, info_ptr, ...) functions return non-zero if the
-data has been read, or zero if it is missing. The parameters to the
-png_get_<chunk> are set directly if they are simple data types, or a pointer
-into the info_ptr is returned for any complex types.
-
- png_get_PLTE(png_ptr, info_ptr, &palette,
- &num_palette);
- palette - the palette for the file
- (array of png_color)
- num_palette - number of entries in the palette
-
- png_get_gAMA(png_ptr, info_ptr, &gamma);
- gamma - the gamma the file is written
- at (PNG_INFO_gAMA)
-
- png_get_sRGB(png_ptr, info_ptr, &srgb_intent);
- srgb_intent - the rendering intent (PNG_INFO_sRGB)
- The presence of the sRGB chunk
- means that the pixel data is in the
- sRGB color space. This chunk also
- implies specific values of gAMA and
- cHRM.
-
- png_get_sBIT(png_ptr, info_ptr, &sig_bit);
- sig_bit - the number of significant bits for
- (PNG_INFO_sBIT) each of the gray,
- red, green, and blue channels,
- whichever are appropriate for the
- given color type (png_color_16)
-
- png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans,
- &trans_values);
- trans - array of transparent entries for
- palette (PNG_INFO_tRNS)
- trans_values - transparent pixel for non-paletted
- images (PNG_INFO_tRNS)
- num_trans - number of transparent entries
- (PNG_INFO_tRNS)
-
- png_get_hIST(png_ptr, info_ptr, &hist);
- (PNG_INFO_hIST)
- hist - histogram of palette (array of
- png_color_16)
-
- png_get_tIME(png_ptr, info_ptr, &mod_time);
- mod_time - time image was last modified
- (PNG_VALID_tIME)
-
- png_get_bKGD(png_ptr, info_ptr, &background);
- background - background color (PNG_VALID_bKGD)
-
- num_text = png_get_text(png_ptr, info_ptr, &text_ptr);
- text_ptr - array of png_text holding image
- comments
- text_ptr[i]->key - keyword for comment.
- text_ptr[i]->text - text comments for current
- keyword.
- text_ptr[i]->compression - type of compression used
- on "text" PNG_TEXT_COMPRESSION_NONE
- or PNG_TEXT_COMPRESSION_zTXt
- num_text - number of comments
-
- png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y,
- &unit_type);
- offset_x - positive offset from the left edge
- of the screen
- offset_y - positive offset from the top edge
- of the screen
- unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER
-
- png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y,
- &unit_type);
- res_x - pixels/unit physical resolution in
- x direction
- res_y - pixels/unit physical resolution in
- x direction
- unit_type - PNG_RESOLUTION_UNKNOWN,
- PNG_RESOLUTION_METER
-
-The data from the pHYs chunk can be retrieved in several convenient
-forms:
-
- res_x = png_get_x_pixels_per_meter(png_ptr,
- info_ptr)
- res_y = png_get_y_pixels_per_meter(png_ptr,
- info_ptr)
- res_x_and_y = png_get_pixels_per_meter(png_ptr,
- info_ptr)
- aspect_ratio = png_get_pixel_aspect_ratio(png_ptr,
- info_ptr)
-
- (Each of these returns 0 [signifying "unknown"] if
- the data is not present or if res_x is 0;
- res_x_and_y is 0 if res_x != res_y)
-
-For more information, see the png_info definition in png.h and the
-PNG specification for chunk contents. Be careful with trusting
-rowbytes, as some of the transformations could increase the space
-needed to hold a row (expand, filler, gray_to_rgb, etc.).
-See png_read_update_info(), below.
-
-A quick word about text_ptr and num_text. PNG stores comments in
-keyword/text pairs, one pair per chunk, with no limit on the number
-of text chunks, and a 2^31 byte limit on their size. While there are
-suggested keywords, there is no requirement to restrict the use to these
-strings. It is strongly suggested that keywords and text be sensible
-to humans (that's the point), so don't use abbreviations. Non-printing
-symbols are not allowed. See the PNG specification for more details.
-There is also no requirement to have text after the keyword.
-
-Keywords should be limited to 79 Latin-1 characters without leading or
-trailing spaces, but non-consecutive spaces are allowed within the
-keyword. It is possible to have the same keyword any number of times.
-The text_ptr is an array of png_text structures, each holding pointer
-to a keyword and a pointer to a text string. Only the text string may
-be null. The keyword/text pairs are put into the array in the order
-that they are received. However, some or all of the text chunks may be
-after the image, so, to make sure you have read all the text chunks,
-don't mess with these until after you read the stuff after the image.
-This will be mentioned again below in the discussion that goes with
-png_read_end().
-
-After you've read the header information, you can set up the library
-to handle any special transformations of the image data. The various
-ways to transform the data will be described in the order that they
-should occur. This is important, as some of these change the color
-type and/or bit depth of the data, and some others only work on
-certain color types and bit depths. Even though each transformation
-checks to see if it has data that it can do something with, you should
-make sure to only enable a transformation if it will be valid for the
-data. For example, don't swap red and blue on grayscale data.
-
-The colors used for the background and transparency values should be
-supplied in the same format/depth as the current image data. They
-are stored in the same format/depth as the image data in a bKGD or tRNS
-chunk, so this is what libpng expects for this data. The colors are
-transformed to keep in sync with the image data when an application
-calls the png_read_update_info() routine (see below).
-
-Data will be decoded into the supplied row buffers packed into bytes
-unless the library has been told to transform it into another format.
-For example, 4 bit/pixel paletted or grayscale data will be returned
-2 pixels/byte with the leftmost pixel in the high-order bits of the
-byte, unless png_set_packing() is called. 8-bit RGB data will be stored
-in RGB RGB RGB format unless png_set_filler() is called to insert filler
-bytes, either before or after each RGB triplet. 16-bit RGB data will
-be returned RRGGBB RRGGBB, with the most significant byte of the color
-value first, unless png_set_strip_16() is called to transform it to
-regular RGB RGB triplets, or png_set_filler() is called to insert
-filler bytes, either before or after each RRGGBB triplet. Similarly,
-8-bit or 16-bit grayscale data can be modified with png_set_filler()
-or png_set_strip_16().
-
-The following code transforms grayscale images of less than 8 to 8 bits,
-changes paletted images to RGB, and adds a full alpha channel if there is
-transparency information in a tRNS chunk. This is most useful on
-grayscale images with bit depths of 2 or 4 or if there is a multiple-image
-viewing application that wishes to treat all images in the same way.
-
- if (color_type == PNG_COLOR_TYPE_PALETTE &&
- bit_depth <= 8) png_set_expand(png_ptr);
-
- if (color_type == PNG_COLOR_TYPE_GRAY &&
- bit_depth < 8) png_set_expand(png_ptr);
-
- if (png_get_valid(png_ptr, info_ptr,
- PNG_INFO_tRNS)) png_set_expand(png_ptr);
-
-PNG can have files with 16 bits per channel. If you only can handle
-8 bits per channel, this will strip the pixels down to 8 bit.
-
- if (bit_depth == 16)
- png_set_strip_16(png_ptr);
-
-The png_set_background() function tells libpng to composite images
-with alpha or simple transparency against the supplied background
-color. If the PNG file contains a bKGD chunk (PNG_INFO_bKGD valid),
-you may use this color, or supply another color more suitable for
-the current display (e.g., the background color from a web page). You
-need to tell libpng whether the color is in the gamma space of the
-display (PNG_BACKGROUND_GAMMA_SCREEN for colors you supply), the file
-(PNG_BACKGROUND_GAMMA_FILE for colors from the bKGD chunk), or one
-that is neither of these gammas (PNG_BACKGROUND_GAMMA_UNIQUE - I don't
-know why anyone would use this, but it's here).
-
-If, for some reason, you don't need the alpha channel on an image,
-and you want to remove it rather than combining it with the background
-(but the image author certainly had in mind that you *would* combine
-it with the background, so that's what you should probably do):
-
- if (color_type & PNG_COLOR_MASK_ALPHA)
- png_set_strip_alpha(png_ptr);
-
-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. This code expands to 1 pixel per byte without changing the
-values of the pixels:
-
- if (bit_depth < 8)
- png_set_packing(png_ptr);
-
-PNG files have possible bit depths of 1, 2, 4, 8, and 16. All pixels
-stored in a PNG image have been "scaled" or "shifted" up to the next
-higher possible bit depth (e.g. from 5 bits/sample in the range [0,31] to
-8 bits/sample in the range [0, 255]). However, it is also possible to
-convert the PNG pixel data back to the original bit depth of the image.
-This call reduces the pixels back down to the original bit depth:
-
- png_color_16p sig_bit;
-
- if (png_get_sBIT(png_ptr, info_ptr, &sig_bit))
- png_set_shift(png_ptr, sig_bit);
-
-PNG files store 3-color pixels in red, green, blue order. This code
-changes the storage of the pixels to blue, green, red:
-
- if (color_type == PNG_COLOR_TYPE_RGB ||
- color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- png_set_bgr(png_ptr);
-
-PNG files store RGB pixels packed into 3 bytes. This code expands them
-into 4 bytes for windowing systems that need them in this format:
-
- if (bit_depth == 8 && color_type ==
- PNG_COLOR_TYPE_RGB) png_set_filler(png_ptr,
- filler, PNG_FILLER_BEFORE);
-
-where "filler" is the 8 or 16-bit 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. This transformation
-does not affect images that already have full alpha channels.
-
-If you are reading an image with an alpha channel, and you need the
-data as ARGB instead of the normal PNG format RGBA:
-
- if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- png_set_swap_alpha(png_ptr);
-
-For some uses, you may want a grayscale image to be represented as
-RGB. This code will do that conversion:
-
- if (color_type == PNG_COLOR_TYPE_GRAY ||
- color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- png_set_gray_to_rgb(png_ptr);
-
-Conversely, you can convert an RGB or RGBA image to grayscale or grayscale
-with alpha. This is intended for conversion of images that really are
-gray (red == green == blue), so the function simply strips out the red
-and blue channels, leaving the green channel in the gray position.
-
- if (color_type == PNG_COLOR_TYPE_RGB ||
- color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- png_set_rgb_to_gray(png_ptr, error_action,
- float red_weight, float green_weight);
-
- error_action = 1: silently do the conversion
- error_action = 2: issue a warning if the original
- image has any pixel where
- red != green or red != blue
- error_action = 3: issue an error and abort the
- conversion if the original
- image has any pixel where
- red != green or red != blue
-
- red_weight: weight of red component
- (NULL -> default 54/256)
- green_weight: weight of green component
- (NULL -> default 183/256)
-
-If you have set error_action = 1 or 2, you can
-later check whether the image really was gray, after processing
-the image rows, with the png_get_rgb_to_gray_status(png_ptr) function.
-It will return a png_byte that is zero if the image was gray or
-1 if there were any non-gray pixels. bKGD and sBIT data
-will be silently converted to grayscale, using the green channel
-data, regardless of the error_action setting.
-
-With 0.0<=red_weight+green_weight<=1.0,
-the normalized graylevel is computed:
-
- int rw = red_weight * 256;
- int gw = green_weight * 256;
- int bw = 256 - (rw + gw);
- gray = (rw*red + gw*green + bw*blue)/256;
-
-The default values approximate those recommended in the Charles
-Poynton's Color FAQ, <http://www.inforamp.net/~poynton/>
-Copyright (c) 1998-01-04 Charles Poynton poynton@inforamp.net
-
- Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
-
-Libpng approximates this with
-
- Y = 0.211 * R + 0.715 * G + 0.074 * B
-
-which can be expressed with integers as
-
- Y = (54 * R + 183 * G + 19 * B)/256
-
-The calculation is done in a linear colorspace, if the image gamma
-is known.
-
-If you have a grayscale and you are using png_set_expand() to change to
-a higher bit-depth, you must either supply the background color as a gray
-value at the original file bit-depth (need_expand = 1) or else supply the
-background color as an RGB triplet at the final, expanded bit depth
-(need_expand = 0). Similarly, if you are reading a paletted image, you
-must either supply the background color as a palette index (need_expand = 1)
-or as an RGB triplet that may or may not be in the palette (need_expand = 0).
-
- png_color_16 my_background;
- png_color_16p image_background;
-
- if (png_get_bKGD(png_ptr, info_ptr, &image_background))
- png_set_background(png_ptr, image_background,
- PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
- else
- png_set_background(png_ptr, &my_background,
- PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
-
-To properly display PNG images on any kind of system, the application needs
-to know what the display gamma is. Ideally, the user will know this, and
-the application will allow them to set it. One method of allowing the user
-to set the display gamma separately for each system is to check for the
-DISPLAY_GAMMA and VIEWING_GAMMA environment variables or for a SCREEN_GAMMA
-environment variable, which will hopefully be correctly set.
-
-Note that display_gamma is the gamma of your display, while screen_gamma is
-the overall gamma correction required to produce pleasing results,
-which depends on the lighting conditions in the surrounding environment.
-Screen_gamma is display_gamma/viewing_gamma, where viewing_gamma is
-the amount of additional gamma correction needed to compensate for
-a (viewing_gamma=1.25) environment. In a dim or brightly lit room, no
-compensation other than the display_gamma is needed (viewing_gamma=1.0).
-
- if (/* We have a user-defined screen
- gamma value */)
- {
- screen_gamma = user_defined_screen_gamma;
- }
- /* One way that applications can share the same
- screen gamma value */
- else if ((gamma_str = getenv("SCREEN_GAMMA"))
- != NULL)
- {
- screen_gamma = atof(gamma_str);
- }
- /* If we don't have another value */
- else
- {
- screen_gamma = 2.2; /* A good guess for a
- PC monitor in a bright office or a dim room */
- screen_gamma = 2.0; /* A good guess for a
- PC monitor in a dark room */
- screen_gamma = 1.7 or 1.0; /* A good
- guess for Mac systems */
- }
-
-The png_set_gamma() function handles gamma transformations of the data.
-Pass both the file gamma and the current screen_gamma. If the file does
-not have a gamma value, you can pass one anyway if you have an idea what
-it is (usually 0.45455 is a good guess for GIF images on PCs). Note
-that file gammas are inverted from screen gammas. See the discussions
-on gamma in the PNG specification for an excellent description of what
-gamma is, and why all applications should support it. It is strongly
-recommended that PNG viewers support gamma correction.
-
- if (png_get_gAMA(png_ptr, info_ptr, &gamma))
- png_set_gamma(png_ptr, screen_gamma, gamma);
- else
- png_set_gamma(png_ptr, screen_gamma, 0.45455);
-
-If you need to reduce an RGB file to a paletted file, or if a paletted
-file has more entries then will fit on your screen, png_set_dither()
-will do that. Note that this is a simple match dither that merely
-finds the closest color available. This should work fairly well with
-optimized palettes, and fairly badly with linear color cubes. If you
-pass a palette that is larger then maximum_colors, the file will
-reduce the number of colors in the palette so it will fit into
-maximum_colors. If there is a histogram, it will use it to make
-more intelligent choices when reducing the palette. If there is no
-histogram, it may not do as good a job.
-
- if (color_type & PNG_COLOR_MASK_COLOR)
- {
- if (png_get_valid(png_ptr, info_ptr,
- PNG_INFO_PLTE))
- {
- png_color_16p histogram;
-
- png_get_hIST(png_ptr, info_ptr,
- &histogram);
- png_set_dither(png_ptr, palette, num_palette,
- max_screen_colors, histogram, 1);
- }
- else
- {
- png_color std_color_cube[MAX_SCREEN_COLORS] =
- { ... colors ... };
-
- png_set_dither(png_ptr, std_color_cube,
- MAX_SCREEN_COLORS, MAX_SCREEN_COLORS,
- NULL,0);
- }
- }
-
-PNG files describe monochrome as black being zero and white being one.
-The following code will reverse this (make black be one and white be
-zero):
-
- if (bit_depth == 1 && color_type == PNG_COLOR_GRAY)
- png_set_invert_mono(png_ptr);
-
-PNG files store 16 bit pixels in network byte order (big-endian,
-ie. most significant bits first). This code changes the storage to the
-other way (little-endian, i.e. least significant bits first, the
-way PCs store them):
-
- if (bit_depth == 16)
- png_set_swap(png_ptr);
-
-If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you
-need to change the order the pixels are packed into bytes, you can use:
-
- if (bit_depth < 8)
- png_set_packswap(png_ptr);
-
-The last thing to handle is interlacing; this is covered in detail below,
-but you must call the function here if you want libpng to handle expansion
-of the interlaced image.
-
- number_of_passes = png_set_interlace_handling(png_ptr);
-
-After setting the transformations, libpng can update your png_info
-structure to reflect any transformations you've requested with this
-call. This is most useful to update the info structure's rowbytes
-field so you can use it to allocate your image memory. This function
-will also update your palette with the correct screen_gamma and
-background if these have been given with the calls above.
-
- 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. The row data is simply
-raw byte data for all forms of images. As the actual allocation
-varies among applications, no example will be given. If you
-are allocating one large chunk, you will need 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
-and put it in the memory area supplied. You will need to pass in
-an array of pointers to each row.
-
-This function automatically handles interlacing, so you don't need
-to call png_set_interlace_handling() or call this function multiple
-times, or any of that other stuff necessary with png_read_rows().
-
- png_read_image(png_ptr, row_pointers);
-
-where row_pointers is:
-
- png_bytep row_pointers[height];
-
-You can point to void or char or whatever you use for pixels.
-
-If you don't want to read in the whole image at once, you can
-use png_read_rows() instead. If there is no interlacing (check
-interlace_type == PNG_INTERLACE_NONE), this is simple:
-
- png_read_rows(png_ptr, row_pointers, NULL,
- number_of_rows);
-
-where row_pointers is the same as in the png_read_image() call.
-
-If you are doing this just one row at a time, you can do this with
-row_pointers:
-
- png_bytep row_pointers = row;
- png_read_row(png_ptr, &row_pointers, NULL);
-
-If the file is interlaced (info_ptr->interlace_type != 0), things get
-somewhat harder. The only current (PNG Specification version 1.0)
-interlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7)
-is a somewhat complicated 2D interlace scheme, known as Adam7, that
-breaks down an image into seven smaller images of varying size, based
-on an 8x8 grid.
-
-libpng can fill out those images or it can give them to you "as is".
-If you want them filled out, there are two ways to do that. The one
-mentioned in the PNG specification is to expand each pixel to cover
-those pixels that have not been read yet (the "rectangle" method).
-This results in a blocky image for the first pass, which gradually
-smooths out as more pixels are read. The other method is the "sparkle"
-method, where pixels are drawn only in their final locations, with the
-rest of the image remaining whatever colors they were initialized to
-before the start of the read. The first method usually looks better,
-but tends to be slower, as there are more pixels to put in the rows.
-
-If you don't want libpng to handle the interlacing details, just call
-png_read_rows() seven times to read in all seven images. Each of the
-images is a valid image by itself, or they can all be combined on an
-8x8 grid to form a single image (although if you intend to combine them
-you would be far better off using the libpng interlace handling).
-
-The first pass will return an image 1/8 as wide as the entire image
-(every 8th column starting in column 0) and 1/8 as high as the original
-(every 8th row starting in row 0), the second will be 1/8 as wide
-(starting in column 4) and 1/8 as high (also starting in row 0). The
-third pass will be 1/4 as wide (every 4th pixel starting in column 0) and
-1/8 as high (every 8th row starting in row 4), and the fourth pass will
-be 1/4 as wide and 1/4 as high (every 4th column starting in column 2,
-and every 4th row starting in row 0). The fifth pass will return an
-image 1/2 as wide, and 1/4 as high (starting at column 0 and row 2),
-while the sixth pass will be 1/2 as wide and 1/2 as high as the original
-(starting in column 1 and row 0). The seventh and final pass will be as
-wide as the original, and 1/2 as high, containing all of the odd
-numbered scanlines. Phew!
-
-If you want libpng to expand the images, call this before calling
-png_start_read_image() or png_read_update_info():
-
- if (interlace_type == PNG_INTERLACE_ADAM7)
- number_of_passes
- = png_set_interlace_handling(png_ptr);
-
-This will return the number of passes needed. Currently, this
-is seven, but may change if another interlace type is added.
-This function can be called even if the file is not interlaced,
-where it will return one pass.
-
-If you are not going to display the image after each pass, but are
-going to wait until the entire image is read in, use the sparkle
-effect. This effect is faster and the end result of either method
-is exactly the same. If you are planning on displaying the image
-after each pass, the "rectangle" effect is generally considered the
-better looking one.
-
-If you only want the "sparkle" effect, just call png_read_rows() as
-normal, with the third parameter NULL. Make sure you make pass over
-the image number_of_passes times, and you don't change the data in the
-rows between calls. You can change the locations of the data, just
-not the data. Each pass only writes the pixels appropriate for that
-pass, and assumes the data from previous passes is still valid.
-
- png_read_rows(png_ptr, row_pointers, NULL,
- number_of_rows);
-
-If you only want the first effect (the rectangles), do the same as
-before except pass the row buffer in the third parameter, and leave
-the second parameter NULL.
-
- png_read_rows(png_ptr, NULL, row_pointers,
- number_of_rows);
-
-After you are finished reading the image, you can finish reading
-the file. If you are interested in comments or time, which may be
-stored either before or after the image data, you should pass the
-separate png_info struct if you want to keep the comments from
-before and after the image separate. If you are not interested, you
-can pass NULL.
-
- png_read_end(png_ptr, end_info);
-
-When you are done, you can free all memory allocated by libpng like this:
-
- png_destroy_read_struct(&png_ptr, &info_ptr,
- &end_info);
-
-For a more compact example of reading a PNG image, see the file example.c.
-
-
-Reading PNG files progressively:
-
-The progressive reader is slightly different then the non-progressive
-reader. Instead of calling png_read_info(), png_read_rows(), and
-png_read_end(), you make one call to png_process_data(), which calls
-callbacks when it has the info, a row, or the end of the image. You
-set up these callbacks with png_set_progressive_read_fn(). You don't
-have to worry about the input/output functions of libpng, as you are
-giving the library the data directly in png_process_data(). I will
-assume that you have read the section on reading PNG files above,
-so I will only highlight the differences (although I will show
-all of the code).
-
-png_structp png_ptr;
-png_infop info_ptr;
-
- /* An example code fragment of how you would
- initialize the progressive reader in your
- application. */
- int
- initialize_png_reader()
- {
- png_ptr = png_create_read_struct
- (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
- user_error_fn, user_warning_fn);
- if (!png_ptr)
- return -1;
- info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr)
- {
- png_destroy_read_struct(&png_ptr, (png_infopp)NULL,
- (png_infopp)NULL);
- return -1;
- }
-
- if (setjmp(png_ptr->jmpbuf))
- {
- png_destroy_read_struct(&png_ptr, &info_ptr,
- (png_infopp)NULL);
- return -1;
- }
-
- /* This one's new. You can provide functions
- to be called when the header info is valid,
- when each row is completed, and when the image
- is finished. If you aren't using all functions,
- you can specify NULL parameters. Even when all
- three functions are NULL, you need to call
- png_set_progressive_read_fn(). You can use
- any struct as the user_ptr (cast to a void pointer
- for the function call), and retrieve the pointer
- from inside the callbacks using the function
-
- png_get_progressive_ptr(png_ptr);
-
- which will return a void pointer, which you have
- to cast appropriately.
- */
- png_set_progressive_read_fn(png_ptr, (void *)user_ptr,
- info_callback, row_callback, end_callback);
-
- return 0;
- }
-
- /* A code fragment that you call as you receive blocks
- of data */
- int
- process_data(png_bytep buffer, png_uint_32 length)
- {
- if (setjmp(png_ptr->jmpbuf))
- {
- png_destroy_read_struct(&png_ptr, &info_ptr,
- (png_infopp)NULL);
- return -1;
- }
-
- /* This one's new also. Simply give it a chunk
- of data from the file stream (in order, of
- course). On machines with segmented memory
- models machines, don't give it any more than
- 64K. The library seems to run fine with sizes
- of 4K. Although you can give it much less if
- necessary (I assume you can give it chunks of
- 1 byte, I haven't tried less then 256 bytes
- yet). When this function returns, you may
- want to display any rows that were generated
- in the row callback if you don't already do
- so there.
- */
- png_process_data(png_ptr, info_ptr, buffer, length);
- return 0;
- }
-
- /* This function is called (as set by
- png_set_progressive_read_fn() above) when enough data
- has been supplied so all of the header has been
- read.
- */
- void
- info_callback(png_structp png_ptr, png_infop info)
- {
- /* Do any setup here, including setting any of
- the transformations mentioned in the Reading
- PNG files section. For now, you _must_ call
- either png_start_read_image() or
- png_read_update_info() after all the
- transformations are set (even if you don't set
- any). You may start getting rows before
- png_process_data() returns, so this is your
- last chance to prepare for that.
- */
- }
-
- /* This function is called when each row of image
- data is complete */
- void
- row_callback(png_structp png_ptr, png_bytep new_row,
- png_uint_32 row_num, int pass)
- {
- /* If the image is interlaced, and you turned
- on the interlace handler, this function will
- be called for every row in every pass. Some
- of these rows will not be changed from the
- previous pass. When the row is not changed,
- the new_row variable will be NULL. The rows
- and passes are called in order, so you don't
- really need the row_num and pass, but I'm
- supplying them because it may make your life
- easier.
-
- For the non-NULL rows of interlaced images,
- you must call png_progressive_combine_row()
- passing in the row and the old row. You can
- call this function for NULL rows (it will just
- return) and for non-interlaced images (it just
- does the memcpy for you) if it will make the
- code easier. Thus, you can just do this for
- all cases:
- */
-
- png_progressive_combine_row(png_ptr, old_row,
- new_row);
-
- /* where old_row is what was displayed for
- previously for the row. Note that the first
- pass (pass == 0, really) will completely cover
- the old row, so the rows do not have to be
- initialized. After the first pass (and only
- for interlaced images), you will have to pass
- the current row, and the function will combine
- the old row and the new row.
- */
- }
-
- void
- end_callback(png_structp png_ptr, png_infop info)
- {
- /* This function is called after the whole image
- has been read, including any chunks after the
- image (up to and including the IEND). You
- will usually have the same info chunk as you
- had in the header, although some data may have
- been added to the comments and time fields.
-
- Most people won't do much here, perhaps setting
- a flag that marks the image as finished.
- */
- }
-
-
-
-.SH IV. Writing
-
-Much of this is very similar to reading. However, everything of
-importance is repeated here, so you won't have to constantly look
-back up in the reading section to understand writing.
-
-You will want to do the I/O initialization before you get into libpng,
-so if it doesn't work, you don't have anything to undo. If you are not
-using the standard I/O functions, you will need to replace them with
-custom writing functions. See the discussion under Customizing libpng.
-
- FILE *fp = fopen(file_name, "wb");
- if (!fp)
- {
- return;
- }
-
-Next, png_struct and png_info need to be allocated and initialized.
-As these can be both relatively large, you may not want to store these
-on the stack, unless you have stack space to spare. Of course, you
-will want to check if they return NULL. If you are also reading,
-you won't want to name your read structure and your write structure
-both "png_ptr"; you can call them anything you like, such as
-"read_ptr" and "write_ptr". Look at pngtest.c, for example.
-
- png_structp png_ptr = png_create_write_struct
- (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
- user_error_fn, user_warning_fn);
- if (!png_ptr)
- return;
-
- png_infop info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr)
- {
- png_destroy_write_struct(&png_ptr,
- (png_infopp)NULL);
- return;
- }
-
-If you want to use your own memory allocation routines,
-define PNG_USER_MEM_SUPPORTED and use
-png_create_write_struct_2() instead of png_create_read_struct():
-
- png_structp png_ptr = png_create_write_struct_2
- (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
- user_error_fn, user_warning_fn, (png_voidp)
- user_mem_ptr, user_malloc_fn, user_free_fn);
-
-After you have these structures, you will need to set up the
-error handling. When libpng encounters an error, it expects to
-longjmp() back to your routine. Therefore, you will need to call
-setjmp() and pass the png_ptr->jmpbuf. If you
-write the file from different routines, you will need to update
-the jmpbuf field every time you enter a new routine that will
-call a png_ function. See your documentation of setjmp/longjmp
-for your compiler for more information on setjmp/longjmp. See
-the discussion on libpng error handling in the Customizing Libpng
-section below for more information on the libpng error handling.
-
- if (setjmp(png_ptr->jmpbuf))
- {
- png_destroy_write_struct(&png_ptr, &info_ptr);
- fclose(fp);
- return;
- }
- ...
- return;
-
-Now you need to set up the output code. The default for libpng is to
-use the C function fwrite(). If you use this, you will need to pass a
-valid FILE * in the function png_init_io(). Be sure that the file is
-opened in binary mode. Again, if you wish to handle writing data in
-another way, see the discussion on libpng I/O handling in the Customizing
-Libpng section below.
-
- png_init_io(png_ptr, fp);
-
-At this point, you can set up a callback function that will be
-called after each row has been written, which you can use to control
-a progress meter or the like. It's demonstrated in pngtest.c.
-You must supply a function
-
- void write_row_callback(png_ptr, png_uint_32 row, int pass);
- {
- /* put your code here */
- }
-
-(You can give it another name that you like instead of "write_row_callback")
-
-To inform libpng about your function, use
-
- png_set_write_status_fn(png_ptr, write_row_callback);
-
-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 some 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 by
-not calling this function at all, as it has been tuned to deliver a good
-speed/compression ratio. The second parameter to png_set_filter() is
-the filter method, for which the only valid value is '0' (as of the
-October 1996 PNG specification, version 1.0). The third parameter is a
-flag that indicates which filter type(s) are to be tested for each
-scanline. See the Compression Library for details on the specific filter
-types.
-
-
- /* turn on or off filtering, and/or choose
- specific filters */
- png_set_filter(png_ptr, 0,
- PNG_FILTER_NONE | PNG_FILTER_SUB |
- PNG_FILTER_PAETH);
-
-The png_set_compression_???() functions interface to the zlib compression
-library, and should mostly be ignored unless you really know what you are
-doing. The only generally useful call is png_set_compression_level()
-which changes how much time zlib spends on trying to compress the image
-data. See the Compression Library for details on the compression levels.
-
- /* set the zlib compression level */
- png_set_compression_level(png_ptr,
- Z_BEST_COMPRESSION);
-
- /* set other zlib parameters */
- 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 time
-chunk (as of PNG Specification 1.0, anyway). See png_write_end() and
-the latest PNG specification for more information on that. If you
-wish to write them before the image, fill them in now, and flag that
-data as being valid. If you want to wait until after the data, don't
-fill them until png_write_end(). For all the fields in png_info and
-their data types, see png.h. For explanations of what the fields
-contain, see the PNG specification.
-
-Some of the more important parts of the png_info are:
-
- png_set_IHDR(png_ptr, info_ptr, width, height,
- bit_depth, color_type, interlace_type,
- compression_type, filter_type)
- width - holds the width of the image
- in pixels (up to 2^31).
- height - holds the height of the image
- in pixels (up to 2^31).
- bit_depth - holds the bit depth of one of the
- image channels.
- (valid values are 1, 2, 4, 8, 16
- and depend also on the
- color_type. See also significant
- bits (sBIT) below).
- color_type - describes which color/alpha
- channels are present.
- PNG_COLOR_TYPE_GRAY
- (bit depths 1, 2, 4, 8, 16)
- PNG_COLOR_TYPE_GRAY_ALPHA
- (bit depths 8, 16)
- PNG_COLOR_TYPE_PALETTE
- (bit depths 1, 2, 4, 8)
- PNG_COLOR_TYPE_RGB
- (bit_depths 8, 16)
- PNG_COLOR_TYPE_RGB_ALPHA
- (bit_depths 8, 16)
-
- PNG_COLOR_MASK_PALETTE
- PNG_COLOR_MASK_COLOR
- PNG_COLOR_MASK_ALPHA
-
- interlace_type - PNG_INTERLACE_NONE or
- PNG_INTERLACE_ADAM7
- compression_type - (must be
- PNG_COMPRESSION_TYPE_DEFAULT)
- filter_type - (must be PNG_FILTER_TYPE_DEFAULT)
-
- png_set_PLTE(png_ptr, info_ptr, palette,
- num_palette);
- palette - the palette for the file
- (array of png_color)
- num_palette - number of entries in the palette
-
- png_set_gAMA(png_ptr, info_ptr, gamma);
- gamma - the gamma the image was created
- at (PNG_INFO_gAMA)
-
- png_set_sRGB(png_ptr, info_ptr, srgb_intent);
- srgb_intent - the rendering intent
- (PNG_INFO_sRGB) The presence of
- the sRGB chunk means that the pixel
- data is in the sRGB color space.
- This chunk also implies specific
- values of gAMA and cHRM. Rendering
- intent is the CSS-1 property that
- has been defined by the International
- Color Consortium
- (http://www.color.org).
- It can be one of
- PNG_SRGB_INTENT_SATURATION,
- PNG_SRGB_INTENT_PERCEPTUAL,
- PNG_SRGB_INTENT_ABSOLUTE, or
- PNG_SRGB_INTENT_RELATIVE.
-
-
- png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr,
- srgb_intent);
- srgb_intent - the rendering intent
- (PNG_INFO_sRGB) The presence of the
- sRGB chunk means that the pixel
- data is in the sRGB color space.
- This function also causes gAMA and
- cHRM chunks with the specific values
- that are consistent with sRGB to be
- written.
-
- png_set_sBIT(png_ptr, info_ptr, sig_bit);
- sig_bit - the number of significant bits for
- (PNG_INFO_sBIT) each of the gray, red,
- green, and blue channels, whichever are
- appropriate for the given color type
- (png_color_16)
-
- png_set_tRNS(png_ptr, info_ptr, trans, num_trans,
- trans_values);
- trans - array of transparent entries for
- palette (PNG_INFO_tRNS)
- trans_values - transparent pixel for non-paletted
- images (PNG_INFO_tRNS)
- num_trans - number of transparent entries
- (PNG_INFO_tRNS)
-
- png_set_hIST(png_ptr, info_ptr, hist);
- (PNG_INFO_hIST)
- hist - histogram of palette (array of
- png_color_16)
-
- png_set_tIME(png_ptr, info_ptr, mod_time);
- mod_time - time image was last modified
- (PNG_VALID_tIME)
-
- png_set_bKGD(png_ptr, info_ptr, background);
- background - background color (PNG_VALID_bKGD)
-
- png_set_text(png_ptr, info_ptr, text_ptr, num_text);
- text_ptr - array of png_text holding image
- comments
- text_ptr[i]->key - keyword for comment.
- text_ptr[i]->text - text comments for current
- keyword.
- text_ptr[i]->compression - type of compression used
- on "text" PNG_TEXT_COMPRESSION_NONE or
- PNG_TEXT_COMPRESSION_zTXt
- num_text - number of comments in text_ptr
-
- png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y,
- unit_type);
- offset_x - positive offset from the left
- edge of the screen
- offset_y - positive offset from the top
- edge of the screen
- unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER
-
- png_set_pHYs(png_ptr, info_ptr, res_x, res_y,
- unit_type);
- res_x - pixels/unit physical resolution
- in x direction
- res_y - pixels/unit physical resolution
- in y direction
- unit_type - PNG_RESOLUTION_UNKNOWN,
- PNG_RESOLUTION_METER
-
-In PNG files, the alpha channel in an image is the level of opacity.
-If your data is supplied as a level of transparency, you can invert the
-alpha channel before you write it, so that 0 is fully transparent and 255
-(in 8-bit or paletted images) or 65535 (in 16-bit images) is fully opaque,
-with
-
- png_set_invert_alpha(png_ptr);
-
-This must appear here instead of later with the other transformations
-because in the case of paletted images the tRNS chunk data has to
-be inverted before the tRNS chunk is written. If your image is not a
-paletted image, the tRNS data (which in such cases represents a single
-color to be rendered as transparent) won't be changed.
-
-A quick word about text and num_text. text is an array of png_text
-structures. num_text is the number of valid structures in the array.
-If you want, you can use max_text to hold the size of the array, but
-libpng ignores it for writing (it does use it for reading). Each
-png_text structure holds a keyword-text value, and a compression type.
-The compression types have the same valid numbers as the compression
-types of the image data. Currently, the only valid number is zero.
-However, you can store text either compressed or uncompressed, unlike
-images, which always have to be compressed. So if you don't want the
-text compressed, set the compression type to PNG_TEXT_COMPRESSION_NONE.
-Until text gets around 1000 bytes, it is not worth compressing it.
-After the text has been written out to the file, the compression type
-is set to PNG_TEXT_COMPRESSION_NONE_WR or PNG_TEXT_COMPRESSION_zTXt_WR,
-so that it isn't written out again at the end (in case you are calling
-png_write_end() with the same struct.
-
-The keywords that are given in the PNG Specification are:
-
- Title Short (one line) title or
- caption for image
- Author Name of image's creator
- Description Description of image (possibly long)
- Copyright Copyright notice
- Creation Time Time of original image creation
- (usually RFC 1123 format, see below)
- Software Software used to create the image
- Disclaimer Legal disclaimer
- Warning Warning of nature of content
- Source Device used to create the image
- Comment Miscellaneous comment; conversion
- from other image format
-
-The keyword-text pairs work like this. Keywords should be short
-simple descriptions of what the comment is about. Some typical
-keywords are found in the PNG specification, as is some recommendations
-on keywords. You can repeat keywords in a file. You can even write
-some text before the image and some after. For example, you may want
-to put a description of the image before the image, but leave the
-disclaimer until after, so viewers working over modem connections
-don't have to wait for the disclaimer to go over the modem before
-they start seeing the image. Finally, keywords should be full
-words, not abbreviations. Keywords and text are in the ISO 8859-1
-(Latin-1) character set (a superset of regular ASCII) and can not
-contain NUL characters, and should not contain control or other
-unprintable characters. To make the comments widely readable, stick
-with basic ASCII, and avoid machine specific character set extensions
-like the IBM-PC character set. The keyword must be present, but
-you can leave off the text string on non-compressed pairs.
-Compressed pairs must have a text string, as only the text string
-is compressed anyway, so the compression would be meaningless.
-
-PNG supports modification time via the png_time structure. Two
-conversion routines are proved, png_convert_from_time_t() for
-time_t and png_convert_from_struct_tm() for struct tm. The
-time_t routine uses gmtime(). You don't have to use either of
-these, but if you wish to fill in the png_time structure directly,
-you should provide the time in universal time (GMT) if possible
-instead of your local time. Note that the year number is the full
-year (e.g. 1998, rather than 98 - PNG is year 2000 compliant!), and
-that months start with 1.
-
-If you want to store the time of the original image creation, you should
-use a plain tEXt chunk with the "Creation Time" keyword. This is
-necessary because the "creation time" of a PNG image is somewhat vague,
-depending on whether you mean the PNG file, the time the image was
-created in a non-PNG format, a still photo from which the image was
-scanned, or possibly the subject matter itself. In order to facilitate
-machine-readable dates, it is recommended that the "Creation Time"
-tEXt chunk use RFC 1123 format dates (e.g. "22 May 1997 18:07:10 GMT"),
-although this isn't a requirement. Unlike the tIME chunk, the
-"Creation Time" tEXt chunk is not expected to be automatically changed
-by the software. To facilitate the use of RFC 1123 dates, a function
-png_convert_to_rfc1123(png_timep) is provided to convert from PNG
-time to an RFC 1123 format string.
-
-You are now ready to write all the file information up to the actual
-image data. You do this with a call to png_write_info().
-
- png_write_info(png_ptr, info_ptr);
-
-After you've written the file information, you can set up the library
-to handle any special transformations of the image data. The various
-ways to transform the data will be described in the order that they
-should occur. This is important, as some of these change the color
-type and/or bit depth of the data, and some others only work on
-certain color types and bit depths. Even though each transformation
-checks to see if it has data that it can do something with, you should
-make sure to only enable a transformation if it will be valid for the
-data. For example, don't swap red and blue on grayscale data.
-
-PNG files store RGB pixels packed into 3 or 6 bytes. This code tells
-the library to expand the input data to 4 or 8 bytes per pixel
-(or expand 1 or 2-byte grayscale data to 2 or 4 bytes per pixel).
-
- png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
-
-where the 0 is the value that will be put in the 4th byte, and the
-location is either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending
-upon whether the filler byte is stored XRGB or RGBX.
-
-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.
-If the data is supplied at 1 pixel per byte, use this code, which will
-correctly pack the pixels into a single byte:
-
- png_set_packing(png_ptr);
-
-PNG files reduce possible bit depths to 1, 2, 4, 8, and 16. If your
-data is of another bit depth, you can write an sBIT chunk into the
-file so that decoders can get the original data if desired.
-
- /* Set the true bit depth of the image data */
- if (color_type & PNG_COLOR_MASK_COLOR)
- {
- sig_bit.red = true_bit_depth;
- sig_bit.green = true_bit_depth;
- sig_bit.blue = true_bit_depth;
- }
- else
- {
- sig_bit.gray = true_bit_depth;
- }
- if (color_type & PNG_COLOR_MASK_ALPHA)
- {
- sig_bit.alpha = true_bit_depth;
- }
-
- png_set_sBIT(png_ptr, info_ptr, &sig_bit);
-
-If the data is stored in the row buffer in a bit depth other than
-one supported by PNG (e.g. 3 bit data in the range 0-7 for a 4-bit PNG),
-this will scale the values to appear to be the correct bit depth as
-is required by PNG.
-
- png_set_shift(png_ptr, &sig_bit);
-
-PNG files store 16 bit pixels in network byte order (big-endian,
-ie. most significant bits first). This code would be used if they are
-supplied the other way (little-endian, i.e. least significant bits
-first, the way PCs store them):
-
- if (bit_depth > 8)
- png_set_swap(png_ptr);
-
-If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you
-need to change the order the pixels are packed into bytes, you can use:
-
- if (bit_depth < 8)
- png_set_packswap(png_ptr);
-
-PNG files store 3 color pixels in red, green, blue order. This code
-would be used if they are supplied as blue, green, red:
-
- png_set_bgr(png_ptr);
-
-PNG files describe monochrome as black being zero and white being
-one. This code would be used if the pixels are supplied with this reversed
-(black being one and white being zero):
-
- png_set_invert_mono(png_ptr);
-
-Finally, you can write your own transformation function if none of
-the existing ones meets your needs. This is done by setting a callback
-with
-
- png_set_write_user_transform_fn(png_ptr,
- write_transform_fn);
-
-You must supply the function
-
- void write_transform_fn(png_ptr ptr, row_info_ptr
- row_info, png_bytep data)
-
-See pngtest.c for a working example. Your function will be called
-before any of the other transformations have been processed.
-
-It is possible to have libpng flush any pending output, either manually,
-or automatically after a certain number of lines have been written. To
-flush the output stream a single time call:
-
- png_write_flush(png_ptr);
-
-and to have libpng flush the output stream periodically after a certain
-number of scanlines have been written, call:
-
- png_set_flush(png_ptr, nrows);
-
-Note that the distance between rows is from the last time png_write_flush()
-was called, or the first row of the image if it has never been called.
-So if you write 50 lines, and then png_set_flush 25, it will flush the
-output on the next scanline, and every 25 lines thereafter, unless
-png_write_flush() is called before 25 more lines have been written.
-If nrows is too small (less than about 10 lines for a 640 pixel wide
-RGB image) the image compression may decrease noticeably (although this
-may be acceptable for real-time applications). Infrequent flushing will
-only degrade the compression performance by a few percent over images
-that do not use flushing.
-
-That's it for the transformations. Now you can write the image data.
-The simplest way to do this is in one function call. If have the
-whole image in memory, you can just call png_write_image() and libpng
-will write the image. You will need to pass in an array of pointers to
-each row. This function automatically handles interlacing, so you don't
-need to call png_set_interlace_handling() or call this function multiple
-times, or any of that other stuff necessary with png_write_rows().
-
- png_write_image(png_ptr, row_pointers);
-
-where row_pointers is:
-
- png_byte *row_pointers[height];
-
-You can point to void or char or whatever you use for pixels.
-
-If you don't want to write the whole image at once, you can
-use png_write_rows() instead. If the file is not interlaced,
-this is simple:
-
- png_write_rows(png_ptr, row_pointers,
- number_of_rows);
-
-row_pointers is the same as in the png_write_image() call.
-
-If you are just writing one row at a time, you can do this with
-row_pointers:
-
- png_bytep row_pointer = row;
-
- png_write_row(png_ptr, &row_pointer);
-
-When the file is interlaced, things can get a good deal more
-complicated. The only currently (as of February 1998 -- PNG Specification
-version 1.0, dated October 1996) defined interlacing scheme for PNG files
-is the "Adam7" interlace scheme, that breaks down an
-image into seven smaller images of varying size. libpng will build
-these images for you, or you can do them yourself. If you want to
-build them yourself, see the PNG specification for details of which
-pixels to write when.
-
-If you don't want libpng to handle the interlacing details, just
-use png_set_interlace_handling() and call png_write_rows() the
-correct number of times to write all seven sub-images.
-
-If you want libpng to build the sub-images, call this before you start
-writing any rows:
-
- number_of_passes =
- png_set_interlace_handling(png_ptr);
-
-This will return the number of passes needed. Currently, this
-is seven, but may change if another interlace type is added.
-
-Then write the complete image number_of_passes times.
-
- png_write_rows(png_ptr, row_pointers,
- number_of_rows);
-
-As some of these rows are not used, and thus return immediately,
-you may want to read about interlacing in the PNG specification,
-and only update the rows that are actually used.
-
-After you are finished writing the image, you should finish writing
-the file. If you are interested in writing comments or time, you should
-pass an appropriately filled png_info pointer. If you are not interested,
-you can pass NULL.
-
- png_write_end(png_ptr, info_ptr);
-
-When you are done, you can free all memory used by libpng like this:
-
- png_destroy_write_struct(&png_ptr, &info_ptr);
-
-You must free any data you allocated for info_ptr, such as comments,
-palette, or histogram, before the call to png_destroy_write_struct();
-
-For a more compact example of writing a PNG image, see the file example.c.
-
-
-.SH V. Modifying/Customizing libpng:
-
-There are two issues here. The first is changing how libpng does
-standard things like memory allocation, input/output, and error handling.
-The second deals with more complicated things like adding new chunks,
-adding new transformations, and generally changing how libpng works.
-
-All of the memory allocation, input/output, and error handling in libpng
-goes through callbacks that are user settable. The default routines are
-in pngmem.c, pngrio.c, pngwio.c, and pngerror.c respectively. To change
-these functions, call the appropriate png_set_???_fn() function.
-
-Memory allocation is done through the functions png_large_malloc(),
-png_malloc(), png_realloc(), png_large_free(), and png_free(). These
-currently just call the standard C functions. The large functions must
-handle exactly 64K, but they don't have to handle more than that. If
-your pointers can't access more then 64K at a time, you will want to set
-MAXSEG_64K in zlib.h. Since it is unlikely that the method of handling
-memory allocation on a platform will change between applications, these
-functions must be modified in the library at compile time.
-
-Input/Output in libpng is done through png_read() and png_write(),
-which currently just call fread() and fwrite(). The FILE * is stored in
-png_struct and is initialized via png_init_io(). If you wish to change
-the method of I/O, the library supplies callbacks that you can set
-through the function png_set_read_fn() and png_set_write_fn() at run
-time, instead of calling the png_init_io() function. These functions
-also provide a void pointer that can be retrieved via the function
-png_get_io_ptr(). For example:
-
- png_set_read_fn(png_structp read_ptr,
- voidp read_io_ptr, png_rw_ptr read_data_fn)
-
- png_set_write_fn(png_structp write_ptr,
- voidp write_io_ptr, png_rw_ptr write_data_fn,
- png_flush_ptr output_flush_fn);
-
- voidp read_io_ptr = png_get_io_ptr(read_ptr);
- voidp write_io_ptr = png_get_io_ptr(write_ptr);
-
-The replacement I/O functions should have prototypes as follows:
-
- void user_read_data(png_structp png_ptr,
- png_bytep data, png_uint_32 length);
- void user_write_data(png_structp png_ptr,
- png_bytep data, png_uint_32 length);
- void user_flush_data(png_structp png_ptr);
-
-Supplying NULL for the read, write, or flush functions sets them back
-to using the default C stream functions. It is an error to read from
-a write stream, and vice versa.
-
-Error handling in libpng is done through png_error() and png_warning().
-Errors handled through png_error() are fatal, meaning that png_error()
-should never return to its caller. Currently, this is handled via
-setjmp() and longjmp(), but you could change this to do things like
-exit() if you should wish. On non-fatal errors, png_warning() is called
-to print a warning message, and then control returns to the calling code.
-By default png_error() and png_warning() print a message on stderr via
-fprintf() unless the library is compiled with PNG_NO_STDIO defined. If
-you wish to change the behavior of the error functions, you will need to
-set up your own message callbacks. These functions are normally supplied
-at the time that the png_struct is created. It is also possible to change
-these functions after png_create_???_struct() has been called by calling:
-
- png_set_error_fn(png_structp png_ptr,
- png_voidp error_ptr, png_error_ptr error_fn,
- png_error_ptr warning_fn);
-
- png_voidp error_ptr = png_get_error_ptr(png_ptr);
-
-If NULL is supplied for either error_fn or warning_fn, then the libpng
-default function will be used, calling fprintf() and/or longjmp() if a
-problem is encountered. The replacement error functions should have
-parameters as follows:
-
- void user_error_fn(png_structp png_ptr,
- png_const_charp error_msg);
- void user_warning_fn(png_structp png_ptr,
- png_const_charp warning_msg);
-
-The motivation behind using setjmp() and longjmp() is the C++ throw and
-catch exception handling methods. This makes the code much easier to write,
-as there is no need to check every return code of every function call.
-However, there are some uncertainties about the status of local variables
-after a longjmp, so the user may want to be careful about doing anything after
-setjmp returns non-zero besides returning itself. Consult your compiler
-documentation for more details.
-
-If you need to read or write custom chunks, you will need to get deeper
-into the libpng code, as a mechanism has not yet been supplied for user
-callbacks with custom chunks. First, read the PNG specification, and have
-a first level of understanding of how it works. Pay particular attention
-to the sections that describe chunk names, and look at how other chunks
-were designed, so you can do things similarly. Second, check out the
-sections of libpng that read and write chunks. Try to find a chunk that
-is similar to yours and copy off of it. More details can be found in the
-comments inside the code. A way of handling unknown chunks in a generic
-method, potentially via callback functions, would be best.
-
-If you wish to write your own transformation for the data, look through
-the part of the code that does the transformations, and check out some of
-the simpler ones to get an idea of how they work. Try to find a similar
-transformation to the one you want to add and copy off of it. More details
-can be found in the comments inside the code itself.
-
-Configuring for 16 bit platforms:
-
-You may need to change the png_large_malloc() and png_large_free()
-routines in pngmem.c, as these are required to allocate 64K, although
-there is already support for many of the common DOS compilers. Also,
-you will want to look into zconf.h to tell zlib (and thus libpng) that
-it cannot allocate more then 64K at a time. Even if you can, the memory
-won't be accessible. So limit zlib and libpng to 64K by defining MAXSEG_64K.
-
-Configuring for DOS:
-
-For DOS users who only have access to the lower 640K, you will
-have to limit zlib's memory usage via a png_set_compression_mem_level()
-call. See zlib.h or zconf.h in the zlib library for more information.
-
-Configuring for Medium Model:
-
-Libpng's support for medium model has been tested on most of the popular
-compilers. Make sure MAXSEG_64K gets defined, USE_FAR_KEYWORD gets
-defined, and FAR gets defined to far in pngconf.h, and you should be
-all set. Everything in the library (except for zlib's structure) is
-expecting far data. You must use the typedefs with the p or pp on
-the end for pointers (or at least look at them and be careful). Make
-note that the row's of data are defined as png_bytepp, which is an
-unsigned char far * far *.
-
-Configuring for gui/windowing platforms:
-
-You will need to write new error and warning functions that use the GUI
-interface, as described previously, and set them to be the error and
-warning functions at the time that png_create_???_struct() is called,
-in order to have them available during the structure initialization.
-They can be changed later via png_set_error_fn(). On some compilers,
-you may also have to change the memory allocators (png_malloc, etc.).
-
-Configuring for compiler xxx:
-
-All includes for libpng are in pngconf.h. If you need to add/change/delete
-an include, this is the place to do it. The includes that are not
-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, which includes pngconf.h.
-
-Configuring zlib:
-
-There are special functions to configure the compression. Perhaps the
-most useful one changes the compression level, which currently uses
-input compression values in the range 0 - 9. The library normally
-uses the default compression level (Z_DEFAULT_COMPRESSION = 6). Tests
-have shown that for a large majority of images, compression values in
-the range 3-6 compress nearly as well as higher levels, and do so much
-faster. For online applications it may be desirable to have maximum speed
-(Z_BEST_SPEED = 1). With versions of zlib after v0.99, you can also
-specify no compression (Z_NO_COMPRESSION = 0), but this would create
-files larger than just storing the raw bitmap. You can specify the
-compression level by calling:
-
- png_set_compression_level(png_ptr, level);
-
-Another useful one is to reduce the memory level used by the library.
-The memory level defaults to 8, but it can be lowered if you are
-short on memory (running DOS, for example, where you only have 640K).
-
- png_set_compression_mem_level(png_ptr, level);
-
-The other functions are for configuring zlib. They are not recommended
-for normal use and may result in writing an invalid PNG file. See
-zlib.h for more information on what these mean.
-
- png_set_compression_strategy(png_ptr,
- strategy);
- png_set_compression_window_bits(png_ptr,
- window_bits);
- png_set_compression_method(png_ptr, method);
-
-Controlling row filtering:
-
-If you want to control whether libpng uses filtering or not, which
-filters are used, and how it goes about picking row filters, you
-can call one of these functions. The selection and configuration
-of row filters can have a significant impact on the size and
-encoding speed and a somewhat lesser impact on the decoding speed
-of an image. Filtering is enabled by default for RGB and grayscale
-images (with and without alpha), but not for paletted images nor
-for any images with bit depths less than 8 bits/pixel.
-
-The 'method' parameter sets the main filtering method, which is
-currently only '0' in the PNG 1.0 specification. The 'filters'
-parameter sets which filter(s), if any, should be used for each
-scanline. Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS
-to turn filtering on and off, respectively.
-
-Individual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB,
-PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise
-ORed together '|' to specify one or more filters to use. These
-filters are described in more detail in the PNG specification. If
-you intend to change the filter type during the course of writing
-the image, you should start with flags set for all of the filters
-you intend to use so that libpng can initialize its internal
-structures appropriately for all of the filter types.
-
- filters = PNG_FILTER_NONE | PNG_FILTER_SUB
- | PNG_FILTER_UP;
- png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE,
- filters);
-
-It is also possible to influence how libpng chooses from among the
-available filters. This is done in two ways - by telling it how
-important it is to keep the same filter for successive rows, and
-by telling it the relative computational costs of the filters.
-
- double weights[3] = {1.5, 1.3, 1.1},
- costs[PNG_FILTER_VALUE_LAST] =
- {1.0, 1.3, 1.3, 1.5, 1.7};
-
- png_set_filter_selection(png_ptr,
- PNG_FILTER_SELECTION_WEIGHTED, 3,
- weights, costs);
-
-The weights are multiplying factors that indicate to libpng that the
-row filter should be the same for successive rows unless another row filter
-is that many times better than the previous filter. In the above example,
-if the previous 3 filters were SUB, SUB, NONE, the SUB filter could have a
-"sum of absolute differences" 1.5 x 1.3 times higher than other filters
-and still be chosen, while the NONE filter could have a sum 1.1 times
-higher than other filters and still be chosen. Unspecified weights are
-taken to be 1.0, and the specified weights should probably be declining
-like those above in order to emphasize recent filters over older filters.
-
-The filter costs specify for each filter type a relative decoding cost
-to be considered when selecting row filters. This means that filters
-with higher costs are less likely to be chosen over filters with lower
-costs, unless their "sum of absolute differences" is that much smaller.
-The costs do not necessarily reflect the exact computational speeds of
-the various filters, since this would unduly influence the final image
-size.
-
-Note that the numbers above were invented purely for this example and
-are given only to help explain the function usage. Little testing has
-been done to find optimum values for either the costs or the weights.
-
-Removing unwanted object code:
-
-There are a bunch of #define's in pngconf.h that control what parts of
-libpng are compiled. All the defines end in _SUPPORTED. If you are
-never going to use a capability, you can change the #define to #undef
-before recompiling libpng and save yourself code and data space, or
-you can turn off individual capabilities with defines that begin with
-PNG_NO_.
-
-You can also turn all of the transforms and ancillary chunk capabilities
-off en masse with compiler directives that define
-PNG_NO_READ[or WRITE]_TRANSFORMS, or PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS,
-or all four,
-along with directives to turn on any of the capabilities that you do
-want. The PNG_NO_READ[or WRITE]_TRANSFORMS directives disable
-the extra transformations but still leave the library fully capable of reading
-and writing PNG files with all known public chunks [except for sPLT].
-Use of the PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS directive
-produces a library that is incapable of reading or writing ancillary chunks.
-If you are not using the progressive reading capability, you can
-turn that off with PNG_NO_PROGRESSIVE_READ (don't confuse
-this with the INTERLACING capability, which you'll still have).
-
-All the reading and writing specific code are in separate 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.
-The progressive reader is in pngpread.c
-
-If you are creating or distributing a dynamically linked library (a .so
-or DLL file), you should not remove or disable any parts of the library,
-as this will cause applications linked with different versions of the
-library to fail if they call functions not available in your library.
-The size of the library itself should not be an issue, because only
-those sections that are actually used will be loaded into memory.
-
-Requesting debug printout:
-
-The macro definition PNG_DEBUG can be used to request debugging
-printout. Set it to an integer value in the range 0 to 3. Higher
-numbers result in increasing amounts of debugging information. The
-information is printed to the "stderr" file, unless another file
-name is specified in the PNG_DEBUG_FILE macro definition.
-
-When PNG_DEBUG > 0, the following functions (macros) become available:
-
- png_debug(level, message)
- png_debug1(level, message, p1)
- png_debug2(level, message, p1, p2)
-
-in which "level" is compared to PNG_DEBUG to decide whether to print
-the message, "message" is the formatted string to be printed,
-and p1 and p2 are parameters that are to be embedded in the string
-according to printf-style formatting directives. For example,
-
- png_debug1(2, "foo=%d\n", foo);
-
-is expanded to
-
- if(PNG_DEBUG > 2)
- fprintf(PNG_DEBUG_FILE, "foo=%d\n", foo);
-
-When PNG_DEBUG is defined but is zero, the macros aren't defined, but you
-can still use PNG_DEBUG to control your own debugging:
-
- #ifdef PNG_DEBUG
- fprintf(stderr, ...
- #endif
-
-When PNG_DEBUG = 1, the macros are defined, but only png_debug statements
-having level = 0 will be printed. There aren't any such statements in
-this version of libpng, but if you insert some they will be printed.
-
-.SH VI. Changes to Libpng from version 0.88
-
-It should be noted that versions of libpng later than 0.96 are not
-distributed by the original libpng author, Guy Schalnat, nor by
-Andreas Dilger, who had taken over from Guy during 1996 and 1997, and
-distributed versions 0.89 through 0.96, but rather by another member
-of the original PNG Group, Glenn Randers-Pehrson. Guy and Andreas are
-still alive and well, but they have moved on to other things.
-
-The old libpng functions png_read_init(), png_write_init(),
-png_info_init(), png_read_destroy(), and png_write_destory() have been
-moved to PNG_INTERNAL in version 0.95 to discourage their use. The
-preferred method of creating and initializing the libpng structures is
-via the png_create_read_struct(), png_create_write_struct(), and
-png_create_info_struct() because they isolate the size of the structures
-from the application, allow version error checking, and also allow the
-use of custom error handling routines during the initialization, which
-the old functions do not. The functions png_read_destroy() and
-png_write_destroy() do not actually free the memory that libpng
-allocated for these structs, but just reset the data structures, so they
-can be used instead of png_destroy_read_struct() and
-png_destroy_write_struct() if you feel there is too much system overhead
-allocating and freeing the png_struct for each image read.
-
-Setting the error callbacks via png_set_message_fn() before
-png_read_init() as was suggested in libpng-0.88 is no longer supported
-because this caused applications that do not use custom error functions
-to fail if the png_ptr was not initialized to zero. It is still possible
-to set the error callbacks AFTER png_read_init(), or to change them with
-png_set_error_fn(), which is essentially the same function, but with a
-new name to force compilation errors with applications that try to use
-the old method.
-
-.SH VII. Y2K Compliance in libpng
-
-January 13, 1999
-
-Since the PNG Development group is an ad-hoc body, we can't make
-an official declaration.
-
-This is your unofficial assurance that libpng from version 0.81 and
-upward are Y2K compliant. It is my belief that earlier versions were
-also Y2K compliant.
-
-Libpng only has three year fields. One is a 2-byte unsigned integer that
-will hold years up to 65535. The other two hold the date in text
-format, and will hold years up to 9999.
-
-The integer is
- "png_uint_16 year" in png_time_struct.
-
-The strings are
- "png_charp time_buffer" in png_struct and
- "near_time_buffer", which is a local character string in png.c.
-
-There are seven time-related functions:
-
- png_convert_to_rfc_1123() in png.c
- (formerly png_convert_to_rfc_1152() in error)
- png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
- png_convert_from_time_t() in pngwrite.c
- png_get_tIME() in pngget.c
- png_handle_tIME() in pngrutil.c, called in pngread.c
- png_set_tIME() in pngset.c
- png_write_tIME() in pngwutil.c, called in pngwrite.c
-
-All appear to handle dates properly in a Y2K environment. The
-png_convert_from_time_t() function calls gmtime() to convert from system
-clock time, which returns (year - 1900), which we properly convert to
-the full 4-digit year. There is a possibility that applications using
-libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
-function, or incorrectly passing only a 2-digit year instead of
-"year - 1900" into the png_convert_from_struct_tm() function, but this
-is not under our control. The libpng documentation has always stated
-that it works with 4-digit years, and the APIs have been documented as
-such.
-
-The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned
-integer to hold the year, and can hold years as large as 65535.
-
-
- Glenn Randers-Pehrson
- libpng maintainer
- PNG Development Group
-
-.SH NOTE
-
-Note about libpng version numbers:
-
-Due to various miscommunications, unforeseen code incompatibilities
-and occasional factors outside the authors' control, version numbering
-on the library has not always been consistent and straightforward.
-The following table summarizes matters since version 0.89c, which was
-the first widely used release:
-
- source png.h png.h shared-lib
- version string int version
- ------- ------ ------ ----------
- 0.89c 0.89 89 1.0.89
- 0.90 0.90 90 0.90 [should be 2.0.90]
- 0.95 0.95 95 0.95 [should be 2.0.95]
- 0.96 0.96 96 0.96 [should be 2.0.96]
- 0.97b 1.00.97 97 1.0.1 [should be 2.0.97]
- 0.97c 0.97 97 2.0.97
- 0.98 0.98 98 2.0.98
- 0.99 0.99 98 2.0.99
- 0.99a-m 0.99 99 2.0.99
- 1.00 1.00 100 2.1.0 [int should be 10000]
- 1.0.0 1.0.0 100 2.1.0 [int should be 10000]
- 1.0.1 1.0.1 10001 2.1.0
-
-Henceforth the source version will match the shared-library
-minor and patch numbers; the shared-library major version number will be
-used for changes in backward compatibility, as it is intended.
-The PNG_PNGLIB_VER macro, which is not used within libpng but
-is available for applications, is an unsigned integer of the form
-xyyzz corresponding to the source version x.y.z (leading zeros in y and z).
-
-.SH "SEE ALSO"
-libpngpf(3), png(5)
-.LP
-.IR libpng :
-.IP
-ftp://ftp.uu.net/graphics/png
-http://www.cdrom.com/pub/png
-
-.LP
-.IR zlib :
-.IP
-(generally) at the same location as
-.I libpng
-or at
-.br
-ftp://ftp.uu.net/pub/archiving/zip/zlib
-.br
-http://www.cdrom.com/pub/infozip/zlib
-
-.LP
-.IR PNG specification: RFC 2083
-.IP
-(generally) at the same location as
-.I libpng
-or at
-.br
-ftp://ds.internic.net/rfc/rfc2083.txt
-.br
-or (as a W3C Recommendation) at
-.br
-http://www.w3.org/TR/REC-png.html
-
-.LP
-In the case of any inconsistency between the PNG specification
-and this library, the specification takes precedence.
-
-.SH AUTHORS
-This man page: Glenn Randers-Pehrson
-<randeg@alumni.rpi.edu>
-
-Contributing Authors: John Bowler, Kevin Bracey, Sam Bushell, Andreas Dilger,
-Magnus Holmgren, Tom Lane, Dave Martindale, Glenn Randers-Pehrson,
-Greg Roelofs, Guy Eric Schalnat, Paul Schmidt, Tom Tanner, Willem van
-Schaik, Tim Wegner.
-<png-implement@dworkin.wustl.edu>
-
-The contributing authors would like to thank all those who helped
-with testing, bug fixes, and patience. This wouldn't have been
-possible without all of you.
-
-Thanks to Frank J. T. Wojcik for helping with the documentation.
-
-Libpng version 1.0.3 - January 14, 1999:
-Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc.
-Currently maintained by Glenn Randers-Pehrson (randeg@alumni.rpi.edu).
-
-Supported by the PNG development group
-.br
-(png-implement@dworkin.wustl.edu).
-
-.SH COPYRIGHT NOTICE:
-
-Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
-Copyright (c) 1996, 1997 Andreas Dilger
-Copyright (c) 1998, 1999 Glenn Randers-Pehrson
-
-The PNG Reference Library (libpng) is supplied "AS IS". The Contributing
-Authors and Group 42, Inc. disclaim all warranties, expressed or implied,
-including, without limitation, the warranties of merchantability and of
-fitness for any purpose. The Contributing Authors and Group 42, Inc.
-assume no liability for direct, indirect, incidental, special, exemplary,
-or consequential damages, which may result from the use of the PNG
-Reference Library, even if advised of the possibility of such damage.
-
-Permission is hereby granted to use, copy, modify, and distribute this
-source code, or portions hereof, for any purpose, without fee, subject
-to the following restrictions:
-
- 1. The origin of this source code must not be
- misrepresented.
-
- 2. Altered versions must be plainly marked as such
- and must not be misrepresented as being the
- original source.
-
- 3. This Copyright notice may not be removed or
- altered from any source or altered source
- distribution.
-
-The Contributing Authors and Group 42, Inc. specifically permit, without
-fee, and encourage the use of this source code as a component to
-supporting the PNG file format in commercial products. If you use this
-source code in a product, acknowledgment is not required but would be
-appreciated.
-
-.\" end of man page
-
+++ /dev/null
-libpng.txt - A description on how to use and modify libpng
-
- libpng version 1.0.3 - January 14, 1999
- Updated and distributed by Glenn Randers-Pehrson
- <randeg@alumni.rpi.edu>
- Copyright (c) 1998, 1999 Glenn Randers-Pehrson
- For conditions of distribution and use, see copyright
- notice in png.h.
-
- based on:
-
- libpng 1.0 beta 6 version 0.96 May 28, 1997
- Updated and distributed by Andreas Dilger
- Copyright (c) 1996, 1997 Andreas Dilger
-
- libpng 1.0 beta 2 - version 0.88 January 26, 1996
- For conditions of distribution and use, see copyright
- notice in png.h. Copyright (c) 1995, 1996 Guy Eric
- Schalnat, Group 42, Inc.
-
- Updated/rewritten per request in the libpng FAQ
- Copyright (c) 1995 Frank J. T. Wojcik
- December 18, 1995 && January 20, 1996
-
-I. Introduction
-
-This file describes how to use and modify the PNG reference library
-(known as libpng) for your own use. There are five sections to this
-file: introduction, structures, reading, writing, and modification and
-configuration notes for various special platforms. In addition to this
-file, example.c is a good starting point for using the library, as
-it is heavily commented and should include everything most people
-will need. We assume that libpng is already installed; see the
-INSTALL file for instructions on how to install libpng.
-
-Libpng was written as a companion to the PNG specification, as a way
-of reducing the amount of time and effort it takes to support the PNG
-file format in application programs. The PNG specification is available
-as RFC 2083 <ftp://ftp.uu.net/graphics/png/documents/> and as a
-W3C Recommendation <http://www.w3.org/TR/REC.png.html>. Some
-additional chunks are described in the special-purpose public chunks
-documents at <ftp://ftp.uu.net/graphics/png/documents/>. Other information
-about PNG, and the latest version of libpng, can be found at the PNG home
-page, <http://www.cdrom.com/pub/png/>.
-
-Most users will not have to modify the library significantly; advanced
-users may want to modify it more. All attempts were made to make it as
-complete as possible, while keeping the code easy to understand.
-Currently, this library only supports C. Support for other languages
-is being considered.
-
-Libpng has been designed to handle multiple sessions at one time,
-to be easily modifiable, to be portable to the vast majority of
-machines (ANSI, K&R, 16-, 32-, and 64-bit) available, and to be easy
-to use. The ultimate goal of libpng is to promote the acceptance of
-the PNG file format in whatever way possible. While there is still
-work to be done (see the TODO file), libpng should cover the
-majority of the needs of its users.
-
-Libpng uses zlib for its compression and decompression of PNG files.
-Further information about zlib, and the latest version of zlib, can
-be found at the zlib home page, <http://www.cdrom.com/pub/infozip/zlib/>.
-The zlib compression utility is a general purpose utility that is
-useful for more than PNG files, and can be used without libpng.
-See the documentation delivered with zlib for more details.
-You can usually find the source files for the zlib utility wherever you
-find the libpng source files.
-
-Libpng is thread safe, provided the threads are using different
-instances of the structures. Each thread should have its own
-png_struct and png_info instances, and thus its own image.
-Libpng does not protect itself against two threads using the
-same instance of a structure.
-
-
-II. Structures
-
-There are two main structures that are important to libpng, png_struct
-and png_info. The first, png_struct, is an internal structure that
-will not, for the most part, be used by a user except as the first
-variable passed to every libpng function call.
-
-The png_info structure is designed to provide information about the
-PNG file. At one time, the fields of png_info were intended to be
-directly accessible to the user. However, this tended to cause problems
-with applications using dynamically loaded libraries, and as a result
-a set of interface functions for png_info was developed. The fields
-of png_info are still available for older applications, but it is
-suggested that applications use the new interfaces if at all possible.
-
-The png.h header file is an invaluable reference for programming with libpng.
-And while I'm on the topic, make sure you include the libpng header file:
-
-#include <png.h>
-
-III. Reading
-
-Reading PNG files:
-
-We'll now walk you through the possible functions to call when reading
-in a PNG file, briefly explaining the syntax and purpose of each one.
-See example.c and png.h for more detail. While Progressive reading
-is covered in the next section, you will still need some of the
-functions discussed in this section to read a PNG file.
-
-You will want to do the I/O initialization(*) before you get into libpng,
-so if it doesn't work, you don't have much to undo. Of course, you
-will also want to insure that you are, in fact, dealing with a PNG
-file. Libpng provides a simple check to see if a file is a PNG file.
-To use it, pass in the first 1 to 8 bytes of the file, and it will
-return true or false (1 or 0) depending on whether the bytes could be
-part of a PNG file. Of course, the more bytes you pass in, the
-greater the accuracy of the prediction.
-
-If you are intending to keep the file pointer open for use in libpng,
-you must ensure you don't read more than 8 bytes from the beginning
-of the file, and you also have to make a call to png_set_sig_bytes_read()
-with the number of bytes you read from the beginning. Libpng will
-then only check the bytes (if any) that your program didn't read.
-
-(*): If you are not using the standard I/O functions, you will need
-to replace them with custom functions. See the discussion under
-Customizing libpng.
-
-
- FILE *fp = fopen(file_name, "rb");
- if (!fp)
- {
- return;
- }
- fread(header, 1, number, fp);
- is_png = !png_sig_cmp(header, 0, number);
- if (!is_png)
- {
- return;
- }
-
-
-Next, png_struct and png_info need to be allocated and initialized. In
-order to ensure that the size of these structures is correct even with a
-dynamically linked libpng, there are functions to initialize and
-allocate the structures. We also pass the library version, optional
-pointers to error handling functions, and a pointer to a data struct for
-use by the error functions, if necessary (the pointer and functions can
-be NULL if the default error handlers are to be used). See the section
-on Changes to Libpng below regarding the old initialization functions.
-
- png_structp png_ptr = png_create_read_struct
- (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
- user_error_fn, user_warning_fn);
- if (!png_ptr)
- return;
-
- png_infop info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr)
- {
- png_destroy_read_struct(&png_ptr,
- (png_infopp)NULL, (png_infopp)NULL);
- return;
- }
-
- png_infop end_info = png_create_info_struct(png_ptr);
- if (!end_info)
- {
- png_destroy_read_struct(&png_ptr, &info_ptr,
- (png_infopp)NULL);
- return;
- }
-
-If you want to use your own memory allocation routines,
-define PNG_USER_MEM_SUPPORTED and use
-png_create_read_struct_2() instead of png_create_read_struct():
-
- png_structp png_ptr = png_create_read_struct_2
- (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
- user_error_fn, user_warning_fn, (png_voidp)
- user_mem_ptr, user_malloc_fn, user_free_fn);
-
-The error handling routines passed to png_create_read_struct()
-and the memory alloc/free routines passed to png_create_struct_2()
-are only necessary if you are not using the libpng supplied error
-handling and memory alloc/free functions.
-
-When libpng encounters an error, it expects to longjmp back
-to your routine. Therefore, you will need to call setjmp and pass
-your png_ptr->jmpbuf. If you read the file from different
-routines, you will need to update the jmpbuf field every time you enter
-a new routine that will call a png_ function.
-
-See your documentation of setjmp/longjmp for your compiler for more
-handling in the Customizing Libpng section below for more information on
-the libpng error handling. If an error occurs, and libpng longjmp's
-back to your setjmp, you will want to call png_destroy_read_struct() to
-free any memory.
-
- if (setjmp(png_ptr->jmpbuf))
- {
- png_destroy_read_struct(&png_ptr, &info_ptr,
- &end_info);
- fclose(fp);
- return;
- }
-
-Now you need to set up the input code. The default for libpng is to
-use the C function fread(). If you use this, you will need to pass a
-valid FILE * in the function png_init_io(). Be sure that the file is
-opened in binary mode. If you wish to handle reading data in another
-way, you need not call the png_init_io() function, but you must then
-implement the libpng I/O methods discussed in the Customizing Libpng
-section below.
-
- png_init_io(png_ptr, fp);
-
-If you had previously opened the file and read any of the signature from
-the beginning in order to see if this was a PNG file, you need to let
-libpng know that there are some bytes missing from the start of the file.
-
- png_set_sig_bytes(png_ptr, number);
-
-At this point, you can set up a callback function that will be
-called after each row has been read, which you can use to control
-a progress meter or the like. It's demonstrated in pngtest.c.
-You must supply a function
-
- void read_row_callback(png_ptr, png_uint_32 row, int pass);
- {
- /* put your code here */
- }
-
-(You can give it another name that you like instead of "read_row_callback")
-
-To inform libpng about your function, use
-
- png_set_read_status_fn(png_ptr, read_row_callback);
-
-In PNG files, the alpha channel in an image is the level of opacity.
-If you need the alpha channel in an image to be the level of transparency
-instead of opacity, you can invert the alpha channel (or the tRNS chunk
-data) after it's read, so that 0 is fully opaque and 255 (in 8-bit or
-paletted images) or 65535 (in 16-bit images) is fully transparent, with
-
- png_set_invert_alpha(png_ptr);
-
-This has to appear here rather than later with the other transformations
-because the tRNS chunk data must be modified in the case of paletted images.
-If your image is not a paletted image, the tRNS data (which in such cases
-represents a single color to be rendered as transparent) won't be changed.
-
-Finally, you can write your own transformation function if none of
-the existing ones meets your needs. This is done by setting a callback
-with
-
- png_set_read_user_transform_fn(png_ptr,
- read_transform_fn);
-
-You must supply the function
-
- void read_transform_fn(png_ptr ptr, row_info_ptr
- row_info, png_bytep data)
-
-See pngtest.c for a working example. Your function will be called
-after all of the other transformations have been processed.
-
-You are now ready to read all the file information up to the actual
-image data. You do this with a call to png_read_info().
-
- png_read_info(png_ptr, info_ptr);
-
-Functions are used to get the information from the info_ptr:
-
- png_get_IHDR(png_ptr, info_ptr, &width, &height,
- &bit_depth, &color_type, &interlace_type,
- &compression_type, &filter_type);
-
- width - holds the width of the image
- in pixels (up to 2^31).
- height - holds the height of the image
- in pixels (up to 2^31).
- bit_depth - holds the bit depth of one of the
- image channels. (valid values are
- 1, 2, 4, 8, 16 and depend also on
- the color_type. See also
- significant bits (sBIT) below).
- color_type - describes which color/alpha channels
- are present.
- PNG_COLOR_TYPE_GRAY
- (bit depths 1, 2, 4, 8, 16)
- PNG_COLOR_TYPE_GRAY_ALPHA
- (bit depths 8, 16)
- PNG_COLOR_TYPE_PALETTE
- (bit depths 1, 2, 4, 8)
- PNG_COLOR_TYPE_RGB
- (bit_depths 8, 16)
- PNG_COLOR_TYPE_RGB_ALPHA
- (bit_depths 8, 16)
-
- PNG_COLOR_MASK_PALETTE
- PNG_COLOR_MASK_COLOR
- PNG_COLOR_MASK_ALPHA
-
- filter_type - (must be PNG_FILTER_TYPE_BASE
- for PNG 1.0)
- compression_type - (must be PNG_COMPRESSION_TYPE_BASE
- for PNG 1.0)
- interlace_type - (PNG_INTERLACE_NONE or
- PNG_INTERLACE_ADAM7)
- Any or all of interlace_type, compression_type, of
- filter_type can be
- NULL if you are not interested in their values.
-
- channels = png_get_channels(png_ptr, info_ptr);
- channels - number of channels of info for the
- color type (valid values are 1 (GRAY,
- PALETTE), 2 (GRAY_ALPHA), 3 (RGB),
- 4 (RGB_ALPHA or RGB + filler byte))
- rowbytes = png_get_rowbytes(png_ptr, info_ptr);
- rowbytes - number of bytes needed to hold a row
-
- signature = png_get_signature(png_ptr, info_ptr);
- signature - holds the signature read from the
- file (if any). The data is kept in
- the same offset it would be if the
- whole signature were read (i.e. if an
- application had already read in 4
- bytes of signature before starting
- libpng, the remaining 4 bytes would
- be in signature[4] through signature[7]
- (see png_set_sig_bytes())).
-
-
- width = png_get_image_width(png_ptr,
- info_ptr);
- height = png_get_image_height(png_ptr,
- info_ptr);
- bit_depth = png_get_bit_depth(png_ptr,
- info_ptr);
- color_type = png_get_color_type(png_ptr,
- info_ptr);
- filter_type = png_get_filter_type(png_ptr,
- info_ptr);
- compression_type = png_get_compression_type(png_ptr,
- info_ptr);
- interlace_type = png_get_interlace_type(png_ptr,
- info_ptr);
-
-
-These are also important, but their validity depends on whether the chunk
-has been read. The png_get_valid(png_ptr, info_ptr, PNG_INFO_<chunk>) and
-png_get_<chunk>(png_ptr, info_ptr, ...) functions return non-zero if the
-data has been read, or zero if it is missing. The parameters to the
-png_get_<chunk> are set directly if they are simple data types, or a pointer
-into the info_ptr is returned for any complex types.
-
- png_get_PLTE(png_ptr, info_ptr, &palette,
- &num_palette);
- palette - the palette for the file
- (array of png_color)
- num_palette - number of entries in the palette
-
- png_get_gAMA(png_ptr, info_ptr, &gamma);
- gamma - the gamma the file is written
- at (PNG_INFO_gAMA)
-
- png_get_sRGB(png_ptr, info_ptr, &srgb_intent);
- srgb_intent - the rendering intent (PNG_INFO_sRGB)
- The presence of the sRGB chunk
- means that the pixel data is in the
- sRGB color space. This chunk also
- implies specific values of gAMA and
- cHRM.
-
- png_get_sBIT(png_ptr, info_ptr, &sig_bit);
- sig_bit - the number of significant bits for
- (PNG_INFO_sBIT) each of the gray,
- red, green, and blue channels,
- whichever are appropriate for the
- given color type (png_color_16)
-
- png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans,
- &trans_values);
- trans - array of transparent entries for
- palette (PNG_INFO_tRNS)
- trans_values - transparent pixel for non-paletted
- images (PNG_INFO_tRNS)
- num_trans - number of transparent entries
- (PNG_INFO_tRNS)
-
- png_get_hIST(png_ptr, info_ptr, &hist);
- (PNG_INFO_hIST)
- hist - histogram of palette (array of
- png_color_16)
-
- png_get_tIME(png_ptr, info_ptr, &mod_time);
- mod_time - time image was last modified
- (PNG_VALID_tIME)
-
- png_get_bKGD(png_ptr, info_ptr, &background);
- background - background color (PNG_VALID_bKGD)
-
- num_text = png_get_text(png_ptr, info_ptr, &text_ptr);
- text_ptr - array of png_text holding image
- comments
- text_ptr[i]->key - keyword for comment.
- text_ptr[i]->text - text comments for current
- keyword.
- text_ptr[i]->compression - type of compression used
- on "text" PNG_TEXT_COMPRESSION_NONE
- or PNG_TEXT_COMPRESSION_zTXt
- num_text - number of comments
-
- png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y,
- &unit_type);
- offset_x - positive offset from the left edge
- of the screen
- offset_y - positive offset from the top edge
- of the screen
- unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER
-
- png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y,
- &unit_type);
- res_x - pixels/unit physical resolution in
- x direction
- res_y - pixels/unit physical resolution in
- x direction
- unit_type - PNG_RESOLUTION_UNKNOWN,
- PNG_RESOLUTION_METER
-
-The data from the pHYs chunk can be retrieved in several convenient
-forms:
-
- res_x = png_get_x_pixels_per_meter(png_ptr,
- info_ptr)
- res_y = png_get_y_pixels_per_meter(png_ptr,
- info_ptr)
- res_x_and_y = png_get_pixels_per_meter(png_ptr,
- info_ptr)
- aspect_ratio = png_get_pixel_aspect_ratio(png_ptr,
- info_ptr)
-
- (Each of these returns 0 [signifying "unknown"] if
- the data is not present or if res_x is 0;
- res_x_and_y is 0 if res_x != res_y)
-
-For more information, see the png_info definition in png.h and the
-PNG specification for chunk contents. Be careful with trusting
-rowbytes, as some of the transformations could increase the space
-needed to hold a row (expand, filler, gray_to_rgb, etc.).
-See png_read_update_info(), below.
-
-A quick word about text_ptr and num_text. PNG stores comments in
-keyword/text pairs, one pair per chunk, with no limit on the number
-of text chunks, and a 2^31 byte limit on their size. While there are
-suggested keywords, there is no requirement to restrict the use to these
-strings. It is strongly suggested that keywords and text be sensible
-to humans (that's the point), so don't use abbreviations. Non-printing
-symbols are not allowed. See the PNG specification for more details.
-There is also no requirement to have text after the keyword.
-
-Keywords should be limited to 79 Latin-1 characters without leading or
-trailing spaces, but non-consecutive spaces are allowed within the
-keyword. It is possible to have the same keyword any number of times.
-The text_ptr is an array of png_text structures, each holding pointer
-to a keyword and a pointer to a text string. Only the text string may
-be null. The keyword/text pairs are put into the array in the order
-that they are received. However, some or all of the text chunks may be
-after the image, so, to make sure you have read all the text chunks,
-don't mess with these until after you read the stuff after the image.
-This will be mentioned again below in the discussion that goes with
-png_read_end().
-
-After you've read the header information, you can set up the library
-to handle any special transformations of the image data. The various
-ways to transform the data will be described in the order that they
-should occur. This is important, as some of these change the color
-type and/or bit depth of the data, and some others only work on
-certain color types and bit depths. Even though each transformation
-checks to see if it has data that it can do something with, you should
-make sure to only enable a transformation if it will be valid for the
-data. For example, don't swap red and blue on grayscale data.
-
-The colors used for the background and transparency values should be
-supplied in the same format/depth as the current image data. They
-are stored in the same format/depth as the image data in a bKGD or tRNS
-chunk, so this is what libpng expects for this data. The colors are
-transformed to keep in sync with the image data when an application
-calls the png_read_update_info() routine (see below).
-
-Data will be decoded into the supplied row buffers packed into bytes
-unless the library has been told to transform it into another format.
-For example, 4 bit/pixel paletted or grayscale data will be returned
-2 pixels/byte with the leftmost pixel in the high-order bits of the
-byte, unless png_set_packing() is called. 8-bit RGB data will be stored
-in RGB RGB RGB format unless png_set_filler() is called to insert filler
-bytes, either before or after each RGB triplet. 16-bit RGB data will
-be returned RRGGBB RRGGBB, with the most significant byte of the color
-value first, unless png_set_strip_16() is called to transform it to
-regular RGB RGB triplets, or png_set_filler() is called to insert
-filler bytes, either before or after each RRGGBB triplet. Similarly,
-8-bit or 16-bit grayscale data can be modified with png_set_filler()
-or png_set_strip_16().
-
-The following code transforms grayscale images of less than 8 to 8 bits,
-changes paletted images to RGB, and adds a full alpha channel if there is
-transparency information in a tRNS chunk. This is most useful on
-grayscale images with bit depths of 2 or 4 or if there is a multiple-image
-viewing application that wishes to treat all images in the same way.
-
- if (color_type == PNG_COLOR_TYPE_PALETTE &&
- bit_depth <= 8) png_set_expand(png_ptr);
-
- if (color_type == PNG_COLOR_TYPE_GRAY &&
- bit_depth < 8) png_set_expand(png_ptr);
-
- if (png_get_valid(png_ptr, info_ptr,
- PNG_INFO_tRNS)) png_set_expand(png_ptr);
-
-PNG can have files with 16 bits per channel. If you only can handle
-8 bits per channel, this will strip the pixels down to 8 bit.
-
- if (bit_depth == 16)
- png_set_strip_16(png_ptr);
-
-The png_set_background() function tells libpng to composite images
-with alpha or simple transparency against the supplied background
-color. If the PNG file contains a bKGD chunk (PNG_INFO_bKGD valid),
-you may use this color, or supply another color more suitable for
-the current display (e.g., the background color from a web page). You
-need to tell libpng whether the color is in the gamma space of the
-display (PNG_BACKGROUND_GAMMA_SCREEN for colors you supply), the file
-(PNG_BACKGROUND_GAMMA_FILE for colors from the bKGD chunk), or one
-that is neither of these gammas (PNG_BACKGROUND_GAMMA_UNIQUE - I don't
-know why anyone would use this, but it's here).
-
-If, for some reason, you don't need the alpha channel on an image,
-and you want to remove it rather than combining it with the background
-(but the image author certainly had in mind that you *would* combine
-it with the background, so that's what you should probably do):
-
- if (color_type & PNG_COLOR_MASK_ALPHA)
- png_set_strip_alpha(png_ptr);
-
-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. This code expands to 1 pixel per byte without changing the
-values of the pixels:
-
- if (bit_depth < 8)
- png_set_packing(png_ptr);
-
-PNG files have possible bit depths of 1, 2, 4, 8, and 16. All pixels
-stored in a PNG image have been "scaled" or "shifted" up to the next
-higher possible bit depth (e.g. from 5 bits/sample in the range [0,31] to
-8 bits/sample in the range [0, 255]). However, it is also possible to
-convert the PNG pixel data back to the original bit depth of the image.
-This call reduces the pixels back down to the original bit depth:
-
- png_color_16p sig_bit;
-
- if (png_get_sBIT(png_ptr, info_ptr, &sig_bit))
- png_set_shift(png_ptr, sig_bit);
-
-PNG files store 3-color pixels in red, green, blue order. This code
-changes the storage of the pixels to blue, green, red:
-
- if (color_type == PNG_COLOR_TYPE_RGB ||
- color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- png_set_bgr(png_ptr);
-
-PNG files store RGB pixels packed into 3 bytes. This code expands them
-into 4 bytes for windowing systems that need them in this format:
-
- if (bit_depth == 8 && color_type ==
- PNG_COLOR_TYPE_RGB) png_set_filler(png_ptr,
- filler, PNG_FILLER_BEFORE);
-
-where "filler" is the 8 or 16-bit 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. This transformation
-does not affect images that already have full alpha channels.
-
-If you are reading an image with an alpha channel, and you need the
-data as ARGB instead of the normal PNG format RGBA:
-
- if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- png_set_swap_alpha(png_ptr);
-
-For some uses, you may want a grayscale image to be represented as
-RGB. This code will do that conversion:
-
- if (color_type == PNG_COLOR_TYPE_GRAY ||
- color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- png_set_gray_to_rgb(png_ptr);
-
-Conversely, you can convert an RGB or RGBA image to grayscale or grayscale
-with alpha. This is intended for conversion of images that really are
-gray (red == green == blue), so the function simply strips out the red
-and blue channels, leaving the green channel in the gray position.
-
- if (color_type == PNG_COLOR_TYPE_RGB ||
- color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- png_set_rgb_to_gray(png_ptr, error_action,
- float red_weight, float green_weight);
-
- error_action = 1: silently do the conversion
- error_action = 2: issue a warning if the original
- image has any pixel where
- red != green or red != blue
- error_action = 3: issue an error and abort the
- conversion if the original
- image has any pixel where
- red != green or red != blue
-
- red_weight: weight of red component
- (NULL -> default 54/256)
- green_weight: weight of green component
- (NULL -> default 183/256)
-
-If you have set error_action = 1 or 2, you can
-later check whether the image really was gray, after processing
-the image rows, with the png_get_rgb_to_gray_status(png_ptr) function.
-It will return a png_byte that is zero if the image was gray or
-1 if there were any non-gray pixels. bKGD and sBIT data
-will be silently converted to grayscale, using the green channel
-data, regardless of the error_action setting.
-
-With 0.0<=red_weight+green_weight<=1.0,
-the normalized graylevel is computed:
-
- int rw = red_weight * 256;
- int gw = green_weight * 256;
- int bw = 256 - (rw + gw);
- gray = (rw*red + gw*green + bw*blue)/256;
-
-The default values approximate those recommended in the Charles
-Poynton's Color FAQ, <http://www.inforamp.net/~poynton/>
-Copyright (c) 1998-01-04 Charles Poynton poynton@inforamp.net
-
- Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
-
-Libpng approximates this with
-
- Y = 0.211 * R + 0.715 * G + 0.074 * B
-
-which can be expressed with integers as
-
- Y = (54 * R + 183 * G + 19 * B)/256
-
-The calculation is done in a linear colorspace, if the image gamma
-is known.
-
-If you have a grayscale and you are using png_set_expand() to change to
-a higher bit-depth, you must either supply the background color as a gray
-value at the original file bit-depth (need_expand = 1) or else supply the
-background color as an RGB triplet at the final, expanded bit depth
-(need_expand = 0). Similarly, if you are reading a paletted image, you
-must either supply the background color as a palette index (need_expand = 1)
-or as an RGB triplet that may or may not be in the palette (need_expand = 0).
-
- png_color_16 my_background;
- png_color_16p image_background;
-
- if (png_get_bKGD(png_ptr, info_ptr, &image_background))
- png_set_background(png_ptr, image_background,
- PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
- else
- png_set_background(png_ptr, &my_background,
- PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
-
-To properly display PNG images on any kind of system, the application needs
-to know what the display gamma is. Ideally, the user will know this, and
-the application will allow them to set it. One method of allowing the user
-to set the display gamma separately for each system is to check for the
-DISPLAY_GAMMA and VIEWING_GAMMA environment variables or for a SCREEN_GAMMA
-environment variable, which will hopefully be correctly set.
-
-Note that display_gamma is the gamma of your display, while screen_gamma is
-the overall gamma correction required to produce pleasing results,
-which depends on the lighting conditions in the surrounding environment.
-Screen_gamma is display_gamma/viewing_gamma, where viewing_gamma is
-the amount of additional gamma correction needed to compensate for
-a (viewing_gamma=1.25) environment. In a dim or brightly lit room, no
-compensation other than the display_gamma is needed (viewing_gamma=1.0).
-
- if (/* We have a user-defined screen
- gamma value */)
- {
- screen_gamma = user_defined_screen_gamma;
- }
- /* One way that applications can share the same
- screen gamma value */
- else if ((gamma_str = getenv("SCREEN_GAMMA"))
- != NULL)
- {
- screen_gamma = atof(gamma_str);
- }
- /* If we don't have another value */
- else
- {
- screen_gamma = 2.2; /* A good guess for a
- PC monitor in a bright office or a dim room */
- screen_gamma = 2.0; /* A good guess for a
- PC monitor in a dark room */
- screen_gamma = 1.7 or 1.0; /* A good
- guess for Mac systems */
- }
-
-The png_set_gamma() function handles gamma transformations of the data.
-Pass both the file gamma and the current screen_gamma. If the file does
-not have a gamma value, you can pass one anyway if you have an idea what
-it is (usually 0.45455 is a good guess for GIF images on PCs). Note
-that file gammas are inverted from screen gammas. See the discussions
-on gamma in the PNG specification for an excellent description of what
-gamma is, and why all applications should support it. It is strongly
-recommended that PNG viewers support gamma correction.
-
- if (png_get_gAMA(png_ptr, info_ptr, &gamma))
- png_set_gamma(png_ptr, screen_gamma, gamma);
- else
- png_set_gamma(png_ptr, screen_gamma, 0.45455);
-
-If you need to reduce an RGB file to a paletted file, or if a paletted
-file has more entries then will fit on your screen, png_set_dither()
-will do that. Note that this is a simple match dither that merely
-finds the closest color available. This should work fairly well with
-optimized palettes, and fairly badly with linear color cubes. If you
-pass a palette that is larger then maximum_colors, the file will
-reduce the number of colors in the palette so it will fit into
-maximum_colors. If there is a histogram, it will use it to make
-more intelligent choices when reducing the palette. If there is no
-histogram, it may not do as good a job.
-
- if (color_type & PNG_COLOR_MASK_COLOR)
- {
- if (png_get_valid(png_ptr, info_ptr,
- PNG_INFO_PLTE))
- {
- png_color_16p histogram;
-
- png_get_hIST(png_ptr, info_ptr,
- &histogram);
- png_set_dither(png_ptr, palette, num_palette,
- max_screen_colors, histogram, 1);
- }
- else
- {
- png_color std_color_cube[MAX_SCREEN_COLORS] =
- { ... colors ... };
-
- png_set_dither(png_ptr, std_color_cube,
- MAX_SCREEN_COLORS, MAX_SCREEN_COLORS,
- NULL,0);
- }
- }
-
-PNG files describe monochrome as black being zero and white being one.
-The following code will reverse this (make black be one and white be
-zero):
-
- if (bit_depth == 1 && color_type == PNG_COLOR_GRAY)
- png_set_invert_mono(png_ptr);
-
-PNG files store 16 bit pixels in network byte order (big-endian,
-ie. most significant bits first). This code changes the storage to the
-other way (little-endian, i.e. least significant bits first, the
-way PCs store them):
-
- if (bit_depth == 16)
- png_set_swap(png_ptr);
-
-If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you
-need to change the order the pixels are packed into bytes, you can use:
-
- if (bit_depth < 8)
- png_set_packswap(png_ptr);
-
-The last thing to handle is interlacing; this is covered in detail below,
-but you must call the function here if you want libpng to handle expansion
-of the interlaced image.
-
- number_of_passes = png_set_interlace_handling(png_ptr);
-
-After setting the transformations, libpng can update your png_info
-structure to reflect any transformations you've requested with this
-call. This is most useful to update the info structure's rowbytes
-field so you can use it to allocate your image memory. This function
-will also update your palette with the correct screen_gamma and
-background if these have been given with the calls above.
-
- 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. The row data is simply
-raw byte data for all forms of images. As the actual allocation
-varies among applications, no example will be given. If you
-are allocating one large chunk, you will need 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
-and put it in the memory area supplied. You will need to pass in
-an array of pointers to each row.
-
-This function automatically handles interlacing, so you don't need
-to call png_set_interlace_handling() or call this function multiple
-times, or any of that other stuff necessary with png_read_rows().
-
- png_read_image(png_ptr, row_pointers);
-
-where row_pointers is:
-
- png_bytep row_pointers[height];
-
-You can point to void or char or whatever you use for pixels.
-
-If you don't want to read in the whole image at once, you can
-use png_read_rows() instead. If there is no interlacing (check
-interlace_type == PNG_INTERLACE_NONE), this is simple:
-
- png_read_rows(png_ptr, row_pointers, NULL,
- number_of_rows);
-
-where row_pointers is the same as in the png_read_image() call.
-
-If you are doing this just one row at a time, you can do this with
-row_pointers:
-
- png_bytep row_pointers = row;
- png_read_row(png_ptr, &row_pointers, NULL);
-
-If the file is interlaced (info_ptr->interlace_type != 0), things get
-somewhat harder. The only current (PNG Specification version 1.0)
-interlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7)
-is a somewhat complicated 2D interlace scheme, known as Adam7, that
-breaks down an image into seven smaller images of varying size, based
-on an 8x8 grid.
-
-libpng can fill out those images or it can give them to you "as is".
-If you want them filled out, there are two ways to do that. The one
-mentioned in the PNG specification is to expand each pixel to cover
-those pixels that have not been read yet (the "rectangle" method).
-This results in a blocky image for the first pass, which gradually
-smooths out as more pixels are read. The other method is the "sparkle"
-method, where pixels are drawn only in their final locations, with the
-rest of the image remaining whatever colors they were initialized to
-before the start of the read. The first method usually looks better,
-but tends to be slower, as there are more pixels to put in the rows.
-
-If you don't want libpng to handle the interlacing details, just call
-png_read_rows() seven times to read in all seven images. Each of the
-images is a valid image by itself, or they can all be combined on an
-8x8 grid to form a single image (although if you intend to combine them
-you would be far better off using the libpng interlace handling).
-
-The first pass will return an image 1/8 as wide as the entire image
-(every 8th column starting in column 0) and 1/8 as high as the original
-(every 8th row starting in row 0), the second will be 1/8 as wide
-(starting in column 4) and 1/8 as high (also starting in row 0). The
-third pass will be 1/4 as wide (every 4th pixel starting in column 0) and
-1/8 as high (every 8th row starting in row 4), and the fourth pass will
-be 1/4 as wide and 1/4 as high (every 4th column starting in column 2,
-and every 4th row starting in row 0). The fifth pass will return an
-image 1/2 as wide, and 1/4 as high (starting at column 0 and row 2),
-while the sixth pass will be 1/2 as wide and 1/2 as high as the original
-(starting in column 1 and row 0). The seventh and final pass will be as
-wide as the original, and 1/2 as high, containing all of the odd
-numbered scanlines. Phew!
-
-If you want libpng to expand the images, call this before calling
-png_start_read_image() or png_read_update_info():
-
- if (interlace_type == PNG_INTERLACE_ADAM7)
- number_of_passes
- = png_set_interlace_handling(png_ptr);
-
-This will return the number of passes needed. Currently, this
-is seven, but may change if another interlace type is added.
-This function can be called even if the file is not interlaced,
-where it will return one pass.
-
-If you are not going to display the image after each pass, but are
-going to wait until the entire image is read in, use the sparkle
-effect. This effect is faster and the end result of either method
-is exactly the same. If you are planning on displaying the image
-after each pass, the "rectangle" effect is generally considered the
-better looking one.
-
-If you only want the "sparkle" effect, just call png_read_rows() as
-normal, with the third parameter NULL. Make sure you make pass over
-the image number_of_passes times, and you don't change the data in the
-rows between calls. You can change the locations of the data, just
-not the data. Each pass only writes the pixels appropriate for that
-pass, and assumes the data from previous passes is still valid.
-
- png_read_rows(png_ptr, row_pointers, NULL,
- number_of_rows);
-
-If you only want the first effect (the rectangles), do the same as
-before except pass the row buffer in the third parameter, and leave
-the second parameter NULL.
-
- png_read_rows(png_ptr, NULL, row_pointers,
- number_of_rows);
-
-After you are finished reading the image, you can finish reading
-the file. If you are interested in comments or time, which may be
-stored either before or after the image data, you should pass the
-separate png_info struct if you want to keep the comments from
-before and after the image separate. If you are not interested, you
-can pass NULL.
-
- png_read_end(png_ptr, end_info);
-
-When you are done, you can free all memory allocated by libpng like this:
-
- png_destroy_read_struct(&png_ptr, &info_ptr,
- &end_info);
-
-For a more compact example of reading a PNG image, see the file example.c.
-
-
-Reading PNG files progressively:
-
-The progressive reader is slightly different then the non-progressive
-reader. Instead of calling png_read_info(), png_read_rows(), and
-png_read_end(), you make one call to png_process_data(), which calls
-callbacks when it has the info, a row, or the end of the image. You
-set up these callbacks with png_set_progressive_read_fn(). You don't
-have to worry about the input/output functions of libpng, as you are
-giving the library the data directly in png_process_data(). I will
-assume that you have read the section on reading PNG files above,
-so I will only highlight the differences (although I will show
-all of the code).
-
-png_structp png_ptr;
-png_infop info_ptr;
-
- /* An example code fragment of how you would
- initialize the progressive reader in your
- application. */
- int
- initialize_png_reader()
- {
- png_ptr = png_create_read_struct
- (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
- user_error_fn, user_warning_fn);
- if (!png_ptr)
- return -1;
- info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr)
- {
- png_destroy_read_struct(&png_ptr, (png_infopp)NULL,
- (png_infopp)NULL);
- return -1;
- }
-
- if (setjmp(png_ptr->jmpbuf))
- {
- png_destroy_read_struct(&png_ptr, &info_ptr,
- (png_infopp)NULL);
- return -1;
- }
-
- /* This one's new. You can provide functions
- to be called when the header info is valid,
- when each row is completed, and when the image
- is finished. If you aren't using all functions,
- you can specify NULL parameters. Even when all
- three functions are NULL, you need to call
- png_set_progressive_read_fn(). You can use
- any struct as the user_ptr (cast to a void pointer
- for the function call), and retrieve the pointer
- from inside the callbacks using the function
-
- png_get_progressive_ptr(png_ptr);
-
- which will return a void pointer, which you have
- to cast appropriately.
- */
- png_set_progressive_read_fn(png_ptr, (void *)user_ptr,
- info_callback, row_callback, end_callback);
-
- return 0;
- }
-
- /* A code fragment that you call as you receive blocks
- of data */
- int
- process_data(png_bytep buffer, png_uint_32 length)
- {
- if (setjmp(png_ptr->jmpbuf))
- {
- png_destroy_read_struct(&png_ptr, &info_ptr,
- (png_infopp)NULL);
- return -1;
- }
-
- /* This one's new also. Simply give it a chunk
- of data from the file stream (in order, of
- course). On machines with segmented memory
- models machines, don't give it any more than
- 64K. The library seems to run fine with sizes
- of 4K. Although you can give it much less if
- necessary (I assume you can give it chunks of
- 1 byte, I haven't tried less then 256 bytes
- yet). When this function returns, you may
- want to display any rows that were generated
- in the row callback if you don't already do
- so there.
- */
- png_process_data(png_ptr, info_ptr, buffer, length);
- return 0;
- }
-
- /* This function is called (as set by
- png_set_progressive_read_fn() above) when enough data
- has been supplied so all of the header has been
- read.
- */
- void
- info_callback(png_structp png_ptr, png_infop info)
- {
- /* Do any setup here, including setting any of
- the transformations mentioned in the Reading
- PNG files section. For now, you _must_ call
- either png_start_read_image() or
- png_read_update_info() after all the
- transformations are set (even if you don't set
- any). You may start getting rows before
- png_process_data() returns, so this is your
- last chance to prepare for that.
- */
- }
-
- /* This function is called when each row of image
- data is complete */
- void
- row_callback(png_structp png_ptr, png_bytep new_row,
- png_uint_32 row_num, int pass)
- {
- /* If the image is interlaced, and you turned
- on the interlace handler, this function will
- be called for every row in every pass. Some
- of these rows will not be changed from the
- previous pass. When the row is not changed,
- the new_row variable will be NULL. The rows
- and passes are called in order, so you don't
- really need the row_num and pass, but I'm
- supplying them because it may make your life
- easier.
-
- For the non-NULL rows of interlaced images,
- you must call png_progressive_combine_row()
- passing in the row and the old row. You can
- call this function for NULL rows (it will just
- return) and for non-interlaced images (it just
- does the memcpy for you) if it will make the
- code easier. Thus, you can just do this for
- all cases:
- */
-
- png_progressive_combine_row(png_ptr, old_row,
- new_row);
-
- /* where old_row is what was displayed for
- previously for the row. Note that the first
- pass (pass == 0, really) will completely cover
- the old row, so the rows do not have to be
- initialized. After the first pass (and only
- for interlaced images), you will have to pass
- the current row, and the function will combine
- the old row and the new row.
- */
- }
-
- void
- end_callback(png_structp png_ptr, png_infop info)
- {
- /* This function is called after the whole image
- has been read, including any chunks after the
- image (up to and including the IEND). You
- will usually have the same info chunk as you
- had in the header, although some data may have
- been added to the comments and time fields.
-
- Most people won't do much here, perhaps setting
- a flag that marks the image as finished.
- */
- }
-
-
-
-IV. Writing
-
-Much of this is very similar to reading. However, everything of
-importance is repeated here, so you won't have to constantly look
-back up in the reading section to understand writing.
-
-You will want to do the I/O initialization before you get into libpng,
-so if it doesn't work, you don't have anything to undo. If you are not
-using the standard I/O functions, you will need to replace them with
-custom writing functions. See the discussion under Customizing libpng.
-
- FILE *fp = fopen(file_name, "wb");
- if (!fp)
- {
- return;
- }
-
-Next, png_struct and png_info need to be allocated and initialized.
-As these can be both relatively large, you may not want to store these
-on the stack, unless you have stack space to spare. Of course, you
-will want to check if they return NULL. If you are also reading,
-you won't want to name your read structure and your write structure
-both "png_ptr"; you can call them anything you like, such as
-"read_ptr" and "write_ptr". Look at pngtest.c, for example.
-
- png_structp png_ptr = png_create_write_struct
- (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
- user_error_fn, user_warning_fn);
- if (!png_ptr)
- return;
-
- png_infop info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr)
- {
- png_destroy_write_struct(&png_ptr,
- (png_infopp)NULL);
- return;
- }
-
-If you want to use your own memory allocation routines,
-define PNG_USER_MEM_SUPPORTED and use
-png_create_write_struct_2() instead of png_create_read_struct():
-
- png_structp png_ptr = png_create_write_struct_2
- (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
- user_error_fn, user_warning_fn, (png_voidp)
- user_mem_ptr, user_malloc_fn, user_free_fn);
-
-After you have these structures, you will need to set up the
-error handling. When libpng encounters an error, it expects to
-longjmp() back to your routine. Therefore, you will need to call
-setjmp() and pass the png_ptr->jmpbuf. If you
-write the file from different routines, you will need to update
-the jmpbuf field every time you enter a new routine that will
-call a png_ function. See your documentation of setjmp/longjmp
-for your compiler for more information on setjmp/longjmp. See
-the discussion on libpng error handling in the Customizing Libpng
-section below for more information on the libpng error handling.
-
- if (setjmp(png_ptr->jmpbuf))
- {
- png_destroy_write_struct(&png_ptr, &info_ptr);
- fclose(fp);
- return;
- }
- ...
- return;
-
-Now you need to set up the output code. The default for libpng is to
-use the C function fwrite(). If you use this, you will need to pass a
-valid FILE * in the function png_init_io(). Be sure that the file is
-opened in binary mode. Again, if you wish to handle writing data in
-another way, see the discussion on libpng I/O handling in the Customizing
-Libpng section below.
-
- png_init_io(png_ptr, fp);
-
-At this point, you can set up a callback function that will be
-called after each row has been written, which you can use to control
-a progress meter or the like. It's demonstrated in pngtest.c.
-You must supply a function
-
- void write_row_callback(png_ptr, png_uint_32 row, int pass);
- {
- /* put your code here */
- }
-
-(You can give it another name that you like instead of "write_row_callback")
-
-To inform libpng about your function, use
-
- png_set_write_status_fn(png_ptr, write_row_callback);
-
-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 some 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 by
-not calling this function at all, as it has been tuned to deliver a good
-speed/compression ratio. The second parameter to png_set_filter() is
-the filter method, for which the only valid value is '0' (as of the
-October 1996 PNG specification, version 1.0). The third parameter is a
-flag that indicates which filter type(s) are to be tested for each
-scanline. See the Compression Library for details on the specific filter
-types.
-
-
- /* turn on or off filtering, and/or choose
- specific filters */
- png_set_filter(png_ptr, 0,
- PNG_FILTER_NONE | PNG_FILTER_SUB |
- PNG_FILTER_PAETH);
-
-The png_set_compression_???() functions interface to the zlib compression
-library, and should mostly be ignored unless you really know what you are
-doing. The only generally useful call is png_set_compression_level()
-which changes how much time zlib spends on trying to compress the image
-data. See the Compression Library for details on the compression levels.
-
- /* set the zlib compression level */
- png_set_compression_level(png_ptr,
- Z_BEST_COMPRESSION);
-
- /* set other zlib parameters */
- 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 time
-chunk (as of PNG Specification 1.0, anyway). See png_write_end() and
-the latest PNG specification for more information on that. If you
-wish to write them before the image, fill them in now, and flag that
-data as being valid. If you want to wait until after the data, don't
-fill them until png_write_end(). For all the fields in png_info and
-their data types, see png.h. For explanations of what the fields
-contain, see the PNG specification.
-
-Some of the more important parts of the png_info are:
-
- png_set_IHDR(png_ptr, info_ptr, width, height,
- bit_depth, color_type, interlace_type,
- compression_type, filter_type)
- width - holds the width of the image
- in pixels (up to 2^31).
- height - holds the height of the image
- in pixels (up to 2^31).
- bit_depth - holds the bit depth of one of the
- image channels.
- (valid values are 1, 2, 4, 8, 16
- and depend also on the
- color_type. See also significant
- bits (sBIT) below).
- color_type - describes which color/alpha
- channels are present.
- PNG_COLOR_TYPE_GRAY
- (bit depths 1, 2, 4, 8, 16)
- PNG_COLOR_TYPE_GRAY_ALPHA
- (bit depths 8, 16)
- PNG_COLOR_TYPE_PALETTE
- (bit depths 1, 2, 4, 8)
- PNG_COLOR_TYPE_RGB
- (bit_depths 8, 16)
- PNG_COLOR_TYPE_RGB_ALPHA
- (bit_depths 8, 16)
-
- PNG_COLOR_MASK_PALETTE
- PNG_COLOR_MASK_COLOR
- PNG_COLOR_MASK_ALPHA
-
- interlace_type - PNG_INTERLACE_NONE or
- PNG_INTERLACE_ADAM7
- compression_type - (must be
- PNG_COMPRESSION_TYPE_DEFAULT)
- filter_type - (must be PNG_FILTER_TYPE_DEFAULT)
-
- png_set_PLTE(png_ptr, info_ptr, palette,
- num_palette);
- palette - the palette for the file
- (array of png_color)
- num_palette - number of entries in the palette
-
- png_set_gAMA(png_ptr, info_ptr, gamma);
- gamma - the gamma the image was created
- at (PNG_INFO_gAMA)
-
- png_set_sRGB(png_ptr, info_ptr, srgb_intent);
- srgb_intent - the rendering intent
- (PNG_INFO_sRGB) The presence of
- the sRGB chunk means that the pixel
- data is in the sRGB color space.
- This chunk also implies specific
- values of gAMA and cHRM. Rendering
- intent is the CSS-1 property that
- has been defined by the International
- Color Consortium
- (http://www.color.org).
- It can be one of
- PNG_SRGB_INTENT_SATURATION,
- PNG_SRGB_INTENT_PERCEPTUAL,
- PNG_SRGB_INTENT_ABSOLUTE, or
- PNG_SRGB_INTENT_RELATIVE.
-
-
- png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr,
- srgb_intent);
- srgb_intent - the rendering intent
- (PNG_INFO_sRGB) The presence of the
- sRGB chunk means that the pixel
- data is in the sRGB color space.
- This function also causes gAMA and
- cHRM chunks with the specific values
- that are consistent with sRGB to be
- written.
-
- png_set_sBIT(png_ptr, info_ptr, sig_bit);
- sig_bit - the number of significant bits for
- (PNG_INFO_sBIT) each of the gray, red,
- green, and blue channels, whichever are
- appropriate for the given color type
- (png_color_16)
-
- png_set_tRNS(png_ptr, info_ptr, trans, num_trans,
- trans_values);
- trans - array of transparent entries for
- palette (PNG_INFO_tRNS)
- trans_values - transparent pixel for non-paletted
- images (PNG_INFO_tRNS)
- num_trans - number of transparent entries
- (PNG_INFO_tRNS)
-
- png_set_hIST(png_ptr, info_ptr, hist);
- (PNG_INFO_hIST)
- hist - histogram of palette (array of
- png_color_16)
-
- png_set_tIME(png_ptr, info_ptr, mod_time);
- mod_time - time image was last modified
- (PNG_VALID_tIME)
-
- png_set_bKGD(png_ptr, info_ptr, background);
- background - background color (PNG_VALID_bKGD)
-
- png_set_text(png_ptr, info_ptr, text_ptr, num_text);
- text_ptr - array of png_text holding image
- comments
- text_ptr[i]->key - keyword for comment.
- text_ptr[i]->text - text comments for current
- keyword.
- text_ptr[i]->compression - type of compression used
- on "text" PNG_TEXT_COMPRESSION_NONE or
- PNG_TEXT_COMPRESSION_zTXt
- num_text - number of comments in text_ptr
-
- png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y,
- unit_type);
- offset_x - positive offset from the left
- edge of the screen
- offset_y - positive offset from the top
- edge of the screen
- unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER
-
- png_set_pHYs(png_ptr, info_ptr, res_x, res_y,
- unit_type);
- res_x - pixels/unit physical resolution
- in x direction
- res_y - pixels/unit physical resolution
- in y direction
- unit_type - PNG_RESOLUTION_UNKNOWN,
- PNG_RESOLUTION_METER
-
-In PNG files, the alpha channel in an image is the level of opacity.
-If your data is supplied as a level of transparency, you can invert the
-alpha channel before you write it, so that 0 is fully transparent and 255
-(in 8-bit or paletted images) or 65535 (in 16-bit images) is fully opaque,
-with
-
- png_set_invert_alpha(png_ptr);
-
-This must appear here instead of later with the other transformations
-because in the case of paletted images the tRNS chunk data has to
-be inverted before the tRNS chunk is written. If your image is not a
-paletted image, the tRNS data (which in such cases represents a single
-color to be rendered as transparent) won't be changed.
-
-A quick word about text and num_text. text is an array of png_text
-structures. num_text is the number of valid structures in the array.
-If you want, you can use max_text to hold the size of the array, but
-libpng ignores it for writing (it does use it for reading). Each
-png_text structure holds a keyword-text value, and a compression type.
-The compression types have the same valid numbers as the compression
-types of the image data. Currently, the only valid number is zero.
-However, you can store text either compressed or uncompressed, unlike
-images, which always have to be compressed. So if you don't want the
-text compressed, set the compression type to PNG_TEXT_COMPRESSION_NONE.
-Until text gets around 1000 bytes, it is not worth compressing it.
-After the text has been written out to the file, the compression type
-is set to PNG_TEXT_COMPRESSION_NONE_WR or PNG_TEXT_COMPRESSION_zTXt_WR,
-so that it isn't written out again at the end (in case you are calling
-png_write_end() with the same struct.
-
-The keywords that are given in the PNG Specification are:
-
- Title Short (one line) title or
- caption for image
- Author Name of image's creator
- Description Description of image (possibly long)
- Copyright Copyright notice
- Creation Time Time of original image creation
- (usually RFC 1123 format, see below)
- Software Software used to create the image
- Disclaimer Legal disclaimer
- Warning Warning of nature of content
- Source Device used to create the image
- Comment Miscellaneous comment; conversion
- from other image format
-
-The keyword-text pairs work like this. Keywords should be short
-simple descriptions of what the comment is about. Some typical
-keywords are found in the PNG specification, as is some recommendations
-on keywords. You can repeat keywords in a file. You can even write
-some text before the image and some after. For example, you may want
-to put a description of the image before the image, but leave the
-disclaimer until after, so viewers working over modem connections
-don't have to wait for the disclaimer to go over the modem before
-they start seeing the image. Finally, keywords should be full
-words, not abbreviations. Keywords and text are in the ISO 8859-1
-(Latin-1) character set (a superset of regular ASCII) and can not
-contain NUL characters, and should not contain control or other
-unprintable characters. To make the comments widely readable, stick
-with basic ASCII, and avoid machine specific character set extensions
-like the IBM-PC character set. The keyword must be present, but
-you can leave off the text string on non-compressed pairs.
-Compressed pairs must have a text string, as only the text string
-is compressed anyway, so the compression would be meaningless.
-
-PNG supports modification time via the png_time structure. Two
-conversion routines are proved, png_convert_from_time_t() for
-time_t and png_convert_from_struct_tm() for struct tm. The
-time_t routine uses gmtime(). You don't have to use either of
-these, but if you wish to fill in the png_time structure directly,
-you should provide the time in universal time (GMT) if possible
-instead of your local time. Note that the year number is the full
-year (e.g. 1998, rather than 98 - PNG is year 2000 compliant!), and
-that months start with 1.
-
-If you want to store the time of the original image creation, you should
-use a plain tEXt chunk with the "Creation Time" keyword. This is
-necessary because the "creation time" of a PNG image is somewhat vague,
-depending on whether you mean the PNG file, the time the image was
-created in a non-PNG format, a still photo from which the image was
-scanned, or possibly the subject matter itself. In order to facilitate
-machine-readable dates, it is recommended that the "Creation Time"
-tEXt chunk use RFC 1123 format dates (e.g. "22 May 1997 18:07:10 GMT"),
-although this isn't a requirement. Unlike the tIME chunk, the
-"Creation Time" tEXt chunk is not expected to be automatically changed
-by the software. To facilitate the use of RFC 1123 dates, a function
-png_convert_to_rfc1123(png_timep) is provided to convert from PNG
-time to an RFC 1123 format string.
-
-You are now ready to write all the file information up to the actual
-image data. You do this with a call to png_write_info().
-
- png_write_info(png_ptr, info_ptr);
-
-After you've written the file information, you can set up the library
-to handle any special transformations of the image data. The various
-ways to transform the data will be described in the order that they
-should occur. This is important, as some of these change the color
-type and/or bit depth of the data, and some others only work on
-certain color types and bit depths. Even though each transformation
-checks to see if it has data that it can do something with, you should
-make sure to only enable a transformation if it will be valid for the
-data. For example, don't swap red and blue on grayscale data.
-
-PNG files store RGB pixels packed into 3 or 6 bytes. This code tells
-the library to expand the input data to 4 or 8 bytes per pixel
-(or expand 1 or 2-byte grayscale data to 2 or 4 bytes per pixel).
-
- png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
-
-where the 0 is the value that will be put in the 4th byte, and the
-location is either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending
-upon whether the filler byte is stored XRGB or RGBX.
-
-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.
-If the data is supplied at 1 pixel per byte, use this code, which will
-correctly pack the pixels into a single byte:
-
- png_set_packing(png_ptr);
-
-PNG files reduce possible bit depths to 1, 2, 4, 8, and 16. If your
-data is of another bit depth, you can write an sBIT chunk into the
-file so that decoders can get the original data if desired.
-
- /* Set the true bit depth of the image data */
- if (color_type & PNG_COLOR_MASK_COLOR)
- {
- sig_bit.red = true_bit_depth;
- sig_bit.green = true_bit_depth;
- sig_bit.blue = true_bit_depth;
- }
- else
- {
- sig_bit.gray = true_bit_depth;
- }
- if (color_type & PNG_COLOR_MASK_ALPHA)
- {
- sig_bit.alpha = true_bit_depth;
- }
-
- png_set_sBIT(png_ptr, info_ptr, &sig_bit);
-
-If the data is stored in the row buffer in a bit depth other than
-one supported by PNG (e.g. 3 bit data in the range 0-7 for a 4-bit PNG),
-this will scale the values to appear to be the correct bit depth as
-is required by PNG.
-
- png_set_shift(png_ptr, &sig_bit);
-
-PNG files store 16 bit pixels in network byte order (big-endian,
-ie. most significant bits first). This code would be used if they are
-supplied the other way (little-endian, i.e. least significant bits
-first, the way PCs store them):
-
- if (bit_depth > 8)
- png_set_swap(png_ptr);
-
-If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you
-need to change the order the pixels are packed into bytes, you can use:
-
- if (bit_depth < 8)
- png_set_packswap(png_ptr);
-
-PNG files store 3 color pixels in red, green, blue order. This code
-would be used if they are supplied as blue, green, red:
-
- png_set_bgr(png_ptr);
-
-PNG files describe monochrome as black being zero and white being
-one. This code would be used if the pixels are supplied with this reversed
-(black being one and white being zero):
-
- png_set_invert_mono(png_ptr);
-
-Finally, you can write your own transformation function if none of
-the existing ones meets your needs. This is done by setting a callback
-with
-
- png_set_write_user_transform_fn(png_ptr,
- write_transform_fn);
-
-You must supply the function
-
- void write_transform_fn(png_ptr ptr, row_info_ptr
- row_info, png_bytep data)
-
-See pngtest.c for a working example. Your function will be called
-before any of the other transformations have been processed.
-
-It is possible to have libpng flush any pending output, either manually,
-or automatically after a certain number of lines have been written. To
-flush the output stream a single time call:
-
- png_write_flush(png_ptr);
-
-and to have libpng flush the output stream periodically after a certain
-number of scanlines have been written, call:
-
- png_set_flush(png_ptr, nrows);
-
-Note that the distance between rows is from the last time png_write_flush()
-was called, or the first row of the image if it has never been called.
-So if you write 50 lines, and then png_set_flush 25, it will flush the
-output on the next scanline, and every 25 lines thereafter, unless
-png_write_flush() is called before 25 more lines have been written.
-If nrows is too small (less than about 10 lines for a 640 pixel wide
-RGB image) the image compression may decrease noticeably (although this
-may be acceptable for real-time applications). Infrequent flushing will
-only degrade the compression performance by a few percent over images
-that do not use flushing.
-
-That's it for the transformations. Now you can write the image data.
-The simplest way to do this is in one function call. If have the
-whole image in memory, you can just call png_write_image() and libpng
-will write the image. You will need to pass in an array of pointers to
-each row. This function automatically handles interlacing, so you don't
-need to call png_set_interlace_handling() or call this function multiple
-times, or any of that other stuff necessary with png_write_rows().
-
- png_write_image(png_ptr, row_pointers);
-
-where row_pointers is:
-
- png_byte *row_pointers[height];
-
-You can point to void or char or whatever you use for pixels.
-
-If you don't want to write the whole image at once, you can
-use png_write_rows() instead. If the file is not interlaced,
-this is simple:
-
- png_write_rows(png_ptr, row_pointers,
- number_of_rows);
-
-row_pointers is the same as in the png_write_image() call.
-
-If you are just writing one row at a time, you can do this with
-row_pointers:
-
- png_bytep row_pointer = row;
-
- png_write_row(png_ptr, &row_pointer);
-
-When the file is interlaced, things can get a good deal more
-complicated. The only currently (as of February 1998 -- PNG Specification
-version 1.0, dated October 1996) defined interlacing scheme for PNG files
-is the "Adam7" interlace scheme, that breaks down an
-image into seven smaller images of varying size. libpng will build
-these images for you, or you can do them yourself. If you want to
-build them yourself, see the PNG specification for details of which
-pixels to write when.
-
-If you don't want libpng to handle the interlacing details, just
-use png_set_interlace_handling() and call png_write_rows() the
-correct number of times to write all seven sub-images.
-
-If you want libpng to build the sub-images, call this before you start
-writing any rows:
-
- number_of_passes =
- png_set_interlace_handling(png_ptr);
-
-This will return the number of passes needed. Currently, this
-is seven, but may change if another interlace type is added.
-
-Then write the complete image number_of_passes times.
-
- png_write_rows(png_ptr, row_pointers,
- number_of_rows);
-
-As some of these rows are not used, and thus return immediately,
-you may want to read about interlacing in the PNG specification,
-and only update the rows that are actually used.
-
-After you are finished writing the image, you should finish writing
-the file. If you are interested in writing comments or time, you should
-pass an appropriately filled png_info pointer. If you are not interested,
-you can pass NULL.
-
- png_write_end(png_ptr, info_ptr);
-
-When you are done, you can free all memory used by libpng like this:
-
- png_destroy_write_struct(&png_ptr, &info_ptr);
-
-You must free any data you allocated for info_ptr, such as comments,
-palette, or histogram, before the call to png_destroy_write_struct();
-
-For a more compact example of writing a PNG image, see the file example.c.
-
-
-V. Modifying/Customizing libpng:
-
-There are two issues here. The first is changing how libpng does
-standard things like memory allocation, input/output, and error handling.
-The second deals with more complicated things like adding new chunks,
-adding new transformations, and generally changing how libpng works.
-
-All of the memory allocation, input/output, and error handling in libpng
-goes through callbacks that are user settable. The default routines are
-in pngmem.c, pngrio.c, pngwio.c, and pngerror.c respectively. To change
-these functions, call the appropriate png_set_???_fn() function.
-
-Memory allocation is done through the functions png_large_malloc(),
-png_malloc(), png_realloc(), png_large_free(), and png_free(). These
-currently just call the standard C functions. The large functions must
-handle exactly 64K, but they don't have to handle more than that. If
-your pointers can't access more then 64K at a time, you will want to set
-MAXSEG_64K in zlib.h. Since it is unlikely that the method of handling
-memory allocation on a platform will change between applications, these
-functions must be modified in the library at compile time.
-
-Input/Output in libpng is done through png_read() and png_write(),
-which currently just call fread() and fwrite(). The FILE * is stored in
-png_struct and is initialized via png_init_io(). If you wish to change
-the method of I/O, the library supplies callbacks that you can set
-through the function png_set_read_fn() and png_set_write_fn() at run
-time, instead of calling the png_init_io() function. These functions
-also provide a void pointer that can be retrieved via the function
-png_get_io_ptr(). For example:
-
- png_set_read_fn(png_structp read_ptr,
- voidp read_io_ptr, png_rw_ptr read_data_fn)
-
- png_set_write_fn(png_structp write_ptr,
- voidp write_io_ptr, png_rw_ptr write_data_fn,
- png_flush_ptr output_flush_fn);
-
- voidp read_io_ptr = png_get_io_ptr(read_ptr);
- voidp write_io_ptr = png_get_io_ptr(write_ptr);
-
-The replacement I/O functions should have prototypes as follows:
-
- void user_read_data(png_structp png_ptr,
- png_bytep data, png_uint_32 length);
- void user_write_data(png_structp png_ptr,
- png_bytep data, png_uint_32 length);
- void user_flush_data(png_structp png_ptr);
-
-Supplying NULL for the read, write, or flush functions sets them back
-to using the default C stream functions. It is an error to read from
-a write stream, and vice versa.
-
-Error handling in libpng is done through png_error() and png_warning().
-Errors handled through png_error() are fatal, meaning that png_error()
-should never return to its caller. Currently, this is handled via
-setjmp() and longjmp(), but you could change this to do things like
-exit() if you should wish. On non-fatal errors, png_warning() is called
-to print a warning message, and then control returns to the calling code.
-By default png_error() and png_warning() print a message on stderr via
-fprintf() unless the library is compiled with PNG_NO_STDIO defined. If
-you wish to change the behavior of the error functions, you will need to
-set up your own message callbacks. These functions are normally supplied
-at the time that the png_struct is created. It is also possible to change
-these functions after png_create_???_struct() has been called by calling:
-
- png_set_error_fn(png_structp png_ptr,
- png_voidp error_ptr, png_error_ptr error_fn,
- png_error_ptr warning_fn);
-
- png_voidp error_ptr = png_get_error_ptr(png_ptr);
-
-If NULL is supplied for either error_fn or warning_fn, then the libpng
-default function will be used, calling fprintf() and/or longjmp() if a
-problem is encountered. The replacement error functions should have
-parameters as follows:
-
- void user_error_fn(png_structp png_ptr,
- png_const_charp error_msg);
- void user_warning_fn(png_structp png_ptr,
- png_const_charp warning_msg);
-
-The motivation behind using setjmp() and longjmp() is the C++ throw and
-catch exception handling methods. This makes the code much easier to write,
-as there is no need to check every return code of every function call.
-However, there are some uncertainties about the status of local variables
-after a longjmp, so the user may want to be careful about doing anything after
-setjmp returns non-zero besides returning itself. Consult your compiler
-documentation for more details.
-
-If you need to read or write custom chunks, you will need to get deeper
-into the libpng code, as a mechanism has not yet been supplied for user
-callbacks with custom chunks. First, read the PNG specification, and have
-a first level of understanding of how it works. Pay particular attention
-to the sections that describe chunk names, and look at how other chunks
-were designed, so you can do things similarly. Second, check out the
-sections of libpng that read and write chunks. Try to find a chunk that
-is similar to yours and copy off of it. More details can be found in the
-comments inside the code. A way of handling unknown chunks in a generic
-method, potentially via callback functions, would be best.
-
-If you wish to write your own transformation for the data, look through
-the part of the code that does the transformations, and check out some of
-the simpler ones to get an idea of how they work. Try to find a similar
-transformation to the one you want to add and copy off of it. More details
-can be found in the comments inside the code itself.
-
-Configuring for 16 bit platforms:
-
-You may need to change the png_large_malloc() and png_large_free()
-routines in pngmem.c, as these are required to allocate 64K, although
-there is already support for many of the common DOS compilers. Also,
-you will want to look into zconf.h to tell zlib (and thus libpng) that
-it cannot allocate more then 64K at a time. Even if you can, the memory
-won't be accessible. So limit zlib and libpng to 64K by defining MAXSEG_64K.
-
-Configuring for DOS:
-
-For DOS users who only have access to the lower 640K, you will
-have to limit zlib's memory usage via a png_set_compression_mem_level()
-call. See zlib.h or zconf.h in the zlib library for more information.
-
-Configuring for Medium Model:
-
-Libpng's support for medium model has been tested on most of the popular
-compilers. Make sure MAXSEG_64K gets defined, USE_FAR_KEYWORD gets
-defined, and FAR gets defined to far in pngconf.h, and you should be
-all set. Everything in the library (except for zlib's structure) is
-expecting far data. You must use the typedefs with the p or pp on
-the end for pointers (or at least look at them and be careful). Make
-note that the row's of data are defined as png_bytepp, which is an
-unsigned char far * far *.
-
-Configuring for gui/windowing platforms:
-
-You will need to write new error and warning functions that use the GUI
-interface, as described previously, and set them to be the error and
-warning functions at the time that png_create_???_struct() is called,
-in order to have them available during the structure initialization.
-They can be changed later via png_set_error_fn(). On some compilers,
-you may also have to change the memory allocators (png_malloc, etc.).
-
-Configuring for compiler xxx:
-
-All includes for libpng are in pngconf.h. If you need to add/change/delete
-an include, this is the place to do it. The includes that are not
-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, which includes pngconf.h.
-
-Configuring zlib:
-
-There are special functions to configure the compression. Perhaps the
-most useful one changes the compression level, which currently uses
-input compression values in the range 0 - 9. The library normally
-uses the default compression level (Z_DEFAULT_COMPRESSION = 6). Tests
-have shown that for a large majority of images, compression values in
-the range 3-6 compress nearly as well as higher levels, and do so much
-faster. For online applications it may be desirable to have maximum speed
-(Z_BEST_SPEED = 1). With versions of zlib after v0.99, you can also
-specify no compression (Z_NO_COMPRESSION = 0), but this would create
-files larger than just storing the raw bitmap. You can specify the
-compression level by calling:
-
- png_set_compression_level(png_ptr, level);
-
-Another useful one is to reduce the memory level used by the library.
-The memory level defaults to 8, but it can be lowered if you are
-short on memory (running DOS, for example, where you only have 640K).
-
- png_set_compression_mem_level(png_ptr, level);
-
-The other functions are for configuring zlib. They are not recommended
-for normal use and may result in writing an invalid PNG file. See
-zlib.h for more information on what these mean.
-
- png_set_compression_strategy(png_ptr,
- strategy);
- png_set_compression_window_bits(png_ptr,
- window_bits);
- png_set_compression_method(png_ptr, method);
-
-Controlling row filtering:
-
-If you want to control whether libpng uses filtering or not, which
-filters are used, and how it goes about picking row filters, you
-can call one of these functions. The selection and configuration
-of row filters can have a significant impact on the size and
-encoding speed and a somewhat lesser impact on the decoding speed
-of an image. Filtering is enabled by default for RGB and grayscale
-images (with and without alpha), but not for paletted images nor
-for any images with bit depths less than 8 bits/pixel.
-
-The 'method' parameter sets the main filtering method, which is
-currently only '0' in the PNG 1.0 specification. The 'filters'
-parameter sets which filter(s), if any, should be used for each
-scanline. Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS
-to turn filtering on and off, respectively.
-
-Individual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB,
-PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise
-ORed together '|' to specify one or more filters to use. These
-filters are described in more detail in the PNG specification. If
-you intend to change the filter type during the course of writing
-the image, you should start with flags set for all of the filters
-you intend to use so that libpng can initialize its internal
-structures appropriately for all of the filter types.
-
- filters = PNG_FILTER_NONE | PNG_FILTER_SUB
- | PNG_FILTER_UP;
- png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE,
- filters);
-
-It is also possible to influence how libpng chooses from among the
-available filters. This is done in two ways - by telling it how
-important it is to keep the same filter for successive rows, and
-by telling it the relative computational costs of the filters.
-
- double weights[3] = {1.5, 1.3, 1.1},
- costs[PNG_FILTER_VALUE_LAST] =
- {1.0, 1.3, 1.3, 1.5, 1.7};
-
- png_set_filter_selection(png_ptr,
- PNG_FILTER_SELECTION_WEIGHTED, 3,
- weights, costs);
-
-The weights are multiplying factors that indicate to libpng that the
-row filter should be the same for successive rows unless another row filter
-is that many times better than the previous filter. In the above example,
-if the previous 3 filters were SUB, SUB, NONE, the SUB filter could have a
-"sum of absolute differences" 1.5 x 1.3 times higher than other filters
-and still be chosen, while the NONE filter could have a sum 1.1 times
-higher than other filters and still be chosen. Unspecified weights are
-taken to be 1.0, and the specified weights should probably be declining
-like those above in order to emphasize recent filters over older filters.
-
-The filter costs specify for each filter type a relative decoding cost
-to be considered when selecting row filters. This means that filters
-with higher costs are less likely to be chosen over filters with lower
-costs, unless their "sum of absolute differences" is that much smaller.
-The costs do not necessarily reflect the exact computational speeds of
-the various filters, since this would unduly influence the final image
-size.
-
-Note that the numbers above were invented purely for this example and
-are given only to help explain the function usage. Little testing has
-been done to find optimum values for either the costs or the weights.
-
-Removing unwanted object code:
-
-There are a bunch of #define's in pngconf.h that control what parts of
-libpng are compiled. All the defines end in _SUPPORTED. If you are
-never going to use a capability, you can change the #define to #undef
-before recompiling libpng and save yourself code and data space, or
-you can turn off individual capabilities with defines that begin with
-PNG_NO_.
-
-You can also turn all of the transforms and ancillary chunk capabilities
-off en masse with compiler directives that define
-PNG_NO_READ[or WRITE]_TRANSFORMS, or PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS,
-or all four,
-along with directives to turn on any of the capabilities that you do
-want. The PNG_NO_READ[or WRITE]_TRANSFORMS directives disable
-the extra transformations but still leave the library fully capable of reading
-and writing PNG files with all known public chunks [except for sPLT].
-Use of the PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS directive
-produces a library that is incapable of reading or writing ancillary chunks.
-If you are not using the progressive reading capability, you can
-turn that off with PNG_NO_PROGRESSIVE_READ (don't confuse
-this with the INTERLACING capability, which you'll still have).
-
-All the reading and writing specific code are in separate 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.
-The progressive reader is in pngpread.c
-
-If you are creating or distributing a dynamically linked library (a .so
-or DLL file), you should not remove or disable any parts of the library,
-as this will cause applications linked with different versions of the
-library to fail if they call functions not available in your library.
-The size of the library itself should not be an issue, because only
-those sections that are actually used will be loaded into memory.
-
-Requesting debug printout:
-
-The macro definition PNG_DEBUG can be used to request debugging
-printout. Set it to an integer value in the range 0 to 3. Higher
-numbers result in increasing amounts of debugging information. The
-information is printed to the "stderr" file, unless another file
-name is specified in the PNG_DEBUG_FILE macro definition.
-
-When PNG_DEBUG > 0, the following functions (macros) become available:
-
- png_debug(level, message)
- png_debug1(level, message, p1)
- png_debug2(level, message, p1, p2)
-
-in which "level" is compared to PNG_DEBUG to decide whether to print
-the message, "message" is the formatted string to be printed,
-and p1 and p2 are parameters that are to be embedded in the string
-according to printf-style formatting directives. For example,
-
- png_debug1(2, "foo=%d\n", foo);
-
-is expanded to
-
- if(PNG_DEBUG > 2)
- fprintf(PNG_DEBUG_FILE, "foo=%d\n", foo);
-
-When PNG_DEBUG is defined but is zero, the macros aren't defined, but you
-can still use PNG_DEBUG to control your own debugging:
-
- #ifdef PNG_DEBUG
- fprintf(stderr, ...
- #endif
-
-When PNG_DEBUG = 1, the macros are defined, but only png_debug statements
-having level = 0 will be printed. There aren't any such statements in
-this version of libpng, but if you insert some they will be printed.
-
-VI. Changes to Libpng from version 0.88
-
-It should be noted that versions of libpng later than 0.96 are not
-distributed by the original libpng author, Guy Schalnat, nor by
-Andreas Dilger, who had taken over from Guy during 1996 and 1997, and
-distributed versions 0.89 through 0.96, but rather by another member
-of the original PNG Group, Glenn Randers-Pehrson. Guy and Andreas are
-still alive and well, but they have moved on to other things.
-
-The old libpng functions png_read_init(), png_write_init(),
-png_info_init(), png_read_destroy(), and png_write_destory() have been
-moved to PNG_INTERNAL in version 0.95 to discourage their use. The
-preferred method of creating and initializing the libpng structures is
-via the png_create_read_struct(), png_create_write_struct(), and
-png_create_info_struct() because they isolate the size of the structures
-from the application, allow version error checking, and also allow the
-use of custom error handling routines during the initialization, which
-the old functions do not. The functions png_read_destroy() and
-png_write_destroy() do not actually free the memory that libpng
-allocated for these structs, but just reset the data structures, so they
-can be used instead of png_destroy_read_struct() and
-png_destroy_write_struct() if you feel there is too much system overhead
-allocating and freeing the png_struct for each image read.
-
-Setting the error callbacks via png_set_message_fn() before
-png_read_init() as was suggested in libpng-0.88 is no longer supported
-because this caused applications that do not use custom error functions
-to fail if the png_ptr was not initialized to zero. It is still possible
-to set the error callbacks AFTER png_read_init(), or to change them with
-png_set_error_fn(), which is essentially the same function, but with a
-new name to force compilation errors with applications that try to use
-the old method.
-
-VII. Y2K Compliance in libpng
-
-January 13, 1999
-
-Since the PNG Development group is an ad-hoc body, we can't make
-an official declaration.
-
-This is your unofficial assurance that libpng from version 0.81 and
-upward are Y2K compliant. It is my belief that earlier versions were
-also Y2K compliant.
-
-Libpng only has three year fields. One is a 2-byte unsigned integer that
-will hold years up to 65535. The other two hold the date in text
-format, and will hold years up to 9999.
-
-The integer is
- "png_uint_16 year" in png_time_struct.
-
-The strings are
- "png_charp time_buffer" in png_struct and
- "near_time_buffer", which is a local character string in png.c.
-
-There are seven time-related functions:
-
- png_convert_to_rfc_1123() in png.c
- (formerly png_convert_to_rfc_1152() in error)
- png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
- png_convert_from_time_t() in pngwrite.c
- png_get_tIME() in pngget.c
- png_handle_tIME() in pngrutil.c, called in pngread.c
- png_set_tIME() in pngset.c
- png_write_tIME() in pngwutil.c, called in pngwrite.c
-
-All appear to handle dates properly in a Y2K environment. The
-png_convert_from_time_t() function calls gmtime() to convert from system
-clock time, which returns (year - 1900), which we properly convert to
-the full 4-digit year. There is a possibility that applications using
-libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
-function, or incorrectly passing only a 2-digit year instead of
-"year - 1900" into the png_convert_from_struct_tm() function, but this
-is not under our control. The libpng documentation has always stated
-that it works with 4-digit years, and the APIs have been documented as
-such.
-
-The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned
-integer to hold the year, and can hold years as large as 65535.
-
-
- Glenn Randers-Pehrson
- libpng maintainer
- PNG Development Group
+++ /dev/null
-.TH LIBPNGPF 3 "January 14, 1999"
-.SH NAME
-libpng \- Portable Network Graphics (PNG) Reference Library 1.0.3 - January 14, 1999
-(private functions)
-.SH SYNOPSIS
-#include <png.h>
-
-void png_build_gamma_table (png_structp png_ptr);
-
-void png_build_grayscale_palette (int bit_depth, png_colorp
-palette);
-
-void png_calculate_crc (png_structp png_ptr, png_bytep ptr,
-png_size_t length);
-void png_check_chunk_name (png_structp png_ptr, png_bytep
-chunk_name);
-
-png_size_t png_check_keyword (png_structp png_ptr, png_charp
-key, png_charpp new_key);
-
-void png_combine_row (png_structp png_ptr, png_bytep row, int
-mask);
-
-void png_correct_palette (png_structp png_ptr, png_colorp
-palette, int num_palette);
-
-int png_crc_error (png_structp png_ptr);
-
-int png_crc_finish (png_structp png_ptr, png_uint_32 skip);
-
-void png_crc_read (png_structp png_ptr, png_bytep buf,
-png_size_t length);
-
-png_voidp png_create_struct (int type, png_malloc_ptr malloc_fn);
-
-png_voidp png_create_struct_2 (int type);
-
-void png_destroy_struct (png_voidp struct_ptr);
-
-void png_destroy_struct_2 (png_voidp struct_ptr, png_free_ptr
-free_fn);
-
-void png_do_background (png_row_infop row_info, png_bytep row,
-png_color_16p trans_values, png_color_16p background,
-png_color_16p background_1, png_bytep gamma_table, png_bytep
-gamma_from_1, png_bytep gamma_to_1, png_uint_16pp gamma_16,
-png_uint_16pp gamma_16_from_1, png_uint_16pp gamma_16_to_1, int
-gamma_shift);
-
-void png_do_bgr (png_row_infop row_info, png_bytep row);
-
-void png_do_chop (png_row_infop row_info, png_bytep row);
-
-void png_do_dither (png_row_infop row_info, png_bytep row,
-png_bytep palette_lookup, png_bytep dither_lookup);
-
-void png_do_expand (png_row_infop row_info, png_bytep row,
-png_color_16p trans_value);
-
-void png_do_expand_palette (png_row_infop row_info, png_bytep
-row, png_colorp palette, png_bytep trans, int num_trans);
-
-void png_do_gamma (png_row_infop row_info, png_bytep row,
-png_bytep gamma_table, png_uint_16pp gamma_16_table, int
-gamma_shift);
-
-void png_do_gray_to_rgb (png_row_infop row_info, png_bytep
-row);
-
-void png_do_invert (png_row_infop row_info, png_bytep row);
-
-void png_do_pack (png_row_infop row_info, png_bytep row,
-png_uint_32 bit_depth);
-
-void png_do_packswap (png_row_infop row_info, png_bytep row);
-
-void png_do_read_filler (png_row_infop row_info, png_bytep row,
-png_uint_32 filler, png_uint_32 flags);
-
-void png_do_read_interlace (png_row_infop row_info, png_bytep
-row, int pass, png_uint_32 transformations);
-
-void png_do_read_invert_alpha (png_row_infop row_info,
-png_bytep row);
-
-void png_do_read_swap_alpha (png_row_infop row_info, png_bytep
-row);
-
-void png_do_read_transformations (png_structp png_ptr);
-
-int png_do_rgb_to_gray (png_row_infop row_info, png_bytep
-row);
-
-void png_do_shift (png_row_infop row_info, png_bytep row,
-png_color_8p bit_depth);
-
-void png_do_strip_filler (png_row_infop row_info, png_bytep
-row, png_uint_32 flags);
-
-void png_do_swap (png_row_infop row_info, png_bytep row);
-
-void png_do_unpack (png_row_infop row_info, png_bytep row);
-
-void png_do_unshift (png_row_infop row_info, png_bytep row,
-png_color_8p sig_bits);
-
-void png_do_write_interlace (png_row_infop row_info, png_bytep
-row, int pass);
-
-void png_do_write_invert_alpha (png_row_infop row_info,
-png_bytep row);
-
-void png_do_write_swap_alpha (png_row_infop row_info, png_bytep
-row);
-
-void png_do_write_transformations (png_structp png_ptr);
-
-void *png_far_to_near (png_structp png_ptr,png_voidp ptr,
-int check);
-
-void png_flush (png_structp png_ptr);
-
-png_int_32 png_get_int_32 (png_bytep buf);
-
-png_uint_16 png_get_uint_16 (png_bytep buf);
-
-png_uint_32 png_get_uint_32 (png_bytep buf);
-
-void png_handle_bKGD (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
-
-void png_handle_cHRM (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
-
-void png_handle_gAMA (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
-
-void png_handle_hIST (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
-
-void png_handle_IEND (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
-
-void png_handle_IHDR (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
-
-void png_handle_oFFs (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
-
-void png_handle_pCAL (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
-
-void png_handle_pHYs (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
-
-void png_handle_PLTE (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
-
-void png_handle_sBIT (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
-
-void png_handle_sRGB (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
-
-void png_handle_tEXt (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
-
-void png_handle_tIME (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
-
-void png_handle_tRNS (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
-
-void png_handle_unknown (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 length);
-
-void png_handle_zTXt (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
-
-void png_info_destroy (png_structp png_ptr, png_infop
-info_ptr);
-
-void png_init_read_transformations (png_structp png_ptr);
-
-void png_process_IDAT_data (png_structp png_ptr, png_bytep
-buffer, png_size_t buffer_length);
-
-void png_process_some_data (png_structp png_ptr, png_infop
-info_ptr);
-
-void png_push_check_crc (png_structp png_ptr);
-
-void png_push_crc_finish (png_structp png_ptr);
-
-void png_push_crc_skip (png_structp png_ptr, png_uint_32
-length);
-
-void png_push_fill_buffer (png_structp png_ptr, png_bytep
-buffer, png_size_t length);
-
-void png_push_handle_tEXt (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 length);
-
-void png_push_handle_unknown (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 length);
-
-void png_push_handle_zTXt (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 length);
-
-void png_push_have_end (png_structp png_ptr, png_infop
-info_ptr);
-
-void png_push_have_info (png_structp png_ptr, png_infop
-info_ptr);
-
-void png_push_have_row (png_structp png_ptr, png_bytep row);
-
-void png_push_process_row (png_structp png_ptr);
-
-void png_push_read_chunk (png_structp png_ptr, png_infop
-info_ptr);
-
-void png_push_read_end (png_structp png_ptr, png_infop
-info_ptr);
-
-void png_push_read_IDAT (png_structp png_ptr);
-
-void png_push_read_sig (png_structp png_ptr, png_infop
-info_ptr);
-
-void png_push_read_tEXt (png_structp png_ptr, png_infop
-info_ptr);
-
-void png_push_read_zTXt (png_structp png_ptr, png_infop
-info_ptr);
-
-void png_push_restore_buffer (png_structp png_ptr, png_bytep
-buffer, png_size_t buffer_length);
-
-void png_push_save_buffer (png_structp png_ptr);
-
-void png_read_data (png_structp png_ptr, png_bytep data,
-png_size_t length);
-
-void png_read_filter_row (png_structp png_ptr, png_row_infop
-row_info, png_bytep row, png_bytep prev_row, int filter);
-
-void png_read_finish_row (png_structp png_ptr);
-
-void png_read_init (png_structp png_ptr);
-
-void png_read_push_finish_row (png_structp png_ptr);
-
-void png_read_start_row (png_structp png_ptr);
-
-void png_read_transform_info (png_structp png_ptr, png_infop
-info_ptr);
-
-void png_reset_crc (png_structp png_ptr);
-
-void png_save_int_32 (png_bytep buf, png_int_32 i);
-
-void png_save_uint_16 (png_bytep buf, unsigned int i);
-
-void png_save_uint_32 (png_bytep buf, png_uint_32 i);
-
-void png_write_bKGD (png_structp png_ptr, png_color_16p values,
-int color_type);
-
-void png_write_cHRM (png_structp png_ptr, double white_x,
-double white_y, double red_x, double red_y, double green_x,
-double green_y, double blue_x, double blue_y);
-
-void png_write_data (png_structp png_ptr, png_bytep data,
-png_size_t length);
-void png_write_filtered_row (png_structp png_ptr, png_bytep
-filtered_row);
-
-void png_write_find_filter (png_structp png_ptr, png_row_infop
-row_info);
-
-void png_write_finish_row (png_structp png_ptr);
-
-void png_write_gAMA (png_structp png_ptr, double file_gamma);
-
-void png_write_hIST (png_structp png_ptr, png_uint_16p hist,
-int num_hist);
-
-void png_write_init (png_structp png_ptr);
-
-void png_write_IDAT (png_structp png_ptr, png_bytep data,
-png_size_t length);
-
-void png_write_IEND (png_structp png_ptr);
-
-void png_write_IHDR (png_structp png_ptr, png_uint_32 width,
-png_uint_32 height, int bit_depth, int color_type, int
-compression_type, int filter_type, int interlace_type);
-
-void png_write_oFFs (png_structp png_ptr, png_uint_32 x_offset,
-png_uint_32 y_offset, int unit_type);
-
-void png_write_pCAL (png_structp png_ptr, png_charp purpose,
-png_int_32 X0, png_int_32 X1, int type, int nparams, png_charp
-units, png_charpp params);
-
-void png_write_pHYs (png_structp png_ptr, png_uint_32
-x_pixels_per_unit, png_uint_32 y_pixels_per_unit, int
-unit_type);
-
-void png_write_PLTE (png_structp png_ptr, png_colorp palette,
-png_uint_32 num_pal);
-
-void png_write_sBIT (png_structp png_ptr, png_color_8p sbit,
-int color_type);
-
-void png_write_sig (png_structp png_ptr);
-
-void png_write_sRGB (png_structp png_ptr, int intent);
-
-void png_write_start_row (png_structp png_ptr);
-
-void png_write_tEXt (png_structp png_ptr, png_charp key,
-png_charp text, png_size_t text_len);
-
-void png_write_tIME (png_structp png_ptr, png_timep mod_time);
-
-void png_write_tRNS (png_structp png_ptr, png_bytep trans,
-png_color_16p values, int number, int color_type);
-
-void png_write_zTXt (png_structp png_ptr, png_charp key,
-png_charp text, png_size_t text_len, int compression);
-
-voidpf png_zalloc (voidpf png_ptr, uInt items, uInt size);
-
-void png_zfree (voidpf png_ptr, voidpf ptr);
-
-.SH DESCRIPTION
-The functions listed above are used privately by libpng
-and are not recommended for use by applications. They
-are listed alphabetically here as an aid to libpng maintainers.
-See png.h for more information on these functions.
-
-.SH SEE ALSO
-libpng(3), png(5)
-.SH AUTHOR
-Glenn Randers-Pehrson
+++ /dev/null
-.TH PNG 5 "January 14, 1999"
-.SH NAME
-png \- Portable Network Graphics (PNG) format
-.SH DESCRIPTION
-PNG (Portable Network Graphics) is an extensible file format for the
-lossless, portable, well-compressed storage of raster images. PNG provides
-a patent-free replacement for GIF and can also replace many
-common uses of TIFF. Indexed-color, grayscale, and truecolor images are
-supported, plus an optional alpha channel. Sample depths range from
-1 to 16 bits.
-.br
-
-PNG is designed to work well in online viewing applications, such as the
-World Wide Web, so it is fully streamable with a progressive display
-option. PNG is robust, providing both full file integrity checking and
-fast, simple detection of common transmission errors. Also, PNG can store
-gamma and chromaticity data for improved color matching on heterogeneous
-platforms.
-
-.SH "SEE ALSO"
-.IR libpng(3), zlib(3), deflate(5), and zlib(5)
-.LP
-PNG specification:
-RFC 2083
-.IP
-.br
-ftp://ds.internic.net/rfc/rfc2083.txt
-.br
-or (as a W3C Recommendation) at
-.br
-http://www.w3.org/TR/REC-png.html
-.SH AUTHORS
-This man page: Glenn Randers-Pehrson
-.LP
-Portable Network Graphics (PNG) Specification Version 1.0 (October 1, 1996):
-Thomas Boutell and others (png-list@dworkin.wustl.edu).
-.LP
-
-.SH COPYRIGHT NOTICE
-The PNG specification is copyright (c) 1996 Massachussets Institute of
-Technology. See the specification for conditions of use and distribution.
-.LP
-.\" end of man page
-
+++ /dev/null
-
-/* png.c - location for general purpose libpng functions
- *
- * libpng version 1.0.3 - January 14, 1999
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
- *
- */
-
-#define PNG_INTERNAL
-#define PNG_NO_EXTERN
-#include "png.h"
-
-/* Version information for C files. This had better match the version
- * string defined in png.h.
- */
-
-char png_libpng_ver[12] = "1.0.3";
-
-/* Place to hold the signature string for a PNG file. */
-png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
-
-/* Constant strings for known chunk types. If you need to add a chunk,
- * add a string holding the name here. If you want to make the code
- * portable to EBCDIC machines, use ASCII numbers, not characters.
- */
-png_byte FARDATA png_IHDR[5] = { 73, 72, 68, 82, '\0'};
-png_byte FARDATA png_IDAT[5] = { 73, 68, 65, 84, '\0'};
-png_byte FARDATA png_IEND[5] = { 73, 69, 78, 68, '\0'};
-png_byte FARDATA png_PLTE[5] = { 80, 76, 84, 69, '\0'};
-png_byte FARDATA png_bKGD[5] = { 98, 75, 71, 68, '\0'};
-png_byte FARDATA png_cHRM[5] = { 99, 72, 82, 77, '\0'};
-png_byte FARDATA png_gAMA[5] = {103, 65, 77, 65, '\0'};
-png_byte FARDATA png_hIST[5] = {104, 73, 83, 84, '\0'};
-png_byte FARDATA png_oFFs[5] = {111, 70, 70, 115, '\0'};
-png_byte FARDATA png_pCAL[5] = {112, 67, 65, 76, '\0'};
-png_byte FARDATA png_pHYs[5] = {112, 72, 89, 115, '\0'};
-png_byte FARDATA png_sBIT[5] = {115, 66, 73, 84, '\0'};
-png_byte FARDATA png_sRGB[5] = {115, 82, 71, 66, '\0'};
-png_byte FARDATA png_tEXt[5] = {116, 69, 88, 116, '\0'};
-png_byte FARDATA png_tIME[5] = {116, 73, 77, 69, '\0'};
-png_byte FARDATA png_tRNS[5] = {116, 82, 78, 83, '\0'};
-png_byte FARDATA png_zTXt[5] = {122, 84, 88, 116, '\0'};
-
-/* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
-/* start of interlace block */
-int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
-
-/* offset to next interlace block */
-int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
-
-/* start of interlace block in the y direction */
-int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
-
-/* offset to next interlace block in the y direction */
-int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
-
-/* Width of interlace block. This is not currently used - if you need
- * it, uncomment it here and in png.h
-int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1};
-*/
-
-/* Height of interlace block. This is not currently used - if you need
- * it, uncomment it here and in png.h
-int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
-*/
-
-/* Mask to determine which pixels are valid in a pass */
-int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
-
-/* Mask to determine which pixels to overwrite while displaying */
-int FARDATA png_pass_dsp_mask[] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
-
-
-/* Tells libpng that we have already handled the first "num_bytes" bytes
- * of the PNG file signature. If the PNG data is embedded into another
- * stream we can set num_bytes = 8 so that libpng will not attempt to read
- * or write any of the magic bytes before it starts on the IHDR.
- */
-void
-png_set_sig_bytes(png_structp png_ptr, int num_bytes)
-{
- png_debug(1, "in png_set_sig_bytes\n");
- if (num_bytes > 8)
- png_error(png_ptr, "Too many bytes for PNG signature.");
-
- png_ptr->sig_bytes = num_bytes < 0 ? 0 : num_bytes;
-}
-
-/* Checks whether the supplied bytes match the PNG signature. We allow
- * checking less than the full 8-byte signature so that those apps that
- * already read the first few bytes of a file to determine the file type
- * can simply check the remaining bytes for extra assurance. Returns
- * an integer less than, equal to, or greater than zero if sig is found,
- * respectively, to be less than, to match, or be greater than the correct
- * PNG signature (this is the same behaviour as strcmp, memcmp, etc).
- */
-int
-png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check)
-{
- if (num_to_check > 8)
- num_to_check = 8;
- else if (num_to_check < 1)
- return (0);
-
- if (start > 7)
- return (0);
-
- if (start + num_to_check > 8)
- num_to_check = 8 - start;
-
- return ((int)(png_memcmp(&sig[start], &png_sig[start], num_to_check)));
-}
-
-/* (Obsolete) function to check signature bytes. It does not allow one
- * to check a partial signature. This function might be removed in the
- * future - use png_sig_cmp(). Returns true (nonzero) if the file is a PNG.
- */
-int
-png_check_sig(png_bytep sig, int num)
-{
- return ((int)!png_sig_cmp(sig, (png_size_t)0, (png_size_t)num));
-}
-
-/* Function to allocate memory for zlib. */
-voidpf
-png_zalloc(voidpf png_ptr, uInt items, uInt size)
-{
- png_uint_32 num_bytes = (png_uint_32)items * size;
- png_voidp ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes);
-
- if (num_bytes > (png_uint_32)0x8000L)
- {
- png_memset(ptr, 0, (png_size_t)0x8000L);
- png_memset((png_bytep)ptr + (png_size_t)0x8000L, 0,
- (png_size_t)(num_bytes - (png_uint_32)0x8000L));
- }
- else
- {
- png_memset(ptr, 0, (png_size_t)num_bytes);
- }
- return ((voidpf)ptr);
-}
-
-/* function to free memory for zlib */
-void
-png_zfree(voidpf png_ptr, voidpf ptr)
-{
- png_free((png_structp)png_ptr, (png_voidp)ptr);
-}
-
-/* Reset the CRC variable to 32 bits of 1's. Care must be taken
- * in case CRC is > 32 bits to leave the top bits 0.
- */
-void
-png_reset_crc(png_structp png_ptr)
-{
- png_ptr->crc = crc32(0, Z_NULL, 0);
-}
-
-/* Calculate the CRC over a section of data. We can only pass as
- * much data to this routine as the largest single buffer size. We
- * also check that this data will actually be used before going to the
- * trouble of calculating it.
- */
-void
-png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)
-{
- int need_crc = 1;
-
- if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
- {
- if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
- (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
- need_crc = 0;
- }
- else /* critical */
- {
- if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
- need_crc = 0;
- }
-
- if (need_crc)
- png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length);
-}
-
-/* Allocate the memory for an info_struct for the application. We don't
- * really need the png_ptr, but it could potentially be useful in the
- * future. This should be used in favour of malloc(sizeof(png_info))
- * and png_info_init() so that applications that want to use a shared
- * libpng don't have to be recompiled if png_info changes size.
- */
-png_infop
-png_create_info_struct(png_structp png_ptr)
-{
- png_infop info_ptr;
-
- png_debug(1, "in png_create_info_struct\n");
- if(png_ptr == NULL) return (NULL);
-#ifdef PNG_USER_MEM_SUPPORTED
- if ((info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO,
- png_ptr->malloc_fn)) != NULL)
-#else
- if ((info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO)) != NULL)
-#endif
- {
- png_info_init(info_ptr);
- }
-
- return (info_ptr);
-}
-
-/* This function frees the memory associated with a single info struct.
- * Normally, one would use either png_destroy_read_struct() or
- * png_destroy_write_struct() to free an info struct, but this may be
- * useful for some applications.
- */
-void
-png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
-{
- png_infop info_ptr = NULL;
-
- png_debug(1, "in png_destroy_info_struct\n");
- if (info_ptr_ptr != NULL)
- info_ptr = *info_ptr_ptr;
-
- if (info_ptr != NULL)
- {
- png_info_destroy(png_ptr, info_ptr);
-
-#ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn);
-#else
- png_destroy_struct((png_voidp)info_ptr);
-#endif
- *info_ptr_ptr = (png_infop)NULL;
- }
-}
-
-/* Initialize the info structure. This is now an internal function (0.89)
- * and applications using it are urged to use png_create_info_struct()
- * instead.
- */
-void
-png_info_init(png_infop info_ptr)
-{
- png_debug(1, "in png_info_init\n");
- /* set everything to 0 */
- png_memset(info_ptr, 0, sizeof (png_info));
-}
-
-/* This is an internal routine to free any memory that the info struct is
- * pointing to before re-using it or freeing the struct itself. Recall
- * that png_free() checks for NULL pointers for us.
- */
-void
-png_info_destroy(png_structp png_ptr, png_infop info_ptr)
-{
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
- png_debug(1, "in png_info_destroy\n");
- if (info_ptr->text != NULL)
- {
- int i;
- for (i = 0; i < info_ptr->num_text; i++)
- {
- png_free(png_ptr, info_ptr->text[i].key);
- }
- png_free(png_ptr, info_ptr->text);
- }
-#endif
-#if defined(PNG_READ_pCAL_SUPPORTED)
- png_free(png_ptr, info_ptr->pcal_purpose);
- png_free(png_ptr, info_ptr->pcal_units);
- if (info_ptr->pcal_params != NULL)
- {
- int i;
- for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
- {
- png_free(png_ptr, info_ptr->pcal_params[i]);
- }
- png_free(png_ptr, info_ptr->pcal_params);
- }
-#endif
-
- png_info_init(info_ptr);
-}
-
-/* This function returns a pointer to the io_ptr associated with the user
- * functions. The application should free any memory associated with this
- * pointer before png_write_destroy() or png_read_destroy() are called.
- */
-png_voidp
-png_get_io_ptr(png_structp png_ptr)
-{
- return (png_ptr->io_ptr);
-}
-
-#if !defined(PNG_NO_STDIO)
-/* Initialize the default input/output functions for the PNG file. If you
- * use your own read or write routines, you can call either png_set_read_fn()
- * or png_set_write_fn() instead of png_init_io().
- */
-void
-png_init_io(png_structp png_ptr, FILE *fp)
-{
- png_debug(1, "in png_init_io\n");
- png_ptr->io_ptr = (png_voidp)fp;
-}
-#endif
-
-#if defined(PNG_TIME_RFC1123_SUPPORTED)
-/* Convert the supplied time into an RFC 1123 string suitable for use in
- * a "Creation Time" or other text-based time string.
- */
-png_charp
-png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
-{
- static PNG_CONST char short_months[12][4] =
- {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
-
- if (png_ptr->time_buffer == NULL)
- {
- png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29*
- sizeof(char)));
- }
-
-#ifdef USE_FAR_KEYWORD
- {
- char near_time_buf[29];
- sprintf(near_time_buf, "%d %s %d %02d:%02d:%02d +0000",
- ptime->day % 32, short_months[(ptime->month - 1) % 12],
- ptime->year, ptime->hour % 24, ptime->minute % 60,
- ptime->second % 61);
- png_memcpy(png_ptr->time_buffer, near_time_buf,
- 29*sizeof(char));
- }
-#else
- sprintf(png_ptr->time_buffer, "%d %s %d %02d:%02d:%02d +0000",
- ptime->day % 32, short_months[(ptime->month - 1) % 12],
- ptime->year, ptime->hour % 24, ptime->minute % 60,
- ptime->second % 61);
-#endif
- return ((png_charp)png_ptr->time_buffer);
-}
-#endif /* PNG_TIME_RFC1123_SUPPORTED */
-
-png_charp
-png_get_copyright(png_structp png_ptr)
-{
- if(png_ptr == NULL)
- /* silence compiler warning about unused png_ptr */ ;
- return("\n libpng version 1.0.3 - January 14, 1999\n\
- Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.\n\
- Copyright (c) 1996, 1997 Andreas Dilger\n\
- Copyright (c) 1998, 1999, Glenn Randers-Pehrson\n");
-}
+++ /dev/null
-
-/* png.h - header file for PNG reference library
- *
- * libpng version 1.0.3 - January 14, 1999
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
- *
- * Y2K compliance in libpng:
- * =========================
- *
- * January 13, 1999
- *
- * Since the PNG Development group is an ad-hoc body, we can't make
- * an official declaration.
- *
- * This is your unofficial assurance that libpng from version 0.81 and
- * upward are Y2K compliant. It is my belief that earlier versions were
- * also Y2K compliant.
- *
- * Libpng only has three year fields. One is a 2-byte unsigned integer
- * that will hold years up to 65535. The other two hold the date in text
- * format, and will hold years up to 9999.
- *
- * The integer is
- * "png_uint_16 year" in png_time_struct.
- *
- * The strings are
- * "png_charp time_buffer" in png_struct and
- * "near_time_buffer", which is a local character string in png.c.
- *
- * There are seven time-related functions:
- * png.c: png_convert_to_rfc_1123() in png.c
- * (formerly png_convert_to_rfc_1152() in error)
- * png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
- * png_convert_from_time_t() in pngwrite.c
- * png_get_tIME() in pngget.c
- * png_handle_tIME() in pngrutil.c, called in pngread.c
- * png_set_tIME() in pngset.c
- * png_write_tIME() in pngwutil.c, called in pngwrite.c
- *
- * All handle dates properly in a Y2K environment. The
- * png_convert_from_time_t() function calls gmtime() to convert from system
- * clock time, which returns (year - 1900), which we properly convert to
- * the full 4-digit year. There is a possibility that applications using
- * libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
- * function, or incorrectly passing only a 2-digit year instead of
- * "year - 1900" into the png_convert_from_struct_tm() function, but this
- * is not under our control. The libpng documentation has always stated
- * that it works with 4-digit years, and the APIs have been documented as
- * such.
- *
- * The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned
- * integer to hold the year, and can hold years as large as 65535.
- *
- *
- * Glenn Randers-Pehrson
- * libpng maintainer
- * PNG Development Group
- *
- * Note about libpng version numbers:
- *
- * Due to various miscommunications, unforeseen code incompatibilities
- * and occasional factors outside the authors' control, version numbering
- * on the library has not always been consistent and straightforward.
- * The following table summarizes matters since version 0.89c, which was
- * the first widely used release:
- *
- * source png.h png.h shared-lib
- * version string int version
- * ------- ------ ----- ----------
- * 0.89c ("1.0 beta 3") 0.89 89 1.0.89
- * 0.90 ("1.0 beta 4") 0.90 90 0.90 [should have been 2.0.90]
- * 0.95 ("1.0 beta 5") 0.95 95 0.95 [should have been 2.0.95]
- * 0.96 ("1.0 beta 6") 0.96 96 0.96 [should have been 2.0.96]
- * 0.97b ("1.00.97 beta 7") 1.00.97 97 1.0.1 [should have been 2.0.97]
- * 0.97c 0.97 97 2.0.97
- * 0.98 0.98 98 2.0.98
- * 0.99 0.99 98 2.0.99
- * 0.99a-m 0.99 99 2.0.99
- * 1.00 1.00 100 2.1.0 [int should be 10000]
- * 1.0.0 1.0.0 100 2.1.0 [int should be 10000]
- * 1.0.1 1.0.1 10001 2.1.0
- * 1.0.1a-e 1.0.1a-e 10002 2.1.0.1a-e
- * 1.0.2 1.0.2 10002 2.1.0.2
- * 1.0.2a-c 1.0.2a 10003 2.1.0.2a-c
- * 1.0.3 1.0.3 10003 2.1.0.3
- *
- * Henceforth the source version will match the shared-library minor
- * and patch numbers; the shared-library major version number will be
- * used for changes in backward compatibility, as it is intended. The
- * PNG_PNGLIB_VER macro, which is not used within libpng but is available
- * for applications, is an unsigned integer of the form xyyzz corresponding
- * to the source version x.y.z (leading zeros in y and z).
- *
- * See libpng.txt or libpng.3 for more information. The PNG specification
- * is available as RFC 2083 <ftp://ftp.uu.net/graphics/png/documents/>
- * and as a W3C Recommendation <http://www.w3.org/TR/REC.png.html>
- *
- * Contributing Authors:
- * John Bowler
- * Kevin Bracey
- * Sam Bushell
- * Andreas Dilger
- * Magnus Holmgren
- * Tom Lane
- * Dave Martindale
- * Glenn Randers-Pehrson
- * Greg Roelofs
- * Guy Eric Schalnat
- * Paul Schmidt
- * Tom Tanner
- * Willem van Schaik
- * Tim Wegner
- *
- * The contributing authors would like to thank all those who helped
- * with testing, bug fixes, and patience. This wouldn't have been
- * possible without all of you.
- *
- * Thanks to Frank J. T. Wojcik for helping with the documentation.
- *
- * COPYRIGHT NOTICE:
- *
- * The PNG Reference Library is supplied "AS IS". The Contributing Authors
- * and Group 42, Inc. disclaim all warranties, expressed or implied,
- * including, without limitation, the warranties of merchantability and of
- * fitness for any purpose. The Contributing Authors and Group 42, Inc.
- * assume no liability for direct, indirect, incidental, special, exemplary,
- * or consequential damages, which may result from the use of the PNG
- * Reference Library, even if advised of the possibility of such damage.
- *
- * Permission is hereby granted to use, copy, modify, and distribute this
- * source code, or portions hereof, for any purpose, without fee, subject
- * to the following restrictions:
- * 1. The origin of this source code must not be misrepresented.
- * 2. Altered versions must be plainly marked as such and must not be
- * misrepresented as being the original source.
- * 3. This Copyright notice may not be removed or altered from any source or
- * altered source distribution.
- *
- * The Contributing Authors and Group 42, Inc. specifically permit, without
- * fee, and encourage the use of this source code as a component to
- * supporting the PNG file format in commercial products. If you use this
- * source code in a product, acknowledgment is not required but would be
- * appreciated.
- */
-
-
-#ifndef _PNG_H
-#define _PNG_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* This is not the place to learn how to use libpng. The file libpng.txt
- * describes how to use libpng, and the file example.c summarizes it
- * with some code on which to build. This file is useful for looking
- * at the actual function definitions and structure components.
- */
-
-/* include the compression library's header */
-#include "zlib.h"
-
-/* include all user configurable info */
-#include "pngconf.h"
-
-/* This file is arranged in several sections. The first section contains
- * structure and type definitions. The second section contains the external
- * library functions, while the third has the internal library functions,
- * which applications aren't expected to use directly.
- */
-
-/* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.0.3"
-
-/* Careful here. At one time, Guy wanted to use 082, but that would be octal.
- * We must not include leading zeros.
- * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only
- * version 1.0.0 was mis-numbered 100 instead of 10000). From
- * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=bugfix */
-#define PNG_LIBPNG_VER 10003 /* 1.0.3 */
-
-/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */
-#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
-/* Version information for C files, stored in png.c. This had better match
- * the version above.
- */
-extern char png_libpng_ver[12]; /* need room for 99.99.99aa */
-
-/* Structures to facilitate easy interlacing. See png.c for more details */
-extern int FARDATA png_pass_start[7];
-extern int FARDATA png_pass_inc[7];
-extern int FARDATA png_pass_ystart[7];
-extern int FARDATA png_pass_yinc[7];
-extern int FARDATA png_pass_mask[7];
-extern int FARDATA png_pass_dsp_mask[7];
-/* These aren't currently used. If you need them, see png.c for more details
-extern int FARDATA png_pass_width[7];
-extern int FARDATA png_pass_height[7];
-*/
-
-#endif /* PNG_NO_EXTERN */
-
-/* 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).
- */
-typedef struct png_color_struct
-{
- png_byte red;
- png_byte green;
- png_byte blue;
-} png_color;
-typedef png_color FAR * png_colorp;
-typedef png_color FAR * FAR * png_colorpp;
-
-typedef struct png_color_16_struct
-{
- png_byte index; /* used for palette files */
- png_uint_16 red; /* for use in red green blue files */
- png_uint_16 green;
- png_uint_16 blue;
- png_uint_16 gray; /* for use in grayscale files */
-} png_color_16;
-typedef png_color_16 FAR * png_color_16p;
-typedef png_color_16 FAR * FAR * png_color_16pp;
-
-typedef struct png_color_8_struct
-{
- png_byte red; /* for use in red green blue files */
- png_byte green;
- png_byte blue;
- png_byte gray; /* for use in grayscale files */
- png_byte alpha; /* for alpha channel files */
-} png_color_8;
-typedef png_color_8 FAR * png_color_8p;
-typedef png_color_8 FAR * FAR * png_color_8pp;
-
-/* png_text holds the text in a PNG file, and whether they are compressed
- in the PNG file or not. The "text" field points to a regular C string. */
-typedef struct png_text_struct
-{
- int compression; /* compression value, see PNG_TEXT_COMPRESSION_ */
- png_charp key; /* keyword, 1-79 character description of "text" */
- png_charp text; /* comment, may be an empty string (ie "") */
- png_size_t text_length; /* length of "text" field */
-} png_text;
-typedef png_text FAR * png_textp;
-typedef png_text FAR * FAR * png_textpp;
-
-/* Supported compression types for text in PNG files (tEXt, and zTXt).
- * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */
-#define PNG_TEXT_COMPRESSION_NONE_WR -3
-#define PNG_TEXT_COMPRESSION_zTXt_WR -2
-#define PNG_TEXT_COMPRESSION_NONE -1
-#define PNG_TEXT_COMPRESSION_zTXt 0
-#define PNG_TEXT_COMPRESSION_LAST 1 /* Not a valid value */
-
-/* png_time is a way to hold the time in an machine independent way.
- * Two conversions are provided, both from time_t and struct tm. There
- * is no portable way to convert to either of these structures, as far
- * as I know. If you know of a portable way, send it to me. As a side
- * note - PNG is Year 2000 compliant!
- */
-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 */
- png_byte second; /* second of minute, 0 - 60 (for leap seconds) */
-} png_time;
-typedef png_time FAR * png_timep;
-typedef png_time FAR * FAR * png_timepp;
-
-/* png_info is a structure that holds the information in a PNG file so
- * that the application can find out the characteristics of the image.
- * If you are reading the file, this structure will tell you what is
- * in the PNG file. If you are writing the file, fill in the information
- * you want to put into the PNG file, then call png_write_info().
- * The names chosen should be very close to the PNG specification, so
- * consult that document for information about the meaning of each field.
- *
- * With libpng < 0.95, it was only possible to directly set and read the
- * the values in the png_info_struct, which meant that the contents and
- * order of the values had to remain fixed. With libpng 0.95 and later,
- * however, there are now functions that abstract the contents of
- * png_info_struct from the application, so this makes it easier to use
- * libpng with dynamic libraries, and even makes it possible to use
- * libraries that don't have all of the libpng ancillary chunk-handing
- * functionality.
- *
- * In any case, the order of the parameters in png_info_struct should NOT
- * be changed for as long as possible to keep compatibility with applications
- * that use the old direct-access method with png_info_struct.
- */
-typedef struct png_info_struct
-{
- /* the following are necessary for every PNG file */
- png_uint_32 width; /* width of image in pixels (from IHDR) */
- png_uint_32 height; /* height of image in pixels (from IHDR) */
- png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */
- png_uint_32 rowbytes; /* bytes needed to hold an untransformed row */
- png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */
- png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */
- png_uint_16 num_trans; /* number of transparent palette color (tRNS) */
- png_byte bit_depth; /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */
- png_byte color_type; /* see PNG_COLOR_TYPE_ below (from IHDR) */
- png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */
- png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */
- png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
-
- /* The following is informational only on read, and not used on writes. */
- png_byte channels; /* number of data channels per pixel (1, 3, 4)*/
- png_byte pixel_depth; /* number of bits per pixel */
- png_byte spare_byte; /* to align the data, and for future use */
- png_byte signature[8]; /* magic bytes read by libpng from start of file */
-
- /* The rest of the data is 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) || \
- defined(PNG_READ_GAMMA_SUPPORTED)
- /* The gAMA chunk describes the gamma characteristics of the system
- * on which the image was created, normally in the range [1.0, 2.5].
- * Data is valid if (valid & PNG_INFO_gAMA) is non-zero.
- */
- float gamma; /* gamma value of image, if (valid & PNG_INFO_gAMA) */
-#endif /* PNG_READ_gAMA_SUPPORTED || PNG_WRITE_gAMA_SUPPORTED */
-
-#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
- /* GR-P, 0.96a */
- /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */
- png_byte srgb_intent; /* sRGB rendering intent [0, 1, 2, or 3] */
-#endif /* PNG_READ_sRGB_SUPPORTED || PNG_WRITE_sRGB_SUPPORTED */
-
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
- defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
- /* The tEXt and zTXt chunks contain human-readable textual data in
- * uncompressed and compressed forms, respectively. The data in "text"
- * is an array of pointers to uncompressed, null-terminated C strings.
- * Each chunk has a keyword that describes the textual data contained
- * in that chunk. Keywords are not required to be unique, and the text
- * string may be empty. Any number of text chunks may be in an image.
- */
- int num_text; /* number of comments read/to write */
- int max_text; /* current size of text array */
- png_textp text; /* array of comments read/to write */
-#endif /* PNG_READ_OR_WRITE_tEXt_OR_zTXt_SUPPORTED */
-#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED)
- /* The tIME chunk holds the last time the displayed image data was
- * modified. See the png_time struct for the contents of this struct.
- */
- png_time mod_time;
-#endif /* PNG_READ_tIME_SUPPORTED || PNG_WRITE_tIME_SUPPORTED */
-#if defined(PNG_READ_sBIT_SUPPORTED) || defined(PNG_WRITE_sBIT_SUPPORTED)
- /* The sBIT chunk specifies the number of significant high-order bits
- * in the pixel data. Values are in the range [1, bit_depth], and are
- * only specified for the channels in the pixel data. The contents of
- * the low-order bits is not specified. Data is valid if
- * (valid & PNG_INFO_sBIT) is non-zero.
- */
- png_color_8 sig_bit; /* significant bits in color channels */
-#endif /* PNG_READ_sBIT_SUPPORTED || PNG_WRITE_sBIT_SUPPORTED */
-#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED) || \
- defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- /* The tRNS chunk supplies transparency data for paletted images and
- * other image types that don't need a full alpha channel. There are
- * "num_trans" transparency values for a paletted image, stored in the
- * same order as the palette colors, starting from index 0. Values
- * for the data are in the range [0, 255], ranging from fully transparent
- * to fully opaque, respectively. For non-paletted images, there is a
- * single color specified that should be treated as fully transparent.
- * Data is valid if (valid & PNG_INFO_tRNS) is non-zero.
- */
- png_bytep trans; /* transparent values for paletted image */
- png_color_16 trans_values; /* transparent color for non-palette image */
-#endif /* PNG_READ_tRNS_SUPPORTED || PNG_WRITE_tRNS_SUPPORTED */
-#if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED) || \
- defined(PNG_READ_BACKGROUND_SUPPORTED)
- /* The bKGD chunk gives the suggested image background color if the
- * display program does not have its own background color and the image
- * is needs to composited onto a background before display. The colors
- * in "background" are normally in the same color space/depth as the
- * pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero.
- */
- png_color_16 background;
-#endif /* PNG_READ_bKGD_SUPPORTED || PNG_WRITE_bKGD_SUPPORTED */
-#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
- /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards
- * and downwards from the top-left corner of the display, page, or other
- * application-specific co-ordinate space. See the PNG_OFFSET_ defines
- * below for the unit types. Valid if (valid & PNG_INFO_oFFs) non-zero.
- */
- 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 /* PNG_READ_oFFs_SUPPORTED || PNG_WRITE_oFFs_SUPPORTED */
-#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
- /* The pHYs chunk gives the physical pixel density of the image for
- * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_
- * defines below). Data is valid if (valid & PNG_INFO_pHYs) is non-zero.
- */
- png_uint_32 x_pixels_per_unit; /* horizontal pixel density */
- png_uint_32 y_pixels_per_unit; /* vertical pixel density */
- png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
-#endif /* PNG_READ_pHYs_SUPPORTED || PNG_WRITE_pHYs_SUPPORTED */
-#if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED)
- /* The hIST chunk contains the relative frequency or importance of the
- * various palette entries, so that a viewer can intelligently select a
- * reduced-color palette, if required. Data is an array of "num_palette"
- * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST)
- * is non-zero.
- */
- png_uint_16p hist;
-#endif /* PNG_READ_hIST_SUPPORTED || PNG_WRITE_hIST_SUPPORTED */
-#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
- /* The cHRM chunk describes the CIE color characteristics of the monitor
- * on which the PNG was created. This data allows the viewer to do gamut
- * mapping of the input image to ensure that the viewer sees the same
- * colors in the image as the creator. Values are in the range
- * [0.0, 0.8]. Data valid if (valid & PNG_INFO_cHRM) non-zero.
- */
- float x_white;
- float y_white;
- float x_red;
- float y_red;
- float x_green;
- float y_green;
- float x_blue;
- float y_blue;
-#endif /* PNG_READ_cHRM_SUPPORTED || PNG_WRITE_cHRM_SUPPORTED */
-#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED)
- /* The pCAL chunk describes a transformation between the stored pixel
- * values and original physcical data values used to create the image.
- * The integer range [0, 2^bit_depth - 1] maps to the floating-point
- * range given by [pcal_X0, pcal_X1], and are further transformed by a
- * (possibly non-linear) transformation function given by "pcal_type"
- * and "pcal_params" into "pcal_units". Please see the PNG_EQUATION_
- * defines below, and the PNG-Group's Scientific Visualization extension
- * chunks document png-scivis-19970203 for a complete description of the
- * transformations and how they should be implemented, as well as the
- * png-extensions document for a description of the ASCII parameter
- * strings. Data values are valid if (valid & PNG_INFO_pCAL) non-zero.
- */
- png_charp pcal_purpose; /* pCAL chunk description string */
- png_int_32 pcal_X0; /* minimum value */
- png_int_32 pcal_X1; /* maximum value */
- png_charp pcal_units; /* Latin-1 string giving physical units */
- png_charpp pcal_params; /* ASCII strings containing parameter values */
- png_byte pcal_type; /* equation type (see PNG_EQUATION_ below) */
- png_byte pcal_nparams; /* number of parameters given in pcal_params */
-#endif /* PNG_READ_pCAL_SUPPORTED || PNG_WRITE_pCAL_SUPPORTED */
-} png_info;
-typedef png_info FAR * png_infop;
-typedef png_info FAR * FAR * png_infopp;
-
-/* These describe the color_type field in png_info. */
-/* color type masks */
-#define PNG_COLOR_MASK_PALETTE 1
-#define PNG_COLOR_MASK_COLOR 2
-#define PNG_COLOR_MASK_ALPHA 4
-
-/* color types. Note that not all combinations are legal */
-#define PNG_COLOR_TYPE_GRAY 0
-#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
-#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR)
-#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
-#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
-
-/* This is for compression type. PNG 1.0 only defines the single type. */
-#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */
-#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE
-
-/* This is for filter type. PNG 1.0 only defines the single type. */
-#define PNG_FILTER_TYPE_BASE 0 /* Single row per-byte filtering */
-#define PNG_FILTER_TYPE_DEFAULT PNG_FILTER_TYPE_BASE
-
-/* These are for the interlacing type. These values should NOT be changed. */
-#define PNG_INTERLACE_NONE 0 /* Non-interlaced image */
-#define PNG_INTERLACE_ADAM7 1 /* Adam7 interlacing */
-#define PNG_INTERLACE_LAST 2 /* Not a valid value */
-
-/* These are for the oFFs chunk. These values should NOT be changed. */
-#define PNG_OFFSET_PIXEL 0 /* Offset in pixels */
-#define PNG_OFFSET_MICROMETER 1 /* Offset in micrometers (1/10^6 meter) */
-#define PNG_OFFSET_LAST 2 /* Not a valid value */
-
-/* These are for the pCAL chunk. These values should NOT be changed. */
-#define PNG_EQUATION_LINEAR 0 /* Linear transformation */
-#define PNG_EQUATION_BASE_E 1 /* Exponential base e transform */
-#define PNG_EQUATION_ARBITRARY 2 /* Arbitrary base exponential transform */
-#define PNG_EQUATION_HYPERBOLIC 3 /* Hyperbolic sine transformation */
-#define PNG_EQUATION_LAST 4 /* Not a valid value */
-
-/* These are for the pHYs chunk. These values should NOT be changed. */
-#define PNG_RESOLUTION_UNKNOWN 0 /* pixels/unknown unit (aspect ratio) */
-#define PNG_RESOLUTION_METER 1 /* pixels/meter */
-#define PNG_RESOLUTION_LAST 2 /* Not a valid value */
-
-/* These are for the sRGB chunk. These values should NOT be changed. */
-#define PNG_sRGB_INTENT_SATURATION 0
-#define PNG_sRGB_INTENT_PERCEPTUAL 1
-#define PNG_sRGB_INTENT_ABSOLUTE 2
-#define PNG_sRGB_INTENT_RELATIVE 3
-#define PNG_sRGB_INTENT_LAST 4 /* Not a valid value */
-
-
-
-/* These determine if an ancillary chunk's data has been successfully read
- * from the PNG header, or if the application has filled in the corresponding
- * data in the info_struct to be written into the output file. The values
- * of the PNG_INFO_<chunk> defines should NOT be changed.
- */
-#define PNG_INFO_gAMA 0x0001
-#define PNG_INFO_sBIT 0x0002
-#define PNG_INFO_cHRM 0x0004
-#define PNG_INFO_PLTE 0x0008
-#define PNG_INFO_tRNS 0x0010
-#define PNG_INFO_bKGD 0x0020
-#define PNG_INFO_hIST 0x0040
-#define PNG_INFO_pHYs 0x0080
-#define PNG_INFO_oFFs 0x0100
-#define PNG_INFO_tIME 0x0200
-#define PNG_INFO_pCAL 0x0400
-#define PNG_INFO_sRGB 0x0800 /* GR-P, 0.96a */
-
-/* This is used for the transformation routines, as some of them
- * change these values for the row. It also should enable using
- * the routines for other purposes.
- */
-typedef struct png_row_info_struct
-{
- png_uint_32 width; /* width of row */
- png_uint_32 rowbytes; /* number of bytes in row */
- png_byte color_type; /* color type of row */
- png_byte bit_depth; /* bit depth of row */
- png_byte channels; /* number of channels (1, 2, 3, or 4) */
- png_byte pixel_depth; /* bits per pixel (depth * channels) */
-} png_row_info;
-
-typedef png_row_info FAR * png_row_infop;
-typedef png_row_info FAR * FAR * png_row_infopp;
-
-/* These are the function types for the I/O functions and for the functions
- * that allow the user to override the default I/O functions with his or her
- * own. The png_error_ptr type should match that of user-supplied warning
- * and error functions, while the png_rw_ptr type should match that of the
- * user read/write data functions.
- */
-typedef struct png_struct_def png_struct;
-typedef png_struct FAR * png_structp;
-
-typedef void (*png_error_ptr) PNGARG((png_structp, png_const_charp));
-typedef void (*png_rw_ptr) PNGARG((png_structp, png_bytep, png_size_t));
-typedef void (*png_flush_ptr) PNGARG((png_structp));
-typedef void (*png_read_status_ptr) PNGARG((png_structp, png_uint_32, int));
-typedef void (*png_write_status_ptr) PNGARG((png_structp, png_uint_32, int));
-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-typedef void (*png_progressive_info_ptr) PNGARG((png_structp, png_infop));
-typedef void (*png_progressive_end_ptr) PNGARG((png_structp, png_infop));
-typedef void (*png_progressive_row_ptr) PNGARG((png_structp, png_bytep,
- png_uint_32, int));
-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
-
-#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
-typedef void (*png_user_transform_ptr) PNGARG((png_structp,
- png_row_infop, png_bytep));
-#endif /* PNG_READ|WRITE_USER_TRANSFORM_SUPPORTED */
-
-typedef png_voidp (*png_malloc_ptr) PNGARG((png_structp, png_size_t));
-typedef void (*png_free_ptr) PNGARG((png_structp, png_structp));
-
-/* The structure that holds the information to read and write PNG files.
- * The only people who need to care about what is inside of this are the
- * people who will be modifying the library for their own special needs.
- * It should NOT be accessed directly by an application, except to store
- * the jmp_buf.
- */
-
-struct png_struct_def
-{
- jmp_buf jmpbuf; /* used in png_error */
-
- png_error_ptr error_fn; /* function for printing errors and aborting */
- png_error_ptr warning_fn; /* function for printing warnings */
- png_voidp error_ptr; /* user supplied struct for error functions */
- png_rw_ptr write_data_fn; /* function for writing output data */
- png_rw_ptr read_data_fn; /* function for reading input data */
-#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
- png_user_transform_ptr read_user_transform_fn; /* user read transform */
- png_user_transform_ptr write_user_transform_fn; /* user write transform */
-#endif
- png_voidp io_ptr; /* ptr to application struct for I/O functions*/
-
- png_uint_32 mode; /* tells us where we are in the PNG file */
- png_uint_32 flags; /* flags indicating various things to libpng */
- png_uint_32 transformations; /* which transformations to perform */
-
- z_stream zstream; /* pointer to decompression structure (below) */
- png_bytep zbuf; /* buffer for zlib */
- png_size_t zbuf_size; /* size of zbuf */
- 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 width; /* width of image in pixels */
- png_uint_32 height; /* height of image in pixels */
- png_uint_32 num_rows; /* number of rows in current pass */
- png_uint_32 usr_width; /* width of row at start of write */
- png_uint_32 rowbytes; /* size of row in bytes */
- png_uint_32 irowbytes; /* size of current interlaced row in bytes */
- png_uint_32 iwidth; /* width of current interlaced row in pixels */
- png_uint_32 row_number; /* current row in interlace pass */
- png_bytep prev_row; /* buffer to save previous (unfiltered) row */
- png_bytep row_buf; /* buffer to save current (unfiltered) row */
- png_bytep sub_row; /* buffer to save "sub" row when filtering */
- png_bytep up_row; /* buffer to save "up" row when filtering */
- png_bytep avg_row; /* buffer to save "avg" row when filtering */
- png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */
- png_row_info row_info; /* used for transformation routines */
-
- png_uint_32 idat_size; /* current IDAT size for read */
- png_uint_32 crc; /* current chunk CRC value */
- png_colorp palette; /* palette from the input file */
- png_uint_16 num_palette; /* number of color entries in palette */
- png_uint_16 num_trans; /* number of transparency values */
- png_byte chunk_name[5]; /* null-terminated name of current chunk */
- png_byte compression; /* file compression type (always 0) */
- png_byte filter; /* file filter type (always 0) */
- png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
- png_byte pass; /* current interlace pass (0 - 6) */
- png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */
- png_byte color_type; /* color type of file */
- png_byte bit_depth; /* bit depth of file */
- png_byte usr_bit_depth; /* bit depth of users row */
- png_byte pixel_depth; /* number of bits per pixel */
- png_byte channels; /* number of channels in file */
- png_byte usr_channels; /* channels at start of write */
- png_byte sig_bytes; /* magic bytes read/written from start of file */
-
-#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
- png_uint_16 filler; /* filler bytes for pixel expansion */
-#endif /* PNG_READ_FILLER_SUPPORTED */
-#if defined(PNG_READ_bKGD_SUPPORTED)
- png_byte background_gamma_type;
- float background_gamma;
- png_color_16 background; /* background color in screen gamma space */
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- png_color_16 background_1; /* background normalized to gamma 1.0 */
-#endif /* PNG_READ_GAMMA && PNG_READ_bKGD_SUPPORTED */
-#endif /* PNG_READ_bKGD_SUPPORTED */
-#if defined(PNG_WRITE_FLUSH_SUPPORTED)
- png_flush_ptr output_flush_fn;/* Function for flushing output */
- png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */
- png_uint_32 flush_rows; /* number of rows written since last flush */
-#endif /* PNG_WRITE_FLUSH_SUPPORTED */
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- int gamma_shift; /* number of "insignificant" bits 16-bit gamma */
- float gamma; /* file gamma value */
- float screen_gamma; /* screen gamma value (display_gamma/viewing_gamma */
-#endif /* PNG_READ_GAMMA_SUPPORTED */
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- png_bytep gamma_table; /* gamma table for 8 bit depth files */
- png_bytep gamma_from_1; /* converts from 1.0 to screen */
- png_bytep gamma_to_1; /* converts from file to 1.0 */
- png_uint_16pp gamma_16_table; /* gamma table for 16 bit depth files */
- png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */
- png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */
-#endif /* PNG_READ_GAMMA_SUPPORTED || PNG_WRITE_GAMMA_SUPPORTED */
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined (PNG_READ_sBIT_SUPPORTED)
- png_color_8 sig_bit; /* significant bits in each available channel */
-#endif /* PNG_READ_GAMMA_SUPPORTED || PNG_READ_sBIT_SUPPORTED */
-#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
- png_color_8 shift; /* shift for significant bit tranformation */
-#endif /* PNG_READ_SHIFT_SUPPORTED || PNG_WRITE_SHIFT_SUPPORTED */
-#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
- || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- png_bytep trans; /* transparency values for paletted files */
- png_color_16 trans_values; /* transparency values for non-paletted files */
-#endif /* PNG_READ|WRITE_tRNS_SUPPORTED||PNG_READ_EXPAND|BACKGROUND_SUPPORTED */
- png_read_status_ptr read_row_fn; /* called after each row is decoded */
- png_write_status_ptr write_row_fn; /* called after each row is encoded */
-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
- png_progressive_info_ptr info_fn; /* called after header data fully read */
- png_progressive_row_ptr row_fn; /* called after each prog. row is decoded */
- png_progressive_end_ptr end_fn; /* called after image is complete */
- png_bytep save_buffer_ptr; /* current location in save_buffer */
- png_bytep save_buffer; /* buffer for previously read data */
- png_bytep current_buffer_ptr; /* current location in current_buffer */
- png_bytep current_buffer; /* buffer for recently used data */
- png_uint_32 push_length; /* size of current input chunk */
- png_uint_32 skip_length; /* bytes to skip in input data */
- png_size_t save_buffer_size; /* amount of data now in save_buffer */
- png_size_t save_buffer_max; /* total size of save_buffer */
- png_size_t buffer_size; /* total amount of available input data */
- png_size_t current_buffer_size; /* amount of data now in current_buffer */
- int process_mode; /* what push library is currently doing */
- int cur_palette; /* current push library palette index */
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
- png_size_t current_text_size; /* current size of text input data */
- png_size_t current_text_left; /* how much text left to read in input */
- png_charp current_text; /* current text chunk buffer */
- png_charp current_text_ptr; /* current location in current_text */
-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_READ_tEXt/zTXt_SUPPORTED */
-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
-#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
-/* for the Borland special 64K segment handler */
- png_bytepp offset_table_ptr;
- png_bytep offset_table;
- png_uint_16 offset_table_number;
- png_uint_16 offset_table_count;
- png_uint_16 offset_table_count_free;
-#endif /* __TURBOC__&&!_Windows&&!__FLAT__ */
-#if defined(PNG_READ_DITHER_SUPPORTED)
- png_bytep palette_lookup; /* lookup table for dithering */
- png_bytep dither_index; /* index translation for palette files */
-#endif /* PNG_READ_DITHER_SUPPORTED */
-#if defined(PNG_READ_DITHER_SUPPORTED) || defined(PNG_READ_hIST_SUPPORTED)
- png_uint_16p hist; /* histogram */
-#endif
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- png_byte heuristic_method; /* heuristic for row filter selection */
- png_byte num_prev_filters; /* number of weights for previous rows */
- png_bytep prev_filters; /* filter type(s) of previous row(s) */
- png_uint_16p filter_weights; /* weight(s) for previous line(s) */
- png_uint_16p inv_filter_weights; /* 1/weight(s) for previous line(s) */
- png_uint_16p filter_costs; /* relative filter calculation cost */
- png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */
-#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
-#if defined(PNG_TIME_RFC1123_SUPPORTED)
- png_charp time_buffer; /* String to hold RFC 1123 time text */
-#endif /* PNG_TIME_RFC1123_SUPPORTED */
-#ifdef PNG_USER_MEM_SUPPORTED
- png_voidp mem_ptr; /* user supplied struct for mem functions */
- png_malloc_ptr malloc_fn; /* function for allocating memory */
- png_free_ptr free_fn; /* function for freeing memory */
-#endif /* PNG_USER_MEM_SUPPORTED */
-#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
- png_byte rgb_to_gray_status;
- png_byte rgb_to_gray_red_coeff;
- png_byte rgb_to_gray_green_coeff;
- png_byte rgb_to_gray_blue_coeff;
-#endif
-};
-
-typedef png_struct FAR * FAR * png_structpp;
-
-/* Here are the function definitions most commonly used. This is not
- * the place to find out how to use libpng. See libpng.txt for the
- * full explanation, see example.c for the summary. This just provides
- * a simple one line of the use of each function.
- */
-
-/* Tell lib we have already handled the first <num_bytes> magic bytes.
- * Handling more than 8 bytes from the beginning of the file is an error.
- */
-extern PNG_EXPORT(void,png_set_sig_bytes) PNGARG((png_structp png_ptr,
- int num_bytes));
-
-/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a
- * PNG file. Returns zero if the supplied bytes match the 8-byte PNG
- * signature, and non-zero otherwise. Having num_to_check == 0 or
- * start > 7 will always fail (ie return non-zero).
- */
-extern PNG_EXPORT(int,png_sig_cmp) PNGARG((png_bytep sig, png_size_t start,
- png_size_t num_to_check));
-
-/* Simple signature checking function. This is the same as calling
- * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n).
- */
-extern PNG_EXPORT(int,png_check_sig) PNGARG((png_bytep sig, int num));
-
-/* Allocate and initialize png_ptr struct for reading, and any other memory. */
-extern PNG_EXPORT(png_structp,png_create_read_struct)
- PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn));
-
-/* Allocate and initialize png_ptr struct for writing, and any other memory */
-extern PNG_EXPORT(png_structp,png_create_write_struct)
- PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn));
-
-#ifdef PNG_USER_MEM_SUPPORTED
-extern PNG_EXPORT(png_structp,png_create_read_struct_2)
- PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
- png_malloc_ptr malloc_fn, png_free_ptr free_fn));
-extern PNG_EXPORT(png_structp,png_create_write_struct_2)
- PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
- png_malloc_ptr malloc_fn, png_free_ptr free_fn));
-#endif
-
-/* Write a PNG chunk - size, type, (optional) data, CRC. */
-extern PNG_EXPORT(void,png_write_chunk) PNGARG((png_structp png_ptr,
- png_bytep chunk_name, png_bytep data, png_size_t length));
-
-/* Write the start of a PNG chunk - length and chunk name. */
-extern PNG_EXPORT(void,png_write_chunk_start) PNGARG((png_structp png_ptr,
- png_bytep chunk_name, png_uint_32 length));
-
-/* Write the data of a PNG chunk started with png_write_chunk_start(). */
-extern PNG_EXPORT(void,png_write_chunk_data) PNGARG((png_structp png_ptr,
- png_bytep data, png_size_t length));
-
-/* Finish a chunk started with png_write_chunk_start() (includes CRC). */
-extern PNG_EXPORT(void,png_write_chunk_end) PNGARG((png_structp png_ptr));
-
-/* Allocate and initialize the info structure */
-extern PNG_EXPORT(png_infop,png_create_info_struct)
- PNGARG((png_structp png_ptr));
-
-/* Initialize the info structure (old interface - NOT DLL EXPORTED) */
-extern void png_info_init PNGARG((png_infop info_ptr));
-
-/* Writes all the PNG information before the image. */
-extern PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
-/* read the information before the actual image data. */
-extern PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
-#if defined(PNG_TIME_RFC1123_SUPPORTED)
-extern PNG_EXPORT(png_charp,png_convert_to_rfc1123)
- PNGARG((png_structp png_ptr, png_timep ptime));
-#endif /* PNG_TIME_RFC1123_SUPPORTED */
-
-#if defined(PNG_WRITE_tIME_SUPPORTED)
-/* convert from a struct tm to png_time */
-extern PNG_EXPORT(void,png_convert_from_struct_tm) PNGARG((png_timep ptime,
- struct tm FAR * ttime));
-
-/* convert from time_t to png_time. Uses gmtime() */
-extern PNG_EXPORT(void,png_convert_from_time_t) PNGARG((png_timep ptime,
- time_t ttime));
-#endif /* PNG_WRITE_tIME_SUPPORTED */
-
-#if defined(PNG_READ_EXPAND_SUPPORTED)
-/* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha if available. */
-extern PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_EXPAND_SUPPORTED */
-
-#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
-/* Use blue, green, red order for pixels. */
-extern PNG_EXPORT(void,png_set_bgr) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_BGR_SUPPORTED || PNG_WRITE_BGR_SUPPORTED */
-
-#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
-/* Expand the grayscale to 24 bit RGB if necessary. */
-extern PNG_EXPORT(void,png_set_gray_to_rgb) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED */
-
-#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-/* Reduce RGB to grayscale. */
-extern PNG_EXPORT(void,png_set_rgb_to_gray) PNGARG((png_structp png_ptr,
- int error_action, float red, float green ));
-extern PNG_EXPORT(png_byte,png_get_rgb_to_gray_status) PNGARG((png_structp
- png_ptr));
-#endif /* PNG_READ_RGB_TO_GRAY_SUPPORTED */
-
-extern PNG_EXPORT(void,png_build_grayscale_palette) PNGARG((int bit_depth,
- png_colorp palette));
-
-#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
-extern PNG_EXPORT(void,png_set_strip_alpha) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_STRIP_ALPHA_SUPPORTED */
-
-#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
- defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
-extern PNG_EXPORT(void,png_set_swap_alpha) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_SWAP_ALPHA_SUPPORTED || PNG_WRITE_SWAP_ALPHA_SUPPORTED */
-
-#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
- defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
-extern PNG_EXPORT(void,png_set_invert_alpha) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED || PNG_WRITE_INVERT_ALPHA_SUPPORTED */
-
-#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
-/* Add a filler byte to 24-bit RGB images. */
-extern PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr,
- png_uint_32 filler, int flags));
-
-/* The values of the PNG_FILLER_ defines should NOT be changed */
-#define PNG_FILLER_BEFORE 0
-#define PNG_FILLER_AFTER 1
-#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */
-
-#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
-/* Swap bytes in 16 bit depth files. */
-extern PNG_EXPORT(void,png_set_swap) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_SWAP_SUPPORTED || PNG_WRITE_SWAP_SUPPORTED */
-
-#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 PNG_EXPORT(void,png_set_packing) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_PACK_SUPPORTED || PNG_WRITE_PACK_SUPPORTED */
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
-/* Swap packing order of pixels in bytes. */
-extern PNG_EXPORT(void,png_set_packswap) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_PACKSWAP_SUPPORTED || PNG_WRITE_PACKSWAP_SUPPOR */
-
-#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
-/* Converts files to legal bit depths. */
-extern PNG_EXPORT(void,png_set_shift) PNGARG((png_structp png_ptr,
- png_color_8p true_bits));
-#endif /* PNG_READ_SHIFT_SUPPORTED || PNG_WRITE_SHIFT_SUPPORTED */
-
-#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
- defined(PNG_WRITE_INTERLACING_SUPPORTED)
-/* Have the code handle the interlacing. Returns the number of passes. */
-extern PNG_EXPORT(int,png_set_interlace_handling) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_INTERLACING_SUPPORTED || PNG_WRITE_INTERLACING_SUPPORTED */
-
-#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
-/* Invert monocrome files */
-extern PNG_EXPORT(void,png_set_invert_mono) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_INVERT_SUPPORTED || PNG_WRITE_INVERT_SUPPORTED */
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
-/* Handle alpha and tRNS by replacing with a background color. */
-extern PNG_EXPORT(void,png_set_background) PNGARG((png_structp png_ptr,
- png_color_16p background_color, int background_gamma_code,
- int need_expand, double background_gamma));
-#define PNG_BACKGROUND_GAMMA_UNKNOWN 0
-#define PNG_BACKGROUND_GAMMA_SCREEN 1
-#define PNG_BACKGROUND_GAMMA_FILE 2
-#define PNG_BACKGROUND_GAMMA_UNIQUE 3
-#endif /* PNG_READ_BACKGROUND_SUPPORTED */
-
-#if defined(PNG_READ_16_TO_8_SUPPORTED)
-/* strip the second byte of information from a 16 bit depth file. */
-extern PNG_EXPORT(void,png_set_strip_16) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_16_TO_8_SUPPORTED */
-
-#if defined(PNG_READ_DITHER_SUPPORTED)
-/* Turn on dithering, and reduce the palette to the number of colors available. */
-extern PNG_EXPORT(void,png_set_dither) PNGARG((png_structp png_ptr,
- png_colorp palette, int num_palette, int maximum_colors,
- png_uint_16p histogram, int full_dither));
-#endif /* PNG_READ_DITHER_SUPPORTED */
-
-#if defined(PNG_READ_GAMMA_SUPPORTED)
-/* Handle gamma correction. Screen_gamma=(display_gamma/viewing_gamma) */
-extern PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr,
- double screen_gamma, double default_file_gamma));
-#endif /* PNG_READ_GAMMA_SUPPORTED */
-
-#if defined(PNG_WRITE_FLUSH_SUPPORTED)
-/* Set how many lines between output flushes - 0 for no flushing */
-extern PNG_EXPORT(void,png_set_flush) PNGARG((png_structp png_ptr, int nrows));
-
-/* Flush the current PNG output buffer */
-extern PNG_EXPORT(void,png_write_flush) PNGARG((png_structp png_ptr));
-#endif /* PNG_WRITE_FLUSH_SUPPORTED */
-
-/* optional update palette with requested transformations */
-extern PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr));
-
-/* optional call to update the users info structure */
-extern PNG_EXPORT(void,png_read_update_info) PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
-/* read a one or more rows of image data.*/
-extern PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr,
- png_bytepp row, png_bytepp display_row, png_uint_32 num_rows));
-
-/* read a row of data.*/
-extern PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr,
- png_bytep row,
- png_bytep display_row));
-
-/* read the whole image into memory at once. */
-extern PNG_EXPORT(void,png_read_image) PNGARG((png_structp png_ptr,
- png_bytepp image));
-
-/* write a row of image data */
-extern PNG_EXPORT(void,png_write_row) PNGARG((png_structp png_ptr,
- png_bytep row));
-
-/* write a few rows of image data */
-extern PNG_EXPORT(void,png_write_rows) PNGARG((png_structp png_ptr,
- png_bytepp row, png_uint_32 num_rows));
-
-/* write the image data */
-extern PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr,
- png_bytepp image));
-
-/* writes the end of the PNG file. */
-extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
-/* read the end of the PNG file. */
-extern PNG_EXPORT(void,png_read_end) PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
-/* free any memory associated with the png_info_struct */
-extern PNG_EXPORT(void,png_destroy_info_struct) PNGARG((png_structp png_ptr,
- png_infopp info_ptr_ptr));
-
-/* free any memory associated with the png_struct and the png_info_structs */
-extern PNG_EXPORT(void,png_destroy_read_struct) PNGARG((png_structpp
- png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr));
-
-/* free all memory used by the read (old method - NOT DLL EXPORTED) */
-extern void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_infop end_info_ptr));
-
-/* free any memory associated with the png_struct and the png_info_structs */
-extern PNG_EXPORT(void,png_destroy_write_struct)
- PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr));
-
-/* free any memory used in info_ptr struct (old method - NOT DLL EXPORTED) */
-extern void png_write_destroy_info PNGARG((png_infop info_ptr));
-
-/* free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */
-extern void png_write_destroy PNGARG((png_structp png_ptr));
-
-/* set the libpng method of handling chunk CRC errors */
-extern PNG_EXPORT(void,png_set_crc_action) PNGARG((png_structp png_ptr,
- int crit_action, int ancil_action));
-
-/* Values for png_set_crc_action() to say how to handle CRC errors in
- * ancillary and critical chunks, and whether to use the data contained
- * therein. Note that it is impossible to "discard" data in a critical
- * chunk. For versions prior to 0.90, the action was always error/quit,
- * whereas in version 0.90 and later, the action for CRC errors in ancillary
- * chunks is warn/discard. These values should NOT be changed.
- *
- * value action:critical action:ancillary
- */
-#define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */
-#define PNG_CRC_ERROR_QUIT 1 /* error/quit error/quit */
-#define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */
-#define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */
-#define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */
-#define PNG_CRC_NO_CHANGE 5 /* use current value use current value */
-
-/* These functions give the user control over the scan-line filtering in
- * libpng and the compression methods 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 want faster performance at the
- * expense of compression can modify them. See the compression library
- * header file (zlib.h) for an explination of the compression functions.
- */
-
-/* set the filtering method(s) used by libpng. Currently, the only valid
- * value for "method" is 0.
- */
-extern PNG_EXPORT(void,png_set_filter) PNGARG((png_structp png_ptr, int method,
- int filters));
-
-/* Flags for png_set_filter() to say which filters to use. The flags
- * are chosen so that they don't conflict with real filter types
- * below, in case they are supplied instead of the #defined constants.
- * These values should NOT be changed.
- */
-#define PNG_NO_FILTERS 0x00
-#define PNG_FILTER_NONE 0x08
-#define PNG_FILTER_SUB 0x10
-#define PNG_FILTER_UP 0x20
-#define PNG_FILTER_AVG 0x40
-#define PNG_FILTER_PAETH 0x80
-#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \
- PNG_FILTER_AVG | PNG_FILTER_PAETH)
-
-/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now.
- * These defines should NOT be changed.
- */
-#define PNG_FILTER_VALUE_NONE 0
-#define PNG_FILTER_VALUE_SUB 1
-#define PNG_FILTER_VALUE_UP 2
-#define PNG_FILTER_VALUE_AVG 3
-#define PNG_FILTER_VALUE_PAETH 4
-#define PNG_FILTER_VALUE_LAST 5
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* EXPERIMENTAL */
-/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_
- * defines, either the default (minimum-sum-of-absolute-differences), or
- * the experimental method (weighted-minimum-sum-of-absolute-differences).
- *
- * Weights are factors >= 1.0, indicating how important it is to keep the
- * filter type consistent between rows. Larger numbers mean the current
- * filter is that many times as likely to be the same as the "num_weights"
- * previous filters. This is cumulative for each previous row with a weight.
- * There needs to be "num_weights" values in "filter_weights", or it can be
- * NULL if the weights aren't being specified. Weights have no influence on
- * the selection of the first row filter. Well chosen weights can (in theory)
- * improve the compression for a given image.
- *
- * Costs are factors >= 1.0 indicating the relative decoding costs of a
- * filter type. Higher costs indicate more decoding expense, and are
- * therefore less likely to be selected over a filter with lower computational
- * costs. There needs to be a value in "filter_costs" for each valid filter
- * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't
- * setting the costs. Costs try to improve the speed of decompression without
- * unduly increasing the compressed image size.
- *
- * A negative weight or cost indicates the default value is to be used, and
- * values in the range [0.0, 1.0) indicate the value is to remain unchanged.
- * The default values for both weights and costs are currently 1.0, but may
- * change if good general weighting/cost heuristics can be found. If both
- * the weights and costs are set to 1.0, this degenerates the WEIGHTED method
- * to the UNWEIGHTED method, but with added encoding time/computation.
- */
-extern PNG_EXPORT(void,png_set_filter_heuristics) PNGARG((png_structp png_ptr,
- int heuristic_method, int num_weights, png_doublep filter_weights,
- png_doublep filter_costs));
-#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
-
-/* Heuristic used for row filter selection. These defines should NOT be
- * changed.
- */
-#define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */
-#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */
-#define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */
-#define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */
-
-/* Set the library compression level. Currently, valid values range from
- * 0 - 9, corresponding directly to the zlib compression levels 0 - 9
- * (0 - no compression, 9 - "maximal" compression). Note that tests have
- * shown that zlib compression levels 3-6 usually perform as well as level 9
- * for PNG images, and do considerably fewer caclulations. In the future,
- * these values may not correspond directly to the zlib compression levels.
- */
-extern PNG_EXPORT(void,png_set_compression_level) PNGARG((png_structp png_ptr,
- int level));
-
-extern PNG_EXPORT(void,png_set_compression_mem_level)
- PNGARG((png_structp png_ptr, int mem_level));
-
-extern PNG_EXPORT(void,png_set_compression_strategy)
- PNGARG((png_structp png_ptr, int strategy));
-
-extern PNG_EXPORT(void,png_set_compression_window_bits)
- PNGARG((png_structp png_ptr, int window_bits));
-
-extern PNG_EXPORT(void,png_set_compression_method) PNGARG((png_structp png_ptr,
- int method));
-
-/* These next functions are called for input/output, memory, and error
- * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c,
- * and call standard C I/O routines such as fread(), fwrite(), and
- * fprintf(). These functions can be made to use other I/O routines
- * at run time for those applications that need to handle I/O in a
- * different manner by calling png_set_???_fn(). See libpng.txt for
- * more information.
- */
-
-#if !defined(PNG_NO_STDIO)
-/* Initialize the input/output for the PNG file to the default functions. */
-extern PNG_EXPORT(void,png_init_io) PNGARG((png_structp png_ptr, FILE *fp));
-#endif
-
-/* Replace the (error and abort), and warning functions with user
- * supplied functions. If no messages are to be printed you must still
- * write and use replacement functions. The replacement error_fn should
- * still do a longjmp to the last setjmp location if you are using this
- * method of error handling. If error_fn or warning_fn is NULL, the
- * default function will be used.
- */
-
-extern PNG_EXPORT(void,png_set_error_fn) PNGARG((png_structp png_ptr,
- png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn));
-
-/* Return the user pointer associated with the error functions */
-extern PNG_EXPORT(png_voidp,png_get_error_ptr) PNGARG((png_structp png_ptr));
-
-/* Replace the default data output functions with a user supplied one(s).
- * If buffered output is not used, then output_flush_fn can be set to NULL.
- * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time
- * output_flush_fn will be ignored (and thus can be NULL).
- */
-extern PNG_EXPORT(void,png_set_write_fn) PNGARG((png_structp png_ptr,
- png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn));
-
-/* Replace the default data input function with a user supplied one. */
-extern PNG_EXPORT(void,png_set_read_fn) PNGARG((png_structp png_ptr,
- png_voidp io_ptr, png_rw_ptr read_data_fn));
-
-/* Return the user pointer associated with the I/O functions */
-extern PNG_EXPORT(png_voidp,png_get_io_ptr) PNGARG((png_structp png_ptr));
-
-extern PNG_EXPORT(void,png_set_read_status_fn) PNGARG((png_structp png_ptr,
- png_read_status_ptr read_row_fn));
-
-extern PNG_EXPORT(void,png_set_write_status_fn) PNGARG((png_structp png_ptr,
- png_write_status_ptr write_row_fn));
-
-#ifdef PNG_USER_MEM_SUPPORTED
-/* Replace the default memory allocation functions with user supplied one(s). */
-extern PNG_EXPORT(void,png_set_mem_fn) PNGARG((png_structp png_ptr,
- png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn));
-
-/* Return the user pointer associated with the memory functions */
-extern PNG_EXPORT(png_voidp,png_get_mem_ptr) PNGARG((png_structp png_ptr));
-#endif /* PNG_USER_MEM_SUPPORTED */
-
-#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
-extern PNG_EXPORT(void,png_set_read_user_transform_fn) PNGARG((png_structp
- png_ptr, png_user_transform_ptr read_user_transform_fn));
-#endif
-
-#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
-extern PNG_EXPORT(void,png_set_write_user_transform_fn) PNGARG((png_structp
- png_ptr, png_user_transform_ptr write_user_transform_fn));
-#endif
-
-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-/* Sets the function callbacks for the push reader, and a pointer to a
- * user-defined structure available to the callback functions.
- */
-extern PNG_EXPORT(void,png_set_progressive_read_fn) PNGARG((png_structp png_ptr,
- png_voidp progressive_ptr,
- png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
- png_progressive_end_ptr end_fn));
-
-/* returns the user pointer associated with the push read functions */
-extern PNG_EXPORT(png_voidp,png_get_progressive_ptr)
- PNGARG((png_structp png_ptr));
-
-/* function to be called when data becomes available */
-extern PNG_EXPORT(void,png_process_data) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_bytep buffer, png_size_t buffer_size));
-
-/* function that combines rows. Not very much different than the
- * png_combine_row() call. Is this even used?????
- */
-extern PNG_EXPORT(void,png_progressive_combine_row) PNGARG((png_structp png_ptr,
- png_bytep old_row, png_bytep new_row));
-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
-
-extern PNG_EXPORT(png_voidp,png_malloc) PNGARG((png_structp png_ptr,
- png_uint_32 size));
-
-/* frees a pointer allocated by png_malloc() */
-extern PNG_EXPORT(void,png_free) PNGARG((png_structp png_ptr, png_voidp ptr));
-
-#ifdef PNG_USER_MEM_SUPPORTED
-extern PNG_EXPORT(png_voidp,png_malloc_default) PNGARG((png_structp png_ptr,
- png_uint_32 size));
-extern PNG_EXPORT(void,png_free_default) PNGARG((png_structp png_ptr,
- png_voidp ptr));
-#endif /* PNG_USER_MEM_SUPPORTED */
-
-extern PNG_EXPORT(png_voidp,png_memcpy_check) PNGARG((png_structp png_ptr,
- png_voidp s1, png_voidp s2, png_uint_32 size));
-
-extern PNG_EXPORT(png_voidp,png_memset_check) PNGARG((png_structp png_ptr,
- png_voidp s1, int value, png_uint_32 size));
-
-#if defined(USE_FAR_KEYWORD) /* memory model conversion function */
-extern void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr,
- int check));
-#endif /* USE_FAR_KEYWORD */
-
-/* Fatal error in PNG image of libpng - can't continue */
-extern PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr,
- png_const_charp error));
-
-/* The same, but the chunk name is prepended to the error string. */
-extern PNG_EXPORT(void,png_chunk_error) PNGARG((png_structp png_ptr,
- png_const_charp error));
-
-/* Non-fatal error in libpng. Can continue, but may have a problem. */
-extern PNG_EXPORT(void,png_warning) PNGARG((png_structp png_ptr,
- png_const_charp message));
-
-/* Non-fatal error in libpng, chunk name is prepended to message. */
-extern PNG_EXPORT(void,png_chunk_warning) PNGARG((png_structp png_ptr,
- png_const_charp message));
-
-/* The png_set_<chunk> functions are for storing values in the png_info_struct.
- * Similarly, the png_get_<chunk> calls are used to read values from the
- * png_info_struct, either storing the parameters in the passed variables, or
- * setting pointers into the png_info_struct where the data is stored. The
- * png_get_<chunk> functions return a non-zero value if the data was available
- * in info_ptr, or return zero and do not change any of the parameters if the
- * data was not available.
- *
- * These functions should be used instead of directly accessing png_info
- * to avoid problems with future changes in the size and internal layout of
- * png_info_struct.
- */
-/* Returns "flag" if chunk data is valid in info_ptr. */
-extern PNG_EXPORT(png_uint_32,png_get_valid) PNGARG((png_structp png_ptr,
-png_infop info_ptr, png_uint_32 flag));
-
-/* Returns number of bytes needed to hold a transformed row. */
-extern PNG_EXPORT(png_uint_32,png_get_rowbytes) PNGARG((png_structp png_ptr,
-png_infop info_ptr));
-
-/* Returns number of color channels in image. */
-extern PNG_EXPORT(png_byte,png_get_channels) PNGARG((png_structp png_ptr,
-png_infop info_ptr));
-
-#ifdef PNG_EASY_ACCESS_SUPPORTED
-/* Returns image width in pixels. */
-extern PNG_EXPORT(png_uint_32, png_get_image_width) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-
-/* Returns image height in pixels. */
-extern PNG_EXPORT(png_uint_32, png_get_image_height) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-
-/* Returns image bit_depth. */
-extern PNG_EXPORT(png_byte, png_get_bit_depth) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-
-/* Returns image color_type. */
-extern PNG_EXPORT(png_byte, png_get_color_type) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-
-/* Returns image filter_type. */
-extern PNG_EXPORT(png_byte, png_get_filter_type) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-
-/* Returns image interlace_type. */
-extern PNG_EXPORT(png_byte, png_get_interlace_type) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-
-/* Returns image compression_type. */
-extern PNG_EXPORT(png_byte, png_get_compression_type) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-
-/* Returns image resolution in pixels per meter, from pHYs chunk data. */
-extern PNG_EXPORT(png_uint_32, png_get_pixels_per_meter) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-extern PNG_EXPORT(png_uint_32, png_get_x_pixels_per_meter) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-extern PNG_EXPORT(png_uint_32, png_get_y_pixels_per_meter) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-
-/* Returns pixel aspect ratio, computed from pHYs chunk data. */
-extern PNG_EXPORT(float, png_get_pixel_aspect_ratio) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-
-/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */
-extern PNG_EXPORT(png_uint_32, png_get_x_offset_pixels) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-extern PNG_EXPORT(png_uint_32, png_get_y_offset_pixels) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-extern PNG_EXPORT(png_uint_32, png_get_x_offset_microns) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-extern PNG_EXPORT(png_uint_32, png_get_y_offset_microns) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-
-#endif /* PNG_EASY_ACCESS_SUPPORTED */
-
-/* Returns pointer to signature string read from PNG header */
-extern PNG_EXPORT(png_bytep,png_get_signature) PNGARG((png_structp png_ptr,
-png_infop info_ptr));
-
-#if defined(PNG_READ_bKGD_SUPPORTED)
-extern PNG_EXPORT(png_uint_32,png_get_bKGD) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_color_16p *background));
-#endif /* PNG_READ_bKGD_SUPPORTED */
-
-#if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED)
-extern PNG_EXPORT(void,png_set_bKGD) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_color_16p background));
-#endif /* PNG_READ_bKGD_SUPPORTED || PNG_WRITE_bKGD_SUPPORTED */
-
-#if defined(PNG_READ_cHRM_SUPPORTED)
-extern PNG_EXPORT(png_uint_32,png_get_cHRM) PNGARG((png_structp png_ptr,
- png_infop info_ptr, double *white_x, double *white_y, double *red_x,
- double *red_y, double *green_x, double *green_y, double *blue_x,
- double *blue_y));
-#endif /* PNG_READ_cHRM_SUPPORTED */
-
-#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
-extern PNG_EXPORT(void,png_set_cHRM) PNGARG((png_structp png_ptr,
- png_infop info_ptr, double white_x, double white_y, double red_x,
- double red_y, double green_x, double green_y, double blue_x, double blue_y));
-#endif /* PNG_READ_cHRM_SUPPORTED || PNG_WRITE_cHRM_SUPPORTED */
-
-#if defined(PNG_READ_gAMA_SUPPORTED)
-extern PNG_EXPORT(png_uint_32,png_get_gAMA) PNGARG((png_structp png_ptr,
- png_infop info_ptr, double *file_gamma));
-#endif /* PNG_READ_gAMA_SUPPORTED */
-
-#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED)
-extern PNG_EXPORT(void,png_set_gAMA) PNGARG((png_structp png_ptr,
- png_infop info_ptr, double file_gamma));
-#endif /* PNG_READ_gAMA_SUPPORTED || PNG_WRITE_gAMA_SUPPORTED */
-
-#if defined(PNG_READ_hIST_SUPPORTED)
-extern PNG_EXPORT(png_uint_32,png_get_hIST) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_16p *hist));
-#endif /* PNG_READ_hIST_SUPPORTED */
-
-#if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED)
-extern PNG_EXPORT(void,png_set_hIST) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_16p hist));
-#endif /* PNG_READ_hIST_SUPPORTED || PNG_WRITE_hIST_SUPPORTED */
-
-extern PNG_EXPORT(png_uint_32,png_get_IHDR) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 *width, png_uint_32 *height,
- int *bit_depth, int *color_type, int *interlace_type,
- int *compression_type, int *filter_type));
-
-extern PNG_EXPORT(void,png_set_IHDR) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth,
- int color_type, int interlace_type, int compression_type, int filter_type));
-
-#if defined(PNG_READ_oFFs_SUPPORTED)
-extern PNG_EXPORT(png_uint_32,png_get_oFFs) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 *offset_x, png_uint_32 *offset_y,
- int *unit_type));
-#endif /* PNG_READ_oFFs_SUPPORTED */
-
-#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
-extern PNG_EXPORT(void,png_set_oFFs) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 offset_x, png_uint_32 offset_y,
- int unit_type));
-#endif /* PNG_READ_oFFs_SUPPORTED || PNG_WRITE_oFFs_SUPPORTED */
-
-#if defined(PNG_READ_pCAL_SUPPORTED)
-extern PNG_EXPORT(png_uint_32,png_get_pCAL) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1,
- int *type, int *nparams, png_charp *units, png_charpp *params));
-#endif /* PNG_READ_pCAL_SUPPORTED */
-
-#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED)
-extern PNG_EXPORT(void,png_set_pCAL) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1,
- int type, int nparams, png_charp units, png_charpp params));
-#endif /* PNG_READ_pCAL_SUPPORTED || PNG_WRITE_pCAL_SUPPORTED */
-
-#if defined(PNG_READ_pHYs_SUPPORTED)
-extern PNG_EXPORT(png_uint_32,png_get_pHYs) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
-#endif /* PNG_READ_pHYs_SUPPORTED */
-
-#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
-extern PNG_EXPORT(void,png_set_pHYs) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type));
-#endif /* PNG_READ_pHYs_SUPPORTED || PNG_WRITE_pHYs_SUPPORTED */
-
-extern PNG_EXPORT(png_uint_32,png_get_PLTE) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_colorp *palette, int *num_palette));
-
-extern PNG_EXPORT(void,png_set_PLTE) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_colorp palette, int num_palette));
-
-#if defined(PNG_READ_sBIT_SUPPORTED)
-extern PNG_EXPORT(png_uint_32,png_get_sBIT) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_color_8p *sig_bit));
-#endif /* PNG_READ_sBIT_SUPPORTED */
-
-#if defined(PNG_READ_sBIT_SUPPORTED) || defined(PNG_WRITE_sBIT_SUPPORTED)
-extern PNG_EXPORT(void,png_set_sBIT) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_color_8p sig_bit));
-#endif /* PNG_READ_sBIT_SUPPORTED || PNG_WRITE_sBIT_SUPPORTED */
-
-#if defined(PNG_READ_sRGB_SUPPORTED)
-extern PNG_EXPORT(png_uint_32,png_get_sRGB) PNGARG((png_structp png_ptr,
- png_infop info_ptr, int *intent));
-#endif /* PNG_READ_sRGB_SUPPORTED */
-
-#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
-extern PNG_EXPORT(void,png_set_sRGB) PNGARG((png_structp png_ptr,
- png_infop info_ptr, int intent));
-extern PNG_EXPORT(void,png_set_sRGB_gAMA_and_cHRM) PNGARG((png_structp png_ptr,
- png_infop info_ptr, int intent));
-#endif /* PNG_READ_sRGB_SUPPORTED || PNG_WRITE_sRGB_SUPPORTED */
-
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
-/* png_get_text also returns the number of text chunks in text_ptr */
-extern PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_textp *text_ptr, int *num_text));
-#endif /* PNG_READ_tEXt_SUPPORTED || PNG_READ_zTXt_SUPPORTED */
-
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
- defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
-extern PNG_EXPORT(void,png_set_text) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_textp text_ptr, int num_text));
-#endif /* PNG_READ_OR_WRITE_tEXt_OR_zTXt_SUPPORTED */
-
-#if defined(PNG_READ_tIME_SUPPORTED)
-extern PNG_EXPORT(png_uint_32,png_get_tIME) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_timep *mod_time));
-#endif /* PNG_READ_tIME_SUPPORTED */
-
-#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED)
-extern PNG_EXPORT(void,png_set_tIME) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_timep mod_time));
-#endif /* PNG_READ_tIME_SUPPORTED || PNG_WRITE_tIME_SUPPORTED */
-
-#if defined(PNG_READ_tRNS_SUPPORTED)
-extern PNG_EXPORT(png_uint_32,png_get_tRNS) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_bytep *trans, int *num_trans,
- png_color_16p *trans_values));
-#endif /* PNG_READ_tRNS_SUPPORTED */
-
-#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED)
-extern PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_bytep trans, int num_trans,
- png_color_16p trans_values));
-#endif /* PNG_READ_tRNS_SUPPORTED || PNG_WRITE_tRNS_SUPPORTED */
-
-/* Define PNG_DEBUG at compile time for debugging information. Higher
- * numbers for PNG_DEBUG mean more debugging information. This has
- * only been added since version 0.95 so it is not implemented throughout
- * libpng yet, but more support will be added as needed.
- */
-#ifdef PNG_DEBUG
-#if (PNG_DEBUG > 0)
-#ifndef PNG_DEBUG_FILE
-#define PNG_DEBUG_FILE stderr
-#endif /* PNG_DEBUG_FILE */
-
-#define png_debug(l,m) if (PNG_DEBUG > l) \
- fprintf(PNG_DEBUG_FILE,"%s"m,(l==1 ? "\t" : \
- (l==2 ? "\t\t":(l>2 ? "\t\t\t":""))))
-#define png_debug1(l,m,p1) if (PNG_DEBUG > l) \
- fprintf(PNG_DEBUG_FILE,"%s"m,(l==1 ? "\t" : \
- (l==2 ? "\t\t":(l>2 ? "\t\t\t":""))),p1)
-#define png_debug2(l,m,p1,p2) if (PNG_DEBUG > l) \
- fprintf(PNG_DEBUG_FILE,"%s"m,(l==1 ? "\t" : \
- (l==2 ? "\t\t":(l>2 ? "\t\t\t":""))),p1,p2)
-#endif /* (PNG_DEBUG > 0) */
-#endif /* PNG_DEBUG */
-#ifndef png_debug
-#define png_debug(l, m)
-#endif
-#ifndef png_debug1
-#define png_debug1(l, m, p1)
-#endif
-#ifndef png_debug2
-#define png_debug2(l, m, p1, p2)
-#endif
-
-extern PNG_EXPORT(png_charp,png_get_copyright) PNGARG((png_structp png_ptr));
-extern PNG_EXPORT(png_charp,png_get_header_version) PNGARG((png_structp png_ptr));
-
-#ifdef PNG_NO_EXTERN
-/* this only gets included in png.c */
-png_charp
-png_get_header_version(png_structp png_ptr)
-{
- if(png_ptr == NULL)
- /* silence compiler warning about unused png_ptr */ ;
- return("\n libpng version 1.0.3 - January 14, 1999 (header)\n");
-}
-#endif
-
-#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED
-/* With these routines we avoid an integer divide, which will be slower on
- * most machines. However, it does take more operations than the corresponding
- * divide method, so it may be slower on a few RISC systems. There are two
- * shifts (by 8 or 16 bits) and an addition, versus a single integer divide.
- *
- * Note that the rounding factors are NOT supposed to be the same! 128 and
- * 32768 are correct for the NODIV code; 127 and 32767 are correct for the
- * standard method.
- *
- * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ]
- */
-
- /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */
-
-# define png_composite(composite, fg, alpha, bg) \
- { png_uint_16 temp = ((png_uint_16)(fg) * (png_uint_16)(alpha) + \
- (png_uint_16)(bg)*(png_uint_16)(255 - \
- (png_uint_16)(alpha)) + (png_uint_16)128); \
- (composite) = (png_byte)((temp + (temp >> 8)) >> 8); }
-
-# define png_composite_16(composite, fg, alpha, bg) \
- { png_uint_32 temp = ((png_uint_32)(fg) * (png_uint_32)(alpha) + \
- (png_uint_32)(bg)*(png_uint_32)(65535L - \
- (png_uint_32)(alpha)) + (png_uint_32)32768L); \
- (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); }
-
-#else /* standard method using integer division */
-
-# define png_composite(composite, fg, alpha, bg) \
- (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \
- (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
- (png_uint_16)127) / 255)
-
-# define png_composite_16(composite, fg, alpha, bg) \
- (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \
- (png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) + \
- (png_uint_32)32767) / (png_uint_32)65535L)
-
-#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */
-
-/* These next functions are used internally in the code. They generally
- * shouldn't be used unless you are writing code to add or replace some
- * functionality in libpng. More information about most functions can
- * be found in the files where the functions are located.
- */
-
-#if defined(PNG_INTERNAL)
-
-/* Various modes of operation. Note that after an init, mode is set to
- * zero automatically when the structure is created.
- */
-#define PNG_BEFORE_IHDR 0x00
-#define PNG_HAVE_IHDR 0x01
-#define PNG_HAVE_PLTE 0x02
-#define PNG_HAVE_IDAT 0x04
-#define PNG_AFTER_IDAT 0x08
-#define PNG_HAVE_IEND 0x10
-#define PNG_HAVE_gAMA 0x20
-#define PNG_HAVE_cHRM 0x40
-#define PNG_HAVE_sRGB 0x80
-
-/* push model modes */
-#define PNG_READ_SIG_MODE 0
-#define PNG_READ_CHUNK_MODE 1
-#define PNG_READ_IDAT_MODE 2
-#define PNG_SKIP_MODE 3
-#define PNG_READ_tEXt_MODE 4
-#define PNG_READ_zTXt_MODE 5
-#define PNG_READ_DONE_MODE 6
-#define PNG_ERROR_MODE 7
-
-/* flags for the transformations the PNG library does on the image data */
-#define PNG_BGR 0x0001
-#define PNG_INTERLACE 0x0002
-#define PNG_PACK 0x0004
-#define PNG_SHIFT 0x0008
-#define PNG_SWAP_BYTES 0x0010
-#define PNG_INVERT_MONO 0x0020
-#define PNG_DITHER 0x0040
-#define PNG_BACKGROUND 0x0080
-#define PNG_BACKGROUND_EXPAND 0x0100
- /* 0x0200 unused */
-#define PNG_16_TO_8 0x0400
-#define PNG_RGBA 0x0800
-#define PNG_EXPAND 0x1000
-#define PNG_GAMMA 0x2000
-#define PNG_GRAY_TO_RGB 0x4000
-#define PNG_FILLER 0x8000
-#define PNG_PACKSWAP 0x10000L
-#define PNG_SWAP_ALPHA 0x20000L
-#define PNG_STRIP_ALPHA 0x40000L
-#define PNG_INVERT_ALPHA 0x80000L
-#define PNG_USER_TRANSFORM 0x100000L
-#define PNG_RGB_TO_GRAY_ERR 0x200000L
-#define PNG_RGB_TO_GRAY_WARN 0x400000L
-#define PNG_RGB_TO_GRAY 0x600000L /* two bits, RGB_TO_GRAY_ERR|WARN */
-
-/* flags for png_create_struct */
-#define PNG_STRUCT_PNG 0x0001
-#define PNG_STRUCT_INFO 0x0002
-
-/* Scaling factor for filter heuristic weighting calculations */
-#define PNG_WEIGHT_SHIFT 8
-#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT))
-#define PNG_COST_SHIFT 3
-#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT))
-
-/* flags for the png_ptr->flags rather than declaring a byte for each one */
-#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001
-#define PNG_FLAG_ZLIB_CUSTOM_LEVEL 0x0002
-#define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL 0x0004
-#define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS 0x0008
-#define PNG_FLAG_ZLIB_CUSTOM_METHOD 0x0010
-#define PNG_FLAG_ZLIB_FINISHED 0x0020
-#define PNG_FLAG_ROW_INIT 0x0040
-#define PNG_FLAG_FILLER_AFTER 0x0080
-#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100
-#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200
-#define PNG_FLAG_CRC_CRITICAL_USE 0x0400
-#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800
-#define PNG_FLAG_FREE_PALETTE 0x1000
-#define PNG_FLAG_FREE_TRANS 0x2000
-#define PNG_FLAG_FREE_HIST 0x4000
-#define PNG_FLAG_HAVE_CHUNK_HEADER 0x8000L
-#define PNG_FLAG_WROTE_tIME 0x10000L
-#define PNG_FLAG_BACKGROUND_IS_GRAY 0x20000L
-
-#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
- PNG_FLAG_CRC_ANCILLARY_NOWARN)
-
-#define PNG_FLAG_CRC_CRITICAL_MASK (PNG_FLAG_CRC_CRITICAL_USE | \
- PNG_FLAG_CRC_CRITICAL_IGNORE)
-
-#define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \
- PNG_FLAG_CRC_CRITICAL_MASK)
-
-/* save typing and make code easier to understand */
-#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
- abs((int)((c1).green) - (int)((c2).green)) + \
- abs((int)((c1).blue) - (int)((c2).blue)))
-
-/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */
-#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
-/* place to hold the signature string for a PNG file. */
-extern png_byte FARDATA png_sig[8];
-
-/* 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. We
- * can't selectively include these, since we still check for chunk in the
- * wrong locations with these labels.
- */
-extern png_byte FARDATA png_IHDR[5];
-extern png_byte FARDATA png_IDAT[5];
-extern png_byte FARDATA png_IEND[5];
-extern png_byte FARDATA png_PLTE[5];
-extern png_byte FARDATA png_bKGD[5];
-extern png_byte FARDATA png_cHRM[5];
-extern png_byte FARDATA png_gAMA[5];
-extern png_byte FARDATA png_hIST[5];
-extern png_byte FARDATA png_oFFs[5];
-extern png_byte FARDATA png_pCAL[5];
-extern png_byte FARDATA png_pHYs[5];
-extern png_byte FARDATA png_sBIT[5];
-extern png_byte FARDATA png_sRGB[5];
-extern png_byte FARDATA png_tEXt[5];
-extern png_byte FARDATA png_tIME[5];
-extern png_byte FARDATA png_tRNS[5];
-extern png_byte FARDATA png_zTXt[5];
-
-#endif /* PNG_NO_EXTERN */
-
-/* Inline macros to do direct reads of bytes from the input buffer. These
- * require that you are using an architecture that uses PNG byte ordering
- * (MSB first) and supports unaligned data storage. I think that PowerPC
- * in big-endian mode and 680x0 are the only ones that will support this.
- * The x86 line of processors definitely do not. The png_get_int_32()
- * routine also assumes we are using two's complement format for negative
- * values, which is almost certainly true.
- */
-#if defined(PNG_READ_BIG_ENDIAN_SUPPORTED)
-#if defined(PNG_READ_pCAL_SUPPORTED)
-#define png_get_int_32(buf) ( *((png_int_32p) (buf)))
-#endif /* PNG_READ_pCAL_SUPPORTED */
-#define png_get_uint_32(buf) ( *((png_uint_32p) (buf)))
-#define png_get_uint_16(buf) ( *((png_uint_16p) (buf)))
-#else
-#if defined(PNG_READ_pCAL_SUPPORTED)
-PNG_EXTERN png_int_32 png_get_int_32 PNGARG((png_bytep buf));
-#endif /* PNG_READ_pCAL_SUPPORTED */
-PNG_EXTERN png_uint_32 png_get_uint_32 PNGARG((png_bytep buf));
-PNG_EXTERN png_uint_16 png_get_uint_16 PNGARG((png_bytep buf));
-#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
-
-/* Initialize png_ptr struct for reading, and allocate any other memory.
- * (old interface - NOT DLL EXPORTED).
- */
-extern void png_read_init PNGARG((png_structp png_ptr));
-
-/* Initialize png_ptr struct for writing, and allocate any other memory.
- * (old interface - NOT DLL EXPORTED).
- */
-extern void png_write_init PNGARG((png_structp png_ptr));
-
-/* allocate memory for an internal libpng struct */
-PNG_EXTERN png_voidp png_create_struct PNGARG((int type));
-
-/* free memory from internal libpng struct */
-PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr));
-
-PNG_EXTERN png_voidp png_create_struct_2 PNGARG((int type, png_malloc_ptr
- malloc_fn));
-PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr,
- png_free_ptr free_fn));
-
-/* free any memory that info_ptr points to and reset struct. */
-PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
-/* Function to allocate memory for zlib. */
-PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size));
-
-/* function to free memory for zlib */
-PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr));
-
-/* reset the CRC variable */
-PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr));
-
-/* Write the "data" buffer to whatever output you are using. */
-PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, png_bytep data,
- png_size_t length));
-
-/* Read data from whatever input you are using into the "data" buffer */
-PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data,
- png_size_t length));
-
-/* read bytes into buf, and update png_ptr->crc */
-PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf,
- png_size_t length));
-
-/* read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */
-PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip));
-
-/* read the CRC from the file and compare it to the libpng calculated CRC */
-PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr));
-
-/* Calculate the CRC over a section of data. Note that we are only
- * passing a maximum of 64K on systems that have this as a memory limit,
- * since this is the maximum buffer size we can specify.
- */
-PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, png_bytep ptr,
- png_size_t length));
-
-#if defined(PNG_WRITE_FLUSH_SUPPORTED)
-PNG_EXTERN void png_flush PNGARG((png_structp png_ptr));
-#endif
-
-/* Place a 32-bit number into a buffer in PNG byte order (big-endian).
- * The only currently known PNG chunks that use signed numbers are
- * the ancillary extension chunks, oFFs and pCAL.
- */
-PNG_EXTERN void png_save_uint_32 PNGARG((png_bytep buf, png_uint_32 i));
-
-#if defined(PNG_WRITE_pCAL_SUPPORTED)
-PNG_EXTERN void png_save_int_32 PNGARG((png_bytep buf, png_int_32 i));
-#endif
-
-/* Place a 16 bit number into a buffer in PNG byte order.
- * The parameter is declared unsigned int, not png_uint_16,
- * just to avoid potential problems on pre-ANSI C compilers.
- */
-PNG_EXTERN void png_save_uint_16 PNGARG((png_bytep buf, unsigned int i));
-
-/* simple function to write the signature */
-PNG_EXTERN void png_write_sig PNGARG((png_structp png_ptr));
-
-/* write various chunks */
-
-/* Write the IHDR chunk, and update the png_struct with the necessary
- * information.
- */
-PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width,
- png_uint_32 height,
- int bit_depth, int color_type, int compression_type, int filter_type,
- int interlace_type));
-
-PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, png_colorp palette,
- png_uint_32 num_pal));
-
-PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data,
- png_size_t length));
-
-PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr));
-
-#if defined(PNG_WRITE_gAMA_SUPPORTED)
-PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma));
-#endif
-
-#if defined(PNG_WRITE_sBIT_SUPPORTED)
-PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, png_color_8p sbit,
- int color_type));
-#endif
-
-#if defined(PNG_WRITE_cHRM_SUPPORTED)
-PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr,
- double white_x, double white_y,
- double red_x, double red_y, double green_x, double green_y,
- double blue_x, double blue_y));
-#endif
-
-#if defined(PNG_WRITE_sRGB_SUPPORTED)
-PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr,
- int intent));
-#endif
-
-#if defined(PNG_WRITE_tRNS_SUPPORTED)
-PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, png_bytep trans,
- png_color_16p values, int number, int color_type));
-#endif
-
-#if defined(PNG_WRITE_bKGD_SUPPORTED)
-PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr,
- png_color_16p values, int color_type));
-#endif
-
-#if defined(PNG_WRITE_hIST_SUPPORTED)
-PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, png_uint_16p hist,
- int num_hist));
-#endif
-
-#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) || \
- defined(PNG_WRITE_pCAL_SUPPORTED)
-PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr,
- png_charp key, png_charpp new_key));
-#endif
-
-#if defined(PNG_WRITE_tEXt_SUPPORTED)
-PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_charp key,
- png_charp text, png_size_t text_len));
-#endif
-
-#if defined(PNG_WRITE_zTXt_SUPPORTED)
-PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_charp key,
- png_charp text, png_size_t text_len, int compression));
-#endif
-
-#if defined(PNG_WRITE_oFFs_SUPPORTED)
-PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr,
- png_uint_32 x_offset, png_uint_32 y_offset, int unit_type));
-#endif
-
-#if defined(PNG_WRITE_pCAL_SUPPORTED)
-PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose,
- png_int_32 X0, png_int_32 X1, int type, int nparams,
- png_charp units, png_charpp params));
-#endif
-
-#if defined(PNG_WRITE_pHYs_SUPPORTED)
-PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr,
- png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit,
- int unit_type));
-#endif
-
-#if defined(PNG_WRITE_tIME_SUPPORTED)
-PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr,
- png_timep mod_time));
-#endif
-
-/* Called when finished processing a row of data */
-PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr));
-
-/* Internal use only. Called before first row of data */
-PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr));
-
-#if defined(PNG_READ_GAMMA_SUPPORTED)
-PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr));
-#endif
-
-/* combine a row of data, dealing with alpha, etc. if requested */
-PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row,
- int mask));
-
-#if defined(PNG_READ_INTERLACING_SUPPORTED)
-/* expand an interlaced row */
-PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info,
- png_bytep row, int pass, png_uint_32 transformations));
-#endif
-
-#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
-/* grab pixels out of a row for an interlaced pass */
-PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info,
- png_bytep row, int pass));
-#endif
-
-/* unfilter a row */
-PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr,
- png_row_infop row_info, png_bytep row, png_bytep prev_row, int filter));
-
-/* Choose the best filter to use and filter the row data */
-PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr,
- png_row_infop row_info));
-
-/* Write out the filtered row. */
-PNG_EXTERN void png_write_filtered_row PNGARG((png_structp png_ptr,
- png_bytep filtered_row));
-/* finish a row while reading, dealing with interlacing passes, etc. */
-PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr));
-
-/* initialize the row buffers, etc. */
-PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr));
-/* optional call to update the users info structure */
-PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
-/* these are the functions that do the transformations */
-#if defined(PNG_READ_FILLER_SUPPORTED)
-PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info,
- png_bytep row, png_uint_32 filler, png_uint_32 flags));
-#endif
-
-#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
-PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info,
- png_bytep row));
-#endif
-
-#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
-PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info,
- png_bytep row));
-#endif
-
-#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
-PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info,
- png_bytep row));
-#endif
-
-#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
-PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info,
- png_bytep row));
-#endif
-
-#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
- defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
-PNG_EXTERN void png_do_strip_filler PNGARG((png_row_infop row_info,
- png_bytep row, png_uint_32 flags));
-#endif
-
-#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
-PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info, png_bytep row));
-#endif
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
-PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info, png_bytep row));
-#endif
-
-#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, png_row_infop
- row_info, png_bytep row));
-#endif
-
-#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
-PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info,
- png_bytep row));
-#endif
-
-#if defined(PNG_READ_PACK_SUPPORTED)
-PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, png_bytep row));
-#endif
-
-#if defined(PNG_READ_SHIFT_SUPPORTED)
-PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, png_bytep row,
- png_color_8p sig_bits));
-#endif
-
-#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
-PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info, png_bytep row));
-#endif
-
-#if defined(PNG_READ_16_TO_8_SUPPORTED)
-PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, png_bytep row));
-#endif
-
-#if defined(PNG_READ_DITHER_SUPPORTED)
-PNG_EXTERN void png_do_dither PNGARG((png_row_infop row_info,
- png_bytep row, png_bytep palette_lookup, png_bytep dither_lookup));
-
-# if defined(PNG_CORRECT_PALETTE_SUPPORTED)
-PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr,
- png_colorp palette, int num_palette));
-# endif
-#endif
-
-#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
-PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info, png_bytep row));
-#endif
-
-#if defined(PNG_WRITE_PACK_SUPPORTED)
-PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info,
- png_bytep row, png_uint_32 bit_depth));
-#endif
-
-#if defined(PNG_WRITE_SHIFT_SUPPORTED)
-PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, png_bytep row,
- png_color_8p bit_depth));
-#endif
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
-PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row,
- png_color_16p trans_values, png_color_16p background,
- png_color_16p background_1,
- png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
- png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
- png_uint_16pp gamma_16_to_1, int gamma_shift));
-#endif
-
-#if defined(PNG_READ_GAMMA_SUPPORTED)
-PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, png_bytep row,
- png_bytep gamma_table, png_uint_16pp gamma_16_table,
- int gamma_shift));
-#endif
-
-#if defined(PNG_READ_EXPAND_SUPPORTED)
-PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info,
- png_bytep row, png_colorp palette, png_bytep trans, int num_trans));
-PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info,
- png_bytep row, png_color_16p trans_value));
-#endif
-
-/* The following decodes the appropriate chunks, and does error correction,
- * then calls the appropriate callback for the chunk if it is valid.
- */
-
-/* decode the IHDR chunk */
-PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-
-#if defined(PNG_READ_gAMA_SUPPORTED)
-PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_sBIT_SUPPORTED)
-PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_cHRM_SUPPORTED)
-PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_sRGB_SUPPORTED)
-PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_tRNS_SUPPORTED)
-PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_bKGD_SUPPORTED)
-PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_hIST_SUPPORTED)
-PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_oFFs_SUPPORTED)
-PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_pCAL_SUPPORTED)
-PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_pHYs_SUPPORTED)
-PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_tIME_SUPPORTED)
-PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_tEXt_SUPPORTED)
-PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_zTXt_SUPPORTED)
-PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 length));
-
-PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr,
- png_bytep chunk_name));
-
-/* handle the transformations for reading and writing */
-PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr));
-PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr));
-
-PNG_EXTERN void png_init_read_transformations PNGARG((png_structp png_ptr));
-
-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr));
-PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr,
- png_uint_32 length));
-PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr));
-PNG_EXTERN void png_push_fill_buffer PNGARG((png_structp png_ptr,
- png_bytep buffer, png_size_t length));
-PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr));
-PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr,
- png_bytep buffer, png_size_t buffer_length));
-PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr));
-PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr,
- png_bytep buffer, png_size_t buffer_length));
-PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr));
-PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 length));
-PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr, png_bytep row));
-PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-PNG_EXTERN void png_read_push_finish_row PNGARG((png_structp png_ptr));
-#if defined(PNG_READ_tEXt_SUPPORTED)
-PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 length));
-PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-#endif
-#if defined(PNG_READ_zTXt_SUPPORTED)
-PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 length));
-PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-#endif
-
-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
-
-#endif /* PNG_INTERNAL */
-
-#ifdef __cplusplus
-}
-#endif
-
-/* do not put anything past this line */
-#endif /* _PNG_H */
+++ /dev/null
-
-/* pngconf.h - machine configurable file for libpng
- *
- * libpng 1.0.3 - January 14, 1999
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
- */
-
-/* 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 extremely 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 than the size of a row (compressed),
- * it should not make much difference how big this is.
- */
-
-#ifndef PNG_ZBUF_SIZE
-#define PNG_ZBUF_SIZE 8192
-#endif
-
-/* If you are running on a machine where you cannot allocate more
- * than 64K of memory at once, 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_MALLOC_64K
- */
-#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
-#define PNG_MAX_MALLOC_64K
-#endif
-
-/* This protects us against compilers that run on a windowing system
- * and thus don't have or would rather us not use the stdio types:
- * stdin, stdout, and stderr. The only one currently used is stderr
- * in png_error() and png_warning(). #defining PNG_NO_CONSOLE_IO will
- * prevent these from being compiled and used. #defining PNG_NO_STDIO
- * will also prevent these, plus will prevent the entire set of stdio
- * macros and functions (FILE *, printf, etc.) from being compiled and used,
- * unless PNG_DEBUG has been #defined.
- *
- * #define PNG_NO_CONSOLE_IO
- * #define PNG_NO_STDIO
- */
-
-#ifdef PNG_DEBUG
-# if (PNG_DEBUG > 0)
-# include <stdio.h>
-# endif
-#else
-# ifdef PNG_NO_STDIO
-# ifndef PNG_NO_CONSOLE_IO
-# define PNG_NO_CONSOLE_IO
-# endif
-# else
-# include <stdio.h>
-# endif
-#endif
-
-/* This macro protects us against machines that don't have function
- * prototypes (ie K&R style headers). If your compiler does not handle
- * function prototypes, define this macro and use the included ansi2knr.
- * 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 /* zlib prototype munger */
-#define PNGARG(arglist) OF(arglist)
-#else
-
-#ifdef _NO_PROTO
-#define PNGARG(arglist) ()
-#else
-#define PNGARG(arglist) arglist
-#endif /* _NO_PROTO */
-
-#endif /* OF */
-
-#endif /* PNGARG */
-
-/* Try to determine if we are compiling on a Mac. Note that testing for
- * just __MWERKS__ is not good enough, because the Codewarrior is now used
- * on non-Mac platforms.
- */
-#ifndef MACOS
-#if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
- defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
-#define MACOS
-#endif
-#endif
-
-/* enough people need this for various reasons to include it here */
-#if !defined(MACOS) && !defined(RISCOS)
-#include <sys/types.h>
-#endif
-
-/* This is an attempt to force a single setjmp behaviour on Linux. If
- * the X config stuff didn't define _BSD_SOURCE we wouldn't need this.
- */
-#ifdef __linux__
-#ifdef _BSD_SOURCE
-#define _PNG_SAVE_BSD_SOURCE
-#undef _BSD_SOURCE
-#endif
-#ifdef _SETJMP_H
-__png.h__ already includes setjmp.h
-__dont__ include it again
-#endif
-#endif /* __linux__ */
-
-/* include setjmp.h for error handling */
-#include <setjmp.h>
-
-#ifdef __linux__
-#ifdef _PNG_SAVE_BSD_SOURCE
-#define _BSD_SOURCE
-#undef _PNG_SAVE_BSD_SOURCE
-#endif
-#endif /* __linux__ */
-
-#ifdef BSD
-#include <strings.h>
-#else
-#include <string.h>
-#endif
-
-/* Other defines for things like memory and the like can go here. */
-#ifdef PNG_INTERNAL
-#include <stdlib.h>
-
-/* The functions exported by PNG_EXTERN are PNG_INTERNAL functions, which
- * aren't usually used outside the library (as far as I know), so it is
- * debatable if they should be exported at all. In the future, when it is
- * possible to have run-time registry of chunk-handling functions, some of
- * these will be made available again.
-#define PNG_EXTERN extern
- */
-#define PNG_EXTERN
-
-/* Other defines specific to compilers can go here. Try to keep
- * them inside an appropriate ifdef/endif pair for portability.
- */
-
-#if defined(MACOS)
-/* We need to check that <math.h> hasn't already been included earlier
- * as it seems it doesn't agree with <fp.h>, yet we should really use
- * <fp.h> if possible.
- */
-#if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
-#include <fp.h>
-#endif
-#else
-#include <math.h>
-#endif
-
-/* Codewarrior on NT has linking problems without this. */
-#if defined(__MWERKS__) && defined(WIN32)
-#define PNG_ALWAYS_EXTERN
-#endif
-
-/* 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 <mem.h>
-#include "alloc.h"
-#endif
-
-#ifdef _MSC_VER
-#include <malloc.h>
-#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.
- */
-#ifndef PNG_DITHER_RED_BITS
-#define PNG_DITHER_RED_BITS 5
-#endif
-#ifndef PNG_DITHER_GREEN_BITS
-#define PNG_DITHER_GREEN_BITS 5
-#endif
-#ifndef PNG_DITHER_BLUE_BITS
-#define PNG_DITHER_BLUE_BITS 5
-#endif
-
-/* 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 set this value
- * less then 8, and even that may not work (I haven't tested it).
- */
-
-#ifndef PNG_MAX_GAMMA_8
-#define PNG_MAX_GAMMA_8 11
-#endif
-
-/* This controls how much a difference in gamma we can tolerate before
- * we actually start doing gamma conversion.
- */
-#ifndef PNG_GAMMA_THRESHOLD
-#define PNG_GAMMA_THRESHOLD 0.05
-#endif
-
-#endif /* PNG_INTERNAL */
-
-/* The following uses const char * instead of char * for error
- * and warning message functions, so some compilers won't complain.
- * If you do not want to use const, define PNG_NO_CONST here.
- */
-
-#ifndef PNG_NO_CONST
-# define PNG_CONST const
-#else
-# define PNG_CONST
-#endif
-
-/* The following defines give you the ability to remove code from the
- * library that you will not be using. I wish I could figure out how to
- * automate this, but I can't do 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. If you are
- * creating or using a shared library, you probably shouldn't touch this,
- * as it will affect the size of the structures, and this will cause bad
- * things to happen if the library and/or application ever change.
- */
-
-/* Any transformations you will not be using can be undef'ed here */
-
-/* GR-P, 0.96a: Set "*TRANSFORMS_SUPPORTED as default but allow user
- to turn it off with "*TRANSFORMS_NOT_SUPPORTED" or *PNG_NO_*_TRANSFORMS
- on the compile line, then pick and choose which ones to define without
- having to edit this file. It is safe to use the *TRANSFORMS_NOT_SUPPORTED
- if you only want to have a png-compliant reader/writer but don't need
- any of the extra transformations. This saves about 80 kbytes in a
- typical installation of the library. (PNG_NO_* form added in version
- 1.0.1c, for consistency)
- */
-
-
-#if !defined(PNG_READ_TRANSFORMS_NOT_SUPPORTED) && \
- !defined(PNG_NO_READ_TRANSFORMS)
-#define PNG_READ_TRANSFORMS_SUPPORTED
-#endif
-#if !defined(PNG_WRITE_TRANSFORMS_NOT_SUPPORTED) && \
- !defined(PNG_NO_WRITE_TRANSFORMS)
-#define PNG_WRITE_TRANSFORMS_SUPPORTED
-#endif
-
-#ifdef PNG_READ_TRANSFORMS_SUPPORTED
-#ifndef PNG_NO_READ_EXPAND
-#define PNG_READ_EXPAND_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_SHIFT
-#define PNG_READ_SHIFT_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_PACK
-#define PNG_READ_PACK_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_BGR
-#define PNG_READ_BGR_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_SWAP
-#define PNG_READ_SWAP_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_PACKSWAP
-#define PNG_READ_PACKSWAP_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_INVERT
-#define PNG_READ_INVERT_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_DITHER
-#define PNG_READ_DITHER_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_BACKGROUND
-#define PNG_READ_BACKGROUND_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_16_TO_8
-#define PNG_READ_16_TO_8_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_FILLER
-#define PNG_READ_FILLER_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_GAMMA
-#define PNG_READ_GAMMA_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_GRAY_TO_RGB
-#define PNG_READ_GRAY_TO_RGB_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_SWAP_ALPHA
-#define PNG_READ_SWAP_ALPHA_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_INVERT_ALPHA
-#define PNG_READ_INVERT_ALPHA_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_STRIP_ALPHA
-#define PNG_READ_STRIP_ALPHA_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_USER_TRANSFORM
-#define PNG_READ_USER_TRANSFORM_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_RGB_TO_GRAY
-#define PNG_READ_RGB_TO_GRAY_SUPPORTED
-#endif
-#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
-
-#if !defined(PNG_NO_PROGRESSIVE_READ) && \
- !defined(PNG_PROGRESSIVE_READ_NOT_SUPPORTED) /* if you don't do progressive */
-#define PNG_PROGRESSIVE_READ_SUPPORTED /* reading. This is not talking */
-#endif /* about interlacing capability! You'll */
- /* still have interlacing unless you change the following line: */
-#define PNG_READ_INTERLACING_SUPPORTED /* required for PNG-compliant decoders */
-
-#ifndef PNG_NO_READ_COMPOSITED_NODIV
-#define PNG_READ_COMPOSITE_NODIV_SUPPORTED /* well tested on Intel and SGI */
-#endif
-
-#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
-#ifndef PNG_NO_WRITE_SHIFT
-#define PNG_WRITE_SHIFT_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_PACK
-#define PNG_WRITE_PACK_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_BGR
-#define PNG_WRITE_BGR_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_SWAP
-#define PNG_WRITE_SWAP_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_PACKSWAP
-#define PNG_WRITE_PACKSWAP_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_INVERT
-#define PNG_WRITE_INVERT_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_FILLER
-#define PNG_WRITE_FILLER_SUPPORTED /* This is the same as WRITE_STRIP_ALPHA */
-#endif
-#ifndef PNG_NO_WRITE_SWAP_ALPHA
-#define PNG_WRITE_SWAP_ALPHA_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_INVERT_ALPHA
-#define PNG_WRITE_INVERT_ALPHA_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_USER_TRANSFORM
-#define PNG_WRITE_USER_TRANSFORM_SUPPORTED
-#endif
-#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */
-
-#define PNG_WRITE_INTERLACING_SUPPORTED /* not required for PNG-compliant
- encoders, but can cause trouble
- if left undefined */
-
-#ifndef PNG_NO_WRITE_WEIGHTED_FILTER
-#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
-#endif
-
-#ifndef PNG_NO_WRITE_FLUSH
-#define PNG_WRITE_FLUSH_SUPPORTED
-#endif
-
-#ifndef PNG_NO_STDIO
-#define PNG_TIME_RFC1123_SUPPORTED
-#endif
-
-/* This adds extra functions in pngget.c for accessing data from the
- * info pointer (added in version 0.99)
- * png_get_image_width()
- * png_get_image_height()
- * png_get_bit_depth()
- * png_get_color_type()
- * png_get_compression_type()
- * png_get_filter_type()
- * png_get_interlace_type()
- * png_get_pixel_aspect_ratio()
- * png_get_pixels_per_meter()
- * png_get_x_offset_pixels()
- * png_get_y_offset_pixels()
- * png_get_x_offset_microns()
- * png_get_y_offset_microns()
- */
-#ifndef PNG_NO_EASY_ACCESS
-#define PNG_EASY_ACCESS_SUPPORTED
-#endif
-
-/* These are currently experimental features, define them if you want */
-
-/* very little testing */
-/*
-#define PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
-#define PNG_USER_MEM_SUPPORTED
-*/
-
-/* This is only for PowerPC big-endian and 680x0 systems */
-/* some testing */
-/*
-#define PNG_READ_BIG_ENDIAN_SUPPORTED
-*/
-
-/* These functions are turned off by default, as they will be phased out. */
-/*
-#define PNG_USELESS_TESTS_SUPPORTED
-#define PNG_CORRECT_PALETTE_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, pCAL). Others will just save time and make png_info
- * a bit smaller.
- */
-
-#if !defined(PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \
- !defined(PNG_NO_READ_ANCILLARY_CHUNKS)
-#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
-#endif
-#if !defined(PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \
- !defined(PNG_NO_WRITE_ANCILLARY_CHUNKS)
-#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
-#endif
-
-#ifdef PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
-#ifndef PNG_NO_READ_bKGD
-#define PNG_READ_bKGD_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_cHRM
-#define PNG_READ_cHRM_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_gAMA
-#define PNG_READ_gAMA_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_hIST
-#define PNG_READ_hIST_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_oFFs
-#define PNG_READ_oFFs_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_pCAL
-#define PNG_READ_pCAL_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_pHYs
-#define PNG_READ_pHYs_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_sBIT
-#define PNG_READ_sBIT_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_sRGB
-#define PNG_READ_sRGB_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_tEXt
-#define PNG_READ_tEXt_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_tIME
-#define PNG_READ_tIME_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_tRNS
-#define PNG_READ_tRNS_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_zTXt
-#define PNG_READ_zTXt_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_OPT_PLTE
-#define PNG_READ_OPT_PLTE_SUPPORTED /* only affects support of the optional */
-#endif /* PLTE chunk in RGB and RGBA images */
-#endif /* PNG_READ_ANCILLARY_CHUNKS_SUPPORTED */
-
-#ifdef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
-#ifndef PNG_NO_WRITE_bKGD
-#define PNG_WRITE_bKGD_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_cHRM
-#define PNG_WRITE_cHRM_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_gAMA
-#define PNG_WRITE_gAMA_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_hIST
-#define PNG_WRITE_hIST_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_oFFs
-#define PNG_WRITE_oFFs_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_pCAL
-#define PNG_WRITE_pCAL_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_pHYs
-#define PNG_WRITE_pHYs_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_sBIT
-#define PNG_WRITE_sBIT_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_sRGB
-#define PNG_WRITE_sRGB_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_tEXt
-#define PNG_WRITE_tEXt_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_tIME
-#define PNG_WRITE_tIME_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_tRNS
-#define PNG_WRITE_tRNS_SUPPORTED
-#endif
-#ifndef PNG_NO_WRITE_zTXt
-#define PNG_WRITE_zTXt_SUPPORTED
-#endif
-#endif /* PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED */
-
-/* need the time information for reading tIME chunks */
-#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED)
-#include <time.h>
-#endif
-
-/* 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. Some compilers dislike passing
- * unsigned shorts as function parameters, so you may be better off using
- * unsigned int for png_uint_16. Likewise, for 64-bit systems, you may
- * want to have unsigned int for png_uint_32 instead of unsigned long.
- */
-
-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 and pointers to be
- * large using the far keyword. The zlib version used must also support
- * model independent data. As of version zlib 1.0.4, the necessary changes
- * have been made in zlib. The USE_FAR_KEYWORD define triggers other
- * changes that are needed. (Tim Wegner)
- */
-
-/* Separate compiler dependencies (problem here is that zlib.h always
- defines FAR. (SJT) */
-#ifdef __BORLANDC__
-#if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
-#define LDATA 1
-#else
-#define LDATA 0
-#endif
-
-#if !defined(__WIN32__) && !defined(__FLAT__)
-#define PNG_MAX_MALLOC_64K
-#if (LDATA != 1)
-#ifndef FAR
-#define FAR __far
-#endif
-#define USE_FAR_KEYWORD
-#endif /* LDATA != 1 */
-
-/* Possibly useful for moving data out of default segment.
- * Uncomment it if you want. Could also define FARDATA as
- * const if your compiler supports it. (SJT)
-# define FARDATA FAR
- */
-#endif /* __WIN32__, __FLAT__ */
-
-#endif /* __BORLANDC__ */
-
-
-/* Suggest testing for specific compiler first before testing for
- * FAR. The Watcom compiler defines both __MEDIUM__ and M_I86MM,
- * making reliance oncertain keywords suspect. (SJT)
- */
-
-/* MSC Medium model */
-#if defined(FAR)
-# if defined(M_I86MM)
-# define USE_FAR_KEYWORD
-# define FARDATA FAR
-# include <dos.h>
-# endif
-#endif
-
-/* SJT: default case */
-#ifndef FAR
-# define FAR
-#endif
-
-/* At this point FAR is always defined */
-#ifndef FARDATA
-#define FARDATA
-#endif
-
-/* Add typedefs for pointers */
-typedef void FAR * png_voidp;
-typedef png_byte FAR * png_bytep;
-typedef png_uint_32 FAR * png_uint_32p;
-typedef png_int_32 FAR * png_int_32p;
-typedef png_uint_16 FAR * png_uint_16p;
-typedef png_int_16 FAR * png_int_16p;
-typedef PNG_CONST char FAR * png_const_charp;
-typedef char FAR * png_charp;
-typedef double FAR * png_doublep;
-
-/* Pointers to pointers; i.e. arrays */
-typedef png_byte FAR * FAR * png_bytepp;
-typedef png_uint_32 FAR * FAR * png_uint_32pp;
-typedef png_int_32 FAR * FAR * png_int_32pp;
-typedef png_uint_16 FAR * FAR * png_uint_16pp;
-typedef png_int_16 FAR * FAR * png_int_16pp;
-typedef PNG_CONST char FAR * FAR * png_const_charpp;
-typedef char FAR * FAR * png_charpp;
-typedef double FAR * FAR * png_doublepp;
-
-/* Pointers to pointers to pointers; i.e. pointer to array */
-typedef char FAR * FAR * FAR * png_charppp;
-
-/* libpng typedefs for types in zlib. If zlib changes
- * or another compression library is used, then change these.
- * Eliminates need to change all the source files.
- */
-typedef charf * png_zcharp;
-typedef charf * FAR * png_zcharpp;
-typedef z_stream FAR * png_zstreamp;
-
-/* allow for compilation as dll under MS Windows */
-#ifdef __WIN32DLL__
-#define PNG_EXPORT(type,symbol) __declspec(dllexport) type symbol
-#endif
-
-/* allow for compilation as dll with BORLAND C++ 5.0 */
-#if defined(__BORLANDC__) && defined(_Windows) && defined(__DLL__)
-# define PNG_EXPORT(type,symbol) type _export symbol
-#endif
-
-/* allow for compilation as shared lib under BeOS */
-#ifdef __BEOSDLL__
-#define PNG_EXPORT(type,symbol) __declspec(export) type symbol
-#endif
-
-#ifndef PNG_EXPORT
-#define PNG_EXPORT(type,symbol) type symbol
-#endif
-
-
-/* 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 */
-/* use this to make far-to-near assignments */
-# define CHECK 1
-# define NOCHECK 0
-# define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK))
-# define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK))
-# define png_strcpy _fstrcpy
-# define png_strlen _fstrlen
-# define png_memcmp _fmemcmp /* SJT: added */
-# define png_memcpy _fmemcpy
-# define png_memset _fmemset
-#else /* use the usual functions */
-# define CVT_PTR(ptr) (ptr)
-# define CVT_PTR_NOCHECK(ptr) (ptr)
-# define png_strcpy strcpy
-# define png_strlen strlen
-# define png_memcmp memcmp /* SJT: added */
-# define png_memcpy memcpy
-# define png_memset memset
-#endif
-/* End of memory model independent support */
-
-/* Just a double check that someone hasn't tried to define something
- * contradictory.
- */
-#if (PNG_ZBUF_SIZE > 65536) && defined(PNG_MAX_MALLOC_64K)
-#undef PNG_ZBUF_SIZE
-#define PNG_ZBUF_SIZE 65536
-#endif
-
-#endif /* PNGCONF_H */
-
+++ /dev/null
-
-/* pngerror.c - stub functions for i/o and memory allocation
- *
- * libpng 1.0.3 - January 14, 1999
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
- *
- * This file provides a location for all error handling. Users who
- * need special error handling are expected to write replacement functions
- * and use png_set_error_fn() to use those functions. See the instructions
- * at each function.
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-
-static void png_default_error PNGARG((png_structp png_ptr,
- png_const_charp message));
-static void png_default_warning PNGARG((png_structp png_ptr,
- png_const_charp message));
-
-/* This function is called whenever there is a fatal error. This function
- * should not be changed. If there is a need to handle errors differently,
- * you should supply a replacement error function and use png_set_error_fn()
- * to replace the error function at run-time.
- */
-void
-png_error(png_structp png_ptr, png_const_charp message)
-{
- if (png_ptr->error_fn != NULL)
- (*(png_ptr->error_fn))(png_ptr, message);
-
- /* if the following returns or doesn't exist, use the default function,
- which will not return */
- png_default_error(png_ptr, message);
-}
-
-/* This function is called whenever there is a non-fatal error. This function
- * should not be changed. If there is a need to handle warnings differently,
- * you should supply a replacement warning function and use
- * png_set_error_fn() to replace the warning function at run-time.
- */
-void
-png_warning(png_structp png_ptr, png_const_charp message)
-{
- if (png_ptr->warning_fn != NULL)
- (*(png_ptr->warning_fn))(png_ptr, message);
- else
- png_default_warning(png_ptr, message);
-}
-
-/* These utilities are used internally to build an error message that relates
- * to the current chunk. The chunk name comes from png_ptr->chunk_name,
- * this is used to prefix the message. The message is limited in length
- * to 63 bytes, the name characters are output as hex digits wrapped in []
- * if the character is invalid.
- */
-#define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97))
-static PNG_CONST char png_digit[16] = {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
-};
-
-static void
-png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp message)
-{
- int iout = 0, iin = 0;
-
- while (iin < 4) {
- int c = png_ptr->chunk_name[iin++];
- if (isnonalpha(c)) {
- buffer[iout++] = '[';
- buffer[iout++] = png_digit[(c & 0xf0) >> 4];
- buffer[iout++] = png_digit[c & 0xf];
- buffer[iout++] = ']';
- } else {
- buffer[iout++] = c;
- }
- }
-
- if (message == NULL)
- buffer[iout] = 0;
- else {
- buffer[iout++] = ':';
- buffer[iout++] = ' ';
- png_memcpy(buffer+iout, message, 64);
- buffer[iout+63] = 0;
- }
-}
-
-void
-png_chunk_error(png_structp png_ptr, png_const_charp message)
-{
- char msg[16+64];
- png_format_buffer(png_ptr, msg, message);
- png_error(png_ptr, msg);
-}
-
-void
-png_chunk_warning(png_structp png_ptr, png_const_charp message)
-{
- char msg[16+64];
- png_format_buffer(png_ptr, msg, message);
- png_warning(png_ptr, msg);
-}
-
-/* This is the default error handling function. Note that replacements for
- * this function MUST NOT RETURN, or the program will likely crash. This
- * function is used by default, or if the program supplies NULL for the
- * error function pointer in png_set_error_fn().
- */
-static void
-png_default_error(png_structp png_ptr, png_const_charp message)
-{
-#ifndef PNG_NO_CONSOLE_IO
- fprintf(stderr, "libpng error: %s\n", message);
-#endif
-
-#ifdef USE_FAR_KEYWORD
- {
- jmp_buf jmpbuf;
- png_memcpy(jmpbuf,png_ptr->jmpbuf,sizeof(jmp_buf));
- longjmp(jmpbuf, 1);
- }
-#else
- longjmp(png_ptr->jmpbuf, 1);
-#endif
-}
-
-/* This function is called when there is a warning, but the library thinks
- * it can continue anyway. Replacement functions don't have to do anything
- * here if you don't want them to. In the default configuration, png_ptr is
- * not used, but it is passed in case it may be useful.
- */
-static void
-png_default_warning(png_structp png_ptr, png_const_charp message)
-{
-#ifndef PNG_NO_CONSOLE_IO
- fprintf(stderr, "libpng warning: %s\n", message);
-#endif
- if (png_ptr == NULL)
- return;
-}
-
-/* This function is called when the application wants to use another method
- * of handling errors and warnings. Note that the error function MUST NOT
- * return to the calling routine or serious problems will occur. The return
- * method used in the default routine calls longjmp(png_ptr->jmpbuf, 1)
- */
-void
-png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warning_fn)
-{
- png_ptr->error_ptr = error_ptr;
- png_ptr->error_fn = error_fn;
- png_ptr->warning_fn = warning_fn;
-}
-
-
-/* This function returns a pointer to the error_ptr associated with the user
- * functions. The application should free any memory associated with this
- * pointer before png_write_destroy and png_read_destroy are called.
- */
-png_voidp
-png_get_error_ptr(png_structp png_ptr)
-{
- return ((png_voidp)png_ptr->error_ptr);
-}
-
-
-
+++ /dev/null
-
-/* pngget.c - retrieval of values from info struct
- *
- * libpng 1.0.3 - January 14, 1999
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-
-png_uint_32
-png_get_valid(png_structp png_ptr, png_infop info_ptr, png_uint_32 flag)
-{
- if (png_ptr != NULL && info_ptr != NULL)
- return(info_ptr->valid & flag);
- else
- return(0);
-}
-
-png_uint_32
-png_get_rowbytes(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
- return(info_ptr->rowbytes);
- else
- return(0);
-}
-
-#ifdef PNG_EASY_ACCESS_SUPPORTED
-/* easy access to info, added in libpng-0.99 */
-png_uint_32
-png_get_image_width(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
- {
- return info_ptr->width;
- }
- return (0);
-}
-
-png_uint_32
-png_get_image_height(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
- {
- return info_ptr->height;
- }
- return (0);
-}
-
-png_byte
-png_get_bit_depth(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
- {
- return info_ptr->bit_depth;
- }
- return (0);
-}
-
-png_byte
-png_get_color_type(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
- {
- return info_ptr->color_type;
- }
- return (0);
-}
-
-png_byte
-png_get_filter_type(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
- {
- return info_ptr->filter_type;
- }
- return (0);
-}
-
-png_byte
-png_get_interlace_type(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
- {
- return info_ptr->interlace_type;
- }
- return (0);
-}
-
-png_byte
-png_get_compression_type(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
- {
- return info_ptr->compression_type;
- }
- return (0);
-}
-
-png_uint_32
-png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
-{
-#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_x_pixels_per_meter");
- if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
- return (0);
- else return (info_ptr->x_pixels_per_unit);
- }
- else
-#endif
- return (0);
-}
-
-png_uint_32
-png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
-{
-#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_y_pixels_per_meter");
- if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
- return (0);
- else return (info_ptr->y_pixels_per_unit);
- }
- else
-#endif
- return (0);
-}
-
-png_uint_32
-png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
-{
-#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_pixels_per_meter");
- if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER ||
- info_ptr->x_pixels_per_unit != info_ptr->y_pixels_per_unit)
- return (0);
- else return (info_ptr->x_pixels_per_unit);
- }
- else
-#endif
- return (0);
-}
-
-float
-png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr)
- {
-#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_aspect_ratio");
- if (info_ptr->x_pixels_per_unit == 0)
- return ((float)0.0);
- else
- return ((float)info_ptr->y_pixels_per_unit
- /(float)info_ptr->x_pixels_per_unit);
- }
- else
-#endif
- return ((float)0.0);
-}
-
-png_uint_32
-png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr)
-{
-#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
- if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
- return (0);
- else return (info_ptr->x_offset);
- }
- else
-#endif
- return (0);
-}
-
-png_uint_32
-png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr)
-{
-#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
- if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
- return (0);
- else return (info_ptr->y_offset);
- }
- else
-#endif
- return (0);
-}
-
-png_uint_32
-png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr)
-{
-#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
- if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
- return (0);
- else return (info_ptr->x_offset);
- }
- else
-#endif
- return (0);
-}
-
-png_uint_32
-png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr)
-{
-#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
- if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
- return (0);
- else return (info_ptr->y_offset);
- }
- else
-#endif
- return (0);
-}
-
-#ifdef PNG_INCH_CONVERSIONS
-png_uint_32
-png_get_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
-{
- return ((png_uint_32)((float)png_get_pixels_per_meter(png_ptr, info_ptr)
- *.03937 +.5)
-}
-
-png_uint_32
-png_get_x_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
-{
- return ((png_uint_32)((float)png_get_x_pixels_per_meter(png_ptr, info_ptr)
- *.03937 +.5)
-}
-
-png_uint_32
-png_get_y_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
-{
- return ((png_uint_32)((float)png_get_y_pixels_per_meter(png_ptr, info_ptr)
- *.03937 +.5)
-}
-
-float
-png_get_x_offset_inches(png_structp png_ptr, png_infop info_ptr)
-{
- return ((float)png_get_x_offset_microns(png_ptr, info_ptr)
- *.03937/1000000. +.5)
-}
-
-float
-png_get_y_offset_inches(png_structp png_ptr, png_infop info_ptr)
-{
- return ((float)png_get_y_offset_microns(png_ptr, info_ptr)
- *.03937/1000000. +.5)
-}
-
-#if defined(PNG_READ_pHYs_SUPPORTED)
-png_uint_32
-png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr,
- png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
-{
- png_uint_32 retval = 0;
-
- if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_pHYs)
- {
- png_debug1(1, "in %s retrieval function\n", "pHYs");
- if (res_x != NULL)
- {
- *res_x = info_ptr->x_pixels_per_unit;
- retval |= PNG_INFO_pHYs;
- }
- if (res_y != NULL)
- {
- *res_y = info_ptr->y_pixels_per_unit;
- retval |= PNG_INFO_pHYs;
- }
- if (unit_type != NULL)
- {
- *unit_type = (int)info_ptr->phys_unit_type;
- retval |= PNG_INFO_pHYs;
- if(unit_type == 1)
- {
- if (res_x != NULL) *res_x = (png_uint_32)(*res_x * 39.37 + .50);
- if (res_y != NULL) *res_y = (png_uint_32)(*res_y * 39.37 + .50);
- }
- }
- }
- return (retval);
-}
-#endif /* PNG_READ_pHYs_SUPPORTED */
-#endif /* PNG_INCH_CONVERSIONS */
-
-/* png_get_channels really belongs in here, too, but it's been around longer */
-
-#endif /* PNG_EASY_ACCESS_SUPPORTED */
-
-png_byte
-png_get_channels(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
- return(info_ptr->channels);
- else
- return (0);
-}
-
-png_bytep
-png_get_signature(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
- return(info_ptr->signature);
- else
- return (NULL);
-}
-
-#if defined(PNG_READ_bKGD_SUPPORTED)
-png_uint_32
-png_get_bKGD(png_structp png_ptr, png_infop info_ptr,
- png_color_16p *background)
-{
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)
- && background != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "bKGD");
- *background = &(info_ptr->background);
- return (PNG_INFO_bKGD);
- }
- return (0);
-}
-#endif
-
-#if defined(PNG_READ_cHRM_SUPPORTED)
-png_uint_32
-png_get_cHRM(png_structp png_ptr, png_infop info_ptr,
- double *white_x, double *white_y, double *red_x, double *red_y,
- double *green_x, double *green_y, double *blue_x, double *blue_y)
-{
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
- {
- png_debug1(1, "in %s retrieval function\n", "cHRM");
- if (white_x != NULL)
- *white_x = (double)info_ptr->x_white;
- if (white_y != NULL)
- *white_y = (double)info_ptr->y_white;
- if (red_x != NULL)
- *red_x = (double)info_ptr->x_red;
- if (red_y != NULL)
- *red_y = (double)info_ptr->y_red;
- if (green_x != NULL)
- *green_x = (double)info_ptr->x_green;
- if (green_y != NULL)
- *green_y = (double)info_ptr->y_green;
- if (blue_x != NULL)
- *blue_x = (double)info_ptr->x_blue;
- if (blue_y != NULL)
- *blue_y = (double)info_ptr->y_blue;
- return (PNG_INFO_cHRM);
- }
- return (0);
-}
-#endif
-
-#if defined(PNG_READ_gAMA_SUPPORTED)
-png_uint_32
-png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma)
-{
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
- && file_gamma != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "gAMA");
- *file_gamma = (double)info_ptr->gamma;
- return (PNG_INFO_gAMA);
- }
- return (0);
-}
-#endif
-
-#if defined(PNG_READ_sRGB_SUPPORTED)
-png_uint_32
-png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent)
-{
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)
- && file_srgb_intent != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "sRGB");
- *file_srgb_intent = (int)info_ptr->srgb_intent;
- return (PNG_INFO_sRGB);
- }
- return (0);
-}
-#endif
-
-#if defined(PNG_READ_hIST_SUPPORTED)
-png_uint_32
-png_get_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist)
-{
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)
- && hist != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "hIST");
- *hist = info_ptr->hist;
- return (PNG_INFO_hIST);
- }
- return (0);
-}
-#endif
-
-png_uint_32
-png_get_IHDR(png_structp png_ptr, png_infop info_ptr,
- png_uint_32 *width, png_uint_32 *height, int *bit_depth,
- int *color_type, int *interlace_type, int *compression_type,
- int *filter_type)
-
-{
- if (png_ptr != NULL && info_ptr != NULL && width != NULL && height != NULL &&
- bit_depth != NULL && color_type != NULL)
- {
- int pixel_depth, channels;
- png_uint_32 rowbytes_per_pixel;
-
- png_debug1(1, "in %s retrieval function\n", "IHDR");
- *width = info_ptr->width;
- *height = info_ptr->height;
- *bit_depth = info_ptr->bit_depth;
- *color_type = info_ptr->color_type;
- if (compression_type != NULL)
- *compression_type = info_ptr->compression_type;
- if (filter_type != NULL)
- *filter_type = info_ptr->filter_type;
- if (interlace_type != NULL)
- *interlace_type = info_ptr->interlace_type;
-
- /* check for potential overflow of rowbytes */
- if (*color_type == PNG_COLOR_TYPE_PALETTE)
- channels = 1;
- else if (*color_type & PNG_COLOR_MASK_COLOR)
- channels = 3;
- else
- channels = 1;
- if (*color_type & PNG_COLOR_MASK_ALPHA)
- channels++;
- pixel_depth = *bit_depth * channels;
- rowbytes_per_pixel = (pixel_depth + 7) >> 3;
- if ((*width > (png_uint_32)2147483647L/rowbytes_per_pixel))
- {
- png_warning(png_ptr,
- "Width too large for libpng to process image data.");
- }
- return (1);
- }
- return (0);
-}
-
-#if defined(PNG_READ_oFFs_SUPPORTED)
-png_uint_32
-png_get_oFFs(png_structp png_ptr, png_infop info_ptr,
- png_uint_32 *offset_x, png_uint_32 *offset_y, int *unit_type)
-{
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)
- && offset_x != NULL && offset_y != NULL && unit_type != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "oFFs");
- *offset_x = info_ptr->x_offset;
- *offset_y = info_ptr->y_offset;
- *unit_type = (int)info_ptr->offset_unit_type;
- return (PNG_INFO_oFFs);
- }
- return (0);
-}
-#endif
-
-#if defined(PNG_READ_pCAL_SUPPORTED)
-png_uint_32
-png_get_pCAL(png_structp png_ptr, png_infop info_ptr,
- png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
- png_charp *units, png_charpp *params)
-{
- if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_pCAL &&
- purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
- nparams != NULL && units != NULL && params != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "pCAL");
- *purpose = info_ptr->pcal_purpose;
- *X0 = info_ptr->pcal_X0;
- *X1 = info_ptr->pcal_X1;
- *type = (int)info_ptr->pcal_type;
- *nparams = (int)info_ptr->pcal_nparams;
- *units = info_ptr->pcal_units;
- *params = info_ptr->pcal_params;
- return (PNG_INFO_pCAL);
- }
- return (0);
-}
-#endif
-
-#if defined(PNG_READ_pHYs_SUPPORTED)
-png_uint_32
-png_get_pHYs(png_structp png_ptr, png_infop info_ptr,
- png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
-{
- png_uint_32 retval = 0;
-
- if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_pHYs)
- {
- png_debug1(1, "in %s retrieval function\n", "pHYs");
- if (res_x != NULL)
- {
- *res_x = info_ptr->x_pixels_per_unit;
- retval |= PNG_INFO_pHYs;
- }
- if (res_y != NULL)
- {
- *res_y = info_ptr->y_pixels_per_unit;
- retval |= PNG_INFO_pHYs;
- }
- if (unit_type != NULL)
- {
- *unit_type = (int)info_ptr->phys_unit_type;
- retval |= PNG_INFO_pHYs;
- }
- }
- return (retval);
-}
-#endif
-
-png_uint_32
-png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette,
- int *num_palette)
-{
- if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_PLTE &&
- palette != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "PLTE");
- *palette = info_ptr->palette;
- *num_palette = info_ptr->num_palette;
- png_debug1(3, "num_palette = %d\n", *num_palette);
- return (PNG_INFO_PLTE);
- }
- return (0);
-}
-
-#if defined(PNG_READ_sBIT_SUPPORTED)
-png_uint_32
-png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit)
-{
- if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_sBIT &&
- sig_bit != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "sBIT");
- *sig_bit = &(info_ptr->sig_bit);
- return (PNG_INFO_sBIT);
- }
- return (0);
-}
-#endif
-
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
-png_uint_32
-png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr,
- int *num_text)
-{
- if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
- {
- png_debug1(1, "in %s retrieval function\n",
- (png_ptr->chunk_name[0] == '\0' ? "text"
- : (png_const_charp)png_ptr->chunk_name));
- if (text_ptr != NULL)
- *text_ptr = info_ptr->text;
- if (num_text != NULL)
- *num_text = info_ptr->num_text;
- return ((png_uint_32)info_ptr->num_text);
- }
- return(0);
-}
-#endif
-
-#if defined(PNG_READ_tIME_SUPPORTED)
-png_uint_32
-png_get_tIME(png_structp png_ptr, png_infop info_ptr, png_timep *mod_time)
-{
- if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_tIME &&
- mod_time != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "tIME");
- *mod_time = &(info_ptr->mod_time);
- return (PNG_INFO_tIME);
- }
- return (0);
-}
-#endif
-
-#if defined(PNG_READ_tRNS_SUPPORTED)
-png_uint_32
-png_get_tRNS(png_structp png_ptr, png_infop info_ptr,
- png_bytep *trans, int *num_trans, png_color_16p *trans_values)
-{
- png_uint_32 retval = 0;
- if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_tRNS)
- {
- png_debug1(1, "in %s retrieval function\n", "tRNS");
- if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (trans != NULL)
- {
- *trans = info_ptr->trans;
- retval |= PNG_INFO_tRNS;
- }
- if (trans_values != NULL)
- *trans_values = &(info_ptr->trans_values);
- }
- else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
- {
- if (trans_values != NULL)
- {
- *trans_values = &(info_ptr->trans_values);
- retval |= PNG_INFO_tRNS;
- }
- if(trans != NULL)
- *trans = NULL;
- }
- if(num_trans != NULL)
- {
- *num_trans = info_ptr->num_trans;
- retval |= PNG_INFO_tRNS;
- }
- }
- return (retval);
-}
-#endif
-
-#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-png_byte
-png_get_rgb_to_gray_status (png_structp png_ptr)
-{
- return png_ptr->rgb_to_gray_status;
-}
-#endif
+++ /dev/null
-
-/* pngmem.c - stub functions for memory allocation
- *
- * libpng 1.0.3 - January 14, 1999
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
- *
- * This file provides a location for all memory allocation. Users who
- * need special memory handling are expected to supply replacement
- * functions for png_malloc() and png_free(), and to use
- * png_create_read_struct_2() and png_create_write_struct_2() to
- * identify the replacement functions.
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-
-/* Borland DOS special memory handler */
-#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
-/* if you change this, be sure to change the one in png.h also */
-
-/* Allocate memory for a png_struct. The malloc and memset can be replaced
- by a single call to calloc() if this is thought to improve performance. */
-png_voidp
-png_create_struct(int type)
-{
-#ifdef PNG_USER_MEM_SUPPORTED
- return (png_create_struct_2(type, NULL));
-}
-
-/* Alternate version of png_create_struct, for use with user-defined malloc. */
-png_voidp
-png_create_struct_2(int type, png_malloc_ptr malloc_fn)
-{
-#endif /* PNG_USER_MEM_SUPPORTED */
- png_size_t size;
- png_voidp struct_ptr;
-
- if (type == PNG_STRUCT_INFO)
- size = sizeof(png_info);
- else if (type == PNG_STRUCT_PNG)
- size = sizeof(png_struct);
- else
- return ((png_voidp)NULL);
-
-#ifdef PNG_USER_MEM_SUPPORTED
- if(malloc_fn != NULL)
- {
- if ((struct_ptr = (*(malloc_fn))(NULL, size)) != NULL)
- png_memset(struct_ptr, 0, size);
- return (struct_ptr);
- }
-#endif /* PNG_USER_MEM_SUPPORTED */
- if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
- {
- png_memset(struct_ptr, 0, size);
- }
- return (struct_ptr);
-}
-
-
-/* Free memory allocated by a png_create_struct() call */
-void
-png_destroy_struct(png_voidp struct_ptr)
-{
-#ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2(struct_ptr, (png_free_ptr)NULL);
-}
-
-/* Free memory allocated by a png_create_struct() call */
-void
-png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn)
-{
-#endif
- if (struct_ptr != NULL)
- {
-#ifdef PNG_USER_MEM_SUPPORTED
- if(free_fn != NULL)
- {
- png_struct dummy_struct;
- png_structp png_ptr = &dummy_struct;
- (*(free_fn))(png_ptr, struct_ptr);
- struct_ptr = NULL;
- return;
- }
-#endif /* PNG_USER_MEM_SUPPORTED */
- farfree (struct_ptr);
- struct_ptr = NULL;
- }
-}
-
-/* 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
- * need to allocate exactly 64K, so whatever you call here must
- * have the ability to do that.
- *
- * Borland seems to have a problem in DOS mode for exactly 64K.
- * It gives you a segment with an offset of 8 (perhaps to store its
- * memory stuff). zlib doesn't like this at all, so we have to
- * detect and deal with it. This code should not be needed in
- * Windows or OS/2 modes, and only in 16 bit mode. This code has
- * been updated by Alexander Lehmann for version 0.89 to waste less
- * memory.
- *
- * Note that we can't use png_size_t for the "size" declaration,
- * since on some systems a png_size_t is a 16-bit quantity, and as a
- * result, we would be truncating potentially larger memory requests
- * (which should cause a fatal error) and introducing major problems.
- */
-png_voidp
-png_malloc(png_structp png_ptr, png_uint_32 size)
-{
-#ifndef PNG_USER_MEM_SUPPORTED
- png_voidp ret;
-#endif
- if (png_ptr == NULL || size == 0)
- return ((png_voidp)NULL);
-
-#ifdef PNG_USER_MEM_SUPPORTED
- if(png_ptr->malloc_fn != NULL)
- return ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, size));
- else
- return png_malloc_default(png_ptr, size);
-}
-
-png_voidp
-png_malloc_default(png_structp png_ptr, png_uint_32 size)
-{
- png_voidp ret;
-#endif /* PNG_USER_MEM_SUPPORTED */
-
-#ifdef PNG_MAX_MALLOC_64K
- if (size > (png_uint_32)65536L)
- png_error(png_ptr, "Cannot Allocate > 64K");
-#endif
-
- if (size == (png_uint_32)65536L)
- {
- if (png_ptr->offset_table == NULL)
- {
- /* try to see if we need to do any of this fancy stuff */
- ret = farmalloc(size);
- if (ret == NULL || ((png_size_t)ret & 0xffff))
- {
- int num_blocks;
- png_uint_32 total_size;
- png_bytep table;
- int i;
- png_byte huge * hptr;
-
- if (ret != NULL)
- {
- farfree(ret);
- ret = NULL;
- }
-
- num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
- if (num_blocks < 1)
- num_blocks = 1;
- if (png_ptr->zlib_mem_level >= 7)
- num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
- else
- num_blocks++;
-
- total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
-
- table = farmalloc(total_size);
-
- if (table == NULL)
- {
- png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
- }
-
- if ((png_size_t)table & 0xfff0)
- {
- png_error(png_ptr, "Farmalloc didn't return normalized pointer");
- }
-
- png_ptr->offset_table = table;
- png_ptr->offset_table_ptr = farmalloc(num_blocks *
- sizeof (png_bytep));
-
- if (png_ptr->offset_table_ptr == NULL)
- {
- png_error(png_ptr, "Out Of memory.");
- }
-
- hptr = (png_byte huge *)table;
- if ((png_size_t)hptr & 0xf)
- {
- hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
- hptr += 16L;
- }
- for (i = 0; i < num_blocks; i++)
- {
- png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
- hptr += (png_uint_32)65536L;
- }
-
- png_ptr->offset_table_number = num_blocks;
- png_ptr->offset_table_count = 0;
- png_ptr->offset_table_count_free = 0;
- }
- }
-
- if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
- png_error(png_ptr, "Out of Memory.");
-
- ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
- }
- else
- ret = farmalloc(size);
-
- if (ret == NULL)
- {
- png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
- }
-
- return (ret);
-}
-
-/* free a pointer allocated by png_malloc(). In the default
- 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_free(png_structp png_ptr, png_voidp ptr)
-{
- if (png_ptr == NULL || ptr == NULL)
- return;
-
-#ifdef PNG_USER_MEM_SUPPORTED
- if (png_ptr->free_fn != NULL)
- {
- (*(png_ptr->free_fn))(png_ptr, ptr);
- ptr = NULL;
- return;
- }
- else png_free_default(png_ptr, ptr);
-}
-
-void
-png_free_default(png_structp png_ptr, png_voidp ptr)
-{
-#endif /* PNG_USER_MEM_SUPPORTED */
-
- if (png_ptr->offset_table != NULL)
- {
- int i;
-
- for (i = 0; i < png_ptr->offset_table_count; i++)
- {
- if (ptr == png_ptr->offset_table_ptr[i])
- {
- ptr = NULL;
- png_ptr->offset_table_count_free++;
- break;
- }
- }
- if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
- {
- farfree(png_ptr->offset_table);
- farfree(png_ptr->offset_table_ptr);
- png_ptr->offset_table = NULL;
- png_ptr->offset_table_ptr = NULL;
- }
- }
-
- if (ptr != NULL)
- {
- farfree(ptr);
- ptr = NULL;
- }
-}
-
-#else /* Not the Borland DOS special memory handler */
-
-/* Allocate memory for a png_struct or a png_info. The malloc and
- memset can be replaced by a single call to calloc() if this is thought
- to improve performance noticably.*/
-png_voidp
-png_create_struct(int type)
-{
-#ifdef PNG_USER_MEM_SUPPORTED
- return (png_create_struct_2(type, NULL));
-}
-
-/* Allocate memory for a png_struct or a png_info. The malloc and
- memset can be replaced by a single call to calloc() if this is thought
- to improve performance noticably.*/
-png_voidp
-png_create_struct_2(int type, png_malloc_ptr malloc_fn)
-{
-#endif /* PNG_USER_MEM_SUPPORTED */
- png_size_t size;
- png_voidp struct_ptr;
-
- if (type == PNG_STRUCT_INFO)
- size = sizeof(png_info);
- else if (type == PNG_STRUCT_PNG)
- size = sizeof(png_struct);
- else
- return ((png_voidp)NULL);
-
-#ifdef PNG_USER_MEM_SUPPORTED
- if(malloc_fn != NULL)
- {
- if ((struct_ptr = (*(malloc_fn))(NULL, size)) != NULL)
- png_memset(struct_ptr, 0, size);
- return (struct_ptr);
- }
-#endif /* PNG_USER_MEM_SUPPORTED */
-
-#if defined(__TURBOC__) && !defined(__FLAT__)
- if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
-#else
-# if defined(_MSC_VER) && defined(MAXSEG_64K)
- if ((struct_ptr = (png_voidp)halloc(size,1)) != NULL)
-# else
- if ((struct_ptr = (png_voidp)malloc(size)) != NULL)
-# endif
-#endif
- {
- png_memset(struct_ptr, 0, size);
- }
-
- return (struct_ptr);
-}
-
-
-/* Free memory allocated by a png_create_struct() call */
-void
-png_destroy_struct(png_voidp struct_ptr)
-{
-#ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2(struct_ptr, (png_free_ptr)NULL);
-}
-
-/* Free memory allocated by a png_create_struct() call */
-void
-png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn)
-{
-#endif /* PNG_USER_MEM_SUPPORTED */
- if (struct_ptr != NULL)
- {
-#ifdef PNG_USER_MEM_SUPPORTED
- if(free_fn != NULL)
- {
- png_struct dummy_struct;
- png_structp png_ptr = &dummy_struct;
- (*(free_fn))(png_ptr, struct_ptr);
- struct_ptr = NULL;
- return;
- }
-#endif /* PNG_USER_MEM_SUPPORTED */
-#if defined(__TURBOC__) && !defined(__FLAT__)
- farfree(struct_ptr);
- struct_ptr = NULL;
-#else
-# if defined(_MSC_VER) && defined(MAXSEG_64K)
- hfree(struct_ptr);
- struct_ptr = NULL;
-# else
- free(struct_ptr);
- struct_ptr = NULL;
-# endif
-#endif
- }
-}
-
-
-/* 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
- need to allocate exactly 64K, so whatever you call here must
- have the ability to do that. */
-
-png_voidp
-png_malloc(png_structp png_ptr, png_uint_32 size)
-{
-#ifndef PNG_USER_MEM_SUPPORTED
- png_voidp ret;
-#endif
- if (png_ptr == NULL || size == 0)
- return ((png_voidp)NULL);
-
-#ifdef PNG_USER_MEM_SUPPORTED
- if(png_ptr->malloc_fn != NULL)
- return ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, size));
- else
- return (png_malloc_default(png_ptr, size));
-}
-png_voidp
-png_malloc_default(png_structp png_ptr, png_uint_32 size)
-{
- png_voidp ret;
-#endif /* PNG_USER_MEM_SUPPORTED */
-
-#ifdef PNG_MAX_MALLOC_64K
- if (size > (png_uint_32)65536L)
- png_error(png_ptr, "Cannot Allocate > 64K");
-#endif
-
-#if defined(__TURBOC__) && !defined(__FLAT__)
- ret = farmalloc(size);
-#else
-# if defined(_MSC_VER) && defined(MAXSEG_64K)
- ret = halloc(size, 1);
-# else
- ret = malloc((size_t)size);
-# endif
-#endif
-
- if (ret == NULL)
- {
- png_error(png_ptr, "Out of Memory");
- }
-
- return (ret);
-}
-
-/* Free a pointer allocated by png_malloc(). If ptr is NULL, return
- without taking any action. */
-void
-png_free(png_structp png_ptr, png_voidp ptr)
-{
- if (png_ptr == NULL || ptr == NULL)
- return;
-
-#ifdef PNG_USER_MEM_SUPPORTED
- if (png_ptr->free_fn != NULL)
- {
- (*(png_ptr->free_fn))(png_ptr, ptr);
- ptr = NULL;
- return;
- }
- else png_free_default(png_ptr, ptr);
-}
-void
-png_free_default(png_structp png_ptr, png_voidp ptr)
-{
-#endif /* PNG_USER_MEM_SUPPORTED */
-
-#if defined(__TURBOC__) && !defined(__FLAT__)
- farfree(ptr);
- ptr = NULL;
-#else
-# if defined(_MSC_VER) && defined(MAXSEG_64K)
- hfree(ptr);
- ptr = NULL;
-# else
- free(ptr);
- ptr = NULL;
-# endif
-#endif
-}
-
-#endif /* Not Borland DOS special memory handler */
-
-png_voidp
-png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
- png_uint_32 length)
-{
- png_size_t size;
-
- size = (png_size_t)length;
- if ((png_uint_32)size != length)
- png_error(png_ptr,"Overflow in png_memcpy_check.");
-
- return(png_memcpy (s1, s2, size));
-}
-
-png_voidp
-png_memset_check (png_structp png_ptr, png_voidp s1, int value,
- png_uint_32 length)
-{
- png_size_t size;
-
- size = (png_size_t)length;
- if ((png_uint_32)size != length)
- png_error(png_ptr,"Overflow in png_memset_check.");
-
- return (png_memset (s1, value, size));
-
-}
-
-#ifdef PNG_USER_MEM_SUPPORTED
-/* This function is called when the application wants to use another method
- * of allocating and freeing memory.
- */
-void
-png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
- malloc_fn, png_free_ptr free_fn)
-{
- png_ptr->mem_ptr = mem_ptr;
- png_ptr->malloc_fn = malloc_fn;
- png_ptr->free_fn = free_fn;
-}
-
-/* This function returns a pointer to the mem_ptr associated with the user
- * functions. The application should free any memory associated with this
- * pointer before png_write_destroy and png_read_destroy are called.
- */
-png_voidp
-png_get_mem_ptr(png_structp png_ptr)
-{
- return ((png_voidp)png_ptr->mem_ptr);
-}
-#endif /* PNG_USER_MEM_SUPPORTED */
+++ /dev/null
-
-/* pngpread.c - read a png file in push mode
- *
- * libpng 1.0.3 - January 14, 1999
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-
-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-
-void
-png_process_data(png_structp png_ptr, png_infop info_ptr,
- png_bytep buffer, png_size_t buffer_size)
-{
- png_push_restore_buffer(png_ptr, buffer, buffer_size);
-
- while (png_ptr->buffer_size)
- {
- png_process_some_data(png_ptr, info_ptr);
- }
-}
-
-/* What we do with the incoming data depends on what we were previously
- * doing before we ran out of data...
- */
-void
-png_process_some_data(png_structp png_ptr, png_infop info_ptr)
-{
- switch (png_ptr->process_mode)
- {
- case PNG_READ_SIG_MODE:
- {
- png_push_read_sig(png_ptr, info_ptr);
- break;
- }
- case PNG_READ_CHUNK_MODE:
- {
- png_push_read_chunk(png_ptr, info_ptr);
- break;
- }
- case PNG_READ_IDAT_MODE:
- {
- png_push_read_IDAT(png_ptr);
- break;
- }
-#if defined(PNG_READ_tEXt_SUPPORTED)
- case PNG_READ_tEXt_MODE:
- {
- png_push_read_tEXt(png_ptr, info_ptr);
- break;
- }
-#endif
-#if defined(PNG_READ_zTXt_SUPPORTED)
- case PNG_READ_zTXt_MODE:
- {
- png_push_read_zTXt(png_ptr, info_ptr);
- break;
- }
-#endif
- case PNG_SKIP_MODE:
- {
- png_push_crc_finish(png_ptr);
- break;
- }
- default:
- {
- png_ptr->buffer_size = 0;
- break;
- }
- }
-}
-
-/* Read any remaining signature bytes from the stream and compare them with
- * the correct PNG signature. It is possible that this routine is called
- * with bytes already read from the signature, either because they have been
- * checked by the calling application, or because of multiple calls to this
- * routine.
- */
-void
-png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
-{
- png_size_t num_checked = png_ptr->sig_bytes,
- num_to_check = 8 - num_checked;
-
- if (png_ptr->buffer_size < num_to_check)
- {
- num_to_check = png_ptr->buffer_size;
- }
-
- png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
- num_to_check);
- png_ptr->sig_bytes += num_to_check;
-
- if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
- {
- if (num_checked < 4 &&
- png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
- png_error(png_ptr, "Not a PNG file");
- else
- png_error(png_ptr, "PNG file corrupted by ASCII conversion");
- }
- else
- {
- if (png_ptr->sig_bytes >= 8)
- {
- png_ptr->process_mode = PNG_READ_CHUNK_MODE;
- }
- }
-}
-
-void
-png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
-{
- /* First we make sure we have enough data for the 4 byte chunk name
- * and the 4 byte chunk length before proceeding with decoding the
- * chunk data. To fully decode each of these chunks, we also make
- * sure we have enough data in the buffer for the 4 byte CRC at the
- * end of every chunk (except IDAT, which is handled separately).
- */
- if (!(png_ptr->flags & PNG_FLAG_HAVE_CHUNK_HEADER))
- {
- png_byte chunk_length[4];
-
- if (png_ptr->buffer_size < 8)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_push_fill_buffer(png_ptr, chunk_length, 4);
- png_ptr->push_length = png_get_uint_32(chunk_length);
- png_reset_crc(png_ptr);
- png_crc_read(png_ptr, png_ptr->chunk_name, 4);
- png_ptr->flags |= PNG_FLAG_HAVE_CHUNK_HEADER;
- }
-
- if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
- }
- else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
- }
- else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- {
- /* If we reach an IDAT chunk, this means we have read all of the
- * header chunks, and we can start reading the image (or if this
- * is called after the image has been read - we have an error).
- */
- if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- if (png_ptr->push_length == 0)
- return;
-
- if (png_ptr->mode & PNG_AFTER_IDAT)
- png_error(png_ptr, "Too many IDAT's found");
- }
-
- png_ptr->idat_size = png_ptr->push_length;
- png_ptr->mode |= PNG_HAVE_IDAT;
- png_ptr->process_mode = PNG_READ_IDAT_MODE;
- png_push_have_info(png_ptr, info_ptr);
- png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
- png_ptr->zstream.next_out = png_ptr->row_buf;
- return;
- }
- else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
- png_ptr->process_mode = PNG_READ_DONE_MODE;
- png_push_have_end(png_ptr, info_ptr);
- }
-#if defined(PNG_READ_gAMA_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_sBIT_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_cHRM_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_sRGB_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_tRNS_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_bKGD_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_hIST_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_pHYs_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_oFFs_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_pCAL_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_tIME_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_tEXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
- {
- png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_zTXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
- {
- png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
- else
- {
- png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
- }
-
- png_ptr->flags &= ~PNG_FLAG_HAVE_CHUNK_HEADER;
-}
-
-void
-png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
-{
- png_ptr->process_mode = PNG_SKIP_MODE;
- png_ptr->skip_length = skip;
-}
-
-void
-png_push_crc_finish(png_structp png_ptr)
-{
- if (png_ptr->skip_length && png_ptr->save_buffer_size)
- {
- png_size_t save_size;
-
- if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
- save_size = (png_size_t)png_ptr->skip_length;
- else
- save_size = png_ptr->save_buffer_size;
-
- png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
-
- png_ptr->skip_length -= save_size;
- png_ptr->buffer_size -= save_size;
- png_ptr->save_buffer_size -= save_size;
- png_ptr->save_buffer_ptr += save_size;
- }
- if (png_ptr->skip_length && png_ptr->current_buffer_size)
- {
- png_size_t save_size;
-
- if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
- save_size = (png_size_t)png_ptr->skip_length;
- else
- save_size = png_ptr->current_buffer_size;
-
- png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
-
- png_ptr->skip_length -= save_size;
- png_ptr->buffer_size -= save_size;
- png_ptr->current_buffer_size -= save_size;
- png_ptr->current_buffer_ptr += save_size;
- }
- if (!png_ptr->skip_length)
- {
- if (png_ptr->buffer_size < 4)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_crc_finish(png_ptr, 0);
- png_ptr->process_mode = PNG_READ_CHUNK_MODE;
- }
-}
-
-void
-png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
-{
- png_bytep ptr;
-
- ptr = buffer;
- if (png_ptr->save_buffer_size)
- {
- png_size_t save_size;
-
- if (length < png_ptr->save_buffer_size)
- save_size = length;
- else
- save_size = png_ptr->save_buffer_size;
-
- png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
- length -= save_size;
- ptr += save_size;
- png_ptr->buffer_size -= save_size;
- png_ptr->save_buffer_size -= save_size;
- png_ptr->save_buffer_ptr += save_size;
- }
- if (length && png_ptr->current_buffer_size)
- {
- png_size_t save_size;
-
- if (length < png_ptr->current_buffer_size)
- save_size = length;
- else
- save_size = png_ptr->current_buffer_size;
-
- png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
- png_ptr->buffer_size -= save_size;
- png_ptr->current_buffer_size -= save_size;
- png_ptr->current_buffer_ptr += save_size;
- }
-}
-
-void
-png_push_save_buffer(png_structp png_ptr)
-{
- if (png_ptr->save_buffer_size)
- {
- if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
- {
- png_size_t i,istop;
- png_bytep sp;
- png_bytep dp;
-
- istop = png_ptr->save_buffer_size;
- for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
- i < istop; i++, sp++, dp++)
- {
- *dp = *sp;
- }
- }
- }
- if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
- png_ptr->save_buffer_max)
- {
- png_size_t new_max;
- png_bytep old_buffer;
-
- new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
- old_buffer = png_ptr->save_buffer;
- png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)new_max);
- png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
- png_free(png_ptr, old_buffer);
- png_ptr->save_buffer_max = new_max;
- }
- if (png_ptr->current_buffer_size)
- {
- png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
- png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
- png_ptr->save_buffer_size += png_ptr->current_buffer_size;
- png_ptr->current_buffer_size = 0;
- }
- png_ptr->save_buffer_ptr = png_ptr->save_buffer;
- png_ptr->buffer_size = 0;
-}
-
-void
-png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
- png_size_t buffer_length)
-{
- png_ptr->current_buffer = buffer;
- png_ptr->current_buffer_size = buffer_length;
- png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
- png_ptr->current_buffer_ptr = png_ptr->current_buffer;
-}
-
-void
-png_push_read_IDAT(png_structp png_ptr)
-{
- if (!(png_ptr->flags & PNG_FLAG_HAVE_CHUNK_HEADER))
- {
- png_byte chunk_length[4];
-
- if (png_ptr->buffer_size < 8)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_push_fill_buffer(png_ptr, chunk_length, 4);
- png_ptr->push_length = png_get_uint_32(chunk_length);
-
- png_reset_crc(png_ptr);
- png_crc_read(png_ptr, png_ptr->chunk_name, 4);
- png_ptr->flags |= PNG_FLAG_HAVE_CHUNK_HEADER;
-
- if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- {
- png_ptr->process_mode = PNG_READ_CHUNK_MODE;
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
- png_error(png_ptr, "Not enough compressed data");
- return;
- }
-
- png_ptr->idat_size = png_ptr->push_length;
- }
- if (png_ptr->idat_size && png_ptr->save_buffer_size)
- {
- png_size_t save_size;
-
- if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
- {
- save_size = (png_size_t)png_ptr->idat_size;
- /* check for overflow */
- if((png_uint_32)save_size != png_ptr->idat_size)
- png_error(png_ptr, "save_size overflowed in pngpread");
- }
- else
- save_size = png_ptr->save_buffer_size;
-
- png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
- png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
-
- png_ptr->idat_size -= save_size;
- png_ptr->buffer_size -= save_size;
- png_ptr->save_buffer_size -= save_size;
- png_ptr->save_buffer_ptr += save_size;
- }
- if (png_ptr->idat_size && png_ptr->current_buffer_size)
- {
- png_size_t save_size;
-
- if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
- {
- save_size = (png_size_t)png_ptr->idat_size;
- /* check for overflow */
- if((png_uint_32)save_size != png_ptr->idat_size)
- png_error(png_ptr, "save_size overflowed in pngpread");
- }
- else
- save_size = png_ptr->current_buffer_size;
-
- png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
- png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
-
- png_ptr->idat_size -= save_size;
- png_ptr->buffer_size -= save_size;
- png_ptr->current_buffer_size -= save_size;
- png_ptr->current_buffer_ptr += save_size;
- }
- if (!png_ptr->idat_size)
- {
- if (png_ptr->buffer_size < 4)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_crc_finish(png_ptr, 0);
- png_ptr->flags &= ~PNG_FLAG_HAVE_CHUNK_HEADER;
- }
-}
-
-void
-png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
- png_size_t buffer_length)
-{
- int ret;
-
- if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length)
- png_error(png_ptr, "Extra compression data");
-
- png_ptr->zstream.next_in = buffer;
- png_ptr->zstream.avail_in = (uInt)buffer_length;
- for(;;)
- {
- ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
- if (ret == Z_STREAM_END)
- {
- if (png_ptr->zstream.avail_in)
- png_error(png_ptr, "Extra compressed data");
- if (!(png_ptr->zstream.avail_out))
- {
- png_push_process_row(png_ptr);
- }
-
- png_ptr->mode |= PNG_AFTER_IDAT;
- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
- break;
- }
- else if (ret == Z_BUF_ERROR)
- break;
- else if (ret != Z_OK)
- png_error(png_ptr, "Decompression Error");
- if (!(png_ptr->zstream.avail_out))
- {
- png_push_process_row(png_ptr);
- png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
- png_ptr->zstream.next_out = png_ptr->row_buf;
- }
- else
- break;
- }
-}
-
-void
-png_push_process_row(png_structp png_ptr)
-{
- png_ptr->row_info.color_type = png_ptr->color_type;
- png_ptr->row_info.width = png_ptr->iwidth;
- png_ptr->row_info.channels = png_ptr->channels;
- png_ptr->row_info.bit_depth = png_ptr->bit_depth;
- png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
-
- png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
- (png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
-
- png_read_filter_row(png_ptr, &(png_ptr->row_info),
- png_ptr->row_buf + 1, png_ptr->prev_row + 1,
- (int)(png_ptr->row_buf[0]));
-
- png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
- png_ptr->rowbytes + 1);
-
- if (png_ptr->transformations)
- png_do_read_transformations(png_ptr);
-
-#if defined(PNG_READ_INTERLACING_SUPPORTED)
- /* blow up interlaced rows to full size */
- if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
- {
- if (png_ptr->pass < 6)
- png_do_read_interlace(&(png_ptr->row_info),
- png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
-
- switch (png_ptr->pass)
- {
- case 0:
- {
- int i;
- for (i = 0; i < 8 && png_ptr->pass == 0; i++)
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr);
- }
- break;
- }
- case 1:
- {
- int i;
- for (i = 0; i < 8 && png_ptr->pass == 1; i++)
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr);
- }
- if (png_ptr->pass == 2)
- {
- for (i = 0; i < 4 && png_ptr->pass == 2; i++)
- {
- png_push_have_row(png_ptr, NULL);
- png_read_push_finish_row(png_ptr);
- }
- }
- break;
- }
- case 2:
- {
- int i;
- for (i = 0; i < 4 && png_ptr->pass == 2; i++)
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr);
- }
- for (i = 0; i < 4 && png_ptr->pass == 2; i++)
- {
- png_push_have_row(png_ptr, NULL);
- png_read_push_finish_row(png_ptr);
- }
- break;
- }
- case 3:
- {
- int i;
- for (i = 0; i < 4 && png_ptr->pass == 3; i++)
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr);
- }
- if (png_ptr->pass == 4)
- {
- for (i = 0; i < 2 && png_ptr->pass == 4; i++)
- {
- png_push_have_row(png_ptr, NULL);
- png_read_push_finish_row(png_ptr);
- }
- }
- break;
- }
- case 4:
- {
- int i;
- for (i = 0; i < 2 && png_ptr->pass == 4; i++)
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr);
- }
- for (i = 0; i < 2 && png_ptr->pass == 4; i++)
- {
- png_push_have_row(png_ptr, NULL);
- png_read_push_finish_row(png_ptr);
- }
- break;
- }
- case 5:
- {
- int i;
- for (i = 0; i < 2 && png_ptr->pass == 5; i++)
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr);
- }
- if (png_ptr->pass == 6)
- {
- png_push_have_row(png_ptr, NULL);
- png_read_push_finish_row(png_ptr);
- }
- break;
- }
- case 6:
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr);
- if (png_ptr->pass != 6)
- break;
- png_push_have_row(png_ptr, NULL);
- png_read_push_finish_row(png_ptr);
- }
- }
- }
- else
-#endif
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr);
- }
-}
-
-void
-png_read_push_finish_row(png_structp png_ptr)
-{
- png_ptr->row_number++;
- if (png_ptr->row_number < png_ptr->num_rows)
- return;
-
- if (png_ptr->interlaced)
- {
- png_ptr->row_number = 0;
- png_memset_check(png_ptr, png_ptr->prev_row, 0,
- png_ptr->rowbytes + 1);
- do
- {
- png_ptr->pass++;
- if (png_ptr->pass >= 7)
- break;
-
- png_ptr->iwidth = (png_ptr->width +
- png_pass_inc[png_ptr->pass] - 1 -
- png_pass_start[png_ptr->pass]) /
- png_pass_inc[png_ptr->pass];
-
- png_ptr->irowbytes = ((png_ptr->iwidth *
- png_ptr->pixel_depth + 7) >> 3) + 1;
-
- if (png_ptr->transformations & PNG_INTERLACE)
- break;
-
- png_ptr->num_rows = (png_ptr->height +
- png_pass_yinc[png_ptr->pass] - 1 -
- png_pass_ystart[png_ptr->pass]) /
- png_pass_yinc[png_ptr->pass];
-
- } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
- }
-}
-
-#if defined(PNG_READ_tEXt_SUPPORTED)
-void
-png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- if (png_ptr->mode == PNG_BEFORE_IHDR || png_ptr->mode & PNG_HAVE_IEND)
- {
- png_error(png_ptr, "Out of place tEXt");
- /* to quiet some compiler warnings */
- if(info_ptr == NULL) return;
- }
-
-#ifdef PNG_MAX_MALLOC_64K
- png_ptr->skip_length = 0; /* This may not be necessary */
-
- if (length > (png_uint_32)65535L) /* Can't hold the entire string in memory */
- {
- png_warning(png_ptr, "tEXt chunk too large to fit in memory");
- png_ptr->skip_length = length - (png_uint_32)65535L;
- length = (png_uint_32)65535L;
- }
-#endif
-
- png_ptr->current_text = (png_charp)png_malloc(png_ptr,
- (png_uint_32)(length+1));
- png_ptr->current_text[length] = '\0';
- png_ptr->current_text_ptr = png_ptr->current_text;
- png_ptr->current_text_size = (png_size_t)length;
- png_ptr->current_text_left = (png_size_t)length;
- png_ptr->process_mode = PNG_READ_tEXt_MODE;
-}
-
-void
-png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr->buffer_size && png_ptr->current_text_left)
- {
- png_size_t text_size;
-
- if (png_ptr->buffer_size < png_ptr->current_text_left)
- text_size = png_ptr->buffer_size;
- else
- text_size = png_ptr->current_text_left;
- png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
- png_ptr->current_text_left -= text_size;
- png_ptr->current_text_ptr += text_size;
- }
- if (!(png_ptr->current_text_left))
- {
- png_textp text_ptr;
- png_charp text;
- png_charp key;
-
- if (png_ptr->buffer_size < 4)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_push_crc_finish(png_ptr);
-
-#if defined(PNG_MAX_MALLOC_64K)
- if (png_ptr->skip_length)
- return;
-#endif
-
- key = png_ptr->current_text;
- png_ptr->current_text = 0;
-
- for (text = key; *text; text++)
- /* empty loop */ ;
-
- if (text != key + png_ptr->current_text_size)
- text++;
-
- text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
- text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
- text_ptr->key = key;
- text_ptr->text = text;
-
- png_set_text(png_ptr, info_ptr, text_ptr, 1);
-
- png_free(png_ptr, text_ptr);
- }
-}
-#endif
-
-#if defined(PNG_READ_zTXt_SUPPORTED)
-void
-png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- if (png_ptr->mode == PNG_BEFORE_IHDR || png_ptr->mode & PNG_HAVE_IEND)
- {
- png_error(png_ptr, "Out of place zTXt");
- /* to quiet some compiler warnings */
- if(info_ptr == NULL) return;
- }
-
-#ifdef PNG_MAX_MALLOC_64K
- /* We can't handle zTXt chunks > 64K, since we don't have enough space
- * to be able to store the uncompressed data. Actually, the threshold
- * is probably around 32K, but it isn't as definite as 64K is.
- */
- if (length > (png_uint_32)65535L)
- {
- png_warning(png_ptr, "zTXt chunk too large to fit in memory");
- png_push_crc_skip(png_ptr, length);
- return;
- }
-#endif
-
- png_ptr->current_text = (png_charp)png_malloc(png_ptr,
- (png_uint_32)(length+1));
- png_ptr->current_text[length] = '\0';
- png_ptr->current_text_ptr = png_ptr->current_text;
- png_ptr->current_text_size = (png_size_t)length;
- png_ptr->current_text_left = (png_size_t)length;
- png_ptr->process_mode = PNG_READ_zTXt_MODE;
-}
-
-void
-png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr->buffer_size && png_ptr->current_text_left)
- {
- png_size_t text_size;
-
- if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
- text_size = png_ptr->buffer_size;
- else
- text_size = png_ptr->current_text_left;
- png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
- png_ptr->current_text_left -= text_size;
- png_ptr->current_text_ptr += text_size;
- }
- if (!(png_ptr->current_text_left))
- {
- png_textp text_ptr;
- png_charp text;
- png_charp key;
- int ret;
- png_size_t text_size, key_size;
-
- if (png_ptr->buffer_size < 4)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_push_crc_finish(png_ptr);
-
- key = png_ptr->current_text;
- png_ptr->current_text = 0;
-
- for (text = key; *text; text++)
- /* empty loop */ ;
-
- /* zTXt can't have zero text */
- if (text == key + png_ptr->current_text_size)
- {
- png_free(png_ptr, key);
- return;
- }
-
- text++;
-
- if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */
- {
- png_free(png_ptr, key);
- return;
- }
-
- text++;
-
- png_ptr->zstream.next_in = (png_bytep )text;
- png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
- (text - key));
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-
- key_size = text - key;
- text_size = 0;
- text = NULL;
- ret = Z_STREAM_END;
-
- while (png_ptr->zstream.avail_in)
- {
- ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
- if (ret != Z_OK && ret != Z_STREAM_END)
- {
- inflateReset(&png_ptr->zstream);
- png_ptr->zstream.avail_in = 0;
- png_free(png_ptr, key);
- png_free(png_ptr, text);
- return;
- }
- if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
- {
- if (text == NULL)
- {
- text = (png_charp)png_malloc(png_ptr,
- (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out +
- key_size + 1));
- png_memcpy(text + key_size, png_ptr->zbuf,
- png_ptr->zbuf_size - png_ptr->zstream.avail_out);
- png_memcpy(text, key, key_size);
- text_size = key_size + png_ptr->zbuf_size -
- png_ptr->zstream.avail_out;
- *(text + text_size) = '\0';
- }
- else
- {
- png_charp tmp;
-
- tmp = text;
- text = (png_charp)png_malloc(png_ptr, text_size +
- (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
- + 1));
- png_memcpy(text, tmp, text_size);
- png_free(png_ptr, tmp);
- png_memcpy(text + text_size, png_ptr->zbuf,
- png_ptr->zbuf_size - png_ptr->zstream.avail_out);
- text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
- *(text + text_size) = '\0';
- }
- if (ret != Z_STREAM_END)
- {
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- }
- }
- else
- {
- break;
- }
-
- if (ret == Z_STREAM_END)
- break;
- }
-
- inflateReset(&png_ptr->zstream);
- png_ptr->zstream.avail_in = 0;
-
- if (ret != Z_STREAM_END)
- {
- png_free(png_ptr, key);
- png_free(png_ptr, text);
- return;
- }
-
- png_free(png_ptr, key);
- key = text;
- text += key_size;
-
- text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
- text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
- text_ptr->key = key;
- text_ptr->text = text;
-
- png_set_text(png_ptr, info_ptr, text_ptr, 1);
-
- png_free(png_ptr, text_ptr);
- }
-}
-#endif
-
-/* This function is called when we haven't found a handler for this
- * chunk. In the future we will have code here that can handle
- * user-defined callback functions for unknown chunks before they are
- * ignored or cause an error. If there isn't a problem with the
- * chunk itself (ie a bad chunk name or a critical chunk), the chunk
- * is (currently) silently ignored.
- */
-void
-png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_check_chunk_name(png_ptr, png_ptr->chunk_name);
-
- if (!(png_ptr->chunk_name[0] & 0x20))
- {
- png_chunk_error(png_ptr, "unknown critical chunk");
- /* to quiet some compiler warnings */
- if(info_ptr == NULL) return;
- }
-
- png_push_crc_skip(png_ptr, length);
-}
-
-void
-png_push_have_info(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr->info_fn != NULL)
- (*(png_ptr->info_fn))(png_ptr, info_ptr);
-}
-
-void
-png_push_have_end(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr->end_fn != NULL)
- (*(png_ptr->end_fn))(png_ptr, info_ptr);
-}
-
-void
-png_push_have_row(png_structp png_ptr, png_bytep row)
-{
- if (png_ptr->row_fn != NULL)
- (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
- (int)png_ptr->pass);
-}
-
-void
-png_progressive_combine_row (png_structp png_ptr,
- png_bytep old_row, png_bytep new_row)
-{
- if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */
- png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
-}
-
-void
-png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
- png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
- png_progressive_end_ptr end_fn)
-{
- png_ptr->info_fn = info_fn;
- png_ptr->row_fn = row_fn;
- png_ptr->end_fn = end_fn;
-
- png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
-}
-
-png_voidp
-png_get_progressive_ptr(png_structp png_ptr)
-{
- return png_ptr->io_ptr;
-}
-
-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
-
+++ /dev/null
-
-/* pngread.c - read a PNG file
- *
- * libpng 1.0.3 - January 14, 1999
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
- *
- * This file contains routines that an application calls directly to
- * read a PNG file or stream.
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-
-/* Create a PNG structure for reading, and allocate any memory needed. */
-png_structp
-png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn)
-{
-
-#ifdef PNG_USER_MEM_SUPPORTED
- return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
- warn_fn, NULL, NULL, NULL));
-}
-
-/* Alternate create PNG structure for reading, and allocate any memory needed. */
-png_structp
-png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
- png_malloc_ptr malloc_fn, png_free_ptr free_fn)
-{
-#endif /* PNG_USER_MEM_SUPPORTED */
-
- png_structp png_ptr;
-#ifdef USE_FAR_KEYWORD
- jmp_buf jmpbuf;
-#endif
- png_debug(1, "in png_create_read_struct\n");
-#ifdef PNG_USER_MEM_SUPPORTED
- if ((png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
- (png_malloc_ptr)malloc_fn)) == NULL)
-#else
- if ((png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG)) == NULL)
-#endif
- {
- return (png_structp)NULL;
- }
-#ifdef USE_FAR_KEYWORD
- if (setjmp(jmpbuf))
-#else
- if (setjmp(png_ptr->jmpbuf))
-#endif
- {
- png_free(png_ptr, png_ptr->zbuf);
- png_destroy_struct(png_ptr);
- return (png_structp)NULL;
- }
-#ifdef USE_FAR_KEYWORD
- png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
-#endif
-
-#ifdef PNG_USER_MEM_SUPPORTED
- png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
-#endif /* PNG_USER_MEM_SUPPORTED */
-
- png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
-
- /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
- * we must recompile any applications that use any older library version.
- * For versions after libpng 1.0, we will be compatible, so we need
- * only check the first digit.
- */
- if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
- (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
- {
- png_error(png_ptr,
- "Incompatible libpng version in application and library");
- }
-
- /* initialize zbuf - compression buffer */
- png_ptr->zbuf_size = PNG_ZBUF_SIZE;
- png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)png_ptr->zbuf_size);
- png_ptr->zstream.zalloc = png_zalloc;
- png_ptr->zstream.zfree = png_zfree;
- png_ptr->zstream.opaque = (voidpf)png_ptr;
-
- switch (inflateInit(&png_ptr->zstream))
- {
- case Z_OK: /* Do nothing */ break;
- case Z_MEM_ERROR:
- case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error"); break;
- case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error"); break;
- default: png_error(png_ptr, "Unknown zlib error");
- }
-
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-
- png_set_read_fn(png_ptr, NULL, NULL);
-
- return (png_ptr);
-}
-
-/* Initialize PNG structure for reading, and allocate any memory needed.
- This interface is deprecated in favour of the png_create_read_struct(),
- and it will eventually disappear. */
-void
-png_read_init(png_structp png_ptr)
-{
- jmp_buf tmp_jmp; /* to save current jump buffer */
-
- png_debug(1, "in png_read_init\n");
- /* save jump buffer and error functions */
- png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
-
- /* reset all variables to 0 */
- png_memset(png_ptr, 0, sizeof (png_struct));
-
- /* restore jump buffer */
- 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_bytep)png_malloc(png_ptr,
- (png_uint_32)png_ptr->zbuf_size);
- png_ptr->zstream.zalloc = png_zalloc;
- png_ptr->zstream.zfree = png_zfree;
- png_ptr->zstream.opaque = (voidpf)png_ptr;
-
- switch (inflateInit(&png_ptr->zstream))
- {
- case Z_OK: /* Do nothing */ break;
- case Z_MEM_ERROR:
- case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory"); break;
- case Z_VERSION_ERROR: png_error(png_ptr, "zlib version"); break;
- default: png_error(png_ptr, "Unknown zlib error");
- }
-
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-
- png_set_read_fn(png_ptr, NULL, NULL);
-}
-
-/* Read the information before the actual image data. This has been
- * changed in v0.90 to allow reading a file that already has the magic
- * bytes read from the stream. You can tell libpng how many bytes have
- * been read from the beginning of the stream (up to the maximum of 8)
- * via png_set_sig_bytes(), and we will only check the remaining bytes
- * here. The application can then have access to the signature bytes we
- * read if it is determined that this isn't a valid PNG file.
- */
-void
-png_read_info(png_structp png_ptr, png_infop info_ptr)
-{
- png_debug(1, "in png_read_info\n");
- /* save jump buffer and error functions */
- /* If we haven't checked all of the PNG signature bytes, do so now. */
- if (png_ptr->sig_bytes < 8)
- {
- png_size_t num_checked = png_ptr->sig_bytes,
- num_to_check = 8 - num_checked;
-
- png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
- png_ptr->sig_bytes = 8;
-
- if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
- {
- if (num_checked < 4 &&
- png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
- png_error(png_ptr, "Not a PNG file");
- else
- png_error(png_ptr, "PNG file corrupted by ASCII conversion");
- }
- }
-
- for(;;)
- {
- png_byte chunk_length[4];
- png_uint_32 length;
-
- png_read_data(png_ptr, chunk_length, 4);
- length = png_get_uint_32(chunk_length);
-
- png_reset_crc(png_ptr);
- png_crc_read(png_ptr, png_ptr->chunk_name, 4);
-
- png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name);
-
- /* This should be a binary subdivision search or a hash for
- * matching the chunk name rather than a linear search.
- */
- if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
- png_handle_IHDR(png_ptr, info_ptr, length);
- else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
- png_handle_PLTE(png_ptr, info_ptr, length);
- else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
- png_handle_IEND(png_ptr, info_ptr, length);
- else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- {
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before IDAT");
- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
- !(png_ptr->mode & PNG_HAVE_PLTE))
- png_error(png_ptr, "Missing PLTE before IDAT");
-
- png_ptr->idat_size = length;
- png_ptr->mode |= PNG_HAVE_IDAT;
- break;
- }
-#if defined(PNG_READ_bKGD_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
- png_handle_bKGD(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_cHRM_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
- png_handle_cHRM(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_gAMA_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
- png_handle_gAMA(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_hIST_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
- png_handle_hIST(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_oFFs_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
- png_handle_oFFs(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_pCAL_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
- png_handle_pCAL(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_pHYs_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
- png_handle_pHYs(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_sBIT_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
- png_handle_sBIT(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_sRGB_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
- png_handle_sRGB(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_tEXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
- png_handle_tEXt(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_tIME_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
- png_handle_tIME(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_tRNS_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
- png_handle_tRNS(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_zTXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
- png_handle_zTXt(png_ptr, info_ptr, length);
-#endif
- else
- png_handle_unknown(png_ptr, info_ptr, length);
- }
-}
-
-/* optional call to update the users info_ptr structure */
-void
-png_read_update_info(png_structp png_ptr, png_infop info_ptr)
-{
- png_debug(1, "in png_read_update_info\n");
- /* save jump buffer and error functions */
- if (!(png_ptr->flags & PNG_FLAG_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 obtain a gamma-corrected palette, for example.
- * If the user doesn't call this, we will do it ourselves.
- */
-void
-png_start_read_image(png_structp png_ptr)
-{
- png_debug(1, "in png_start_read_image\n");
- /* save jump buffer and error functions */
- if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
- png_read_start_row(png_ptr);
-}
-
-void
-png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
-{
- int ret;
- png_debug2(1, "in png_read_row (row %d, pass %d)\n",
- png_ptr->row_number, png_ptr->pass);
- /* save jump buffer and error functions */
- if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
- png_read_start_row(png_ptr);
- if (png_ptr->row_number == 0 && png_ptr->pass == 0)
- {
- /* check for transforms that have been set but were defined out */
-#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
- if (png_ptr->transformations & PNG_INVERT_MONO)
- png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined.");
-#endif
-#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
- if (png_ptr->transformations & PNG_FILLER)
- png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined.");
-#endif
-#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && !defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined.");
-#endif
-#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
- if (png_ptr->transformations & PNG_PACK)
- png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined.");
-#endif
-#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
- if (png_ptr->transformations & PNG_SHIFT)
- png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined.");
-#endif
-#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
- if (png_ptr->transformations & PNG_BGR)
- png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined.");
-#endif
-#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_SWAP_BYTES)
- png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined.");
-#endif
- }
-
-#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))
- {
- switch (png_ptr->pass)
- {
- case 0:
- if (png_ptr->row_number & 7)
- {
- if (dsp_row != NULL)
- png_combine_row(png_ptr, dsp_row,
- png_pass_dsp_mask[png_ptr->pass]);
- png_read_finish_row(png_ptr);
- return;
- }
- break;
- case 1:
- if ((png_ptr->row_number & 7) || png_ptr->width < 5)
- {
- if (dsp_row != NULL)
- png_combine_row(png_ptr, dsp_row,
- png_pass_dsp_mask[png_ptr->pass]);
- png_read_finish_row(png_ptr);
- return;
- }
- break;
- case 2:
- if ((png_ptr->row_number & 7) != 4)
- {
- if (dsp_row != NULL && (png_ptr->row_number & 4))
- png_combine_row(png_ptr, dsp_row,
- png_pass_dsp_mask[png_ptr->pass]);
- png_read_finish_row(png_ptr);
- return;
- }
- break;
- case 3:
- if ((png_ptr->row_number & 3) || png_ptr->width < 3)
- {
- if (dsp_row != NULL)
- png_combine_row(png_ptr, dsp_row,
- png_pass_dsp_mask[png_ptr->pass]);
- png_read_finish_row(png_ptr);
- return;
- }
- break;
- case 4:
- if ((png_ptr->row_number & 3) != 2)
- {
- if (dsp_row != NULL && (png_ptr->row_number & 2))
- png_combine_row(png_ptr, dsp_row,
- png_pass_dsp_mask[png_ptr->pass]);
- png_read_finish_row(png_ptr);
- return;
- }
- break;
- case 5:
- if ((png_ptr->row_number & 1) || png_ptr->width < 2)
- {
- if (dsp_row != NULL)
- png_combine_row(png_ptr, dsp_row,
- png_pass_dsp_mask[png_ptr->pass]);
- png_read_finish_row(png_ptr);
- return;
- }
- break;
- case 6:
- if (!(png_ptr->row_number & 1))
- {
- png_read_finish_row(png_ptr);
- return;
- }
- break;
- }
- }
-#endif
-
- if (!(png_ptr->mode & PNG_HAVE_IDAT))
- png_error(png_ptr, "Invalid attempt to read row data");
-
- png_ptr->zstream.next_out = png_ptr->row_buf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
- do
- {
- if (!(png_ptr->zstream.avail_in))
- {
- while (!png_ptr->idat_size)
- {
- png_byte chunk_length[4];
-
- png_crc_finish(png_ptr, 0);
-
- png_read_data(png_ptr, chunk_length, 4);
- png_ptr->idat_size = png_get_uint_32(chunk_length);
-
- png_reset_crc(png_ptr);
- png_crc_read(png_ptr, png_ptr->chunk_name, 4);
- if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- png_error(png_ptr, "Not enough image data");
- }
- png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
- png_ptr->zstream.next_in = png_ptr->zbuf;
- if (png_ptr->zbuf_size > png_ptr->idat_size)
- png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
- png_crc_read(png_ptr, png_ptr->zbuf,
- (png_size_t)png_ptr->zstream.avail_in);
- png_ptr->idat_size -= png_ptr->zstream.avail_in;
- }
- ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
- if (ret == Z_STREAM_END)
- {
- if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
- png_ptr->idat_size)
- png_error(png_ptr, "Extra compressed data");
- png_ptr->mode |= PNG_AFTER_IDAT;
- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
- break;
- }
- if (ret != Z_OK)
- png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
- "Decompression error");
-
- } while (png_ptr->zstream.avail_out);
-
- png_ptr->row_info.color_type = png_ptr->color_type;
- png_ptr->row_info.width = png_ptr->iwidth;
- png_ptr->row_info.channels = png_ptr->channels;
- png_ptr->row_info.bit_depth = png_ptr->bit_depth;
- png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
- {
- png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
- (png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
- }
-
- png_read_filter_row(png_ptr, &(png_ptr->row_info),
- png_ptr->row_buf + 1, png_ptr->prev_row + 1,
- (int)(png_ptr->row_buf[0]));
-
- png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
- png_ptr->rowbytes + 1);
-
- if (png_ptr->transformations)
- png_do_read_transformations(png_ptr);
-
-#if defined(PNG_READ_INTERLACING_SUPPORTED)
- /* blow up interlaced rows to full size */
- if (png_ptr->interlaced &&
- (png_ptr->transformations & PNG_INTERLACE))
- {
- if (png_ptr->pass < 6)
- png_do_read_interlace(&(png_ptr->row_info),
- png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
-
- if (dsp_row != NULL)
- png_combine_row(png_ptr, dsp_row,
- png_pass_dsp_mask[png_ptr->pass]);
- if (row != NULL)
- png_combine_row(png_ptr, row,
- png_pass_mask[png_ptr->pass]);
- }
- else
-#endif
- {
- if (row != NULL)
- png_combine_row(png_ptr, row, 0xff);
- if (dsp_row != NULL)
- png_combine_row(png_ptr, dsp_row, 0xff);
- }
- png_read_finish_row(png_ptr);
-
- if (png_ptr->read_row_fn != NULL)
- (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
-}
-
-/* Read one or more rows of image data. If the image is interlaced,
- * and png_set_interlace_handling() has been called, the rows need to
- * contain the contents of the rows from the previous pass. If the
- * image has alpha or transparency, and png_handle_alpha()[*] has been
- * called, the rows contents must be initialized to the contents of the
- * screen.
- *
- * "row" holds the actual image, and pixels are placed in it
- * as they arrive. If the image is displayed after each pass, it will
- * appear to "sparkle" in. "display_row" can be used to display a
- * "chunky" progressive image, with finer detail added as it becomes
- * available. If you do not want this "chunky" display, you may pass
- * NULL for display_row. If you do not want the sparkle display, and
- * you have not called png_handle_alpha(), you may pass NULL for rows.
- * If you have called png_handle_alpha(), and the image has either an
- * alpha channel or a transparency chunk, you must provide a buffer for
- * rows. In this case, you do not have to provide a display_row buffer
- * also, but you may. If the image is not interlaced, or if you have
- * not called png_set_interlace_handling(), the display_row buffer will
- * be ignored, so pass NULL to it.
- *
- * [*] png_handle_alpha() does not exist yet, as of libpng version 1.0.3.
- */
-
-void
-png_read_rows(png_structp png_ptr, png_bytepp row,
- png_bytepp display_row, png_uint_32 num_rows)
-{
- png_uint_32 i;
- png_bytepp rp;
- png_bytepp dp;
-
- png_debug(1, "in png_read_rows\n");
- /* save jump buffer and error functions */
- rp = row;
- dp = display_row;
- if (rp != NULL && dp != NULL)
- for (i = 0; i < num_rows; i++)
- {
- png_bytep rptr = *rp++;
- png_bytep dptr = *dp++;
-
- png_read_row(png_ptr, rptr, dptr);
- }
- else if(rp != NULL)
- for (i = 0; i < num_rows; i++)
- {
- png_bytep rptr = *rp;
- png_read_row(png_ptr, rptr, NULL);
- rp++;
- }
- else if(dp != NULL)
- for (i = 0; i < num_rows; i++)
- {
- png_bytep dptr = *dp;
- png_read_row(png_ptr, NULL, dptr);
- dp++;
- }
-}
-
-/* Read the entire image. If the image has an alpha channel or a tRNS
- * chunk, and you have called png_handle_alpha()[*], you will need to
- * initialize the image to the current image that PNG will be overlaying.
- * We set the num_rows again here, in case it was incorrectly set in
- * png_read_start_row() by a call to png_read_update_info() or
- * png_start_read_image() if png_set_interlace_handling() wasn't called
- * prior to either of these functions like it should have been. You can
- * only call this function once. If you desire to have an image for
- * each pass of a interlaced image, use png_read_rows() instead.
- *
- * [*] png_handle_alpha() does not exist yet, as of libpng version 1.0.3.
- */
-void
-png_read_image(png_structp png_ptr, png_bytepp image)
-{
- png_uint_32 i,image_height;
- int pass, j;
- png_bytepp rp;
-
- png_debug(1, "in png_read_image\n");
- /* save jump buffer and error functions */
- pass = png_set_interlace_handling(png_ptr);
-
- image_height=png_ptr->height;
- png_ptr->num_rows = image_height; /* Make sure this is set correctly */
-
- for (j = 0; j < pass; j++)
- {
- rp = image;
- for (i = 0; i < image_height; i++)
- {
- png_read_row(png_ptr, *rp, NULL);
- rp++;
- }
- }
-}
-
-/* Read the end of the PNG file. Will not read past the end of the
- * file, will verify the end is accurate, and will read any comments
- * or time information at the end of the file, if info is not NULL.
- */
-void
-png_read_end(png_structp png_ptr, png_infop info_ptr)
-{
- png_byte chunk_length[4];
- png_uint_32 length;
-
- png_debug(1, "in png_read_end\n");
- /* save jump buffer and error functions */
- png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
-
- do
- {
- png_read_data(png_ptr, chunk_length, 4);
- length = png_get_uint_32(chunk_length);
-
- png_reset_crc(png_ptr);
- png_crc_read(png_ptr, png_ptr->chunk_name, 4);
-
- png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name);
-
- if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
- png_handle_IHDR(png_ptr, info_ptr, length);
- else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- {
- /* Zero length IDATs are legal after the last IDAT has been
- * read, but not after other chunks have been read.
- */
- if (length > 0 || png_ptr->mode & PNG_AFTER_IDAT)
- png_error(png_ptr, "Too many IDAT's found");
- else
- png_crc_finish(png_ptr, 0);
- }
- else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
- png_handle_PLTE(png_ptr, info_ptr, length);
- else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
- png_handle_IEND(png_ptr, info_ptr, length);
-#if defined(PNG_READ_bKGD_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
- png_handle_bKGD(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_cHRM_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
- png_handle_cHRM(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_gAMA_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
- png_handle_gAMA(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_hIST_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
- png_handle_hIST(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_oFFs_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
- png_handle_oFFs(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_pCAL_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
- png_handle_pCAL(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_pHYs_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
- png_handle_pHYs(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_sBIT_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
- png_handle_sBIT(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_sRGB_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
- png_handle_sRGB(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_tEXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
- png_handle_tEXt(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_tIME_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
- png_handle_tIME(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_tRNS_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
- png_handle_tRNS(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_zTXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
- png_handle_zTXt(png_ptr, info_ptr, length);
-#endif
- else
- png_handle_unknown(png_ptr, info_ptr, length);
- } while (!(png_ptr->mode & PNG_HAVE_IEND));
-}
-
-/* free all memory used by the read */
-void
-png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
- png_infopp end_info_ptr_ptr)
-{
- png_structp png_ptr = NULL;
- png_infop info_ptr = NULL, end_info_ptr = NULL;
-#ifdef PNG_USER_MEM_SUPPORTED
- png_free_ptr free_fn = NULL;
-#endif /* PNG_USER_MEM_SUPPORTED */
-
- png_debug(1, "in png_destroy_read_struct\n");
- /* save jump buffer and error functions */
- if (png_ptr_ptr != NULL)
- png_ptr = *png_ptr_ptr;
-
- if (info_ptr_ptr != NULL)
- info_ptr = *info_ptr_ptr;
-
- if (end_info_ptr_ptr != NULL)
- end_info_ptr = *end_info_ptr_ptr;
-
-#ifdef PNG_USER_MEM_SUPPORTED
- free_fn = png_ptr->free_fn;
-#endif
-
- png_read_destroy(png_ptr, info_ptr, end_info_ptr);
-
- if (info_ptr != NULL)
- {
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
- png_free(png_ptr, info_ptr->text);
-#endif
-
-#ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2((png_voidp)info_ptr, free_fn);
-#else
- png_destroy_struct((png_voidp)info_ptr);
-#endif
- *info_ptr_ptr = (png_infop)NULL;
- }
-
- if (end_info_ptr != NULL)
- {
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
- png_free(png_ptr, end_info_ptr->text);
-#endif
-#ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2((png_voidp)end_info_ptr, free_fn);
-#else
- png_destroy_struct((png_voidp)end_info_ptr);
-#endif
- *end_info_ptr_ptr = (png_infop)NULL;
- }
-
- if (png_ptr != NULL)
- {
-#ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2((png_voidp)png_ptr, free_fn);
-#else
- png_destroy_struct((png_voidp)png_ptr);
-#endif
- *png_ptr_ptr = (png_structp)NULL;
- }
-}
-
-/* free all memory used by the read (old method) */
-void
-png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr)
-{
- jmp_buf tmp_jmp;
- png_error_ptr error_fn;
- png_error_ptr warning_fn;
- png_voidp error_ptr;
-#ifdef PNG_USER_MEM_SUPPORTED
- png_free_ptr free_fn;
-#endif
-
- png_debug(1, "in png_read_destroy\n");
- /* save jump buffer and error functions */
- if (info_ptr != NULL)
- png_info_destroy(png_ptr, info_ptr);
-
- if (end_info_ptr != NULL)
- png_info_destroy(png_ptr, end_info_ptr);
-
- png_free(png_ptr, png_ptr->zbuf);
- png_free(png_ptr, png_ptr->row_buf);
- png_free(png_ptr, png_ptr->prev_row);
-#if defined(PNG_READ_DITHER_SUPPORTED)
- png_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 (png_ptr->flags & PNG_FLAG_FREE_PALETTE)
- png_zfree(png_ptr, png_ptr->palette);
- if (png_ptr->flags & PNG_FLAG_FREE_TRANS)
- png_free(png_ptr, png_ptr->trans);
-#if defined(PNG_READ_hIST_SUPPORTED)
- if (png_ptr->flags & PNG_FLAG_FREE_HIST)
- png_free(png_ptr, png_ptr->hist);
-#endif
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (png_ptr->gamma_16_table != NULL)
- {
- int i;
- int istop = (1 << (8 - png_ptr->gamma_shift));
- for (i = 0; i < istop; i++)
- {
- png_free(png_ptr, png_ptr->gamma_16_table[i]);
- }
- png_free(png_ptr, png_ptr->gamma_16_table);
- }
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->gamma_16_from_1 != NULL)
- {
- int i;
- int istop = (1 << (8 - png_ptr->gamma_shift));
- for (i = 0; i < istop; i++)
- {
- png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
- }
- png_free(png_ptr, png_ptr->gamma_16_from_1);
- }
- if (png_ptr->gamma_16_to_1 != NULL)
- {
- int i;
- int istop = (1 << (8 - png_ptr->gamma_shift));
- for (i = 0; i < istop; i++)
- {
- png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
- }
- png_free(png_ptr, png_ptr->gamma_16_to_1);
- }
-#endif
-#endif
-#if defined(PNG_TIME_RFC1123_SUPPORTED)
- png_free(png_ptr, png_ptr->time_buffer);
-#endif /* PNG_TIME_RFC1123_SUPPORTED */
-
- inflateEnd(&png_ptr->zstream);
-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
- png_free(png_ptr, png_ptr->save_buffer);
-#endif
-
- /* Save the important info out of the png_struct, in case it is
- * being used again.
- */
- png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
-
- error_fn = png_ptr->error_fn;
- warning_fn = png_ptr->warning_fn;
- error_ptr = png_ptr->error_ptr;
-#ifdef PNG_USER_MEM_SUPPORTED
- free_fn = png_ptr->free_fn;
-#endif
-
- png_memset(png_ptr, 0, sizeof (png_struct));
-
- png_ptr->error_fn = error_fn;
- png_ptr->warning_fn = warning_fn;
- png_ptr->error_ptr = error_ptr;
-#ifdef PNG_USER_MEM_SUPPORTED
- png_ptr->free_fn = free_fn;
-#endif
-
- png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
-}
-
-void
-png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
-{
- png_ptr->read_row_fn = read_row_fn;
-}
+++ /dev/null
-
-/* pngrio.c - functions for data input
- *
- * libpng 1.0.3 - January 14, 1999
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
- *
- * This file provides a location for all input. Users who need
- * special handling are expected to write a function that has the same
- * arguments as this and performs a similar function, but that possibly
- * has a different input method. Note that you shouldn't change this
- * function, but rather write a replacement function and then make
- * libpng use it at run time with png_set_read_fn(...).
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-
-/* Read the data from whatever input you are using. The default routine
- reads from a file pointer. 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. */
-void
-png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
- png_debug1(4,"reading %d bytes\n", length);
- if (png_ptr->read_data_fn != NULL)
- (*(png_ptr->read_data_fn))(png_ptr, data, length);
- else
- png_error(png_ptr, "Call to NULL read function");
-}
-
-#if !defined(PNG_NO_STDIO)
-/* This is the function that does the actual reading of data. If you are
- not reading from a standard C stream, you should create a replacement
- read_data function and use it at run time with png_set_read_fn(), rather
- than changing the library. */
-#ifndef USE_FAR_KEYWORD
-#ifdef __VISAGECPP__
-static void _Optlink
-png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
-#else
-static void
-png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
-#endif
-{
- png_size_t check;
-
- /* fread() returns 0 on error, so it is OK to store this in a png_size_t
- * instead of an int, which is what fread() actually returns.
- */
- check = (png_size_t)fread(data, (png_size_t)1, length,
- (FILE *)png_ptr->io_ptr);
-
- if (check != length)
- {
- png_error(png_ptr, "Read 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)
-
-static void
-png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
- int check;
- png_byte *n_data;
- FILE *io_ptr;
-
- /* Check if data really is near. If so, use usual code. */
- n_data = (png_byte *)CVT_PTR_NOCHECK(data);
- io_ptr = (FILE *)CVT_PTR(png_ptr->io_ptr);
- if ((png_bytep)n_data == data)
- {
- check = fread(n_data, 1, length, io_ptr);
- }
- else
- {
- png_byte buf[NEAR_BUF_SIZE];
- png_size_t read, remaining, err;
- check = 0;
- remaining = length;
- do
- {
- read = MIN(NEAR_BUF_SIZE, remaining);
- err = fread(buf, (png_size_t)1, read, io_ptr);
- 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 ((png_uint_32)check != (png_uint_32)length)
- {
- png_error(png_ptr, "read Error");
- }
-}
-#endif
-#endif
-
-/* This function allows the application to supply a new input function
- for libpng if standard C streams aren't being used.
-
- This function takes as its arguments:
- png_ptr - pointer to a png input data structure
- io_ptr - pointer to user supplied structure containing info about
- the input functions. May be NULL.
- read_data_fn - pointer to a new input function that takes as its
- arguments a pointer to a png_struct, a pointer to
- a location where input data can be stored, and a 32-bit
- unsigned int that is the number of bytes to be read.
- To exit and output any fatal error messages the new write
- function should call png_error(png_ptr, "Error msg"). */
-void
-png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
- png_rw_ptr read_data_fn)
-{
- png_ptr->io_ptr = io_ptr;
-
-#if !defined(PNG_NO_STDIO)
- if (read_data_fn != NULL)
- png_ptr->read_data_fn = read_data_fn;
- else
- png_ptr->read_data_fn = png_default_read_data;
-#else
- png_ptr->read_data_fn = read_data_fn;
-#endif
-
- /* It is an error to write to a read device */
- if (png_ptr->write_data_fn != NULL)
- {
- png_ptr->write_data_fn = NULL;
- png_warning(png_ptr,
- "It's an error to set both read_data_fn and write_data_fn in the ");
- png_warning(png_ptr,
- "same structure. Resetting write_data_fn to NULL.");
- }
-
-#if defined(PNG_WRITE_FLUSH_SUPPORTED)
- png_ptr->output_flush_fn = NULL;
-#endif /* PNG_WRITE_FLUSH_SUPPORTED */
-}
-
+++ /dev/null
-
-/* pngrtran.c - transforms the data in a row for PNG readers
- *
- * libpng 1.0.3 - January 14, 1999
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
- *
- * This file contains functions optionally called by an application
- * in order to tell libpng how to handle data when reading a PNG.
- * Transformations that are used in both reading and writing are
- * in pngtrans.c.
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-
-#if defined(_MSC_VER) && !defined(__MWERKS__)
-#define __VISUALC__ _MSC_VER
-#endif
-#ifdef __VISUALC__
-#ifndef WIN32
-#pragma warning(disable:4135)
-#endif
-#endif
-
-/* Set the action on getting a CRC error for an ancillary or critical chunk. */
-void
-png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
-{
- png_debug(1, "in png_set_crc_action\n");
- /* Tell libpng how we react to CRC errors in critical chunks */
- switch (crit_action)
- {
- case PNG_CRC_NO_CHANGE: /* leave setting as is */
- break;
- case PNG_CRC_WARN_USE: /* warn/use data */
- png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
- png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
- break;
- case PNG_CRC_QUIET_USE: /* quiet/use data */
- png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
- png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
- PNG_FLAG_CRC_CRITICAL_IGNORE;
- break;
- case PNG_CRC_WARN_DISCARD: /* not a valid action for critical data */
- png_warning(png_ptr, "Can't discard critical data on CRC error.");
- case PNG_CRC_ERROR_QUIT: /* error/quit */
- case PNG_CRC_DEFAULT:
- default:
- png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
- break;
- }
-
- switch (ancil_action)
- {
- case PNG_CRC_NO_CHANGE: /* leave setting as is */
- break;
- case PNG_CRC_WARN_USE: /* warn/use data */
- png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
- png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
- break;
- case PNG_CRC_QUIET_USE: /* quiet/use data */
- png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
- png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
- PNG_FLAG_CRC_ANCILLARY_NOWARN;
- break;
- case PNG_CRC_ERROR_QUIT: /* error/quit */
- png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
- png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
- break;
- case PNG_CRC_WARN_DISCARD: /* warn/discard data */
- case PNG_CRC_DEFAULT:
- default:
- png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
- break;
- }
-}
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
-/* handle alpha and tRNS via a background color */
-void
-png_set_background(png_structp png_ptr,
- png_color_16p background_color, int background_gamma_code,
- int need_expand, double background_gamma)
-{
- png_debug(1, "in png_set_background\n");
- if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
- {
- png_warning(png_ptr, "Application must supply a known background gamma");
- return;
- }
-
- png_ptr->transformations |= PNG_BACKGROUND;
- png_memcpy(&(png_ptr->background), background_color, sizeof(png_color_16));
- png_ptr->background_gamma = (float)background_gamma;
- png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
- png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
-
- /* Note: if need_expand is set and color_type is either RGB or RGB_ALPHA
- * (in which case need_expand is superfluous anyway), the background color
- * might actually be gray yet not be flagged as such. This is not a problem
- * for the current code, which uses PNG_FLAG_BACKGROUND_IS_GRAY only to
- * decide when to do the png_do_gray_to_rgb() transformation.
- */
- if ((need_expand && !(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) ||
- (!need_expand && background_color->red == background_color->green &&
- background_color->red == background_color->blue))
- png_ptr->flags |= PNG_FLAG_BACKGROUND_IS_GRAY;
-}
-#endif
-
-#if defined(PNG_READ_16_TO_8_SUPPORTED)
-/* strip 16 bit depth files to 8 bit depth */
-void
-png_set_strip_16(png_structp png_ptr)
-{
- png_debug(1, "in png_set_strip_16\n");
- png_ptr->transformations |= PNG_16_TO_8;
-}
-#endif
-
-#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
-void
-png_set_strip_alpha(png_structp png_ptr)
-{
- png_debug(1, "in png_set_strip_alpha\n");
- png_ptr->transformations |= PNG_STRIP_ALPHA;
-}
-#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
- * of colors is greater then the maximum number, the palette will be
- * modified to fit in the maximum number. "full_dither" indicates
- * whether we need a dithering cube set up for RGB images, or if we
- * simply are reducing the number of colors in a paletted image.
- */
-
-typedef struct png_dsort_struct
-{
- struct png_dsort_struct FAR * next;
- png_byte left;
- png_byte right;
-} png_dsort;
-typedef png_dsort FAR * png_dsortp;
-typedef png_dsort FAR * FAR * png_dsortpp;
-
-void
-png_set_dither(png_structp png_ptr, png_colorp palette,
- int num_palette, int maximum_colors, png_uint_16p histogram,
- int full_dither)
-{
- png_debug(1, "in png_set_dither\n");
- png_ptr->transformations |= PNG_DITHER;
-
- if (!full_dither)
- {
- int i;
-
- png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)(num_palette * sizeof (png_byte)));
- for (i = 0; i < num_palette; i++)
- png_ptr->dither_index[i] = (png_byte)i;
- }
-
- if (num_palette > maximum_colors)
- {
- if (histogram != NULL)
- {
- /* This is easy enough, just throw out the least used colors.
- Perhaps not the best solution, but good enough. */
-
- int i;
- png_bytep sort;
-
- /* initialize an array to sort colors */
- sort = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_palette
- * sizeof (png_byte)));
-
- /* initialize the sort array */
- for (i = 0; i < num_palette; i++)
- sort[i] = (png_byte)i;
-
- /* Find the least used palette entries by starting a
- bubble sort, and running it until we have sorted
- out enough colors. Note that we don't care about
- sorting all the colors, just finding which are
- least used. */
-
- for (i = num_palette - 1; i >= maximum_colors; i--)
- {
- int done; /* to stop early if the list is pre-sorted */
- int j;
-
- done = 1;
- for (j = 0; j < i; j++)
- {
- if (histogram[sort[j]] < histogram[sort[j + 1]])
- {
- png_byte t;
-
- t = sort[j];
- sort[j] = sort[j + 1];
- sort[j + 1] = t;
- done = 0;
- }
- }
- if (done)
- break;
- }
-
- /* swap the palette around, and set up a table, if necessary */
- if (full_dither)
- {
- int j = num_palette;
-
- /* put all the useful colors within the max, but don't
- move the others */
- for (i = 0; i < maximum_colors; i++)
- {
- if ((int)sort[i] >= maximum_colors)
- {
- do
- j--;
- while ((int)sort[j] >= maximum_colors);
- palette[i] = palette[j];
- }
- }
- }
- else
- {
- int j = num_palette;
-
- /* move all the used colors inside the max limit, and
- develop a translation table */
- for (i = 0; i < maximum_colors; i++)
- {
- /* only move the colors we need to */
- if ((int)sort[i] >= maximum_colors)
- {
- png_color tmp_color;
-
- do
- j--;
- while ((int)sort[j] >= maximum_colors);
-
- tmp_color = palette[j];
- palette[j] = palette[i];
- palette[i] = tmp_color;
- /* indicate where the color went */
- png_ptr->dither_index[j] = (png_byte)i;
- png_ptr->dither_index[i] = (png_byte)j;
- }
- }
-
- /* find closest color for those colors we are not using */
- for (i = 0; i < num_palette; i++)
- {
- if ((int)png_ptr->dither_index[i] >= maximum_colors)
- {
- int min_d, k, min_k, d_index;
-
- /* find the closest color to one we threw out */
- d_index = png_ptr->dither_index[i];
- min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
- for (k = 1, min_k = 0; k < maximum_colors; k++)
- {
- int d;
-
- d = PNG_COLOR_DIST(palette[d_index], palette[k]);
-
- if (d < min_d)
- {
- min_d = d;
- min_k = k;
- }
- }
- /* point to closest color */
- png_ptr->dither_index[i] = (png_byte)min_k;
- }
- }
- }
- png_free(png_ptr, sort);
- }
- else
- {
- /* This is much harder to do simply (and quickly). Perhaps
- we need to go through a median cut routine, but those
- don't always behave themselves with only a few colors
- as input. So we will just find the closest two colors,
- and throw out one of them (chosen somewhat randomly).
- [We don't understand this at all, so if someone wants to
- work on improving it, be our guest - AED, GRP]
- */
- int i;
- int max_d;
- int num_new_palette;
- png_dsortpp hash;
- png_bytep index_to_palette;
- /* where the original index currently is in the palette */
- png_bytep palette_to_index;
- /* which original index points to this palette color */
-
- /* initialize palette index arrays */
- index_to_palette = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)(num_palette * sizeof (png_byte)));
- palette_to_index = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)(num_palette * sizeof (png_byte)));
-
- /* initialize the sort array */
- for (i = 0; i < num_palette; i++)
- {
- index_to_palette[i] = (png_byte)i;
- palette_to_index[i] = (png_byte)i;
- }
-
- hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 *
- sizeof (png_dsortp)));
- for (i = 0; i < 769; i++)
- hash[i] = NULL;
-/* png_memset(hash, 0, 769 * sizeof (png_dsortp)); */
-
- num_new_palette = num_palette;
-
- /* initial wild guess at how far apart the farthest pixel
- pair we will be eliminating will be. Larger
- numbers mean more areas will be allocated, Smaller
- numbers run the risk of not saving enough data, and
- having to do this all over again.
-
- I have not done extensive checking on this number.
- */
- max_d = 96;
-
- while (num_new_palette > maximum_colors)
- {
- for (i = 0; i < num_new_palette - 1; i++)
- {
- int j;
-
- for (j = i + 1; j < num_new_palette; j++)
- {
- int d;
-
- d = PNG_COLOR_DIST(palette[i], palette[j]);
-
- if (d <= max_d)
- {
- png_dsortp t;
-
- t = (png_dsortp)png_malloc(png_ptr, (png_uint_32)(sizeof
- (png_dsort)));
- t->next = hash[d];
- t->left = (png_byte)i;
- t->right = (png_byte)j;
- hash[d] = t;
- }
- }
- }
-
- for (i = 0; i <= max_d; i++)
- {
- if (hash[i] != NULL)
- {
- png_dsortp p;
-
- for (p = hash[i]; p; p = p->next)
- {
- if ((int)index_to_palette[p->left] < num_new_palette &&
- (int)index_to_palette[p->right] < num_new_palette)
- {
- int j, next_j;
-
- if (num_new_palette & 1)
- {
- j = p->left;
- next_j = p->right;
- }
- else
- {
- j = p->right;
- next_j = p->left;
- }
-
- num_new_palette--;
- palette[index_to_palette[j]] = palette[num_new_palette];
- if (!full_dither)
- {
- int k;
-
- for (k = 0; k < num_palette; k++)
- {
- if (png_ptr->dither_index[k] ==
- index_to_palette[j])
- png_ptr->dither_index[k] =
- index_to_palette[next_j];
- if ((int)png_ptr->dither_index[k] ==
- num_new_palette)
- png_ptr->dither_index[k] =
- index_to_palette[j];
- }
- }
-
- index_to_palette[palette_to_index[num_new_palette]] =
- index_to_palette[j];
- palette_to_index[index_to_palette[j]] =
- palette_to_index[num_new_palette];
-
- index_to_palette[j] = (png_byte)num_new_palette;
- palette_to_index[num_new_palette] = (png_byte)j;
- }
- if (num_new_palette <= maximum_colors)
- break;
- }
- if (num_new_palette <= maximum_colors)
- break;
- }
- }
-
- for (i = 0; i < 769; i++)
- {
- if (hash[i] != NULL)
- {
- png_dsortp p = hash[i];
- while (p)
- {
- png_dsortp t;
-
- t = p->next;
- png_free(png_ptr, p);
- p = t;
- }
- }
- hash[i] = 0;
- }
- max_d += 96;
- }
- png_free(png_ptr, hash);
- png_free(png_ptr, palette_to_index);
- png_free(png_ptr, index_to_palette);
- }
- num_palette = maximum_colors;
- }
- if (png_ptr->palette == NULL)
- {
- png_ptr->palette = palette;
- }
- png_ptr->num_palette = (png_uint_16)num_palette;
-
- if (full_dither)
- {
- int i;
- png_bytep distance;
- int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
- PNG_DITHER_BLUE_BITS;
- int num_red = (1 << PNG_DITHER_RED_BITS);
- int num_green = (1 << PNG_DITHER_GREEN_BITS);
- int num_blue = (1 << PNG_DITHER_BLUE_BITS);
- png_size_t num_entries = ((png_size_t)1 << total_bits);
-
- png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr,
- (png_uint_32)(num_entries * sizeof (png_byte)));
-
- png_memset(png_ptr->palette_lookup, 0, num_entries * sizeof (png_byte));
-
- distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
- sizeof(png_byte)));
-
- png_memset(distance, 0xff, num_entries * sizeof(png_byte));
-
- for (i = 0; i < num_palette; i++)
- {
- int ir, ig, ib;
- int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
- int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
- int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
-
- for (ir = 0; ir < num_red; ir++)
- {
- int dr = abs(ir - r);
- int index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS));
-
- for (ig = 0; ig < num_green; ig++)
- {
- int dg = abs(ig - g);
- int dt = dr + dg;
- int dm = ((dr > dg) ? dr : dg);
- int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
-
- for (ib = 0; ib < num_blue; ib++)
- {
- int d_index = index_g | ib;
- int db = abs(ib - b);
- int dmax = ((dm > db) ? dm : db);
- int d = dmax + dt + db;
-
- if (d < (int)distance[d_index])
- {
- distance[d_index] = (png_byte)d;
- png_ptr->palette_lookup[d_index] = (png_byte)i;
- }
- }
- }
- }
- }
-
- png_free(png_ptr, distance);
- }
-}
-#endif
-
-#if defined(PNG_READ_GAMMA_SUPPORTED)
-/* Transform the image from the file_gamma to the screen_gamma. We
- * only do transformations on images where the file_gamma and screen_gamma
- * are not close reciprocals, otherwise it slows things down slightly, and
- * also needlessly introduces small errors.
- */
-void
-png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
-{
- png_debug(1, "in png_set_gamma\n");
- if (fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD)
- png_ptr->transformations |= PNG_GAMMA;
- png_ptr->gamma = (float)file_gamma;
- png_ptr->screen_gamma = (float)scrn_gamma;
-}
-#endif
-
-#if defined(PNG_READ_EXPAND_SUPPORTED)
-/* Expand paletted images to rgb, expand grayscale images of
- * less than 8 bit depth to 8 bit depth, and expand tRNS chunks
- * to alpha channels.
- */
-void
-png_set_expand(png_structp png_ptr)
-{
- png_debug(1, "in png_set_expand\n");
- png_ptr->transformations |= PNG_EXPAND;
-}
-#endif
-
-#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
-void
-png_set_gray_to_rgb(png_structp png_ptr)
-{
- png_debug(1, "in png_set_gray_to_rgb\n");
- png_ptr->transformations |= PNG_GRAY_TO_RGB;
-}
-#endif
-
-#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-/* Convert a RGB image to a grayscale of the same width. This allows us,
- * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
- */
-void
-png_set_rgb_to_gray(png_structp png_ptr, int error_action, float red,
- float green)
-{
- png_debug(1, "in png_set_rgb_to_gray\n");
- switch(error_action)
- {
- case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY;
- break;
- case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
- break;
- case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
- }
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-#if defined(PNG_READ_EXPAND_SUPPORTED)
- png_ptr->transformations |= PNG_EXPAND;
-#else
- {
- png_warning(png_ptr, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
- png_ptr->transformations &= ~PNG_RGB_TO_GRAY;
- }
-#endif
- {
- png_byte red_byte = (png_byte)(red*255.0 + 0.5);
- png_byte green_byte = (png_byte)(green*255.0 + 0.5);
- if(red < 0.0 || green < 0.0)
- {
- red_byte = 54;
- green_byte = 183;
- }
- else if(red_byte + green_byte > 255)
- {
- png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
- red_byte = 54;
- green_byte = 183;
- }
- png_ptr->rgb_to_gray_red_coeff = red_byte;
- png_ptr->rgb_to_gray_green_coeff = green_byte;
- png_ptr->rgb_to_gray_blue_coeff = 255 - red_byte - green_byte;
- }
-}
-#endif
-
-#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
-void
-png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
- read_user_transform_fn)
-{
- png_debug(1, "in png_set_read_user_transform_fn\n");
- png_ptr->transformations |= PNG_USER_TRANSFORM;
- png_ptr->read_user_transform_fn = read_user_transform_fn;
-}
-#endif
-
-/* Initialize everything needed for the read. This includes modifying
- * the palette.
- */
-void
-png_init_read_transformations(png_structp png_ptr)
-{
- png_debug(1, "in png_init_read_transformations\n");
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if(png_ptr != NULL)
-#endif
- {
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
- || defined(PNG_READ_GAMMA_SUPPORTED)
- int color_type = png_ptr->color_type;
-#endif
-
-#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->transformations & PNG_BACKGROUND_EXPAND)
- {
- if (!(color_type & PNG_COLOR_MASK_COLOR)) /* i.e., GRAY or GRAY_ALPHA */
- {
- /* expand background chunk. */
- switch (png_ptr->bit_depth)
- {
- case 1:
- png_ptr->background.gray *= (png_uint_16)0xff;
- png_ptr->background.red = png_ptr->background.green =
- png_ptr->background.blue = png_ptr->background.gray;
- break;
- case 2:
- png_ptr->background.gray *= (png_uint_16)0x55;
- png_ptr->background.red = png_ptr->background.green =
- png_ptr->background.blue = png_ptr->background.gray;
- break;
- case 4:
- png_ptr->background.gray *= (png_uint_16)0x11;
- png_ptr->background.red = png_ptr->background.green =
- png_ptr->background.blue = png_ptr->background.gray;
- break;
- case 8:
- case 16:
- png_ptr->background.red = png_ptr->background.green =
- png_ptr->background.blue = png_ptr->background.gray;
- break;
- }
- }
- else if (color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_ptr->background.red =
- png_ptr->palette[png_ptr->background.index].red;
- png_ptr->background.green =
- png_ptr->palette[png_ptr->background.index].green;
- png_ptr->background.blue =
- png_ptr->palette[png_ptr->background.index].blue;
-
-#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
- if (png_ptr->transformations & PNG_INVERT_ALPHA)
- {
-#if defined(PNG_READ_EXPAND_SUPPORTED)
- if (!(png_ptr->transformations & PNG_EXPAND))
-#endif
- {
- /* invert the alpha channel (in tRNS) unless the pixels are
- going to be expanded, in which case leave it for later */
- int i,istop;
- istop=(int)png_ptr->num_trans;
- for (i=0; i<istop; i++)
- png_ptr->trans[i] = 255 - png_ptr->trans[i];
- }
- }
-#endif
-
- }
- }
-#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_RGB_TO_GRAY))
- {
- png_build_gamma_table(png_ptr);
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->transformations & PNG_BACKGROUND)
- {
- if (color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_color back, back_1;
- png_colorp palette = png_ptr->palette;
- int num_palette = png_ptr->num_palette;
- int i;
-
- if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
- {
- back.red = png_ptr->gamma_table[png_ptr->background.red];
- back.green = png_ptr->gamma_table[png_ptr->background.green];
- back.blue = png_ptr->gamma_table[png_ptr->background.blue];
-
- back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
- back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
- back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
- }
- else
- {
- double g, gs;
-
- switch (png_ptr->background_gamma_type)
- {
- case PNG_BACKGROUND_GAMMA_SCREEN:
- g = (png_ptr->screen_gamma);
- gs = 1.0;
- break;
- case PNG_BACKGROUND_GAMMA_FILE:
- g = 1.0 / (png_ptr->gamma);
- gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
- break;
- case PNG_BACKGROUND_GAMMA_UNIQUE:
- g = 1.0 / (png_ptr->background_gamma);
- gs = 1.0 / (png_ptr->background_gamma *
- png_ptr->screen_gamma);
- break;
- default:
- g = 1.0; /* back_1 */
- gs = 1.0; /* back */
- }
-
- if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD)
- {
- back.red = (png_byte)png_ptr->background.red;
- back.green = (png_byte)png_ptr->background.green;
- back.blue = (png_byte)png_ptr->background.blue;
- }
- else
- {
- back.red = (png_byte)(pow(
- (double)png_ptr->background.red/255, gs) * 255.0 + .5);
- back.green = (png_byte)(pow(
- (double)png_ptr->background.green/255, gs) * 255.0 + .5);
- back.blue = (png_byte)(pow(
- (double)png_ptr->background.blue/255, gs) * 255.0 + .5);
- }
-
- back_1.red = (png_byte)(pow(
- (double)png_ptr->background.red/255, g) * 255.0 + .5);
- back_1.green = (png_byte)(pow(
- (double)png_ptr->background.green/255, g) * 255.0 + .5);
- back_1.blue = (png_byte)(pow(
- (double)png_ptr->background.blue/255, g) * 255.0 + .5);
- }
-
- for (i = 0; i < num_palette; i++)
- {
- if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
- {
- if (png_ptr->trans[i] == 0)
- {
- palette[i] = back;
- }
- else /* if (png_ptr->trans[i] != 0xff) */
- {
- png_byte v, w;
-
- v = png_ptr->gamma_to_1[palette[i].red];
- png_composite(w, v, png_ptr->trans[i], back_1.red);
- palette[i].red = png_ptr->gamma_from_1[w];
-
- v = png_ptr->gamma_to_1[palette[i].green];
- png_composite(w, v, png_ptr->trans[i], back_1.green);
- palette[i].green = png_ptr->gamma_from_1[w];
-
- v = png_ptr->gamma_to_1[palette[i].blue];
- png_composite(w, v, png_ptr->trans[i], back_1.blue);
- palette[i].blue = png_ptr->gamma_from_1[w];
- }
- }
- else
- {
- palette[i].red = png_ptr->gamma_table[palette[i].red];
- palette[i].green = png_ptr->gamma_table[palette[i].green];
- palette[i].blue = png_ptr->gamma_table[palette[i].blue];
- }
- }
- }
- /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN)*/
- else
- /* color_type != PNG_COLOR_TYPE_PALETTE */
- {
- double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
- double g = 1.0;
- double gs = 1.0;
-
- switch (png_ptr->background_gamma_type)
- {
- case PNG_BACKGROUND_GAMMA_SCREEN:
- g = (png_ptr->screen_gamma);
- gs = 1.0;
- break;
- case PNG_BACKGROUND_GAMMA_FILE:
- g = 1.0 / (png_ptr->gamma);
- gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
- break;
- case PNG_BACKGROUND_GAMMA_UNIQUE:
- g = 1.0 / (png_ptr->background_gamma);
- gs = 1.0 / (png_ptr->background_gamma *
- png_ptr->screen_gamma);
- break;
- }
-
- if (color_type & PNG_COLOR_MASK_COLOR)
- {
- /* RGB or RGBA */
- png_ptr->background_1.red = (png_uint_16)(pow(
- (double)png_ptr->background.red / m, g) * m + .5);
- png_ptr->background_1.green = (png_uint_16)(pow(
- (double)png_ptr->background.green / m, g) * m + .5);
- png_ptr->background_1.blue = (png_uint_16)(pow(
- (double)png_ptr->background.blue / m, g) * m + .5);
- png_ptr->background.red = (png_uint_16)(pow(
- (double)png_ptr->background.red / m, gs) * m + .5);
- png_ptr->background.green = (png_uint_16)(pow(
- (double)png_ptr->background.green / m, gs) * m + .5);
- png_ptr->background.blue = (png_uint_16)(pow(
- (double)png_ptr->background.blue / m, gs) * m + .5);
- }
- else
- {
- /* GRAY or GRAY ALPHA */
- png_ptr->background_1.gray = (png_uint_16)(pow(
- (double)png_ptr->background.gray / m, g) * m + .5);
- png_ptr->background.gray = (png_uint_16)(pow(
- (double)png_ptr->background.gray / m, gs) * m + .5);
- }
- }
- }
- else
- /* transformation does not include PNG_BACKGROUND */
-#endif
- if (color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_colorp palette = png_ptr->palette;
- int num_palette = png_ptr->num_palette;
- int i;
-
- for (i = 0; i < num_palette; i++)
- {
- palette[i].red = png_ptr->gamma_table[palette[i].red];
- palette[i].green = png_ptr->gamma_table[palette[i].green];
- palette[i].blue = png_ptr->gamma_table[palette[i].blue];
- }
- }
- }
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
- else
-#endif
-#endif
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
- /* No GAMMA transformation */
- if (png_ptr->transformations & PNG_BACKGROUND &&
- color_type == PNG_COLOR_TYPE_PALETTE)
- {
- int i;
- int istop = (int)png_ptr->num_trans;
- png_color back;
- png_colorp palette = png_ptr->palette;
-
- back.red = (png_byte)png_ptr->background.red;
- back.green = (png_byte)png_ptr->background.green;
- back.blue = (png_byte)png_ptr->background.blue;
-
- for (i = 0; i < istop; i++)
- {
- if (png_ptr->trans[i] == 0)
- {
- palette[i] = back;
- }
- else if (png_ptr->trans[i] != 0xff)
- {
- /* The png_composite() macro is defined in png.h */
- png_composite(palette[i].red, palette[i].red,
- png_ptr->trans[i], back.red);
- png_composite(palette[i].green, palette[i].green,
- png_ptr->trans[i], back.green);
- png_composite(palette[i].blue, palette[i].blue,
- png_ptr->trans[i], back.blue);
- }
- }
- }
-#endif
-
-#if defined(PNG_READ_SHIFT_SUPPORTED)
- if ((png_ptr->transformations & PNG_SHIFT) &&
- color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_uint_16 i;
- png_uint_16 istop = png_ptr->num_palette;
- int sr = 8 - png_ptr->sig_bit.red;
- int sg = 8 - png_ptr->sig_bit.green;
- int sb = 8 - png_ptr->sig_bit.blue;
-
- if (sr < 0 || sr > 8)
- sr = 0;
- if (sg < 0 || sg > 8)
- sg = 0;
- if (sb < 0 || sb > 8)
- sb = 0;
- for (i = 0; i < istop; 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_structp png_ptr, png_infop info_ptr)
-{
- png_debug(1, "in png_read_transform_info\n");
-#if defined(PNG_READ_EXPAND_SUPPORTED)
- if (png_ptr->transformations & PNG_EXPAND)
- {
- if (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->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_GAMMA_SUPPORTED)
- if (png_ptr->transformations & PNG_GAMMA)
- info_ptr->gamma = png_ptr->gamma;
-#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;
-#endif
-
-#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
- if (png_ptr->transformations & PNG_RGB_TO_GRAY)
- 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 defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
- if (png_ptr->transformations & PNG_STRIP_ALPHA)
- info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
-#endif
-
- if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
- info_ptr->channels++;
-
-#if defined(PNG_READ_FILLER_SUPPORTED)
- /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
- if (png_ptr->transformations & PNG_FILLER &&
- (info_ptr->color_type == PNG_COLOR_TYPE_RGB ||
- info_ptr->color_type == PNG_COLOR_TYPE_GRAY))
- ++info_ptr->channels;
-#endif
-
- info_ptr->pixel_depth = (png_byte)(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,
- * and is very touchy. If you add a transformation, take care to
- * decide how it fits in with the other transformations here.
- */
-void
-png_do_read_transformations(png_structp png_ptr)
-{
- png_debug(1, "in png_do_read_transformations\n");
-#if !defined(PNG_USELESS_TESTS_SUPPORTED)
- if (png_ptr->row_buf == NULL)
- {
-#if !defined(PNG_NO_STDIO)
- char msg[50];
-
- sprintf(msg, "NULL row buffer for row %ld, pass %d", png_ptr->row_number,
- png_ptr->pass);
- png_error(png_ptr, msg);
-#else
- png_error(png_ptr, "NULL row buffer");
-#endif
- }
-#endif
-
-#if defined(PNG_READ_EXPAND_SUPPORTED)
- if (png_ptr->transformations & PNG_EXPAND)
- {
- if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
- png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
- }
- else
- {
- if (png_ptr->num_trans)
- png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
- &(png_ptr->trans_values));
- else
- png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
- NULL);
- }
- }
-#endif
-
-#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
- if (png_ptr->transformations & PNG_STRIP_ALPHA)
- png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
- PNG_FLAG_FILLER_AFTER);
-#endif
-
-#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
- if (png_ptr->transformations & PNG_RGB_TO_GRAY)
- {
- int rgb_error =
- png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1);
- if(rgb_error)
- {
- png_ptr->rgb_to_gray_status=1;
- if(png_ptr->transformations == PNG_RGB_TO_GRAY_WARN)
- png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
- if(png_ptr->transformations == PNG_RGB_TO_GRAY_ERR)
- png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
- }
- }
-#endif
-
-/*
-From Andreas Dilger e-mail to png-implement, 26 March 1998:
-
- In most cases, the "simple transparency" should be done prior to doing
- gray-to-RGB, or you will have to test 3x as many bytes to check if a
- pixel is transparent. You would also need to make sure that the
- transparency information is upgraded to RGB.
-
- To summarize, the current flow is:
- - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
- with background "in place" if transparent,
- convert to RGB if necessary
- - Gray + alpha -> composite with gray background and remove alpha bytes,
- convert to RGB if necessary
-
- To support RGB backgrounds for gray images we need:
- - Gray + simple transparency -> convert to RGB + simple transparency, compare
- 3 or 6 bytes and composite with background
- "in place" if transparent (3x compare/pixel
- compared to doing composite with gray bkgrnd)
- - Gray + alpha -> convert to RGB + alpha, composite with background and
- remove alpha bytes (3x float operations/pixel
- compared with composite on gray background)
-
- Greg's change will do this. The reason it wasn't done before is for
- performance, as this increases the per-pixel operations. If we would check
- in advance if the background was gray or RGB, and position the gray-to-RGB
- transform appropriately, then it would save a lot of work/time.
- */
-
-#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
- /* if gray -> RGB, do so now only if background is non-gray; else do later
- * for performance reasons */
- if (png_ptr->transformations & PNG_GRAY_TO_RGB &&
- !(png_ptr->flags & PNG_FLAG_BACKGROUND_IS_GRAY))
- png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
-#endif
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
- if ((png_ptr->transformations & PNG_BACKGROUND) &&
- ((png_ptr->num_trans != 0 ) ||
- (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)))
- png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
- &(png_ptr->trans_values), &(png_ptr->background),
- &(png_ptr->background_1),
- png_ptr->gamma_table, png_ptr->gamma_from_1,
- 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);
-#endif
-
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if ((png_ptr->transformations & PNG_GAMMA) &&
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
- !((png_ptr->transformations & PNG_BACKGROUND) &&
- ((png_ptr->num_trans != 0) ||
- (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
-#endif
- (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
- 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_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1,
- png_ptr->palette_lookup, png_ptr->dither_index);
- if(png_ptr->row_info.rowbytes == (png_uint_32)0)
- png_error(png_ptr, "png_do_dither returned rowbytes=0");
- }
-#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_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
-#endif
-
-#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
- /* if gray -> RGB, do so now only if we did not do so above */
- if (png_ptr->transformations & PNG_GRAY_TO_RGB &&
- png_ptr->flags & PNG_FLAG_BACKGROUND_IS_GRAY)
- png_do_gray_to_rgb(&(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_uint_32)png_ptr->filler, png_ptr->flags);
-#endif
-
-#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
- if (png_ptr->transformations & PNG_INVERT_ALPHA)
- png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
-#endif
-
-#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
- if (png_ptr->transformations & PNG_SWAP_ALPHA)
- png_do_read_swap_alpha(&(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);
-#endif
-
-#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
- if (png_ptr->transformations & PNG_USER_TRANSFORM)
- if(png_ptr->read_user_transform_fn != NULL)
- (*(png_ptr->read_user_transform_fn)) /* user read transform function */
- (png_ptr, /* png_ptr */
- &(png_ptr->row_info), /* row_info: */
- /* png_uint_32 width; width of row */
- /* png_uint_32 rowbytes; number of bytes in row */
- /* png_byte color_type; color type of pixels */
- /* png_byte bit_depth; bit depth of samples */
- /* png_byte channels; number of channels (1-4) */
- /* png_byte pixel_depth; bits per pixel (depth*channels) */
- png_ptr->row_buf + 1); /* start of pixel data for row */
-#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_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_unpack\n");
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL && row_info->bit_depth < 8)
-#else
- if (row_info->bit_depth < 8)
-#endif
- {
- png_uint_32 i;
- png_uint_32 row_width=row_info->width;
-
- switch (row_info->bit_depth)
- {
- case 1:
- {
- png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
- png_bytep dp = row + (png_size_t)row_width - 1;
- png_uint_32 shift = 7 - (int)((row_width + 7) & 7);
- for (i = 0; i < row_width; i++)
- {
- *dp = (png_byte)((*sp >> shift) & 0x1);
- if (shift == 7)
- {
- shift = 0;
- sp--;
- }
- else
- shift++;
-
- dp--;
- }
- break;
- }
- case 2:
- {
-
- png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
- png_bytep dp = row + (png_size_t)row_width - 1;
- png_uint_32 shift = (int)((3 - ((row_width + 3) & 3)) << 1);
- for (i = 0; i < row_width; i++)
- {
- *dp = (png_byte)((*sp >> shift) & 0x3);
- if (shift == 6)
- {
- shift = 0;
- sp--;
- }
- else
- shift += 2;
-
- dp--;
- }
- break;
- }
- case 4:
- {
- png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
- png_bytep dp = row + (png_size_t)row_width - 1;
- png_uint_32 shift = (int)((1 - ((row_width + 1) & 1)) << 2);
- for (i = 0; i < row_width; i++)
- {
- *dp = (png_byte)((*sp >> shift) & 0xf);
- if (shift == 4)
- {
- shift = 0;
- sp--;
- }
- else
- shift = 4;
-
- dp--;
- }
- break;
- }
- }
- row_info->bit_depth = 8;
- row_info->pixel_depth = (png_byte)(8 * row_info->channels);
- row_info->rowbytes = row_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_infop row_info, png_bytep row, png_color_8p sig_bits)
-{
- png_debug(1, "in png_do_unshift\n");
- if (
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL && sig_bits != NULL &&
-#endif
- row_info->color_type != PNG_COLOR_TYPE_PALETTE)
- {
- int shift[4];
- int channels = 0;
- int c;
- png_uint_16 value = 0;
- png_uint_32 row_width = row_info->width;
-
- if (row_info->color_type & PNG_COLOR_MASK_COLOR)
- {
- shift[channels++] = row_info->bit_depth - sig_bits->red;
- shift[channels++] = row_info->bit_depth - sig_bits->green;
- shift[channels++] = row_info->bit_depth - sig_bits->blue;
- }
- else
- {
- shift[channels++] = row_info->bit_depth - sig_bits->gray;
- }
- if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
- {
- shift[channels++] = row_info->bit_depth - sig_bits->alpha;
- }
-
- for (c = 0; c < channels; c++)
- {
- if (shift[c] <= 0)
- shift[c] = 0;
- else
- value = 1;
- }
-
- if (!value)
- return;
-
- switch (row_info->bit_depth)
- {
- case 2:
- {
- png_bytep bp;
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
-
- for (bp = row, i = 0; i < istop; i++)
- {
- *bp >>= 1;
- *bp++ &= 0x55;
- }
- break;
- }
- case 4:
- {
- png_bytep bp = row;
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
- png_byte mask = (png_byte)(((int)0xf0 >> shift[0]) & (int)0xf0) |
- (png_byte)((int)0xf >> shift[0]);
-
- for (i = 0; i < istop; i++)
- {
- *bp >>= shift[0];
- *bp++ &= mask;
- }
- break;
- }
- case 8:
- {
- png_bytep bp = row;
- png_uint_32 i;
- png_uint_32 istop = row_width * channels;
-
- for (i = 0; i < istop; i++)
- {
- *bp++ >>= shift[i%channels];
- }
- break;
- }
- case 16:
- {
- png_bytep bp = row;
- png_uint_32 i;
- png_uint_32 istop = channels * row_width;
-
- for (i = 0; i < istop; i++)
- {
- value = (png_uint_16)((*bp << 8) + *(bp + 1));
- value >>= shift[i%channels];
- *bp++ = (png_byte)(value >> 8);
- *bp++ = (png_byte)(value & 0xff);
- }
- break;
- }
- }
- }
-}
-#endif
-
-#if defined(PNG_READ_16_TO_8_SUPPORTED)
-/* chop rows of bit depth 16 down to 8 */
-void
-png_do_chop(png_row_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_chop\n");
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL && row_info->bit_depth == 16)
-#else
- if (row_info->bit_depth == 16)
-#endif
- {
- png_bytep sp = row;
- png_bytep dp = row;
- png_uint_32 i;
- png_uint_32 istop = row_info->width * row_info->channels;
-
- for (i = 0; i<istop; i++, sp += 2, dp++)
- {
-#if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
- /* This does a more accurate scaling of the 16-bit color
- * value, rather than a simple low-byte truncation.
- *
- * What the ideal calculation should be:
- * *dp = (((((png_uint_32)(*sp) << 8) |
- * (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L;
- *
- * GRR: no, I think this is what it really should be:
- * *dp = (((((png_uint_32)(*sp) << 8) |
- * (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L;
- *
- * GRR: here's the exact calculation with shifts:
- * temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L;
- * *dp = (temp - (temp >> 8)) >> 8;
- *
- * Approximate calculation with shift/add instead of multiply/divide:
- * *dp = ((((png_uint_32)(*sp) << 8) |
- * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
- *
- * What we actually do to avoid extra shifting and conversion:
- */
-
- *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0);
-#else
- /* Simply discard the low order byte */
- *dp = *sp;
-#endif
- }
- row_info->bit_depth = 8;
- row_info->pixel_depth = (png_byte)(8 * row_info->channels);
- row_info->rowbytes = row_info->width * row_info->channels;
- }
-}
-#endif
-
-#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
-void
-png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_read_swap_alpha\n");
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL)
-#endif
- {
- png_uint_32 row_width = row_info->width;
- if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- {
- /* This converts from RGBA to ARGB */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_byte save;
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- save = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = save;
- }
- }
- /* This converts from RRGGBBAA to AARRGGBB */
- else
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_byte save[2];
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- save[0] = *(--sp);
- save[1] = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = save[0];
- *(--dp) = save[1];
- }
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- {
- /* This converts from GA to AG */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_byte save;
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- save = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = save;
- }
- }
- /* This converts from GGAA to AAGG */
- else
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_byte save[2];
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- save[0] = *(--sp);
- save[1] = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = save[0];
- *(--dp) = save[1];
- }
- }
- }
- }
-}
-#endif
-
-#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
-void
-png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_read_invert_alpha\n");
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL)
-#endif
- {
- png_uint_32 row_width = row_info->width;
- if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- {
- /* This inverts the alpha channel in RGBA */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = 255 - *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- }
- }
- /* This inverts the alpha channel in RRGGBBAA */
- else
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = 255 - *(--sp);
- *(--dp) = 255 - *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- }
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- {
- /* This inverts the alpha channel in GA */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = 255 - *(--sp);
- *(--dp) = *(--sp);
- }
- }
- /* This inverts the alpha channel in GGAA */
- else
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = 255 - *(--sp);
- *(--dp) = 255 - *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- }
- }
- }
- }
-}
-#endif
-
-#if defined(PNG_READ_FILLER_SUPPORTED)
-/* Add filler channel if we have RGB color */
-void
-png_do_read_filler(png_row_infop row_info, png_bytep row,
- png_uint_32 filler, png_uint_32 flags)
-{
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
- png_byte lo_filler = (png_byte)(filler & 0xff);
-
- png_debug(1, "in png_do_read_filler\n");
- if (
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
-#endif
- row_info->color_type == PNG_COLOR_TYPE_GRAY)
- {
- if(row_info->bit_depth == 8)
- {
- /* This changes the data from G to GX */
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- png_bytep sp = row + (png_size_t)row_width;
- png_bytep dp = sp + (png_size_t)row_width;
- for (i = 1; i < row_width; i++)
- {
- *(--dp) = lo_filler;
- *(--dp) = *(--sp);
- }
- *(--dp) = lo_filler;
- row_info->channels = 2;
- row_info->pixel_depth = 16;
- row_info->rowbytes = row_width * 2;
- }
- /* This changes the data from G to XG */
- else
- {
- png_bytep sp = row + (png_size_t)row_width;
- png_bytep dp = sp + (png_size_t)row_width;
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = *(--sp);
- *(--dp) = lo_filler;
- }
- row_info->channels = 2;
- row_info->pixel_depth = 16;
- row_info->rowbytes = row_width * 2;
- }
- }
- else if(row_info->bit_depth == 16)
- {
- /* This changes the data from GG to GGXX */
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- png_bytep sp = row + (png_size_t)row_width;
- png_bytep dp = sp + (png_size_t)row_width;
- for (i = 1; i < row_width; i++)
- {
- *(--dp) = hi_filler;
- *(--dp) = lo_filler;
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- }
- *(--dp) = hi_filler;
- *(--dp) = lo_filler;
- row_info->channels = 2;
- row_info->pixel_depth = 32;
- row_info->rowbytes = row_width * 2;
- }
- /* This changes the data from GG to XXGG */
- else
- {
- png_bytep sp = row + (png_size_t)row_width;
- png_bytep dp = sp + (png_size_t)row_width;
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = hi_filler;
- *(--dp) = lo_filler;
- }
- row_info->channels = 2;
- row_info->pixel_depth = 16;
- row_info->rowbytes = row_width * 2;
- }
- }
- } /* COLOR_TYPE == GRAY */
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- {
- if(row_info->bit_depth == 8)
- {
- /* This changes the data from RGB to RGBX */
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- png_bytep sp = row + (png_size_t)row_width * 3;
- png_bytep dp = sp + (png_size_t)row_width;
- for (i = 1; i < row_width; i++)
- {
- *(--dp) = lo_filler;
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- }
- *(--dp) = lo_filler;
- row_info->channels = 4;
- row_info->pixel_depth = 32;
- row_info->rowbytes = row_width * 4;
- }
- /* This changes the data from RGB to XRGB */
- else
- {
- png_bytep sp = row + (png_size_t)row_width * 3;
- png_bytep dp = sp + (png_size_t)row_width;
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = lo_filler;
- }
- row_info->channels = 4;
- row_info->pixel_depth = 32;
- row_info->rowbytes = row_width * 4;
- }
- }
- else if(row_info->bit_depth == 16)
- {
- /* This changes the data from RRGGBB to RRGGBBXX */
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- png_bytep sp = row + (png_size_t)row_width * 3;
- png_bytep dp = sp + (png_size_t)row_width;
- for (i = 1; i < row_width; i++)
- {
- *(--dp) = hi_filler;
- *(--dp) = lo_filler;
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- }
- *(--dp) = hi_filler;
- *(--dp) = lo_filler;
- row_info->channels = 4;
- row_info->pixel_depth = 64;
- row_info->rowbytes = row_width * 4;
- }
- /* This changes the data from RRGGBB to XXRRGGBB */
- else
- {
- png_bytep sp = row + (png_size_t)row_width * 3;
- png_bytep dp = sp + (png_size_t)row_width;
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = hi_filler;
- *(--dp) = lo_filler;
- }
- row_info->channels = 4;
- row_info->pixel_depth = 64;
- row_info->rowbytes = row_width * 4;
- }
- }
- } /* COLOR_TYPE == RGB */
-}
-#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_infop row_info, png_bytep row)
-{
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- png_debug(1, "in png_do_gray_to_rgb\n");
- if (row_info->bit_depth >= 8 &&
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
-#endif
- !(row_info->color_type & PNG_COLOR_MASK_COLOR))
- {
- if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
- {
- if (row_info->bit_depth == 8)
- {
- png_bytep sp = row + (png_size_t)row_width - 1;
- png_bytep dp = sp + (png_size_t)row_width * 2;
- for (i = 0; i < row_width; i++)
- {
- *(dp--) = *sp;
- *(dp--) = *sp;
- *(dp--) = *sp;
- sp--;
- }
- }
- else
- {
- png_bytep sp = row + (png_size_t)row_width * 2 - 1;
- png_bytep dp = sp + (png_size_t)row_width * 4;
- for (i = 0; i < row_width; i++)
- {
- *(dp--) = *sp;
- *(dp--) = *(sp - 1);
- *(dp--) = *sp;
- *(dp--) = *(sp - 1);
- *(dp--) = *sp;
- *(dp--) = *(sp - 1);
- sp--;
- sp--;
- }
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- {
- if (row_info->bit_depth == 8)
- {
- png_bytep sp = row + (png_size_t)row_width * 2 - 1;
- png_bytep dp = sp + (png_size_t)row_width * 2;
- for (i = 0; i < row_width; i++)
- {
- *(dp--) = *(sp--);
- *(dp--) = *sp;
- *(dp--) = *sp;
- *(dp--) = *sp;
- sp--;
- }
- }
- else
- {
- png_bytep sp = row + (png_size_t)row_width * 4 - 1;
- png_bytep dp = sp + (png_size_t)row_width * 4;
- for (i = 0; i < row_width; i++)
- {
- *(dp--) = *(sp--);
- *(dp--) = *(sp--);
- *(dp--) = *sp;
- *(dp--) = *(sp - 1);
- *(dp--) = *sp;
- *(dp--) = *(sp - 1);
- *(dp--) = *sp;
- *(dp--) = *(sp - 1);
- sp--;
- sp--;
- }
- }
- }
- row_info->channels += (png_byte)2;
- row_info->color_type |= PNG_COLOR_MASK_COLOR;
- row_info->pixel_depth = (png_byte)(row_info->channels *
- row_info->bit_depth);
- row_info->rowbytes = ((row_width *
- row_info->pixel_depth + 7) >> 3);
- }
-}
-#endif
-
-#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-/* reduce RGB files to grayscale, with or without alpha
- * using the equation given in Poynton's ColorFAQ at
- * <http://www.inforamp.net/~poynton/>
- * Copyright (c) 1998-01-04 Charles Poynton poynton@inforamp.net
- *
- * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
- *
- * We approximate this with
- *
- * Y = 0.211 * R + 0.715 * G + 0.074 * B
- *
- * which can be expressed with integers as
- *
- * Y = (54 * R + 183 * G + 19 * B)/256
- *
- * The calculation is to be done in a linear colorspace.
- *
- * Other integer coefficents can be used via png_set_rgb_to_gray().
- */
-int
-png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
-
-{
- png_uint_32 i;
-
- png_uint_32 row_width = row_info->width;
- int rgb_error = 0;
-
- png_debug(1, "in png_do_rgb_to_gray\n");
- if (
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
-#endif
- (row_info->color_type & PNG_COLOR_MASK_COLOR))
- {
- png_byte rc = png_ptr->rgb_to_gray_red_coeff;
- png_byte gc = png_ptr->rgb_to_gray_green_coeff;
- png_byte bc = png_ptr->rgb_to_gray_blue_coeff;
-
- if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- {
- if (row_info->bit_depth == 8)
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
- {
- png_bytep sp = row;
- png_bytep dp = row;
-
- for (i = 0; i < row_width; i++)
- {
- png_byte red = png_ptr->gamma_to_1[*(sp++)];
- png_byte green = png_ptr->gamma_to_1[*(sp++)];
- png_byte blue = png_ptr->gamma_to_1[*(sp++)];
- if(red != green || red != blue)
- {
- rgb_error |= 1;
- *(dp++) = png_ptr->gamma_from_1[
- (rc*red+gc*green+bc*blue)>>8];
- }
- else
- *(dp++) = *(sp-1);
- }
- }
- else
-#endif
- {
- png_bytep sp = row;
- png_bytep dp = row;
- for (i = 0; i < row_width; i++)
- {
- png_byte red = *(sp++);
- png_byte green = *(sp++);
- png_byte blue = *(sp++);
- if(red != green || red != blue)
- {
- rgb_error |= 1;
- *(dp++) = (rc*red+gc*green+bc*blue)>>8;
- }
- else
- *(dp++) = *(sp-1);
- }
- }
- }
-
- else /* RGB bit_depth == 16 */
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->gamma_16_to_1 != NULL &&
- png_ptr->gamma_16_from_1 != NULL)
- {
- png_bytep sp = row;
- png_bytep dp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 red, green, blue, w;
-
- red = ((*(sp))<<8) | *(sp+1); sp+=2;
- green = ((*(sp))<<8) | *(sp+1); sp+=2;
- blue = ((*(sp))<<8) | *(sp+1); sp+=2;
-
- if(red == green && red == blue)
- w = red;
- else
- {
- png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >>
- png_ptr->gamma_shift][red>>8];
- png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
- png_ptr->gamma_shift][green>>8];
- png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
- png_ptr->gamma_shift][blue>>8];
- png_uint_16 gray16 = (rc * red_1 + gc * green_1
- + bc * blue_1)>>8;
- w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
- png_ptr->gamma_shift][gray16 >> 8];
- rgb_error |= 1;
- }
-
- *(dp++) = (w>>8) & 0xff;
- *(dp++) = w & 0xff;
- }
- }
- else
-#endif
- {
- png_bytep sp = row;
- png_bytep dp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 red, green, blue, gray16;
-
- red = ((*(sp))<<8) | *(sp+1); sp+=2;
- green = ((*(sp))<<8) | *(sp+1); sp+=2;
- blue = ((*(sp))<<8) | *(sp+1); sp+=2;
-
- if(red != green || red != blue)
- rgb_error |= 1;
- gray16 = (rc * red + gc * green + bc * blue)>>8;
- *(dp++) = (gray16>>8) & 0xff;
- *(dp++) = gray16 & 0xff;
- }
- }
- }
- }
- if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- {
- if (row_info->bit_depth == 8)
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
- {
- png_bytep sp = row;
- png_bytep dp = row;
- for (i = 0; i < row_width; i++)
- {
- png_byte red = png_ptr->gamma_to_1[*(sp++)];
- png_byte green = png_ptr->gamma_to_1[*(sp++)];
- png_byte blue = png_ptr->gamma_to_1[*(sp++)];
- if(red != green || red != blue)
- rgb_error |= 1;
- *(dp++) = png_ptr->gamma_from_1
- [(rc*red + gc*green + bc*blue)>>8];
- *(dp++) = *(sp++); /* alpha */
- }
- }
- else
-#endif
- {
- png_bytep sp = row;
- png_bytep dp = row;
- for (i = 0; i < row_width; i++)
- {
- png_byte red = *(sp++);
- png_byte green = *(sp++);
- png_byte blue = *(sp++);
- if(red != green || red != blue)
- rgb_error |= 1;
- *(dp++) = (gc*red + gc*green + bc*blue)>>8;
- *(dp++) = *(sp++); /* alpha */
- }
- }
- }
- else /* RGBA bit_depth == 16 */
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->gamma_16_to_1 != NULL &&
- png_ptr->gamma_16_from_1 != NULL)
- {
- png_bytep sp = row;
- png_bytep dp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 red, green, blue, w;
-
- red = ((*(sp))<<8) | *(sp+1); sp+=2;
- green = ((*(sp))<<8) | *(sp+1); sp+=2;
- blue = ((*(sp))<<8) | *(sp+1); sp+=2;
-
- if(red == green && red == blue)
- w = red;
- else
- {
- png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >>
- png_ptr->gamma_shift][red>>8];
- png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
- png_ptr->gamma_shift][green>>8];
- png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
- png_ptr->gamma_shift][blue>>8];
- png_uint_16 gray16 = (rc * red_1 + gc * green_1
- + bc * blue_1)>>8;
- w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
- png_ptr->gamma_shift][gray16 >> 8];
- rgb_error |= 1;
- }
-
- *(dp++) = (w>>8) & 0xff;
- *(dp++) = w & 0xff;
- *(dp++) = *(sp++); /* alpha */
- *(dp++) = *(sp++);
- }
- }
- else
-#endif
- {
- png_bytep sp = row;
- png_bytep dp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 red, green, blue, gray16;
- red = (*(sp)<<8) | *(sp+1); sp+=2;
- green = (*(sp)<<8) | *(sp+1); sp+=2;
- blue = (*(sp)<<8) | *(sp+1); sp+=2;
- if(red != green || red != blue)
- rgb_error |= 1;
- gray16 = (rc * red + gc * green + bc * blue)>>8;
- *(dp++) = (gray16>>8) & 0xff;
- *(dp++) = gray16 & 0xff;
- *(dp++) = *(sp++); /* alpha */
- *(dp++) = *(sp++);
- }
- }
- }
- }
- row_info->channels -= (png_byte)2;
- row_info->color_type &= ~PNG_COLOR_MASK_COLOR;
- row_info->pixel_depth = (png_byte)(row_info->channels *
- row_info->bit_depth);
- row_info->rowbytes = ((row_width *
- row_info->pixel_depth + 7) >> 3);
- }
- return rgb_error;
-}
-#endif
-
-/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
- * large of png_color. This lets grayscale images be treated as
- * paletted. Most useful for gamma correction and simplification
- * of code.
- */
-void
-png_build_grayscale_palette(int bit_depth, png_colorp palette)
-{
- int num_palette;
- int color_inc;
- int i;
- int v;
-
- png_debug(1, "in png_do_build_grayscale_palette\n");
- if (palette == NULL)
- return;
-
- switch (bit_depth)
- {
- case 1:
- num_palette = 2;
- color_inc = 0xff;
- break;
- case 2:
- num_palette = 4;
- color_inc = 0x55;
- break;
- case 4:
- num_palette = 16;
- color_inc = 0x11;
- break;
- case 8:
- num_palette = 256;
- color_inc = 1;
- break;
- default:
- num_palette = 0;
- color_inc = 0;
- break;
- }
-
- for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
- {
- palette[i].red = (png_byte)v;
- palette[i].green = (png_byte)v;
- palette[i].blue = (png_byte)v;
- }
-}
-
-/* This function is currently unused. Do we really need it? */
-#if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
-void
-png_correct_palette(png_structp png_ptr, png_colorp palette,
- int num_palette)
-{
- png_debug(1, "in png_correct_palette\n");
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
- if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND))
- {
- png_color back, back_1;
-
- if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
- {
- back.red = png_ptr->gamma_table[png_ptr->background.red];
- back.green = png_ptr->gamma_table[png_ptr->background.green];
- back.blue = png_ptr->gamma_table[png_ptr->background.blue];
-
- back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
- back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
- back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
- }
- else
- {
- double g;
-
- g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma);
-
- if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN ||
- fabs(g - 1.0) < PNG_GAMMA_THRESHOLD)
- {
- back.red = png_ptr->background.red;
- back.green = png_ptr->background.green;
- back.blue = png_ptr->background.blue;
- }
- else
- {
- back.red =
- (png_byte)(pow((double)png_ptr->background.red/255, g) *
- 255.0 + 0.5);
- back.green =
- (png_byte)(pow((double)png_ptr->background.green/255, g) *
- 255.0 + 0.5);
- back.blue =
- (png_byte)(pow((double)png_ptr->background.blue/255, g) *
- 255.0 + 0.5);
- }
-
- g = 1.0 / png_ptr->background_gamma;
-
- back_1.red =
- (png_byte)(pow((double)png_ptr->background.red/255, g) *
- 255.0 + 0.5);
- back_1.green =
- (png_byte)(pow((double)png_ptr->background.green/255, g) *
- 255.0 + 0.5);
- back_1.blue =
- (png_byte)(pow((double)png_ptr->background.blue/255, g) *
- 255.0 + 0.5);
- }
-
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_uint_32 i;
-
- for (i = 0; i < (png_uint_32)num_palette; i++)
- {
- if (i < png_ptr->num_trans && png_ptr->trans[i] == 0)
- {
- palette[i] = back;
- }
- else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff)
- {
- png_byte v, w;
-
- v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
- png_composite(w, v, png_ptr->trans[i], back_1.red);
- palette[i].red = png_ptr->gamma_from_1[w];
-
- v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
- png_composite(w, v, png_ptr->trans[i], back_1.green);
- palette[i].green = png_ptr->gamma_from_1[w];
-
- v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
- png_composite(w, v, png_ptr->trans[i], back_1.blue);
- palette[i].blue = png_ptr->gamma_from_1[w];
- }
- else
- {
- palette[i].red = png_ptr->gamma_table[palette[i].red];
- palette[i].green = png_ptr->gamma_table[palette[i].green];
- palette[i].blue = png_ptr->gamma_table[palette[i].blue];
- }
- }
- }
- else
- {
- int i;
-
- for (i = 0; i < num_palette; i++)
- {
- if (palette[i].red == (png_byte)png_ptr->trans_values.gray)
- {
- palette[i] = back;
- }
- else
- {
- palette[i].red = png_ptr->gamma_table[palette[i].red];
- palette[i].green = png_ptr->gamma_table[palette[i].green];
- palette[i].blue = png_ptr->gamma_table[palette[i].blue];
- }
- }
- }
- }
- else
-#endif
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (png_ptr->transformations & PNG_GAMMA)
- {
- int i;
-
- for (i = 0; i < num_palette; i++)
- {
- palette[i].red = png_ptr->gamma_table[palette[i].red];
- palette[i].green = png_ptr->gamma_table[palette[i].green];
- palette[i].blue = png_ptr->gamma_table[palette[i].blue];
- }
- }
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
- else
-#endif
-#endif
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->transformations & PNG_BACKGROUND)
- {
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_color back;
-
- back.red = (png_byte)png_ptr->background.red;
- back.green = (png_byte)png_ptr->background.green;
- back.blue = (png_byte)png_ptr->background.blue;
-
- for (i = 0; i < (int)png_ptr->num_trans; i++)
- {
- if (png_ptr->trans[i] == 0)
- {
- palette[i].red = back.red;
- palette[i].green = back.green;
- palette[i].blue = back.blue;
- }
- else if (png_ptr->trans[i] != 0xff)
- {
- png_composite(palette[i].red, png_ptr->palette[i].red,
- png_ptr->trans[i], back.red);
- png_composite(palette[i].green, png_ptr->palette[i].green,
- png_ptr->trans[i], back.green);
- png_composite(palette[i].blue, png_ptr->palette[i].blue,
- png_ptr->trans[i], back.blue);
- }
- }
- }
- else /* assume grayscale palette (what else could it be?) */
- {
- int i;
-
- for (i = 0; i < num_palette; i++)
- {
- if (i == (png_byte)png_ptr->trans_values.gray)
- {
- palette[i].red = (png_byte)png_ptr->background.red;
- palette[i].green = (png_byte)png_ptr->background.green;
- palette[i].blue = (png_byte)png_ptr->background.blue;
- }
- }
- }
- }
-#endif
-}
-#endif
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
-/* Replace any alpha or transparency with the supplied background color.
- * "background" is already in the screen gamma, while "background_1" is
- * at a gamma of 1.0. Paletted files have already been taken care of.
- */
-void
-png_do_background(png_row_infop row_info, png_bytep row,
- png_color_16p trans_values, png_color_16p background,
- png_color_16p background_1,
- png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
- png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
- png_uint_16pp gamma_16_to_1, int gamma_shift)
-{
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width=row_info->width;
- int shift;
-
- png_debug(1, "in png_do_background\n");
- if (background != NULL &&
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
-#endif
- (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
- (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values)))
- {
- switch (row_info->color_type)
- {
- case PNG_COLOR_TYPE_GRAY:
- {
- switch (row_info->bit_depth)
- {
- case 1:
- {
- sp = row;
- shift = 7;
- for (i = 0; i < row_width; i++)
- {
- if ((png_uint_16)((*sp >> shift) & 0x1)
- == trans_values->gray)
- {
- *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
- *sp |= (png_byte)(background->gray << shift);
- }
- if (!shift)
- {
- shift = 7;
- sp++;
- }
- else
- shift--;
- }
- break;
- }
- case 2:
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_table != NULL)
- {
- sp = row;
- shift = 6;
- for (i = 0; i < row_width; i++)
- {
- if ((png_uint_16)((*sp >> shift) & 0x3)
- == trans_values->gray)
- {
- *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
- *sp |= (png_byte)(background->gray << shift);
- }
- else
- {
- png_byte p = (*sp >> shift) & 0x3;
- png_byte g = (gamma_table [p | (p << 2) | (p << 4) |
- (p << 6)] >> 6) & 0x3;
- *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
- *sp |= (png_byte)(g << shift);
- }
- if (!shift)
- {
- shift = 6;
- sp++;
- }
- else
- shift -= 2;
- }
- }
- else
-#endif
- {
- sp = row;
- shift = 6;
- for (i = 0; i < row_width; i++)
- {
- if ((png_uint_16)((*sp >> shift) & 0x3)
- == trans_values->gray)
- {
- *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
- *sp |= (png_byte)(background->gray << shift);
- }
- if (!shift)
- {
- shift = 6;
- sp++;
- }
- else
- shift -= 2;
- }
- }
- break;
- }
- case 4:
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_table != NULL)
- {
- sp = row;
- shift = 4;
- for (i = 0; i < row_width; i++)
- {
- if ((png_uint_16)((*sp >> shift) & 0xf)
- == trans_values->gray)
- {
- *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
- *sp |= (png_byte)(background->gray << shift);
- }
- else
- {
- png_byte p = (*sp >> shift) & 0xf;
- png_byte g = (gamma_table[p | (p << 4)] >> 4) & 0xf;
- *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
- *sp |= (png_byte)(g << shift);
- }
- if (!shift)
- {
- shift = 4;
- sp++;
- }
- else
- shift -= 4;
- }
- }
- else
-#endif
- {
- sp = row;
- shift = 4;
- for (i = 0; i < row_width; i++)
- {
- if ((png_uint_16)((*sp >> shift) & 0xf)
- == trans_values->gray)
- {
- *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
- *sp |= (png_byte)(background->gray << shift);
- }
- if (!shift)
- {
- shift = 4;
- sp++;
- }
- else
- shift -= 4;
- }
- }
- break;
- }
- case 8:
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_table != NULL)
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp++)
- {
- if (*sp == trans_values->gray)
- {
- *sp = (png_byte)background->gray;
- }
- else
- {
- *sp = gamma_table[*sp];
- }
- }
- }
- else
-#endif
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp++)
- {
- if (*sp == trans_values->gray)
- {
- *sp = (png_byte)background->gray;
- }
- }
- }
- break;
- }
- case 16:
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_16 != NULL)
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 2)
- {
- png_uint_16 v;
-
- v = ((png_uint_16)(*sp) << 8) + *(sp + 1);
- if (v == trans_values->gray)
- {
- /* background is already in screen gamma */
- *sp = (png_byte)((background->gray >> 8) & 0xff);
- *(sp + 1) = (png_byte)(background->gray & 0xff);
- }
- else
- {
- v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- }
- }
- }
- else
-#endif
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 2)
- {
- png_uint_16 v;
-
- v = ((png_uint_16)(*sp) << 8) + *(sp + 1);
- if (v == trans_values->gray)
- {
- *sp = (png_byte)((background->gray >> 8) & 0xff);
- *(sp + 1) = (png_byte)(background->gray & 0xff);
- }
- }
- }
- break;
- }
- }
- break;
- }
- case PNG_COLOR_TYPE_RGB:
- {
- if (row_info->bit_depth == 8)
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_table != NULL)
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 3)
- {
- if (*sp == trans_values->red &&
- *(sp + 1) == trans_values->green &&
- *(sp + 2) == trans_values->blue)
- {
- *sp = (png_byte)background->red;
- *(sp + 1) = (png_byte)background->green;
- *(sp + 2) = (png_byte)background->blue;
- }
- else
- {
- *sp = gamma_table[*sp];
- *(sp + 1) = gamma_table[*(sp + 1)];
- *(sp + 2) = gamma_table[*(sp + 2)];
- }
- }
- }
- else
-#endif
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 3)
- {
- if (*sp == trans_values->red &&
- *(sp + 1) == trans_values->green &&
- *(sp + 2) == trans_values->blue)
- {
- *sp = (png_byte)background->red;
- *(sp + 1) = (png_byte)background->green;
- *(sp + 2) = (png_byte)background->blue;
- }
- }
- }
- }
- else /* if (row_info->bit_depth == 16) */
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_16 != NULL)
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 6)
- {
- png_uint_16 r = ((png_uint_16)(*sp) << 8) + *(sp + 1);
- png_uint_16 g = ((png_uint_16)(*(sp + 2)) << 8) + *(sp + 3);
- png_uint_16 b = ((png_uint_16)(*(sp + 4)) << 8) + *(sp + 5);
- if (r == trans_values->red && g == trans_values->green &&
- b == trans_values->blue)
- {
- /* background is already in screen gamma */
- *sp = (png_byte)((background->red >> 8) & 0xff);
- *(sp + 1) = (png_byte)(background->red & 0xff);
- *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
- *(sp + 3) = (png_byte)(background->green & 0xff);
- *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
- *(sp + 5) = (png_byte)(background->blue & 0xff);
- }
- else
- {
- png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
- *(sp + 2) = (png_byte)((v >> 8) & 0xff);
- *(sp + 3) = (png_byte)(v & 0xff);
- v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
- *(sp + 4) = (png_byte)((v >> 8) & 0xff);
- *(sp + 5) = (png_byte)(v & 0xff);
- }
- }
- }
- else
-#endif
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 6)
- {
- png_uint_16 r = ((png_uint_16)(*sp) << 8) + *(sp + 1);
- png_uint_16 g = ((png_uint_16)(*(sp + 2)) << 8) + *(sp + 3);
- png_uint_16 b = ((png_uint_16)(*(sp + 4)) << 8) + *(sp + 5);
-
- if (r == trans_values->red && g == trans_values->green &&
- b == trans_values->blue)
- {
- *sp = (png_byte)((background->red >> 8) & 0xff);
- *(sp + 1) = (png_byte)(background->red & 0xff);
- *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
- *(sp + 3) = (png_byte)(background->green & 0xff);
- *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
- *(sp + 5) = (png_byte)(background->blue & 0xff);
- }
- }
- }
- }
- break;
- }
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- {
- if (row_info->bit_depth == 8)
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
- gamma_table != NULL)
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 2, dp++)
- {
- png_uint_16 a = *(sp + 1);
-
- if (a == 0xff)
- {
- *dp = gamma_table[*sp];
- }
- else if (a == 0)
- {
- /* background is already in screen gamma */
- *dp = (png_byte)background->gray;
- }
- else
- {
- png_byte v, w;
-
- v = gamma_to_1[*sp];
- png_composite(w, v, a, background_1->gray);
- *dp = gamma_from_1[w];
- }
- }
- }
- else
-#endif
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 2, dp++)
- {
- png_byte a = *(sp + 1);
-
- if (a == 0xff)
- {
- *dp = *sp;
- }
- else if (a == 0)
- {
- *dp = (png_byte)background->gray;
- }
- else
- {
- png_composite(*dp, *sp, a, background_1->gray);
- }
- }
- }
- }
- else /* if (png_ptr->bit_depth == 16) */
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
- gamma_16_to_1 != NULL)
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 4, dp += 2)
- {
- png_uint_16 a = ((png_uint_16)(*(sp + 2)) << 8) + *(sp + 3);
-
- if (a == (png_uint_16)0xffff)
- {
- png_uint_16 v;
-
- v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
- *dp = (png_byte)((v >> 8) & 0xff);
- *(dp + 1) = (png_byte)(v & 0xff);
- }
- else if (a == 0)
- {
- /* background is already in screen gamma */
- *dp = (png_byte)((background->gray >> 8) & 0xff);
- *(dp + 1) = (png_byte)(background->gray & 0xff);
- }
- else
- {
- png_uint_16 g, v, w;
-
- g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
- png_composite_16(v, g, a, background_1->gray);
- w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
- *dp = (png_byte)((w >> 8) & 0xff);
- *(dp + 1) = (png_byte)(w & 0xff);
- }
- }
- }
- else
-#endif
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 4, dp += 2)
- {
- png_uint_16 a = ((png_uint_16)(*(sp + 2)) << 8) + *(sp + 3);
- if (a == (png_uint_16)0xffff)
- {
- png_memcpy(dp, sp, 2);
- }
- else if (a == 0)
- {
- *dp = (png_byte)((background->gray >> 8) & 0xff);
- *(dp + 1) = (png_byte)(background->gray & 0xff);
- }
- else
- {
- png_uint_16 g, v;
-
- g = ((png_uint_16)(*sp) << 8) + *(sp + 1);
- png_composite_16(v, g, a, background_1->gray);
- *dp = (png_byte)((v >> 8) & 0xff);
- *(dp + 1) = (png_byte)(v & 0xff);
- }
- }
- }
- }
- break;
- }
- case PNG_COLOR_TYPE_RGB_ALPHA:
- {
- if (row_info->bit_depth == 8)
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
- gamma_table != NULL)
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 4, dp += 3)
- {
- png_byte a = *(sp + 3);
-
- if (a == 0xff)
- {
- *dp = gamma_table[*sp];
- *(dp + 1) = gamma_table[*(sp + 1)];
- *(dp + 2) = gamma_table[*(sp + 2)];
- }
- else if (a == 0)
- {
- /* background is already in screen gamma */
- *dp = (png_byte)background->red;
- *(dp + 1) = (png_byte)background->green;
- *(dp + 2) = (png_byte)background->blue;
- }
- else
- {
- png_byte v, w;
-
- v = gamma_to_1[*sp];
- png_composite(w, v, a, background_1->red);
- *dp = gamma_from_1[w];
- v = gamma_to_1[*(sp + 1)];
- png_composite(w, v, a, background_1->green);
- *(dp + 1) = gamma_from_1[w];
- v = gamma_to_1[*(sp + 2)];
- png_composite(w, v, a, background_1->blue);
- *(dp + 2) = gamma_from_1[w];
- }
- }
- }
- else
-#endif
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 4, dp += 3)
- {
- png_byte a = *(sp + 3);
-
- if (a == 0xff)
- {
- *dp = *sp;
- *(dp + 1) = *(sp + 1);
- *(dp + 2) = *(sp + 2);
- }
- else if (a == 0)
- {
- *dp = (png_byte)background->red;
- *(dp + 1) = (png_byte)background->green;
- *(dp + 2) = (png_byte)background->blue;
- }
- else
- {
- png_composite(*dp, *sp, a, background->red);
- png_composite(*(dp + 1), *(sp + 1), a,
- background->green);
- png_composite(*(dp + 2), *(sp + 2), a,
- background->blue);
- }
- }
- }
- }
- else /* if (row_info->bit_depth == 16) */
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
- gamma_16_to_1 != NULL)
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 8, dp += 6)
- {
- png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
- << 8) + (png_uint_16)(*(sp + 7)));
- if (a == (png_uint_16)0xffff)
- {
- png_uint_16 v;
-
- v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
- *dp = (png_byte)((v >> 8) & 0xff);
- *(dp + 1) = (png_byte)(v & 0xff);
- v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
- *(dp + 2) = (png_byte)((v >> 8) & 0xff);
- *(dp + 3) = (png_byte)(v & 0xff);
- v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
- *(dp + 4) = (png_byte)((v >> 8) & 0xff);
- *(dp + 5) = (png_byte)(v & 0xff);
- }
- else if (a == 0)
- {
- /* background is already in screen gamma */
- *dp = (png_byte)((background->red >> 8) & 0xff);
- *(dp + 1) = (png_byte)(background->red & 0xff);
- *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
- *(dp + 3) = (png_byte)(background->green & 0xff);
- *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
- *(dp + 5) = (png_byte)(background->blue & 0xff);
- }
- else
- {
- png_uint_16 v, w, x;
-
- v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
- png_composite_16(w, v, a, background->red);
- x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
- *dp = (png_byte)((x >> 8) & 0xff);
- *(dp + 1) = (png_byte)(x & 0xff);
- v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
- png_composite_16(w, v, a, background->green);
- x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
- *(dp + 2) = (png_byte)((x >> 8) & 0xff);
- *(dp + 3) = (png_byte)(x & 0xff);
- v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
- png_composite_16(w, v, a, background->blue);
- x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8];
- *(dp + 4) = (png_byte)((x >> 8) & 0xff);
- *(dp + 5) = (png_byte)(x & 0xff);
- }
- }
- }
- else
-#endif
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 8, dp += 6)
- {
- png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
- << 8) + (png_uint_16)(*(sp + 7)));
- if (a == (png_uint_16)0xffff)
- {
- png_memcpy(dp, sp, 6);
- }
- else if (a == 0)
- {
- *dp = (png_byte)((background->red >> 8) & 0xff);
- *(dp + 1) = (png_byte)(background->red & 0xff);
- *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
- *(dp + 3) = (png_byte)(background->green & 0xff);
- *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
- *(dp + 5) = (png_byte)(background->blue & 0xff);
- }
- else
- {
- png_uint_16 v;
-
- png_uint_16 r = ((png_uint_16)(*sp) << 8) + *(sp + 1);
- png_uint_16 g = ((png_uint_16)(*(sp + 2)) << 8)
- + *(sp + 3);
- png_uint_16 b = ((png_uint_16)(*(sp + 4)) << 8)
- + *(sp + 5);
-
- png_composite_16(v, r, a, background->red);
- *dp = (png_byte)((v >> 8) & 0xff);
- *(dp + 1) = (png_byte)(v & 0xff);
- png_composite_16(v, g, a, background->green);
- *(dp + 2) = (png_byte)((v >> 8) & 0xff);
- *(dp + 3) = (png_byte)(v & 0xff);
- png_composite_16(v, b, a, background->blue);
- *(dp + 4) = (png_byte)((v >> 8) & 0xff);
- *(dp + 5) = (png_byte)(v & 0xff);
- }
- }
- }
- }
- break;
- }
- }
-
- if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
- {
- row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
- row_info->channels--;
- row_info->pixel_depth = (png_byte)(row_info->channels *
- row_info->bit_depth);
- row_info->rowbytes = ((row_width *
- row_info->pixel_depth + 7) >> 3);
- }
- }
-}
-#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 transparency issue on grayscale
- * or rgb images. If your bit depth is 8, use gamma_table, if it
- * is 16, use gamma_16_table and gamma_shift. Build these with
- * build_gamma_table().
- */
-void
-png_do_gamma(png_row_infop row_info, png_bytep row,
- png_bytep gamma_table, png_uint_16pp gamma_16_table,
- int gamma_shift)
-{
- png_bytep sp;
- png_uint_32 i;
- png_uint_32 row_width=row_info->width;
-
- png_debug(1, "in png_do_gamma\n");
- if (
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
-#endif
- ((row_info->bit_depth <= 8 && gamma_table != NULL) ||
- (row_info->bit_depth == 16 && gamma_16_table != NULL)))
- {
- switch (row_info->color_type)
- {
- case PNG_COLOR_TYPE_RGB:
- {
- if (row_info->bit_depth == 8)
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- *sp = gamma_table[*sp];
- sp++;
- *sp = gamma_table[*sp];
- sp++;
- *sp = gamma_table[*sp];
- sp++;
- }
- }
- else /* if (row_info->bit_depth == 16) */
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 v;
-
- v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 2;
- v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 2;
- v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 2;
- }
- }
- break;
- }
- case PNG_COLOR_TYPE_RGB_ALPHA:
- {
- if (row_info->bit_depth == 8)
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- *sp = gamma_table[*sp];
- sp++;
- *sp = gamma_table[*sp];
- sp++;
- *sp = gamma_table[*sp];
- sp++;
- sp++;
- }
- }
- else /* if (row_info->bit_depth == 16) */
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 2;
- v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 2;
- v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 4;
- }
- }
- break;
- }
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- {
- if (row_info->bit_depth == 8)
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- *sp = gamma_table[*sp];
- sp += 2;
- }
- }
- else /* if (row_info->bit_depth == 16) */
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 4;
- }
- }
- break;
- }
- case PNG_COLOR_TYPE_GRAY:
- {
- if (row_info->bit_depth == 2)
- {
- sp = row;
- for (i = 0; i < row_width; i += 4)
- {
- int a = *sp & 0xc0;
- int b = *sp & 0x30;
- int c = *sp & 0x0c;
- int d = *sp & 0x03;
-
- *sp = ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)|
- ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
- ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
- ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) );
- sp++;
- }
- }
- if (row_info->bit_depth == 4)
- {
- sp = row;
- for (i = 0; i < row_width; i += 2)
- {
- int msb = *sp & 0xf0;
- int lsb = *sp & 0x0f;
-
- *sp = (((int)gamma_table[msb | (msb >> 4)]) & 0xf0) |
- (((int)gamma_table[(lsb << 4) | lsb]) >> 4);
- sp++;
- }
- }
- else if (row_info->bit_depth == 8)
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- *sp = gamma_table[*sp];
- sp++;
- }
- }
- else if (row_info->bit_depth == 16)
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 2;
- }
- }
- break;
- }
- }
- }
-}
-#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_infop row_info, png_bytep row,
- png_colorp palette, png_bytep trans, int num_trans)
-{
- int shift, value;
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width=row_info->width;
-
- png_debug(1, "in png_do_expand_palette\n");
- if (
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
-#endif
- row_info->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (row_info->bit_depth < 8)
- {
- switch (row_info->bit_depth)
- {
- case 1:
- {
- sp = row + (png_size_t)((row_width - 1) >> 3);
- dp = row + (png_size_t)row_width - 1;
- shift = 7 - (int)((row_width + 7) & 7);
- for (i = 0; i < row_width; i++)
- {
- if ((*sp >> shift) & 0x1)
- *dp = 1;
- else
- *dp = 0;
- if (shift == 7)
- {
- shift = 0;
- sp--;
- }
- else
- shift++;
-
- dp--;
- }
- break;
- }
- case 2:
- {
- sp = row + (png_size_t)((row_width - 1) >> 2);
- dp = row + (png_size_t)row_width - 1;
- shift = (int)((3 - ((row_width + 3) & 3)) << 1);
- for (i = 0; i < row_width; i++)
- {
- value = (*sp >> shift) & 0x3;
- *dp = (png_byte)value;
- if (shift == 6)
- {
- shift = 0;
- sp--;
- }
- else
- shift += 2;
-
- dp--;
- }
- break;
- }
- case 4:
- {
- sp = row + (png_size_t)((row_width - 1) >> 1);
- dp = row + (png_size_t)row_width - 1;
- shift = (int)((row_width & 1) << 2);
- for (i = 0; i < row_width; i++)
- {
- value = (*sp >> shift) & 0xf;
- *dp = (png_byte)value;
- if (shift == 4)
- {
- shift = 0;
- sp--;
- }
- else
- shift += 4;
-
- dp--;
- }
- break;
- }
- }
- row_info->bit_depth = 8;
- row_info->pixel_depth = 8;
- row_info->rowbytes = row_width;
- }
- switch (row_info->bit_depth)
- {
- case 8:
- {
- if (trans != NULL)
- {
- sp = row + (png_size_t)row_width - 1;
- dp = row + (png_size_t)(row_width << 2) - 1;
-
- for (i = 0; i < row_width; i++)
- {
- if ((int)(*sp) >= num_trans)
- *dp-- = 0xff;
- else
- *dp-- = trans[*sp];
- *dp-- = palette[*sp].blue;
- *dp-- = palette[*sp].green;
- *dp-- = palette[*sp].red;
- sp--;
- }
- row_info->bit_depth = 8;
- row_info->pixel_depth = 32;
- row_info->rowbytes = row_width * 4;
- row_info->color_type = 6;
- row_info->channels = 4;
- }
- else
- {
- sp = row + (png_size_t)row_width - 1;
- dp = row + (png_size_t)(row_width * 3) - 1;
-
- for (i = 0; i < row_width; i++)
- {
- *dp-- = palette[*sp].blue;
- *dp-- = palette[*sp].green;
- *dp-- = palette[*sp].red;
- sp--;
- }
- row_info->bit_depth = 8;
- row_info->pixel_depth = 24;
- row_info->rowbytes = row_width * 3;
- row_info->color_type = 2;
- row_info->channels = 3;
- }
- break;
- }
- }
- }
-}
-
-/* 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_infop row_info, png_bytep row,
- png_color_16p trans_value)
-{
- int shift, value;
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width=row_info->width;
-
- png_debug(1, "in png_do_expand\n");
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL)
-#endif
- {
- if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
- {
- png_uint_16 gray = trans_value ? trans_value->gray : 0;
-
- if (row_info->bit_depth < 8)
- {
- switch (row_info->bit_depth)
- {
- case 1:
- {
- gray *= 0xff;
- sp = row + (png_size_t)((row_width - 1) >> 3);
- dp = row + (png_size_t)row_width - 1;
- shift = 7 - (int)((row_width + 7) & 7);
- for (i = 0; i < row_width; i++)
- {
- if ((*sp >> shift) & 0x1)
- *dp = 0xff;
- else
- *dp = 0;
- if (shift == 7)
- {
- shift = 0;
- sp--;
- }
- else
- shift++;
-
- dp--;
- }
- break;
- }
- case 2:
- {
- gray *= 0x55;
- sp = row + (png_size_t)((row_width - 1) >> 2);
- dp = row + (png_size_t)row_width - 1;
- shift = (int)((3 - ((row_width + 3) & 3)) << 1);
- for (i = 0; i < row_width; i++)
- {
- value = (*sp >> shift) & 0x3;
- *dp = (png_byte)(value | (value << 2) | (value << 4) |
- (value << 6));
- if (shift == 6)
- {
- shift = 0;
- sp--;
- }
- else
- shift += 2;
-
- dp--;
- }
- break;
- }
- case 4:
- {
- gray *= 0x11;
- sp = row + (png_size_t)((row_width - 1) >> 1);
- dp = row + (png_size_t)row_width - 1;
- shift = (int)((1 - ((row_width + 1) & 1)) << 2);
- for (i = 0; i < row_width; i++)
- {
- value = (*sp >> shift) & 0xf;
- *dp = (png_byte)(value | (value << 4));
- if (shift == 4)
- {
- shift = 0;
- sp--;
- }
- else
- shift = 4;
-
- dp--;
- }
- break;
- }
- }
- row_info->bit_depth = 8;
- row_info->pixel_depth = 8;
- row_info->rowbytes = row_width;
- }
-
- if (trans_value != NULL)
- {
- if (row_info->bit_depth == 8)
- {
- sp = row + (png_size_t)row_width - 1;
- dp = row + (png_size_t)(row_width << 1) - 1;
- for (i = 0; i < row_width; i++)
- {
- if (*sp == gray)
- *dp-- = 0;
- else
- *dp-- = 0xff;
- *dp-- = *sp--;
- }
- }
- else if (row_info->bit_depth == 16)
- {
- sp = row + row_info->rowbytes - 1;
- dp = row + (row_info->rowbytes << 1) - 1;
- for (i = 0; i < row_width; i++)
- {
- if (((png_uint_16)*(sp) |
- ((png_uint_16)*(sp - 1) << 8)) == gray)
- {
- *dp-- = 0;
- *dp-- = 0;
- }
- else
- {
- *dp-- = 0xff;
- *dp-- = 0xff;
- }
- *dp-- = *sp--;
- *dp-- = *sp--;
- }
- }
- row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
- row_info->channels = 2;
- row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
- row_info->rowbytes =
- ((row_width * row_info->pixel_depth) >> 3);
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
- {
- if (row_info->bit_depth == 8)
- {
- sp = row + (png_size_t)row_info->rowbytes - 1;
- dp = row + (png_size_t)(row_width << 2) - 1;
- for (i = 0; i < row_width; i++)
- {
- if (*(sp - 2) == trans_value->red &&
- *(sp - 1) == trans_value->green &&
- *(sp - 0) == trans_value->blue)
- *dp-- = 0;
- else
- *dp-- = 0xff;
- *dp-- = *sp--;
- *dp-- = *sp--;
- *dp-- = *sp--;
- }
- }
- else if (row_info->bit_depth == 16)
- {
- sp = row + row_info->rowbytes - 1;
- dp = row + (png_size_t)(row_width << 3) - 1;
- for (i = 0; i < row_width; i++)
- {
- if ((((png_uint_16)*(sp - 4) |
- ((png_uint_16)*(sp - 5) << 8)) == trans_value->red) &&
- (((png_uint_16)*(sp - 2) |
- ((png_uint_16)*(sp - 3) << 8)) == trans_value->green) &&
- (((png_uint_16)*(sp - 0) |
- ((png_uint_16)*(sp - 1) << 8)) == trans_value->blue))
- {
- *dp-- = 0;
- *dp-- = 0;
- }
- else
- {
- *dp-- = 0xff;
- *dp-- = 0xff;
- }
- *dp-- = *sp--;
- *dp-- = *sp--;
- *dp-- = *sp--;
- *dp-- = *sp--;
- *dp-- = *sp--;
- *dp-- = *sp--;
- }
- }
- row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
- row_info->channels = 4;
- row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
- row_info->rowbytes =
- ((row_width * row_info->pixel_depth) >> 3);
- }
- }
-}
-#endif
-
-#if defined(PNG_READ_DITHER_SUPPORTED)
-void
-png_do_dither(png_row_infop row_info, png_bytep row,
- png_bytep palette_lookup, png_bytep dither_lookup)
-{
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width=row_info->width;
-
- png_debug(1, "in png_do_dither\n");
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL)
-#endif
- {
- if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
- palette_lookup && row_info->bit_depth == 8)
- {
- int r, g, b, p;
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++)
- {
- r = *sp++;
- g = *sp++;
- b = *sp++;
-
- /* this looks real messy, but the compiler will reduce
- it down to a reasonable formula. For example, with
- 5 bits per color, we get:
- p = (((r >> 3) & 0x1f) << 10) |
- (((g >> 3) & 0x1f) << 5) |
- ((b >> 3) & 0x1f);
- */
- p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
- ((1 << PNG_DITHER_RED_BITS) - 1)) <<
- (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
- (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
- ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
- (PNG_DITHER_BLUE_BITS)) |
- ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
- ((1 << PNG_DITHER_BLUE_BITS) - 1));
-
- *dp++ = palette_lookup[p];
- }
- row_info->color_type = PNG_COLOR_TYPE_PALETTE;
- row_info->channels = 1;
- row_info->pixel_depth = row_info->bit_depth;
- row_info->rowbytes =
- ((row_width * row_info->pixel_depth + 7) >> 3);
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
- palette_lookup != NULL && row_info->bit_depth == 8)
- {
- int r, g, b, p;
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++)
- {
- r = *sp++;
- g = *sp++;
- b = *sp++;
- sp++;
-
- p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
- ((1 << PNG_DITHER_RED_BITS) - 1)) <<
- (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
- (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
- ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
- (PNG_DITHER_BLUE_BITS)) |
- ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
- ((1 << PNG_DITHER_BLUE_BITS) - 1));
-
- *dp++ = palette_lookup[p];
- }
- row_info->color_type = PNG_COLOR_TYPE_PALETTE;
- row_info->channels = 1;
- row_info->pixel_depth = row_info->bit_depth;
- row_info->rowbytes =
- ((row_width * row_info->pixel_depth + 7) >> 3);
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
- dither_lookup && row_info->bit_depth == 8)
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp++)
- {
- *sp = dither_lookup[*sp];
- }
- }
- }
-}
-#endif
-
-#if defined(PNG_READ_GAMMA_SUPPORTED)
-static int png_gamma_shift[] =
- {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0};
-
-/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit
- * tables, we don't make a full table if we are reducing to 8-bit in
- * the future. Note also how the gamma_16 tables are segmented so that
- * we don't need to allocate > 64K chunks for a full 16-bit table.
- */
-void
-png_build_gamma_table(png_structp png_ptr)
-{
- png_debug(1, "in png_build_gamma_table\n");
- if(png_ptr->gamma != 0.0)
- {
- if (png_ptr->bit_depth <= 8)
- {
- int i;
- double g;
-
- if (png_ptr->screen_gamma > .000001)
- g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
- else
- g = 1.0;
-
- png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)256);
-
- for (i = 0; i < 256; i++)
- {
- png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
- g) * 255.0 + .5);
- }
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
- defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
- if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY))
- {
-
- g = 1.0 / (png_ptr->gamma);
-
- png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)256);
-
- for (i = 0; i < 256; i++)
- {
- png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
- g) * 255.0 + .5);
- }
-
-
- png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)256);
-
- if(png_ptr->screen_gamma > 0.000001)
- g = 1.0 / png_ptr->screen_gamma;
- else
- g = png_ptr->gamma; /* probably doing rgb_to_gray */
-
- for (i = 0; i < 256; i++)
- {
- png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
- g) * 255.0 + .5);
-
- }
- }
-#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
- }
- else
- {
- double g;
- int i, j, shift, num;
- int sig_bit;
- png_uint_32 ig;
-
- if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
- {
- sig_bit = (int)png_ptr->sig_bit.red;
- if ((int)png_ptr->sig_bit.green > sig_bit)
- sig_bit = png_ptr->sig_bit.green;
- if ((int)png_ptr->sig_bit.blue > sig_bit)
- sig_bit = png_ptr->sig_bit.blue;
- }
- else
- {
- sig_bit = (int)png_ptr->sig_bit.gray;
- }
-
- if (sig_bit > 0)
- shift = 16 - sig_bit;
- else
- shift = 0;
-
- if (png_ptr->transformations & PNG_16_TO_8)
- {
- if (shift < (16 - PNG_MAX_GAMMA_8))
- shift = (16 - PNG_MAX_GAMMA_8);
- }
-
- if (shift > 8)
- shift = 8;
- if (shift < 0)
- shift = 0;
-
- png_ptr->gamma_shift = (png_byte)shift;
-
- num = (1 << (8 - shift));
-
- if (png_ptr->screen_gamma > .000001)
- g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
- else
- g = 1.0;
-
- png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr,
- (png_uint_32)(num * sizeof (png_uint_16p)));
-
- if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND))
- {
- double fin, fout;
- png_uint_32 last, max;
-
- for (i = 0; i < num; i++)
- {
- png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
- (png_uint_32)(256 * sizeof (png_uint_16)));
- }
-
- g = 1.0 / g;
- last = 0;
- for (i = 0; i < 256; i++)
- {
- fout = ((double)i + 0.5) / 256.0;
- fin = pow(fout, g);
- max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
- while (last <= max)
- {
- png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
- [(int)(last >> (8 - shift))] = (png_uint_16)(
- (png_uint_16)i | ((png_uint_16)i << 8));
- last++;
- }
- }
- while (last < ((png_uint_32)num << 8))
- {
- png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
- [(int)(last >> (8 - shift))] = (png_uint_16)65535L;
- last++;
- }
- }
- else
- {
- for (i = 0; i < num; i++)
- {
- png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
- (png_uint_32)(256 * sizeof (png_uint_16)));
-
- ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4);
- for (j = 0; j < 256; j++)
- {
- png_ptr->gamma_16_table[i][j] =
- (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
- 65535.0, g) * 65535.0 + .5);
- }
- }
- }
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
- defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
- if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY))
- {
-
- g = 1.0 / (png_ptr->gamma);
-
- png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr,
- (png_uint_32)(num * sizeof (png_uint_16p )));
-
- for (i = 0; i < num; i++)
- {
- png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
- (png_uint_32)(256 * sizeof (png_uint_16)));
-
- ig = (((png_uint_32)i *
- (png_uint_32)png_gamma_shift[shift]) >> 4);
- for (j = 0; j < 256; j++)
- {
- png_ptr->gamma_16_to_1[i][j] =
- (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
- 65535.0, g) * 65535.0 + .5);
- }
- }
-
- if(png_ptr->screen_gamma > 0.000001)
- g = 1.0 / png_ptr->screen_gamma;
- else
- g = png_ptr->gamma; /* probably doing rgb_to_gray */
-
- png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr,
- (png_uint_32)(num * sizeof (png_uint_16p)));
-
- for (i = 0; i < num; i++)
- {
- png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
- (png_uint_32)(256 * sizeof (png_uint_16)));
-
- ig = (((png_uint_32)i *
- (png_uint_32)png_gamma_shift[shift]) >> 4);
- for (j = 0; j < 256; j++)
- {
- png_ptr->gamma_16_from_1[i][j] =
- (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
- 65535.0, g) * 65535.0 + .5);
- }
- }
- }
-#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
- }
- }
-}
-#endif
-
+++ /dev/null
-
-/* pngrutil.c - utilities to read a PNG file
- *
- * libpng 1.0.3 - January 14, 1999
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
- *
- * This file contains routines that are only called from within
- * libpng itself during the course of reading an image.
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-
-#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
-/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
-png_uint_32
-png_get_uint_32(png_bytep buf)
-{
- png_uint_32 i = ((png_uint_32)(*buf) << 24) +
- ((png_uint_32)(*(buf + 1)) << 16) +
- ((png_uint_32)(*(buf + 2)) << 8) +
- (png_uint_32)(*(buf + 3));
-
- return (i);
-}
-
-#if defined(PNG_READ_pCAL_SUPPORTED)
-/* Grab a signed 32-bit integer from a buffer in big-endian format. The
- * data is stored in the PNG file in two's complement format, and it is
- * assumed that the machine format for signed integers is the same. */
-png_int_32
-png_get_int_32(png_bytep buf)
-{
- png_int_32 i = ((png_int_32)(*buf) << 24) +
- ((png_int_32)(*(buf + 1)) << 16) +
- ((png_int_32)(*(buf + 2)) << 8) +
- (png_int_32)(*(buf + 3));
-
- return (i);
-}
-#endif /* PNG_READ_pCAL_SUPPORTED */
-
-/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
-png_uint_16
-png_get_uint_16(png_bytep buf)
-{
- png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
- (png_uint_16)(*(buf + 1)));
-
- return (i);
-}
-#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
-
-/* Read data, and (optionally) run it through the CRC. */
-void
-png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
-{
- png_read_data(png_ptr, buf, length);
- png_calculate_crc(png_ptr, buf, length);
-}
-
-/* Optionally skip data and then check the CRC. Depending on whether we
- are reading a ancillary or critical chunk, and how the program has set
- things up, we may calculate the CRC on the data and print a message.
- Returns '1' if there was a CRC error, '0' otherwise. */
-int
-png_crc_finish(png_structp png_ptr, png_uint_32 skip)
-{
- png_size_t i;
- png_size_t istop = png_ptr->zbuf_size;
-
- for (i = (png_size_t)skip; i > istop; i -= istop)
- {
- png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
- }
- if (i)
- {
- png_crc_read(png_ptr, png_ptr->zbuf, i);
- }
-
- if (png_crc_error(png_ptr))
- {
- if ((png_ptr->chunk_name[0] & 0x20 && /* Ancillary */
- !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
- (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */
- png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))
- {
- png_chunk_warning(png_ptr, "CRC error");
- }
- else
- {
- png_chunk_error(png_ptr, "CRC error");
- }
- return (1);
- }
-
- return (0);
-}
-
-/* Compare the CRC stored in the PNG file with that calculated by libpng from
- the data it has read thus far. */
-int
-png_crc_error(png_structp png_ptr)
-{
- png_byte crc_bytes[4];
- png_uint_32 crc;
- int need_crc = 1;
-
- if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
- {
- if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
- (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
- need_crc = 0;
- }
- else /* critical */
- {
- if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
- need_crc = 0;
- }
-
- png_read_data(png_ptr, crc_bytes, 4);
-
- if (need_crc)
- {
- crc = png_get_uint_32(crc_bytes);
- return ((int)(crc != png_ptr->crc));
- }
- else
- return (0);
-}
-
-
-/* read and check the IDHR chunk */
-void
-png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_byte buf[13];
- png_uint_32 width, height;
- int bit_depth, color_type, compression_type, filter_type;
- int interlace_type;
-
- png_debug(1, "in png_handle_IHDR\n");
-
- if (png_ptr->mode != PNG_BEFORE_IHDR)
- png_error(png_ptr, "Out of place IHDR");
-
- /* check the length */
- if (length != 13)
- png_error(png_ptr, "Invalid IHDR chunk");
-
- png_ptr->mode |= PNG_HAVE_IHDR;
-
- png_crc_read(png_ptr, buf, 13);
- png_crc_finish(png_ptr, 0);
-
- width = png_get_uint_32(buf);
- height = png_get_uint_32(buf + 4);
- bit_depth = buf[8];
- color_type = buf[9];
- compression_type = buf[10];
- filter_type = buf[11];
- interlace_type = buf[12];
-
- /* check for width and height valid values */
- if (width == 0 || width > (png_uint_32)2147483647L || height == 0 ||
- height > (png_uint_32)2147483647L)
- png_error(png_ptr, "Invalid image size in IHDR");
-
- /* check other values */
- if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
- bit_depth != 8 && bit_depth != 16)
- png_error(png_ptr, "Invalid bit depth in IHDR");
-
- if (color_type < 0 || color_type == 1 ||
- color_type == 5 || color_type > 6)
- png_error(png_ptr, "Invalid color type in IHDR");
-
- if ((color_type == PNG_COLOR_TYPE_PALETTE && bit_depth) > 8 ||
- ((color_type == PNG_COLOR_TYPE_RGB ||
- color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
- color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
- png_error(png_ptr, "Invalid color type/bit depth combination in IHDR");
-
- if (interlace_type >= PNG_INTERLACE_LAST)
- png_error(png_ptr, "Unknown interlace method in IHDR");
-
- if (compression_type != PNG_COMPRESSION_TYPE_BASE)
- png_error(png_ptr, "Unknown compression method in IHDR");
-
- if (filter_type != PNG_FILTER_TYPE_BASE)
- png_error(png_ptr, "Unknown filter method in IHDR");
-
- /* set internal variables */
- png_ptr->width = width;
- png_ptr->height = height;
- png_ptr->bit_depth = (png_byte)bit_depth;
- png_ptr->interlaced = (png_byte)interlace_type;
- png_ptr->color_type = (png_byte)color_type;
-
- /* find number of channels */
- switch (png_ptr->color_type)
- {
- case PNG_COLOR_TYPE_GRAY:
- case PNG_COLOR_TYPE_PALETTE:
- png_ptr->channels = 1;
- break;
- case PNG_COLOR_TYPE_RGB:
- png_ptr->channels = 3;
- break;
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- png_ptr->channels = 2;
- break;
- case PNG_COLOR_TYPE_RGB_ALPHA:
- png_ptr->channels = 4;
- break;
- }
-
- /* set up other useful info */
- png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
- png_ptr->channels);
- png_ptr->rowbytes = ((png_ptr->width *
- (png_uint_32)png_ptr->pixel_depth + 7) >> 3);
- png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth);
- png_debug1(3,"channels = %d\n", png_ptr->channels);
- png_debug1(3,"rowbytes = %d\n", png_ptr->rowbytes);
- png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
- color_type, interlace_type, compression_type, filter_type);
-}
-
-/* read and check the palette */
-void
-png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_colorp palette;
- int num, i;
-
- png_debug(1, "in png_handle_PLTE\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before PLTE");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid PLTE after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (png_ptr->mode & PNG_HAVE_PLTE)
- png_error(png_ptr, "Duplicate PLTE chunk");
-
- png_ptr->mode |= PNG_HAVE_PLTE;
-
-#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
- if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
- {
- png_crc_finish(png_ptr, length);
- return;
- }
-#endif
-
- if (length % 3)
- {
- if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
- {
- png_warning(png_ptr, "Invalid palette chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
- else
- {
- png_error(png_ptr, "Invalid palette chunk");
- }
- }
-
- num = (int)length / 3;
- palette = (png_colorp)png_zalloc(png_ptr, (uInt)num, sizeof (png_color));
- png_ptr->flags |= PNG_FLAG_FREE_PALETTE;
- for (i = 0; i < num; i++)
- {
- png_byte buf[3];
-
- png_crc_read(png_ptr, buf, 3);
- /* don't depend upon png_color being any order */
- palette[i].red = buf[0];
- palette[i].green = buf[1];
- palette[i].blue = buf[2];
- }
-
- /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
- whatever the normal CRC configuration tells us. However, if we
- have an RGB image, the PLTE can be considered ancillary, so
- we will act as though it is. */
-#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-#endif
- {
- png_crc_finish(png_ptr, 0);
- }
-#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
- else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */
- {
- /* If we don't want to use the data from an ancillary chunk,
- we have two options: an error abort, or a warning and we
- ignore the data in this chunk (which should be OK, since
- it's considered ancillary for a RGB or RGBA image). */
- if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
- {
- if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
- {
- png_chunk_error(png_ptr, "CRC error");
- }
- else
- {
- png_chunk_warning(png_ptr, "CRC error");
- png_ptr->flags &= ~PNG_FLAG_FREE_PALETTE;
- png_zfree(png_ptr, palette);
- return;
- }
- }
- /* Otherwise, we (optionally) emit a warning and use the chunk. */
- else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
- {
- png_chunk_warning(png_ptr, "CRC error");
- }
- }
-#endif
- png_ptr->palette = palette;
- png_ptr->num_palette = (png_uint_16)num;
- png_set_PLTE(png_ptr, info_ptr, palette, num);
-
-#if defined (PNG_READ_tRNS_SUPPORTED)
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (info_ptr != NULL && info_ptr->valid & PNG_INFO_tRNS)
- {
- if (png_ptr->num_trans > png_ptr->num_palette)
- {
- png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
- png_ptr->num_trans = png_ptr->num_palette;
- }
- }
- }
-#endif
-
-}
-
-void
-png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_debug(1, "in png_handle_IEND\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
- {
- png_error(png_ptr, "No image in file");
-
- /* to quiet compiler warnings about unused info_ptr */
- if (info_ptr == NULL)
- return;
- }
-
- png_ptr->mode |= PNG_AFTER_IDAT | PNG_HAVE_IEND;
-
- if (length != 0)
- {
- png_warning(png_ptr, "Incorrect IEND chunk length");
- }
- png_crc_finish(png_ptr, length);
-}
-
-#if defined(PNG_READ_gAMA_SUPPORTED)
-void
-png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_uint_32 igamma;
- float file_gamma;
- png_byte buf[4];
-
- png_debug(1, "in png_handle_gAMA\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before gAMA");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid gAMA after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (png_ptr->mode & PNG_HAVE_PLTE)
- /* Should be an error, but we can cope with it */
- png_warning(png_ptr, "Out of place gAMA chunk");
-
- else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_gAMA
-#if defined(PNG_READ_sRGB_SUPPORTED)
- && !(info_ptr->valid & PNG_INFO_sRGB)
-#endif
- )
- {
- png_warning(png_ptr, "Duplicate gAMA chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (length != 4)
- {
- png_warning(png_ptr, "Incorrect gAMA chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, 4);
- if (png_crc_finish(png_ptr, 0))
- return;
-
- igamma = png_get_uint_32(buf);
- /* check for zero gamma */
- if (igamma == 0)
- return;
-
-#if defined(PNG_READ_sRGB_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_sRGB)
- if(igamma != (png_uint_32)45000L)
- {
- png_warning(png_ptr,
- "Ignoring incorrect gAMA value when sRGB is also present");
-#ifndef PNG_NO_CONSOLE_IO
- fprintf(stderr, "igamma = %lu\n", igamma);
-#endif
- return;
- }
-#endif /* PNG_READ_sRGB_SUPPORTED */
-
- file_gamma = (float)igamma / (float)100000.0;
-#ifdef PNG_READ_GAMMA_SUPPORTED
- png_ptr->gamma = file_gamma;
-#endif
- png_set_gAMA(png_ptr, info_ptr, file_gamma);
-}
-#endif
-
-#if defined(PNG_READ_sBIT_SUPPORTED)
-void
-png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_size_t truelen;
- png_byte buf[4];
-
- png_debug(1, "in png_handle_sBIT\n");
-
- buf[0] = buf[1] = buf[2] = buf[3] = 0;
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before sBIT");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid sBIT after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (png_ptr->mode & PNG_HAVE_PLTE)
- {
- /* Should be an error, but we can cope with it */
- png_warning(png_ptr, "Out of place sBIT chunk");
- }
- else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_sBIT)
- {
- png_warning(png_ptr, "Duplicate sBIT chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- truelen = 3;
- else
- truelen = (png_size_t)png_ptr->channels;
-
- if (length != truelen)
- {
- png_warning(png_ptr, "Incorrect sBIT chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, truelen);
- if (png_crc_finish(png_ptr, 0))
- return;
-
- if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
- {
- png_ptr->sig_bit.red = buf[0];
- png_ptr->sig_bit.green = buf[1];
- png_ptr->sig_bit.blue = buf[2];
- png_ptr->sig_bit.alpha = buf[3];
- }
- else
- {
- png_ptr->sig_bit.gray = buf[0];
- png_ptr->sig_bit.red = buf[0];
- png_ptr->sig_bit.green = buf[0];
- png_ptr->sig_bit.blue = buf[0];
- png_ptr->sig_bit.alpha = buf[1];
- }
- png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
-}
-#endif
-
-#if defined(PNG_READ_cHRM_SUPPORTED)
-void
-png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_byte buf[4];
- png_uint_32 val;
- float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
-
- png_debug(1, "in png_handle_cHRM\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before sBIT");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid cHRM after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (png_ptr->mode & PNG_HAVE_PLTE)
- /* Should be an error, but we can cope with it */
- png_warning(png_ptr, "Missing PLTE before cHRM");
-
- else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_cHRM
-#if defined(PNG_READ_sRGB_SUPPORTED)
- && !(info_ptr->valid & PNG_INFO_sRGB)
-#endif
- )
- {
- png_warning(png_ptr, "Duplicate cHRM chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (length != 32)
- {
- png_warning(png_ptr, "Incorrect cHRM chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, 4);
- val = png_get_uint_32(buf);
- white_x = (float)val / (float)100000.0;
-
- png_crc_read(png_ptr, buf, 4);
- val = png_get_uint_32(buf);
- white_y = (float)val / (float)100000.0;
-
- if (white_x < 0 || white_x > 0.8 || white_y < 0 || white_y > 0.8 ||
- white_x + white_y > 1.0)
- {
- png_warning(png_ptr, "Invalid cHRM white point");
- png_crc_finish(png_ptr, 24);
- return;
- }
-
- png_crc_read(png_ptr, buf, 4);
- val = png_get_uint_32(buf);
- red_x = (float)val / (float)100000.0;
-
- png_crc_read(png_ptr, buf, 4);
- val = png_get_uint_32(buf);
- red_y = (float)val / (float)100000.0;
-
- if (red_x < 0 || red_x > 0.8 || red_y < 0 || red_y > 0.8 ||
- red_x + red_y > 1.0)
- {
- png_warning(png_ptr, "Invalid cHRM red point");
- png_crc_finish(png_ptr, 16);
- return;
- }
-
- png_crc_read(png_ptr, buf, 4);
- val = png_get_uint_32(buf);
- green_x = (float)val / (float)100000.0;
-
- png_crc_read(png_ptr, buf, 4);
- val = png_get_uint_32(buf);
- green_y = (float)val / (float)100000.0;
-
- if (green_x < 0 || green_x > 0.8 || green_y < 0 || green_y > 0.8 ||
- green_x + green_y > 1.0)
- {
- png_warning(png_ptr, "Invalid cHRM green point");
- png_crc_finish(png_ptr, 8);
- return;
- }
-
- png_crc_read(png_ptr, buf, 4);
- val = png_get_uint_32(buf);
- blue_x = (float)val / (float)100000.0;
-
- png_crc_read(png_ptr, buf, 4);
- val = png_get_uint_32(buf);
- blue_y = (float)val / (float)100000.0;
-
- if (blue_x < (float)0 || blue_x > (float)0.8 || blue_y < (float)0 ||
- blue_y > (float)0.8 || blue_x + blue_y > (float)1.0)
- {
- png_warning(png_ptr, "Invalid cHRM blue point");
- png_crc_finish(png_ptr, 0);
- return;
- }
-
- if (png_crc_finish(png_ptr, 0))
- return;
-
-#if defined(PNG_READ_sRGB_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_sRGB)
- {
- if (fabs(white_x - (float).3127) > (float).001 ||
- fabs(white_y - (float).3290) > (float).001 ||
- fabs( red_x - (float).6400) > (float).001 ||
- fabs( red_y - (float).3300) > (float).001 ||
- fabs(green_x - (float).3000) > (float).001 ||
- fabs(green_y - (float).6000) > (float).001 ||
- fabs( blue_x - (float).1500) > (float).001 ||
- fabs( blue_y - (float).0600) > (float).001)
- {
-
- png_warning(png_ptr,
- "Ignoring incorrect cHRM value when sRGB is also present");
-#ifndef PNG_NO_CONSOLE_IO
- fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n",
- white_x, white_y, red_x, red_y);
- fprintf(stderr,"gx=%f, gy=%f, bx=%f, by=%f\n",
- green_x, green_y, blue_x, blue_y);
-#endif
- }
- return;
- }
-#endif /* PNG_READ_sRGB_SUPPORTED */
-
- png_set_cHRM(png_ptr, info_ptr,
- white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
-}
-#endif
-
-#if defined(PNG_READ_sRGB_SUPPORTED)
-void
-png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- int intent;
- png_byte buf[1];
-
- png_debug(1, "in png_handle_sRGB\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before sRGB");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid sRGB after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (png_ptr->mode & PNG_HAVE_PLTE)
- /* Should be an error, but we can cope with it */
- png_warning(png_ptr, "Out of place sRGB chunk");
-
- else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_sRGB)
- {
- png_warning(png_ptr, "Duplicate sRGB chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (length != 1)
- {
- png_warning(png_ptr, "Incorrect sRGB chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, 1);
- if (png_crc_finish(png_ptr, 0))
- return;
-
- intent = buf[0];
- /* check for bad intent */
- if (intent >= PNG_sRGB_INTENT_LAST)
- {
- png_warning(png_ptr, "Unknown sRGB intent");
- return;
- }
-
-#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
- if ((info_ptr->valid & PNG_INFO_gAMA))
- if((png_uint_32)(png_ptr->gamma*(float)100000.+.5) != (png_uint_32)45000L)
- {
- png_warning(png_ptr,
- "Ignoring incorrect gAMA value when sRGB is also present");
-#ifndef PNG_NO_CONSOLE_IO
- fprintf(stderr,"gamma=%f\n",png_ptr->gamma);
-#endif
- }
-#endif /* PNG_READ_gAMA_SUPPORTED */
-
-#ifdef PNG_READ_cHRM_SUPPORTED
- if (info_ptr->valid & PNG_INFO_cHRM)
- if (fabs(info_ptr->x_white - (float).3127) > (float).001 ||
- fabs(info_ptr->y_white - (float).3290) > (float).001 ||
- fabs( info_ptr->x_red - (float).6400) > (float).001 ||
- fabs( info_ptr->y_red - (float).3300) > (float).001 ||
- fabs(info_ptr->x_green - (float).3000) > (float).001 ||
- fabs(info_ptr->y_green - (float).6000) > (float).001 ||
- fabs( info_ptr->x_blue - (float).1500) > (float).001 ||
- fabs( info_ptr->y_blue - (float).0600) > (float).001)
- {
- png_warning(png_ptr,
- "Ignoring incorrect cHRM value when sRGB is also present");
- }
-#endif /* PNG_READ_cHRM_SUPPORTED */
-
- png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
-}
-#endif /* PNG_READ_sRGB_SUPPORTED */
-
-#if defined(PNG_READ_tRNS_SUPPORTED)
-void
-png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_debug(1, "in png_handle_tRNS\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before tRNS");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid tRNS after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_tRNS)
- {
- png_warning(png_ptr, "Duplicate tRNS chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (!(png_ptr->mode & PNG_HAVE_PLTE))
- {
- /* Should be an error, but we can cope with it */
- png_warning(png_ptr, "Missing PLTE before tRNS");
- }
- else if (length > png_ptr->num_palette)
- {
- png_warning(png_ptr, "Incorrect tRNS chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
- if (length == 0)
- {
- png_warning(png_ptr, "Zero length tRNS chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_ptr->trans = (png_bytep)png_malloc(png_ptr, length);
- png_ptr->flags |= PNG_FLAG_FREE_TRANS;
- png_crc_read(png_ptr, png_ptr->trans, (png_size_t)length);
- png_ptr->num_trans = (png_uint_16)length;
- }
- else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
- {
- png_byte buf[6];
-
- if (length != 6)
- {
- png_warning(png_ptr, "Incorrect tRNS chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, (png_size_t)length);
- png_ptr->num_trans = 1;
- png_ptr->trans_values.red = png_get_uint_16(buf);
- png_ptr->trans_values.green = png_get_uint_16(buf + 2);
- png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
- }
- else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
- {
- png_byte buf[6];
-
- if (length != 2)
- {
- png_warning(png_ptr, "Incorrect tRNS chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, 2);
- png_ptr->num_trans = 1;
- png_ptr->trans_values.gray = png_get_uint_16(buf);
- }
- else
- {
- png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (png_crc_finish(png_ptr, 0))
- return;
-
- png_set_tRNS(png_ptr, info_ptr, png_ptr->trans, png_ptr->num_trans,
- &(png_ptr->trans_values));
-}
-#endif
-
-#if defined(PNG_READ_bKGD_SUPPORTED)
-void
-png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_size_t truelen;
- png_byte buf[6];
-
- png_debug(1, "in png_handle_bKGD\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before bKGD");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid bKGD after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
- !(png_ptr->mode & PNG_HAVE_PLTE))
- {
- png_warning(png_ptr, "Missing PLTE before bKGD");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_bKGD)
- {
- png_warning(png_ptr, "Duplicate bKGD chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- truelen = 1;
- else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
- truelen = 6;
- else
- truelen = 2;
-
- if (length != truelen)
- {
- png_warning(png_ptr, "Incorrect bKGD chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, truelen);
- if (png_crc_finish(png_ptr, 0))
- return;
-
- /* We convert the index value into RGB components so that we can allow
- * arbitrary RGB values for background when we have transparency, and
- * so it is easy to determine the RGB values of the background color
- * from the info_ptr struct. */
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_ptr->background.index = buf[0];
- png_ptr->background.red = (png_uint_16)png_ptr->palette[buf[0]].red;
- png_ptr->background.green = (png_uint_16)png_ptr->palette[buf[0]].green;
- png_ptr->background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue;
- }
- else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
- {
- png_ptr->background.red =
- png_ptr->background.green =
- png_ptr->background.blue =
- png_ptr->background.gray = png_get_uint_16(buf);
- }
- else
- {
- png_ptr->background.red = png_get_uint_16(buf);
- png_ptr->background.green = png_get_uint_16(buf + 2);
- png_ptr->background.blue = png_get_uint_16(buf + 4);
- }
-
- png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
-}
-#endif
-
-#if defined(PNG_READ_hIST_SUPPORTED)
-void
-png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- int num, i;
-
- png_debug(1, "in png_handle_hIST\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before hIST");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid hIST after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (!(png_ptr->mode & PNG_HAVE_PLTE))
- {
- png_warning(png_ptr, "Missing PLTE before hIST");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_hIST)
- {
- png_warning(png_ptr, "Duplicate hIST chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (length != (png_uint_32)(2 * png_ptr->num_palette))
- {
- png_warning(png_ptr, "Incorrect hIST chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- num = (int)length / 2;
- png_ptr->hist = (png_uint_16p)png_malloc(png_ptr,
- (png_uint_32)(num * sizeof (png_uint_16)));
- png_ptr->flags |= PNG_FLAG_FREE_HIST;
- for (i = 0; i < num; i++)
- {
- png_byte buf[2];
-
- png_crc_read(png_ptr, buf, 2);
- png_ptr->hist[i] = png_get_uint_16(buf);
- }
-
- if (png_crc_finish(png_ptr, 0))
- return;
-
- png_set_hIST(png_ptr, info_ptr, png_ptr->hist);
-}
-#endif
-
-#if defined(PNG_READ_pHYs_SUPPORTED)
-void
-png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_byte buf[9];
- png_uint_32 res_x, res_y;
- int unit_type;
-
- png_debug(1, "in png_handle_pHYs\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before pHYS");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid pHYS after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_pHYs)
- {
- png_warning(png_ptr, "Duplicate pHYS chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (length != 9)
- {
- png_warning(png_ptr, "Incorrect pHYs chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, 9);
- if (png_crc_finish(png_ptr, 0))
- return;
-
- res_x = png_get_uint_32(buf);
- res_y = png_get_uint_32(buf + 4);
- unit_type = buf[8];
- png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
-}
-#endif
-
-#if defined(PNG_READ_oFFs_SUPPORTED)
-void
-png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_byte buf[9];
- png_uint_32 offset_x, offset_y;
- int unit_type;
-
- png_debug(1, "in png_handle_oFFs\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before oFFs");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid oFFs after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_oFFs)
- {
- png_warning(png_ptr, "Duplicate oFFs chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (length != 9)
- {
- png_warning(png_ptr, "Incorrect oFFs chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, 9);
- if (png_crc_finish(png_ptr, 0))
- return;
-
- offset_x = png_get_uint_32(buf);
- offset_y = png_get_uint_32(buf + 4);
- unit_type = buf[8];
- png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
-}
-#endif
-
-#if defined(PNG_READ_pCAL_SUPPORTED)
-/* read the pCAL chunk (png-scivis-19970203) */
-void
-png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_charp purpose;
- png_int_32 X0, X1;
- png_byte type, nparams;
- png_charp buf, units, endptr;
- png_charpp params;
- png_size_t slength;
- int i;
-
- png_debug(1, "in png_handle_pCAL\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before pCAL");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid pCAL after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_pCAL)
- {
- png_warning(png_ptr, "Duplicate pCAL chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_debug1(2, "Allocating and reading pCAL chunk data (%d bytes)\n",
- length + 1);
- purpose = (png_charp)png_malloc(png_ptr, length + 1);
- slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)purpose, slength);
-
- if (png_crc_finish(png_ptr, 0))
- {
- png_free(png_ptr, purpose);
- return;
- }
-
- purpose[slength] = 0x00; /* null terminate the last string */
-
- png_debug(3, "Finding end of pCAL purpose string\n");
- for (buf = purpose; *buf; buf++)
- /* empty loop */ ;
-
- endptr = purpose + slength;
-
- /* We need to have at least 12 bytes after the purpose string
- in order to get the parameter information. */
- if (endptr <= buf + 12)
- {
- png_warning(png_ptr, "Invalid pCAL data");
- png_free(png_ptr, purpose);
- return;
- }
-
- png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
- X0 = png_get_int_32((png_bytep)buf+1);
- X1 = png_get_int_32((png_bytep)buf+5);
- type = buf[9];
- nparams = buf[10];
- units = buf + 11;
-
- png_debug(3, "Checking pCAL equation type and number of parameters\n");
- /* Check that we have the right number of parameters for known
- equation types. */
- if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
- (type == PNG_EQUATION_BASE_E && nparams != 3) ||
- (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
- (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
- {
- png_warning(png_ptr, "Invalid pCAL parameters for equation type");
- png_free(png_ptr, purpose);
- return;
- }
- else if (type >= PNG_EQUATION_LAST)
- {
- png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
- }
-
- for (buf = units; *buf; buf++)
- /* Empty loop to move past the units string. */ ;
-
- png_debug(3, "Allocating pCAL parameters array\n");
- params = (png_charpp)png_malloc(png_ptr, (png_uint_32)(nparams
- *sizeof(png_charp))) ;
-
- /* Get pointers to the start of each parameter string. */
- for (i = 0; i < (int)nparams; i++)
- {
- buf++; /* Skip the null string terminator from previous parameter. */
-
- png_debug1(3, "Reading pCAL parameter %d\n", i);
- for (params[i] = buf; *buf != 0x00 && buf <= endptr; buf++)
- /* Empty loop to move past each parameter string */ ;
-
- /* Make sure we haven't run out of data yet */
- if (buf > endptr)
- {
- png_warning(png_ptr, "Invalid pCAL data");
- png_free(png_ptr, purpose);
- png_free(png_ptr, params);
- return;
- }
- }
-
- png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams,
- units, params);
-
- png_free(png_ptr, purpose);
- png_free(png_ptr, params);
-}
-#endif
-
-#if defined(PNG_READ_tIME_SUPPORTED)
-void
-png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_byte buf[7];
- png_time mod_time;
-
- png_debug(1, "in png_handle_tIME\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Out of place tIME chunk");
- else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_tIME)
- {
- png_warning(png_ptr, "Duplicate tIME chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (png_ptr->mode & PNG_HAVE_IDAT)
- png_ptr->mode |= PNG_AFTER_IDAT;
-
- if (length != 7)
- {
- png_warning(png_ptr, "Incorrect tIME chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, 7);
- if (png_crc_finish(png_ptr, 0))
- return;
-
- mod_time.second = buf[6];
- mod_time.minute = buf[5];
- mod_time.hour = buf[4];
- mod_time.day = buf[3];
- mod_time.month = buf[2];
- mod_time.year = png_get_uint_16(buf);
-
- png_set_tIME(png_ptr, info_ptr, &mod_time);
-}
-#endif
-
-#if defined(PNG_READ_tEXt_SUPPORTED)
-/* Note: this does not properly handle chunks that are > 64K under DOS */
-void
-png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_textp text_ptr;
- png_charp key;
- png_charp text;
- png_uint_32 skip = 0;
- png_size_t slength;
-
- png_debug(1, "in png_handle_tEXt\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before tEXt");
-
- if (png_ptr->mode & PNG_HAVE_IDAT)
- png_ptr->mode |= PNG_AFTER_IDAT;
-
-#ifdef PNG_MAX_MALLOC_64K
- if (length > (png_uint_32)65535L)
- {
- png_warning(png_ptr, "tEXt chunk too large to fit in memory");
- skip = length - (png_uint_32)65535L;
- length = (png_uint_32)65535L;
- }
-#endif
-
- key = (png_charp)png_malloc(png_ptr, length + 1);
- slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)key, slength);
-
- if (png_crc_finish(png_ptr, skip))
- {
- png_free(png_ptr, key);
- return;
- }
-
- key[slength] = 0x00;
-
- for (text = key; *text; text++)
- /* empty loop to find end of key */ ;
-
- if (text != key + slength)
- text++;
-
- text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
- text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
- text_ptr->key = key;
- text_ptr->text = text;
-
- png_set_text(png_ptr, info_ptr, text_ptr, 1);
-
- png_free(png_ptr, text_ptr);
-}
-#endif
-
-#if defined(PNG_READ_zTXt_SUPPORTED)
-/* note: this does not correctly handle chunks that are > 64K under DOS */
-void
-png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- static char msg[] = "Error decoding zTXt chunk";
- png_textp text_ptr;
- png_charp key;
- png_charp text;
- int comp_type = PNG_TEXT_COMPRESSION_NONE;
- png_size_t slength;
-
- png_debug(1, "in png_handle_zTXt\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before zTXt");
-
- if (png_ptr->mode & PNG_HAVE_IDAT)
- png_ptr->mode |= PNG_AFTER_IDAT;
-
-#ifdef PNG_MAX_MALLOC_64K
- /* We will no doubt have problems with chunks even half this size, but
- there is no hard and fast rule to tell us where to stop. */
- if (length > (png_uint_32)65535L)
- {
- png_warning(png_ptr,"zTXt chunk too large to fit in memory");
- png_crc_finish(png_ptr, length);
- return;
- }
-#endif
-
- key = (png_charp)png_malloc(png_ptr, length + 1);
- slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)key, slength);
- if (png_crc_finish(png_ptr, 0))
- {
- png_free(png_ptr, key);
- return;
- }
-
- key[slength] = 0x00;
-
- for (text = key; *text; text++)
- /* empty loop */ ;
-
- /* zTXt must have some text after the keyword */
- if (text == key + slength)
- {
- png_warning(png_ptr, "Zero length zTXt chunk");
- }
- else if ((comp_type = *(++text)) == PNG_TEXT_COMPRESSION_zTXt)
- {
- png_size_t text_size, key_size;
- text++;
-
- png_ptr->zstream.next_in = (png_bytep)text;
- png_ptr->zstream.avail_in = (uInt)(length - (text - key));
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-
- key_size = (png_size_t)(text - key);
- text_size = 0;
- text = NULL;
-
- while (png_ptr->zstream.avail_in)
- {
- int ret;
-
- ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
- if (ret != Z_OK && ret != Z_STREAM_END)
- {
- if (png_ptr->zstream.msg != NULL)
- png_warning(png_ptr, png_ptr->zstream.msg);
- else
- png_warning(png_ptr, msg);
- inflateReset(&png_ptr->zstream);
- png_ptr->zstream.avail_in = 0;
-
- if (text == NULL)
- {
- text_size = key_size + sizeof(msg) + 1;
- text = (png_charp)png_malloc(png_ptr, (png_uint_32)text_size);
- png_memcpy(text, key, key_size);
- }
-
- text[text_size - 1] = 0x00;
-
- /* Copy what we can of the error message into the text chunk */
- text_size = (png_size_t)(slength - (text - key) - 1);
- text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);
- png_memcpy(text + key_size, msg, text_size + 1);
- break;
- }
- if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
- {
- if (text == NULL)
- {
- text = (png_charp)png_malloc(png_ptr,
- (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
- + key_size + 1));
- png_memcpy(text + key_size, png_ptr->zbuf,
- png_ptr->zbuf_size - png_ptr->zstream.avail_out);
- png_memcpy(text, key, key_size);
- text_size = key_size + png_ptr->zbuf_size -
- png_ptr->zstream.avail_out;
- *(text + text_size) = 0x00;
- }
- else
- {
- png_charp tmp;
-
- tmp = text;
- text = (png_charp)png_malloc(png_ptr, (png_uint_32)(text_size +
- png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
- png_memcpy(text, tmp, text_size);
- png_free(png_ptr, tmp);
- png_memcpy(text + text_size, png_ptr->zbuf,
- (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
- text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
- *(text + text_size) = 0x00;
- }
- if (ret != Z_STREAM_END)
- {
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- }
- else
- {
- break;
- }
- }
- }
-
- inflateReset(&png_ptr->zstream);
- png_ptr->zstream.avail_in = 0;
-
- png_free(png_ptr, key);
- key = text;
- text += key_size;
- }
- else /* if (comp_type >= PNG_TEXT_COMPRESSION_LAST) */
- {
- png_size_t text_size;
-#if !defined(PNG_NO_STDIO)
- char umsg[50];
-
- sprintf(umsg, "Unknown zTXt compression type %d", comp_type);
- png_warning(png_ptr, umsg);
-#else
- png_warning(png_ptr, "Unknown zTXt compression type");
-#endif
-
- /* Copy what we can of the error message into the text chunk */
- text_size = (png_size_t)(slength - (text - key) - 1);
- text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);
- png_memcpy(text, msg, text_size + 1);
- }
-
- text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
- text_ptr->compression = comp_type;
- text_ptr->key = key;
- text_ptr->text = text;
-
- png_set_text(png_ptr, info_ptr, text_ptr, 1);
-
- png_free(png_ptr, text_ptr);
-}
-#endif
-
-/* This function is called when we haven't found a handler for a
- chunk. If there isn't a problem with the chunk itself (ie bad
- chunk name, CRC, or a critical chunk), the chunk is silently ignored. */
-void
-png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_debug(1, "in png_handle_unknown\n");
-
- /* In the future we can have code here that calls user-supplied
- * callback functions for unknown chunks before they are ignored or
- * cause an error.
- */
- png_check_chunk_name(png_ptr, png_ptr->chunk_name);
-
- if (!(png_ptr->chunk_name[0] & 0x20))
- {
- png_chunk_error(png_ptr, "unknown critical chunk");
-
- /* to quiet compiler warnings about unused info_ptr */
- if (info_ptr == NULL)
- return;
- }
-
- if (png_ptr->mode & PNG_HAVE_IDAT)
- png_ptr->mode |= PNG_AFTER_IDAT;
-
- png_crc_finish(png_ptr, length);
-
-}
-
-/* This function is called to verify that a chunk name is valid.
- This function can't have the "critical chunk check" incorporated
- into it, since in the future we will need to be able to call user
- functions to handle unknown critical chunks after we check that
- the chunk name itself is valid. */
-
-#define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97))
-
-void
-png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
-{
- png_debug(1, "in png_check_chunk_name\n");
- if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
- isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
- {
- png_chunk_error(png_ptr, "invalid chunk type");
- }
-}
-
-/* Combines the row recently read in with the existing pixels in the
- row. This routine takes care of alpha and transparency if requested.
- This routine also handles the two methods of progressive display
- of interlaced images, depending on the mask value.
- The mask value describes which pixels are to be combined with
- the row. The pattern always repeats every 8 pixels, so just 8
- bits are needed. A one indicates the pixel is to be combined,
- a zero indicates the pixel is to be skipped. This is in addition
- to any alpha or transparency value associated with the pixel. If
- you want all pixels to be combined, pass 0xff (255) in mask. */
-void
-png_combine_row(png_structp png_ptr, png_bytep row,
- int mask)
-{
- png_debug(1,"in png_combine_row\n");
- if (mask == 0xff)
- {
- png_memcpy(row, png_ptr->row_buf + 1,
- (png_size_t)((png_ptr->width *
- png_ptr->row_info.pixel_depth + 7) >> 3));
- }
- else
- {
- switch (png_ptr->row_info.pixel_depth)
- {
- case 1:
- {
- png_bytep sp = png_ptr->row_buf + 1;
- png_bytep dp = row;
- int s_inc, s_start, s_end;
- int m = 0x80;
- int shift;
- png_uint_32 i;
- png_uint_32 row_width = png_ptr->width;
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- {
- s_start = 0;
- s_end = 7;
- s_inc = 1;
- }
- else
-#endif
- {
- s_start = 7;
- s_end = 0;
- s_inc = -1;
- }
-
- shift = s_start;
-
- for (i = 0; i < row_width; i++)
- {
- if (m & mask)
- {
- int value;
-
- value = (*sp >> shift) & 0x1;
- *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
- *dp |= (png_byte)(value << shift);
- }
-
- if (shift == s_end)
- {
- shift = s_start;
- sp++;
- dp++;
- }
- else
- shift += s_inc;
-
- if (m == 1)
- m = 0x80;
- else
- m >>= 1;
- }
- break;
- }
- case 2:
- {
- png_bytep sp = png_ptr->row_buf + 1;
- png_bytep dp = row;
- int s_start, s_end, s_inc;
- int m = 0x80;
- int shift;
- png_uint_32 i;
- png_uint_32 row_width = png_ptr->width;
- int value;
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- {
- s_start = 0;
- s_end = 6;
- s_inc = 2;
- }
- else
-#endif
- {
- s_start = 6;
- s_end = 0;
- s_inc = -2;
- }
-
- shift = s_start;
-
- for (i = 0; i < row_width; i++)
- {
- if (m & mask)
- {
- value = (*sp >> shift) & 0x3;
- *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
- *dp |= (png_byte)(value << shift);
- }
-
- if (shift == s_end)
- {
- shift = s_start;
- sp++;
- dp++;
- }
- else
- shift += s_inc;
- if (m == 1)
- m = 0x80;
- else
- m >>= 1;
- }
- break;
- }
- case 4:
- {
- png_bytep sp = png_ptr->row_buf + 1;
- png_bytep dp = row;
- int s_start, s_end, s_inc;
- int m = 0x80;
- int shift;
- png_uint_32 i;
- png_uint_32 row_width = png_ptr->width;
- int value;
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- {
- s_start = 0;
- s_end = 4;
- s_inc = 4;
- }
- else
-#endif
- {
- s_start = 4;
- s_end = 0;
- s_inc = -4;
- }
- shift = s_start;
-
- for (i = 0; i < row_width; i++)
- {
- if (m & mask)
- {
- value = (*sp >> shift) & 0xf;
- *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
- *dp |= (png_byte)(value << shift);
- }
-
- if (shift == s_end)
- {
- shift = s_start;
- sp++;
- dp++;
- }
- else
- shift += s_inc;
- if (m == 1)
- m = 0x80;
- else
- m >>= 1;
- }
- break;
- }
- default:
- {
- png_bytep sp = png_ptr->row_buf + 1;
- png_bytep dp = row;
- png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
- png_uint_32 i;
- png_uint_32 row_width = png_ptr->width;
- png_byte m = 0x80;
-
-
- for (i = 0; i < row_width; i++)
- {
- if (m & mask)
- {
- png_memcpy(dp, sp, pixel_bytes);
- }
-
- sp += pixel_bytes;
- dp += pixel_bytes;
-
- if (m == 1)
- m = 0x80;
- else
- m >>= 1;
- }
- break;
- }
- }
- }
-}
-
-#if defined(PNG_READ_INTERLACING_SUPPORTED)
-void
-png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
- png_uint_32 transformations)
-{
- png_debug(1,"in png_do_read_interlace\n");
- if (row != NULL && row_info != NULL)
- {
- png_uint_32 final_width;
-
- final_width = row_info->width * png_pass_inc[pass];
-
- switch (row_info->pixel_depth)
- {
- case 1:
- {
- png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
- png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
- int sshift, dshift;
- int s_start, s_end, s_inc;
- int jstop = png_pass_inc[pass];
- png_byte v;
- png_uint_32 i;
- int j;
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (transformations & PNG_PACKSWAP)
- {
- sshift = (int)((row_info->width + 7) & 7);
- dshift = (int)((final_width + 7) & 7);
- s_start = 7;
- s_end = 0;
- s_inc = -1;
- }
- else
-#endif
- {
- sshift = 7 - (int)((row_info->width + 7) & 7);
- dshift = 7 - (int)((final_width + 7) & 7);
- s_start = 0;
- s_end = 7;
- s_inc = 1;
- }
-
- for (i = 0; i < row_info->width; i++)
- {
- v = (png_byte)((*sp >> sshift) & 0x1);
- for (j = 0; j < jstop; j++)
- {
- *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
- *dp |= (png_byte)(v << dshift);
- if (dshift == s_end)
- {
- dshift = s_start;
- dp--;
- }
- else
- dshift += s_inc;
- }
- if (sshift == s_end)
- {
- sshift = s_start;
- sp--;
- }
- else
- sshift += s_inc;
- }
- break;
- }
- case 2:
- {
- png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
- png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
- int sshift, dshift;
- int s_start, s_end, s_inc;
- int jstop = png_pass_inc[pass];
- png_uint_32 i;
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (transformations & PNG_PACKSWAP)
- {
- sshift = (int)(((row_info->width + 3) & 3) << 1);
- dshift = (int)(((final_width + 3) & 3) << 1);
- s_start = 6;
- s_end = 0;
- s_inc = -2;
- }
- else
-#endif
- {
- sshift = (int)((3 - ((row_info->width + 3) & 3)) << 1);
- dshift = (int)((3 - ((final_width + 3) & 3)) << 1);
- s_start = 0;
- s_end = 6;
- s_inc = 2;
- }
-
- for (i = 0; i < row_info->width; i++)
- {
- png_byte v;
- int j;
-
- v = (png_byte)((*sp >> sshift) & 0x3);
- for (j = 0; j < jstop; j++)
- {
- *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
- *dp |= (png_byte)(v << dshift);
- if (dshift == s_end)
- {
- dshift = s_start;
- dp--;
- }
- else
- dshift += s_inc;
- }
- if (sshift == s_end)
- {
- sshift = s_start;
- sp--;
- }
- else
- sshift += s_inc;
- }
- break;
- }
- case 4:
- {
- png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
- png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
- int sshift, dshift;
- int s_start, s_end, s_inc;
- png_uint_32 i;
- int jstop = png_pass_inc[pass];
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (transformations & PNG_PACKSWAP)
- {
- sshift = (int)(((row_info->width + 1) & 1) << 2);
- dshift = (int)(((final_width + 1) & 1) << 2);
- s_start = 4;
- s_end = 0;
- s_inc = -4;
- }
- else
-#endif
- {
- sshift = (int)((1 - ((row_info->width + 1) & 1)) << 2);
- dshift = (int)((1 - ((final_width + 1) & 1)) << 2);
- s_start = 0;
- s_end = 4;
- s_inc = 4;
- }
-
- for (i = 0; i < row_info->width; i++)
- {
- png_byte v = (png_byte)((*sp >> sshift) & 0xf);
- int j;
-
- for (j = 0; j < jstop; j++)
- {
- *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
- *dp |= (png_byte)(v << dshift);
- if (dshift == s_end)
- {
- dshift = s_start;
- dp--;
- }
- else
- dshift += s_inc;
- }
- if (sshift == s_end)
- {
- sshift = s_start;
- sp--;
- }
- else
- sshift += s_inc;
- }
- break;
- }
- default:
- {
- png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
- png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes;
- png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
- int jstop = png_pass_inc[pass];
- png_uint_32 i;
-
- for (i = 0; i < row_info->width; i++)
- {
- png_byte v[8];
- int j;
-
- png_memcpy(v, sp, pixel_bytes);
- for (j = 0; j < jstop; j++)
- {
- png_memcpy(dp, v, pixel_bytes);
- dp -= pixel_bytes;
- }
- sp -= pixel_bytes;
- }
- break;
- }
- }
- row_info->width = final_width;
- row_info->rowbytes = ((final_width *
- (png_uint_32)row_info->pixel_depth + 7) >> 3);
- }
-}
-#endif
-
-void
-png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
- png_bytep prev_row, int filter)
-{
- png_debug(1, "in png_read_filter_row\n");
- png_debug2(2,"row = %d, filter = %d\n", png_ptr->row_number, filter);
-
-
- switch (filter)
- {
- case PNG_FILTER_VALUE_NONE:
- break;
- case PNG_FILTER_VALUE_SUB:
- {
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
- png_uint_32 bpp = (row_info->pixel_depth + 7) / 8;
- png_bytep rp = row + bpp;
- png_bytep lp = row;
-
- for (i = bpp; i < istop; i++)
- {
- *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
- rp++;
- }
- break;
- }
- case PNG_FILTER_VALUE_UP:
- {
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
- png_bytep rp = row;
- png_bytep pp = prev_row;
-
- for (i = 0; i < istop; i++)
- {
- *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
- rp++;
- }
- break;
- }
- case PNG_FILTER_VALUE_AVG:
- {
- png_uint_32 i;
- png_bytep rp = row;
- png_bytep pp = prev_row;
- png_bytep lp = row;
- png_uint_32 bpp = (row_info->pixel_depth + 7) / 8;
- png_uint_32 istop = row_info->rowbytes - bpp;
-
- for (i = 0; i < bpp; i++)
- {
- *rp = (png_byte)(((int)(*rp) +
- ((int)(*pp++) / 2)) & 0xff);
- rp++;
- }
-
- for (i = 0; i < istop; i++)
- {
- *rp = (png_byte)(((int)(*rp) +
- (int)(*pp++ + *lp++) / 2) & 0xff);
- rp++;
- }
- break;
- }
- case PNG_FILTER_VALUE_PAETH:
- {
- png_uint_32 i;
- png_bytep rp = row;
- png_bytep pp = prev_row;
- png_bytep lp = row;
- png_bytep cp = prev_row;
- png_uint_32 bpp = (row_info->pixel_depth + 7) / 8;
- png_uint_32 istop=row_info->rowbytes - bpp;
-
- for (i = 0; i < bpp; i++)
- {
- *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
- rp++;
- }
-
- for (i = 0; i < istop; i++) /* use leftover rp,pp */
- {
- int a, b, c, pa, pb, pc, p;
-
- a = *lp++;
- b = *pp++;
- c = *cp++;
-
- p = b - c;
- pc = a - c;
-
-#ifdef PNG_USE_ABS
- pa = abs(p);
- pb = abs(pc);
- pc = abs(p + pc);
-#else
- pa = p < 0 ? -p : p;
- pb = pc < 0 ? -pc : pc;
- pc = (p + pc) < 0 ? -(p + pc) : p + pc;
-#endif
-
- /*
- if (pa <= pb && pa <= pc)
- p = a;
- else if (pb <= pc)
- p = b;
- else
- p = c;
- */
-
- p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
-
- *rp = (png_byte)(((int)(*rp) + p) & 0xff);
- rp++;
- }
- break;
- }
- default:
- png_warning(png_ptr, "Ignoring bad adaptive filter type");
- *row=0;
- break;
- }
-}
-
-void
-png_read_finish_row(png_structp png_ptr)
-{
- png_debug(1, "in png_read_finish_row\n");
- png_ptr->row_number++;
- if (png_ptr->row_number < png_ptr->num_rows)
- return;
-
- if (png_ptr->interlaced)
- {
- png_ptr->row_number = 0;
- png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
- do
- {
- png_ptr->pass++;
- if (png_ptr->pass >= 7)
- break;
- png_ptr->iwidth = (png_ptr->width +
- png_pass_inc[png_ptr->pass] - 1 -
- png_pass_start[png_ptr->pass]) /
- png_pass_inc[png_ptr->pass];
- png_ptr->irowbytes = ((png_ptr->iwidth *
- (png_uint_32)png_ptr->pixel_depth + 7) >> 3) +1;
-
- if (!(png_ptr->transformations & PNG_INTERLACE))
- {
- png_ptr->num_rows = (png_ptr->height +
- png_pass_yinc[png_ptr->pass] - 1 -
- png_pass_ystart[png_ptr->pass]) /
- png_pass_yinc[png_ptr->pass];
- if (!(png_ptr->num_rows))
- continue;
- }
- else /* if (png_ptr->transformations & PNG_INTERLACE) */
- break;
- } while (png_ptr->iwidth == 0);
-
- if (png_ptr->pass < 7)
- return;
- }
-
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
- {
- char extra;
- int ret;
-
- png_ptr->zstream.next_out = (Byte *)&extra;
- png_ptr->zstream.avail_out = (uInt)1;
- for(;;)
- {
- if (!(png_ptr->zstream.avail_in))
- {
- while (!png_ptr->idat_size)
- {
- png_byte chunk_length[4];
-
- png_crc_finish(png_ptr, 0);
-
- png_read_data(png_ptr, chunk_length, 4);
- png_ptr->idat_size = png_get_uint_32(chunk_length);
-
- png_reset_crc(png_ptr);
- png_crc_read(png_ptr, png_ptr->chunk_name, 4);
- if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- png_error(png_ptr, "Not enough image data");
-
- }
- png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
- png_ptr->zstream.next_in = png_ptr->zbuf;
- if (png_ptr->zbuf_size > png_ptr->idat_size)
- png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
- png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
- png_ptr->idat_size -= png_ptr->zstream.avail_in;
- }
- ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
- if (ret == Z_STREAM_END)
- {
- if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
- png_ptr->idat_size)
- png_error(png_ptr, "Extra compressed data");
- png_ptr->mode |= PNG_AFTER_IDAT;
- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
- break;
- }
- if (ret != Z_OK)
- png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
- "Decompression Error");
-
- if (!(png_ptr->zstream.avail_out))
- png_error(png_ptr, "Extra compressed data");
-
- }
- png_ptr->zstream.avail_out = 0;
- }
-
- if (png_ptr->idat_size || png_ptr->zstream.avail_in)
- png_error(png_ptr, "Extra compression data");
-
- inflateReset(&png_ptr->zstream);
-
- png_ptr->mode |= PNG_AFTER_IDAT;
-}
-
-void
-png_read_start_row(png_structp png_ptr)
-{
- int max_pixel_depth;
- png_uint_32 row_bytes;
-
- png_debug(1, "in png_read_start_row\n");
- png_ptr->zstream.avail_in = 0;
- png_init_read_transformations(png_ptr);
- if (png_ptr->interlaced)
- {
- if (!(png_ptr->transformations & PNG_INTERLACE))
- png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
- png_pass_ystart[0]) / png_pass_yinc[0];
- else
- png_ptr->num_rows = png_ptr->height;
-
- png_ptr->iwidth = (png_ptr->width +
- png_pass_inc[png_ptr->pass] - 1 -
- png_pass_start[png_ptr->pass]) /
- png_pass_inc[png_ptr->pass];
-
- row_bytes = ((png_ptr->iwidth *
- (png_uint_32)png_ptr->pixel_depth + 7) >> 3) +1;
- png_ptr->irowbytes = (png_size_t)row_bytes;
- if((png_uint_32)png_ptr->irowbytes != row_bytes)
- png_error(png_ptr, "Rowbytes overflow in png_read_start_row");
- }
- else
- {
- png_ptr->num_rows = png_ptr->height;
- png_ptr->iwidth = png_ptr->width;
- png_ptr->irowbytes = png_ptr->rowbytes + 1;
- }
- 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)
- if (png_ptr->transformations & PNG_EXPAND)
- {
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (png_ptr->num_trans)
- max_pixel_depth = 32;
- else
- max_pixel_depth = 24;
- }
- else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
- {
- if (max_pixel_depth < 8)
- max_pixel_depth = 8;
- if (png_ptr->num_trans)
- max_pixel_depth *= 2;
- }
- else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
- {
- if (png_ptr->num_trans)
- {
- max_pixel_depth *= 4;
- max_pixel_depth /= 3;
- }
- }
- }
-#endif
-
-#if defined(PNG_READ_FILLER_SUPPORTED)
- if (png_ptr->transformations & (PNG_FILLER))
- {
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- max_pixel_depth = 32;
- else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
- {
- if (max_pixel_depth <= 8)
- max_pixel_depth = 16;
- else
- max_pixel_depth = 32;
- }
- else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
- {
- if (max_pixel_depth <= 32)
- max_pixel_depth = 32;
- else
- max_pixel_depth = 64;
- }
- }
-#endif
-
-#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
- if (png_ptr->transformations & PNG_GRAY_TO_RGB)
- {
- if (
-#if defined(PNG_READ_EXPAND_SUPPORTED)
- (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
-#endif
-#if defined(PNG_READ_FILLER_SUPPORTED)
- (png_ptr->transformations & (PNG_FILLER)) ||
-#endif
- png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- {
- if (max_pixel_depth <= 16)
- max_pixel_depth = 32;
- else
- max_pixel_depth = 64;
- }
- else
- {
- if (max_pixel_depth <= 8)
- max_pixel_depth = 24;
- else
- max_pixel_depth = 48;
- }
- }
-#endif
-
- /* align the width on the next larger 8 pixels. Mainly used
- for interlacing */
- row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
- /* calculate the maximum bytes needed, adding a byte and a pixel
- for safety's sake */
- row_bytes = ((row_bytes * (png_uint_32)max_pixel_depth + 7) >> 3) +
- 1 + ((max_pixel_depth + 7) >> 3);
-#ifdef PNG_MAX_MALLOC_64K
- if (row_bytes > (png_uint_32)65536L)
- png_error(png_ptr, "This image requires a row greater than 64KB");
-#endif
- png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, row_bytes);
-
-#ifdef PNG_MAX_MALLOC_64K
- if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
- png_error(png_ptr, "This image requires a row greater than 64KB");
-#endif
- png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
- png_ptr->rowbytes + 1));
-
- png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
-
- png_debug1(3, "width = %d,\n", png_ptr->width);
- png_debug1(3, "height = %d,\n", png_ptr->height);
- png_debug1(3, "iwidth = %d,\n", png_ptr->iwidth);
- png_debug1(3, "num_rows = %d\n", png_ptr->num_rows);
- png_debug1(3, "rowbytes = %d,\n", png_ptr->rowbytes);
- png_debug1(3, "irowbytes = %d,\n", png_ptr->irowbytes);
-
- png_ptr->flags |= PNG_FLAG_ROW_INIT;
-}
+++ /dev/null
-
-/* pngset.c - storage of image information into info struct
- *
- * libpng 1.0.3 - January 14, 1999
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
- *
- * The functions here are used during reads to store data from the file
- * into the info struct, and during writes to store application data
- * into the info struct for writing into the file. This abstracts the
- * info struct and allows us to change the structure in the future.
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-
-#if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED)
-void
-png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background)
-{
- png_debug1(1, "in %s storage function\n", "bKGD");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- png_memcpy(&(info_ptr->background), background, sizeof(png_color_16));
- info_ptr->valid |= PNG_INFO_bKGD;
-}
-#endif
-
-#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
-void
-png_set_cHRM(png_structp png_ptr, png_infop info_ptr,
- double white_x, double white_y, double red_x, double red_y,
- double green_x, double green_y, double blue_x, double blue_y)
-{
- png_debug1(1, "in %s storage function\n", "cHRM");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- info_ptr->x_white = (float)white_x;
- info_ptr->y_white = (float)white_y;
- info_ptr->x_red = (float)red_x;
- info_ptr->y_red = (float)red_y;
- info_ptr->x_green = (float)green_x;
- info_ptr->y_green = (float)green_y;
- info_ptr->x_blue = (float)blue_x;
- info_ptr->y_blue = (float)blue_y;
- info_ptr->valid |= PNG_INFO_cHRM;
-}
-#endif
-
-#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED)
-void
-png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
-{
- png_debug1(1, "in %s storage function\n", "gAMA");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- info_ptr->gamma = (float)file_gamma;
- info_ptr->valid |= PNG_INFO_gAMA;
-}
-#endif
-
-#if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED)
-void
-png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist)
-{
- png_debug1(1, "in %s storage function\n", "hIST");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- info_ptr->hist = hist;
- info_ptr->valid |= PNG_INFO_hIST;
-}
-#endif
-
-void
-png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
- png_uint_32 width, png_uint_32 height, int bit_depth,
- int color_type, int interlace_type, int compression_type,
- int filter_type)
-{
- int rowbytes_per_pixel;
- png_debug1(1, "in %s storage function\n", "IHDR");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- info_ptr->width = width;
- info_ptr->height = height;
- info_ptr->bit_depth = (png_byte)bit_depth;
- info_ptr->color_type =(png_byte) color_type;
- info_ptr->compression_type = (png_byte)compression_type;
- info_ptr->filter_type = (png_byte)filter_type;
- info_ptr->interlace_type = (png_byte)interlace_type;
- 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 = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
-
- /* check for overflow */
- rowbytes_per_pixel = (info_ptr->pixel_depth + 7) >> 3;
- if (( width > (png_uint_32)2147483647L/rowbytes_per_pixel))
- {
- png_warning(png_ptr,
- "Width too large to process image data; rowbytes will overflow.");
- info_ptr->rowbytes = (png_size_t)0;
- }
- else
- info_ptr->rowbytes = (info_ptr->width * info_ptr->pixel_depth + 7) >> 3;
-}
-
-#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
-void
-png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
- png_uint_32 offset_x, png_uint_32 offset_y, int unit_type)
-{
- png_debug1(1, "in %s storage function\n", "oFFs");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- info_ptr->x_offset = offset_x;
- info_ptr->y_offset = offset_y;
- info_ptr->offset_unit_type = (png_byte)unit_type;
- info_ptr->valid |= PNG_INFO_oFFs;
-}
-#endif
-
-#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED)
-void
-png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
- png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams,
- png_charp units, png_charpp params)
-{
- png_uint_32 length;
- int i;
-
- png_debug1(1, "in %s storage function\n", "pCAL");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- length = png_strlen(purpose) + 1;
- png_debug1(3, "allocating purpose for info (%d bytes)\n", length);
- info_ptr->pcal_purpose = (png_charp)png_malloc(png_ptr, length);
- png_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length);
-
- png_debug(3, "storing X0, X1, type, and nparams in info\n");
- info_ptr->pcal_X0 = X0;
- info_ptr->pcal_X1 = X1;
- info_ptr->pcal_type = (png_byte)type;
- info_ptr->pcal_nparams = (png_byte)nparams;
-
- length = png_strlen(units) + 1;
- png_debug1(3, "allocating units for info (%d bytes)\n", length);
- info_ptr->pcal_units = (png_charp)png_malloc(png_ptr, length);
- png_memcpy(info_ptr->pcal_units, units, (png_size_t)length);
-
- info_ptr->pcal_params = (png_charpp)png_malloc(png_ptr,
- (png_uint_32)((nparams + 1) * sizeof(png_charp)));
- info_ptr->pcal_params[nparams] = NULL;
-
- for (i = 0; i < nparams; i++)
- {
- length = png_strlen(params[i]) + 1;
- png_debug2(3, "allocating parameter %d for info (%d bytes)\n", i, length);
- info_ptr->pcal_params[i] = (png_charp)png_malloc(png_ptr, length);
- png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length);
- }
-
- info_ptr->valid |= PNG_INFO_pCAL;
-}
-#endif
-
-#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
-void
-png_set_pHYs(png_structp png_ptr, png_infop info_ptr,
- png_uint_32 res_x, png_uint_32 res_y, int unit_type)
-{
- png_debug1(1, "in %s storage function\n", "pHYs");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- info_ptr->x_pixels_per_unit = res_x;
- info_ptr->y_pixels_per_unit = res_y;
- info_ptr->phys_unit_type = (png_byte)unit_type;
- info_ptr->valid |= PNG_INFO_pHYs;
-}
-#endif
-
-void
-png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
- png_colorp palette, int num_palette)
-{
- png_debug1(1, "in %s storage function\n", "PLTE");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- info_ptr->palette = palette;
- info_ptr->num_palette = (png_uint_16)num_palette;
- info_ptr->valid |= PNG_INFO_PLTE;
-}
-
-#if defined(PNG_READ_sBIT_SUPPORTED) || defined(PNG_WRITE_sBIT_SUPPORTED)
-void
-png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
- png_color_8p sig_bit)
-{
- png_debug1(1, "in %s storage function\n", "sBIT");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- png_memcpy(&(info_ptr->sig_bit), sig_bit, sizeof (png_color_8));
- info_ptr->valid |= PNG_INFO_sBIT;
-}
-#endif
-
-#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
-void
-png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent)
-{
- png_debug1(1, "in %s storage function\n", "sRGB");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- info_ptr->srgb_intent = (png_byte)intent;
- info_ptr->valid |= PNG_INFO_sRGB;
-}
-void
-png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
- int intent)
-{
-#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED)
- float file_gamma;
-#endif
-#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
- float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
-#endif
- png_debug1(1, "in %s storage function\n", "sRGB_gAMA_and_cHRM");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- png_set_sRGB(png_ptr, info_ptr, intent);
-
-#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED)
- file_gamma = (float).45;
- png_set_gAMA(png_ptr, info_ptr, file_gamma);
-#endif
-
-#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
- white_x = (float).3127;
- white_y = (float).3290;
- red_x = (float).64;
- red_y = (float).33;
- green_x = (float).30;
- green_y = (float).60;
- blue_x = (float).15;
- blue_y = (float).06;
-
- png_set_cHRM(png_ptr, info_ptr,
- white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
-
-#endif
-}
-#endif
-
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
- defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
-void
-png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
- int num_text)
-{
- int i;
-
- png_debug1(1, "in %s storage function\n", (png_ptr->chunk_name[0] == '\0' ?
- "text" : (png_const_charp)png_ptr->chunk_name));
-
- if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
- return;
-
- /* Make sure we have enough space in the "text" array in info_struct
- * to hold all of the incoming text_ptr objects.
- */
- if (info_ptr->num_text + num_text > info_ptr->max_text)
- {
- if (info_ptr->text != NULL)
- {
- png_textp old_text;
- int old_max;
-
- old_max = info_ptr->max_text;
- info_ptr->max_text = info_ptr->num_text + num_text + 8;
- old_text = info_ptr->text;
- info_ptr->text = (png_textp)png_malloc(png_ptr,
- (png_uint_32)(info_ptr->max_text * sizeof (png_text)));
- png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
- sizeof(png_text)));
- png_free(png_ptr, old_text);
- }
- else
- {
- info_ptr->max_text = num_text + 8;
- info_ptr->num_text = 0;
- info_ptr->text = (png_textp)png_malloc(png_ptr,
- (png_uint_32)(info_ptr->max_text * sizeof (png_text)));
- }
- png_debug1(3, "allocated %d entries for info_ptr->text\n",
- info_ptr->max_text);
- }
-
- for (i = 0; i < num_text; i++)
- {
- png_textp textp = &(info_ptr->text[info_ptr->num_text]);
-
- if (text_ptr[i].text == NULL)
- text_ptr[i].text = (png_charp)"";
-
- if (text_ptr[i].text[0] == '\0')
- {
- textp->text_length = 0;
- textp->compression = PNG_TEXT_COMPRESSION_NONE;
- }
- else
- {
- textp->text_length = png_strlen(text_ptr[i].text);
- textp->compression = text_ptr[i].compression;
- }
- textp->text = text_ptr[i].text;
- textp->key = text_ptr[i].key;
- info_ptr->num_text++;
- png_debug1(3, "transferred text chunk %d\n", info_ptr->num_text);
- }
-}
-#endif
-
-#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED)
-void
-png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time)
-{
- png_debug1(1, "in %s storage function\n", "tIME");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- png_memcpy(&(info_ptr->mod_time), mod_time, sizeof (png_time));
- info_ptr->valid |= PNG_INFO_tIME;
-}
-#endif
-
-#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED)
-void
-png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
- png_bytep trans, int num_trans, png_color_16p trans_values)
-{
- png_debug1(1, "in %s storage function\n", "tRNS");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- if (trans != NULL)
- {
- info_ptr->trans = trans;
- }
-
- if (trans_values != NULL)
- {
- png_memcpy(&(info_ptr->trans_values), trans_values,
- sizeof(png_color_16));
- if (num_trans == 0)
- num_trans = 1;
- }
- info_ptr->num_trans = (png_uint_16)num_trans;
- info_ptr->valid |= PNG_INFO_tRNS;
-}
-#endif
-
+++ /dev/null
-
-/* pngtest.c - a simple test program to test libpng
- *
- * libpng 1.0.3 -January 14, 1999
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
- *
- * This program reads in a PNG image, writes it out again, and then
- * compares the two files. If the files are identical, this shows that
- * the basic chunk handling, filtering, and (de)compression code is working
- * properly. It does not currently test all of the transforms, although
- * it probably should.
- *
- * The program will report "FAIL" in certain legitimate cases:
- * 1) when the compression level or filter selection method is changed.
- * 2) when the chunk size is not 8K.
- * 3) unknown ancillary chunks exist in the input file.
- * 4) others not listed here...
- * In these cases, it is best to check with another tool such as "pngcheck"
- * to see what the differences between the two images are.
- *
- * If a filename is given on the command-line, then this file is used
- * for the input, rather than the default "pngtest.png". This allows
- * testing a wide variety of files easily. You can also test a number
- * of files at once by typing "pngtest -m file1.png file2.png ..."
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-/* Makes pngtest verbose so we can find problems (needs to be before png.h) */
-#ifndef PNG_DEBUG
-#define PNG_DEBUG 0
-#endif
-
-#include "png.h"
-
-#if defined(PNG_TIME_RFC1123_SUPPORTED)
-static int tIME_chunk_present=0;
-static char tIME_string[30] = "no tIME chunk present in file";
-#endif /* PNG_TIME_RFC1123_SUPPORTED */
-
-int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname));
-
-#ifdef __TURBOC__
-#include <mem.h>
-#endif
-
-/* defined so I can write to a file on gui/windowing platforms */
-/* #define STDERR stderr */
-#define STDERR stdout /* for DOS */
-
-/* example of using row callbacks to make a simple progress meter */
-static int status_pass=1;
-static int status_dots_requested=0;
-static int status_dots=1;
-
-void
-read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
-{
- if(png_ptr == NULL || row_number > 0x3fffffffL) return;
- if(status_pass != pass)
- {
- fprintf(stdout,"\n Pass %d: ",pass);
- status_pass = pass;
- status_dots = 30;
- }
- status_dots--;
- if(status_dots == 0)
- {
- fprintf(stdout, "\n ");
- status_dots=30;
- }
- fprintf(stdout, "r");
-}
-
-void
-write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
-{
- if(png_ptr == NULL || row_number > 0x3fffffffL || pass > 7) return;
- fprintf(stdout, "w");
-}
-
-
-#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
-/* example of using user transform callback (we don't transform anything,
- but merely count the zero samples) */
-
-static png_uint_32 zero_samples;
-
-void
-count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
-{
- png_bytep dp = data;
- if(png_ptr == NULL)return;
-
- /* contents of row_info:
- * png_uint_32 width width of row
- * png_uint_32 rowbytes number of bytes in row
- * png_byte color_type color type of pixels
- * png_byte bit_depth bit depth of samples
- * png_byte channels number of channels (1-4)
- * png_byte pixel_depth bits per pixel (depth*channels)
- */
-
- /* counts the number of zero samples (or zero pixels if color_type is 3 */
-
- if(row_info->color_type == 0 || row_info->color_type == 3)
- {
- int pos=0;
- png_uint_32 n, nstop;
- for (n=0, nstop=row_info->width; n<nstop; n++)
- {
- if(row_info->bit_depth == 1)
- {
- if(((*dp << pos++ )& 0x80) == 0) zero_samples++;
- if(pos == 8)
- {
- pos = 0;
- dp++;
- }
- }
- if(row_info->bit_depth == 2)
- {
- if(((*dp << (pos+=2))& 0xc0) == 0) zero_samples++;
- if(pos == 8)
- {
- pos = 0;
- dp++;
- }
- }
- if(row_info->bit_depth == 4)
- {
- if(((*dp << (pos+=4))& 0xf0) == 0) zero_samples++;
- if(pos == 8)
- {
- pos = 0;
- dp++;
- }
- }
- if(row_info->bit_depth == 8)
- if(*dp++ == 0) zero_samples++;
- if(row_info->bit_depth == 16)
- {
- if((*dp | *(dp+1)) == 0) zero_samples++;
- dp+=2;
- }
- }
- }
- else /* other color types */
- {
- png_uint_32 n, nstop;
- int channel;
- int color_channels = row_info->channels;
- if(row_info->color_type > 3)color_channels--;
-
- for (n=0, nstop=row_info->width; n<nstop; n++)
- {
- for (channel = 0; channel < color_channels; channel++)
- {
- if(row_info->bit_depth == 8)
- if(*dp++ == 0) zero_samples++;
- if(row_info->bit_depth == 16)
- {
- if((*dp | *(dp+1)) == 0) zero_samples++;
- dp+=2;
- }
- }
- if(row_info->color_type > 3)
- {
- dp++;
- if(row_info->bit_depth == 16)dp++;
- }
- }
- }
-}
-#endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */
-
-static int verbose = 0;
-static int wrote_question = 0;
-
-#if defined(PNG_NO_STDIO)
-/* START of code to validate stdio-free compilation */
-/* These copies of the default read/write functions come from pngrio.c and */
-/* pngwio.c. They allow "don't include stdio" testing of the library. */
-/* This is the function that does the actual reading of data. If you are
- not reading from a standard C stream, you should create a replacement
- read_data function and use it at run time with png_set_read_fn(), rather
- than changing the library. */
-#ifndef USE_FAR_KEYWORD
-static void
-png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
- png_size_t check;
-
- /* fread() returns 0 on error, so it is OK to store this in a png_size_t
- * instead of an int, which is what fread() actually returns.
- */
- check = (png_size_t)fread(data, (png_size_t)1, length,
- (FILE *)png_ptr->io_ptr);
-
- if (check != length)
- {
- png_error(png_ptr, "Read 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)
-
-static void
-png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
- int check;
- png_byte *n_data;
- FILE *io_ptr;
-
- /* Check if data really is near. If so, use usual code. */
- n_data = (png_byte *)CVT_PTR_NOCHECK(data);
- io_ptr = (FILE *)CVT_PTR(png_ptr->io_ptr);
- if ((png_bytep)n_data == data)
- {
- check = fread(n_data, 1, length, io_ptr);
- }
- else
- {
- png_byte buf[NEAR_BUF_SIZE];
- png_size_t read, remaining, err;
- check = 0;
- remaining = length;
- do
- {
- read = MIN(NEAR_BUF_SIZE, remaining);
- err = fread(buf, (png_size_t)1, read, io_ptr);
- 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 /* USE_FAR_KEYWORD */
-
-#if defined(PNG_WRITE_FLUSH_SUPPORTED)
-static void
-png_default_flush(png_structp png_ptr)
-{
- FILE *io_ptr;
- io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr));
- if (io_ptr != NULL)
- fflush(io_ptr);
-}
-#endif
-
-/* This is the function that does the actual writing of data. If you are
- not writing to a standard C stream, you should create a replacement
- write_data function and use it at run time with png_set_write_fn(), rather
- than changing the library. */
-#ifndef USE_FAR_KEYWORD
-static void
-png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
- png_uint_32 check;
-
- check = fwrite(data, 1, length, (FILE *)(png_ptr->io_ptr));
- 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)
-
-static void
-png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
- png_uint_32 check;
- png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
- FILE *io_ptr;
-
- /* Check if data really is near. If so, use usual code. */
- near_data = (png_byte *)CVT_PTR_NOCHECK(data);
- io_ptr = (FILE *)CVT_PTR(png_ptr->io_ptr);
- if ((png_bytep)near_data == data)
- {
- check = fwrite(near_data, 1, length, io_ptr);
- }
- else
- {
- png_byte buf[NEAR_BUF_SIZE];
- png_size_t written, remaining, err;
- check = 0;
- remaining = length;
- do
- {
- written = MIN(NEAR_BUF_SIZE, remaining);
- png_memcpy(buf, data, written); /* copy far buffer to near buffer */
- err = fwrite(buf, 1, written, io_ptr);
- if (err != written)
- break;
- else
- check += err;
- data += written;
- remaining -= written;
- }
- while (remaining != 0);
- }
- if (check != length)
- {
- png_error(png_ptr, "Write Error");
- }
-}
-
-#endif /* USE_FAR_KEYWORD */
-
-/* This function is called when there is a warning, but the library thinks
- * it can continue anyway. Replacement functions don't have to do anything
- * here if you don't want to. In the default configuration, png_ptr is
- * not used, but it is passed in case it may be useful.
- */
-static void
-png_default_warning(png_structp png_ptr, png_const_charp message)
-{
- PNG_CONST char *name = "UNKNOWN (ERROR!)";
- if (png_ptr != NULL && png_ptr->error_ptr != NULL)
- name = png_ptr->error_ptr;
- fprintf(STDERR, "%s: libpng warning: %s\n", name, message);
-}
-
-/* This is the default error handling function. Note that replacements for
- * this function MUST NOT RETURN, or the program will likely crash. This
- * function is used by default, or if the program supplies NULL for the
- * error function pointer in png_set_error_fn().
- */
-static void
-png_default_error(png_structp png_ptr, png_const_charp message)
-{
- png_default_warning(png_ptr, message);
- /* We can return because png_error calls the default handler, which is
- * actually OK in this case. */
-}
-#endif /* PNG_NO_STDIO */
-/* END of code to validate stdio-free compilation */
-
-/* START of code to validate memory allocation and deallocation */
-#ifdef PNG_USER_MEM_SUPPORTED
-
-/* 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
- need to allocate exactly 64K, so whatever you call here must
- have the ability to do that.
-
- This piece of code can be compiled to validate max 64K allocations
- by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K. */
-typedef struct memory_information {
- png_uint_32 size;
- png_voidp pointer;
- struct memory_information FAR *next;
-} memory_information;
-typedef memory_information FAR *memory_infop;
-
-static memory_infop pinformation = NULL;
-static int current_allocation = 0;
-static int maximum_allocation = 0;
-
-extern PNG_EXPORT(png_voidp,png_debug_malloc) PNGARG((png_structp png_ptr,
- png_uint_32 size));
-extern PNG_EXPORT(void,png_debug_free) PNGARG((png_structp png_ptr,
- png_voidp ptr));
-
-png_voidp
-png_debug_malloc(png_structp png_ptr, png_uint_32 size) {
-
- /* png_malloc has already tested for NULL; png_create_struct calls
- png_debug_malloc directly, with png_ptr == NULL which is OK */
-
- if (size == 0)
- return (png_voidp)(NULL);
-
- /* This calls the library allocator twice, once to get the requested
- buffer and once to get a new free list entry. */
- {
- memory_infop pinfo = png_malloc_default(png_ptr, sizeof *pinfo);
- pinfo->size = size;
- current_allocation += size;
- if (current_allocation > maximum_allocation)
- maximum_allocation = current_allocation;
- pinfo->pointer = png_malloc_default(png_ptr, size);
- pinfo->next = pinformation;
- pinformation = pinfo;
- /* Make sure the caller isn't assuming zeroed memory. */
- png_memset(pinfo->pointer, 0xdd, pinfo->size);
- return (png_voidp)(pinfo->pointer);
- }
-}
-
-/* Free a pointer. It is removed from the list at the same time. */
-void
-png_debug_free(png_structp png_ptr, png_voidp ptr)
-{
- if (png_ptr == NULL)
- fprintf(STDERR, "NULL pointer to png_debug_free.\n");
- if (ptr == 0) {
-#if 0 /* This happens all the time. */
- fprintf(STDERR, "WARNING: freeing NULL pointer\n");
-#endif
- return;
- }
-
- /* Unlink the element from the list. */
- {
- memory_infop FAR *ppinfo = &pinformation;
- for (;;) {
- memory_infop pinfo = *ppinfo;
- if (pinfo->pointer == ptr) {
- *ppinfo = pinfo->next;
- current_allocation -= pinfo->size;
- if (current_allocation < 0)
- fprintf(STDERR, "Duplicate free of memory\n");
- /* We must free the list element too, but first kill
- the memory that is to be freed. */
- memset(ptr, 0x55, pinfo->size);
- png_free_default(png_ptr, pinfo);
- break;
- }
- if (pinfo->next == NULL) {
- fprintf(STDERR, "Pointer %x not found\n", ptr);
- break;
- }
- ppinfo = &pinfo->next;
- }
- }
-
- /* Finally free the data. */
- png_free_default(png_ptr, ptr);
-}
-#endif /* PNG_USER_MEM_SUPPORTED */
-/* END of code to test memory allocation/deallocation */
-
-/* Test one file */
-int
-test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
-{
- static FILE *fpin, *fpout; /* "static" prevents setjmp corruption */
- png_structp read_ptr, write_ptr;
- png_infop read_info_ptr, write_info_ptr, end_info_ptr;
- png_bytep row_buf;
- png_uint_32 y;
- png_uint_32 width, height;
- int num_pass, pass;
- int bit_depth, color_type;
-#ifdef USE_FAR_KEYWORD
- jmp_buf jmpbuf;
-#endif
-
- char inbuf[256], outbuf[256];
-
- row_buf = (png_bytep)NULL;
-
- if ((fpin = fopen(inname, "rb")) == NULL)
- {
- fprintf(STDERR, "Could not find input file %s\n", inname);
- return (1);
- }
-
- if ((fpout = fopen(outname, "wb")) == NULL)
- {
- fprintf(STDERR, "Could not open output file %s\n", outname);
- fclose(fpin);
- return (1);
- }
-
- png_debug(0, "Allocating read and write structures\n");
-#ifdef PNG_USER_MEM_SUPPORTED
- read_ptr = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
- (png_error_ptr)NULL, (png_error_ptr)NULL, (png_voidp)NULL,
- (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
-#else
- read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
- (png_error_ptr)NULL, (png_error_ptr)NULL);
-#endif
-#if defined(PNG_NO_STDIO)
- png_set_error_fn(read_ptr, (png_voidp)inname, png_default_error,
- png_default_warning);
-#endif
-#ifdef PNG_USER_MEM_SUPPORTED
- write_ptr = png_create_write_struct_2(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
- (png_error_ptr)NULL, (png_error_ptr)NULL, (png_voidp)NULL,
- (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
-#else
- write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
- (png_error_ptr)NULL, (png_error_ptr)NULL);
-#endif
-#if defined(PNG_NO_STDIO)
- png_set_error_fn(write_ptr, (png_voidp)inname, png_default_error,
- png_default_warning);
-#endif
- png_debug(0, "Allocating read_info, write_info and end_info structures\n");
- read_info_ptr = png_create_info_struct(read_ptr);
- write_info_ptr = png_create_info_struct(write_ptr);
- end_info_ptr = png_create_info_struct(read_ptr);
-#ifdef PNG_USER_MEM_SUPPORTED
-#endif
-
- png_debug(0, "Setting jmpbuf for read struct\n");
-#ifdef USE_FAR_KEYWORD
- if (setjmp(jmpbuf))
-#else
- if (setjmp(read_ptr->jmpbuf))
-#endif
- {
- fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
- png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
- png_destroy_write_struct(&write_ptr, &write_info_ptr);
- fclose(fpin);
- fclose(fpout);
- return (1);
- }
-#ifdef USE_FAR_KEYWORD
- png_memcpy(read_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
-#endif
-
- png_debug(0, "Setting jmpbuf for write struct\n");
-#ifdef USE_FAR_KEYWORD
- if (setjmp(jmpbuf))
-#else
- if (setjmp(write_ptr->jmpbuf))
-#endif
- {
- fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
- png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
- png_destroy_write_struct(&write_ptr, &write_info_ptr);
- fclose(fpin);
- fclose(fpout);
- return (1);
- }
-#ifdef USE_FAR_KEYWORD
- png_memcpy(write_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
-#endif
-
- png_debug(0, "Initializing input and output streams\n");
-#if !defined(PNG_NO_STDIO)
- png_init_io(read_ptr, fpin);
- png_init_io(write_ptr, fpout);
-#else
- png_set_read_fn(read_ptr, (png_voidp)fpin, png_default_read_data);
- png_set_write_fn(write_ptr, (png_voidp)fpout, png_default_write_data,
-#if defined(PNG_WRITE_FLUSH_SUPPORTED)
- png_default_flush);
-#else
- NULL);
-#endif
-#endif
- if(status_dots_requested == 1)
- {
- png_set_write_status_fn(write_ptr, write_row_callback);
- png_set_read_status_fn(read_ptr, read_row_callback);
- }
- else
- {
- png_set_write_status_fn(write_ptr, NULL);
- png_set_read_status_fn(read_ptr, NULL);
- }
-
-# if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
- zero_samples=0;
- png_set_write_user_transform_fn(write_ptr, count_zero_samples);
-# endif
-
- png_debug(0, "Reading info struct\n");
- png_read_info(read_ptr, read_info_ptr);
-
- png_debug(0, "Transferring info struct\n");
- {
- int interlace_type, compression_type, filter_type;
-
- if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,
- &color_type, &interlace_type, &compression_type, &filter_type))
- {
- png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
-#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
- color_type, interlace_type, compression_type, filter_type);
-#else
- color_type, PNG_INTERLACE_NONE, compression_type, filter_type);
-#endif
- }
- }
-#if defined(PNG_READ_bKGD_SUPPORTED) && defined(PNG_WRITE_bKGD_SUPPORTED)
- {
- png_color_16p background;
-
- if (png_get_bKGD(read_ptr, read_info_ptr, &background))
- {
- png_set_bKGD(write_ptr, write_info_ptr, background);
- }
- }
-#endif
-#if defined(PNG_READ_cHRM_SUPPORTED) && defined(PNG_WRITE_cHRM_SUPPORTED)
- {
- double white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
-
- if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
- &red_y, &green_x, &green_y, &blue_x, &blue_y))
- {
- png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x,
- red_y, green_x, green_y, blue_x, blue_y);
- }
- }
-#endif
-#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_WRITE_gAMA_SUPPORTED)
- {
- double gamma;
-
- if (png_get_gAMA(read_ptr, read_info_ptr, &gamma))
- {
- png_set_gAMA(write_ptr, write_info_ptr, gamma);
- }
- }
-#endif
-#if defined(PNG_READ_sRGB_SUPPORTED) && defined(PNG_WRITE_sRGB_SUPPORTED)
- {
- int intent;
-
- if (png_get_sRGB(read_ptr, read_info_ptr, &intent))
- {
- png_set_sRGB(write_ptr, write_info_ptr, intent);
- }
- }
-#endif
-#if defined(PNG_READ_hIST_SUPPORTED) && defined(PNG_WRITE_hIST_SUPPORTED)
- {
- png_uint_16p hist;
-
- if (png_get_hIST(read_ptr, read_info_ptr, &hist))
- {
- png_set_hIST(write_ptr, write_info_ptr, hist);
- }
- }
-#endif
-#if defined(PNG_READ_oFFs_SUPPORTED) && defined(PNG_WRITE_oFFs_SUPPORTED)
- {
- png_uint_32 offset_x, offset_y;
- int unit_type;
-
- if (png_get_oFFs(read_ptr, read_info_ptr,&offset_x,&offset_y,&unit_type))
- {
- png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type);
- }
- }
-#endif
-#if defined(PNG_READ_pCAL_SUPPORTED) && defined(PNG_WRITE_pCAL_SUPPORTED)
- {
- png_charp purpose, units;
- png_charpp params;
- png_int_32 X0, X1;
- int type, nparams;
-
- if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,
- &nparams, &units, ¶ms))
- {
- png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,
- nparams, units, params);
- }
- }
-#endif
-#if defined(PNG_READ_pHYs_SUPPORTED) && defined(PNG_WRITE_pHYs_SUPPORTED)
- {
- png_uint_32 res_x, res_y;
- int unit_type;
-
- if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type))
- {
- png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type);
- }
- }
-#endif
- {
- png_colorp palette;
- int num_palette;
-
- if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette))
- {
- png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
- }
- }
-#if defined(PNG_READ_sBIT_SUPPORTED) && defined(PNG_WRITE_sBIT_SUPPORTED)
- {
- png_color_8p sig_bit;
-
- if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit))
- {
- png_set_sBIT(write_ptr, write_info_ptr, sig_bit);
- }
- }
-#endif
-#if (defined(PNG_READ_tEXt_SUPPORTED) && defined(PNG_WRITE_tEXt_SUPPORTED)) || \
- (defined(PNG_READ_zTXt_SUPPORTED) && defined(PNG_WRITE_zTXt_SUPPORTED))
- {
- png_textp text_ptr;
- int num_text;
-
- if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0)
- {
- png_debug1(0, "Handling %d tEXt/zTXt chunks\n", num_text);
- png_set_text(write_ptr, write_info_ptr, text_ptr, num_text);
- }
- }
-#endif
-#if defined(PNG_READ_tIME_SUPPORTED) && defined(PNG_WRITE_tIME_SUPPORTED)
- {
- png_timep mod_time;
-
- if (png_get_tIME(read_ptr, read_info_ptr, &mod_time))
- {
- png_set_tIME(write_ptr, write_info_ptr, mod_time);
-#if defined(PNG_TIME_RFC1123_SUPPORTED)
- /* we have to use png_strcpy instead of "=" because the string
- pointed to by png_convert_to_rfc1123() gets free'ed before
- we use it */
- png_strcpy(tIME_string,png_convert_to_rfc1123(read_ptr, mod_time));
- tIME_chunk_present++;
-#endif /* PNG_TIME_RFC1123_SUPPORTED */
- }
- }
-#endif
-#if defined(PNG_READ_tRNS_SUPPORTED) && defined(PNG_WRITE_tRNS_SUPPORTED)
- {
- png_bytep trans;
- int num_trans;
- png_color_16p trans_values;
-
- if (png_get_tRNS(read_ptr, read_info_ptr, &trans, &num_trans,
- &trans_values))
- {
- png_set_tRNS(write_ptr, write_info_ptr, trans, num_trans,
- trans_values);
- }
- }
-#endif
-
- png_debug(0, "\nWriting info struct\n");
- png_write_info(write_ptr, write_info_ptr);
-
- png_debug(0, "\nAllocating row buffer \n");
- row_buf = (png_bytep)png_malloc(read_ptr,
- png_get_rowbytes(read_ptr, read_info_ptr));
- if (row_buf == NULL)
- {
- fprintf(STDERR, "No memory to allocate row buffer\n");
- png_destroy_read_struct(&read_ptr, &read_info_ptr, (png_infopp)NULL);
- png_destroy_write_struct(&write_ptr, &write_info_ptr);
- fclose(fpin);
- fclose(fpout);
- return (1);
- }
- png_debug(0, "Writing row data\n");
-
- num_pass = png_set_interlace_handling(read_ptr);
- png_set_interlace_handling(write_ptr);
-
- for (pass = 0; pass < num_pass; pass++)
- {
- png_debug1(0, "Writing row data for pass %d\n",pass);
- for (y = 0; y < height; y++)
- {
- png_read_rows(read_ptr, (png_bytepp)&row_buf, (png_bytepp)NULL, 1);
- png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);
- }
- }
-
- png_debug(0, "Reading and writing end_info data\n");
- png_read_end(read_ptr, end_info_ptr);
- png_write_end(write_ptr, end_info_ptr);
-
-#ifdef PNG_EASY_ACCESS_SUPPORTED
- if(verbose)
- {
- png_uint_32 iwidth, iheight;
- iwidth = png_get_image_width(write_ptr, write_info_ptr);
- iheight = png_get_image_height(write_ptr, write_info_ptr);
- fprintf(STDERR, "Image width = %lu, height = %lu\n",
- iwidth, iheight);
- }
-#endif
-
- png_debug(0, "Destroying data structs\n");
- png_free(read_ptr, row_buf);
- png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
- png_destroy_write_struct(&write_ptr, &write_info_ptr);
-
- fclose(fpin);
- fclose(fpout);
-
- png_debug(0, "Opening files for comparison\n");
- if ((fpin = fopen(inname, "rb")) == NULL)
- {
- fprintf(STDERR, "Could not find file %s\n", inname);
- return (1);
- }
-
- if ((fpout = fopen(outname, "rb")) == NULL)
- {
- fprintf(STDERR, "Could not find file %s\n", outname);
- fclose(fpin);
- return (1);
- }
-
- for(;;)
- {
- png_size_t num_in, num_out;
-
- num_in = fread(inbuf, 1, 1, fpin);
- num_out = fread(outbuf, 1, 1, fpout);
-
- if (num_in != num_out)
- {
- fprintf(STDERR, "Files %s and %s are of a different size\n",
- inname, outname);
- if(wrote_question == 0)
- {
- fprintf(STDERR,
- " Was %s written with the same chunk size (8k),",inname);
- fprintf(STDERR,
- " filtering\n heuristic (libpng default), compression");
- fprintf(STDERR,
- " level (zlib default)\n and zlib version (%s)?\n\n",
- ZLIB_VERSION);
- wrote_question=1;
- }
- fclose(fpin);
- fclose(fpout);
- return (0);
- }
-
- if (!num_in)
- break;
-
- if (png_memcmp(inbuf, outbuf, num_in))
- {
- fprintf(STDERR, "Files %s and %s are different\n", inname, outname);
- if(wrote_question == 0)
- {
- fprintf(STDERR,
- " Was %s written with the same chunk size (8k),",inname);
- fprintf(STDERR,
- " filtering\n heuristic (libpng default), compression");
- fprintf(STDERR,
- " level (zlib default)\n and zlib version (%s)?\n\n",
- ZLIB_VERSION);
- wrote_question=1;
- }
- fclose(fpin);
- fclose(fpout);
- return (0);
- }
- }
-
- fclose(fpin);
- fclose(fpout);
-
- return (0);
-}
-
-/* input and output filenames */
-#ifdef RISCOS
-PNG_CONST char *inname = "pngtest/png";
-PNG_CONST char *outname = "pngout/png";
-#else
-static PNG_CONST char *inname = "pngtest.png";
-static PNG_CONST char *outname = "pngout.png";
-#endif
-
-int
-main(int argc, char *argv[])
-{
- int multiple = 0;
- int ierror = 0;
-
- fprintf(STDERR, "Testing libpng version %s\n", PNG_LIBPNG_VER_STRING);
- fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION);
- fprintf(STDERR,"%s",png_get_copyright(NULL));
-
- /* Do some consistency checking on the memory allocation settings, I'm
- not sure this matters, but it is nice to know, the first of these
- tests should be impossible because of the way the macros are set
- in pngconf.h */
-#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
- fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n");
-#endif
- /* I think the following can happen. */
-#if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K)
- fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n");
-#endif
-
- 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);
- ++ierror;
- }
-
- if (argc > 1)
- {
- if (strcmp(argv[1], "-m") == 0)
- {
- multiple = 1;
- status_dots_requested = 0;
- }
- else if (strcmp(argv[1], "-mv") == 0 ||
- strcmp(argv[1], "-vm") == 0 )
- {
- multiple = 1;
- verbose = 1;
- status_dots_requested = 1;
- }
- else if (strcmp(argv[1], "-v") == 0)
- {
- verbose = 1;
- status_dots_requested = 1;
- inname = argv[2];
- }
- else
- {
- inname = argv[1];
- status_dots_requested = 0;
- }
- }
-
- if (!multiple && argc == 3+verbose)
- outname = argv[2+verbose];
-
- if ((!multiple && argc > 3+verbose) || (multiple && argc < 2))
- {
- fprintf(STDERR,
- "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
- argv[0], argv[0]);
- fprintf(STDERR,
- " reads/writes one PNG file (without -m) or multiple files (-m)\n");
- fprintf(STDERR,
- " with -m %s is used as a temporary file\n", outname);
- exit(1);
- }
-
- if (multiple)
- {
- int i;
-#ifdef PNG_USER_MEM_SUPPORTED
- int allocation_now = current_allocation;
-#endif
- for (i=2; i<argc; ++i)
- {
- int kerror;
- fprintf(STDERR, "Testing %s:",argv[i]);
- kerror = test_one_file(argv[i], outname);
- if (kerror == 0)
- {
-#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
- fprintf(STDERR, " PASS (%lu zero samples)\n",zero_samples);
-#else
- fprintf(STDERR, " PASS\n");
-#endif
-#if defined(PNG_TIME_RFC1123_SUPPORTED)
- if(tIME_chunk_present != 0)
- fprintf(STDERR, " tIME = %s\n",tIME_string);
- tIME_chunk_present = 0;
-#endif /* PNG_TIME_RFC1123_SUPPORTED */
- }
- else
- {
- fprintf(STDERR, " FAIL\n");
- ierror += kerror;
- }
-#ifdef PNG_USER_MEM_SUPPORTED
- if (allocation_now != current_allocation)
- fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
- current_allocation-allocation_now);
- if (current_allocation != 0) {
- memory_infop pinfo = pinformation;
-
- fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
- current_allocation);
- while (pinfo != NULL) {
- fprintf(STDERR, " %d bytes at %x\n", pinfo->size, pinfo->pointer);
- pinfo = pinfo->next;
- }
- }
-#endif
- }
-#ifdef PNG_USER_MEM_SUPPORTED
- fprintf(STDERR, "Maximum memory allocation: %d bytes\n",
- maximum_allocation);
-#endif
- }
- else
- {
- int i;
- for (i=0; i<3; ++i) {
- int kerror;
-#ifdef PNG_USER_MEM_SUPPORTED
- int allocation_now = current_allocation;
-#endif
- if (i == 1) status_dots_requested = 1;
- else if(verbose == 0)status_dots_requested = 0;
- if (i == 0 || verbose == 1 || ierror != 0)
- fprintf(STDERR, "Testing %s:",inname);
- kerror = test_one_file(inname, outname);
- if(kerror == 0)
- {
- if(verbose == 1 || i == 2)
- {
-#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
- fprintf(STDERR, " PASS (%lu zero samples)\n",zero_samples);
-#else
- fprintf(STDERR, " PASS\n");
-#endif
-#if defined(PNG_TIME_RFC1123_SUPPORTED)
- if(tIME_chunk_present != 0)
- fprintf(STDERR, " tIME = %s\n",tIME_string);
-#endif /* PNG_TIME_RFC1123_SUPPORTED */
- }
- }
- else
- {
- if(verbose == 0 && i != 2)
- fprintf(STDERR, "Testing %s:",inname);
- fprintf(STDERR, " FAIL\n");
- ierror += kerror;
- }
-#ifdef PNG_USER_MEM_SUPPORTED
- if (allocation_now != current_allocation)
- fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
- current_allocation-allocation_now);
- if (current_allocation != 0) {
- memory_infop pinfo = pinformation;
-
- fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
- current_allocation);
- while (pinfo != NULL) {
- fprintf(STDERR, " %d bytes at %x\n", pinfo->size, pinfo->pointer);
- pinfo = pinfo->next;
- }
- }
-#endif
- }
-#ifdef PNG_USER_MEM_SUPPORTED
- fprintf(STDERR, "Maximum memory allocation: %d bytes\n",
- maximum_allocation);
-#endif
- }
-
- if (ierror == 0)
- fprintf(STDERR, "libpng passes test\n");
- else
- fprintf(STDERR, "libpng FAILS test\n");
- return (int)(ierror != 0);
-}
-
+++ /dev/null
-
-/* pngtrans.c - transforms the data in a row (used by both readers and writers)
- *
- * libpng 1.0.3 - January 14, 1999
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
- */
-
-#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_structp png_ptr)
-{
- png_debug(1, "in png_set_bgr\n");
- 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_structp png_ptr)
-{
- png_debug(1, "in png_set_swap\n");
- 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_structp png_ptr)
-{
- png_debug(1, "in png_set_packing\n");
- if (png_ptr->bit_depth < 8)
- {
- png_ptr->transformations |= PNG_PACK;
- png_ptr->usr_bit_depth = 8;
- }
-}
-#endif
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
-/* turn on packed pixel swapping */
-void
-png_set_packswap(png_structp png_ptr)
-{
- png_debug(1, "in png_set_packswap\n");
- if (png_ptr->bit_depth < 8)
- png_ptr->transformations |= PNG_PACKSWAP;
-}
-#endif
-
-#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
-void
-png_set_shift(png_structp png_ptr, png_color_8p true_bits)
-{
- png_debug(1, "in png_set_shift\n");
- 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_structp png_ptr)
-{
- png_debug(1, "in png_set_interlace handling\n");
- if (png_ptr->interlaced)
- {
- png_ptr->transformations |= PNG_INTERLACE;
- return (7);
- }
-
- return (1);
-}
-#endif
-
-#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
-/* Add a filler byte on read, or remove a filler or alpha byte on write.
- * The filler type has changed in v0.95 to allow future 2-byte fillers
- * for 48-bit input data, as well as to avoid problems with some compilers
- * that don't like bytes as parameters.
- */
-void
-png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
-{
- png_debug(1, "in png_set_filler\n");
- png_ptr->transformations |= PNG_FILLER;
- png_ptr->filler = (png_byte)filler;
- if (filler_loc == PNG_FILLER_AFTER)
- png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
- else
- png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
-
- /* This should probably go in the "do_filler" routine.
- * I attempted to do that in libpng-1.0.1a but that caused problems
- * so I restored it in libpng-1.0.2a
- */
-
- if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
- {
- png_ptr->usr_channels = 4;
- }
-
- /* Also I added this in libpng-1.0.2a (what happens when we expand
- * a less-than-8-bit grayscale to GA? */
-
- if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
- {
- png_ptr->usr_channels = 2;
- }
-}
-#endif
-
-#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
- defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
-void
-png_set_swap_alpha(png_structp png_ptr)
-{
- png_debug(1, "in png_set_swap_alpha\n");
- png_ptr->transformations |= PNG_SWAP_ALPHA;
-}
-#endif
-
-#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
- defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
-void
-png_set_invert_alpha(png_structp png_ptr)
-{
- png_debug(1, "in png_set_invert_alpha\n");
- png_ptr->transformations |= PNG_INVERT_ALPHA;
-}
-#endif
-
-#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
-void
-png_set_invert_mono(png_structp png_ptr)
-{
- png_debug(1, "in png_set_invert_mono\n");
- png_ptr->transformations |= PNG_INVERT_MONO;
-}
-
-/* invert monochrome grayscale data */
-void
-png_do_invert(png_row_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_invert\n");
- if (row_info->bit_depth == 1 &&
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
-#endif
- row_info->color_type == PNG_COLOR_TYPE_GRAY)
- {
- png_bytep rp = row;
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
-
- for (i = 0; i < istop; i++)
- {
- *rp = (png_byte)(~(*rp));
- rp++;
- }
- }
-}
-#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_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_swap\n");
- if (
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
-#endif
- row_info->bit_depth == 16)
- {
- png_bytep rp = row;
- png_uint_32 i;
- png_uint_32 istop= row_info->width * row_info->channels;
-
- for (i = 0; i < istop; i++, rp += 2)
- {
- png_byte t = *rp;
- *rp = *(rp + 1);
- *(rp + 1) = t;
- }
- }
-}
-#endif
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
-static png_byte onebppswaptable[256] = {
- 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
- 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
- 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
- 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
- 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
- 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
- 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
- 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
- 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
- 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
- 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
- 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
- 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
- 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
- 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
- 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
- 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
- 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
- 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
- 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
- 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
- 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
- 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
- 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
- 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
- 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
- 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
- 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
- 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
- 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
- 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
- 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
-};
-
-static png_byte twobppswaptable[256] = {
- 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
- 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
- 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
- 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
- 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
- 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
- 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
- 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
- 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
- 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
- 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
- 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
- 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
- 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
- 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
- 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
- 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
- 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
- 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
- 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
- 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
- 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
- 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
- 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
- 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
- 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
- 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
- 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
- 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
- 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
- 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
- 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
-};
-
-static png_byte fourbppswaptable[256] = {
- 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
- 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
- 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
- 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
- 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
- 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
- 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
- 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
- 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
- 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
- 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
- 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
- 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
- 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
- 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
- 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
- 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
- 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
- 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
- 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
- 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
- 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
- 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
- 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
- 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
- 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
- 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
- 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
- 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
- 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
- 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
- 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
-};
-
-/* swaps pixel packing order within bytes */
-void
-png_do_packswap(png_row_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_packswap\n");
- if (
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
-#endif
- row_info->bit_depth < 8)
- {
- png_bytep rp, end, table;
-
- end = row + row_info->rowbytes;
-
- if (row_info->bit_depth == 1)
- table = onebppswaptable;
- else if (row_info->bit_depth == 2)
- table = twobppswaptable;
- else if (row_info->bit_depth == 4)
- table = fourbppswaptable;
- else
- return;
-
- for (rp = row; rp < end; rp++)
- *rp = table[*rp];
- }
-}
-#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
-
-#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
- defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
-/* remove filler or alpha byte(s) */
-void
-png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
-{
- png_debug(1, "in png_do_strip_filler\n");
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL)
-#endif
- {
-/*
- if (row_info->color_type == PNG_COLOR_TYPE_RGB ||
- row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
-*/
- png_bytep sp=row;
- png_bytep dp=row;
- png_uint_32 row_width=row_info->width;
- png_uint_32 i;
-
- if (row_info->channels == 4)
- {
- if (row_info->bit_depth == 8)
- {
- /* This converts from RGBX or RGBA to RGB */
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- dp+=3; sp+=4;
- for (i = 1; i < row_width; i++)
- {
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- sp++;
- }
- }
- /* This converts from XRGB or ARGB to RGB */
- else
- {
- for (i = 0; i < row_width; i++)
- {
- sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- }
- }
- row_info->pixel_depth = 24;
- row_info->rowbytes = row_width * 3;
- }
- else /* if (row_info->bit_depth == 16) */
- {
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
- sp += 8; dp += 6;
- for (i = 1; i < row_width; i++)
- {
- /* This could be (although memcpy is probably slower):
- png_memcpy(dp, sp, 6);
- sp += 8;
- dp += 6;
- */
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- sp += 2;
- }
- }
- else
- {
- /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
- for (i = 0; i < row_width; i++)
- {
- /* This could be (although memcpy is probably slower):
- png_memcpy(dp, sp, 6);
- sp += 8;
- dp += 6;
- */
- sp+=2;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- }
- }
- row_info->pixel_depth = 48;
- row_info->rowbytes = row_width * 6;
- }
- row_info->channels = 3;
- row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
- }
-/*
- else if (row_info->color_type == PNG_COLOR_TYPE_GRAY ||
- row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
-*/
- else if (row_info->channels == 2)
- {
- if (row_info->bit_depth == 8)
- {
- /* This converts from GX or GA to G */
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- for (i = 0; i < row_width; i++)
- {
- *dp++ = *sp++;
- sp++;
- }
- }
- /* This converts from XG or AG to G */
- else
- {
- for (i = 0; i < row_width; i++)
- {
- sp++;
- *dp++ = *sp++;
- }
- }
- row_info->pixel_depth = 8;
- row_info->rowbytes = row_width;
- }
- else /* if (row_info->bit_depth == 16) */
- {
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- /* This converts from GGXX or GGAA to GG */
- sp += 4; dp += 2;
- for (i = 1; i < row_width; i++)
- {
- *dp++ = *sp++;
- *dp++ = *sp++;
- sp += 2;
- }
- }
- else
- {
- /* This converts from XXGG or AAGG to GG */
- for (i = 0; i < row_width; i++)
- {
- sp += 2;
- *dp++ = *sp++;
- *dp++ = *sp++;
- }
- }
- row_info->pixel_depth = 16;
- row_info->rowbytes = row_width * 2;
- }
- row_info->channels = 1;
- row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
- }
- }
-}
-#endif
-
-#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
-/* swaps red and blue bytes within a pixel */
-void
-png_do_bgr(png_row_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_bgr\n");
- if (
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
-#endif
- (row_info->color_type & PNG_COLOR_MASK_COLOR))
- {
- png_uint_32 row_width = row_info->width;
- if (row_info->bit_depth == 8)
- {
- if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- {
- png_bytep rp;
- png_uint_32 i;
-
- for (i = 0, rp = row; i < row_width; i++, rp += 3)
- {
- png_byte save = *rp;
- *rp = *(rp + 2);
- *(rp + 2) = save;
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- {
- png_bytep rp;
- png_uint_32 i;
-
- for (i = 0, rp = row; i < row_width; i++, rp += 4)
- {
- png_byte save = *rp;
- *rp = *(rp + 2);
- *(rp + 2) = save;
- }
- }
- }
- else if (row_info->bit_depth == 16)
- {
- if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- {
- png_bytep rp;
- png_uint_32 i;
-
- for (i = 0, rp = row; i < row_width; i++, rp += 6)
- {
- png_byte save = *rp;
- *rp = *(rp + 4);
- *(rp + 4) = save;
- save = *(rp + 1);
- *(rp + 1) = *(rp + 5);
- *(rp + 5) = save;
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- {
- png_bytep rp;
- png_uint_32 i;
-
- for (i = 0, rp = row; i < row_width; i++, rp += 8)
- {
- png_byte save = *rp;
- *rp = *(rp + 4);
- *(rp + 4) = save;
- save = *(rp + 1);
- *(rp + 1) = *(rp + 5);
- *(rp + 5) = save;
- }
- }
- }
- }
-}
-#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
-
+++ /dev/null
-
-/* pngwio.c - functions for data output
- *
- * libpng 1.0.3 - January 14, 1999
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
- *
- * This file provides a location for all output. Users who need
- * special handling are expected to write functions that have the same
- * arguments as these and perform similar functions, but that possibly
- * use different output methods. Note that you shouldn't change these
- * functions, but rather write replacement functions and then change
- * them at run time with png_set_write_fn(...).
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-
-/* Write the data to whatever output you are using. The default routine
- writes to a file pointer. 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 than 64K on a 16 bit machine. */
-
-void
-png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
- if (png_ptr->write_data_fn != NULL )
- (*(png_ptr->write_data_fn))(png_ptr, data, length);
- else
- png_error(png_ptr, "Call to NULL write function");
-}
-
-#if !defined(PNG_NO_STDIO)
-/* This is the function that does the actual writing of data. If you are
- not writing to a standard C stream, you should create a replacement
- write_data function and use it at run time with png_set_write_fn(), rather
- than changing the library. */
-#ifndef USE_FAR_KEYWORD
-#ifdef __VISAGECPP__
-static void _Optlink
-png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
-#else
-static void
-png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
-#endif
-{
- png_uint_32 check;
-
- check = fwrite(data, 1, length, (FILE *)(png_ptr->io_ptr));
- 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 __VISAGECPP__
-static void _Optlink
-png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
-#else
-static void
-png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
-#endif
-{
- png_uint_32 check;
- png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
- FILE *io_ptr;
-
- /* Check if data really is near. If so, use usual code. */
- near_data = (png_byte *)CVT_PTR_NOCHECK(data);
- io_ptr = (FILE *)CVT_PTR(png_ptr->io_ptr);
- if ((png_bytep)near_data == data)
- {
- check = fwrite(near_data, 1, length, io_ptr);
- }
- else
- {
- png_byte buf[NEAR_BUF_SIZE];
- png_size_t written, remaining, err;
- check = 0;
- remaining = length;
- do
- {
- written = MIN(NEAR_BUF_SIZE, remaining);
- png_memcpy(buf, data, written); /* copy far buffer to near buffer */
- err = fwrite(buf, 1, written, io_ptr);
- if (err != written)
- break;
- else
- check += err;
- data += written;
- remaining -= written;
- }
- while (remaining != 0);
- }
- if (check != length)
- {
- png_error(png_ptr, "Write Error");
- }
-}
-
-#endif
-#endif
-
-/* This function is called to output any data pending writing (normally
- to disk). After png_flush is called, there should be no data pending
- writing in any buffers. */
-#if defined(PNG_WRITE_FLUSH_SUPPORTED)
-void
-png_flush(png_structp png_ptr)
-{
- if (png_ptr->output_flush_fn != NULL)
- (*(png_ptr->output_flush_fn))(png_ptr);
-}
-
-#if !defined(PNG_NO_STDIO)
-#ifdef __VISAGECPP__
-static void _Optlink
-png_default_flush(png_structp png_ptr)
-#else
-static void
-png_default_flush(png_structp png_ptr)
-#endif
-{
- FILE *io_ptr;
- io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr));
- if (io_ptr != NULL)
- fflush(io_ptr);
-}
-#endif
-#endif
-
-/* This function allows the application to supply new output functions for
- libpng if standard C streams aren't being used.
-
- This function takes as its arguments:
- png_ptr - pointer to a png output data structure
- io_ptr - pointer to user supplied structure containing info about
- the output functions. May be NULL.
- write_data_fn - pointer to a new output function that takes as its
- arguments a pointer to a png_struct, a pointer to
- data to be written, and a 32-bit unsigned int that is
- the number of bytes to be written. The new write
- function should call png_error(png_ptr, "Error msg")
- to exit and output any fatal error messages.
- flush_data_fn - pointer to a new flush function that takes as its
- arguments a pointer to a png_struct. After a call to
- the flush function, there should be no data in any buffers
- or pending transmission. If the output method doesn't do
- any buffering of ouput, a function prototype must still be
- supplied although it doesn't have to do anything. If
- PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
- time, output_flush_fn will be ignored, although it must be
- supplied for compatibility. */
-void
-png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
- png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
-{
- png_ptr->io_ptr = io_ptr;
-
-#if !defined(PNG_NO_STDIO)
- if (write_data_fn != NULL)
- png_ptr->write_data_fn = write_data_fn;
- else
- png_ptr->write_data_fn = png_default_write_data;
-#else
- png_ptr->write_data_fn = write_data_fn;
-#endif
-
-#if defined(PNG_WRITE_FLUSH_SUPPORTED)
-#if !defined(PNG_NO_STDIO)
- if (output_flush_fn != NULL)
- png_ptr->output_flush_fn = output_flush_fn;
- else
- png_ptr->output_flush_fn = png_default_flush;
-#else
- png_ptr->output_flush_fn = output_flush_fn;
-#endif
-#endif /* PNG_WRITE_FLUSH_SUPPORTED */
-
- /* It is an error to read while writing a png file */
- if (png_ptr->read_data_fn != NULL)
- {
- png_ptr->read_data_fn = NULL;
- png_warning(png_ptr,
- "Attempted to set both read_data_fn and write_data_fn in");
- png_warning(png_ptr,
- "the same structure. Resetting read_data_fn to NULL.");
- }
-}
-
-#if defined(USE_FAR_KEYWORD)
-#if defined(_MSC_VER)
-void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check)
-{
- void *near_ptr;
- void FAR *far_ptr;
- FP_OFF(near_ptr) = FP_OFF(ptr);
- far_ptr = (void FAR *)near_ptr;
- if(check != 0)
- if(FP_SEG(ptr) != FP_SEG(far_ptr))
- png_error(png_ptr,"segment lost in conversion");
- return(near_ptr);
-}
-# else
-void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check)
-{
- void *near_ptr;
- void FAR *far_ptr;
- near_ptr = (void FAR *)ptr;
- far_ptr = (void FAR *)near_ptr;
- if(check != 0)
- if(far_ptr != ptr)
- png_error(png_ptr,"segment lost in conversion");
- return(near_ptr);
-}
-# endif
-# endif
+++ /dev/null
-
-/* pngwrite.c - general routines to write a PNG file
- *
- * libpng 1.0.3 - January 14, 1999
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
- */
-
-/* get internal access to png.h */
-#define PNG_INTERNAL
-#include "png.h"
-
-/* Writes all the PNG information. This is the suggested way to use the
- * library. If you have a new chunk to add, make a function to write it,
- * and put it in the correct location here. If you want the chunk written
- * after the image data, put it in png_write_end(). I strongly encourage
- * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing
- * the chunk, as that will keep the code from breaking if you want to just
- * write a plain PNG file. If you have long comments, I suggest writing
- * them in png_write_end(), and compressing them.
- */
-void
-png_write_info(png_structp png_ptr, png_infop info_ptr)
-{
-#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
- int i;
-#endif
-
- png_debug(1, "in png_write_info\n");
- png_write_sig(png_ptr); /* write PNG signature */
- /* write IHDR information. */
- png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
- info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,
- info_ptr->filter_type,
-#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
- info_ptr->interlace_type);
-#else
- 0);
-#endif
- /* 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_ptr->valid & PNG_INFO_gAMA)
- png_write_gAMA(png_ptr, info_ptr->gamma);
-#endif
-#if defined(PNG_WRITE_sRGB_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_sRGB)
- png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent);
-#endif
-#if defined(PNG_WRITE_sBIT_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_sBIT)
- png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);
-#endif
-#if defined(PNG_WRITE_cHRM_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_cHRM)
- png_write_cHRM(png_ptr,
- info_ptr->x_white, info_ptr->y_white,
- info_ptr->x_red, info_ptr->y_red,
- info_ptr->x_green, info_ptr->y_green,
- info_ptr->x_blue, info_ptr->y_blue);
-#endif
- if (info_ptr->valid & PNG_INFO_PLTE)
- png_write_PLTE(png_ptr, info_ptr->palette,
- (png_uint_32)info_ptr->num_palette);
- else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- png_error(png_ptr, "Valid palette required for paletted images\n");
-
-#if defined(PNG_WRITE_tRNS_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_tRNS)
- {
-#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
- /* invert the alpha channel (in tRNS) */
- if (png_ptr->transformations & PNG_INVERT_ALPHA &&
- info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- int j;
- for (j=0; j<(int)info_ptr->num_trans; j++)
- info_ptr->trans[j] = 255 - info_ptr->trans[j];
- }
-#endif
- png_write_tRNS(png_ptr, info_ptr->trans, &(info_ptr->trans_values),
- info_ptr->num_trans, info_ptr->color_type);
- }
-#endif
-#if defined(PNG_WRITE_bKGD_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_bKGD)
- png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
-#endif
-#if defined(PNG_WRITE_hIST_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_hIST)
- png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
-#endif
-#if defined(PNG_WRITE_oFFs_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_oFFs)
- png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset,
- info_ptr->offset_unit_type);
-#endif
-#if defined(PNG_WRITE_pCAL_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_pCAL)
- png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0,
- info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams,
- info_ptr->pcal_units, info_ptr->pcal_params);
-#endif
-#if defined(PNG_WRITE_pHYs_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_pHYs)
- png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,
- info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type);
-#endif
-#if defined(PNG_WRITE_tIME_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_tIME)
- {
- png_write_tIME(png_ptr, &(info_ptr->mod_time));
- png_ptr->flags |= PNG_FLAG_WROTE_tIME;
- }
-#endif
-#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
- /* Check to see if we need to write text chunks */
- for (i = 0; i < info_ptr->num_text; i++)
- {
- png_debug2(2, "Writing header text chunk %d, type %d\n", i,
- info_ptr->text[i].compression);
- /* If we want a compressed text chunk */
- if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
- {
-#if defined(PNG_WRITE_zTXt_SUPPORTED)
- /* write compressed chunk */
- png_write_zTXt(png_ptr, info_ptr->text[i].key,
- info_ptr->text[i].text, info_ptr->text[i].text_length,
- info_ptr->text[i].compression);
-#else
- png_warning(png_ptr, "Unable to write compressed text\n");
-#endif
- /* Mark this chunk as written */
- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
- }
- else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
- {
-#if defined(PNG_WRITE_tEXt_SUPPORTED)
- /* write uncompressed chunk */
- png_write_tEXt(png_ptr, info_ptr->text[i].key,
- info_ptr->text[i].text, info_ptr->text[i].text_length);
-#else
- png_warning(png_ptr, "Unable to write uncompressed text\n");
-#endif
- /* Mark this chunk as written */
- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
- }
- }
-#endif
-}
-
-/* Writes the end of the PNG file. If you don't want to write comments or
- * time information, you can pass NULL for info. If you already wrote these
- * in png_write_info(), do not write them again here. If you have long
- * comments, I suggest writing them here, and compressing them.
- */
-void
-png_write_end(png_structp png_ptr, png_infop info_ptr)
-{
- png_debug(1, "in png_write_end\n");
- if (!(png_ptr->mode & PNG_HAVE_IDAT))
- png_error(png_ptr, "No IDATs written into file");
-
- /* see if user wants us to write information chunks */
- if (info_ptr != NULL)
- {
-#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
- int i; /* local index variable */
-#endif
-#if defined(PNG_WRITE_tIME_SUPPORTED)
- /* check to see if user has supplied a time chunk */
- if (info_ptr->valid & PNG_INFO_tIME &&
- !(png_ptr->flags & PNG_FLAG_WROTE_tIME))
- png_write_tIME(png_ptr, &(info_ptr->mod_time));
-#endif
-#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
- /* loop through comment chunks */
- for (i = 0; i < info_ptr->num_text; i++)
- {
- png_debug2(2, "Writing trailer text chunk %d, type %d\n", i,
- info_ptr->text[i].compression);
- if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
- {
-#if defined(PNG_WRITE_zTXt_SUPPORTED)
- /* write compressed chunk */
- png_write_zTXt(png_ptr, info_ptr->text[i].key,
- info_ptr->text[i].text, info_ptr->text[i].text_length,
- info_ptr->text[i].compression);
-#else
- png_warning(png_ptr, "Unable to write compressed text\n");
-#endif
- /* Mark this chunk as written */
- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
- }
- else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
- {
-#if defined(PNG_WRITE_tEXt_SUPPORTED)
- /* write uncompressed chunk */
- png_write_tEXt(png_ptr, info_ptr->text[i].key,
- info_ptr->text[i].text, info_ptr->text[i].text_length);
-#else
- png_warning(png_ptr, "Unable to write uncompressed text\n");
-#endif
-
- /* Mark this chunk as written */
- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
- }
- }
-#endif
- }
-
- png_ptr->mode |= PNG_AFTER_IDAT;
-
- /* write end of PNG file */
- png_write_IEND(png_ptr);
-}
-
-#if defined(PNG_WRITE_tIME_SUPPORTED)
-void
-png_convert_from_struct_tm(png_timep ptime, struct tm FAR * ttime)
-{
- png_debug(1, "in png_convert_from_struct_tm\n");
- ptime->year = (png_uint_16)(1900 + ttime->tm_year);
- ptime->month = (png_byte)(ttime->tm_mon + 1);
- ptime->day = (png_byte)ttime->tm_mday;
- ptime->hour = (png_byte)ttime->tm_hour;
- ptime->minute = (png_byte)ttime->tm_min;
- ptime->second = (png_byte)ttime->tm_sec;
-}
-
-void
-png_convert_from_time_t(png_timep ptime, time_t ttime)
-{
- struct tm *tbuf;
-
- png_debug(1, "in png_convert_from_time_t\n");
- tbuf = gmtime(&ttime);
- png_convert_from_struct_tm(ptime, tbuf);
-}
-#endif
-
-/* Initialize png_ptr structure, and allocate any memory needed */
-png_structp
-png_create_write_struct(png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn)
-{
-#ifdef PNG_USER_MEM_SUPPORTED
- return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn,
- warn_fn, NULL, NULL, NULL));
-}
-
-/* Alternate initialize png_ptr structure, and allocate any memory needed */
-png_structp
-png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
- png_malloc_ptr malloc_fn, png_free_ptr free_fn)
-{
-#endif /* PNG_USER_MEM_SUPPORTED */
- png_structp png_ptr;
-#ifdef USE_FAR_KEYWORD
- jmp_buf jmpbuf;
-#endif
- png_debug(1, "in png_create_write_struct\n");
-#ifdef PNG_USER_MEM_SUPPORTED
- if ((png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
- (png_malloc_ptr)malloc_fn)) == NULL)
-#else
- if ((png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG)) == NULL)
-#endif /* PNG_USER_MEM_SUPPORTED */
- {
- return ((png_structp)NULL);
- }
-#ifdef USE_FAR_KEYWORD
- if (setjmp(jmpbuf))
-#else
- if (setjmp(png_ptr->jmpbuf))
-#endif
- {
- png_free(png_ptr, png_ptr->zbuf);
- png_destroy_struct(png_ptr);
- return ((png_structp)NULL);
- }
-#ifdef USE_FAR_KEYWORD
- png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
-#endif
-#ifdef PNG_USER_MEM_SUPPORTED
- png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
-#endif /* PNG_USER_MEM_SUPPORTED */
- png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
-
- /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
- * we must recompile any applications that use any older library version.
- * For versions after libpng 1.0, we will be compatible, so we need
- * only check the first digit.
- */
- if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
- (png_libpng_ver[0] == '0' && user_png_ver[2] < '9'))
- {
- png_error(png_ptr,
- "Incompatible libpng version in application and library");
- }
-
- /* initialize zbuf - compression buffer */
- png_ptr->zbuf_size = PNG_ZBUF_SIZE;
- png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)png_ptr->zbuf_size);
-
- png_set_write_fn(png_ptr, NULL, NULL, NULL);
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
- 1, NULL, NULL);
-#endif
-
- return ((png_structp)png_ptr);
-}
-
-/* Initialize png_ptr structure, and allocate any memory needed */
-void
-png_write_init(png_structp png_ptr)
-{
- jmp_buf tmp_jmp; /* to save current jump buffer */
-
- png_debug(1, "in png_write_init\n");
- /* save jump buffer and error functions */
- png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
-
- /* reset all variables to 0 */
- png_memset(png_ptr, 0, sizeof (png_struct));
-
- /* restore jump buffer */
- 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_bytep)png_malloc(png_ptr,
- (png_uint_32)png_ptr->zbuf_size);
- png_set_write_fn(png_ptr, NULL, NULL, NULL);
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
- 1, NULL, NULL);
-#endif
-}
-
-/* Write a few rows of image data. If the image is interlaced,
- * either you will have to write the 7 sub images, or, if you
- * have called png_set_interlace_handling(), you will have to
- * "write" the image seven times.
- */
-void
-png_write_rows(png_structp png_ptr, png_bytepp row,
- png_uint_32 num_rows)
-{
- png_uint_32 i; /* row counter */
- png_bytepp rp; /* row pointer */
-
- png_debug(1, "in png_write_rows\n");
- /* loop through the rows */
- for (i = 0, rp = row; i < num_rows; i++, rp++)
- {
- png_write_row(png_ptr, *rp);
- }
-}
-
-/* Write the image. You only need to call this function once, even
- * if you are writing an interlaced image.
- */
-void
-png_write_image(png_structp png_ptr, png_bytepp image)
-{
- png_uint_32 i; /* row index */
- int pass, num_pass; /* pass variables */
- png_bytepp rp; /* points to current row */
-
- png_debug(1, "in png_write_image\n");
-#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
- /* intialize interlace handling. If image is not interlaced,
- this will set pass to 1 */
- num_pass = png_set_interlace_handling(png_ptr);
-#else
- num_pass = 1;
-#endif
- /* loop through passes */
- for (pass = 0; pass < num_pass; pass++)
- {
- /* loop through image */
- for (i = 0, rp = image; i < png_ptr->height; i++, rp++)
- {
- png_write_row(png_ptr, *rp);
- }
- }
-}
-
-/* called by user to write a row of image data */
-void
-png_write_row(png_structp png_ptr, png_bytep row)
-{
- png_debug2(1, "in png_write_row (row %ld, pass %d)\n",
- png_ptr->row_number, png_ptr->pass);
- /* initialize transformations and other stuff if first time */
- if (png_ptr->row_number == 0 && png_ptr->pass == 0)
- {
- /* check for transforms that have been set but were defined out */
-#if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED)
- if (png_ptr->transformations & PNG_INVERT_MONO)
- png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined.");
-#endif
-#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED)
- if (png_ptr->transformations & PNG_FILLER)
- png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined.");
-#endif
-#if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- png_warning(png_ptr, "PNG_WRITE_PACKSWAP_SUPPORTED is not defined.");
-#endif
-#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED)
- if (png_ptr->transformations & PNG_PACK)
- png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined.");
-#endif
-#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED)
- if (png_ptr->transformations & PNG_SHIFT)
- png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined.");
-#endif
-#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED)
- if (png_ptr->transformations & PNG_BGR)
- png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined.");
-#endif
-#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_SWAP_BYTES)
- png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined.");
-#endif
-
- 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))
- {
- switch (png_ptr->pass)
- {
- case 0:
- if (png_ptr->row_number & 7)
- {
- png_write_finish_row(png_ptr);
- return;
- }
- break;
- case 1:
- if ((png_ptr->row_number & 7) || png_ptr->width < 5)
- {
- png_write_finish_row(png_ptr);
- return;
- }
- break;
- case 2:
- if ((png_ptr->row_number & 7) != 4)
- {
- png_write_finish_row(png_ptr);
- return;
- }
- break;
- case 3:
- if ((png_ptr->row_number & 3) || png_ptr->width < 3)
- {
- png_write_finish_row(png_ptr);
- return;
- }
- break;
- case 4:
- if ((png_ptr->row_number & 3) != 2)
- {
- png_write_finish_row(png_ptr);
- return;
- }
- break;
- case 5:
- if ((png_ptr->row_number & 1) || png_ptr->width < 2)
- {
- png_write_finish_row(png_ptr);
- return;
- }
- break;
- case 6:
- if (!(png_ptr->row_number & 1))
- {
- png_write_finish_row(png_ptr);
- return;
- }
- break;
- }
- }
-#endif
-
- /* set up row info for transformations */
- png_ptr->row_info.color_type = png_ptr->color_type;
- png_ptr->row_info.width = png_ptr->usr_width;
- png_ptr->row_info.channels = png_ptr->usr_channels;
- png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth;
- png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
- png_ptr->row_info.channels);
-
- png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
- (png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
-
- png_debug1(3, "row_info->color_type = %d\n", png_ptr->row_info.color_type);
- png_debug1(3, "row_info->width = %d\n", png_ptr->row_info.width);
- png_debug1(3, "row_info->channels = %d\n", png_ptr->row_info.channels);
- png_debug1(3, "row_info->bit_depth = %d\n", png_ptr->row_info.bit_depth);
- png_debug1(3, "row_info->pixel_depth = %d\n", png_ptr->row_info.pixel_depth);
- png_debug1(3, "row_info->rowbytes = %d\n", png_ptr->row_info.rowbytes);
-
- /* Copy user's row into buffer, leaving room for filter byte. */
- png_memcpy_check(png_ptr, png_ptr->row_buf + 1, row,
- 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))
- {
- png_do_write_interlace(&(png_ptr->row_info),
- png_ptr->row_buf + 1, png_ptr->pass);
- /* this should always get caught above, but still ... */
- if (!(png_ptr->row_info.width))
- {
- png_write_finish_row(png_ptr);
- return;
- }
- }
-#endif
-
- /* handle other transformations */
- if (png_ptr->transformations)
- png_do_write_transformations(png_ptr);
-
- /* Find a filter if necessary, filter the row and write it out. */
- png_write_find_filter(png_ptr, &(png_ptr->row_info));
-
- if (png_ptr->write_row_fn != NULL)
- (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
-}
-
-#if defined(PNG_WRITE_FLUSH_SUPPORTED)
-/* Set the automatic flush interval or 0 to turn flushing off */
-void
-png_set_flush(png_structp png_ptr, int nrows)
-{
- png_debug(1, "in png_set_flush\n");
- png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
-}
-
-/* flush the current output buffers now */
-void
-png_write_flush(png_structp png_ptr)
-{
- int wrote_IDAT;
-
- png_debug(1, "in png_write_flush\n");
- /* We have already written out all of the data */
- if (png_ptr->row_number >= png_ptr->num_rows)
- return;
-
- do
- {
- int ret;
-
- /* compress the data */
- ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH);
- wrote_IDAT = 0;
-
- /* check for compression errors */
- if (ret != Z_OK)
- {
- if (png_ptr->zstream.msg != NULL)
- png_error(png_ptr, png_ptr->zstream.msg);
- else
- png_error(png_ptr, "zlib error");
- }
-
- if (!(png_ptr->zstream.avail_out))
- {
- /* write the IDAT and reset the zlib output buffer */
- png_write_IDAT(png_ptr, png_ptr->zbuf,
- png_ptr->zbuf_size);
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- wrote_IDAT = 1;
- }
- } while(wrote_IDAT == 1);
-
- /* If there is any data left to be output, write it into a new IDAT */
- if (png_ptr->zbuf_size != png_ptr->zstream.avail_out)
- {
- /* write the IDAT and reset the zlib output buffer */
- png_write_IDAT(png_ptr, png_ptr->zbuf,
- png_ptr->zbuf_size - png_ptr->zstream.avail_out);
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- }
- png_ptr->flush_rows = 0;
- png_flush(png_ptr);
-}
-#endif /* PNG_WRITE_FLUSH_SUPPORTED */
-
-/* free all memory used by the write */
-void
-png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
-{
- png_structp png_ptr = NULL;
- png_infop info_ptr = NULL;
-#ifdef PNG_USER_MEM_SUPPORTED
- png_free_ptr free_fn = NULL;
-#endif
-
- png_debug(1, "in png_destroy_write_struct\n");
- if (png_ptr_ptr != NULL)
- {
- png_ptr = *png_ptr_ptr;
-#ifdef PNG_USER_MEM_SUPPORTED
- free_fn = png_ptr->free_fn;
-#endif
- }
-
- if (info_ptr_ptr != NULL)
- info_ptr = *info_ptr_ptr;
-
- if (info_ptr != NULL)
- {
-#ifdef PNG_WRITE_tEXt_SUPPORTED
- png_free(png_ptr, info_ptr->text);
-#endif
-#if defined(PNG_READ_pCAL_SUPPORTED)
- png_free(png_ptr, info_ptr->pcal_purpose);
- png_free(png_ptr, info_ptr->pcal_units);
- if (info_ptr->pcal_params != NULL)
- {
- int i;
- for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
- {
- png_free(png_ptr, info_ptr->pcal_params[i]);
- }
- png_free(png_ptr, info_ptr->pcal_params);
- }
-#endif
-#ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2((png_voidp)info_ptr, free_fn);
-#else
- png_destroy_struct((png_voidp)info_ptr);
-#endif
- *info_ptr_ptr = (png_infop)NULL;
- }
-
- if (png_ptr != NULL)
- {
- png_write_destroy(png_ptr);
-#ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2((png_voidp)png_ptr, free_fn);
-#else
- png_destroy_struct((png_voidp)png_ptr);
-#endif
- *png_ptr_ptr = (png_structp)NULL;
- }
-}
-
-
-/* Free any memory used in png_ptr struct (old method) */
-void
-png_write_destroy(png_structp png_ptr)
-{
- jmp_buf tmp_jmp; /* save jump buffer */
- png_error_ptr error_fn;
- png_error_ptr warning_fn;
- png_voidp error_ptr;
-#ifdef PNG_USER_MEM_SUPPORTED
- png_free_ptr free_fn;
-#endif
-
- png_debug(1, "in png_write_destroy\n");
- /* free any memory zlib uses */
- deflateEnd(&png_ptr->zstream);
-
- /* free our memory. png_free checks NULL for us. */
- png_free(png_ptr, png_ptr->zbuf);
- png_free(png_ptr, png_ptr->row_buf);
- png_free(png_ptr, png_ptr->prev_row);
- png_free(png_ptr, png_ptr->sub_row);
- png_free(png_ptr, png_ptr->up_row);
- png_free(png_ptr, png_ptr->avg_row);
- png_free(png_ptr, png_ptr->paeth_row);
-#if defined(PNG_TIME_RFC1123_SUPPORTED)
- png_free(png_ptr, png_ptr->time_buffer);
-#endif /* PNG_TIME_RFC1123_SUPPORTED */
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- png_free(png_ptr, png_ptr->prev_filters);
- png_free(png_ptr, png_ptr->filter_weights);
- png_free(png_ptr, png_ptr->inv_filter_weights);
- png_free(png_ptr, png_ptr->filter_costs);
- png_free(png_ptr, png_ptr->inv_filter_costs);
-#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
-
- /* reset structure */
- png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
-
- error_fn = png_ptr->error_fn;
- warning_fn = png_ptr->warning_fn;
- error_ptr = png_ptr->error_ptr;
-#ifdef PNG_USER_MEM_SUPPORTED
- free_fn = png_ptr->free_fn;
-#endif
-
- png_memset(png_ptr, 0, sizeof (png_struct));
-
- png_ptr->error_fn = error_fn;
- png_ptr->warning_fn = warning_fn;
- png_ptr->error_ptr = error_ptr;
-#ifdef PNG_USER_MEM_SUPPORTED
- png_ptr->free_fn = free_fn;
-#endif
-
- png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
-}
-
-/* Allow the application to select one or more row filters to use. */
-void
-png_set_filter(png_structp png_ptr, int method, int filters)
-{
- png_debug(1, "in png_set_filter\n");
- /* We allow 'method' only for future expansion of the base filter method. */
- if (method == PNG_FILTER_TYPE_BASE)
- {
- switch (filters & (PNG_ALL_FILTERS | 0x07))
- {
- case 5:
- case 6:
- case 7: png_warning(png_ptr, "Unknown row filter for method 0");
- case PNG_FILTER_VALUE_NONE: png_ptr->do_filter=PNG_FILTER_NONE; break;
- case PNG_FILTER_VALUE_SUB: png_ptr->do_filter=PNG_FILTER_SUB; break;
- case PNG_FILTER_VALUE_UP: png_ptr->do_filter=PNG_FILTER_UP; break;
- case PNG_FILTER_VALUE_AVG: png_ptr->do_filter=PNG_FILTER_AVG; break;
- case PNG_FILTER_VALUE_PAETH: png_ptr->do_filter=PNG_FILTER_PAETH;break;
- default: png_ptr->do_filter = (png_byte)filters; break;
- }
-
- /* If we have allocated the row_buf, this means we have already started
- * with the image and we should have allocated all of the filter buffers
- * that have been selected. If prev_row isn't already allocated, then
- * it is too late to start using the filters that need it, since we
- * will be missing the data in the previous row. If an application
- * wants to start and stop using particular filters during compression,
- * it should start out with all of the filters, and then add and
- * remove them after the start of compression.
- */
- if (png_ptr->row_buf != NULL)
- {
- if (png_ptr->do_filter & PNG_FILTER_SUB && png_ptr->sub_row == NULL)
- {
- png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
- }
-
- if (png_ptr->do_filter & PNG_FILTER_UP && png_ptr->up_row == NULL)
- {
- if (png_ptr->prev_row == NULL)
- {
- png_warning(png_ptr, "Can't add Up filter after starting");
- png_ptr->do_filter &= ~PNG_FILTER_UP;
- }
- else
- {
- png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
- }
- }
-
- if (png_ptr->do_filter & PNG_FILTER_AVG && png_ptr->avg_row == NULL)
- {
- if (png_ptr->prev_row == NULL)
- {
- png_warning(png_ptr, "Can't add Average filter after starting");
- png_ptr->do_filter &= ~PNG_FILTER_AVG;
- }
- else
- {
- png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
- }
- }
-
- if (png_ptr->do_filter & PNG_FILTER_PAETH &&
- png_ptr->paeth_row == NULL)
- {
- if (png_ptr->prev_row == NULL)
- {
- png_warning(png_ptr, "Can't add Paeth filter after starting");
- png_ptr->do_filter &= ~PNG_FILTER_PAETH;
- }
- else
- {
- png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
- }
- }
-
- if (png_ptr->do_filter == PNG_NO_FILTERS)
- png_ptr->do_filter = PNG_FILTER_NONE;
- }
- }
- else
- png_error(png_ptr, "Unknown custom filter method");
-}
-
-/* This allows us to influence the way in which libpng chooses the "best"
- * filter for the current scanline. While the "minimum-sum-of-absolute-
- * differences metric is relatively fast and effective, there is some
- * question as to whether it can be improved upon by trying to keep the
- * filtered data going to zlib more consistent, hopefully resulting in
- * better compression.
- */
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* GRR 970116 */
-void
-png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
- int num_weights, png_doublep filter_weights,
- png_doublep filter_costs)
-{
- int i;
-
- png_debug(1, "in png_set_filter_heuristics\n");
- if (heuristic_method >= PNG_FILTER_HEURISTIC_LAST)
- {
- png_warning(png_ptr, "Unknown filter heuristic method");
- return;
- }
-
- if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT)
- {
- heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED;
- }
-
- if (num_weights < 0 || filter_weights == NULL ||
- heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED)
- {
- num_weights = 0;
- }
-
- png_ptr->num_prev_filters = num_weights;
- png_ptr->heuristic_method = heuristic_method;
-
- if (num_weights > 0)
- {
- if (png_ptr->prev_filters == NULL)
- {
- png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)(sizeof(png_byte) * num_weights));
-
- /* To make sure that the weighting starts out fairly */
- for (i = 0; i < num_weights; i++)
- {
- png_ptr->prev_filters[i] = 255;
- }
- }
-
- if (png_ptr->filter_weights == NULL)
- {
- png_ptr->filter_weights = (png_uint_16p) png_malloc(png_ptr,
- (png_uint_32)(sizeof(png_uint_16) * num_weights));
-
- png_ptr->inv_filter_weights = (png_uint_16p) png_malloc(png_ptr,
- (png_uint_32)(sizeof(png_uint_16) * num_weights));
-
- for (i = 0; i < num_weights; i++)
- {
- png_ptr->inv_filter_weights[i] =
- png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
- }
- }
-
- for (i = 0; i < num_weights; i++)
- {
- if (filter_weights[i] < 0.0)
- {
- png_ptr->inv_filter_weights[i] =
- png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
- }
- else
- {
- png_ptr->inv_filter_weights[i] =
- (png_uint_16)((double)PNG_WEIGHT_FACTOR*filter_weights[i]+0.5);
- png_ptr->filter_weights[i] =
- (png_uint_16)((double)PNG_WEIGHT_FACTOR/filter_weights[i]+0.5);
- }
- }
- }
-
- /* If, in the future, there are other filter methods, this would
- * need to be based on png_ptr->filter.
- */
- if (png_ptr->filter_costs == NULL)
- {
- png_ptr->filter_costs = (png_uint_16p) png_malloc(png_ptr,
- (png_uint_32)(sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
-
- png_ptr->inv_filter_costs = (png_uint_16p) png_malloc(png_ptr,
- (png_uint_32)(sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
-
- for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
- {
- png_ptr->inv_filter_costs[i] =
- png_ptr->filter_costs[i] = PNG_COST_FACTOR;
- }
- }
-
- /* Here is where we set the relative costs of the different filters. We
- * should take the desired compression level into account when setting
- * the costs, so that Paeth, for instance, has a high relative cost at low
- * compression levels, while it has a lower relative cost at higher
- * compression settings. The filter types are in order of increasing
- * relative cost, so it would be possible to do this with an algorithm.
- */
- for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
- {
- if (filter_costs == NULL || filter_costs[i] < 0.0)
- {
- png_ptr->inv_filter_costs[i] =
- png_ptr->filter_costs[i] = PNG_COST_FACTOR;
- }
- else if (filter_costs[i] >= 1.0)
- {
- png_ptr->inv_filter_costs[i] =
- (png_uint_16)((double)PNG_COST_FACTOR / filter_costs[i] + 0.5);
- png_ptr->filter_costs[i] =
- (png_uint_16)((double)PNG_COST_FACTOR * filter_costs[i] + 0.5);
- }
- }
-}
-#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
-
-void
-png_set_compression_level(png_structp png_ptr, int level)
-{
- png_debug(1, "in png_set_compression_level\n");
- png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL;
- png_ptr->zlib_level = level;
-}
-
-void
-png_set_compression_mem_level(png_structp png_ptr, int mem_level)
-{
- png_debug(1, "in png_set_compression_mem_level\n");
- png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL;
- png_ptr->zlib_mem_level = mem_level;
-}
-
-void
-png_set_compression_strategy(png_structp png_ptr, int strategy)
-{
- png_debug(1, "in png_set_compression_strategy\n");
- png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY;
- png_ptr->zlib_strategy = strategy;
-}
-
-void
-png_set_compression_window_bits(png_structp png_ptr, int window_bits)
-{
- if (window_bits > 15)
- png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
- png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS;
- png_ptr->zlib_window_bits = window_bits;
-}
-
-void
-png_set_compression_method(png_structp png_ptr, int method)
-{
- png_debug(1, "in png_set_compression_method\n");
- if (method != 8)
- png_warning(png_ptr, "Only compression method 8 is supported by PNG");
- png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD;
- png_ptr->zlib_method = method;
-}
-
-void
-png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn)
-{
- png_ptr->write_row_fn = write_row_fn;
-}
-
-#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
-void
-png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
- write_user_transform_fn)
-{
- png_debug(1, "in png_set_write_user_transform_fn\n");
- png_ptr->transformations |= PNG_USER_TRANSFORM;
- png_ptr->write_user_transform_fn = write_user_transform_fn;
-}
-#endif
-
+++ /dev/null
-
-/* pngwtran.c - transforms the data in a row for PNG writers
- *
- * libpng 1.0.3 - January 14, 1999
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-
-/* Transform the data according to the user's wishes. The order of
- * transformations is significant.
- */
-void
-png_do_write_transformations(png_structp png_ptr)
-{
- png_debug(1, "in png_do_write_transformations\n");
-
-#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
- if (png_ptr->transformations & PNG_USER_TRANSFORM)
- if(png_ptr->write_user_transform_fn != NULL)
- (*(png_ptr->write_user_transform_fn)) /* user write transform function */
- (png_ptr, /* png_ptr */
- &(png_ptr->row_info), /* row_info: */
- /* png_uint_32 width; width of row */
- /* png_uint_32 rowbytes; number of bytes in row */
- /* png_byte color_type; color type of pixels */
- /* png_byte bit_depth; bit depth of samples */
- /* png_byte channels; number of channels (1-4) */
- /* png_byte pixel_depth; bits per pixel (depth*channels) */
- png_ptr->row_buf + 1); /* start of pixel data for row */
-#endif
-#if defined(PNG_WRITE_FILLER_SUPPORTED)
- if (png_ptr->transformations & PNG_FILLER)
- png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
- png_ptr->flags);
-#endif
-#if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
-#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_uint_32)png_ptr->bit_depth);
-#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_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_INVERT_ALPHA_SUPPORTED)
- if (png_ptr->transformations & PNG_INVERT_ALPHA)
- png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
-#endif
-#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
- if (png_ptr->transformations & PNG_SWAP_ALPHA)
- png_do_write_swap_alpha(&(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_infop row_info, png_bytep row, png_uint_32 bit_depth)
-{
- png_debug(1, "in png_do_pack\n");
- if (row_info->bit_depth == 8 &&
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
-#endif
- row_info->channels == 1)
- {
- switch ((int)bit_depth)
- {
- case 1:
- {
- png_bytep sp, dp;
- int mask, v;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- sp = row;
- dp = row;
- mask = 0x80;
- v = 0;
-
- for (i = 0; i < row_width; i++)
- {
- if (*sp != 0)
- v |= mask;
- sp++;
- if (mask > 1)
- mask >>= 1;
- else
- {
- mask = 0x80;
- *dp = (png_byte)v;
- dp++;
- v = 0;
- }
- }
- if (mask != 0x80)
- *dp = (png_byte)v;
- break;
- }
- case 2:
- {
- png_bytep sp, dp;
- int shift, v;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- sp = row;
- dp = row;
- shift = 6;
- v = 0;
- for (i = 0; i < row_width; i++)
- {
- png_byte value;
-
- value = (png_byte)(*sp & 0x3);
- v |= (value << shift);
- if (shift == 0)
- {
- shift = 6;
- *dp = (png_byte)v;
- dp++;
- v = 0;
- }
- else
- shift -= 2;
- sp++;
- }
- if (shift != 6)
- *dp = (png_byte)v;
- break;
- }
- case 4:
- {
- png_bytep sp, dp;
- int shift, v;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- sp = row;
- dp = row;
- shift = 4;
- v = 0;
- for (i = 0; i < row_width; i++)
- {
- png_byte value;
-
- value = (png_byte)(*sp & 0xf);
- v |= (value << shift);
-
- if (shift == 0)
- {
- shift = 4;
- *dp = (png_byte)v;
- dp++;
- v = 0;
- }
- else
- shift -= 4;
-
- sp++;
- }
- if (shift != 4)
- *dp = (png_byte)v;
- break;
- }
- }
- row_info->bit_depth = (png_byte)bit_depth;
- row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
- row_info->rowbytes =
- ((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
- * bit depth 4, but the pixels only had values from 0 to 7, you
- * would pass 3 as bit_depth, and this routine would translate the
- * data to 0 to 15.
- */
-void
-png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
-{
- png_debug(1, "in png_do_shift\n");
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL &&
-#else
- if (
-#endif
- row_info->color_type != PNG_COLOR_TYPE_PALETTE)
- {
- int shift_start[4], shift_dec[4];
- int channels = 0;
-
- if (row_info->color_type & PNG_COLOR_MASK_COLOR)
- {
- shift_start[channels] = row_info->bit_depth - bit_depth->red;
- shift_dec[channels] = bit_depth->red;
- channels++;
- shift_start[channels] = row_info->bit_depth - bit_depth->green;
- shift_dec[channels] = bit_depth->green;
- channels++;
- shift_start[channels] = row_info->bit_depth - bit_depth->blue;
- shift_dec[channels] = bit_depth->blue;
- channels++;
- }
- else
- {
- shift_start[channels] = row_info->bit_depth - bit_depth->gray;
- shift_dec[channels] = bit_depth->gray;
- channels++;
- }
- if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
- {
- shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
- shift_dec[channels] = bit_depth->alpha;
- channels++;
- }
-
- /* with low row depths, could only be grayscale, so one channel */
- if (row_info->bit_depth < 8)
- {
- png_bytep bp = row;
- png_uint_32 i;
- png_byte mask;
- png_uint_32 row_bytes = row_info->rowbytes;
-
- if (bit_depth->gray == 1 && row_info->bit_depth == 2)
- mask = 0x55;
- else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
- mask = 0x11;
- else
- mask = 0xff;
-
- for (i = 0; i < row_bytes; i++, bp++)
- {
- png_uint_16 v;
- int j;
-
- v = *bp;
- *bp = 0;
- for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
- {
- if (j > 0)
- *bp |= (png_byte)((v << j) & 0xff);
- else
- *bp |= (png_byte)((v >> (-j)) & mask);
- }
- }
- }
- else if (row_info->bit_depth == 8)
- {
- png_bytep bp = row;
- png_uint_32 i;
- png_uint_32 istop = channels * row_info->width;
-
- for (i = 0; i < istop; i++, bp++)
- {
-
- png_uint_16 v;
- int j;
- int c = (int)(i%channels);
-
- v = *bp;
- *bp = 0;
- for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
- {
- if (j > 0)
- *bp |= (png_byte)((v << j) & 0xff);
- else
- *bp |= (png_byte)((v >> (-j)) & 0xff);
- }
- }
- }
- else
- {
- png_bytep bp;
- png_uint_32 i;
- png_uint_32 istop = channels * row_info->width;
-
- for (bp = row, i = 0; i < istop; i++)
- {
- int c = (int)(i%channels);
- png_uint_16 value, v;
- int j;
-
- v = ((png_uint_16)(*bp) << 8) + *(bp + 1);
- value = 0;
- for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
- {
- if (j > 0)
- value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
- else
- value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
- }
- *bp++ = (png_byte)(value >> 8);
- *bp++ = (png_byte)(value & 0xff);
- }
- }
- }
-}
-#endif
-
-#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
-void
-png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_write_swap_alpha\n");
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL)
-#endif
- {
- if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- {
- /* This converts from ARGB to RGBA */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- png_byte save = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = save;
- }
- }
- /* This converts from AARRGGBB to RRGGBBAA */
- else
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- png_byte save[2];
- save[0] = *(sp++);
- save[1] = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = save[0];
- *(dp++) = save[1];
- }
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- {
- /* This converts from AG to GA */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- png_byte save = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = save;
- }
- }
- /* This converts from AAGG to GGAA */
- else
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- png_byte save[2];
- save[0] = *(sp++);
- save[1] = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = save[0];
- *(dp++) = save[1];
- }
- }
- }
- }
-}
-#endif
-
-#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
-void
-png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_write_invert_alpha\n");
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL)
-#endif
- {
- if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- {
- /* This inverts the alpha channel in RGBA */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = 255 - *(sp++);
- }
- }
- /* This inverts the alpha channel in RRGGBBAA */
- else
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = 255 - *(sp++);
- *(dp++) = 255 - *(sp++);
- }
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- {
- /* This inverts the alpha channel in GA */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- *(dp++) = *(sp++);
- *(dp++) = 255 - *(sp++);
- }
- }
- /* This inverts the alpha channel in GGAA */
- else
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = 255 - *(sp++);
- *(dp++) = 255 - *(sp++);
- }
- }
- }
- }
-}
-#endif
+++ /dev/null
-
-/* pngwutil.c - utilities to write a PNG file
- *
- * libpng 1.0.3 - January 14, 1999
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-
-/* Place a 32-bit number into a buffer in PNG byte order. We work
- * with unsigned numbers for convenience, although one supported
- * ancillary chunk uses signed (two's complement) numbers.
- */
-void
-png_save_uint_32(png_bytep buf, png_uint_32 i)
-{
- buf[0] = (png_byte)((i >> 24) & 0xff);
- buf[1] = (png_byte)((i >> 16) & 0xff);
- buf[2] = (png_byte)((i >> 8) & 0xff);
- buf[3] = (png_byte)(i & 0xff);
-}
-
-#if defined(PNG_WRITE_pCAL_SUPPORTED)
-/* The png_save_int_32 function assumes integers are stored in two's
- * complement format. If this isn't the case, then this routine needs to
- * be modified to write data in two's complement format.
- */
-void
-png_save_int_32(png_bytep buf, png_int_32 i)
-{
- buf[0] = (png_byte)((i >> 24) & 0xff);
- buf[1] = (png_byte)((i >> 16) & 0xff);
- buf[2] = (png_byte)((i >> 8) & 0xff);
- buf[3] = (png_byte)(i & 0xff);
-}
-#endif
-
-/* Place a 16-bit number into a buffer in PNG byte order.
- * The parameter is declared unsigned int, not png_uint_16,
- * just to avoid potential problems on pre-ANSI C compilers.
- */
-void
-png_save_uint_16(png_bytep buf, unsigned int i)
-{
- buf[0] = (png_byte)((i >> 8) & 0xff);
- buf[1] = (png_byte)(i & 0xff);
-}
-
-/* Write a PNG chunk all at once. The type is an array of ASCII characters
- * representing the chunk name. The array must be at least 4 bytes in
- * length, and does not need to be null terminated. To be safe, pass the
- * pre-defined chunk names here, and if you need a new one, define it
- * where the others are defined. The length is the length of the data.
- * All the data must be present. If that is not possible, use the
- * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
- * functions instead.
- */
-void
-png_write_chunk(png_structp png_ptr, png_bytep chunk_name,
- png_bytep data, png_size_t length)
-{
- png_write_chunk_start(png_ptr, chunk_name, (png_uint_32)length);
- png_write_chunk_data(png_ptr, data, length);
- png_write_chunk_end(png_ptr);
-}
-
-/* Write the start of a PNG chunk. The type is the chunk type.
- * The total_length is the sum of the lengths of all the data you will be
- * passing in png_write_chunk_data().
- */
-void
-png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name,
- png_uint_32 length)
-{
- png_byte buf[4];
- png_debug2(0, "Writing %s chunk (%d bytes)\n", chunk_name, length);
-
- /* write the length */
- png_save_uint_32(buf, length);
- png_write_data(png_ptr, buf, (png_size_t)4);
-
- /* write the chunk name */
- png_write_data(png_ptr, chunk_name, (png_size_t)4);
- /* reset the crc and run it over the chunk name */
- png_reset_crc(png_ptr);
- png_calculate_crc(png_ptr, chunk_name, (png_size_t)4);
-}
-
-/* Write the data of a PNG chunk started with png_write_chunk_start().
- * Note that multiple calls to this function are allowed, and that the
- * 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_structp png_ptr, png_bytep data, png_size_t length)
-{
- /* write the data, and run the CRC over it */
- if (data != NULL && length > 0)
- {
- png_calculate_crc(png_ptr, data, length);
- png_write_data(png_ptr, data, length);
- }
-}
-
-/* Finish a chunk started with png_write_chunk_start(). */
-void
-png_write_chunk_end(png_structp png_ptr)
-{
- png_byte buf[4];
-
- /* write the crc */
- png_save_uint_32(buf, png_ptr->crc);
-
- png_write_data(png_ptr, buf, (png_size_t)4);
-}
-
-/* Simple function to write the signature. If we have already written
- * the magic bytes of the signature, or more likely, the PNG stream is
- * being embedded into another stream and doesn't need its own signature,
- * we should call png_set_sig_bytes() to tell libpng how many of the
- * bytes have already been written.
- */
-void
-png_write_sig(png_structp png_ptr)
-{
- /* write the rest of the 8 byte signature */
- png_write_data(png_ptr, &png_sig[png_ptr->sig_bytes],
- (png_size_t)8 - png_ptr->sig_bytes);
-}
-
-/* Write the IHDR chunk, and update the png_struct with the necessary
- * information. Note that the rest of this code depends upon this
- * information being correct.
- */
-void
-png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
- int bit_depth, int color_type, int compression_type, int filter_type,
- int interlace_type)
-{
- png_byte buf[13]; /* buffer to store the IHDR info */
-
- png_debug(1, "in png_write_IHDR\n");
- /* Check that we have valid input data from the application info */
- switch (color_type)
- {
- case PNG_COLOR_TYPE_GRAY:
- switch (bit_depth)
- {
- case 1:
- case 2:
- case 4:
- case 8:
- case 16: png_ptr->channels = 1; break;
- default: png_error(png_ptr,"Invalid bit depth for grayscale image");
- }
- break;
- case PNG_COLOR_TYPE_RGB:
- if (bit_depth != 8 && bit_depth != 16)
- png_error(png_ptr, "Invalid bit depth for RGB image");
- png_ptr->channels = 3;
- break;
- case PNG_COLOR_TYPE_PALETTE:
- switch (bit_depth)
- {
- case 1:
- case 2:
- case 4:
- case 8: png_ptr->channels = 1; break;
- default: png_error(png_ptr, "Invalid bit depth for paletted image");
- }
- break;
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- if (bit_depth != 8 && bit_depth != 16)
- png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
- png_ptr->channels = 2;
- break;
- case PNG_COLOR_TYPE_RGB_ALPHA:
- if (bit_depth != 8 && bit_depth != 16)
- png_error(png_ptr, "Invalid bit depth for RGBA image");
- png_ptr->channels = 4;
- break;
- default:
- png_error(png_ptr, "Invalid image color type specified");
- }
-
- if (compression_type != PNG_COMPRESSION_TYPE_BASE)
- {
- png_warning(png_ptr, "Invalid compression type specified");
- compression_type = PNG_COMPRESSION_TYPE_BASE;
- }
-
- if (filter_type != PNG_FILTER_TYPE_BASE)
- {
- png_warning(png_ptr, "Invalid filter type specified");
- filter_type = PNG_FILTER_TYPE_BASE;
- }
-
-#ifdef PNG_WRITE_INTERLACING_SUPPORTED
- if (interlace_type != PNG_INTERLACE_NONE &&
- interlace_type != PNG_INTERLACE_ADAM7)
- {
- png_warning(png_ptr, "Invalid interlace type specified");
- interlace_type = PNG_INTERLACE_ADAM7;
- }
-#else
- interlace_type=PNG_INTERLACE_NONE;
-#endif
-
- /* save off the relevent information */
- png_ptr->bit_depth = (png_byte)bit_depth;
- png_ptr->color_type = (png_byte)color_type;
- png_ptr->interlaced = (png_byte)interlace_type;
- png_ptr->width = width;
- png_ptr->height = height;
-
- png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
- png_ptr->rowbytes = ((width * (png_size_t)png_ptr->pixel_depth + 7) >> 3);
- /* set the usr info, so any transformations can modify it */
- png_ptr->usr_width = png_ptr->width;
- png_ptr->usr_bit_depth = png_ptr->bit_depth;
- png_ptr->usr_channels = png_ptr->channels;
-
- /* pack the header information into the buffer */
- png_save_uint_32(buf, width);
- png_save_uint_32(buf + 4, height);
- buf[8] = (png_byte)bit_depth;
- buf[9] = (png_byte)color_type;
- buf[10] = (png_byte)compression_type;
- buf[11] = (png_byte)filter_type;
- buf[12] = (png_byte)interlace_type;
-
- /* write the chunk */
- png_write_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);
-
- /* initialize zlib with PNG info */
- png_ptr->zstream.zalloc = png_zalloc;
- png_ptr->zstream.zfree = png_zfree;
- png_ptr->zstream.opaque = (voidpf)png_ptr;
- if (!(png_ptr->do_filter))
- {
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
- png_ptr->bit_depth < 8)
- png_ptr->do_filter = PNG_FILTER_NONE;
- else
- png_ptr->do_filter = PNG_ALL_FILTERS;
- }
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY))
- {
- if (png_ptr->do_filter != PNG_FILTER_NONE)
- png_ptr->zlib_strategy = Z_FILTERED;
- else
- png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY;
- }
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL))
- png_ptr->zlib_level = Z_DEFAULT_COMPRESSION;
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL))
- png_ptr->zlib_mem_level = 8;
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS))
- png_ptr->zlib_window_bits = 15;
- if (!(png_ptr->flags & PNG_FLAG_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;
-
- png_ptr->mode = PNG_HAVE_IHDR;
-}
-
-/* write the palette. We are careful not to trust png_color to be in the
- * correct order for PNG, so people can redefine it to any convenient
- * structure.
- */
-void
-png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal)
-{
- png_uint_32 i;
- png_colorp pal_ptr;
- png_byte buf[3];
-
- png_debug(1, "in png_write_PLTE\n");
- if (num_pal == 0 || num_pal > 256)
- {
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_error(png_ptr, "Invalid number of colors in palette");
- }
- else
- {
- png_warning(png_ptr, "Invalid number of colors in palette");
- return;
- }
- }
-
- png_ptr->num_palette = (png_uint_16)num_pal;
- png_debug1(3, "num_palette = %d\n", png_ptr->num_palette);
-
- png_write_chunk_start(png_ptr, png_PLTE, num_pal * 3);
- for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
- {
- buf[0] = pal_ptr->red;
- buf[1] = pal_ptr->green;
- buf[2] = pal_ptr->blue;
- png_write_chunk_data(png_ptr, buf, (png_size_t)3);
- }
- png_write_chunk_end(png_ptr);
- png_ptr->mode |= PNG_HAVE_PLTE;
-}
-
-/* write an IDAT chunk */
-void
-png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
-{
- png_debug(1, "in png_write_IDAT\n");
- png_write_chunk(png_ptr, png_IDAT, data, length);
- png_ptr->mode |= PNG_HAVE_IDAT;
-}
-
-/* write an IEND chunk */
-void
-png_write_IEND(png_structp png_ptr)
-{
- png_debug(1, "in png_write_IEND\n");
- png_write_chunk(png_ptr, png_IEND, NULL, (png_size_t)0);
- png_ptr->mode |= PNG_HAVE_IEND;
-}
-
-#if defined(PNG_WRITE_gAMA_SUPPORTED)
-/* write a gAMA chunk */
-void
-png_write_gAMA(png_structp png_ptr, double file_gamma)
-{
- png_uint_32 igamma;
- png_byte buf[4];
-
- png_debug(1, "in png_write_gAMA\n");
- /* file_gamma is saved in 1/1000000ths */
- igamma = (png_uint_32)(file_gamma * 100000.0 + 0.5);
- png_save_uint_32(buf, igamma);
- png_write_chunk(png_ptr, png_gAMA, buf, (png_size_t)4);
-}
-#endif
-
-#if defined(PNG_WRITE_sRGB_SUPPORTED)
-/* write a sRGB chunk */
-void
-png_write_sRGB(png_structp png_ptr, int srgb_intent)
-{
- png_byte buf[1];
-
- png_debug(1, "in png_write_sRGB\n");
- if(srgb_intent >= PNG_sRGB_INTENT_LAST)
- png_warning(png_ptr,
- "Invalid sRGB rendering intent specified");
- buf[0]=(png_byte)srgb_intent;
- png_write_chunk(png_ptr, png_sRGB, buf, (png_size_t)1);
-}
-#endif
-
-#if defined(PNG_WRITE_sBIT_SUPPORTED)
-/* write the sBIT chunk */
-void
-png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type)
-{
- png_byte buf[4];
- png_size_t size;
-
- png_debug(1, "in png_write_sBIT\n");
- /* make sure we don't depend upon the order of PNG_COLOR_8 */
- if (color_type & PNG_COLOR_MASK_COLOR)
- {
- png_byte maxbits;
-
- maxbits = color_type==PNG_COLOR_TYPE_PALETTE ? 8 : png_ptr->usr_bit_depth;
- if (sbit->red == 0 || sbit->red > maxbits ||
- sbit->green == 0 || sbit->green > maxbits ||
- sbit->blue == 0 || sbit->blue > maxbits)
- {
- png_warning(png_ptr, "Invalid sBIT depth specified");
- return;
- }
- buf[0] = sbit->red;
- buf[1] = sbit->green;
- buf[2] = sbit->blue;
- size = 3;
- }
- else
- {
- if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)
- {
- png_warning(png_ptr, "Invalid sBIT depth specified");
- return;
- }
- buf[0] = sbit->gray;
- size = 1;
- }
-
- if (color_type & PNG_COLOR_MASK_ALPHA)
- {
- if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
- {
- png_warning(png_ptr, "Invalid sBIT depth specified");
- return;
- }
- buf[size++] = sbit->alpha;
- }
-
- png_write_chunk(png_ptr, png_sBIT, buf, size);
-}
-#endif
-
-#if defined(PNG_WRITE_cHRM_SUPPORTED)
-/* write the cHRM chunk */
-void
-png_write_cHRM(png_structp png_ptr, double white_x, double white_y,
- double red_x, double red_y, double green_x, double green_y,
- double blue_x, double blue_y)
-{
- png_uint_32 itemp;
- png_byte buf[32];
-
- png_debug(1, "in png_write_cHRM\n");
- /* each value is saved int 1/1000000ths */
- if (white_x < 0 || white_x > 0.8 || white_y < 0 || white_y > 0.8 ||
- white_x + white_y > 1.0)
- {
- png_warning(png_ptr, "Invalid cHRM white point specified");
- return;
- }
- itemp = (png_uint_32)(white_x * 100000.0 + 0.5);
- png_save_uint_32(buf, itemp);
- itemp = (png_uint_32)(white_y * 100000.0 + 0.5);
- png_save_uint_32(buf + 4, itemp);
-
- if (red_x < 0 || red_x > 0.8 || red_y < 0 || red_y > 0.8 ||
- red_x + red_y > 1.0)
- {
- png_warning(png_ptr, "Invalid cHRM red point specified");
- return;
- }
- itemp = (png_uint_32)(red_x * 100000.0 + 0.5);
- png_save_uint_32(buf + 8, itemp);
- itemp = (png_uint_32)(red_y * 100000.0 + 0.5);
- png_save_uint_32(buf + 12, itemp);
-
- if (green_x < 0 || green_x > 0.8 || green_y < 0 || green_y > 0.8 ||
- green_x + green_y > 1.0)
- {
- png_warning(png_ptr, "Invalid cHRM green point specified");
- return;
- }
- itemp = (png_uint_32)(green_x * 100000.0 + 0.5);
- png_save_uint_32(buf + 16, itemp);
- itemp = (png_uint_32)(green_y * 100000.0 + 0.5);
- png_save_uint_32(buf + 20, itemp);
-
- if (blue_x < 0 || blue_x > 0.8 || blue_y < 0 || blue_y > 0.8 ||
- blue_x + blue_y > 1.0)
- {
- png_warning(png_ptr, "Invalid cHRM blue point specified");
- return;
- }
- itemp = (png_uint_32)(blue_x * 100000.0 + 0.5);
- png_save_uint_32(buf + 24, itemp);
- itemp = (png_uint_32)(blue_y * 100000.0 + 0.5);
- png_save_uint_32(buf + 28, itemp);
-
- png_write_chunk(png_ptr, png_cHRM, buf, (png_size_t)32);
-}
-#endif
-
-#if defined(PNG_WRITE_tRNS_SUPPORTED)
-/* write the tRNS chunk */
-void
-png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran,
- int num_trans, int color_type)
-{
- png_byte buf[6];
-
- png_debug(1, "in png_write_tRNS\n");
- if (color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)
- {
- png_warning(png_ptr,"Invalid number of transparent colors specified");
- return;
- }
- /* write the chunk out as it is */
- png_write_chunk(png_ptr, png_tRNS, trans, (png_size_t)num_trans);
- }
- else if (color_type == PNG_COLOR_TYPE_GRAY)
- {
- /* one 16 bit value */
- png_save_uint_16(buf, tran->gray);
- png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)2);
- }
- else if (color_type == PNG_COLOR_TYPE_RGB)
- {
- /* three 16 bit values */
- png_save_uint_16(buf, tran->red);
- png_save_uint_16(buf + 2, tran->green);
- png_save_uint_16(buf + 4, tran->blue);
- png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)6);
- }
- else
- {
- png_warning(png_ptr, "Can't write tRNS with an alpha channel");
- }
-}
-#endif
-
-#if defined(PNG_WRITE_bKGD_SUPPORTED)
-/* write the background chunk */
-void
-png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type)
-{
- png_byte buf[6];
-
- png_debug(1, "in png_write_bKGD\n");
- if (color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (back->index > png_ptr->num_palette)
- {
- png_warning(png_ptr, "Invalid background palette index");
- return;
- }
- buf[0] = back->index;
- png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)1);
- }
- else if (color_type & PNG_COLOR_MASK_COLOR)
- {
- png_save_uint_16(buf, back->red);
- png_save_uint_16(buf + 2, back->green);
- png_save_uint_16(buf + 4, back->blue);
- png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)6);
- }
- else
- {
- png_save_uint_16(buf, back->gray);
- png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)2);
- }
-}
-#endif
-
-#if defined(PNG_WRITE_hIST_SUPPORTED)
-/* write the histogram */
-void
-png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist)
-{
- int i;
- png_byte buf[3];
-
- png_debug(1, "in png_write_hIST\n");
- if (num_hist > (int)png_ptr->num_palette)
- {
- png_debug2(3, "num_hist = %d, num_palette = %d\n", num_hist,
- png_ptr->num_palette);
- png_warning(png_ptr, "Invalid number of histogram entries specified");
- return;
- }
-
- png_write_chunk_start(png_ptr, png_hIST, (png_uint_32)(num_hist * 2));
- for (i = 0; i < num_hist; i++)
- {
- png_save_uint_16(buf, hist[i]);
- png_write_chunk_data(png_ptr, buf, (png_size_t)2);
- }
- png_write_chunk_end(png_ptr);
-}
-#endif
-
-#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) || \
- defined(PNG_WRITE_pCAL_SUPPORTED)
-/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
- * and if invalid, correct the keyword rather than discarding the entire
- * chunk. The PNG 1.0 specification requires keywords 1-79 characters in
- * length, forbids leading or trailing whitespace, multiple internal spaces,
- * and the non-break space (0x80) from ISO 8859-1. Returns keyword length.
- *
- * The new_key is allocated to hold the corrected keyword and must be freed
- * by the calling routine. This avoids problems with trying to write to
- * static keywords without having to have duplicate copies of the strings.
- */
-png_size_t
-png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key)
-{
- png_size_t key_len;
- png_charp kp, dp;
- int kflag;
-
- png_debug(1, "in png_check_keyword\n");
- *new_key = NULL;
-
- if (key == NULL || (key_len = png_strlen(key)) == 0)
- {
- png_chunk_warning(png_ptr, "zero length keyword");
- return ((png_size_t)0);
- }
-
- png_debug1(2, "Keyword to be checked is '%s'\n", key);
-
- *new_key = (png_charp)png_malloc(png_ptr, (png_uint_32)(key_len + 1));
-
- /* Replace non-printing characters with a blank and print a warning */
- for (kp = key, dp = *new_key; *kp != '\0'; kp++, dp++)
- {
- if (*kp < 0x20 || (*kp > 0x7E && (png_byte)*kp < 0xA1))
- {
-#if !defined(PNG_NO_STDIO)
- char msg[40];
-
- sprintf(msg, "invalid keyword character 0x%02X", *kp);
- png_chunk_warning(png_ptr, msg);
-#else
- png_chunk_warning(png_ptr, "invalid character in keyword");
-#endif
- *dp = ' ';
- }
- else
- {
- *dp = *kp;
- }
- }
- *dp = '\0';
-
- /* Remove any trailing white space. */
- kp = *new_key + key_len - 1;
- if (*kp == ' ')
- {
- png_chunk_warning(png_ptr, "trailing spaces removed from keyword");
-
- while (*kp == ' ')
- {
- *(kp--) = '\0';
- key_len--;
- }
- }
-
- /* Remove any leading white space. */
- kp = *new_key;
- if (*kp == ' ')
- {
- png_chunk_warning(png_ptr, "leading spaces removed from keyword");
-
- while (*kp == ' ')
- {
- kp++;
- key_len--;
- }
- }
-
- png_debug1(2, "Checking for multiple internal spaces in '%s'\n", kp);
-
- /* Remove multiple internal spaces. */
- for (kflag = 0, dp = *new_key; *kp != '\0'; kp++)
- {
- if (*kp == ' ' && kflag == 0)
- {
- *(dp++) = *kp;
- kflag = 1;
- }
- else if (*kp == ' ')
- {
- key_len--;
- }
- else
- {
- *(dp++) = *kp;
- kflag = 0;
- }
- }
- *dp = '\0';
-
- if (key_len == 0)
- {
- png_chunk_warning(png_ptr, "zero length keyword");
- }
-
- if (key_len > 79)
- {
- png_chunk_warning(png_ptr, "keyword length must be 1 - 79 characters");
- new_key[79] = '\0';
- key_len = 79;
- }
-
- return (key_len);
-}
-#endif
-
-#if defined(PNG_WRITE_tEXt_SUPPORTED)
-/* write a tEXt chunk */
-void
-png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text,
- png_size_t text_len)
-{
- png_size_t key_len;
- png_charp new_key;
-
- png_debug(1, "in png_write_tEXt\n");
- if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
- {
- png_warning(png_ptr, "Empty keyword in tEXt chunk");
- return;
- }
-
- if (text == NULL || *text == '\0')
- text_len = 0;
-
- /* make sure we include the 0 after the key */
- png_write_chunk_start(png_ptr, png_tEXt, (png_uint_32)key_len+text_len+1);
- png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1);
- if (text_len)
- png_write_chunk_data(png_ptr, (png_bytep)text, text_len);
-
- png_write_chunk_end(png_ptr);
- png_free(png_ptr, new_key);
-}
-#endif
-
-#if defined(PNG_WRITE_zTXt_SUPPORTED)
-/* write a compressed text chunk */
-void
-png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text,
- png_size_t text_len, int compression)
-{
- png_size_t key_len;
- char buf[1];
- png_charp new_key;
- int i, ret;
- png_charpp output_ptr = NULL; /* array of pointers to output */
- int num_output_ptr = 0; /* number of output pointers used */
- int max_output_ptr = 0; /* size of output_ptr */
-
- png_debug(1, "in png_write_zTXt\n");
-
- if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
- {
- png_warning(png_ptr, "Empty keyword in zTXt chunk");
- return;
- }
-
- if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE)
- {
- png_write_tEXt(png_ptr, new_key, text, (png_size_t)0);
- png_free(png_ptr, new_key);
- return;
- }
-
- png_free(png_ptr, new_key);
-
- if (compression >= PNG_TEXT_COMPRESSION_LAST)
- {
-#if !defined(PNG_NO_STDIO)
- char msg[50];
- sprintf(msg, "Unknown zTXt compression type %d", compression);
- png_warning(png_ptr, msg);
-#else
- png_warning(png_ptr, "Unknown zTXt compression type");
-#endif
- compression = PNG_TEXT_COMPRESSION_zTXt;
- }
-
- /* We can't write the chunk until we find out how much data we have,
- * which means we need to run the compressor first and save the
- * output. This shouldn't be a problem, as the vast majority of
- * comments should be reasonable, but we will set up an array of
- * malloc'd pointers to be sure.
- *
- * If we knew the application was well behaved, we could simplify this
- * greatly by assuming we can always malloc an output buffer large
- * enough to hold the compressed text ((1001 * text_len / 1000) + 12)
- * and malloc this directly. The only time this would be a bad idea is
- * if we can't malloc more than 64K and we have 64K of random input
- * data, or if the input string is incredibly large (although this
- * wouldn't cause a failure, just a slowdown due to swapping).
- */
-
- /* set up the compression buffers */
- png_ptr->zstream.avail_in = (uInt)text_len;
- png_ptr->zstream.next_in = (Bytef *)text;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf;
-
- /* this is the same compression loop as in png_write_row() */
- do
- {
- /* compress the data */
- ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
- if (ret != Z_OK)
- {
- /* error */
- if (png_ptr->zstream.msg != NULL)
- png_error(png_ptr, png_ptr->zstream.msg);
- else
- png_error(png_ptr, "zlib error");
- }
- /* check to see if we need more room */
- if (!png_ptr->zstream.avail_out && png_ptr->zstream.avail_in)
- {
- /* make sure the output array has room */
- if (num_output_ptr >= max_output_ptr)
- {
- int old_max;
-
- old_max = max_output_ptr;
- max_output_ptr = num_output_ptr + 4;
- if (output_ptr != NULL)
- {
- png_charpp old_ptr;
-
- old_ptr = output_ptr;
- output_ptr = (png_charpp)png_malloc(png_ptr,
- (png_uint_32)(max_output_ptr * sizeof (png_charpp)));
- png_memcpy(output_ptr, old_ptr, old_max * sizeof (png_charp));
- png_free(png_ptr, old_ptr);
- }
- else
- output_ptr = (png_charpp)png_malloc(png_ptr,
- (png_uint_32)(max_output_ptr * sizeof (png_charp)));
- }
-
- /* save the data */
- output_ptr[num_output_ptr] = (png_charp)png_malloc(png_ptr,
- (png_uint_32)png_ptr->zbuf_size);
- png_memcpy(output_ptr[num_output_ptr], png_ptr->zbuf,
- png_ptr->zbuf_size);
- num_output_ptr++;
-
- /* and reset the buffer */
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- png_ptr->zstream.next_out = png_ptr->zbuf;
- }
- /* continue until we don't have any more to compress */
- } while (png_ptr->zstream.avail_in);
-
- /* finish the compression */
- do
- {
- /* tell zlib we are finished */
- ret = deflate(&png_ptr->zstream, Z_FINISH);
- if (ret != Z_OK && ret != Z_STREAM_END)
- {
- /* we got an error */
- if (png_ptr->zstream.msg != NULL)
- png_error(png_ptr, png_ptr->zstream.msg);
- else
- png_error(png_ptr, "zlib error");
- }
-
- /* check to see if we need more room */
- if (!(png_ptr->zstream.avail_out) && ret == Z_OK)
- {
- /* check to make sure our output array has room */
- if (num_output_ptr >= max_output_ptr)
- {
- int old_max;
-
- old_max = max_output_ptr;
- max_output_ptr = num_output_ptr + 4;
- if (output_ptr != NULL)
- {
- png_charpp old_ptr;
-
- old_ptr = output_ptr;
- /* This could be optimized to realloc() */
- output_ptr = (png_charpp)png_malloc(png_ptr,
- (png_uint_32)(max_output_ptr * sizeof (png_charpp)));
- png_memcpy(output_ptr, old_ptr, old_max * sizeof (png_charp));
- png_free(png_ptr, old_ptr);
- }
- else
- output_ptr = (png_charpp)png_malloc(png_ptr,
- (png_uint_32)(max_output_ptr * sizeof (png_charp)));
- }
-
- /* save off the data */
- output_ptr[num_output_ptr] = (png_charp)png_malloc(png_ptr,
- (png_uint_32)png_ptr->zbuf_size);
- png_memcpy(output_ptr[num_output_ptr], png_ptr->zbuf,
- png_ptr->zbuf_size);
- num_output_ptr++;
-
- /* and reset the buffer pointers */
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- png_ptr->zstream.next_out = png_ptr->zbuf;
- }
- } while (ret != Z_STREAM_END);
-
- /* text length is number of buffers plus last buffer */
- text_len = png_ptr->zbuf_size * num_output_ptr;
- if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
- text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out;
-
- /* write start of chunk */
- 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_bytep)key, key_len + 1);
- buf[0] = (png_byte)compression;
- /* write compression */
- png_write_chunk_data(png_ptr, (png_bytep)buf, (png_size_t)1);
-
- /* write saved output buffers, if any */
- for (i = 0; i < num_output_ptr; i++)
- {
- png_write_chunk_data(png_ptr,(png_bytep)output_ptr[i],png_ptr->zbuf_size);
- png_free(png_ptr, output_ptr[i]);
- }
- if (max_output_ptr != 0)
- png_free(png_ptr, output_ptr);
- /* write anything left in zbuf */
- if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)
- png_write_chunk_data(png_ptr, png_ptr->zbuf,
- png_ptr->zbuf_size - png_ptr->zstream.avail_out);
- /* close the chunk */
- png_write_chunk_end(png_ptr);
-
- /* reset zlib for another zTXt or the image data */
- deflateReset(&png_ptr->zstream);
-}
-#endif
-
-
-#if defined(PNG_WRITE_oFFs_SUPPORTED)
-/* write the oFFs chunk */
-void
-png_write_oFFs(png_structp png_ptr, png_uint_32 x_offset,
- png_uint_32 y_offset,
- int unit_type)
-{
- png_byte buf[9];
-
- png_debug(1, "in png_write_oFFs\n");
- if (unit_type >= PNG_OFFSET_LAST)
- png_warning(png_ptr, "Unrecognized unit type for oFFs chunk");
-
- png_save_uint_32(buf, x_offset);
- png_save_uint_32(buf + 4, y_offset);
- buf[8] = (png_byte)unit_type;
-
- png_write_chunk(png_ptr, png_oFFs, buf, (png_size_t)9);
-}
-#endif
-
-#if defined(PNG_WRITE_pCAL_SUPPORTED)
-/* write the pCAL chunk (png-scivis-19970203) */
-void
-png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
- png_int_32 X1, int type, int nparams, png_charp units, png_charpp params)
-{
- png_size_t purpose_len, units_len, total_len;
- png_uint_32p params_len;
- png_byte buf[10];
- png_charp new_purpose;
- int i;
-
- png_debug1(1, "in png_write_pCAL (%d parameters)\n", nparams);
- if (type >= PNG_EQUATION_LAST)
- png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
-
- purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1;
- png_debug1(3, "pCAL purpose length = %d\n", purpose_len);
- units_len = png_strlen(units) + (nparams == 0 ? 0 : 1);
- png_debug1(3, "pCAL units length = %d\n", units_len);
- total_len = purpose_len + units_len + 10;
-
- params_len = (png_uint_32p)png_malloc(png_ptr, (png_uint_32)(nparams
- *sizeof(png_uint_32)));
-
- /* Find the length of each parameter, making sure we don't count the
- null terminator for the last parameter. */
- for (i = 0; i < nparams; i++)
- {
- params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
- png_debug2(3, "pCAL parameter %d length = %d\n", i, params_len[i]);
- total_len += (png_size_t)params_len[i];
- }
-
- png_debug1(3, "pCAL total length = %d\n", total_len);
- png_write_chunk_start(png_ptr, png_pCAL, (png_uint_32)total_len);
- png_write_chunk_data(png_ptr, (png_bytep)new_purpose, purpose_len);
- png_save_int_32(buf, X0);
- png_save_int_32(buf + 4, X1);
- buf[8] = (png_byte)type;
- buf[9] = (png_byte)nparams;
- png_write_chunk_data(png_ptr, buf, (png_size_t)10);
- png_write_chunk_data(png_ptr, (png_bytep)units, (png_size_t)units_len);
-
- png_free(png_ptr, new_purpose);
-
- for (i = 0; i < nparams; i++)
- {
- png_write_chunk_data(png_ptr, (png_bytep)params[i],
- (png_size_t)params_len[i]);
- }
-
- png_free(png_ptr, params_len);
- png_write_chunk_end(png_ptr);
-}
-#endif
-
-#if defined(PNG_WRITE_pHYs_SUPPORTED)
-/* write the pHYs chunk */
-void
-png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
- png_uint_32 y_pixels_per_unit,
- int unit_type)
-{
- png_byte buf[9];
-
- png_debug(1, "in png_write_pHYs\n");
- if (unit_type >= PNG_RESOLUTION_LAST)
- png_warning(png_ptr, "Unrecognized unit type for pHYs chunk");
-
- png_save_uint_32(buf, x_pixels_per_unit);
- png_save_uint_32(buf + 4, y_pixels_per_unit);
- buf[8] = (png_byte)unit_type;
-
- png_write_chunk(png_ptr, png_pHYs, buf, (png_size_t)9);
-}
-#endif
-
-#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_structp png_ptr, png_timep mod_time)
-{
- png_byte buf[7];
-
- png_debug(1, "in png_write_tIME\n");
- if (mod_time->month > 12 || mod_time->month < 1 ||
- mod_time->day > 31 || mod_time->day < 1 ||
- mod_time->hour > 23 || mod_time->second > 60)
- {
- png_warning(png_ptr, "Invalid time specified for tIME chunk");
- return;
- }
-
- png_save_uint_16(buf, mod_time->year);
- buf[2] = mod_time->month;
- buf[3] = mod_time->day;
- buf[4] = mod_time->hour;
- buf[5] = mod_time->minute;
- buf[6] = mod_time->second;
-
- png_write_chunk(png_ptr, png_tIME, buf, (png_size_t)7);
-}
-#endif
-
-/* initializes the row writing capability of libpng */
-void
-png_write_start_row(png_structp png_ptr)
-{
- png_size_t buf_size;
-
- png_debug(1, "in png_write_start_row\n");
- buf_size = (png_size_t)(((png_ptr->width * png_ptr->usr_channels *
- png_ptr->usr_bit_depth + 7) >> 3) + 1);
-
- /* set up row buffer */
- png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size);
- png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
-
- /* set up filtering buffer, if using this filter */
- if (png_ptr->do_filter & PNG_FILTER_SUB)
- {
- png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
- }
-
- /* We only need to keep the previous row if we are using one of these. */
- if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH))
- {
- /* set up previous row buffer */
- png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size);
- png_memset(png_ptr->prev_row, 0, buf_size);
-
- if (png_ptr->do_filter & PNG_FILTER_UP)
- {
- png_ptr->up_row = (png_bytep )png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
- }
-
- if (png_ptr->do_filter & PNG_FILTER_AVG)
- {
- png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
- }
-
- if (png_ptr->do_filter & PNG_FILTER_PAETH)
- {
- png_ptr->paeth_row = (png_bytep )png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
- }
- }
-
-#ifdef PNG_WRITE_INTERLACING_SUPPORTED
- /* if interlaced, we need to set up width and height of pass */
- if (png_ptr->interlaced)
- {
- if (!(png_ptr->transformations & PNG_INTERLACE))
- {
- png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
- png_pass_ystart[0]) / png_pass_yinc[0];
- png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 -
- png_pass_start[0]) / png_pass_inc[0];
- }
- else
- {
- png_ptr->num_rows = png_ptr->height;
- png_ptr->usr_width = png_ptr->width;
- }
- }
- else
-#endif
- {
- png_ptr->num_rows = png_ptr->height;
- png_ptr->usr_width = png_ptr->width;
- }
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- png_ptr->zstream.next_out = png_ptr->zbuf;
-}
-
-/* Internal use only. Called when finished processing a row of data. */
-void
-png_write_finish_row(png_structp png_ptr)
-{
- int ret;
-
- png_debug(1, "in png_write_finish_row\n");
- /* next row */
- png_ptr->row_number++;
-
- /* see if we are done */
- if (png_ptr->row_number < png_ptr->num_rows)
- return;
-
-#ifdef PNG_WRITE_INTERLACING_SUPPORTED
- /* if interlaced, go to next pass */
- if (png_ptr->interlaced)
- {
- png_ptr->row_number = 0;
- if (png_ptr->transformations & PNG_INTERLACE)
- {
- png_ptr->pass++;
- }
- else
- {
- /* loop until we find a non-zero width or height pass */
- do
- {
- png_ptr->pass++;
- if (png_ptr->pass >= 7)
- break;
- png_ptr->usr_width = (png_ptr->width +
- png_pass_inc[png_ptr->pass] - 1 -
- png_pass_start[png_ptr->pass]) /
- png_pass_inc[png_ptr->pass];
- png_ptr->num_rows = (png_ptr->height +
- png_pass_yinc[png_ptr->pass] - 1 -
- png_pass_ystart[png_ptr->pass]) /
- png_pass_yinc[png_ptr->pass];
- if (png_ptr->transformations & PNG_INTERLACE)
- break;
- } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);
-
- }
-
- /* reset the row above the image for the next pass */
- if (png_ptr->pass < 7)
- {
- if (png_ptr->prev_row != NULL)
- png_memset(png_ptr->prev_row, 0,
- (png_size_t) (((png_uint_32)png_ptr->usr_channels *
- (png_uint_32)png_ptr->usr_bit_depth *
- png_ptr->width + 7) >> 3) + 1);
- return;
- }
- }
-#endif
-
- /* if we get here, we've just written the last row, so we need
- to flush the compressor */
- do
- {
- /* tell the compressor we are done */
- ret = deflate(&png_ptr->zstream, Z_FINISH);
- /* check for an error */
- if (ret != Z_OK && ret != Z_STREAM_END)
- {
- if (png_ptr->zstream.msg != NULL)
- png_error(png_ptr, png_ptr->zstream.msg);
- else
- png_error(png_ptr, "zlib error");
- }
- /* check to see if we need more room */
- if (!(png_ptr->zstream.avail_out) && ret == Z_OK)
- {
- png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- }
- } while (ret != Z_STREAM_END);
-
- /* write any extra space */
- if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
- {
- png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size -
- png_ptr->zstream.avail_out);
- }
-
- 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
- * pointer and a destination pointer (sp and dp), and copy the
- * correct pixels for the pass. As the row gets compacted,
- * sp will always be >= dp, so we should never overwrite anything.
- * See the default: case for the easiest code to understand.
- */
-void
-png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
-{
- png_debug(1, "in png_do_write_interlace\n");
- /* we don't have to do anything on the last pass (6) */
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL && pass < 6)
-#else
- if (pass < 6)
-#endif
- {
- /* each pixel depth is handled separately */
- switch (row_info->pixel_depth)
- {
- case 1:
- {
- png_bytep sp;
- png_bytep dp;
- int shift;
- int d;
- int value;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- dp = row;
- d = 0;
- shift = 7;
- for (i = png_pass_start[pass]; i < row_width;
- i += png_pass_inc[pass])
- {
- sp = row + (png_size_t)(i >> 3);
- value = (int)(*sp >> (7 - (int)(i & 7))) & 0x1;
- d |= (value << shift);
-
- if (shift == 0)
- {
- shift = 7;
- *dp++ = (png_byte)d;
- d = 0;
- }
- else
- shift--;
-
- }
- if (shift != 7)
- *dp = (png_byte)d;
- break;
- }
- case 2:
- {
- png_bytep sp;
- png_bytep dp;
- int shift;
- int d;
- int value;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- dp = row;
- shift = 6;
- d = 0;
- for (i = png_pass_start[pass]; i < row_width;
- i += png_pass_inc[pass])
- {
- sp = row + (png_size_t)(i >> 2);
- value = (*sp >> ((3 - (int)(i & 3)) << 1)) & 0x3;
- d |= (value << shift);
-
- if (shift == 0)
- {
- shift = 6;
- *dp++ = (png_byte)d;
- d = 0;
- }
- else
- shift -= 2;
- }
- if (shift != 6)
- *dp = (png_byte)d;
- break;
- }
- case 4:
- {
- png_bytep sp;
- png_bytep dp;
- int shift;
- int d;
- int value;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- dp = row;
- shift = 4;
- d = 0;
- for (i = png_pass_start[pass]; i < row_width;
- i += png_pass_inc[pass])
- {
- sp = row + (png_size_t)(i >> 1);
- value = (*sp >> ((1 - (int)(i & 1)) << 2)) & 0xf;
- d |= (value << shift);
-
- if (shift == 0)
- {
- shift = 4;
- *dp++ = (png_byte)d;
- d = 0;
- }
- else
- shift -= 4;
- }
- if (shift != 4)
- *dp = (png_byte)d;
- break;
- }
- default:
- {
- png_bytep sp;
- png_bytep dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
- png_size_t pixel_bytes;
-
- /* start at the beginning */
- dp = row;
- /* find out how many bytes each pixel takes up */
- pixel_bytes = (row_info->pixel_depth >> 3);
- /* loop through the row, only looking at the pixels that
- matter */
- for (i = png_pass_start[pass]; i < row_width;
- i += png_pass_inc[pass])
- {
- /* find out where the original pixel is */
- sp = row + (png_size_t)i * pixel_bytes;
- /* move the pixel */
- if (dp != sp)
- png_memcpy(dp, sp, pixel_bytes);
- /* next pixel */
- dp += pixel_bytes;
- }
- break;
- }
- }
- /* set new row width */
- row_info->width = (row_info->width +
- png_pass_inc[pass] - 1 -
- png_pass_start[pass]) /
- png_pass_inc[pass];
- row_info->rowbytes = ((row_info->width *
- row_info->pixel_depth + 7) >> 3);
- }
-}
-#endif
-
-/* This filters the row, chooses which filter to use, if it has not already
- * been specified by the application, and then writes the row out with the
- * chosen filter.
- */
-#define PNG_MAXSUM (~((png_uint_32)0) >> 1)
-#define PNG_HISHIFT 10
-#define PNG_LOMASK ((png_uint_32)0xffffL)
-#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
-void
-png_write_find_filter(png_structp png_ptr, png_row_infop row_info)
-{
- png_bytep prev_row, best_row, row_buf;
- png_uint_32 mins, bpp;
- png_byte filter_to_do = png_ptr->do_filter;
- png_uint_32 row_bytes = row_info->rowbytes;
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- int num_p_filters = (int)png_ptr->num_prev_filters;
-#endif
-
- png_debug(1, "in png_write_find_filter\n");
- /* find out how many bytes offset each pixel is */
- bpp = (row_info->pixel_depth + 7) / 8;
-
- prev_row = png_ptr->prev_row;
- best_row = row_buf = png_ptr->row_buf;
- mins = PNG_MAXSUM;
-
- /* The prediction method we use is to find which method provides the
- * smallest value when summing the absolute values of the distances
- * from zero, using anything >= 128 as negative numbers. This is known
- * as the "minimum sum of absolute differences" heuristic. Other
- * heuristics are the "weighted minimum sum of absolute differences"
- * (experimental and can in theory improve compression), and the "zlib
- * predictive" method (not implemented yet), which does test compressions
- * of lines using different filter methods, and then chooses the
- * (series of) filter(s) that give minimum compressed data size (VERY
- * computationally expensive).
- *
- * GRR 980525: consider also
- * (1) minimum sum of absolute differences from running average (i.e.,
- * keep running sum of non-absolute differences & count of bytes)
- * [track dispersion, too? restart average if dispersion too large?]
- * (1b) minimum sum of absolute differences from sliding average, probably
- * with window size <= deflate window (usually 32K)
- * (2) minimum sum of squared differences from zero or running average
- * (i.e., ~ root-mean-square approach)
- */
-
-
- /* We don't need to test the 'no filter' case if this is the only filter
- * that has been chosen, as it doesn't actually do anything to the data.
- */
- if (filter_to_do & PNG_FILTER_NONE &&
- filter_to_do != PNG_FILTER_NONE)
- {
- png_bytep rp;
- png_uint_32 sum = 0;
- png_uint_32 i;
- int v;
-
- for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
- {
- v = *rp;
- sum += (v < 128) ? v : 256 - v;
- }
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- png_uint_32 sumhi, sumlo;
- int j;
- sumlo = sum & PNG_LOMASK;
- sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */
-
- /* Reduce the sum if we match any of the previous rows */
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
- {
- sumlo = (sumlo * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- sumhi = (sumhi * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- /* Factor in the cost of this filter (this is here for completeness,
- * but it makes no sense to have a "cost" for the NONE filter, as
- * it has the minimum possible computational cost - none).
- */
- sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
- PNG_COST_SHIFT;
- sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
- PNG_COST_SHIFT;
-
- if (sumhi > PNG_HIMASK)
- sum = PNG_MAXSUM;
- else
- sum = (sumhi << PNG_HISHIFT) + sumlo;
- }
-#endif
- mins = sum;
- }
-
- /* sub filter */
- if (filter_to_do == PNG_FILTER_SUB)
- /* it's the only filter so no testing is needed */
- {
- png_bytep rp, lp, dp;
- png_uint_32 i;
- for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
- i++, rp++, dp++)
- {
- *dp = *rp;
- }
- for (lp = row_buf + 1; i < row_bytes;
- i++, rp++, lp++, dp++)
- {
- *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
- }
- best_row = png_ptr->sub_row;
- }
-
- else if (filter_to_do & PNG_FILTER_SUB)
- {
- png_bytep rp, dp, lp;
- png_uint_32 sum = 0, lmins = mins;
- png_uint_32 i;
- int v;
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- /* We temporarily increase the "minimum sum" by the factor we
- * would reduce the sum of this filter, so that we can do the
- * early exit comparison without scaling the sum each time.
- */
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 lmhi, lmlo;
- lmlo = lmins & PNG_LOMASK;
- lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
- {
- lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
- PNG_COST_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
- PNG_COST_SHIFT;
-
- if (lmhi > PNG_HIMASK)
- lmins = PNG_MAXSUM;
- else
- lmins = (lmhi << PNG_HISHIFT) + lmlo;
- }
-#endif
-
- for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
- i++, rp++, dp++)
- {
- v = *dp = *rp;
-
- sum += (v < 128) ? v : 256 - v;
- }
- for (lp = row_buf + 1; i < row_info->rowbytes;
- i++, rp++, lp++, dp++)
- {
- v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
-
- if (sum > lmins) /* We are already worse, don't continue. */
- break;
- }
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 sumhi, sumlo;
- sumlo = sum & PNG_LOMASK;
- sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
- {
- sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
- PNG_COST_SHIFT;
- sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
- PNG_COST_SHIFT;
-
- if (sumhi > PNG_HIMASK)
- sum = PNG_MAXSUM;
- else
- sum = (sumhi << PNG_HISHIFT) + sumlo;
- }
-#endif
-
- if (sum < mins)
- {
- mins = sum;
- best_row = png_ptr->sub_row;
- }
- }
-
- /* up filter */
- if (filter_to_do == PNG_FILTER_UP)
- {
- png_bytep rp, dp, pp;
- png_uint_32 i;
-
- for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
- pp = prev_row + 1; i < row_bytes;
- i++, rp++, pp++, dp++)
- {
- *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
- }
- best_row = png_ptr->up_row;
- }
-
- else if (filter_to_do & PNG_FILTER_UP)
- {
- png_bytep rp, dp, pp;
- png_uint_32 sum = 0, lmins = mins;
- png_uint_32 i;
- int v;
-
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 lmhi, lmlo;
- lmlo = lmins & PNG_LOMASK;
- lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
- {
- lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
- PNG_COST_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
- PNG_COST_SHIFT;
-
- if (lmhi > PNG_HIMASK)
- lmins = PNG_MAXSUM;
- else
- lmins = (lmhi << PNG_HISHIFT) + lmlo;
- }
-#endif
-
- for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
- pp = prev_row + 1; i < row_bytes; i++)
- {
- v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
-
- if (sum > lmins) /* We are already worse, don't continue. */
- break;
- }
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 sumhi, sumlo;
- sumlo = sum & PNG_LOMASK;
- sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
- {
- sumlo = (sumlo * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- sumhi = (sumhi * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
- PNG_COST_SHIFT;
- sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
- PNG_COST_SHIFT;
-
- if (sumhi > PNG_HIMASK)
- sum = PNG_MAXSUM;
- else
- sum = (sumhi << PNG_HISHIFT) + sumlo;
- }
-#endif
-
- if (sum < mins)
- {
- mins = sum;
- best_row = png_ptr->up_row;
- }
- }
-
- /* avg filter */
- if (filter_to_do == PNG_FILTER_AVG)
- {
- png_bytep rp, dp, pp, lp;
- png_uint_32 i;
- for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
- pp = prev_row + 1; i < bpp; i++)
- {
- *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
- }
- for (lp = row_buf + 1; i < row_bytes; i++)
- {
- *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
- & 0xff);
- }
- best_row = png_ptr->avg_row;
- }
-
- else if (filter_to_do & PNG_FILTER_AVG)
- {
- png_bytep rp, dp, pp, lp;
- png_uint_32 sum = 0, lmins = mins;
- png_uint_32 i;
- int v;
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 lmhi, lmlo;
- lmlo = lmins & PNG_LOMASK;
- lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG)
- {
- lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
- PNG_COST_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
- PNG_COST_SHIFT;
-
- if (lmhi > PNG_HIMASK)
- lmins = PNG_MAXSUM;
- else
- lmins = (lmhi << PNG_HISHIFT) + lmlo;
- }
-#endif
-
- for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
- pp = prev_row + 1; i < bpp; i++)
- {
- v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
- }
- for (lp = row_buf + 1; i < row_bytes; i++)
- {
- v = *dp++ =
- (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
-
- if (sum > lmins) /* We are already worse, don't continue. */
- break;
- }
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 sumhi, sumlo;
- sumlo = sum & PNG_LOMASK;
- sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
- {
- sumlo = (sumlo * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- sumhi = (sumhi * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
- PNG_COST_SHIFT;
- sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
- PNG_COST_SHIFT;
-
- if (sumhi > PNG_HIMASK)
- sum = PNG_MAXSUM;
- else
- sum = (sumhi << PNG_HISHIFT) + sumlo;
- }
-#endif
-
- if (sum < mins)
- {
- mins = sum;
- best_row = png_ptr->avg_row;
- }
- }
-
- /* Paeth filter */
- if (filter_to_do == PNG_FILTER_PAETH)
- {
- png_bytep rp, dp, pp, cp, lp;
- png_uint_32 i;
- for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
- pp = prev_row + 1; i < bpp; i++)
- {
- *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
- }
-
- for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
- {
- int a, b, c, pa, pb, pc, p;
-
- b = *pp++;
- c = *cp++;
- a = *lp++;
-
- p = b - c;
- pc = a - c;
-
-#ifdef PNG_USE_ABS
- pa = abs(p);
- pb = abs(pc);
- pc = abs(p + pc);
-#else
- pa = p < 0 ? -p : p;
- pb = pc < 0 ? -pc : pc;
- pc = (p + pc) < 0 ? -(p + pc) : p + pc;
-#endif
-
- p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
-
- *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
- }
- best_row = png_ptr->paeth_row;
- }
-
- else if (filter_to_do & PNG_FILTER_PAETH)
- {
- png_bytep rp, dp, pp, cp, lp;
- png_uint_32 sum = 0, lmins = mins;
- png_uint_32 i;
- int v;
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 lmhi, lmlo;
- lmlo = lmins & PNG_LOMASK;
- lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
- {
- lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
- PNG_COST_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
- PNG_COST_SHIFT;
-
- if (lmhi > PNG_HIMASK)
- lmins = PNG_MAXSUM;
- else
- lmins = (lmhi << PNG_HISHIFT) + lmlo;
- }
-#endif
-
- for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
- pp = prev_row + 1; i < bpp; i++)
- {
- v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
- }
-
- for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
- {
- int a, b, c, pa, pb, pc, p;
-
- b = *pp++;
- c = *cp++;
- a = *lp++;
-
-#ifndef PNG_SLOW_PAETH
- p = b - c;
- pc = a - c;
-#ifdef PNG_USE_ABS
- pa = abs(p);
- pb = abs(pc);
- pc = abs(p + pc);
-#else
- pa = p < 0 ? -p : p;
- pb = pc < 0 ? -pc : pc;
- pc = (p + pc) < 0 ? -(p + pc) : p + pc;
-#endif
- p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
-#else /* PNG_SLOW_PAETH */
- p = a + b - c;
- pa = abs(p - a);
- pb = abs(p - b);
- pc = abs(p - c);
- if (pa <= pb && pa <= pc)
- p = a;
- else if (pb <= pc)
- p = b;
- else
- p = c;
-#endif /* PNG_SLOW_PAETH */
-
- v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
-
- if (sum > lmins) /* We are already worse, don't continue. */
- break;
- }
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 sumhi, sumlo;
- sumlo = sum & PNG_LOMASK;
- sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
- {
- sumlo = (sumlo * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- sumhi = (sumhi * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
- PNG_COST_SHIFT;
- sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
- PNG_COST_SHIFT;
-
- if (sumhi > PNG_HIMASK)
- sum = PNG_MAXSUM;
- else
- sum = (sumhi << PNG_HISHIFT) + sumlo;
- }
-#endif
-
- if (sum < mins)
- {
- best_row = png_ptr->paeth_row;
- }
- }
-
- /* Do the actual writing of the filtered row data from the chosen filter. */
-
- png_write_filtered_row(png_ptr, best_row);
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- /* Save the type of filter we picked this time for future calculations */
- if (png_ptr->num_prev_filters > 0)
- {
- int j;
- for (j = 1; j < num_p_filters; j++)
- {
- png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1];
- }
- png_ptr->prev_filters[j] = best_row[0];
- }
-#endif
-}
-
-
-/* Do the actual writing of a previously filtered row. */
-void
-png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row)
-{
- png_debug(1, "in png_write_filtered_row\n");
- png_debug1(2, "filter = %d\n", filtered_row[0]);
- /* set up the zlib input buffer */
- png_ptr->zstream.next_in = filtered_row;
- png_ptr->zstream.avail_in = (uInt)png_ptr->row_info.rowbytes + 1;
- /* repeat until we have compressed all the data */
- do
- {
- int ret; /* return of zlib */
-
- /* compress the data */
- ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
- /* check for compression errors */
- if (ret != Z_OK)
- {
- if (png_ptr->zstream.msg != NULL)
- png_error(png_ptr, png_ptr->zstream.msg);
- else
- png_error(png_ptr, "zlib error");
- }
-
- /* see if it is time to write another IDAT */
- if (!(png_ptr->zstream.avail_out))
- {
- /* write the IDAT and reset the zlib output buffer */
- png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- }
- /* repeat until all data has been compressed */
- } while (png_ptr->zstream.avail_in);
-
- /* swap the current and previous rows */
- if (png_ptr->prev_row != NULL)
- {
- png_bytep tptr;
-
- tptr = png_ptr->prev_row;
- png_ptr->prev_row = png_ptr->row_buf;
- png_ptr->row_buf = tptr;
- }
-
- /* finish row - updates counters and flushes zlib if last row */
- png_write_finish_row(png_ptr);
-
-#if defined(PNG_WRITE_FLUSH_SUPPORTED)
- png_ptr->flush_rows++;
-
- if (png_ptr->flush_dist > 0 &&
- png_ptr->flush_rows >= png_ptr->flush_dist)
- {
- png_write_flush(png_ptr);
- }
-#endif /* PNG_WRITE_FLUSH_SUPPORTED */
-}
+++ /dev/null
-# makefile for libpng
-# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
-# For conditions of distribution and use, see copyright notice in png.h
-
-# Where the zlib library and include files are located
-#ZLIBLIB=/usr/local/lib
-#ZLIBINC=/usr/local/include
-ZLIBLIB=../zlib
-ZLIBINC=../zlib
-
-CC=cc
-
-CFLAGS=-I$(ZLIBINC) -O -fullwarn # -g -DPNG_DEBUG=1
-LDFLAGS=-L. -L$(ZLIBLIB) -lpng -lz -lm
-
-RANLIB=echo
-#RANLIB=ranlib
-
-# where make install puts libpng.a and png.h
-prefix=/usr/local
-
-OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
- pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
- pngwtran.o pngmem.o pngerror.o pngpread.o
-
-all: libpng.a pngtest
-
-libpng.a: $(OBJS)
- ar rc $@ $(OBJS)
- $(RANLIB) $@
-
-pngtest: pngtest.o libpng.a
- $(CC) -o pngtest $(CFLAGS) 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
-
-clean:
- rm -f *.o libpng.a pngtest pngout.png
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-png.o: png.h pngconf.h
-pngerror.o: png.h pngconf.h
-pngrio.o: png.h pngconf.h
-pngwio.o: png.h pngconf.h
-pngmem.o: png.h pngconf.h
-pngset.o: png.h pngconf.h
-pngget.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
-pngpread.o: png.h pngconf.h
-