Imported from pngcrush-1.6.2.tar

This commit is contained in:
Glenn Randers-Pehrson
2006-02-16 17:47:00 -06:00
parent 7c91bdf295
commit ebc4c9db72
61 changed files with 14984 additions and 8316 deletions

355
ChangeLog.txt Normal file
View File

@@ -0,0 +1,355 @@
Change log:
Version 1.6.2 (built with libpng-1.2.8 and zlib-1.2.3)
Fixed bug with "PNG_ROWBYTES" usage, introduced in version 1.6.0.
The bug could cause a crash and only affects the "nolib" builds.
Converted C++ style (// ...) comments to C style (/* ... */).
Defined TOO_FAR == 32767 in deflate.c (again). The definition was
omitted from version 1.6.0 when zlib was upgraded to version 1.2.3.
Version 1.6.1 (distributed as 1.6.0, built with libpng-1.2.8 and zlib-1.2.3)
Copied non-exported libpng functions from libpng into pngcrush, to make
pngcrush play more nicely with shared libpng. These are #ifdef'ed out
when a static library is being built with the bundled libpng and
pngcrush.h is included.
Version 1.6.0-grr (built with libpng-1.2.4 and zlib-1.1.4pc or zlib-1.2.2)
Moved ChangeLog out of pngcrush.c comments and into a separate file.
Filtered pngcrush.c through "indent -kr" and "expand" for readability.
Moved 550 lines of usage/help/copyright/license/version info to separate
function(s) and cleaned up significantly.
Added some comments for ease of navigation and readability.
Stripped out a bunch of ancient-libpng compatibility stuff.
Defined PNG_UINT_* macros (pngcrush.h for now).
Fixed unknown-chunk handling ("-rem alla" and "-rem gifx" now work).
Created modified version of makefile that supports external zlib.
Added support for methods using Z_RLE zlib strategy (zlib 1.2.x only).
Documented -huffman option in usage screen.
Added IDAT statistics to final per-file summary.
Added utime() support to give output files same timestamps as input files.
Version 1.5.10 (built with libpng-1.2.4 and zlib-1.1.4pc)
Fixed bug, introduced in 1.5.9, that caused defaults for method 0 to
be used instead of copying the original image, when the original was
already smallest.
Version 1.5.9 (built with libpng-1.2.4beta3 and zlib-1.1.4pc)
Work around CPU timer wraparound at 2G microseconds.
Upgraded zlib from 1.1.3 to 1.1.4. Pngcrush is believed not to
be vulnerable to the zlib-1.1.3 buffer-overflow bug.
Choose the first instance of smallest IDAT instead of the last,
for faster final recompression, suggested by TSamuel.
Version 1.5.8 (built with libpng-1.2.1)
Added -trns_a option for entering a tRNS array.
Version 1.5.7 (built with libpng-1.2.0)
Added setargv.obj to Makefile.msc to expand wildcards, e.g., *.png
Use constant string "pngcrush" instead of argv[0] when appropriate.
Only check stats for infile==outfile once per input file, or not at all
if "-nofilecheck" option is present or if a directory was created.
Fixed bugs with changing bit_depth of grayscale images.
Version 1.5.6 (built with libpng-1.0.12)
Eliminated extra "Removed the cHNK chunk" messages generated by version
1.5.5 when "-rem alla" or "-rem allb" is used.
All unknown chunks including safe-to-copy chunks are now removed in
response to the "-rem alla" or "-rem allb" options.
Issue a warning if the user tries "-cc" option when it is not supported.
Version 1.5.5 (built with libpng-1.0.12)
Reset reduce_to_gray and it_is_opaque flags prior to processing each
image.
Enable removal of safe-to-copy chunks that are being handled as unknown
e.g., "-rem time".
Version 1.5.4 (built with libpng-1.0.11)
Added 262 to the length of uncompressed data when calculating
required_window_size, to account for zlib/deflate implementation.
Added "-bit_depth n" to the help screen.
Call png_set_packing() when increasing bit_depth to 2 or 4.
Added warning about not overwriting an existing tRNS chunk.
Reduced the memory usage
Write 500K IDAT chunks even when system libpng is being used.
Ignore all-zero cHRM chunks, with a warning.
Version 1.5.3 (built with libpng-1.0.9beta5)
Added "-loco" option (writes MNG files with filter_method 64)
"-dir" and "-ext" options are no longer mutually exclusive, e.g.:
pngcrush -loco -dir Crushed -ext .mng *.png
Version 1.5.2 (built with libpng-1.0.9beta1)
Added "-iccp" option.
Increased the zlib memory level, which improves compression (typically
about 1.3 percent for photos) at the expense of increased memory usage.
Enabled the "-max max_idat_size" option, even when max_idat_size
exceeds the default 1/2 megabyte size.
Added missing "png_ptr" argument to png_error() call
Added "-loco" option, to enable the LOCO color transformation
(R->R-G, G, B->B-G) while writing a MNG with filter_method 64. Undo
the transformation and write the regular PNG filter_method (0) if the
MNG filter_method 64 is detected.
Revised the "-help" output slightly and improved the "-version" output.
The "-already[_crushed]" option is now ignored if the "-force" option
is present or if chunks are being added, deleted, or modified.
Improved "things_have_changed" behavior (now, when set in a particular
file, it is not set for all remaining files)
Version 1.5.1 (built with libpng-1.0.8)
Disabled color counting by default and made it controllable with new
-cc and -no_cc commandline arguments.
Added some #ifdef PNGCRUSH_COUNT_COLORS around code that needs it.
Revised count_colors() attempting to avoid stack corruption that has
been observed on RedHat 6.2
Added the word "irrevocably" to the license and changed "without fee"
to "without payment of any fee".
Version 1.5.0 (built with libpng-1.0.8)
After encountering an image with a bad Photoshop iCCP chunk, pngcrush
1.4.5 through 1.4.8 write sRGB and gAMA=45455 chunks in all
remaining PNG files on the command line. This has been fixed so the
correction is only applied to the particular bad input file.
Version 1.4.8 (built with libpng-1.0.8rc1)
Detect and remove all-opaque alpha channel.
Detect and reduce all-gray truecolor images to grayscale.
Version 1.4.7 (built with libpng-1.0.8rc1)
Restored the "-ext" option that was inadvertently overridden with
a new "-exit" option in version 1.4.6 ("-exit" is used to force an
"exit" instead of a "return" from the main program).
Version 1.4.6 (built with libpng-1.0.8rc1)
Fixed bug in color-counting of noninterlaced images.
Added capability of processing multiple rows at a time (disabled by
default because it turns out to be no faster).
Replaced "return" statements in main() with "exit" statements.
Force exit instead of return with "-exit" argument.
Added the UCITA disclaimers to the help output.
Version 1.4.5 (built with libpng-1.0.7rc2 and cexcept-1.0.0)
Added color-counting and palette-building capability (enable by
defining PNGCRUSH_COUNT_COLORS). In a future version, this will
give pngcrush the ability to reduce RGBA images to indexed-color
or grayscale when fewer than 257 RGBA combinations are present,
and no color is present that requires 16-bit precision. For now,
it only reports the frequencies.
Added "-fix" option, for fixing bad CRC's and other correctable
conditions.
Write sBIT.alpha=1 when adding an opaque alpha channel and sBIT
is present.
Identify the erroneous 2615-byte sRGB monitor profile being written
by Photoshop 5.5, which causes many apps to crash, and replace it with
an sRGB chunk.
Added a check for input and output on different devices before rejecting
the output file as being the same as the input file based on inode.
Added some UCITA language to the disclaimer.
Version 1.4.4 (built with libpng-1.0.6i and cexcept-0.6.3)
Can be built on RISC OS platforms, thanks to Darren Salt.
Version 1.4.3 (built with libpng-1.0.6h and cexcept-0.6.3)
Reduced scope of Try/Catch blocks to avoid nesting them, and
removed returns from within the Try blocks, where they are not
allowed.
Removed direct access to the png structure when possible, and isolated
the remaining direct accesses to the png structure into new
png_get_compression_buffer_size(), png_set_compression_buffer_size(),
and png_set_unknown_chunk_location() functions that were installed
in libpng version 1.0.6g.
Version 1.4.2 (built with libpng-1.0.6f and cexcept-0.6.0)
Removes extra IDAT chunks (such as found in some POV-ray PNGs) with
a warning instead of bailing out (this feature requires libpng-1.0.6f
or later, compiled with "#define PNG_ABORT()").
Removed old setjmp interface entirely.
Version 1.4.1 (built with libpng-1.0.6e and cexcept-0.6.0)
Uses cexcept.h for error handling instead of libpng's built-in
setjmp/longjmp mechanism. See http://cexcept.sf.net/
Pngcrush.c will now run when compiled with old versions of libpng back
to version 0.96, although some features will not be available.
Version 1.4.0 (built with libpng-1.0.6 + libpng-1.0.6-patch-a)
Version 1.3.6 (built with libpng-1.0.5v)
RGB to Grayscale conversion is more accurate (15-bit instead of 8-bit)
and now uses only integer arithmetic.
#ifdef'ed out PNG_READ_DITHER
Changed "Compressed" to "Uncompressed" in help for -itxt.
Stifled some compiler warnings
Version 1.3.5 (built with libpng-1.0.5s)
Add test on stat_buf.st_size to verify fpin==fpout, because stat in
MSVC++6.0 standard version returns stat_buf.st_ino=0 for all files.
Revised pngcrush.h to make it easier to control PNG_ZBUF_SIZE and
PNG_NO_FLOATING_POINT_SUPPORTED from a makefile.
Restored ability to enter "replace_gamma" value as a float even when
floating point arithmetic is not enabled.
Enabled removing tEXt, zTXt, or iTXt chunks by chunk type, i.e.,
"-rem tEXt" only removes tEXt chunks, while "-rem text" removes all
three types of text chunk.
Removed definition of TOO_FAR from pngcrush.h
Uses new libpng error handler; if a file has errors, pngcrush now will
continue on and compress the remaining files instead of bailing out.
Version 1.3.4 (built with libpng-1.0.5m)
Do not allow pngcrush to overwrite the input file.
Version 1.3.3 (built with libpng-1.0.5m)
Restored ability to enter gamma as a float even when floating point
arithmetic is not enabled.
Version 1.3.2 (built with libpng-1.0.5k)
Renamed "dirname" to "directory_name" to avoid conflict with "dirname"
that appears in string.h on some platforms.
Fixed "PNG_NO_FLOAING_POINT" typo in pngcrush.h
#ifdef'ed out parts of the help screen for options that are unsupported.
Version 1.3.1 (built with libpng-1.0.5k): Eliminated some spurious warnings
that were being issued by libpng-1.0.5j. Added -itxt, -ztxt, and
-zitxt descriptions to the help screen.
Dropped explicit support for pCAL, hIST, sCAL, sPLT, iCCP, tIME, and
cHRM chunks and handle them as unknown but safe-to-copy instead, using
new png_handle_as_unknown function available in libpng-1.0.5k.
Version 1.3.0 (built with libpng-1.0.5j): Added support for handling
unknown chunks.
pngcrush is now fixed-point only, unless PNG_NO_FLOATING_POINT_SUPPORTED
is undefined in pngcrush.h.
Added support for the iCCP, iTXt, sCAL, and sPLT chunks, which
are now supported by libpng (since libpng-1.0.5j). None of these have
been adequately tested.
#ifdef'ed out more unused code (weighted filters and progressive read;
this saves about 15k in the size of the executable).
Moved the special definitions from pngconf.h into a new pngcrush.h
Disallow 256-byte compression window size when writing, to work around
an apparent zlib bug. Either deflate was producing incorrect results in a
21x21 4-bit image or inflate was decoding it incorrectly; the uncompressed
stream is 252 bytes, which is uncomfortably close to the resulting
256-byte compression window. This workaround can be removed when zlib
is fixed.
The "-m method" can be used any of the 124 methods, without having to
specify the filter, level, and strategy, instead of just the first 10.
Version 1.2.1 (built with libpng-1.0.5f): Fixed -srgb parameter so it
really does take an argument, and so it continues to use "0" if an
integer does not follow the -srgb.
Added "-plte_len n" argument for truncating the PLTE. Be sure not to
truncate it to less than the greatest index actually appearing in IDAT.
Version 1.2.0: Removed registration requirement. Added open source
license. Redefined TOO_FAR=32k in deflate.c.
Changes prior to going "open source":
Version 1.1.8: built with libpng-1.0.5a. Runs OK with pngvcrd.c.
Version 1.1.7: added ability to add tEXt/zTXt chunks. Fixed bug with
closing a file that wasn't opened when using "pngcrush -n". Fixed
bug with tEXt/zTXt chunks after IDAT not being copied.
Added alpha to the displayed palette table. Rebuilt with libpng-1.0.5.
Version 1.1.6: fixed bug with one file left open after each image is
processed
Version 1.1.5: Shorten or remove tRNS chunks that are all opaque or have
opaque entries at the end. Added timing report.
Version 1.1.4: added ability to restrict brute_force to one or more filter
types, compression levels, or compression strategies.

View File

@@ -1,27 +0,0 @@
There are sample Makefile.gcc and Makefile.msc for pngcrush, which you can use
by typing, for example
make -f Makefile.gcc
However, all you should need to do is enter the pngcrush-n.n.n
directory and type
cc -O -o pngcrush *.c -lm
cp pngcrush /usr/local/bin # or wherever you want
You might want to create your own Makefile if you are planning to do
something more complicated, like loading with your system's shared
libraries for libpng and zlib.
Here's a command for compiling on SGI IRIX:
cc -n32 -fullwarn -O2 -IPA:plimit=256 -OPT:Olimit=0 -o pngcrush *.c -lm
cp pngcrush /usr/local/bin
On a PC with DJGCC, you can type
gcc -O3 -Wall -funroll-loops -o pngcrush *.c
copy /B pmodstub.exe + pngcrush pngcrush.exe
then put pngcrush.exe wherever you want.

73
Makefile Normal file
View File

@@ -0,0 +1,73 @@
# Sample makefile for pngcrush using gcc and GNU make.
# Glenn Randers-Pehrson
# Last modified: 19 February 2005
#
# Invoke this makefile from a shell prompt in the usual way; for example:
#
# make -f makefile.gcc
#
# This makefile builds a statically linked executable.
# macros --------------------------------------------------------------------
GAS_VERSION := $(shell as --version | grep "GNU assembler" | sed -e 's/GNU assembler //' -e 's/ .*//')
# uncomment these 2 lines only if you are using an external copy of zlib:
#ZINC = ../../zlib
#ZLIB = ../../zlib
CC = gcc
LD = gcc
RM = rm -f
#CFLAGS = -I. -O -Wall
#CFLAGS = -I. -O3 -fomit-frame-pointer -Wall -DPNG_USE_PNGGCCRD
CFLAGS = -I. -O3 -fomit-frame-pointer -Wall -DPNG_USE_PNGGCCRD \
-DGAS_VERSION="\"${GAS_VERSION}\""
#CFLAGS = -I${ZINC} -I. -O3 -fomit-frame-pointer -Wall -DPNG_USE_PNGGCCRD \
# -DGAS_VERSION="\"${GAS_VERSION}\""
# [note that -Wall is a gcc-specific compilation flag ("all warnings on")]
LDFLAGS =
O = .o
E =
PNGCRUSH = pngcrush
LIBS = -lm
#LIBS = -L${ZLIB} -lz -lm
#LIBS = ${ZLIB}/libz.a -lm
# uncomment these 4 lines only if you are NOT using an external copy of zlib:
ZHDR = zlib.h
ZOBJS = adler32$(O) compress$(O) crc32$(O) deflate$(O) gzio$(O) \
infback$(O) inffast$(O) inflate$(O) inftrees$(O) \
trees$(O) uncompr$(O) zutil$(O)
OBJS = pngcrush$(O) png$(O) pngerror$(O) pngget$(O) pngmem$(O) \
pngpread$(O) pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) \
pngset$(O) pngtrans$(O) pngwio$(O) pngwrite$(O) pnggccrd$(O) \
pngwtran$(O) pngwutil$(O) $(ZOBJS)
EXES = $(PNGCRUSH)$(E)
# implicit make rules -------------------------------------------------------
.c$(O): png.h pngconf.h pngcrush.h cexcept.h $(ZHDR)
$(CC) -c $(CFLAGS) $<
# dependencies --------------------------------------------------------------
all: $(EXES)
pngcrush$(O): pngcrush.c png.h pngconf.h pngcrush.h cexcept.h $(ZHDR)
$(CC) -c $(CFLAGS) $<
$(PNGCRUSH)$(E): $(OBJS)
$(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
# maintenance ---------------------------------------------------------------
clean:
$(RM) $(EXES) $(OBJS)

72
Makefile.ext-zlib Normal file
View File

@@ -0,0 +1,72 @@
# Sample makefile for pngcrush using gcc and GNU make.
# Glenn Randers-Pehrson
# Last modified: 19 February 2005
#
# Invoke this makefile from a shell prompt in the usual way; for example:
#
# make -f makefile.gcc
#
# This makefile builds a statically linked executable.
# macros --------------------------------------------------------------------
GAS_VERSION := $(shell as --version | grep "GNU assembler" | sed -e 's/GNU assembler //' -e 's/ .*//')
ZINC = ../../zlib
ZLIB = ../../zlib
CC = gcc
LD = gcc
RM = rm -f
#CFLAGS = -I. -O -Wall
#CFLAGS = -I. -O3 -fomit-frame-pointer -Wall -DPNG_USE_PNGGCCRD
#CFLAGS = -I. -O3 -fomit-frame-pointer -Wall -DPNG_USE_PNGGCCRD \
# -DGAS_VERSION="\"${GAS_VERSION}\""
CFLAGS = -I${ZINC} -I. -O3 -fomit-frame-pointer -Wall -DPNG_USE_PNGGCCRD \
-DGAS_VERSION="\"${GAS_VERSION}\""
# [note that -Wall is a gcc-specific compilation flag ("all warnings on")]
LDFLAGS =
O = .o
E =
PNGCRUSH = pngcrush-zlib
#LIBS = -lm
#LIBS = -L${ZLIB} -lz -lm
LIBS = ${ZLIB}/libz.a -lm
# uncomment these 4 lines only if you are NOT using an external copy of zlib:
#ZHDR = zlib.h
#ZOBJS = adler32$(O) crc32$(O) deflate$(O) gzio$(O) \
# infblock$(O) infcodes$(O) inffast$(O) inflate$(O) inftrees$(O) \
# infutil$(O) trees$(O) zutil$(O)
OBJS = pngcrush$(O) png$(O) pngerror$(O) pngget$(O) pngmem$(O) \
pngpread$(O) pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) \
pngset$(O) pngtrans$(O) pngwio$(O) pngwrite$(O) pnggccrd$(O) \
pngwtran$(O) pngwutil$(O) $(ZOBJS)
EXES = $(PNGCRUSH)$(E)
# implicit make rules -------------------------------------------------------
.c$(O): png.h pngconf.h pngcrush.h cexcept.h $(ZHDR)
$(CC) -c $(CFLAGS) $<
# dependencies --------------------------------------------------------------
all: $(EXES)
pngcrush$(O): pngcrush.c png.h pngconf.h pngcrush.h cexcept.h $(ZHDR)
$(CC) -c $(CFLAGS) $<
$(PNGCRUSH)$(E): $(OBJS)
$(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
# maintenance ---------------------------------------------------------------
clean:
$(RM) $(EXES) $(OBJS)

View File

@@ -1,55 +0,0 @@
# Sample makefile for pngcrush using gcc and make.
# Glenn Randers-Pehrson
# Last modified: 7 December 1999
#
# Invoke this makefile from a shell prompt in the usual way; for example:
#
# make -f makefile.unx
#
# This makefile builds a statically linked executable.
# macros --------------------------------------------------------------------
CC = gcc
LD = gcc
RM = rm -f
CFLAGS = -I. -O -Wall
# [note that -Wall is a gcc-specific compilation flag ("all warnings on")]
LDFLAGS =
O = .o
E =
PNGCRUSH = pngcrush
LIBS = -lm
OBJS = $(PNGCRUSH)$(O) adler32$(O) crc32$(O) deflate$(O) gzio$(O) \
infblock$(O) infcodes$(O) inffast$(O) inflate$(O) inftrees$(O) \
infutil$(O) png$(O) pngerror$(O) pngget$(O) pngmem$(O) \
pngpread$(O) pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) \
pngset$(O) pngtrans$(O) pngwio$(O) pngwrite$(O) pnggccrd$(O) \
pngwtran$(O) pngwutil$(O) trees$(O) zutil$(O)
EXES = $(PNGCRUSH)$(E)
# implicit make rules -------------------------------------------------------
.c$(O): png.h pngconf.h zlib.h pngcrush.h cexcept.h
$(CC) -c $(CFLAGS) $<
# dependencies --------------------------------------------------------------
all: $(EXES)
$(PNGCRUSH)$(E): $(OBJS)
$(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
$(PNGCRUSH)$(O): $(PNGCRUSH).c png.h pngconf.h zlib.h pngcrush.h cexcept.h
# maintenance ---------------------------------------------------------------
clean:
$(RM) $(EXES) $(OBJS)

View File

@@ -1,57 +0,0 @@
# Sample makefile for pngcrush using Microsoft (Visual) C compiler.
# Author: Cosmin Truta
# Derived from Makefile.gcc by Glenn Randers-Pehrson
# Last modified: 14 January 2000
#
# Invoke this makefile from a console prompt in the usual way; for example:
#
# nmake -f Makefile.msc
#
# This makefile builds a statically linked executable.
# macros --------------------------------------------------------------------
CC = cl -nologo
LD = link -nologo setargv.obj
RM = del
CFLAGS = -I. -DPNG_ZBUF_SIZE=0x080000 -DWIN32 -O2
LDFLAGS =
O = .obj
E = .exe
PNGCRUSH = pngcrush
LIBS =
OBJS = $(PNGCRUSH)$(O) adler32$(O) crc32$(O) deflate$(O) gzio$(O) \
infblock$(O) infcodes$(O) inffast$(O) inflate$(O) inftrees$(O) \
infutil$(O) png$(O) pngerror$(O) pngget$(O) pngmem$(O) \
pngpread$(O) pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) \
pngset$(O) pngtrans$(O) pngvcrd$(O) pngwio$(O) pngwrite$(O) \
pngwtran$(O) pngwutil$(O) trees$(O) zutil$(O)
EXES = $(PNGCRUSH)$(E)
# implicit make rules -------------------------------------------------------
.c$(O):
$(CC) -c $(CFLAGS) $<
# dependencies --------------------------------------------------------------
all: $(EXES)
$(PNGCRUSH)$(E): $(OBJS)
$(LD) $(LDFLAGS) -out:$@ $(OBJS) $(LIBS)
$(PNGCRUSH)$(O): $(PNGCRUSH).c png.h pngconf.h zlib.h pngcrush.h cexcept.h
# maintenance ---------------------------------------------------------------
clean:
$(RM) *$(O)
$(RM) $(PNGCRUSH)$(E)

70
Makefile.solaris Normal file
View File

@@ -0,0 +1,70 @@
# Sample makefile for pngcrush using gcc and GNU make.
# Glenn Randers-Pehrson
# Last modified: 19 February 2005
#
# Invoke this makefile from a shell prompt in the usual way; for example:
#
# make -f makefile.gcc
#
# This makefile builds a statically linked executable.
# macros --------------------------------------------------------------------
# uncomment these 2 lines only if you are using an external copy of zlib:
#ZINC = ../../zlib
#ZLIB = ../../zlib
CC = gcc
LD = gcc
RM = rm -f
#CFLAGS = -I. -O -Wall
#CFLAGS = -I. -O3 -fomit-frame-pointer -Wall -DPNG_USE_PNGGCCRD
CFLAGS = -I. -O3 -fomit-frame-pointer -Wall
#CFLAGS = -I${ZINC} -I. -O3 -fomit-frame-pointer -Wall -DPNG_USE_PNGGCCRD \
# -DGAS_VERSION="\"${GAS_VERSION}\""
# [note that -Wall is a gcc-specific compilation flag ("all warnings on")]
LDFLAGS =
O = .o
E =
PNGCRUSH = pngcrush
LIBS = -lm
#LIBS = -L${ZLIB} -lz -lm
#LIBS = ${ZLIB}/libz.a -lm
# uncomment these 4 lines only if you are NOT using an external copy of zlib:
ZHDR = zlib.h
ZOBJS = adler32$(O) compress$(O) crc32$(O) deflate$(O) gzio$(O) \
infback$(O) inffast$(O) inflate$(O) inftrees$(O) \
trees$(O) uncompr$(O) zutil$(O)
OBJS = pngcrush$(O) png$(O) pngerror$(O) pngget$(O) pngmem$(O) \
pngpread$(O) pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) \
pngset$(O) pngtrans$(O) pngwio$(O) pngwrite$(O) pnggccrd$(O) \
pngwtran$(O) pngwutil$(O) $(ZOBJS)
EXES = $(PNGCRUSH)$(E)
# implicit make rules -------------------------------------------------------
.c$(O): png.h pngconf.h pngcrush.h cexcept.h $(ZHDR)
$(CC) -c $(CFLAGS) $<
# dependencies --------------------------------------------------------------
all: $(EXES)
pngcrush$(O): pngcrush.c png.h pngconf.h pngcrush.h cexcept.h $(ZHDR)
$(CC) -c $(CFLAGS) $<
$(PNGCRUSH)$(E): $(OBJS)
$(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
# maintenance ---------------------------------------------------------------
clean:
$(RM) $(EXES) $(OBJS)

View File

@@ -1,321 +0,0 @@
Pngcrush documentation
This is is a copy of the copyright notice, disclaimer, and license, for
your convenience (the actual notice appears in the file pngcrush.c; in
case of any discrepancy, the copy in pngcrush.c shall prevail):
/*
* COPYRIGHT NOTICE, DISCLAIMER, AND LICENSE:
*
* If you have modified this source, you may insert additional notices
* immediately after this sentence.
*
* Copyright (C) 1998-2002 Glenn Randers-Pehrson (randeg@alum.rpi.edu)
*
* The pngcrush computer program is supplied "AS IS". The Author disclaims all
* warranties, expressed or implied, including, without limitation, the
* warranties of merchantability and of fitness for any purpose. The
* Author assumes no liability for direct, indirect, incidental, special,
* exemplary, or consequential damages, which may result from the use of
* the computer program, even if advised of the possibility of such damage.
* There is no warranty against interference with your enjoyment of the
* computer program or against infringement. There is no warranty that my
* efforts or the computer program will fulfill any of your particular purposes
* or needs. This computer program is provided with all faults, and the entire
* risk of satisfactory quality, performance, accuracy, and effort is with
* the user.
*
* Permission is hereby irrevocably granted to everyone to use, copy, modify,
* and distribute this source code, or portions hereof, for any purpose,
* without payment of any 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, disclaimer, and license may not be removed
* or altered from any source or altered source distribution.
*/
This is the output of "pngcrush" and "pngcrush -help":
| pngcrush 1.5.10, Copyright (C) 1998-2002 Glenn Randers-Pehrson
| This is a free, open-source program. Permission is irrevocably
| granted to everyone to use this version of pngcrush without
| payment of any fee.
| Executable name is pngcrush
| It was built with libpng version 1.2.4, and is
| running with libpng version 1.2.4 - July 8, 2002 (header)
| Copyright (C) 1998-2002 Glenn Randers-Pehrson,
| Copyright (C) 1996, 1997 Andreas Dilger,
| Copyright (C) 1995, Guy Eric Schalnat, Group 42 Inc.,
| and zlib version 1.1.4pc, Copyright (C) 1998,
| Jean-loup Gailly and Mark Adler.
usage: pngcrush [options] infile.png outfile.png
pngcrush -e ext [other options] files.png ...
pngcrush -d dir [other options] files.png ...
options:
-already already_crushed_size [e.g., 8192]
-bit_depth depth (bit_depth to use in output file)
-brute (Use brute-force, try 114 different methods [11-124])
-c color_type of output file [0, 2, 4, or 6]
-d directory_name (where output files will go)
-double_gamma (used for fixing gamma in PhotoShop 5.0/5.02 files)
-e extension (used for creating output filename)
-f user_filter [0-5]
-fix (fix otherwise fatal conditions such as bad CRCs)
-force (Write a new output file even if larger than input)
-g gamma (float or fixed*100000, e.g., 0.45455 or 45455)
-iccp length "Profile Name" iccp_file
-itxt b[efore_IDAT]|a[fter_IDAT] "keyword" "text"
-l zlib_compression_level [0-9]
-loco ("loco crush" truecolor PNGs)
-m method [0 through 200]
-max maximum_IDAT_size [default 8192]
-nofilecheck (do not check for infile.png == outfile.png)
-n (no save; does not do compression or write output PNG)
-plte_len n (truncate PLTE)
-q (quiet)
-reduce (do lossless color type or bit depth reduction)
-rem chunkname (or "alla" or "allb")
-replace_gamma gamma (float or fixed*100000) even if gAMA is present.
-res dpi
-save (keep all copy-unsafe chunks)
-srgb [0, 1, 2, or 3]
-text b[efore_IDAT]|a[fter_IDAT] "keyword" "text"
-trns_array n trns[0] trns[1] .. trns[n-1]
-trns index red green blue gray
-v (display more detailed information)
-version (display the pngcrush version)
-w compression_window_size [32, 16, 8, 4, 2, 1, 512]
-z zlib_strategy [0, 1, or 2]
-zmem zlib_compression_mem_level [1-9, default 9]
-zitxt b[efore_IDAT]|a[fter_IDAT] "keyword" "text"
-ztxt b[efore_IDAT]|a[fter_IDAT] "keyword" "text"
-h (help and legal notices)
-p (pause)
options (Note: any option can be spelled out for clarity, e.g.,
"pngcrush -dir New -method 7 -remove bkgd *.png"
is the same as "pngcrush -d New -m 7 -rem bkgd *.png"):
-already already_crushed_size [e.g., 8192]
If file has an IDAT greater than this size, it
will be considered to be already crushed and will
not be processed, unless you are making other changes
or the "-force" option is present.
-bit_depth depth (bit_depth to use in output file)
Default output depth is same as input depth.
-brute (Use brute-force, try 114 different methods [11-124])
Very time-consuming and generally not worthwhile.
You can restrict this option to certain filter types,
compression levels, or strategies by following it with
"-f filter", "-l level", or "-z strategy".
-c color_type of output file [0, 2, 4, or 6]
Color type for the output file. Future versions
will also allow color_type 3, if there are 256 or
fewer colors present in the input file. Color types
4 and 6 are padded with an opaque alpha channel if
the input file does not have alpha information.
You can use 0 or 4 to convert color to grayscale.
Use 0 or 2 to delete an unwanted alpha channel.
Default is to use same color type as the input file.
-d directory_name (where output files will go)
If a directory name is given, then the output
files are placed in it, with the same filenames as
those of the original files. For example,
you would type 'pngcrush -directory CRUSHED *.png'
to get *.png => CRUSHED/*.png
-double_gamma (used for fixing gamma in PhotoShop 5.0/5.02 files)
It has been claimed that the PS5 bug is actually
more complex than that, in some unspecified way.
-e extension (used for creating output filename)
e.g., -ext .new means *.png => *.new
and -e _C.png means *.png => *_C.png
-f user_filter [0-5]
filter to use with the method specified in the
preceding '-m method' or '-brute_force' argument.
0: none; 1-4: use specified filter; 5: adaptive.
-fix (fix otherwise fatal conditions such as bad CRCs)
-force (Write a new output file even if larger than input)
Otherwise the input file will be copied to output
if it is smaller than any generated file and no chunk
additions, removals, or changes were requested.
-g gamma (float or fixed*100000, e.g., 0.45455 or 45455)
Value to insert in gAMA chunk, only if the input
file has no gAMA chunk. To replace an existing
gAMA chunk, use the '-replace_gamma' option.
-iccp length "Profile Name" iccp_file
file with ICC profile to insert in an iCCP chunk.
-itxt b[efore_IDAT]|a[fter_IDAT] "keyword" "text"
Uncompressed iTXt chunk to insert (see -text).
-l zlib_compression_level [0-9]
zlib compression level to use with method specified
with the preceding '-m method' or '-brute_force'
argument.
-loco ("loco crush" truecolor PNGs)
Make the file more compressible by performing a
lossless reversible color transformation.
The resulting file is a MNG, not a PNG, and should
be given the ".mng" file extension. The
"loco" option has no effect on grayscale or
indexed-color PNG files.
-m method [0 through 200]
pngcrush method to try (0 means try all of 1-10).
Can be repeated as in '-m 1 -m 4 -m 7'.
This can be useful if pngcrush runs out of memory
when it tries methods 2, 3, 5, 6, 8, 9, or 10 which
use filtering and are memory intensive. Methods
1, 4, and 7 use no filtering; methods 11 and up use
specified filter, compression level, and strategy.
-max maximum_IDAT_size [default 8192]
-nofilecheck (do not check for infile.png == outfile.png)
To avoid false hits from MSVC-compiled code. Note
that if you use this option, you are responsible for
ensuring that the input file is not the output file.
-n (no save; does not do compression or write output PNG)
Useful in conjunction with -v option to get info.
-plte_len n (truncate PLTE)
Truncates the PLTE. Be sure not to truncate it to
less than the greatest index present in IDAT.
-q (quiet)
-reduce (do lossless color type or bit depth reduction)
(if possible)
-rem chunkname (or "alla" or "allb")
Name of an ancillary chunk or optional PLTE to be
removed. Be careful with this. Please don't use
this feature to remove transparency, gamma, copyright,
or other valuable information. To remove several
different chunks, repeat: -rem tEXt -rem pHYs.
Known chunks (those in the PNG 1.1 spec or extensions
document) can be named with all lower-case letters,
so "-rem bkgd" is equivalent to "-rem bKGD". But
note: "-rem text" removes all forms of text chunks;
Exact case is required to remove unknown chunks.
To do surgery with a chain-saw, "-rem alla" removes
all known ancillary chunks except for tRNS, and
"-rem allb" removes all but tRNS and gAMA.
-replace_gamma gamma (float or fixed*100000) even if gAMA is present.
-res dpi
Write a pHYs chunk with the given resolution.
-save (keep all copy-unsafe chunks)
Save otherwise unknown ancillary chunks that would
be considered copy-unsafe. This option makes
chunks 'known' to pngcrush, so they can be copied.
-srgb [0, 1, 2, or 3]
Value of 'rendering intent' for sRGB chunk.
-text b[efore_IDAT]|a[fter_IDAT] "keyword" "text"
tEXt chunk to insert. keyword < 80 chars,
text < 2048 chars. For now, you can only add ten
tEXt, iTXt, or zTXt chunks per pngcrush run.
-trns_array n trns[0] trns[1] .. trns[n-1]
Insert a tRNS chunk, if no tRNS chunk found in file.
Values are for the tRNS array in indexed-color PNG.
-trns index red green blue gray
Insert a tRNS chunk, if no tRNS chunk found in file.
You must give all five parameters regardless of the
color type, scaled to the output bit depth.
-v (display more detailed information)
Repeat the option (use "-v -v") for even more.
-version (display the pngcrush version)
Look for the most recent version of pngcrush at
http://pmt.sf.net
-w compression_window_size [32, 16, 8, 4, 2, 1, 512]
Size of the sliding compression window, in kbytes
(or bytes, in case of 512). It's best to
use the default (32) unless you run out of memory.
The program will use a smaller window anyway when
the uncompressed file is smaller than 16k.
-z zlib_strategy [0, 1, or 2]
zlib compression strategy to use with the preceding
'-m method' argument.
-zmem zlib_compression_mem_level [1-9, default 9]
-zitxt b[efore_IDAT]|a[fter_IDAT] "keyword" "text"
Compressed iTXt chunk to insert (see -text).
-ztxt b[efore_IDAT]|a[fter_IDAT] "keyword" "text"
zTXt chunk to insert (see -text).
-h (help and legal notices)
Display this information.
-p (pause)
Wait for [enter] key before continuing display.
e.g., type 'pngcrush -pause -help', if the help
screen scrolls out of sight.

139
adler32.c
View File

@@ -1,48 +1,149 @@
/* adler32.c -- compute the Adler-32 checksum of a data stream /* adler32.c -- compute the Adler-32 checksum of a data stream
* Copyright (C) 1995-1998 Mark Adler * Copyright (C) 1995-2004 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* @(#) $Id$ */ /* @(#) $Id$ */
#define ZLIB_INTERNAL
#include "zlib.h" #include "zlib.h"
#define BASE 65521L /* largest prime smaller than 65536 */ #define BASE 65521UL /* largest prime smaller than 65536 */
#define NMAX 5552 #define NMAX 5552
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} #define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
#define DO16(buf) DO8(buf,0); DO8(buf,8); #define DO16(buf) DO8(buf,0); DO8(buf,8);
/* use NO_DIVIDE if your processor does not do division in hardware */
#ifdef NO_DIVIDE
# define MOD(a) \
do { \
if (a >= (BASE << 16)) a -= (BASE << 16); \
if (a >= (BASE << 15)) a -= (BASE << 15); \
if (a >= (BASE << 14)) a -= (BASE << 14); \
if (a >= (BASE << 13)) a -= (BASE << 13); \
if (a >= (BASE << 12)) a -= (BASE << 12); \
if (a >= (BASE << 11)) a -= (BASE << 11); \
if (a >= (BASE << 10)) a -= (BASE << 10); \
if (a >= (BASE << 9)) a -= (BASE << 9); \
if (a >= (BASE << 8)) a -= (BASE << 8); \
if (a >= (BASE << 7)) a -= (BASE << 7); \
if (a >= (BASE << 6)) a -= (BASE << 6); \
if (a >= (BASE << 5)) a -= (BASE << 5); \
if (a >= (BASE << 4)) a -= (BASE << 4); \
if (a >= (BASE << 3)) a -= (BASE << 3); \
if (a >= (BASE << 2)) a -= (BASE << 2); \
if (a >= (BASE << 1)) a -= (BASE << 1); \
if (a >= BASE) a -= BASE; \
} while (0)
# define MOD4(a) \
do { \
if (a >= (BASE << 4)) a -= (BASE << 4); \
if (a >= (BASE << 3)) a -= (BASE << 3); \
if (a >= (BASE << 2)) a -= (BASE << 2); \
if (a >= (BASE << 1)) a -= (BASE << 1); \
if (a >= BASE) a -= BASE; \
} while (0)
#else
# define MOD(a) a %= BASE
# define MOD4(a) a %= BASE
#endif
/* ========================================================================= */ /* ========================================================================= */
uLong ZEXPORT adler32(adler, buf, len) uLong ZEXPORT adler32(adler, buf, len)
uLong adler; uLong adler;
const Bytef *buf; const Bytef *buf;
uInt len; uInt len;
{ {
unsigned long s1 = adler & 0xffff; unsigned long sum2;
unsigned long s2 = (adler >> 16) & 0xffff; unsigned n;
int k;
if (buf == Z_NULL) return 1L; /* split Adler-32 into component sums */
sum2 = (adler >> 16) & 0xffff;
adler &= 0xffff;
while (len > 0) { /* in case user likes doing a byte at a time, keep it fast */
k = len < NMAX ? len : NMAX; if (len == 1) {
len -= k; adler += buf[0];
while (k >= 16) { if (adler >= BASE)
adler -= BASE;
sum2 += adler;
if (sum2 >= BASE)
sum2 -= BASE;
return adler | (sum2 << 16);
}
/* initial Adler-32 value (deferred check for len == 1 speed) */
if (buf == Z_NULL)
return 1L;
/* in case short lengths are provided, keep it somewhat fast */
if (len < 16) {
while (len--) {
adler += *buf++;
sum2 += adler;
}
if (adler >= BASE)
adler -= BASE;
MOD4(sum2); /* only added so many BASE's */
return adler | (sum2 << 16);
}
/* do length NMAX blocks -- requires just one modulo operation */
while (len >= NMAX) {
len -= NMAX;
n = NMAX / 16; /* NMAX is divisible by 16 */
do {
DO16(buf); /* 16 sums unrolled */
buf += 16;
} while (--n);
MOD(adler);
MOD(sum2);
}
/* do remaining bytes (less than NMAX, still just one modulo) */
if (len) { /* avoid modulos if none remaining */
while (len >= 16) {
len -= 16;
DO16(buf); DO16(buf);
buf += 16; buf += 16;
k -= 16;
} }
if (k != 0) do { while (len--) {
s1 += *buf++; adler += *buf++;
s2 += s1; sum2 += adler;
} while (--k);
s1 %= BASE;
s2 %= BASE;
} }
return (s2 << 16) | s1; MOD(adler);
MOD(sum2);
}
/* return recombined sums */
return adler | (sum2 << 16);
}
/* ========================================================================= */
uLong ZEXPORT adler32_combine(adler1, adler2, len2)
uLong adler1;
uLong adler2;
z_off_t len2;
{
unsigned long sum1;
unsigned long sum2;
unsigned rem;
/* the derivation of this formula is left as an exercise for the reader */
rem = (unsigned)(len2 % BASE);
sum1 = adler1 & 0xffff;
sum2 = rem * sum1;
MOD(sum2);
sum1 += (adler2 & 0xffff) + BASE - 1;
sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
if (sum1 > BASE) sum1 -= BASE;
if (sum1 > BASE) sum1 -= BASE;
if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
if (sum2 > BASE) sum2 -= BASE;
return sum1 | (sum2 << 16);
} }

107
cexcept.h
View File

@@ -1,17 +1,20 @@
/*=== /*===
cexcept.h 1.0.0 (2000-Jun-21-Wed) cexcept.h 2.0.0 (2001-Jul-12-Thu)
Adam M. Costello <amc@cs.berkeley.edu> Adam M. Costello <amc@cs.berkeley.edu>
An interface for exception-handling in ANSI C, developed jointly with An interface for exception-handling in ANSI C (C89 and subsequent ISO
Cosmin Truta <cosmin@cs.toronto.edu>. standards), developed jointly with Cosmin Truta <cosmin@cs.toronto.edu>.
Copyright (c) 2000 Adam M. Costello and Cosmin Truta. Everyone Copyright (c) 2001 Adam M. Costello and Cosmin Truta. Everyone
is hereby granted permission to do whatever they like with this is hereby granted permission to do whatever they like with this
file, provided that if they modify it they take reasonable steps to file, provided that if they modify it they take reasonable steps to
avoid confusing or misleading people about the authors, version, avoid confusing or misleading people about the authors, version,
and terms of use of the derived file. The copyright holders make and terms of use of the derived file. The copyright holders make
no guarantees about the correctness of this file, and are not no guarantees regarding this file, and are not responsible for any
responsible for any damage resulting from its use. damage resulting from its use.
Only user-defined exceptions are supported, not "real" exceptions like
division by zero or memory segmentation violations.
If this interface is used by multiple .c files, they shouldn't include If this interface is used by multiple .c files, they shouldn't include
this header file directly. Instead, create a wrapper header file that this header file directly. Instead, create a wrapper header file that
@@ -37,6 +40,10 @@ define_exception_type(type_name);
struct exception { int code; const char *msg; }; struct exception { int code; const char *msg; };
define_exception_type(struct exception); define_exception_type(struct exception);
Because throwing an exception causes the object to be copied (not
just once, but twice), programmers may wish to consider size when
choosing the exception type.
struct exception_context; struct exception_context;
@@ -62,7 +69,7 @@ struct exception_context *the_exception_context;
application may declare a variable of this name anywhere it likes application may declare a variable of this name anywhere it likes
(inside a function, in a parameter list, or externally), and may (inside a function, in a parameter list, or externally), and may
use whatever storage class specifiers (static, extern, etc) or type use whatever storage class specifiers (static, extern, etc) or type
qualifiers (const, volatile) it likes. Examples: qualifiers (const, volatile, etc) it likes. Examples:
static struct exception_context static struct exception_context
* const the_exception_context = &foo; * const the_exception_context = &foo;
@@ -107,15 +114,15 @@ Catch (expression) statement
confusion with the C++ keywords, which have subtly different confusion with the C++ keywords, which have subtly different
semantics. semantics.
A Try/Catch statement has a syntax similar to an if/else A Try/Catch statement has a syntax similar to an if/else statement,
statement, except that the parenthesized expression goes after except that the parenthesized expression goes after the second
the second keyword rather than the first. As with if/else, keyword rather than the first. As with if/else, there are two
there are two clauses, each of which may be a simple statement clauses, each of which may be a simple statement ending with a
ending with a semicolon or a brace-enclosed compound statement. semicolon or a brace-enclosed compound statement. But whereas
But whereas the else clause is optional, the Catch clause is the else clause is optional, the Catch clause is required. The
required. The expression must be a modifiable lvalue (something expression must be a modifiable lvalue (something capable of being
capable of being assigned to) of the exact same type passed to assigned to) of the same type (disregarding type qualifiers) that
define_exception_type(). was passed to define_exception_type().
If a Throw that uses the same exception context as the Try/Catch is If a Throw that uses the same exception context as the Try/Catch is
executed within the Try clause (typically within a function called executed within the Try clause (typically within a function called
@@ -125,9 +132,8 @@ Catch (expression) statement
such Throw is executed, then the assignment is not performed, and such Throw is executed, then the assignment is not performed, and
the Catch clause is not executed. the Catch clause is not executed.
Regardless of whether an exception is caught, the expression is The expression is not evaluated unless and until the exception is
always evaluated exactly once, which is significant if it has side caught, which is significant if it has side effects, for example:
effects, for example:
Try foo(); Try foo();
Catch (p[++i].e) { ... } Catch (p[++i].e) { ... }
@@ -183,62 +189,55 @@ is subject to change.
#include <setjmp.h> #include <setjmp.h>
#define define_exception_type(etype) \ #define define_exception_type(etype) \
struct exception__state { \ struct exception_context { \
etype *exception; \ jmp_buf *penv; \
jmp_buf env; \ int caught; \
volatile struct { etype etmp; } v; \
} }
struct exception_context { \ /* etmp must be volatile because the application might use automatic */
struct exception__state *last; \ /* storage for the_exception_context, and etmp is modified between */
int caught; \ /* the calls to setjmp() and longjmp(). A wrapper struct is used to */
}; /* avoid warnings about a duplicate volatile qualifier in case etype */
/* already includes it. */
#define init_exception_context(ec) ((void)((ec)->last = 0)) #define init_exception_context(ec) ((void)((ec)->penv = 0))
#define Catch(e) exception__catch(&(e))
#define Catch_anonymous exception__catch(0)
#define Try \ #define Try \
{ \ { \
struct exception__state *exception__p, exception__s; \ jmp_buf *exception__prev, exception__env; \
int exception__i; \ exception__prev = the_exception_context->penv; \
exception__p = the_exception_context->last; \ the_exception_context->penv = &exception__env; \
the_exception_context->last = &exception__s; \ if (setjmp(exception__env) == 0) { \
for (exception__i = 0; ; exception__i = 1) \ if (&exception__prev)
if (exception__i) { \
if (setjmp(exception__s.env) == 0) { \
if (&exception__s)
#define exception__catch(e_addr) \ #define exception__catch(action) \
else { } \ else { } \
the_exception_context->caught = 0; \ the_exception_context->caught = 0; \
} \ } \
else the_exception_context->caught = 1; \ else { \
the_exception_context->last = exception__p; \ the_exception_context->caught = 1; \
break; \
} \ } \
else exception__s.exception = e_addr; \ the_exception_context->penv = exception__prev; \
} \ } \
if (!the_exception_context->caught) { } \ if (!the_exception_context->caught || action) { } \
else else
#define Catch(e) exception__catch(((e) = the_exception_context->v.etmp, 0))
#define Catch_anonymous exception__catch(0)
/* Try ends with if(), and Catch begins and ends with else. This */ /* Try ends with if(), and Catch begins and ends with else. This */
/* ensures that the Try/Catch syntax is really the same as the */ /* ensures that the Try/Catch syntax is really the same as the */
/* if/else syntax. */ /* if/else syntax. */
/* */ /* */
/* We use &exception__s instead of 1 to appease compilers that */ /* We use &exception__prev instead of 1 to appease compilers that */
/* warn about constant expressions inside if(). Most compilers */ /* warn about constant expressions inside if(). Most compilers */
/* should still recognize that &exception__s is never zero and avoid */ /* should still recognize that &exception__prev is never zero and */
/* generating test code. */ /* avoid generating test code. */
/* */
/* We use the variable exception__i to start the loop at the bottom, */
/* rather than jump into the loop using a switch statement, to */
/* appease compilers that warn about jumping into loops. */
#define Throw \ #define Throw \
for (;; longjmp(the_exception_context->last->env, 1)) \ for (;; longjmp(*the_exception_context->penv, 1)) \
if (the_exception_context->last->exception) \ the_exception_context->v.etmp =
*the_exception_context->last->exception =
#endif /* CEXCEPT_H */ #endif /* CEXCEPT_H */

View File

@@ -1,10 +1,11 @@
/* compress.c -- compress a memory buffer /* compress.c -- compress a memory buffer
* Copyright (C) 1995-1998 Jean-loup Gailly. * Copyright (C) 1995-2003 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* @(#) $Id$ */ /* @(#) $Id$ */
#define ZLIB_INTERNAL
#include "zlib.h" #include "zlib.h"
/* =========================================================================== /* ===========================================================================
@@ -66,3 +67,13 @@ int ZEXPORT compress (dest, destLen, source, sourceLen)
{ {
return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
} }
/* ===========================================================================
If the default memLevel or windowBits for deflateInit() is changed, then
this function needs to be updated.
*/
uLong ZEXPORT compressBound (sourceLen)
uLong sourceLen;
{
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
}

467
crc32.c
View File

@@ -1,22 +1,84 @@
/* crc32.c -- compute the CRC-32 of a data stream /* crc32.c -- compute the CRC-32 of a data stream
* Copyright (C) 1995-1998 Mark Adler * Copyright (C) 1995-2005 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*
* Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
* CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
* tables for updating the shift register in one step with three exclusive-ors
* instead of four steps with four exclusive-ors. This results in about a
* factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
*/ */
/* @(#) $Id$ */ /* @(#) $Id$ */
#include "zlib.h" /*
Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
protection on the static variables used to control the first-use generation
of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
first call get_crc_table() to initialize the tables before allowing more than
one thread to use crc32().
*/
#ifdef MAKECRCH
# include <stdio.h>
# ifndef DYNAMIC_CRC_TABLE
# define DYNAMIC_CRC_TABLE
# endif /* !DYNAMIC_CRC_TABLE */
#endif /* MAKECRCH */
#include "zutil.h" /* for STDC and FAR definitions */
#define local static #define local static
/* Find a four-byte integer type for crc32_little() and crc32_big(). */
#ifndef NOBYFOUR
# ifdef STDC /* need ANSI C limits.h to determine sizes */
# include <limits.h>
# define BYFOUR
# if (UINT_MAX == 0xffffffffUL)
typedef unsigned int u4;
# else
# if (ULONG_MAX == 0xffffffffUL)
typedef unsigned long u4;
# else
# if (USHRT_MAX == 0xffffffffUL)
typedef unsigned short u4;
# else
# undef BYFOUR /* can't find a four-byte integer type! */
# endif
# endif
# endif
# endif /* STDC */
#endif /* !NOBYFOUR */
/* Definitions for doing the crc four data bytes at a time. */
#ifdef BYFOUR
# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
(((w)&0xff00)<<8)+(((w)&0xff)<<24))
local unsigned long crc32_little OF((unsigned long,
const unsigned char FAR *, unsigned));
local unsigned long crc32_big OF((unsigned long,
const unsigned char FAR *, unsigned));
# define TBLS 8
#else
# define TBLS 1
#endif /* BYFOUR */
/* Local functions for crc concatenation */
local unsigned long gf2_matrix_times OF((unsigned long *mat,
unsigned long vec));
local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
#ifdef DYNAMIC_CRC_TABLE #ifdef DYNAMIC_CRC_TABLE
local int crc_table_empty = 1; local volatile int crc_table_empty = 1;
local uLongf crc_table[256]; local unsigned long FAR crc_table[TBLS][256];
local void make_crc_table OF((void)); local void make_crc_table OF((void));
#ifdef MAKECRCH
local void write_table OF((FILE *, const unsigned long FAR *));
#endif /* MAKECRCH */
/* /*
Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
Polynomials over GF(2) are represented in binary, one bit per coefficient, Polynomials over GF(2) are represented in binary, one bit per coefficient,
@@ -35,128 +97,327 @@ local void make_crc_table OF((void));
out is a one). We start with the highest power (least significant bit) of out is a one). We start with the highest power (least significant bit) of
q and repeat for all eight bits of q. q and repeat for all eight bits of q.
The table is simply the CRC of all possible eight bit values. This is all The first table is simply the CRC of all possible eight bit values. This is
the information needed to generate CRC's on data a byte at a time for all all the information needed to generate CRCs on data a byte at a time for all
combinations of CRC register values and incoming bytes. combinations of CRC register values and incoming bytes. The remaining tables
allow for word-at-a-time CRC calculation for both big-endian and little-
endian machines, where a word is four bytes.
*/ */
local void make_crc_table() local void make_crc_table()
{ {
uLong c; unsigned long c;
int n, k; int n, k;
uLong poly; /* polynomial exclusive-or pattern */ unsigned long poly; /* polynomial exclusive-or pattern */
/* terms of polynomial defining this crc (except x^32): */ /* terms of polynomial defining this crc (except x^32): */
static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; static volatile int first = 1; /* flag to limit concurrent making */
static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
/* make exclusive-or pattern from polynomial (0xedb88320L) */ /* See if another task is already doing this (not thread-safe, but better
poly = 0L; than nothing -- significantly reduces duration of vulnerability in
for (n = 0; n < sizeof(p)/sizeof(Byte); n++) case the advice about DYNAMIC_CRC_TABLE is ignored) */
poly |= 1L << (31 - p[n]); if (first) {
first = 0;
for (n = 0; n < 256; n++) /* make exclusive-or pattern from polynomial (0xedb88320UL) */
{ poly = 0UL;
c = (uLong)n; for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
poly |= 1UL << (31 - p[n]);
/* generate a crc for every 8-bit value */
for (n = 0; n < 256; n++) {
c = (unsigned long)n;
for (k = 0; k < 8; k++) for (k = 0; k < 8; k++)
c = c & 1 ? poly ^ (c >> 1) : c >> 1; c = c & 1 ? poly ^ (c >> 1) : c >> 1;
crc_table[n] = c; crc_table[0][n] = c;
} }
#ifdef BYFOUR
/* generate crc for each value followed by one, two, and three zeros,
and then the byte reversal of those as well as the first table */
for (n = 0; n < 256; n++) {
c = crc_table[0][n];
crc_table[4][n] = REV(c);
for (k = 1; k < 4; k++) {
c = crc_table[0][c & 0xff] ^ (c >> 8);
crc_table[k][n] = c;
crc_table[k + 4][n] = REV(c);
}
}
#endif /* BYFOUR */
crc_table_empty = 0; crc_table_empty = 0;
} }
#else else { /* not first */
/* wait for the other guy to finish (not efficient, but rare) */
while (crc_table_empty)
;
}
#ifdef MAKECRCH
/* write out CRC tables to crc32.h */
{
FILE *out;
out = fopen("crc32.h", "w");
if (out == NULL) return;
fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
fprintf(out, "local const unsigned long FAR ");
fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
write_table(out, crc_table[0]);
# ifdef BYFOUR
fprintf(out, "#ifdef BYFOUR\n");
for (k = 1; k < 8; k++) {
fprintf(out, " },\n {\n");
write_table(out, crc_table[k]);
}
fprintf(out, "#endif\n");
# endif /* BYFOUR */
fprintf(out, " }\n};\n");
fclose(out);
}
#endif /* MAKECRCH */
}
#ifdef MAKECRCH
local void write_table(out, table)
FILE *out;
const unsigned long FAR *table;
{
int n;
for (n = 0; n < 256; n++)
fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
}
#endif /* MAKECRCH */
#else /* !DYNAMIC_CRC_TABLE */
/* ======================================================================== /* ========================================================================
* Table of CRC-32's of all single-byte values (made by make_crc_table) * Tables of CRC-32s of all single-byte values, made by make_crc_table().
*/ */
local const uLongf crc_table[256] = { #include "crc32.h"
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, #endif /* DYNAMIC_CRC_TABLE */
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
0x2d02ef8dL
};
#endif
/* ========================================================================= /* =========================================================================
* This function can be used by asm versions of crc32() * This function can be used by asm versions of crc32()
*/ */
const uLongf * ZEXPORT get_crc_table() const unsigned long FAR * ZEXPORT get_crc_table()
{ {
#ifdef DYNAMIC_CRC_TABLE
if (crc_table_empty) make_crc_table();
#endif
return (const uLongf *)crc_table;
}
/* ========================================================================= */
#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
#define DO2(buf) DO1(buf); DO1(buf);
#define DO4(buf) DO2(buf); DO2(buf);
#define DO8(buf) DO4(buf); DO4(buf);
/* ========================================================================= */
uLong ZEXPORT crc32(crc, buf, len)
uLong crc;
const Bytef *buf;
uInt len;
{
if (buf == Z_NULL) return 0L;
#ifdef DYNAMIC_CRC_TABLE #ifdef DYNAMIC_CRC_TABLE
if (crc_table_empty) if (crc_table_empty)
make_crc_table(); make_crc_table();
#endif #endif /* DYNAMIC_CRC_TABLE */
crc = crc ^ 0xffffffffL; return (const unsigned long FAR *)crc_table;
while (len >= 8) }
/* ========================================================================= */
#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
/* ========================================================================= */
unsigned long ZEXPORT crc32(crc, buf, len)
unsigned long crc;
const unsigned char FAR *buf;
unsigned len;
{ {
DO8(buf); if (buf == Z_NULL) return 0UL;
#ifdef DYNAMIC_CRC_TABLE
if (crc_table_empty)
make_crc_table();
#endif /* DYNAMIC_CRC_TABLE */
#ifdef BYFOUR
if (sizeof(void *) == sizeof(ptrdiff_t)) {
u4 endian;
endian = 1;
if (*((unsigned char *)(&endian)))
return crc32_little(crc, buf, len);
else
return crc32_big(crc, buf, len);
}
#endif /* BYFOUR */
crc = crc ^ 0xffffffffUL;
while (len >= 8) {
DO8;
len -= 8; len -= 8;
} }
if (len) do { if (len) do {
DO1(buf); DO1;
} while (--len); } while (--len);
return crc ^ 0xffffffffL; return crc ^ 0xffffffffUL;
}
#ifdef BYFOUR
/* ========================================================================= */
#define DOLIT4 c ^= *buf4++; \
c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
/* ========================================================================= */
local unsigned long crc32_little(crc, buf, len)
unsigned long crc;
const unsigned char FAR *buf;
unsigned len;
{
register u4 c;
register const u4 FAR *buf4;
c = (u4)crc;
c = ~c;
while (len && ((ptrdiff_t)buf & 3)) {
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
len--;
}
buf4 = (const u4 FAR *)(const void FAR *)buf;
while (len >= 32) {
DOLIT32;
len -= 32;
}
while (len >= 4) {
DOLIT4;
len -= 4;
}
buf = (const unsigned char FAR *)buf4;
if (len) do {
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
} while (--len);
c = ~c;
return (unsigned long)c;
}
/* ========================================================================= */
#define DOBIG4 c ^= *++buf4; \
c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
/* ========================================================================= */
local unsigned long crc32_big(crc, buf, len)
unsigned long crc;
const unsigned char FAR *buf;
unsigned len;
{
register u4 c;
register const u4 FAR *buf4;
c = REV((u4)crc);
c = ~c;
while (len && ((ptrdiff_t)buf & 3)) {
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
len--;
}
buf4 = (const u4 FAR *)(const void FAR *)buf;
buf4--;
while (len >= 32) {
DOBIG32;
len -= 32;
}
while (len >= 4) {
DOBIG4;
len -= 4;
}
buf4++;
buf = (const unsigned char FAR *)buf4;
if (len) do {
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
} while (--len);
c = ~c;
return (unsigned long)(REV(c));
}
#endif /* BYFOUR */
#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
/* ========================================================================= */
local unsigned long gf2_matrix_times(mat, vec)
unsigned long *mat;
unsigned long vec;
{
unsigned long sum;
sum = 0;
while (vec) {
if (vec & 1)
sum ^= *mat;
vec >>= 1;
mat++;
}
return sum;
}
/* ========================================================================= */
local void gf2_matrix_square(square, mat)
unsigned long *square;
unsigned long *mat;
{
int n;
for (n = 0; n < GF2_DIM; n++)
square[n] = gf2_matrix_times(mat, mat[n]);
}
/* ========================================================================= */
uLong ZEXPORT crc32_combine(crc1, crc2, len2)
uLong crc1;
uLong crc2;
z_off_t len2;
{
int n;
unsigned long row;
unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
/* degenerate case */
if (len2 == 0)
return crc1;
/* put operator for one zero bit in odd */
odd[0] = 0xedb88320L; /* CRC-32 polynomial */
row = 1;
for (n = 1; n < GF2_DIM; n++) {
odd[n] = row;
row <<= 1;
}
/* put operator for two zero bits in even */
gf2_matrix_square(even, odd);
/* put operator for four zero bits in odd */
gf2_matrix_square(odd, even);
/* apply len2 zeros to crc1 (first square will put the operator for one
zero byte, eight zero bits, in even) */
do {
/* apply zeros operator for this bit of len2 */
gf2_matrix_square(even, odd);
if (len2 & 1)
crc1 = gf2_matrix_times(even, crc1);
len2 >>= 1;
/* if no more bits set, then done */
if (len2 == 0)
break;
/* another iteration of the loop with odd and even swapped */
gf2_matrix_square(odd, even);
if (len2 & 1)
crc1 = gf2_matrix_times(odd, crc1);
len2 >>= 1;
/* if no more bits set, then done */
} while (len2 != 0);
/* return combined crc */
crc1 ^= crc2;
return crc1;
} }

441
crc32.h Normal file
View File

@@ -0,0 +1,441 @@
/* crc32.h -- tables for rapid CRC calculation
* Generated automatically by crc32.c
*/
local const unsigned long FAR crc_table[TBLS][256] =
{
{
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
0x2d02ef8dUL
#ifdef BYFOUR
},
{
0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
0x9324fd72UL
},
{
0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
0xbe9834edUL
},
{
0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
0xde0506f1UL
},
{
0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
0x8def022dUL
},
{
0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
0x72fd2493UL
},
{
0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
0xed3498beUL
},
{
0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
0xf10605deUL
#endif
}
};

508
deflate.c
View File

@@ -1,5 +1,5 @@
/* deflate.c -- compress data using the deflation algorithm /* deflate.c -- compress data using the deflation algorithm
* Copyright (C) 1995-1998 Jean-loup Gailly. * Copyright (C) 1995-2005 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -37,7 +37,7 @@
* REFERENCES * REFERENCES
* *
* Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
* Available in ftp://ds.internic.net/rfc/rfc1951.txt * Available in http://www.ietf.org/rfc/rfc1951.txt
* *
* A description of the Rabin and Karp algorithm is given in the book * A description of the Rabin and Karp algorithm is given in the book
* "Algorithms" by R. Sedgewick, Addison-Wesley, p252. * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
@@ -52,7 +52,7 @@
#include "deflate.h" #include "deflate.h"
const char deflate_copyright[] = const char deflate_copyright[] =
" deflate 1.1.3pc Copyright 1995-1998 Jean-loup Gailly "; " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly ";
/* /*
If you use the zlib library in a product, an acknowledgment is welcome If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot in the documentation of your product. If for some reason you cannot
@@ -76,17 +76,22 @@ typedef block_state (*compress_func) OF((deflate_state *s, int flush));
local void fill_window OF((deflate_state *s)); local void fill_window OF((deflate_state *s));
local block_state deflate_stored OF((deflate_state *s, int flush)); local block_state deflate_stored OF((deflate_state *s, int flush));
local block_state deflate_fast OF((deflate_state *s, int flush)); local block_state deflate_fast OF((deflate_state *s, int flush));
#ifndef FASTEST
local block_state deflate_slow OF((deflate_state *s, int flush)); local block_state deflate_slow OF((deflate_state *s, int flush));
#endif
local void lm_init OF((deflate_state *s)); local void lm_init OF((deflate_state *s));
local void putShortMSB OF((deflate_state *s, uInt b)); local void putShortMSB OF((deflate_state *s, uInt b));
local void flush_pending OF((z_streamp strm)); local void flush_pending OF((z_streamp strm));
local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
#ifndef FASTEST
#ifdef ASMV #ifdef ASMV
void match_init OF((void)); /* asm code initialization */ void match_init OF((void)); /* asm code initialization */
uInt longest_match OF((deflate_state *s, IPos cur_match)); uInt longest_match OF((deflate_state *s, IPos cur_match));
#else #else
local uInt longest_match OF((deflate_state *s, IPos cur_match)); local uInt longest_match OF((deflate_state *s, IPos cur_match));
#endif #endif
#endif
local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
#ifdef DEBUG #ifdef DEBUG
local void check_match OF((deflate_state *s, IPos start, IPos match, local void check_match OF((deflate_state *s, IPos start, IPos match,
@@ -123,10 +128,16 @@ typedef struct config_s {
compress_func func; compress_func func;
} config; } config;
#ifdef FASTEST
local const config configuration_table[2] = {
/* good lazy nice chain */
/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */
#else
local const config configuration_table[10] = { local const config configuration_table[10] = {
/* good lazy nice chain */ /* good lazy nice chain */
/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */ /* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */
/* 2 */ {4, 5, 16, 8, deflate_fast}, /* 2 */ {4, 5, 16, 8, deflate_fast},
/* 3 */ {4, 6, 32, 32, deflate_fast}, /* 3 */ {4, 6, 32, 32, deflate_fast},
@@ -135,7 +146,8 @@ local const config configuration_table[10] = {
/* 6 */ {8, 16, 128, 128, deflate_slow}, /* 6 */ {8, 16, 128, 128, deflate_slow},
/* 7 */ {8, 32, 128, 256, deflate_slow}, /* 7 */ {8, 32, 128, 256, deflate_slow},
/* 8 */ {32, 128, 258, 1024, deflate_slow}, /* 8 */ {32, 128, 258, 1024, deflate_slow},
/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */ /* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
#endif
/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
* For deflate_fast() (levels <= 3) good is ignored and lazy has a different * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
@@ -145,7 +157,9 @@ local const config configuration_table[10] = {
#define EQUAL 0 #define EQUAL 0
/* result of memcmp for equal strings */ /* result of memcmp for equal strings */
#ifndef NO_DUMMY_DECL
struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
#endif
/* =========================================================================== /* ===========================================================================
* Update a hash value with the given input byte * Update a hash value with the given input byte
@@ -174,7 +188,7 @@ struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
#else #else
#define INSERT_STRING(s, str, match_head) \ #define INSERT_STRING(s, str, match_head) \
(UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
s->head[s->ins_h] = (Pos)(str)) s->head[s->ins_h] = (Pos)(str))
#endif #endif
@@ -211,8 +225,8 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
int stream_size; int stream_size;
{ {
deflate_state *s; deflate_state *s;
int noheader = 0; int wrap = 1;
static const char* my_version = ZLIB_VERSION; static const char my_version[] = ZLIB_VERSION;
ushf *overlay; ushf *overlay;
/* We overlay pending_buf and d_buf+l_buf. This works since the average /* We overlay pending_buf and d_buf+l_buf. This works since the average
@@ -226,33 +240,41 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
if (strm == Z_NULL) return Z_STREAM_ERROR; if (strm == Z_NULL) return Z_STREAM_ERROR;
strm->msg = Z_NULL; strm->msg = Z_NULL;
if (strm->zalloc == Z_NULL) { if (strm->zalloc == (alloc_func)0) {
strm->zalloc = zcalloc; strm->zalloc = zcalloc;
strm->opaque = (voidpf)0; strm->opaque = (voidpf)0;
} }
if (strm->zfree == Z_NULL) strm->zfree = zcfree; if (strm->zfree == (free_func)0) strm->zfree = zcfree;
#ifdef FASTEST #ifdef FASTEST
level = 1; if (level != 0) level = 1;
#else #else
if (level == Z_DEFAULT_COMPRESSION) level = 6; if (level == Z_DEFAULT_COMPRESSION) level = 6;
#endif #endif
if (windowBits < 0) { /* undocumented feature: suppress zlib header */ if (windowBits < 0) { /* suppress zlib wrapper */
noheader = 1; wrap = 0;
windowBits = -windowBits; windowBits = -windowBits;
} }
#ifdef GZIP
else if (windowBits > 15) {
wrap = 2; /* write gzip wrapper instead */
windowBits -= 16;
}
#endif
if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
strategy < 0 || strategy > Z_HUFFMAN_ONLY) { strategy < 0 || strategy > Z_FIXED) {
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
} }
if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
if (s == Z_NULL) return Z_MEM_ERROR; if (s == Z_NULL) return Z_MEM_ERROR;
strm->state = (struct internal_state FAR *)s; strm->state = (struct internal_state FAR *)s;
s->strm = strm; s->strm = strm;
s->noheader = noheader; s->wrap = wrap;
s->gzhead = Z_NULL;
s->w_bits = windowBits; s->w_bits = windowBits;
s->w_size = 1 << s->w_bits; s->w_size = 1 << s->w_bits;
s->w_mask = s->w_size - 1; s->w_mask = s->w_size - 1;
@@ -262,10 +284,8 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
s->hash_mask = s->hash_size - 1; s->hash_mask = s->hash_size - 1;
s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
s->window = (Bytef *) ZALLOC(strm, (windowBits == 8 ? 264 : s->w_size), s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
2*sizeof(Byte)); s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
s->prev = (Posf *) ZALLOC(strm, (windowBits == 8 ? 264 : s->w_size),
sizeof(Pos));
s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
@@ -276,6 +296,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
s->pending_buf == Z_NULL) { s->pending_buf == Z_NULL) {
s->status = FINISH_STATE;
strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
deflateEnd (strm); deflateEnd (strm);
return Z_MEM_ERROR; return Z_MEM_ERROR;
@@ -302,17 +323,18 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
IPos hash_head = 0; IPos hash_head = 0;
if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
strm->state->status != INIT_STATE) return Z_STREAM_ERROR; strm->state->wrap == 2 ||
(strm->state->wrap == 1 && strm->state->status != INIT_STATE))
return Z_STREAM_ERROR;
s = strm->state; s = strm->state;
if (s->wrap)
strm->adler = adler32(strm->adler, dictionary, dictLength); strm->adler = adler32(strm->adler, dictionary, dictLength);
if (length < MIN_MATCH) return Z_OK; if (length < MIN_MATCH) return Z_OK;
if (length > MAX_DIST(s)) { if (length > MAX_DIST(s)) {
length = MAX_DIST(s); length = MAX_DIST(s);
#ifndef USE_DICT_HEAD
dictionary += dictLength - length; /* use the tail of the dictionary */ dictionary += dictLength - length; /* use the tail of the dictionary */
#endif
} }
zmemcpy(s->window, dictionary, length); zmemcpy(s->window, dictionary, length);
s->strstart = length; s->strstart = length;
@@ -338,7 +360,9 @@ int ZEXPORT deflateReset (strm)
deflate_state *s; deflate_state *s;
if (strm == Z_NULL || strm->state == Z_NULL || if (strm == Z_NULL || strm->state == Z_NULL ||
strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR; strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
return Z_STREAM_ERROR;
}
strm->total_in = strm->total_out = 0; strm->total_in = strm->total_out = 0;
strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
@@ -348,11 +372,15 @@ int ZEXPORT deflateReset (strm)
s->pending = 0; s->pending = 0;
s->pending_out = s->pending_buf; s->pending_out = s->pending_buf;
if (s->noheader < 0) { if (s->wrap < 0) {
s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
} }
s->status = s->noheader ? BUSY_STATE : INIT_STATE; s->status = s->wrap ? INIT_STATE : BUSY_STATE;
strm->adler = 1; strm->adler =
#ifdef GZIP
s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
#endif
adler32(0L, Z_NULL, 0);
s->last_flush = Z_NO_FLUSH; s->last_flush = Z_NO_FLUSH;
_tr_init(s); _tr_init(s);
@@ -361,6 +389,29 @@ int ZEXPORT deflateReset (strm)
return Z_OK; return Z_OK;
} }
/* ========================================================================= */
int ZEXPORT deflateSetHeader (strm, head)
z_streamp strm;
gz_headerp head;
{
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
if (strm->state->wrap != 2) return Z_STREAM_ERROR;
strm->state->gzhead = head;
return Z_OK;
}
/* ========================================================================= */
int ZEXPORT deflatePrime (strm, bits, value)
z_streamp strm;
int bits;
int value;
{
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
strm->state->bi_valid = bits;
strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
return Z_OK;
}
/* ========================================================================= */ /* ========================================================================= */
int ZEXPORT deflateParams(strm, level, strategy) int ZEXPORT deflateParams(strm, level, strategy)
z_streamp strm; z_streamp strm;
@@ -374,10 +425,12 @@ int ZEXPORT deflateParams(strm, level, strategy)
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
s = strm->state; s = strm->state;
if (level == Z_DEFAULT_COMPRESSION) { #ifdef FASTEST
level = 6; if (level != 0) level = 1;
} #else
if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { if (level == Z_DEFAULT_COMPRESSION) level = 6;
#endif
if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
} }
func = configuration_table[s->level].func; func = configuration_table[s->level].func;
@@ -397,6 +450,66 @@ int ZEXPORT deflateParams(strm, level, strategy)
return err; return err;
} }
/* ========================================================================= */
int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
z_streamp strm;
int good_length;
int max_lazy;
int nice_length;
int max_chain;
{
deflate_state *s;
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
s = strm->state;
s->good_match = good_length;
s->max_lazy_match = max_lazy;
s->nice_match = nice_length;
s->max_chain_length = max_chain;
return Z_OK;
}
/* =========================================================================
* For the default windowBits of 15 and memLevel of 8, this function returns
* a close to exact, as well as small, upper bound on the compressed size.
* They are coded as constants here for a reason--if the #define's are
* changed, then this function needs to be changed as well. The return
* value for 15 and 8 only works for those exact settings.
*
* For any setting other than those defaults for windowBits and memLevel,
* the value returned is a conservative worst case for the maximum expansion
* resulting from using fixed blocks instead of stored blocks, which deflate
* can emit on compressed data for some combinations of the parameters.
*
* This function could be more sophisticated to provide closer upper bounds
* for every combination of windowBits and memLevel, as well as wrap.
* But even the conservative upper bound of about 14% expansion does not
* seem onerous for output buffer allocation.
*/
uLong ZEXPORT deflateBound(strm, sourceLen)
z_streamp strm;
uLong sourceLen;
{
deflate_state *s;
uLong destLen;
/* conservative upper bound */
destLen = sourceLen +
((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
/* if can't get parameters, return conservative bound */
if (strm == Z_NULL || strm->state == Z_NULL)
return destLen;
/* if not default parameters, return conservative bound */
s = strm->state;
if (s->w_bits != 15 || s->hash_bits != 8 + 7)
return destLen;
/* default settings: return tight bound for that case */
return compressBound(sourceLen);
}
/* ========================================================================= /* =========================================================================
* Put a short in the pending buffer. The 16-bit value is put in MSB order. * Put a short in the pending buffer. The 16-bit value is put in MSB order.
* IN assertion: the stream state is correct and there is enough room in * IN assertion: the stream state is correct and there is enough room in
@@ -460,13 +573,66 @@ int ZEXPORT deflate (strm, flush)
old_flush = s->last_flush; old_flush = s->last_flush;
s->last_flush = flush; s->last_flush = flush;
/* Write the zlib header */ /* Write the header */
if (s->status == INIT_STATE) { if (s->status == INIT_STATE) {
#ifdef GZIP
if (s->wrap == 2) {
strm->adler = crc32(0L, Z_NULL, 0);
put_byte(s, 31);
put_byte(s, 139);
put_byte(s, 8);
if (s->gzhead == NULL) {
put_byte(s, 0);
put_byte(s, 0);
put_byte(s, 0);
put_byte(s, 0);
put_byte(s, 0);
put_byte(s, s->level == 9 ? 2 :
(s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
4 : 0));
put_byte(s, OS_CODE);
s->status = BUSY_STATE;
}
else {
put_byte(s, (s->gzhead->text ? 1 : 0) +
(s->gzhead->hcrc ? 2 : 0) +
(s->gzhead->extra == Z_NULL ? 0 : 4) +
(s->gzhead->name == Z_NULL ? 0 : 8) +
(s->gzhead->comment == Z_NULL ? 0 : 16)
);
put_byte(s, (Byte)(s->gzhead->time & 0xff));
put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
put_byte(s, s->level == 9 ? 2 :
(s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
4 : 0));
put_byte(s, s->gzhead->os & 0xff);
if (s->gzhead->extra != NULL) {
put_byte(s, s->gzhead->extra_len & 0xff);
put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
}
if (s->gzhead->hcrc)
strm->adler = crc32(strm->adler, s->pending_buf,
s->pending);
s->gzindex = 0;
s->status = EXTRA_STATE;
}
}
else
#endif
{
uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
uInt level_flags = (s->level-1) >> 1; uInt level_flags;
if (level_flags > 3) level_flags = 3; if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
level_flags = 0;
else if (s->level < 6)
level_flags = 1;
else if (s->level == 6)
level_flags = 2;
else
level_flags = 3;
header |= (level_flags << 6); header |= (level_flags << 6);
if (s->strstart != 0) header |= PRESET_DICT; if (s->strstart != 0) header |= PRESET_DICT;
header += 31 - (header % 31); header += 31 - (header % 31);
@@ -479,8 +645,113 @@ int ZEXPORT deflate (strm, flush)
putShortMSB(s, (uInt)(strm->adler >> 16)); putShortMSB(s, (uInt)(strm->adler >> 16));
putShortMSB(s, (uInt)(strm->adler & 0xffff)); putShortMSB(s, (uInt)(strm->adler & 0xffff));
} }
strm->adler = 1L; strm->adler = adler32(0L, Z_NULL, 0);
} }
}
#ifdef GZIP
if (s->status == EXTRA_STATE) {
if (s->gzhead->extra != NULL) {
uInt beg = s->pending; /* start of bytes to update crc */
while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
if (s->pending == s->pending_buf_size) {
if (s->gzhead->hcrc && s->pending > beg)
strm->adler = crc32(strm->adler, s->pending_buf + beg,
s->pending - beg);
flush_pending(strm);
beg = s->pending;
if (s->pending == s->pending_buf_size)
break;
}
put_byte(s, s->gzhead->extra[s->gzindex]);
s->gzindex++;
}
if (s->gzhead->hcrc && s->pending > beg)
strm->adler = crc32(strm->adler, s->pending_buf + beg,
s->pending - beg);
if (s->gzindex == s->gzhead->extra_len) {
s->gzindex = 0;
s->status = NAME_STATE;
}
}
else
s->status = NAME_STATE;
}
if (s->status == NAME_STATE) {
if (s->gzhead->name != NULL) {
uInt beg = s->pending; /* start of bytes to update crc */
int val;
do {
if (s->pending == s->pending_buf_size) {
if (s->gzhead->hcrc && s->pending > beg)
strm->adler = crc32(strm->adler, s->pending_buf + beg,
s->pending - beg);
flush_pending(strm);
beg = s->pending;
if (s->pending == s->pending_buf_size) {
val = 1;
break;
}
}
val = s->gzhead->name[s->gzindex++];
put_byte(s, val);
} while (val != 0);
if (s->gzhead->hcrc && s->pending > beg)
strm->adler = crc32(strm->adler, s->pending_buf + beg,
s->pending - beg);
if (val == 0) {
s->gzindex = 0;
s->status = COMMENT_STATE;
}
}
else
s->status = COMMENT_STATE;
}
if (s->status == COMMENT_STATE) {
if (s->gzhead->comment != NULL) {
uInt beg = s->pending; /* start of bytes to update crc */
int val;
do {
if (s->pending == s->pending_buf_size) {
if (s->gzhead->hcrc && s->pending > beg)
strm->adler = crc32(strm->adler, s->pending_buf + beg,
s->pending - beg);
flush_pending(strm);
beg = s->pending;
if (s->pending == s->pending_buf_size) {
val = 1;
break;
}
}
val = s->gzhead->comment[s->gzindex++];
put_byte(s, val);
} while (val != 0);
if (s->gzhead->hcrc && s->pending > beg)
strm->adler = crc32(strm->adler, s->pending_buf + beg,
s->pending - beg);
if (val == 0)
s->status = HCRC_STATE;
}
else
s->status = HCRC_STATE;
}
if (s->status == HCRC_STATE) {
if (s->gzhead->hcrc) {
if (s->pending + 2 > s->pending_buf_size)
flush_pending(strm);
if (s->pending + 2 <= s->pending_buf_size) {
put_byte(s, (Byte)(strm->adler & 0xff));
put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
strm->adler = crc32(0L, Z_NULL, 0);
s->status = BUSY_STATE;
}
}
else
s->status = BUSY_STATE;
}
#endif
/* Flush as much pending output as possible */ /* Flush as much pending output as possible */
if (s->pending != 0) { if (s->pending != 0) {
@@ -498,7 +769,7 @@ int ZEXPORT deflate (strm, flush)
/* Make sure there is something to do and avoid duplicate consecutive /* Make sure there is something to do and avoid duplicate consecutive
* flushes. For repeated and useless calls with Z_FINISH, we keep * flushes. For repeated and useless calls with Z_FINISH, we keep
* returning Z_STREAM_END instead of Z_BUFF_ERROR. * returning Z_STREAM_END instead of Z_BUF_ERROR.
*/ */
} else if (strm->avail_in == 0 && flush <= old_flush && } else if (strm->avail_in == 0 && flush <= old_flush &&
flush != Z_FINISH) { flush != Z_FINISH) {
@@ -556,16 +827,31 @@ int ZEXPORT deflate (strm, flush)
Assert(strm->avail_out > 0, "bug2"); Assert(strm->avail_out > 0, "bug2");
if (flush != Z_FINISH) return Z_OK; if (flush != Z_FINISH) return Z_OK;
if (s->noheader) return Z_STREAM_END; if (s->wrap <= 0) return Z_STREAM_END;
/* Write the zlib trailer (adler32) */ /* Write the trailer */
#ifdef GZIP
if (s->wrap == 2) {
put_byte(s, (Byte)(strm->adler & 0xff));
put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
put_byte(s, (Byte)(strm->total_in & 0xff));
put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
}
else
#endif
{
putShortMSB(s, (uInt)(strm->adler >> 16)); putShortMSB(s, (uInt)(strm->adler >> 16));
putShortMSB(s, (uInt)(strm->adler & 0xffff)); putShortMSB(s, (uInt)(strm->adler & 0xffff));
}
flush_pending(strm); flush_pending(strm);
/* If avail_out is zero, the application will call deflate again /* If avail_out is zero, the application will call deflate again
* to flush the rest. * to flush the rest.
*/ */
s->noheader = -1; /* write the trailer only once! */ if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
return s->pending != 0 ? Z_OK : Z_STREAM_END; return s->pending != 0 ? Z_OK : Z_STREAM_END;
} }
@@ -578,7 +864,12 @@ int ZEXPORT deflateEnd (strm)
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
status = strm->state->status; status = strm->state->status;
if (status != INIT_STATE && status != BUSY_STATE && if (status != INIT_STATE &&
status != EXTRA_STATE &&
status != NAME_STATE &&
status != COMMENT_STATE &&
status != HCRC_STATE &&
status != BUSY_STATE &&
status != FINISH_STATE) { status != FINISH_STATE) {
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
} }
@@ -618,12 +909,12 @@ int ZEXPORT deflateCopy (dest, source)
ss = source->state; ss = source->state;
*dest = *source; zmemcpy(dest, source, sizeof(z_stream));
ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
if (ds == Z_NULL) return Z_MEM_ERROR; if (ds == Z_NULL) return Z_MEM_ERROR;
dest->state = (struct internal_state FAR *) ds; dest->state = (struct internal_state FAR *) ds;
*ds = *ss; zmemcpy(ds, ss, sizeof(deflate_state));
ds->strm = dest; ds->strm = dest;
ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
@@ -652,7 +943,7 @@ int ZEXPORT deflateCopy (dest, source)
ds->bl_desc.dyn_tree = ds->bl_tree; ds->bl_desc.dyn_tree = ds->bl_tree;
return Z_OK; return Z_OK;
#endif #endif /* MAXSEG_64K */
} }
/* =========================================================================== /* ===========================================================================
@@ -674,9 +965,14 @@ local int read_buf(strm, buf, size)
strm->avail_in -= len; strm->avail_in -= len;
if (!strm->state->noheader) { if (strm->state->wrap == 1) {
strm->adler = adler32(strm->adler, strm->next_in, len); strm->adler = adler32(strm->adler, strm->next_in, len);
} }
#ifdef GZIP
else if (strm->state->wrap == 2) {
strm->adler = crc32(strm->adler, strm->next_in, len);
}
#endif
zmemcpy(buf, strm->next_in, len); zmemcpy(buf, strm->next_in, len);
strm->next_in += len; strm->next_in += len;
strm->total_in += len; strm->total_in += len;
@@ -707,11 +1003,14 @@ local void lm_init (s)
s->match_length = s->prev_length = MIN_MATCH-1; s->match_length = s->prev_length = MIN_MATCH-1;
s->match_available = 0; s->match_available = 0;
s->ins_h = 0; s->ins_h = 0;
#ifndef FASTEST
#ifdef ASMV #ifdef ASMV
match_init(); /* initialize the asm code */ match_init(); /* initialize the asm code */
#endif #endif
#endif
} }
#ifndef FASTEST
/* =========================================================================== /* ===========================================================================
* Set match_start to the longest match starting at the given string and * Set match_start to the longest match starting at the given string and
* return its length. Matches shorter or equal to prev_length are discarded, * return its length. Matches shorter or equal to prev_length are discarded,
@@ -725,7 +1024,6 @@ local void lm_init (s)
/* For 80x86 and 680x0, an optimized version will be provided in match.asm or /* For 80x86 and 680x0, an optimized version will be provided in match.asm or
* match.S. The code will be functionally equivalent. * match.S. The code will be functionally equivalent.
*/ */
#ifndef FASTEST
local uInt longest_match(s, cur_match) local uInt longest_match(s, cur_match)
deflate_state *s; deflate_state *s;
IPos cur_match; /* current match */ IPos cur_match; /* current match */
@@ -778,7 +1076,12 @@ local uInt longest_match(s, cur_match)
match = s->window + cur_match; match = s->window + cur_match;
/* Skip to next match if the match length cannot increase /* Skip to next match if the match length cannot increase
* or if the match length is less than 2: * or if the match length is less than 2. Note that the checks below
* for insufficient lookahead only occur occasionally for performance
* reasons. Therefore uninitialized memory will be accessed, and
* conditional jumps will be made that depend on those values.
* However the length of the match is limited to the lookahead, so
* the output of deflate is not affected by the uninitialized values.
*/ */
#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) #if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
/* This code assumes sizeof(unsigned short) == 2. Do not use /* This code assumes sizeof(unsigned short) == 2. Do not use
@@ -863,12 +1166,13 @@ local uInt longest_match(s, cur_match)
if ((uInt)best_len <= s->lookahead) return (uInt)best_len; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
return s->lookahead; return s->lookahead;
} }
#endif /* ASMV */
#endif /* FASTEST */
#else /* FASTEST */
/* --------------------------------------------------------------------------- /* ---------------------------------------------------------------------------
* Optimized version for level == 1 only * Optimized version for level == 1 or strategy == Z_RLE only
*/ */
local uInt longest_match(s, cur_match) local uInt longest_match_fast(s, cur_match)
deflate_state *s; deflate_state *s;
IPos cur_match; /* current match */ IPos cur_match; /* current match */
{ {
@@ -918,10 +1222,8 @@ local uInt longest_match(s, cur_match)
if (len < MIN_MATCH) return MIN_MATCH - 1; if (len < MIN_MATCH) return MIN_MATCH - 1;
s->match_start = cur_match; s->match_start = cur_match;
return len <= s->lookahead ? len : s->lookahead; return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
} }
#endif /* FASTEST */
#endif /* ASMV */
#ifdef DEBUG #ifdef DEBUG
/* =========================================================================== /* ===========================================================================
@@ -949,7 +1251,7 @@ local void check_match(s, start, match, length)
} }
#else #else
# define check_match(s, start, match, length) # define check_match(s, start, match, length)
#endif #endif /* DEBUG */
/* =========================================================================== /* ===========================================================================
* Fill the window when the lookahead becomes insufficient. * Fill the window when the lookahead becomes insufficient.
@@ -973,19 +1275,22 @@ local void fill_window(s)
more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
/* Deal with !@#$% 64K limit: */ /* Deal with !@#$% 64K limit: */
if (sizeof(int) <= 2) {
if (more == 0 && s->strstart == 0 && s->lookahead == 0) { if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
more = wsize; more = wsize;
} else if (more == (unsigned)(-1)) { } else if (more == (unsigned)(-1)) {
/* Very unlikely, but possible on 16 bit machine if strstart == 0 /* Very unlikely, but possible on 16 bit machine if
* and lookahead == 1 (input done one byte at time) * strstart == 0 && lookahead == 1 (input done a byte at time)
*/ */
more--; more--;
}
}
/* If the window is almost full and there is insufficient lookahead, /* If the window is almost full and there is insufficient lookahead,
* move the upper half to the lower one to make room in the upper half. * move the upper half to the lower one to make room in the upper half.
*/ */
} else if (s->strstart >= wsize+MAX_DIST(s)) { if (s->strstart >= wsize+MAX_DIST(s)) {
zmemcpy(s->window, s->window+wsize, (unsigned)wsize); zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
s->match_start -= wsize; s->match_start -= wsize;
@@ -998,6 +1303,7 @@ local void fill_window(s)
later. (Using level 0 permanently is not an optimal usage of later. (Using level 0 permanently is not an optimal usage of
zlib, so we don't care about this pathological case.) zlib, so we don't care about this pathological case.)
*/ */
/* %%% avoid this when Z_RLE */
n = s->hash_size; n = s->hash_size;
p = &s->head[n]; p = &s->head[n];
do { do {
@@ -1175,10 +1481,19 @@ local block_state deflate_fast(s, flush)
* of window index 0 (in particular we have to avoid a match * of window index 0 (in particular we have to avoid a match
* of the string with itself at the start of the input file). * of the string with itself at the start of the input file).
*/ */
if (s->strategy != Z_HUFFMAN_ONLY) { #ifdef FASTEST
s->match_length = longest_match (s, hash_head); if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
(s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
s->match_length = longest_match_fast (s, hash_head);
} }
/* longest_match() sets match_start */ #else
if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
s->match_length = longest_match (s, hash_head);
} else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
s->match_length = longest_match_fast (s, hash_head);
}
#endif
/* longest_match() or longest_match_fast() sets match_start */
} }
if (s->match_length >= MIN_MATCH) { if (s->match_length >= MIN_MATCH) {
check_match(s, s->strstart, s->match_start, s->match_length); check_match(s, s->strstart, s->match_start, s->match_length);
@@ -1194,7 +1509,7 @@ local block_state deflate_fast(s, flush)
#ifndef FASTEST #ifndef FASTEST
if (s->match_length <= s->max_insert_length && if (s->match_length <= s->max_insert_length &&
s->lookahead >= MIN_MATCH) { s->lookahead >= MIN_MATCH) {
s->match_length--; /* string at strstart already in hash table */ s->match_length--; /* string at strstart already in table */
do { do {
s->strstart++; s->strstart++;
INSERT_STRING(s, s->strstart, hash_head); INSERT_STRING(s, s->strstart, hash_head);
@@ -1230,6 +1545,7 @@ local block_state deflate_fast(s, flush)
return flush == Z_FINISH ? finish_done : block_done; return flush == Z_FINISH ? finish_done : block_done;
} }
#ifndef FASTEST
/* =========================================================================== /* ===========================================================================
* Same as above, but achieves better compression. We use a lazy * Same as above, but achieves better compression. We use a lazy
* evaluation for matches: a match is finally adopted only if there is * evaluation for matches: a match is finally adopted only if there is
@@ -1275,13 +1591,15 @@ local block_state deflate_slow(s, flush)
* of window index 0 (in particular we have to avoid a match * of window index 0 (in particular we have to avoid a match
* of the string with itself at the start of the input file). * of the string with itself at the start of the input file).
*/ */
if (s->strategy != Z_HUFFMAN_ONLY) { if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
s->match_length = longest_match (s, hash_head); s->match_length = longest_match (s, hash_head);
} else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
s->match_length = longest_match_fast (s, hash_head);
} }
/* longest_match() sets match_start */ /* longest_match() or longest_match_fast() sets match_start */
if (s->match_length <= 5 && (s->strategy == Z_FILTERED if (s->match_length <= 5 && (s->strategy == Z_FILTERED
#if (TOO_FAR > 0 && TOO_FAR < 32767) #if TOO_FAR <= 32767
|| (s->match_length == MIN_MATCH && || (s->match_length == MIN_MATCH &&
s->strstart - s->match_start > TOO_FAR) s->strstart - s->match_start > TOO_FAR)
#endif #endif
@@ -1354,3 +1672,65 @@ local block_state deflate_slow(s, flush)
FLUSH_BLOCK(s, flush == Z_FINISH); FLUSH_BLOCK(s, flush == Z_FINISH);
return flush == Z_FINISH ? finish_done : block_done; return flush == Z_FINISH ? finish_done : block_done;
} }
#endif /* FASTEST */
#if 0
/* ===========================================================================
* For Z_RLE, simply look for runs of bytes, generate matches only of distance
* one. Do not maintain a hash table. (It will be regenerated if this run of
* deflate switches away from Z_RLE.)
*/
local block_state deflate_rle(s, flush)
deflate_state *s;
int flush;
{
int bflush; /* set if current block must be flushed */
uInt run; /* length of run */
uInt max; /* maximum length of run */
uInt prev; /* byte at distance one to match */
Bytef *scan; /* scan for end of run */
for (;;) {
/* Make sure that we always have enough lookahead, except
* at the end of the input file. We need MAX_MATCH bytes
* for the longest encodable run.
*/
if (s->lookahead < MAX_MATCH) {
fill_window(s);
if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
return need_more;
}
if (s->lookahead == 0) break; /* flush the current block */
}
/* See how many times the previous byte repeats */
run = 0;
if (s->strstart > 0) { /* if there is a previous byte, that is */
max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH;
scan = s->window + s->strstart - 1;
prev = *scan++;
do {
if (*scan++ != prev)
break;
} while (++run < max);
}
/* Emit match if have run of MIN_MATCH or longer, else emit literal */
if (run >= MIN_MATCH) {
check_match(s, s->strstart, s->strstart - 1, run);
_tr_tally_dist(s, 1, run - MIN_MATCH, bflush);
s->lookahead -= run;
s->strstart += run;
} else {
/* No match, output a literal byte */
Tracevv((stderr,"%c", s->window[s->strstart]));
_tr_tally_lit (s, s->window[s->strstart], bflush);
s->lookahead--;
s->strstart++;
}
if (bflush) FLUSH_BLOCK(s, 0);
}
FLUSH_BLOCK(s, flush == Z_FINISH);
return flush == Z_FINISH ? finish_done : block_done;
}
#endif

View File

@@ -1,5 +1,5 @@
/* deflate.h -- internal compression state /* deflate.h -- internal compression state
* Copyright (C) 1995-1998 Jean-loup Gailly * Copyright (C) 1995-2004 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -10,11 +10,19 @@
/* @(#) $Id$ */ /* @(#) $Id$ */
#ifndef _DEFLATE_H #ifndef DEFLATE_H
#define _DEFLATE_H #define DEFLATE_H
#include "zutil.h" #include "zutil.h"
/* define NO_GZIP when compiling if you want to disable gzip header and
trailer creation by deflate(). NO_GZIP would be used to avoid linking in
the crc code when it is not needed. For shared libraries, gzip encoding
should be left enabled. */
#ifndef NO_GZIP
# define GZIP
#endif
/* =========================================================================== /* ===========================================================================
* Internal compression state. * Internal compression state.
*/ */
@@ -41,6 +49,10 @@
/* All codes must not exceed MAX_BITS bits */ /* All codes must not exceed MAX_BITS bits */
#define INIT_STATE 42 #define INIT_STATE 42
#define EXTRA_STATE 69
#define NAME_STATE 73
#define COMMENT_STATE 91
#define HCRC_STATE 103
#define BUSY_STATE 113 #define BUSY_STATE 113
#define FINISH_STATE 666 #define FINISH_STATE 666
/* Stream status */ /* Stream status */
@@ -85,9 +97,10 @@ typedef struct internal_state {
Bytef *pending_buf; /* output still pending */ Bytef *pending_buf; /* output still pending */
ulg pending_buf_size; /* size of pending_buf */ ulg pending_buf_size; /* size of pending_buf */
Bytef *pending_out; /* next pending byte to output to the stream */ Bytef *pending_out; /* next pending byte to output to the stream */
int pending; /* nb of bytes in the pending buffer */ uInt pending; /* nb of bytes in the pending buffer */
int noheader; /* suppress zlib header and adler32 */ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
Byte data_type; /* UNKNOWN, BINARY or ASCII */ gz_headerp gzhead; /* gzip header information to write */
uInt gzindex; /* where in extra, name, or comment */
Byte method; /* STORED (for zip only) or DEFLATED */ Byte method; /* STORED (for zip only) or DEFLATED */
int last_flush; /* value of flush param for previous deflate call */ int last_flush; /* value of flush param for previous deflate call */
@@ -315,4 +328,4 @@ void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
flush = _tr_tally(s, distance, length) flush = _tr_tally(s, distance, length)
#endif #endif
#endif #endif /* DEFLATE_H */

565
example.c Normal file
View File

@@ -0,0 +1,565 @@
/* example.c -- usage example of the zlib compression library
* Copyright (C) 1995-2004 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#include <stdio.h>
#include "zlib.h"
#ifdef STDC
# include <string.h>
# include <stdlib.h>
#endif
#if defined(VMS) || defined(RISCOS)
# define TESTFILE "foo-gz"
#else
# define TESTFILE "foo.gz"
#endif
#define CHECK_ERR(err, msg) { \
if (err != Z_OK) { \
fprintf(stderr, "%s error: %d\n", msg, err); \
exit(1); \
} \
}
const char hello[] = "hello, hello!";
/* "hello world" would be more standard, but the repeated "hello"
* stresses the compression code better, sorry...
*/
const char dictionary[] = "hello";
uLong dictId; /* Adler32 value of the dictionary */
void test_compress OF((Byte *compr, uLong comprLen,
Byte *uncompr, uLong uncomprLen));
void test_gzio OF((const char *fname,
Byte *uncompr, uLong uncomprLen));
void test_deflate OF((Byte *compr, uLong comprLen));
void test_inflate OF((Byte *compr, uLong comprLen,
Byte *uncompr, uLong uncomprLen));
void test_large_deflate OF((Byte *compr, uLong comprLen,
Byte *uncompr, uLong uncomprLen));
void test_large_inflate OF((Byte *compr, uLong comprLen,
Byte *uncompr, uLong uncomprLen));
void test_flush OF((Byte *compr, uLong *comprLen));
void test_sync OF((Byte *compr, uLong comprLen,
Byte *uncompr, uLong uncomprLen));
void test_dict_deflate OF((Byte *compr, uLong comprLen));
void test_dict_inflate OF((Byte *compr, uLong comprLen,
Byte *uncompr, uLong uncomprLen));
int main OF((int argc, char *argv[]));
/* ===========================================================================
* Test compress() and uncompress()
*/
void test_compress(compr, comprLen, uncompr, uncomprLen)
Byte *compr, *uncompr;
uLong comprLen, uncomprLen;
{
int err;
uLong len = (uLong)strlen(hello)+1;
err = compress(compr, &comprLen, (const Bytef*)hello, len);
CHECK_ERR(err, "compress");
strcpy((char*)uncompr, "garbage");
err = uncompress(uncompr, &uncomprLen, compr, comprLen);
CHECK_ERR(err, "uncompress");
if (strcmp((char*)uncompr, hello)) {
fprintf(stderr, "bad uncompress\n");
exit(1);
} else {
printf("uncompress(): %s\n", (char *)uncompr);
}
}
/* ===========================================================================
* Test read/write of .gz files
*/
void test_gzio(fname, uncompr, uncomprLen)
const char *fname; /* compressed file name */
Byte *uncompr;
uLong uncomprLen;
{
#ifdef NO_GZCOMPRESS
fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
#else
int err;
int len = (int)strlen(hello)+1;
gzFile file;
z_off_t pos;
file = gzopen(fname, "wb");
if (file == NULL) {
fprintf(stderr, "gzopen error\n");
exit(1);
}
gzputc(file, 'h');
if (gzputs(file, "ello") != 4) {
fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
exit(1);
}
if (gzprintf(file, ", %s!", "hello") != 8) {
fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
exit(1);
}
gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
gzclose(file);
file = gzopen(fname, "rb");
if (file == NULL) {
fprintf(stderr, "gzopen error\n");
exit(1);
}
strcpy((char*)uncompr, "garbage");
if (gzread(file, uncompr, (unsigned)uncomprLen) != len) {
fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
exit(1);
}
if (strcmp((char*)uncompr, hello)) {
fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
exit(1);
} else {
printf("gzread(): %s\n", (char*)uncompr);
}
pos = gzseek(file, -8L, SEEK_CUR);
if (pos != 6 || gztell(file) != pos) {
fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
(long)pos, (long)gztell(file));
exit(1);
}
if (gzgetc(file) != ' ') {
fprintf(stderr, "gzgetc error\n");
exit(1);
}
if (gzungetc(' ', file) != ' ') {
fprintf(stderr, "gzungetc error\n");
exit(1);
}
gzgets(file, (char*)uncompr, (int)uncomprLen);
if (strlen((char*)uncompr) != 7) { /* " hello!" */
fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
exit(1);
}
if (strcmp((char*)uncompr, hello + 6)) {
fprintf(stderr, "bad gzgets after gzseek\n");
exit(1);
} else {
printf("gzgets() after gzseek: %s\n", (char*)uncompr);
}
gzclose(file);
#endif
}
/* ===========================================================================
* Test deflate() with small buffers
*/
void test_deflate(compr, comprLen)
Byte *compr;
uLong comprLen;
{
z_stream c_stream; /* compression stream */
int err;
uLong len = (uLong)strlen(hello)+1;
c_stream.zalloc = (alloc_func)0;
c_stream.zfree = (free_func)0;
c_stream.opaque = (voidpf)0;
err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
CHECK_ERR(err, "deflateInit");
c_stream.next_in = (Bytef*)hello;
c_stream.next_out = compr;
while (c_stream.total_in != len && c_stream.total_out < comprLen) {
c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
err = deflate(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate");
}
/* Finish the stream, still forcing small buffers: */
for (;;) {
c_stream.avail_out = 1;
err = deflate(&c_stream, Z_FINISH);
if (err == Z_STREAM_END) break;
CHECK_ERR(err, "deflate");
}
err = deflateEnd(&c_stream);
CHECK_ERR(err, "deflateEnd");
}
/* ===========================================================================
* Test inflate() with small buffers
*/
void test_inflate(compr, comprLen, uncompr, uncomprLen)
Byte *compr, *uncompr;
uLong comprLen, uncomprLen;
{
int err;
z_stream d_stream; /* decompression stream */
strcpy((char*)uncompr, "garbage");
d_stream.zalloc = (alloc_func)0;
d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
d_stream.next_in = compr;
d_stream.avail_in = 0;
d_stream.next_out = uncompr;
err = inflateInit(&d_stream);
CHECK_ERR(err, "inflateInit");
while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
err = inflate(&d_stream, Z_NO_FLUSH);
if (err == Z_STREAM_END) break;
CHECK_ERR(err, "inflate");
}
err = inflateEnd(&d_stream);
CHECK_ERR(err, "inflateEnd");
if (strcmp((char*)uncompr, hello)) {
fprintf(stderr, "bad inflate\n");
exit(1);
} else {
printf("inflate(): %s\n", (char *)uncompr);
}
}
/* ===========================================================================
* Test deflate() with large buffers and dynamic change of compression level
*/
void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
Byte *compr, *uncompr;
uLong comprLen, uncomprLen;
{
z_stream c_stream; /* compression stream */
int err;
c_stream.zalloc = (alloc_func)0;
c_stream.zfree = (free_func)0;
c_stream.opaque = (voidpf)0;
err = deflateInit(&c_stream, Z_BEST_SPEED);
CHECK_ERR(err, "deflateInit");
c_stream.next_out = compr;
c_stream.avail_out = (uInt)comprLen;
/* At this point, uncompr is still mostly zeroes, so it should compress
* very well:
*/
c_stream.next_in = uncompr;
c_stream.avail_in = (uInt)uncomprLen;
err = deflate(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate");
if (c_stream.avail_in != 0) {
fprintf(stderr, "deflate not greedy\n");
exit(1);
}
/* Feed in already compressed data and switch to no compression: */
deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
c_stream.next_in = compr;
c_stream.avail_in = (uInt)comprLen/2;
err = deflate(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate");
/* Switch back to compressing mode: */
deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
c_stream.next_in = uncompr;
c_stream.avail_in = (uInt)uncomprLen;
err = deflate(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate");
err = deflate(&c_stream, Z_FINISH);
if (err != Z_STREAM_END) {
fprintf(stderr, "deflate should report Z_STREAM_END\n");
exit(1);
}
err = deflateEnd(&c_stream);
CHECK_ERR(err, "deflateEnd");
}
/* ===========================================================================
* Test inflate() with large buffers
*/
void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
Byte *compr, *uncompr;
uLong comprLen, uncomprLen;
{
int err;
z_stream d_stream; /* decompression stream */
strcpy((char*)uncompr, "garbage");
d_stream.zalloc = (alloc_func)0;
d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
d_stream.next_in = compr;
d_stream.avail_in = (uInt)comprLen;
err = inflateInit(&d_stream);
CHECK_ERR(err, "inflateInit");
for (;;) {
d_stream.next_out = uncompr; /* discard the output */
d_stream.avail_out = (uInt)uncomprLen;
err = inflate(&d_stream, Z_NO_FLUSH);
if (err == Z_STREAM_END) break;
CHECK_ERR(err, "large inflate");
}
err = inflateEnd(&d_stream);
CHECK_ERR(err, "inflateEnd");
if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
exit(1);
} else {
printf("large_inflate(): OK\n");
}
}
/* ===========================================================================
* Test deflate() with full flush
*/
void test_flush(compr, comprLen)
Byte *compr;
uLong *comprLen;
{
z_stream c_stream; /* compression stream */
int err;
uInt len = (uInt)strlen(hello)+1;
c_stream.zalloc = (alloc_func)0;
c_stream.zfree = (free_func)0;
c_stream.opaque = (voidpf)0;
err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
CHECK_ERR(err, "deflateInit");
c_stream.next_in = (Bytef*)hello;
c_stream.next_out = compr;
c_stream.avail_in = 3;
c_stream.avail_out = (uInt)*comprLen;
err = deflate(&c_stream, Z_FULL_FLUSH);
CHECK_ERR(err, "deflate");
compr[3]++; /* force an error in first compressed block */
c_stream.avail_in = len - 3;
err = deflate(&c_stream, Z_FINISH);
if (err != Z_STREAM_END) {
CHECK_ERR(err, "deflate");
}
err = deflateEnd(&c_stream);
CHECK_ERR(err, "deflateEnd");
*comprLen = c_stream.total_out;
}
/* ===========================================================================
* Test inflateSync()
*/
void test_sync(compr, comprLen, uncompr, uncomprLen)
Byte *compr, *uncompr;
uLong comprLen, uncomprLen;
{
int err;
z_stream d_stream; /* decompression stream */
strcpy((char*)uncompr, "garbage");
d_stream.zalloc = (alloc_func)0;
d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
d_stream.next_in = compr;
d_stream.avail_in = 2; /* just read the zlib header */
err = inflateInit(&d_stream);
CHECK_ERR(err, "inflateInit");
d_stream.next_out = uncompr;
d_stream.avail_out = (uInt)uncomprLen;
inflate(&d_stream, Z_NO_FLUSH);
CHECK_ERR(err, "inflate");
d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */
err = inflateSync(&d_stream); /* but skip the damaged part */
CHECK_ERR(err, "inflateSync");
err = inflate(&d_stream, Z_FINISH);
if (err != Z_DATA_ERROR) {
fprintf(stderr, "inflate should report DATA_ERROR\n");
/* Because of incorrect adler32 */
exit(1);
}
err = inflateEnd(&d_stream);
CHECK_ERR(err, "inflateEnd");
printf("after inflateSync(): hel%s\n", (char *)uncompr);
}
/* ===========================================================================
* Test deflate() with preset dictionary
*/
void test_dict_deflate(compr, comprLen)
Byte *compr;
uLong comprLen;
{
z_stream c_stream; /* compression stream */
int err;
c_stream.zalloc = (alloc_func)0;
c_stream.zfree = (free_func)0;
c_stream.opaque = (voidpf)0;
err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
CHECK_ERR(err, "deflateInit");
err = deflateSetDictionary(&c_stream,
(const Bytef*)dictionary, sizeof(dictionary));
CHECK_ERR(err, "deflateSetDictionary");
dictId = c_stream.adler;
c_stream.next_out = compr;
c_stream.avail_out = (uInt)comprLen;
c_stream.next_in = (Bytef*)hello;
c_stream.avail_in = (uInt)strlen(hello)+1;
err = deflate(&c_stream, Z_FINISH);
if (err != Z_STREAM_END) {
fprintf(stderr, "deflate should report Z_STREAM_END\n");
exit(1);
}
err = deflateEnd(&c_stream);
CHECK_ERR(err, "deflateEnd");
}
/* ===========================================================================
* Test inflate() with a preset dictionary
*/
void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
Byte *compr, *uncompr;
uLong comprLen, uncomprLen;
{
int err;
z_stream d_stream; /* decompression stream */
strcpy((char*)uncompr, "garbage");
d_stream.zalloc = (alloc_func)0;
d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
d_stream.next_in = compr;
d_stream.avail_in = (uInt)comprLen;
err = inflateInit(&d_stream);
CHECK_ERR(err, "inflateInit");
d_stream.next_out = uncompr;
d_stream.avail_out = (uInt)uncomprLen;
for (;;) {
err = inflate(&d_stream, Z_NO_FLUSH);
if (err == Z_STREAM_END) break;
if (err == Z_NEED_DICT) {
if (d_stream.adler != dictId) {
fprintf(stderr, "unexpected dictionary");
exit(1);
}
err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
sizeof(dictionary));
}
CHECK_ERR(err, "inflate with dict");
}
err = inflateEnd(&d_stream);
CHECK_ERR(err, "inflateEnd");
if (strcmp((char*)uncompr, hello)) {
fprintf(stderr, "bad inflate with dict\n");
exit(1);
} else {
printf("inflate with dictionary: %s\n", (char *)uncompr);
}
}
/* ===========================================================================
* Usage: example [output.gz [input.gz]]
*/
int main(argc, argv)
int argc;
char *argv[];
{
Byte *compr, *uncompr;
uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
uLong uncomprLen = comprLen;
static const char* myVersion = ZLIB_VERSION;
if (zlibVersion()[0] != myVersion[0]) {
fprintf(stderr, "incompatible zlib version\n");
exit(1);
} else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
fprintf(stderr, "warning: different zlib version\n");
}
printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
compr = (Byte*)calloc((uInt)comprLen, 1);
uncompr = (Byte*)calloc((uInt)uncomprLen, 1);
/* compr and uncompr are cleared to avoid reading uninitialized
* data and to ensure that uncompr compresses well.
*/
if (compr == Z_NULL || uncompr == Z_NULL) {
printf("out of memory\n");
exit(1);
}
test_compress(compr, comprLen, uncompr, uncomprLen);
test_gzio((argc > 1 ? argv[1] : TESTFILE),
uncompr, uncomprLen);
test_deflate(compr, comprLen);
test_inflate(compr, comprLen, uncompr, uncomprLen);
test_large_deflate(compr, comprLen, uncompr, uncomprLen);
test_large_inflate(compr, comprLen, uncompr, uncomprLen);
test_flush(compr, &comprLen);
test_sync(compr, comprLen, uncompr, uncomprLen);
comprLen = uncomprLen;
test_dict_deflate(compr, comprLen);
test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
free(compr);
free(uncompr);
return 0;
}

303
gzio.c
View File

@@ -1,8 +1,8 @@
/* gzio.c -- IO on .gz files /* gzio.c -- IO on .gz files
* Copyright (C) 1995-1998 Jean-loup Gailly. * Copyright (C) 1995-2005 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
* *
* Compile this file with -DNO_DEFLATE to avoid the compression code. * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
*/ */
/* @(#) $Id$ */ /* @(#) $Id$ */
@@ -11,7 +11,13 @@
#include "zutil.h" #include "zutil.h"
#ifdef NO_DEFLATE /* for compatibility with old definition */
# define NO_GZCOMPRESS
#endif
#ifndef NO_DUMMY_DECL
struct internal_state {int dummy;}; /* for buggy compilers */ struct internal_state {int dummy;}; /* for buggy compilers */
#endif
#ifndef Z_BUFSIZE #ifndef Z_BUFSIZE
# ifdef MAXSEG_64K # ifdef MAXSEG_64K
@@ -24,10 +30,20 @@ struct internal_state {int dummy;}; /* for buggy compilers */
# define Z_PRINTF_BUFSIZE 4096 # define Z_PRINTF_BUFSIZE 4096
#endif #endif
#ifdef __MVS__
# pragma map (fdopen , "\174\174FDOPEN")
FILE *fdopen(int, const char *);
#endif
#ifndef STDC
extern voidp malloc OF((uInt size));
extern void free OF((voidpf ptr));
#endif
#define ALLOC(size) malloc(size) #define ALLOC(size) malloc(size)
#define TRYFREE(p) {if (p) free(p);} #define TRYFREE(p) {if (p) free(p);}
static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
/* gzip flag byte */ /* gzip flag byte */
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
@@ -49,7 +65,11 @@ typedef struct gz_stream {
char *path; /* path name for debugging only */ char *path; /* path name for debugging only */
int transparent; /* 1 if input file is not a .gz file */ int transparent; /* 1 if input file is not a .gz file */
char mode; /* 'w' or 'r' */ char mode; /* 'w' or 'r' */
long startpos; /* start of compressed data in file (header skipped) */ z_off_t start; /* start of compressed data in file (header skipped) */
z_off_t in; /* bytes into deflate or inflate */
z_off_t out; /* bytes out of deflate or inflate */
int back; /* one character push-back */
int last; /* true if push-back is last character */
} gz_stream; } gz_stream;
@@ -65,7 +85,7 @@ local uLong getLong OF((gz_stream *s));
Opens a gzip (.gz) file for reading or writing. The mode parameter Opens a gzip (.gz) file for reading or writing. The mode parameter
is as in fopen ("rb" or "wb"). The file is given either by file descriptor is as in fopen ("rb" or "wb"). The file is given either by file descriptor
or path name (if fd == -1). or path name (if fd == -1).
gz_open return NULL if the file could not be opened or if there was gz_open returns NULL if the file could not be opened or if there was
insufficient memory to allocate the (de)compression state; errno insufficient memory to allocate the (de)compression state; errno
can be checked to distinguish the two cases (if errno is zero, the can be checked to distinguish the two cases (if errno is zero, the
zlib error is Z_MEM_ERROR). zlib error is Z_MEM_ERROR).
@@ -97,6 +117,9 @@ local gzFile gz_open (path, mode, fd)
s->file = NULL; s->file = NULL;
s->z_err = Z_OK; s->z_err = Z_OK;
s->z_eof = 0; s->z_eof = 0;
s->in = 0;
s->out = 0;
s->back = EOF;
s->crc = crc32(0L, Z_NULL, 0); s->crc = crc32(0L, Z_NULL, 0);
s->msg = NULL; s->msg = NULL;
s->transparent = 0; s->transparent = 0;
@@ -117,6 +140,8 @@ local gzFile gz_open (path, mode, fd)
strategy = Z_FILTERED; strategy = Z_FILTERED;
} else if (*p == 'h') { } else if (*p == 'h') {
strategy = Z_HUFFMAN_ONLY; strategy = Z_HUFFMAN_ONLY;
} else if (*p == 'R') {
strategy = Z_RLE;
} else { } else {
*m++ = *p; /* copy the mode */ *m++ = *p; /* copy the mode */
} }
@@ -124,7 +149,7 @@ local gzFile gz_open (path, mode, fd)
if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
if (s->mode == 'w') { if (s->mode == 'w') {
#ifdef NO_DEFLATE #ifdef NO_GZCOMPRESS
err = Z_STREAM_ERROR; err = Z_STREAM_ERROR;
#else #else
err = deflateInit2(&(s->stream), level, err = deflateInit2(&(s->stream), level,
@@ -163,15 +188,15 @@ local gzFile gz_open (path, mode, fd)
*/ */
fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
s->startpos = 10L; s->start = 10L;
/* We use 10L instead of ftell(s->file) to because ftell causes an /* We use 10L instead of ftell(s->file) to because ftell causes an
* fflush on some systems. This version of the library doesn't use * fflush on some systems. This version of the library doesn't use
* startpos anyway in write mode, so this initialization is not * start anyway in write mode, so this initialization is not
* necessary. * necessary.
*/ */
} else { } else {
check_header(s); /* skip the .gz header */ check_header(s); /* skip the .gz header */
s->startpos = (ftell(s->file) - s->stream.avail_in); s->start = ftell(s->file) - s->stream.avail_in;
} }
return (gzFile)s; return (gzFile)s;
@@ -195,7 +220,7 @@ gzFile ZEXPORT gzdopen (fd, mode)
int fd; int fd;
const char *mode; const char *mode;
{ {
char name[20]; char name[46]; /* allow for up to 128-bit integers */
if (fd < 0) return (gzFile)Z_NULL; if (fd < 0) return (gzFile)Z_NULL;
sprintf(name, "<fd:%d>", fd); /* for debugging */ sprintf(name, "<fd:%d>", fd); /* for debugging */
@@ -239,7 +264,7 @@ local int get_byte(s)
if (s->z_eof) return EOF; if (s->z_eof) return EOF;
if (s->stream.avail_in == 0) { if (s->stream.avail_in == 0) {
errno = 0; errno = 0;
s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
if (s->stream.avail_in == 0) { if (s->stream.avail_in == 0) {
s->z_eof = 1; s->z_eof = 1;
if (ferror(s->file)) s->z_err = Z_ERRNO; if (ferror(s->file)) s->z_err = Z_ERRNO;
@@ -268,19 +293,33 @@ local void check_header(s)
uInt len; uInt len;
int c; int c;
/* Check the gzip magic header */ /* Assure two bytes in the buffer so we can peek ahead -- handle case
for (len = 0; len < 2; len++) { where first byte of header is at the end of the buffer after the last
c = get_byte(s); gzip segment */
if (c != gz_magic[len]) { len = s->stream.avail_in;
if (len != 0) s->stream.avail_in++, s->stream.next_in--; if (len < 2) {
if (c != EOF) { if (len) s->inbuf[0] = s->stream.next_in[0];
s->stream.avail_in++, s->stream.next_in--; errno = 0;
s->transparent = 1; len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
} if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END; s->stream.avail_in += len;
s->stream.next_in = s->inbuf;
if (s->stream.avail_in < 2) {
s->transparent = s->stream.avail_in;
return; return;
} }
} }
/* Peek ahead to check the gzip magic header */
if (s->stream.next_in[0] != gz_magic[0] ||
s->stream.next_in[1] != gz_magic[1]) {
s->transparent = 1;
return;
}
s->stream.avail_in -= 2;
s->stream.next_in += 2;
/* Check the rest of the gzip header */
method = get_byte(s); method = get_byte(s);
flags = get_byte(s); flags = get_byte(s);
if (method != Z_DEFLATED || (flags & RESERVED) != 0) { if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
@@ -324,7 +363,7 @@ local int destroy (s)
if (s->stream.state != NULL) { if (s->stream.state != NULL) {
if (s->mode == 'w') { if (s->mode == 'w') {
#ifdef NO_DEFLATE #ifdef NO_GZCOMPRESS
err = Z_STREAM_ERROR; err = Z_STREAM_ERROR;
#else #else
err = deflateEnd(&(s->stream)); err = deflateEnd(&(s->stream));
@@ -370,6 +409,19 @@ int ZEXPORT gzread (file, buf, len)
s->stream.next_out = (Bytef*)buf; s->stream.next_out = (Bytef*)buf;
s->stream.avail_out = len; s->stream.avail_out = len;
if (s->stream.avail_out && s->back != EOF) {
*next_out++ = s->back;
s->stream.next_out++;
s->stream.avail_out--;
s->back = EOF;
s->out++;
start++;
if (s->last) {
s->z_err = Z_STREAM_END;
return 1;
}
}
while (s->stream.avail_out != 0) { while (s->stream.avail_out != 0) {
if (s->transparent) { if (s->transparent) {
@@ -385,19 +437,19 @@ int ZEXPORT gzread (file, buf, len)
s->stream.avail_in -= n; s->stream.avail_in -= n;
} }
if (s->stream.avail_out > 0) { if (s->stream.avail_out > 0) {
s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out, s->stream.avail_out -=
s->file); (uInt)fread(next_out, 1, s->stream.avail_out, s->file);
} }
len -= s->stream.avail_out; len -= s->stream.avail_out;
s->stream.total_in += (uLong)len; s->in += len;
s->stream.total_out += (uLong)len; s->out += len;
if (len == 0) s->z_eof = 1; if (len == 0) s->z_eof = 1;
return (int)len; return (int)len;
} }
if (s->stream.avail_in == 0 && !s->z_eof) { if (s->stream.avail_in == 0 && !s->z_eof) {
errno = 0; errno = 0;
s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
if (s->stream.avail_in == 0) { if (s->stream.avail_in == 0) {
s->z_eof = 1; s->z_eof = 1;
if (ferror(s->file)) { if (ferror(s->file)) {
@@ -407,7 +459,11 @@ int ZEXPORT gzread (file, buf, len)
} }
s->stream.next_in = s->inbuf; s->stream.next_in = s->inbuf;
} }
s->in += s->stream.avail_in;
s->out += s->stream.avail_out;
s->z_err = inflate(&(s->stream), Z_NO_FLUSH); s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
s->in -= s->stream.avail_in;
s->out -= s->stream.avail_out;
if (s->z_err == Z_STREAM_END) { if (s->z_err == Z_STREAM_END) {
/* Check CRC and original size */ /* Check CRC and original size */
@@ -418,18 +474,13 @@ int ZEXPORT gzread (file, buf, len)
s->z_err = Z_DATA_ERROR; s->z_err = Z_DATA_ERROR;
} else { } else {
(void)getLong(s); (void)getLong(s);
/* The uncompressed length returned by above getlong() may /* The uncompressed length returned by above getlong() may be
* be different from s->stream.total_out) in case of * different from s->out in case of concatenated .gz files.
* concatenated .gz files. Check for such files: * Check for such files:
*/ */
check_header(s); check_header(s);
if (s->z_err == Z_OK) { if (s->z_err == Z_OK) {
uLong total_in = s->stream.total_in;
uLong total_out = s->stream.total_out;
inflateReset(&(s->stream)); inflateReset(&(s->stream));
s->stream.total_in = total_in;
s->stream.total_out = total_out;
s->crc = crc32(0L, Z_NULL, 0); s->crc = crc32(0L, Z_NULL, 0);
} }
} }
@@ -438,6 +489,9 @@ int ZEXPORT gzread (file, buf, len)
} }
s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
if (len == s->stream.avail_out &&
(s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO))
return -1;
return (int)(len - s->stream.avail_out); return (int)(len - s->stream.avail_out);
} }
@@ -455,6 +509,25 @@ int ZEXPORT gzgetc(file)
} }
/* ===========================================================================
Push one byte back onto the stream.
*/
int ZEXPORT gzungetc(c, file)
int c;
gzFile file;
{
gz_stream *s = (gz_stream*)file;
if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF;
s->back = c;
s->out--;
s->last = (s->z_err == Z_STREAM_END);
if (s->last) s->z_err = Z_OK;
s->z_eof = 0;
return c;
}
/* =========================================================================== /* ===========================================================================
Reads bytes from the compressed file until len-1 characters are Reads bytes from the compressed file until len-1 characters are
read, or a newline character is read and transferred to buf, or an read, or a newline character is read and transferred to buf, or an
@@ -478,14 +551,14 @@ char * ZEXPORT gzgets(file, buf, len)
} }
#ifndef NO_DEFLATE #ifndef NO_GZCOMPRESS
/* =========================================================================== /* ===========================================================================
Writes the given number of uncompressed bytes into the compressed file. Writes the given number of uncompressed bytes into the compressed file.
gzwrite returns the number of bytes actually written (0 in case of error). gzwrite returns the number of bytes actually written (0 in case of error).
*/ */
int ZEXPORT gzwrite (file, buf, len) int ZEXPORT gzwrite (file, buf, len)
gzFile file; gzFile file;
const voidp buf; voidpc buf;
unsigned len; unsigned len;
{ {
gz_stream *s = (gz_stream*)file; gz_stream *s = (gz_stream*)file;
@@ -506,7 +579,11 @@ int ZEXPORT gzwrite (file, buf, len)
} }
s->stream.avail_out = Z_BUFSIZE; s->stream.avail_out = Z_BUFSIZE;
} }
s->in += s->stream.avail_in;
s->out += s->stream.avail_out;
s->z_err = deflate(&(s->stream), Z_NO_FLUSH); s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
s->in -= s->stream.avail_in;
s->out -= s->stream.avail_out;
if (s->z_err != Z_OK) break; if (s->z_err != Z_OK) break;
} }
s->crc = crc32(s->crc, (const Bytef *)buf, len); s->crc = crc32(s->crc, (const Bytef *)buf, len);
@@ -514,6 +591,7 @@ int ZEXPORT gzwrite (file, buf, len)
return (int)(len - s->stream.avail_in); return (int)(len - s->stream.avail_in);
} }
/* =========================================================================== /* ===========================================================================
Converts, formats, and writes the args to the compressed file under Converts, formats, and writes the args to the compressed file under
control of the format string, as in fprintf. gzprintf returns the number of control of the format string, as in fprintf. gzprintf returns the number of
@@ -528,16 +606,30 @@ int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
va_list va; va_list va;
int len; int len;
buf[sizeof(buf) - 1] = 0;
va_start(va, format); va_start(va, format);
#ifdef HAS_vsnprintf #ifdef NO_vsnprintf
(void)vsnprintf(buf, sizeof(buf), format, va); # ifdef HAS_vsprintf_void
#else
(void)vsprintf(buf, format, va); (void)vsprintf(buf, format, va);
#endif
va_end(va); va_end(va);
len = strlen(buf); /* some *sprintf don't return the nb of bytes written */ for (len = 0; len < sizeof(buf); len++)
if (len <= 0) return 0; if (buf[len] == 0) break;
# else
len = vsprintf(buf, format, va);
va_end(va);
# endif
#else
# ifdef HAS_vsnprintf_void
(void)vsnprintf(buf, sizeof(buf), format, va);
va_end(va);
len = strlen(buf);
# else
len = vsnprintf(buf, sizeof(buf), format, va);
va_end(va);
# endif
#endif
if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0)
return 0;
return gzwrite(file, buf, (unsigned)len); return gzwrite(file, buf, (unsigned)len);
} }
#else /* not ANSI C */ #else /* not ANSI C */
@@ -552,16 +644,29 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
char buf[Z_PRINTF_BUFSIZE]; char buf[Z_PRINTF_BUFSIZE];
int len; int len;
#ifdef HAS_snprintf buf[sizeof(buf) - 1] = 0;
snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, #ifdef NO_snprintf
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); # ifdef HAS_sprintf_void
#else
sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
for (len = 0; len < sizeof(buf); len++)
if (buf[len] == 0) break;
# else
len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
# endif # endif
len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */ #else
if (len <= 0) return 0; # ifdef HAS_snprintf_void
snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
len = strlen(buf);
# else
len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
# endif
#endif
if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0)
return 0;
return gzwrite(file, buf, len); return gzwrite(file, buf, len);
} }
#endif #endif
@@ -621,7 +726,9 @@ local int do_flush (file, flush)
s->stream.avail_out = Z_BUFSIZE; s->stream.avail_out = Z_BUFSIZE;
} }
if (done) break; if (done) break;
s->out += s->stream.avail_out;
s->z_err = deflate(&(s->stream), flush); s->z_err = deflate(&(s->stream), flush);
s->out -= s->stream.avail_out;
/* Ignore the second of two consecutive flushes: */ /* Ignore the second of two consecutive flushes: */
if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
@@ -647,7 +754,7 @@ int ZEXPORT gzflush (file, flush)
fflush(s->file); fflush(s->file);
return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
} }
#endif /* NO_DEFLATE */ #endif /* NO_GZCOMPRESS */
/* =========================================================================== /* ===========================================================================
Sets the starting position for the next gzread or gzwrite on the given Sets the starting position for the next gzread or gzwrite on the given
@@ -670,17 +777,18 @@ z_off_t ZEXPORT gzseek (file, offset, whence)
} }
if (s->mode == 'w') { if (s->mode == 'w') {
#ifdef NO_DEFLATE #ifdef NO_GZCOMPRESS
return -1L; return -1L;
#else #else
if (whence == SEEK_SET) { if (whence == SEEK_SET) {
offset -= s->stream.total_in; offset -= s->in;
} }
if (offset < 0) return -1L; if (offset < 0) return -1L;
/* At this point, offset is the number of zero bytes to write. */ /* At this point, offset is the number of zero bytes to write. */
if (s->inbuf == Z_NULL) { if (s->inbuf == Z_NULL) {
s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
if (s->inbuf == Z_NULL) return -1L;
zmemzero(s->inbuf, Z_BUFSIZE); zmemzero(s->inbuf, Z_BUFSIZE);
} }
while (offset > 0) { while (offset > 0) {
@@ -692,30 +800,31 @@ z_off_t ZEXPORT gzseek (file, offset, whence)
offset -= size; offset -= size;
} }
return (z_off_t)s->stream.total_in; return s->in;
#endif #endif
} }
/* Rest of function is for reading only */ /* Rest of function is for reading only */
/* compute absolute position */ /* compute absolute position */
if (whence == SEEK_CUR) { if (whence == SEEK_CUR) {
offset += s->stream.total_out; offset += s->out;
} }
if (offset < 0) return -1L; if (offset < 0) return -1L;
if (s->transparent) { if (s->transparent) {
/* map to fseek */ /* map to fseek */
s->back = EOF;
s->stream.avail_in = 0; s->stream.avail_in = 0;
s->stream.next_in = s->inbuf; s->stream.next_in = s->inbuf;
if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
s->stream.total_in = s->stream.total_out = (uLong)offset; s->in = s->out = offset;
return offset; return offset;
} }
/* For a negative seek, rewind and use positive seek */ /* For a negative seek, rewind and use positive seek */
if ((uLong)offset >= s->stream.total_out) { if (offset >= s->out) {
offset -= s->stream.total_out; offset -= s->out;
} else if (gzrewind(file) < 0) { } else if (gzrewind(file) < 0) {
return -1L; return -1L;
} }
@@ -723,6 +832,13 @@ z_off_t ZEXPORT gzseek (file, offset, whence)
if (offset != 0 && s->outbuf == Z_NULL) { if (offset != 0 && s->outbuf == Z_NULL) {
s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
if (s->outbuf == Z_NULL) return -1L;
}
if (offset && s->back != EOF) {
s->back = EOF;
s->out++;
offset--;
if (s->last) s->z_err = Z_STREAM_END;
} }
while (offset > 0) { while (offset > 0) {
int size = Z_BUFSIZE; int size = Z_BUFSIZE;
@@ -732,7 +848,7 @@ z_off_t ZEXPORT gzseek (file, offset, whence)
if (size <= 0) return -1L; if (size <= 0) return -1L;
offset -= size; offset -= size;
} }
return (z_off_t)s->stream.total_out; return s->out;
} }
/* =========================================================================== /* ===========================================================================
@@ -747,17 +863,14 @@ int ZEXPORT gzrewind (file)
s->z_err = Z_OK; s->z_err = Z_OK;
s->z_eof = 0; s->z_eof = 0;
s->back = EOF;
s->stream.avail_in = 0; s->stream.avail_in = 0;
s->stream.next_in = s->inbuf; s->stream.next_in = s->inbuf;
s->crc = crc32(0L, Z_NULL, 0); s->crc = crc32(0L, Z_NULL, 0);
if (!s->transparent) (void)inflateReset(&s->stream);
if (s->startpos == 0) { /* not a compressed file */ s->in = 0;
rewind(s->file); s->out = 0;
return 0; return fseek(s->file, s->start, SEEK_SET);
}
(void) inflateReset(&s->stream);
return fseek(s->file, s->startpos, SEEK_SET);
} }
/* =========================================================================== /* ===========================================================================
@@ -780,7 +893,25 @@ int ZEXPORT gzeof (file)
{ {
gz_stream *s = (gz_stream*)file; gz_stream *s = (gz_stream*)file;
return (s == NULL || s->mode != 'r') ? 0 : s->z_eof; /* With concatenated compressed files that can have embedded
* crc trailers, z_eof is no longer the only/best indicator of EOF
* on a gz_stream. Handle end-of-stream error explicitly here.
*/
if (s == NULL || s->mode != 'r') return 0;
if (s->z_eof) return 1;
return s->z_err == Z_STREAM_END;
}
/* ===========================================================================
Returns 1 if reading and doing so transparently, otherwise zero.
*/
int ZEXPORT gzdirect (file)
gzFile file;
{
gz_stream *s = (gz_stream*)file;
if (s == NULL || s->mode != 'r') return 0;
return s->transparent;
} }
/* =========================================================================== /* ===========================================================================
@@ -822,29 +953,34 @@ local uLong getLong (s)
int ZEXPORT gzclose (file) int ZEXPORT gzclose (file)
gzFile file; gzFile file;
{ {
int err;
gz_stream *s = (gz_stream*)file; gz_stream *s = (gz_stream*)file;
if (s == NULL) return Z_STREAM_ERROR; if (s == NULL) return Z_STREAM_ERROR;
if (s->mode == 'w') { if (s->mode == 'w') {
#ifdef NO_DEFLATE #ifdef NO_GZCOMPRESS
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
#else #else
err = do_flush (file, Z_FINISH); if (do_flush (file, Z_FINISH) != Z_OK)
if (err != Z_OK) return destroy((gz_stream*)file); return destroy((gz_stream*)file);
putLong (s->file, s->crc); putLong (s->file, s->crc);
putLong (s->file, s->stream.total_in); putLong (s->file, (uLong)(s->in & 0xffffffff));
#endif #endif
} }
return destroy((gz_stream*)file); return destroy((gz_stream*)file);
} }
#ifdef STDC
# define zstrerror(errnum) strerror(errnum)
#else
# define zstrerror(errnum) ""
#endif
/* =========================================================================== /* ===========================================================================
Returns the error message for the last error which occured on the Returns the error message for the last error which occurred on the
given compressed file. errnum is set to zlib error number. If an given compressed file. errnum is set to zlib error number. If an
error occured in the file system and not in the compression library, error occurred in the file system and not in the compression library,
errnum is set to Z_ERRNO and the application may consult errno errnum is set to Z_ERRNO and the application may consult errno
to get the exact error code. to get the exact error code.
*/ */
@@ -868,8 +1004,23 @@ const char* ZEXPORT gzerror (file, errnum)
TRYFREE(s->msg); TRYFREE(s->msg);
s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR);
strcpy(s->msg, s->path); strcpy(s->msg, s->path);
strcat(s->msg, ": "); strcat(s->msg, ": ");
strcat(s->msg, m); strcat(s->msg, m);
return (const char*)s->msg; return (const char*)s->msg;
} }
/* ===========================================================================
Clear the error and end-of-file flags, and do the same for the real file.
*/
void ZEXPORT gzclearerr (file)
gzFile file;
{
gz_stream *s = (gz_stream*)file;
if (s == NULL) return;
if (s->z_err != Z_STREAM_END) s->z_err = Z_OK;
s->z_eof = 0;
clearerr(s->file);
}

623
infback.c Normal file
View File

@@ -0,0 +1,623 @@
/* infback.c -- inflate using a call-back interface
* Copyright (C) 1995-2005 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/*
This code is largely copied from inflate.c. Normally either infback.o or
inflate.o would be linked into an application--not both. The interface
with inffast.c is retained so that optimized assembler-coded versions of
inflate_fast() can be used with either inflate.c or infback.c.
*/
#include "zutil.h"
#include "inftrees.h"
#include "inflate.h"
#include "inffast.h"
/* function prototypes */
local void fixedtables OF((struct inflate_state FAR *state));
/*
strm provides memory allocation functions in zalloc and zfree, or
Z_NULL to use the library memory allocation functions.
windowBits is in the range 8..15, and window is a user-supplied
window and output buffer that is 2**windowBits bytes.
*/
int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
z_streamp strm;
int windowBits;
unsigned char FAR *window;
const char *version;
int stream_size;
{
struct inflate_state FAR *state;
if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
stream_size != (int)(sizeof(z_stream)))
return Z_VERSION_ERROR;
if (strm == Z_NULL || window == Z_NULL ||
windowBits < 8 || windowBits > 15)
return Z_STREAM_ERROR;
strm->msg = Z_NULL; /* in case we return an error */
if (strm->zalloc == (alloc_func)0) {
strm->zalloc = zcalloc;
strm->opaque = (voidpf)0;
}
if (strm->zfree == (free_func)0) strm->zfree = zcfree;
state = (struct inflate_state FAR *)ZALLOC(strm, 1,
sizeof(struct inflate_state));
if (state == Z_NULL) return Z_MEM_ERROR;
Tracev((stderr, "inflate: allocated\n"));
strm->state = (struct internal_state FAR *)state;
state->dmax = 32768U;
state->wbits = windowBits;
state->wsize = 1U << windowBits;
state->window = window;
state->write = 0;
state->whave = 0;
return Z_OK;
}
/*
Return state with length and distance decoding tables and index sizes set to
fixed code decoding. Normally this returns fixed tables from inffixed.h.
If BUILDFIXED is defined, then instead this routine builds the tables the
first time it's called, and returns those tables the first time and
thereafter. This reduces the size of the code by about 2K bytes, in
exchange for a little execution time. However, BUILDFIXED should not be
used for threaded applications, since the rewriting of the tables and virgin
may not be thread-safe.
*/
local void fixedtables(state)
struct inflate_state FAR *state;
{
#ifdef BUILDFIXED
static int virgin = 1;
static code *lenfix, *distfix;
static code fixed[544];
/* build fixed huffman tables if first call (may not be thread safe) */
if (virgin) {
unsigned sym, bits;
static code *next;
/* literal/length table */
sym = 0;
while (sym < 144) state->lens[sym++] = 8;
while (sym < 256) state->lens[sym++] = 9;
while (sym < 280) state->lens[sym++] = 7;
while (sym < 288) state->lens[sym++] = 8;
next = fixed;
lenfix = next;
bits = 9;
inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
/* distance table */
sym = 0;
while (sym < 32) state->lens[sym++] = 5;
distfix = next;
bits = 5;
inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
/* do this just once */
virgin = 0;
}
#else /* !BUILDFIXED */
# include "inffixed.h"
#endif /* BUILDFIXED */
state->lencode = lenfix;
state->lenbits = 9;
state->distcode = distfix;
state->distbits = 5;
}
/* Macros for inflateBack(): */
/* Load returned state from inflate_fast() */
#define LOAD() \
do { \
put = strm->next_out; \
left = strm->avail_out; \
next = strm->next_in; \
have = strm->avail_in; \
hold = state->hold; \
bits = state->bits; \
} while (0)
/* Set state from registers for inflate_fast() */
#define RESTORE() \
do { \
strm->next_out = put; \
strm->avail_out = left; \
strm->next_in = next; \
strm->avail_in = have; \
state->hold = hold; \
state->bits = bits; \
} while (0)
/* Clear the input bit accumulator */
#define INITBITS() \
do { \
hold = 0; \
bits = 0; \
} while (0)
/* Assure that some input is available. If input is requested, but denied,
then return a Z_BUF_ERROR from inflateBack(). */
#define PULL() \
do { \
if (have == 0) { \
have = in(in_desc, &next); \
if (have == 0) { \
next = Z_NULL; \
ret = Z_BUF_ERROR; \
goto inf_leave; \
} \
} \
} while (0)
/* Get a byte of input into the bit accumulator, or return from inflateBack()
with an error if there is no input available. */
#define PULLBYTE() \
do { \
PULL(); \
have--; \
hold += (unsigned long)(*next++) << bits; \
bits += 8; \
} while (0)
/* Assure that there are at least n bits in the bit accumulator. If there is
not enough available input to do that, then return from inflateBack() with
an error. */
#define NEEDBITS(n) \
do { \
while (bits < (unsigned)(n)) \
PULLBYTE(); \
} while (0)
/* Return the low n bits of the bit accumulator (n < 16) */
#define BITS(n) \
((unsigned)hold & ((1U << (n)) - 1))
/* Remove n bits from the bit accumulator */
#define DROPBITS(n) \
do { \
hold >>= (n); \
bits -= (unsigned)(n); \
} while (0)
/* Remove zero to seven bits as needed to go to a byte boundary */
#define BYTEBITS() \
do { \
hold >>= bits & 7; \
bits -= bits & 7; \
} while (0)
/* Assure that some output space is available, by writing out the window
if it's full. If the write fails, return from inflateBack() with a
Z_BUF_ERROR. */
#define ROOM() \
do { \
if (left == 0) { \
put = state->window; \
left = state->wsize; \
state->whave = left; \
if (out(out_desc, put, left)) { \
ret = Z_BUF_ERROR; \
goto inf_leave; \
} \
} \
} while (0)
/*
strm provides the memory allocation functions and window buffer on input,
and provides information on the unused input on return. For Z_DATA_ERROR
returns, strm will also provide an error message.
in() and out() are the call-back input and output functions. When
inflateBack() needs more input, it calls in(). When inflateBack() has
filled the window with output, or when it completes with data in the
window, it calls out() to write out the data. The application must not
change the provided input until in() is called again or inflateBack()
returns. The application must not change the window/output buffer until
inflateBack() returns.
in() and out() are called with a descriptor parameter provided in the
inflateBack() call. This parameter can be a structure that provides the
information required to do the read or write, as well as accumulated
information on the input and output such as totals and check values.
in() should return zero on failure. out() should return non-zero on
failure. If either in() or out() fails, than inflateBack() returns a
Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
was in() or out() that caused in the error. Otherwise, inflateBack()
returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
error, or Z_MEM_ERROR if it could not allocate memory for the state.
inflateBack() can also return Z_STREAM_ERROR if the input parameters
are not correct, i.e. strm is Z_NULL or the state was not initialized.
*/
int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
z_streamp strm;
in_func in;
void FAR *in_desc;
out_func out;
void FAR *out_desc;
{
struct inflate_state FAR *state;
unsigned char FAR *next; /* next input */
unsigned char FAR *put; /* next output */
unsigned have, left; /* available input and output */
unsigned long hold; /* bit buffer */
unsigned bits; /* bits in bit buffer */
unsigned copy; /* number of stored or match bytes to copy */
unsigned char FAR *from; /* where to copy match bytes from */
code this; /* current decoding table entry */
code last; /* parent table entry */
unsigned len; /* length to copy for repeats, bits to drop */
int ret; /* return code */
static const unsigned short order[19] = /* permutation of code lengths */
{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
/* Check that the strm exists and that the state was initialized */
if (strm == Z_NULL || strm->state == Z_NULL)
return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
/* Reset the state */
strm->msg = Z_NULL;
state->mode = TYPE;
state->last = 0;
state->whave = 0;
next = strm->next_in;
have = next != Z_NULL ? strm->avail_in : 0;
hold = 0;
bits = 0;
put = state->window;
left = state->wsize;
/* Inflate until end of block marked as last */
for (;;)
switch (state->mode) {
case TYPE:
/* determine and dispatch block type */
if (state->last) {
BYTEBITS();
state->mode = DONE;
break;
}
NEEDBITS(3);
state->last = BITS(1);
DROPBITS(1);
switch (BITS(2)) {
case 0: /* stored block */
Tracev((stderr, "inflate: stored block%s\n",
state->last ? " (last)" : ""));
state->mode = STORED;
break;
case 1: /* fixed block */
fixedtables(state);
Tracev((stderr, "inflate: fixed codes block%s\n",
state->last ? " (last)" : ""));
state->mode = LEN; /* decode codes */
break;
case 2: /* dynamic block */
Tracev((stderr, "inflate: dynamic codes block%s\n",
state->last ? " (last)" : ""));
state->mode = TABLE;
break;
case 3:
strm->msg = (char *)"invalid block type";
state->mode = BAD;
}
DROPBITS(2);
break;
case STORED:
/* get and verify stored block length */
BYTEBITS(); /* go to byte boundary */
NEEDBITS(32);
if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
strm->msg = (char *)"invalid stored block lengths";
state->mode = BAD;
break;
}
state->length = (unsigned)hold & 0xffff;
Tracev((stderr, "inflate: stored length %u\n",
state->length));
INITBITS();
/* copy stored block from input to output */
while (state->length != 0) {
copy = state->length;
PULL();
ROOM();
if (copy > have) copy = have;
if (copy > left) copy = left;
zmemcpy(put, next, copy);
have -= copy;
next += copy;
left -= copy;
put += copy;
state->length -= copy;
}
Tracev((stderr, "inflate: stored end\n"));
state->mode = TYPE;
break;
case TABLE:
/* get dynamic table entries descriptor */
NEEDBITS(14);
state->nlen = BITS(5) + 257;
DROPBITS(5);
state->ndist = BITS(5) + 1;
DROPBITS(5);
state->ncode = BITS(4) + 4;
DROPBITS(4);
#ifndef PKZIP_BUG_WORKAROUND
if (state->nlen > 286 || state->ndist > 30) {
strm->msg = (char *)"too many length or distance symbols";
state->mode = BAD;
break;
}
#endif
Tracev((stderr, "inflate: table sizes ok\n"));
/* get code length code lengths (not a typo) */
state->have = 0;
while (state->have < state->ncode) {
NEEDBITS(3);
state->lens[order[state->have++]] = (unsigned short)BITS(3);
DROPBITS(3);
}
while (state->have < 19)
state->lens[order[state->have++]] = 0;
state->next = state->codes;
state->lencode = (code const FAR *)(state->next);
state->lenbits = 7;
ret = inflate_table(CODES, state->lens, 19, &(state->next),
&(state->lenbits), state->work);
if (ret) {
strm->msg = (char *)"invalid code lengths set";
state->mode = BAD;
break;
}
Tracev((stderr, "inflate: code lengths ok\n"));
/* get length and distance code code lengths */
state->have = 0;
while (state->have < state->nlen + state->ndist) {
for (;;) {
this = state->lencode[BITS(state->lenbits)];
if ((unsigned)(this.bits) <= bits) break;
PULLBYTE();
}
if (this.val < 16) {
NEEDBITS(this.bits);
DROPBITS(this.bits);
state->lens[state->have++] = this.val;
}
else {
if (this.val == 16) {
NEEDBITS(this.bits + 2);
DROPBITS(this.bits);
if (state->have == 0) {
strm->msg = (char *)"invalid bit length repeat";
state->mode = BAD;
break;
}
len = (unsigned)(state->lens[state->have - 1]);
copy = 3 + BITS(2);
DROPBITS(2);
}
else if (this.val == 17) {
NEEDBITS(this.bits + 3);
DROPBITS(this.bits);
len = 0;
copy = 3 + BITS(3);
DROPBITS(3);
}
else {
NEEDBITS(this.bits + 7);
DROPBITS(this.bits);
len = 0;
copy = 11 + BITS(7);
DROPBITS(7);
}
if (state->have + copy > state->nlen + state->ndist) {
strm->msg = (char *)"invalid bit length repeat";
state->mode = BAD;
break;
}
while (copy--)
state->lens[state->have++] = (unsigned short)len;
}
}
/* handle error breaks in while */
if (state->mode == BAD) break;
/* build code tables */
state->next = state->codes;
state->lencode = (code const FAR *)(state->next);
state->lenbits = 9;
ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
&(state->lenbits), state->work);
if (ret) {
strm->msg = (char *)"invalid literal/lengths set";
state->mode = BAD;
break;
}
state->distcode = (code const FAR *)(state->next);
state->distbits = 6;
ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
&(state->next), &(state->distbits), state->work);
if (ret) {
strm->msg = (char *)"invalid distances set";
state->mode = BAD;
break;
}
Tracev((stderr, "inflate: codes ok\n"));
state->mode = LEN;
case LEN:
/* use inflate_fast() if we have enough input and output */
if (have >= 6 && left >= 258) {
RESTORE();
if (state->whave < state->wsize)
state->whave = state->wsize - left;
inflate_fast(strm, state->wsize);
LOAD();
break;
}
/* get a literal, length, or end-of-block code */
for (;;) {
this = state->lencode[BITS(state->lenbits)];
if ((unsigned)(this.bits) <= bits) break;
PULLBYTE();
}
if (this.op && (this.op & 0xf0) == 0) {
last = this;
for (;;) {
this = state->lencode[last.val +
(BITS(last.bits + last.op) >> last.bits)];
if ((unsigned)(last.bits + this.bits) <= bits) break;
PULLBYTE();
}
DROPBITS(last.bits);
}
DROPBITS(this.bits);
state->length = (unsigned)this.val;
/* process literal */
if (this.op == 0) {
Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
"inflate: literal '%c'\n" :
"inflate: literal 0x%02x\n", this.val));
ROOM();
*put++ = (unsigned char)(state->length);
left--;
state->mode = LEN;
break;
}
/* process end of block */
if (this.op & 32) {
Tracevv((stderr, "inflate: end of block\n"));
state->mode = TYPE;
break;
}
/* invalid code */
if (this.op & 64) {
strm->msg = (char *)"invalid literal/length code";
state->mode = BAD;
break;
}
/* length code -- get extra bits, if any */
state->extra = (unsigned)(this.op) & 15;
if (state->extra != 0) {
NEEDBITS(state->extra);
state->length += BITS(state->extra);
DROPBITS(state->extra);
}
Tracevv((stderr, "inflate: length %u\n", state->length));
/* get distance code */
for (;;) {
this = state->distcode[BITS(state->distbits)];
if ((unsigned)(this.bits) <= bits) break;
PULLBYTE();
}
if ((this.op & 0xf0) == 0) {
last = this;
for (;;) {
this = state->distcode[last.val +
(BITS(last.bits + last.op) >> last.bits)];
if ((unsigned)(last.bits + this.bits) <= bits) break;
PULLBYTE();
}
DROPBITS(last.bits);
}
DROPBITS(this.bits);
if (this.op & 64) {
strm->msg = (char *)"invalid distance code";
state->mode = BAD;
break;
}
state->offset = (unsigned)this.val;
/* get distance extra bits, if any */
state->extra = (unsigned)(this.op) & 15;
if (state->extra != 0) {
NEEDBITS(state->extra);
state->offset += BITS(state->extra);
DROPBITS(state->extra);
}
if (state->offset > state->wsize - (state->whave < state->wsize ?
left : 0)) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD;
break;
}
Tracevv((stderr, "inflate: distance %u\n", state->offset));
/* copy match from window to output */
do {
ROOM();
copy = state->wsize - state->offset;
if (copy < left) {
from = put + copy;
copy = left - copy;
}
else {
from = put - state->offset;
copy = left;
}
if (copy > state->length) copy = state->length;
state->length -= copy;
left -= copy;
do {
*put++ = *from++;
} while (--copy);
} while (state->length != 0);
break;
case DONE:
/* inflate stream terminated properly -- write leftover output */
ret = Z_STREAM_END;
if (left < state->wsize) {
if (out(out_desc, state->window, state->wsize - left))
ret = Z_BUF_ERROR;
}
goto inf_leave;
case BAD:
ret = Z_DATA_ERROR;
goto inf_leave;
default: /* can't happen, but makes compilers happy */
ret = Z_STREAM_ERROR;
goto inf_leave;
}
/* Return unused input */
inf_leave:
strm->next_in = next;
strm->avail_in = have;
return ret;
}
int ZEXPORT inflateBackEnd(strm)
z_streamp strm;
{
if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
return Z_STREAM_ERROR;
ZFREE(strm, strm->state);
strm->state = Z_NULL;
Tracev((stderr, "inflate: end\n"));
return Z_OK;
}

View File

@@ -1,398 +0,0 @@
/* infblock.c -- interpret and process block types to last block
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "infblock.h"
#include "inftrees.h"
#include "infcodes.h"
#include "infutil.h"
struct inflate_codes_state {int dummy;}; /* for buggy compilers */
/* simplify the use of the inflate_huft type with some defines */
#define exop word.what.Exop
#define bits word.what.Bits
/* Table for deflate from PKZIP's appnote.txt. */
local const uInt border[] = { /* Order of the bit length code lengths */
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
/*
Notes beyond the 1.93a appnote.txt:
1. Distance pointers never point before the beginning of the output
stream.
2. Distance pointers can point back across blocks, up to 32k away.
3. There is an implied maximum of 7 bits for the bit length table and
15 bits for the actual data.
4. If only one code exists, then it is encoded using one bit. (Zero
would be more efficient, but perhaps a little confusing.) If two
codes exist, they are coded using one bit each (0 and 1).
5. There is no way of sending zero distance codes--a dummy must be
sent if there are none. (History: a pre 2.0 version of PKZIP would
store blocks with no distance codes, but this was discovered to be
too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
zero distance codes, which is sent as one code of zero bits in
length.
6. There are up to 286 literal/length codes. Code 256 represents the
end-of-block. Note however that the static length tree defines
288 codes just to fill out the Huffman codes. Codes 286 and 287
cannot be used though, since there is no length base or extra bits
defined for them. Similarily, there are up to 30 distance codes.
However, static trees define 32 codes (all 5 bits) to fill out the
Huffman codes, but the last two had better not show up in the data.
7. Unzip can check dynamic Huffman blocks for complete code sets.
The exception is that a single code would not be complete (see #4).
8. The five bits following the block type is really the number of
literal codes sent minus 257.
9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
(1+6+6). Therefore, to output three times the length, you output
three codes (1+1+1), whereas to output four times the same length,
you only need two codes (1+3). Hmm.
10. In the tree reconstruction algorithm, Code = Code + Increment
only if BitLength(i) is not zero. (Pretty obvious.)
11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
12. Note: length code 284 can represent 227-258, but length code 285
really is 258. The last length deserves its own, short code
since it gets used a lot in very redundant files. The length
258 is special since 258 - 3 (the min match length) is 255.
13. The literal/length and distance code bit lengths are read as a
single stream of lengths. It is possible (and advantageous) for
a repeat code (16, 17, or 18) to go across the boundary between
the two sets of lengths.
*/
void inflate_blocks_reset(s, z, c)
inflate_blocks_statef *s;
z_streamp z;
uLongf *c;
{
if (c != Z_NULL)
*c = s->check;
if (s->mode == BTREE || s->mode == DTREE)
ZFREE(z, s->sub.trees.blens);
if (s->mode == CODES)
inflate_codes_free(s->sub.decode.codes, z);
s->mode = TYPE;
s->bitk = 0;
s->bitb = 0;
s->read = s->write = s->window;
if (s->checkfn != Z_NULL)
z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
Tracev((stderr, "inflate: blocks reset\n"));
}
inflate_blocks_statef *inflate_blocks_new(z, c, w)
z_streamp z;
check_func c;
uInt w;
{
inflate_blocks_statef *s;
if ((s = (inflate_blocks_statef *)ZALLOC
(z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
return s;
if ((s->hufts =
(inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
{
ZFREE(z, s);
return Z_NULL;
}
if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
{
ZFREE(z, s->hufts);
ZFREE(z, s);
return Z_NULL;
}
s->end = s->window + w;
s->checkfn = c;
s->mode = TYPE;
Tracev((stderr, "inflate: blocks allocated\n"));
inflate_blocks_reset(s, z, Z_NULL);
return s;
}
int inflate_blocks(s, z, r)
inflate_blocks_statef *s;
z_streamp z;
int r;
{
uInt t; /* temporary storage */
uLong b; /* bit buffer */
uInt k; /* bits in bit buffer */
Bytef *p; /* input data pointer */
uInt n; /* bytes available there */
Bytef *q; /* output window write pointer */
uInt m; /* bytes to end of window or read pointer */
/* copy input/output information to locals (UPDATE macro restores) */
LOAD
/* process input based on current state */
while (1) switch (s->mode)
{
case TYPE:
NEEDBITS(3)
t = (uInt)b & 7;
s->last = t & 1;
switch (t >> 1)
{
case 0: /* stored */
Tracev((stderr, "inflate: stored block%s\n",
s->last ? " (last)" : ""));
DUMPBITS(3)
t = k & 7; /* go to byte boundary */
DUMPBITS(t)
s->mode = LENS; /* get length of stored block */
break;
case 1: /* fixed */
Tracev((stderr, "inflate: fixed codes block%s\n",
s->last ? " (last)" : ""));
{
uInt bl, bd;
inflate_huft *tl, *td;
inflate_trees_fixed(&bl, &bd, &tl, &td, z);
s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
if (s->sub.decode.codes == Z_NULL)
{
r = Z_MEM_ERROR;
LEAVE
}
}
DUMPBITS(3)
s->mode = CODES;
break;
case 2: /* dynamic */
Tracev((stderr, "inflate: dynamic codes block%s\n",
s->last ? " (last)" : ""));
DUMPBITS(3)
s->mode = TABLE;
break;
case 3: /* illegal */
DUMPBITS(3)
s->mode = BAD;
z->msg = (char*)"invalid block type";
r = Z_DATA_ERROR;
LEAVE
}
break;
case LENS:
NEEDBITS(32)
if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
{
s->mode = BAD;
z->msg = (char*)"invalid stored block lengths";
r = Z_DATA_ERROR;
LEAVE
}
s->sub.left = (uInt)b & 0xffff;
b = k = 0; /* dump bits */
Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
break;
case STORED:
if (n == 0)
LEAVE
NEEDOUT
t = s->sub.left;
if (t > n) t = n;
if (t > m) t = m;
zmemcpy(q, p, t);
p += t; n -= t;
q += t; m -= t;
if ((s->sub.left -= t) != 0)
break;
Tracev((stderr, "inflate: stored end, %lu total out\n",
z->total_out + (q >= s->read ? q - s->read :
(s->end - s->read) + (q - s->window))));
s->mode = s->last ? DRY : TYPE;
break;
case TABLE:
NEEDBITS(14)
s->sub.trees.table = t = (uInt)b & 0x3fff;
#ifndef PKZIP_BUG_WORKAROUND
if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
{
s->mode = BAD;
z->msg = (char*)"too many length or distance symbols";
r = Z_DATA_ERROR;
LEAVE
}
#endif
t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
{
r = Z_MEM_ERROR;
LEAVE
}
DUMPBITS(14)
s->sub.trees.index = 0;
Tracev((stderr, "inflate: table sizes ok\n"));
s->mode = BTREE;
case BTREE:
while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
{
NEEDBITS(3)
s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
DUMPBITS(3)
}
while (s->sub.trees.index < 19)
s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
s->sub.trees.bb = 7;
t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
&s->sub.trees.tb, s->hufts, z);
if (t != Z_OK)
{
ZFREE(z, s->sub.trees.blens);
r = t;
if (r == Z_DATA_ERROR)
s->mode = BAD;
LEAVE
}
s->sub.trees.index = 0;
Tracev((stderr, "inflate: bits tree ok\n"));
s->mode = DTREE;
case DTREE:
while (t = s->sub.trees.table,
s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
{
inflate_huft *h;
uInt i, j, c;
t = s->sub.trees.bb;
NEEDBITS(t)
h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
t = h->bits;
c = h->base;
if (c < 16)
{
DUMPBITS(t)
s->sub.trees.blens[s->sub.trees.index++] = c;
}
else /* c == 16..18 */
{
i = c == 18 ? 7 : c - 14;
j = c == 18 ? 11 : 3;
NEEDBITS(t + i)
DUMPBITS(t)
j += (uInt)b & inflate_mask[i];
DUMPBITS(i)
i = s->sub.trees.index;
t = s->sub.trees.table;
if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
(c == 16 && i < 1))
{
ZFREE(z, s->sub.trees.blens);
s->mode = BAD;
z->msg = (char*)"invalid bit length repeat";
r = Z_DATA_ERROR;
LEAVE
}
c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
do {
s->sub.trees.blens[i++] = c;
} while (--j);
s->sub.trees.index = i;
}
}
s->sub.trees.tb = Z_NULL;
{
uInt bl, bd;
inflate_huft *tl, *td;
inflate_codes_statef *c;
bl = 9; /* must be <= 9 for lookahead assumptions */
bd = 6; /* must be <= 9 for lookahead assumptions */
t = s->sub.trees.table;
t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
s->sub.trees.blens, &bl, &bd, &tl, &td,
s->hufts, z);
ZFREE(z, s->sub.trees.blens);
if (t != Z_OK)
{
if (t == (uInt)Z_DATA_ERROR)
s->mode = BAD;
r = t;
LEAVE
}
Tracev((stderr, "inflate: trees ok\n"));
if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
{
r = Z_MEM_ERROR;
LEAVE
}
s->sub.decode.codes = c;
}
s->mode = CODES;
case CODES:
UPDATE
if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
return inflate_flush(s, z, r);
r = Z_OK;
inflate_codes_free(s->sub.decode.codes, z);
LOAD
Tracev((stderr, "inflate: codes end, %lu total out\n",
z->total_out + (q >= s->read ? q - s->read :
(s->end - s->read) + (q - s->window))));
if (!s->last)
{
s->mode = TYPE;
break;
}
s->mode = DRY;
case DRY:
FLUSH
if (s->read != s->write)
LEAVE
s->mode = DONE;
case DONE:
r = Z_STREAM_END;
LEAVE
case BAD:
r = Z_DATA_ERROR;
LEAVE
default:
r = Z_STREAM_ERROR;
LEAVE
}
}
int inflate_blocks_free(s, z)
inflate_blocks_statef *s;
z_streamp z;
{
inflate_blocks_reset(s, z, Z_NULL);
ZFREE(z, s->window);
ZFREE(z, s->hufts);
ZFREE(z, s);
Tracev((stderr, "inflate: blocks freed\n"));
return Z_OK;
}
void inflate_set_dictionary(s, d, n)
inflate_blocks_statef *s;
const Bytef *d;
uInt n;
{
zmemcpy(s->window, d, n);
s->read = s->write = s->window + n;
}
/* Returns true if inflate is currently at the end of a block generated
* by Z_SYNC_FLUSH or Z_FULL_FLUSH.
* IN assertion: s != Z_NULL
*/
int inflate_blocks_sync_point(s)
inflate_blocks_statef *s;
{
return s->mode == LENS;
}

View File

@@ -1,39 +0,0 @@
/* infblock.h -- header to use infblock.c
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
struct inflate_blocks_state;
typedef struct inflate_blocks_state FAR inflate_blocks_statef;
extern inflate_blocks_statef * inflate_blocks_new OF((
z_streamp z,
check_func c, /* check function */
uInt w)); /* window size */
extern int inflate_blocks OF((
inflate_blocks_statef *,
z_streamp ,
int)); /* initial return code */
extern void inflate_blocks_reset OF((
inflate_blocks_statef *,
z_streamp ,
uLongf *)); /* check value on output */
extern int inflate_blocks_free OF((
inflate_blocks_statef *,
z_streamp));
extern void inflate_set_dictionary OF((
inflate_blocks_statef *s,
const Bytef *d, /* dictionary */
uInt n)); /* dictionary length */
extern int inflate_blocks_sync_point OF((
inflate_blocks_statef *s));

View File

@@ -1,257 +0,0 @@
/* infcodes.c -- process literals and length/distance pairs
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "inftrees.h"
#include "infblock.h"
#include "infcodes.h"
#include "infutil.h"
#include "inffast.h"
/* simplify the use of the inflate_huft type with some defines */
#define exop word.what.Exop
#define bits word.what.Bits
typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
START, /* x: set up for LEN */
LEN, /* i: get length/literal/eob next */
LENEXT, /* i: getting length extra (have base) */
DIST, /* i: get distance next */
DISTEXT, /* i: getting distance extra */
COPY, /* o: copying bytes in window, waiting for space */
LIT, /* o: got literal, waiting for output space */
WASH, /* o: got eob, possibly still output waiting */
END, /* x: got eob and all data flushed */
BADCODE} /* x: got error */
inflate_codes_mode;
/* inflate codes private state */
struct inflate_codes_state {
/* mode */
inflate_codes_mode mode; /* current inflate_codes mode */
/* mode dependent information */
uInt len;
union {
struct {
inflate_huft *tree; /* pointer into tree */
uInt need; /* bits needed */
} code; /* if LEN or DIST, where in tree */
uInt lit; /* if LIT, literal */
struct {
uInt get; /* bits to get for extra */
uInt dist; /* distance back to copy from */
} copy; /* if EXT or COPY, where and how much */
} sub; /* submode */
/* mode independent information */
Byte lbits; /* ltree bits decoded per branch */
Byte dbits; /* dtree bits decoder per branch */
inflate_huft *ltree; /* literal/length/eob tree */
inflate_huft *dtree; /* distance tree */
};
inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
uInt bl, bd;
inflate_huft *tl;
inflate_huft *td; /* need separate declaration for Borland C++ */
z_streamp z;
{
inflate_codes_statef *c;
if ((c = (inflate_codes_statef *)
ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
{
c->mode = START;
c->lbits = (Byte)bl;
c->dbits = (Byte)bd;
c->ltree = tl;
c->dtree = td;
Tracev((stderr, "inflate: codes new\n"));
}
return c;
}
int inflate_codes(s, z, r)
inflate_blocks_statef *s;
z_streamp z;
int r;
{
uInt j; /* temporary storage */
inflate_huft *t; /* temporary pointer */
uInt e; /* extra bits or operation */
uLong b; /* bit buffer */
uInt k; /* bits in bit buffer */
Bytef *p; /* input data pointer */
uInt n; /* bytes available there */
Bytef *q; /* output window write pointer */
uInt m; /* bytes to end of window or read pointer */
Bytef *f; /* pointer to copy strings from */
inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
/* copy input/output information to locals (UPDATE macro restores) */
LOAD
/* process input and output based on current state */
while (1) switch (c->mode)
{ /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
case START: /* x: set up for LEN */
#ifndef SLOW
if (m >= 258 && n >= 10)
{
UPDATE
r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
LOAD
if (r != Z_OK)
{
c->mode = r == Z_STREAM_END ? WASH : BADCODE;
break;
}
}
#endif /* !SLOW */
c->sub.code.need = c->lbits;
c->sub.code.tree = c->ltree;
c->mode = LEN;
case LEN: /* i: get length/literal/eob next */
j = c->sub.code.need;
NEEDBITS(j)
t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
DUMPBITS(t->bits)
e = (uInt)(t->exop);
if (e == 0) /* literal */
{
c->sub.lit = t->base;
Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
"inflate: literal '%c'\n" :
"inflate: literal 0x%02x\n", t->base));
c->mode = LIT;
break;
}
if (e & 16) /* length */
{
c->sub.copy.get = e & 15;
c->len = t->base;
c->mode = LENEXT;
break;
}
if ((e & 64) == 0) /* next table */
{
c->sub.code.need = e;
c->sub.code.tree = t + t->base;
break;
}
if (e & 32) /* end of block */
{
Tracevv((stderr, "inflate: end of block\n"));
c->mode = WASH;
break;
}
c->mode = BADCODE; /* invalid code */
z->msg = (char*)"invalid literal/length code";
r = Z_DATA_ERROR;
LEAVE
case LENEXT: /* i: getting length extra (have base) */
j = c->sub.copy.get;
NEEDBITS(j)
c->len += (uInt)b & inflate_mask[j];
DUMPBITS(j)
c->sub.code.need = c->dbits;
c->sub.code.tree = c->dtree;
Tracevv((stderr, "inflate: length %u\n", c->len));
c->mode = DIST;
case DIST: /* i: get distance next */
j = c->sub.code.need;
NEEDBITS(j)
t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
DUMPBITS(t->bits)
e = (uInt)(t->exop);
if (e & 16) /* distance */
{
c->sub.copy.get = e & 15;
c->sub.copy.dist = t->base;
c->mode = DISTEXT;
break;
}
if ((e & 64) == 0) /* next table */
{
c->sub.code.need = e;
c->sub.code.tree = t + t->base;
break;
}
c->mode = BADCODE; /* invalid code */
z->msg = (char*)"invalid distance code";
r = Z_DATA_ERROR;
LEAVE
case DISTEXT: /* i: getting distance extra */
j = c->sub.copy.get;
NEEDBITS(j)
c->sub.copy.dist += (uInt)b & inflate_mask[j];
DUMPBITS(j)
Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
c->mode = COPY;
case COPY: /* o: copying bytes in window, waiting for space */
#ifndef __TURBOC__ /* Turbo C bug for following expression */
f = (uInt)(q - s->window) < c->sub.copy.dist ?
s->end - (c->sub.copy.dist - (q - s->window)) :
q - c->sub.copy.dist;
#else
f = q - c->sub.copy.dist;
if ((uInt)(q - s->window) < c->sub.copy.dist)
f = s->end - (c->sub.copy.dist - (uInt)(q - s->window));
#endif
while (c->len)
{
NEEDOUT
OUTBYTE(*f++)
if (f == s->end)
f = s->window;
c->len--;
}
c->mode = START;
break;
case LIT: /* o: got literal, waiting for output space */
NEEDOUT
OUTBYTE(c->sub.lit)
c->mode = START;
break;
case WASH: /* o: got eob, possibly more output */
if (k > 7) /* return unused byte, if any */
{
Assert(k < 16, "inflate_codes grabbed too many bytes")
k -= 8;
n++;
p--; /* can always return one */
}
FLUSH
if (s->read != s->write)
LEAVE
c->mode = END;
case END:
r = Z_STREAM_END;
LEAVE
case BADCODE: /* x: got error */
r = Z_DATA_ERROR;
LEAVE
default:
r = Z_STREAM_ERROR;
LEAVE
}
#ifdef NEED_DUMMY_RETURN
return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
#endif
}
void inflate_codes_free(c, z)
inflate_codes_statef *c;
z_streamp z;
{
ZFREE(z, c);
Tracev((stderr, "inflate: codes free\n"));
}

View File

@@ -1,27 +0,0 @@
/* infcodes.h -- header to use infcodes.c
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
struct inflate_codes_state;
typedef struct inflate_codes_state FAR inflate_codes_statef;
extern inflate_codes_statef *inflate_codes_new OF((
uInt, uInt,
inflate_huft *, inflate_huft *,
z_streamp ));
extern int inflate_codes OF((
inflate_blocks_statef *,
z_streamp ,
int));
extern void inflate_codes_free OF((
inflate_codes_statef *,
z_streamp ));

430
inffast.c
View File

@@ -1,170 +1,318 @@
/* inffast.c -- process literals and length/distance pairs fast /* inffast.c -- fast decoding
* Copyright (C) 1995-1998 Mark Adler * Copyright (C) 1995-2004 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
#include "zutil.h" #include "zutil.h"
#include "inftrees.h" #include "inftrees.h"
#include "infblock.h" #include "inflate.h"
#include "infcodes.h"
#include "infutil.h"
#include "inffast.h" #include "inffast.h"
struct inflate_codes_state {int dummy;}; /* for buggy compilers */ #ifndef ASMINF
/* simplify the use of the inflate_huft type with some defines */ /* Allow machine dependent optimization for post-increment or pre-increment.
#define exop word.what.Exop Based on testing to date,
#define bits word.what.Bits Pre-increment preferred for:
- PowerPC G3 (Adler)
- MIPS R5000 (Randers-Pehrson)
Post-increment preferred for:
- none
No measurable difference:
- Pentium III (Anderson)
- M68060 (Nikl)
*/
#ifdef POSTINC
# define OFF 0
# define PUP(a) *(a)++
#else
# define OFF 1
# define PUP(a) *++(a)
#endif
/* macros for bit input with no checking and for returning unused bytes */ /*
#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}} Decode literal, length, and distance codes and write out the resulting
#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;} literal and match bytes until either not enough input or output is
available, an end-of-block is encountered, or a data error is encountered.
When large enough input and output buffers are supplied to inflate(), for
example, a 16K input buffer and a 64K output buffer, more than 95% of the
inflate execution time is spent in this routine.
/* Called with number of bytes left to write in window at least 258 Entry assumptions:
(the maximum string length) and number of input bytes available
at least ten. The ten bytes are six bytes for the longest length/
distance pair plus four bytes for overloading the bit buffer. */
int inflate_fast(bl, bd, tl, td, s, z) state->mode == LEN
uInt bl, bd; strm->avail_in >= 6
inflate_huft *tl; strm->avail_out >= 258
inflate_huft *td; /* need separate declaration for Borland C++ */ start >= strm->avail_out
inflate_blocks_statef *s; state->bits < 8
z_streamp z;
On return, state->mode is one of:
LEN -- ran out of enough output space or enough available input
TYPE -- reached end of block code, inflate() to interpret next block
BAD -- error in block data
Notes:
- The maximum input bits used by a length/distance pair is 15 bits for the
length code, 5 bits for the length extra, 15 bits for the distance code,
and 13 bits for the distance extra. This totals 48 bits, or six bytes.
Therefore if strm->avail_in >= 6, then there is enough input to avoid
checking for available input while decoding.
- The maximum bytes that a single length/distance pair can output is 258
bytes, which is the maximum length that can be coded. inflate_fast()
requires strm->avail_out >= 258 for each loop to avoid checking for
output space.
*/
void inflate_fast(strm, start)
z_streamp strm;
unsigned start; /* inflate()'s starting value for strm->avail_out */
{ {
inflate_huft *t; /* temporary pointer */ struct inflate_state FAR *state;
uInt e; /* extra bits or operation */ unsigned char FAR *in; /* local strm->next_in */
uLong b; /* bit buffer */ unsigned char FAR *last; /* while in < last, enough input available */
uInt k; /* bits in bit buffer */ unsigned char FAR *out; /* local strm->next_out */
Bytef *p; /* input data pointer */ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
uInt n; /* bytes available there */ unsigned char FAR *end; /* while out < end, enough space available */
Bytef *q; /* output window write pointer */ #ifdef INFLATE_STRICT
uInt m; /* bytes to end of window or read pointer */ unsigned dmax; /* maximum distance from zlib header */
uInt ml; /* mask for literal/length tree */ #endif
uInt md; /* mask for distance tree */ unsigned wsize; /* window size or zero if not using window */
uInt c; /* bytes to copy */ unsigned whave; /* valid bytes in the window */
uInt d; /* distance back to copy from */ unsigned write; /* window write index */
Bytef *r; /* copy source pointer */ unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
unsigned long hold; /* local strm->hold */
unsigned bits; /* local strm->bits */
code const FAR *lcode; /* local strm->lencode */
code const FAR *dcode; /* local strm->distcode */
unsigned lmask; /* mask for first level of length codes */
unsigned dmask; /* mask for first level of distance codes */
code this; /* retrieved table entry */
unsigned op; /* code bits, operation, extra bits, or */
/* window position, window bytes to copy */
unsigned len; /* match length, unused bytes */
unsigned dist; /* match distance */
unsigned char FAR *from; /* where to copy match from */
/* load input, output, bit values */ /* copy state to local variables */
LOAD state = (struct inflate_state FAR *)strm->state;
in = strm->next_in - OFF;
last = in + (strm->avail_in - 5);
out = strm->next_out - OFF;
beg = out - (start - strm->avail_out);
end = out + (strm->avail_out - 257);
#ifdef INFLATE_STRICT
dmax = state->dmax;
#endif
wsize = state->wsize;
whave = state->whave;
write = state->write;
window = state->window;
hold = state->hold;
bits = state->bits;
lcode = state->lencode;
dcode = state->distcode;
lmask = (1U << state->lenbits) - 1;
dmask = (1U << state->distbits) - 1;
/* initialize masks */ /* decode literals and length/distances until end-of-block or not enough
ml = inflate_mask[bl]; input data or output space */
md = inflate_mask[bd];
/* do until not enough input or output space for fast loop */
do { /* assume called with m >= 258 && n >= 10 */
/* get literal/length code */
GRABBITS(20) /* max bits for literal/length code */
if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
{
DUMPBITS(t->bits)
Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
"inflate: * literal '%c'\n" :
"inflate: * literal 0x%02x\n", t->base));
*q++ = (Byte)t->base;
m--;
continue;
}
do { do {
DUMPBITS(t->bits) if (bits < 15) {
if (e & 16) hold += (unsigned long)(PUP(in)) << bits;
{ bits += 8;
/* get extra bits for length */ hold += (unsigned long)(PUP(in)) << bits;
e &= 15; bits += 8;
c = t->base + ((uInt)b & inflate_mask[e]);
DUMPBITS(e)
Tracevv((stderr, "inflate: * length %u\n", c));
/* decode distance base of block to copy */
GRABBITS(15); /* max bits for distance code */
e = (t = td + ((uInt)b & md))->exop;
do {
DUMPBITS(t->bits)
if (e & 16)
{
/* get extra bits to add to distance base */
e &= 15;
GRABBITS(e) /* get extra bits (up to 13) */
d = t->base + ((uInt)b & inflate_mask[e]);
DUMPBITS(e)
Tracevv((stderr, "inflate: * distance %u\n", d));
/* do the copy */
m -= c;
if ((uInt)(q - s->window) >= d) /* offset before dest */
{ /* just copy */
r = q - d;
*q++ = *r++; c--; /* minimum count is three, */
*q++ = *r++; c--; /* so unroll loop a little */
} }
else /* else offset after destination */ this = lcode[hold & lmask];
{ dolen:
e = d - (uInt)(q - s->window); /* bytes from offset to end */ op = (unsigned)(this.bits);
r = s->end - e; /* pointer to offset */ hold >>= op;
if (c > e) /* if source crosses, */ bits -= op;
{ op = (unsigned)(this.op);
c -= e; /* copy to end of window */ if (op == 0) { /* literal */
do { Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
*q++ = *r++; "inflate: literal '%c'\n" :
} while (--e); "inflate: literal 0x%02x\n", this.val));
r = s->window; /* copy rest from start of window */ PUP(out) = (unsigned char)(this.val);
}
else if (op & 16) { /* length base */
len = (unsigned)(this.val);
op &= 15; /* number of extra bits */
if (op) {
if (bits < op) {
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
}
len += (unsigned)hold & ((1U << op) - 1);
hold >>= op;
bits -= op;
}
Tracevv((stderr, "inflate: length %u\n", len));
if (bits < 15) {
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
}
this = dcode[hold & dmask];
dodist:
op = (unsigned)(this.bits);
hold >>= op;
bits -= op;
op = (unsigned)(this.op);
if (op & 16) { /* distance base */
dist = (unsigned)(this.val);
op &= 15; /* number of extra bits */
if (bits < op) {
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
if (bits < op) {
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
} }
} }
do { /* copy all or what's left */ dist += (unsigned)hold & ((1U << op) - 1);
*q++ = *r++; #ifdef INFLATE_STRICT
} while (--c); if (dist > dmax) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD;
break; break;
} }
else if ((e & 64) == 0) #endif
{ hold >>= op;
t += t->base; bits -= op;
e = (t += ((uInt)b & inflate_mask[e]))->exop; Tracevv((stderr, "inflate: distance %u\n", dist));
} op = (unsigned)(out - beg); /* max distance in output */
else if (dist > op) { /* see if copy from window */
{ op = dist - op; /* distance back in window */
z->msg = (char*)"invalid distance code"; if (op > whave) {
UNGRAB strm->msg = (char *)"invalid distance too far back";
UPDATE state->mode = BAD;
return Z_DATA_ERROR;
}
} while (1);
break; break;
} }
if ((e & 64) == 0) from = window - OFF;
{ if (write == 0) { /* very common case */
t += t->base; from += wsize - op;
if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0) if (op < len) { /* some from window */
{ len -= op;
DUMPBITS(t->bits) do {
Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? PUP(out) = PUP(from);
"inflate: * literal '%c'\n" : } while (--op);
"inflate: * literal 0x%02x\n", t->base)); from = out - dist; /* rest from output */
*q++ = (Byte)t->base; }
m--; }
else if (write < op) { /* wrap around window */
from += wsize + write - op;
op -= write;
if (op < len) { /* some from end of window */
len -= op;
do {
PUP(out) = PUP(from);
} while (--op);
from = window - OFF;
if (write < len) { /* some from start of window */
op = write;
len -= op;
do {
PUP(out) = PUP(from);
} while (--op);
from = out - dist; /* rest from output */
}
}
}
else { /* contiguous in window */
from += write - op;
if (op < len) { /* some from window */
len -= op;
do {
PUP(out) = PUP(from);
} while (--op);
from = out - dist; /* rest from output */
}
}
while (len > 2) {
PUP(out) = PUP(from);
PUP(out) = PUP(from);
PUP(out) = PUP(from);
len -= 3;
}
if (len) {
PUP(out) = PUP(from);
if (len > 1)
PUP(out) = PUP(from);
}
}
else {
from = out - dist; /* copy direct from output */
do { /* minimum length is three */
PUP(out) = PUP(from);
PUP(out) = PUP(from);
PUP(out) = PUP(from);
len -= 3;
} while (len > 2);
if (len) {
PUP(out) = PUP(from);
if (len > 1)
PUP(out) = PUP(from);
}
}
}
else if ((op & 64) == 0) { /* 2nd level distance code */
this = dcode[this.val + (hold & ((1U << op) - 1))];
goto dodist;
}
else {
strm->msg = (char *)"invalid distance code";
state->mode = BAD;
break; break;
} }
} }
else if (e & 32) else if ((op & 64) == 0) { /* 2nd level length code */
{ this = lcode[this.val + (hold & ((1U << op) - 1))];
Tracevv((stderr, "inflate: * end of block\n")); goto dolen;
UNGRAB
UPDATE
return Z_STREAM_END;
} }
else else if (op & 32) { /* end-of-block */
{ Tracevv((stderr, "inflate: end of block\n"));
z->msg = (char*)"invalid literal/length code"; state->mode = TYPE;
UNGRAB break;
UPDATE
return Z_DATA_ERROR;
} }
} while (1); else {
} while (m >= 258 && n >= 10); strm->msg = (char *)"invalid literal/length code";
state->mode = BAD;
break;
}
} while (in < last && out < end);
/* not enough input or output--restore pointers and return */ /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
UNGRAB len = bits >> 3;
UPDATE in -= len;
return Z_OK; bits -= len << 3;
hold &= (1U << bits) - 1;
/* update state and return */
strm->next_in = in + OFF;
strm->next_out = out + OFF;
strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
strm->avail_out = (unsigned)(out < end ?
257 + (end - out) : 257 - (out - end));
state->hold = hold;
state->bits = bits;
return;
} }
/*
inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
- Using bit fields for code structure
- Different op definition to avoid & for extra bits (do & for table bits)
- Three separate decoding do-loops for direct, window, and write == 0
- Special case for distance > 1 copies to do overlapped load and store copy
- Explicit branch predictions (based on measured branch probabilities)
- Deferring match copy and interspersed it with decoding subsequent codes
- Swapping literal/length else
- Swapping window/direct else
- Larger unrolled copy loops (three is about right)
- Moving len -= 3 statement into middle of loop
*/
#endif /* !ASMINF */

View File

@@ -1,5 +1,5 @@
/* inffast.h -- header to use inffast.c /* inffast.h -- header to use inffast.c
* Copyright (C) 1995-1998 Mark Adler * Copyright (C) 1995-2003 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -8,10 +8,4 @@
subject to change. Applications should only use zlib.h. subject to change. Applications should only use zlib.h.
*/ */
extern int inflate_fast OF(( void inflate_fast OF((z_streamp strm, unsigned start));
uInt,
uInt,
inflate_huft *,
inflate_huft *,
inflate_blocks_statef *,
z_streamp ));

View File

@@ -1,151 +1,94 @@
/* inffixed.h -- table for decoding fixed codes /* inffixed.h -- table for decoding fixed codes
* Generated automatically by the maketree.c program * Generated automatically by makefixed().
*/ */
/* WARNING: this file should *not* be used by applications. It is /* WARNING: this file should *not* be used by applications. It
part of the implementation of the compression library and is is part of the implementation of the compression library and
subject to change. Applications should only use zlib.h. is subject to change. Applications should only use zlib.h.
*/ */
local uInt fixed_bl = 9; static const code lenfix[512] = {
local uInt fixed_bd = 5; {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
local inflate_huft fixed_tl[] = { {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
{{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
{{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
{{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
{{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224}, {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
{{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144}, {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
{{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208}, {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
{{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176}, {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
{{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240}, {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
{{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
{{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200}, {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
{{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168}, {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
{{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232}, {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
{{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152}, {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
{{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216}, {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
{{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184}, {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
{{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248}, {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
{{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
{{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196}, {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
{{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164}, {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
{{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228}, {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
{{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148}, {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
{{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212}, {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
{{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180}, {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
{{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244}, {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
{{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
{{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204}, {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
{{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172}, {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
{{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236}, {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
{{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156}, {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
{{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220}, {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
{{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188}, {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
{{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252}, {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
{{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
{{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194}, {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
{{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162}, {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
{{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226}, {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
{{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146}, {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
{{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210}, {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
{{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178}, {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
{{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242}, {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
{{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
{{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202}, {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
{{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170}, {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
{{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234}, {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
{{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154}, {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
{{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218}, {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
{{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186}, {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
{{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250}, {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
{{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
{{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198}, {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
{{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166}, {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
{{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230}, {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
{{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150}, {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
{{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214}, {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
{{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182}, {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
{{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246}, {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
{{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
{{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206}, {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
{{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174}, {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
{{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238}, {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
{{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158}, {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
{{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222}, {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
{{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190}, {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
{{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254}, {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
{{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
{{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193}, {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
{{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161}, {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
{{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225}, {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
{{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145}, {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
{{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209}, {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
{{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177}, {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
{{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241}, {0,9,255}
{{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
{{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
{{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
{{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
{{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
{{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
{{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
{{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
{{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
{{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
{{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
{{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
{{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
{{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
{{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
{{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
{{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
{{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
{{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
{{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
{{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
{{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
{{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
{{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
{{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
{{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
{{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
{{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
{{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
{{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
{{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
{{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
{{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
{{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
{{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
{{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
{{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
{{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
{{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
{{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
{{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
{{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
{{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
{{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
{{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
{{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
{{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
{{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
{{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
{{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
{{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
{{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
{{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
{{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
{{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
{{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
}; };
local inflate_huft fixed_td[] = {
{{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, static const code distfix[32] = {
{{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
{{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
{{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577}, {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
{{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145}, {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
{{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577}, {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
{{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289}, {22,5,193},{64,5,0}
{{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
}; };

1673
inflate.c

File diff suppressed because it is too large Load Diff

115
inflate.h Normal file
View File

@@ -0,0 +1,115 @@
/* inflate.h -- internal inflate state definition
* Copyright (C) 1995-2004 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
/* define NO_GZIP when compiling if you want to disable gzip header and
trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
the crc code when it is not needed. For shared libraries, gzip decoding
should be left enabled. */
#ifndef NO_GZIP
# define GUNZIP
#endif
/* Possible inflate modes between inflate() calls */
typedef enum {
HEAD, /* i: waiting for magic header */
FLAGS, /* i: waiting for method and flags (gzip) */
TIME, /* i: waiting for modification time (gzip) */
OS, /* i: waiting for extra flags and operating system (gzip) */
EXLEN, /* i: waiting for extra length (gzip) */
EXTRA, /* i: waiting for extra bytes (gzip) */
NAME, /* i: waiting for end of file name (gzip) */
COMMENT, /* i: waiting for end of comment (gzip) */
HCRC, /* i: waiting for header crc (gzip) */
DICTID, /* i: waiting for dictionary check value */
DICT, /* waiting for inflateSetDictionary() call */
TYPE, /* i: waiting for type bits, including last-flag bit */
TYPEDO, /* i: same, but skip check to exit inflate on new block */
STORED, /* i: waiting for stored size (length and complement) */
COPY, /* i/o: waiting for input or output to copy stored block */
TABLE, /* i: waiting for dynamic block table lengths */
LENLENS, /* i: waiting for code length code lengths */
CODELENS, /* i: waiting for length/lit and distance code lengths */
LEN, /* i: waiting for length/lit code */
LENEXT, /* i: waiting for length extra bits */
DIST, /* i: waiting for distance code */
DISTEXT, /* i: waiting for distance extra bits */
MATCH, /* o: waiting for output space to copy string */
LIT, /* o: waiting for output space to write literal */
CHECK, /* i: waiting for 32-bit check value */
LENGTH, /* i: waiting for 32-bit length (gzip) */
DONE, /* finished check, done -- remain here until reset */
BAD, /* got a data error -- remain here until reset */
MEM, /* got an inflate() memory error -- remain here until reset */
SYNC /* looking for synchronization bytes to restart inflate() */
} inflate_mode;
/*
State transitions between above modes -
(most modes can go to the BAD or MEM mode -- not shown for clarity)
Process header:
HEAD -> (gzip) or (zlib)
(gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
NAME -> COMMENT -> HCRC -> TYPE
(zlib) -> DICTID or TYPE
DICTID -> DICT -> TYPE
Read deflate blocks:
TYPE -> STORED or TABLE or LEN or CHECK
STORED -> COPY -> TYPE
TABLE -> LENLENS -> CODELENS -> LEN
Read deflate codes:
LEN -> LENEXT or LIT or TYPE
LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
LIT -> LEN
Process trailer:
CHECK -> LENGTH -> DONE
*/
/* state maintained between inflate() calls. Approximately 7K bytes. */
struct inflate_state {
inflate_mode mode; /* current inflate mode */
int last; /* true if processing last block */
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
int havedict; /* true if dictionary provided */
int flags; /* gzip header method and flags (0 if zlib) */
unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
unsigned long check; /* protected copy of check value */
unsigned long total; /* protected copy of output count */
gz_headerp head; /* where to save gzip header information */
/* sliding window */
unsigned wbits; /* log base 2 of requested window size */
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
unsigned write; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if needed */
/* bit accumulator */
unsigned long hold; /* input bit accumulator */
unsigned bits; /* number of bits in "in" */
/* for string and stored block copying */
unsigned length; /* literal or length of data to copy */
unsigned offset; /* distance back to copy string from */
/* for table and code decoding */
unsigned extra; /* extra bits needed */
/* fixed and dynamic code tables */
code const FAR *lencode; /* starting table for length/literal codes */
code const FAR *distcode; /* starting table for distance codes */
unsigned lenbits; /* index bits for lencode */
unsigned distbits; /* index bits for distcode */
/* dynamic table building */
unsigned ncode; /* number of code length code lengths */
unsigned nlen; /* number of length code lengths */
unsigned ndist; /* number of distance code lengths */
unsigned have; /* number of code lengths in lens[] */
code FAR *next; /* next available space in codes[] */
unsigned short lens[320]; /* temporary storage for code lengths */
unsigned short work[288]; /* work area for code table building */
code codes[ENOUGH]; /* space for code tables */
};

View File

@@ -1,455 +1,329 @@
/* inftrees.c -- generate Huffman trees for efficient decoding /* inftrees.c -- generate Huffman trees for efficient decoding
* Copyright (C) 1995-1998 Mark Adler * Copyright (C) 1995-2005 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
#include "zutil.h" #include "zutil.h"
#include "inftrees.h" #include "inftrees.h"
#if !defined(BUILDFIXED) && !defined(STDC) #define MAXBITS 15
# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */
#endif
const char inflate_copyright[] = const char inflate_copyright[] =
" inflate 1.1.3 Copyright 1995-1998 Mark Adler "; " inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
/* /*
If you use the zlib library in a product, an acknowledgment is welcome If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot in the documentation of your product. If for some reason you cannot
include such an acknowledgment, I would appreciate that you keep this include such an acknowledgment, I would appreciate that you keep this
copyright string in the executable of your product. copyright string in the executable of your product.
*/ */
struct internal_state {int dummy;}; /* for buggy compilers */
/* simplify the use of the inflate_huft type with some defines */
#define exop word.what.Exop
#define bits word.what.Bits
local int huft_build OF((
uIntf *, /* code lengths in bits */
uInt, /* number of codes */
uInt, /* number of "simple" codes */
const uIntf *, /* list of base values for non-simple codes */
const uIntf *, /* list of extra bits for non-simple codes */
inflate_huft * FAR*,/* result: starting table */
uIntf *, /* maximum lookup bits (returns actual) */
inflate_huft *, /* space for trees */
uInt *, /* hufts used in space */
uIntf * )); /* space for values */
/* Tables for deflate from PKZIP's appnote.txt. */
local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
/* see note #13 above about 258 */
local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
8193, 12289, 16385, 24577};
local const uInt cpdext[30] = { /* Extra bits for distance codes */
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
12, 12, 13, 13};
/* /*
Huffman code decoding is performed using a multi-level table lookup. Build a set of tables to decode the provided canonical Huffman code.
The fastest way to decode is to simply build a lookup table whose The code lengths are lens[0..codes-1]. The result starts at *table,
size is determined by the longest code. However, the time it takes whose indices are 0..2^bits-1. work is a writable array of at least
to build this table can also be a factor if the data being decoded lens shorts, which is used as a work area. type is the type of code
is not very long. The most common codes are necessarily the to be generated, CODES, LENS, or DISTS. On return, zero is success,
shortest codes, so those codes dominate the decoding time, and hence -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
the speed. The idea is you can have a shorter table that decodes the on return points to the next available entry's address. bits is the
shorter, more probable codes, and then point to subsidiary tables for requested root table index bits, and on return it is the actual root
the longer codes. The time it costs to decode the longer codes is table index bits. It will differ if the request is greater than the
then traded against the time it takes to make longer tables. longest code or if it is less than the shortest code.
*/
int inflate_table(type, lens, codes, table, bits, work)
codetype type;
unsigned short FAR *lens;
unsigned codes;
code FAR * FAR *table;
unsigned FAR *bits;
unsigned short FAR *work;
{
unsigned len; /* a code's length in bits */
unsigned sym; /* index of code symbols */
unsigned min, max; /* minimum and maximum code lengths */
unsigned root; /* number of index bits for root table */
unsigned curr; /* number of index bits for current table */
unsigned drop; /* code bits to drop for sub-table */
int left; /* number of prefix codes available */
unsigned used; /* code entries in table used */
unsigned huff; /* Huffman code */
unsigned incr; /* for incrementing code, index */
unsigned fill; /* index for replicating entries */
unsigned low; /* low bits for current root entry */
unsigned mask; /* mask for low root bits */
code this; /* table entry for duplication */
code FAR *next; /* next available space in table */
const unsigned short FAR *base; /* base value table to use */
const unsigned short FAR *extra; /* extra bits table to use */
int end; /* use base and extra for symbol > end */
unsigned short count[MAXBITS+1]; /* number of codes of each length */
unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
static const unsigned short lbase[31] = { /* Length codes 257..285 base */
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
8193, 12289, 16385, 24577, 0, 0};
static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
28, 28, 29, 29, 64, 64};
This results of this trade are in the variables lbits and dbits /*
below. lbits is the number of bits the first level table for literal/ Process a set of code lengths to create a canonical Huffman code. The
length codes can decode in one step, and dbits is the same thing for code lengths are lens[0..codes-1]. Each length corresponds to the
the distance codes. Subsequent tables are also less than or equal to symbols 0..codes-1. The Huffman code is generated by first sorting the
those sizes. These values may be adjusted either when all of the symbols by length from short to long, and retaining the symbol order
codes are shorter than that, in which case the longest code length in for codes with equal lengths. Then the code starts with all zero bits
bits is used, or when the shortest code is *longer* than the requested for the first code of the shortest length, and the codes are integer
table size, in which case the length of the shortest code in bits is increments for the same length, and zeros are appended as the length
used. increases. For the deflate format, these bits are stored backwards
from their more natural integer increment ordering, and so when the
decoding tables are built in the large loop below, the integer codes
are incremented backwards.
There are two different values for the two tables, since they code a This routine assumes, but does not check, that all of the entries in
different number of possibilities each. The literal/length table lens[] are in the range 0..MAXBITS. The caller must assure this.
codes 286 possible values, or in a flat code, a little over eight 1..MAXBITS is interpreted as that code length. zero means that that
bits. The distance table codes 30 possible values, or a little less symbol does not occur in this code.
than five bits, flat. The optimum values for speed end up being
about one bit more than those, so lbits is 8+1 and dbits is 5+1. The codes are sorted by computing a count of codes for each length,
The optimum values may differ though from machine to machine, and creating from that a table of starting indices for each length in the
possibly even between compilers. Your mileage may vary. sorted table, and then entering the symbols in order in the sorted
table. The sorted table is work[], with that space being provided by
the caller.
The length counts are used for other purposes as well, i.e. finding
the minimum and maximum length codes, determining if there are any
codes at all, checking for a valid set of lengths, and looking ahead
at length counts to determine sub-table sizes when building the
decoding tables.
*/ */
/* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
for (len = 0; len <= MAXBITS; len++)
count[len] = 0;
for (sym = 0; sym < codes; sym++)
count[lens[sym]]++;
/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ /* bound code lengths, force root to be within code lengths */
#define BMAX 15 /* maximum bit length of any code */ root = *bits;
for (max = MAXBITS; max >= 1; max--)
local int huft_build(b, n, s, d, e, t, m, hp, hn, v) if (count[max] != 0) break;
uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ if (root > max) root = max;
uInt n; /* number of codes (assumed <= 288) */ if (max == 0) { /* no symbols to code at all */
uInt s; /* number of simple-valued codes (0..s-1) */ this.op = (unsigned char)64; /* invalid code marker */
const uIntf *d; /* list of base values for non-simple codes */ this.bits = (unsigned char)1;
const uIntf *e; /* list of extra bits for non-simple codes */ this.val = (unsigned short)0;
inflate_huft * FAR *t; /* result: starting table */ *(*table)++ = this; /* make a table to force an error */
uIntf *m; /* maximum lookup bits, returns actual */ *(*table)++ = this;
inflate_huft *hp; /* space for trees */ *bits = 1;
uInt *hn; /* hufts used in space */ return 0; /* no symbols, but wait for decoding to report error */
uIntf *v; /* working area: values in order of bit length */
/* Given a list of code lengths and a maximum table size, make a set of
tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
if the given code set is incomplete (the tables are still built in this
case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of
lengths), or Z_MEM_ERROR if not enough memory. */
{
uInt a; /* counter for codes of length k */
uInt c[BMAX+1]; /* bit length count table */
uInt f; /* i repeats in table every f entries */
int g; /* maximum code length */
int h; /* table level */
register uInt i; /* counter, current code */
register uInt j; /* counter */
register int k; /* number of bits in current code */
int l; /* bits per table (returned in m) */
uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */
register uIntf *p; /* pointer into c[], b[], or v[] */
inflate_huft *q; /* points to current table */
struct inflate_huft_s r; /* table entry for structure assignment */
inflate_huft *u[BMAX]; /* table stack */
register int w; /* bits before this table == (l * h) */
uInt x[BMAX+1]; /* bit offsets, then code stack */
uIntf *xp; /* pointer into x */
int y; /* number of dummy codes added */
uInt z; /* number of entries in current table */
/* Generate counts for each bit length */
p = c;
#define C0 *p++ = 0;
#define C2 C0 C0 C0 C0
#define C4 C2 C2 C2 C2
C4 /* clear c[]--assume BMAX+1 is 16 */
p = b; i = n;
do {
c[*p++]++; /* assume all entries <= BMAX */
} while (--i);
if (c[0] == n) /* null input--all zero length codes */
{
*t = (inflate_huft *)Z_NULL;
*m = 0;
return Z_OK;
} }
for (min = 1; min <= MAXBITS; min++)
if (count[min] != 0) break;
if (root < min) root = min;
/* check for an over-subscribed or incomplete set of lengths */
left = 1;
for (len = 1; len <= MAXBITS; len++) {
left <<= 1;
left -= count[len];
if (left < 0) return -1; /* over-subscribed */
}
if (left > 0 && (type == CODES || max != 1))
return -1; /* incomplete set */
/* Find minimum and maximum length, bound *m by those */ /* generate offsets into symbol table for each length for sorting */
l = *m; offs[1] = 0;
for (j = 1; j <= BMAX; j++) for (len = 1; len < MAXBITS; len++)
if (c[j]) offs[len + 1] = offs[len] + count[len];
/* sort symbols by length, by symbol order within each length */
for (sym = 0; sym < codes; sym++)
if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
/*
Create and fill in decoding tables. In this loop, the table being
filled is at next and has curr index bits. The code being used is huff
with length len. That code is converted to an index by dropping drop
bits off of the bottom. For codes where len is less than drop + curr,
those top drop + curr - len bits are incremented through all values to
fill the table with replicated entries.
root is the number of index bits for the root table. When len exceeds
root, sub-tables are created pointed to by the root entry with an index
of the low root bits of huff. This is saved in low to check for when a
new sub-table should be started. drop is zero when the root table is
being filled, and drop is root when sub-tables are being filled.
When a new sub-table is needed, it is necessary to look ahead in the
code lengths to determine what size sub-table is needed. The length
counts are used for this, and so count[] is decremented as codes are
entered in the tables.
used keeps track of how many table entries have been allocated from the
provided *table space. It is checked when a LENS table is being made
against the space in *table, ENOUGH, minus the maximum space needed by
the worst case distance code, MAXD. This should never happen, but the
sufficiency of ENOUGH has not been proven exhaustively, hence the check.
This assumes that when type == LENS, bits == 9.
sym increments through all symbols, and the loop terminates when
all codes of length max, i.e. all codes, have been processed. This
routine permits incomplete codes, so another loop after this one fills
in the rest of the decoding tables with invalid code markers.
*/
/* set up for code type */
switch (type) {
case CODES:
base = extra = work; /* dummy value--not used */
end = 19;
break; break;
k = j; /* minimum code length */ case LENS:
if ((uInt)l < j) base = lbase;
l = j; base -= 257;
for (i = BMAX; i; i--) extra = lext;
if (c[i]) extra -= 257;
end = 256;
break; break;
g = i; /* maximum code length */ default: /* DISTS */
if ((uInt)l > i) base = dbase;
l = i; extra = dext;
*m = l; end = -1;
/* Adjust last length count to fill out codes, if needed */
for (y = 1 << j; j < i; j++, y <<= 1)
if ((y -= c[j]) < 0)
return Z_DATA_ERROR;
if ((y -= c[i]) < 0)
return Z_DATA_ERROR;
c[i] += y;
/* Generate starting offsets into the value table for each length */
x[1] = j = 0;
p = c + 1; xp = x + 2;
while (--i) { /* note that i == g from above */
*xp++ = (j += *p++);
} }
/* initialize state for loop */
huff = 0; /* starting code */
sym = 0; /* starting code symbol */
len = min; /* starting code length */
next = *table; /* current table to fill in */
curr = root; /* current table index bits */
drop = 0; /* current bits to drop from code for index */
low = (unsigned)(-1); /* trigger new sub-table when len > root */
used = 1U << root; /* use root table entries */
mask = used - 1; /* mask for comparing low */
/* Make a table of values in order of bit lengths */ /* check available table space */
p = b; i = 0; if (type == LENS && used >= ENOUGH - MAXD)
return 1;
/* process all codes and make table entries */
for (;;) {
/* create table entry */
this.bits = (unsigned char)(len - drop);
if ((int)(work[sym]) < end) {
this.op = (unsigned char)0;
this.val = work[sym];
}
else if ((int)(work[sym]) > end) {
this.op = (unsigned char)(extra[work[sym]]);
this.val = base[work[sym]];
}
else {
this.op = (unsigned char)(32 + 64); /* end of block */
this.val = 0;
}
/* replicate for those indices with low len bits equal to huff */
incr = 1U << (len - drop);
fill = 1U << curr;
min = fill; /* save offset to next table */
do { do {
if ((j = *p++) != 0) fill -= incr;
v[x[j]++] = i; next[(huff >> drop) + fill] = this;
} while (++i < n); } while (fill != 0);
n = x[g]; /* set n to length of v */
/* backwards increment the len-bit code huff */
/* Generate the Huffman codes and for each, make the table entries */ incr = 1U << (len - 1);
x[0] = i = 0; /* first Huffman code is zero */ while (huff & incr)
p = v; /* grab values in bit order */ incr >>= 1;
h = -1; /* no tables yet--level -1 */ if (incr != 0) {
w = -l; /* bits decoded == (l * h) */ huff &= incr - 1;
u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ huff += incr;
q = (inflate_huft *)Z_NULL; /* ditto */
z = 0; /* ditto */
/* go through the bit lengths (k already is bits in shortest code) */
for (; k <= g; k++)
{
a = c[k];
while (a--)
{
/* here i is the Huffman code of length k bits for value *p */
/* make tables up to required level */
while (k > w + l)
{
h++;
w += l; /* previous table always l bits */
/* compute minimum size table less than or equal to l bits */
z = g - w;
z = z > (uInt)l ? l : z; /* table size upper limit */
if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
{ /* too few codes for k-w bit table */
f -= a + 1; /* deduct codes from patterns left */
xp = c + k;
if (j < z)
while (++j < z) /* try smaller tables up to z bits */
{
if ((f <<= 1) <= *++xp)
break; /* enough codes to use up j bits */
f -= *xp; /* else deduct codes from patterns */
}
}
z = 1 << j; /* table entries for j-bit table */
/* allocate new table */
if (*hn + z > MANY) /* (note: doesn't matter for fixed) */
return Z_MEM_ERROR; /* not enough memory */
u[h] = q = hp + *hn;
*hn += z;
/* connect to last table, if there is one */
if (h)
{
x[h] = i; /* save pattern for backing up */
r.bits = (Byte)l; /* bits to dump before this table */
r.exop = (Byte)j; /* bits in this table */
j = i >> (w - l);
r.base = (uInt)(q - u[h-1] - j); /* offset to this table */
u[h-1][j] = r; /* connect to last table */
} }
else else
*t = q; /* first table is returned result */ huff = 0;
/* go to next symbol, update count, len */
sym++;
if (--(count[len]) == 0) {
if (len == max) break;
len = lens[work[sym]];
} }
/* set up table entry in r */ /* create new sub-table if needed */
r.bits = (Byte)(k - w); if (len > root && (huff & mask) != low) {
if (p >= v + n) /* if first time, transition to sub-tables */
r.exop = 128 + 64; /* out of values--invalid code */ if (drop == 0)
else if (*p < s) drop = root;
{
r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ /* increment past last table */
r.base = *p++; /* simple code is just the value */ next += min; /* here min is 1 << curr */
/* determine length of next table */
curr = len - drop;
left = (int)(1 << curr);
while (curr + drop < max) {
left -= count[curr + drop];
if (left <= 0) break;
curr++;
left <<= 1;
}
/* check for enough space */
used += 1U << curr;
if (type == LENS && used >= ENOUGH - MAXD)
return 1;
/* point entry in root table to sub-table */
low = huff & mask;
(*table)[low].op = (unsigned char)curr;
(*table)[low].bits = (unsigned char)root;
(*table)[low].val = (unsigned short)(next - *table);
}
}
/*
Fill in rest of table for incomplete codes. This loop is similar to the
loop above in incrementing huff for table indices. It is assumed that
len is equal to curr + drop, so there is no loop needed to increment
through high index bits. When the current sub-table is filled, the loop
drops back to the root table to fill in any remaining entries there.
*/
this.op = (unsigned char)64; /* invalid code marker */
this.bits = (unsigned char)(len - drop);
this.val = (unsigned short)0;
while (huff != 0) {
/* when done with sub-table, drop back to root table */
if (drop != 0 && (huff & mask) != low) {
drop = 0;
len = root;
next = *table;
this.bits = (unsigned char)len;
}
/* put invalid code marker in table */
next[huff >> drop] = this;
/* backwards increment the len-bit code huff */
incr = 1U << (len - 1);
while (huff & incr)
incr >>= 1;
if (incr != 0) {
huff &= incr - 1;
huff += incr;
} }
else else
{ huff = 0;
r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
r.base = d[*p++ - s];
} }
/* fill code-like entries with r */ /* set return parameters */
f = 1 << (k - w); *table += used;
for (j = i >> w; j < z; j += f) *bits = root;
q[j] = r; return 0;
/* backwards increment the k-bit code i */
for (j = 1 << (k - 1); i & j; j >>= 1)
i ^= j;
i ^= j;
/* backup over finished tables */
mask = (1 << w) - 1; /* needed on HP, cc -O bug */
while ((i & mask) != x[h])
{
h--; /* don't need to update q */
w -= l;
mask = (1 << w) - 1;
}
}
}
/* Return Z_BUF_ERROR if we were given an incomplete table */
return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
}
int inflate_trees_bits(c, bb, tb, hp, z)
uIntf *c; /* 19 code lengths */
uIntf *bb; /* bits tree desired/actual depth */
inflate_huft * FAR *tb; /* bits tree result */
inflate_huft *hp; /* space for trees */
z_streamp z; /* for messages */
{
int r;
uInt hn = 0; /* hufts used in space */
uIntf *v; /* work area for huft_build */
if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
return Z_MEM_ERROR;
r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
tb, bb, hp, &hn, v);
if (r == Z_DATA_ERROR)
z->msg = (char*)"oversubscribed dynamic bit lengths tree";
else if (r == Z_BUF_ERROR || *bb == 0)
{
z->msg = (char*)"incomplete dynamic bit lengths tree";
r = Z_DATA_ERROR;
}
ZFREE(z, v);
return r;
}
int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
uInt nl; /* number of literal/length codes */
uInt nd; /* number of distance codes */
uIntf *c; /* that many (total) code lengths */
uIntf *bl; /* literal desired/actual bit depth */
uIntf *bd; /* distance desired/actual bit depth */
inflate_huft * FAR *tl; /* literal/length tree result */
inflate_huft * FAR *td; /* distance tree result */
inflate_huft *hp; /* space for trees */
z_streamp z; /* for messages */
{
int r;
uInt hn = 0; /* hufts used in space */
uIntf *v; /* work area for huft_build */
/* allocate work area */
if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
return Z_MEM_ERROR;
/* build literal/length tree */
r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
if (r != Z_OK || *bl == 0)
{
if (r == Z_DATA_ERROR)
z->msg = (char*)"oversubscribed literal/length tree";
else if (r != Z_MEM_ERROR)
{
z->msg = (char*)"incomplete literal/length tree";
r = Z_DATA_ERROR;
}
ZFREE(z, v);
return r;
}
/* build distance tree */
r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
if (r != Z_OK || (*bd == 0 && nl > 257))
{
if (r == Z_DATA_ERROR)
z->msg = (char*)"oversubscribed distance tree";
else if (r == Z_BUF_ERROR) {
#ifdef PKZIP_BUG_WORKAROUND
r = Z_OK;
}
#else
z->msg = (char*)"incomplete distance tree";
r = Z_DATA_ERROR;
}
else if (r != Z_MEM_ERROR)
{
z->msg = (char*)"empty distance tree with lengths";
r = Z_DATA_ERROR;
}
ZFREE(z, v);
return r;
#endif
}
/* done */
ZFREE(z, v);
return Z_OK;
}
/* build fixed tables only once--keep them here */
#ifdef BUILDFIXED
local int fixed_built = 0;
#define FIXEDH 544 /* number of hufts used by fixed tables */
local inflate_huft fixed_mem[FIXEDH];
local uInt fixed_bl;
local uInt fixed_bd;
local inflate_huft *fixed_tl;
local inflate_huft *fixed_td;
#else
#include "inffixed.h"
#endif
int inflate_trees_fixed(bl, bd, tl, td, z)
uIntf *bl; /* literal desired/actual bit depth */
uIntf *bd; /* distance desired/actual bit depth */
inflate_huft * FAR *tl; /* literal/length tree result */
inflate_huft * FAR *td; /* distance tree result */
z_streamp z; /* for memory allocation */
{
#ifdef BUILDFIXED
/* build fixed tables if not already */
if (!fixed_built)
{
int k; /* temporary variable */
uInt f = 0; /* number of hufts used in fixed_mem */
uIntf *c; /* length list for huft_build */
uIntf *v; /* work area for huft_build */
/* allocate memory */
if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
return Z_MEM_ERROR;
if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
{
ZFREE(z, c);
return Z_MEM_ERROR;
}
/* literal table */
for (k = 0; k < 144; k++)
c[k] = 8;
for (; k < 256; k++)
c[k] = 9;
for (; k < 280; k++)
c[k] = 7;
for (; k < 288; k++)
c[k] = 8;
fixed_bl = 9;
huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
fixed_mem, &f, v);
/* distance table */
for (k = 0; k < 30; k++)
c[k] = 5;
fixed_bd = 5;
huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
fixed_mem, &f, v);
/* done */
ZFREE(z, v);
ZFREE(z, c);
fixed_built = 1;
}
#endif
*bl = fixed_bl;
*bd = fixed_bd;
*tl = fixed_tl;
*td = fixed_td;
return Z_OK;
} }

View File

@@ -1,5 +1,5 @@
/* inftrees.h -- header to use inftrees.c /* inftrees.h -- header to use inftrees.c
* Copyright (C) 1995-1998 Mark Adler * Copyright (C) 1995-2005 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -8,51 +8,48 @@
subject to change. Applications should only use zlib.h. subject to change. Applications should only use zlib.h.
*/ */
/* Huffman code lookup table entry--this entry is four bytes for machines /* Structure for decoding tables. Each entry provides either the
that have 16-bit pointers (e.g. PC's in the small or medium model). */ information needed to do the operation requested by the code that
indexed that table entry, or it provides a pointer to another
table that indexes more bits of the code. op indicates whether
the entry is a pointer to another table, a literal, a length or
distance, an end-of-block, or an invalid code. For a table
pointer, the low four bits of op is the number of index bits of
that table. For a length or distance, the low four bits of op
is the number of extra bits to get after the code. bits is
the number of bits in this code or part of the code to drop off
of the bit buffer. val is the actual byte to output in the case
of a literal, the base length or distance, or the offset from
the current table to the next table. Each entry is four bytes. */
typedef struct {
unsigned char op; /* operation, extra bits, table bits */
unsigned char bits; /* bits in this part of the code */
unsigned short val; /* offset in table or code value */
} code;
typedef struct inflate_huft_s FAR inflate_huft; /* op values as set by inflate_table():
00000000 - literal
struct inflate_huft_s { 0000tttt - table link, tttt != 0 is the number of table index bits
union { 0001eeee - length or distance, eeee is the number of extra bits
struct { 01100000 - end of block
Byte Exop; /* number of extra bits or operation */ 01000000 - invalid code
Byte Bits; /* number of bits in this code or subcode */ */
} what;
uInt pad; /* pad structure to a power of 2 (4 bytes for */
} word; /* 16-bit, 8 bytes for 32-bit int's) */
uInt base; /* literal, length base, distance base,
or table offset */
};
/* Maximum size of dynamic tree. The maximum found in a long but non- /* Maximum size of dynamic tree. The maximum found in a long but non-
exhaustive search was 1004 huft structures (850 for length/literals exhaustive search was 1444 code structures (852 for length/literals
and 154 for distances, the latter actually the result of an and 592 for distances, the latter actually the result of an
exhaustive search). The actual maximum is not known, but the exhaustive search). The true maximum is not known, but the value
value below is more than safe. */ below is more than safe. */
#define MANY 1440 #define ENOUGH 2048
#define MAXD 592
extern int inflate_trees_bits OF(( /* Type of code to build for inftable() */
uIntf *, /* 19 code lengths */ typedef enum {
uIntf *, /* bits tree desired/actual depth */ CODES,
inflate_huft * FAR *, /* bits tree result */ LENS,
inflate_huft *, /* space for trees */ DISTS
z_streamp)); /* for messages */ } codetype;
extern int inflate_trees_dynamic OF(( extern int inflate_table OF((codetype type, unsigned short FAR *lens,
uInt, /* number of literal/length codes */ unsigned codes, code FAR * FAR *table,
uInt, /* number of distance codes */ unsigned FAR *bits, unsigned short FAR *work));
uIntf *, /* that many (total) code lengths */
uIntf *, /* literal desired/actual bit depth */
uIntf *, /* distance desired/actual bit depth */
inflate_huft * FAR *, /* literal/length tree result */
inflate_huft * FAR *, /* distance tree result */
inflate_huft *, /* space for trees */
z_streamp)); /* for messages */
extern int inflate_trees_fixed OF((
uIntf *, /* literal desired/actual bit depth */
uIntf *, /* distance desired/actual bit depth */
inflate_huft * FAR *, /* literal/length tree result */
inflate_huft * FAR *, /* distance tree result */
z_streamp)); /* for memory allocation */

View File

@@ -1,87 +0,0 @@
/* inflate_util.c -- data and routines common to blocks and codes
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "infblock.h"
#include "inftrees.h"
#include "infcodes.h"
#include "infutil.h"
struct inflate_codes_state {int dummy;}; /* for buggy compilers */
/* And'ing with mask[n] masks the lower n bits */
uInt inflate_mask[17] = {
0x0000,
0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
};
/* copy as much as possible from the sliding window to the output area */
int inflate_flush(s, z, r)
inflate_blocks_statef *s;
z_streamp z;
int r;
{
uInt n;
Bytef *p;
Bytef *q;
/* local copies of source and destination pointers */
p = z->next_out;
q = s->read;
/* compute number of bytes to copy as far as end of window */
n = (uInt)((q <= s->write ? s->write : s->end) - q);
if (n > z->avail_out) n = z->avail_out;
if (n && r == Z_BUF_ERROR) r = Z_OK;
/* update counters */
z->avail_out -= n;
z->total_out += n;
/* update check information */
if (s->checkfn != Z_NULL)
z->adler = s->check = (*s->checkfn)(s->check, q, n);
/* copy as far as end of window */
zmemcpy(p, q, n);
p += n;
q += n;
/* see if more to copy at beginning of window */
if (q == s->end)
{
/* wrap pointers */
q = s->window;
if (s->write == s->end)
s->write = s->window;
/* compute bytes to copy */
n = (uInt)(s->write - q);
if (n > z->avail_out) n = z->avail_out;
if (n && r == Z_BUF_ERROR) r = Z_OK;
/* update counters */
z->avail_out -= n;
z->total_out += n;
/* update check information */
if (s->checkfn != Z_NULL)
z->adler = s->check = (*s->checkfn)(s->check, q, n);
/* copy */
zmemcpy(p, q, n);
p += n;
q += n;
}
/* update pointers */
z->next_out = p;
s->read = q;
/* done */
return r;
}

View File

@@ -1,98 +0,0 @@
/* infutil.h -- types and macros common to blocks and codes
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
#ifndef _INFUTIL_H
#define _INFUTIL_H
typedef enum {
TYPE, /* get type bits (3, including end bit) */
LENS, /* get lengths for stored */
STORED, /* processing stored block */
TABLE, /* get table lengths */
BTREE, /* get bit lengths tree for a dynamic block */
DTREE, /* get length, distance trees for a dynamic block */
CODES, /* processing fixed or dynamic block */
DRY, /* output remaining window bytes */
DONE, /* finished last block, done */
BAD} /* got a data error--stuck here */
inflate_block_mode;
/* inflate blocks semi-private state */
struct inflate_blocks_state {
/* mode */
inflate_block_mode mode; /* current inflate_block mode */
/* mode dependent information */
union {
uInt left; /* if STORED, bytes left to copy */
struct {
uInt table; /* table lengths (14 bits) */
uInt index; /* index into blens (or border) */
uIntf *blens; /* bit lengths of codes */
uInt bb; /* bit length tree depth */
inflate_huft *tb; /* bit length decoding tree */
} trees; /* if DTREE, decoding info for trees */
struct {
inflate_codes_statef
*codes;
} decode; /* if CODES, current state */
} sub; /* submode */
uInt last; /* true if this block is the last block */
/* mode independent information */
uInt bitk; /* bits in bit buffer */
uLong bitb; /* bit buffer */
inflate_huft *hufts; /* single malloc for tree space */
Bytef *window; /* sliding window */
Bytef *end; /* one byte after sliding window */
Bytef *read; /* window read pointer */
Bytef *write; /* window write pointer */
check_func checkfn; /* check function */
uLong check; /* check on output */
};
/* defines for inflate input/output */
/* update pointers and return */
#define UPDBITS {s->bitb=b;s->bitk=k;}
#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
#define UPDOUT {s->write=q;}
#define UPDATE {UPDBITS UPDIN UPDOUT}
#define LEAVE {UPDATE return inflate_flush(s,z,r);}
/* get bytes and bits */
#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
#define NEXTBYTE (n--,*p++)
#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
#define DUMPBITS(j) {b>>=(j);k-=(j);}
/* output bytes */
#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
/* load local pointers */
#define LOAD {LOADIN LOADOUT}
/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
extern uInt inflate_mask[17];
/* copy as much as possible from the sliding window to the output area */
extern int inflate_flush OF((
inflate_blocks_statef *,
z_streamp ,
int));
struct internal_state {int dummy;}; /* for buggy compilers */
#endif

322
minigzip.c Normal file
View File

@@ -0,0 +1,322 @@
/* minigzip.c -- simulate gzip using the zlib compression library
* Copyright (C) 1995-2005 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/*
* minigzip is a minimal implementation of the gzip utility. This is
* only an example of using zlib and isn't meant to replace the
* full-featured gzip. No attempt is made to deal with file systems
* limiting names to 14 or 8+3 characters, etc... Error checking is
* very limited. So use minigzip only for testing; use gzip for the
* real thing. On MSDOS, use only on file names without extension
* or in pipe mode.
*/
/* @(#) $Id$ */
#include <stdio.h>
#include "zlib.h"
#ifdef STDC
# include <string.h>
# include <stdlib.h>
#endif
#ifdef USE_MMAP
# include <sys/types.h>
# include <sys/mman.h>
# include <sys/stat.h>
#endif
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
# include <fcntl.h>
# include <io.h>
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
#else
# define SET_BINARY_MODE(file)
#endif
#ifdef VMS
# define unlink delete
# define GZ_SUFFIX "-gz"
#endif
#ifdef RISCOS
# define unlink remove
# define GZ_SUFFIX "-gz"
# define fileno(file) file->__file
#endif
#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
# include <unix.h> /* for fileno */
#endif
#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
extern int unlink OF((const char *));
#endif
#ifndef GZ_SUFFIX
# define GZ_SUFFIX ".gz"
#endif
#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
#define BUFLEN 16384
#define MAX_NAME_LEN 1024
#ifdef MAXSEG_64K
# define local static
/* Needed for systems with limitation on stack size. */
#else
# define local
#endif
char *prog;
void error OF((const char *msg));
void gz_compress OF((FILE *in, gzFile out));
#ifdef USE_MMAP
int gz_compress_mmap OF((FILE *in, gzFile out));
#endif
void gz_uncompress OF((gzFile in, FILE *out));
void file_compress OF((char *file, char *mode));
void file_uncompress OF((char *file));
int main OF((int argc, char *argv[]));
/* ===========================================================================
* Display error message and exit
*/
void error(msg)
const char *msg;
{
fprintf(stderr, "%s: %s\n", prog, msg);
exit(1);
}
/* ===========================================================================
* Compress input to output then close both files.
*/
void gz_compress(in, out)
FILE *in;
gzFile out;
{
local char buf[BUFLEN];
int len;
int err;
#ifdef USE_MMAP
/* Try first compressing with mmap. If mmap fails (minigzip used in a
* pipe), use the normal fread loop.
*/
if (gz_compress_mmap(in, out) == Z_OK) return;
#endif
for (;;) {
len = (int)fread(buf, 1, sizeof(buf), in);
if (ferror(in)) {
perror("fread");
exit(1);
}
if (len == 0) break;
if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
}
fclose(in);
if (gzclose(out) != Z_OK) error("failed gzclose");
}
#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
/* Try compressing the input file at once using mmap. Return Z_OK if
* if success, Z_ERRNO otherwise.
*/
int gz_compress_mmap(in, out)
FILE *in;
gzFile out;
{
int len;
int err;
int ifd = fileno(in);
caddr_t buf; /* mmap'ed buffer for the entire input file */
off_t buf_len; /* length of the input file */
struct stat sb;
/* Determine the size of the file, needed for mmap: */
if (fstat(ifd, &sb) < 0) return Z_ERRNO;
buf_len = sb.st_size;
if (buf_len <= 0) return Z_ERRNO;
/* Now do the actual mmap: */
buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
if (buf == (caddr_t)(-1)) return Z_ERRNO;
/* Compress the whole file at once: */
len = gzwrite(out, (char *)buf, (unsigned)buf_len);
if (len != (int)buf_len) error(gzerror(out, &err));
munmap(buf, buf_len);
fclose(in);
if (gzclose(out) != Z_OK) error("failed gzclose");
return Z_OK;
}
#endif /* USE_MMAP */
/* ===========================================================================
* Uncompress input to output then close both files.
*/
void gz_uncompress(in, out)
gzFile in;
FILE *out;
{
local char buf[BUFLEN];
int len;
int err;
for (;;) {
len = gzread(in, buf, sizeof(buf));
if (len < 0) error (gzerror(in, &err));
if (len == 0) break;
if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
error("failed fwrite");
}
}
if (fclose(out)) error("failed fclose");
if (gzclose(in) != Z_OK) error("failed gzclose");
}
/* ===========================================================================
* Compress the given file: create a corresponding .gz file and remove the
* original.
*/
void file_compress(file, mode)
char *file;
char *mode;
{
local char outfile[MAX_NAME_LEN];
FILE *in;
gzFile out;
strcpy(outfile, file);
strcat(outfile, GZ_SUFFIX);
in = fopen(file, "rb");
if (in == NULL) {
perror(file);
exit(1);
}
out = gzopen(outfile, mode);
if (out == NULL) {
fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
exit(1);
}
gz_compress(in, out);
unlink(file);
}
/* ===========================================================================
* Uncompress the given file and remove the original.
*/
void file_uncompress(file)
char *file;
{
local char buf[MAX_NAME_LEN];
char *infile, *outfile;
FILE *out;
gzFile in;
uInt len = (uInt)strlen(file);
strcpy(buf, file);
if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
infile = file;
outfile = buf;
outfile[len-3] = '\0';
} else {
outfile = file;
infile = buf;
strcat(infile, GZ_SUFFIX);
}
in = gzopen(infile, "rb");
if (in == NULL) {
fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
exit(1);
}
out = fopen(outfile, "wb");
if (out == NULL) {
perror(file);
exit(1);
}
gz_uncompress(in, out);
unlink(infile);
}
/* ===========================================================================
* Usage: minigzip [-d] [-f] [-h] [-r] [-1 to -9] [files...]
* -d : decompress
* -f : compress with Z_FILTERED
* -h : compress with Z_HUFFMAN_ONLY
* -r : compress with Z_RLE
* -1 to -9 : compression level
*/
int main(argc, argv)
int argc;
char *argv[];
{
int uncompr = 0;
gzFile file;
char outmode[20];
strcpy(outmode, "wb6 ");
prog = argv[0];
argc--, argv++;
while (argc > 0) {
if (strcmp(*argv, "-d") == 0)
uncompr = 1;
else if (strcmp(*argv, "-f") == 0)
outmode[3] = 'f';
else if (strcmp(*argv, "-h") == 0)
outmode[3] = 'h';
else if (strcmp(*argv, "-r") == 0)
outmode[3] = 'R';
else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
(*argv)[2] == 0)
outmode[2] = (*argv)[1];
else
break;
argc--, argv++;
}
if (outmode[3] == ' ')
outmode[3] = 0;
if (argc == 0) {
SET_BINARY_MODE(stdin);
SET_BINARY_MODE(stdout);
if (uncompr) {
file = gzdopen(fileno(stdin), "rb");
if (file == NULL) error("can't gzdopen stdin");
gz_uncompress(file, stdout);
} else {
file = gzdopen(fileno(stdout), outmode);
if (file == NULL) error("can't gzdopen stdout");
gz_compress(stdin, file);
}
} else {
do {
if (uncompr) {
file_uncompress(*argv);
} else {
file_compress(*argv, outmode);
}
} while (argv++, --argc);
}
return 0;
}

87
png.c
View File

@@ -1,11 +1,11 @@
/* png.c - location for general purpose libpng functions /* png.c - location for general purpose libpng functions
* *
* libpng version 1.2.4 - July 8, 2002 * libpng version 1.2.8 - December 3, 2004
* Copyright (c) 1998-2002 Glenn Randers-Pehrson * For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2004 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
*/ */
#define PNG_INTERNAL #define PNG_INTERNAL
@@ -13,14 +13,14 @@
#include "png.h" #include "png.h"
/* Generate a compiler error if there is an old png.h in the search path. */ /* Generate a compiler error if there is an old png.h in the search path. */
typedef version_1_2_4 Your_png_h_is_not_version_1_2_4; typedef version_1_2_8 Your_png_h_is_not_version_1_2_8;
/* Version information for C files. This had better match the version /* Version information for C files. This had better match the version
* string defined in png.h. */ * string defined in png.h. */
#ifdef PNG_USE_GLOBAL_ARRAYS #ifdef PNG_USE_GLOBAL_ARRAYS
/* png_libpng_ver was changed to a function in version 1.0.5c */ /* png_libpng_ver was changed to a function in version 1.0.5c */
const char png_libpng_ver[18] = "1.2.4"; const char png_libpng_ver[18] = PNG_LIBPNG_VER_STRING;
/* png_sig was changed to a function in version 1.0.5c */ /* png_sig was changed to a function in version 1.0.5c */
/* Place to hold the signature string for a PNG file. */ /* Place to hold the signature string for a PNG file. */
@@ -80,7 +80,7 @@ const int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
const int FARDATA png_pass_dsp_mask[] const int FARDATA png_pass_dsp_mask[]
= {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
#endif #endif /* PNG_USE_GLOBAL_ARRAYS */
/* Tells libpng that we have already handled the first "num_bytes" bytes /* 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 * of the PNG file signature. If the PNG data is embedded into another
@@ -136,22 +136,29 @@ png_check_sig(png_bytep sig, int num)
/* Function to allocate memory for zlib and clear it to 0. */ /* Function to allocate memory for zlib and clear it to 0. */
#ifdef PNG_1_0_X #ifdef PNG_1_0_X
void PNGAPI voidpf PNGAPI
#else #else
voidpf /* private */ voidpf /* private */
#endif #endif
png_zalloc(voidpf png_ptr, uInt items, uInt size) png_zalloc(voidpf png_ptr, uInt items, uInt size)
{ {
png_uint_32 num_bytes = (png_uint_32)items * size;
png_voidp ptr; png_voidp ptr;
png_structp p=png_ptr; png_structp p=png_ptr;
png_uint_32 save_flags=p->flags; png_uint_32 save_flags=p->flags;
png_uint_32 num_bytes;
if (items > PNG_UINT_32_MAX/size)
{
png_warning (png_ptr, "Potential overflow in png_zalloc()");
return (NULL);
}
num_bytes = (png_uint_32)items * size;
p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK; p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes); ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes);
p->flags=save_flags; p->flags=save_flags;
#ifndef PNG_NO_ZALLOC_ZERO #if defined(PNG_1_0_X) && !defined(PNG_NO_ZALLOC_ZERO)
if (ptr == NULL) if (ptr == NULL)
return ((voidpf)ptr); return ((voidpf)ptr);
@@ -217,7 +224,7 @@ png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)
/* Allocate the memory for an info_struct for the application. We don't /* 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 * 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)) * future. This should be used in favour of malloc(png_sizeof(png_info))
* and png_info_init() so that applications that want to use a shared * 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. * libpng don't have to be recompiled if png_info changes size.
*/ */
@@ -235,7 +242,7 @@ png_create_info_struct(png_structp png_ptr)
info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO); info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
#endif #endif
if (info_ptr != NULL) if (info_ptr != NULL)
png_info_init_3(&info_ptr, sizeof(png_info)); png_info_init_3(&info_ptr, png_sizeof(png_info));
return (info_ptr); return (info_ptr);
} }
@@ -272,6 +279,7 @@ png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
* and applications using it are urged to use png_create_info_struct() * and applications using it are urged to use png_create_info_struct()
* instead. * instead.
*/ */
#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
#undef png_info_init #undef png_info_init
void PNGAPI void PNGAPI
png_info_init(png_infop info_ptr) png_info_init(png_infop info_ptr)
@@ -279,6 +287,7 @@ png_info_init(png_infop info_ptr)
/* We only come here via pre-1.0.12-compiled applications */ /* We only come here via pre-1.0.12-compiled applications */
png_info_init_3(&info_ptr, 0); png_info_init_3(&info_ptr, 0);
} }
#endif
void PNGAPI void PNGAPI
png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size) png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size)
@@ -287,7 +296,7 @@ png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size)
png_debug(1, "in png_info_init_3\n"); png_debug(1, "in png_info_init_3\n");
if(sizeof(png_info) > png_info_struct_size) if(png_sizeof(png_info) > png_info_struct_size)
{ {
png_destroy_struct(info_ptr); png_destroy_struct(info_ptr);
info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO); info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
@@ -295,7 +304,7 @@ png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size)
} }
/* set everything to 0 */ /* set everything to 0 */
png_memset(info_ptr, 0, sizeof (png_info)); png_memset(info_ptr, 0, png_sizeof (png_info));
} }
#ifdef PNG_FREE_ME_SUPPORTED #ifdef PNG_FREE_ME_SUPPORTED
@@ -581,7 +590,7 @@ png_info_destroy(png_structp png_ptr, png_infop info_ptr)
} }
#endif #endif
png_info_init_3(&info_ptr, sizeof(png_info)); png_info_init_3(&info_ptr, png_sizeof(png_info));
} }
/* This function returns a pointer to the io_ptr associated with the user /* This function returns a pointer to the io_ptr associated with the user
@@ -623,7 +632,7 @@ png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
if (png_ptr->time_buffer == NULL) if (png_ptr->time_buffer == NULL)
{ {
png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29* png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29*
sizeof(char))); png_sizeof(char)));
} }
#if defined(_WIN32_WCE) #if defined(_WIN32_WCE)
@@ -645,7 +654,7 @@ png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
ptime->year, ptime->hour % 24, ptime->minute % 60, ptime->year, ptime->hour % 24, ptime->minute % 60,
ptime->second % 61); ptime->second % 61);
png_memcpy(png_ptr->time_buffer, near_time_buf, png_memcpy(png_ptr->time_buffer, near_time_buf,
29*sizeof(char)); 29*png_sizeof(char));
} }
#else #else
sprintf(png_ptr->time_buffer, "%d %s %d %02d:%02d:%02d +0000", sprintf(png_ptr->time_buffer, "%d %s %d %02d:%02d:%02d +0000",
@@ -670,45 +679,47 @@ png_sig_bytes(void)
png_charp PNGAPI png_charp PNGAPI
png_get_copyright(png_structp png_ptr) png_get_copyright(png_structp png_ptr)
{ {
if (png_ptr != NULL || png_ptr == NULL) /* silence compiler warning */ if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */
return ((png_charp) "\n libpng version 1.2.4 - July 8, 2002\n\ return ((png_charp) "\n libpng version 1.2.8 - December 3, 2004\n\
Copyright (c) 1998-2002 Glenn Randers-Pehrson\n\ Copyright (c) 1998-2004 Glenn Randers-Pehrson\n\
Copyright (c) 1996-1997 Andreas Dilger\n\ Copyright (c) 1996-1997 Andreas Dilger\n\
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\n"); Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\n");
return ((png_charp) ""); return ((png_charp) "");
} }
/* The following return the library version as a short string in the /* The following return the library version as a short string in the
* format 1.0.0 through 99.99.99zz. To get the version of *.h files used * format 1.0.0 through 99.99.99zz. To get the version of *.h files
* with your application, print out PNG_LIBPNG_VER_STRING, which is defined * used with your application, print out PNG_LIBPNG_VER_STRING, which
* in png.h. * is defined in png.h.
* Note: now there is no difference between png_get_libpng_ver() and
* png_get_header_ver(). Due to the version_nn_nn_nn typedef guard,
* it is guaranteed that png.c uses the correct version of png.h.
*/ */
png_charp PNGAPI png_charp PNGAPI
png_get_libpng_ver(png_structp png_ptr) png_get_libpng_ver(png_structp png_ptr)
{ {
/* Version of *.c files used when building libpng */ /* Version of *.c files used when building libpng */
if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */ if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */
return((png_charp) "1.2.4"); return ((png_charp) PNG_LIBPNG_VER_STRING);
return((png_charp) "1.2.4"); return ((png_charp) "");
} }
png_charp PNGAPI png_charp PNGAPI
png_get_header_ver(png_structp png_ptr) png_get_header_ver(png_structp png_ptr)
{ {
/* Version of *.h files used when building libpng */ /* Version of *.h files used when building libpng */
if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */ if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */
return((png_charp) PNG_LIBPNG_VER_STRING);
return ((png_charp) PNG_LIBPNG_VER_STRING); return ((png_charp) PNG_LIBPNG_VER_STRING);
return ((png_charp) "");
} }
png_charp PNGAPI png_charp PNGAPI
png_get_header_version(png_structp png_ptr) png_get_header_version(png_structp png_ptr)
{ {
/* Returns longer string containing both version and date */ /* Returns longer string containing both version and date */
if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */ if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */
return((png_charp) PNG_HEADER_VERSION_STRING);
return ((png_charp) PNG_HEADER_VERSION_STRING); return ((png_charp) PNG_HEADER_VERSION_STRING);
return ((png_charp) "");
} }
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
@@ -740,7 +751,7 @@ png_uint_32 PNGAPI
png_access_version_number(void) png_access_version_number(void)
{ {
/* Version of *.c files used when building libpng */ /* Version of *.c files used when building libpng */
return((png_uint_32) 10204L); return((png_uint_32) PNG_LIBPNG_VER);
} }
@@ -758,7 +769,7 @@ png_init_mmx_flags (png_structp png_ptr)
png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_COMPILED; png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_COMPILED;
if (png_mmx_support()) { if (png_mmx_support() > 0) {
png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU
# ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW # ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW
| PNG_ASM_FLAG_MMX_READ_COMBINE_ROW | PNG_ASM_FLAG_MMX_READ_COMBINE_ROW
@@ -803,3 +814,15 @@ png_mmx_support(void)
} }
#endif #endif
#endif /* PNG_1_0_X */ #endif /* PNG_1_0_X */
#ifdef PNG_SIZE_T
/* Added at libpng version 1.2.6 */
PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size));
png_size_t PNGAPI
png_convert_size(size_t size)
{
if (size > (png_size_t)-1)
PNG_ABORT(); /* We haven't got access to png_ptr, so no png_error() */
return ((png_size_t)size);
}
#endif /* PNG_SIZE_T */

215
png.h
View File

@@ -1,14 +1,14 @@
/* png.h - header file for PNG reference library /* png.h - header file for PNG reference library
* *
* libpng version 1.2.4 - July 8, 2002 * libpng version 1.2.8 - December 3, 2004
* Copyright (c) 1998-2002 Glenn Randers-Pehrson * Copyright (c) 1998-2004 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
* Authors and maintainers: * Authors and maintainers:
* libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
* libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
* libpng versions 0.97, January 1998, through 1.2.4 - July 8, 2002: Glenn * libpng versions 0.97, January 1998, through 1.2.8 - December 3, 2004: Glenn
* See also "Contributing Authors", below. * See also "Contributing Authors", below.
* *
* Note about libpng version numbers: * Note about libpng version numbers:
@@ -93,6 +93,24 @@
* 1.2.4rc1 13 10204 12.so.0.1.2.4rc1 * 1.2.4rc1 13 10204 12.so.0.1.2.4rc1
* 1.0.14 10 10014 10.so.0.1.0.14 * 1.0.14 10 10014 10.so.0.1.0.14
* 1.2.4 13 10204 12.so.0.1.2.4 * 1.2.4 13 10204 12.so.0.1.2.4
* 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2
* 1.0.15rc1-3 10 10015 10.so.0.1.0.15rc1-3
* 1.2.5rc1-3 13 10205 12.so.0.1.2.5rc1-3
* 1.0.15 10 10015 10.so.0.1.0.15
* 1.2.5 13 10205 12.so.0.1.2.5
* 1.2.6beta1-4 13 10206 12.so.0.1.2.6beta1-4
* 1.0.16 10 10016 10.so.0.1.0.16
* 1.2.6 13 10206 12.so.0.1.2.6
* 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2
* 1.0.17rc1 10 10017 12.so.0.1.0.17rc1
* 1.2.7rc1 13 10207 12.so.0.1.2.7rc1
* 1.0.17 10 10017 12.so.0.1.0.17
* 1.2.7 13 10207 12.so.0.1.2.7
* 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5
* 1.0.18rc1-5 10 10018 12.so.0.1.0.18rc1-5
* 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5
* 1.0.18 10 10018 12.so.0.1.0.18
* 1.2.8 13 10208 12.so.0.1.2.8
* *
* Henceforth the source version will match the shared-library major * Henceforth the source version will match the shared-library major
* and minor numbers; the shared-library major version number will be * and minor numbers; the shared-library major version number will be
@@ -112,8 +130,8 @@
* in binary compatibility (e.g., when a new feature is added). * in binary compatibility (e.g., when a new feature is added).
* *
* See libpng.txt or libpng.3 for more information. The PNG specification * See libpng.txt or libpng.3 for more information. The PNG specification
* is available as RFC 2083 <ftp://ftp.uu.net/graphics/png/documents/> * is available as a W3C Recommendation and as an ISO Specification,
* and as a W3C Recommendation <http://www.w3.org/TR/REC.png.html> * <http://www.w3.org/TR/2003/REC-PNG-20031110/
*/ */
/* /*
@@ -122,10 +140,17 @@
* If you modify libpng you may insert additional notices immediately following * If you modify libpng you may insert additional notices immediately following
* this sentence. * this sentence.
* *
* libpng versions 1.0.7, July 1, 2000, through 1.2.4, July 8, 2002, are * libpng versions 1.2.6, August 15, 2004, through 1.2.8, December 3, 2004, are
* Copyright (c) 2004 Glenn Randers-Pehrson, and are
* distributed according to the same disclaimer and license as libpng-1.2.5
* with the following individual added to the list of Contributing Authors:
*
* Cosmin Truta
*
* libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are
* Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are * Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
* distributed according to the same disclaimer and license as libpng-1.0.6 * distributed according to the same disclaimer and license as libpng-1.0.6
* with the following individuals added to the list of Contributing Authors * with the following individuals added to the list of Contributing Authors:
* *
* Simon-Pierre Cadieux * Simon-Pierre Cadieux
* Eric S. Raymond * Eric S. Raymond
@@ -141,8 +166,8 @@
* the user. * the user.
* *
* libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
* Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson * Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson, and are
* Distributed according to the same disclaimer and license as libpng-0.96, * distributed according to the same disclaimer and license as libpng-0.96,
* with the following individuals added to the list of Contributing Authors: * with the following individuals added to the list of Contributing Authors:
* *
* Tom Lane * Tom Lane
@@ -227,13 +252,13 @@
* Y2K compliance in libpng: * Y2K compliance in libpng:
* ========================= * =========================
* *
* July 8, 2002 * December 3, 2004
* *
* Since the PNG Development group is an ad-hoc body, we can't make * Since the PNG Development group is an ad-hoc body, we can't make
* an official declaration. * an official declaration.
* *
* This is your unofficial assurance that libpng from version 0.71 and * This is your unofficial assurance that libpng from version 0.71 and
* upward through 1.2.4 are Y2K compliant. It is my belief that earlier * upward through 1.2.8 are Y2K compliant. It is my belief that earlier
* versions were also Y2K compliant. * versions were also Y2K compliant.
* *
* Libpng only has three year fields. One is a 2-byte unsigned integer * Libpng only has three year fields. One is a 2-byte unsigned integer
@@ -289,43 +314,81 @@
*/ */
/* Version information for png.h - this should match the version in png.c */ /* Version information for png.h - this should match the version in png.c */
#define PNG_LIBPNG_VER_STRING "1.2.4" #define PNG_LIBPNG_VER_STRING "1.2.8"
#define PNG_HEADER_VERSION_STRING \
" libpng version 1.2.8 - December 3, 2004 (header)\n"
#define PNG_LIBPNG_VER_SONUM 0 #define PNG_LIBPNG_VER_SONUM 0
#define PNG_LIBPNG_VER_DLLNUM %DLLNUM% #define PNG_LIBPNG_VER_DLLNUM 13
/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
#define PNG_LIBPNG_VER_MAJOR 1 #define PNG_LIBPNG_VER_MAJOR 1
#define PNG_LIBPNG_VER_MINOR 2 #define PNG_LIBPNG_VER_MINOR 2
#define PNG_LIBPNG_VER_RELEASE 4 #define PNG_LIBPNG_VER_RELEASE 8
/* This should match the numeric part of the final component of /* This should match the numeric part of the final component of
* PNG_LIBPNG_VER_STRING, omitting any leading zero: */ * PNG_LIBPNG_VER_STRING, omitting any leading zero: */
#define PNG_LIBPNG_VER_BUILD 0 #define PNG_LIBPNG_VER_BUILD 0
/* Release Status */
#define PNG_LIBPNG_BUILD_ALPHA 1 #define PNG_LIBPNG_BUILD_ALPHA 1
#define PNG_LIBPNG_BUILD_BETA 2 #define PNG_LIBPNG_BUILD_BETA 2
#define PNG_LIBPNG_BUILD_RC 3 #define PNG_LIBPNG_BUILD_RC 3
#define PNG_LIBPNG_BUILD_STABLE 4 #define PNG_LIBPNG_BUILD_STABLE 4
#define PNG_LIBPNG_BUILD_TYPEMASK 7 #define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7
#define PNG_LIBPNG_BUILD_PATCH 8 /* Can be OR'ed with STABLE only */
#define PNG_LIBPNG_BUILD_TYPE 4 /* Release-Specific Flags */
#define PNG_LIBPNG_BUILD_PATCH 8 /* Can be OR'ed with
PNG_LIBPNG_BUILD_STABLE only */
#define PNG_LIBPNG_BUILD_PRIVATE 16 /* Cannot be OR'ed with
PNG_LIBPNG_BUILD_SPECIAL */
#define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with
PNG_LIBPNG_BUILD_PRIVATE */
#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE
/* Careful here. At one time, Guy wanted to use 082, but that would be octal. /* Careful here. At one time, Guy wanted to use 082, but that would be octal.
* We must not include leading zeros. * We must not include leading zeros.
* Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only * 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.0 was mis-numbered 100 instead of 10000). From
* version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release */ * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release */
#define PNG_LIBPNG_VER 10204 /* 1.2.4 */ #define PNG_LIBPNG_VER 10208 /* 1.2.8 */
#ifndef PNG_VERSION_INFO_ONLY #ifndef PNG_VERSION_INFO_ONLY
/* include the compression library's header */ /* include the compression library's header */
#include "zlib.h" #include "zlib.h"
#endif
/* include all user configurable info, including optional assembler routines */ /* include all user configurable info, including optional assembler routines */
#include "pngconf.h" #include "pngconf.h"
/*
* Added at libpng-1.2.8 */
/* Ref MSDN: Private as priority over Special
* VS_FF_PRIVATEBUILD File *was not* built using standard release
* procedures. If this value is given, the StringFileInfo block must
* contain a PrivateBuild string.
*
* VS_FF_SPECIALBUILD File *was* built by the original company using
* standard release procedures but is a variation of the standard
* file of the same version number. If this value is given, the
* StringFileInfo block must contain a SpecialBuild string.
*/
#if defined(PNG_USER_PRIVATEBUILD)
# define PNG_LIBPNG_BUILD_TYPE PNG_LIBPNG_BUILD_BASE_TYPE | \
PNG_LIBPNG_BUILD_PRIVATE
#else
# if defined(PNG_LIBPNG_SPECIALBUILD)
# define PNG_LIBPNG_BUILD_TYPE PNG_LIBPNG_BUILD_BASE_TYPE | \
PNG_LIBPNG_BUILD_SPECIAL
# else
# define PNG_LIBPNG_BUILD_TYPE PNG_LIBPNG_BUILD_BASE_TYPE
# endif
#endif
#ifndef PNG_VERSION_INFO_ONLY
/* Inhibit C++ name-mangling for libpng functions but not for system calls. */ /* Inhibit C++ name-mangling for libpng functions but not for system calls. */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@@ -828,7 +891,11 @@ typedef png_info FAR * png_infop;
typedef png_info FAR * FAR * png_infopp; typedef png_info FAR * FAR * png_infopp;
/* Maximum positive integer used in PNG is (2^31)-1 */ /* Maximum positive integer used in PNG is (2^31)-1 */
#define PNG_MAX_UINT ((png_uint_32)0x7fffffffL) #define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL)
#define PNG_UINT_32_MAX ((png_uint_32)(-1))
#define PNG_SIZE_MAX ((png_size_t)(-1))
/* PNG_MAX_UINT is deprecated; use PNG_UINT_31_MAX instead. */
#define PNG_MAX_UINT PNG_UINT_31_MAX
/* These describe the color_type field in png_info. */ /* These describe the color_type field in png_info. */
/* color type masks */ /* color type masks */
@@ -1275,13 +1342,21 @@ struct png_struct_def
/* palette color */ /* palette color */
#endif #endif
/* New members added in libpng-1.0.16 and 1.2.6 */
png_byte compression_type;
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
png_uint_32 user_width_max;
png_uint_32 user_height_max;
#endif
}; };
/* This prevents a compiler error in png.c if png.c and png.h are both at /* This triggers a compiler error in png.c, if png.c and png.h
version 1.2.4 * do not agree upon the version number.
*/ */
typedef png_structp version_1_2_4; typedef png_structp version_1_2_8;
typedef png_struct FAR * FAR * png_structpp; typedef png_struct FAR * FAR * png_structpp;
@@ -1323,11 +1398,15 @@ extern PNG_EXPORT(png_structp,png_create_write_struct)
PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
png_error_ptr error_fn, png_error_ptr warn_fn)); png_error_ptr error_fn, png_error_ptr warn_fn));
#ifdef PNG_WRITE_SUPPORTED
extern PNG_EXPORT(png_uint_32,png_get_compression_buffer_size) extern PNG_EXPORT(png_uint_32,png_get_compression_buffer_size)
PNGARG((png_structp png_ptr)); PNGARG((png_structp png_ptr));
#endif
#ifdef PNG_WRITE_SUPPORTED
extern PNG_EXPORT(void,png_set_compression_buffer_size) extern PNG_EXPORT(void,png_set_compression_buffer_size)
PNGARG((png_structp png_ptr, png_uint_32 size)); PNGARG((png_structp png_ptr, png_uint_32 size));
#endif
/* Reset the compression stream */ /* Reset the compression stream */
extern PNG_EXPORT(int,png_reset_zstream) PNGARG((png_structp png_ptr)); extern PNG_EXPORT(int,png_reset_zstream) PNGARG((png_structp png_ptr));
@@ -1366,7 +1445,8 @@ extern PNG_EXPORT(png_infop,png_create_info_struct)
/* Initialize the info structure (old interface - DEPRECATED) */ /* Initialize the info structure (old interface - DEPRECATED) */
extern PNG_EXPORT(void,png_info_init) PNGARG((png_infop info_ptr)); extern PNG_EXPORT(void,png_info_init) PNGARG((png_infop info_ptr));
#undef png_info_init #undef png_info_init
#define png_info_init(info_ptr) png_info_init_3(&info_ptr, sizeof(png_info)); #define png_info_init(info_ptr) png_info_init_3(&info_ptr,\
png_sizeof(png_info));
extern PNG_EXPORT(void,png_info_init_3) PNGARG((png_infopp info_ptr, extern PNG_EXPORT(void,png_info_init_3) PNGARG((png_infopp info_ptr,
png_size_t png_info_struct_size)); png_size_t png_info_struct_size));
@@ -1376,9 +1456,11 @@ extern PNG_EXPORT(void,png_write_info_before_PLTE) PNGARG((png_structp png_ptr,
extern PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr, extern PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr,
png_infop info_ptr)); png_infop info_ptr));
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
/* read the information before the actual image data. */ /* read the information before the actual image data. */
extern PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr, extern PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr,
png_infop info_ptr)); png_infop info_ptr));
#endif
#if defined(PNG_TIME_RFC1123_SUPPORTED) #if defined(PNG_TIME_RFC1123_SUPPORTED)
extern PNG_EXPORT(png_charp,png_convert_to_rfc1123) extern PNG_EXPORT(png_charp,png_convert_to_rfc1123)
@@ -1446,12 +1528,17 @@ extern PNG_EXPORT(void,png_set_invert_alpha) PNGARG((png_structp png_ptr));
#endif #endif
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
/* Add a filler byte to 24-bit RGB images. */ /* Add a filler byte to 8-bit Gray or 24-bit RGB images. */
extern PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr, extern PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr,
png_uint_32 filler, int flags)); png_uint_32 filler, int flags));
/* The values of the PNG_FILLER_ defines should NOT be changed */ /* The values of the PNG_FILLER_ defines should NOT be changed */
#define PNG_FILLER_BEFORE 0 #define PNG_FILLER_BEFORE 0
#define PNG_FILLER_AFTER 1 #define PNG_FILLER_AFTER 1
/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */
#if !defined(PNG_1_0_X)
extern PNG_EXPORT(void,png_set_add_alpha) PNGARG((png_structp png_ptr,
png_uint_32 filler, int flags));
#endif
#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */ #endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
@@ -1541,18 +1628,24 @@ extern PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr));
extern PNG_EXPORT(void,png_read_update_info) PNGARG((png_structp png_ptr, extern PNG_EXPORT(void,png_read_update_info) PNGARG((png_structp png_ptr,
png_infop info_ptr)); png_infop info_ptr));
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
/* read one or more rows of image data. */ /* read one or more rows of image data. */
extern PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr, extern PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr,
png_bytepp row, png_bytepp display_row, png_uint_32 num_rows)); png_bytepp row, png_bytepp display_row, png_uint_32 num_rows));
#endif
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
/* read a row of data. */ /* read a row of data. */
extern PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr, extern PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr,
png_bytep row, png_bytep row,
png_bytep display_row)); png_bytep display_row));
#endif
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
/* read the whole image into memory at once. */ /* read the whole image into memory at once. */
extern PNG_EXPORT(void,png_read_image) PNGARG((png_structp png_ptr, extern PNG_EXPORT(void,png_read_image) PNGARG((png_structp png_ptr,
png_bytepp image)); png_bytepp image));
#endif
/* write a row of image data */ /* write a row of image data */
extern PNG_EXPORT(void,png_write_row) PNGARG((png_structp png_ptr, extern PNG_EXPORT(void,png_write_row) PNGARG((png_structp png_ptr,
@@ -1570,9 +1663,11 @@ extern PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr,
extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr, extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr,
png_infop info_ptr)); png_infop info_ptr));
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
/* read the end of the PNG file. */ /* read the end of the PNG file. */
extern PNG_EXPORT(void,png_read_end) PNGARG((png_structp png_ptr, extern PNG_EXPORT(void,png_read_end) PNGARG((png_structp png_ptr,
png_infop info_ptr)); png_infop info_ptr));
#endif
/* free any memory associated with the png_info_struct */ /* free any memory associated with the png_info_struct */
extern PNG_EXPORT(void,png_destroy_info_struct) PNGARG((png_structp png_ptr, extern PNG_EXPORT(void,png_destroy_info_struct) PNGARG((png_structp png_ptr,
@@ -2344,6 +2439,12 @@ extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp
png_ptr, png_uint_32 mng_features_permitted)); png_ptr, png_uint_32 mng_features_permitted));
#endif #endif
/* For use in png_set_keep_unknown, added to version 1.2.6 */
#define PNG_HANDLE_CHUNK_AS_DEFAULT 0
#define PNG_HANDLE_CHUNK_NEVER 1
#define PNG_HANDLE_CHUNK_IF_SAFE 2
#define PNG_HANDLE_CHUNK_ALWAYS 3
/* Added to version 1.2.0 */ /* Added to version 1.2.0 */
#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) #if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
#define PNG_ASM_FLAG_MMX_SUPPORT_COMPILED 0x01 /* not user-settable */ #define PNG_ASM_FLAG_MMX_SUPPORT_COMPILED 0x01 /* not user-settable */
@@ -2372,7 +2473,6 @@ extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp
#define PNG_SELECT_READ 1 #define PNG_SELECT_READ 1
#define PNG_SELECT_WRITE 2 #define PNG_SELECT_WRITE 2
#if !defined(PNG_1_0_X) #if !defined(PNG_1_0_X)
/* pngget.c */ /* pngget.c */
extern PNG_EXPORT(png_uint_32,png_get_mmx_flagmask) extern PNG_EXPORT(png_uint_32,png_get_mmx_flagmask)
@@ -2416,12 +2516,20 @@ extern PNG_EXPORT(int,png_mmx_support) PNGARG((void));
extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp
png_ptr, png_uint_32 strip_mode)); png_ptr, png_uint_32 strip_mode));
#endif #endif
#endif /* PNG_1_0_X */ #endif /* PNG_1_0_X */
/* Maintainer: Put new public prototypes here ^, in libpng.3, and project defs */ /* Added at libpng-1.2.6 */
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
extern PNG_EXPORT(void,png_set_user_limits) PNGARG((png_structp
png_ptr, png_uint_32 user_width_max, png_uint_32 user_height_max));
extern PNG_EXPORT(png_uint_32,png_get_user_width_max) PNGARG((png_structp
png_ptr));
extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp
png_ptr));
#endif
#define PNG_HEADER_VERSION_STRING \ /* Maintainer: Put new public prototypes here ^, in libpng.3, and project defs */
" libpng version 1.2.4 - July 8, 2002 (header)\n"
#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED #ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED
/* With these routines we avoid an integer divide, which will be slower on /* With these routines we avoid an integer divide, which will be slower on
@@ -2514,6 +2622,14 @@ extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp
#define PNG_RGB_TO_GRAY_ERR 0x200000L #define PNG_RGB_TO_GRAY_ERR 0x200000L
#define PNG_RGB_TO_GRAY_WARN 0x400000L #define PNG_RGB_TO_GRAY_WARN 0x400000L
#define PNG_RGB_TO_GRAY 0x600000L /* two bits, RGB_TO_GRAY_ERR|WARN */ #define PNG_RGB_TO_GRAY 0x600000L /* two bits, RGB_TO_GRAY_ERR|WARN */
/* 0x800000L Unused */
#define PNG_ADD_ALPHA 0x1000000L /* Added to libpng-1.2.7 */
/* 0x2000000L unused */
/* 0x4000000L unused */
/* 0x8000000L unused */
/* 0x10000000L unused */
/* 0x20000000L unused */
/* 0x40000000L unused */
/* flags for png_create_struct */ /* flags for png_create_struct */
#define PNG_STRUCT_PNG 0x0001 #define PNG_STRUCT_PNG 0x0001
@@ -2547,12 +2663,16 @@ extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp
#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000L #define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000L
#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000L #define PNG_FLAG_STRIP_ERROR_TEXT 0x80000L
#define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000L #define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000L
#define PNG_FLAG_ADD_ALPHA 0x200000L /* Added to libpng-1.2.8 */
/* For use in png_set_keep_unknown, png_handle_as_unknown */ #define PNG_FLAG_STRIP_ALPHA 0x400000L /* Added to libpng-1.2.8 */
#define HANDLE_CHUNK_AS_DEFAULT 0 /* 0x800000L unused */
#define HANDLE_CHUNK_NEVER 1 /* 0x1000000L unused */
#define HANDLE_CHUNK_IF_SAFE 2 /* 0x2000000L unused */
#define HANDLE_CHUNK_ALWAYS 3 /* 0x4000000L unused */
/* 0x8000000L unused */
/* 0x10000000L unused */
/* 0x20000000L unused */
/* 0x40000000L unused */
#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \ #define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
PNG_FLAG_CRC_ANCILLARY_NOWARN) PNG_FLAG_CRC_ANCILLARY_NOWARN)
@@ -2564,10 +2684,24 @@ extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp
PNG_FLAG_CRC_CRITICAL_MASK) PNG_FLAG_CRC_CRITICAL_MASK)
/* save typing and make code easier to understand */ /* save typing and make code easier to understand */
#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \ #define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
abs((int)((c1).green) - (int)((c2).green)) + \ abs((int)((c1).green) - (int)((c2).green)) + \
abs((int)((c1).blue) - (int)((c2).blue))) abs((int)((c1).blue) - (int)((c2).blue)))
/* Added to libpng-1.2.6 JB */
#define PNG_ROWBYTES(pixel_bits, width) \
((pixel_bits) >= 8 ? \
((width) * (((png_uint_32)(pixel_bits)) >> 3)) : \
(( ((width) * ((png_uint_32)(pixel_bits))) + 7) >> 3) )
/* PNG_OUT_OF_RANGE returns true if value is outside the range
ideal-delta..ideal+delta. Each argument is evaluated twice.
"ideal" and "delta" should be constants, normally simple
integers, "value" a variable. Added to libpng-1.2.6 JB */
#define PNG_OUT_OF_RANGE(value, ideal, delta) \
( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) )
/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */ /* variables declared in png.c - only it needs to define PNG_NO_EXTERN */
#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN) #if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
/* place to hold the signature string for a PNG file. */ /* place to hold the signature string for a PNG file. */
@@ -2650,6 +2784,8 @@ PNG_EXTERN png_int_32 png_get_int_32 PNGARG((png_bytep buf));
PNG_EXTERN png_uint_32 png_get_uint_32 PNGARG((png_bytep buf)); 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)); PNG_EXTERN png_uint_16 png_get_uint_16 PNGARG((png_bytep buf));
#endif /* !PNG_READ_BIG_ENDIAN_SUPPORTED */ #endif /* !PNG_READ_BIG_ENDIAN_SUPPORTED */
PNG_EXTERN png_uint_32 png_get_uint_31 PNGARG((png_structp png_ptr,
png_bytep buf));
/* Initialize png_ptr struct for reading, and allocate any other memory. /* Initialize png_ptr struct for reading, and allocate any other memory.
* (old interface - DEPRECATED - use png_create_read_struct instead). * (old interface - DEPRECATED - use png_create_read_struct instead).
@@ -2657,7 +2793,7 @@ PNG_EXTERN png_uint_16 png_get_uint_16 PNGARG((png_bytep buf));
extern PNG_EXPORT(void,png_read_init) PNGARG((png_structp png_ptr)); extern PNG_EXPORT(void,png_read_init) PNGARG((png_structp png_ptr));
#undef png_read_init #undef png_read_init
#define png_read_init(png_ptr) png_read_init_3(&png_ptr, \ #define png_read_init(png_ptr) png_read_init_3(&png_ptr, \
PNG_LIBPNG_VER_STRING, sizeof(png_struct)); PNG_LIBPNG_VER_STRING, png_sizeof(png_struct));
extern PNG_EXPORT(void,png_read_init_3) PNGARG((png_structpp ptr_ptr, extern PNG_EXPORT(void,png_read_init_3) PNGARG((png_structpp ptr_ptr,
png_const_charp user_png_ver, png_size_t png_struct_size)); png_const_charp user_png_ver, png_size_t png_struct_size));
extern PNG_EXPORT(void,png_read_init_2) PNGARG((png_structp png_ptr, extern PNG_EXPORT(void,png_read_init_2) PNGARG((png_structp png_ptr,
@@ -2670,7 +2806,7 @@ extern PNG_EXPORT(void,png_read_init_2) PNGARG((png_structp png_ptr,
extern PNG_EXPORT(void,png_write_init) PNGARG((png_structp png_ptr)); extern PNG_EXPORT(void,png_write_init) PNGARG((png_structp png_ptr));
#undef png_write_init #undef png_write_init
#define png_write_init(png_ptr) png_write_init_3(&png_ptr, \ #define png_write_init(png_ptr) png_write_init_3(&png_ptr, \
PNG_LIBPNG_VER_STRING, sizeof(png_struct)); PNG_LIBPNG_VER_STRING, png_sizeof(png_struct));
extern PNG_EXPORT(void,png_write_init_3) PNGARG((png_structpp ptr_ptr, extern PNG_EXPORT(void,png_write_init_3) PNGARG((png_structpp ptr_ptr,
png_const_charp user_png_ver, png_size_t png_struct_size)); png_const_charp user_png_ver, png_size_t png_struct_size));
extern PNG_EXPORT(void,png_write_init_2) PNGARG((png_structp png_ptr, extern PNG_EXPORT(void,png_write_init_2) PNGARG((png_structp png_ptr,
@@ -2699,6 +2835,11 @@ PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size));
/* Function to free memory for zlib */ /* Function to free memory for zlib */
PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr)); PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr));
#ifdef PNG_SIZE_T
/* Function to convert a sizeof an item to png_sizeof item */
PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size));
#endif
/* Next four functions are used internally as callbacks. PNGAPI is required /* Next four functions are used internally as callbacks. PNGAPI is required
* but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3. */ * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3. */

161
pngconf.h
View File

@@ -1,8 +1,9 @@
/* pngconf.h - machine configurable file for libpng /* pngconf.h - machine configurable file for libpng
* *
* libpng 1.2.4 - July 8, 2002 * libpng version 1.2.8 - December 3, 2004
* For conditions of distribution and use, see copyright notice in png.h * For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2002 Glenn Randers-Pehrson * Copyright (c) 1998-2004 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*/ */
@@ -16,7 +17,55 @@
#ifndef PNGCONF_H #ifndef PNGCONF_H
#define PNGCONF_H #define PNGCONF_H
#include "pngcrush.h" /* except for this line, this is libpng's pngconf.h */ #include "pngcrush.h"
#define PNG_1_2_X
/*
* PNG_USER_CONFIG has to be defined on the compiler command line. This
* includes the resource compiler for Windows DLL configurations.
*/
#ifdef PNG_USER_CONFIG
#include "pngusr.h"
#endif
/*
* Added at libpng-1.2.8
*
* If you create a private DLL you need to define in "pngusr.h" the followings:
* #define PNG_USER_PRIVATEBUILD <Describes by whom and why this version of
* the DLL was built>
* e.g. #define PNG_USER_PRIVATEBUILD "Build by MyCompany for xyz reasons."
* #define PNG_USER_DLLFNAME_POSTFIX <two-letter postfix that serve to
* distinguish your DLL from those of the official release. These
* correspond to the trailing letters that come after the version
* number and must match your private DLL name>
* e.g. // private DLL "libpng13gx.dll"
* #define PNG_USER_DLLFNAME_POSTFIX "gx"
*
* The following macros are also at your disposal if you want to complete the
* DLL VERSIONINFO structure.
* - PNG_USER_VERSIONINFO_COMMENTS
* - PNG_USER_VERSIONINFO_COMPANYNAME
* - PNG_USER_VERSIONINFO_LEGALTRADEMARKS
*/
#ifdef __STDC__
#ifdef SPECIALBUILD
# pragma message("PNG_LIBPNG_SPECIALBUILD (and deprecated SPECIALBUILD)\
are now LIBPNG reserved macros. Use PNG_USER_PRIVATEBUILD instead.")
#endif
#ifdef PRIVATEBUILD
# pragma message("PRIVATEBUILD is deprecated. Use\
PNG_USER_PRIVATEBUILD instead.")
# define PNG_USER_PRIVATEBUILD PRIVATEBUILD
#endif
#endif /* __STDC__ */
#ifndef PNG_VERSION_INFO_ONLY
/* End of material added to libpng-1.2.8 */
/* This is the size of the compression buffer, and thus the size of /* 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 * an IDAT chunk. Make this whatever size you feel is best for your
@@ -254,6 +303,9 @@
# undef _BSD_SOURCE # undef _BSD_SOURCE
# endif # endif
# ifdef _SETJMP_H # ifdef _SETJMP_H
/* If you encounter a compiler error here, see the explanation
* near the end of INSTALL.
*/
__png.h__ already includes setjmp.h; __png.h__ already includes setjmp.h;
__dont__ include it again.; __dont__ include it again.;
# endif # endif
@@ -319,15 +371,13 @@
# define PNG_ALWAYS_EXTERN # define PNG_ALWAYS_EXTERN
#endif #endif
/* For some reason, Borland C++ defines memcmp, etc. in mem.h, not /* This provides the non-ANSI (far) memory allocation routines. */
* stdlib.h like it should (I think). Or perhaps this is a C++ #if defined(__TURBOC__) && defined(__MSDOS__)
* "feature"?
*/
#ifdef __TURBOC__
# include <mem.h> # include <mem.h>
# include "alloc.h" # include <alloc.h>
#endif #endif
/* I have no idea why is this necessary... */
#if defined(_MSC_VER) && (defined(WIN32) || defined(_Windows) || \ #if defined(_MSC_VER) && (defined(WIN32) || defined(_Windows) || \
defined(_WINDOWS) || defined(_WIN32) || defined(__WIN32__)) defined(_WINDOWS) || defined(_WIN32) || defined(__WIN32__))
# include <malloc.h> # include <malloc.h>
@@ -585,13 +635,6 @@
# endif # endif
#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */ #endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
# ifndef PNG_NO_USER_TRANSFORM_PTR
# define PNG_USER_TRANSFORM_PTR_SUPPORTED
# endif
#endif
#define PNG_WRITE_INTERLACING_SUPPORTED /* not required for PNG-compliant #define PNG_WRITE_INTERLACING_SUPPORTED /* not required for PNG-compliant
encoders, but can cause trouble encoders, but can cause trouble
if left undefined */ if left undefined */
@@ -601,12 +644,6 @@
# define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED # define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
#endif #endif
#ifndef PNG_1_0_X
#ifndef PNG_NO_ERROR_NUMBERS
#define PNG_ERROR_NUMBERS_SUPPORTED
#endif
#endif /* PNG_1_0_X */
#ifndef PNG_NO_WRITE_FLUSH #ifndef PNG_NO_WRITE_FLUSH
# define PNG_WRITE_FLUSH_SUPPORTED # define PNG_WRITE_FLUSH_SUPPORTED
#endif #endif
@@ -618,6 +655,19 @@
#endif /* PNG_WRITE_SUPPORTED */ #endif /* PNG_WRITE_SUPPORTED */
#ifndef PNG_1_0_X
# ifndef PNG_NO_ERROR_NUMBERS
# define PNG_ERROR_NUMBERS_SUPPORTED
# endif
#endif /* PNG_1_0_X */
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
# ifndef PNG_NO_USER_TRANSFORM_PTR
# define PNG_USER_TRANSFORM_PTR_SUPPORTED
# endif
#endif
#ifndef PNG_NO_STDIO #ifndef PNG_NO_STDIO
# define PNG_TIME_RFC1123_SUPPORTED # define PNG_TIME_RFC1123_SUPPORTED
#endif #endif
@@ -665,6 +715,25 @@
#endif #endif
#endif /* PNG_1_0_X */ #endif /* PNG_1_0_X */
/* Added at libpng-1.2.6 */
#if !defined(PNG_1_0_X)
#ifndef PNG_SET_USER_LIMITS_SUPPORTED
#if !defined(PNG_NO_SET_USER_LIMITS) && !defined(PNG_SET_USER_LIMITS_SUPPORTED)
# define PNG_SET_USER_LIMITS_SUPPORTED
#endif
#endif
#endif /* PNG_1_0_X */
/* Added at libpng-1.0.16 and 1.2.6. To accept all valid PNGS no matter
* how large, set these limits to 0x7fffffffL
*/
#ifndef PNG_USER_WIDTH_MAX
# define PNG_USER_WIDTH_MAX 1000000L
#endif
#ifndef PNG_USER_HEIGHT_MAX
# define PNG_USER_HEIGHT_MAX 1000000L
#endif
/* These are currently experimental features, define them if you want */ /* These are currently experimental features, define them if you want */
/* very little testing */ /* very little testing */
@@ -679,11 +748,9 @@
/* This is only for PowerPC big-endian and 680x0 systems */ /* This is only for PowerPC big-endian and 680x0 systems */
/* some testing */ /* some testing */
/* /*
#ifdef PNG_READ_SUPPORTED #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
# ifndef PNG_PNG_READ_BIG_ENDIAN_SUPPORTED
# define PNG_READ_BIG_ENDIAN_SUPPORTED # define PNG_READ_BIG_ENDIAN_SUPPORTED
#endif #endif
#endif
*/ */
/* Buggy compilers (e.g., gcc 2.7.2.2) need this */ /* Buggy compilers (e.g., gcc 2.7.2.2) need this */
@@ -990,7 +1057,13 @@ typedef unsigned char png_byte;
/* This is usually size_t. It is typedef'ed just in case you need it to /* 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) */ change (I'm not sure if you will or not, so I thought I'd be safe) */
#ifdef PNG_SIZE_T
typedef PNG_SIZE_T png_size_t;
# define png_sizeof(x) png_convert_size(sizeof (x))
#else
typedef size_t png_size_t; typedef size_t png_size_t;
# define png_sizeof(x) sizeof (x)
#endif
/* The following is needed for medium model support. It cannot be in the /* The following is needed for medium model support. It cannot be in the
* PNG_INTERNAL section. Needs modification for other compilers besides * PNG_INTERNAL section. Needs modification for other compilers besides
@@ -1094,6 +1167,9 @@ typedef double FAR * FAR * png_doublepp;
/* Pointers to pointers to pointers; i.e., pointer to array */ /* Pointers to pointers to pointers; i.e., pointer to array */
typedef char FAR * FAR * FAR * png_charppp; typedef char FAR * FAR * FAR * png_charppp;
#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
/* SPC - Is this stuff deprecated? */
/* It'll be removed as of libpng-1.3.0 - GR-P */
/* libpng typedefs for types in zlib. If zlib changes /* libpng typedefs for types in zlib. If zlib changes
* or another compression library is used, then change these. * or another compression library is used, then change these.
* Eliminates need to change all the source files. * Eliminates need to change all the source files.
@@ -1101,6 +1177,7 @@ typedef char FAR * FAR * FAR * png_charppp;
typedef charf * png_zcharp; typedef charf * png_zcharp;
typedef charf * FAR * png_zcharpp; typedef charf * FAR * png_zcharpp;
typedef z_stream FAR * png_zstreamp; typedef z_stream FAR * png_zstreamp;
#endif /* (PNG_1_0_X) || defined(PNG_1_2_X) */
/* /*
* Define PNG_BUILD_DLL if the module being built is a Windows * Define PNG_BUILD_DLL if the module being built is a Windows
@@ -1173,8 +1250,6 @@ typedef z_stream FAR * png_zstreamp;
* zlib and your applications the same way you build libpng. * zlib and your applications the same way you build libpng.
*/ */
#ifndef PNGAPI
#if defined(__MINGW32__) && !defined(PNG_MODULEDEF) #if defined(__MINGW32__) && !defined(PNG_MODULEDEF)
# ifndef PNG_NO_MODULEDEF # ifndef PNG_NO_MODULEDEF
# define PNG_NO_MODULEDEF # define PNG_NO_MODULEDEF
@@ -1189,11 +1264,13 @@ typedef z_stream FAR * png_zstreamp;
(( defined(_Windows) || defined(_WINDOWS) || \ (( defined(_Windows) || defined(_WINDOWS) || \
defined(WIN32) || defined(_WIN32) || defined(__WIN32__) )) defined(WIN32) || defined(_WIN32) || defined(__WIN32__) ))
# ifndef PNGAPI
# if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800)) # if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800))
# define PNGAPI __cdecl # define PNGAPI __cdecl
# else # else
# define PNGAPI _cdecl # define PNGAPI _cdecl
# endif # endif
# endif
# if !defined(PNG_IMPEXP) && (!defined(PNG_DLL) || \ # if !defined(PNG_IMPEXP) && (!defined(PNG_DLL) || \
0 /* WINCOMPILER_WITH_NO_SUPPORT_FOR_DECLIMPEXP */) 0 /* WINCOMPILER_WITH_NO_SUPPORT_FOR_DECLIMPEXP */)
@@ -1230,15 +1307,12 @@ typedef z_stream FAR * png_zstreamp;
# endif # endif
# endif /* PNG_IMPEXP */ # endif /* PNG_IMPEXP */
#else /* !(DLL || non-cygwin WINDOWS) */ #else /* !(DLL || non-cygwin WINDOWS) */
# if (defined(__IBMC__) || defined(IBMCPP__)) && defined(__OS2__) # if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
# ifndef PNGAPI
# define PNGAPI _System # define PNGAPI _System
# define PNG_IMPEXP # endif
# else # else
# if 0 /* ... other platforms, with other meanings */ # if 0 /* ... other platforms, with other meanings */
# else
# define PNGAPI
# define PNG_IMPEXP
# endif
# endif # endif
# endif # endif
#endif #endif
@@ -1250,6 +1324,17 @@ typedef z_stream FAR * png_zstreamp;
# define PNG_IMPEXP # define PNG_IMPEXP
#endif #endif
#ifdef PNG_BUILDSYMS
# ifndef PNG_EXPORT
# define PNG_EXPORT(type,symbol) PNG_FUNCTION_EXPORT symbol END
# endif
# ifdef PNG_USE_GLOBAL_ARRAYS
# ifndef PNG_EXPORT_VAR
# define PNG_EXPORT_VAR(type) PNG_DATA_EXPORT
# endif
# endif
#endif
#ifndef PNG_EXPORT #ifndef PNG_EXPORT
# define PNG_EXPORT(type,symbol) PNG_IMPEXP type PNGAPI symbol # define PNG_EXPORT(type,symbol) PNG_IMPEXP type PNGAPI symbol
#endif #endif
@@ -1282,6 +1367,7 @@ typedef z_stream FAR * png_zstreamp;
# define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK)) # 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 CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK))
# define png_strcpy _fstrcpy # define png_strcpy _fstrcpy
# define png_strncpy _fstrncpy /* Added to v 1.2.6 */
# define png_strlen _fstrlen # define png_strlen _fstrlen
# define png_memcmp _fmemcmp /* SJT: added */ # define png_memcmp _fmemcmp /* SJT: added */
# define png_memcpy _fmemcpy # define png_memcpy _fmemcpy
@@ -1290,6 +1376,7 @@ typedef z_stream FAR * png_zstreamp;
# define CVT_PTR(ptr) (ptr) # define CVT_PTR(ptr) (ptr)
# define CVT_PTR_NOCHECK(ptr) (ptr) # define CVT_PTR_NOCHECK(ptr) (ptr)
# define png_strcpy strcpy # define png_strcpy strcpy
# define png_strncpy strncpy /* Added to v 1.2.6 */
# define png_strlen strlen # define png_strlen strlen
# define png_memcmp memcmp /* SJT: added */ # define png_memcmp memcmp /* SJT: added */
# define png_memcpy memcpy # define png_memcpy memcpy
@@ -1300,9 +1387,9 @@ typedef z_stream FAR * png_zstreamp;
/* Just a little check that someone hasn't tried to define something /* Just a little check that someone hasn't tried to define something
* contradictory. * contradictory.
*/ */
#if (PNG_ZBUF_SIZE > 65536) && defined(PNG_MAX_MALLOC_64K) #if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K)
# undef PNG_ZBUF_SIZE # undef PNG_ZBUF_SIZE
# define PNG_ZBUF_SIZE 65536 # define PNG_ZBUF_SIZE 65536L
#endif #endif
#ifdef PNG_READ_SUPPORTED #ifdef PNG_READ_SUPPORTED
@@ -1346,5 +1433,7 @@ typedef z_stream FAR * png_zstreamp;
#endif /* PNG_INTERNAL */ #endif /* PNG_INTERNAL */
#endif /* PNG_READ_SUPPORTED */ #endif /* PNG_READ_SUPPORTED */
#endif /* PNGCONF_H */ /* Added at libpng-1.2.8 */
#endif /* PNG_VERSION_INFO_ONLY */
#endif /* PNGCONF_H */

5112
pngcrush.c

File diff suppressed because it is too large Load Diff

View File

@@ -113,4 +113,152 @@
an error. */ an error. */
#define PNG_ABORT() #define PNG_ABORT()
/* GRR 20050220: added these, which apparently aren't defined anywhere else */
#ifndef PNG_UINT_IHDR
# define PNG_UINT_IHDR (((png_uint_32) 73<<24) | \
((png_uint_32) 72<<16) | \
((png_uint_32) 68<< 8) | \
((png_uint_32) 82 ))
#endif #endif
#ifndef PNG_UINT_IDAT
# define PNG_UINT_IDAT (((png_uint_32) 73<<24) | \
((png_uint_32) 68<<16) | \
((png_uint_32) 65<< 8) | \
((png_uint_32) 84 ))
#endif
#ifndef PNG_UINT_IEND
# define PNG_UINT_IEND (((png_uint_32) 73<<24) | \
((png_uint_32) 69<<16) | \
((png_uint_32) 78<< 8) | \
((png_uint_32) 68 ))
#endif
#ifndef PNG_UINT_PLTE
# define PNG_UINT_PLTE (((png_uint_32) 80<<24) | \
((png_uint_32) 76<<16) | \
((png_uint_32) 84<< 8) | \
((png_uint_32) 69 ))
#endif
#ifndef PNG_UINT_bKGD
# define PNG_UINT_bKGD (((png_uint_32) 98<<24) | \
((png_uint_32) 75<<16) | \
((png_uint_32) 71<< 8) | \
((png_uint_32) 68 ))
#endif
#ifndef PNG_UINT_cHRM
# define PNG_UINT_cHRM (((png_uint_32) 99<<24) | \
((png_uint_32) 72<<16) | \
((png_uint_32) 82<< 8) | \
((png_uint_32) 77 ))
#endif
#ifndef PNG_UINT_gAMA
# define PNG_UINT_gAMA (((png_uint_32) 103<<24) | \
((png_uint_32) 65<<16) | \
((png_uint_32) 77<< 8) | \
((png_uint_32) 65 ))
#endif
#ifndef PNG_UINT_hIST
# define PNG_UINT_hIST (((png_uint_32) 104<<24) | \
((png_uint_32) 73<<16) | \
((png_uint_32) 83<< 8) | \
((png_uint_32) 84 ))
#endif
#ifndef PNG_UINT_iCCP
# define PNG_UINT_iCCP (((png_uint_32) 105<<24) | \
((png_uint_32) 67<<16) | \
((png_uint_32) 67<< 8) | \
((png_uint_32) 80 ))
#endif
#ifndef PNG_UINT_iTXt
# define PNG_UINT_iTXt (((png_uint_32) 105<<24) | \
((png_uint_32) 84<<16) | \
((png_uint_32) 88<< 8) | \
((png_uint_32) 116 ))
#endif
#ifndef PNG_UINT_oFFs
# define PNG_UINT_oFFs (((png_uint_32) 111<<24) | \
((png_uint_32) 70<<16) | \
((png_uint_32) 70<< 8) | \
((png_uint_32) 115 ))
#endif
#ifndef PNG_UINT_pCAL
# define PNG_UINT_pCAL (((png_uint_32) 112<<24) | \
((png_uint_32) 67<<16) | \
((png_uint_32) 65<< 8) | \
((png_uint_32) 76 ))
#endif
#ifndef PNG_UINT_sCAL
# define PNG_UINT_sCAL (((png_uint_32) 115<<24) | \
((png_uint_32) 67<<16) | \
((png_uint_32) 65<< 8) | \
((png_uint_32) 76 ))
#endif
#ifndef PNG_UINT_pHYs
# define PNG_UINT_pHYs (((png_uint_32) 112<<24) | \
((png_uint_32) 72<<16) | \
((png_uint_32) 89<< 8) | \
((png_uint_32) 115 ))
#endif
#ifndef PNG_UINT_sBIT
# define PNG_UINT_sBIT (((png_uint_32) 115<<24) | \
((png_uint_32) 66<<16) | \
((png_uint_32) 73<< 8) | \
((png_uint_32) 84 ))
#endif
#ifndef PNG_UINT_sPLT
# define PNG_UINT_sPLT (((png_uint_32) 115<<24) | \
((png_uint_32) 80<<16) | \
((png_uint_32) 76<< 8) | \
((png_uint_32) 84 ))
#endif
#ifndef PNG_UINT_sRGB
# define PNG_UINT_sRGB (((png_uint_32) 115<<24) | \
((png_uint_32) 82<<16) | \
((png_uint_32) 71<< 8) | \
((png_uint_32) 66 ))
#endif
#ifndef PNG_UINT_tEXt
# define PNG_UINT_tEXt (((png_uint_32) 116<<24) | \
((png_uint_32) 69<<16) | \
((png_uint_32) 88<< 8) | \
((png_uint_32) 116 ))
#endif
#ifndef PNG_UINT_tIME
# define PNG_UINT_tIME (((png_uint_32) 116<<24) | \
((png_uint_32) 73<<16) | \
((png_uint_32) 77<< 8) | \
((png_uint_32) 69 ))
#endif
#ifndef PNG_UINT_tRNS
# define PNG_UINT_tRNS (((png_uint_32) 116<<24) | \
((png_uint_32) 82<<16) | \
((png_uint_32) 78<< 8) | \
((png_uint_32) 83 ))
#endif
#ifndef PNG_UINT_zTXt
# define PNG_UINT_zTXt (((png_uint_32) 122<<24) | \
((png_uint_32) 84<<16) | \
((png_uint_32) 88<< 8) | \
((png_uint_32) 116 ))
#endif
#endif /* !PNGCRUSH_H */

View File

@@ -1,9 +1,9 @@
/* pngerror.c - stub functions for i/o and memory allocation /* pngerror.c - stub functions for i/o and memory allocation
* *
* libpng 1.2.4 - July 8, 2002 * libpng version 1.2.8 - December 3, 2004
* For conditions of distribution and use, see copyright notice in png.h * For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2002 Glenn Randers-Pehrson * Copyright (c) 1998-2004 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
@@ -35,9 +35,9 @@ png_error(png_structp png_ptr, png_const_charp error_message)
char msg[16]; char msg[16];
if (png_ptr->flags&(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) if (png_ptr->flags&(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
{ {
int offset = 0;
if (*error_message == '#') if (*error_message == '#')
{ {
int offset;
for (offset=1; offset<15; offset++) for (offset=1; offset<15; offset++)
if (*(error_message+offset) == ' ') if (*(error_message+offset) == ' ')
break; break;
@@ -63,11 +63,11 @@ png_error(png_structp png_ptr, png_const_charp error_message)
} }
} }
#endif #endif
if (png_ptr->error_fn != NULL) if (png_ptr != NULL && png_ptr->error_fn != NULL)
(*(png_ptr->error_fn))(png_ptr, error_message); (*(png_ptr->error_fn))(png_ptr, error_message);
/* if the following returns or doesn't exist, use the default function, /* If the custom handler doesn't exist, or if it returns,
which will not return */ use the default handler, which will not return. */
png_default_error(png_ptr, error_message); png_default_error(png_ptr, error_message);
} }
@@ -91,11 +91,10 @@ png_warning(png_structp png_ptr, png_const_charp warning_message)
break; break;
} }
} }
if (png_ptr->warning_fn != NULL) if (png_ptr != NULL && png_ptr->warning_fn != NULL)
(*(png_ptr->warning_fn))(png_ptr, (*(png_ptr->warning_fn))(png_ptr, warning_message+offset);
(png_const_charp)(warning_message+offset));
else else
png_default_warning(png_ptr, (png_const_charp)(warning_message+offset)); png_default_warning(png_ptr, warning_message+offset);
} }
/* These utilities are used internally to build an error message that relates /* These utilities are used internally to build an error message that relates
@@ -104,10 +103,11 @@ png_warning(png_structp png_ptr, png_const_charp warning_message)
* to 63 bytes, the name characters are output as hex digits wrapped in [] * to 63 bytes, the name characters are output as hex digits wrapped in []
* if the character is invalid. * if the character is invalid.
*/ */
#define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97)) #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
static PNG_CONST char png_digit[16] = { static PNG_CONST char png_digit[16] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'F' }; 'A', 'B', 'C', 'D', 'E', 'F'
};
static void /* PRIVATE */ static void /* PRIVATE */
png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
@@ -137,7 +137,7 @@ png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
{ {
buffer[iout++] = ':'; buffer[iout++] = ':';
buffer[iout++] = ' '; buffer[iout++] = ' ';
png_memcpy(buffer+iout, error_message, 64); png_strncpy(buffer+iout, error_message, 63);
buffer[iout+63] = 0; buffer[iout+63] = 0;
} }
} }
@@ -190,26 +190,28 @@ png_default_error(png_structp png_ptr, png_const_charp error_message)
else else
#endif #endif
fprintf(stderr, "libpng error: %s\n", error_message); fprintf(stderr, "libpng error: %s\n", error_message);
#else
if (error_message)
/* make compiler happy */ ;
#endif #endif
#ifdef PNG_SETJMP_SUPPORTED #ifdef PNG_SETJMP_SUPPORTED
# ifdef USE_FAR_KEYWORD # ifdef USE_FAR_KEYWORD
{ {
jmp_buf jmpbuf; jmp_buf jmpbuf;
png_memcpy(jmpbuf,png_ptr->jmpbuf,sizeof(jmp_buf)); png_memcpy(jmpbuf,png_ptr->jmpbuf,png_sizeof(jmp_buf));
longjmp(jmpbuf, 1); longjmp(jmpbuf, 1);
} }
# else # else
longjmp(png_ptr->jmpbuf, 1); longjmp(png_ptr->jmpbuf, 1);
# endif # endif
#else #else
if (png_ptr)
/* make compiler happy */ ; /* make compiler happy */ ;
if (png_ptr)
PNG_ABORT(); PNG_ABORT();
#endif #endif
#ifdef PNG_NO_CONSOLE_IO
/* make compiler happy */ ;
if (&error_message != NULL)
return;
#endif
} }
/* This function is called when there is a warning, but the library thinks /* This function is called when there is a warning, but the library thinks
@@ -245,9 +247,11 @@ png_default_warning(png_structp png_ptr, png_const_charp warning_message)
# endif # endif
fprintf(stderr, "libpng warning: %s\n", warning_message); fprintf(stderr, "libpng warning: %s\n", warning_message);
#else #else
/* make compiler happy */ ;
if (warning_message) if (warning_message)
/* appease compiler */ ; return;
#endif #endif
/* make compiler happy */ ;
if (png_ptr) if (png_ptr)
return; return;
} }

View File

@@ -6,9 +6,9 @@
* and http://www.intel.com/drg/pentiumII/appnotes/923/923.htm * and http://www.intel.com/drg/pentiumII/appnotes/923/923.htm
* for Intel's performance analysis of the MMX vs. non-MMX code. * for Intel's performance analysis of the MMX vs. non-MMX code.
* *
* libpng version 1.2.4 - July 8, 2002 * libpng version 1.2.8 - December 3, 2004
* For conditions of distribution and use, see copyright notice in png.h * For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2002 Glenn Randers-Pehrson * Copyright (c) 1998-2004 Glenn Randers-Pehrson
* Copyright (c) 1998, Intel Corporation * Copyright (c) 1998, Intel Corporation
* *
* Based on MSVC code contributed by Nirav Chhatrapati, Intel Corp., 1998. * Based on MSVC code contributed by Nirav Chhatrapati, Intel Corp., 1998.
@@ -223,6 +223,10 @@
* 20020304: * 20020304:
* - eliminated incorrect use of width_mmx in pixel_bytes == 8 case * - eliminated incorrect use of width_mmx in pixel_bytes == 8 case
* *
* 20040724:
* - more tinkering with clobber list at lines 4529 and 5033, to get
* it to compile on gcc-3.4.
*
* STILL TO DO: * STILL TO DO:
* - test png_do_read_interlace() 64-bit case (pixel_bytes == 8) * - test png_do_read_interlace() 64-bit case (pixel_bytes == 8)
* - write MMX code for 48-bit case (pixel_bytes == 6) * - write MMX code for 48-bit case (pixel_bytes == 6)
@@ -412,8 +416,10 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask)
#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) #if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
if (_mmx_supported == 2) { if (_mmx_supported == 2) {
#if !defined(PNG_1_0_X)
/* this should have happened in png_init_mmx_flags() already */ /* this should have happened in png_init_mmx_flags() already */
png_warning(png_ptr, "asm_flags may not have been initialized"); png_warning(png_ptr, "asm_flags may not have been initialized");
#endif
png_mmx_support(); png_mmx_support();
} }
#endif #endif
@@ -422,7 +428,7 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask)
{ {
png_debug(2,"mask == 0xff: doing single png_memcpy()\n"); png_debug(2,"mask == 0xff: doing single png_memcpy()\n");
png_memcpy(row, png_ptr->row_buf + 1, png_memcpy(row, png_ptr->row_buf + 1,
(png_size_t)((png_ptr->width * png_ptr->row_info.pixel_depth + 7) >> 3)); (png_size_t)PNG_ROWBYTES(png_ptr->row_info.pixel_depth,png_ptr->width));
} }
else /* (png_combine_row() is never called with mask == 0) */ else /* (png_combine_row() is never called with mask == 0) */
{ {
@@ -1767,8 +1773,8 @@ png_do_read_interlace(png_structp png_ptr)
: "1" (sptr), // esi // input regs : "1" (sptr), // esi // input regs
"2" (dp), // edi "2" (dp), // edi
"0" (width) // ecx "0" (width), // ecx
// doesn't work "i" (0x0000000000FFFFFFLL) // %1 (a.k.a. _const4) "rim" (_const4) // %1(?) (0x0000000000FFFFFFLL)
#if 0 /* %mm0, ..., %mm4 not supported by gcc 2.7.2.3 or egcs 1.1 */ #if 0 /* %mm0, ..., %mm4 not supported by gcc 2.7.2.3 or egcs 1.1 */
: "%mm0", "%mm1", "%mm2" // clobber list : "%mm0", "%mm1", "%mm2" // clobber list
@@ -1811,7 +1817,8 @@ png_do_read_interlace(png_structp png_ptr)
: "1" (sptr), // esi // input regs : "1" (sptr), // esi // input regs
"2" (dp), // edi "2" (dp), // edi
"0" (width) // ecx "0" (width), // ecx
"rim" (_const4) // (0x0000000000FFFFFFLL)
#if 0 /* %mm0, ..., %mm2 not supported by gcc 2.7.2.3 or egcs 1.1 */ #if 0 /* %mm0, ..., %mm2 not supported by gcc 2.7.2.3 or egcs 1.1 */
: "%mm0", "%mm1", "%mm2" // clobber list : "%mm0", "%mm1", "%mm2" // clobber list
@@ -1865,7 +1872,9 @@ png_do_read_interlace(png_structp png_ptr)
: "1" (sptr), // esi // input regs : "1" (sptr), // esi // input regs
"2" (dp), // edi "2" (dp), // edi
"0" (width_mmx) // ecx "0" (width_mmx), // ecx
"rim" (_const4), // 0x0000000000FFFFFFLL
"rim" (_const6) // 0x00000000000000FFLL
#if 0 /* %mm0, ..., %mm3 not supported by gcc 2.7.2.3 or egcs 1.1 */ #if 0 /* %mm0, ..., %mm3 not supported by gcc 2.7.2.3 or egcs 1.1 */
: "%mm0", "%mm1" // clobber list : "%mm0", "%mm1" // clobber list
@@ -2727,8 +2736,8 @@ png_do_read_interlace(png_structp png_ptr)
} /* end switch (row_info->pixel_depth) */ } /* end switch (row_info->pixel_depth) */
row_info->width = final_width; row_info->width = final_width;
row_info->rowbytes = ((final_width *
(png_uint_32)row_info->pixel_depth + 7) >> 3); row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width);
} }
} /* end png_do_read_interlace() */ } /* end png_do_read_interlace() */
@@ -4529,8 +4538,7 @@ png_read_filter_row_mmx_sub(png_row_infop row_info, png_bytep row)
: "0" (bpp), // eax // input regs : "0" (bpp), // eax // input regs
"1" (row) // edi "1" (row) // edi
: "%ebx", "%ecx", "%edx" // clobber list : "%esi", "%ecx", "%edx" // clobber list
, "%esi"
#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ #if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */
, "%mm0", "%mm1", "%mm2", "%mm3" , "%mm0", "%mm1", "%mm2", "%mm3"
@@ -4990,7 +4998,7 @@ png_read_filter_row_mmx_up(png_row_infop row_info, png_bytep row,
"jz up_end \n\t" "jz up_end \n\t"
"cmpl $8, %%edx \n\t" // test for less than 8 bytes "cmpl $8, %%edx \n\t" // test for less than 8 bytes
"jb up_lt8 \n\t" // [added by lcreeve@netins.net] "jb up_lt8 \n\t" // [added by lcreeve at netins.net]
"addl %%edx, %%ecx \n\t" "addl %%edx, %%ecx \n\t"
"andl $0x00000007, %%edx \n\t" // calc bytes over mult of 8 "andl $0x00000007, %%edx \n\t" // calc bytes over mult of 8
@@ -5034,7 +5042,10 @@ png_read_filter_row_mmx_up(png_row_infop row_info, png_bytep row,
"1" (prev_row), // esi "1" (prev_row), // esi
"2" (row) // edi "2" (row) // edi
: "%eax", "%ebx", "%ecx" // clobber list (no input regs!) : "%eax", "%ecx" // clobber list (no input regs!)
#ifndef __PIC__
, "%ebx"
#endif
#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ #if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */
, "%mm0", "%mm1", "%mm2", "%mm3" , "%mm0", "%mm1", "%mm2", "%mm3"
@@ -5075,7 +5086,9 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep
if (_mmx_supported == 2) { if (_mmx_supported == 2) {
/* this should have happened in png_init_mmx_flags() already */ /* this should have happened in png_init_mmx_flags() already */
#if !defined(PNG_1_0_X)
png_warning(png_ptr, "asm_flags may not have been initialized"); png_warning(png_ptr, "asm_flags may not have been initialized");
#endif
png_mmx_support(); png_mmx_support();
} }
#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ #endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
@@ -5345,13 +5358,13 @@ png_mmx_support(void)
"pushl %%ecx \n\t" // save original Eflag to stack "pushl %%ecx \n\t" // save original Eflag to stack
"popfl \n\t" // restore original Eflag "popfl \n\t" // restore original Eflag
"xorl %%ecx, %%eax \n\t" // compare new Eflag with original Eflag "xorl %%ecx, %%eax \n\t" // compare new Eflag with original Eflag
"jz .NOT_SUPPORTED \n\t" // if same, CPUID instr. is not supported "jz 0f \n\t" // if same, CPUID instr. is not supported
"xorl %%eax, %%eax \n\t" // set eax to zero "xorl %%eax, %%eax \n\t" // set eax to zero
// ".byte 0x0f, 0xa2 \n\t" // CPUID instruction (two-byte opcode) // ".byte 0x0f, 0xa2 \n\t" // CPUID instruction (two-byte opcode)
"cpuid \n\t" // get the CPU identification info "cpuid \n\t" // get the CPU identification info
"cmpl $1, %%eax \n\t" // make sure eax return non-zero value "cmpl $1, %%eax \n\t" // make sure eax return non-zero value
"jl .NOT_SUPPORTED \n\t" // if eax is zero, MMX is not supported "jl 0f \n\t" // if eax is zero, MMX is not supported
"xorl %%eax, %%eax \n\t" // set eax to zero and... "xorl %%eax, %%eax \n\t" // set eax to zero and...
"incl %%eax \n\t" // ...increment eax to 1. This pair is "incl %%eax \n\t" // ...increment eax to 1. This pair is
@@ -5359,14 +5372,14 @@ png_mmx_support(void)
"cpuid \n\t" // get the CPU identification info again "cpuid \n\t" // get the CPU identification info again
"andl $0x800000, %%edx \n\t" // mask out all bits but MMX bit (23) "andl $0x800000, %%edx \n\t" // mask out all bits but MMX bit (23)
"cmpl $0, %%edx \n\t" // 0 = MMX not supported "cmpl $0, %%edx \n\t" // 0 = MMX not supported
"jz .NOT_SUPPORTED \n\t" // non-zero = yes, MMX IS supported "jz 0f \n\t" // non-zero = yes, MMX IS supported
"movl $1, %%eax \n\t" // set return value to 1 "movl $1, %%eax \n\t" // set return value to 1
"jmp .RETURN \n\t" // DONE: have MMX support "jmp 1f \n\t" // DONE: have MMX support
".NOT_SUPPORTED: \n\t" // target label for jump instructions "0: \n\t" // .NOT_SUPPORTED: target label for jump instructions
"movl $0, %%eax \n\t" // set return value to 0 "movl $0, %%eax \n\t" // set return value to 0
".RETURN: \n\t" // target label for jump instructions "1: \n\t" // .RETURN: target label for jump instructions
"movl %%eax, _mmx_supported \n\t" // save in global static variable, too "movl %%eax, _mmx_supported \n\t" // save in global static variable, too
"popl %%edx \n\t" // restore edx "popl %%edx \n\t" // restore edx
"popl %%ecx \n\t" // restore ecx "popl %%ecx \n\t" // restore ecx

View File

@@ -1,9 +1,9 @@
/* pngget.c - retrieval of values from info struct /* pngget.c - retrieval of values from info struct
* *
* libpng 1.2.4 - July 8, 2002 * libpng 1.2.8 - December 3, 2004
* For conditions of distribution and use, see copyright notice in png.h * For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2002 Glenn Randers-Pehrson * Copyright (c) 1998-2004 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*/ */
@@ -540,9 +540,6 @@ png_get_IHDR(png_structp png_ptr, png_infop info_ptr,
if (png_ptr != NULL && info_ptr != NULL && width != NULL && height != NULL && if (png_ptr != NULL && info_ptr != NULL && width != NULL && height != NULL &&
bit_depth != NULL && color_type != 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"); png_debug1(1, "in %s retrieval function\n", "IHDR");
*width = info_ptr->width; *width = info_ptr->width;
*height = info_ptr->height; *height = info_ptr->height;
@@ -560,23 +557,18 @@ png_get_IHDR(png_structp png_ptr, png_infop info_ptr,
*interlace_type = info_ptr->interlace_type; *interlace_type = info_ptr->interlace_type;
/* check for potential overflow of rowbytes */ /* check for potential overflow of rowbytes */
if (*color_type == PNG_COLOR_TYPE_PALETTE) if (*width == 0 || *width > PNG_UINT_31_MAX)
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 == 0 || *width > PNG_MAX_UINT)
png_error(png_ptr, "Invalid image width"); png_error(png_ptr, "Invalid image width");
if (height == 0 || *height > PNG_MAX_UINT) if (*height == 0 || *height > PNG_UINT_31_MAX)
png_error(png_ptr, "Invalid image height"); png_error(png_ptr, "Invalid image height");
if (*width > PNG_MAX_UINT/rowbytes_per_pixel - 64) if (info_ptr->width > (PNG_UINT_32_MAX
>> 3) /* 8-byte RGBA pixels */
- 64 /* bigrowbuf hack */
- 1 /* filter byte */
- 7*8 /* rounding of width to multiple of 8 pixels */
- 8) /* extra max_pixel_depth pad */
{ {
png_error(png_ptr, png_warning(png_ptr,
"Width too large for libpng to process image data."); "Width too large for libpng to process image data.");
} }
return (1); return (1);
@@ -827,13 +819,13 @@ png_get_user_chunk_ptr(png_structp png_ptr)
} }
#endif #endif
#ifdef PNG_WRITE_SUPPORTED
png_uint_32 PNGAPI png_uint_32 PNGAPI
png_get_compression_buffer_size(png_structp png_ptr) png_get_compression_buffer_size(png_structp png_ptr)
{ {
return (png_uint_32)(png_ptr? png_ptr->zbuf_size : 0L); return (png_uint_32)(png_ptr? png_ptr->zbuf_size : 0L);
} }
#endif
#ifndef PNG_1_0_X #ifndef PNG_1_0_X
#ifdef PNG_ASSEMBLER_CODE_SUPPORTED #ifdef PNG_ASSEMBLER_CODE_SUPPORTED
@@ -923,5 +915,20 @@ png_get_mmx_rowbytes_threshold (png_structp png_ptr)
{ {
return (png_uint_32)(png_ptr? png_ptr->mmx_rowbytes_threshold : 0L); return (png_uint_32)(png_ptr? png_ptr->mmx_rowbytes_threshold : 0L);
} }
#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ #endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
#endif /* PNG_1_0_X */
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
/* these functions were added to libpng 1.2.6 */
png_uint_32 PNGAPI
png_get_user_width_max (png_structp png_ptr)
{
return (png_ptr? png_ptr->user_width_max : 0);
}
png_uint_32 PNGAPI
png_get_user_height_max (png_structp png_ptr)
{
return (png_ptr? png_ptr->user_height_max : 0);
}
#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
#endif /* ?PNG_1_0_X */

View File

@@ -1,9 +1,9 @@
/* pngmem.c - stub functions for memory allocation /* pngmem.c - stub functions for memory allocation
* *
* libpng 1.2.4 - July 8, 2002 * libpng version 1.2.8 - December 3, 2004
* For conditions of distribution and use, see copyright notice in png.h * For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2002 Glenn Randers-Pehrson * Copyright (c) 1998-2004 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
@@ -39,11 +39,11 @@ png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
png_voidp struct_ptr; png_voidp struct_ptr;
if (type == PNG_STRUCT_INFO) if (type == PNG_STRUCT_INFO)
size = sizeof(png_info); size = png_sizeof(png_info);
else if (type == PNG_STRUCT_PNG) else if (type == PNG_STRUCT_PNG)
size = sizeof(png_struct); size = png_sizeof(png_struct);
else else
return (png_get_copyright()); return (png_get_copyright(NULL));
#ifdef PNG_USER_MEM_SUPPORTED #ifdef PNG_USER_MEM_SUPPORTED
if(malloc_fn != NULL) if(malloc_fn != NULL)
@@ -55,7 +55,7 @@ png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
} }
else else
#endif /* PNG_USER_MEM_SUPPORTED */ #endif /* PNG_USER_MEM_SUPPORTED */
struct_ptr = (png_voidp)farmalloc(size)); struct_ptr = (png_voidp)farmalloc(size);
if (struct_ptr != NULL) if (struct_ptr != NULL)
png_memset(struct_ptr, 0, size); png_memset(struct_ptr, 0, size);
return (struct_ptr); return (struct_ptr);
@@ -121,15 +121,13 @@ png_malloc(png_structp png_ptr, png_uint_32 size)
#ifdef PNG_USER_MEM_SUPPORTED #ifdef PNG_USER_MEM_SUPPORTED
if(png_ptr->malloc_fn != NULL) if(png_ptr->malloc_fn != NULL)
{
ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size)); ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
else
ret = (png_malloc_default(png_ptr, size));
if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out of memory!"); png_error(png_ptr, "Out of memory!");
return (ret); return (ret);
} }
else
return png_malloc_default(png_ptr, size);
}
png_voidp PNGAPI png_voidp PNGAPI
png_malloc_default(png_structp png_ptr, png_uint_32 size) png_malloc_default(png_structp png_ptr, png_uint_32 size)
@@ -139,10 +137,16 @@ png_malloc_default(png_structp png_ptr, png_uint_32 size)
#ifdef PNG_MAX_MALLOC_64K #ifdef PNG_MAX_MALLOC_64K
if (size > (png_uint_32)65536L) if (size > (png_uint_32)65536L)
png_error(png_ptr, "Cannot Allocate > 64K"); {
png_warning(png_ptr, "Cannot Allocate > 64K");
ret = NULL;
}
else
#endif #endif
if (size == (png_uint_32)65536L) if (size != (size_t)size)
ret = NULL;
else if (size == (png_uint_32)65536L)
{ {
if (png_ptr->offset_table == NULL) if (png_ptr->offset_table == NULL)
{ {
@@ -177,34 +181,40 @@ png_malloc_default(png_structp png_ptr, png_uint_32 size)
if (table == NULL) if (table == NULL)
{ {
if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) #ifndef PNG_USER_MEM_SUPPORTED
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */ png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
else else
png_warning(png_ptr, "Out Of Memory."); png_warning(png_ptr, "Out Of Memory.");
#endif
return (NULL); return (NULL);
} }
if ((png_size_t)table & 0xfff0) if ((png_size_t)table & 0xfff0)
{ {
if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) #ifndef PNG_USER_MEM_SUPPORTED
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, png_error(png_ptr,
"Farmalloc didn't return normalized pointer"); "Farmalloc didn't return normalized pointer");
else else
png_warning(png_ptr, png_warning(png_ptr,
"Farmalloc didn't return normalized pointer"); "Farmalloc didn't return normalized pointer");
#endif
return (NULL); return (NULL);
} }
png_ptr->offset_table = table; png_ptr->offset_table = table;
png_ptr->offset_table_ptr = farmalloc(num_blocks * png_ptr->offset_table_ptr = farmalloc(num_blocks *
sizeof (png_bytep)); png_sizeof (png_bytep));
if (png_ptr->offset_table_ptr == NULL) if (png_ptr->offset_table_ptr == NULL)
{ {
if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) #ifndef PNG_USER_MEM_SUPPORTED
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out Of memory."); /* Note "O" and "M" */ png_error(png_ptr, "Out Of memory."); /* Note "O" and "M" */
else else
png_warning(png_ptr, "Out Of memory."); png_warning(png_ptr, "Out Of memory.");
#endif
return (NULL); return (NULL);
} }
@@ -228,10 +238,12 @@ png_malloc_default(png_structp png_ptr, png_uint_32 size)
if (png_ptr->offset_table_count >= png_ptr->offset_table_number) if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
{ {
if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) #ifndef PNG_USER_MEM_SUPPORTED
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */ png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */
else else
png_warning(png_ptr, "Out of Memory."); png_warning(png_ptr, "Out of Memory.");
#endif
return (NULL); return (NULL);
} }
@@ -240,13 +252,15 @@ png_malloc_default(png_structp png_ptr, png_uint_32 size)
else else
ret = farmalloc(size); ret = farmalloc(size);
#ifndef PNG_USER_MEM_SUPPORTED
if (ret == NULL) if (ret == NULL)
{ {
if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */ png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
else else
png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */ png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */
} }
#endif
return (ret); return (ret);
} }
@@ -325,9 +339,9 @@ png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
png_voidp struct_ptr; png_voidp struct_ptr;
if (type == PNG_STRUCT_INFO) if (type == PNG_STRUCT_INFO)
size = sizeof(png_info); size = png_sizeof(png_info);
else if (type == PNG_STRUCT_PNG) else if (type == PNG_STRUCT_PNG)
size = sizeof(png_struct); size = png_sizeof(png_struct);
else else
return (NULL); return (NULL);
@@ -345,17 +359,16 @@ png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
#endif /* PNG_USER_MEM_SUPPORTED */ #endif /* PNG_USER_MEM_SUPPORTED */
#if defined(__TURBOC__) && !defined(__FLAT__) #if defined(__TURBOC__) && !defined(__FLAT__)
if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL) struct_ptr = (png_voidp)farmalloc(size);
#else #else
# if defined(_MSC_VER) && defined(MAXSEG_64K) # if defined(_MSC_VER) && defined(MAXSEG_64K)
if ((struct_ptr = (png_voidp)halloc(size,1)) != NULL) struct_ptr = (png_voidp)halloc(size,1);
# else # else
if ((struct_ptr = (png_voidp)malloc(size)) != NULL) struct_ptr = (png_voidp)malloc(size);
# endif # endif
#endif #endif
{ if (struct_ptr != NULL)
png_memset(struct_ptr, 0, size); png_memset(struct_ptr, 0, size);
}
return (struct_ptr); return (struct_ptr);
} }
@@ -410,20 +423,18 @@ png_malloc(png_structp png_ptr, png_uint_32 size)
{ {
png_voidp ret; png_voidp ret;
#ifdef PNG_USER_MEM_SUPPORTED
if (png_ptr == NULL || size == 0) if (png_ptr == NULL || size == 0)
return (NULL); return (NULL);
#ifdef PNG_USER_MEM_SUPPORTED
if(png_ptr->malloc_fn != NULL) if(png_ptr->malloc_fn != NULL)
{
ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size)); ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
else
ret = (png_malloc_default(png_ptr, size));
if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out of Memory!"); png_error(png_ptr, "Out of Memory!");
return (ret); return (ret);
} }
else
return (png_malloc_default(png_ptr, size));
}
png_voidp PNGAPI png_voidp PNGAPI
png_malloc_default(png_structp png_ptr, png_uint_32 size) png_malloc_default(png_structp png_ptr, png_uint_32 size)
@@ -431,28 +442,45 @@ png_malloc_default(png_structp png_ptr, png_uint_32 size)
png_voidp ret; png_voidp ret;
#endif /* PNG_USER_MEM_SUPPORTED */ #endif /* PNG_USER_MEM_SUPPORTED */
if (png_ptr == NULL || size == 0)
return (NULL);
#ifdef PNG_MAX_MALLOC_64K #ifdef PNG_MAX_MALLOC_64K
if (size > (png_uint_32)65536L) if (size > (png_uint_32)65536L)
{ {
#ifndef PNG_USER_MEM_SUPPORTED
if(png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) if(png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Cannot Allocate > 64K"); png_error(png_ptr, "Cannot Allocate > 64K");
else else
#endif
return NULL; return NULL;
} }
#endif #endif
/* Check for overflow */
#if defined(__TURBOC__) && !defined(__FLAT__) #if defined(__TURBOC__) && !defined(__FLAT__)
if (size != (unsigned long)size)
ret = NULL;
else
ret = farmalloc(size); ret = farmalloc(size);
#else #else
# if defined(_MSC_VER) && defined(MAXSEG_64K) # if defined(_MSC_VER) && defined(MAXSEG_64K)
if (size != (unsigned long)size)
ret = NULL;
else
ret = halloc(size, 1); ret = halloc(size, 1);
# else # else
if (size != (size_t)size)
ret = NULL;
else
ret = malloc((size_t)size); ret = malloc((size_t)size);
# endif # endif
#endif #endif
#ifndef PNG_USER_MEM_SUPPORTED
if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
png_error(png_ptr, "Out of Memory"); png_error(png_ptr, "Out of Memory");
#endif
return (ret); return (ret);
} }
@@ -498,8 +526,9 @@ png_free_default(png_structp png_ptr, png_voidp ptr)
# define png_malloc_warn png_malloc # define png_malloc_warn png_malloc
#else #else
/* This function was added at libpng version 1.2.3. The png_malloc_warn() /* This function was added at libpng version 1.2.3. The png_malloc_warn()
* function will issue a png_warning and return NULL instead of issuing a * function will set up png_malloc() to issue a png_warning and return NULL
* png_error, if it fails to allocate the requested memory. * instead of issuing a png_error, if it fails to allocate the requested
* memory.
*/ */
png_voidp PNGAPI png_voidp PNGAPI
png_malloc_warn(png_structp png_ptr, png_uint_32 size) png_malloc_warn(png_structp png_ptr, png_uint_32 size)

View File

@@ -1,9 +1,9 @@
/* pngpread.c - read a png file in push mode /* pngpread.c - read a png file in push mode
* *
* libpng 1.2.4 - July 8, 2002 * libpng version 1.2.8 - December 3, 2004
* For conditions of distribution and use, see copyright notice in png.h * For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2002 Glenn Randers-Pehrson * Copyright (c) 1998-2004 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*/ */
@@ -208,7 +208,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
} }
png_push_fill_buffer(png_ptr, chunk_length, 4); png_push_fill_buffer(png_ptr, chunk_length, 4);
png_ptr->push_length = png_get_uint_32(chunk_length); png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length);
png_reset_crc(png_ptr); png_reset_crc(png_ptr);
png_crc_read(png_ptr, png_ptr->chunk_name, 4); png_crc_read(png_ptr, png_ptr->chunk_name, 4);
png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
@@ -223,6 +223,41 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
} }
png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length); png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
} }
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);
}
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
{
if (png_ptr->push_length + 4 > png_ptr->buffer_size)
{
png_push_save_buffer(png_ptr);
return;
}
if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
png_ptr->mode |= PNG_HAVE_IDAT;
png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
png_ptr->mode |= PNG_HAVE_PLTE;
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");
}
}
#endif
else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
{ {
if (png_ptr->push_length + 4 > png_ptr->buffer_size) if (png_ptr->push_length + 4 > png_ptr->buffer_size)
@@ -261,18 +296,6 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
png_ptr->zstream.next_out = png_ptr->row_buf; png_ptr->zstream.next_out = png_ptr->row_buf;
return; 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) #if defined(PNG_READ_gAMA_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
{ {
@@ -591,6 +614,11 @@ png_push_save_buffer(png_structp png_ptr)
png_size_t new_max; png_size_t new_max;
png_bytep old_buffer; png_bytep old_buffer;
if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
(png_ptr->current_buffer_size + 256))
{
png_error(png_ptr, "Potential overflow of save_buffer");
}
new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256; new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
old_buffer = png_ptr->save_buffer; old_buffer = png_ptr->save_buffer;
png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr, png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr,
@@ -637,8 +665,7 @@ png_push_read_IDAT(png_structp png_ptr)
} }
png_push_fill_buffer(png_ptr, chunk_length, 4); png_push_fill_buffer(png_ptr, chunk_length, 4);
png_ptr->push_length = png_get_uint_32(chunk_length); png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length);
png_reset_crc(png_ptr); png_reset_crc(png_ptr);
png_crc_read(png_ptr, png_ptr->chunk_name, 4); png_crc_read(png_ptr, png_ptr->chunk_name, 4);
png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
@@ -668,8 +695,8 @@ png_push_read_IDAT(png_structp png_ptr)
save_size = png_ptr->save_buffer_size; save_size = png_ptr->save_buffer_size;
png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
png_process_IDAT_data(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->idat_size -= save_size;
png_ptr->buffer_size -= save_size; png_ptr->buffer_size -= save_size;
png_ptr->save_buffer_size -= save_size; png_ptr->save_buffer_size -= save_size;
@@ -690,6 +717,7 @@ png_push_read_IDAT(png_structp png_ptr)
save_size = png_ptr->current_buffer_size; save_size = png_ptr->current_buffer_size;
png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
png_process_IDAT_data(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->idat_size -= save_size;
@@ -707,6 +735,7 @@ png_push_read_IDAT(png_structp png_ptr)
png_crc_finish(png_ptr, 0); png_crc_finish(png_ptr, 0);
png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
png_ptr->mode |= PNG_AFTER_IDAT;
} }
} }
@@ -751,8 +780,13 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
png_ptr->interlaced && png_ptr->pass > 6) || png_ptr->interlaced && png_ptr->pass > 6) ||
(!png_ptr->interlaced && (!png_ptr->interlaced &&
#endif #endif
png_ptr->row_number == png_ptr->num_rows-1)) png_ptr->row_number == png_ptr->num_rows))
png_error(png_ptr, "Too much data in IDAT chunks"); {
if (png_ptr->zstream.avail_in)
png_warning(png_ptr, "Too much data in IDAT chunks");
png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
break;
}
png_push_process_row(png_ptr); png_push_process_row(png_ptr);
png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes; png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
png_ptr->zstream.next_out = png_ptr->row_buf; png_ptr->zstream.next_out = png_ptr->row_buf;
@@ -771,8 +805,8 @@ png_push_process_row(png_structp png_ptr)
png_ptr->row_info.bit_depth = png_ptr->bit_depth; png_ptr->row_info.bit_depth = png_ptr->bit_depth;
png_ptr->row_info.pixel_depth = png_ptr->pixel_depth; png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
png_ptr->row_info.rowbytes = ((png_ptr->row_info.width * png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
(png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3); png_ptr->row_info.width);
png_read_filter_row(png_ptr, &(png_ptr->row_info), png_read_filter_row(png_ptr, &(png_ptr->row_info),
png_ptr->row_buf + 1, png_ptr->prev_row + 1, png_ptr->row_buf + 1, png_ptr->prev_row + 1,
@@ -781,7 +815,7 @@ png_push_process_row(png_structp png_ptr)
png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf, png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
png_ptr->rowbytes + 1); png_ptr->rowbytes + 1);
if (png_ptr->transformations) if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
png_do_read_transformations(png_ptr); png_do_read_transformations(png_ptr);
#if defined(PNG_READ_INTERLACING_SUPPORTED) #if defined(PNG_READ_INTERLACING_SUPPORTED)
@@ -987,6 +1021,8 @@ png_read_push_finish_row(png_structp png_ptr)
(png_ptr->pass == 5 && png_ptr->width < 2)) (png_ptr->pass == 5 && png_ptr->width < 2))
png_ptr->pass++; png_ptr->pass++;
if (png_ptr->pass > 7)
png_ptr->pass--;
if (png_ptr->pass >= 7) if (png_ptr->pass >= 7)
break; break;
@@ -995,8 +1031,8 @@ png_read_push_finish_row(png_structp png_ptr)
png_pass_start[png_ptr->pass]) / png_pass_start[png_ptr->pass]) /
png_pass_inc[png_ptr->pass]; png_pass_inc[png_ptr->pass];
png_ptr->irowbytes = ((png_ptr->iwidth * png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
png_ptr->pixel_depth + 7) >> 3) + 1; png_ptr->iwidth) + 1;
if (png_ptr->transformations & PNG_INTERLACE) if (png_ptr->transformations & PNG_INTERLACE)
break; break;
@@ -1085,7 +1121,8 @@ png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
if (text != key + png_ptr->current_text_size) if (text != key + png_ptr->current_text_size)
text++; text++;
text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text)); text_ptr = (png_textp)png_malloc(png_ptr,
(png_uint_32)png_sizeof(png_text));
text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
text_ptr->key = key; text_ptr->key = key;
#ifdef PNG_iTXt_SUPPORTED #ifdef PNG_iTXt_SUPPORTED
@@ -1278,7 +1315,8 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
key = text; key = text;
text += key_size; text += key_size;
text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text)); text_ptr = (png_textp)png_malloc(png_ptr,
(png_uint_32)png_sizeof(png_text));
text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt; text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
text_ptr->key = key; text_ptr->key = key;
#ifdef PNG_iTXt_SUPPORTED #ifdef PNG_iTXt_SUPPORTED
@@ -1390,7 +1428,8 @@ png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
if (text != key + png_ptr->current_text_size) if (text != key + png_ptr->current_text_size)
text++; text++;
text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text)); text_ptr = (png_textp)png_malloc(png_ptr,
(png_uint_32)png_sizeof(png_text));
text_ptr->compression = comp_flag + 2; text_ptr->compression = comp_flag + 2;
text_ptr->key = key; text_ptr->key = key;
text_ptr->lang = lang; text_ptr->lang = lang;
@@ -1425,7 +1464,7 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
{ {
#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
HANDLE_CHUNK_ALWAYS PNG_HANDLE_CHUNK_ALWAYS
#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
&& png_ptr->read_user_chunk_fn == NULL && png_ptr->read_user_chunk_fn == NULL
#endif #endif
@@ -1464,7 +1503,7 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
{ {
if (!(png_ptr->chunk_name[0] & 0x20)) if (!(png_ptr->chunk_name[0] & 0x20))
if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
HANDLE_CHUNK_ALWAYS) PNG_HANDLE_CHUNK_ALWAYS)
png_chunk_error(png_ptr, "unknown critical chunk"); png_chunk_error(png_ptr, "unknown critical chunk");
} }
png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1); png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);

128
pngread.c
View File

@@ -1,9 +1,9 @@
/* pngread.c - read a PNG file /* pngread.c - read a PNG file
* *
* libpng 1.2.4 - July 8, 2002 * libpng 1.2.8 - December 3, 2004
* For conditions of distribution and use, see copyright notice in png.h * For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2002 Glenn Randers-Pehrson * Copyright (c) 1998-2004 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
@@ -59,6 +59,12 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
#endif #endif
#endif /* PNG_1_0_X */ #endif /* PNG_1_0_X */
/* added at libpng-1.2.6 */
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
#endif
#ifdef PNG_SETJMP_SUPPORTED #ifdef PNG_SETJMP_SUPPORTED
#ifdef USE_FAR_KEYWORD #ifdef USE_FAR_KEYWORD
if (setjmp(jmpbuf)) if (setjmp(jmpbuf))
@@ -77,7 +83,7 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
return (NULL); return (NULL);
} }
#ifdef USE_FAR_KEYWORD #ifdef USE_FAR_KEYWORD
png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf)); png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
#endif #endif
#endif #endif
@@ -154,7 +160,7 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
#ifdef USE_FAR_KEYWORD #ifdef USE_FAR_KEYWORD
if (setjmp(jmpbuf)) if (setjmp(jmpbuf))
PNG_ABORT(); PNG_ABORT();
png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf)); png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
#else #else
if (setjmp(png_ptr->jmpbuf)) if (setjmp(png_ptr->jmpbuf))
PNG_ABORT(); PNG_ABORT();
@@ -166,6 +172,7 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
/* Initialize PNG structure for reading, and allocate any memory needed. /* Initialize PNG structure for reading, and allocate any memory needed.
This interface is deprecated in favour of the png_create_read_struct(), This interface is deprecated in favour of the png_create_read_struct(),
and it will eventually disappear. */ and it will eventually disappear. */
#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
#undef png_read_init #undef png_read_init
void PNGAPI void PNGAPI
png_read_init(png_structp png_ptr) png_read_init(png_structp png_ptr)
@@ -173,6 +180,7 @@ png_read_init(png_structp png_ptr)
/* We only come here via pre-1.0.7-compiled applications */ /* We only come here via pre-1.0.7-compiled applications */
png_read_init_2(png_ptr, "1.0.6 or earlier", 0, 0); png_read_init_2(png_ptr, "1.0.6 or earlier", 0, 0);
} }
#endif
void PNGAPI void PNGAPI
png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver, png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver,
@@ -180,7 +188,8 @@ png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver,
{ {
/* We only come here via pre-1.0.12-compiled applications */ /* We only come here via pre-1.0.12-compiled applications */
#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
if(sizeof(png_struct) > png_struct_size || sizeof(png_info) > png_info_size) if(png_sizeof(png_struct) > png_struct_size ||
png_sizeof(png_info) > png_info_size)
{ {
char msg[80]; char msg[80];
png_ptr->warning_fn=NULL; png_ptr->warning_fn=NULL;
@@ -195,7 +204,7 @@ png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver,
png_warning(png_ptr, msg); png_warning(png_ptr, msg);
} }
#endif #endif
if(sizeof(png_struct) > png_struct_size) if(png_sizeof(png_struct) > png_struct_size)
{ {
png_ptr->error_fn=NULL; png_ptr->error_fn=NULL;
#ifdef PNG_ERROR_NUMBERS_SUPPORTED #ifdef PNG_ERROR_NUMBERS_SUPPORTED
@@ -204,7 +213,7 @@ png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver,
png_error(png_ptr, png_error(png_ptr,
"The png struct allocated by the application for reading is too small."); "The png struct allocated by the application for reading is too small.");
} }
if(sizeof(png_info) > png_info_size) if(png_sizeof(png_info) > png_info_size)
{ {
png_ptr->error_fn=NULL; png_ptr->error_fn=NULL;
#ifdef PNG_ERROR_NUMBERS_SUPPORTED #ifdef PNG_ERROR_NUMBERS_SUPPORTED
@@ -247,10 +256,10 @@ png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
#ifdef PNG_SETJMP_SUPPORTED #ifdef PNG_SETJMP_SUPPORTED
/* save jump buffer and error functions */ /* save jump buffer and error functions */
png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf)); png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
#endif #endif
if(sizeof(png_struct) > png_struct_size) if(png_sizeof(png_struct) > png_struct_size)
{ {
png_destroy_struct(png_ptr); png_destroy_struct(png_ptr);
*ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
@@ -258,11 +267,17 @@ png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
} }
/* reset all variables to 0 */ /* reset all variables to 0 */
png_memset(png_ptr, 0, sizeof (png_struct)); png_memset(png_ptr, 0, png_sizeof (png_struct));
#ifdef PNG_SETJMP_SUPPORTED #ifdef PNG_SETJMP_SUPPORTED
/* restore jump buffer */ /* restore jump buffer */
png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf)); png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
#endif
/* added at libpng-1.2.6 */
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
#endif #endif
/* initialize zbuf - compression buffer */ /* initialize zbuf - compression buffer */
@@ -288,6 +303,7 @@ png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL); png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
} }
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
/* Read the information before the actual image data. This has been /* 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 * 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 * bytes read from the stream. You can tell libpng how many bytes have
@@ -379,12 +395,12 @@ png_read_info(png_structp png_ptr, png_infop info_ptr)
#if defined(PNG_READ_zTXt_SUPPORTED) #if defined(PNG_READ_zTXt_SUPPORTED)
PNG_zTXt; PNG_zTXt;
#endif #endif
#endif /* PNG_GLOBAL_ARRAYS */ #endif /* PNG_USE_LOCAL_ARRAYS */
png_byte chunk_length[4]; png_byte chunk_length[4];
png_uint_32 length; png_uint_32 length;
png_read_data(png_ptr, chunk_length, 4); png_read_data(png_ptr, chunk_length, 4);
length = png_get_uint_32(chunk_length); length = png_get_uint_31(png_ptr,chunk_length);
png_reset_crc(png_ptr); png_reset_crc(png_ptr);
png_crc_read(png_ptr, png_ptr->chunk_name, 4); png_crc_read(png_ptr, png_ptr->chunk_name, 4);
@@ -392,9 +408,6 @@ png_read_info(png_structp png_ptr, png_infop info_ptr)
png_debug2(0, "Reading %s chunk, length=%lu.\n", png_ptr->chunk_name, png_debug2(0, "Reading %s chunk, length=%lu.\n", png_ptr->chunk_name,
length); length);
if (length > PNG_MAX_UINT)
png_error(png_ptr, "Invalid chunk length.");
/* This should be a binary subdivision search or a hash for /* This should be a binary subdivision search or a hash for
* matching the chunk name rather than a linear search. * matching the chunk name rather than a linear search.
*/ */
@@ -507,6 +520,7 @@ png_read_info(png_structp png_ptr, png_infop info_ptr)
png_handle_unknown(png_ptr, info_ptr, length); png_handle_unknown(png_ptr, info_ptr, length);
} }
} }
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
/* optional call to update the users info_ptr structure */ /* optional call to update the users info_ptr structure */
void PNGAPI void PNGAPI
@@ -521,6 +535,7 @@ png_read_update_info(png_structp png_ptr, png_infop info_ptr)
png_read_transform_info(png_ptr, info_ptr); png_read_transform_info(png_ptr, info_ptr);
} }
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
/* Initialize palette, background, etc, after transformations /* Initialize palette, background, etc, after transformations
* are set, but before any reading takes place. This allows * are set, but before any reading takes place. This allows
* the user to obtain a gamma-corrected palette, for example. * the user to obtain a gamma-corrected palette, for example.
@@ -533,7 +548,9 @@ png_start_read_image(png_structp png_ptr)
if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
png_read_start_row(png_ptr); png_read_start_row(png_ptr);
} }
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
void PNGAPI void PNGAPI
png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
{ {
@@ -673,10 +690,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
png_crc_finish(png_ptr, 0); png_crc_finish(png_ptr, 0);
png_read_data(png_ptr, chunk_length, 4); png_read_data(png_ptr, chunk_length, 4);
png_ptr->idat_size = png_get_uint_32(chunk_length); png_ptr->idat_size = png_get_uint_31(png_ptr,chunk_length);
if (png_ptr->idat_size > PNG_MAX_UINT)
png_error(png_ptr, "Invalid chunk length.");
png_reset_crc(png_ptr); png_reset_crc(png_ptr);
png_crc_read(png_ptr, png_ptr->chunk_name, 4); png_crc_read(png_ptr, png_ptr->chunk_name, 4);
@@ -712,8 +726,8 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
png_ptr->row_info.channels = png_ptr->channels; png_ptr->row_info.channels = png_ptr->channels;
png_ptr->row_info.bit_depth = png_ptr->bit_depth; png_ptr->row_info.bit_depth = png_ptr->bit_depth;
png_ptr->row_info.pixel_depth = png_ptr->pixel_depth; png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
png_ptr->row_info.rowbytes = ((png_ptr->row_info.width * png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
(png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3); png_ptr->row_info.width);
if(png_ptr->row_buf[0]) if(png_ptr->row_buf[0])
png_read_filter_row(png_ptr, &(png_ptr->row_info), png_read_filter_row(png_ptr, &(png_ptr->row_info),
@@ -732,7 +746,8 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
} }
#endif #endif
if (png_ptr->transformations)
if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
png_do_read_transformations(png_ptr); png_do_read_transformations(png_ptr);
#if defined(PNG_READ_INTERLACING_SUPPORTED) #if defined(PNG_READ_INTERLACING_SUPPORTED)
@@ -767,7 +782,9 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
if (png_ptr->read_row_fn != NULL) if (png_ptr->read_row_fn != NULL)
(*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
} }
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
/* Read one or more rows of image data. If the image is interlaced, /* 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 * and png_set_interlace_handling() has been called, the rows need to
* contain the contents of the rows from the previous pass. If the * contain the contents of the rows from the previous pass. If the
@@ -789,7 +806,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
* not called png_set_interlace_handling(), the display_row buffer will * not called png_set_interlace_handling(), the display_row buffer will
* be ignored, so pass NULL to it. * be ignored, so pass NULL to it.
* *
* [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.4 * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.8
*/ */
void PNGAPI void PNGAPI
@@ -826,7 +843,9 @@ png_read_rows(png_structp png_ptr, png_bytepp row,
dp++; dp++;
} }
} }
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
/* Read the entire image. If the image has an alpha channel or a tRNS /* 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 * chunk, and you have called png_handle_alpha()[*], you will need to
* initialize the image to the current image that PNG will be overlaying. * initialize the image to the current image that PNG will be overlaying.
@@ -837,7 +856,7 @@ png_read_rows(png_structp png_ptr, png_bytepp row,
* only call this function once. If you desire to have an image for * only call this function once. If you desire to have an image for
* each pass of a interlaced image, use png_read_rows() instead. * each pass of a interlaced image, use png_read_rows() instead.
* *
* [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.4 * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.8
*/ */
void PNGAPI void PNGAPI
png_read_image(png_structp png_ptr, png_bytepp image) png_read_image(png_structp png_ptr, png_bytepp image)
@@ -871,7 +890,9 @@ png_read_image(png_structp png_ptr, png_bytepp image)
} }
} }
} }
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
/* Read the end of the PNG file. Will not read past the end of the /* 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 * 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. * or time information at the end of the file, if info is not NULL.
@@ -943,19 +964,16 @@ png_read_end(png_structp png_ptr, png_infop info_ptr)
#if defined(PNG_READ_zTXt_SUPPORTED) #if defined(PNG_READ_zTXt_SUPPORTED)
PNG_zTXt; PNG_zTXt;
#endif #endif
#endif /* PNG_GLOBAL_ARRAYS */ #endif /* PNG_USE_LOCAL_ARRAYS */
png_read_data(png_ptr, chunk_length, 4); png_read_data(png_ptr, chunk_length, 4);
length = png_get_uint_32(chunk_length); length = png_get_uint_31(png_ptr,chunk_length);
png_reset_crc(png_ptr); png_reset_crc(png_ptr);
png_crc_read(png_ptr, png_ptr->chunk_name, 4); png_crc_read(png_ptr, png_ptr->chunk_name, 4);
png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name); png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name);
if (length > PNG_MAX_UINT)
png_error(png_ptr, "Invalid chunk length.");
if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
png_handle_IHDR(png_ptr, info_ptr, length); png_handle_IHDR(png_ptr, info_ptr, length);
else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
@@ -1058,6 +1076,7 @@ png_read_end(png_structp png_ptr, png_infop info_ptr)
png_handle_unknown(png_ptr, info_ptr, length); png_handle_unknown(png_ptr, info_ptr, length);
} while (!(png_ptr->mode & PNG_HAVE_IEND)); } while (!(png_ptr->mode & PNG_HAVE_IEND));
} }
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
/* free all memory used by the read */ /* free all memory used by the read */
void PNGAPI void PNGAPI
@@ -1067,8 +1086,8 @@ png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
png_structp png_ptr = NULL; png_structp png_ptr = NULL;
png_infop info_ptr = NULL, end_info_ptr = NULL; png_infop info_ptr = NULL, end_info_ptr = NULL;
#ifdef PNG_USER_MEM_SUPPORTED #ifdef PNG_USER_MEM_SUPPORTED
png_free_ptr free_fn = NULL; png_free_ptr free_fn;
png_voidp mem_ptr = NULL; png_voidp mem_ptr;
#endif #endif
png_debug(1, "in png_destroy_read_struct\n"); png_debug(1, "in png_destroy_read_struct\n");
@@ -1249,7 +1268,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr
* being used again. * being used again.
*/ */
#ifdef PNG_SETJMP_SUPPORTED #ifdef PNG_SETJMP_SUPPORTED
png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf)); png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
#endif #endif
error_fn = png_ptr->error_fn; error_fn = png_ptr->error_fn;
@@ -1259,7 +1278,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr
free_fn = png_ptr->free_fn; free_fn = png_ptr->free_fn;
#endif #endif
png_memset(png_ptr, 0, sizeof (png_struct)); png_memset(png_ptr, 0, png_sizeof (png_struct));
png_ptr->error_fn = error_fn; png_ptr->error_fn = error_fn;
png_ptr->warning_fn = warning_fn; png_ptr->warning_fn = warning_fn;
@@ -1269,7 +1288,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr
#endif #endif
#ifdef PNG_SETJMP_SUPPORTED #ifdef PNG_SETJMP_SUPPORTED
png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf)); png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
#endif #endif
} }
@@ -1280,6 +1299,8 @@ png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
png_ptr->read_row_fn = read_row_fn; png_ptr->read_row_fn = read_row_fn;
} }
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
#if defined(PNG_INFO_IMAGE_SUPPORTED) #if defined(PNG_INFO_IMAGE_SUPPORTED)
void PNGAPI void PNGAPI
png_read_png(png_structp png_ptr, png_infop info_ptr, png_read_png(png_structp png_ptr, png_infop info_ptr,
@@ -1289,34 +1310,38 @@ png_read_png(png_structp png_ptr, png_infop info_ptr,
int row; int row;
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
/* invert the alpha channel from opacity to transparency */ /* invert the alpha channel from opacity to transparency
*/
if (transforms & PNG_TRANSFORM_INVERT_ALPHA) if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
png_set_invert_alpha(png_ptr); png_set_invert_alpha(png_ptr);
#endif #endif
/* The call to png_read_info() gives us all of the information from the /* png_read_info() gives us all of the information from the
* PNG file before the first IDAT (image data chunk). * PNG file before the first IDAT (image data chunk).
*/ */
png_read_info(png_ptr, info_ptr); png_read_info(png_ptr, info_ptr);
if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
png_error(png_ptr,"Image is too high to process with png_read_png()");
/* -------------- image transformations start here ------------------- */ /* -------------- image transformations start here ------------------- */
#if defined(PNG_READ_16_TO_8_SUPPORTED) #if defined(PNG_READ_16_TO_8_SUPPORTED)
/* tell libpng to strip 16 bit/color files down to 8 bits/color */ /* tell libpng to strip 16 bit/color files down to 8 bits per color
*/
if (transforms & PNG_TRANSFORM_STRIP_16) if (transforms & PNG_TRANSFORM_STRIP_16)
png_set_strip_16(png_ptr); png_set_strip_16(png_ptr);
#endif #endif
#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
/* Strip alpha bytes from the input data without combining with the /* Strip alpha bytes from the input data without combining with
* background (not recommended). * the background (not recommended).
*/ */
if (transforms & PNG_TRANSFORM_STRIP_ALPHA) if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
png_set_strip_alpha(png_ptr); png_set_strip_alpha(png_ptr);
#endif #endif
#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED) #if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
/* Extract multiple pixels with bit depths of 1, 2, and 4 from a single /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
* byte into separate bytes (useful for paletted and grayscale images). * byte into separate bytes (useful for paletted and grayscale images).
*/ */
if (transforms & PNG_TRANSFORM_PACKING) if (transforms & PNG_TRANSFORM_PACKING)
@@ -1325,7 +1350,8 @@ png_read_png(png_structp png_ptr, png_infop info_ptr,
#if defined(PNG_READ_PACKSWAP_SUPPORTED) #if defined(PNG_READ_PACKSWAP_SUPPORTED)
/* Change the order of packed pixels to least significant bit first /* Change the order of packed pixels to least significant bit first
* (not useful if you are using png_set_packing). */ * (not useful if you are using png_set_packing).
*/
if (transforms & PNG_TRANSFORM_PACKSWAP) if (transforms & PNG_TRANSFORM_PACKSWAP)
png_set_packswap(png_ptr); png_set_packswap(png_ptr);
#endif #endif
@@ -1343,10 +1369,12 @@ png_read_png(png_structp png_ptr, png_infop info_ptr,
png_set_expand(png_ptr); png_set_expand(png_ptr);
#endif #endif
/* We don't handle background color or gamma transformation or dithering. */ /* We don't handle background color or gamma transformation or dithering.
*/
#if defined(PNG_READ_INVERT_SUPPORTED) #if defined(PNG_READ_INVERT_SUPPORTED)
/* invert monochrome files to have 0 as white and 1 as black */ /* invert monochrome files to have 0 as white and 1 as black
*/
if (transforms & PNG_TRANSFORM_INVERT_MONO) if (transforms & PNG_TRANSFORM_INVERT_MONO)
png_set_invert_mono(png_ptr); png_set_invert_mono(png_ptr);
#endif #endif
@@ -1367,19 +1395,22 @@ png_read_png(png_structp png_ptr, png_infop info_ptr,
#endif #endif
#if defined(PNG_READ_BGR_SUPPORTED) #if defined(PNG_READ_BGR_SUPPORTED)
/* flip the RGB pixels to BGR (or RGBA to BGRA) */ /* flip the RGB pixels to BGR (or RGBA to BGRA)
*/
if (transforms & PNG_TRANSFORM_BGR) if (transforms & PNG_TRANSFORM_BGR)
png_set_bgr(png_ptr); png_set_bgr(png_ptr);
#endif #endif
#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
/* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR)
*/
if (transforms & PNG_TRANSFORM_SWAP_ALPHA) if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
png_set_swap_alpha(png_ptr); png_set_swap_alpha(png_ptr);
#endif #endif
#if defined(PNG_READ_SWAP_SUPPORTED) #if defined(PNG_READ_SWAP_SUPPORTED)
/* swap bytes of 16 bit files to least significant byte first */ /* swap bytes of 16 bit files to least significant byte first
*/
if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
png_set_swap(png_ptr); png_set_swap(png_ptr);
#endif #endif
@@ -1400,7 +1431,7 @@ png_read_png(png_structp png_ptr, png_infop info_ptr,
if(info_ptr->row_pointers == NULL) if(info_ptr->row_pointers == NULL)
{ {
info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr, info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
info_ptr->height * sizeof(png_bytep)); info_ptr->height * png_sizeof(png_bytep));
#ifdef PNG_FREE_ME_SUPPORTED #ifdef PNG_FREE_ME_SUPPORTED
info_ptr->free_me |= PNG_FREE_ROWS; info_ptr->free_me |= PNG_FREE_ROWS;
#endif #endif
@@ -1422,3 +1453,4 @@ png_read_png(png_structp png_ptr, png_infop info_ptr,
} }
#endif #endif
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */

View File

@@ -1,9 +1,9 @@
/* pngrio.c - functions for data input /* pngrio.c - functions for data input
* *
* libpng 1.2.4 - July 8, 2002 * libpng 1.2.8 - December 3, 2004
* For conditions of distribution and use, see copyright notice in png.h * For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2002 Glenn Randers-Pehrson * Copyright (c) 1998-2004 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *

View File

@@ -1,9 +1,9 @@
/* pngrtran.c - transforms the data in a row for PNG readers /* pngrtran.c - transforms the data in a row for PNG readers
* *
* libpng 1.2.4 - July 8, 2002 * libpng version 1.2.8 - December 3, 2004
* For conditions of distribution and use, see copyright notice in png.h * For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2002 Glenn Randers-Pehrson * Copyright (c) 1998-2004 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
@@ -85,7 +85,8 @@ png_set_background(png_structp png_ptr,
} }
png_ptr->transformations |= PNG_BACKGROUND; png_ptr->transformations |= PNG_BACKGROUND;
png_memcpy(&(png_ptr->background), background_color, sizeof(png_color_16)); png_memcpy(&(png_ptr->background), background_color,
png_sizeof(png_color_16));
png_ptr->background_gamma = (float)background_gamma; png_ptr->background_gamma = (float)background_gamma;
png_ptr->background_gamma_type = (png_byte)(background_gamma_code); png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0); png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
@@ -118,7 +119,7 @@ void PNGAPI
png_set_strip_alpha(png_structp png_ptr) png_set_strip_alpha(png_structp png_ptr)
{ {
png_debug(1, "in png_set_strip_alpha\n"); png_debug(1, "in png_set_strip_alpha\n");
png_ptr->transformations |= PNG_STRIP_ALPHA; png_ptr->flags |= PNG_FLAG_STRIP_ALPHA;
} }
#endif #endif
@@ -154,7 +155,7 @@ png_set_dither(png_structp png_ptr, png_colorp palette,
int i; int i;
png_ptr->dither_index = (png_bytep)png_malloc(png_ptr, png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
(png_uint_32)(num_palette * sizeof (png_byte))); (png_uint_32)(num_palette * png_sizeof (png_byte)));
for (i = 0; i < num_palette; i++) for (i = 0; i < num_palette; i++)
png_ptr->dither_index[i] = (png_byte)i; png_ptr->dither_index[i] = (png_byte)i;
} }
@@ -170,7 +171,7 @@ png_set_dither(png_structp png_ptr, png_colorp palette,
/* initialize an array to sort colors */ /* initialize an array to sort colors */
png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr, png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr,
(png_uint_32)(num_palette * sizeof (png_byte))); (png_uint_32)(num_palette * png_sizeof (png_byte)));
/* initialize the dither_sort array */ /* initialize the dither_sort array */
for (i = 0; i < num_palette; i++) for (i = 0; i < num_palette; i++)
@@ -299,9 +300,9 @@ png_set_dither(png_structp png_ptr, png_colorp palette,
/* initialize palette index arrays */ /* initialize palette index arrays */
png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
(png_uint_32)(num_palette * sizeof (png_byte))); (png_uint_32)(num_palette * png_sizeof (png_byte)));
png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
(png_uint_32)(num_palette * sizeof (png_byte))); (png_uint_32)(num_palette * png_sizeof (png_byte)));
/* initialize the sort array */ /* initialize the sort array */
for (i = 0; i < num_palette; i++) for (i = 0; i < num_palette; i++)
@@ -311,10 +312,10 @@ png_set_dither(png_structp png_ptr, png_colorp palette,
} }
hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 * hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 *
sizeof (png_dsortp))); png_sizeof (png_dsortp)));
for (i = 0; i < 769; i++) for (i = 0; i < 769; i++)
hash[i] = NULL; hash[i] = NULL;
/* png_memset(hash, 0, 769 * sizeof (png_dsortp)); */ /* png_memset(hash, 0, 769 * png_sizeof (png_dsortp)); */
num_new_palette = num_palette; num_new_palette = num_palette;
@@ -344,7 +345,7 @@ png_set_dither(png_structp png_ptr, png_colorp palette,
{ {
t = (png_dsortp)png_malloc_warn(png_ptr, t = (png_dsortp)png_malloc_warn(png_ptr,
(png_uint_32)(sizeof(png_dsort))); (png_uint_32)(png_sizeof(png_dsort)));
if (t == NULL) if (t == NULL)
break; break;
t->next = hash[d]; t->next = hash[d];
@@ -462,14 +463,15 @@ png_set_dither(png_structp png_ptr, png_colorp palette,
png_size_t num_entries = ((png_size_t)1 << total_bits); png_size_t num_entries = ((png_size_t)1 << total_bits);
png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr, png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr,
(png_uint_32)(num_entries * sizeof (png_byte))); (png_uint_32)(num_entries * png_sizeof (png_byte)));
png_memset(png_ptr->palette_lookup, 0, num_entries * sizeof (png_byte)); png_memset(png_ptr->palette_lookup, 0, num_entries *
png_sizeof (png_byte));
distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
sizeof(png_byte))); png_sizeof(png_byte)));
png_memset(distance, 0xff, num_entries * sizeof(png_byte)); png_memset(distance, 0xff, num_entries * png_sizeof(png_byte));
for (i = 0; i < num_palette; i++) for (i = 0; i < num_palette; i++)
{ {
@@ -480,12 +482,14 @@ png_set_dither(png_structp png_ptr, png_colorp palette,
for (ir = 0; ir < num_red; ir++) for (ir = 0; ir < num_red; ir++)
{ {
int dr = abs(ir - r); /* int dr = abs(ir - r); */
int dr = ((ir > r) ? ir - r : r - ir);
int index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS)); int index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS));
for (ig = 0; ig < num_green; ig++) for (ig = 0; ig < num_green; ig++)
{ {
int dg = abs(ig - g); /* int dg = abs(ig - g); */
int dg = ((ig > g) ? ig - g : g - ig);
int dt = dr + dg; int dt = dr + dg;
int dm = ((dr > dg) ? dr : dg); int dm = ((dr > dg) ? dr : dg);
int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS); int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
@@ -493,7 +497,8 @@ png_set_dither(png_structp png_ptr, png_colorp palette,
for (ib = 0; ib < num_blue; ib++) for (ib = 0; ib < num_blue; ib++)
{ {
int d_index = index_g | ib; int d_index = index_g | ib;
int db = abs(ib - b); /* int db = abs(ib - b); */
int db = ((ib > b) ? ib - b : b - ib);
int dmax = ((dm > db) ? dm : db); int dmax = ((dm > db) ? dm : db);
int d = dmax + dt + db; int d = dmax + dt + db;
@@ -1116,7 +1121,7 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
info_ptr->channels = 1; info_ptr->channels = 1;
#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
if (png_ptr->transformations & PNG_STRIP_ALPHA) if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
#endif #endif
@@ -1130,7 +1135,9 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
(info_ptr->color_type == PNG_COLOR_TYPE_GRAY))) (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
{ {
info_ptr->channels++; info_ptr->channels++;
#if 0 /* if adding a true alpha channel not just filler */ /* if adding a true alpha channel not just filler */
#if !defined(PNG_1_0_X)
if (png_ptr->transformations & PNG_ADD_ALPHA)
info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
#endif #endif
} }
@@ -1149,7 +1156,8 @@ defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
info_ptr->bit_depth); info_ptr->bit_depth);
info_ptr->rowbytes = ((info_ptr->width * info_ptr->pixel_depth + 7) >> 3);
info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,info_ptr->width);
#if !defined(PNG_READ_EXPAND_SUPPORTED) #if !defined(PNG_READ_EXPAND_SUPPORTED)
if(png_ptr) if(png_ptr)
@@ -1201,9 +1209,9 @@ png_do_read_transformations(png_structp png_ptr)
#endif #endif
#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
if (png_ptr->transformations & PNG_STRIP_ALPHA) if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
PNG_FLAG_FILLER_AFTER); PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA));
#endif #endif
#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
@@ -1380,8 +1388,8 @@ From Andreas Dilger e-mail to png-implement, 26 March 1998:
#endif #endif
png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.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.channels);
png_ptr->row_info.rowbytes = (png_ptr->row_info.width * png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
png_ptr->row_info.pixel_depth+7)>>3; png_ptr->row_info.width);
} }
#endif #endif
@@ -1889,8 +1897,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
/* This changes the data from GG to GGXX */ /* This changes the data from GG to GGXX */
if (flags & PNG_FLAG_FILLER_AFTER) if (flags & PNG_FLAG_FILLER_AFTER)
{ {
png_bytep sp = row + (png_size_t)row_width; png_bytep sp = row + (png_size_t)row_width * 2;
png_bytep dp = sp + (png_size_t)row_width; png_bytep dp = sp + (png_size_t)row_width * 2;
for (i = 1; i < row_width; i++) for (i = 1; i < row_width; i++)
{ {
*(--dp) = hi_filler; *(--dp) = hi_filler;
@@ -1907,8 +1915,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
/* This changes the data from GG to XXGG */ /* This changes the data from GG to XXGG */
else else
{ {
png_bytep sp = row + (png_size_t)row_width; png_bytep sp = row + (png_size_t)row_width * 2;
png_bytep dp = sp + (png_size_t)row_width; png_bytep dp = sp + (png_size_t)row_width * 2;
for (i = 0; i < row_width; i++) for (i = 0; i < row_width; i++)
{ {
*(--dp) = *(--sp); *(--dp) = *(--sp);
@@ -1965,8 +1973,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
/* This changes the data from RRGGBB to RRGGBBXX */ /* This changes the data from RRGGBB to RRGGBBXX */
if (flags & PNG_FLAG_FILLER_AFTER) if (flags & PNG_FLAG_FILLER_AFTER)
{ {
png_bytep sp = row + (png_size_t)row_width * 3; png_bytep sp = row + (png_size_t)row_width * 6;
png_bytep dp = sp + (png_size_t)row_width; png_bytep dp = sp + (png_size_t)row_width * 2;
for (i = 1; i < row_width; i++) for (i = 1; i < row_width; i++)
{ {
*(--dp) = hi_filler; *(--dp) = hi_filler;
@@ -1987,8 +1995,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
/* This changes the data from RRGGBB to XXRRGGBB */ /* This changes the data from RRGGBB to XXRRGGBB */
else else
{ {
png_bytep sp = row + (png_size_t)row_width * 3; png_bytep sp = row + (png_size_t)row_width * 6;
png_bytep dp = sp + (png_size_t)row_width; png_bytep dp = sp + (png_size_t)row_width * 2;
for (i = 0; i < row_width; i++) for (i = 0; i < row_width; i++)
{ {
*(--dp) = *(--sp); *(--dp) = *(--sp);
@@ -2087,8 +2095,7 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
row_info->color_type |= PNG_COLOR_MASK_COLOR; row_info->color_type |= PNG_COLOR_MASK_COLOR;
row_info->pixel_depth = (png_byte)(row_info->channels * row_info->pixel_depth = (png_byte)(row_info->channels *
row_info->bit_depth); row_info->bit_depth);
row_info->rowbytes = ((row_width * row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
row_info->pixel_depth + 7) >> 3);
} }
} }
#endif #endif
@@ -2097,7 +2104,7 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
/* reduce RGB files to grayscale, with or without alpha /* reduce RGB files to grayscale, with or without alpha
* using the equation given in Poynton's ColorFAQ at * using the equation given in Poynton's ColorFAQ at
* <http://www.inforamp.net/~poynton/> * <http://www.inforamp.net/~poynton/>
* Copyright (c) 1998-01-04 Charles Poynton poynton@inforamp.net * Copyright (c) 1998-01-04 Charles Poynton poynton at inforamp.net
* *
* Y = 0.212671 * R + 0.715160 * G + 0.072169 * B * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
* *
@@ -2271,7 +2278,7 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
png_byte blue = *(sp++); png_byte blue = *(sp++);
if(red != green || red != blue) if(red != green || red != blue)
rgb_error |= 1; rgb_error |= 1;
*(dp++) = (png_byte)((gc*red + gc*green + bc*blue)>>8); *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
*(dp++) = *(sp++); /* alpha */ *(dp++) = *(sp++); /* alpha */
} }
} }
@@ -2341,8 +2348,7 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
row_info->color_type &= ~PNG_COLOR_MASK_COLOR; row_info->color_type &= ~PNG_COLOR_MASK_COLOR;
row_info->pixel_depth = (png_byte)(row_info->channels * row_info->pixel_depth = (png_byte)(row_info->channels *
row_info->bit_depth); row_info->bit_depth);
row_info->rowbytes = ((row_width * row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
row_info->pixel_depth + 7) >> 3);
} }
return rgb_error; return rgb_error;
} }
@@ -3260,8 +3266,7 @@ png_do_background(png_row_infop row_info, png_bytep row,
row_info->channels--; row_info->channels--;
row_info->pixel_depth = (png_byte)(row_info->channels * row_info->pixel_depth = (png_byte)(row_info->channels *
row_info->bit_depth); row_info->bit_depth);
row_info->rowbytes = ((row_width * row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
row_info->pixel_depth + 7) >> 3);
} }
} }
} }
@@ -3735,8 +3740,8 @@ png_do_expand(png_row_infop row_info, png_bytep row,
row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA; row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
row_info->channels = 2; row_info->channels = 2;
row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1); row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
row_info->rowbytes = row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
((row_width * row_info->pixel_depth) >> 3); row_width);
} }
} }
else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value) else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
@@ -3790,8 +3795,7 @@ png_do_expand(png_row_infop row_info, png_bytep row,
row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA; row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
row_info->channels = 4; row_info->channels = 4;
row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2); row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
row_info->rowbytes = row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
((row_width * row_info->pixel_depth) >> 3);
} }
} }
} }
@@ -3844,8 +3848,7 @@ png_do_dither(png_row_infop row_info, png_bytep row,
row_info->color_type = PNG_COLOR_TYPE_PALETTE; row_info->color_type = PNG_COLOR_TYPE_PALETTE;
row_info->channels = 1; row_info->channels = 1;
row_info->pixel_depth = row_info->bit_depth; row_info->pixel_depth = row_info->bit_depth;
row_info->rowbytes = row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
((row_width * row_info->pixel_depth + 7) >> 3);
} }
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA && else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
palette_lookup != NULL && row_info->bit_depth == 8) palette_lookup != NULL && row_info->bit_depth == 8)
@@ -3874,8 +3877,7 @@ png_do_dither(png_row_infop row_info, png_bytep row,
row_info->color_type = PNG_COLOR_TYPE_PALETTE; row_info->color_type = PNG_COLOR_TYPE_PALETTE;
row_info->channels = 1; row_info->channels = 1;
row_info->pixel_depth = row_info->bit_depth; row_info->pixel_depth = row_info->bit_depth;
row_info->rowbytes = row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
((row_width * row_info->pixel_depth + 7) >> 3);
} }
else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
dither_lookup && row_info->bit_depth == 8) dither_lookup && row_info->bit_depth == 8)
@@ -4005,7 +4007,7 @@ png_build_gamma_table(png_structp png_ptr)
g = 1.0; g = 1.0;
png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr, png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr,
(png_uint_32)(num * sizeof (png_uint_16p))); (png_uint_32)(num * png_sizeof (png_uint_16p)));
if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND)) if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND))
{ {
@@ -4015,7 +4017,7 @@ png_build_gamma_table(png_structp png_ptr)
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
{ {
png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr, png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
(png_uint_32)(256 * sizeof (png_uint_16))); (png_uint_32)(256 * png_sizeof (png_uint_16)));
} }
g = 1.0 / g; g = 1.0 / g;
@@ -4045,7 +4047,7 @@ png_build_gamma_table(png_structp png_ptr)
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
{ {
png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr, png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
(png_uint_32)(256 * sizeof (png_uint_16))); (png_uint_32)(256 * png_sizeof (png_uint_16)));
ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4); ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4);
for (j = 0; j < 256; j++) for (j = 0; j < 256; j++)
@@ -4065,12 +4067,12 @@ png_build_gamma_table(png_structp png_ptr)
g = 1.0 / (png_ptr->gamma); g = 1.0 / (png_ptr->gamma);
png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr, png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr,
(png_uint_32)(num * sizeof (png_uint_16p ))); (png_uint_32)(num * png_sizeof (png_uint_16p )));
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
{ {
png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr, png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
(png_uint_32)(256 * sizeof (png_uint_16))); (png_uint_32)(256 * png_sizeof (png_uint_16)));
ig = (((png_uint_32)i * ig = (((png_uint_32)i *
(png_uint_32)png_gamma_shift[shift]) >> 4); (png_uint_32)png_gamma_shift[shift]) >> 4);
@@ -4088,12 +4090,12 @@ png_build_gamma_table(png_structp png_ptr)
g = png_ptr->gamma; /* probably doing rgb_to_gray */ g = png_ptr->gamma; /* probably doing rgb_to_gray */
png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr, png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr,
(png_uint_32)(num * sizeof (png_uint_16p))); (png_uint_32)(num * png_sizeof (png_uint_16p)));
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
{ {
png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr, png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
(png_uint_32)(256 * sizeof (png_uint_16))); (png_uint_32)(256 * png_sizeof (png_uint_16)));
ig = (((png_uint_32)i * ig = (((png_uint_32)i *
(png_uint_32)png_gamma_shift[shift]) >> 4); (png_uint_32)png_gamma_shift[shift]) >> 4);
@@ -4159,11 +4161,11 @@ png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
{ {
png_uint_32 s0=*(rp )<<8 | *(rp+1); png_uint_32 s0 = (*(rp ) << 8) | *(rp+1);
png_uint_32 s1=*(rp+2)<<8 | *(rp+3); png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3);
png_uint_32 s2=*(rp+4)<<8 | *(rp+5); png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5);
png_uint_32 red=(65536+s0+s1)&0xffff; png_uint_32 red = (png_uint_32)((s0+s1+65536L) & 0xffffL);
png_uint_32 blue=(65536+s2+s1)&0xffff; png_uint_32 blue = (png_uint_32)((s2+s1+65536L) & 0xffffL);
*(rp ) = (png_byte)((red >> 8) & 0xff); *(rp ) = (png_byte)((red >> 8) & 0xff);
*(rp+1) = (png_byte)(red & 0xff); *(rp+1) = (png_byte)(red & 0xff);
*(rp+4) = (png_byte)((blue >> 8) & 0xff); *(rp+4) = (png_byte)((blue >> 8) & 0xff);

View File

@@ -1,9 +1,8 @@
/* pngrutil.c - utilities to read a PNG file /* pngrutil.c - utilities to read a PNG file
* *
* libpng 1.2.4 - July 8, 2002 * libpng version 1.2.8 - December 3, 2004
* For conditions of distribution and use, see copyright notice in png.h * For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2002 Glenn Randers-Pehrson * Copyright (c) 1998-2004 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
@@ -38,6 +37,14 @@ __inline double strtod(const char *nptr, char **endptr)
# endif # endif
#endif #endif
png_uint_32 /* PRIVATE */
png_get_uint_31(png_structp png_ptr, png_bytep buf)
{
png_uint_32 i = png_get_uint_32(buf);
if (i > PNG_UINT_31_MAX)
png_error(png_ptr, "PNG unsigned integer out of range.\n");
return (i);
}
#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */ /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
png_uint_32 /* PRIVATE */ png_uint_32 /* PRIVATE */
@@ -171,7 +178,7 @@ png_decompress_chunk(png_structp png_ptr, int comp_type,
png_size_t prefix_size, png_size_t *newlength) png_size_t prefix_size, png_size_t *newlength)
{ {
static char msg[] = "Error decoding compressed text"; static char msg[] = "Error decoding compressed text";
png_charp text = NULL; png_charp text;
png_size_t text_size; png_size_t text_size;
if (comp_type == PNG_COMPRESSION_TYPE_BASE) if (comp_type == PNG_COMPRESSION_TYPE_BASE)
@@ -199,7 +206,7 @@ png_decompress_chunk(png_structp png_ptr, int comp_type,
if (text == NULL) if (text == NULL)
{ {
text_size = prefix_size + sizeof(msg) + 1; text_size = prefix_size + png_sizeof(msg) + 1;
text = (png_charp)png_malloc_warn(png_ptr, text_size); text = (png_charp)png_malloc_warn(png_ptr, text_size);
if (text == NULL) if (text == NULL)
{ {
@@ -213,7 +220,8 @@ png_decompress_chunk(png_structp png_ptr, int comp_type,
/* Copy what we can of the error message into the text chunk */ /* Copy what we can of the error message into the text chunk */
text_size = (png_size_t)(chunklength - (text - chunkdata) - 1); text_size = (png_size_t)(chunklength - (text - chunkdata) - 1);
text_size = sizeof(msg) > text_size ? text_size : sizeof(msg); text_size = png_sizeof(msg) > text_size ? text_size :
png_sizeof(msg);
png_memcpy(text + prefix_size, msg, text_size + 1); png_memcpy(text + prefix_size, msg, text_size + 1);
break; break;
} }
@@ -346,15 +354,14 @@ png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
png_crc_read(png_ptr, buf, 13); png_crc_read(png_ptr, buf, 13);
png_crc_finish(png_ptr, 0); png_crc_finish(png_ptr, 0);
width = png_get_uint_32(buf); width = png_get_uint_31(png_ptr, buf);
height = png_get_uint_32(buf + 4); height = png_get_uint_31(png_ptr, buf + 4);
bit_depth = buf[8]; bit_depth = buf[8];
color_type = buf[9]; color_type = buf[9];
compression_type = buf[10]; compression_type = buf[10];
filter_type = buf[11]; filter_type = buf[11];
interlace_type = buf[12]; interlace_type = buf[12];
/* set internal variables */ /* set internal variables */
png_ptr->width = width; png_ptr->width = width;
png_ptr->height = height; png_ptr->height = height;
@@ -364,6 +371,7 @@ png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
#if defined(PNG_MNG_FEATURES_SUPPORTED) #if defined(PNG_MNG_FEATURES_SUPPORTED)
png_ptr->filter_type = (png_byte)filter_type; png_ptr->filter_type = (png_byte)filter_type;
#endif #endif
png_ptr->compression_type = (png_byte)compression_type;
/* find number of channels */ /* find number of channels */
switch (png_ptr->color_type) switch (png_ptr->color_type)
@@ -386,8 +394,7 @@ png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
/* set up other useful info */ /* set up other useful info */
png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
png_ptr->channels); png_ptr->channels);
png_ptr->rowbytes = ((png_ptr->width * png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,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,"bit_depth = %d\n", png_ptr->bit_depth);
png_debug1(3,"channels = %d\n", png_ptr->channels); png_debug1(3,"channels = %d\n", png_ptr->channels);
png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes); png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes);
@@ -542,8 +549,6 @@ png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT)) if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
{ {
png_error(png_ptr, "No image in file"); png_error(png_ptr, "No image in file");
info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */
} }
png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
@@ -553,6 +558,9 @@ png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
png_warning(png_ptr, "Incorrect IEND chunk length"); png_warning(png_ptr, "Incorrect IEND chunk length");
} }
png_crc_finish(png_ptr, length); png_crc_finish(png_ptr, length);
if (&info_ptr == NULL) /* quiet compiler warnings about unused info_ptr */
return;
} }
#if defined(PNG_READ_gAMA_SUPPORTED) #if defined(PNG_READ_gAMA_SUPPORTED)
@@ -579,7 +587,7 @@ png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
/* Should be an error, but we can cope with it */ /* Should be an error, but we can cope with it */
png_warning(png_ptr, "Out of place gAMA chunk"); png_warning(png_ptr, "Out of place gAMA chunk");
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
#if defined(PNG_READ_sRGB_SUPPORTED) #if defined(PNG_READ_sRGB_SUPPORTED)
&& !(info_ptr->valid & PNG_INFO_sRGB) && !(info_ptr->valid & PNG_INFO_sRGB)
#endif #endif
@@ -612,7 +620,7 @@ png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
#if defined(PNG_READ_sRGB_SUPPORTED) #if defined(PNG_READ_sRGB_SUPPORTED)
if (info_ptr->valid & PNG_INFO_sRGB) if (info_ptr->valid & PNG_INFO_sRGB)
if(igamma < 45000L || igamma > 46000L) if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
{ {
png_warning(png_ptr, png_warning(png_ptr,
"Ignoring incorrect gAMA value when sRGB is also present"); "Ignoring incorrect gAMA value when sRGB is also present");
@@ -660,7 +668,7 @@ png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
/* Should be an error, but we can cope with it */ /* Should be an error, but we can cope with it */
png_warning(png_ptr, "Out of place sBIT chunk"); png_warning(png_ptr, "Out of place sBIT chunk");
} }
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)) if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
{ {
png_warning(png_ptr, "Duplicate sBIT chunk"); png_warning(png_ptr, "Duplicate sBIT chunk");
png_crc_finish(png_ptr, length); png_crc_finish(png_ptr, length);
@@ -672,7 +680,7 @@ png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
else else
truelen = (png_size_t)png_ptr->channels; truelen = (png_size_t)png_ptr->channels;
if (length != truelen) if (length != truelen || length > 4)
{ {
png_warning(png_ptr, "Incorrect sBIT chunk length"); png_warning(png_ptr, "Incorrect sBIT chunk length");
png_crc_finish(png_ptr, length); png_crc_finish(png_ptr, length);
@@ -729,7 +737,7 @@ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
/* Should be an error, but we can cope with it */ /* Should be an error, but we can cope with it */
png_warning(png_ptr, "Missing PLTE before cHRM"); png_warning(png_ptr, "Missing PLTE before cHRM");
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM) if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
#if defined(PNG_READ_sRGB_SUPPORTED) #if defined(PNG_READ_sRGB_SUPPORTED)
&& !(info_ptr->valid & PNG_INFO_sRGB) && !(info_ptr->valid & PNG_INFO_sRGB)
#endif #endif
@@ -825,14 +833,14 @@ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
#if defined(PNG_READ_sRGB_SUPPORTED) #if defined(PNG_READ_sRGB_SUPPORTED)
if (info_ptr->valid & PNG_INFO_sRGB) if (info_ptr->valid & PNG_INFO_sRGB)
{ {
if (abs(int_x_white - 31270L) > 1000 || if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) ||
abs(int_y_white - 32900L) > 1000 || PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) ||
abs(int_x_red - 64000L) > 1000 || PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) ||
abs(int_y_red - 33000L) > 1000 || PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) ||
abs(int_x_green - 30000L) > 1000 || PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) ||
abs(int_y_green - 60000L) > 1000 || PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
abs(int_x_blue - 15000L) > 1000 || PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) ||
abs(int_y_blue - 6000L) > 1000) PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000))
{ {
png_warning(png_ptr, png_warning(png_ptr,
@@ -891,7 +899,7 @@ png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
/* Should be an error, but we can cope with it */ /* Should be an error, but we can cope with it */
png_warning(png_ptr, "Out of place sRGB chunk"); png_warning(png_ptr, "Out of place sRGB chunk");
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
{ {
png_warning(png_ptr, "Duplicate sRGB chunk"); png_warning(png_ptr, "Duplicate sRGB chunk");
png_crc_finish(png_ptr, length); png_crc_finish(png_ptr, length);
@@ -920,15 +928,15 @@ png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
if ((info_ptr->valid & PNG_INFO_gAMA)) if ((info_ptr->valid & PNG_INFO_gAMA))
{ {
int igamma; png_fixed_point igamma;
#ifdef PNG_FIXED_POINT_SUPPORTED #ifdef PNG_FIXED_POINT_SUPPORTED
igamma=(int)info_ptr->int_gamma; igamma=info_ptr->int_gamma;
#else #else
# ifdef PNG_FLOATING_POINT_SUPPORTED # ifdef PNG_FLOATING_POINT_SUPPORTED
igamma=(int)(info_ptr->gamma * 100000.); igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
# endif # endif
#endif #endif
if(igamma < 45000L || igamma > 46000L) if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
{ {
png_warning(png_ptr, png_warning(png_ptr,
"Ignoring incorrect gAMA value when sRGB is also present"); "Ignoring incorrect gAMA value when sRGB is also present");
@@ -948,14 +956,14 @@ png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
#ifdef PNG_READ_cHRM_SUPPORTED #ifdef PNG_READ_cHRM_SUPPORTED
#ifdef PNG_FIXED_POINT_SUPPORTED #ifdef PNG_FIXED_POINT_SUPPORTED
if (info_ptr->valid & PNG_INFO_cHRM) if (info_ptr->valid & PNG_INFO_cHRM)
if (abs(info_ptr->int_x_white - 31270L) > 1000 || if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) ||
abs(info_ptr->int_y_white - 32900L) > 1000 || PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) ||
abs(info_ptr->int_x_red - 64000L) > 1000 || PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) ||
abs(info_ptr->int_y_red - 33000L) > 1000 || PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) ||
abs(info_ptr->int_x_green - 30000L) > 1000 || PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) ||
abs(info_ptr->int_y_green - 60000L) > 1000 || PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
abs(info_ptr->int_x_blue - 15000L) > 1000 || PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) ||
abs(info_ptr->int_y_blue - 6000L) > 1000) PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000))
{ {
png_warning(png_ptr, png_warning(png_ptr,
"Ignoring incorrect cHRM value when sRGB is also present"); "Ignoring incorrect cHRM value when sRGB is also present");
@@ -977,8 +985,7 @@ png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
png_bytep pC; png_bytep pC;
png_charp profile; png_charp profile;
png_uint_32 skip = 0; png_uint_32 skip = 0;
png_uint_32 profile_size = 0; png_uint_32 profile_size, profile_length;
png_uint_32 profile_length = 0;
png_size_t slength, prefix_length, data_length; png_size_t slength, prefix_length, data_length;
png_debug(1, "in png_handle_iCCP\n"); png_debug(1, "in png_handle_iCCP\n");
@@ -995,7 +1002,7 @@ png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
/* Should be an error, but we can cope with it */ /* Should be an error, but we can cope with it */
png_warning(png_ptr, "Out of place iCCP chunk"); png_warning(png_ptr, "Out of place iCCP chunk");
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)) if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
{ {
png_warning(png_ptr, "Duplicate iCCP chunk"); png_warning(png_ptr, "Duplicate iCCP chunk");
png_crc_finish(png_ptr, length); png_crc_finish(png_ptr, length);
@@ -1153,9 +1160,20 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
return; return;
} }
new_palette.nentries = data_length / entry_size; new_palette.nentries = (png_uint_32) (data_length / entry_size);
new_palette.entries = (png_sPLT_entryp)png_malloc( if ((png_uint_32) new_palette.nentries > (png_uint_32) (PNG_SIZE_MAX /
png_ptr, new_palette.nentries * sizeof(png_sPLT_entry)); png_sizeof(png_sPLT_entry)))
{
png_warning(png_ptr, "sPLT chunk too long");
return;
}
new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
if (new_palette.entries == NULL)
{
png_warning(png_ptr, "sPLT chunk requires too much memory");
return;
}
#ifndef PNG_NO_POINTER_INDEXING #ifndef PNG_NO_POINTER_INDEXING
for (i = 0; i < new_palette.nentries; i++) for (i = 0; i < new_palette.nentries; i++)
@@ -1234,49 +1252,9 @@ png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
return; return;
} }
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
{ {
if (!(png_ptr->mode & PNG_HAVE_PLTE)) png_byte buf[2];
{
/* Should be an error, but we can cope with it */
png_warning(png_ptr, "Missing PLTE before tRNS");
}
else if (length > (png_uint_32)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_crc_read(png_ptr, readbuf, (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) if (length != 2)
{ {
@@ -1289,6 +1267,45 @@ png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
png_ptr->num_trans = 1; png_ptr->num_trans = 1;
png_ptr->trans_values.gray = png_get_uint_16(buf); png_ptr->trans_values.gray = png_get_uint_16(buf);
} }
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_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");
}
if (length > (png_uint_32)png_ptr->num_palette ||
length > PNG_MAX_PALETTE_LENGTH)
{
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_crc_read(png_ptr, readbuf, (png_size_t)length);
png_ptr->num_trans = (png_uint_16)length;
}
else else
{ {
png_warning(png_ptr, "tRNS chunk not allowed with alpha channel"); png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
@@ -1397,7 +1414,7 @@ png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
void /* PRIVATE */ void /* PRIVATE */
png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{ {
int num, i; unsigned int num, i;
png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
png_debug(1, "in png_handle_hIST\n"); png_debug(1, "in png_handle_hIST\n");
@@ -1423,8 +1440,9 @@ png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
return; return;
} }
num = (int)length / 2 ; num = length / 2 ;
if (num != png_ptr->num_palette) if (num != (unsigned int) png_ptr->num_palette || num >
(unsigned int) PNG_MAX_PALETTE_LENGTH)
{ {
png_warning(png_ptr, "Incorrect hIST chunk length"); png_warning(png_ptr, "Incorrect hIST chunk length");
png_crc_finish(png_ptr, length); png_crc_finish(png_ptr, length);
@@ -1625,7 +1643,7 @@ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
png_debug(3, "Allocating pCAL parameters array\n"); png_debug(3, "Allocating pCAL parameters array\n");
params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams
*sizeof(png_charp))) ; *png_sizeof(png_charp))) ;
if (params == NULL) if (params == NULL)
{ {
png_free(png_ptr, purpose); png_free(png_ptr, purpose);
@@ -1883,7 +1901,8 @@ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
if (text != key + slength) if (text != key + slength)
text++; text++;
text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text)); text_ptr = (png_textp)png_malloc_warn(png_ptr,
(png_uint_32)png_sizeof(png_text));
if (text_ptr == NULL) if (text_ptr == NULL)
{ {
png_warning(png_ptr, "Not enough memory to process text chunk."); png_warning(png_ptr, "Not enough memory to process text chunk.");
@@ -1979,7 +1998,8 @@ png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata, chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata,
(png_size_t)length, prefix_len, &data_len); (png_size_t)length, prefix_len, &data_len);
text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text)); text_ptr = (png_textp)png_malloc_warn(png_ptr,
(png_uint_32)png_sizeof(png_text));
if (text_ptr == NULL) if (text_ptr == NULL)
{ {
png_warning(png_ptr,"Not enough memory to process zTXt chunk."); png_warning(png_ptr,"Not enough memory to process zTXt chunk.");
@@ -2088,7 +2108,8 @@ png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
(size_t)length, prefix_len, &data_len); (size_t)length, prefix_len, &data_len);
else else
data_len=png_strlen(chunkdata + prefix_len); data_len=png_strlen(chunkdata + prefix_len);
text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text)); text_ptr = (png_textp)png_malloc_warn(png_ptr,
(png_uint_32)png_sizeof(png_text));
if (text_ptr == NULL) if (text_ptr == NULL)
{ {
png_warning(png_ptr,"Not enough memory to process iTXt chunk."); png_warning(png_ptr,"Not enough memory to process iTXt chunk.");
@@ -2139,7 +2160,7 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{ {
#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
HANDLE_CHUNK_ALWAYS PNG_HANDLE_CHUNK_ALWAYS
#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
&& png_ptr->read_user_chunk_fn == NULL && png_ptr->read_user_chunk_fn == NULL
#endif #endif
@@ -2173,7 +2194,7 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{ {
if (!(png_ptr->chunk_name[0] & 0x20)) if (!(png_ptr->chunk_name[0] & 0x20))
if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
HANDLE_CHUNK_ALWAYS) PNG_HANDLE_CHUNK_ALWAYS)
{ {
png_free(png_ptr, chunk.data); png_free(png_ptr, chunk.data);
png_chunk_error(png_ptr, "unknown critical chunk"); png_chunk_error(png_ptr, "unknown critical chunk");
@@ -2193,7 +2214,8 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
png_crc_finish(png_ptr, skip); png_crc_finish(png_ptr, skip);
#if !defined(PNG_READ_USER_CHUNKS_SUPPORTED) #if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */ if (&info_ptr == NULL) /* quiet compiler warnings about unused info_ptr */
return;
#endif #endif
} }
@@ -2203,7 +2225,7 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
functions to handle unknown critical chunks after we check that functions to handle unknown critical chunks after we check that
the chunk name itself is valid. */ the chunk name itself is valid. */
#define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97)) #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
void /* PRIVATE */ void /* PRIVATE */
png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name) png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
@@ -2234,8 +2256,7 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask)
if (mask == 0xff) if (mask == 0xff)
{ {
png_memcpy(row, png_ptr->row_buf + 1, png_memcpy(row, png_ptr->row_buf + 1,
(png_size_t)((png_ptr->width * PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
png_ptr->row_info.pixel_depth + 7) >> 3));
} }
else else
{ {
@@ -2650,11 +2671,11 @@ png_do_read_interlace(png_structp png_ptr)
} }
} }
row_info->width = final_width; row_info->width = final_width;
row_info->rowbytes = ((final_width * row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width);
(png_uint_32)row_info->pixel_depth + 7) >> 3);
} }
#if !defined(PNG_READ_PACKSWAP_SUPPORTED) #if !defined(PNG_READ_PACKSWAP_SUPPORTED)
transformations = transformations; /* silence compiler warning */ if (&transformations == NULL) /* silence compiler warning */
return;
#endif #endif
} }
#endif /* !PNG_HAVE_ASSEMBLER_READ_INTERLACE */ #endif /* !PNG_HAVE_ASSEMBLER_READ_INTERLACE */
@@ -2822,8 +2843,9 @@ png_read_finish_row(png_structp png_ptr)
png_pass_inc[png_ptr->pass] - 1 - png_pass_inc[png_ptr->pass] - 1 -
png_pass_start[png_ptr->pass]) / png_pass_start[png_ptr->pass]) /
png_pass_inc[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; png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
png_ptr->iwidth) + 1;
if (!(png_ptr->transformations & PNG_INTERLACE)) if (!(png_ptr->transformations & PNG_INTERLACE))
{ {
@@ -2863,8 +2885,7 @@ png_read_finish_row(png_structp png_ptr)
png_crc_finish(png_ptr, 0); png_crc_finish(png_ptr, 0);
png_read_data(png_ptr, chunk_length, 4); png_read_data(png_ptr, chunk_length, 4);
png_ptr->idat_size = png_get_uint_32(chunk_length); png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
png_reset_crc(png_ptr); png_reset_crc(png_ptr);
png_crc_read(png_ptr, png_ptr->chunk_name, 4); png_crc_read(png_ptr, png_ptr->chunk_name, 4);
if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)) if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
@@ -2883,7 +2904,7 @@ png_read_finish_row(png_structp png_ptr)
{ {
if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in || if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
png_ptr->idat_size) png_ptr->idat_size)
png_error(png_ptr, "Extra compressed data"); png_warning(png_ptr, "Extra compressed data");
png_ptr->mode |= PNG_AFTER_IDAT; png_ptr->mode |= PNG_AFTER_IDAT;
png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
break; break;
@@ -2893,14 +2914,19 @@ png_read_finish_row(png_structp png_ptr)
"Decompression Error"); "Decompression Error");
if (!(png_ptr->zstream.avail_out)) if (!(png_ptr->zstream.avail_out))
png_error(png_ptr, "Extra compressed data"); {
png_warning(png_ptr, "Extra compressed data.");
png_ptr->mode |= PNG_AFTER_IDAT;
png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
break;
}
} }
png_ptr->zstream.avail_out = 0; png_ptr->zstream.avail_out = 0;
} }
if (png_ptr->idat_size || png_ptr->zstream.avail_in) if (png_ptr->idat_size || png_ptr->zstream.avail_in)
png_error(png_ptr, "Extra compression data"); png_warning(png_ptr, "Extra compression data");
inflateReset(&png_ptr->zstream); inflateReset(&png_ptr->zstream);
@@ -2945,8 +2971,8 @@ png_read_start_row(png_structp png_ptr)
png_pass_start[png_ptr->pass]) / png_pass_start[png_ptr->pass]) /
png_pass_inc[png_ptr->pass]; png_pass_inc[png_ptr->pass];
row_bytes = ((png_ptr->iwidth * row_bytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->iwidth) + 1;
(png_uint_32)png_ptr->pixel_depth + 7) >> 3) +1;
png_ptr->irowbytes = (png_size_t)row_bytes; png_ptr->irowbytes = (png_size_t)row_bytes;
if((png_uint_32)png_ptr->irowbytes != row_bytes) if((png_uint_32)png_ptr->irowbytes != row_bytes)
png_error(png_ptr, "Rowbytes overflow in png_read_start_row"); png_error(png_ptr, "Rowbytes overflow in png_read_start_row");
@@ -3064,7 +3090,7 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7)); row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
/* calculate the maximum bytes needed, adding a byte and a pixel /* calculate the maximum bytes needed, adding a byte and a pixel
for safety's sake */ for safety's sake */
row_bytes = ((row_bytes * (png_uint_32)max_pixel_depth + 7) >> 3) + row_bytes = PNG_ROWBYTES(max_pixel_depth,row_bytes) +
1 + ((max_pixel_depth + 7) >> 3); 1 + ((max_pixel_depth + 7) >> 3);
#ifdef PNG_MAX_MALLOC_64K #ifdef PNG_MAX_MALLOC_64K
if (row_bytes > (png_uint_32)65536L) if (row_bytes > (png_uint_32)65536L)
@@ -3080,6 +3106,8 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L) if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
png_error(png_ptr, "This image requires a row greater than 64KB"); png_error(png_ptr, "This image requires a row greater than 64KB");
#endif #endif
if ((png_uint_32)png_ptr->rowbytes > PNG_SIZE_MAX - 1)
png_error(png_ptr, "Row has too many bytes to allocate in memory.");
png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)( png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
png_ptr->rowbytes + 1)); png_ptr->rowbytes + 1));

153
pngset.c
View File

@@ -1,9 +1,9 @@
/* pngset.c - storage of image information into info struct /* pngset.c - storage of image information into info struct
* *
* libpng 1.2.4 - July 8, 2002 * libpng 1.2.8 - December 3, 2004
* For conditions of distribution and use, see copyright notice in png.h * For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2002 Glenn Randers-Pehrson * Copyright (c) 1998-2004 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
@@ -24,7 +24,7 @@ png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background)
if (png_ptr == NULL || info_ptr == NULL) if (png_ptr == NULL || info_ptr == NULL)
return; return;
png_memcpy(&(info_ptr->background), background, sizeof(png_color_16)); png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16));
info_ptr->valid |= PNG_INFO_bKGD; info_ptr->valid |= PNG_INFO_bKGD;
} }
#endif #endif
@@ -100,10 +100,14 @@ png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
"Ignoring attempt to set negative chromaticity value"); "Ignoring attempt to set negative chromaticity value");
return; return;
} }
if (white_x > (double) PNG_MAX_UINT || white_y > (double) PNG_MAX_UINT || if (white_x > (double) PNG_UINT_31_MAX ||
red_x > (double) PNG_MAX_UINT || red_y > (double) PNG_MAX_UINT || white_y > (double) PNG_UINT_31_MAX ||
green_x > (double) PNG_MAX_UINT || green_y > (double) PNG_MAX_UINT || red_x > (double) PNG_UINT_31_MAX ||
blue_x > (double) PNG_MAX_UINT || blue_y > (double) PNG_MAX_UINT) red_y > (double) PNG_UINT_31_MAX ||
green_x > (double) PNG_UINT_31_MAX ||
green_y > (double) PNG_UINT_31_MAX ||
blue_x > (double) PNG_UINT_31_MAX ||
blue_y > (double) PNG_UINT_31_MAX)
{ {
png_warning(png_ptr, png_warning(png_ptr,
"Ignoring attempt to set chromaticity value exceeding 21474.83"); "Ignoring attempt to set chromaticity value exceeding 21474.83");
@@ -169,10 +173,10 @@ png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
if (png_ptr == NULL || info_ptr == NULL) if (png_ptr == NULL || info_ptr == NULL)
return; return;
if (int_gamma > (png_fixed_point) PNG_MAX_UINT) if (int_gamma > (png_fixed_point) PNG_UINT_31_MAX)
{ {
png_warning(png_ptr, "Limiting gamma to 21474.83"); png_warning(png_ptr, "Limiting gamma to 21474.83");
gamma=PNG_MAX_UINT; gamma=PNG_UINT_31_MAX;
} }
else else
{ {
@@ -217,7 +221,7 @@ png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist)
#endif #endif
/* Changed from info->num_palette to 256 in version 1.2.1 */ /* Changed from info->num_palette to 256 in version 1.2.1 */
png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr, png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr,
(png_uint_32)(256 * sizeof (png_uint_16))); (png_uint_32)(256 * png_sizeof (png_uint_16)));
if (png_ptr->hist == NULL) if (png_ptr->hist == NULL)
{ {
png_warning(png_ptr, "Insufficient memory for hIST chunk data."); png_warning(png_ptr, "Insufficient memory for hIST chunk data.");
@@ -243,7 +247,6 @@ png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
int color_type, int interlace_type, int compression_type, int color_type, int interlace_type, int compression_type,
int filter_type) int filter_type)
{ {
int rowbytes_per_pixel;
png_debug1(1, "in %s storage function\n", "IHDR"); png_debug1(1, "in %s storage function\n", "IHDR");
if (png_ptr == NULL || info_ptr == NULL) if (png_ptr == NULL || info_ptr == NULL)
return; return;
@@ -251,8 +254,22 @@ png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
/* check for width and height valid values */ /* check for width and height valid values */
if (width == 0 || height == 0) if (width == 0 || height == 0)
png_error(png_ptr, "Image width or height is zero in IHDR"); png_error(png_ptr, "Image width or height is zero in IHDR");
if (width > PNG_MAX_UINT || height > PNG_MAX_UINT) #ifdef PNG_SET_USER_LIMITS_SUPPORTED
if (width > png_ptr->user_width_max || height > png_ptr->user_height_max)
png_error(png_ptr, "image size exceeds user limits in IHDR");
#else
if (width > PNG_USER_WIDTH_MAX || height > PNG_USER_HEIGHT_MAX)
png_error(png_ptr, "image size exceeds user limits in IHDR");
#endif
if (width > PNG_UINT_31_MAX || height > PNG_UINT_31_MAX)
png_error(png_ptr, "Invalid image size in IHDR"); png_error(png_ptr, "Invalid image size in IHDR");
if ( width > (PNG_UINT_32_MAX
>> 3) /* 8-byte RGBA pixels */
- 64 /* bigrowbuf hack */
- 1 /* filter byte */
- 7*8 /* rounding of width to multiple of 8 pixels */
- 8) /* extra max_pixel_depth pad */
png_warning(png_ptr, "Width is too large for libpng to process pixels");
/* check other values */ /* check other values */
if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
@@ -320,16 +337,16 @@ png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
info_ptr->channels++; info_ptr->channels++;
info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth); info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
/* check for overflow */ /* check for potential overflow */
rowbytes_per_pixel = (info_ptr->pixel_depth + 7) >> 3; if ( width > (PNG_UINT_32_MAX
if ( width > PNG_MAX_UINT/rowbytes_per_pixel - 64) >> 3) /* 8-byte RGBA pixels */
{ - 64 /* bigrowbuf hack */
png_warning(png_ptr, - 1 /* filter byte */
"Width too large to process image data; rowbytes will overflow."); - 7*8 /* rounding of width to multiple of 8 pixels */
- 8) /* extra max_pixel_depth pad */
info_ptr->rowbytes = (png_size_t)0; info_ptr->rowbytes = (png_size_t)0;
}
else else
info_ptr->rowbytes = (info_ptr->width * info_ptr->pixel_depth + 7) >> 3; info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,width);
} }
#if defined(PNG_oFFs_SUPPORTED) #if defined(PNG_oFFs_SUPPORTED)
@@ -388,7 +405,7 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
png_memcpy(info_ptr->pcal_units, units, (png_size_t)length); png_memcpy(info_ptr->pcal_units, units, (png_size_t)length);
info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr, info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr,
(png_uint_32)((nparams + 1) * sizeof(png_charp))); (png_uint_32)((nparams + 1) * png_sizeof(png_charp)));
if (info_ptr->pcal_params == NULL) if (info_ptr->pcal_params == NULL)
{ {
png_warning(png_ptr, "Insufficient memory for pCAL params."); png_warning(png_ptr, "Insufficient memory for pCAL params.");
@@ -449,12 +466,21 @@ png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,
length = png_strlen(swidth) + 1; length = png_strlen(swidth) + 1;
png_debug1(3, "allocating unit for info (%d bytes)\n", length); png_debug1(3, "allocating unit for info (%d bytes)\n", length);
info_ptr->scal_s_width = (png_charp)png_malloc(png_ptr, length); info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, length);
if (info_ptr->scal_s_width == NULL)
{
png_warning(png_ptr, "Memory allocation failed while processing sCAL.");
}
png_memcpy(info_ptr->scal_s_width, swidth, (png_size_t)length); png_memcpy(info_ptr->scal_s_width, swidth, (png_size_t)length);
length = png_strlen(sheight) + 1; length = png_strlen(sheight) + 1;
png_debug1(3, "allocating unit for info (%d bytes)\n", length); png_debug1(3, "allocating unit for info (%d bytes)\n", length);
info_ptr->scal_s_height = (png_charp)png_malloc(png_ptr, length); info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, length);
if (info_ptr->scal_s_height == NULL)
{
png_free (png_ptr, info_ptr->scal_s_width);
png_warning(png_ptr, "Memory allocation failed while processing sCAL.");
}
png_memcpy(info_ptr->scal_s_height, sheight, (png_size_t)length); png_memcpy(info_ptr->scal_s_height, sheight, (png_size_t)length);
info_ptr->valid |= PNG_INFO_sCAL; info_ptr->valid |= PNG_INFO_sCAL;
@@ -499,13 +525,13 @@ png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
#ifdef PNG_FREE_ME_SUPPORTED #ifdef PNG_FREE_ME_SUPPORTED
png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
#endif #endif
/* Changed in libpng-1.2.1 to allocate 256 instead of num_palette entries, /* Changed in libpng-1.2.1 to allocate 256 instead of num_palette entries,
in case of an invalid PNG file that has too-large sample values. */ in case of an invalid PNG file that has too-large sample values. */
png_ptr->palette = (png_colorp)png_zalloc(png_ptr, (uInt)256, png_ptr->palette = (png_colorp)png_malloc(png_ptr,
sizeof (png_color)); 256 * png_sizeof(png_color));
if (png_ptr->palette == NULL) png_memset(png_ptr->palette, 0, 256 * png_sizeof(png_color));
png_error(png_ptr, "Unable to malloc palette"); png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof (png_color));
png_memcpy(png_ptr->palette, palette, num_palette * sizeof (png_color));
info_ptr->palette = png_ptr->palette; info_ptr->palette = png_ptr->palette;
info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette; info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
@@ -527,7 +553,7 @@ png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
if (png_ptr == NULL || info_ptr == NULL) if (png_ptr == NULL || info_ptr == NULL)
return; return;
png_memcpy(&(info_ptr->sig_bit), sig_bit, sizeof (png_color_8)); png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof (png_color_8));
info_ptr->valid |= PNG_INFO_sBIT; info_ptr->valid |= PNG_INFO_sBIT;
} }
#endif #endif
@@ -628,9 +654,20 @@ png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL) if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
return; return;
new_iccp_name = (png_charp)png_malloc(png_ptr, png_strlen(name)+1); new_iccp_name = (png_charp)png_malloc_warn(png_ptr, png_strlen(name)+1);
if (new_iccp_name == NULL)
{
png_warning(png_ptr, "Insufficient memory to process iCCP chunk.");
return;
}
png_strcpy(new_iccp_name, name); png_strcpy(new_iccp_name, name);
new_iccp_profile = (png_charp)png_malloc(png_ptr, proflen); new_iccp_profile = (png_charp)png_malloc_warn(png_ptr, proflen);
if (new_iccp_profile == NULL)
{
png_free (png_ptr, new_iccp_name);
png_warning(png_ptr, "Insufficient memory to process iCCP profile.");
return;
}
png_memcpy(new_iccp_profile, profile, (png_size_t)proflen); png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);
png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0); png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
@@ -685,14 +722,14 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
info_ptr->max_text = info_ptr->num_text + num_text + 8; info_ptr->max_text = info_ptr->num_text + num_text + 8;
old_text = info_ptr->text; old_text = info_ptr->text;
info_ptr->text = (png_textp)png_malloc_warn(png_ptr, info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
(png_uint_32)(info_ptr->max_text * sizeof (png_text))); (png_uint_32)(info_ptr->max_text * png_sizeof (png_text)));
if (info_ptr->text == NULL) if (info_ptr->text == NULL)
{ {
png_free(png_ptr, old_text); png_free(png_ptr, old_text);
return(1); return(1);
} }
png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max * png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
sizeof(png_text))); png_sizeof(png_text)));
png_free(png_ptr, old_text); png_free(png_ptr, old_text);
} }
else else
@@ -700,7 +737,7 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
info_ptr->max_text = num_text + 8; info_ptr->max_text = num_text + 8;
info_ptr->num_text = 0; info_ptr->num_text = 0;
info_ptr->text = (png_textp)png_malloc_warn(png_ptr, info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
(png_uint_32)(info_ptr->max_text * sizeof (png_text))); (png_uint_32)(info_ptr->max_text * png_sizeof (png_text)));
if (info_ptr->text == NULL) if (info_ptr->text == NULL)
return(1); return(1);
#ifdef PNG_FREE_ME_SUPPORTED #ifdef PNG_FREE_ME_SUPPORTED
@@ -829,7 +866,7 @@ png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time)
(png_ptr->mode & PNG_WROTE_tIME)) (png_ptr->mode & PNG_WROTE_tIME))
return; return;
png_memcpy(&(info_ptr->mod_time), mod_time, sizeof (png_time)); png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof (png_time));
info_ptr->valid |= PNG_INFO_tIME; info_ptr->valid |= PNG_INFO_tIME;
} }
#endif #endif
@@ -867,7 +904,7 @@ png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
if (trans_values != NULL) if (trans_values != NULL)
{ {
png_memcpy(&(info_ptr->trans_values), trans_values, png_memcpy(&(info_ptr->trans_values), trans_values,
sizeof(png_color_16)); png_sizeof(png_color_16));
if (num_trans == 0) if (num_trans == 0)
num_trans = 1; num_trans = 1;
} }
@@ -885,7 +922,7 @@ png_set_sPLT(png_structp png_ptr,
int i; int i;
np = (png_sPLT_tp)png_malloc_warn(png_ptr, np = (png_sPLT_tp)png_malloc_warn(png_ptr,
(info_ptr->splt_palettes_num + nentries) * sizeof(png_sPLT_t)); (info_ptr->splt_palettes_num + nentries) * png_sizeof(png_sPLT_t));
if (np == NULL) if (np == NULL)
{ {
png_warning(png_ptr, "No memory for sPLT palettes."); png_warning(png_ptr, "No memory for sPLT palettes.");
@@ -893,7 +930,7 @@ png_set_sPLT(png_structp png_ptr,
} }
png_memcpy(np, info_ptr->splt_palettes, png_memcpy(np, info_ptr->splt_palettes,
info_ptr->splt_palettes_num * sizeof(png_sPLT_t)); info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t));
png_free(png_ptr, info_ptr->splt_palettes); png_free(png_ptr, info_ptr->splt_palettes);
info_ptr->splt_palettes=NULL; info_ptr->splt_palettes=NULL;
@@ -904,11 +941,13 @@ png_set_sPLT(png_structp png_ptr,
to->name = (png_charp)png_malloc(png_ptr, to->name = (png_charp)png_malloc(png_ptr,
png_strlen(from->name) + 1); png_strlen(from->name) + 1);
/* TODO: use png_malloc_warn */
png_strcpy(to->name, from->name); png_strcpy(to->name, from->name);
to->entries = (png_sPLT_entryp)png_malloc(png_ptr, to->entries = (png_sPLT_entryp)png_malloc(png_ptr,
from->nentries * sizeof(png_sPLT_t)); from->nentries * png_sizeof(png_sPLT_t));
/* TODO: use png_malloc_warn */
png_memcpy(to->entries, from->entries, png_memcpy(to->entries, from->entries,
from->nentries * sizeof(png_sPLT_t)); from->nentries * png_sizeof(png_sPLT_t));
to->nentries = from->nentries; to->nentries = from->nentries;
to->depth = from->depth; to->depth = from->depth;
} }
@@ -935,7 +974,7 @@ png_set_unknown_chunks(png_structp png_ptr,
np = (png_unknown_chunkp)png_malloc_warn(png_ptr, np = (png_unknown_chunkp)png_malloc_warn(png_ptr,
(info_ptr->unknown_chunks_num + num_unknowns) * (info_ptr->unknown_chunks_num + num_unknowns) *
sizeof(png_unknown_chunk)); png_sizeof(png_unknown_chunk));
if (np == NULL) if (np == NULL)
{ {
png_warning(png_ptr, "Out of memory while processing unknown chunk."); png_warning(png_ptr, "Out of memory while processing unknown chunk.");
@@ -943,7 +982,7 @@ png_set_unknown_chunks(png_structp png_ptr,
} }
png_memcpy(np, info_ptr->unknown_chunks, png_memcpy(np, info_ptr->unknown_chunks,
info_ptr->unknown_chunks_num * sizeof(png_unknown_chunk)); info_ptr->unknown_chunks_num * png_sizeof(png_unknown_chunk));
png_free(png_ptr, info_ptr->unknown_chunks); png_free(png_ptr, info_ptr->unknown_chunks);
info_ptr->unknown_chunks=NULL; info_ptr->unknown_chunks=NULL;
@@ -952,10 +991,12 @@ png_set_unknown_chunks(png_structp png_ptr,
png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i; png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;
png_unknown_chunkp from = unknowns + i; png_unknown_chunkp from = unknowns + i;
png_strcpy((png_charp)to->name, (png_charp)from->name); png_strncpy((png_charp)to->name, (png_charp)from->name, 5);
to->data = (png_bytep)png_malloc(png_ptr, from->size); to->data = (png_bytep)png_malloc_warn(png_ptr, from->size);
if (to->data == NULL) if (to->data == NULL)
png_warning(png_ptr, "Out of memory while processing unknown chunk."); {
png_warning(png_ptr, "Out of memory processing unknown chunk.");
}
else else
{ {
png_memcpy(to->data, from->data, from->size); png_memcpy(to->data, from->data, from->size);
@@ -1020,12 +1061,12 @@ png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep
int i, old_num_chunks; int i, old_num_chunks;
if (num_chunks == 0) if (num_chunks == 0)
{ {
if(keep == HANDLE_CHUNK_ALWAYS || keep == HANDLE_CHUNK_IF_SAFE) if(keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE)
png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS; png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
else else
png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS; png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
if(keep == HANDLE_CHUNK_ALWAYS) if(keep == PNG_HANDLE_CHUNK_ALWAYS)
png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS; png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS;
else else
png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS; png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS;
@@ -1083,6 +1124,7 @@ png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
} }
#endif #endif
#ifdef PNG_WRITE_SUPPORTED
void PNGAPI void PNGAPI
png_set_compression_buffer_size(png_structp png_ptr, png_uint_32 size) png_set_compression_buffer_size(png_structp png_ptr, png_uint_32 size)
{ {
@@ -1093,6 +1135,7 @@ png_set_compression_buffer_size(png_structp png_ptr, png_uint_32 size)
png_ptr->zstream.next_out = png_ptr->zbuf; png_ptr->zstream.next_out = png_ptr->zbuf;
png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
} }
#endif
void PNGAPI void PNGAPI
png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask) png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask)
@@ -1157,4 +1200,20 @@ png_set_mmx_thresholds (png_structp png_ptr,
png_ptr->mmx_rowbytes_threshold = mmx_rowbytes_threshold; png_ptr->mmx_rowbytes_threshold = mmx_rowbytes_threshold;
} }
#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */ #endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
/* this function was added to libpng 1.2.6 */
void PNGAPI
png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max,
png_uint_32 user_height_max)
{
/* Images with dimensions larger than these limits will be
* rejected by png_set_IHDR(). To accept any PNG datastream
* regardless of dimensions, set both limits to 0x7ffffffL.
*/
png_ptr->user_width_max = user_width_max;
png_ptr->user_height_max = user_height_max;
}
#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
#endif /* ?PNG_1_0_X */ #endif /* ?PNG_1_0_X */

1554
pngtest.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,9 @@
/* pngtrans.c - transforms the data in a row (used by both readers and writers) /* pngtrans.c - transforms the data in a row (used by both readers and writers)
* *
* libpng 1.2.4 - July 8, 2002 * libpng 1.2.8 - December 3, 2004
* For conditions of distribution and use, see copyright notice in png.h * For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2002 Glenn Randers-Pehrson * Copyright (c) 1998-2004 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*/ */
@@ -100,7 +100,7 @@ png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
else else
png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER; png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
/* This should probably go in the "do_filler" routine. /* This should probably go in the "do_read_filler" routine.
* I attempted to do that in libpng-1.0.1a but that caused problems * I attempted to do that in libpng-1.0.1a but that caused problems
* so I restored it in libpng-1.0.2a * so I restored it in libpng-1.0.2a
*/ */
@@ -118,6 +118,18 @@ png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
png_ptr->usr_channels = 2; png_ptr->usr_channels = 2;
} }
} }
#if !defined(PNG_1_0_X)
/* Added to libpng-1.2.7 */
void PNGAPI
png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
{
png_debug(1, "in png_set_add_alpha\n");
png_set_filler(png_ptr, filler, filler_loc);
png_ptr->transformations |= PNG_ADD_ALPHA;
}
#endif
#endif #endif
#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
@@ -375,16 +387,15 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
if (row != NULL && row_info != NULL) if (row != NULL && row_info != NULL)
#endif #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 sp=row;
png_bytep dp=row; png_bytep dp=row;
png_uint_32 row_width=row_info->width; png_uint_32 row_width=row_info->width;
png_uint_32 i; png_uint_32 i;
if (row_info->channels == 4) if ((row_info->color_type == PNG_COLOR_TYPE_RGB ||
(row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
(flags & PNG_FLAG_STRIP_ALPHA))) &&
row_info->channels == 4)
{ {
if (row_info->bit_depth == 8) if (row_info->bit_depth == 8)
{ {
@@ -461,13 +472,11 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
row_info->rowbytes = row_width * 6; row_info->rowbytes = row_width * 6;
} }
row_info->channels = 3; row_info->channels = 3;
row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
} }
/* else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY ||
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY || (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) (flags & PNG_FLAG_STRIP_ALPHA))) &&
*/ row_info->channels == 2)
else if (row_info->channels == 2)
{ {
if (row_info->bit_depth == 8) if (row_info->bit_depth == 8)
{ {
@@ -519,8 +528,9 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
row_info->rowbytes = row_width * 2; row_info->rowbytes = row_width * 2;
} }
row_info->channels = 1; row_info->channels = 1;
row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
} }
if (flags & PNG_FLAG_STRIP_ALPHA)
row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
} }
} }
#endif #endif

View File

@@ -2,9 +2,9 @@
* *
* For Intel x86 CPU and Microsoft Visual C++ compiler * For Intel x86 CPU and Microsoft Visual C++ compiler
* *
* libpng version 1.2.4 - July 8, 2002 * libpng version 1.2.8 - December 3, 2004
* For conditions of distribution and use, see copyright notice in png.h * For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2002 Glenn Randers-Pehrson * Copyright (c) 1998-2004 Glenn Randers-Pehrson
* Copyright (c) 1998, Intel Corporation * Copyright (c) 1998, Intel Corporation
* *
* Contributed by Nirav Chhatrapati, Intel Corporation, 1998 * Contributed by Nirav Chhatrapati, Intel Corporation, 1998
@@ -115,15 +115,18 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask)
png_debug(1,"in png_combine_row_asm\n"); png_debug(1,"in png_combine_row_asm\n");
if (mmx_supported == 2) { if (mmx_supported == 2) {
#if !defined(PNG_1_0_X)
/* this should have happened in png_init_mmx_flags() already */ /* this should have happened in png_init_mmx_flags() already */
png_warning(png_ptr, "asm_flags may not have been initialized"); png_warning(png_ptr, "asm_flags may not have been initialized");
#endif
png_mmx_support(); png_mmx_support();
} }
if (mask == 0xff) if (mask == 0xff)
{ {
png_memcpy(row, png_ptr->row_buf + 1, png_memcpy(row, png_ptr->row_buf + 1,
(png_size_t)((png_ptr->width * png_ptr->row_info.pixel_depth + 7) >> 3)); (png_size_t)PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
png_ptr->width));
} }
/* GRR: add "else if (mask == 0)" case? /* GRR: add "else if (mask == 0)" case?
* or does png_combine_row() not even get called in that case? */ * or does png_combine_row() not even get called in that case? */
@@ -307,8 +310,12 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask)
__int64 mask0=0x0102040810204080; __int64 mask0=0x0102040810204080;
#if !defined(PNG_1_0_X)
if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
/* && mmx_supported */ ) /* && mmx_supported */ )
#else
if (mmx_supported)
#endif
{ {
srcptr = png_ptr->row_buf + 1; srcptr = png_ptr->row_buf + 1;
dstptr = row; dstptr = row;
@@ -408,8 +415,12 @@ end8:
__int64 mask1=0x0101020204040808, __int64 mask1=0x0101020204040808,
mask0=0x1010202040408080; mask0=0x1010202040408080;
#if !defined(PNG_1_0_X)
if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
/* && mmx_supported */ ) /* && mmx_supported */ )
#else
if (mmx_supported)
#endif
{ {
srcptr = png_ptr->row_buf + 1; srcptr = png_ptr->row_buf + 1;
dstptr = row; dstptr = row;
@@ -529,8 +540,12 @@ end16:
len = (png_ptr->width)&~7; len = (png_ptr->width)&~7;
diff = (png_ptr->width)&7; diff = (png_ptr->width)&7;
#if !defined(PNG_1_0_X)
if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
/* && mmx_supported */ ) /* && mmx_supported */ )
#else
if (mmx_supported)
#endif
{ {
_asm _asm
{ {
@@ -661,8 +676,12 @@ end24:
len = (png_ptr->width)&~7; len = (png_ptr->width)&~7;
diff = (png_ptr->width)&7; diff = (png_ptr->width)&7;
#if !defined(PNG_1_0_X)
if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
/* && mmx_supported */ ) /* && mmx_supported */ )
#else
if (mmx_supported)
#endif
{ {
_asm _asm
{ {
@@ -796,8 +815,12 @@ end32:
mask1=0x2020202040404040, mask1=0x2020202040404040,
mask0=0x4040808080808080; mask0=0x4040808080808080;
#if !defined(PNG_1_0_X)
if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
/* && mmx_supported */ ) /* && mmx_supported */ )
#else
if (mmx_supported)
#endif
{ {
srcptr = png_ptr->row_buf + 1; srcptr = png_ptr->row_buf + 1;
dstptr = row; dstptr = row;
@@ -987,8 +1010,10 @@ png_do_read_interlace(png_structp png_ptr)
png_debug(1,"in png_do_read_interlace\n"); png_debug(1,"in png_do_read_interlace\n");
if (mmx_supported == 2) { if (mmx_supported == 2) {
#if !defined(PNG_1_0_X)
/* this should have happened in png_init_mmx_flags() already */ /* this should have happened in png_init_mmx_flags() already */
png_warning(png_ptr, "asm_flags may not have been initialized"); png_warning(png_ptr, "asm_flags may not have been initialized");
#endif
png_mmx_support(); png_mmx_support();
} }
@@ -1189,8 +1214,12 @@ png_do_read_interlace(png_structp png_ptr)
// NOTE: there is NO MMX code for 48-bit and 64-bit images // NOTE: there is NO MMX code for 48-bit and 64-bit images
// use MMX routine if machine supports it // use MMX routine if machine supports it
#if !defined(PNG_1_0_X)
if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_INTERLACE) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_INTERLACE)
/* && mmx_supported */ ) /* && mmx_supported */ )
#else
if (mmx_supported)
#endif
{ {
if (pixel_bytes == 3) if (pixel_bytes == 3)
{ {
@@ -1874,8 +1903,8 @@ loop4_pass4:
} /* end switch (row_info->pixel_depth) */ } /* end switch (row_info->pixel_depth) */
row_info->width = final_width; row_info->width = final_width;
row_info->rowbytes = ((final_width *
(png_uint_32)row_info->pixel_depth + 7) >> 3); row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width);
} }
} }
@@ -3603,7 +3632,7 @@ duploop:
jz dupend jz dupend
// 2 lines added by lcreeve@netins.net // 2 lines added by lcreeve at netins.net
// (mail 11 Jul 98 in png-implement list) // (mail 11 Jul 98 in png-implement list)
cmp edx, 8 //test for less than 8 bytes cmp edx, 8 //test for less than 8 bytes
jb duplt8 jb duplt8
@@ -3652,8 +3681,10 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep
#endif #endif
if (mmx_supported == 2) { if (mmx_supported == 2) {
#if !defined(PNG_1_0_X)
/* this should have happened in png_init_mmx_flags() already */ /* this should have happened in png_init_mmx_flags() already */
png_warning(png_ptr, "asm_flags may not have been initialized"); png_warning(png_ptr, "asm_flags may not have been initialized");
#endif
png_mmx_support(); png_mmx_support();
} }
@@ -3663,6 +3694,7 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep
{ {
case 0: sprintf(filnm, "none"); case 0: sprintf(filnm, "none");
break; break;
#if !defined(PNG_1_0_X)
case 1: sprintf(filnm, "sub-%s", case 1: sprintf(filnm, "sub-%s",
(png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB)? "MMX" : "x86"); (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB)? "MMX" : "x86");
break; break;
@@ -3675,6 +3707,16 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep
case 4: sprintf(filnm, "Paeth-%s", case 4: sprintf(filnm, "Paeth-%s",
(png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH)? "MMX":"x86"); (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH)? "MMX":"x86");
break; break;
#else
case 1: sprintf(filnm, "sub");
break;
case 2: sprintf(filnm, "up");
break;
case 3: sprintf(filnm, "avg");
break;
case 4: sprintf(filnm, "Paeth");
break;
#endif
default: sprintf(filnm, "unknw"); default: sprintf(filnm, "unknw");
break; break;
} }
@@ -3691,9 +3733,13 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep
case PNG_FILTER_VALUE_SUB: case PNG_FILTER_VALUE_SUB:
{ {
#if !defined(PNG_1_0_X)
if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB) && if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB) &&
(row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
(row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
#else
if (mmx_supported)
#endif
{ {
png_read_filter_row_mmx_sub(row_info, row); png_read_filter_row_mmx_sub(row_info, row);
} }
@@ -3716,9 +3762,13 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep
case PNG_FILTER_VALUE_UP: case PNG_FILTER_VALUE_UP:
{ {
#if !defined(PNG_1_0_X)
if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP) && if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP) &&
(row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
(row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
#else
if (mmx_supported)
#endif
{ {
png_read_filter_row_mmx_up(row_info, row, prev_row); png_read_filter_row_mmx_up(row_info, row, prev_row);
} }
@@ -3740,9 +3790,13 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep
case PNG_FILTER_VALUE_AVG: case PNG_FILTER_VALUE_AVG:
{ {
#if !defined(PNG_1_0_X)
if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG) && if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG) &&
(row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
(row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
#else
if (mmx_supported)
#endif
{ {
png_read_filter_row_mmx_avg(row_info, row, prev_row); png_read_filter_row_mmx_avg(row_info, row, prev_row);
} }
@@ -3774,9 +3828,13 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep
case PNG_FILTER_VALUE_PAETH: case PNG_FILTER_VALUE_PAETH:
{ {
#if !defined(PNG_1_0_X)
if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH) && if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH) &&
(row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
(row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
#else
if (mmx_supported)
#endif
{ {
png_read_filter_row_mmx_paeth(row_info, row, prev_row); png_read_filter_row_mmx_paeth(row_info, row, prev_row);
} }

View File

@@ -1,9 +1,9 @@
/* pngwio.c - functions for data output /* pngwio.c - functions for data output
* *
* libpng 1.2.4 - July 8, 2002 * libpng 1.2.8 - December 3, 2004
* For conditions of distribution and use, see copyright notice in png.h * For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2002 Glenn Randers-Pehrson * Copyright (c) 1998-2004 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *

View File

@@ -1,9 +1,9 @@
/* pngwrite.c - general routines to write a PNG file /* pngwrite.c - general routines to write a PNG file
* *
* libpng 1.2.4 - July 8, 2002 * libpng 1.2.8 - December 3, 2004
* For conditions of distribution and use, see copyright notice in png.h * For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2002 Glenn Randers-Pehrson * Copyright (c) 1998-2004 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*/ */
@@ -104,9 +104,10 @@ png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr)
up++) up++)
{ {
int keep=png_handle_as_unknown(png_ptr, up->name); int keep=png_handle_as_unknown(png_ptr, up->name);
if (keep != HANDLE_CHUNK_NEVER && if (keep != PNG_HANDLE_CHUNK_NEVER &&
up->location && (!(up->location & PNG_HAVE_PLTE)) && up->location && !(up->location & PNG_HAVE_PLTE) &&
((up->name[3] & 0x20) || keep == HANDLE_CHUNK_ALWAYS || !(up->location & PNG_HAVE_IDAT) &&
((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
(png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
{ {
png_write_chunk(png_ptr, up->name, up->data, up->size); png_write_chunk(png_ptr, up->name, up->data, up->size);
@@ -267,10 +268,10 @@ png_write_info(png_structp png_ptr, png_infop info_ptr)
up++) up++)
{ {
int keep=png_handle_as_unknown(png_ptr, up->name); int keep=png_handle_as_unknown(png_ptr, up->name);
if (keep != HANDLE_CHUNK_NEVER && if (keep != PNG_HANDLE_CHUNK_NEVER &&
up->location && (up->location & PNG_HAVE_PLTE) && up->location && (up->location & PNG_HAVE_PLTE) &&
!(up->location & PNG_HAVE_IDAT) && !(up->location & PNG_HAVE_IDAT) &&
((up->name[3] & 0x20) || keep == HANDLE_CHUNK_ALWAYS || ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
(png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
{ {
png_write_chunk(png_ptr, up->name, up->data, up->size); png_write_chunk(png_ptr, up->name, up->data, up->size);
@@ -367,9 +368,9 @@ png_write_end(png_structp png_ptr, png_infop info_ptr)
up++) up++)
{ {
int keep=png_handle_as_unknown(png_ptr, up->name); int keep=png_handle_as_unknown(png_ptr, up->name);
if (keep != HANDLE_CHUNK_NEVER && if (keep != PNG_HANDLE_CHUNK_NEVER &&
up->location && (up->location & PNG_AFTER_IDAT) && up->location && (up->location & PNG_AFTER_IDAT) &&
((up->name[3] & 0x20) || keep == HANDLE_CHUNK_ALWAYS || ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
(png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
{ {
png_write_chunk(png_ptr, up->name, up->data, up->size); png_write_chunk(png_ptr, up->name, up->data, up->size);
@@ -457,6 +458,12 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
#endif #endif
#endif /* PNG_1_0_X */ #endif /* PNG_1_0_X */
/* added at libpng-1.2.6 */
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
#endif
#ifdef PNG_SETJMP_SUPPORTED #ifdef PNG_SETJMP_SUPPORTED
#ifdef USE_FAR_KEYWORD #ifdef USE_FAR_KEYWORD
if (setjmp(jmpbuf)) if (setjmp(jmpbuf))
@@ -470,7 +477,7 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
return (NULL); return (NULL);
} }
#ifdef USE_FAR_KEYWORD #ifdef USE_FAR_KEYWORD
png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf)); png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
#endif #endif
#endif #endif
@@ -537,7 +544,7 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
#ifdef USE_FAR_KEYWORD #ifdef USE_FAR_KEYWORD
if (setjmp(jmpbuf)) if (setjmp(jmpbuf))
PNG_ABORT(); PNG_ABORT();
png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf)); png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
#else #else
if (setjmp(png_ptr->jmpbuf)) if (setjmp(png_ptr->jmpbuf))
PNG_ABORT(); PNG_ABORT();
@@ -561,7 +568,8 @@ png_write_init_2(png_structp png_ptr, png_const_charp user_png_ver,
{ {
/* We only come here via pre-1.0.12-compiled applications */ /* We only come here via pre-1.0.12-compiled applications */
#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
if(sizeof(png_struct) > png_struct_size || sizeof(png_info) > png_info_size) if(png_sizeof(png_struct) > png_struct_size ||
png_sizeof(png_info) > png_info_size)
{ {
char msg[80]; char msg[80];
png_ptr->warning_fn=NULL; png_ptr->warning_fn=NULL;
@@ -576,7 +584,7 @@ png_write_init_2(png_structp png_ptr, png_const_charp user_png_ver,
png_warning(png_ptr, msg); png_warning(png_ptr, msg);
} }
#endif #endif
if(sizeof(png_struct) > png_struct_size) if(png_sizeof(png_struct) > png_struct_size)
{ {
png_ptr->error_fn=NULL; png_ptr->error_fn=NULL;
#ifdef PNG_ERROR_NUMBERS_SUPPORTED #ifdef PNG_ERROR_NUMBERS_SUPPORTED
@@ -585,7 +593,7 @@ png_write_init_2(png_structp png_ptr, png_const_charp user_png_ver,
png_error(png_ptr, png_error(png_ptr,
"The png struct allocated by the application for writing is too small."); "The png struct allocated by the application for writing is too small.");
} }
if(sizeof(png_info) > png_info_size) if(png_sizeof(png_info) > png_info_size)
{ {
png_ptr->error_fn=NULL; png_ptr->error_fn=NULL;
#ifdef PNG_ERROR_NUMBERS_SUPPORTED #ifdef PNG_ERROR_NUMBERS_SUPPORTED
@@ -626,10 +634,10 @@ png_write_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
#ifdef PNG_SETJMP_SUPPORTED #ifdef PNG_SETJMP_SUPPORTED
/* save jump buffer and error functions */ /* save jump buffer and error functions */
png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf)); png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
#endif #endif
if (sizeof(png_struct) > png_struct_size) if (png_sizeof(png_struct) > png_struct_size)
{ {
png_destroy_struct(png_ptr); png_destroy_struct(png_ptr);
png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
@@ -637,7 +645,13 @@ png_write_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
} }
/* reset all variables to 0 */ /* reset all variables to 0 */
png_memset(png_ptr, 0, sizeof (png_struct)); png_memset(png_ptr, 0, png_sizeof (png_struct));
/* added at libpng-1.2.6 */
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
#endif
#if !defined(PNG_1_0_X) #if !defined(PNG_1_0_X)
#ifdef PNG_ASSEMBLER_CODE_SUPPORTED #ifdef PNG_ASSEMBLER_CODE_SUPPORTED
@@ -647,7 +661,7 @@ png_write_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
#ifdef PNG_SETJMP_SUPPORTED #ifdef PNG_SETJMP_SUPPORTED
/* restore jump buffer */ /* restore jump buffer */
png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf)); png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
#endif #endif
png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL, png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL,
@@ -827,8 +841,8 @@ png_write_row(png_structp png_ptr, png_bytep row)
png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.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.channels);
png_ptr->row_info.rowbytes = ((png_ptr->row_info.width * png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
(png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3); png_ptr->row_info.width);
png_debug1(3, "row_info->color_type = %d\n", png_ptr->row_info.color_type); png_debug1(3, "row_info->color_type = %d\n", png_ptr->row_info.color_type);
png_debug1(3, "row_info->width = %lu\n", png_ptr->row_info.width); png_debug1(3, "row_info->width = %lu\n", png_ptr->row_info.width);
@@ -1049,7 +1063,7 @@ png_write_destroy(png_structp png_ptr)
#ifdef PNG_SETJMP_SUPPORTED #ifdef PNG_SETJMP_SUPPORTED
/* reset structure */ /* reset structure */
png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf)); png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
#endif #endif
error_fn = png_ptr->error_fn; error_fn = png_ptr->error_fn;
@@ -1059,7 +1073,7 @@ png_write_destroy(png_structp png_ptr)
free_fn = png_ptr->free_fn; free_fn = png_ptr->free_fn;
#endif #endif
png_memset(png_ptr, 0, sizeof (png_struct)); png_memset(png_ptr, 0, png_sizeof (png_struct));
png_ptr->error_fn = error_fn; png_ptr->error_fn = error_fn;
png_ptr->warning_fn = warning_fn; png_ptr->warning_fn = warning_fn;
@@ -1069,7 +1083,7 @@ png_write_destroy(png_structp png_ptr)
#endif #endif
#ifdef PNG_SETJMP_SUPPORTED #ifdef PNG_SETJMP_SUPPORTED
png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf)); png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
#endif #endif
} }
@@ -1211,7 +1225,7 @@ png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
if (png_ptr->prev_filters == NULL) if (png_ptr->prev_filters == NULL)
{ {
png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr, png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr,
(png_uint_32)(sizeof(png_byte) * num_weights)); (png_uint_32)(png_sizeof(png_byte) * num_weights));
/* To make sure that the weighting starts out fairly */ /* To make sure that the weighting starts out fairly */
for (i = 0; i < num_weights; i++) for (i = 0; i < num_weights; i++)
@@ -1223,10 +1237,10 @@ png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
if (png_ptr->filter_weights == NULL) if (png_ptr->filter_weights == NULL)
{ {
png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr, png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr,
(png_uint_32)(sizeof(png_uint_16) * num_weights)); (png_uint_32)(png_sizeof(png_uint_16) * num_weights));
png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr, png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr,
(png_uint_32)(sizeof(png_uint_16) * num_weights)); (png_uint_32)(png_sizeof(png_uint_16) * num_weights));
for (i = 0; i < num_weights; i++) for (i = 0; i < num_weights; i++)
{ {
png_ptr->inv_filter_weights[i] = png_ptr->inv_filter_weights[i] =
@@ -1257,10 +1271,10 @@ png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
if (png_ptr->filter_costs == NULL) if (png_ptr->filter_costs == NULL)
{ {
png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr, png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr,
(png_uint_32)(sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr, png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr,
(png_uint_32)(sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
{ {

View File

@@ -1,9 +1,9 @@
/* pngwtran.c - transforms the data in a row for PNG writers /* pngwtran.c - transforms the data in a row for PNG writers
* *
* libpng 1.2.4 - July 8, 2002 * libpng version 1.2.8 - December 3, 2004
* For conditions of distribution and use, see copyright notice in png.h * For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2002 Glenn Randers-Pehrson * Copyright (c) 1998-2004 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*/ */
@@ -195,8 +195,8 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
} }
row_info->bit_depth = (png_byte)bit_depth; row_info->bit_depth = (png_byte)bit_depth;
row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels); row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
row_info->rowbytes = row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
((row_info->width * row_info->pixel_depth + 7) >> 3); row_info->width);
} }
} }
#endif #endif
@@ -546,11 +546,11 @@ png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
{ {
png_uint_32 s0=*(rp )<<8 | *(rp+1); png_uint_32 s0 = (*(rp ) << 8) | *(rp+1);
png_uint_32 s1=*(rp+2)<<8 | *(rp+3); png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3);
png_uint_32 s2=*(rp+4)<<8 | *(rp+5); png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5);
png_uint_32 red=(s0-s1)&0xffff; png_uint_32 red = (png_uint_32)((s0-s1) & 0xffffL);
png_uint_32 blue=(s2-s1)&0xffff; png_uint_32 blue = (png_uint_32)((s2-s1) & 0xffffL);
*(rp ) = (png_byte)((red >> 8) & 0xff); *(rp ) = (png_byte)((red >> 8) & 0xff);
*(rp+1) = (png_byte)(red & 0xff); *(rp+1) = (png_byte)(red & 0xff);
*(rp+4) = (png_byte)((blue >> 8) & 0xff); *(rp+4) = (png_byte)((blue >> 8) & 0xff);

View File

@@ -1,9 +1,9 @@
/* pngwutil.c - utilities to write a PNG file /* pngwutil.c - utilities to write a PNG file
* *
* libpng 1.2.4 - July 8, 2002 * libpng version 1.2.8 - December 3, 2004
* For conditions of distribution and use, see copyright notice in png.h * For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2002 Glenn Randers-Pehrson * Copyright (c) 1998-2004 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*/ */
@@ -219,7 +219,7 @@ png_text_compress(png_structp png_ptr,
png_error(png_ptr, "zlib error"); png_error(png_ptr, "zlib error");
} }
/* check to see if we need more room */ /* check to see if we need more room */
if (!png_ptr->zstream.avail_out && png_ptr->zstream.avail_in) if (!(png_ptr->zstream.avail_out))
{ {
/* make sure the output array has room */ /* make sure the output array has room */
if (comp->num_output_ptr >= comp->max_output_ptr) if (comp->num_output_ptr >= comp->max_output_ptr)
@@ -234,14 +234,16 @@ png_text_compress(png_structp png_ptr,
old_ptr = comp->output_ptr; old_ptr = comp->output_ptr;
comp->output_ptr = (png_charpp)png_malloc(png_ptr, comp->output_ptr = (png_charpp)png_malloc(png_ptr,
(png_uint_32)(comp->max_output_ptr * sizeof (png_charpp))); (png_uint_32)(comp->max_output_ptr *
png_sizeof (png_charpp)));
png_memcpy(comp->output_ptr, old_ptr, old_max png_memcpy(comp->output_ptr, old_ptr, old_max
* sizeof (png_charp)); * png_sizeof (png_charp));
png_free(png_ptr, old_ptr); png_free(png_ptr, old_ptr);
} }
else else
comp->output_ptr = (png_charpp)png_malloc(png_ptr, comp->output_ptr = (png_charpp)png_malloc(png_ptr,
(png_uint_32)(comp->max_output_ptr * sizeof (png_charp))); (png_uint_32)(comp->max_output_ptr *
png_sizeof (png_charp)));
} }
/* save the data */ /* save the data */
@@ -283,14 +285,16 @@ png_text_compress(png_structp png_ptr,
old_ptr = comp->output_ptr; old_ptr = comp->output_ptr;
/* This could be optimized to realloc() */ /* This could be optimized to realloc() */
comp->output_ptr = (png_charpp)png_malloc(png_ptr, comp->output_ptr = (png_charpp)png_malloc(png_ptr,
(png_uint_32)(comp->max_output_ptr * sizeof (png_charpp))); (png_uint_32)(comp->max_output_ptr *
png_sizeof (png_charpp)));
png_memcpy(comp->output_ptr, old_ptr, png_memcpy(comp->output_ptr, old_ptr,
old_max * sizeof (png_charp)); old_max * png_sizeof (png_charp));
png_free(png_ptr, old_ptr); png_free(png_ptr, old_ptr);
} }
else else
comp->output_ptr = (png_charpp)png_malloc(png_ptr, comp->output_ptr = (png_charpp)png_malloc(png_ptr,
(png_uint_32)(comp->max_output_ptr * sizeof (png_charp))); (png_uint_32)(comp->max_output_ptr *
png_sizeof (png_charp)));
} }
/* save off the data */ /* save off the data */
@@ -353,9 +357,9 @@ png_write_compressed_data_out(png_structp png_ptr, compression_state *comp)
png_write_chunk_data(png_ptr, png_ptr->zbuf, png_write_chunk_data(png_ptr, png_ptr->zbuf,
png_ptr->zbuf_size - png_ptr->zstream.avail_out); png_ptr->zbuf_size - png_ptr->zstream.avail_out);
/* reset zlib for another zTXt/iTXt or the image data */ /* reset zlib for another zTXt/iTXt or image data */
deflateReset(&png_ptr->zstream); deflateReset(&png_ptr->zstream);
png_ptr->zstream.data_type = Z_BINARY;
} }
#endif #endif
@@ -464,11 +468,12 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
#if defined(PNG_MNG_FEATURES_SUPPORTED) #if defined(PNG_MNG_FEATURES_SUPPORTED)
png_ptr->filter_type = (png_byte)filter_type; png_ptr->filter_type = (png_byte)filter_type;
#endif #endif
png_ptr->compression_type = (png_byte)compression_type;
png_ptr->width = width; png_ptr->width = width;
png_ptr->height = height; png_ptr->height = height;
png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels); png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
png_ptr->rowbytes = ((width * (png_size_t)png_ptr->pixel_depth + 7) >> 3); png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
/* set the usr info, so any transformations can modify it */ /* set the usr info, so any transformations can modify it */
png_ptr->usr_width = png_ptr->width; png_ptr->usr_width = png_ptr->width;
png_ptr->usr_bit_depth = png_ptr->bit_depth; png_ptr->usr_bit_depth = png_ptr->bit_depth;
@@ -518,6 +523,9 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
png_ptr->zlib_mem_level, png_ptr->zlib_strategy); png_ptr->zlib_mem_level, png_ptr->zlib_strategy);
png_ptr->zstream.next_out = png_ptr->zbuf; png_ptr->zstream.next_out = png_ptr->zbuf;
png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
/* libpng is not interested in zstream.data_type */
/* set it to a predefined value, to avoid its evaluation inside zlib */
png_ptr->zstream.data_type = Z_BINARY;
png_ptr->mode = PNG_HAVE_IHDR; png_ptr->mode = PNG_HAVE_IHDR;
} }
@@ -596,6 +604,46 @@ png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
PNG_IDAT; PNG_IDAT;
#endif #endif
png_debug(1, "in png_write_IDAT\n"); png_debug(1, "in png_write_IDAT\n");
/* Optimize the CMF field in the zlib stream. */
/* This hack of the zlib stream is compliant to the stream specification. */
if (!(png_ptr->mode & PNG_HAVE_IDAT) &&
png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
{
unsigned int z_cmf = data[0]; /* zlib compression method and flags */
if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
{
/* Avoid memory underflows and multiplication overflows. */
/* The conditions below are practically always satisfied;
however, they still must be checked. */
if (length >= 2 &&
png_ptr->height < 16384 && png_ptr->width < 16384)
{
png_uint_32 uncompressed_idat_size = png_ptr->height *
((png_ptr->width *
png_ptr->channels * png_ptr->bit_depth + 15) >> 3);
unsigned int z_cinfo = z_cmf >> 4;
unsigned int half_z_window_size = 1 << (z_cinfo + 7);
while (uncompressed_idat_size <= half_z_window_size &&
half_z_window_size >= 256)
{
z_cinfo--;
half_z_window_size >>= 1;
}
z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
if (data[0] != (png_byte)z_cmf)
{
data[0] = (png_byte)z_cmf;
data[1] &= 0xe0;
data[1] += (png_byte)(0x1f - ((z_cmf << 8) + data[1]) % 0x1f);
}
}
}
else
png_error(png_ptr,
"Invalid zlib compression method or flags in IDAT");
}
png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length); png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length);
png_ptr->mode |= PNG_HAVE_IDAT; png_ptr->mode |= PNG_HAVE_IDAT;
} }
@@ -1141,7 +1189,12 @@ png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key)
png_debug1(2, "Keyword to be checked is '%s'\n", key); png_debug1(2, "Keyword to be checked is '%s'\n", key);
*new_key = (png_charp)png_malloc(png_ptr, (png_uint_32)(key_len + 2)); *new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2));
if (*new_key == NULL)
{
png_warning(png_ptr, "Out of memory while procesing keyword");
return ((png_size_t)0);
}
/* Replace non-printing characters with a blank and print a warning */ /* Replace non-printing characters with a blank and print a warning */
for (kp = key, dp = *new_key; *kp != '\0'; kp++, dp++) for (kp = key, dp = *new_key; *kp != '\0'; kp++, dp++)
@@ -1461,7 +1514,7 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
total_len = purpose_len + units_len + 10; total_len = purpose_len + units_len + 10;
params_len = (png_uint_32p)png_malloc(png_ptr, (png_uint_32)(nparams params_len = (png_uint_32p)png_malloc(png_ptr, (png_uint_32)(nparams
*sizeof(png_uint_32))); *png_sizeof(png_uint_32)));
/* Find the length of each parameter, making sure we don't count the /* Find the length of each parameter, making sure we don't count the
null terminator for the last parameter. */ null terminator for the last parameter. */
@@ -1506,6 +1559,7 @@ png_write_sCAL(png_structp png_ptr, int unit, double width,double height)
#endif #endif
png_size_t total_len; png_size_t total_len;
char wbuf[32], hbuf[32]; char wbuf[32], hbuf[32];
png_byte bunit = unit;
png_debug(1, "in png_write_sCAL\n"); png_debug(1, "in png_write_sCAL\n");
@@ -1526,7 +1580,7 @@ png_write_sCAL(png_structp png_ptr, int unit, double width,double height)
png_debug1(3, "sCAL total length = %d\n", (int)total_len); png_debug1(3, "sCAL total length = %d\n", (int)total_len);
png_write_chunk_start(png_ptr, (png_bytep)png_sCAL, (png_uint_32)total_len); png_write_chunk_start(png_ptr, (png_bytep)png_sCAL, (png_uint_32)total_len);
png_write_chunk_data(png_ptr, (png_bytep)&unit, 1); png_write_chunk_data(png_ptr, (png_bytep)&bunit, 1);
png_write_chunk_data(png_ptr, (png_bytep)wbuf, png_strlen(wbuf)+1); png_write_chunk_data(png_ptr, (png_bytep)wbuf, png_strlen(wbuf)+1);
png_write_chunk_data(png_ptr, (png_bytep)hbuf, png_strlen(hbuf)); png_write_chunk_data(png_ptr, (png_bytep)hbuf, png_strlen(hbuf));
@@ -1543,6 +1597,7 @@ png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width,
#endif #endif
png_size_t total_len; png_size_t total_len;
char wbuf[32], hbuf[32]; char wbuf[32], hbuf[32];
png_byte bunit = unit;
png_debug(1, "in png_write_sCAL_s\n"); png_debug(1, "in png_write_sCAL_s\n");
@@ -1552,7 +1607,7 @@ png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width,
png_debug1(3, "sCAL total length = %d\n", total_len); png_debug1(3, "sCAL total length = %d\n", total_len);
png_write_chunk_start(png_ptr, (png_bytep)png_sCAL, (png_uint_32)total_len); png_write_chunk_start(png_ptr, (png_bytep)png_sCAL, (png_uint_32)total_len);
png_write_chunk_data(png_ptr, (png_bytep)&unit, 1); png_write_chunk_data(png_ptr, (png_bytep)&bunit, 1);
png_write_chunk_data(png_ptr, (png_bytep)wbuf, png_strlen(wbuf)+1); png_write_chunk_data(png_ptr, (png_bytep)wbuf, png_strlen(wbuf)+1);
png_write_chunk_data(png_ptr, (png_bytep)hbuf, png_strlen(hbuf)); png_write_chunk_data(png_ptr, (png_bytep)hbuf, png_strlen(hbuf));
@@ -1641,8 +1696,8 @@ png_write_start_row(png_structp png_ptr)
png_size_t buf_size; png_size_t buf_size;
png_debug(1, "in png_write_start_row\n"); png_debug(1, "in png_write_start_row\n");
buf_size = (png_size_t)(((png_ptr->width * png_ptr->usr_channels * buf_size = (png_size_t)(PNG_ROWBYTES(
png_ptr->usr_bit_depth + 7) >> 3) + 1); png_ptr->usr_channels*png_ptr->usr_bit_depth,png_ptr->width)+1);
/* set up row buffer */ /* set up row buffer */
png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size); png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size);
@@ -1778,9 +1833,8 @@ png_write_finish_row(png_structp png_ptr)
{ {
if (png_ptr->prev_row != NULL) if (png_ptr->prev_row != NULL)
png_memset(png_ptr->prev_row, 0, png_memset(png_ptr->prev_row, 0,
(png_size_t) (((png_uint_32)png_ptr->usr_channels * (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels*
(png_uint_32)png_ptr->usr_bit_depth * png_ptr->usr_bit_depth,png_ptr->width))+1);
png_ptr->width + 7) >> 3) + 1);
return; return;
} }
} }
@@ -1820,6 +1874,7 @@ png_write_finish_row(png_structp png_ptr)
} }
deflateReset(&png_ptr->zstream); deflateReset(&png_ptr->zstream);
png_ptr->zstream.data_type = Z_BINARY;
} }
#if defined(PNG_WRITE_INTERLACING_SUPPORTED) #if defined(PNG_WRITE_INTERLACING_SUPPORTED)
@@ -1987,8 +2042,8 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
png_pass_inc[pass] - 1 - png_pass_inc[pass] - 1 -
png_pass_start[pass]) / png_pass_start[pass]) /
png_pass_inc[pass]; png_pass_inc[pass];
row_info->rowbytes = ((row_info->width * row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
row_info->pixel_depth + 7) >> 3); row_info->width);
} }
} }
#endif #endif
@@ -1997,7 +2052,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
* been specified by the application, and then writes the row out with the * been specified by the application, and then writes the row out with the
* chosen filter. * chosen filter.
*/ */
#define PNG_MAXSUM (~((png_uint_32)0) >> 1) #define PNG_MAXSUM (((png_uint_32)(-1)) >> 1)
#define PNG_HISHIFT 10 #define PNG_HISHIFT 10
#define PNG_LOMASK ((png_uint_32)0xffffL) #define PNG_LOMASK ((png_uint_32)0xffffL)
#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT)) #define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
@@ -2014,7 +2069,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info)
png_debug(1, "in png_write_find_filter\n"); png_debug(1, "in png_write_find_filter\n");
/* find out how many bytes offset each pixel is */ /* find out how many bytes offset each pixel is */
bpp = (row_info->pixel_depth + 7) / 8; bpp = (row_info->pixel_depth + 7) >> 3;
prev_row = png_ptr->prev_row; prev_row = png_ptr->prev_row;
best_row = row_buf = png_ptr->row_buf; best_row = row_buf = png_ptr->row_buf;
@@ -2165,7 +2220,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info)
sum += (v < 128) ? v : 256 - v; sum += (v < 128) ? v : 256 - v;
} }
for (lp = row_buf + 1; i < row_info->rowbytes; for (lp = row_buf + 1; i < row_bytes;
i++, rp++, lp++, dp++) i++, rp++, lp++, dp++)
{ {
v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);

45
trees.c
View File

@@ -1,5 +1,5 @@
/* trees.c -- output deflated data using Huffman coding /* trees.c -- output deflated data using Huffman coding
* Copyright (C) 1995-1998 Jean-loup Gailly * Copyright (C) 1995-2005 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -230,7 +230,6 @@ local void send_bits(s, value, length)
#endif /* DEBUG */ #endif /* DEBUG */
#define MAX(a,b) (a >= b ? a : b)
/* the arguments must not have side effects */ /* the arguments must not have side effects */
/* =========================================================================== /* ===========================================================================
@@ -556,7 +555,7 @@ local void gen_bitlen(s, desc)
while (n != 0) { while (n != 0) {
m = s->heap[--h]; m = s->heap[--h];
if (m > max_code) continue; if (m > max_code) continue;
if (tree[m].Len != (unsigned) bits) { if ((unsigned) tree[m].Len != (unsigned) bits) {
Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
s->opt_len += ((long)bits - (long)tree[m].Len) s->opt_len += ((long)bits - (long)tree[m].Len)
*(long)tree[m].Freq; *(long)tree[m].Freq;
@@ -675,7 +674,8 @@ local void build_tree(s, desc)
/* Create a new node father of n and m */ /* Create a new node father of n and m */
tree[node].Freq = tree[n].Freq + tree[m].Freq; tree[node].Freq = tree[n].Freq + tree[m].Freq;
s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1); s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
s->depth[n] : s->depth[m]) + 1);
tree[n].Dad = tree[m].Dad = (ush)node; tree[n].Dad = tree[m].Dad = (ush)node;
#ifdef DUMP_BL_TREE #ifdef DUMP_BL_TREE
if (tree == s->bl_tree) { if (tree == s->bl_tree) {
@@ -930,8 +930,9 @@ void _tr_flush_block(s, buf, stored_len, eof)
/* Build the Huffman trees unless a stored block is forced */ /* Build the Huffman trees unless a stored block is forced */
if (s->level > 0) { if (s->level > 0) {
/* Check if the file is ascii or binary */ /* Check if the file is binary or text */
if (s->data_type == Z_UNKNOWN) set_data_type(s); if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
set_data_type(s);
/* Construct the literal and distance trees */ /* Construct the literal and distance trees */
build_tree(s, (tree_desc *)(&(s->l_desc))); build_tree(s, (tree_desc *)(&(s->l_desc)));
@@ -950,7 +951,7 @@ void _tr_flush_block(s, buf, stored_len, eof)
*/ */
max_blindex = build_bl_tree(s); max_blindex = build_bl_tree(s);
/* Determine the best encoding. Compute first the block length in bytes*/ /* Determine the best encoding. Compute the block lengths in bytes. */
opt_lenb = (s->opt_len+3+7)>>3; opt_lenb = (s->opt_len+3+7)>>3;
static_lenb = (s->static_len+3+7)>>3; static_lenb = (s->static_len+3+7)>>3;
@@ -982,7 +983,7 @@ void _tr_flush_block(s, buf, stored_len, eof)
#ifdef FORCE_STATIC #ifdef FORCE_STATIC
} else if (static_lenb >= 0) { /* force static trees */ } else if (static_lenb >= 0) { /* force static trees */
#else #else
} else if (static_lenb == opt_lenb) { } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
#endif #endif
send_bits(s, (STATIC_TREES<<1)+eof, 3); send_bits(s, (STATIC_TREES<<1)+eof, 3);
compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
@@ -1107,7 +1108,8 @@ local void compress_block(s, ltree, dtree)
} /* literal or match pair ? */ } /* literal or match pair ? */
/* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow"); Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
"pendingBuf overflow");
} while (lx < s->last_lit); } while (lx < s->last_lit);
@@ -1116,21 +1118,24 @@ local void compress_block(s, ltree, dtree)
} }
/* =========================================================================== /* ===========================================================================
* Set the data type to ASCII or BINARY, using a crude approximation: * Set the data type to BINARY or TEXT, using a crude approximation:
* binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. * set it to Z_TEXT if all symbols are either printable characters (33 to 255)
* IN assertion: the fields freq of dyn_ltree are set and the total of all * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise.
* frequencies does not exceed 64K (to fit in an int on 16 bit machines). * IN assertion: the fields Freq of dyn_ltree are set.
*/ */
local void set_data_type(s) local void set_data_type(s)
deflate_state *s; deflate_state *s;
{ {
int n = 0; int n;
unsigned ascii_freq = 0;
unsigned bin_freq = 0; for (n = 0; n < 9; n++)
while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; if (s->dyn_ltree[n].Freq != 0)
while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; break;
while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; if (n == 9)
s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); for (n = 14; n < 32; n++)
if (s->dyn_ltree[n].Freq != 0)
break;
s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY;
} }
/* =========================================================================== /* ===========================================================================

View File

@@ -1,10 +1,11 @@
/* uncompr.c -- decompress a memory buffer /* uncompr.c -- decompress a memory buffer
* Copyright (C) 1995-1998 Jean-loup Gailly. * Copyright (C) 1995-2003 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* @(#) $Id$ */ /* @(#) $Id$ */
#define ZLIB_INTERNAL
#include "zlib.h" #include "zlib.h"
/* =========================================================================== /* ===========================================================================
@@ -49,7 +50,9 @@ int ZEXPORT uncompress (dest, destLen, source, sourceLen)
err = inflate(&stream, Z_FINISH); err = inflate(&stream, Z_FINISH);
if (err != Z_STREAM_END) { if (err != Z_STREAM_END) {
inflateEnd(&stream); inflateEnd(&stream);
return err == Z_OK ? Z_BUF_ERROR : err; if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
return Z_DATA_ERROR;
return err;
} }
*destLen = stream.total_out; *destLen = stream.total_out;

199
zconf.h
View File

@@ -1,12 +1,12 @@
/* zconf.h -- configuration of the zlib compression library /* zconf.h -- configuration of the zlib compression library
* Copyright (C) 1995-1998 Jean-loup Gailly. * Copyright (C) 1995-2005 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* @(#) $Id$ */ /* @(#) $Id$ */
#ifndef _ZCONF_H #ifndef ZCONF_H
#define _ZCONF_H #define ZCONF_H
/* /*
* If you *really* need a unique prefix for all types and library functions, * If you *really* need a unique prefix for all types and library functions,
@@ -24,18 +24,29 @@
# define deflateCopy z_deflateCopy # define deflateCopy z_deflateCopy
# define deflateReset z_deflateReset # define deflateReset z_deflateReset
# define deflateParams z_deflateParams # define deflateParams z_deflateParams
# define deflateBound z_deflateBound
# define deflatePrime z_deflatePrime
# define inflateInit2_ z_inflateInit2_ # define inflateInit2_ z_inflateInit2_
# define inflateSetDictionary z_inflateSetDictionary # define inflateSetDictionary z_inflateSetDictionary
# define inflateSync z_inflateSync # define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint # define inflateSyncPoint z_inflateSyncPoint
# define inflateCopy z_inflateCopy
# define inflateReset z_inflateReset # define inflateReset z_inflateReset
# define inflateBack z_inflateBack
# define inflateBackEnd z_inflateBackEnd
# define compress z_compress # define compress z_compress
# define compress2 z_compress2 # define compress2 z_compress2
# define compressBound z_compressBound
# define uncompress z_uncompress # define uncompress z_uncompress
# define adler32 z_adler32 # define adler32 z_adler32
# define crc32 z_crc32 # define crc32 z_crc32
# define get_crc_table z_get_crc_table # define get_crc_table z_get_crc_table
# define zError z_zError
# define alloc_func z_alloc_func
# define free_func z_free_func
# define in_func z_in_func
# define out_func z_out_func
# define Byte z_Byte # define Byte z_Byte
# define uInt z_uInt # define uInt z_uInt
# define uLong z_uLong # define uLong z_uLong
@@ -48,41 +59,69 @@
# define voidp z_voidp # define voidp z_voidp
#endif #endif
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
# define WIN32
#endif
#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
# ifndef __32BIT__
# define __32BIT__
# endif
#endif
#if defined(__MSDOS__) && !defined(MSDOS) #if defined(__MSDOS__) && !defined(MSDOS)
# define MSDOS # define MSDOS
#endif #endif
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
# define OS2
#endif
#if defined(_WINDOWS) && !defined(WINDOWS)
# define WINDOWS
#endif
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
# ifndef WIN32
# define WIN32
# endif
#endif
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
# ifndef SYS16BIT
# define SYS16BIT
# endif
# endif
#endif
/* /*
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
* than 64k bytes at a time (needed on systems with 16-bit int). * than 64k bytes at a time (needed on systems with 16-bit int).
*/ */
#if defined(MSDOS) && !defined(__32BIT__) #ifdef SYS16BIT
# define MAXSEG_64K # define MAXSEG_64K
#endif #endif
#ifdef MSDOS #ifdef MSDOS
# define UNALIGNED_OK # define UNALIGNED_OK
#endif #endif
#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) #ifdef __STDC_VERSION__
# define STDC
#endif
#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
# ifndef STDC # ifndef STDC
# define STDC # define STDC
# endif # endif
# if __STDC_VERSION__ >= 199901L
# ifndef STDC99
# define STDC99
# endif
# endif
#endif
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
# define STDC
#endif
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
# define STDC
#endif
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
# define STDC
#endif
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
# define STDC
#endif
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
# define STDC
#endif #endif
#ifndef STDC #ifndef STDC
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ # ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
# define const # define const /* note: need a more gentle solution here */
# endif # endif
#endif #endif
@@ -91,12 +130,6 @@
# define NO_DUMMY_DECL # define NO_DUMMY_DECL
#endif #endif
/* Old Borland C incorrectly complains about missing returns: */
#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
# define NEED_DUMMY_RETURN
#endif
/* Maximum value for memLevel in deflateInit2 */ /* Maximum value for memLevel in deflateInit2 */
#ifndef MAX_MEM_LEVEL #ifndef MAX_MEM_LEVEL
# ifdef MAXSEG_64K # ifdef MAXSEG_64K
@@ -144,7 +177,8 @@
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model, * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
* just define FAR to be empty. * just define FAR to be empty.
*/ */
#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) #ifdef SYS16BIT
# if defined(M_I86SM) || defined(M_I86MM)
/* MSC small or medium model */ /* MSC small or medium model */
# define SMALL_MEDIUM # define SMALL_MEDIUM
# ifdef _MSC_VER # ifdef _MSC_VER
@@ -153,64 +187,77 @@
# define FAR far # define FAR far
# endif # endif
# endif # endif
#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) # if (defined(__SMALL__) || defined(__MEDIUM__))
# ifndef __32BIT__ /* Turbo C small or medium model */
# define SMALL_MEDIUM # define SMALL_MEDIUM
# ifdef __BORLANDC__
# define FAR _far # define FAR _far
# endif
#endif
/* Compile with -DZLIB_DLL for Windows DLL support */
#if defined(ZLIB_DLL)
# if defined(_WINDOWS) || defined(WINDOWS)
# ifdef FAR
# undef FAR
# endif
# include <windows.h>
# define ZEXPORT WINAPI
# ifdef WIN32
# define ZEXPORTVA WINAPIV
# else # else
# define ZEXPORTVA FAR _cdecl _export # define FAR far
# endif
# endif
# if defined (__BORLANDC__)
# if (__BORLANDC__ >= 0x0500) && defined (WIN32)
# include <windows.h>
# define ZEXPORT __declspec(dllexport) WINAPI
# define ZEXPORTRVA __declspec(dllexport) WINAPIV
# else
# if defined (_Windows) && defined (__DLL__)
# define ZEXPORT _export
# define ZEXPORTVA _export
# endif
# endif # endif
# endif # endif
#endif #endif
#if defined (__BEOS__) #if defined(WINDOWS) || defined(WIN32)
# if defined (ZLIB_DLL) /* If building or using zlib as a DLL, define ZLIB_DLL.
* This is not mandatory, but it offers a little performance increase.
*/
# ifdef ZLIB_DLL
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
# ifdef ZLIB_INTERNAL
# define ZEXTERN extern __declspec(dllexport) # define ZEXTERN extern __declspec(dllexport)
# else # else
# define ZEXTERN extern __declspec(dllimport) # define ZEXTERN extern __declspec(dllimport)
# endif # endif
# endif # endif
# endif /* ZLIB_DLL */
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
* define ZLIB_WINAPI.
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
*/
# ifdef ZLIB_WINAPI
# ifdef FAR
# undef FAR
# endif
# include <windows.h>
/* No need for _export, use ZLIB.DEF instead. */
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
# define ZEXPORT WINAPI
# ifdef WIN32
# define ZEXPORTVA WINAPIV
# else
# define ZEXPORTVA FAR CDECL
# endif
# endif
#endif
#if defined (__BEOS__)
# ifdef ZLIB_DLL
# ifdef ZLIB_INTERNAL
# define ZEXPORT __declspec(dllexport)
# define ZEXPORTVA __declspec(dllexport)
# else
# define ZEXPORT __declspec(dllimport)
# define ZEXPORTVA __declspec(dllimport)
# endif
# endif
#endif
#ifndef ZEXTERN
# define ZEXTERN extern
#endif
#ifndef ZEXPORT #ifndef ZEXPORT
# define ZEXPORT # define ZEXPORT
#endif #endif
#ifndef ZEXPORTVA #ifndef ZEXPORTVA
# define ZEXPORTVA # define ZEXPORTVA
#endif #endif
#ifndef ZEXTERN
# define ZEXTERN extern
#endif
#ifndef FAR #ifndef FAR
# define FAR # define FAR
#endif #endif
#if !defined(MACOS) && !defined(TARGET_OS_MAC) #if !defined(__MACTYPES__)
typedef unsigned char Byte; /* 8 bits */ typedef unsigned char Byte; /* 8 bits */
#endif #endif
typedef unsigned int uInt; /* 16 bits or more */ typedef unsigned int uInt; /* 16 bits or more */
@@ -228,16 +275,21 @@ typedef uInt FAR uIntf;
typedef uLong FAR uLongf; typedef uLong FAR uLongf;
#ifdef STDC #ifdef STDC
typedef void const *voidpc;
typedef void FAR *voidpf; typedef void FAR *voidpf;
typedef void *voidp; typedef void *voidp;
#else #else
typedef Byte const *voidpc;
typedef Byte FAR *voidpf; typedef Byte FAR *voidpf;
typedef Byte *voidp; typedef Byte *voidp;
#endif #endif
#ifdef HAVE_UNISTD_H #if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
# include <sys/types.h> /* for off_t */ # include <sys/types.h> /* for off_t */
# include <unistd.h> /* for SEEK_* and off_t */ # include <unistd.h> /* for SEEK_* and off_t */
# ifdef VMS
# include <unixio.h> /* for off_t */
# endif
# define z_off_t off_t # define z_off_t off_t
#endif #endif
#ifndef SEEK_SET #ifndef SEEK_SET
@@ -249,31 +301,32 @@ typedef uLong FAR uLongf;
# define z_off_t long # define z_off_t long
#endif #endif
#if defined(__OS400__)
# define NO_vsnprintf
#endif
#if defined(__MVS__)
# define NO_vsnprintf
# ifdef FAR
# undef FAR
# endif
#endif
/* MVS linker does not support external names larger than 8 bytes */ /* MVS linker does not support external names larger than 8 bytes */
#if defined(__MVS__) #if defined(__MVS__)
# pragma map(deflateInit_,"DEIN") # pragma map(deflateInit_,"DEIN")
# pragma map(deflateInit2_,"DEIN2") # pragma map(deflateInit2_,"DEIN2")
# pragma map(deflateEnd,"DEEND") # pragma map(deflateEnd,"DEEND")
# pragma map(deflateBound,"DEBND")
# pragma map(inflateInit_,"ININ") # pragma map(inflateInit_,"ININ")
# pragma map(inflateInit2_,"ININ2") # pragma map(inflateInit2_,"ININ2")
# pragma map(inflateEnd,"INEND") # pragma map(inflateEnd,"INEND")
# pragma map(inflateSync,"INSY") # pragma map(inflateSync,"INSY")
# pragma map(inflateSetDictionary,"INSEDI") # pragma map(inflateSetDictionary,"INSEDI")
# pragma map(inflate_blocks,"INBL") # pragma map(compressBound,"CMBND")
# pragma map(inflate_blocks_new,"INBLNE") # pragma map(inflate_table,"INTABL")
# pragma map(inflate_blocks_free,"INBLFR")
# pragma map(inflate_blocks_reset,"INBLRE")
# pragma map(inflate_codes_free,"INCOFR")
# pragma map(inflate_codes,"INCO")
# pragma map(inflate_fast,"INFA") # pragma map(inflate_fast,"INFA")
# pragma map(inflate_flush,"INFLU")
# pragma map(inflate_mask,"INMA")
# pragma map(inflate_set_dictionary,"INSEDI2")
# pragma map(inflate_copyright,"INCOPY") # pragma map(inflate_copyright,"INCOPY")
# pragma map(inflate_trees_bits,"INTRBI")
# pragma map(inflate_trees_dynamic,"INTRDY")
# pragma map(inflate_trees_fixed,"INTRFI")
# pragma map(inflate_trees_free,"INTRFR")
#endif #endif
#endif /* _ZCONF_H */ #endif /* ZCONF_H */

332
zconf.in.h Normal file
View File

@@ -0,0 +1,332 @@
/* zconf.h -- configuration of the zlib compression library
* Copyright (C) 1995-2005 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#ifndef ZCONF_H
#define ZCONF_H
/*
* If you *really* need a unique prefix for all types and library functions,
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
*/
#ifdef Z_PREFIX
# define deflateInit_ z_deflateInit_
# define deflate z_deflate
# define deflateEnd z_deflateEnd
# define inflateInit_ z_inflateInit_
# define inflate z_inflate
# define inflateEnd z_inflateEnd
# define deflateInit2_ z_deflateInit2_
# define deflateSetDictionary z_deflateSetDictionary
# define deflateCopy z_deflateCopy
# define deflateReset z_deflateReset
# define deflateParams z_deflateParams
# define deflateBound z_deflateBound
# define deflatePrime z_deflatePrime
# define inflateInit2_ z_inflateInit2_
# define inflateSetDictionary z_inflateSetDictionary
# define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint
# define inflateCopy z_inflateCopy
# define inflateReset z_inflateReset
# define inflateBack z_inflateBack
# define inflateBackEnd z_inflateBackEnd
# define compress z_compress
# define compress2 z_compress2
# define compressBound z_compressBound
# define uncompress z_uncompress
# define adler32 z_adler32
# define crc32 z_crc32
# define get_crc_table z_get_crc_table
# define zError z_zError
# define alloc_func z_alloc_func
# define free_func z_free_func
# define in_func z_in_func
# define out_func z_out_func
# define Byte z_Byte
# define uInt z_uInt
# define uLong z_uLong
# define Bytef z_Bytef
# define charf z_charf
# define intf z_intf
# define uIntf z_uIntf
# define uLongf z_uLongf
# define voidpf z_voidpf
# define voidp z_voidp
#endif
#if defined(__MSDOS__) && !defined(MSDOS)
# define MSDOS
#endif
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
# define OS2
#endif
#if defined(_WINDOWS) && !defined(WINDOWS)
# define WINDOWS
#endif
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
# ifndef WIN32
# define WIN32
# endif
#endif
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
# ifndef SYS16BIT
# define SYS16BIT
# endif
# endif
#endif
/*
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
* than 64k bytes at a time (needed on systems with 16-bit int).
*/
#ifdef SYS16BIT
# define MAXSEG_64K
#endif
#ifdef MSDOS
# define UNALIGNED_OK
#endif
#ifdef __STDC_VERSION__
# ifndef STDC
# define STDC
# endif
# if __STDC_VERSION__ >= 199901L
# ifndef STDC99
# define STDC99
# endif
# endif
#endif
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
# define STDC
#endif
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
# define STDC
#endif
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
# define STDC
#endif
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
# define STDC
#endif
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
# define STDC
#endif
#ifndef STDC
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
# define const /* note: need a more gentle solution here */
# endif
#endif
/* Some Mac compilers merge all .h files incorrectly: */
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
# define NO_DUMMY_DECL
#endif
/* Maximum value for memLevel in deflateInit2 */
#ifndef MAX_MEM_LEVEL
# ifdef MAXSEG_64K
# define MAX_MEM_LEVEL 8
# else
# define MAX_MEM_LEVEL 9
# endif
#endif
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
* created by gzip. (Files created by minigzip can still be extracted by
* gzip.)
*/
#ifndef MAX_WBITS
# define MAX_WBITS 15 /* 32K LZ77 window */
#endif
/* The memory requirements for deflate are (in bytes):
(1 << (windowBits+2)) + (1 << (memLevel+9))
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
plus a few kilobytes for small objects. For example, if you want to reduce
the default memory requirements from 256K to 128K, compile with
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
Of course this will generally degrade compression (there's no free lunch).
The memory requirements for inflate are (in bytes) 1 << windowBits
that is, 32K for windowBits=15 (default value) plus a few kilobytes
for small objects.
*/
/* Type declarations */
#ifndef OF /* function prototypes */
# ifdef STDC
# define OF(args) args
# else
# define OF(args) ()
# endif
#endif
/* The following definitions for FAR are needed only for MSDOS mixed
* model programming (small or medium model with some far allocations).
* This was tested only with MSC; for other MSDOS compilers you may have
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
* just define FAR to be empty.
*/
#ifdef SYS16BIT
# if defined(M_I86SM) || defined(M_I86MM)
/* MSC small or medium model */
# define SMALL_MEDIUM
# ifdef _MSC_VER
# define FAR _far
# else
# define FAR far
# endif
# endif
# if (defined(__SMALL__) || defined(__MEDIUM__))
/* Turbo C small or medium model */
# define SMALL_MEDIUM
# ifdef __BORLANDC__
# define FAR _far
# else
# define FAR far
# endif
# endif
#endif
#if defined(WINDOWS) || defined(WIN32)
/* If building or using zlib as a DLL, define ZLIB_DLL.
* This is not mandatory, but it offers a little performance increase.
*/
# ifdef ZLIB_DLL
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
# ifdef ZLIB_INTERNAL
# define ZEXTERN extern __declspec(dllexport)
# else
# define ZEXTERN extern __declspec(dllimport)
# endif
# endif
# endif /* ZLIB_DLL */
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
* define ZLIB_WINAPI.
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
*/
# ifdef ZLIB_WINAPI
# ifdef FAR
# undef FAR
# endif
# include <windows.h>
/* No need for _export, use ZLIB.DEF instead. */
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
# define ZEXPORT WINAPI
# ifdef WIN32
# define ZEXPORTVA WINAPIV
# else
# define ZEXPORTVA FAR CDECL
# endif
# endif
#endif
#if defined (__BEOS__)
# ifdef ZLIB_DLL
# ifdef ZLIB_INTERNAL
# define ZEXPORT __declspec(dllexport)
# define ZEXPORTVA __declspec(dllexport)
# else
# define ZEXPORT __declspec(dllimport)
# define ZEXPORTVA __declspec(dllimport)
# endif
# endif
#endif
#ifndef ZEXTERN
# define ZEXTERN extern
#endif
#ifndef ZEXPORT
# define ZEXPORT
#endif
#ifndef ZEXPORTVA
# define ZEXPORTVA
#endif
#ifndef FAR
# define FAR
#endif
#if !defined(__MACTYPES__)
typedef unsigned char Byte; /* 8 bits */
#endif
typedef unsigned int uInt; /* 16 bits or more */
typedef unsigned long uLong; /* 32 bits or more */
#ifdef SMALL_MEDIUM
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
# define Bytef Byte FAR
#else
typedef Byte FAR Bytef;
#endif
typedef char FAR charf;
typedef int FAR intf;
typedef uInt FAR uIntf;
typedef uLong FAR uLongf;
#ifdef STDC
typedef void const *voidpc;
typedef void FAR *voidpf;
typedef void *voidp;
#else
typedef Byte const *voidpc;
typedef Byte FAR *voidpf;
typedef Byte *voidp;
#endif
#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
# include <sys/types.h> /* for off_t */
# include <unistd.h> /* for SEEK_* and off_t */
# ifdef VMS
# include <unixio.h> /* for off_t */
# endif
# define z_off_t off_t
#endif
#ifndef SEEK_SET
# define SEEK_SET 0 /* Seek from beginning of file. */
# define SEEK_CUR 1 /* Seek from current position. */
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
#endif
#ifndef z_off_t
# define z_off_t long
#endif
#if defined(__OS400__)
# define NO_vsnprintf
#endif
#if defined(__MVS__)
# define NO_vsnprintf
# ifdef FAR
# undef FAR
# endif
#endif
/* MVS linker does not support external names larger than 8 bytes */
#if defined(__MVS__)
# pragma map(deflateInit_,"DEIN")
# pragma map(deflateInit2_,"DEIN2")
# pragma map(deflateEnd,"DEEND")
# pragma map(deflateBound,"DEBND")
# pragma map(inflateInit_,"ININ")
# pragma map(inflateInit2_,"ININ2")
# pragma map(inflateEnd,"INEND")
# pragma map(inflateSync,"INSY")
# pragma map(inflateSetDictionary,"INSEDI")
# pragma map(compressBound,"CMBND")
# pragma map(inflate_table,"INTABL")
# pragma map(inflate_fast,"INFA")
# pragma map(inflate_copyright,"INCOPY")
#endif
#endif /* ZCONF_H */

646
zlib.h
View File

@@ -1,7 +1,7 @@
/* zlib.h -- interface of the 'zlib' general purpose compression library /* zlib.h -- interface of the 'zlib' general purpose compression library
version 1.1.4pc, March 2002 version 1.2.3, July 18th, 2005
Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@@ -24,26 +24,12 @@
The data format used by the zlib library is described by RFCs (Request for The data format used by the zlib library is described by RFCs (Request for
Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
(zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
*/ */
/* Changes from version 1.1.4 to version 1.1.4pc #ifndef ZLIB_H
* #define ZLIB_H
* The default value of TOO_FAR has been changed to 32767 in deflate.c
* Glenn Randers-Pehrson, February 2000.
*
* The switch statement in inflate.c was rearranged so that case BLOCKS is
* checked first. Glenn Randers-Pehrson, April 2001.
*
* Added tests for Windows platforms at line 136 in zutil.h, since some
* emulators will use MSC compiler on other platforms. Glenn Randers-Pehrson,
* May 2001. Suggested by Emmanuel Blot.
*
*/
#ifndef _ZLIB_H
#define _ZLIB_H
#include "zconf.h" #include "zconf.h"
@@ -51,7 +37,8 @@
extern "C" { extern "C" {
#endif #endif
#define ZLIB_VERSION "1.1.4pc" #define ZLIB_VERSION "1.2.3"
#define ZLIB_VERNUM 0x1230
/* /*
The 'zlib' compression library provides in-memory compression and The 'zlib' compression library provides in-memory compression and
@@ -66,8 +53,21 @@ extern "C" {
application must provide more input and/or consume the output application must provide more input and/or consume the output
(providing more output space) before each call. (providing more output space) before each call.
The compressed data format used by default by the in-memory functions is
the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
around a deflate stream, which is itself documented in RFC 1951.
The library also supports reading and writing files in gzip (.gz) format The library also supports reading and writing files in gzip (.gz) format
with an interface similar to that of stdio. with an interface similar to that of stdio using the functions that start
with "gz". The gzip format is different from the zlib format. gzip is a
gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
This library can optionally read and write gzip streams in memory as well.
The zlib format was designed to be compact and fast for use in memory
and on communications channels. The gzip format was designed for single-
file compression on file systems, has a larger header than zlib to maintain
directory information, and uses a different, slower check method than zlib.
The library does not install any signal handler. The decoder checks The library does not install any signal handler. The decoder checks
the consistency of the compressed data, so the library should never the consistency of the compressed data, so the library should never
@@ -95,13 +95,36 @@ typedef struct z_stream_s {
free_func zfree; /* used to free the internal state */ free_func zfree; /* used to free the internal state */
voidpf opaque; /* private data object passed to zalloc and zfree */ voidpf opaque; /* private data object passed to zalloc and zfree */
int data_type; /* best guess about the data type: ascii or binary */ int data_type; /* best guess about the data type: binary or text */
uLong adler; /* adler32 value of the uncompressed data */ uLong adler; /* adler32 value of the uncompressed data */
uLong reserved; /* reserved for future use */ uLong reserved; /* reserved for future use */
} z_stream; } z_stream;
typedef z_stream FAR *z_streamp; typedef z_stream FAR *z_streamp;
/*
gzip header information passed to and from zlib routines. See RFC 1952
for more details on the meanings of these fields.
*/
typedef struct gz_header_s {
int text; /* true if compressed data believed to be text */
uLong time; /* modification time */
int xflags; /* extra flags (not used when writing a gzip file) */
int os; /* operating system */
Bytef *extra; /* pointer to extra field or Z_NULL if none */
uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
uInt extra_max; /* space at extra (only when reading header) */
Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
uInt name_max; /* space at name (only when reading header) */
Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
uInt comm_max; /* space at comment (only when reading header) */
int hcrc; /* true if there was or will be a header crc */
int done; /* true when done reading gzip header (not used
when writing a gzip file) */
} gz_header;
typedef gz_header FAR *gz_headerp;
/* /*
The application must update next_in and avail_in when avail_in has The application must update next_in and avail_in when avail_in has
dropped to zero. It must update next_out and avail_out when avail_out dropped to zero. It must update next_out and avail_out when avail_out
@@ -141,7 +164,8 @@ typedef z_stream FAR *z_streamp;
#define Z_SYNC_FLUSH 2 #define Z_SYNC_FLUSH 2
#define Z_FULL_FLUSH 3 #define Z_FULL_FLUSH 3
#define Z_FINISH 4 #define Z_FINISH 4
/* Allowed flush values; see deflate() below for details */ #define Z_BLOCK 5
/* Allowed flush values; see deflate() and inflate() below for details */
#define Z_OK 0 #define Z_OK 0
#define Z_STREAM_END 1 #define Z_STREAM_END 1
@@ -164,13 +188,16 @@ typedef z_stream FAR *z_streamp;
#define Z_FILTERED 1 #define Z_FILTERED 1
#define Z_HUFFMAN_ONLY 2 #define Z_HUFFMAN_ONLY 2
#define Z_RLE 3
#define Z_FIXED 4
#define Z_DEFAULT_STRATEGY 0 #define Z_DEFAULT_STRATEGY 0
/* compression strategy; see deflateInit2() below for details */ /* compression strategy; see deflateInit2() below for details */
#define Z_BINARY 0 #define Z_BINARY 0
#define Z_ASCII 1 #define Z_TEXT 1
#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
#define Z_UNKNOWN 2 #define Z_UNKNOWN 2
/* Possible values of the data_type field */ /* Possible values of the data_type field (though see inflate()) */
#define Z_DEFLATED 8 #define Z_DEFLATED 8
/* The deflate compression method (the only one supported in this version) */ /* The deflate compression method (the only one supported in this version) */
@@ -242,6 +269,10 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
and with zero avail_out, it must be called again after making room in the and with zero avail_out, it must be called again after making room in the
output buffer because there might be more output pending. output buffer because there might be more output pending.
Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
decide how much data to accumualte before producing output, in order to
maximize compression.
If the parameter flush is set to Z_SYNC_FLUSH, all pending output is If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
flushed to the output buffer and the output is aligned on a byte boundary, so flushed to the output buffer and the output is aligned on a byte boundary, so
that the decompressor can get all input data available so far. (In particular that the decompressor can get all input data available so far. (In particular
@@ -253,12 +284,14 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
Z_SYNC_FLUSH, and the compression state is reset so that decompression can Z_SYNC_FLUSH, and the compression state is reset so that decompression can
restart from this point if previous compressed data has been damaged or if restart from this point if previous compressed data has been damaged or if
random access is desired. Using Z_FULL_FLUSH too often can seriously degrade random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
the compression. compression.
If deflate returns with avail_out == 0, this function must be called again If deflate returns with avail_out == 0, this function must be called again
with the same value of the flush parameter and more output space (updated with the same value of the flush parameter and more output space (updated
avail_out), until the flush is complete (deflate returns with non-zero avail_out), until the flush is complete (deflate returns with non-zero
avail_out). avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
avail_out is greater than six to avoid repeated flush markers due to
avail_out == 0 on return.
If the parameter flush is set to Z_FINISH, pending input is processed, If the parameter flush is set to Z_FINISH, pending input is processed,
pending output is flushed and deflate returns with Z_STREAM_END if there pending output is flushed and deflate returns with Z_STREAM_END if there
@@ -270,14 +303,14 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
Z_FINISH can be used immediately after deflateInit if all the compression Z_FINISH can be used immediately after deflateInit if all the compression
is to be done in a single step. In this case, avail_out must be at least is to be done in a single step. In this case, avail_out must be at least
0.1% larger than avail_in plus 12 bytes. If deflate does not return the value returned by deflateBound (see below). If deflate does not return
Z_STREAM_END, then it must be called again as described above. Z_STREAM_END, then it must be called again as described above.
deflate() sets strm->adler to the adler32 checksum of all input read deflate() sets strm->adler to the adler32 checksum of all input read
so far (that is, total_in bytes). so far (that is, total_in bytes).
deflate() may update data_type if it can make a good guess about deflate() may update strm->data_type if it can make a good guess about
the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
binary. This field is only for information purposes and does not affect binary. This field is only for information purposes and does not affect
the compression algorithm in any manner. the compression algorithm in any manner.
@@ -286,7 +319,9 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
consumed and all output has been produced (only when flush is set to consumed and all output has been produced (only when flush is set to
Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
(for example avail_in or avail_out was zero). (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
fatal, and deflate() can be called again with more input and more output
space to continue compressing.
*/ */
@@ -328,9 +363,9 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
/* /*
inflate decompresses as much data as possible, and stops when the input inflate decompresses as much data as possible, and stops when the input
buffer becomes empty or the output buffer becomes full. It may some buffer becomes empty or the output buffer becomes full. It may introduce
introduce some output latency (reading input without producing any output) some output latency (reading input without producing any output) except when
except when forced to flush. forced to flush.
The detailed semantics are as follows. inflate performs one or both of the The detailed semantics are as follows. inflate performs one or both of the
following actions: following actions:
@@ -354,11 +389,26 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
must be called again after making room in the output buffer because there must be called again after making room in the output buffer because there
might be more output pending. might be more output pending.
If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
output as possible to the output buffer. The flushing behavior of inflate is Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
not specified for values of the flush parameter other than Z_SYNC_FLUSH output as possible to the output buffer. Z_BLOCK requests that inflate() stop
and Z_FINISH, but the current implementation actually flushes as much output if and when it gets to the next deflate block boundary. When decoding the
as possible anyway. zlib or gzip format, this will cause inflate() to return immediately after
the header and before the first block. When doing a raw inflate, inflate()
will go ahead and process the first block, and will return when it gets to
the end of that block, or when it runs out of data.
The Z_BLOCK option assists in appending to or combining deflate streams.
Also to assist in this, on return inflate() will set strm->data_type to the
number of unused bits in the last byte taken from strm->next_in, plus 64
if inflate() is currently decoding the last block in the deflate stream,
plus 128 if inflate() returned immediately after decoding an end-of-block
code or decoding the complete header up to just before the first byte of the
deflate stream. The end-of-block will not be indicated until all of the
uncompressed data from that block has been written to strm->next_out. The
number of unused bits may in general be greater than seven, except when
bit 7 of data_type is set, in which case the number of unused bits will be
less than eight.
inflate() should normally be called until it returns Z_STREAM_END or an inflate() should normally be called until it returns Z_STREAM_END or an
error. However if all decompression is to be performed in a single step error. However if all decompression is to be performed in a single step
@@ -368,29 +418,44 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
uncompressed data. (The size of the uncompressed data may have been saved uncompressed data. (The size of the uncompressed data may have been saved
by the compressor for this purpose.) The next operation on this stream must by the compressor for this purpose.) The next operation on this stream must
be inflateEnd to deallocate the decompression state. The use of Z_FINISH be inflateEnd to deallocate the decompression state. The use of Z_FINISH
is never required, but can be used to inform inflate that a faster routine is never required, but can be used to inform inflate that a faster approach
may be used for the single inflate() call. may be used for the single inflate() call.
If a preset dictionary is needed at this point (see inflateSetDictionary In this implementation, inflate() always flushes as much output as
below), inflate sets strm-adler to the adler32 checksum of the possible to the output buffer, and always uses the faster approach on the
dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise first call. So the only effect of the flush parameter in this implementation
it sets strm->adler to the adler32 checksum of all output produced is on the return value of inflate(), as noted below, or when it returns early
so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or because Z_BLOCK is used.
an error code as described below. At the end of the stream, inflate()
checks that its computed adler32 checksum is equal to that saved by the If a preset dictionary is needed after this call (see inflateSetDictionary
compressor and returns Z_STREAM_END only if the checksum is correct. below), inflate sets strm->adler to the adler32 checksum of the dictionary
chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
strm->adler to the adler32 checksum of all output produced so far (that is,
total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
below. At the end of the stream, inflate() checks that its computed adler32
checksum is equal to that saved by the compressor and returns Z_STREAM_END
only if the checksum is correct.
inflate() will decompress and check either zlib-wrapped or gzip-wrapped
deflate data. The header type is detected automatically. Any information
contained in the gzip header is not retained, so applications that need that
information should instead use raw inflate, see inflateInit2() below, or
inflateBack() and perform their own processing of the gzip header and
trailer.
inflate() returns Z_OK if some progress has been made (more input processed inflate() returns Z_OK if some progress has been made (more input processed
or more output produced), Z_STREAM_END if the end of the compressed data has or more output produced), Z_STREAM_END if the end of the compressed data has
been reached and all uncompressed output has been produced, Z_NEED_DICT if a been reached and all uncompressed output has been produced, Z_NEED_DICT if a
preset dictionary is needed at this point, Z_DATA_ERROR if the input data was preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
corrupted (input stream not conforming to the zlib format or incorrect corrupted (input stream not conforming to the zlib format or incorrect check
adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
(for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
enough memory, Z_BUF_ERROR if no progress is possible or if there was not Z_BUF_ERROR if no progress is possible or if there was not enough room in the
enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
case, the application may then call inflateSync to look for a good inflate() can be called again with more input and more output space to
compression block. continue decompressing. If Z_DATA_ERROR is returned, the application may then
call inflateSync() to look for a good compression block if a partial recovery
of the data is desired.
*/ */
@@ -432,6 +497,17 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
compression at the expense of memory usage. The default value is 15 if compression at the expense of memory usage. The default value is 15 if
deflateInit is used instead. deflateInit is used instead.
windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
determines the window size. deflate() will then generate raw deflate data
with no zlib header or trailer, and will not compute an adler32 check value.
windowBits can also be greater than 15 for optional gzip encoding. Add
16 to windowBits to write a simple gzip header and trailer around the
compressed data instead of a zlib wrapper. The gzip header will have no
file name, no extra data, no comment, no modification time (set to zero),
no header crc, and the operating system will be set to 255 (unknown). If a
gzip stream is being written, strm->adler is a crc32 instead of an adler32.
The memLevel parameter specifies how much memory should be allocated The memLevel parameter specifies how much memory should be allocated
for the internal compression state. memLevel=1 uses minimum memory but for the internal compression state. memLevel=1 uses minimum memory but
is slow and reduces compression ratio; memLevel=9 uses maximum memory is slow and reduces compression ratio; memLevel=9 uses maximum memory
@@ -440,14 +516,18 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
The strategy parameter is used to tune the compression algorithm. Use the The strategy parameter is used to tune the compression algorithm. Use the
value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
string match). Filtered data consists mostly of small values with a string match), or Z_RLE to limit match distances to one (run-length
somewhat random distribution. In this case, the compression algorithm is encoding). Filtered data consists mostly of small values with a somewhat
tuned to compress them better. The effect of Z_FILTERED is to force more random distribution. In this case, the compression algorithm is tuned to
Huffman coding and less string matching; it is somewhat intermediate compress them better. The effect of Z_FILTERED is to force more Huffman
between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects coding and less string matching; it is somewhat intermediate between
the compression ratio but not the correctness of the compressed output even Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
if it is not set appropriately. Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
parameter only affects the compression ratio but not the correctness of the
compressed output even if it is not set appropriately. Z_FIXED prevents the
use of dynamic Huffman codes, allowing for a simpler decoder for special
applications.
deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
@@ -476,13 +556,16 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
deflateInit or deflateInit2, a part of the dictionary may in effect be deflateInit or deflateInit2, a part of the dictionary may in effect be
discarded, for example if the dictionary is larger than the window size in discarded, for example if the dictionary is larger than the window size in
deflate or deflate2. Thus the strings most likely to be useful should be deflate or deflate2. Thus the strings most likely to be useful should be
put at the end of the dictionary, not at the front. put at the end of the dictionary, not at the front. In addition, the
current implementation of deflate will use at most the window size minus
262 bytes of the provided dictionary.
Upon return of this function, strm->adler is set to the Adler32 value Upon return of this function, strm->adler is set to the adler32 value
of the dictionary; the decompressor may later use this value to determine of the dictionary; the decompressor may later use this value to determine
which dictionary has been used by the compressor. (The Adler32 value which dictionary has been used by the compressor. (The adler32 value
applies to the whole dictionary even if only a subset of the dictionary is applies to the whole dictionary even if only a subset of the dictionary is
actually used by the compressor.) actually used by the compressor.) If a raw deflate was requested, then the
adler32 value is not computed and strm->adler is not set.
deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
parameter is invalid (such as NULL dictionary) or the stream state is parameter is invalid (such as NULL dictionary) or the stream state is
@@ -541,6 +624,72 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
if strm->avail_out was zero. if strm->avail_out was zero.
*/ */
ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
int good_length,
int max_lazy,
int nice_length,
int max_chain));
/*
Fine tune deflate's internal compression parameters. This should only be
used by someone who understands the algorithm used by zlib's deflate for
searching for the best matching string, and even then only by the most
fanatic optimizer trying to squeeze out the last compressed bit for their
specific input data. Read the deflate.c source code for the meaning of the
max_lazy, good_length, nice_length, and max_chain parameters.
deflateTune() can be called after deflateInit() or deflateInit2(), and
returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
*/
ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
uLong sourceLen));
/*
deflateBound() returns an upper bound on the compressed size after
deflation of sourceLen bytes. It must be called after deflateInit()
or deflateInit2(). This would be used to allocate an output buffer
for deflation in a single pass, and so would be called before deflate().
*/
ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
int bits,
int value));
/*
deflatePrime() inserts bits in the deflate output stream. The intent
is that this function is used to start off the deflate output with the
bits leftover from a previous deflate stream when appending to it. As such,
this function can only be used for raw deflate, and must be used before the
first deflate() call after a deflateInit2() or deflateReset(). bits must be
less than or equal to 16, and that many of the least significant bits of
value will be inserted in the output.
deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent.
*/
ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
gz_headerp head));
/*
deflateSetHeader() provides gzip header information for when a gzip
stream is requested by deflateInit2(). deflateSetHeader() may be called
after deflateInit2() or deflateReset() and before the first call of
deflate(). The text, time, os, extra field, name, and comment information
in the provided gz_header structure are written to the gzip header (xflag is
ignored -- the extra flags are set according to the compression level). The
caller must assure that, if not Z_NULL, name and comment are terminated with
a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
available there. If hcrc is true, a gzip header crc is included. Note that
the current versions of the command-line version of gzip (up through version
1.3.x) do not support header crc's, and will report that it is a "multi-part
gzip file" and give up.
If deflateSetHeader is not used, the default gzip header has text false,
the time set to zero, and os set to 255, with no extra, name, or comment
fields. The gzip header is returned to the default state by deflateReset().
deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent.
*/
/* /*
ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
int windowBits)); int windowBits));
@@ -552,16 +701,36 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
The windowBits parameter is the base two logarithm of the maximum window The windowBits parameter is the base two logarithm of the maximum window
size (the size of the history buffer). It should be in the range 8..15 for size (the size of the history buffer). It should be in the range 8..15 for
this version of the library. The default value is 15 if inflateInit is used this version of the library. The default value is 15 if inflateInit is used
instead. If a compressed stream with a larger window size is given as instead. windowBits must be greater than or equal to the windowBits value
input, inflate() will return with the error code Z_DATA_ERROR instead of provided to deflateInit2() while compressing, or it must be equal to 15 if
trying to allocate a larger window. deflateInit2() was not used. If a compressed stream with a larger window
size is given as input, inflate() will return with the error code
Z_DATA_ERROR instead of trying to allocate a larger window.
windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
determines the window size. inflate() will then process raw deflate data,
not looking for a zlib or gzip header, not generating a check value, and not
looking for any check values for comparison at the end of the stream. This
is for use with other formats that use the deflate compressed data format
such as zip. Those formats provide their own check values. If a custom
format is developed using the raw deflate format for compressed data, it is
recommended that a check value such as an adler32 or a crc32 be applied to
the uncompressed data as is done in the zlib, gzip, and zip formats. For
most applications, the zlib format should be used as is. Note that comments
above on the use in deflateInit2() applies to the magnitude of windowBits.
windowBits can also be greater than 15 for optional gzip decoding. Add
32 to windowBits to enable zlib and gzip decoding with automatic header
detection, or add 16 to decode only the gzip format (the zlib format will
return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
a crc32 instead of an adler32.
inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
memLevel). msg is set to null if there is no error message. inflateInit2 is set to null if there is no error message. inflateInit2 does not perform
does not perform any decompression apart from reading the zlib header if any decompression apart from reading the zlib header if present: this will
present: this will be done by inflate(). (So next_in and avail_in may be be done by inflate(). (So next_in and avail_in may be modified, but next_out
modified, but next_out and avail_out are unchanged.) and avail_out are unchanged.)
*/ */
ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
@@ -569,16 +738,19 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
uInt dictLength)); uInt dictLength));
/* /*
Initializes the decompression dictionary from the given uncompressed byte Initializes the decompression dictionary from the given uncompressed byte
sequence. This function must be called immediately after a call of inflate sequence. This function must be called immediately after a call of inflate,
if this call returned Z_NEED_DICT. The dictionary chosen by the compressor if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
can be determined from the Adler32 value returned by this call of can be determined from the adler32 value returned by that call of inflate.
inflate. The compressor and decompressor must use exactly the same The compressor and decompressor must use exactly the same dictionary (see
dictionary (see deflateSetDictionary). deflateSetDictionary). For raw inflate, this function can be called
immediately after inflateInit2() or inflateReset() and before any call of
inflate() to set the dictionary. The application must insure that the
dictionary that was used for compression is provided.
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
parameter is invalid (such as NULL dictionary) or the stream state is parameter is invalid (such as NULL dictionary) or the stream state is
inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
expected one (incorrect Adler32 value). inflateSetDictionary does not expected one (incorrect adler32 value). inflateSetDictionary does not
perform any decompression: this will be done by subsequent calls of perform any decompression: this will be done by subsequent calls of
inflate(). inflate().
*/ */
@@ -598,6 +770,22 @@ ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
until success or end of the input data. until success or end of the input data.
*/ */
ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
z_streamp source));
/*
Sets the destination stream as a complete copy of the source stream.
This function can be useful when randomly accessing a large stream. The
first pass through the stream can periodically record the inflate state,
allowing restarting inflate at those points when randomly accessing the
stream.
inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
(such as zalloc being NULL). msg is left unchanged in both source and
destination.
*/
ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
/* /*
This function is equivalent to inflateEnd followed by inflateInit, This function is equivalent to inflateEnd followed by inflateInit,
@@ -608,6 +796,205 @@ ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
stream state was inconsistent (such as zalloc or state being NULL). stream state was inconsistent (such as zalloc or state being NULL).
*/ */
ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
int bits,
int value));
/*
This function inserts bits in the inflate input stream. The intent is
that this function is used to start inflating at a bit position in the
middle of a byte. The provided bits will be used before any bytes are used
from next_in. This function should only be used with raw inflate, and
should be used before the first inflate() call after inflateInit2() or
inflateReset(). bits must be less than or equal to 16, and that many of the
least significant bits of value will be inserted in the input.
inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent.
*/
ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
gz_headerp head));
/*
inflateGetHeader() requests that gzip header information be stored in the
provided gz_header structure. inflateGetHeader() may be called after
inflateInit2() or inflateReset(), and before the first call of inflate().
As inflate() processes the gzip stream, head->done is zero until the header
is completed, at which time head->done is set to one. If a zlib stream is
being decoded, then head->done is set to -1 to indicate that there will be
no gzip header information forthcoming. Note that Z_BLOCK can be used to
force inflate() to return immediately after header processing is complete
and before any actual data is decompressed.
The text, time, xflags, and os fields are filled in with the gzip header
contents. hcrc is set to true if there is a header CRC. (The header CRC
was valid if done is set to one.) If extra is not Z_NULL, then extra_max
contains the maximum number of bytes to write to extra. Once done is true,
extra_len contains the actual extra field length, and extra contains the
extra field, or that field truncated if extra_max is less than extra_len.
If name is not Z_NULL, then up to name_max characters are written there,
terminated with a zero unless the length is greater than name_max. If
comment is not Z_NULL, then up to comm_max characters are written there,
terminated with a zero unless the length is greater than comm_max. When
any of extra, name, or comment are not Z_NULL and the respective field is
not present in the header, then that field is set to Z_NULL to signal its
absence. This allows the use of deflateSetHeader() with the returned
structure to duplicate the header. However if those fields are set to
allocated memory, then the application will need to save those pointers
elsewhere so that they can be eventually freed.
If inflateGetHeader is not used, then the header information is simply
discarded. The header is always checked for validity, including the header
CRC if present. inflateReset() will reset the process to discard the header
information. The application would need to call inflateGetHeader() again to
retrieve the header from the next gzip stream.
inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent.
*/
/*
ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
unsigned char FAR *window));
Initialize the internal stream state for decompression using inflateBack()
calls. The fields zalloc, zfree and opaque in strm must be initialized
before the call. If zalloc and zfree are Z_NULL, then the default library-
derived memory allocation routines are used. windowBits is the base two
logarithm of the window size, in the range 8..15. window is a caller
supplied buffer of that size. Except for special applications where it is
assured that deflate was used with small window sizes, windowBits must be 15
and a 32K byte window must be supplied to be able to decompress general
deflate streams.
See inflateBack() for the usage of these routines.
inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
the paramaters are invalid, Z_MEM_ERROR if the internal state could not
be allocated, or Z_VERSION_ERROR if the version of the library does not
match the version of the header file.
*/
typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
in_func in, void FAR *in_desc,
out_func out, void FAR *out_desc));
/*
inflateBack() does a raw inflate with a single call using a call-back
interface for input and output. This is more efficient than inflate() for
file i/o applications in that it avoids copying between the output and the
sliding window by simply making the window itself the output buffer. This
function trusts the application to not change the output buffer passed by
the output function, at least until inflateBack() returns.
inflateBackInit() must be called first to allocate the internal state
and to initialize the state with the user-provided window buffer.
inflateBack() may then be used multiple times to inflate a complete, raw
deflate stream with each call. inflateBackEnd() is then called to free
the allocated state.
A raw deflate stream is one with no zlib or gzip header or trailer.
This routine would normally be used in a utility that reads zip or gzip
files and writes out uncompressed files. The utility would decode the
header and process the trailer on its own, hence this routine expects
only the raw deflate stream to decompress. This is different from the
normal behavior of inflate(), which expects either a zlib or gzip header and
trailer around the deflate stream.
inflateBack() uses two subroutines supplied by the caller that are then
called by inflateBack() for input and output. inflateBack() calls those
routines until it reads a complete deflate stream and writes out all of the
uncompressed data, or until it encounters an error. The function's
parameters and return types are defined above in the in_func and out_func
typedefs. inflateBack() will call in(in_desc, &buf) which should return the
number of bytes of provided input, and a pointer to that input in buf. If
there is no input available, in() must return zero--buf is ignored in that
case--and inflateBack() will return a buffer error. inflateBack() will call
out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
should return zero on success, or non-zero on failure. If out() returns
non-zero, inflateBack() will return with an error. Neither in() nor out()
are permitted to change the contents of the window provided to
inflateBackInit(), which is also the buffer that out() uses to write from.
The length written by out() will be at most the window size. Any non-zero
amount of input may be provided by in().
For convenience, inflateBack() can be provided input on the first call by
setting strm->next_in and strm->avail_in. If that input is exhausted, then
in() will be called. Therefore strm->next_in must be initialized before
calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
must also be initialized, and then if strm->avail_in is not zero, input will
initially be taken from strm->next_in[0 .. strm->avail_in - 1].
The in_desc and out_desc parameters of inflateBack() is passed as the
first parameter of in() and out() respectively when they are called. These
descriptors can be optionally used to pass any information that the caller-
supplied in() and out() functions need to do their job.
On return, inflateBack() will set strm->next_in and strm->avail_in to
pass back any unused input that was provided by the last in() call. The
return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
if in() or out() returned an error, Z_DATA_ERROR if there was a format
error in the deflate stream (in which case strm->msg is set to indicate the
nature of the error), or Z_STREAM_ERROR if the stream was not properly
initialized. In the case of Z_BUF_ERROR, an input or output error can be
distinguished using strm->next_in which will be Z_NULL only if in() returned
an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
out() returning non-zero. (in() will always be called before out(), so
strm->next_in is assured to be defined if out() returns non-zero.) Note
that inflateBack() cannot return Z_OK.
*/
ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
/*
All memory allocated by inflateBackInit() is freed.
inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
state was inconsistent.
*/
ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
/* Return flags indicating compile-time options.
Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
1.0: size of uInt
3.2: size of uLong
5.4: size of voidpf (pointer)
7.6: size of z_off_t
Compiler, assembler, and debug options:
8: DEBUG
9: ASMV or ASMINF -- use ASM code
10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
11: 0 (reserved)
One-time table building (smaller code, but not thread-safe if true):
12: BUILDFIXED -- build static block decoding tables when needed
13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
14,15: 0 (reserved)
Library content (indicates missing functionality):
16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
deflate code when not needed)
17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
and decode gzip streams (to avoid linking crc code)
18-19: 0 (reserved)
Operation variations (changes in library functionality):
20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
21: FASTEST -- deflate algorithm with only one, lowest compression level
22,23: 0 (reserved)
The sprintf variant used by gzprintf (zero is best):
24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
26: 0 = returns value, 1 = void -- 1 means inferred string length returned
Remainder:
27-31: 0 (reserved)
*/
/* utility functions */ /* utility functions */
@@ -624,8 +1011,8 @@ ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
/* /*
Compresses the source buffer into the destination buffer. sourceLen is Compresses the source buffer into the destination buffer. sourceLen is
the byte length of the source buffer. Upon entry, destLen is the total the byte length of the source buffer. Upon entry, destLen is the total
size of the destination buffer, which must be at least 0.1% larger than size of the destination buffer, which must be at least the value returned
sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the by compressBound(sourceLen). Upon exit, destLen is the actual size of the
compressed buffer. compressed buffer.
This function can be used to compress a whole file at once if the This function can be used to compress a whole file at once if the
input file is mmap'ed. input file is mmap'ed.
@@ -641,14 +1028,22 @@ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
Compresses the source buffer into the destination buffer. The level Compresses the source buffer into the destination buffer. The level
parameter has the same meaning as in deflateInit. sourceLen is the byte parameter has the same meaning as in deflateInit. sourceLen is the byte
length of the source buffer. Upon entry, destLen is the total size of the length of the source buffer. Upon entry, destLen is the total size of the
destination buffer, which must be at least 0.1% larger than sourceLen plus destination buffer, which must be at least the value returned by
12 bytes. Upon exit, destLen is the actual size of the compressed buffer. compressBound(sourceLen). Upon exit, destLen is the actual size of the
compressed buffer.
compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_BUF_ERROR if there was not enough room in the output buffer, memory, Z_BUF_ERROR if there was not enough room in the output buffer,
Z_STREAM_ERROR if the level parameter is invalid. Z_STREAM_ERROR if the level parameter is invalid.
*/ */
ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
/*
compressBound() returns an upper bound on the compressed size after
compress() or compress2() on sourceLen bytes. It would be used before
a compress() or compress2() call to allocate the destination buffer.
*/
ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen)); const Bytef *source, uLong sourceLen));
/* /*
@@ -664,7 +1059,7 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output enough memory, Z_BUF_ERROR if there was not enough room in the output
buffer, or Z_DATA_ERROR if the input data was corrupted. buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
*/ */
@@ -675,8 +1070,9 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
Opens a gzip (.gz) file for reading or writing. The mode parameter Opens a gzip (.gz) file for reading or writing. The mode parameter
is as in fopen ("rb" or "wb") but can also include a compression level is as in fopen ("rb" or "wb") but can also include a compression level
("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
Huffman only compression as in "wb1h". (See the description Huffman only compression as in "wb1h", or 'R' for run-length encoding
of deflateInit2 for more information about the strategy parameter.) as in "wb1R". (See the description of deflateInit2 for more information
about the strategy parameter.)
gzopen can be used to read a file which is not in gzip format; in this gzopen can be used to read a file which is not in gzip format; in this
case gzread will directly read from the file without decompression. case gzread will directly read from the file without decompression.
@@ -716,7 +1112,7 @@ ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
end of file, -1 for error). */ end of file, -1 for error). */
ZEXTERN int ZEXPORT gzwrite OF((gzFile file, ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
const voidp buf, unsigned len)); voidpc buf, unsigned len));
/* /*
Writes the given number of uncompressed bytes into the compressed file. Writes the given number of uncompressed bytes into the compressed file.
gzwrite returns the number of uncompressed bytes actually written gzwrite returns the number of uncompressed bytes actually written
@@ -727,7 +1123,13 @@ ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
/* /*
Converts, formats, and writes the args to the compressed file under Converts, formats, and writes the args to the compressed file under
control of the format string, as in fprintf. gzprintf returns the number of control of the format string, as in fprintf. gzprintf returns the number of
uncompressed bytes actually written (0 in case of error). uncompressed bytes actually written (0 in case of error). The number of
uncompressed bytes written is limited to 4095. The caller should assure that
this limit is not exceeded. If it is exceeded, then gzprintf() will return
return an error (0) with nothing written. In this case, there may also be a
buffer overflow with unpredictable consequences, which is possible only if
zlib was compiled with the insecure functions sprintf() or vsprintf()
because the secure snprintf() or vsnprintf() functions were not available.
*/ */
ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
@@ -758,6 +1160,16 @@ ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
or -1 in case of end of file or error. or -1 in case of end of file or error.
*/ */
ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
/*
Push one character back onto the stream to be read again later.
Only one character of push-back is allowed. gzungetc() returns the
character pushed, or -1 on failure. gzungetc() will fail if a
character has been pushed but not read yet, or if c is -1. The pushed
character will be discarded if the stream is repositioned with gzseek()
or gzrewind().
*/
ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
/* /*
Flushes all pending output into the compressed file. The parameter Flushes all pending output into the compressed file. The parameter
@@ -808,6 +1220,12 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file));
input stream, otherwise zero. input stream, otherwise zero.
*/ */
ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
/*
Returns 1 if file is being read directly without decompression, otherwise
zero.
*/
ZEXTERN int ZEXPORT gzclose OF((gzFile file)); ZEXTERN int ZEXPORT gzclose OF((gzFile file));
/* /*
Flushes all pending output if necessary, closes the compressed file Flushes all pending output if necessary, closes the compressed file
@@ -824,6 +1242,13 @@ ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
to get the exact error code. to get the exact error code.
*/ */
ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
/*
Clears the error and end-of-file flags for file. This is analogous to the
clearerr() function in stdio. This is useful for continuing to read a gzip
file that is being written concurrently.
*/
/* checksum functions */ /* checksum functions */
/* /*
@@ -833,7 +1258,6 @@ ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
*/ */
ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
/* /*
Update a running Adler-32 checksum with the bytes buf[0..len-1] and Update a running Adler-32 checksum with the bytes buf[0..len-1] and
return the updated checksum. If buf is NULL, this function returns return the updated checksum. If buf is NULL, this function returns
@@ -849,12 +1273,21 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
if (adler != original_adler) error(); if (adler != original_adler) error();
*/ */
ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
z_off_t len2));
/*
Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
*/
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
/* /*
Update a running crc with the bytes buf[0..len-1] and return the updated Update a running CRC-32 with the bytes buf[0..len-1] and return the
crc. If buf is NULL, this function returns the required initial value updated CRC-32. If buf is NULL, this function returns the required initial
for the crc. Pre- and post-conditioning (one's complement) is performed value for the for the crc. Pre- and post-conditioning (one's complement) is
within this function so it shouldn't be done by the application. performed within this function so it shouldn't be done by the application.
Usage example: Usage example:
uLong crc = crc32(0L, Z_NULL, 0); uLong crc = crc32(0L, Z_NULL, 0);
@@ -865,6 +1298,16 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
if (crc != original_crc) error(); if (crc != original_crc) error();
*/ */
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
/*
Combine two CRC-32 check values into one. For two sequences of bytes,
seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
len2.
*/
/* various hacks, don't look :) */ /* various hacks, don't look :) */
@@ -881,6 +1324,10 @@ ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
int stream_size)); int stream_size));
ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
const char *version, int stream_size)); const char *version, int stream_size));
ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
unsigned char FAR *window,
const char *version,
int stream_size));
#define deflateInit(strm, level) \ #define deflateInit(strm, level) \
deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
#define inflateInit(strm) \ #define inflateInit(strm) \
@@ -890,13 +1337,16 @@ ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
(strategy), ZLIB_VERSION, sizeof(z_stream)) (strategy), ZLIB_VERSION, sizeof(z_stream))
#define inflateInit2(strm, windowBits) \ #define inflateInit2(strm, windowBits) \
inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
#define inflateBackInit(strm, windowBits, window) \
inflateBackInit_((strm), (windowBits), (window), \
ZLIB_VERSION, sizeof(z_stream))
#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) #if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
struct internal_state {int dummy;}; /* hack for buggy compilers */ struct internal_state {int dummy;}; /* hack for buggy compilers */
#endif #endif
ZEXTERN const char * ZEXPORT zError OF((int err)); ZEXTERN const char * ZEXPORT zError OF((int));
ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
@@ -904,4 +1354,4 @@ ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
} }
#endif #endif
#endif /* _ZLIB_H */ #endif /* ZLIB_H */

130
zutil.c
View File

@@ -1,5 +1,5 @@
/* zutil.c -- target dependent utility functions for the compression library /* zutil.c -- target dependent utility functions for the compression library
* Copyright (C) 1995-1998 Jean-loup Gailly. * Copyright (C) 1995-2005 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -7,13 +7,11 @@
#include "zutil.h" #include "zutil.h"
#ifndef NO_DUMMY_DECL
struct internal_state {int dummy;}; /* for buggy compilers */ struct internal_state {int dummy;}; /* for buggy compilers */
#ifndef STDC
extern void exit OF((int));
#endif #endif
const char *z_errmsg[10] = { const char * const z_errmsg[10] = {
"need dictionary", /* Z_NEED_DICT 2 */ "need dictionary", /* Z_NEED_DICT 2 */
"stream end", /* Z_STREAM_END 1 */ "stream end", /* Z_STREAM_END 1 */
"", /* Z_OK 0 */ "", /* Z_OK 0 */
@@ -31,6 +29,89 @@ const char * ZEXPORT zlibVersion()
return ZLIB_VERSION; return ZLIB_VERSION;
} }
uLong ZEXPORT zlibCompileFlags()
{
uLong flags;
flags = 0;
switch (sizeof(uInt)) {
case 2: break;
case 4: flags += 1; break;
case 8: flags += 2; break;
default: flags += 3;
}
switch (sizeof(uLong)) {
case 2: break;
case 4: flags += 1 << 2; break;
case 8: flags += 2 << 2; break;
default: flags += 3 << 2;
}
switch (sizeof(voidpf)) {
case 2: break;
case 4: flags += 1 << 4; break;
case 8: flags += 2 << 4; break;
default: flags += 3 << 4;
}
switch (sizeof(z_off_t)) {
case 2: break;
case 4: flags += 1 << 6; break;
case 8: flags += 2 << 6; break;
default: flags += 3 << 6;
}
#ifdef DEBUG
flags += 1 << 8;
#endif
#if defined(ASMV) || defined(ASMINF)
flags += 1 << 9;
#endif
#ifdef ZLIB_WINAPI
flags += 1 << 10;
#endif
#ifdef BUILDFIXED
flags += 1 << 12;
#endif
#ifdef DYNAMIC_CRC_TABLE
flags += 1 << 13;
#endif
#ifdef NO_GZCOMPRESS
flags += 1L << 16;
#endif
#ifdef NO_GZIP
flags += 1L << 17;
#endif
#ifdef PKZIP_BUG_WORKAROUND
flags += 1L << 20;
#endif
#ifdef FASTEST
flags += 1L << 21;
#endif
#ifdef STDC
# ifdef NO_vsnprintf
flags += 1L << 25;
# ifdef HAS_vsprintf_void
flags += 1L << 26;
# endif
# else
# ifdef HAS_vsnprintf_void
flags += 1L << 26;
# endif
# endif
#else
flags += 1L << 24;
# ifdef NO_snprintf
flags += 1L << 25;
# ifdef HAS_sprintf_void
flags += 1L << 26;
# endif
# else
# ifdef HAS_snprintf_void
flags += 1L << 26;
# endif
# endif
#endif
return flags;
}
#ifdef DEBUG #ifdef DEBUG
# ifndef verbose # ifndef verbose
@@ -55,6 +136,13 @@ const char * ZEXPORT zError(err)
return ERR_MSG(err); return ERR_MSG(err);
} }
#if defined(_WIN32_WCE)
/* The Microsoft C Run-Time Library for Windows CE doesn't have
* errno. We define it as a global variable to simplify porting.
* Its value is always 0 and should not be used.
*/
int errno = 0;
#endif
#ifndef HAVE_MEMCPY #ifndef HAVE_MEMCPY
@@ -93,11 +181,12 @@ void zmemzero(dest, len)
} }
#endif #endif
#ifdef SYS16BIT
#ifdef __TURBOC__ #ifdef __TURBOC__
#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__) /* Turbo C in 16-bit mode */
/* Small and medium model in Turbo C are for now limited to near allocation
* with reduced MAX_WBITS and MAX_MEM_LEVEL
*/
# define MY_ZCALLOC # define MY_ZCALLOC
/* Turbo C malloc() does not allow dynamic allocation of 64K bytes /* Turbo C malloc() does not allow dynamic allocation of 64K bytes
@@ -169,11 +258,11 @@ void zcfree (voidpf opaque, voidpf ptr)
ptr = opaque; /* just to make some compilers happy */ ptr = opaque; /* just to make some compilers happy */
Assert(0, "zcfree: ptr not found"); Assert(0, "zcfree: ptr not found");
} }
#endif
#endif /* __TURBOC__ */ #endif /* __TURBOC__ */
#if defined(M_I86) && !defined(__32BIT__) #ifdef M_I86
/* Microsoft C in 16-bit mode */ /* Microsoft C in 16-bit mode */
# define MY_ZCALLOC # define MY_ZCALLOC
@@ -195,14 +284,16 @@ void zcfree (voidpf opaque, voidpf ptr)
_hfree(ptr); _hfree(ptr);
} }
#endif /* MSC */ #endif /* M_I86 */
#endif /* SYS16BIT */
#ifndef MY_ZCALLOC /* Any system without a special alloc function */ #ifndef MY_ZCALLOC /* Any system without a special alloc function */
#ifndef STDC #ifndef STDC
extern voidp malloc OF((uInt size));
extern voidp calloc OF((uInt items, uInt size)); extern voidp calloc OF((uInt items, uInt size));
extern voidp malloc OF((uInt items));
extern void free OF((voidpf ptr)); extern void free OF((voidpf ptr));
#endif #endif
@@ -212,17 +303,8 @@ voidpf zcalloc (opaque, items, size)
unsigned size; unsigned size;
{ {
if (opaque) items += size - size; /* make compiler happy */ if (opaque) items += size - size; /* make compiler happy */
return (voidpf)calloc(items, size); return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
} (voidpf)calloc(items, size);
/* added to version 1.1.3pc -- glennrp */
voidpf zmalloc (opaque, items, size)
voidpf opaque;
unsigned items;
unsigned size;
{
if (opaque) items += size - size; /* make compiler happy */
return (voidpf)malloc(items * size);
} }
void zcfree (opaque, ptr) void zcfree (opaque, ptr)

113
zutil.h
View File

@@ -1,5 +1,5 @@
/* zutil.h -- internal interface and configuration of the compression library /* zutil.h -- internal interface and configuration of the compression library
* Copyright (C) 1995-1998 Jean-loup Gailly. * Copyright (C) 1995-2005 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -8,25 +8,36 @@
subject to change. Applications should only use zlib.h. subject to change. Applications should only use zlib.h.
*/ */
/* Added tests for Windows platforms at line 136. glennrp, May 2001 */
/* @(#) $Id$ */ /* @(#) $Id$ */
#ifndef _Z_UTIL_H #ifndef ZUTIL_H
#define _Z_UTIL_H #define ZUTIL_H
#define ZLIB_INTERNAL
#include "zlib.h" #include "zlib.h"
#ifdef STDC #ifdef STDC
# ifndef _WIN32_WCE
# include <stddef.h> # include <stddef.h>
# endif
# include <string.h> # include <string.h>
# include <stdlib.h> # include <stdlib.h>
#endif #endif
#ifdef NO_ERRNO_H #ifdef NO_ERRNO_H
# ifdef _WIN32_WCE
/* The Microsoft C Run-Time Library for Windows CE doesn't have
* errno. We define it as a global variable to simplify porting.
* Its value is always 0 and should not be used. We rename it to
* avoid conflict with other libraries that use the same workaround.
*/
# define errno z_errno
# endif
extern int errno; extern int errno;
#else #else
# ifndef _WIN32_WCE
# include <errno.h> # include <errno.h>
# endif # endif
#endif
#ifndef local #ifndef local
# define local static # define local static
@@ -39,7 +50,7 @@ typedef unsigned short ush;
typedef ush FAR ushf; typedef ush FAR ushf;
typedef unsigned long ulg; typedef unsigned long ulg;
extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
/* (size given to avoid silly warnings with Visual C++) */ /* (size given to avoid silly warnings with Visual C++) */
#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] #define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
@@ -75,7 +86,7 @@ extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
/* target dependencies */ /* target dependencies */
#ifdef MSDOS #if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
# define OS_CODE 0x00 # define OS_CODE 0x00
# if defined(__TURBOC__) || defined(__BORLANDC__) # if defined(__TURBOC__) || defined(__BORLANDC__)
# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) # if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
@@ -90,12 +101,8 @@ extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
# endif # endif
#endif #endif
#ifdef OS2 #ifdef AMIGA
# define OS_CODE 0x06 # define OS_CODE 0x01
#endif
#ifdef WIN32 /* Window 95 & Windows NT */
# define OS_CODE 0x0b
#endif #endif
#if defined(VAXC) || defined(VMS) #if defined(VAXC) || defined(VMS)
@@ -104,14 +111,17 @@ extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
#endif #endif
#ifdef AMIGA
# define OS_CODE 0x01
#endif
#if defined(ATARI) || defined(atarist) #if defined(ATARI) || defined(atarist)
# define OS_CODE 0x05 # define OS_CODE 0x05
#endif #endif
#ifdef OS2
# define OS_CODE 0x06
# ifdef M_I86
#include <malloc.h>
# endif
#endif
#if defined(MACOS) || defined(TARGET_OS_MAC) #if defined(MACOS) || defined(TARGET_OS_MAC)
# define OS_CODE 0x07 # define OS_CODE 0x07
# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os # if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
@@ -123,26 +133,37 @@ extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
# endif # endif
#endif #endif
#ifdef __50SERIES /* Prime/PRIMOS */
# define OS_CODE 0x0F
#endif
#ifdef TOPS20 #ifdef TOPS20
# define OS_CODE 0x0a # define OS_CODE 0x0a
#endif #endif
#ifdef WIN32
# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
# define OS_CODE 0x0b
# endif
#endif
#ifdef __50SERIES /* Prime/PRIMOS */
# define OS_CODE 0x0f
#endif
#if defined(_BEOS_) || defined(RISCOS) #if defined(_BEOS_) || defined(RISCOS)
# define fdopen(fd,mode) NULL /* No fdopen() */ # define fdopen(fd,mode) NULL /* No fdopen() */
#endif #endif
#if (defined(_MSC_VER) && (_MSC_VER > 600)) && (defined(WIN32) || \ #if (defined(_MSC_VER) && (_MSC_VER > 600))
defined(_Windows) || defined(_WINDOWS) || defined(_WIN32) || \ # if defined(_WIN32_WCE)
defined(__WIN32__)) # define fdopen(fd,mode) NULL /* No fdopen() */
# ifndef _PTRDIFF_T_DEFINED
typedef int ptrdiff_t;
# define _PTRDIFF_T_DEFINED
# endif
# else
# define fdopen(fd,type) _fdopen(fd,type) # define fdopen(fd,type) _fdopen(fd,type)
# endif
#endif #endif
/* common defaults */
/* Common defaults */
#ifndef OS_CODE #ifndef OS_CODE
# define OS_CODE 0x03 /* assume Unix */ # define OS_CODE 0x03 /* assume Unix */
@@ -154,11 +175,37 @@ extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
/* functions */ /* functions */
#ifdef HAVE_STRERROR #if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
extern char *strerror OF((int)); # ifndef HAVE_VSNPRINTF
# define zstrerror(errnum) strerror(errnum) # define HAVE_VSNPRINTF
#else # endif
# define zstrerror(errnum) "" #endif
#if defined(__CYGWIN__)
# ifndef HAVE_VSNPRINTF
# define HAVE_VSNPRINTF
# endif
#endif
#ifndef HAVE_VSNPRINTF
# ifdef MSDOS
/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
but for now we just assume it doesn't. */
# define NO_vsnprintf
# endif
# ifdef __TURBOC__
# define NO_vsnprintf
# endif
# ifdef WIN32
/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
# if !defined(vsnprintf) && !defined(NO_vsnprintf)
# define vsnprintf _vsnprintf
# endif
# endif
# ifdef __SASC
# define NO_vsnprintf
# endif
#endif
#ifdef VMS
# define NO_vsnprintf
#endif #endif
#if defined(pyr) #if defined(pyr)
@@ -211,8 +258,6 @@ extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
#endif #endif
typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
uInt len));
voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
void zcfree OF((voidpf opaque, voidpf ptr)); void zcfree OF((voidpf opaque, voidpf ptr));
@@ -221,4 +266,4 @@ void zcfree OF((voidpf opaque, voidpf ptr));
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) #define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} #define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
#endif /* _Z_UTIL_H */ #endif /* ZUTIL_H */