1
0
mirror of https://github.com/mariadb-corporation/mariadb-connector-c.git synced 2025-08-07 02:42:49 +03:00

CONC-575: Support for MySQL zstd compression

ZSTD compression is now supported for connections
to a MySQL Server 8.0.

Compression algorithms are supported via compression
plugins, which can be found in plugins/compress.
This commit is contained in:
Georg Richter
2022-01-25 05:02:33 +01:00
parent b5c1a23c82
commit 770cf2286a
222 changed files with 86766 additions and 71 deletions

View File

@@ -24,7 +24,7 @@ get_directory_property(IS_SUBPROJECT PARENT_DIRECTORY)
# do not inherit include directories from the parent project
SET_PROPERTY(DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
FOREACH(V WITH_MYSQLCOMPAT WITH_MSI WITH_SIGNCODE WITH_RTC WITH_UNIT_TESTS
WITH_DYNCOL WITH_EXTERNAL_ZLIB WITH_CURL WITH_SQLITE WITH_SSL WITH_ICONV
WITH_DYNCOL WITH_EXTERNAL_ZLIB WITH_EXTERNAL_ZSTD WITH_CURL WITH_SQLITE WITH_SSL WITH_ICONV
DEFAULT_CHARSET INSTALL_LAYOUT WITH_TEST_SRCPKG)
SET(${V} ${${OPT}${V}})
ENDFOREACH()
@@ -63,6 +63,7 @@ ENDIF()
ADD_OPTION(WITH_UNIT_TESTS "build test suite" ON)
ADD_OPTION(WITH_DYNCOL "Enables support of dynamic columns" ON)
ADD_OPTION(WITH_EXTERNAL_ZLIB "Enables use of external zlib" OFF)
ADD_OPTION(WITH_EXTERNAL_ZSTD "Enables use of external zstd" OFF)
ADD_OPTION(WITH_CURL "Enables use of curl" ON)
ADD_OPTION(WITH_SSL "Enables use of TLS/SSL library" ON)
###############
@@ -217,16 +218,27 @@ SET(DEFAULT_CHARSET_HOME "${CMAKE_INSTALL_PREFIX}")
INCLUDE(${CC_SOURCE_DIR}/cmake/SearchLibrary.cmake)
IF(WITH_EXTERNAL_ZSTD)
INCLUDE(${CC_SOURCE_DIR}/cmake/zstd.cmake)
IF(NOT ZSTD_FOUND)
MESSAGE(FATAL_ERROR "Zstd not found")
ENDIF()
ELSE()
INCLUDE_DIRECTORIES(${CC_SOURCE_DIR}/external/zstd/lib)
ADD_SUBDIRECTORY(external/zstd)
SET(ZSTD_LIBRARY zstd)
ENDIF()
IF(WITH_EXTERNAL_ZLIB)
IF(NOT ZLIB_FOUND)
FIND_PACKAGE(ZLIB REQUIRED)
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
SET(LIBZ ${ZLIB_LIBRARY})
ELSE()
# ZLIB was already specified by another (parent) project
SET(INTERNAL_ZLIB_LIBRARY ${ZLIB_LIBRARY})
ENDIF()
ELSE()
SET(ZLIB_INCLUDE_DIR "${CC_SOURCE_DIR}/external/zlib")
ADD_SUBDIRECTORY(external/zlib)
SET(ZLIB_LIBRARY zlib)
ENDIF()
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
IF(NOT WIN32)
INCLUDE(TestBigEndian)
@@ -246,9 +258,9 @@ IF(UNIX)
SEARCH_LIBRARY(LIBNSL gethostbyname_r "nsl_r;nsl")
SEARCH_LIBRARY(LIBSOCKET setsockopt socket)
FIND_PACKAGE(Threads)
SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${LIBNSL} ${LIBBIND} ${LIBICONV} ${LIBZ}
${LIBSOCKET} ${CMAKE_DL_LIBS} ${LIBM} ${LIBPTHREAD})
SET(SYSTEM_LIBS ${SYSTEM_LIBS} ${LIBNSL} ${LIBBIND} ${LIBICONV} ${LIBZ}
SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${LIBNSL} ${LIBBIND} ${LIBICONV} ${ZLIB_LIBRARY}
${ZSTD_LIBRARY} } ${LIBSOCKET} ${CMAKE_DL_LIBS} ${LIBM} ${LIBPTHREAD})
SET(SYSTEM_LIBS ${SYSTEM_LIBS} ${LIBNSL} ${LIBBIND} ${LIBICONV}
${LIBSOCKET} ${CMAKE_DL_LIBS} ${LIBM} ${LIBPTHREAD})
#remove possible dups from required libraries
LIST(LENGTH CMAKE_REQUIRED_LIBRARIES rllength)

20
cmake/zstd.cmake Normal file
View File

@@ -0,0 +1,20 @@
#
# Copyright (C) 2011 MariaDB Corporation AB
#
# Redistribution and use is allowed according to the terms of the New
# BSD license.
# For details see the COPYING-CMAKE-SCRIPTS file.
#
find_path(ZSTD_INCLUDE_DIR NAMES zstd.h)
find_library(ZSTD_LIBRARY_RELEASE NAMES zstd)
include(SelectLibraryConfigurations)
SELECT_LIBRARY_CONFIGURATIONS(ZSTD)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(
ZSTD DEFAULT_MSG
ZSTD_LIBRARY ZSTD_INCLUDE_DIR
)
mark_as_advanced(ZSTD_FOUND ZSTD_INCLUDE_DIR ZSTD_LIBRARY)

5
external/zlib/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,5 @@
INCLUDE_DIRECTORIES(${CC_SOURCE_DIR}/zlib)
SET(SOURCE_FILES adler32.c compress.c crc32.c deflate.c gzclose.c gzlib.c gzread.c gzwrite.c infback.c inffast.c inflate.c inftrees.c minigzip.c trees.c uncompr.c zutil.c)
ADD_LIBRARY(zlib STATIC ${SOURCE_FILES})

View File

View File

306
external/zlib/Makefile.in vendored Normal file
View File

@@ -0,0 +1,306 @@
# Makefile for zlib
# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler
# For conditions of distribution and use, see copyright notice in zlib.h
# To compile and test, type:
# ./configure; make test
# Normally configure builds both a static and a shared library.
# If you want to build just a static library, use: ./configure --static
# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:
# make install
# To install in $HOME instead of /usr/local, use:
# make install prefix=$HOME
TGT_ARCH=
CC=cc
CFLAGS=-O
#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
#CFLAGS=-g -DDEBUG
#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
# -Wstrict-prototypes -Wmissing-prototypes
SFLAGS=-O
LDFLAGS=
TEST_LDFLAGS=-L. libz.a
LDSHARED=$(CC)
CPP=$(CC) -E
STATICLIB=libz.a
SHAREDLIB=libz.so
SHAREDLIBV=libz.so.1.2.8
SHAREDLIBM=libz.so.1
LIBS=$(STATICLIB) $(SHAREDLIBV)
AR=ar
ARFLAGS=rc
RANLIB=ranlib
LDCONFIG=ldconfig
LDSHAREDLIBC=-lc
TAR=tar
SHELL=/bin/sh
EXE=
prefix = /usr/local
exec_prefix = ${prefix}
libdir = ${exec_prefix}/lib
sharedlibdir = ${libdir}
includedir = ${prefix}/include
mandir = ${prefix}/share/man
man3dir = ${mandir}/man3
pkgconfigdir = ${libdir}/pkgconfig
OBJZ = adler32.o adler32_simd.o crc32.o deflate.o infback.o inffast.o inflate.o inftrees.o trees.o zutil.o
OBJG = compress.o uncompr.o gzclose.o gzlib.o gzread.o gzwrite.o
PIC_OBJZ = adler32.lo adler32_simd.lo crc32.lo deflate.lo infback.lo inffast.lo inflate.lo inftrees.lo trees.lo zutil.lo
PIC_OBJG = compress.lo uncompr.lo gzclose.lo gzlib.lo gzread.lo gzwrite.lo
ifneq ($(findstring -DINFLATE_CHUNK_SIMD_NEON, $(CFLAGS)),)
OBJZ += inffast_chunk.o
PIC_OBJZ += inffast_chunk.lo
endif
ifneq ($(findstring -DINFLATE_CHUNK_SIMD_SSE2, $(CFLAGS)),)
OBJZ += inffast_chunk.o
PIC_OBJZ += inffast_chunk.lo
endif
ifneq ($(findstring -DHAS_PCLMUL, $(CFLAGS)),)
OBJZ += crc32_simd.o
PIC_OBJZ += crc32_simd.lo
endif
OBJC = $(OBJZ) $(OBJG)
PIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG)
# to use the asm code: make OBJA=match.o, PIC_OBJA=match.lo
OBJA =
PIC_OBJA =
OBJS = $(OBJC) $(OBJA)
PIC_OBJS = $(PIC_OBJC) $(PIC_OBJA)
all: static shared
static: example$(EXE) minigzip$(EXE)
shared: examplesh$(EXE) minigzipsh$(EXE)
all64: example64$(EXE) minigzip64$(EXE)
check: test
test: all teststatic testshared
teststatic: static
@TMPST=tmpst_$$; \
if echo hello world | ./minigzip | ./minigzip -d && ./example $$TMPST ; then \
echo ' *** zlib test OK ***'; \
else \
echo ' *** zlib test FAILED ***'; false; \
fi; \
rm -f $$TMPST
testshared: shared
@LD_LIBRARY_PATH=`pwd`:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
LD_LIBRARYN32_PATH=`pwd`:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \
DYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \
SHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \
TMPSH=tmpsh_$$; \
if echo hello world | ./minigzipsh | ./minigzipsh -d && ./examplesh $$TMPSH; then \
echo ' *** zlib shared test OK ***'; \
else \
echo ' *** zlib shared test FAILED ***'; false; \
fi; \
rm -f $$TMPSH
test64: all64
@TMP64=tmp64_$$; \
if echo hello world | ./minigzip64 | ./minigzip64 -d && ./example64 $$TMP64; then \
echo ' *** zlib 64-bit test OK ***'; \
else \
echo ' *** zlib 64-bit test FAILED ***'; false; \
fi; \
rm -f $$TMP64
infcover.o: test/infcover.c zlib.h zconf.h
$(CC) $(CFLAGS) -I. -c -o $@ test/infcover.c
infcover: infcover.o libz.a
$(CC) $(CFLAGS) -o $@ infcover.o libz.a
cover: infcover
rm -f *.gcda
./infcover
gcov inf*.c
libz.a: $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
-@ ($(RANLIB) $@ || true) >/dev/null 2>&1
match.o: match.S
$(CPP) match.S > _match.s
$(CC) -c _match.s
mv _match.o match.o
rm -f _match.s
match.lo: match.S
$(CPP) match.S > _match.s
$(CC) -c -fPIC _match.s
mv _match.o match.lo
rm -f _match.s
example.o: test/example.c zlib.h zconf.h
$(CC) $(CFLAGS) -I. -c -o $@ test/example.c
minigzip.o: test/minigzip.c zlib.h zconf.h
$(CC) $(CFLAGS) -I. -c -o $@ test/minigzip.c
example64.o: test/example.c zlib.h zconf.h
$(CC) $(CFLAGS) -I. -D_FILE_OFFSET_BITS=64 -c -o $@ test/example.c
minigzip64.o: test/minigzip.c zlib.h zconf.h
$(CC) $(CFLAGS) -I. -D_FILE_OFFSET_BITS=64 -c -o $@ test/minigzip.c
.SUFFIXES: .lo
.c.lo:
-@mkdir objs 2>/dev/null || test -d objs
$(CC) $(SFLAGS) -DPIC -c -o objs/$*.o $<
-@mv objs/$*.o $@
placebo $(SHAREDLIBV): $(PIC_OBJS) libz.a
$(LDSHARED) $(SFLAGS) -o $@ $(PIC_OBJS) $(LDSHAREDLIBC) $(LDFLAGS)
rm -f $(SHAREDLIB) $(SHAREDLIBM)
ln -s $@ $(SHAREDLIB)
ln -s $@ $(SHAREDLIBM)
-@rmdir objs
example$(EXE): example.o $(STATICLIB)
$(CC) $(CFLAGS) -o $@ example.o $(TEST_LDFLAGS)
minigzip$(EXE): minigzip.o $(STATICLIB)
$(CC) $(CFLAGS) -o $@ minigzip.o $(TEST_LDFLAGS)
examplesh$(EXE): example.o $(SHAREDLIBV)
$(CC) $(CFLAGS) -o $@ example.o -L. $(SHAREDLIBV)
minigzipsh$(EXE): minigzip.o $(SHAREDLIBV)
$(CC) $(CFLAGS) -o $@ minigzip.o -L. $(SHAREDLIBV)
example64$(EXE): example64.o $(STATICLIB)
$(CC) $(CFLAGS) -o $@ example64.o $(TEST_LDFLAGS)
minigzip64$(EXE): minigzip64.o $(STATICLIB)
$(CC) $(CFLAGS) -o $@ minigzip64.o $(TEST_LDFLAGS)
install-libs: $(LIBS)
-@if [ ! -d $(DESTDIR)$(exec_prefix) ]; then mkdir -p $(DESTDIR)$(exec_prefix); fi
-@if [ ! -d $(DESTDIR)$(libdir) ]; then mkdir -p $(DESTDIR)$(libdir); fi
-@if [ ! -d $(DESTDIR)$(sharedlibdir) ]; then mkdir -p $(DESTDIR)$(sharedlibdir); fi
-@if [ ! -d $(DESTDIR)$(man3dir) ]; then mkdir -p $(DESTDIR)$(man3dir); fi
-@if [ ! -d $(DESTDIR)$(pkgconfigdir) ]; then mkdir -p $(DESTDIR)$(pkgconfigdir); fi
cp $(STATICLIB) $(DESTDIR)$(libdir)
chmod 644 $(DESTDIR)$(libdir)/$(STATICLIB)
-@($(RANLIB) $(DESTDIR)$(libdir)/libz.a || true) >/dev/null 2>&1
-@if test -n "$(SHAREDLIBV)"; then \
cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir); \
echo "cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)"; \
chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV); \
echo "chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV)"; \
rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \
ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB); \
ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \
($(LDCONFIG) || true) >/dev/null 2>&1; \
fi
cp zlib.3 $(DESTDIR)$(man3dir)
chmod 644 $(DESTDIR)$(man3dir)/zlib.3
cp zlib.pc $(DESTDIR)$(pkgconfigdir)
chmod 644 $(DESTDIR)$(pkgconfigdir)/zlib.pc
# The ranlib in install is needed on NeXTSTEP which checks file times
# ldconfig is for Linux
install: install-libs
-@if [ ! -d $(DESTDIR)$(includedir) ]; then mkdir -p $(DESTDIR)$(includedir); fi
cp zlib.h zconf.h $(DESTDIR)$(includedir)
chmod 644 $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h
uninstall:
cd $(DESTDIR)$(includedir) && rm -f zlib.h zconf.h
cd $(DESTDIR)$(libdir) && rm -f libz.a; \
if test -n "$(SHAREDLIBV)" -a -f $(SHAREDLIBV); then \
rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \
fi
cd $(DESTDIR)$(man3dir) && rm -f zlib.3
cd $(DESTDIR)$(pkgconfigdir) && rm -f zlib.pc
docs: zlib.3.pdf
zlib.3.pdf: zlib.3
groff -mandoc -f H -T ps zlib.3 | ps2pdf - zlib.3.pdf
zconf.h.cmakein: zconf.h.in
-@ TEMPFILE=zconfh_$$; \
echo "/#define ZCONF_H/ a\\\\\n#cmakedefine Z_PREFIX\\\\\n#cmakedefine Z_HAVE_UNISTD_H\n" >> $$TEMPFILE &&\
sed -f $$TEMPFILE zconf.h.in > zconf.h.cmakein &&\
touch -r zconf.h.in zconf.h.cmakein &&\
rm $$TEMPFILE
zconf: zconf.h.in
cp -p zconf.h.in zconf.h
mostlyclean: clean
clean:
rm -f *.o *.lo *~ \
example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \
example64$(EXE) minigzip64$(EXE) \
infcover \
libz.* foo.gz so_locations \
_match.s maketree contrib/infback9/*.o
rm -rf objs
rm -f *.gcda *.gcno *.gcov
rm -f contrib/infback9/*.gcda contrib/infback9/*.gcno contrib/infback9/*.gcov
maintainer-clean: distclean
distclean: clean zconf zconf.h.cmakein docs
rm -f Makefile zlib.pc configure.log
-@rm -f .DS_Store
-@printf 'all:\n\t-@echo "Please use ./configure first. Thank you."\n' > Makefile
-@printf '\ndistclean:\n\tmake -f Makefile.in distclean\n' >> Makefile
-@touch -r Makefile.in Makefile
tags:
etags *.[ch]
depend:
makedepend -- $(CFLAGS) -- *.[ch]
# DO NOT DELETE THIS LINE -- make depend depends on it.
adler32.o zutil.o: zutil.h zlib.h zconf.h
adler32_simd.o: zlib.h
gzclose.o gzlib.o gzread.o gzwrite.o: zlib.h zconf.h gzguts.h
compress.o example.o minigzip.o uncompr.o: zlib.h zconf.h
crc32.o: zutil.h zlib.h zconf.h crc32.h
deflate.o: deflate.h zutil.h zlib.h zconf.h
infback.o inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inffixed.h inffast_chunk.h chunkcopy.h
inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
inffast_chunk.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast_chunk.h chunkcopy.h
inftrees.o: zutil.h zlib.h zconf.h inftrees.h
trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
adler32.lo zutil.lo: zutil.h zlib.h zconf.h
adler32_simd.o: zlib.h
gzclose.lo gzlib.lo gzread.lo gzwrite.lo: zlib.h zconf.h gzguts.h
compress.lo example.lo minigzip.lo uncompr.lo: zlib.h zconf.h
crc32.lo: zutil.h zlib.h zconf.h crc32.h
deflate.lo: deflate.h zutil.h zlib.h zconf.h
infback.lo inflate.lo: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inffixed.h inffast_chunk.h chunkcopy.h
inffast.lo: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
inffast_chunk.lo: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast_chunk.h chunkcopy.h
inftrees.lo: zutil.h zlib.h zconf.h inftrees.h
trees.lo: deflate.h zutil.h zlib.h zconf.h trees.h

View File

387
external/zlib/adler32_simd.c vendored Normal file
View File

@@ -0,0 +1,387 @@
/* adler32_simd.c
*
* (C) 1995-2013 Jean-loup Gailly and Mark Adler
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* Jean-loup Gailly Mark Adler
* jloup@gzip.org madler@alumni.caltech.edu
*
* Copyright 2017 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the Chromium source repository LICENSE file.
*
* Per http://en.wikipedia.org/wiki/Adler-32 the adler32 A value (aka s1) is
* the sum of N input data bytes D1 ... DN,
*
* A = A0 + D1 + D2 + ... + DN
*
* where A0 is the initial value.
*
* SSE2 _mm_sad_epu8() can be used for byte sums (see http://bit.ly/2wpUOeD,
* for example) and accumulating the byte sums can use SSE shuffle-adds (see
* the "Integer" section of http://bit.ly/2erPT8t for details). Arm NEON has
* similar instructions.
*
* The adler32 B value (aka s2) sums the A values from each step:
*
* B0 + (A0 + D1) + (A0 + D1 + D2) + ... + (A0 + D1 + D2 + ... + DN) or
*
* B0 + N.A0 + N.D1 + (N-1).D2 + (N-2).D3 + ... + (N-(N-1)).DN
*
* B0 being the initial value. For 32 bytes (ideal for garden-variety SIMD):
*
* B = B0 + 32.A0 + [D1 D2 D3 ... D32] x [32 31 30 ... 1].
*
* Adjacent blocks of 32 input bytes can be iterated with the expressions to
* compute the adler32 s1 s2 of M >> 32 input bytes [1].
*
* As M grows, the s1 s2 sums grow. If left unchecked, they would eventually
* overflow the precision of their integer representation (bad). However, s1
* and s2 also need to be computed modulo the adler BASE value (reduced). If
* at most NMAX bytes are processed before a reduce, s1 s2 _cannot_ overflow
* a uint32_t type (the NMAX constraint) [2].
*
* [1] the iterative equations for s2 contain constant factors; these can be
* hoisted from the n-blocks do loop of the SIMD code.
*
* [2] zlib adler32_z() uses this fact to implement NMAX-block-based updates
* of the adler s1 s2 of uint32_t type (see adler32.c).
*/
#include "adler32_simd.h"
/* Definitions from adler32.c: largest prime smaller than 65536 */
#define BASE 65521U
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
#define NMAX 5552
#if defined(ADLER32_SIMD_SSSE3)
#include <tmmintrin.h>
uint32_t ZLIB_INTERNAL adler32_simd_( /* SSSE3 */
uint32_t adler,
const unsigned char *buf,
unsigned long len)
{
/*
* Split Adler-32 into component sums.
*/
uint32_t s1 = adler & 0xffff;
uint32_t s2 = adler >> 16;
/*
* Process the data in blocks.
*/
const unsigned BLOCK_SIZE = 1 << 5;
unsigned long blocks = len / BLOCK_SIZE;
len -= blocks * BLOCK_SIZE;
while (blocks)
{
unsigned n = NMAX / BLOCK_SIZE; /* The NMAX constraint. */
if (n > blocks)
n = (unsigned) blocks;
blocks -= n;
const __m128i tap1 =
_mm_setr_epi8(32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17);
const __m128i tap2 =
_mm_setr_epi8(16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1);
const __m128i zero =
_mm_setr_epi8( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
const __m128i ones =
_mm_set_epi16( 1, 1, 1, 1, 1, 1, 1, 1);
/*
* Process n blocks of data. At most NMAX data bytes can be
* processed before s2 must be reduced modulo BASE.
*/
__m128i v_ps = _mm_set_epi32(0, 0, 0, s1 * n);
__m128i v_s2 = _mm_set_epi32(0, 0, 0, s2);
__m128i v_s1 = _mm_set_epi32(0, 0, 0, 0);
do {
/*
* Load 32 input bytes.
*/
const __m128i bytes1 = _mm_loadu_si128((__m128i*)(buf));
const __m128i bytes2 = _mm_loadu_si128((__m128i*)(buf + 16));
/*
* Add previous block byte sum to v_ps.
*/
v_ps = _mm_add_epi32(v_ps, v_s1);
/*
* Horizontally add the bytes for s1, multiply-adds the
* bytes by [ 32, 31, 30, ... ] for s2.
*/
v_s1 = _mm_add_epi32(v_s1, _mm_sad_epu8(bytes1, zero));
const __m128i mad1 = _mm_maddubs_epi16(bytes1, tap1);
v_s2 = _mm_add_epi32(v_s2, _mm_madd_epi16(mad1, ones));
v_s1 = _mm_add_epi32(v_s1, _mm_sad_epu8(bytes2, zero));
const __m128i mad2 = _mm_maddubs_epi16(bytes2, tap2);
v_s2 = _mm_add_epi32(v_s2, _mm_madd_epi16(mad2, ones));
buf += BLOCK_SIZE;
} while (--n);
v_s2 = _mm_add_epi32(v_s2, _mm_slli_epi32(v_ps, 5));
/*
* Sum epi32 ints v_s1(s2) and accumulate in s1(s2).
*/
#define S23O1 _MM_SHUFFLE(2,3,0,1) /* A B C D -> B A D C */
#define S1O32 _MM_SHUFFLE(1,0,3,2) /* A B C D -> C D A B */
v_s1 = _mm_add_epi32(v_s1, _mm_shuffle_epi32(v_s1, S23O1));
v_s1 = _mm_add_epi32(v_s1, _mm_shuffle_epi32(v_s1, S1O32));
s1 += _mm_cvtsi128_si32(v_s1);
v_s2 = _mm_add_epi32(v_s2, _mm_shuffle_epi32(v_s2, S23O1));
v_s2 = _mm_add_epi32(v_s2, _mm_shuffle_epi32(v_s2, S1O32));
s2 = _mm_cvtsi128_si32(v_s2);
#undef S23O1
#undef S1O32
/*
* Reduce.
*/
s1 %= BASE;
s2 %= BASE;
}
/*
* Handle leftover data.
*/
if (len) {
if (len >= 16) {
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
len -= 16;
}
while (len--) {
s2 += (s1 += *buf++);
}
if (s1 >= BASE)
s1 -= BASE;
s2 %= BASE;
}
/*
* Return the recombined sums.
*/
return s1 | (s2 << 16);
}
#elif defined(ADLER32_SIMD_NEON)
#include <arm_neon.h>
uint32_t ZLIB_INTERNAL adler32_simd_( /* NEON */
uint32_t adler,
const unsigned char *buf,
unsigned long len)
{
/*
* Split Adler-32 into component sums.
*/
uint32_t s1 = adler & 0xffff;
uint32_t s2 = adler >> 16;
/*
* Serially compute s1 & s2, until the data is 16-byte aligned.
*/
if ((uintptr_t)buf & 15) {
while ((uintptr_t)buf & 15) {
s2 += (s1 += *buf++);
--len;
}
if (s1 >= BASE)
s1 -= BASE;
s2 %= BASE;
}
/*
* Process the data in blocks.
*/
const unsigned BLOCK_SIZE = 1 << 5;
unsigned long blocks = len / BLOCK_SIZE;
len -= blocks * BLOCK_SIZE;
while (blocks)
{
unsigned n = NMAX / BLOCK_SIZE; /* The NMAX constraint. */
if (n > blocks)
n = blocks;
blocks -= n;
/*
* Process n blocks of data. At most NMAX data bytes can be
* processed before s2 must be reduced modulo BASE.
*/
uint32x4_t v_s2 = (uint32x4_t) { 0, 0, 0, s1 * n };
uint32x4_t v_s1 = (uint32x4_t) { 0, 0, 0, 0 };
uint16x8_t v_column_sum_1 = vdupq_n_u16(0);
uint16x8_t v_column_sum_2 = vdupq_n_u16(0);
uint16x8_t v_column_sum_3 = vdupq_n_u16(0);
uint16x8_t v_column_sum_4 = vdupq_n_u16(0);
do {
/*
* Load 32 input bytes.
*/
const uint8x16_t bytes1 = vld1q_u8((uint8_t*)(buf));
const uint8x16_t bytes2 = vld1q_u8((uint8_t*)(buf + 16));
/*
* Add previous block byte sum to v_s2.
*/
v_s2 = vaddq_u32(v_s2, v_s1);
/*
* Horizontally add the bytes for s1.
*/
v_s1 = vpadalq_u16(v_s1, vpadalq_u8(vpaddlq_u8(bytes1), bytes2));
/*
* Vertically add the bytes for s2.
*/
v_column_sum_1 = vaddw_u8(v_column_sum_1, vget_low_u8 (bytes1));
v_column_sum_2 = vaddw_u8(v_column_sum_2, vget_high_u8(bytes1));
v_column_sum_3 = vaddw_u8(v_column_sum_3, vget_low_u8 (bytes2));
v_column_sum_4 = vaddw_u8(v_column_sum_4, vget_high_u8(bytes2));
buf += BLOCK_SIZE;
} while (--n);
v_s2 = vshlq_n_u32(v_s2, 5);
/*
* Multiply-add bytes by [ 32, 31, 30, ... ] for s2.
*/
v_s2 = vmlal_u16(v_s2, vget_low_u16 (v_column_sum_1),
(uint16x4_t) { 32, 31, 30, 29 });
v_s2 = vmlal_u16(v_s2, vget_high_u16(v_column_sum_1),
(uint16x4_t) { 28, 27, 26, 25 });
v_s2 = vmlal_u16(v_s2, vget_low_u16 (v_column_sum_2),
(uint16x4_t) { 24, 23, 22, 21 });
v_s2 = vmlal_u16(v_s2, vget_high_u16(v_column_sum_2),
(uint16x4_t) { 20, 19, 18, 17 });
v_s2 = vmlal_u16(v_s2, vget_low_u16 (v_column_sum_3),
(uint16x4_t) { 16, 15, 14, 13 });
v_s2 = vmlal_u16(v_s2, vget_high_u16(v_column_sum_3),
(uint16x4_t) { 12, 11, 10, 9 });
v_s2 = vmlal_u16(v_s2, vget_low_u16 (v_column_sum_4),
(uint16x4_t) { 8, 7, 6, 5 });
v_s2 = vmlal_u16(v_s2, vget_high_u16(v_column_sum_4),
(uint16x4_t) { 4, 3, 2, 1 });
/*
* Sum epi32 ints v_s1(s2) and accumulate in s1(s2).
*/
uint32x2_t sum1 = vpadd_u32(vget_low_u32(v_s1), vget_high_u32(v_s1));
uint32x2_t sum2 = vpadd_u32(vget_low_u32(v_s2), vget_high_u32(v_s2));
uint32x2_t s1s2 = vpadd_u32(sum1, sum2);
s1 += vget_lane_u32(s1s2, 0);
s2 += vget_lane_u32(s1s2, 1);
/*
* Reduce.
*/
s1 %= BASE;
s2 %= BASE;
}
/*
* Handle leftover data.
*/
if (len) {
if (len >= 16) {
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
s2 += (s1 += *buf++);
len -= 16;
}
while (len--) {
s2 += (s1 += *buf++);
}
if (s1 >= BASE)
s1 -= BASE;
s2 %= BASE;
}
/*
* Return the recombined sums.
*/
return s1 | (s2 << 16);
}
#endif /* ADLER32_SIMD_SSSE3 */

37
external/zlib/adler32_simd.h vendored Normal file
View File

@@ -0,0 +1,37 @@
/* adler32_simd.h
*
* (C) 1995-2013 Jean-loup Gailly and Mark Adler
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* Jean-loup Gailly Mark Adler
* jloup@gzip.org madler@alumni.caltech.edu
*
* Copyright 2017 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the Chromium source repository LICENSE file.
*/
#include <stdint.h>
#include "zconf.h"
#include "zutil.h"
uint32_t ZLIB_INTERNAL adler32_simd_(
uint32_t adler,
const unsigned char *buf,
unsigned long len);

69
external/zlib/amiga/Makefile.pup vendored Normal file
View File

@@ -0,0 +1,69 @@
# Amiga powerUP (TM) Makefile
# makefile for libpng and SAS C V6.58/7.00 PPC compiler
# Copyright (C) 1998 by Andreas R. Kleinert
LIBNAME = libzip.a
CC = scppc
CFLAGS = NOSTKCHK NOSINT OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL \
OPTLOOP OPTRDEP=8 OPTDEP=8 OPTCOMP=8 NOVER
AR = ppc-amigaos-ar cr
RANLIB = ppc-amigaos-ranlib
LD = ppc-amigaos-ld -r
LDFLAGS = -o
LDLIBS = LIB:scppc.a LIB:end.o
RM = delete quiet
OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \
uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o
TEST_OBJS = example.o minigzip.o
all: example minigzip
check: test
test: all
example
echo hello world | minigzip | minigzip -d
$(LIBNAME): $(OBJS)
$(AR) $@ $(OBJS)
-$(RANLIB) $@
example: example.o $(LIBNAME)
$(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS)
minigzip: minigzip.o $(LIBNAME)
$(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS)
mostlyclean: clean
clean:
$(RM) *.o example minigzip $(LIBNAME) foo.gz
zip:
zip -ul9 zlib README ChangeLog Makefile Make????.??? Makefile.?? \
descrip.mms *.[ch]
tgz:
cd ..; tar cfz zlib/zlib.tgz zlib/README zlib/ChangeLog zlib/Makefile \
zlib/Make????.??? zlib/Makefile.?? zlib/descrip.mms zlib/*.[ch]
# DO NOT DELETE THIS LINE -- make depend depends on it.
adler32.o: zlib.h zconf.h
compress.o: zlib.h zconf.h
crc32.o: crc32.h zlib.h zconf.h
deflate.o: deflate.h zutil.h zlib.h zconf.h
example.o: zlib.h zconf.h
gzclose.o: zlib.h zconf.h gzguts.h
gzlib.o: zlib.h zconf.h gzguts.h
gzread.o: zlib.h zconf.h gzguts.h
gzwrite.o: zlib.h zconf.h gzguts.h
inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
inftrees.o: zutil.h zlib.h zconf.h inftrees.h
minigzip.o: zlib.h zconf.h
trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
uncompr.o: zlib.h zconf.h
zutil.o: zutil.h zlib.h zconf.h

68
external/zlib/amiga/Makefile.sas vendored Normal file
View File

@@ -0,0 +1,68 @@
# SMakefile for zlib
# Modified from the standard UNIX Makefile Copyright Jean-loup Gailly
# Osma Ahvenlampi <Osma.Ahvenlampi@hut.fi>
# Amiga, SAS/C 6.56 & Smake
CC=sc
CFLAGS=OPT
#CFLAGS=OPT CPU=68030
#CFLAGS=DEBUG=LINE
LDFLAGS=LIB z.lib
SCOPTIONS=OPTSCHED OPTINLINE OPTALIAS OPTTIME OPTINLOCAL STRMERGE \
NOICONS PARMS=BOTH NOSTACKCHECK UTILLIB NOVERSION ERRORREXX \
DEF=POSTINC
OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \
uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o
TEST_OBJS = example.o minigzip.o
all: SCOPTIONS example minigzip
check: test
test: all
example
echo hello world | minigzip | minigzip -d
install: z.lib
copy clone zlib.h zconf.h INCLUDE:
copy clone z.lib LIB:
z.lib: $(OBJS)
oml z.lib r $(OBJS)
example: example.o z.lib
$(CC) $(CFLAGS) LINK TO $@ example.o $(LDFLAGS)
minigzip: minigzip.o z.lib
$(CC) $(CFLAGS) LINK TO $@ minigzip.o $(LDFLAGS)
mostlyclean: clean
clean:
-delete force quiet example minigzip *.o z.lib foo.gz *.lnk SCOPTIONS
SCOPTIONS: Makefile.sas
copy to $@ <from <
$(SCOPTIONS)
<
# DO NOT DELETE THIS LINE -- make depend depends on it.
adler32.o: zlib.h zconf.h
compress.o: zlib.h zconf.h
crc32.o: crc32.h zlib.h zconf.h
deflate.o: deflate.h zutil.h zlib.h zconf.h
example.o: zlib.h zconf.h
gzclose.o: zlib.h zconf.h gzguts.h
gzlib.o: zlib.h zconf.h gzguts.h
gzread.o: zlib.h zconf.h gzguts.h
gzwrite.o: zlib.h zconf.h gzguts.h
inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
inftrees.o: zutil.h zlib.h zconf.h inftrees.h
minigzip.o: zlib.h zconf.h
trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
uncompr.o: zlib.h zconf.h
zutil.o: zutil.h zlib.h zconf.h

215
external/zlib/as400/bndsrc vendored Normal file
View File

@@ -0,0 +1,215 @@
STRPGMEXP PGMLVL(*CURRENT) SIGNATURE('ZLIB')
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/* Version 1.1.3 entry points. */
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/********************************************************************/
/* *MODULE ADLER32 ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("adler32")
/********************************************************************/
/* *MODULE COMPRESS ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("compress")
EXPORT SYMBOL("compress2")
/********************************************************************/
/* *MODULE CRC32 ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("crc32")
EXPORT SYMBOL("get_crc_table")
/********************************************************************/
/* *MODULE DEFLATE ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("deflate")
EXPORT SYMBOL("deflateEnd")
EXPORT SYMBOL("deflateSetDictionary")
EXPORT SYMBOL("deflateCopy")
EXPORT SYMBOL("deflateReset")
EXPORT SYMBOL("deflateParams")
EXPORT SYMBOL("deflatePrime")
EXPORT SYMBOL("deflateInit_")
EXPORT SYMBOL("deflateInit2_")
/********************************************************************/
/* *MODULE GZIO ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("gzopen")
EXPORT SYMBOL("gzdopen")
EXPORT SYMBOL("gzsetparams")
EXPORT SYMBOL("gzread")
EXPORT SYMBOL("gzwrite")
EXPORT SYMBOL("gzprintf")
EXPORT SYMBOL("gzputs")
EXPORT SYMBOL("gzgets")
EXPORT SYMBOL("gzputc")
EXPORT SYMBOL("gzgetc")
EXPORT SYMBOL("gzflush")
EXPORT SYMBOL("gzseek")
EXPORT SYMBOL("gzrewind")
EXPORT SYMBOL("gztell")
EXPORT SYMBOL("gzeof")
EXPORT SYMBOL("gzclose")
EXPORT SYMBOL("gzerror")
/********************************************************************/
/* *MODULE INFLATE ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("inflate")
EXPORT SYMBOL("inflateEnd")
EXPORT SYMBOL("inflateSetDictionary")
EXPORT SYMBOL("inflateSync")
EXPORT SYMBOL("inflateReset")
EXPORT SYMBOL("inflateInit_")
EXPORT SYMBOL("inflateInit2_")
EXPORT SYMBOL("inflateSyncPoint")
/********************************************************************/
/* *MODULE UNCOMPR ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("uncompress")
/********************************************************************/
/* *MODULE ZUTIL ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("zlibVersion")
EXPORT SYMBOL("zError")
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/* Version 1.2.1 additional entry points. */
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/********************************************************************/
/* *MODULE COMPRESS ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("compressBound")
/********************************************************************/
/* *MODULE DEFLATE ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("deflateBound")
/********************************************************************/
/* *MODULE GZIO ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("gzungetc")
EXPORT SYMBOL("gzclearerr")
/********************************************************************/
/* *MODULE INFBACK ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("inflateBack")
EXPORT SYMBOL("inflateBackEnd")
EXPORT SYMBOL("inflateBackInit_")
/********************************************************************/
/* *MODULE INFLATE ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("inflateCopy")
/********************************************************************/
/* *MODULE ZUTIL ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("zlibCompileFlags")
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/* Version 1.2.5 additional entry points. */
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/********************************************************************/
/* *MODULE ADLER32 ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("adler32_combine")
EXPORT SYMBOL("adler32_combine64")
/********************************************************************/
/* *MODULE CRC32 ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("crc32_combine")
EXPORT SYMBOL("crc32_combine64")
/********************************************************************/
/* *MODULE GZLIB ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("gzbuffer")
EXPORT SYMBOL("gzoffset")
EXPORT SYMBOL("gzoffset64")
EXPORT SYMBOL("gzopen64")
EXPORT SYMBOL("gzseek64")
EXPORT SYMBOL("gztell64")
/********************************************************************/
/* *MODULE GZREAD ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("gzclose_r")
/********************************************************************/
/* *MODULE GZWRITE ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("gzclose_w")
/********************************************************************/
/* *MODULE INFLATE ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("inflateMark")
EXPORT SYMBOL("inflatePrime")
EXPORT SYMBOL("inflateReset2")
EXPORT SYMBOL("inflateUndermine")
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/* Version 1.2.6 additional entry points. */
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/********************************************************************/
/* *MODULE DEFLATE ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("deflateResetKeep")
EXPORT SYMBOL("deflatePending")
/********************************************************************/
/* *MODULE GZWRITE ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("gzgetc_")
/********************************************************************/
/* *MODULE INFLATE ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("inflateResetKeep")
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/* Version 1.2.8 additional entry points. */
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/********************************************************************/
/* *MODULE INFLATE ZLIB 01/02/01 00:15:09 */
/********************************************************************/
EXPORT SYMBOL("inflateGetDictionary")
ENDPGMEXP

110
external/zlib/as400/compile.clp vendored Normal file
View File

@@ -0,0 +1,110 @@
/******************************************************************************/
/* */
/* ZLIB */
/* */
/* Compile sources into modules and link them into a service program. */
/* */
/******************************************************************************/
PGM
/* Configuration adjustable parameters. */
DCL VAR(&SRCLIB) TYPE(*CHAR) LEN(10) +
VALUE('ZLIB') /* Source library. */
DCL VAR(&SRCFILE) TYPE(*CHAR) LEN(10) +
VALUE('SOURCES') /* Source member file. */
DCL VAR(&CTLFILE) TYPE(*CHAR) LEN(10) +
VALUE('TOOLS') /* Control member file. */
DCL VAR(&MODLIB) TYPE(*CHAR) LEN(10) +
VALUE('ZLIB') /* Module library. */
DCL VAR(&SRVLIB) TYPE(*CHAR) LEN(10) +
VALUE('LGPL') /* Service program library. */
DCL VAR(&CFLAGS) TYPE(*CHAR) +
VALUE('OPTIMIZE(40)') /* Compile options. */
DCL VAR(&TGTRLS) TYPE(*CHAR) +
VALUE('V5R3M0') /* Target release. */
/* Working storage. */
DCL VAR(&CMDLEN) TYPE(*DEC) LEN(15 5) VALUE(300) /* Command length. */
DCL VAR(&CMD) TYPE(*CHAR) LEN(512)
DCL VAR(&FIXDCMD) TYPE(*CHAR) LEN(512)
/* Compile sources into modules. */
CHGVAR VAR(&FIXDCMD) VALUE('CRTCMOD' *BCAT &CFLAGS *BCAT +
'SYSIFCOPT(*IFS64IO)' *BCAT +
'DEFINE(''_LARGEFILE64_SOURCE''' *BCAT +
'''_LFS64_LARGEFILE=1'') TGTRLS(' *TCAT &TGTRLS *TCAT +
') SRCFILE(' *TCAT &SRCLIB *TCAT '/' *TCAT +
&SRCFILE *TCAT ') MODULE(' *TCAT &MODLIB *TCAT '/')
CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'ADLER32)')
CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'COMPRESS)')
CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'CRC32)')
CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'DEFLATE)')
CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'GZCLOSE)')
CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'GZLIB)')
CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'GZREAD)')
CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'GZWRITE)')
CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'INFBACK)')
CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'INFFAST)')
CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'INFLATE)')
CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'INFTREES)')
CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'TREES)')
CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'UNCOMPR)')
CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'ZUTIL)')
CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
/* Link modules into a service program. */
CRTSRVPGM SRVPGM(&SRVLIB/ZLIB) +
MODULE(&MODLIB/ADLER32 &MODLIB/COMPRESS +
&MODLIB/CRC32 &MODLIB/DEFLATE +
&MODLIB/GZCLOSE &MODLIB/GZLIB +
&MODLIB/GZREAD &MODLIB/GZWRITE +
&MODLIB/INFBACK &MODLIB/INFFAST +
&MODLIB/INFLATE &MODLIB/INFTREES +
&MODLIB/TREES &MODLIB/UNCOMPR +
&MODLIB/ZUTIL) +
SRCFILE(&SRCLIB/&CTLFILE) SRCMBR(BNDSRC) +
TEXT('ZLIB 1.2.8') TGTRLS(&TGTRLS)
ENDPGM

115
external/zlib/as400/readme.txt vendored Normal file
View File

@@ -0,0 +1,115 @@
ZLIB version 1.2.8 for AS400 installation instructions
I) From an AS400 *SAVF file:
1) Unpacking archive to an AS400 save file
On the AS400:
_ Create the ZLIB AS400 library:
CRTLIB LIB(ZLIB) TYPE(*PROD) TEXT('ZLIB compression API library')
_ Create a work save file, for example:
CRTSAVF FILE(ZLIB/ZLIBSAVF)
On a PC connected to the target AS400:
_ Unpack the save file image to a PC file "ZLIBSAVF"
_ Upload this file into the save file on the AS400, for example
using ftp in BINARY mode.
2) Populating the ZLIB AS400 source library
On the AS400:
_ Extract the saved objects into the ZLIB AS400 library using:
RSTOBJ OBJ(*ALL) SAVLIB(ZLIB) DEV(*SAVF) SAVF(ZLIB/ZLIBSAVF) RSTLIB(ZLIB)
3) Customize installation:
_ Edit CL member ZLIB/TOOLS(COMPILE) and change parameters if needed,
according to the comments.
_ Compile this member with:
CRTCLPGM PGM(ZLIB/COMPILE) SRCFILE(ZLIB/TOOLS) SRCMBR(COMPILE)
4) Compile and generate the service program:
_ This can now be done by executing:
CALL PGM(ZLIB/COMPILE)
II) From the original source distribution:
1) On the AS400, create the source library:
CRTLIB LIB(ZLIB) TYPE(*PROD) TEXT('ZLIB compression API library')
2) Create the source files:
CRTSRCPF FILE(ZLIB/SOURCES) RCDLEN(112) TEXT('ZLIB library modules')
CRTSRCPF FILE(ZLIB/H) RCDLEN(112) TEXT('ZLIB library includes')
CRTSRCPF FILE(ZLIB/TOOLS) RCDLEN(112) TEXT('ZLIB library control utilities')
3) From the machine hosting the distribution files, upload them (with
FTP in text mode, for example) according to the following table:
Original AS400 AS400 AS400 AS400
file file member type description
SOURCES Original ZLIB C subprogram sources
adler32.c ADLER32 C ZLIB - Compute the Adler-32 checksum of a dta strm
compress.c COMPRESS C ZLIB - Compress a memory buffer
crc32.c CRC32 C ZLIB - Compute the CRC-32 of a data stream
deflate.c DEFLATE C ZLIB - Compress data using the deflation algorithm
gzclose.c GZCLOSE C ZLIB - Close .gz files
gzlib.c GZLIB C ZLIB - Miscellaneous .gz files IO support
gzread.c GZREAD C ZLIB - Read .gz files
gzwrite.c GZWRITE C ZLIB - Write .gz files
infback.c INFBACK C ZLIB - Inflate using a callback interface
inffast.c INFFAST C ZLIB - Fast proc. literals & length/distance pairs
inflate.c INFLATE C ZLIB - Interface to inflate modules
inftrees.c INFTREES C ZLIB - Generate Huffman trees for efficient decode
trees.c TREES C ZLIB - Output deflated data using Huffman coding
uncompr.c UNCOMPR C ZLIB - Decompress a memory buffer
zutil.c ZUTIL C ZLIB - Target dependent utility functions
H Original ZLIB C and ILE/RPG include files
crc32.h CRC32 C ZLIB - CRC32 tables
deflate.h DEFLATE C ZLIB - Internal compression state
gzguts.h GZGUTS C ZLIB - Definitions for the gzclose module
inffast.h INFFAST C ZLIB - Header to use inffast.c
inffixed.h INFFIXED C ZLIB - Table for decoding fixed codes
inflate.h INFLATE C ZLIB - Internal inflate state definitions
inftrees.h INFTREES C ZLIB - Header to use inftrees.c
trees.h TREES C ZLIB - Created automatically with -DGEN_TREES_H
zconf.h ZCONF C ZLIB - Compression library configuration
zlib.h ZLIB C ZLIB - Compression library C user interface
as400/zlib.inc ZLIB.INC RPGLE ZLIB - Compression library ILE RPG user interface
zutil.h ZUTIL C ZLIB - Internal interface and configuration
TOOLS Building source software & AS/400 README
as400/bndsrc BNDSRC Entry point exportation list
as400/compile.clp COMPILE CLP Compile sources & generate service program
as400/readme.txt README TXT Installation instructions
4) Continue as in I)3).
Notes: For AS400 ILE RPG programmers, a /copy member defining the ZLIB
API prototypes for ILE RPG can be found in ZLIB/H(ZLIB.INC).
Please read comments in this member for more information.
Remember that most foreign textual data are ASCII coded: this
implementation does not handle conversion from/to ASCII, so
text data code conversions must be done explicitely.
Mainly for the reason above, always open zipped files in binary mode.

451
external/zlib/as400/zlib.inc vendored Normal file
View File

@@ -0,0 +1,451 @@
* ZLIB.INC - Interface to the general purpose compression library
*
* ILE RPG400 version by Patrick Monnerat, DATASPHERE.
* Version 1.2.8
*
*
* WARNING:
* Procedures inflateInit(), inflateInit2(), deflateInit(),
* deflateInit2() and inflateBackInit() need to be called with
* two additional arguments:
* the package version string and the stream control structure.
* size. This is needed because RPG lacks some macro feature.
* Call these procedures as:
* inflateInit(...: ZLIB_VERSION: %size(z_stream))
*
/if not defined(ZLIB_H_)
/define ZLIB_H_
*
**************************************************************************
* Constants
**************************************************************************
*
* Versioning information.
*
D ZLIB_VERSION C '1.2.8'
D ZLIB_VERNUM C X'1280'
D ZLIB_VER_MAJOR C 1
D ZLIB_VER_MINOR C 2
D ZLIB_VER_REVISION...
D C 8
D ZLIB_VER_SUBREVISION...
D C 0
*
* Other equates.
*
D Z_NO_FLUSH C 0
D Z_PARTIAL_FLUSH...
D C 1
D Z_SYNC_FLUSH C 2
D Z_FULL_FLUSH C 3
D Z_FINISH C 4
D Z_BLOCK C 5
D Z_TREES C 6
*
D Z_OK C 0
D Z_STREAM_END C 1
D Z_NEED_DICT C 2
D Z_ERRNO C -1
D Z_STREAM_ERROR C -2
D Z_DATA_ERROR C -3
D Z_MEM_ERROR C -4
D Z_BUF_ERROR C -5
DZ_VERSION_ERROR C -6
*
D Z_NO_COMPRESSION...
D C 0
D Z_BEST_SPEED C 1
D Z_BEST_COMPRESSION...
D C 9
D Z_DEFAULT_COMPRESSION...
D C -1
*
D Z_FILTERED C 1
D Z_HUFFMAN_ONLY C 2
D Z_RLE C 3
D Z_DEFAULT_STRATEGY...
D C 0
*
D Z_BINARY C 0
D Z_ASCII C 1
D Z_UNKNOWN C 2
*
D Z_DEFLATED C 8
*
D Z_NULL C 0
*
**************************************************************************
* Types
**************************************************************************
*
D z_streamp S * Stream struct ptr
D gzFile S * File pointer
D z_off_t S 10i 0 Stream offsets
D z_off64_t S 20i 0 Stream offsets
*
**************************************************************************
* Structures
**************************************************************************
*
* The GZIP encode/decode stream support structure.
*
D z_stream DS align based(z_streamp)
D zs_next_in * Next input byte
D zs_avail_in 10U 0 Byte cnt at next_in
D zs_total_in 10U 0 Total bytes read
D zs_next_out * Output buffer ptr
D zs_avail_out 10U 0 Room left @ next_out
D zs_total_out 10U 0 Total bytes written
D zs_msg * Last errmsg or null
D zs_state * Internal state
D zs_zalloc * procptr Int. state allocator
D zs_free * procptr Int. state dealloc.
D zs_opaque * Private alloc. data
D zs_data_type 10i 0 ASC/BIN best guess
D zs_adler 10u 0 Uncompr. adler32 val
D 10U 0 Reserved
D 10U 0 Ptr. alignment
*
**************************************************************************
* Utility function prototypes
**************************************************************************
*
D compress PR 10I 0 extproc('compress')
D dest 65535 options(*varsize) Destination buffer
D destLen 10U 0 Destination length
D source 65535 const options(*varsize) Source buffer
D sourceLen 10u 0 value Source length
*
D compress2 PR 10I 0 extproc('compress2')
D dest 65535 options(*varsize) Destination buffer
D destLen 10U 0 Destination length
D source 65535 const options(*varsize) Source buffer
D sourceLen 10U 0 value Source length
D level 10I 0 value Compression level
*
D compressBound PR 10U 0 extproc('compressBound')
D sourceLen 10U 0 value
*
D uncompress PR 10I 0 extproc('uncompress')
D dest 65535 options(*varsize) Destination buffer
D destLen 10U 0 Destination length
D source 65535 const options(*varsize) Source buffer
D sourceLen 10U 0 value Source length
*
/if not defined(LARGE_FILES)
D gzopen PR extproc('gzopen')
D like(gzFile)
D path * value options(*string) File pathname
D mode * value options(*string) Open mode
/else
D gzopen PR extproc('gzopen64')
D like(gzFile)
D path * value options(*string) File pathname
D mode * value options(*string) Open mode
*
D gzopen64 PR extproc('gzopen64')
D like(gzFile)
D path * value options(*string) File pathname
D mode * value options(*string) Open mode
/endif
*
D gzdopen PR extproc('gzdopen')
D like(gzFile)
D fd 10I 0 value File descriptor
D mode * value options(*string) Open mode
*
D gzbuffer PR 10I 0 extproc('gzbuffer')
D file value like(gzFile) File pointer
D size 10U 0 value
*
D gzsetparams PR 10I 0 extproc('gzsetparams')
D file value like(gzFile) File pointer
D level 10I 0 value
D strategy 10I 0 value
*
D gzread PR 10I 0 extproc('gzread')
D file value like(gzFile) File pointer
D buf 65535 options(*varsize) Buffer
D len 10u 0 value Buffer length
*
D gzwrite PR 10I 0 extproc('gzwrite')
D file value like(gzFile) File pointer
D buf 65535 const options(*varsize) Buffer
D len 10u 0 value Buffer length
*
D gzputs PR 10I 0 extproc('gzputs')
D file value like(gzFile) File pointer
D s * value options(*string) String to output
*
D gzgets PR * extproc('gzgets')
D file value like(gzFile) File pointer
D buf 65535 options(*varsize) Read buffer
D len 10i 0 value Buffer length
*
D gzputc PR 10i 0 extproc('gzputc')
D file value like(gzFile) File pointer
D c 10I 0 value Character to write
*
D gzgetc PR 10i 0 extproc('gzgetc')
D file value like(gzFile) File pointer
*
D gzgetc_ PR 10i 0 extproc('gzgetc_')
D file value like(gzFile) File pointer
*
D gzungetc PR 10i 0 extproc('gzungetc')
D c 10I 0 value Character to push
D file value like(gzFile) File pointer
*
D gzflush PR 10i 0 extproc('gzflush')
D file value like(gzFile) File pointer
D flush 10I 0 value Type of flush
*
/if not defined(LARGE_FILES)
D gzseek PR extproc('gzseek')
D like(z_off_t)
D file value like(gzFile) File pointer
D offset value like(z_off_t) Offset
D whence 10i 0 value Origin
/else
D gzseek PR extproc('gzseek64')
D like(z_off_t)
D file value like(gzFile) File pointer
D offset value like(z_off_t) Offset
D whence 10i 0 value Origin
*
D gzseek64 PR extproc('gzseek64')
D like(z_off64_t)
D file value like(gzFile) File pointer
D offset value like(z_off64_t) Offset
D whence 10i 0 value Origin
/endif
*
D gzrewind PR 10i 0 extproc('gzrewind')
D file value like(gzFile) File pointer
*
/if not defined(LARGE_FILES)
D gztell PR extproc('gztell')
D like(z_off_t)
D file value like(gzFile) File pointer
/else
D gztell PR extproc('gztell64')
D like(z_off_t)
D file value like(gzFile) File pointer
*
D gztell64 PR extproc('gztell64')
D like(z_off64_t)
D file value like(gzFile) File pointer
/endif
*
/if not defined(LARGE_FILES)
D gzoffset PR extproc('gzoffset')
D like(z_off_t)
D file value like(gzFile) File pointer
/else
D gzoffset PR extproc('gzoffset64')
D like(z_off_t)
D file value like(gzFile) File pointer
*
D gzoffset64 PR extproc('gzoffset64')
D like(z_off64_t)
D file value like(gzFile) File pointer
/endif
*
D gzeof PR 10i 0 extproc('gzeof')
D file value like(gzFile) File pointer
*
D gzclose_r PR 10i 0 extproc('gzclose_r')
D file value like(gzFile) File pointer
*
D gzclose_w PR 10i 0 extproc('gzclose_w')
D file value like(gzFile) File pointer
*
D gzclose PR 10i 0 extproc('gzclose')
D file value like(gzFile) File pointer
*
D gzerror PR * extproc('gzerror') Error string
D file value like(gzFile) File pointer
D errnum 10I 0 Error code
*
D gzclearerr PR extproc('gzclearerr')
D file value like(gzFile) File pointer
*
**************************************************************************
* Basic function prototypes
**************************************************************************
*
D zlibVersion PR * extproc('zlibVersion') Version string
*
D deflateInit PR 10I 0 extproc('deflateInit_') Init. compression
D strm like(z_stream) Compression stream
D level 10I 0 value Compression level
D version * value options(*string) Version string
D stream_size 10i 0 value Stream struct. size
*
D deflate PR 10I 0 extproc('deflate') Compress data
D strm like(z_stream) Compression stream
D flush 10I 0 value Flush type required
*
D deflateEnd PR 10I 0 extproc('deflateEnd') Termin. compression
D strm like(z_stream) Compression stream
*
D inflateInit PR 10I 0 extproc('inflateInit_') Init. expansion
D strm like(z_stream) Expansion stream
D version * value options(*string) Version string
D stream_size 10i 0 value Stream struct. size
*
D inflate PR 10I 0 extproc('inflate') Expand data
D strm like(z_stream) Expansion stream
D flush 10I 0 value Flush type required
*
D inflateEnd PR 10I 0 extproc('inflateEnd') Termin. expansion
D strm like(z_stream) Expansion stream
*
**************************************************************************
* Advanced function prototypes
**************************************************************************
*
D deflateInit2 PR 10I 0 extproc('deflateInit2_') Init. compression
D strm like(z_stream) Compression stream
D level 10I 0 value Compression level
D method 10I 0 value Compression method
D windowBits 10I 0 value log2(window size)
D memLevel 10I 0 value Mem/cmpress tradeoff
D strategy 10I 0 value Compression stategy
D version * value options(*string) Version string
D stream_size 10i 0 value Stream struct. size
*
D deflateSetDictionary...
D PR 10I 0 extproc('deflateSetDictionary') Init. dictionary
D strm like(z_stream) Compression stream
D dictionary 65535 const options(*varsize) Dictionary bytes
D dictLength 10U 0 value Dictionary length
*
D deflateCopy PR 10I 0 extproc('deflateCopy') Compress strm 2 strm
D dest like(z_stream) Destination stream
D source like(z_stream) Source stream
*
D deflateReset PR 10I 0 extproc('deflateReset') End and init. stream
D strm like(z_stream) Compression stream
*
D deflateParams PR 10I 0 extproc('deflateParams') Change level & strat
D strm like(z_stream) Compression stream
D level 10I 0 value Compression level
D strategy 10I 0 value Compression stategy
*
D deflateBound PR 10U 0 extproc('deflateBound') Change level & strat
D strm like(z_stream) Compression stream
D sourcelen 10U 0 value Compression level
*
D deflatePending PR 10I 0 extproc('deflatePending') Change level & strat
D strm like(z_stream) Compression stream
D pending 10U 0 Pending bytes
D bits 10I 0 Pending bits
*
D deflatePrime PR 10I 0 extproc('deflatePrime') Change level & strat
D strm like(z_stream) Compression stream
D bits 10I 0 value # of bits to insert
D value 10I 0 value Bits to insert
*
D inflateInit2 PR 10I 0 extproc('inflateInit2_') Init. expansion
D strm like(z_stream) Expansion stream
D windowBits 10I 0 value log2(window size)
D version * value options(*string) Version string
D stream_size 10i 0 value Stream struct. size
*
D inflateSetDictionary...
D PR 10I 0 extproc('inflateSetDictionary') Init. dictionary
D strm like(z_stream) Expansion stream
D dictionary 65535 const options(*varsize) Dictionary bytes
D dictLength 10U 0 value Dictionary length
*
D inflateGetDictionary...
D PR 10I 0 extproc('inflateGetDictionary') Get dictionary
D strm like(z_stream) Expansion stream
D dictionary 65535 options(*varsize) Dictionary bytes
D dictLength 10U 0 Dictionary length
*
D inflateSync PR 10I 0 extproc('inflateSync') Sync. expansion
D strm like(z_stream) Expansion stream
*
D inflateCopy PR 10I 0 extproc('inflateCopy')
D dest like(z_stream) Destination stream
D source like(z_stream) Source stream
*
D inflateReset PR 10I 0 extproc('inflateReset') End and init. stream
D strm like(z_stream) Expansion stream
*
D inflateReset2 PR 10I 0 extproc('inflateReset2') End and init. stream
D strm like(z_stream) Expansion stream
D windowBits 10I 0 value Log2(buffer size)
*
D inflatePrime PR 10I 0 extproc('inflatePrime') Insert bits
D strm like(z_stream) Expansion stream
D bits 10I 0 value Bit count
D value 10I 0 value Bits to insert
*
D inflateMark PR 10I 0 extproc('inflateMark') Get inflate info
D strm like(z_stream) Expansion stream
*
D inflateBackInit...
D PR 10I 0 extproc('inflateBackInit_')
D strm like(z_stream) Expansion stream
D windowBits 10I 0 value Log2(buffer size)
D window 65535 options(*varsize) Buffer
D version * value options(*string) Version string
D stream_size 10i 0 value Stream struct. size
*
D inflateBack PR 10I 0 extproc('inflateBack')
D strm like(z_stream) Expansion stream
D in * value procptr Input function
D in_desc * value Input descriptor
D out * value procptr Output function
D out_desc * value Output descriptor
*
D inflateBackEnd PR 10I 0 extproc('inflateBackEnd')
D strm like(z_stream) Expansion stream
*
D zlibCompileFlags...
D PR 10U 0 extproc('zlibCompileFlags')
*
**************************************************************************
* Checksum function prototypes
**************************************************************************
*
D adler32 PR 10U 0 extproc('adler32') New checksum
D adler 10U 0 value Old checksum
D buf 65535 const options(*varsize) Bytes to accumulate
D len 10U 0 value Buffer length
*
D crc32 PR 10U 0 extproc('crc32') New checksum
D crc 10U 0 value Old checksum
D buf 65535 const options(*varsize) Bytes to accumulate
D len 10U 0 value Buffer length
*
**************************************************************************
* Miscellaneous function prototypes
**************************************************************************
*
D zError PR * extproc('zError') Error string
D err 10I 0 value Error code
*
D inflateSyncPoint...
D PR 10I 0 extproc('inflateSyncPoint')
D strm like(z_stream) Expansion stream
*
D get_crc_table PR * extproc('get_crc_table') Ptr to ulongs
*
D inflateUndermine...
D PR 10I 0 extproc('inflateUndermine')
D strm like(z_stream) Expansion stream
D arg 10I 0 value Error code
*
D inflateResetKeep...
D PR 10I 0 extproc('inflateResetKeep') End and init. stream
D strm like(z_stream) Expansion stream
*
D deflateResetKeep...
D PR 10I 0 extproc('deflateResetKeep') End and init. stream
D strm like(z_stream) Expansion stream
*
/endif

485
external/zlib/chunkcopy.h vendored Normal file
View File

@@ -0,0 +1,485 @@
/* chunkcopy.h -- fast chunk copy and set operations
*
* (C) 1995-2013 Jean-loup Gailly and Mark Adler
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* Jean-loup Gailly Mark Adler
* jloup@gzip.org madler@alumni.caltech.edu
*
* Copyright (C) 2017 ARM, Inc.
* Copyright 2017 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the Chromium source repository LICENSE file.
*/
#ifndef CHUNKCOPY_H
#define CHUNKCOPY_H
#include <stdint.h>
#include "zutil.h"
#define Z_STATIC_ASSERT(name, assert) typedef char name[(assert) ? 1 : -1]
#if __STDC_VERSION__ >= 199901L
#define Z_RESTRICT restrict
#else
#define Z_RESTRICT
#endif
#if defined(__clang__) || defined(__GNUC__) || defined(__llvm__)
#define Z_BUILTIN_MEMCPY __builtin_memcpy
#else
#define Z_BUILTIN_MEMCPY zmemcpy
#endif
#if defined(INFLATE_CHUNK_SIMD_NEON)
#include <arm_neon.h>
typedef uint8x16_t z_vec128i_t;
#elif defined(INFLATE_CHUNK_SIMD_SSE2)
#include <emmintrin.h>
typedef __m128i z_vec128i_t;
#else
#error chunkcopy.h inflate chunk SIMD is not defined for your build target
#endif
/*
* chunk copy type: the z_vec128i_t type size should be exactly 128-bits
* and equal to CHUNKCOPY_CHUNK_SIZE.
*/
#define CHUNKCOPY_CHUNK_SIZE sizeof(z_vec128i_t)
Z_STATIC_ASSERT(vector_128_bits_wide,
CHUNKCOPY_CHUNK_SIZE == sizeof(int8_t) * 16);
/*
* Ask the compiler to perform a wide, unaligned load with a machine
* instruction appropriate for the z_vec128i_t type.
*/
static inline z_vec128i_t loadchunk(
const unsigned char FAR* s) {
z_vec128i_t v;
Z_BUILTIN_MEMCPY(&v, s, sizeof(v));
return v;
}
/*
* Ask the compiler to perform a wide, unaligned store with a machine
* instruction appropriate for the z_vec128i_t type.
*/
static inline void storechunk(
unsigned char FAR* d,
const z_vec128i_t v) {
Z_BUILTIN_MEMCPY(d, &v, sizeof(v));
}
/*
* Perform a memcpy-like operation, assuming that length is non-zero and that
* it's OK to overwrite at least CHUNKCOPY_CHUNK_SIZE bytes of output even if
* the length is shorter than this.
*
* It also guarantees that it will properly unroll the data if the distance
* between `out` and `from` is at least CHUNKCOPY_CHUNK_SIZE, which we rely on
* in chunkcopy_relaxed().
*
* Aside from better memory bus utilisation, this means that short copies
* (CHUNKCOPY_CHUNK_SIZE bytes or fewer) will fall straight through the loop
* without iteration, which will hopefully make the branch prediction more
* reliable.
*/
static inline unsigned char FAR* chunkcopy_core(
unsigned char FAR* out,
const unsigned char FAR* from,
unsigned len) {
const int bump = (--len % CHUNKCOPY_CHUNK_SIZE) + 1;
storechunk(out, loadchunk(from));
out += bump;
from += bump;
len /= CHUNKCOPY_CHUNK_SIZE;
while (len-- > 0) {
storechunk(out, loadchunk(from));
out += CHUNKCOPY_CHUNK_SIZE;
from += CHUNKCOPY_CHUNK_SIZE;
}
return out;
}
/*
* Like chunkcopy_core(), but avoid writing beyond of legal output.
*
* Accepts an additional pointer to the end of safe output. A generic safe
* copy would use (out + len), but it's normally the case that the end of the
* output buffer is beyond the end of the current copy, and this can still be
* exploited.
*/
static inline unsigned char FAR* chunkcopy_core_safe(
unsigned char FAR* out,
const unsigned char FAR* from,
unsigned len,
unsigned char FAR* limit) {
Assert(out + len <= limit, "chunk copy exceeds safety limit");
if ((limit - out) < (ptrdiff_t)CHUNKCOPY_CHUNK_SIZE) {
const unsigned char FAR* Z_RESTRICT rfrom = from;
if (len & 8) {
Z_BUILTIN_MEMCPY(out, rfrom, 8);
out += 8;
rfrom += 8;
}
if (len & 4) {
Z_BUILTIN_MEMCPY(out, rfrom, 4);
out += 4;
rfrom += 4;
}
if (len & 2) {
Z_BUILTIN_MEMCPY(out, rfrom, 2);
out += 2;
rfrom += 2;
}
if (len & 1) {
*out++ = *rfrom++;
}
return out;
}
return chunkcopy_core(out, from, len);
}
/*
* Perform short copies until distance can be rewritten as being at least
* CHUNKCOPY_CHUNK_SIZE.
*
* Assumes it's OK to overwrite at least the first 2*CHUNKCOPY_CHUNK_SIZE
* bytes of output even if the copy is shorter than this. This assumption
* holds within zlib inflate_fast(), which starts every iteration with at
* least 258 bytes of output space available (258 being the maximum length
* output from a single token; see inffast.c).
*/
static inline unsigned char FAR* chunkunroll_relaxed(
unsigned char FAR* out,
unsigned FAR* dist,
unsigned FAR* len) {
const unsigned char FAR* from = out - *dist;
while (*dist < *len && *dist < CHUNKCOPY_CHUNK_SIZE) {
storechunk(out, loadchunk(from));
out += *dist;
*len -= *dist;
*dist += *dist;
}
return out;
}
#if defined(INFLATE_CHUNK_SIMD_NEON)
/*
* v_load64_dup(): load *src as an unaligned 64-bit int and duplicate it in
* every 64-bit component of the 128-bit result (64-bit int splat).
*/
static inline z_vec128i_t v_load64_dup(const void* src) {
return vcombine_u8(vld1_u8(src), vld1_u8(src));
}
/*
* v_load32_dup(): load *src as an unaligned 32-bit int and duplicate it in
* every 32-bit component of the 128-bit result (32-bit int splat).
*/
static inline z_vec128i_t v_load32_dup(const void* src) {
int32_t i32;
Z_BUILTIN_MEMCPY(&i32, src, sizeof(i32));
return vreinterpretq_u8_s32(vdupq_n_s32(i32));
}
/*
* v_load16_dup(): load *src as an unaligned 16-bit int and duplicate it in
* every 16-bit component of the 128-bit result (16-bit int splat).
*/
static inline z_vec128i_t v_load16_dup(const void* src) {
int16_t i16;
Z_BUILTIN_MEMCPY(&i16, src, sizeof(i16));
return vreinterpretq_u8_s16(vdupq_n_s16(i16));
}
/*
* v_load8_dup(): load the 8-bit int *src and duplicate it in every 8-bit
* component of the 128-bit result (8-bit int splat).
*/
static inline z_vec128i_t v_load8_dup(const void* src) {
return vld1q_dup_u8((const uint8_t*)src);
}
/*
* v_store_128(): store the 128-bit vec in a memory destination (that might
* not be 16-byte aligned) void* out.
*/
static inline void v_store_128(void* out, const z_vec128i_t vec) {
vst1q_u8(out, vec);
}
#elif defined (INFLATE_CHUNK_SIMD_SSE2)
/*
* v_load64_dup(): load *src as an unaligned 64-bit int and duplicate it in
* every 64-bit component of the 128-bit result (64-bit int splat).
*/
static inline z_vec128i_t v_load64_dup(const void* src) {
int64_t i64;
Z_BUILTIN_MEMCPY(&i64, src, sizeof(i64));
return _mm_set1_epi64x(i64);
}
/*
* v_load32_dup(): load *src as an unaligned 32-bit int and duplicate it in
* every 32-bit component of the 128-bit result (32-bit int splat).
*/
static inline z_vec128i_t v_load32_dup(const void* src) {
int32_t i32;
Z_BUILTIN_MEMCPY(&i32, src, sizeof(i32));
return _mm_set1_epi32(i32);
}
/*
* v_load16_dup(): load *src as an unaligned 16-bit int and duplicate it in
* every 16-bit component of the 128-bit result (16-bit int splat).
*/
static inline z_vec128i_t v_load16_dup(const void* src) {
int16_t i16;
Z_BUILTIN_MEMCPY(&i16, src, sizeof(i16));
return _mm_set1_epi16(i16);
}
/*
* v_load8_dup(): load the 8-bit int *src and duplicate it in every 8-bit
* component of the 128-bit result (8-bit int splat).
*/
static inline z_vec128i_t v_load8_dup(const void* src) {
return _mm_set1_epi8(*(const char*)src);
}
/*
* v_store_128(): store the 128-bit vec in a memory destination (that might
* not be 16-byte aligned) void* out.
*/
static inline void v_store_128(void* out, const z_vec128i_t vec) {
_mm_storeu_si128((__m128i*)out, vec);
}
#endif
/*
* Perform an overlapping copy which behaves as a memset() operation, but
* supporting periods other than one, and assume that length is non-zero and
* that it's OK to overwrite at least CHUNKCOPY_CHUNK_SIZE*3 bytes of output
* even if the length is shorter than this.
*/
static inline unsigned char FAR* chunkset_core(
unsigned char FAR* out,
unsigned period,
unsigned len) {
z_vec128i_t v;
const int bump = ((len - 1) % sizeof(v)) + 1;
switch (period) {
case 1:
v = v_load8_dup(out - 1);
v_store_128(out, v);
out += bump;
len -= bump;
while (len > 0) {
v_store_128(out, v);
out += sizeof(v);
len -= sizeof(v);
}
return out;
case 2:
v = v_load16_dup(out - 2);
v_store_128(out, v);
out += bump;
len -= bump;
if (len > 0) {
v = v_load16_dup(out - 2);
do {
v_store_128(out, v);
out += sizeof(v);
len -= sizeof(v);
} while (len > 0);
}
return out;
case 4:
v = v_load32_dup(out - 4);
v_store_128(out, v);
out += bump;
len -= bump;
if (len > 0) {
v = v_load32_dup(out - 4);
do {
v_store_128(out, v);
out += sizeof(v);
len -= sizeof(v);
} while (len > 0);
}
return out;
case 8:
v = v_load64_dup(out - 8);
v_store_128(out, v);
out += bump;
len -= bump;
if (len > 0) {
v = v_load64_dup(out - 8);
do {
v_store_128(out, v);
out += sizeof(v);
len -= sizeof(v);
} while (len > 0);
}
return out;
}
out = chunkunroll_relaxed(out, &period, &len);
return chunkcopy_core(out, out - period, len);
}
/*
* Perform a memcpy-like operation, but assume that length is non-zero and that
* it's OK to overwrite at least CHUNKCOPY_CHUNK_SIZE bytes of output even if
* the length is shorter than this.
*
* Unlike chunkcopy_core() above, no guarantee is made regarding the behaviour
* of overlapping buffers, regardless of the distance between the pointers.
* This is reflected in the `restrict`-qualified pointers, allowing the
* compiler to re-order loads and stores.
*/
static inline unsigned char FAR* chunkcopy_relaxed(
unsigned char FAR* Z_RESTRICT out,
const unsigned char FAR* Z_RESTRICT from,
unsigned len) {
return chunkcopy_core(out, from, len);
}
/*
* Like chunkcopy_relaxed(), but avoid writing beyond of legal output.
*
* Unlike chunkcopy_core_safe() above, no guarantee is made regarding the
* behaviour of overlapping buffers, regardless of the distance between the
* pointers. This is reflected in the `restrict`-qualified pointers, allowing
* the compiler to re-order loads and stores.
*
* Accepts an additional pointer to the end of safe output. A generic safe
* copy would use (out + len), but it's normally the case that the end of the
* output buffer is beyond the end of the current copy, and this can still be
* exploited.
*/
static inline unsigned char FAR* chunkcopy_safe(
unsigned char FAR* out,
const unsigned char FAR* Z_RESTRICT from,
unsigned len,
unsigned char FAR* limit) {
Assert(out + len <= limit, "chunk copy exceeds safety limit");
return chunkcopy_core_safe(out, from, len, limit);
}
/*
* Perform chunky copy within the same buffer, where the source and destination
* may potentially overlap.
*
* Assumes that len > 0 on entry, and that it's safe to write at least
* CHUNKCOPY_CHUNK_SIZE*3 bytes to the output.
*/
static inline unsigned char FAR* chunkcopy_lapped_relaxed(
unsigned char FAR* out,
unsigned dist,
unsigned len) {
if (dist < len && dist < CHUNKCOPY_CHUNK_SIZE) {
return chunkset_core(out, dist, len);
}
return chunkcopy_core(out, out - dist, len);
}
/*
* Behave like chunkcopy_lapped_relaxed(), but avoid writing beyond of legal
* output.
*
* Accepts an additional pointer to the end of safe output. A generic safe
* copy would use (out + len), but it's normally the case that the end of the
* output buffer is beyond the end of the current copy, and this can still be
* exploited.
*/
static inline unsigned char FAR* chunkcopy_lapped_safe(
unsigned char FAR* out,
unsigned dist,
unsigned len,
unsigned char FAR* limit) {
Assert(out + len <= limit, "chunk copy exceeds safety limit");
if ((limit - out) < (ptrdiff_t)(3 * CHUNKCOPY_CHUNK_SIZE)) {
/* TODO(cavalcantii): try harder to optimise this */
while (len-- > 0) {
*out = *(out - dist);
out++;
}
return out;
}
return chunkcopy_lapped_relaxed(out, dist, len);
}
/* TODO(cavalcanti): see crbug.com/1110083. */
static inline unsigned char FAR* chunkcopy_safe_ugly(unsigned char FAR* out,
unsigned dist,
unsigned len,
unsigned char FAR* limit) {
#if defined(__GNUC__) && !defined(__clang__)
/* Speed is the same as using chunkcopy_safe
w/ GCC on ARM (tested gcc 6.3 and 7.5) and avoids
undefined behavior.
*/
return chunkcopy_core_safe(out, out - dist, len, limit);
#elif defined(__clang__) && !defined(__aarch64__)
/* Seems to perform better on 32bit (i.e. Android). */
return chunkcopy_core_safe(out, out - dist, len, limit);
#else
/* Seems to perform better on 64-bit. */
return chunkcopy_lapped_safe(out, dist, len, limit);
#endif
}
/*
* The chunk-copy code above deals with writing the decoded DEFLATE data to
* the output with SIMD methods to increase decode speed. Reading the input
* to the DEFLATE decoder with a wide, SIMD method can also increase decode
* speed. This option is supported on little endian machines, and reads the
* input data in 64-bit (8 byte) chunks.
*/
#ifdef INFLATE_CHUNK_READ_64LE
/*
* Buffer the input in a uint64_t (8 bytes) in the wide input reading case.
*/
typedef uint64_t inflate_holder_t;
/*
* Ask the compiler to perform a wide, unaligned load of a uint64_t using a
* machine instruction appropriate for the uint64_t type.
*/
static inline inflate_holder_t read64le(const unsigned char FAR *in) {
inflate_holder_t input;
Z_BUILTIN_MEMCPY(&input, in, sizeof(input));
return input;
}
#else
/*
* Otherwise, buffer the input bits using zlib's default input buffer type.
*/
typedef unsigned long inflate_holder_t;
#endif /* INFLATE_CHUNK_READ_64LE */
#undef Z_STATIC_ASSERT
#undef Z_RESTRICT
#undef Z_BUILTIN_MEMCPY
#endif /* CHUNKCOPY_H */

931
external/zlib/configure vendored Executable file
View File

@@ -0,0 +1,931 @@
#!/bin/sh
# configure script for zlib.
#
# Normally configure builds both a static and a shared library.
# If you want to build just a static library, use: ./configure --static
#
# To impose specific compiler or flags or install directory, use for example:
# prefix=$HOME CC=cc CFLAGS="-O4" ./configure
# or for csh/tcsh users:
# (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure)
# Incorrect settings of CC or CFLAGS may prevent creating a shared library.
# If you have problems, try without defining CC and CFLAGS before reporting
# an error.
# start off configure.log
echo -------------------- >> configure.log
echo $0 $* >> configure.log
date >> configure.log
# set command prefix for cross-compilation
if [ -n "${CHOST}" ]; then
uname="`echo "${CHOST}" | sed -e 's/^[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)-.*$/\1/'`"
CROSS_PREFIX="${CHOST}-"
fi
# destination name for static library
STATICLIB=libz.a
# extract zlib version numbers from zlib.h
VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`
VER3=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\\.[0-9]*\).*/\1/p' < zlib.h`
VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < zlib.h`
VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < zlib.h`
# establish commands for library building
if "${CROSS_PREFIX}ar" --version >/dev/null 2>/dev/null || test $? -lt 126; then
AR=${AR-"${CROSS_PREFIX}ar"}
test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log
else
AR=${AR-"ar"}
test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log
fi
ARFLAGS=${ARFLAGS-"rc"}
if "${CROSS_PREFIX}ranlib" --version >/dev/null 2>/dev/null || test $? -lt 126; then
RANLIB=${RANLIB-"${CROSS_PREFIX}ranlib"}
test -n "${CROSS_PREFIX}" && echo Using ${RANLIB} | tee -a configure.log
else
RANLIB=${RANLIB-"ranlib"}
fi
if "${CROSS_PREFIX}nm" --version >/dev/null 2>/dev/null || test $? -lt 126; then
NM=${NM-"${CROSS_PREFIX}nm"}
test -n "${CROSS_PREFIX}" && echo Using ${NM} | tee -a configure.log
else
NM=${NM-"nm"}
fi
# set defaults before processing command line options
LDCONFIG=${LDCONFIG-"ldconfig"}
LDSHAREDLIBC="${LDSHAREDLIBC--lc}"
ARCHS= # target specific flags
TGT_ARCH=$(uname -m) # the name of target architecture
prefix=${prefix-/usr/local}
exec_prefix=${exec_prefix-'${prefix}'}
libdir=${libdir-'${exec_prefix}/lib'}
sharedlibdir=${sharedlibdir-'${libdir}'}
includedir=${includedir-'${prefix}/include'}
mandir=${mandir-'${prefix}/share/man'}
shared_ext='.so'
shared=1
solo=0
cover=0
zprefix=0
zconst=0
build64=0
gcc=0
old_cc="$CC"
old_cflags="$CFLAGS"
OBJC='$(OBJZ) $(OBJG)'
PIC_OBJC='$(PIC_OBJZ) $(PIC_OBJG)'
# leave this script, optionally in a bad way
leave()
{
if test "$*" != "0"; then
echo "** $0 aborting." | tee -a configure.log
fi
rm -f $test.[co] $test $test$shared_ext $test.gcno ./--version
echo -------------------- >> configure.log
echo >> configure.log
echo >> configure.log
exit $1
}
# process command line options
while test $# -ge 1
do
case "$1" in
-h* | --help)
echo 'usage:' | tee -a configure.log
echo ' configure [--const] [--zprefix] [--prefix=PREFIX] [--eprefix=EXPREFIX]' | tee -a configure.log
echo ' [--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' | tee -a configure.log
echo ' [--includedir=INCLUDEDIR] [--archs="-arch i386 -arch x86_64"]' | tee -a configure.log
exit 0 ;;
-p*=* | --prefix=*) prefix=`echo $1 | sed 's/.*=//'`; shift ;;
-e*=* | --eprefix=*) exec_prefix=`echo $1 | sed 's/.*=//'`; shift ;;
-l*=* | --libdir=*) libdir=`echo $1 | sed 's/.*=//'`; shift ;;
--sharedlibdir=*) sharedlibdir=`echo $1 | sed 's/.*=//'`; shift ;;
-i*=* | --includedir=*) includedir=`echo $1 | sed 's/.*=//'`;shift ;;
-u*=* | --uname=*) uname=`echo $1 | sed 's/.*=//'`;shift ;;
-p* | --prefix) prefix="$2"; shift; shift ;;
-e* | --eprefix) exec_prefix="$2"; shift; shift ;;
-l* | --libdir) libdir="$2"; shift; shift ;;
-i* | --includedir) includedir="$2"; shift; shift ;;
-s* | --shared | --enable-shared) shared=1; shift ;;
-t | --static) shared=0; shift ;;
--solo) solo=1; shift ;;
--cover) cover=1; shift ;;
-z* | --zprefix) zprefix=1; shift ;;
-6* | --64) build64=1; shift ;;
-a*=* | --archs=*) ARCHS=`echo $1 | sed 's/.*=//'`; shift ;;
-T*=* | --target=*) TGT_ARCH=`echo $1 | sed 's/.*=//'`; shift ;;
--sysconfdir=*) echo "ignored option: --sysconfdir" | tee -a configure.log; shift ;;
--localstatedir=*) echo "ignored option: --localstatedir" | tee -a configure.log; shift ;;
-c* | --const) zconst=1; shift ;;
*)
echo "unknown option: $1" | tee -a configure.log
echo "$0 --help for help" | tee -a configure.log
leave 1;;
esac
done
# temporary file name
test=ztest$$
# put arguments in log, also put test file in log if used in arguments
show()
{
case "$*" in
*$test.c*)
echo === $test.c === >> configure.log
cat $test.c >> configure.log
echo === >> configure.log;;
esac
echo $* >> configure.log
}
# check for gcc vs. cc and set compile and link flags based on the system identified by uname
cat > $test.c <<EOF
extern int getchar();
int hello() {return getchar();}
EOF
test -z "$CC" && echo Checking for ${CROSS_PREFIX}gcc... | tee -a configure.log
cc=${CC-${CROSS_PREFIX}gcc}
cflags=${CFLAGS-"-O3"}
# to force the asm version use: CFLAGS="-O3 -DASMV" ./configure
case "$cc" in
*gcc*) gcc=1 ;;
*clang*) gcc=1 ;;
esac
case `$cc -v 2>&1` in
*gcc*) gcc=1 ;;
esac
show $cc -c $test.c
if test "$gcc" -eq 1 && ($cc -c $test.c) >> configure.log 2>&1; then
echo ... using gcc >> configure.log
CC="$cc"
CFLAGS="${CFLAGS--O3} ${ARCHS}"
SFLAGS="${CFLAGS--O3} -fPIC"
LDFLAGS="${LDFLAGS} ${ARCHS}"
if test $build64 -eq 1; then
CFLAGS="${CFLAGS} -m64"
SFLAGS="${SFLAGS} -m64"
fi
if test "${ZLIBGCCWARN}" = "YES"; then
if test "$zconst" -eq 1; then
CFLAGS="${CFLAGS} -Wall -Wextra -Wcast-qual -pedantic -DZLIB_CONST"
else
CFLAGS="${CFLAGS} -Wall -Wextra -pedantic"
fi
fi
if test -z "$uname"; then
uname=`(uname -s || echo unknown) 2>/dev/null`
fi
case "$uname" in
Linux* | linux* | GNU | GNU/* | solaris*)
LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map"} ;;
*BSD | *bsd* | DragonFly)
LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map"}
LDCONFIG="ldconfig -m" ;;
CYGWIN* | Cygwin* | cygwin* | OS/2*)
EXE='.exe' ;;
MINGW* | mingw*)
# temporary bypass
rm -f $test.[co] $test $test$shared_ext
echo "Please use win32/Makefile.gcc instead." | tee -a configure.log
leave 1
LDSHARED=${LDSHARED-"$cc -shared"}
LDSHAREDLIBC=""
EXE='.exe' ;;
QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4
# (alain.bonnefoy@icbt.com)
LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"} ;;
HP-UX*)
LDSHARED=${LDSHARED-"$cc -shared $SFLAGS"}
case `(uname -m || echo unknown) 2>/dev/null` in
ia64)
shared_ext='.so'
SHAREDLIB='libz.so' ;;
*)
shared_ext='.sl'
SHAREDLIB='libz.sl' ;;
esac ;;
Darwin* | darwin*)
shared_ext='.dylib'
SHAREDLIB=libz$shared_ext
SHAREDLIBV=libz.$VER$shared_ext
SHAREDLIBM=libz.$VER1$shared_ext
LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER3"}
if libtool -V 2>&1 | grep Apple > /dev/null; then
AR="libtool"
else
AR="/usr/bin/libtool"
fi
ARFLAGS="-o" ;;
*) LDSHARED=${LDSHARED-"$cc -shared"} ;;
esac
else
# find system name and corresponding cc options
CC=${CC-cc}
gcc=0
echo ... using $CC >> configure.log
if test -z "$uname"; then
uname=`(uname -sr || echo unknown) 2>/dev/null`
fi
case "$uname" in
HP-UX*) SFLAGS=${CFLAGS-"-O +z"}
CFLAGS=${CFLAGS-"-O"}
# LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"}
LDSHARED=${LDSHARED-"ld -b"}
case `(uname -m || echo unknown) 2>/dev/null` in
ia64)
shared_ext='.so'
SHAREDLIB='libz.so' ;;
*)
shared_ext='.sl'
SHAREDLIB='libz.sl' ;;
esac ;;
IRIX*) SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."}
CFLAGS=${CFLAGS-"-ansi -O2"}
LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;;
OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"}
CFLAGS=${CFLAGS-"-O -std1"}
LDFLAGS="${LDFLAGS} -Wl,-rpath,."
LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"} ;;
OSF1*) SFLAGS=${CFLAGS-"-O -std1"}
CFLAGS=${CFLAGS-"-O -std1"}
LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;;
QNX*) SFLAGS=${CFLAGS-"-4 -O"}
CFLAGS=${CFLAGS-"-4 -O"}
LDSHARED=${LDSHARED-"cc"}
RANLIB=${RANLIB-"true"}
AR="cc"
ARFLAGS="-A" ;;
SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "}
CFLAGS=${CFLAGS-"-O3"}
LDSHARED=${LDSHARED-"cc -dy -KPIC -G"} ;;
SunOS\ 5* | solaris*)
LDSHARED=${LDSHARED-"cc -G -h libz$shared_ext.$VER1"}
SFLAGS=${CFLAGS-"-fast -KPIC"}
CFLAGS=${CFLAGS-"-fast"}
if test $build64 -eq 1; then
# old versions of SunPRO/Workshop/Studio don't support -m64,
# but newer ones do. Check for it.
flag64=`$CC -flags | egrep -- '^-m64'`
if test x"$flag64" != x"" ; then
CFLAGS="${CFLAGS} -m64"
SFLAGS="${SFLAGS} -m64"
else
case `(uname -m || echo unknown) 2>/dev/null` in
i86*)
SFLAGS="$SFLAGS -xarch=amd64"
CFLAGS="$CFLAGS -xarch=amd64" ;;
*)
SFLAGS="$SFLAGS -xarch=v9"
CFLAGS="$CFLAGS -xarch=v9" ;;
esac
fi
fi
;;
SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"}
CFLAGS=${CFLAGS-"-O2"}
LDSHARED=${LDSHARED-"ld"} ;;
SunStudio\ 9*) SFLAGS=${CFLAGS-"-fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"}
CFLAGS=${CFLAGS-"-fast -xtarget=ultra3 -xarch=v9b"}
LDSHARED=${LDSHARED-"cc -xarch=v9b"} ;;
UNIX_System_V\ 4.2.0)
SFLAGS=${CFLAGS-"-KPIC -O"}
CFLAGS=${CFLAGS-"-O"}
LDSHARED=${LDSHARED-"cc -G"} ;;
UNIX_SV\ 4.2MP)
SFLAGS=${CFLAGS-"-Kconform_pic -O"}
CFLAGS=${CFLAGS-"-O"}
LDSHARED=${LDSHARED-"cc -G"} ;;
OpenUNIX\ 5)
SFLAGS=${CFLAGS-"-KPIC -O"}
CFLAGS=${CFLAGS-"-O"}
LDSHARED=${LDSHARED-"cc -G"} ;;
AIX*) # Courtesy of dbakker@arrayasolutions.com
SFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
CFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
LDSHARED=${LDSHARED-"xlc -G"} ;;
# send working options for other systems to zlib@gzip.org
*) SFLAGS=${CFLAGS-"-O"}
CFLAGS=${CFLAGS-"-O"}
LDSHARED=${LDSHARED-"cc -shared"} ;;
esac
fi
# destination names for shared library if not defined above
SHAREDLIB=${SHAREDLIB-"libz$shared_ext"}
SHAREDLIBV=${SHAREDLIBV-"libz$shared_ext.$VER"}
SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"}
echo >> configure.log
# define functions for testing compiler and library characteristics and logging the results
cat > $test.c <<EOF
#error error
EOF
if ($CC -c $CFLAGS $test.c) 2>/dev/null; then
try()
{
show $*
test "`( $* ) 2>&1 | tee -a configure.log`" = ""
}
echo - using any output from compiler to indicate an error >> configure.log
else
try()
{
show $*
( $* ) >> configure.log 2>&1
ret=$?
if test $ret -ne 0; then
echo "(exit code "$ret")" >> configure.log
fi
return $ret
}
fi
tryboth()
{
show $*
got=`( $* ) 2>&1`
ret=$?
printf %s "$got" >> configure.log
if test $ret -ne 0; then
return $ret
fi
test "$got" = ""
}
cat > $test.c << EOF
int foo() { return 0; }
EOF
echo "Checking for obsessive-compulsive compiler options..." >> configure.log
if try $CC -c $CFLAGS $test.c; then
:
else
echo "Compiler error reporting is too harsh for $0 (perhaps remove -Werror)." | tee -a configure.log
leave 1
fi
echo >> configure.log
# see if shared library build supported
cat > $test.c <<EOF
extern int getchar();
int hello() {return getchar();}
EOF
if test $shared -eq 1; then
echo Checking for shared library support... | tee -a configure.log
# we must test in two steps (cc then ld), required at least on SunOS 4.x
if try $CC -w -c $SFLAGS $test.c &&
try $LDSHARED $SFLAGS -o $test$shared_ext $test.o; then
echo Building shared library $SHAREDLIBV with $CC. | tee -a configure.log
elif test -z "$old_cc" -a -z "$old_cflags"; then
echo No shared library support. | tee -a configure.log
shared=0;
else
echo 'No shared library support; try without defining CC and CFLAGS' | tee -a configure.log
shared=0;
fi
fi
if test $shared -eq 0; then
LDSHARED="$CC"
ALL="static"
TEST="all teststatic"
SHAREDLIB=""
SHAREDLIBV=""
SHAREDLIBM=""
echo Building static library $STATICLIB version $VER with $CC. | tee -a configure.log
else
ALL="static shared"
TEST="all teststatic testshared"
fi
# check for underscores in external names for use by assembler code
CPP=${CPP-"$CC -E"}
case $CFLAGS in
*ASMV*)
echo >> configure.log
show "$NM $test.o | grep _hello"
if test "`$NM $test.o | grep _hello | tee -a configure.log`" = ""; then
CPP="$CPP -DNO_UNDERLINE"
echo Checking for underline in external names... No. | tee -a configure.log
else
echo Checking for underline in external names... Yes. | tee -a configure.log
fi ;;
esac
echo >> configure.log
# check for large file support, and if none, check for fseeko()
cat > $test.c <<EOF
#include <sys/types.h>
off64_t dummy = 0;
EOF
if try $CC -c $CFLAGS -D_LARGEFILE64_SOURCE=1 $test.c; then
CFLAGS="${CFLAGS} -D_LARGEFILE64_SOURCE=1"
SFLAGS="${SFLAGS} -D_LARGEFILE64_SOURCE=1"
ALL="${ALL} all64"
TEST="${TEST} test64"
echo "Checking for off64_t... Yes." | tee -a configure.log
echo "Checking for fseeko... Yes." | tee -a configure.log
else
echo "Checking for off64_t... No." | tee -a configure.log
echo >> configure.log
cat > $test.c <<EOF
#include <stdio.h>
int main(void) {
fseeko(NULL, 0, 0);
return 0;
}
EOF
if try $CC $CFLAGS -o $test $test.c; then
echo "Checking for fseeko... Yes." | tee -a configure.log
else
CFLAGS="${CFLAGS} -DNO_FSEEKO"
SFLAGS="${SFLAGS} -DNO_FSEEKO"
echo "Checking for fseeko... No." | tee -a configure.log
fi
fi
echo >> configure.log
# check for strerror() for use by gz* functions
cat > $test.c <<EOF
#include <string.h>
#include <errno.h>
int main() { return strlen(strerror(errno)); }
EOF
if try $CC $CFLAGS -o $test $test.c; then
echo "Checking for strerror... Yes." | tee -a configure.log
else
CFLAGS="${CFLAGS} -DNO_STRERROR"
SFLAGS="${SFLAGS} -DNO_STRERROR"
echo "Checking for strerror... No." | tee -a configure.log
fi
# copy clean zconf.h for subsequent edits
cp -p zconf.h.in zconf.h
echo >> configure.log
# check for unistd.h and save result in zconf.h
cat > $test.c <<EOF
#include <unistd.h>
int main() { return 0; }
EOF
if try $CC -c $CFLAGS $test.c; then
sed < zconf.h "/^#ifdef HAVE_UNISTD_H.* may be/s/def HAVE_UNISTD_H\(.*\) may be/ 1\1 was/" > zconf.temp.h
mv zconf.temp.h zconf.h
echo "Checking for unistd.h... Yes." | tee -a configure.log
else
echo "Checking for unistd.h... No." | tee -a configure.log
fi
echo >> configure.log
# check for stdarg.h and save result in zconf.h
cat > $test.c <<EOF
#include <stdarg.h>
int main() { return 0; }
EOF
if try $CC -c $CFLAGS $test.c; then
sed < zconf.h "/^#ifdef HAVE_STDARG_H.* may be/s/def HAVE_STDARG_H\(.*\) may be/ 1\1 was/" > zconf.temp.h
mv zconf.temp.h zconf.h
echo "Checking for stdarg.h... Yes." | tee -a configure.log
else
echo "Checking for stdarg.h... No." | tee -a configure.log
fi
# if the z_ prefix was requested, save that in zconf.h
if test $zprefix -eq 1; then
sed < zconf.h "/#ifdef Z_PREFIX.* may be/s/def Z_PREFIX\(.*\) may be/ 1\1 was/" > zconf.temp.h
mv zconf.temp.h zconf.h
echo >> configure.log
echo "Using z_ prefix on all symbols." | tee -a configure.log
fi
# if --solo compilation was requested, save that in zconf.h and remove gz stuff from object lists
if test $solo -eq 1; then
sed '/#define ZCONF_H/a\
#define Z_SOLO
' < zconf.h > zconf.temp.h
mv zconf.temp.h zconf.h
OBJC='$(OBJZ)'
PIC_OBJC='$(PIC_OBJZ)'
fi
# if code coverage testing was requested, use older gcc if defined, e.g. "gcc-4.2" on Mac OS X
if test $cover -eq 1; then
CFLAGS="${CFLAGS} -fprofile-arcs -ftest-coverage"
if test -n "$GCC_CLASSIC"; then
CC=$GCC_CLASSIC
fi
fi
echo >> configure.log
# conduct a series of tests to resolve eight possible cases of using "vs" or "s" printf functions
# (using stdarg or not), with or without "n" (proving size of buffer), and with or without a
# return value. The most secure result is vsnprintf() with a return value. snprintf() with a
# return value is secure as well, but then gzprintf() will be limited to 20 arguments.
cat > $test.c <<EOF
#include <stdio.h>
#include <stdarg.h>
#include "zconf.h"
int main()
{
#ifndef STDC
choke me
#endif
return 0;
}
EOF
if try $CC -c $CFLAGS $test.c; then
echo "Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()." | tee -a configure.log
echo >> configure.log
cat > $test.c <<EOF
#include <stdio.h>
#include <stdarg.h>
int mytest(const char *fmt, ...)
{
char buf[20];
va_list ap;
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
return 0;
}
int main()
{
return (mytest("Hello%d\n", 1));
}
EOF
if try $CC $CFLAGS -o $test $test.c; then
echo "Checking for vsnprintf() in stdio.h... Yes." | tee -a configure.log
echo >> configure.log
cat >$test.c <<EOF
#include <stdio.h>
#include <stdarg.h>
int mytest(const char *fmt, ...)
{
int n;
char buf[20];
va_list ap;
va_start(ap, fmt);
n = vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
return n;
}
int main()
{
return (mytest("Hello%d\n", 1));
}
EOF
if try $CC -c $CFLAGS $test.c; then
echo "Checking for return value of vsnprintf()... Yes." | tee -a configure.log
else
CFLAGS="$CFLAGS -DHAS_vsnprintf_void"
SFLAGS="$SFLAGS -DHAS_vsnprintf_void"
echo "Checking for return value of vsnprintf()... No." | tee -a configure.log
echo " WARNING: apparently vsnprintf() does not return a value. zlib" | tee -a configure.log
echo " can build but will be open to possible string-format security" | tee -a configure.log
echo " vulnerabilities." | tee -a configure.log
fi
else
CFLAGS="$CFLAGS -DNO_vsnprintf"
SFLAGS="$SFLAGS -DNO_vsnprintf"
echo "Checking for vsnprintf() in stdio.h... No." | tee -a configure.log
echo " WARNING: vsnprintf() not found, falling back to vsprintf(). zlib" | tee -a configure.log
echo " can build but will be open to possible buffer-overflow security" | tee -a configure.log
echo " vulnerabilities." | tee -a configure.log
echo >> configure.log
cat >$test.c <<EOF
#include <stdio.h>
#include <stdarg.h>
int mytest(const char *fmt, ...)
{
int n;
char buf[20];
va_list ap;
va_start(ap, fmt);
n = vsprintf(buf, fmt, ap);
va_end(ap);
return n;
}
int main()
{
return (mytest("Hello%d\n", 1));
}
EOF
if try $CC -c $CFLAGS $test.c; then
echo "Checking for return value of vsprintf()... Yes." | tee -a configure.log
else
CFLAGS="$CFLAGS -DHAS_vsprintf_void"
SFLAGS="$SFLAGS -DHAS_vsprintf_void"
echo "Checking for return value of vsprintf()... No." | tee -a configure.log
echo " WARNING: apparently vsprintf() does not return a value. zlib" | tee -a configure.log
echo " can build but will be open to possible string-format security" | tee -a configure.log
echo " vulnerabilities." | tee -a configure.log
fi
fi
else
echo "Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf()." | tee -a configure.log
echo >> configure.log
cat >$test.c <<EOF
#include <stdio.h>
int mytest()
{
char buf[20];
snprintf(buf, sizeof(buf), "%s", "foo");
return 0;
}
int main()
{
return (mytest());
}
EOF
if try $CC $CFLAGS -o $test $test.c; then
echo "Checking for snprintf() in stdio.h... Yes." | tee -a configure.log
echo >> configure.log
cat >$test.c <<EOF
#include <stdio.h>
int mytest()
{
char buf[20];
return snprintf(buf, sizeof(buf), "%s", "foo");
}
int main()
{
return (mytest());
}
EOF
if try $CC -c $CFLAGS $test.c; then
echo "Checking for return value of snprintf()... Yes." | tee -a configure.log
else
CFLAGS="$CFLAGS -DHAS_snprintf_void"
SFLAGS="$SFLAGS -DHAS_snprintf_void"
echo "Checking for return value of snprintf()... No." | tee -a configure.log
echo " WARNING: apparently snprintf() does not return a value. zlib" | tee -a configure.log
echo " can build but will be open to possible string-format security" | tee -a configure.log
echo " vulnerabilities." | tee -a configure.log
fi
else
CFLAGS="$CFLAGS -DNO_snprintf"
SFLAGS="$SFLAGS -DNO_snprintf"
echo "Checking for snprintf() in stdio.h... No." | tee -a configure.log
echo " WARNING: snprintf() not found, falling back to sprintf(). zlib" | tee -a configure.log
echo " can build but will be open to possible buffer-overflow security" | tee -a configure.log
echo " vulnerabilities." | tee -a configure.log
echo >> configure.log
cat >$test.c <<EOF
#include <stdio.h>
int mytest()
{
char buf[20];
return sprintf(buf, "%s", "foo");
}
int main()
{
return (mytest());
}
EOF
if try $CC -c $CFLAGS $test.c; then
echo "Checking for return value of sprintf()... Yes." | tee -a configure.log
else
CFLAGS="$CFLAGS -DHAS_sprintf_void"
SFLAGS="$SFLAGS -DHAS_sprintf_void"
echo "Checking for return value of sprintf()... No." | tee -a configure.log
echo " WARNING: apparently sprintf() does not return a value. zlib" | tee -a configure.log
echo " can build but will be open to possible string-format security" | tee -a configure.log
echo " vulnerabilities." | tee -a configure.log
fi
fi
fi
# see if we can hide zlib internal symbols that are linked between separate source files
if test "$gcc" -eq 1; then
echo >> configure.log
cat > $test.c <<EOF
#define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
int ZLIB_INTERNAL foo;
int main()
{
return 0;
}
EOF
if tryboth $CC -c $CFLAGS $test.c; then
CFLAGS="$CFLAGS -DHAVE_HIDDEN"
SFLAGS="$SFLAGS -DHAVE_HIDDEN"
echo "Checking for attribute(visibility) support... Yes." | tee -a configure.log
else
echo "Checking for attribute(visibility) support... No." | tee -a configure.log
fi
fi
# Check for AMD64 hardware support.
if [ x$TGT_ARCH = "xx86_64" -o x$TGT_ARCH = "xamd64" ] ; then
cat > $test.c << EOF
#include <emmintrin.h>
void foo(void) {
__m64 a, b;
_mm_add_si64(a, b);
}
EOF
if try $CC -msse2 $CFLAGS $test.c -c $test; then
CFLAGS="-DINFLATE_CHUNK_SIMD_SSE2 -msse2 -DINFLATE_CHUNK_READ_64LE $CFLAGS"
SFLAGS="-DINFLATE_CHUNK_SIMD_SSE2 -msse2 -DINFLATE_CHUNK_READ_64LE $SFLAGS"
echo "Checking for SSE2 support ... Yes" | tee -a configure.log
else
echo "Checking for SSE2 support ... No" | tee -a configure.log
leave 1
fi
# Check for SSSE3 support
cat > $test.c << EOF
#include <tmmintrin.h>
void foo(void) {
__m128i a;
_mm_abs_epi8(a);
}
EOF
if try $CC -mssse3 $CFLAGS $test.c -c $test; then
CFLAGS="-DADLER32_SIMD_SSSE3 -mssse3 $CFLAGS"
SFLAGS="-DADLER32_SIMD_SSSE3 -mssse3 $SFLAGS"
echo "Checking for SSSE3 support ... Yes" | tee -a configure.log
else
echo "Checking for SSSE3 support ... No" | tee -a configure.log
leave 1
fi
# Check for SSE4.2 and CRC support
cat > $test.c << EOF
#include <immintrin.h>
void foo(void) {
_mm_crc32_u32(0, 0);
}
EOF
if try $CC -msse4.2 $CFLAGS $test.c -c $test; then
CFLAGS="-DHAS_SSE42 -msse4.2 $CFLAGS"
SFLAGS="-DHAS_SSE42 -msse4.2 $SFLAGS"
echo "Checking for CRC and SSE4.2 support ... Yes" | tee -a configure.log
else
echo "Checking for CRC and SSE4.2 support ... No" | tee -a configure.log
echo "CRC and SSE4.2 support is required" | tee -a configure.log
leave 1
fi
#Project copied from zlib-ng:
# Check for PCLMUL support
cat > $test.c << EOF
#include <immintrin.h>
int main(void) {
__m128i a = _mm_setzero_si128();
__m128i b = _mm_setzero_si128();
__m128i c = _mm_clmulepi64_si128(a, b, 0x10);
(void)c;
return 0;
}
EOF
if try $CC -c -mpclmul $CFLAGS $test.c ; then
CFLAGS="-DHAS_PCLMUL -mpclmul $CFLAGS"
SFLAGS="-DHAS_PCLMUL -mpclmul $SFLAGS"
echo "Checking for PCLMUL support ... Yes" | tee -a configure.log
else
echo "Checking for PCLMUL support ... No" | tee -a configure.log
fi
elif [ x$TGT_ARCH = "xaarch64" ] ; then
# Check for NEON and CRC support
cat > $test.c << EOF
#include <arm_neon.h>
#include <arm_acle.h>
void foo(void) {
__crc32cw(0, 0);
vqsubq_u16(vmovq_n_u16(1), vmovq_n_u16(2));
}
EOF
if try $CC -march=armv8-a+crc $CFLAGS $test.c -c $test; then
CFLAGS="-march=armv8-a+crc -DADLER32_SIMD_NEON -DINFLATE_CHUNK_SIMD_NEON -DINFLATE_CHUNK_READ_64LE $CFLAGS"
SFLAGS="-march=armv8-a+crc -DADLER32_SIMD_NEON -DINFLATE_CHUNK_SIMD_NEON -DINFLATE_CHUNK_READ_64LE $SFLAGS"
echo "Checking for CRC and NEON support ... Yes" | tee -a configure.log
else
echo "Checking for CRC and NEON support ... No" | tee -a configure.log
echo "CRC and NEON support is required" | tee -a configure.log
leave 1
fi
fi # end of "Check amd64 hardware support"
# show the results in the log
echo >> configure.log
echo ALL = $ALL >> configure.log
echo AR = $AR >> configure.log
echo ARFLAGS = $ARFLAGS >> configure.log
echo CC = $CC >> configure.log
echo CFLAGS = $CFLAGS >> configure.log
echo CPP = $CPP >> configure.log
echo EXE = $EXE >> configure.log
echo LDCONFIG = $LDCONFIG >> configure.log
echo LDFLAGS = $LDFLAGS >> configure.log
echo LDSHARED = $LDSHARED >> configure.log
echo LDSHAREDLIBC = $LDSHAREDLIBC >> configure.log
echo OBJC = $OBJC >> configure.log
echo PIC_OBJC = $PIC_OBJC >> configure.log
echo RANLIB = $RANLIB >> configure.log
echo SFLAGS = $SFLAGS >> configure.log
echo SHAREDLIB = $SHAREDLIB >> configure.log
echo SHAREDLIBM = $SHAREDLIBM >> configure.log
echo SHAREDLIBV = $SHAREDLIBV >> configure.log
echo STATICLIB = $STATICLIB >> configure.log
echo TEST = $TEST >> configure.log
echo VER = $VER >> configure.log
echo Z_U4 = $Z_U4 >> configure.log
echo exec_prefix = $exec_prefix >> configure.log
echo includedir = $includedir >> configure.log
echo libdir = $libdir >> configure.log
echo mandir = $mandir >> configure.log
echo prefix = $prefix >> configure.log
echo sharedlibdir = $sharedlibdir >> configure.log
echo uname = $uname >> configure.log
# udpate Makefile with the configure results
sed < Makefile.in "
/^TGT_ARCH *=/s#=.*#=$TGT_ARCH#
/^CC *=/s#=.*#=$CC#
/^CFLAGS *=/s#=.*#=$CFLAGS#
/^SFLAGS *=/s#=.*#=$SFLAGS#
/^LDFLAGS *=/s#=.*#=$LDFLAGS#
/^LDSHARED *=/s#=.*#=$LDSHARED#
/^CPP *=/s#=.*#=$CPP#
/^STATICLIB *=/s#=.*#=$STATICLIB#
/^SHAREDLIB *=/s#=.*#=$SHAREDLIB#
/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV#
/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM#
/^AR *=/s#=.*#=$AR#
/^ARFLAGS *=/s#=.*#=$ARFLAGS#
/^RANLIB *=/s#=.*#=$RANLIB#
/^LDCONFIG *=/s#=.*#=$LDCONFIG#
/^LDSHAREDLIBC *=/s#=.*#=$LDSHAREDLIBC#
/^EXE *=/s#=.*#=$EXE#
/^prefix *=/s#=.*#=$prefix#
/^exec_prefix *=/s#=.*#=$exec_prefix#
/^libdir *=/s#=.*#=$libdir#
/^sharedlibdir *=/s#=.*#=$sharedlibdir#
/^includedir *=/s#=.*#=$includedir#
/^mandir *=/s#=.*#=$mandir#
/^OBJC *=/s#=.*#= $OBJC#
/^PIC_OBJC *=/s#=.*#= $PIC_OBJC#
/^all: */s#:.*#: $ALL#
/^test: */s#:.*#: $TEST#
" > Makefile
# create zlib.pc with the configure results
sed < zlib.pc.in "
/^CC *=/s#=.*#=$CC#
/^CFLAGS *=/s#=.*#=$CFLAGS#
/^CPP *=/s#=.*#=$CPP#
/^LDSHARED *=/s#=.*#=$LDSHARED#
/^STATICLIB *=/s#=.*#=$STATICLIB#
/^SHAREDLIB *=/s#=.*#=$SHAREDLIB#
/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV#
/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM#
/^AR *=/s#=.*#=$AR#
/^ARFLAGS *=/s#=.*#=$ARFLAGS#
/^RANLIB *=/s#=.*#=$RANLIB#
/^EXE *=/s#=.*#=$EXE#
/^prefix *=/s#=.*#=$prefix#
/^exec_prefix *=/s#=.*#=$exec_prefix#
/^libdir *=/s#=.*#=$libdir#
/^sharedlibdir *=/s#=.*#=$sharedlibdir#
/^includedir *=/s#=.*#=$includedir#
/^mandir *=/s#=.*#=$mandir#
/^LDFLAGS *=/s#=.*#=$LDFLAGS#
" | sed -e "
s/\@VERSION\@/$VER/g;
" > zlib.pc
# done
leave 0

244
external/zlib/crc32_simd.c vendored Normal file
View File

@@ -0,0 +1,244 @@
/* crc32_simd.c
*
* Copyright 2017 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the Chromium source repository LICENSE file.
*/
#include "crc32_simd.h"
#if defined(CRC32_SIMD_SSE42_PCLMUL)
/*
* crc32_sse42_simd_(): compute the crc32 of the buffer, where the buffer
* length must be at least 64, and a multiple of 16. Based on:
*
* "Fast CRC Computation for Generic Polynomials Using PCLMULQDQ Instruction"
* V. Gopal, E. Ozturk, et al., 2009, http://intel.ly/2ySEwL0
*/
#include <emmintrin.h>
#include <smmintrin.h>
#include <wmmintrin.h>
uint32_t ZLIB_INTERNAL crc32_sse42_simd_( /* SSE4.2+PCLMUL */
const unsigned char *buf,
z_size_t len,
uint32_t crc)
{
/*
* Definitions of the bit-reflected domain constants k1,k2,k3, etc and
* the CRC32+Barrett polynomials given at the end of the paper.
*/
static const uint64_t zalign(16) k1k2[] = { 0x0154442bd4, 0x01c6e41596 };
static const uint64_t zalign(16) k3k4[] = { 0x01751997d0, 0x00ccaa009e };
static const uint64_t zalign(16) k5k0[] = { 0x0163cd6124, 0x0000000000 };
static const uint64_t zalign(16) poly[] = { 0x01db710641, 0x01f7011641 };
__m128i x0, x1, x2, x3, x4, x5, x6, x7, x8, y5, y6, y7, y8;
/*
* There's at least one block of 64.
*/
x1 = _mm_loadu_si128((__m128i *)(buf + 0x00));
x2 = _mm_loadu_si128((__m128i *)(buf + 0x10));
x3 = _mm_loadu_si128((__m128i *)(buf + 0x20));
x4 = _mm_loadu_si128((__m128i *)(buf + 0x30));
x1 = _mm_xor_si128(x1, _mm_cvtsi32_si128(crc));
x0 = _mm_load_si128((__m128i *)k1k2);
buf += 64;
len -= 64;
/*
* Parallel fold blocks of 64, if any.
*/
while (len >= 64)
{
x5 = _mm_clmulepi64_si128(x1, x0, 0x00);
x6 = _mm_clmulepi64_si128(x2, x0, 0x00);
x7 = _mm_clmulepi64_si128(x3, x0, 0x00);
x8 = _mm_clmulepi64_si128(x4, x0, 0x00);
x1 = _mm_clmulepi64_si128(x1, x0, 0x11);
x2 = _mm_clmulepi64_si128(x2, x0, 0x11);
x3 = _mm_clmulepi64_si128(x3, x0, 0x11);
x4 = _mm_clmulepi64_si128(x4, x0, 0x11);
y5 = _mm_loadu_si128((__m128i *)(buf + 0x00));
y6 = _mm_loadu_si128((__m128i *)(buf + 0x10));
y7 = _mm_loadu_si128((__m128i *)(buf + 0x20));
y8 = _mm_loadu_si128((__m128i *)(buf + 0x30));
x1 = _mm_xor_si128(x1, x5);
x2 = _mm_xor_si128(x2, x6);
x3 = _mm_xor_si128(x3, x7);
x4 = _mm_xor_si128(x4, x8);
x1 = _mm_xor_si128(x1, y5);
x2 = _mm_xor_si128(x2, y6);
x3 = _mm_xor_si128(x3, y7);
x4 = _mm_xor_si128(x4, y8);
buf += 64;
len -= 64;
}
/*
* Fold into 128-bits.
*/
x0 = _mm_load_si128((__m128i *)k3k4);
x5 = _mm_clmulepi64_si128(x1, x0, 0x00);
x1 = _mm_clmulepi64_si128(x1, x0, 0x11);
x1 = _mm_xor_si128(x1, x2);
x1 = _mm_xor_si128(x1, x5);
x5 = _mm_clmulepi64_si128(x1, x0, 0x00);
x1 = _mm_clmulepi64_si128(x1, x0, 0x11);
x1 = _mm_xor_si128(x1, x3);
x1 = _mm_xor_si128(x1, x5);
x5 = _mm_clmulepi64_si128(x1, x0, 0x00);
x1 = _mm_clmulepi64_si128(x1, x0, 0x11);
x1 = _mm_xor_si128(x1, x4);
x1 = _mm_xor_si128(x1, x5);
/*
* Single fold blocks of 16, if any.
*/
while (len >= 16)
{
x2 = _mm_loadu_si128((__m128i *)buf);
x5 = _mm_clmulepi64_si128(x1, x0, 0x00);
x1 = _mm_clmulepi64_si128(x1, x0, 0x11);
x1 = _mm_xor_si128(x1, x2);
x1 = _mm_xor_si128(x1, x5);
buf += 16;
len -= 16;
}
/*
* Fold 128-bits to 64-bits.
*/
x2 = _mm_clmulepi64_si128(x1, x0, 0x10);
x3 = _mm_setr_epi32(~0, 0, ~0, 0);
x1 = _mm_srli_si128(x1, 8);
x1 = _mm_xor_si128(x1, x2);
x0 = _mm_loadl_epi64((__m128i*)k5k0);
x2 = _mm_srli_si128(x1, 4);
x1 = _mm_and_si128(x1, x3);
x1 = _mm_clmulepi64_si128(x1, x0, 0x00);
x1 = _mm_xor_si128(x1, x2);
/*
* Barret reduce to 32-bits.
*/
x0 = _mm_load_si128((__m128i*)poly);
x2 = _mm_and_si128(x1, x3);
x2 = _mm_clmulepi64_si128(x2, x0, 0x10);
x2 = _mm_and_si128(x2, x3);
x2 = _mm_clmulepi64_si128(x2, x0, 0x00);
x1 = _mm_xor_si128(x1, x2);
/*
* Return the crc32.
*/
return _mm_extract_epi32(x1, 1);
}
#elif defined(CRC32_ARMV8_CRC32)
/* CRC32 checksums using ARMv8-a crypto instructions.
*
* TODO: implement a version using the PMULL instruction.
*/
#if defined(__clang__)
/* CRC32 intrinsics are #ifdef'ed out of arm_acle.h unless we build with an
* armv8 target, which is incompatible with ThinLTO optimizations on Android.
* (Namely, mixing and matching different module-level targets makes ThinLTO
* warn, and Android defaults to armv7-a. This restriction does not apply to
* function-level `target`s, however.)
*
* Since we only need four crc intrinsics, and since clang's implementation of
* those are just wrappers around compiler builtins, it's simplest to #define
* those builtins directly. If this #define list grows too much (or we depend on
* an intrinsic that isn't a trivial wrapper), we may have to find a better way
* to go about this.
*
* NOTE: clang currently complains that "'+soft-float-abi' is not a recognized
* feature for this target (ignoring feature)." This appears to be a harmless
* bug in clang.
*/
#define __crc32b __builtin_arm_crc32b
#define __crc32d __builtin_arm_crc32d
#define __crc32w __builtin_arm_crc32w
#define __crc32cw __builtin_arm_crc32cw
#if defined(__aarch64__)
#define TARGET_ARMV8_WITH_CRC __attribute__((target("crc")))
#else // !defined(__aarch64__)
#define TARGET_ARMV8_WITH_CRC __attribute__((target("armv8-a,crc")))
#endif // defined(__aarch64__)
#elif defined(__GNUC__)
/* For GCC, we are setting CRC extensions at module level, so ThinLTO is not
* allowed. We can just include arm_acle.h.
*/
#include <arm_acle.h>
#define TARGET_ARMV8_WITH_CRC
#else // !defined(__GNUC__) && !defined(_aarch64__)
#error ARM CRC32 SIMD extensions only supported for Clang and GCC
#endif
TARGET_ARMV8_WITH_CRC
uint32_t ZLIB_INTERNAL armv8_crc32_little(unsigned long crc,
const unsigned char *buf,
z_size_t len)
{
uint32_t c = (uint32_t) ~crc;
while (len && ((uintptr_t)buf & 7)) {
c = __crc32b(c, *buf++);
--len;
}
const uint64_t *buf8 = (const uint64_t *)buf;
while (len >= 64) {
c = __crc32d(c, *buf8++);
c = __crc32d(c, *buf8++);
c = __crc32d(c, *buf8++);
c = __crc32d(c, *buf8++);
c = __crc32d(c, *buf8++);
c = __crc32d(c, *buf8++);
c = __crc32d(c, *buf8++);
c = __crc32d(c, *buf8++);
len -= 64;
}
while (len >= 8) {
c = __crc32d(c, *buf8++);
len -= 8;
}
buf = (const unsigned char *)buf8;
while (len--) {
c = __crc32b(c, *buf++);
}
return ~c;
}
#endif

69
external/zlib/crc32_simd.h vendored Normal file
View File

@@ -0,0 +1,69 @@
//https://cs.chromium.org/chromium/src/third_party/zlib/crc32_simd.c
/* crc32_simd.h
*
* Copyright 2017 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the Chromium source repository LICENSE file.
*/
#ifndef CRC32_SIMD_H
#define CRC32_SIMD_H
#include <stdint.h>
//#include "zconf.h"
//#include "zutil.h"
#include "deflate.h"
//#ifndef local
// #define local static
//#endif
//#ifndef z_crc_t
// #ifdef Z_U4
// typedef Z_U4 z_crc_t;
// #else
// typedef unsigned long z_crc_t;
// #endif
//#endif
#ifdef HAS_PCLMUL
#define CRC32_SIMD_SSE42_PCLMUL
#endif
#ifndef z_size_t
#define z_size_t size_t
#endif
#ifndef zalign
#ifdef _MSC_VER
#define zalign(x) __declspec(align(x))
#else
#define zalign(x) __attribute__((aligned((x))))
#endif
#endif
/*
* crc32_sse42_simd_(): compute the crc32 of the buffer, where the buffer
* length must be at least 64, and a multiple of 16.
*/
uint32_t ZLIB_INTERNAL crc32_sse42_simd_(
const unsigned char *buf,
z_size_t len,
uint32_t crc);
/*
* crc32_sse42_simd_ buffer size constraints: see the use in zlib/crc32.c
* for computing the crc32 of an arbitrary length buffer.
*/
#define Z_CRC32_SSE42_MINIMUM_LENGTH 64
#define Z_CRC32_SSE42_CHUNKSIZE_MASK 15
/*
* CRC32 checksums using ARMv8-a crypto instructions.
*/
uint32_t ZLIB_INTERNAL armv8_crc32_little(unsigned long crc,
const unsigned char* buf,
z_size_t len);
#endif /* CRC32_SIMD_H */

209
external/zlib/doc/algorithm.txt vendored Normal file
View File

@@ -0,0 +1,209 @@
1. Compression algorithm (deflate)
The deflation algorithm used by gzip (also zip and zlib) is a variation of
LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in
the input data. The second occurrence of a string is replaced by a
pointer to the previous string, in the form of a pair (distance,
length). Distances are limited to 32K bytes, and lengths are limited
to 258 bytes. When a string does not occur anywhere in the previous
32K bytes, it is emitted as a sequence of literal bytes. (In this
description, `string' must be taken as an arbitrary sequence of bytes,
and is not restricted to printable characters.)
Literals or match lengths are compressed with one Huffman tree, and
match distances are compressed with another tree. The trees are stored
in a compact form at the start of each block. The blocks can have any
size (except that the compressed data for one block must fit in
available memory). A block is terminated when deflate() determines that
it would be useful to start another block with fresh trees. (This is
somewhat similar to the behavior of LZW-based _compress_.)
Duplicated strings are found using a hash table. All input strings of
length 3 are inserted in the hash table. A hash index is computed for
the next 3 bytes. If the hash chain for this index is not empty, all
strings in the chain are compared with the current input string, and
the longest match is selected.
The hash chains are searched starting with the most recent strings, to
favor small distances and thus take advantage of the Huffman encoding.
The hash chains are singly linked. There are no deletions from the
hash chains, the algorithm simply discards matches that are too old.
To avoid a worst-case situation, very long hash chains are arbitrarily
truncated at a certain length, determined by a runtime option (level
parameter of deflateInit). So deflate() does not always find the longest
possible match but generally finds a match which is long enough.
deflate() also defers the selection of matches with a lazy evaluation
mechanism. After a match of length N has been found, deflate() searches for
a longer match at the next input byte. If a longer match is found, the
previous match is truncated to a length of one (thus producing a single
literal byte) and the process of lazy evaluation begins again. Otherwise,
the original match is kept, and the next match search is attempted only N
steps later.
The lazy match evaluation is also subject to a runtime parameter. If
the current match is long enough, deflate() reduces the search for a longer
match, thus speeding up the whole process. If compression ratio is more
important than speed, deflate() attempts a complete second search even if
the first match is already long enough.
The lazy match evaluation is not performed for the fastest compression
modes (level parameter 1 to 3). For these fast modes, new strings
are inserted in the hash table only when no match was found, or
when the match is not too long. This degrades the compression ratio
but saves time since there are both fewer insertions and fewer searches.
2. Decompression algorithm (inflate)
2.1 Introduction
The key question is how to represent a Huffman code (or any prefix code) so
that you can decode fast. The most important characteristic is that shorter
codes are much more common than longer codes, so pay attention to decoding the
short codes fast, and let the long codes take longer to decode.
inflate() sets up a first level table that covers some number of bits of
input less than the length of longest code. It gets that many bits from the
stream, and looks it up in the table. The table will tell if the next
code is that many bits or less and how many, and if it is, it will tell
the value, else it will point to the next level table for which inflate()
grabs more bits and tries to decode a longer code.
How many bits to make the first lookup is a tradeoff between the time it
takes to decode and the time it takes to build the table. If building the
table took no time (and if you had infinite memory), then there would only
be a first level table to cover all the way to the longest code. However,
building the table ends up taking a lot longer for more bits since short
codes are replicated many times in such a table. What inflate() does is
simply to make the number of bits in the first table a variable, and then
to set that variable for the maximum speed.
For inflate, which has 286 possible codes for the literal/length tree, the size
of the first table is nine bits. Also the distance trees have 30 possible
values, and the size of the first table is six bits. Note that for each of
those cases, the table ended up one bit longer than the ``average'' code
length, i.e. the code length of an approximately flat code which would be a
little more than eight bits for 286 symbols and a little less than five bits
for 30 symbols.
2.2 More details on the inflate table lookup
Ok, you want to know what this cleverly obfuscated inflate tree actually
looks like. You are correct that it's not a Huffman tree. It is simply a
lookup table for the first, let's say, nine bits of a Huffman symbol. The
symbol could be as short as one bit or as long as 15 bits. If a particular
symbol is shorter than nine bits, then that symbol's translation is duplicated
in all those entries that start with that symbol's bits. For example, if the
symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a
symbol is nine bits long, it appears in the table once.
If the symbol is longer than nine bits, then that entry in the table points
to another similar table for the remaining bits. Again, there are duplicated
entries as needed. The idea is that most of the time the symbol will be short
and there will only be one table look up. (That's whole idea behind data
compression in the first place.) For the less frequent long symbols, there
will be two lookups. If you had a compression method with really long
symbols, you could have as many levels of lookups as is efficient. For
inflate, two is enough.
So a table entry either points to another table (in which case nine bits in
the above example are gobbled), or it contains the translation for the symbol
and the number of bits to gobble. Then you start again with the next
ungobbled bit.
You may wonder: why not just have one lookup table for how ever many bits the
longest symbol is? The reason is that if you do that, you end up spending
more time filling in duplicate symbol entries than you do actually decoding.
At least for deflate's output that generates new trees every several 10's of
kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code
would take too long if you're only decoding several thousand symbols. At the
other extreme, you could make a new table for every bit in the code. In fact,
that's essentially a Huffman tree. But then you spend too much time
traversing the tree while decoding, even for short symbols.
So the number of bits for the first lookup table is a trade of the time to
fill out the table vs. the time spent looking at the second level and above of
the table.
Here is an example, scaled down:
The code being decoded, with 10 symbols, from 1 to 6 bits long:
A: 0
B: 10
C: 1100
D: 11010
E: 11011
F: 11100
G: 11101
H: 11110
I: 111110
J: 111111
Let's make the first table three bits long (eight entries):
000: A,1
001: A,1
010: A,1
011: A,1
100: B,2
101: B,2
110: -> table X (gobble 3 bits)
111: -> table Y (gobble 3 bits)
Each entry is what the bits decode as and how many bits that is, i.e. how
many bits to gobble. Or the entry points to another table, with the number of
bits to gobble implicit in the size of the table.
Table X is two bits long since the longest code starting with 110 is five bits
long:
00: C,1
01: C,1
10: D,2
11: E,2
Table Y is three bits long since the longest code starting with 111 is six
bits long:
000: F,2
001: F,2
010: G,2
011: G,2
100: H,2
101: H,2
110: I,3
111: J,3
So what we have here are three tables with a total of 20 entries that had to
be constructed. That's compared to 64 entries for a single table. Or
compared to 16 entries for a Huffman tree (six two entry tables and one four
entry table). Assuming that the code ideally represents the probability of
the symbols, it takes on the average 1.25 lookups per symbol. That's compared
to one lookup for the single table, or 1.66 lookups per symbol for the
Huffman tree.
There, I think that gives you a picture of what's going on. For inflate, the
meaning of a particular symbol is often more than just a letter. It can be a
byte (a "literal"), or it can be either a length or a distance which
indicates a base value and a number of bits to fetch after the code that is
added to the base value. Or it might be the special end-of-block code. The
data structures created in inftrees.c try to encode all that information
compactly in the tables.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
References:
[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data
Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3,
pp. 337-343.
``DEFLATE Compressed Data Format Specification'' available in
http://tools.ietf.org/html/rfc1951

619
external/zlib/doc/rfc1950.txt vendored Normal file
View File

@@ -0,0 +1,619 @@
Network Working Group P. Deutsch
Request for Comments: 1950 Aladdin Enterprises
Category: Informational J-L. Gailly
Info-ZIP
May 1996
ZLIB Compressed Data Format Specification version 3.3
Status of This Memo
This memo provides information for the Internet community. This memo
does not specify an Internet standard of any kind. Distribution of
this memo is unlimited.
IESG Note:
The IESG takes no position on the validity of any Intellectual
Property Rights statements contained in this document.
Notices
Copyright (c) 1996 L. Peter Deutsch and Jean-Loup Gailly
Permission is granted to copy and distribute this document for any
purpose and without charge, including translations into other
languages and incorporation into compilations, provided that the
copyright notice and this notice are preserved, and that any
substantive changes or deletions from the original are clearly
marked.
A pointer to the latest version of this and related documentation in
HTML format can be found at the URL
<ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
Abstract
This specification defines a lossless compressed data format. The
data can be produced or consumed, even for an arbitrarily long
sequentially presented input data stream, using only an a priori
bounded amount of intermediate storage. The format presently uses
the DEFLATE compression method but can be easily extended to use
other compression methods. It can be implemented readily in a manner
not covered by patents. This specification also defines the ADLER-32
checksum (an extension and improvement of the Fletcher checksum),
used for detection of data corruption, and provides an algorithm for
computing it.
Deutsch & Gailly Informational [Page 1]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
Table of Contents
1. Introduction ................................................... 2
1.1. Purpose ................................................... 2
1.2. Intended audience ......................................... 3
1.3. Scope ..................................................... 3
1.4. Compliance ................................................ 3
1.5. Definitions of terms and conventions used ................ 3
1.6. Changes from previous versions ............................ 3
2. Detailed specification ......................................... 3
2.1. Overall conventions ....................................... 3
2.2. Data format ............................................... 4
2.3. Compliance ................................................ 7
3. References ..................................................... 7
4. Source code .................................................... 8
5. Security Considerations ........................................ 8
6. Acknowledgements ............................................... 8
7. Authors' Addresses ............................................. 8
8. Appendix: Rationale ............................................ 9
9. Appendix: Sample code ..........................................10
1. Introduction
1.1. Purpose
The purpose of this specification is to define a lossless
compressed data format that:
* Is independent of CPU type, operating system, file system,
and character set, and hence can be used for interchange;
* Can be produced or consumed, even for an arbitrarily long
sequentially presented input data stream, using only an a
priori bounded amount of intermediate storage, and hence can
be used in data communications or similar structures such as
Unix filters;
* Can use a number of different compression methods;
* Can be implemented readily in a manner not covered by
patents, and hence can be practiced freely.
The data format defined by this specification does not attempt to
allow random access to compressed data.
Deutsch & Gailly Informational [Page 2]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
1.2. Intended audience
This specification is intended for use by implementors of software
to compress data into zlib format and/or decompress data from zlib
format.
The text of the specification assumes a basic background in
programming at the level of bits and other primitive data
representations.
1.3. Scope
The specification specifies a compressed data format that can be
used for in-memory compression of a sequence of arbitrary bytes.
1.4. Compliance
Unless otherwise indicated below, a compliant decompressor must be
able to accept and decompress any data set that conforms to all
the specifications presented here; a compliant compressor must
produce data sets that conform to all the specifications presented
here.
1.5. Definitions of terms and conventions used
byte: 8 bits stored or transmitted as a unit (same as an octet).
(For this specification, a byte is exactly 8 bits, even on
machines which store a character on a number of bits different
from 8.) See below, for the numbering of bits within a byte.
1.6. Changes from previous versions
Version 3.1 was the first public release of this specification.
In version 3.2, some terminology was changed and the Adler-32
sample code was rewritten for clarity. In version 3.3, the
support for a preset dictionary was introduced, and the
specification was converted to RFC style.
2. Detailed specification
2.1. Overall conventions
In the diagrams below, a box like this:
+---+
| | <-- the vertical bars might be missing
+---+
Deutsch & Gailly Informational [Page 3]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
represents one byte; a box like this:
+==============+
| |
+==============+
represents a variable number of bytes.
Bytes stored within a computer do not have a "bit order", since
they are always treated as a unit. However, a byte considered as
an integer between 0 and 255 does have a most- and least-
significant bit, and since we write numbers with the most-
significant digit on the left, we also write bytes with the most-
significant bit on the left. In the diagrams below, we number the
bits of a byte so that bit 0 is the least-significant bit, i.e.,
the bits are numbered:
+--------+
|76543210|
+--------+
Within a computer, a number may occupy multiple bytes. All
multi-byte numbers in the format described here are stored with
the MOST-significant byte first (at the lower memory address).
For example, the decimal number 520 is stored as:
0 1
+--------+--------+
|00000010|00001000|
+--------+--------+
^ ^
| |
| + less significant byte = 8
+ more significant byte = 2 x 256
2.2. Data format
A zlib stream has the following structure:
0 1
+---+---+
|CMF|FLG| (more-->)
+---+---+
Deutsch & Gailly Informational [Page 4]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
(if FLG.FDICT set)
0 1 2 3
+---+---+---+---+
| DICTID | (more-->)
+---+---+---+---+
+=====================+---+---+---+---+
|...compressed data...| ADLER32 |
+=====================+---+---+---+---+
Any data which may appear after ADLER32 are not part of the zlib
stream.
CMF (Compression Method and flags)
This byte is divided into a 4-bit compression method and a 4-
bit information field depending on the compression method.
bits 0 to 3 CM Compression method
bits 4 to 7 CINFO Compression info
CM (Compression method)
This identifies the compression method used in the file. CM = 8
denotes the "deflate" compression method with a window size up
to 32K. This is the method used by gzip and PNG (see
references [1] and [2] in Chapter 3, below, for the reference
documents). CM = 15 is reserved. It might be used in a future
version of this specification to indicate the presence of an
extra field before the compressed data.
CINFO (Compression info)
For CM = 8, CINFO is the base-2 logarithm of the LZ77 window
size, minus eight (CINFO=7 indicates a 32K window size). Values
of CINFO above 7 are not allowed in this version of the
specification. CINFO is not defined in this specification for
CM not equal to 8.
FLG (FLaGs)
This flag byte is divided as follows:
bits 0 to 4 FCHECK (check bits for CMF and FLG)
bit 5 FDICT (preset dictionary)
bits 6 to 7 FLEVEL (compression level)
The FCHECK value must be such that CMF and FLG, when viewed as
a 16-bit unsigned integer stored in MSB order (CMF*256 + FLG),
is a multiple of 31.
Deutsch & Gailly Informational [Page 5]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
FDICT (Preset dictionary)
If FDICT is set, a DICT dictionary identifier is present
immediately after the FLG byte. The dictionary is a sequence of
bytes which are initially fed to the compressor without
producing any compressed output. DICT is the Adler-32 checksum
of this sequence of bytes (see the definition of ADLER32
below). The decompressor can use this identifier to determine
which dictionary has been used by the compressor.
FLEVEL (Compression level)
These flags are available for use by specific compression
methods. The "deflate" method (CM = 8) sets these flags as
follows:
0 - compressor used fastest algorithm
1 - compressor used fast algorithm
2 - compressor used default algorithm
3 - compressor used maximum compression, slowest algorithm
The information in FLEVEL is not needed for decompression; it
is there to indicate if recompression might be worthwhile.
compressed data
For compression method 8, the compressed data is stored in the
deflate compressed data format as described in the document
"DEFLATE Compressed Data Format Specification" by L. Peter
Deutsch. (See reference [3] in Chapter 3, below)
Other compressed data formats are not specified in this version
of the zlib specification.
ADLER32 (Adler-32 checksum)
This contains a checksum value of the uncompressed data
(excluding any dictionary data) computed according to Adler-32
algorithm. This algorithm is a 32-bit extension and improvement
of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073
standard. See references [4] and [5] in Chapter 3, below)
Adler-32 is composed of two sums accumulated per byte: s1 is
the sum of all bytes, s2 is the sum of all s1 values. Both sums
are done modulo 65521. s1 is initialized to 1, s2 to zero. The
Adler-32 checksum is stored as s2*65536 + s1 in most-
significant-byte first (network) order.
Deutsch & Gailly Informational [Page 6]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
2.3. Compliance
A compliant compressor must produce streams with correct CMF, FLG
and ADLER32, but need not support preset dictionaries. When the
zlib data format is used as part of another standard data format,
the compressor may use only preset dictionaries that are specified
by this other data format. If this other format does not use the
preset dictionary feature, the compressor must not set the FDICT
flag.
A compliant decompressor must check CMF, FLG, and ADLER32, and
provide an error indication if any of these have incorrect values.
A compliant decompressor must give an error indication if CM is
not one of the values defined in this specification (only the
value 8 is permitted in this version), since another value could
indicate the presence of new features that would cause subsequent
data to be interpreted incorrectly. A compliant decompressor must
give an error indication if FDICT is set and DICTID is not the
identifier of a known preset dictionary. A decompressor may
ignore FLEVEL and still be compliant. When the zlib data format
is being used as a part of another standard format, a compliant
decompressor must support all the preset dictionaries specified by
the other format. When the other format does not use the preset
dictionary feature, a compliant decompressor must reject any
stream in which the FDICT flag is set.
3. References
[1] Deutsch, L.P.,"GZIP Compressed Data Format Specification",
available in ftp://ftp.uu.net/pub/archiving/zip/doc/
[2] Thomas Boutell, "PNG (Portable Network Graphics) specification",
available in ftp://ftp.uu.net/graphics/png/documents/
[3] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification",
available in ftp://ftp.uu.net/pub/archiving/zip/doc/
[4] Fletcher, J. G., "An Arithmetic Checksum for Serial
Transmissions," IEEE Transactions on Communications, Vol. COM-30,
No. 1, January 1982, pp. 247-252.
[5] ITU-T Recommendation X.224, Annex D, "Checksum Algorithms,"
November, 1993, pp. 144, 145. (Available from
gopher://info.itu.ch). ITU-T X.244 is also the same as ISO 8073.
Deutsch & Gailly Informational [Page 7]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
4. Source code
Source code for a C language implementation of a "zlib" compliant
library is available at ftp://ftp.uu.net/pub/archiving/zip/zlib/.
5. Security Considerations
A decoder that fails to check the ADLER32 checksum value may be
subject to undetected data corruption.
6. Acknowledgements
Trademarks cited in this document are the property of their
respective owners.
Jean-Loup Gailly and Mark Adler designed the zlib format and wrote
the related software described in this specification. Glenn
Randers-Pehrson converted this document to RFC and HTML format.
7. Authors' Addresses
L. Peter Deutsch
Aladdin Enterprises
203 Santa Margarita Ave.
Menlo Park, CA 94025
Phone: (415) 322-0103 (AM only)
FAX: (415) 322-1734
EMail: <ghost@aladdin.com>
Jean-Loup Gailly
EMail: <gzip@prep.ai.mit.edu>
Questions about the technical content of this specification can be
sent by email to
Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
Mark Adler <madler@alumni.caltech.edu>
Editorial comments on this specification can be sent by email to
L. Peter Deutsch <ghost@aladdin.com> and
Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
Deutsch & Gailly Informational [Page 8]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
8. Appendix: Rationale
8.1. Preset dictionaries
A preset dictionary is specially useful to compress short input
sequences. The compressor can take advantage of the dictionary
context to encode the input in a more compact manner. The
decompressor can be initialized with the appropriate context by
virtually decompressing a compressed version of the dictionary
without producing any output. However for certain compression
algorithms such as the deflate algorithm this operation can be
achieved without actually performing any decompression.
The compressor and the decompressor must use exactly the same
dictionary. The dictionary may be fixed or may be chosen among a
certain number of predefined dictionaries, according to the kind
of input data. The decompressor can determine which dictionary has
been chosen by the compressor by checking the dictionary
identifier. This document does not specify the contents of
predefined dictionaries, since the optimal dictionaries are
application specific. Standard data formats using this feature of
the zlib specification must precisely define the allowed
dictionaries.
8.2. The Adler-32 algorithm
The Adler-32 algorithm is much faster than the CRC32 algorithm yet
still provides an extremely low probability of undetected errors.
The modulo on unsigned long accumulators can be delayed for 5552
bytes, so the modulo operation time is negligible. If the bytes
are a, b, c, the second sum is 3a + 2b + c + 3, and so is position
and order sensitive, unlike the first sum, which is just a
checksum. That 65521 is prime is important to avoid a possible
large class of two-byte errors that leave the check unchanged.
(The Fletcher checksum uses 255, which is not prime and which also
makes the Fletcher check insensitive to single byte changes 0 <->
255.)
The sum s1 is initialized to 1 instead of zero to make the length
of the sequence part of s2, so that the length does not have to be
checked separately. (Any sequence of zeroes has a Fletcher
checksum of zero.)
Deutsch & Gailly Informational [Page 9]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
9. Appendix: Sample code
The following C code computes the Adler-32 checksum of a data buffer.
It is written for clarity, not for speed. The sample code is in the
ANSI C programming language. Non C users may find it easier to read
with these hints:
& Bitwise AND operator.
>> Bitwise right shift operator. When applied to an
unsigned quantity, as here, right shift inserts zero bit(s)
at the left.
<< Bitwise left shift operator. Left shift inserts zero
bit(s) at the right.
++ "n++" increments the variable n.
% modulo operator: a % b is the remainder of a divided by b.
#define BASE 65521 /* largest prime smaller than 65536 */
/*
Update a running Adler-32 checksum with the bytes buf[0..len-1]
and return the updated checksum. The Adler-32 checksum should be
initialized to 1.
Usage example:
unsigned long adler = 1L;
while (read_buffer(buffer, length) != EOF) {
adler = update_adler32(adler, buffer, length);
}
if (adler != original_adler) error();
*/
unsigned long update_adler32(unsigned long adler,
unsigned char *buf, int len)
{
unsigned long s1 = adler & 0xffff;
unsigned long s2 = (adler >> 16) & 0xffff;
int n;
for (n = 0; n < len; n++) {
s1 = (s1 + buf[n]) % BASE;
s2 = (s2 + s1) % BASE;
}
return (s2 << 16) + s1;
}
/* Return the adler32 of the bytes buf[0..len-1] */
Deutsch & Gailly Informational [Page 10]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
unsigned long adler32(unsigned char *buf, int len)
{
return update_adler32(1L, buf, len);
}
Deutsch & Gailly Informational [Page 11]

955
external/zlib/doc/rfc1951.txt vendored Normal file
View File

@@ -0,0 +1,955 @@
Network Working Group P. Deutsch
Request for Comments: 1951 Aladdin Enterprises
Category: Informational May 1996
DEFLATE Compressed Data Format Specification version 1.3
Status of This Memo
This memo provides information for the Internet community. This memo
does not specify an Internet standard of any kind. Distribution of
this memo is unlimited.
IESG Note:
The IESG takes no position on the validity of any Intellectual
Property Rights statements contained in this document.
Notices
Copyright (c) 1996 L. Peter Deutsch
Permission is granted to copy and distribute this document for any
purpose and without charge, including translations into other
languages and incorporation into compilations, provided that the
copyright notice and this notice are preserved, and that any
substantive changes or deletions from the original are clearly
marked.
A pointer to the latest version of this and related documentation in
HTML format can be found at the URL
<ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
Abstract
This specification defines a lossless compressed data format that
compresses data using a combination of the LZ77 algorithm and Huffman
coding, with efficiency comparable to the best currently available
general-purpose compression methods. The data can be produced or
consumed, even for an arbitrarily long sequentially presented input
data stream, using only an a priori bounded amount of intermediate
storage. The format can be implemented readily in a manner not
covered by patents.
Deutsch Informational [Page 1]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
Table of Contents
1. Introduction ................................................... 2
1.1. Purpose ................................................... 2
1.2. Intended audience ......................................... 3
1.3. Scope ..................................................... 3
1.4. Compliance ................................................ 3
1.5. Definitions of terms and conventions used ................ 3
1.6. Changes from previous versions ............................ 4
2. Compressed representation overview ............................. 4
3. Detailed specification ......................................... 5
3.1. Overall conventions ....................................... 5
3.1.1. Packing into bytes .................................. 5
3.2. Compressed block format ................................... 6
3.2.1. Synopsis of prefix and Huffman coding ............... 6
3.2.2. Use of Huffman coding in the "deflate" format ....... 7
3.2.3. Details of block format ............................. 9
3.2.4. Non-compressed blocks (BTYPE=00) ................... 11
3.2.5. Compressed blocks (length and distance codes) ...... 11
3.2.6. Compression with fixed Huffman codes (BTYPE=01) .... 12
3.2.7. Compression with dynamic Huffman codes (BTYPE=10) .. 13
3.3. Compliance ............................................... 14
4. Compression algorithm details ................................. 14
5. References .................................................... 16
6. Security Considerations ....................................... 16
7. Source code ................................................... 16
8. Acknowledgements .............................................. 16
9. Author's Address .............................................. 17
1. Introduction
1.1. Purpose
The purpose of this specification is to define a lossless
compressed data format that:
* Is independent of CPU type, operating system, file system,
and character set, and hence can be used for interchange;
* Can be produced or consumed, even for an arbitrarily long
sequentially presented input data stream, using only an a
priori bounded amount of intermediate storage, and hence
can be used in data communications or similar structures
such as Unix filters;
* Compresses data with efficiency comparable to the best
currently available general-purpose compression methods,
and in particular considerably better than the "compress"
program;
* Can be implemented readily in a manner not covered by
patents, and hence can be practiced freely;
Deutsch Informational [Page 2]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
* Is compatible with the file format produced by the current
widely used gzip utility, in that conforming decompressors
will be able to read data produced by the existing gzip
compressor.
The data format defined by this specification does not attempt to:
* Allow random access to compressed data;
* Compress specialized data (e.g., raster graphics) as well
as the best currently available specialized algorithms.
A simple counting argument shows that no lossless compression
algorithm can compress every possible input data set. For the
format defined here, the worst case expansion is 5 bytes per 32K-
byte block, i.e., a size increase of 0.015% for large data sets.
English text usually compresses by a factor of 2.5 to 3;
executable files usually compress somewhat less; graphical data
such as raster images may compress much more.
1.2. Intended audience
This specification is intended for use by implementors of software
to compress data into "deflate" format and/or decompress data from
"deflate" format.
The text of the specification assumes a basic background in
programming at the level of bits and other primitive data
representations. Familiarity with the technique of Huffman coding
is helpful but not required.
1.3. Scope
The specification specifies a method for representing a sequence
of bytes as a (usually shorter) sequence of bits, and a method for
packing the latter bit sequence into bytes.
1.4. Compliance
Unless otherwise indicated below, a compliant decompressor must be
able to accept and decompress any data set that conforms to all
the specifications presented here; a compliant compressor must
produce data sets that conform to all the specifications presented
here.
1.5. Definitions of terms and conventions used
Byte: 8 bits stored or transmitted as a unit (same as an octet).
For this specification, a byte is exactly 8 bits, even on machines
Deutsch Informational [Page 3]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
which store a character on a number of bits different from eight.
See below, for the numbering of bits within a byte.
String: a sequence of arbitrary bytes.
1.6. Changes from previous versions
There have been no technical changes to the deflate format since
version 1.1 of this specification. In version 1.2, some
terminology was changed. Version 1.3 is a conversion of the
specification to RFC style.
2. Compressed representation overview
A compressed data set consists of a series of blocks, corresponding
to successive blocks of input data. The block sizes are arbitrary,
except that non-compressible blocks are limited to 65,535 bytes.
Each block is compressed using a combination of the LZ77 algorithm
and Huffman coding. The Huffman trees for each block are independent
of those for previous or subsequent blocks; the LZ77 algorithm may
use a reference to a duplicated string occurring in a previous block,
up to 32K input bytes before.
Each block consists of two parts: a pair of Huffman code trees that
describe the representation of the compressed data part, and a
compressed data part. (The Huffman trees themselves are compressed
using Huffman encoding.) The compressed data consists of a series of
elements of two types: literal bytes (of strings that have not been
detected as duplicated within the previous 32K input bytes), and
pointers to duplicated strings, where a pointer is represented as a
pair <length, backward distance>. The representation used in the
"deflate" format limits distances to 32K bytes and lengths to 258
bytes, but does not limit the size of a block, except for
uncompressible blocks, which are limited as noted above.
Each type of value (literals, distances, and lengths) in the
compressed data is represented using a Huffman code, using one code
tree for literals and lengths and a separate code tree for distances.
The code trees for each block appear in a compact form just before
the compressed data for that block.
Deutsch Informational [Page 4]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
3. Detailed specification
3.1. Overall conventions In the diagrams below, a box like this:
+---+
| | <-- the vertical bars might be missing
+---+
represents one byte; a box like this:
+==============+
| |
+==============+
represents a variable number of bytes.
Bytes stored within a computer do not have a "bit order", since
they are always treated as a unit. However, a byte considered as
an integer between 0 and 255 does have a most- and least-
significant bit, and since we write numbers with the most-
significant digit on the left, we also write bytes with the most-
significant bit on the left. In the diagrams below, we number the
bits of a byte so that bit 0 is the least-significant bit, i.e.,
the bits are numbered:
+--------+
|76543210|
+--------+
Within a computer, a number may occupy multiple bytes. All
multi-byte numbers in the format described here are stored with
the least-significant byte first (at the lower memory address).
For example, the decimal number 520 is stored as:
0 1
+--------+--------+
|00001000|00000010|
+--------+--------+
^ ^
| |
| + more significant byte = 2 x 256
+ less significant byte = 8
3.1.1. Packing into bytes
This document does not address the issue of the order in which
bits of a byte are transmitted on a bit-sequential medium,
since the final data format described here is byte- rather than
Deutsch Informational [Page 5]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
bit-oriented. However, we describe the compressed block format
in below, as a sequence of data elements of various bit
lengths, not a sequence of bytes. We must therefore specify
how to pack these data elements into bytes to form the final
compressed byte sequence:
* Data elements are packed into bytes in order of
increasing bit number within the byte, i.e., starting
with the least-significant bit of the byte.
* Data elements other than Huffman codes are packed
starting with the least-significant bit of the data
element.
* Huffman codes are packed starting with the most-
significant bit of the code.
In other words, if one were to print out the compressed data as
a sequence of bytes, starting with the first byte at the
*right* margin and proceeding to the *left*, with the most-
significant bit of each byte on the left as usual, one would be
able to parse the result from right to left, with fixed-width
elements in the correct MSB-to-LSB order and Huffman codes in
bit-reversed order (i.e., with the first bit of the code in the
relative LSB position).
3.2. Compressed block format
3.2.1. Synopsis of prefix and Huffman coding
Prefix coding represents symbols from an a priori known
alphabet by bit sequences (codes), one code for each symbol, in
a manner such that different symbols may be represented by bit
sequences of different lengths, but a parser can always parse
an encoded string unambiguously symbol-by-symbol.
We define a prefix code in terms of a binary tree in which the
two edges descending from each non-leaf node are labeled 0 and
1 and in which the leaf nodes correspond one-for-one with (are
labeled with) the symbols of the alphabet; then the code for a
symbol is the sequence of 0's and 1's on the edges leading from
the root to the leaf labeled with that symbol. For example:
Deutsch Informational [Page 6]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
/\ Symbol Code
0 1 ------ ----
/ \ A 00
/\ B B 1
0 1 C 011
/ \ D 010
A /\
0 1
/ \
D C
A parser can decode the next symbol from an encoded input
stream by walking down the tree from the root, at each step
choosing the edge corresponding to the next input bit.
Given an alphabet with known symbol frequencies, the Huffman
algorithm allows the construction of an optimal prefix code
(one which represents strings with those symbol frequencies
using the fewest bits of any possible prefix codes for that
alphabet). Such a code is called a Huffman code. (See
reference [1] in Chapter 5, references for additional
information on Huffman codes.)
Note that in the "deflate" format, the Huffman codes for the
various alphabets must not exceed certain maximum code lengths.
This constraint complicates the algorithm for computing code
lengths from symbol frequencies. Again, see Chapter 5,
references for details.
3.2.2. Use of Huffman coding in the "deflate" format
The Huffman codes used for each alphabet in the "deflate"
format have two additional rules:
* All codes of a given bit length have lexicographically
consecutive values, in the same order as the symbols
they represent;
* Shorter codes lexicographically precede longer codes.
Deutsch Informational [Page 7]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
We could recode the example above to follow this rule as
follows, assuming that the order of the alphabet is ABCD:
Symbol Code
------ ----
A 10
B 0
C 110
D 111
I.e., 0 precedes 10 which precedes 11x, and 110 and 111 are
lexicographically consecutive.
Given this rule, we can define the Huffman code for an alphabet
just by giving the bit lengths of the codes for each symbol of
the alphabet in order; this is sufficient to determine the
actual codes. In our example, the code is completely defined
by the sequence of bit lengths (2, 1, 3, 3). The following
algorithm generates the codes as integers, intended to be read
from most- to least-significant bit. The code lengths are
initially in tree[I].Len; the codes are produced in
tree[I].Code.
1) Count the number of codes for each code length. Let
bl_count[N] be the number of codes of length N, N >= 1.
2) Find the numerical value of the smallest code for each
code length:
code = 0;
bl_count[0] = 0;
for (bits = 1; bits <= MAX_BITS; bits++) {
code = (code + bl_count[bits-1]) << 1;
next_code[bits] = code;
}
3) Assign numerical values to all codes, using consecutive
values for all codes of the same length with the base
values determined at step 2. Codes that are never used
(which have a bit length of zero) must not be assigned a
value.
for (n = 0; n <= max_code; n++) {
len = tree[n].Len;
if (len != 0) {
tree[n].Code = next_code[len];
next_code[len]++;
}
Deutsch Informational [Page 8]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
}
Example:
Consider the alphabet ABCDEFGH, with bit lengths (3, 3, 3, 3,
3, 2, 4, 4). After step 1, we have:
N bl_count[N]
- -----------
2 1
3 5
4 2
Step 2 computes the following next_code values:
N next_code[N]
- ------------
1 0
2 0
3 2
4 14
Step 3 produces the following code values:
Symbol Length Code
------ ------ ----
A 3 010
B 3 011
C 3 100
D 3 101
E 3 110
F 2 00
G 4 1110
H 4 1111
3.2.3. Details of block format
Each block of compressed data begins with 3 header bits
containing the following data:
first bit BFINAL
next 2 bits BTYPE
Note that the header bits do not necessarily begin on a byte
boundary, since a block does not necessarily occupy an integral
number of bytes.
Deutsch Informational [Page 9]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
BFINAL is set if and only if this is the last block of the data
set.
BTYPE specifies how the data are compressed, as follows:
00 - no compression
01 - compressed with fixed Huffman codes
10 - compressed with dynamic Huffman codes
11 - reserved (error)
The only difference between the two compressed cases is how the
Huffman codes for the literal/length and distance alphabets are
defined.
In all cases, the decoding algorithm for the actual data is as
follows:
do
read block header from input stream.
if stored with no compression
skip any remaining bits in current partially
processed byte
read LEN and NLEN (see next section)
copy LEN bytes of data to output
otherwise
if compressed with dynamic Huffman codes
read representation of code trees (see
subsection below)
loop (until end of block code recognized)
decode literal/length value from input stream
if value < 256
copy value (literal byte) to output stream
otherwise
if value = end of block (256)
break from loop
otherwise (value = 257..285)
decode distance from input stream
move backwards distance bytes in the output
stream, and copy length bytes from this
position to the output stream.
end loop
while not last block
Note that a duplicated string reference may refer to a string
in a previous block; i.e., the backward distance may cross one
or more block boundaries. However a distance cannot refer past
the beginning of the output stream. (An application using a
Deutsch Informational [Page 10]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
preset dictionary might discard part of the output stream; a
distance can refer to that part of the output stream anyway)
Note also that the referenced string may overlap the current
position; for example, if the last 2 bytes decoded have values
X and Y, a string reference with <length = 5, distance = 2>
adds X,Y,X,Y,X to the output stream.
We now specify each compression method in turn.
3.2.4. Non-compressed blocks (BTYPE=00)
Any bits of input up to the next byte boundary are ignored.
The rest of the block consists of the following information:
0 1 2 3 4...
+---+---+---+---+================================+
| LEN | NLEN |... LEN bytes of literal data...|
+---+---+---+---+================================+
LEN is the number of data bytes in the block. NLEN is the
one's complement of LEN.
3.2.5. Compressed blocks (length and distance codes)
As noted above, encoded data blocks in the "deflate" format
consist of sequences of symbols drawn from three conceptually
distinct alphabets: either literal bytes, from the alphabet of
byte values (0..255), or <length, backward distance> pairs,
where the length is drawn from (3..258) and the distance is
drawn from (1..32,768). In fact, the literal and length
alphabets are merged into a single alphabet (0..285), where
values 0..255 represent literal bytes, the value 256 indicates
end-of-block, and values 257..285 represent length codes
(possibly in conjunction with extra bits following the symbol
code) as follows:
Deutsch Informational [Page 11]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
Extra Extra Extra
Code Bits Length(s) Code Bits Lengths Code Bits Length(s)
---- ---- ------ ---- ---- ------- ---- ---- -------
257 0 3 267 1 15,16 277 4 67-82
258 0 4 268 1 17,18 278 4 83-98
259 0 5 269 2 19-22 279 4 99-114
260 0 6 270 2 23-26 280 4 115-130
261 0 7 271 2 27-30 281 5 131-162
262 0 8 272 2 31-34 282 5 163-194
263 0 9 273 3 35-42 283 5 195-226
264 0 10 274 3 43-50 284 5 227-257
265 1 11,12 275 3 51-58 285 0 258
266 1 13,14 276 3 59-66
The extra bits should be interpreted as a machine integer
stored with the most-significant bit first, e.g., bits 1110
represent the value 14.
Extra Extra Extra
Code Bits Dist Code Bits Dist Code Bits Distance
---- ---- ---- ---- ---- ------ ---- ---- --------
0 0 1 10 4 33-48 20 9 1025-1536
1 0 2 11 4 49-64 21 9 1537-2048
2 0 3 12 5 65-96 22 10 2049-3072
3 0 4 13 5 97-128 23 10 3073-4096
4 1 5,6 14 6 129-192 24 11 4097-6144
5 1 7,8 15 6 193-256 25 11 6145-8192
6 2 9-12 16 7 257-384 26 12 8193-12288
7 2 13-16 17 7 385-512 27 12 12289-16384
8 3 17-24 18 8 513-768 28 13 16385-24576
9 3 25-32 19 8 769-1024 29 13 24577-32768
3.2.6. Compression with fixed Huffman codes (BTYPE=01)
The Huffman codes for the two alphabets are fixed, and are not
represented explicitly in the data. The Huffman code lengths
for the literal/length alphabet are:
Lit Value Bits Codes
--------- ---- -----
0 - 143 8 00110000 through
10111111
144 - 255 9 110010000 through
111111111
256 - 279 7 0000000 through
0010111
280 - 287 8 11000000 through
11000111
Deutsch Informational [Page 12]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
The code lengths are sufficient to generate the actual codes,
as described above; we show the codes in the table for added
clarity. Literal/length values 286-287 will never actually
occur in the compressed data, but participate in the code
construction.
Distance codes 0-31 are represented by (fixed-length) 5-bit
codes, with possible additional bits as shown in the table
shown in Paragraph 3.2.5, above. Note that distance codes 30-
31 will never actually occur in the compressed data.
3.2.7. Compression with dynamic Huffman codes (BTYPE=10)
The Huffman codes for the two alphabets appear in the block
immediately after the header bits and before the actual
compressed data, first the literal/length code and then the
distance code. Each code is defined by a sequence of code
lengths, as discussed in Paragraph 3.2.2, above. For even
greater compactness, the code length sequences themselves are
compressed using a Huffman code. The alphabet for code lengths
is as follows:
0 - 15: Represent code lengths of 0 - 15
16: Copy the previous code length 3 - 6 times.
The next 2 bits indicate repeat length
(0 = 3, ... , 3 = 6)
Example: Codes 8, 16 (+2 bits 11),
16 (+2 bits 10) will expand to
12 code lengths of 8 (1 + 6 + 5)
17: Repeat a code length of 0 for 3 - 10 times.
(3 bits of length)
18: Repeat a code length of 0 for 11 - 138 times
(7 bits of length)
A code length of 0 indicates that the corresponding symbol in
the literal/length or distance alphabet will not occur in the
block, and should not participate in the Huffman code
construction algorithm given earlier. If only one distance
code is used, it is encoded using one bit, not zero bits; in
this case there is a single code length of one, with one unused
code. One distance code of zero bits means that there are no
distance codes used at all (the data is all literals).
We can now define the format of the block:
5 Bits: HLIT, # of Literal/Length codes - 257 (257 - 286)
5 Bits: HDIST, # of Distance codes - 1 (1 - 32)
4 Bits: HCLEN, # of Code Length codes - 4 (4 - 19)
Deutsch Informational [Page 13]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
(HCLEN + 4) x 3 bits: code lengths for the code length
alphabet given just above, in the order: 16, 17, 18,
0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
These code lengths are interpreted as 3-bit integers
(0-7); as above, a code length of 0 means the
corresponding symbol (literal/length or distance code
length) is not used.
HLIT + 257 code lengths for the literal/length alphabet,
encoded using the code length Huffman code
HDIST + 1 code lengths for the distance alphabet,
encoded using the code length Huffman code
The actual compressed data of the block,
encoded using the literal/length and distance Huffman
codes
The literal/length symbol 256 (end of data),
encoded using the literal/length Huffman code
The code length repeat codes can cross from HLIT + 257 to the
HDIST + 1 code lengths. In other words, all code lengths form
a single sequence of HLIT + HDIST + 258 values.
3.3. Compliance
A compressor may limit further the ranges of values specified in
the previous section and still be compliant; for example, it may
limit the range of backward pointers to some value smaller than
32K. Similarly, a compressor may limit the size of blocks so that
a compressible block fits in memory.
A compliant decompressor must accept the full range of possible
values defined in the previous section, and must accept blocks of
arbitrary size.
4. Compression algorithm details
While it is the intent of this document to define the "deflate"
compressed data format without reference to any particular
compression algorithm, the format is related to the compressed
formats produced by LZ77 (Lempel-Ziv 1977, see reference [2] below);
since many variations of LZ77 are patented, it is strongly
recommended that the implementor of a compressor follow the general
algorithm presented here, which is known not to be patented per se.
The material in this section is not part of the definition of the
Deutsch Informational [Page 14]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
specification per se, and a compressor need not follow it in order to
be compliant.
The compressor terminates a block when it determines that starting a
new block with fresh trees would be useful, or when the block size
fills up the compressor's block buffer.
The compressor uses a chained hash table to find duplicated strings,
using a hash function that operates on 3-byte sequences. At any
given point during compression, let XYZ be the next 3 input bytes to
be examined (not necessarily all different, of course). First, the
compressor examines the hash chain for XYZ. If the chain is empty,
the compressor simply writes out X as a literal byte and advances one
byte in the input. If the hash chain is not empty, indicating that
the sequence XYZ (or, if we are unlucky, some other 3 bytes with the
same hash function value) has occurred recently, the compressor
compares all strings on the XYZ hash chain with the actual input data
sequence starting at the current point, and selects the longest
match.
The compressor searches the hash chains starting with the most recent
strings, to favor small distances and thus take advantage of the
Huffman encoding. The hash chains are singly linked. There are no
deletions from the hash chains; the algorithm simply discards matches
that are too old. To avoid a worst-case situation, very long hash
chains are arbitrarily truncated at a certain length, determined by a
run-time parameter.
To improve overall compression, the compressor optionally defers the
selection of matches ("lazy matching"): after a match of length N has
been found, the compressor searches for a longer match starting at
the next input byte. If it finds a longer match, it truncates the
previous match to a length of one (thus producing a single literal
byte) and then emits the longer match. Otherwise, it emits the
original match, and, as described above, advances N bytes before
continuing.
Run-time parameters also control this "lazy match" procedure. If
compression ratio is most important, the compressor attempts a
complete second search regardless of the length of the first match.
In the normal case, if the current match is "long enough", the
compressor reduces the search for a longer match, thus speeding up
the process. If speed is most important, the compressor inserts new
strings in the hash table only when no match was found, or when the
match is not "too long". This degrades the compression ratio but
saves time since there are both fewer insertions and fewer searches.
Deutsch Informational [Page 15]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
5. References
[1] Huffman, D. A., "A Method for the Construction of Minimum
Redundancy Codes", Proceedings of the Institute of Radio
Engineers, September 1952, Volume 40, Number 9, pp. 1098-1101.
[2] Ziv J., Lempel A., "A Universal Algorithm for Sequential Data
Compression", IEEE Transactions on Information Theory, Vol. 23,
No. 3, pp. 337-343.
[3] Gailly, J.-L., and Adler, M., ZLIB documentation and sources,
available in ftp://ftp.uu.net/pub/archiving/zip/doc/
[4] Gailly, J.-L., and Adler, M., GZIP documentation and sources,
available as gzip-*.tar in ftp://prep.ai.mit.edu/pub/gnu/
[5] Schwartz, E. S., and Kallick, B. "Generating a canonical prefix
encoding." Comm. ACM, 7,3 (Mar. 1964), pp. 166-169.
[6] Hirschberg and Lelewer, "Efficient decoding of prefix codes,"
Comm. ACM, 33,4, April 1990, pp. 449-459.
6. Security Considerations
Any data compression method involves the reduction of redundancy in
the data. Consequently, any corruption of the data is likely to have
severe effects and be difficult to correct. Uncompressed text, on
the other hand, will probably still be readable despite the presence
of some corrupted bytes.
It is recommended that systems using this data format provide some
means of validating the integrity of the compressed data. See
reference [3], for example.
7. Source code
Source code for a C language implementation of a "deflate" compliant
compressor and decompressor is available within the zlib package at
ftp://ftp.uu.net/pub/archiving/zip/zlib/.
8. Acknowledgements
Trademarks cited in this document are the property of their
respective owners.
Phil Katz designed the deflate format. Jean-Loup Gailly and Mark
Adler wrote the related software described in this specification.
Glenn Randers-Pehrson converted this document to RFC and HTML format.
Deutsch Informational [Page 16]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
9. Author's Address
L. Peter Deutsch
Aladdin Enterprises
203 Santa Margarita Ave.
Menlo Park, CA 94025
Phone: (415) 322-0103 (AM only)
FAX: (415) 322-1734
EMail: <ghost@aladdin.com>
Questions about the technical content of this specification can be
sent by email to:
Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
Mark Adler <madler@alumni.caltech.edu>
Editorial comments on this specification can be sent by email to:
L. Peter Deutsch <ghost@aladdin.com> and
Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
Deutsch Informational [Page 17]

675
external/zlib/doc/rfc1952.txt vendored Normal file
View File

@@ -0,0 +1,675 @@
Network Working Group P. Deutsch
Request for Comments: 1952 Aladdin Enterprises
Category: Informational May 1996
GZIP file format specification version 4.3
Status of This Memo
This memo provides information for the Internet community. This memo
does not specify an Internet standard of any kind. Distribution of
this memo is unlimited.
IESG Note:
The IESG takes no position on the validity of any Intellectual
Property Rights statements contained in this document.
Notices
Copyright (c) 1996 L. Peter Deutsch
Permission is granted to copy and distribute this document for any
purpose and without charge, including translations into other
languages and incorporation into compilations, provided that the
copyright notice and this notice are preserved, and that any
substantive changes or deletions from the original are clearly
marked.
A pointer to the latest version of this and related documentation in
HTML format can be found at the URL
<ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
Abstract
This specification defines a lossless compressed data format that is
compatible with the widely used GZIP utility. The format includes a
cyclic redundancy check value for detecting data corruption. The
format presently uses the DEFLATE method of compression but can be
easily extended to use other compression methods. The format can be
implemented readily in a manner not covered by patents.
Deutsch Informational [Page 1]
RFC 1952 GZIP File Format Specification May 1996
Table of Contents
1. Introduction ................................................... 2
1.1. Purpose ................................................... 2
1.2. Intended audience ......................................... 3
1.3. Scope ..................................................... 3
1.4. Compliance ................................................ 3
1.5. Definitions of terms and conventions used ................. 3
1.6. Changes from previous versions ............................ 3
2. Detailed specification ......................................... 4
2.1. Overall conventions ....................................... 4
2.2. File format ............................................... 5
2.3. Member format ............................................. 5
2.3.1. Member header and trailer ........................... 6
2.3.1.1. Extra field ................................... 8
2.3.1.2. Compliance .................................... 9
3. References .................................................. 9
4. Security Considerations .................................... 10
5. Acknowledgements ........................................... 10
6. Author's Address ........................................... 10
7. Appendix: Jean-Loup Gailly's gzip utility .................. 11
8. Appendix: Sample CRC Code .................................. 11
1. Introduction
1.1. Purpose
The purpose of this specification is to define a lossless
compressed data format that:
* Is independent of CPU type, operating system, file system,
and character set, and hence can be used for interchange;
* Can compress or decompress a data stream (as opposed to a
randomly accessible file) to produce another data stream,
using only an a priori bounded amount of intermediate
storage, and hence can be used in data communications or
similar structures such as Unix filters;
* Compresses data with efficiency comparable to the best
currently available general-purpose compression methods,
and in particular considerably better than the "compress"
program;
* Can be implemented readily in a manner not covered by
patents, and hence can be practiced freely;
* Is compatible with the file format produced by the current
widely used gzip utility, in that conforming decompressors
will be able to read data produced by the existing gzip
compressor.
Deutsch Informational [Page 2]
RFC 1952 GZIP File Format Specification May 1996
The data format defined by this specification does not attempt to:
* Provide random access to compressed data;
* Compress specialized data (e.g., raster graphics) as well as
the best currently available specialized algorithms.
1.2. Intended audience
This specification is intended for use by implementors of software
to compress data into gzip format and/or decompress data from gzip
format.
The text of the specification assumes a basic background in
programming at the level of bits and other primitive data
representations.
1.3. Scope
The specification specifies a compression method and a file format
(the latter assuming only that a file can store a sequence of
arbitrary bytes). It does not specify any particular interface to
a file system or anything about character sets or encodings
(except for file names and comments, which are optional).
1.4. Compliance
Unless otherwise indicated below, a compliant decompressor must be
able to accept and decompress any file that conforms to all the
specifications presented here; a compliant compressor must produce
files that conform to all the specifications presented here. The
material in the appendices is not part of the specification per se
and is not relevant to compliance.
1.5. Definitions of terms and conventions used
byte: 8 bits stored or transmitted as a unit (same as an octet).
(For this specification, a byte is exactly 8 bits, even on
machines which store a character on a number of bits different
from 8.) See below for the numbering of bits within a byte.
1.6. Changes from previous versions
There have been no technical changes to the gzip format since
version 4.1 of this specification. In version 4.2, some
terminology was changed, and the sample CRC code was rewritten for
clarity and to eliminate the requirement for the caller to do pre-
and post-conditioning. Version 4.3 is a conversion of the
specification to RFC style.
Deutsch Informational [Page 3]
RFC 1952 GZIP File Format Specification May 1996
2. Detailed specification
2.1. Overall conventions
In the diagrams below, a box like this:
+---+
| | <-- the vertical bars might be missing
+---+
represents one byte; a box like this:
+==============+
| |
+==============+
represents a variable number of bytes.
Bytes stored within a computer do not have a "bit order", since
they are always treated as a unit. However, a byte considered as
an integer between 0 and 255 does have a most- and least-
significant bit, and since we write numbers with the most-
significant digit on the left, we also write bytes with the most-
significant bit on the left. In the diagrams below, we number the
bits of a byte so that bit 0 is the least-significant bit, i.e.,
the bits are numbered:
+--------+
|76543210|
+--------+
This document does not address the issue of the order in which
bits of a byte are transmitted on a bit-sequential medium, since
the data format described here is byte- rather than bit-oriented.
Within a computer, a number may occupy multiple bytes. All
multi-byte numbers in the format described here are stored with
the least-significant byte first (at the lower memory address).
For example, the decimal number 520 is stored as:
0 1
+--------+--------+
|00001000|00000010|
+--------+--------+
^ ^
| |
| + more significant byte = 2 x 256
+ less significant byte = 8
Deutsch Informational [Page 4]
RFC 1952 GZIP File Format Specification May 1996
2.2. File format
A gzip file consists of a series of "members" (compressed data
sets). The format of each member is specified in the following
section. The members simply appear one after another in the file,
with no additional information before, between, or after them.
2.3. Member format
Each member has the following structure:
+---+---+---+---+---+---+---+---+---+---+
|ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->)
+---+---+---+---+---+---+---+---+---+---+
(if FLG.FEXTRA set)
+---+---+=================================+
| XLEN |...XLEN bytes of "extra field"...| (more-->)
+---+---+=================================+
(if FLG.FNAME set)
+=========================================+
|...original file name, zero-terminated...| (more-->)
+=========================================+
(if FLG.FCOMMENT set)
+===================================+
|...file comment, zero-terminated...| (more-->)
+===================================+
(if FLG.FHCRC set)
+---+---+
| CRC16 |
+---+---+
+=======================+
|...compressed blocks...| (more-->)
+=======================+
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| CRC32 | ISIZE |
+---+---+---+---+---+---+---+---+
Deutsch Informational [Page 5]
RFC 1952 GZIP File Format Specification May 1996
2.3.1. Member header and trailer
ID1 (IDentification 1)
ID2 (IDentification 2)
These have the fixed values ID1 = 31 (0x1f, \037), ID2 = 139
(0x8b, \213), to identify the file as being in gzip format.
CM (Compression Method)
This identifies the compression method used in the file. CM
= 0-7 are reserved. CM = 8 denotes the "deflate"
compression method, which is the one customarily used by
gzip and which is documented elsewhere.
FLG (FLaGs)
This flag byte is divided into individual bits as follows:
bit 0 FTEXT
bit 1 FHCRC
bit 2 FEXTRA
bit 3 FNAME
bit 4 FCOMMENT
bit 5 reserved
bit 6 reserved
bit 7 reserved
If FTEXT is set, the file is probably ASCII text. This is
an optional indication, which the compressor may set by
checking a small amount of the input data to see whether any
non-ASCII characters are present. In case of doubt, FTEXT
is cleared, indicating binary data. For systems which have
different file formats for ascii text and binary data, the
decompressor can use FTEXT to choose the appropriate format.
We deliberately do not specify the algorithm used to set
this bit, since a compressor always has the option of
leaving it cleared and a decompressor always has the option
of ignoring it and letting some other program handle issues
of data conversion.
If FHCRC is set, a CRC16 for the gzip header is present,
immediately before the compressed data. The CRC16 consists
of the two least significant bytes of the CRC32 for all
bytes of the gzip header up to and not including the CRC16.
[The FHCRC bit was never set by versions of gzip up to
1.2.4, even though it was documented with a different
meaning in gzip 1.2.4.]
If FEXTRA is set, optional extra fields are present, as
described in a following section.
Deutsch Informational [Page 6]
RFC 1952 GZIP File Format Specification May 1996
If FNAME is set, an original file name is present,
terminated by a zero byte. The name must consist of ISO
8859-1 (LATIN-1) characters; on operating systems using
EBCDIC or any other character set for file names, the name
must be translated to the ISO LATIN-1 character set. This
is the original name of the file being compressed, with any
directory components removed, and, if the file being
compressed is on a file system with case insensitive names,
forced to lower case. There is no original file name if the
data was compressed from a source other than a named file;
for example, if the source was stdin on a Unix system, there
is no file name.
If FCOMMENT is set, a zero-terminated file comment is
present. This comment is not interpreted; it is only
intended for human consumption. The comment must consist of
ISO 8859-1 (LATIN-1) characters. Line breaks should be
denoted by a single line feed character (10 decimal).
Reserved FLG bits must be zero.
MTIME (Modification TIME)
This gives the most recent modification time of the original
file being compressed. The time is in Unix format, i.e.,
seconds since 00:00:00 GMT, Jan. 1, 1970. (Note that this
may cause problems for MS-DOS and other systems that use
local rather than Universal time.) If the compressed data
did not come from a file, MTIME is set to the time at which
compression started. MTIME = 0 means no time stamp is
available.
XFL (eXtra FLags)
These flags are available for use by specific compression
methods. The "deflate" method (CM = 8) sets these flags as
follows:
XFL = 2 - compressor used maximum compression,
slowest algorithm
XFL = 4 - compressor used fastest algorithm
OS (Operating System)
This identifies the type of file system on which compression
took place. This may be useful in determining end-of-line
convention for text files. The currently defined values are
as follows:
Deutsch Informational [Page 7]
RFC 1952 GZIP File Format Specification May 1996
0 - FAT filesystem (MS-DOS, OS/2, NT/Win32)
1 - Amiga
2 - VMS (or OpenVMS)
3 - Unix
4 - VM/CMS
5 - Atari TOS
6 - HPFS filesystem (OS/2, NT)
7 - Macintosh
8 - Z-System
9 - CP/M
10 - TOPS-20
11 - NTFS filesystem (NT)
12 - QDOS
13 - Acorn RISCOS
255 - unknown
XLEN (eXtra LENgth)
If FLG.FEXTRA is set, this gives the length of the optional
extra field. See below for details.
CRC32 (CRC-32)
This contains a Cyclic Redundancy Check value of the
uncompressed data computed according to CRC-32 algorithm
used in the ISO 3309 standard and in section 8.1.1.6.2 of
ITU-T recommendation V.42. (See http://www.iso.ch for
ordering ISO documents. See gopher://info.itu.ch for an
online version of ITU-T V.42.)
ISIZE (Input SIZE)
This contains the size of the original (uncompressed) input
data modulo 2^32.
2.3.1.1. Extra field
If the FLG.FEXTRA bit is set, an "extra field" is present in
the header, with total length XLEN bytes. It consists of a
series of subfields, each of the form:
+---+---+---+---+==================================+
|SI1|SI2| LEN |... LEN bytes of subfield data ...|
+---+---+---+---+==================================+
SI1 and SI2 provide a subfield ID, typically two ASCII letters
with some mnemonic value. Jean-Loup Gailly
<gzip@prep.ai.mit.edu> is maintaining a registry of subfield
IDs; please send him any subfield ID you wish to use. Subfield
IDs with SI2 = 0 are reserved for future use. The following
IDs are currently defined:
Deutsch Informational [Page 8]
RFC 1952 GZIP File Format Specification May 1996
SI1 SI2 Data
---------- ---------- ----
0x41 ('A') 0x70 ('P') Apollo file type information
LEN gives the length of the subfield data, excluding the 4
initial bytes.
2.3.1.2. Compliance
A compliant compressor must produce files with correct ID1,
ID2, CM, CRC32, and ISIZE, but may set all the other fields in
the fixed-length part of the header to default values (255 for
OS, 0 for all others). The compressor must set all reserved
bits to zero.
A compliant decompressor must check ID1, ID2, and CM, and
provide an error indication if any of these have incorrect
values. It must examine FEXTRA/XLEN, FNAME, FCOMMENT and FHCRC
at least so it can skip over the optional fields if they are
present. It need not examine any other part of the header or
trailer; in particular, a decompressor may ignore FTEXT and OS
and always produce binary output, and still be compliant. A
compliant decompressor must give an error indication if any
reserved bit is non-zero, since such a bit could indicate the
presence of a new field that would cause subsequent data to be
interpreted incorrectly.
3. References
[1] "Information Processing - 8-bit single-byte coded graphic
character sets - Part 1: Latin alphabet No.1" (ISO 8859-1:1987).
The ISO 8859-1 (Latin-1) character set is a superset of 7-bit
ASCII. Files defining this character set are available as
iso_8859-1.* in ftp://ftp.uu.net/graphics/png/documents/
[2] ISO 3309
[3] ITU-T recommendation V.42
[4] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification",
available in ftp://ftp.uu.net/pub/archiving/zip/doc/
[5] Gailly, J.-L., GZIP documentation, available as gzip-*.tar in
ftp://prep.ai.mit.edu/pub/gnu/
[6] Sarwate, D.V., "Computation of Cyclic Redundancy Checks via Table
Look-Up", Communications of the ACM, 31(8), pp.1008-1013.
Deutsch Informational [Page 9]
RFC 1952 GZIP File Format Specification May 1996
[7] Schwaderer, W.D., "CRC Calculation", April 85 PC Tech Journal,
pp.118-133.
[8] ftp://ftp.adelaide.edu.au/pub/rocksoft/papers/crc_v3.txt,
describing the CRC concept.
4. Security Considerations
Any data compression method involves the reduction of redundancy in
the data. Consequently, any corruption of the data is likely to have
severe effects and be difficult to correct. Uncompressed text, on
the other hand, will probably still be readable despite the presence
of some corrupted bytes.
It is recommended that systems using this data format provide some
means of validating the integrity of the compressed data, such as by
setting and checking the CRC-32 check value.
5. Acknowledgements
Trademarks cited in this document are the property of their
respective owners.
Jean-Loup Gailly designed the gzip format and wrote, with Mark Adler,
the related software described in this specification. Glenn
Randers-Pehrson converted this document to RFC and HTML format.
6. Author's Address
L. Peter Deutsch
Aladdin Enterprises
203 Santa Margarita Ave.
Menlo Park, CA 94025
Phone: (415) 322-0103 (AM only)
FAX: (415) 322-1734
EMail: <ghost@aladdin.com>
Questions about the technical content of this specification can be
sent by email to:
Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
Mark Adler <madler@alumni.caltech.edu>
Editorial comments on this specification can be sent by email to:
L. Peter Deutsch <ghost@aladdin.com> and
Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
Deutsch Informational [Page 10]
RFC 1952 GZIP File Format Specification May 1996
7. Appendix: Jean-Loup Gailly's gzip utility
The most widely used implementation of gzip compression, and the
original documentation on which this specification is based, were
created by Jean-Loup Gailly <gzip@prep.ai.mit.edu>. Since this
implementation is a de facto standard, we mention some more of its
features here. Again, the material in this section is not part of
the specification per se, and implementations need not follow it to
be compliant.
When compressing or decompressing a file, gzip preserves the
protection, ownership, and modification time attributes on the local
file system, since there is no provision for representing protection
attributes in the gzip file format itself. Since the file format
includes a modification time, the gzip decompressor provides a
command line switch that assigns the modification time from the file,
rather than the local modification time of the compressed input, to
the decompressed output.
8. Appendix: Sample CRC Code
The following sample code represents a practical implementation of
the CRC (Cyclic Redundancy Check). (See also ISO 3309 and ITU-T V.42
for a formal specification.)
The sample code is in the ANSI C programming language. Non C users
may find it easier to read with these hints:
& Bitwise AND operator.
^ Bitwise exclusive-OR operator.
>> Bitwise right shift operator. When applied to an
unsigned quantity, as here, right shift inserts zero
bit(s) at the left.
! Logical NOT operator.
++ "n++" increments the variable n.
0xNNN 0x introduces a hexadecimal (base 16) constant.
Suffix L indicates a long value (at least 32 bits).
/* Table of CRCs of all 8-bit messages. */
unsigned long crc_table[256];
/* Flag: has the table been computed? Initially false. */
int crc_table_computed = 0;
/* Make the table for a fast CRC. */
void make_crc_table(void)
{
unsigned long c;
Deutsch Informational [Page 11]
RFC 1952 GZIP File Format Specification May 1996
int n, k;
for (n = 0; n < 256; n++) {
c = (unsigned long) n;
for (k = 0; k < 8; k++) {
if (c & 1) {
c = 0xedb88320L ^ (c >> 1);
} else {
c = c >> 1;
}
}
crc_table[n] = c;
}
crc_table_computed = 1;
}
/*
Update a running crc with the bytes buf[0..len-1] and return
the updated crc. The crc should be initialized to zero. Pre- and
post-conditioning (one's complement) is performed within this
function so it shouldn't be done by the caller. Usage example:
unsigned long crc = 0L;
while (read_buffer(buffer, length) != EOF) {
crc = update_crc(crc, buffer, length);
}
if (crc != original_crc) error();
*/
unsigned long update_crc(unsigned long crc,
unsigned char *buf, int len)
{
unsigned long c = crc ^ 0xffffffffL;
int n;
if (!crc_table_computed)
make_crc_table();
for (n = 0; n < len; n++) {
c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
}
return c ^ 0xffffffffL;
}
/* Return the CRC of the bytes buf[0..len-1]. */
unsigned long crc(unsigned char *buf, int len)
{
return update_crc(0L, buf, len);
}
Deutsch Informational [Page 12]

107
external/zlib/doc/txtvsbin.txt vendored Normal file
View File

@@ -0,0 +1,107 @@
A Fast Method for Identifying Plain Text Files
==============================================
Introduction
------------
Given a file coming from an unknown source, it is sometimes desirable
to find out whether the format of that file is plain text. Although
this may appear like a simple task, a fully accurate detection of the
file type requires heavy-duty semantic analysis on the file contents.
It is, however, possible to obtain satisfactory results by employing
various heuristics.
Previous versions of PKZip and other zip-compatible compression tools
were using a crude detection scheme: if more than 80% (4/5) of the bytes
found in a certain buffer are within the range [7..127], the file is
labeled as plain text, otherwise it is labeled as binary. A prominent
limitation of this scheme is the restriction to Latin-based alphabets.
Other alphabets, like Greek, Cyrillic or Asian, make extensive use of
the bytes within the range [128..255], and texts using these alphabets
are most often misidentified by this scheme; in other words, the rate
of false negatives is sometimes too high, which means that the recall
is low. Another weakness of this scheme is a reduced precision, due to
the false positives that may occur when binary files containing large
amounts of textual characters are misidentified as plain text.
In this article we propose a new, simple detection scheme that features
a much increased precision and a near-100% recall. This scheme is
designed to work on ASCII, Unicode and other ASCII-derived alphabets,
and it handles single-byte encodings (ISO-8859, MacRoman, KOI8, etc.)
and variable-sized encodings (ISO-2022, UTF-8, etc.). Wider encodings
(UCS-2/UTF-16 and UCS-4/UTF-32) are not handled, however.
The Algorithm
-------------
The algorithm works by dividing the set of bytecodes [0..255] into three
categories:
- The white list of textual bytecodes:
9 (TAB), 10 (LF), 13 (CR), 32 (SPACE) to 255.
- The gray list of tolerated bytecodes:
7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB), 27 (ESC).
- The black list of undesired, non-textual bytecodes:
0 (NUL) to 6, 14 to 31.
If a file contains at least one byte that belongs to the white list and
no byte that belongs to the black list, then the file is categorized as
plain text; otherwise, it is categorized as binary. (The boundary case,
when the file is empty, automatically falls into the latter category.)
Rationale
---------
The idea behind this algorithm relies on two observations.
The first observation is that, although the full range of 7-bit codes
[0..127] is properly specified by the ASCII standard, most control
characters in the range [0..31] are not used in practice. The only
widely-used, almost universally-portable control codes are 9 (TAB),
10 (LF) and 13 (CR). There are a few more control codes that are
recognized on a reduced range of platforms and text viewers/editors:
7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB) and 27 (ESC); but these
codes are rarely (if ever) used alone, without being accompanied by
some printable text. Even the newer, portable text formats such as
XML avoid using control characters outside the list mentioned here.
The second observation is that most of the binary files tend to contain
control characters, especially 0 (NUL). Even though the older text
detection schemes observe the presence of non-ASCII codes from the range
[128..255], the precision rarely has to suffer if this upper range is
labeled as textual, because the files that are genuinely binary tend to
contain both control characters and codes from the upper range. On the
other hand, the upper range needs to be labeled as textual, because it
is used by virtually all ASCII extensions. In particular, this range is
used for encoding non-Latin scripts.
Since there is no counting involved, other than simply observing the
presence or the absence of some byte values, the algorithm produces
consistent results, regardless what alphabet encoding is being used.
(If counting were involved, it could be possible to obtain different
results on a text encoded, say, using ISO-8859-16 versus UTF-8.)
There is an extra category of plain text files that are "polluted" with
one or more black-listed codes, either by mistake or by peculiar design
considerations. In such cases, a scheme that tolerates a small fraction
of black-listed codes would provide an increased recall (i.e. more true
positives). This, however, incurs a reduced precision overall, since
false positives are more likely to appear in binary files that contain
large chunks of textual data. Furthermore, "polluted" plain text should
be regarded as binary by general-purpose text detection schemes, because
general-purpose text processing algorithms might not be applicable.
Under this premise, it is safe to say that our detection method provides
a near-100% recall.
Experiments have been run on many files coming from various platforms
and applications. We tried plain text files, system logs, source code,
formatted office documents, compiled object code, etc. The results
confirm the optimistic assumptions about the capabilities of this
algorithm.
--
Cosmin Truta
Last updated: 2006-May-28

49
external/zlib/examples/README.examples vendored Normal file
View File

@@ -0,0 +1,49 @@
This directory contains examples of the use of zlib and other relevant
programs and documentation.
enough.c
calculation and justification of ENOUGH parameter in inftrees.h
- calculates the maximum table space used in inflate tree
construction over all possible Huffman codes
fitblk.c
compress just enough input to nearly fill a requested output size
- zlib isn't designed to do this, but fitblk does it anyway
gun.c
uncompress a gzip file
- illustrates the use of inflateBack() for high speed file-to-file
decompression using call-back functions
- is approximately twice as fast as gzip -d
- also provides Unix uncompress functionality, again twice as fast
gzappend.c
append to a gzip file
- illustrates the use of the Z_BLOCK flush parameter for inflate()
- illustrates the use of deflatePrime() to start at any bit
gzjoin.c
join gzip files without recalculating the crc or recompressing
- illustrates the use of the Z_BLOCK flush parameter for inflate()
- illustrates the use of crc32_combine()
gzlog.c
gzlog.h
efficiently and robustly maintain a message log file in gzip format
- illustrates use of raw deflate, Z_PARTIAL_FLUSH, deflatePrime(),
and deflateSetDictionary()
- illustrates use of a gzip header extra field
zlib_how.html
painfully comprehensive description of zpipe.c (see below)
- describes in excruciating detail the use of deflate() and inflate()
zpipe.c
reads and writes zlib streams from stdin to stdout
- illustrates the proper use of deflate() and inflate()
- deeply commented in zlib_how.html (see above)
zran.c
index a zlib or gzip stream and randomly access it
- illustrates the use of Z_BLOCK, inflatePrime(), and
inflateSetDictionary() to provide random access

572
external/zlib/examples/enough.c vendored Normal file
View File

@@ -0,0 +1,572 @@
/* enough.c -- determine the maximum size of inflate's Huffman code tables over
* all possible valid and complete Huffman codes, subject to a length limit.
* Copyright (C) 2007, 2008, 2012 Mark Adler
* Version 1.4 18 August 2012 Mark Adler
*/
/* Version history:
1.0 3 Jan 2007 First version (derived from codecount.c version 1.4)
1.1 4 Jan 2007 Use faster incremental table usage computation
Prune examine() search on previously visited states
1.2 5 Jan 2007 Comments clean up
As inflate does, decrease root for short codes
Refuse cases where inflate would increase root
1.3 17 Feb 2008 Add argument for initial root table size
Fix bug for initial root table size == max - 1
Use a macro to compute the history index
1.4 18 Aug 2012 Avoid shifts more than bits in type (caused endless loop!)
Clean up comparisons of different types
Clean up code indentation
*/
/*
Examine all possible Huffman codes for a given number of symbols and a
maximum code length in bits to determine the maximum table size for zilb's
inflate. Only complete Huffman codes are counted.
Two codes are considered distinct if the vectors of the number of codes per
length are not identical. So permutations of the symbol assignments result
in the same code for the counting, as do permutations of the assignments of
the bit values to the codes (i.e. only canonical codes are counted).
We build a code from shorter to longer lengths, determining how many symbols
are coded at each length. At each step, we have how many symbols remain to
be coded, what the last code length used was, and how many bit patterns of
that length remain unused. Then we add one to the code length and double the
number of unused patterns to graduate to the next code length. We then
assign all portions of the remaining symbols to that code length that
preserve the properties of a correct and eventually complete code. Those
properties are: we cannot use more bit patterns than are available; and when
all the symbols are used, there are exactly zero possible bit patterns
remaining.
The inflate Huffman decoding algorithm uses two-level lookup tables for
speed. There is a single first-level table to decode codes up to root bits
in length (root == 9 in the current inflate implementation). The table
has 1 << root entries and is indexed by the next root bits of input. Codes
shorter than root bits have replicated table entries, so that the correct
entry is pointed to regardless of the bits that follow the short code. If
the code is longer than root bits, then the table entry points to a second-
level table. The size of that table is determined by the longest code with
that root-bit prefix. If that longest code has length len, then the table
has size 1 << (len - root), to index the remaining bits in that set of
codes. Each subsequent root-bit prefix then has its own sub-table. The
total number of table entries required by the code is calculated
incrementally as the number of codes at each bit length is populated. When
all of the codes are shorter than root bits, then root is reduced to the
longest code length, resulting in a single, smaller, one-level table.
The inflate algorithm also provides for small values of root (relative to
the log2 of the number of symbols), where the shortest code has more bits
than root. In that case, root is increased to the length of the shortest
code. This program, by design, does not handle that case, so it is verified
that the number of symbols is less than 2^(root + 1).
In order to speed up the examination (by about ten orders of magnitude for
the default arguments), the intermediate states in the build-up of a code
are remembered and previously visited branches are pruned. The memory
required for this will increase rapidly with the total number of symbols and
the maximum code length in bits. However this is a very small price to pay
for the vast speedup.
First, all of the possible Huffman codes are counted, and reachable
intermediate states are noted by a non-zero count in a saved-results array.
Second, the intermediate states that lead to (root + 1) bit or longer codes
are used to look at all sub-codes from those junctures for their inflate
memory usage. (The amount of memory used is not affected by the number of
codes of root bits or less in length.) Third, the visited states in the
construction of those sub-codes and the associated calculation of the table
size is recalled in order to avoid recalculating from the same juncture.
Beginning the code examination at (root + 1) bit codes, which is enabled by
identifying the reachable nodes, accounts for about six of the orders of
magnitude of improvement for the default arguments. About another four
orders of magnitude come from not revisiting previous states. Out of
approximately 2x10^16 possible Huffman codes, only about 2x10^6 sub-codes
need to be examined to cover all of the possible table memory usage cases
for the default arguments of 286 symbols limited to 15-bit codes.
Note that an unsigned long long type is used for counting. It is quite easy
to exceed the capacity of an eight-byte integer with a large number of
symbols and a large maximum code length, so multiple-precision arithmetic
would need to replace the unsigned long long arithmetic in that case. This
program will abort if an overflow occurs. The big_t type identifies where
the counting takes place.
An unsigned long long type is also used for calculating the number of
possible codes remaining at the maximum length. This limits the maximum
code length to the number of bits in a long long minus the number of bits
needed to represent the symbols in a flat code. The code_t type identifies
where the bit pattern counting takes place.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define local static
/* special data types */
typedef unsigned long long big_t; /* type for code counting */
typedef unsigned long long code_t; /* type for bit pattern counting */
struct tab { /* type for been here check */
size_t len; /* length of bit vector in char's */
char *vec; /* allocated bit vector */
};
/* The array for saving results, num[], is indexed with this triplet:
syms: number of symbols remaining to code
left: number of available bit patterns at length len
len: number of bits in the codes currently being assigned
Those indices are constrained thusly when saving results:
syms: 3..totsym (totsym == total symbols to code)
left: 2..syms - 1, but only the evens (so syms == 8 -> 2, 4, 6)
len: 1..max - 1 (max == maximum code length in bits)
syms == 2 is not saved since that immediately leads to a single code. left
must be even, since it represents the number of available bit patterns at
the current length, which is double the number at the previous length.
left ends at syms-1 since left == syms immediately results in a single code.
(left > sym is not allowed since that would result in an incomplete code.)
len is less than max, since the code completes immediately when len == max.
The offset into the array is calculated for the three indices with the
first one (syms) being outermost, and the last one (len) being innermost.
We build the array with length max-1 lists for the len index, with syms-3
of those for each symbol. There are totsym-2 of those, with each one
varying in length as a function of sym. See the calculation of index in
count() for the index, and the calculation of size in main() for the size
of the array.
For the deflate example of 286 symbols limited to 15-bit codes, the array
has 284,284 entries, taking up 2.17 MB for an 8-byte big_t. More than
half of the space allocated for saved results is actually used -- not all
possible triplets are reached in the generation of valid Huffman codes.
*/
/* The array for tracking visited states, done[], is itself indexed identically
to the num[] array as described above for the (syms, left, len) triplet.
Each element in the array is further indexed by the (mem, rem) doublet,
where mem is the amount of inflate table space used so far, and rem is the
remaining unused entries in the current inflate sub-table. Each indexed
element is simply one bit indicating whether the state has been visited or
not. Since the ranges for mem and rem are not known a priori, each bit
vector is of a variable size, and grows as needed to accommodate the visited
states. mem and rem are used to calculate a single index in a triangular
array. Since the range of mem is expected in the default case to be about
ten times larger than the range of rem, the array is skewed to reduce the
memory usage, with eight times the range for mem than for rem. See the
calculations for offset and bit in beenhere() for the details.
For the deflate example of 286 symbols limited to 15-bit codes, the bit
vectors grow to total approximately 21 MB, in addition to the 4.3 MB done[]
array itself.
*/
/* Globals to avoid propagating constants or constant pointers recursively */
local int max; /* maximum allowed bit length for the codes */
local int root; /* size of base code table in bits */
local int large; /* largest code table so far */
local size_t size; /* number of elements in num and done */
local int *code; /* number of symbols assigned to each bit length */
local big_t *num; /* saved results array for code counting */
local struct tab *done; /* states already evaluated array */
/* Index function for num[] and done[] */
#define INDEX(i,j,k) (((size_t)((i-1)>>1)*((i-2)>>1)+(j>>1)-1)*(max-1)+k-1)
/* Free allocated space. Uses globals code, num, and done. */
local void cleanup(void)
{
size_t n;
if (done != NULL) {
for (n = 0; n < size; n++)
if (done[n].len)
free(done[n].vec);
free(done);
}
if (num != NULL)
free(num);
if (code != NULL)
free(code);
}
/* Return the number of possible Huffman codes using bit patterns of lengths
len through max inclusive, coding syms symbols, with left bit patterns of
length len unused -- return -1 if there is an overflow in the counting.
Keep a record of previous results in num to prevent repeating the same
calculation. Uses the globals max and num. */
local big_t count(int syms, int len, int left)
{
big_t sum; /* number of possible codes from this juncture */
big_t got; /* value returned from count() */
int least; /* least number of syms to use at this juncture */
int most; /* most number of syms to use at this juncture */
int use; /* number of bit patterns to use in next call */
size_t index; /* index of this case in *num */
/* see if only one possible code */
if (syms == left)
return 1;
/* note and verify the expected state */
assert(syms > left && left > 0 && len < max);
/* see if we've done this one already */
index = INDEX(syms, left, len);
got = num[index];
if (got)
return got; /* we have -- return the saved result */
/* we need to use at least this many bit patterns so that the code won't be
incomplete at the next length (more bit patterns than symbols) */
least = (left << 1) - syms;
if (least < 0)
least = 0;
/* we can use at most this many bit patterns, lest there not be enough
available for the remaining symbols at the maximum length (if there were
no limit to the code length, this would become: most = left - 1) */
most = (((code_t)left << (max - len)) - syms) /
(((code_t)1 << (max - len)) - 1);
/* count all possible codes from this juncture and add them up */
sum = 0;
for (use = least; use <= most; use++) {
got = count(syms - use, len + 1, (left - use) << 1);
sum += got;
if (got == (big_t)0 - 1 || sum < got) /* overflow */
return (big_t)0 - 1;
}
/* verify that all recursive calls are productive */
assert(sum != 0);
/* save the result and return it */
num[index] = sum;
return sum;
}
/* Return true if we've been here before, set to true if not. Set a bit in a
bit vector to indicate visiting this state. Each (syms,len,left) state
has a variable size bit vector indexed by (mem,rem). The bit vector is
lengthened if needed to allow setting the (mem,rem) bit. */
local int beenhere(int syms, int len, int left, int mem, int rem)
{
size_t index; /* index for this state's bit vector */
size_t offset; /* offset in this state's bit vector */
int bit; /* mask for this state's bit */
size_t length; /* length of the bit vector in bytes */
char *vector; /* new or enlarged bit vector */
/* point to vector for (syms,left,len), bit in vector for (mem,rem) */
index = INDEX(syms, left, len);
mem -= 1 << root;
offset = (mem >> 3) + rem;
offset = ((offset * (offset + 1)) >> 1) + rem;
bit = 1 << (mem & 7);
/* see if we've been here */
length = done[index].len;
if (offset < length && (done[index].vec[offset] & bit) != 0)
return 1; /* done this! */
/* we haven't been here before -- set the bit to show we have now */
/* see if we need to lengthen the vector in order to set the bit */
if (length <= offset) {
/* if we have one already, enlarge it, zero out the appended space */
if (length) {
do {
length <<= 1;
} while (length <= offset);
vector = realloc(done[index].vec, length);
if (vector != NULL)
memset(vector + done[index].len, 0, length - done[index].len);
}
/* otherwise we need to make a new vector and zero it out */
else {
length = 1 << (len - root);
while (length <= offset)
length <<= 1;
vector = calloc(length, sizeof(char));
}
/* in either case, bail if we can't get the memory */
if (vector == NULL) {
fputs("abort: unable to allocate enough memory\n", stderr);
cleanup();
exit(1);
}
/* install the new vector */
done[index].len = length;
done[index].vec = vector;
}
/* set the bit */
done[index].vec[offset] |= bit;
return 0;
}
/* Examine all possible codes from the given node (syms, len, left). Compute
the amount of memory required to build inflate's decoding tables, where the
number of code structures used so far is mem, and the number remaining in
the current sub-table is rem. Uses the globals max, code, root, large, and
done. */
local void examine(int syms, int len, int left, int mem, int rem)
{
int least; /* least number of syms to use at this juncture */
int most; /* most number of syms to use at this juncture */
int use; /* number of bit patterns to use in next call */
/* see if we have a complete code */
if (syms == left) {
/* set the last code entry */
code[len] = left;
/* complete computation of memory used by this code */
while (rem < left) {
left -= rem;
rem = 1 << (len - root);
mem += rem;
}
assert(rem == left);
/* if this is a new maximum, show the entries used and the sub-code */
if (mem > large) {
large = mem;
printf("max %d: ", mem);
for (use = root + 1; use <= max; use++)
if (code[use])
printf("%d[%d] ", code[use], use);
putchar('\n');
fflush(stdout);
}
/* remove entries as we drop back down in the recursion */
code[len] = 0;
return;
}
/* prune the tree if we can */
if (beenhere(syms, len, left, mem, rem))
return;
/* we need to use at least this many bit patterns so that the code won't be
incomplete at the next length (more bit patterns than symbols) */
least = (left << 1) - syms;
if (least < 0)
least = 0;
/* we can use at most this many bit patterns, lest there not be enough
available for the remaining symbols at the maximum length (if there were
no limit to the code length, this would become: most = left - 1) */
most = (((code_t)left << (max - len)) - syms) /
(((code_t)1 << (max - len)) - 1);
/* occupy least table spaces, creating new sub-tables as needed */
use = least;
while (rem < use) {
use -= rem;
rem = 1 << (len - root);
mem += rem;
}
rem -= use;
/* examine codes from here, updating table space as we go */
for (use = least; use <= most; use++) {
code[len] = use;
examine(syms - use, len + 1, (left - use) << 1,
mem + (rem ? 1 << (len - root) : 0), rem << 1);
if (rem == 0) {
rem = 1 << (len - root);
mem += rem;
}
rem--;
}
/* remove entries as we drop back down in the recursion */
code[len] = 0;
}
/* Look at all sub-codes starting with root + 1 bits. Look at only the valid
intermediate code states (syms, left, len). For each completed code,
calculate the amount of memory required by inflate to build the decoding
tables. Find the maximum amount of memory required and show the code that
requires that maximum. Uses the globals max, root, and num. */
local void enough(int syms)
{
int n; /* number of remaing symbols for this node */
int left; /* number of unused bit patterns at this length */
size_t index; /* index of this case in *num */
/* clear code */
for (n = 0; n <= max; n++)
code[n] = 0;
/* look at all (root + 1) bit and longer codes */
large = 1 << root; /* base table */
if (root < max) /* otherwise, there's only a base table */
for (n = 3; n <= syms; n++)
for (left = 2; left < n; left += 2)
{
/* look at all reachable (root + 1) bit nodes, and the
resulting codes (complete at root + 2 or more) */
index = INDEX(n, left, root + 1);
if (root + 1 < max && num[index]) /* reachable node */
examine(n, root + 1, left, 1 << root, 0);
/* also look at root bit codes with completions at root + 1
bits (not saved in num, since complete), just in case */
if (num[index - 1] && n <= left << 1)
examine((n - left) << 1, root + 1, (n - left) << 1,
1 << root, 0);
}
/* done */
printf("done: maximum of %d table entries\n", large);
}
/*
Examine and show the total number of possible Huffman codes for a given
maximum number of symbols, initial root table size, and maximum code length
in bits -- those are the command arguments in that order. The default
values are 286, 9, and 15 respectively, for the deflate literal/length code.
The possible codes are counted for each number of coded symbols from two to
the maximum. The counts for each of those and the total number of codes are
shown. The maximum number of inflate table entires is then calculated
across all possible codes. Each new maximum number of table entries and the
associated sub-code (starting at root + 1 == 10 bits) is shown.
To count and examine Huffman codes that are not length-limited, provide a
maximum length equal to the number of symbols minus one.
For the deflate literal/length code, use "enough". For the deflate distance
code, use "enough 30 6".
This uses the %llu printf format to print big_t numbers, which assumes that
big_t is an unsigned long long. If the big_t type is changed (for example
to a multiple precision type), the method of printing will also need to be
updated.
*/
int main(int argc, char **argv)
{
int syms; /* total number of symbols to code */
int n; /* number of symbols to code for this run */
big_t got; /* return value of count() */
big_t sum; /* accumulated number of codes over n */
code_t word; /* for counting bits in code_t */
/* set up globals for cleanup() */
code = NULL;
num = NULL;
done = NULL;
/* get arguments -- default to the deflate literal/length code */
syms = 286;
root = 9;
max = 15;
if (argc > 1) {
syms = atoi(argv[1]);
if (argc > 2) {
root = atoi(argv[2]);
if (argc > 3)
max = atoi(argv[3]);
}
}
if (argc > 4 || syms < 2 || root < 1 || max < 1) {
fputs("invalid arguments, need: [sym >= 2 [root >= 1 [max >= 1]]]\n",
stderr);
return 1;
}
/* if not restricting the code length, the longest is syms - 1 */
if (max > syms - 1)
max = syms - 1;
/* determine the number of bits in a code_t */
for (n = 0, word = 1; word; n++, word <<= 1)
;
/* make sure that the calculation of most will not overflow */
if (max > n || (code_t)(syms - 2) >= (((code_t)0 - 1) >> (max - 1))) {
fputs("abort: code length too long for internal types\n", stderr);
return 1;
}
/* reject impossible code requests */
if ((code_t)(syms - 1) > ((code_t)1 << max) - 1) {
fprintf(stderr, "%d symbols cannot be coded in %d bits\n",
syms, max);
return 1;
}
/* allocate code vector */
code = calloc(max + 1, sizeof(int));
if (code == NULL) {
fputs("abort: unable to allocate enough memory\n", stderr);
return 1;
}
/* determine size of saved results array, checking for overflows,
allocate and clear the array (set all to zero with calloc()) */
if (syms == 2) /* iff max == 1 */
num = NULL; /* won't be saving any results */
else {
size = syms >> 1;
if (size > ((size_t)0 - 1) / (n = (syms - 1) >> 1) ||
(size *= n, size > ((size_t)0 - 1) / (n = max - 1)) ||
(size *= n, size > ((size_t)0 - 1) / sizeof(big_t)) ||
(num = calloc(size, sizeof(big_t))) == NULL) {
fputs("abort: unable to allocate enough memory\n", stderr);
cleanup();
return 1;
}
}
/* count possible codes for all numbers of symbols, add up counts */
sum = 0;
for (n = 2; n <= syms; n++) {
got = count(n, 1, 2);
sum += got;
if (got == (big_t)0 - 1 || sum < got) { /* overflow */
fputs("abort: can't count that high!\n", stderr);
cleanup();
return 1;
}
printf("%llu %d-codes\n", got, n);
}
printf("%llu total codes for 2 to %d symbols", sum, syms);
if (max < syms - 1)
printf(" (%d-bit length limit)\n", max);
else
puts(" (no length limit)");
/* allocate and clear done array for beenhere() */
if (syms == 2)
done = NULL;
else if (size > ((size_t)0 - 1) / sizeof(struct tab) ||
(done = calloc(size, sizeof(struct tab))) == NULL) {
fputs("abort: unable to allocate enough memory\n", stderr);
cleanup();
return 1;
}
/* find and show maximum inflate table usage */
if (root > max) /* reduce root to max length */
root = max;
if ((code_t)syms < ((code_t)1 << (root + 1)))
enough(syms);
else
puts("cannot handle minimum code lengths > root");
/* done */
cleanup();
return 0;
}

233
external/zlib/examples/fitblk.c vendored Normal file
View File

@@ -0,0 +1,233 @@
/* fitblk.c: example of fitting compressed output to a specified size
Not copyrighted -- provided to the public domain
Version 1.1 25 November 2004 Mark Adler */
/* Version history:
1.0 24 Nov 2004 First version
1.1 25 Nov 2004 Change deflateInit2() to deflateInit()
Use fixed-size, stack-allocated raw buffers
Simplify code moving compression to subroutines
Use assert() for internal errors
Add detailed description of approach
*/
/* Approach to just fitting a requested compressed size:
fitblk performs three compression passes on a portion of the input
data in order to determine how much of that input will compress to
nearly the requested output block size. The first pass generates
enough deflate blocks to produce output to fill the requested
output size plus a specfied excess amount (see the EXCESS define
below). The last deflate block may go quite a bit past that, but
is discarded. The second pass decompresses and recompresses just
the compressed data that fit in the requested plus excess sized
buffer. The deflate process is terminated after that amount of
input, which is less than the amount consumed on the first pass.
The last deflate block of the result will be of a comparable size
to the final product, so that the header for that deflate block and
the compression ratio for that block will be about the same as in
the final product. The third compression pass decompresses the
result of the second step, but only the compressed data up to the
requested size minus an amount to allow the compressed stream to
complete (see the MARGIN define below). That will result in a
final compressed stream whose length is less than or equal to the
requested size. Assuming sufficient input and a requested size
greater than a few hundred bytes, the shortfall will typically be
less than ten bytes.
If the input is short enough that the first compression completes
before filling the requested output size, then that compressed
stream is return with no recompression.
EXCESS is chosen to be just greater than the shortfall seen in a
two pass approach similar to the above. That shortfall is due to
the last deflate block compressing more efficiently with a smaller
header on the second pass. EXCESS is set to be large enough so
that there is enough uncompressed data for the second pass to fill
out the requested size, and small enough so that the final deflate
block of the second pass will be close in size to the final deflate
block of the third and final pass. MARGIN is chosen to be just
large enough to assure that the final compression has enough room
to complete in all cases.
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "zlib.h"
#define local static
/* print nastygram and leave */
local void quit(char *why)
{
fprintf(stderr, "fitblk abort: %s\n", why);
exit(1);
}
#define RAWLEN 4096 /* intermediate uncompressed buffer size */
/* compress from file to def until provided buffer is full or end of
input reached; return last deflate() return value, or Z_ERRNO if
there was read error on the file */
local int partcompress(FILE *in, z_streamp def)
{
int ret, flush;
unsigned char raw[RAWLEN];
flush = Z_NO_FLUSH;
do {
def->avail_in = fread(raw, 1, RAWLEN, in);
if (ferror(in))
return Z_ERRNO;
def->next_in = raw;
if (feof(in))
flush = Z_FINISH;
ret = deflate(def, flush);
assert(ret != Z_STREAM_ERROR);
} while (def->avail_out != 0 && flush == Z_NO_FLUSH);
return ret;
}
/* recompress from inf's input to def's output; the input for inf and
the output for def are set in those structures before calling;
return last deflate() return value, or Z_MEM_ERROR if inflate()
was not able to allocate enough memory when it needed to */
local int recompress(z_streamp inf, z_streamp def)
{
int ret, flush;
unsigned char raw[RAWLEN];
flush = Z_NO_FLUSH;
do {
/* decompress */
inf->avail_out = RAWLEN;
inf->next_out = raw;
ret = inflate(inf, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR && ret != Z_DATA_ERROR &&
ret != Z_NEED_DICT);
if (ret == Z_MEM_ERROR)
return ret;
/* compress what was decompresed until done or no room */
def->avail_in = RAWLEN - inf->avail_out;
def->next_in = raw;
if (inf->avail_out != 0)
flush = Z_FINISH;
ret = deflate(def, flush);
assert(ret != Z_STREAM_ERROR);
} while (ret != Z_STREAM_END && def->avail_out != 0);
return ret;
}
#define EXCESS 256 /* empirically determined stream overage */
#define MARGIN 8 /* amount to back off for completion */
/* compress from stdin to fixed-size block on stdout */
int main(int argc, char **argv)
{
int ret; /* return code */
unsigned size; /* requested fixed output block size */
unsigned have; /* bytes written by deflate() call */
unsigned char *blk; /* intermediate and final stream */
unsigned char *tmp; /* close to desired size stream */
z_stream def, inf; /* zlib deflate and inflate states */
/* get requested output size */
if (argc != 2)
quit("need one argument: size of output block");
ret = strtol(argv[1], argv + 1, 10);
if (argv[1][0] != 0)
quit("argument must be a number");
if (ret < 8) /* 8 is minimum zlib stream size */
quit("need positive size of 8 or greater");
size = (unsigned)ret;
/* allocate memory for buffers and compression engine */
blk = malloc(size + EXCESS);
def.zalloc = Z_NULL;
def.zfree = Z_NULL;
def.opaque = Z_NULL;
ret = deflateInit(&def, Z_DEFAULT_COMPRESSION);
if (ret != Z_OK || blk == NULL)
quit("out of memory");
/* compress from stdin until output full, or no more input */
def.avail_out = size + EXCESS;
def.next_out = blk;
ret = partcompress(stdin, &def);
if (ret == Z_ERRNO)
quit("error reading input");
/* if it all fit, then size was undersubscribed -- done! */
if (ret == Z_STREAM_END && def.avail_out >= EXCESS) {
/* write block to stdout */
have = size + EXCESS - def.avail_out;
if (fwrite(blk, 1, have, stdout) != have || ferror(stdout))
quit("error writing output");
/* clean up and print results to stderr */
ret = deflateEnd(&def);
assert(ret != Z_STREAM_ERROR);
free(blk);
fprintf(stderr,
"%u bytes unused out of %u requested (all input)\n",
size - have, size);
return 0;
}
/* it didn't all fit -- set up for recompression */
inf.zalloc = Z_NULL;
inf.zfree = Z_NULL;
inf.opaque = Z_NULL;
inf.avail_in = 0;
inf.next_in = Z_NULL;
ret = inflateInit(&inf);
tmp = malloc(size + EXCESS);
if (ret != Z_OK || tmp == NULL)
quit("out of memory");
ret = deflateReset(&def);
assert(ret != Z_STREAM_ERROR);
/* do first recompression close to the right amount */
inf.avail_in = size + EXCESS;
inf.next_in = blk;
def.avail_out = size + EXCESS;
def.next_out = tmp;
ret = recompress(&inf, &def);
if (ret == Z_MEM_ERROR)
quit("out of memory");
/* set up for next reocmpression */
ret = inflateReset(&inf);
assert(ret != Z_STREAM_ERROR);
ret = deflateReset(&def);
assert(ret != Z_STREAM_ERROR);
/* do second and final recompression (third compression) */
inf.avail_in = size - MARGIN; /* assure stream will complete */
inf.next_in = tmp;
def.avail_out = size;
def.next_out = blk;
ret = recompress(&inf, &def);
if (ret == Z_MEM_ERROR)
quit("out of memory");
assert(ret == Z_STREAM_END); /* otherwise MARGIN too small */
/* done -- write block to stdout */
have = size - def.avail_out;
if (fwrite(blk, 1, have, stdout) != have || ferror(stdout))
quit("error writing output");
/* clean up and print results to stderr */
free(tmp);
ret = inflateEnd(&inf);
assert(ret != Z_STREAM_ERROR);
ret = deflateEnd(&def);
assert(ret != Z_STREAM_ERROR);
free(blk);
fprintf(stderr,
"%u bytes unused out of %u requested (%lu input)\n",
size - have, size, def.total_in);
return 0;
}

702
external/zlib/examples/gun.c vendored Normal file
View File

@@ -0,0 +1,702 @@
/* gun.c -- simple gunzip to give an example of the use of inflateBack()
* Copyright (C) 2003, 2005, 2008, 2010, 2012 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
Version 1.7 12 August 2012 Mark Adler */
/* Version history:
1.0 16 Feb 2003 First version for testing of inflateBack()
1.1 21 Feb 2005 Decompress concatenated gzip streams
Remove use of "this" variable (C++ keyword)
Fix return value for in()
Improve allocation failure checking
Add typecasting for void * structures
Add -h option for command version and usage
Add a bunch of comments
1.2 20 Mar 2005 Add Unix compress (LZW) decompression
Copy file attributes from input file to output file
1.3 12 Jun 2005 Add casts for error messages [Oberhumer]
1.4 8 Dec 2006 LZW decompression speed improvements
1.5 9 Feb 2008 Avoid warning in latest version of gcc
1.6 17 Jan 2010 Avoid signed/unsigned comparison warnings
1.7 12 Aug 2012 Update for z_const usage in zlib 1.2.8
*/
/*
gun [ -t ] [ name ... ]
decompresses the data in the named gzip files. If no arguments are given,
gun will decompress from stdin to stdout. The names must end in .gz, -gz,
.z, -z, _z, or .Z. The uncompressed data will be written to a file name
with the suffix stripped. On success, the original file is deleted. On
failure, the output file is deleted. For most failures, the command will
continue to process the remaining names on the command line. A memory
allocation failure will abort the command. If -t is specified, then the
listed files or stdin will be tested as gzip files for integrity (without
checking for a proper suffix), no output will be written, and no files
will be deleted.
Like gzip, gun allows concatenated gzip streams and will decompress them,
writing all of the uncompressed data to the output. Unlike gzip, gun allows
an empty file on input, and will produce no error writing an empty output
file.
gun will also decompress files made by Unix compress, which uses LZW
compression. These files are automatically detected by virtue of their
magic header bytes. Since the end of Unix compress stream is marked by the
end-of-file, they cannot be concantenated. If a Unix compress stream is
encountered in an input file, it is the last stream in that file.
Like gunzip and uncompress, the file attributes of the orignal compressed
file are maintained in the final uncompressed file, to the extent that the
user permissions allow it.
On my Mac OS X PowerPC G4, gun is almost twice as fast as gunzip (version
1.2.4) is on the same file, when gun is linked with zlib 1.2.2. Also the
LZW decompression provided by gun is about twice as fast as the standard
Unix uncompress command.
*/
/* external functions and related types and constants */
#include <stdio.h> /* fprintf() */
#include <stdlib.h> /* malloc(), free() */
#include <string.h> /* strerror(), strcmp(), strlen(), memcpy() */
#include <errno.h> /* errno */
#include <fcntl.h> /* open() */
#include <unistd.h> /* read(), write(), close(), chown(), unlink() */
#include <sys/types.h>
#include <sys/stat.h> /* stat(), chmod() */
#include <utime.h> /* utime() */
#include "zlib.h" /* inflateBackInit(), inflateBack(), */
/* inflateBackEnd(), crc32() */
/* function declaration */
#define local static
/* buffer constants */
#define SIZE 32768U /* input and output buffer sizes */
#define PIECE 16384 /* limits i/o chunks for 16-bit int case */
/* structure for infback() to pass to input function in() -- it maintains the
input file and a buffer of size SIZE */
struct ind {
int infile;
unsigned char *inbuf;
};
/* Load input buffer, assumed to be empty, and return bytes loaded and a
pointer to them. read() is called until the buffer is full, or until it
returns end-of-file or error. Return 0 on error. */
local unsigned in(void *in_desc, z_const unsigned char **buf)
{
int ret;
unsigned len;
unsigned char *next;
struct ind *me = (struct ind *)in_desc;
next = me->inbuf;
*buf = next;
len = 0;
do {
ret = PIECE;
if ((unsigned)ret > SIZE - len)
ret = (int)(SIZE - len);
ret = (int)read(me->infile, next, ret);
if (ret == -1) {
len = 0;
break;
}
next += ret;
len += ret;
} while (ret != 0 && len < SIZE);
return len;
}
/* structure for infback() to pass to output function out() -- it maintains the
output file, a running CRC-32 check on the output and the total number of
bytes output, both for checking against the gzip trailer. (The length in
the gzip trailer is stored modulo 2^32, so it's ok if a long is 32 bits and
the output is greater than 4 GB.) */
struct outd {
int outfile;
int check; /* true if checking crc and total */
unsigned long crc;
unsigned long total;
};
/* Write output buffer and update the CRC-32 and total bytes written. write()
is called until all of the output is written or an error is encountered.
On success out() returns 0. For a write failure, out() returns 1. If the
output file descriptor is -1, then nothing is written.
*/
local int out(void *out_desc, unsigned char *buf, unsigned len)
{
int ret;
struct outd *me = (struct outd *)out_desc;
if (me->check) {
me->crc = crc32(me->crc, buf, len);
me->total += len;
}
if (me->outfile != -1)
do {
ret = PIECE;
if ((unsigned)ret > len)
ret = (int)len;
ret = (int)write(me->outfile, buf, ret);
if (ret == -1)
return 1;
buf += ret;
len -= ret;
} while (len != 0);
return 0;
}
/* next input byte macro for use inside lunpipe() and gunpipe() */
#define NEXT() (have ? 0 : (have = in(indp, &next)), \
last = have ? (have--, (int)(*next++)) : -1)
/* memory for gunpipe() and lunpipe() --
the first 256 entries of prefix[] and suffix[] are never used, could
have offset the index, but it's faster to waste the memory */
unsigned char inbuf[SIZE]; /* input buffer */
unsigned char outbuf[SIZE]; /* output buffer */
unsigned short prefix[65536]; /* index to LZW prefix string */
unsigned char suffix[65536]; /* one-character LZW suffix */
unsigned char match[65280 + 2]; /* buffer for reversed match or gzip
32K sliding window */
/* throw out what's left in the current bits byte buffer (this is a vestigial
aspect of the compressed data format derived from an implementation that
made use of a special VAX machine instruction!) */
#define FLUSHCODE() \
do { \
left = 0; \
rem = 0; \
if (chunk > have) { \
chunk -= have; \
have = 0; \
if (NEXT() == -1) \
break; \
chunk--; \
if (chunk > have) { \
chunk = have = 0; \
break; \
} \
} \
have -= chunk; \
next += chunk; \
chunk = 0; \
} while (0)
/* Decompress a compress (LZW) file from indp to outfile. The compress magic
header (two bytes) has already been read and verified. There are have bytes
of buffered input at next. strm is used for passing error information back
to gunpipe().
lunpipe() will return Z_OK on success, Z_BUF_ERROR for an unexpected end of
file, read error, or write error (a write error indicated by strm->next_in
not equal to Z_NULL), or Z_DATA_ERROR for invalid input.
*/
local int lunpipe(unsigned have, z_const unsigned char *next, struct ind *indp,
int outfile, z_stream *strm)
{
int last; /* last byte read by NEXT(), or -1 if EOF */
unsigned chunk; /* bytes left in current chunk */
int left; /* bits left in rem */
unsigned rem; /* unused bits from input */
int bits; /* current bits per code */
unsigned code; /* code, table traversal index */
unsigned mask; /* mask for current bits codes */
int max; /* maximum bits per code for this stream */
unsigned flags; /* compress flags, then block compress flag */
unsigned end; /* last valid entry in prefix/suffix tables */
unsigned temp; /* current code */
unsigned prev; /* previous code */
unsigned final; /* last character written for previous code */
unsigned stack; /* next position for reversed string */
unsigned outcnt; /* bytes in output buffer */
struct outd outd; /* output structure */
unsigned char *p;
/* set up output */
outd.outfile = outfile;
outd.check = 0;
/* process remainder of compress header -- a flags byte */
flags = NEXT();
if (last == -1)
return Z_BUF_ERROR;
if (flags & 0x60) {
strm->msg = (char *)"unknown lzw flags set";
return Z_DATA_ERROR;
}
max = flags & 0x1f;
if (max < 9 || max > 16) {
strm->msg = (char *)"lzw bits out of range";
return Z_DATA_ERROR;
}
if (max == 9) /* 9 doesn't really mean 9 */
max = 10;
flags &= 0x80; /* true if block compress */
/* clear table */
bits = 9;
mask = 0x1ff;
end = flags ? 256 : 255;
/* set up: get first 9-bit code, which is the first decompressed byte, but
don't create a table entry until the next code */
if (NEXT() == -1) /* no compressed data is ok */
return Z_OK;
final = prev = (unsigned)last; /* low 8 bits of code */
if (NEXT() == -1) /* missing a bit */
return Z_BUF_ERROR;
if (last & 1) { /* code must be < 256 */
strm->msg = (char *)"invalid lzw code";
return Z_DATA_ERROR;
}
rem = (unsigned)last >> 1; /* remaining 7 bits */
left = 7;
chunk = bits - 2; /* 7 bytes left in this chunk */
outbuf[0] = (unsigned char)final; /* write first decompressed byte */
outcnt = 1;
/* decode codes */
stack = 0;
for (;;) {
/* if the table will be full after this, increment the code size */
if (end >= mask && bits < max) {
FLUSHCODE();
bits++;
mask <<= 1;
mask++;
}
/* get a code of length bits */
if (chunk == 0) /* decrement chunk modulo bits */
chunk = bits;
code = rem; /* low bits of code */
if (NEXT() == -1) { /* EOF is end of compressed data */
/* write remaining buffered output */
if (outcnt && out(&outd, outbuf, outcnt)) {
strm->next_in = outbuf; /* signal write error */
return Z_BUF_ERROR;
}
return Z_OK;
}
code += (unsigned)last << left; /* middle (or high) bits of code */
left += 8;
chunk--;
if (bits > left) { /* need more bits */
if (NEXT() == -1) /* can't end in middle of code */
return Z_BUF_ERROR;
code += (unsigned)last << left; /* high bits of code */
left += 8;
chunk--;
}
code &= mask; /* mask to current code length */
left -= bits; /* number of unused bits */
rem = (unsigned)last >> (8 - left); /* unused bits from last byte */
/* process clear code (256) */
if (code == 256 && flags) {
FLUSHCODE();
bits = 9; /* initialize bits and mask */
mask = 0x1ff;
end = 255; /* empty table */
continue; /* get next code */
}
/* special code to reuse last match */
temp = code; /* save the current code */
if (code > end) {
/* Be picky on the allowed code here, and make sure that the code
we drop through (prev) will be a valid index so that random
input does not cause an exception. The code != end + 1 check is
empirically derived, and not checked in the original uncompress
code. If this ever causes a problem, that check could be safely
removed. Leaving this check in greatly improves gun's ability
to detect random or corrupted input after a compress header.
In any case, the prev > end check must be retained. */
if (code != end + 1 || prev > end) {
strm->msg = (char *)"invalid lzw code";
return Z_DATA_ERROR;
}
match[stack++] = (unsigned char)final;
code = prev;
}
/* walk through linked list to generate output in reverse order */
p = match + stack;
while (code >= 256) {
*p++ = suffix[code];
code = prefix[code];
}
stack = p - match;
match[stack++] = (unsigned char)code;
final = code;
/* link new table entry */
if (end < mask) {
end++;
prefix[end] = (unsigned short)prev;
suffix[end] = (unsigned char)final;
}
/* set previous code for next iteration */
prev = temp;
/* write output in forward order */
while (stack > SIZE - outcnt) {
while (outcnt < SIZE)
outbuf[outcnt++] = match[--stack];
if (out(&outd, outbuf, outcnt)) {
strm->next_in = outbuf; /* signal write error */
return Z_BUF_ERROR;
}
outcnt = 0;
}
p = match + stack;
do {
outbuf[outcnt++] = *--p;
} while (p > match);
stack = 0;
/* loop for next code with final and prev as the last match, rem and
left provide the first 0..7 bits of the next code, end is the last
valid table entry */
}
}
/* Decompress a gzip file from infile to outfile. strm is assumed to have been
successfully initialized with inflateBackInit(). The input file may consist
of a series of gzip streams, in which case all of them will be decompressed
to the output file. If outfile is -1, then the gzip stream(s) integrity is
checked and nothing is written.
The return value is a zlib error code: Z_MEM_ERROR if out of memory,
Z_DATA_ERROR if the header or the compressed data is invalid, or if the
trailer CRC-32 check or length doesn't match, Z_BUF_ERROR if the input ends
prematurely or a write error occurs, or Z_ERRNO if junk (not a another gzip
stream) follows a valid gzip stream.
*/
local int gunpipe(z_stream *strm, int infile, int outfile)
{
int ret, first, last;
unsigned have, flags, len;
z_const unsigned char *next = NULL;
struct ind ind, *indp;
struct outd outd;
/* setup input buffer */
ind.infile = infile;
ind.inbuf = inbuf;
indp = &ind;
/* decompress concatenated gzip streams */
have = 0; /* no input data read in yet */
first = 1; /* looking for first gzip header */
strm->next_in = Z_NULL; /* so Z_BUF_ERROR means EOF */
for (;;) {
/* look for the two magic header bytes for a gzip stream */
if (NEXT() == -1) {
ret = Z_OK;
break; /* empty gzip stream is ok */
}
if (last != 31 || (NEXT() != 139 && last != 157)) {
strm->msg = (char *)"incorrect header check";
ret = first ? Z_DATA_ERROR : Z_ERRNO;
break; /* not a gzip or compress header */
}
first = 0; /* next non-header is junk */
/* process a compress (LZW) file -- can't be concatenated after this */
if (last == 157) {
ret = lunpipe(have, next, indp, outfile, strm);
break;
}
/* process remainder of gzip header */
ret = Z_BUF_ERROR;
if (NEXT() != 8) { /* only deflate method allowed */
if (last == -1) break;
strm->msg = (char *)"unknown compression method";
ret = Z_DATA_ERROR;
break;
}
flags = NEXT(); /* header flags */
NEXT(); /* discard mod time, xflgs, os */
NEXT();
NEXT();
NEXT();
NEXT();
NEXT();
if (last == -1) break;
if (flags & 0xe0) {
strm->msg = (char *)"unknown header flags set";
ret = Z_DATA_ERROR;
break;
}
if (flags & 4) { /* extra field */
len = NEXT();
len += (unsigned)(NEXT()) << 8;
if (last == -1) break;
while (len > have) {
len -= have;
have = 0;
if (NEXT() == -1) break;
len--;
}
if (last == -1) break;
have -= len;
next += len;
}
if (flags & 8) /* file name */
while (NEXT() != 0 && last != -1)
;
if (flags & 16) /* comment */
while (NEXT() != 0 && last != -1)
;
if (flags & 2) { /* header crc */
NEXT();
NEXT();
}
if (last == -1) break;
/* set up output */
outd.outfile = outfile;
outd.check = 1;
outd.crc = crc32(0L, Z_NULL, 0);
outd.total = 0;
/* decompress data to output */
strm->next_in = next;
strm->avail_in = have;
ret = inflateBack(strm, in, indp, out, &outd);
if (ret != Z_STREAM_END) break;
next = strm->next_in;
have = strm->avail_in;
strm->next_in = Z_NULL; /* so Z_BUF_ERROR means EOF */
/* check trailer */
ret = Z_BUF_ERROR;
if (NEXT() != (int)(outd.crc & 0xff) ||
NEXT() != (int)((outd.crc >> 8) & 0xff) ||
NEXT() != (int)((outd.crc >> 16) & 0xff) ||
NEXT() != (int)((outd.crc >> 24) & 0xff)) {
/* crc error */
if (last != -1) {
strm->msg = (char *)"incorrect data check";
ret = Z_DATA_ERROR;
}
break;
}
if (NEXT() != (int)(outd.total & 0xff) ||
NEXT() != (int)((outd.total >> 8) & 0xff) ||
NEXT() != (int)((outd.total >> 16) & 0xff) ||
NEXT() != (int)((outd.total >> 24) & 0xff)) {
/* length error */
if (last != -1) {
strm->msg = (char *)"incorrect length check";
ret = Z_DATA_ERROR;
}
break;
}
/* go back and look for another gzip stream */
}
/* clean up and return */
return ret;
}
/* Copy file attributes, from -> to, as best we can. This is best effort, so
no errors are reported. The mode bits, including suid, sgid, and the sticky
bit are copied (if allowed), the owner's user id and group id are copied
(again if allowed), and the access and modify times are copied. */
local void copymeta(char *from, char *to)
{
struct stat was;
struct utimbuf when;
/* get all of from's Unix meta data, return if not a regular file */
if (stat(from, &was) != 0 || (was.st_mode & S_IFMT) != S_IFREG)
return;
/* set to's mode bits, ignore errors */
(void)chmod(to, was.st_mode & 07777);
/* copy owner's user and group, ignore errors */
(void)chown(to, was.st_uid, was.st_gid);
/* copy access and modify times, ignore errors */
when.actime = was.st_atime;
when.modtime = was.st_mtime;
(void)utime(to, &when);
}
/* Decompress the file inname to the file outnname, of if test is true, just
decompress without writing and check the gzip trailer for integrity. If
inname is NULL or an empty string, read from stdin. If outname is NULL or
an empty string, write to stdout. strm is a pre-initialized inflateBack
structure. When appropriate, copy the file attributes from inname to
outname.
gunzip() returns 1 if there is an out-of-memory error or an unexpected
return code from gunpipe(). Otherwise it returns 0.
*/
local int gunzip(z_stream *strm, char *inname, char *outname, int test)
{
int ret;
int infile, outfile;
/* open files */
if (inname == NULL || *inname == 0) {
inname = "-";
infile = 0; /* stdin */
}
else {
infile = open(inname, O_RDONLY, 0);
if (infile == -1) {
fprintf(stderr, "gun cannot open %s\n", inname);
return 0;
}
}
if (test)
outfile = -1;
else if (outname == NULL || *outname == 0) {
outname = "-";
outfile = 1; /* stdout */
}
else {
outfile = open(outname, O_CREAT | O_TRUNC | O_WRONLY, 0666);
if (outfile == -1) {
close(infile);
fprintf(stderr, "gun cannot create %s\n", outname);
return 0;
}
}
errno = 0;
/* decompress */
ret = gunpipe(strm, infile, outfile);
if (outfile > 2) close(outfile);
if (infile > 2) close(infile);
/* interpret result */
switch (ret) {
case Z_OK:
case Z_ERRNO:
if (infile > 2 && outfile > 2) {
copymeta(inname, outname); /* copy attributes */
unlink(inname);
}
if (ret == Z_ERRNO)
fprintf(stderr, "gun warning: trailing garbage ignored in %s\n",
inname);
break;
case Z_DATA_ERROR:
if (outfile > 2) unlink(outname);
fprintf(stderr, "gun data error on %s: %s\n", inname, strm->msg);
break;
case Z_MEM_ERROR:
if (outfile > 2) unlink(outname);
fprintf(stderr, "gun out of memory error--aborting\n");
return 1;
case Z_BUF_ERROR:
if (outfile > 2) unlink(outname);
if (strm->next_in != Z_NULL) {
fprintf(stderr, "gun write error on %s: %s\n",
outname, strerror(errno));
}
else if (errno) {
fprintf(stderr, "gun read error on %s: %s\n",
inname, strerror(errno));
}
else {
fprintf(stderr, "gun unexpected end of file on %s\n",
inname);
}
break;
default:
if (outfile > 2) unlink(outname);
fprintf(stderr, "gun internal error--aborting\n");
return 1;
}
return 0;
}
/* Process the gun command line arguments. See the command syntax near the
beginning of this source file. */
int main(int argc, char **argv)
{
int ret, len, test;
char *outname;
unsigned char *window;
z_stream strm;
/* initialize inflateBack state for repeated use */
window = match; /* reuse LZW match buffer */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
ret = inflateBackInit(&strm, 15, window);
if (ret != Z_OK) {
fprintf(stderr, "gun out of memory error--aborting\n");
return 1;
}
/* decompress each file to the same name with the suffix removed */
argc--;
argv++;
test = 0;
if (argc && strcmp(*argv, "-h") == 0) {
fprintf(stderr, "gun 1.6 (17 Jan 2010)\n");
fprintf(stderr, "Copyright (C) 2003-2010 Mark Adler\n");
fprintf(stderr, "usage: gun [-t] [file1.gz [file2.Z ...]]\n");
return 0;
}
if (argc && strcmp(*argv, "-t") == 0) {
test = 1;
argc--;
argv++;
}
if (argc)
do {
if (test)
outname = NULL;
else {
len = (int)strlen(*argv);
if (strcmp(*argv + len - 3, ".gz") == 0 ||
strcmp(*argv + len - 3, "-gz") == 0)
len -= 3;
else if (strcmp(*argv + len - 2, ".z") == 0 ||
strcmp(*argv + len - 2, "-z") == 0 ||
strcmp(*argv + len - 2, "_z") == 0 ||
strcmp(*argv + len - 2, ".Z") == 0)
len -= 2;
else {
fprintf(stderr, "gun error: no gz type on %s--skipping\n",
*argv);
continue;
}
outname = malloc(len + 1);
if (outname == NULL) {
fprintf(stderr, "gun out of memory error--aborting\n");
ret = 1;
break;
}
memcpy(outname, *argv, len);
outname[len] = 0;
}
ret = gunzip(&strm, *argv, outname, test);
if (outname != NULL) free(outname);
if (ret) break;
} while (argv++, --argc);
else
ret = gunzip(&strm, NULL, NULL, test);
/* clean up */
inflateBackEnd(&strm);
return ret;
}

504
external/zlib/examples/gzappend.c vendored Normal file
View File

@@ -0,0 +1,504 @@
/* gzappend -- command to append to a gzip file
Copyright (C) 2003, 2012 Mark Adler, all rights reserved
version 1.2, 11 Oct 2012
This software is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Mark Adler madler@alumni.caltech.edu
*/
/*
* Change history:
*
* 1.0 19 Oct 2003 - First version
* 1.1 4 Nov 2003 - Expand and clarify some comments and notes
* - Add version and copyright to help
* - Send help to stdout instead of stderr
* - Add some preemptive typecasts
* - Add L to constants in lseek() calls
* - Remove some debugging information in error messages
* - Use new data_type definition for zlib 1.2.1
* - Simplfy and unify file operations
* - Finish off gzip file in gztack()
* - Use deflatePrime() instead of adding empty blocks
* - Keep gzip file clean on appended file read errors
* - Use in-place rotate instead of auxiliary buffer
* (Why you ask? Because it was fun to write!)
* 1.2 11 Oct 2012 - Fix for proper z_const usage
* - Check for input buffer malloc failure
*/
/*
gzappend takes a gzip file and appends to it, compressing files from the
command line or data from stdin. The gzip file is written to directly, to
avoid copying that file, in case it's large. Note that this results in the
unfriendly behavior that if gzappend fails, the gzip file is corrupted.
This program was written to illustrate the use of the new Z_BLOCK option of
zlib 1.2.x's inflate() function. This option returns from inflate() at each
block boundary to facilitate locating and modifying the last block bit at
the start of the final deflate block. Also whether using Z_BLOCK or not,
another required feature of zlib 1.2.x is that inflate() now provides the
number of unusued bits in the last input byte used. gzappend will not work
with versions of zlib earlier than 1.2.1.
gzappend first decompresses the gzip file internally, discarding all but
the last 32K of uncompressed data, and noting the location of the last block
bit and the number of unused bits in the last byte of the compressed data.
The gzip trailer containing the CRC-32 and length of the uncompressed data
is verified. This trailer will be later overwritten.
Then the last block bit is cleared by seeking back in the file and rewriting
the byte that contains it. Seeking forward, the last byte of the compressed
data is saved along with the number of unused bits to initialize deflate.
A deflate process is initialized, using the last 32K of the uncompressed
data from the gzip file to initialize the dictionary. If the total
uncompressed data was less than 32K, then all of it is used to initialize
the dictionary. The deflate output bit buffer is also initialized with the
last bits from the original deflate stream. From here on, the data to
append is simply compressed using deflate, and written to the gzip file.
When that is complete, the new CRC-32 and uncompressed length are written
as the trailer of the gzip file.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include "zlib.h"
#define local static
#define LGCHUNK 14
#define CHUNK (1U << LGCHUNK)
#define DSIZE 32768U
/* print an error message and terminate with extreme prejudice */
local void bye(char *msg1, char *msg2)
{
fprintf(stderr, "gzappend error: %s%s\n", msg1, msg2);
exit(1);
}
/* return the greatest common divisor of a and b using Euclid's algorithm,
modified to be fast when one argument much greater than the other, and
coded to avoid unnecessary swapping */
local unsigned gcd(unsigned a, unsigned b)
{
unsigned c;
while (a && b)
if (a > b) {
c = b;
while (a - c >= c)
c <<= 1;
a -= c;
}
else {
c = a;
while (b - c >= c)
c <<= 1;
b -= c;
}
return a + b;
}
/* rotate list[0..len-1] left by rot positions, in place */
local void rotate(unsigned char *list, unsigned len, unsigned rot)
{
unsigned char tmp;
unsigned cycles;
unsigned char *start, *last, *to, *from;
/* normalize rot and handle degenerate cases */
if (len < 2) return;
if (rot >= len) rot %= len;
if (rot == 0) return;
/* pointer to last entry in list */
last = list + (len - 1);
/* do simple left shift by one */
if (rot == 1) {
tmp = *list;
memcpy(list, list + 1, len - 1);
*last = tmp;
return;
}
/* do simple right shift by one */
if (rot == len - 1) {
tmp = *last;
memmove(list + 1, list, len - 1);
*list = tmp;
return;
}
/* otherwise do rotate as a set of cycles in place */
cycles = gcd(len, rot); /* number of cycles */
do {
start = from = list + cycles; /* start index is arbitrary */
tmp = *from; /* save entry to be overwritten */
for (;;) {
to = from; /* next step in cycle */
from += rot; /* go right rot positions */
if (from > last) from -= len; /* (pointer better not wrap) */
if (from == start) break; /* all but one shifted */
*to = *from; /* shift left */
}
*to = tmp; /* complete the circle */
} while (--cycles);
}
/* structure for gzip file read operations */
typedef struct {
int fd; /* file descriptor */
int size; /* 1 << size is bytes in buf */
unsigned left; /* bytes available at next */
unsigned char *buf; /* buffer */
z_const unsigned char *next; /* next byte in buffer */
char *name; /* file name for error messages */
} file;
/* reload buffer */
local int readin(file *in)
{
int len;
len = read(in->fd, in->buf, 1 << in->size);
if (len == -1) bye("error reading ", in->name);
in->left = (unsigned)len;
in->next = in->buf;
return len;
}
/* read from file in, exit if end-of-file */
local int readmore(file *in)
{
if (readin(in) == 0) bye("unexpected end of ", in->name);
return 0;
}
#define read1(in) (in->left == 0 ? readmore(in) : 0, \
in->left--, *(in->next)++)
/* skip over n bytes of in */
local void skip(file *in, unsigned n)
{
unsigned bypass;
if (n > in->left) {
n -= in->left;
bypass = n & ~((1U << in->size) - 1);
if (bypass) {
if (lseek(in->fd, (off_t)bypass, SEEK_CUR) == -1)
bye("seeking ", in->name);
n -= bypass;
}
readmore(in);
if (n > in->left)
bye("unexpected end of ", in->name);
}
in->left -= n;
in->next += n;
}
/* read a four-byte unsigned integer, little-endian, from in */
unsigned long read4(file *in)
{
unsigned long val;
val = read1(in);
val += (unsigned)read1(in) << 8;
val += (unsigned long)read1(in) << 16;
val += (unsigned long)read1(in) << 24;
return val;
}
/* skip over gzip header */
local void gzheader(file *in)
{
int flags;
unsigned n;
if (read1(in) != 31 || read1(in) != 139) bye(in->name, " not a gzip file");
if (read1(in) != 8) bye("unknown compression method in", in->name);
flags = read1(in);
if (flags & 0xe0) bye("unknown header flags set in", in->name);
skip(in, 6);
if (flags & 4) {
n = read1(in);
n += (unsigned)(read1(in)) << 8;
skip(in, n);
}
if (flags & 8) while (read1(in) != 0) ;
if (flags & 16) while (read1(in) != 0) ;
if (flags & 2) skip(in, 2);
}
/* decompress gzip file "name", return strm with a deflate stream ready to
continue compression of the data in the gzip file, and return a file
descriptor pointing to where to write the compressed data -- the deflate
stream is initialized to compress using level "level" */
local int gzscan(char *name, z_stream *strm, int level)
{
int ret, lastbit, left, full;
unsigned have;
unsigned long crc, tot;
unsigned char *window;
off_t lastoff, end;
file gz;
/* open gzip file */
gz.name = name;
gz.fd = open(name, O_RDWR, 0);
if (gz.fd == -1) bye("cannot open ", name);
gz.buf = malloc(CHUNK);
if (gz.buf == NULL) bye("out of memory", "");
gz.size = LGCHUNK;
gz.left = 0;
/* skip gzip header */
gzheader(&gz);
/* prepare to decompress */
window = malloc(DSIZE);
if (window == NULL) bye("out of memory", "");
strm->zalloc = Z_NULL;
strm->zfree = Z_NULL;
strm->opaque = Z_NULL;
ret = inflateInit2(strm, -15);
if (ret != Z_OK) bye("out of memory", " or library mismatch");
/* decompress the deflate stream, saving append information */
lastbit = 0;
lastoff = lseek(gz.fd, 0L, SEEK_CUR) - gz.left;
left = 0;
strm->avail_in = gz.left;
strm->next_in = gz.next;
crc = crc32(0L, Z_NULL, 0);
have = full = 0;
do {
/* if needed, get more input */
if (strm->avail_in == 0) {
readmore(&gz);
strm->avail_in = gz.left;
strm->next_in = gz.next;
}
/* set up output to next available section of sliding window */
strm->avail_out = DSIZE - have;
strm->next_out = window + have;
/* inflate and check for errors */
ret = inflate(strm, Z_BLOCK);
if (ret == Z_STREAM_ERROR) bye("internal stream error!", "");
if (ret == Z_MEM_ERROR) bye("out of memory", "");
if (ret == Z_DATA_ERROR)
bye("invalid compressed data--format violated in", name);
/* update crc and sliding window pointer */
crc = crc32(crc, window + have, DSIZE - have - strm->avail_out);
if (strm->avail_out)
have = DSIZE - strm->avail_out;
else {
have = 0;
full = 1;
}
/* process end of block */
if (strm->data_type & 128) {
if (strm->data_type & 64)
left = strm->data_type & 0x1f;
else {
lastbit = strm->data_type & 0x1f;
lastoff = lseek(gz.fd, 0L, SEEK_CUR) - strm->avail_in;
}
}
} while (ret != Z_STREAM_END);
inflateEnd(strm);
gz.left = strm->avail_in;
gz.next = strm->next_in;
/* save the location of the end of the compressed data */
end = lseek(gz.fd, 0L, SEEK_CUR) - gz.left;
/* check gzip trailer and save total for deflate */
if (crc != read4(&gz))
bye("invalid compressed data--crc mismatch in ", name);
tot = strm->total_out;
if ((tot & 0xffffffffUL) != read4(&gz))
bye("invalid compressed data--length mismatch in", name);
/* if not at end of file, warn */
if (gz.left || readin(&gz))
fprintf(stderr,
"gzappend warning: junk at end of gzip file overwritten\n");
/* clear last block bit */
lseek(gz.fd, lastoff - (lastbit != 0), SEEK_SET);
if (read(gz.fd, gz.buf, 1) != 1) bye("reading after seek on ", name);
*gz.buf = (unsigned char)(*gz.buf ^ (1 << ((8 - lastbit) & 7)));
lseek(gz.fd, -1L, SEEK_CUR);
if (write(gz.fd, gz.buf, 1) != 1) bye("writing after seek to ", name);
/* if window wrapped, build dictionary from window by rotating */
if (full) {
rotate(window, DSIZE, have);
have = DSIZE;
}
/* set up deflate stream with window, crc, total_in, and leftover bits */
ret = deflateInit2(strm, level, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
if (ret != Z_OK) bye("out of memory", "");
deflateSetDictionary(strm, window, have);
strm->adler = crc;
strm->total_in = tot;
if (left) {
lseek(gz.fd, --end, SEEK_SET);
if (read(gz.fd, gz.buf, 1) != 1) bye("reading after seek on ", name);
deflatePrime(strm, 8 - left, *gz.buf);
}
lseek(gz.fd, end, SEEK_SET);
/* clean up and return */
free(window);
free(gz.buf);
return gz.fd;
}
/* append file "name" to gzip file gd using deflate stream strm -- if last
is true, then finish off the deflate stream at the end */
local void gztack(char *name, int gd, z_stream *strm, int last)
{
int fd, len, ret;
unsigned left;
unsigned char *in, *out;
/* open file to compress and append */
fd = 0;
if (name != NULL) {
fd = open(name, O_RDONLY, 0);
if (fd == -1)
fprintf(stderr, "gzappend warning: %s not found, skipping ...\n",
name);
}
/* allocate buffers */
in = malloc(CHUNK);
out = malloc(CHUNK);
if (in == NULL || out == NULL) bye("out of memory", "");
/* compress input file and append to gzip file */
do {
/* get more input */
len = read(fd, in, CHUNK);
if (len == -1) {
fprintf(stderr,
"gzappend warning: error reading %s, skipping rest ...\n",
name);
len = 0;
}
strm->avail_in = (unsigned)len;
strm->next_in = in;
if (len) strm->adler = crc32(strm->adler, in, (unsigned)len);
/* compress and write all available output */
do {
strm->avail_out = CHUNK;
strm->next_out = out;
ret = deflate(strm, last && len == 0 ? Z_FINISH : Z_NO_FLUSH);
left = CHUNK - strm->avail_out;
while (left) {
len = write(gd, out + CHUNK - strm->avail_out - left, left);
if (len == -1) bye("writing gzip file", "");
left -= (unsigned)len;
}
} while (strm->avail_out == 0 && ret != Z_STREAM_END);
} while (len != 0);
/* write trailer after last entry */
if (last) {
deflateEnd(strm);
out[0] = (unsigned char)(strm->adler);
out[1] = (unsigned char)(strm->adler >> 8);
out[2] = (unsigned char)(strm->adler >> 16);
out[3] = (unsigned char)(strm->adler >> 24);
out[4] = (unsigned char)(strm->total_in);
out[5] = (unsigned char)(strm->total_in >> 8);
out[6] = (unsigned char)(strm->total_in >> 16);
out[7] = (unsigned char)(strm->total_in >> 24);
len = 8;
do {
ret = write(gd, out + 8 - len, len);
if (ret == -1) bye("writing gzip file", "");
len -= ret;
} while (len);
close(gd);
}
/* clean up and return */
free(out);
free(in);
if (fd > 0) close(fd);
}
/* process the compression level option if present, scan the gzip file, and
append the specified files, or append the data from stdin if no other file
names are provided on the command line -- the gzip file must be writable
and seekable */
int main(int argc, char **argv)
{
int gd, level;
z_stream strm;
/* ignore command name */
argc--; argv++;
/* provide usage if no arguments */
if (*argv == NULL) {
printf(
"gzappend 1.2 (11 Oct 2012) Copyright (C) 2003, 2012 Mark Adler\n"
);
printf(
"usage: gzappend [-level] file.gz [ addthis [ andthis ... ]]\n");
return 0;
}
/* set compression level */
level = Z_DEFAULT_COMPRESSION;
if (argv[0][0] == '-') {
if (argv[0][1] < '0' || argv[0][1] > '9' || argv[0][2] != 0)
bye("invalid compression level", "");
level = argv[0][1] - '0';
if (*++argv == NULL) bye("no gzip file name after options", "");
}
/* prepare to append to gzip file */
gd = gzscan(*argv++, &strm, level);
/* append files on command line, or from stdin if none */
if (*argv == NULL)
gztack(NULL, gd, &strm, 1);
else
do {
gztack(*argv, gd, &strm, argv[1] == NULL);
} while (*++argv != NULL);
return 0;
}

449
external/zlib/examples/gzjoin.c vendored Normal file
View File

@@ -0,0 +1,449 @@
/* gzjoin -- command to join gzip files into one gzip file
Copyright (C) 2004, 2005, 2012 Mark Adler, all rights reserved
version 1.2, 14 Aug 2012
This software is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Mark Adler madler@alumni.caltech.edu
*/
/*
* Change history:
*
* 1.0 11 Dec 2004 - First version
* 1.1 12 Jun 2005 - Changed ssize_t to long for portability
* 1.2 14 Aug 2012 - Clean up for z_const usage
*/
/*
gzjoin takes one or more gzip files on the command line and writes out a
single gzip file that will uncompress to the concatenation of the
uncompressed data from the individual gzip files. gzjoin does this without
having to recompress any of the data and without having to calculate a new
crc32 for the concatenated uncompressed data. gzjoin does however have to
decompress all of the input data in order to find the bits in the compressed
data that need to be modified to concatenate the streams.
gzjoin does not do an integrity check on the input gzip files other than
checking the gzip header and decompressing the compressed data. They are
otherwise assumed to be complete and correct.
Each joint between gzip files removes at least 18 bytes of previous trailer
and subsequent header, and inserts an average of about three bytes to the
compressed data in order to connect the streams. The output gzip file
has a minimal ten-byte gzip header with no file name or modification time.
This program was written to illustrate the use of the Z_BLOCK option of
inflate() and the crc32_combine() function. gzjoin will not compile with
versions of zlib earlier than 1.2.3.
*/
#include <stdio.h> /* fputs(), fprintf(), fwrite(), putc() */
#include <stdlib.h> /* exit(), malloc(), free() */
#include <fcntl.h> /* open() */
#include <unistd.h> /* close(), read(), lseek() */
#include "zlib.h"
/* crc32(), crc32_combine(), inflateInit2(), inflate(), inflateEnd() */
#define local static
/* exit with an error (return a value to allow use in an expression) */
local int bail(char *why1, char *why2)
{
fprintf(stderr, "gzjoin error: %s%s, output incomplete\n", why1, why2);
exit(1);
return 0;
}
/* -- simple buffered file input with access to the buffer -- */
#define CHUNK 32768 /* must be a power of two and fit in unsigned */
/* bin buffered input file type */
typedef struct {
char *name; /* name of file for error messages */
int fd; /* file descriptor */
unsigned left; /* bytes remaining at next */
unsigned char *next; /* next byte to read */
unsigned char *buf; /* allocated buffer of length CHUNK */
} bin;
/* close a buffered file and free allocated memory */
local void bclose(bin *in)
{
if (in != NULL) {
if (in->fd != -1)
close(in->fd);
if (in->buf != NULL)
free(in->buf);
free(in);
}
}
/* open a buffered file for input, return a pointer to type bin, or NULL on
failure */
local bin *bopen(char *name)
{
bin *in;
in = malloc(sizeof(bin));
if (in == NULL)
return NULL;
in->buf = malloc(CHUNK);
in->fd = open(name, O_RDONLY, 0);
if (in->buf == NULL || in->fd == -1) {
bclose(in);
return NULL;
}
in->left = 0;
in->next = in->buf;
in->name = name;
return in;
}
/* load buffer from file, return -1 on read error, 0 or 1 on success, with
1 indicating that end-of-file was reached */
local int bload(bin *in)
{
long len;
if (in == NULL)
return -1;
if (in->left != 0)
return 0;
in->next = in->buf;
do {
len = (long)read(in->fd, in->buf + in->left, CHUNK - in->left);
if (len < 0)
return -1;
in->left += (unsigned)len;
} while (len != 0 && in->left < CHUNK);
return len == 0 ? 1 : 0;
}
/* get a byte from the file, bail if end of file */
#define bget(in) (in->left ? 0 : bload(in), \
in->left ? (in->left--, *(in->next)++) : \
bail("unexpected end of file on ", in->name))
/* get a four-byte little-endian unsigned integer from file */
local unsigned long bget4(bin *in)
{
unsigned long val;
val = bget(in);
val += (unsigned long)(bget(in)) << 8;
val += (unsigned long)(bget(in)) << 16;
val += (unsigned long)(bget(in)) << 24;
return val;
}
/* skip bytes in file */
local void bskip(bin *in, unsigned skip)
{
/* check pointer */
if (in == NULL)
return;
/* easy case -- skip bytes in buffer */
if (skip <= in->left) {
in->left -= skip;
in->next += skip;
return;
}
/* skip what's in buffer, discard buffer contents */
skip -= in->left;
in->left = 0;
/* seek past multiples of CHUNK bytes */
if (skip > CHUNK) {
unsigned left;
left = skip & (CHUNK - 1);
if (left == 0) {
/* exact number of chunks: seek all the way minus one byte to check
for end-of-file with a read */
lseek(in->fd, skip - 1, SEEK_CUR);
if (read(in->fd, in->buf, 1) != 1)
bail("unexpected end of file on ", in->name);
return;
}
/* skip the integral chunks, update skip with remainder */
lseek(in->fd, skip - left, SEEK_CUR);
skip = left;
}
/* read more input and skip remainder */
bload(in);
if (skip > in->left)
bail("unexpected end of file on ", in->name);
in->left -= skip;
in->next += skip;
}
/* -- end of buffered input functions -- */
/* skip the gzip header from file in */
local void gzhead(bin *in)
{
int flags;
/* verify gzip magic header and compression method */
if (bget(in) != 0x1f || bget(in) != 0x8b || bget(in) != 8)
bail(in->name, " is not a valid gzip file");
/* get and verify flags */
flags = bget(in);
if ((flags & 0xe0) != 0)
bail("unknown reserved bits set in ", in->name);
/* skip modification time, extra flags, and os */
bskip(in, 6);
/* skip extra field if present */
if (flags & 4) {
unsigned len;
len = bget(in);
len += (unsigned)(bget(in)) << 8;
bskip(in, len);
}
/* skip file name if present */
if (flags & 8)
while (bget(in) != 0)
;
/* skip comment if present */
if (flags & 16)
while (bget(in) != 0)
;
/* skip header crc if present */
if (flags & 2)
bskip(in, 2);
}
/* write a four-byte little-endian unsigned integer to out */
local void put4(unsigned long val, FILE *out)
{
putc(val & 0xff, out);
putc((val >> 8) & 0xff, out);
putc((val >> 16) & 0xff, out);
putc((val >> 24) & 0xff, out);
}
/* Load up zlib stream from buffered input, bail if end of file */
local void zpull(z_streamp strm, bin *in)
{
if (in->left == 0)
bload(in);
if (in->left == 0)
bail("unexpected end of file on ", in->name);
strm->avail_in = in->left;
strm->next_in = in->next;
}
/* Write header for gzip file to out and initialize trailer. */
local void gzinit(unsigned long *crc, unsigned long *tot, FILE *out)
{
fwrite("\x1f\x8b\x08\0\0\0\0\0\0\xff", 1, 10, out);
*crc = crc32(0L, Z_NULL, 0);
*tot = 0;
}
/* Copy the compressed data from name, zeroing the last block bit of the last
block if clr is true, and adding empty blocks as needed to get to a byte
boundary. If clr is false, then the last block becomes the last block of
the output, and the gzip trailer is written. crc and tot maintains the
crc and length (modulo 2^32) of the output for the trailer. The resulting
gzip file is written to out. gzinit() must be called before the first call
of gzcopy() to write the gzip header and to initialize crc and tot. */
local void gzcopy(char *name, int clr, unsigned long *crc, unsigned long *tot,
FILE *out)
{
int ret; /* return value from zlib functions */
int pos; /* where the "last block" bit is in byte */
int last; /* true if processing the last block */
bin *in; /* buffered input file */
unsigned char *start; /* start of compressed data in buffer */
unsigned char *junk; /* buffer for uncompressed data -- discarded */
z_off_t len; /* length of uncompressed data (support > 4 GB) */
z_stream strm; /* zlib inflate stream */
/* open gzip file and skip header */
in = bopen(name);
if (in == NULL)
bail("could not open ", name);
gzhead(in);
/* allocate buffer for uncompressed data and initialize raw inflate
stream */
junk = malloc(CHUNK);
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit2(&strm, -15);
if (junk == NULL || ret != Z_OK)
bail("out of memory", "");
/* inflate and copy compressed data, clear last-block bit if requested */
len = 0;
zpull(&strm, in);
start = in->next;
last = start[0] & 1;
if (last && clr)
start[0] &= ~1;
strm.avail_out = 0;
for (;;) {
/* if input used and output done, write used input and get more */
if (strm.avail_in == 0 && strm.avail_out != 0) {
fwrite(start, 1, strm.next_in - start, out);
start = in->buf;
in->left = 0;
zpull(&strm, in);
}
/* decompress -- return early when end-of-block reached */
strm.avail_out = CHUNK;
strm.next_out = junk;
ret = inflate(&strm, Z_BLOCK);
switch (ret) {
case Z_MEM_ERROR:
bail("out of memory", "");
case Z_DATA_ERROR:
bail("invalid compressed data in ", in->name);
}
/* update length of uncompressed data */
len += CHUNK - strm.avail_out;
/* check for block boundary (only get this when block copied out) */
if (strm.data_type & 128) {
/* if that was the last block, then done */
if (last)
break;
/* number of unused bits in last byte */
pos = strm.data_type & 7;
/* find the next last-block bit */
if (pos != 0) {
/* next last-block bit is in last used byte */
pos = 0x100 >> pos;
last = strm.next_in[-1] & pos;
if (last && clr)
in->buf[strm.next_in - in->buf - 1] &= ~pos;
}
else {
/* next last-block bit is in next unused byte */
if (strm.avail_in == 0) {
/* don't have that byte yet -- get it */
fwrite(start, 1, strm.next_in - start, out);
start = in->buf;
in->left = 0;
zpull(&strm, in);
}
last = strm.next_in[0] & 1;
if (last && clr)
in->buf[strm.next_in - in->buf] &= ~1;
}
}
}
/* update buffer with unused input */
in->left = strm.avail_in;
in->next = in->buf + (strm.next_in - in->buf);
/* copy used input, write empty blocks to get to byte boundary */
pos = strm.data_type & 7;
fwrite(start, 1, in->next - start - 1, out);
last = in->next[-1];
if (pos == 0 || !clr)
/* already at byte boundary, or last file: write last byte */
putc(last, out);
else {
/* append empty blocks to last byte */
last &= ((0x100 >> pos) - 1); /* assure unused bits are zero */
if (pos & 1) {
/* odd -- append an empty stored block */
putc(last, out);
if (pos == 1)
putc(0, out); /* two more bits in block header */
fwrite("\0\0\xff\xff", 1, 4, out);
}
else {
/* even -- append 1, 2, or 3 empty fixed blocks */
switch (pos) {
case 6:
putc(last | 8, out);
last = 0;
case 4:
putc(last | 0x20, out);
last = 0;
case 2:
putc(last | 0x80, out);
putc(0, out);
}
}
}
/* update crc and tot */
*crc = crc32_combine(*crc, bget4(in), len);
*tot += (unsigned long)len;
/* clean up */
inflateEnd(&strm);
free(junk);
bclose(in);
/* write trailer if this is the last gzip file */
if (!clr) {
put4(*crc, out);
put4(*tot, out);
}
}
/* join the gzip files on the command line, write result to stdout */
int main(int argc, char **argv)
{
unsigned long crc, tot; /* running crc and total uncompressed length */
/* skip command name */
argc--;
argv++;
/* show usage if no arguments */
if (argc == 0) {
fputs("gzjoin usage: gzjoin f1.gz [f2.gz [f3.gz ...]] > fjoin.gz\n",
stderr);
return 0;
}
/* join gzip files on command line and write to stdout */
gzinit(&crc, &tot, stdout);
while (argc--)
gzcopy(*argv++, argc, &crc, &tot, stdout);
/* done */
return 0;
}

1059
external/zlib/examples/gzlog.c vendored Normal file

File diff suppressed because it is too large Load Diff

91
external/zlib/examples/gzlog.h vendored Normal file
View File

@@ -0,0 +1,91 @@
/* gzlog.h
Copyright (C) 2004, 2008, 2012 Mark Adler, all rights reserved
version 2.2, 14 Aug 2012
This software is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Mark Adler madler@alumni.caltech.edu
*/
/* Version History:
1.0 26 Nov 2004 First version
2.0 25 Apr 2008 Complete redesign for recovery of interrupted operations
Interface changed slightly in that now path is a prefix
Compression now occurs as needed during gzlog_write()
gzlog_write() now always leaves the log file as valid gzip
2.1 8 Jul 2012 Fix argument checks in gzlog_compress() and gzlog_write()
2.2 14 Aug 2012 Clean up signed comparisons
*/
/*
The gzlog object allows writing short messages to a gzipped log file,
opening the log file locked for small bursts, and then closing it. The log
object works by appending stored (uncompressed) data to the gzip file until
1 MB has been accumulated. At that time, the stored data is compressed, and
replaces the uncompressed data in the file. The log file is truncated to
its new size at that time. After each write operation, the log file is a
valid gzip file that can decompressed to recover what was written.
The gzlog operations can be interupted at any point due to an application or
system crash, and the log file will be recovered the next time the log is
opened with gzlog_open().
*/
#ifndef GZLOG_H
#define GZLOG_H
/* gzlog object type */
typedef void gzlog;
/* Open a gzlog object, creating the log file if it does not exist. Return
NULL on error. Note that gzlog_open() could take a while to complete if it
has to wait to verify that a lock is stale (possibly for five minutes), or
if there is significant contention with other instantiations of this object
when locking the resource. path is the prefix of the file names created by
this object. If path is "foo", then the log file will be "foo.gz", and
other auxiliary files will be created and destroyed during the process:
"foo.dict" for a compression dictionary, "foo.temp" for a temporary (next)
dictionary, "foo.add" for data being added or compressed, "foo.lock" for the
lock file, and "foo.repairs" to log recovery operations performed due to
interrupted gzlog operations. A gzlog_open() followed by a gzlog_close()
will recover a previously interrupted operation, if any. */
gzlog *gzlog_open(char *path);
/* Write to a gzlog object. Return zero on success, -1 if there is a file i/o
error on any of the gzlog files (this should not happen if gzlog_open()
succeeded, unless the device has run out of space or leftover auxiliary
files have permissions or ownership that prevent their use), -2 if there is
a memory allocation failure, or -3 if the log argument is invalid (e.g. if
it was not created by gzlog_open()). This function will write data to the
file uncompressed, until 1 MB has been accumulated, at which time that data
will be compressed. The log file will be a valid gzip file upon successful
return. */
int gzlog_write(gzlog *log, void *data, size_t len);
/* Force compression of any uncompressed data in the log. This should be used
sparingly, if at all. The main application would be when a log file will
not be appended to again. If this is used to compress frequently while
appending, it will both significantly increase the execution time and
reduce the compression ratio. The return codes are the same as for
gzlog_write(). */
int gzlog_compress(gzlog *log);
/* Close a gzlog object. Return zero on success, -3 if the log argument is
invalid. The log object is freed, and so cannot be referenced again. */
int gzlog_close(gzlog *log);
#endif

545
external/zlib/examples/zlib_how.html vendored Normal file
View File

@@ -0,0 +1,545 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>zlib Usage Example</title>
<!-- Copyright (c) 2004, 2005 Mark Adler. -->
</head>
<body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#00A000">
<h2 align="center"> zlib Usage Example </h2>
We often get questions about how the <tt>deflate()</tt> and <tt>inflate()</tt> functions should be used.
Users wonder when they should provide more input, when they should use more output,
what to do with a <tt>Z_BUF_ERROR</tt>, how to make sure the process terminates properly, and
so on. So for those who have read <tt>zlib.h</tt> (a few times), and
would like further edification, below is an annotated example in C of simple routines to compress and decompress
from an input file to an output file using <tt>deflate()</tt> and <tt>inflate()</tt> respectively. The
annotations are interspersed between lines of the code. So please read between the lines.
We hope this helps explain some of the intricacies of <em>zlib</em>.
<p>
Without further adieu, here is the program <a href="zpipe.c"><tt>zpipe.c</tt></a>:
<pre><b>
/* zpipe.c: example of proper use of zlib's inflate() and deflate()
Not copyrighted -- provided to the public domain
Version 1.4 11 December 2005 Mark Adler */
/* Version history:
1.0 30 Oct 2004 First version
1.1 8 Nov 2004 Add void casting for unused return values
Use switch statement for inflate() return values
1.2 9 Nov 2004 Add assertions to document zlib guarantees
1.3 6 Apr 2005 Remove incorrect assertion in inf()
1.4 11 Dec 2005 Add hack to avoid MSDOS end-of-line conversions
Avoid some compiler warnings for input and output buffers
*/
</b></pre><!-- -->
We now include the header files for the required definitions. From
<tt>stdio.h</tt> we use <tt>fopen()</tt>, <tt>fread()</tt>, <tt>fwrite()</tt>,
<tt>feof()</tt>, <tt>ferror()</tt>, and <tt>fclose()</tt> for file i/o, and
<tt>fputs()</tt> for error messages. From <tt>string.h</tt> we use
<tt>strcmp()</tt> for command line argument processing.
From <tt>assert.h</tt> we use the <tt>assert()</tt> macro.
From <tt>zlib.h</tt>
we use the basic compression functions <tt>deflateInit()</tt>,
<tt>deflate()</tt>, and <tt>deflateEnd()</tt>, and the basic decompression
functions <tt>inflateInit()</tt>, <tt>inflate()</tt>, and
<tt>inflateEnd()</tt>.
<pre><b>
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include &lt;assert.h&gt;
#include "zlib.h"
</b></pre><!-- -->
This is an ugly hack required to avoid corruption of the input and output data on
Windows/MS-DOS systems. Without this, those systems would assume that the input and output
files are text, and try to convert the end-of-line characters from one standard to
another. That would corrupt binary data, and in particular would render the compressed data unusable.
This sets the input and output to binary which suppresses the end-of-line conversions.
<tt>SET_BINARY_MODE()</tt> will be used later on <tt>stdin</tt> and <tt>stdout</tt>, at the beginning of <tt>main()</tt>.
<pre><b>
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
# include &lt;fcntl.h&gt;
# include &lt;io.h&gt;
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
#else
# define SET_BINARY_MODE(file)
#endif
</b></pre><!-- -->
<tt>CHUNK</tt> is simply the buffer size for feeding data to and pulling data
from the <em>zlib</em> routines. Larger buffer sizes would be more efficient,
especially for <tt>inflate()</tt>. If the memory is available, buffers sizes
on the order of 128K or 256K bytes should be used.
<pre><b>
#define CHUNK 16384
</b></pre><!-- -->
The <tt>def()</tt> routine compresses data from an input file to an output file. The output data
will be in the <em>zlib</em> format, which is different from the <em>gzip</em> or <em>zip</em>
formats. The <em>zlib</em> format has a very small header of only two bytes to identify it as
a <em>zlib</em> stream and to provide decoding information, and a four-byte trailer with a fast
check value to verify the integrity of the uncompressed data after decoding.
<pre><b>
/* Compress from file source to file dest until EOF on source.
def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_STREAM_ERROR if an invalid compression
level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
version of the library linked do not match, or Z_ERRNO if there is
an error reading or writing the files. */
int def(FILE *source, FILE *dest, int level)
{
</b></pre>
Here are the local variables for <tt>def()</tt>. <tt>ret</tt> will be used for <em>zlib</em>
return codes. <tt>flush</tt> will keep track of the current flushing state for <tt>deflate()</tt>,
which is either no flushing, or flush to completion after the end of the input file is reached.
<tt>have</tt> is the amount of data returned from <tt>deflate()</tt>. The <tt>strm</tt> structure
is used to pass information to and from the <em>zlib</em> routines, and to maintain the
<tt>deflate()</tt> state. <tt>in</tt> and <tt>out</tt> are the input and output buffers for
<tt>deflate()</tt>.
<pre><b>
int ret, flush;
unsigned have;
z_stream strm;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
</b></pre><!-- -->
The first thing we do is to initialize the <em>zlib</em> state for compression using
<tt>deflateInit()</tt>. This must be done before the first use of <tt>deflate()</tt>.
The <tt>zalloc</tt>, <tt>zfree</tt>, and <tt>opaque</tt> fields in the <tt>strm</tt>
structure must be initialized before calling <tt>deflateInit()</tt>. Here they are
set to the <em>zlib</em> constant <tt>Z_NULL</tt> to request that <em>zlib</em> use
the default memory allocation routines. An application may also choose to provide
custom memory allocation routines here. <tt>deflateInit()</tt> will allocate on the
order of 256K bytes for the internal state.
(See <a href="zlib_tech.html"><em>zlib Technical Details</em></a>.)
<p>
<tt>deflateInit()</tt> is called with a pointer to the structure to be initialized and
the compression level, which is an integer in the range of -1 to 9. Lower compression
levels result in faster execution, but less compression. Higher levels result in
greater compression, but slower execution. The <em>zlib</em> constant Z_DEFAULT_COMPRESSION,
equal to -1,
provides a good compromise between compression and speed and is equivalent to level 6.
Level 0 actually does no compression at all, and in fact expands the data slightly to produce
the <em>zlib</em> format (it is not a byte-for-byte copy of the input).
More advanced applications of <em>zlib</em>
may use <tt>deflateInit2()</tt> here instead. Such an application may want to reduce how
much memory will be used, at some price in compression. Or it may need to request a
<em>gzip</em> header and trailer instead of a <em>zlib</em> header and trailer, or raw
encoding with no header or trailer at all.
<p>
We must check the return value of <tt>deflateInit()</tt> against the <em>zlib</em> constant
<tt>Z_OK</tt> to make sure that it was able to
allocate memory for the internal state, and that the provided arguments were valid.
<tt>deflateInit()</tt> will also check that the version of <em>zlib</em> that the <tt>zlib.h</tt>
file came from matches the version of <em>zlib</em> actually linked with the program. This
is especially important for environments in which <em>zlib</em> is a shared library.
<p>
Note that an application can initialize multiple, independent <em>zlib</em> streams, which can
operate in parallel. The state information maintained in the structure allows the <em>zlib</em>
routines to be reentrant.
<pre><b>
/* allocate deflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
ret = deflateInit(&amp;strm, level);
if (ret != Z_OK)
return ret;
</b></pre><!-- -->
With the pleasantries out of the way, now we can get down to business. The outer <tt>do</tt>-loop
reads all of the input file and exits at the bottom of the loop once end-of-file is reached.
This loop contains the only call of <tt>deflate()</tt>. So we must make sure that all of the
input data has been processed and that all of the output data has been generated and consumed
before we fall out of the loop at the bottom.
<pre><b>
/* compress until end of file */
do {
</b></pre>
We start off by reading data from the input file. The number of bytes read is put directly
into <tt>avail_in</tt>, and a pointer to those bytes is put into <tt>next_in</tt>. We also
check to see if end-of-file on the input has been reached. If we are at the end of file, then <tt>flush</tt> is set to the
<em>zlib</em> constant <tt>Z_FINISH</tt>, which is later passed to <tt>deflate()</tt> to
indicate that this is the last chunk of input data to compress. We need to use <tt>feof()</tt>
to check for end-of-file as opposed to seeing if fewer than <tt>CHUNK</tt> bytes have been read. The
reason is that if the input file length is an exact multiple of <tt>CHUNK</tt>, we will miss
the fact that we got to the end-of-file, and not know to tell <tt>deflate()</tt> to finish
up the compressed stream. If we are not yet at the end of the input, then the <em>zlib</em>
constant <tt>Z_NO_FLUSH</tt> will be passed to <tt>deflate</tt> to indicate that we are still
in the middle of the uncompressed data.
<p>
If there is an error in reading from the input file, the process is aborted with
<tt>deflateEnd()</tt> being called to free the allocated <em>zlib</em> state before returning
the error. We wouldn't want a memory leak, now would we? <tt>deflateEnd()</tt> can be called
at any time after the state has been initialized. Once that's done, <tt>deflateInit()</tt> (or
<tt>deflateInit2()</tt>) would have to be called to start a new compression process. There is
no point here in checking the <tt>deflateEnd()</tt> return code. The deallocation can't fail.
<pre><b>
strm.avail_in = fread(in, 1, CHUNK, source);
if (ferror(source)) {
(void)deflateEnd(&amp;strm);
return Z_ERRNO;
}
flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
strm.next_in = in;
</b></pre><!-- -->
The inner <tt>do</tt>-loop passes our chunk of input data to <tt>deflate()</tt>, and then
keeps calling <tt>deflate()</tt> until it is done producing output. Once there is no more
new output, <tt>deflate()</tt> is guaranteed to have consumed all of the input, i.e.,
<tt>avail_in</tt> will be zero.
<pre><b>
/* run deflate() on input until output buffer not full, finish
compression if all of source has been read in */
do {
</b></pre>
Output space is provided to <tt>deflate()</tt> by setting <tt>avail_out</tt> to the number
of available output bytes and <tt>next_out</tt> to a pointer to that space.
<pre><b>
strm.avail_out = CHUNK;
strm.next_out = out;
</b></pre>
Now we call the compression engine itself, <tt>deflate()</tt>. It takes as many of the
<tt>avail_in</tt> bytes at <tt>next_in</tt> as it can process, and writes as many as
<tt>avail_out</tt> bytes to <tt>next_out</tt>. Those counters and pointers are then
updated past the input data consumed and the output data written. It is the amount of
output space available that may limit how much input is consumed.
Hence the inner loop to make sure that
all of the input is consumed by providing more output space each time. Since <tt>avail_in</tt>
and <tt>next_in</tt> are updated by <tt>deflate()</tt>, we don't have to mess with those
between <tt>deflate()</tt> calls until it's all used up.
<p>
The parameters to <tt>deflate()</tt> are a pointer to the <tt>strm</tt> structure containing
the input and output information and the internal compression engine state, and a parameter
indicating whether and how to flush data to the output. Normally <tt>deflate</tt> will consume
several K bytes of input data before producing any output (except for the header), in order
to accumulate statistics on the data for optimum compression. It will then put out a burst of
compressed data, and proceed to consume more input before the next burst. Eventually,
<tt>deflate()</tt>
must be told to terminate the stream, complete the compression with provided input data, and
write out the trailer check value. <tt>deflate()</tt> will continue to compress normally as long
as the flush parameter is <tt>Z_NO_FLUSH</tt>. Once the <tt>Z_FINISH</tt> parameter is provided,
<tt>deflate()</tt> will begin to complete the compressed output stream. However depending on how
much output space is provided, <tt>deflate()</tt> may have to be called several times until it
has provided the complete compressed stream, even after it has consumed all of the input. The flush
parameter must continue to be <tt>Z_FINISH</tt> for those subsequent calls.
<p>
There are other values of the flush parameter that are used in more advanced applications. You can
force <tt>deflate()</tt> to produce a burst of output that encodes all of the input data provided
so far, even if it wouldn't have otherwise, for example to control data latency on a link with
compressed data. You can also ask that <tt>deflate()</tt> do that as well as erase any history up to
that point so that what follows can be decompressed independently, for example for random access
applications. Both requests will degrade compression by an amount depending on how often such
requests are made.
<p>
<tt>deflate()</tt> has a return value that can indicate errors, yet we do not check it here. Why
not? Well, it turns out that <tt>deflate()</tt> can do no wrong here. Let's go through
<tt>deflate()</tt>'s return values and dispense with them one by one. The possible values are
<tt>Z_OK</tt>, <tt>Z_STREAM_END</tt>, <tt>Z_STREAM_ERROR</tt>, or <tt>Z_BUF_ERROR</tt>. <tt>Z_OK</tt>
is, well, ok. <tt>Z_STREAM_END</tt> is also ok and will be returned for the last call of
<tt>deflate()</tt>. This is already guaranteed by calling <tt>deflate()</tt> with <tt>Z_FINISH</tt>
until it has no more output. <tt>Z_STREAM_ERROR</tt> is only possible if the stream is not
initialized properly, but we did initialize it properly. There is no harm in checking for
<tt>Z_STREAM_ERROR</tt> here, for example to check for the possibility that some
other part of the application inadvertently clobbered the memory containing the <em>zlib</em> state.
<tt>Z_BUF_ERROR</tt> will be explained further below, but
suffice it to say that this is simply an indication that <tt>deflate()</tt> could not consume
more input or produce more output. <tt>deflate()</tt> can be called again with more output space
or more available input, which it will be in this code.
<pre><b>
ret = deflate(&amp;strm, flush); /* no bad return value */
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
</b></pre>
Now we compute how much output <tt>deflate()</tt> provided on the last call, which is the
difference between how much space was provided before the call, and how much output space
is still available after the call. Then that data, if any, is written to the output file.
We can then reuse the output buffer for the next call of <tt>deflate()</tt>. Again if there
is a file i/o error, we call <tt>deflateEnd()</tt> before returning to avoid a memory leak.
<pre><b>
have = CHUNK - strm.avail_out;
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
(void)deflateEnd(&amp;strm);
return Z_ERRNO;
}
</b></pre>
The inner <tt>do</tt>-loop is repeated until the last <tt>deflate()</tt> call fails to fill the
provided output buffer. Then we know that <tt>deflate()</tt> has done as much as it can with
the provided input, and that all of that input has been consumed. We can then fall out of this
loop and reuse the input buffer.
<p>
The way we tell that <tt>deflate()</tt> has no more output is by seeing that it did not fill
the output buffer, leaving <tt>avail_out</tt> greater than zero. However suppose that
<tt>deflate()</tt> has no more output, but just so happened to exactly fill the output buffer!
<tt>avail_out</tt> is zero, and we can't tell that <tt>deflate()</tt> has done all it can.
As far as we know, <tt>deflate()</tt>
has more output for us. So we call it again. But now <tt>deflate()</tt> produces no output
at all, and <tt>avail_out</tt> remains unchanged as <tt>CHUNK</tt>. That <tt>deflate()</tt> call
wasn't able to do anything, either consume input or produce output, and so it returns
<tt>Z_BUF_ERROR</tt>. (See, I told you I'd cover this later.) However this is not a problem at
all. Now we finally have the desired indication that <tt>deflate()</tt> is really done,
and so we drop out of the inner loop to provide more input to <tt>deflate()</tt>.
<p>
With <tt>flush</tt> set to <tt>Z_FINISH</tt>, this final set of <tt>deflate()</tt> calls will
complete the output stream. Once that is done, subsequent calls of <tt>deflate()</tt> would return
<tt>Z_STREAM_ERROR</tt> if the flush parameter is not <tt>Z_FINISH</tt>, and do no more processing
until the state is reinitialized.
<p>
Some applications of <em>zlib</em> have two loops that call <tt>deflate()</tt>
instead of the single inner loop we have here. The first loop would call
without flushing and feed all of the data to <tt>deflate()</tt>. The second loop would call
<tt>deflate()</tt> with no more
data and the <tt>Z_FINISH</tt> parameter to complete the process. As you can see from this
example, that can be avoided by simply keeping track of the current flush state.
<pre><b>
} while (strm.avail_out == 0);
assert(strm.avail_in == 0); /* all input will be used */
</b></pre><!-- -->
Now we check to see if we have already processed all of the input file. That information was
saved in the <tt>flush</tt> variable, so we see if that was set to <tt>Z_FINISH</tt>. If so,
then we're done and we fall out of the outer loop. We're guaranteed to get <tt>Z_STREAM_END</tt>
from the last <tt>deflate()</tt> call, since we ran it until the last chunk of input was
consumed and all of the output was generated.
<pre><b>
/* done when last data in file processed */
} while (flush != Z_FINISH);
assert(ret == Z_STREAM_END); /* stream will be complete */
</b></pre><!-- -->
The process is complete, but we still need to deallocate the state to avoid a memory leak
(or rather more like a memory hemorrhage if you didn't do this). Then
finally we can return with a happy return value.
<pre><b>
/* clean up and return */
(void)deflateEnd(&amp;strm);
return Z_OK;
}
</b></pre><!-- -->
Now we do the same thing for decompression in the <tt>inf()</tt> routine. <tt>inf()</tt>
decompresses what is hopefully a valid <em>zlib</em> stream from the input file and writes the
uncompressed data to the output file. Much of the discussion above for <tt>def()</tt>
applies to <tt>inf()</tt> as well, so the discussion here will focus on the differences between
the two.
<pre><b>
/* Decompress from file source to file dest until stream ends or EOF.
inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_DATA_ERROR if the deflate data is
invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
the version of the library linked do not match, or Z_ERRNO if there
is an error reading or writing the files. */
int inf(FILE *source, FILE *dest)
{
</b></pre>
The local variables have the same functionality as they do for <tt>def()</tt>. The
only difference is that there is no <tt>flush</tt> variable, since <tt>inflate()</tt>
can tell from the <em>zlib</em> stream itself when the stream is complete.
<pre><b>
int ret;
unsigned have;
z_stream strm;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
</b></pre><!-- -->
The initialization of the state is the same, except that there is no compression level,
of course, and two more elements of the structure are initialized. <tt>avail_in</tt>
and <tt>next_in</tt> must be initialized before calling <tt>inflateInit()</tt>. This
is because the application has the option to provide the start of the zlib stream in
order for <tt>inflateInit()</tt> to have access to information about the compression
method to aid in memory allocation. In the current implementation of <em>zlib</em>
(up through versions 1.2.x), the method-dependent memory allocations are deferred to the first call of
<tt>inflate()</tt> anyway. However those fields must be initialized since later versions
of <em>zlib</em> that provide more compression methods may take advantage of this interface.
In any case, no decompression is performed by <tt>inflateInit()</tt>, so the
<tt>avail_out</tt> and <tt>next_out</tt> fields do not need to be initialized before calling.
<p>
Here <tt>avail_in</tt> is set to zero and <tt>next_in</tt> is set to <tt>Z_NULL</tt> to
indicate that no input data is being provided.
<pre><b>
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit(&amp;strm);
if (ret != Z_OK)
return ret;
</b></pre><!-- -->
The outer <tt>do</tt>-loop decompresses input until <tt>inflate()</tt> indicates
that it has reached the end of the compressed data and has produced all of the uncompressed
output. This is in contrast to <tt>def()</tt> which processes all of the input file.
If end-of-file is reached before the compressed data self-terminates, then the compressed
data is incomplete and an error is returned.
<pre><b>
/* decompress until deflate stream ends or end of file */
do {
</b></pre>
We read input data and set the <tt>strm</tt> structure accordingly. If we've reached the
end of the input file, then we leave the outer loop and report an error, since the
compressed data is incomplete. Note that we may read more data than is eventually consumed
by <tt>inflate()</tt>, if the input file continues past the <em>zlib</em> stream.
For applications where <em>zlib</em> streams are embedded in other data, this routine would
need to be modified to return the unused data, or at least indicate how much of the input
data was not used, so the application would know where to pick up after the <em>zlib</em> stream.
<pre><b>
strm.avail_in = fread(in, 1, CHUNK, source);
if (ferror(source)) {
(void)inflateEnd(&amp;strm);
return Z_ERRNO;
}
if (strm.avail_in == 0)
break;
strm.next_in = in;
</b></pre><!-- -->
The inner <tt>do</tt>-loop has the same function it did in <tt>def()</tt>, which is to
keep calling <tt>inflate()</tt> until has generated all of the output it can with the
provided input.
<pre><b>
/* run inflate() on input until output buffer not full */
do {
</b></pre>
Just like in <tt>def()</tt>, the same output space is provided for each call of <tt>inflate()</tt>.
<pre><b>
strm.avail_out = CHUNK;
strm.next_out = out;
</b></pre>
Now we run the decompression engine itself. There is no need to adjust the flush parameter, since
the <em>zlib</em> format is self-terminating. The main difference here is that there are
return values that we need to pay attention to. <tt>Z_DATA_ERROR</tt>
indicates that <tt>inflate()</tt> detected an error in the <em>zlib</em> compressed data format,
which means that either the data is not a <em>zlib</em> stream to begin with, or that the data was
corrupted somewhere along the way since it was compressed. The other error to be processed is
<tt>Z_MEM_ERROR</tt>, which can occur since memory allocation is deferred until <tt>inflate()</tt>
needs it, unlike <tt>deflate()</tt>, whose memory is allocated at the start by <tt>deflateInit()</tt>.
<p>
Advanced applications may use
<tt>deflateSetDictionary()</tt> to prime <tt>deflate()</tt> with a set of likely data to improve the
first 32K or so of compression. This is noted in the <em>zlib</em> header, so <tt>inflate()</tt>
requests that that dictionary be provided before it can start to decompress. Without the dictionary,
correct decompression is not possible. For this routine, we have no idea what the dictionary is,
so the <tt>Z_NEED_DICT</tt> indication is converted to a <tt>Z_DATA_ERROR</tt>.
<p>
<tt>inflate()</tt> can also return <tt>Z_STREAM_ERROR</tt>, which should not be possible here,
but could be checked for as noted above for <tt>def()</tt>. <tt>Z_BUF_ERROR</tt> does not need to be
checked for here, for the same reasons noted for <tt>def()</tt>. <tt>Z_STREAM_END</tt> will be
checked for later.
<pre><b>
ret = inflate(&amp;strm, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR; /* and fall through */
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&amp;strm);
return ret;
}
</b></pre>
The output of <tt>inflate()</tt> is handled identically to that of <tt>deflate()</tt>.
<pre><b>
have = CHUNK - strm.avail_out;
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
(void)inflateEnd(&amp;strm);
return Z_ERRNO;
}
</b></pre>
The inner <tt>do</tt>-loop ends when <tt>inflate()</tt> has no more output as indicated
by not filling the output buffer, just as for <tt>deflate()</tt>. In this case, we cannot
assert that <tt>strm.avail_in</tt> will be zero, since the deflate stream may end before the file
does.
<pre><b>
} while (strm.avail_out == 0);
</b></pre><!-- -->
The outer <tt>do</tt>-loop ends when <tt>inflate()</tt> reports that it has reached the
end of the input <em>zlib</em> stream, has completed the decompression and integrity
check, and has provided all of the output. This is indicated by the <tt>inflate()</tt>
return value <tt>Z_STREAM_END</tt>. The inner loop is guaranteed to leave <tt>ret</tt>
equal to <tt>Z_STREAM_END</tt> if the last chunk of the input file read contained the end
of the <em>zlib</em> stream. So if the return value is not <tt>Z_STREAM_END</tt>, the
loop continues to read more input.
<pre><b>
/* done when inflate() says it's done */
} while (ret != Z_STREAM_END);
</b></pre><!-- -->
At this point, decompression successfully completed, or we broke out of the loop due to no
more data being available from the input file. If the last <tt>inflate()</tt> return value
is not <tt>Z_STREAM_END</tt>, then the <em>zlib</em> stream was incomplete and a data error
is returned. Otherwise, we return with a happy return value. Of course, <tt>inflateEnd()</tt>
is called first to avoid a memory leak.
<pre><b>
/* clean up and return */
(void)inflateEnd(&amp;strm);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
</b></pre><!-- -->
That ends the routines that directly use <em>zlib</em>. The following routines make this
a command-line program by running data through the above routines from <tt>stdin</tt> to
<tt>stdout</tt>, and handling any errors reported by <tt>def()</tt> or <tt>inf()</tt>.
<p>
<tt>zerr()</tt> is used to interpret the possible error codes from <tt>def()</tt>
and <tt>inf()</tt>, as detailed in their comments above, and print out an error message.
Note that these are only a subset of the possible return values from <tt>deflate()</tt>
and <tt>inflate()</tt>.
<pre><b>
/* report a zlib or i/o error */
void zerr(int ret)
{
fputs("zpipe: ", stderr);
switch (ret) {
case Z_ERRNO:
if (ferror(stdin))
fputs("error reading stdin\n", stderr);
if (ferror(stdout))
fputs("error writing stdout\n", stderr);
break;
case Z_STREAM_ERROR:
fputs("invalid compression level\n", stderr);
break;
case Z_DATA_ERROR:
fputs("invalid or incomplete deflate data\n", stderr);
break;
case Z_MEM_ERROR:
fputs("out of memory\n", stderr);
break;
case Z_VERSION_ERROR:
fputs("zlib version mismatch!\n", stderr);
}
}
</b></pre><!-- -->
Here is the <tt>main()</tt> routine used to test <tt>def()</tt> and <tt>inf()</tt>. The
<tt>zpipe</tt> command is simply a compression pipe from <tt>stdin</tt> to <tt>stdout</tt>, if
no arguments are given, or it is a decompression pipe if <tt>zpipe -d</tt> is used. If any other
arguments are provided, no compression or decompression is performed. Instead a usage
message is displayed. Examples are <tt>zpipe < foo.txt > foo.txt.z</tt> to compress, and
<tt>zpipe -d < foo.txt.z > foo.txt</tt> to decompress.
<pre><b>
/* compress or decompress from stdin to stdout */
int main(int argc, char **argv)
{
int ret;
/* avoid end-of-line conversions */
SET_BINARY_MODE(stdin);
SET_BINARY_MODE(stdout);
/* do compression if no arguments */
if (argc == 1) {
ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
if (ret != Z_OK)
zerr(ret);
return ret;
}
/* do decompression if -d specified */
else if (argc == 2 &amp;&amp; strcmp(argv[1], "-d") == 0) {
ret = inf(stdin, stdout);
if (ret != Z_OK)
zerr(ret);
return ret;
}
/* otherwise, report usage */
else {
fputs("zpipe usage: zpipe [-d] &lt; source &gt; dest\n", stderr);
return 1;
}
}
</b></pre>
<hr>
<i>Copyright (c) 2004, 2005 by Mark Adler<br>Last modified 11 December 2005</i>
</body>
</html>

205
external/zlib/examples/zpipe.c vendored Normal file
View File

@@ -0,0 +1,205 @@
/* zpipe.c: example of proper use of zlib's inflate() and deflate()
Not copyrighted -- provided to the public domain
Version 1.4 11 December 2005 Mark Adler */
/* Version history:
1.0 30 Oct 2004 First version
1.1 8 Nov 2004 Add void casting for unused return values
Use switch statement for inflate() return values
1.2 9 Nov 2004 Add assertions to document zlib guarantees
1.3 6 Apr 2005 Remove incorrect assertion in inf()
1.4 11 Dec 2005 Add hack to avoid MSDOS end-of-line conversions
Avoid some compiler warnings for input and output buffers
*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "zlib.h"
#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
#define CHUNK 16384
/* Compress from file source to file dest until EOF on source.
def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_STREAM_ERROR if an invalid compression
level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
version of the library linked do not match, or Z_ERRNO if there is
an error reading or writing the files. */
int def(FILE *source, FILE *dest, int level)
{
int ret, flush;
unsigned have;
z_stream strm;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
/* allocate deflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
ret = deflateInit(&strm, level);
if (ret != Z_OK)
return ret;
/* compress until end of file */
do {
strm.avail_in = fread(in, 1, CHUNK, source);
if (ferror(source)) {
(void)deflateEnd(&strm);
return Z_ERRNO;
}
flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
strm.next_in = in;
/* run deflate() on input until output buffer not full, finish
compression if all of source has been read in */
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = deflate(&strm, flush); /* no bad return value */
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
have = CHUNK - strm.avail_out;
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
(void)deflateEnd(&strm);
return Z_ERRNO;
}
} while (strm.avail_out == 0);
assert(strm.avail_in == 0); /* all input will be used */
/* done when last data in file processed */
} while (flush != Z_FINISH);
assert(ret == Z_STREAM_END); /* stream will be complete */
/* clean up and return */
(void)deflateEnd(&strm);
return Z_OK;
}
/* Decompress from file source to file dest until stream ends or EOF.
inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_DATA_ERROR if the deflate data is
invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
the version of the library linked do not match, or Z_ERRNO if there
is an error reading or writing the files. */
int inf(FILE *source, FILE *dest)
{
int ret;
unsigned have;
z_stream strm;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit(&strm);
if (ret != Z_OK)
return ret;
/* decompress until deflate stream ends or end of file */
do {
strm.avail_in = fread(in, 1, CHUNK, source);
if (ferror(source)) {
(void)inflateEnd(&strm);
return Z_ERRNO;
}
if (strm.avail_in == 0)
break;
strm.next_in = in;
/* run inflate() on input until output buffer not full */
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR; /* and fall through */
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
return ret;
}
have = CHUNK - strm.avail_out;
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
(void)inflateEnd(&strm);
return Z_ERRNO;
}
} while (strm.avail_out == 0);
/* done when inflate() says it's done */
} while (ret != Z_STREAM_END);
/* clean up and return */
(void)inflateEnd(&strm);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
/* report a zlib or i/o error */
void zerr(int ret)
{
fputs("zpipe: ", stderr);
switch (ret) {
case Z_ERRNO:
if (ferror(stdin))
fputs("error reading stdin\n", stderr);
if (ferror(stdout))
fputs("error writing stdout\n", stderr);
break;
case Z_STREAM_ERROR:
fputs("invalid compression level\n", stderr);
break;
case Z_DATA_ERROR:
fputs("invalid or incomplete deflate data\n", stderr);
break;
case Z_MEM_ERROR:
fputs("out of memory\n", stderr);
break;
case Z_VERSION_ERROR:
fputs("zlib version mismatch!\n", stderr);
}
}
/* compress or decompress from stdin to stdout */
int main(int argc, char **argv)
{
int ret;
/* avoid end-of-line conversions */
SET_BINARY_MODE(stdin);
SET_BINARY_MODE(stdout);
/* do compression if no arguments */
if (argc == 1) {
ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
if (ret != Z_OK)
zerr(ret);
return ret;
}
/* do decompression if -d specified */
else if (argc == 2 && strcmp(argv[1], "-d") == 0) {
ret = inf(stdin, stdout);
if (ret != Z_OK)
zerr(ret);
return ret;
}
/* otherwise, report usage */
else {
fputs("zpipe usage: zpipe [-d] < source > dest\n", stderr);
return 1;
}
}

409
external/zlib/examples/zran.c vendored Normal file
View File

@@ -0,0 +1,409 @@
/* zran.c -- example of zlib/gzip stream indexing and random access
* Copyright (C) 2005, 2012 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
Version 1.1 29 Sep 2012 Mark Adler */
/* Version History:
1.0 29 May 2005 First version
1.1 29 Sep 2012 Fix memory reallocation error
*/
/* Illustrate the use of Z_BLOCK, inflatePrime(), and inflateSetDictionary()
for random access of a compressed file. A file containing a zlib or gzip
stream is provided on the command line. The compressed stream is decoded in
its entirety, and an index built with access points about every SPAN bytes
in the uncompressed output. The compressed file is left open, and can then
be read randomly, having to decompress on the average SPAN/2 uncompressed
bytes before getting to the desired block of data.
An access point can be created at the start of any deflate block, by saving
the starting file offset and bit of that block, and the 32K bytes of
uncompressed data that precede that block. Also the uncompressed offset of
that block is saved to provide a referece for locating a desired starting
point in the uncompressed stream. build_index() works by decompressing the
input zlib or gzip stream a block at a time, and at the end of each block
deciding if enough uncompressed data has gone by to justify the creation of
a new access point. If so, that point is saved in a data structure that
grows as needed to accommodate the points.
To use the index, an offset in the uncompressed data is provided, for which
the latest accees point at or preceding that offset is located in the index.
The input file is positioned to the specified location in the index, and if
necessary the first few bits of the compressed data is read from the file.
inflate is initialized with those bits and the 32K of uncompressed data, and
the decompression then proceeds until the desired offset in the file is
reached. Then the decompression continues to read the desired uncompressed
data from the file.
Another approach would be to generate the index on demand. In that case,
requests for random access reads from the compressed data would try to use
the index, but if a read far enough past the end of the index is required,
then further index entries would be generated and added.
There is some fair bit of overhead to starting inflation for the random
access, mainly copying the 32K byte dictionary. So if small pieces of the
file are being accessed, it would make sense to implement a cache to hold
some lookahead and avoid many calls to extract() for small lengths.
Another way to build an index would be to use inflateCopy(). That would
not be constrained to have access points at block boundaries, but requires
more memory per access point, and also cannot be saved to file due to the
use of pointers in the state. The approach here allows for storage of the
index in a file.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "zlib.h"
#define local static
#define SPAN 1048576L /* desired distance between access points */
#define WINSIZE 32768U /* sliding window size */
#define CHUNK 16384 /* file input buffer size */
/* access point entry */
struct point {
off_t out; /* corresponding offset in uncompressed data */
off_t in; /* offset in input file of first full byte */
int bits; /* number of bits (1-7) from byte at in - 1, or 0 */
unsigned char window[WINSIZE]; /* preceding 32K of uncompressed data */
};
/* access point list */
struct access {
int have; /* number of list entries filled in */
int size; /* number of list entries allocated */
struct point *list; /* allocated list */
};
/* Deallocate an index built by build_index() */
local void free_index(struct access *index)
{
if (index != NULL) {
free(index->list);
free(index);
}
}
/* Add an entry to the access point list. If out of memory, deallocate the
existing list and return NULL. */
local struct access *addpoint(struct access *index, int bits,
off_t in, off_t out, unsigned left, unsigned char *window)
{
struct point *next;
/* if list is empty, create it (start with eight points) */
if (index == NULL) {
index = malloc(sizeof(struct access));
if (index == NULL) return NULL;
index->list = malloc(sizeof(struct point) << 3);
if (index->list == NULL) {
free(index);
return NULL;
}
index->size = 8;
index->have = 0;
}
/* if list is full, make it bigger */
else if (index->have == index->size) {
index->size <<= 1;
next = realloc(index->list, sizeof(struct point) * index->size);
if (next == NULL) {
free_index(index);
return NULL;
}
index->list = next;
}
/* fill in entry and increment how many we have */
next = index->list + index->have;
next->bits = bits;
next->in = in;
next->out = out;
if (left)
memcpy(next->window, window + WINSIZE - left, left);
if (left < WINSIZE)
memcpy(next->window + left, window, WINSIZE - left);
index->have++;
/* return list, possibly reallocated */
return index;
}
/* Make one entire pass through the compressed stream and build an index, with
access points about every span bytes of uncompressed output -- span is
chosen to balance the speed of random access against the memory requirements
of the list, about 32K bytes per access point. Note that data after the end
of the first zlib or gzip stream in the file is ignored. build_index()
returns the number of access points on success (>= 1), Z_MEM_ERROR for out
of memory, Z_DATA_ERROR for an error in the input file, or Z_ERRNO for a
file read error. On success, *built points to the resulting index. */
local int build_index(FILE *in, off_t span, struct access **built)
{
int ret;
off_t totin, totout; /* our own total counters to avoid 4GB limit */
off_t last; /* totout value of last access point */
struct access *index; /* access points being generated */
z_stream strm;
unsigned char input[CHUNK];
unsigned char window[WINSIZE];
/* initialize inflate */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit2(&strm, 47); /* automatic zlib or gzip decoding */
if (ret != Z_OK)
return ret;
/* inflate the input, maintain a sliding window, and build an index -- this
also validates the integrity of the compressed data using the check
information at the end of the gzip or zlib stream */
totin = totout = last = 0;
index = NULL; /* will be allocated by first addpoint() */
strm.avail_out = 0;
do {
/* get some compressed data from input file */
strm.avail_in = fread(input, 1, CHUNK, in);
if (ferror(in)) {
ret = Z_ERRNO;
goto build_index_error;
}
if (strm.avail_in == 0) {
ret = Z_DATA_ERROR;
goto build_index_error;
}
strm.next_in = input;
/* process all of that, or until end of stream */
do {
/* reset sliding window if necessary */
if (strm.avail_out == 0) {
strm.avail_out = WINSIZE;
strm.next_out = window;
}
/* inflate until out of input, output, or at end of block --
update the total input and output counters */
totin += strm.avail_in;
totout += strm.avail_out;
ret = inflate(&strm, Z_BLOCK); /* return at end of block */
totin -= strm.avail_in;
totout -= strm.avail_out;
if (ret == Z_NEED_DICT)
ret = Z_DATA_ERROR;
if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR)
goto build_index_error;
if (ret == Z_STREAM_END)
break;
/* if at end of block, consider adding an index entry (note that if
data_type indicates an end-of-block, then all of the
uncompressed data from that block has been delivered, and none
of the compressed data after that block has been consumed,
except for up to seven bits) -- the totout == 0 provides an
entry point after the zlib or gzip header, and assures that the
index always has at least one access point; we avoid creating an
access point after the last block by checking bit 6 of data_type
*/
if ((strm.data_type & 128) && !(strm.data_type & 64) &&
(totout == 0 || totout - last > span)) {
index = addpoint(index, strm.data_type & 7, totin,
totout, strm.avail_out, window);
if (index == NULL) {
ret = Z_MEM_ERROR;
goto build_index_error;
}
last = totout;
}
} while (strm.avail_in != 0);
} while (ret != Z_STREAM_END);
/* clean up and return index (release unused entries in list) */
(void)inflateEnd(&strm);
index->list = realloc(index->list, sizeof(struct point) * index->have);
index->size = index->have;
*built = index;
return index->size;
/* return error */
build_index_error:
(void)inflateEnd(&strm);
if (index != NULL)
free_index(index);
return ret;
}
/* Use the index to read len bytes from offset into buf, return bytes read or
negative for error (Z_DATA_ERROR or Z_MEM_ERROR). If data is requested past
the end of the uncompressed data, then extract() will return a value less
than len, indicating how much as actually read into buf. This function
should not return a data error unless the file was modified since the index
was generated. extract() may also return Z_ERRNO if there is an error on
reading or seeking the input file. */
local int extract(FILE *in, struct access *index, off_t offset,
unsigned char *buf, int len)
{
int ret, skip;
z_stream strm;
struct point *here;
unsigned char input[CHUNK];
unsigned char discard[WINSIZE];
/* proceed only if something reasonable to do */
if (len < 0)
return 0;
/* find where in stream to start */
here = index->list;
ret = index->have;
while (--ret && here[1].out <= offset)
here++;
/* initialize file and inflate state to start there */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit2(&strm, -15); /* raw inflate */
if (ret != Z_OK)
return ret;
ret = fseeko(in, here->in - (here->bits ? 1 : 0), SEEK_SET);
if (ret == -1)
goto extract_ret;
if (here->bits) {
ret = getc(in);
if (ret == -1) {
ret = ferror(in) ? Z_ERRNO : Z_DATA_ERROR;
goto extract_ret;
}
(void)inflatePrime(&strm, here->bits, ret >> (8 - here->bits));
}
(void)inflateSetDictionary(&strm, here->window, WINSIZE);
/* skip uncompressed bytes until offset reached, then satisfy request */
offset -= here->out;
strm.avail_in = 0;
skip = 1; /* while skipping to offset */
do {
/* define where to put uncompressed data, and how much */
if (offset == 0 && skip) { /* at offset now */
strm.avail_out = len;
strm.next_out = buf;
skip = 0; /* only do this once */
}
if (offset > WINSIZE) { /* skip WINSIZE bytes */
strm.avail_out = WINSIZE;
strm.next_out = discard;
offset -= WINSIZE;
}
else if (offset != 0) { /* last skip */
strm.avail_out = (unsigned)offset;
strm.next_out = discard;
offset = 0;
}
/* uncompress until avail_out filled, or end of stream */
do {
if (strm.avail_in == 0) {
strm.avail_in = fread(input, 1, CHUNK, in);
if (ferror(in)) {
ret = Z_ERRNO;
goto extract_ret;
}
if (strm.avail_in == 0) {
ret = Z_DATA_ERROR;
goto extract_ret;
}
strm.next_in = input;
}
ret = inflate(&strm, Z_NO_FLUSH); /* normal inflate */
if (ret == Z_NEED_DICT)
ret = Z_DATA_ERROR;
if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR)
goto extract_ret;
if (ret == Z_STREAM_END)
break;
} while (strm.avail_out != 0);
/* if reach end of stream, then don't keep trying to get more */
if (ret == Z_STREAM_END)
break;
/* do until offset reached and requested data read, or stream ends */
} while (skip);
/* compute number of uncompressed bytes read after offset */
ret = skip ? 0 : len - strm.avail_out;
/* clean up and return bytes read or error */
extract_ret:
(void)inflateEnd(&strm);
return ret;
}
/* Demonstrate the use of build_index() and extract() by processing the file
provided on the command line, and the extracting 16K from about 2/3rds of
the way through the uncompressed output, and writing that to stdout. */
int main(int argc, char **argv)
{
int len;
off_t offset;
FILE *in;
struct access *index = NULL;
unsigned char buf[CHUNK];
/* open input file */
if (argc != 2) {
fprintf(stderr, "usage: zran file.gz\n");
return 1;
}
in = fopen(argv[1], "rb");
if (in == NULL) {
fprintf(stderr, "zran: could not open %s for reading\n", argv[1]);
return 1;
}
/* build index */
len = build_index(in, SPAN, &index);
if (len < 0) {
fclose(in);
switch (len) {
case Z_MEM_ERROR:
fprintf(stderr, "zran: out of memory\n");
break;
case Z_DATA_ERROR:
fprintf(stderr, "zran: compressed data error in %s\n", argv[1]);
break;
case Z_ERRNO:
fprintf(stderr, "zran: read error on %s\n", argv[1]);
break;
default:
fprintf(stderr, "zran: error %d while building index\n", len);
}
return 1;
}
fprintf(stderr, "zran: built index with %d access points\n", len);
/* use index by reading some bytes from an arbitrary offset */
offset = (index->list[index->have - 1].out << 1) / 3;
len = extract(in, index, offset, buf, CHUNK);
if (len < 0)
fprintf(stderr, "zran: extraction failed: %s error\n",
len == Z_MEM_ERROR ? "out of memory" : "input corrupted");
else {
fwrite(buf, 1, len, stdout);
fprintf(stderr, "zran: extracted %d bytes at %llu\n", len, offset);
}
/* clean up and exit */
free_index(index);
fclose(in);
return 0;
}

379
external/zlib/inffast_chunk.c vendored Normal file
View File

@@ -0,0 +1,379 @@
/* inffast_chunk.c -- fast decoding
*
* (C) 1995-2013 Jean-loup Gailly and Mark Adler
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* Jean-loup Gailly Mark Adler
* jloup@gzip.org madler@alumni.caltech.edu
*
* Copyright (C) 1995-2017 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "inftrees.h"
#include "inflate.h"
#include "inffast_chunk.h"
#include "chunkcopy.h"
#ifdef ASMINF
# pragma message("Assembler code may have bugs -- use at your own risk")
#else
/*
Decode literal, length, and distance codes and write out the resulting
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.
Entry assumptions:
state->mode == LEN
strm->avail_in >= INFLATE_FAST_MIN_INPUT (6 or 8 bytes)
strm->avail_out >= INFLATE_FAST_MIN_OUTPUT (258 bytes)
start >= strm->avail_out
state->bits < 8
strm->next_out[0..strm->avail_out] does not overlap with
strm->next_in[0..strm->avail_in]
strm->state->window is allocated with an additional
CHUNKCOPY_CHUNK_SIZE-1 bytes of padding beyond strm->state->wsize
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:
INFLATE_FAST_MIN_INPUT: 6 or 8 bytes
- 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 wide input data reading option reads 64 input bits at a time. Thus,
if strm->avail_in >= 8, then there is enough input to avoid checking for
available input while decoding. Reading consumes the input with:
hold |= read64le(in) << bits;
in += 6;
bits += 48;
reporting 6 bytes of new input because |bits| is 0..15 (2 bytes rounded
up, worst case) and 6 bytes is enough to decode as noted above. At exit,
hold &= (1U << bits) - 1 drops excess input to keep the invariant:
(state->hold >> state->bits) == 0
INFLATE_FAST_MIN_OUTPUT: 258 bytes
- 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
available output space while decoding.
*/
void ZLIB_INTERNAL inflate_fast_chunk_(strm, start)
z_streamp strm;
unsigned start; /* inflate()'s starting value for strm->avail_out */
{
struct inflate_state FAR *state;
z_const unsigned char FAR *in; /* local strm->next_in */
z_const unsigned char FAR *last; /* have enough input while in < last */
unsigned char FAR *out; /* local strm->next_out */
unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
unsigned char FAR *end; /* while out < end, enough space available */
unsigned char FAR *limit; /* safety limit for chunky copies */
#ifdef INFLATE_STRICT
unsigned dmax; /* maximum distance from zlib header */
#endif
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
unsigned wnext; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
inflate_holder_t 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 here; /* 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 */
/* copy state to local variables */
state = (struct inflate_state FAR *)strm->state;
in = strm->next_in;
last = in + (strm->avail_in - (INFLATE_FAST_MIN_INPUT - 1));
out = strm->next_out;
beg = out - (start - strm->avail_out);
end = out + (strm->avail_out - (INFLATE_FAST_MIN_OUTPUT - 1));
limit = out + strm->avail_out;
#ifdef INFLATE_STRICT
dmax = state->dmax;
#endif
wsize = state->wsize;
whave = state->whave;
wnext = (state->wnext == 0 && whave >= wsize) ? wsize : state->wnext;
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;
/* decode literals and length/distances until end-of-block or not enough
input data or output space */
do {
if (bits < 15) {
#ifdef INFLATE_CHUNK_READ_64LE
hold |= read64le(in) << bits;
in += 6;
bits += 48;
#else
hold += (unsigned long)(*in++) << bits;
bits += 8;
hold += (unsigned long)(*in++) << bits;
bits += 8;
#endif
}
here = lcode[hold & lmask];
dolen:
op = (unsigned)(here.bits);
hold >>= op;
bits -= op;
op = (unsigned)(here.op);
if (op == 0) { /* literal */
Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
"inflate: literal '%c'\n" :
"inflate: literal 0x%02x\n", here.val));
*out++ = (unsigned char)(here.val);
}
else if (op & 16) { /* length base */
len = (unsigned)(here.val);
op &= 15; /* number of extra bits */
if (op) {
if (bits < op) {
#ifdef INFLATE_CHUNK_READ_64LE
hold |= read64le(in) << bits;
in += 6;
bits += 48;
#else
hold += (unsigned long)(*in++) << bits;
bits += 8;
#endif
}
len += (unsigned)hold & ((1U << op) - 1);
hold >>= op;
bits -= op;
}
Tracevv((stderr, "inflate: length %u\n", len));
if (bits < 15) {
#ifdef INFLATE_CHUNK_READ_64LE
hold |= read64le(in) << bits;
in += 6;
bits += 48;
#else
hold += (unsigned long)(*in++) << bits;
bits += 8;
hold += (unsigned long)(*in++) << bits;
bits += 8;
#endif
}
here = dcode[hold & dmask];
dodist:
op = (unsigned)(here.bits);
hold >>= op;
bits -= op;
op = (unsigned)(here.op);
if (op & 16) { /* distance base */
dist = (unsigned)(here.val);
op &= 15; /* number of extra bits */
if (bits < op) {
#ifdef INFLATE_CHUNK_READ_64LE
hold |= read64le(in) << bits;
in += 6;
bits += 48;
#else
hold += (unsigned long)(*in++) << bits;
bits += 8;
if (bits < op) {
hold += (unsigned long)(*in++) << bits;
bits += 8;
}
#endif
}
dist += (unsigned)hold & ((1U << op) - 1);
#ifdef INFLATE_STRICT
if (dist > dmax) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD;
break;
}
#endif
hold >>= op;
bits -= op;
Tracevv((stderr, "inflate: distance %u\n", dist));
op = (unsigned)(out - beg); /* max distance in output */
if (dist > op) { /* see if copy from window */
op = dist - op; /* distance back in window */
if (op > whave) {
if (state->sane) {
strm->msg =
(char *)"invalid distance too far back";
state->mode = BAD;
break;
}
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
if (len <= op - whave) {
do {
*out++ = 0;
} while (--len);
continue;
}
len -= op - whave;
do {
*out++ = 0;
} while (--op > whave);
if (op == 0) {
from = out - dist;
do {
*out++ = *from++;
} while (--len);
continue;
}
#endif
}
from = window;
if (wnext >= op) { /* contiguous in window */
from += wnext - op;
}
else { /* wrap around window */
op -= wnext;
from += wsize - op;
if (op < len) { /* some from end of window */
len -= op;
out = chunkcopy_safe(out, from, op, limit);
from = window; /* more from start of window */
op = wnext;
/* This (rare) case can create a situation where
the first chunkcopy below must be checked.
*/
}
}
if (op < len) { /* still need some from output */
out = chunkcopy_safe(out, from, op, limit);
len -= op;
/* When dist is small the amount of data that can be
copied from the window is also small, and progress
towards the dangerous end of the output buffer is
also small. This means that for trivial memsets and
for chunkunroll_relaxed() a safety check is
unnecessary. However, these conditions may not be
entered at all, and in that case it's possible that
the main copy is near the end.
*/
out = chunkunroll_relaxed(out, &dist, &len);
out = chunkcopy_safe_ugly(out, dist, len, limit);
} else {
/* from points to window, so there is no risk of
overlapping pointers requiring memset-like behaviour
*/
out = chunkcopy_safe(out, from, len, limit);
}
}
else {
/* Whole reference is in range of current output. No
range checks are necessary because we start with room
for at least 258 bytes of output, so unroll and roundoff
operations can write beyond `out+len` so long as they
stay within 258 bytes of `out`.
*/
out = chunkcopy_lapped_relaxed(out, dist, len);
}
}
else if ((op & 64) == 0) { /* 2nd level distance code */
here = dcode[here.val + (hold & ((1U << op) - 1))];
goto dodist;
}
else {
strm->msg = (char *)"invalid distance code";
state->mode = BAD;
break;
}
}
else if ((op & 64) == 0) { /* 2nd level length code */
here = lcode[here.val + (hold & ((1U << op) - 1))];
goto dolen;
}
else if (op & 32) { /* end-of-block */
Tracevv((stderr, "inflate: end of block\n"));
state->mode = TYPE;
break;
}
else {
strm->msg = (char *)"invalid literal/length code";
state->mode = BAD;
break;
}
} while (in < last && out < end);
/* return unused bytes (on entry, bits < 8, so in won't go too far back) */
len = bits >> 3;
in -= len;
bits -= len << 3;
hold &= (1U << bits) - 1;
/* update state and return */
strm->next_in = in;
strm->next_out = out;
strm->avail_in = (unsigned)(in < last ?
(INFLATE_FAST_MIN_INPUT - 1) + (last - in) :
(INFLATE_FAST_MIN_INPUT - 1) - (in - last));
strm->avail_out = (unsigned)(out < end ?
(INFLATE_FAST_MIN_OUTPUT - 1) + (end - out) :
(INFLATE_FAST_MIN_OUTPUT - 1) - (out - end));
state->hold = hold;
state->bits = bits;
Assert((state->hold >> state->bits) == 0, "invalid input data state");
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 wnext == 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 */

48
external/zlib/inffast_chunk.h vendored Normal file
View File

@@ -0,0 +1,48 @@
/* inffast_chunk.h -- header to use inffast_chunk.c
*
* (C) 1995-2013 Jean-loup Gailly and Mark Adler
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* Jean-loup Gailly Mark Adler
* jloup@gzip.org madler@alumni.caltech.edu
*
* Copyright (C) 1995-2003, 2010 Mark Adler
* Copyright (C) 2017 ARM, Inc.
* 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.
*/
#include "inffast.h"
/* INFLATE_FAST_MIN_INPUT: the minimum number of input bytes needed so that
we can safely call inflate_fast() with only one up-front bounds check. One
length/distance code pair (15 bits for the length code, 5 bits for length
extra, 15 bits for the distance code, 13 bits for distance extra) requires
reading up to 48 input bits (6 bytes). The wide input data reading option
requires a little endian machine, and reads 64 input bits (8 bytes).
*/
#ifdef INFLATE_CHUNK_READ_64LE
#undef INFLATE_FAST_MIN_INPUT
#define INFLATE_FAST_MIN_INPUT 8
#endif
void ZLIB_INTERNAL inflate_fast_chunk_ OF((z_streamp strm, unsigned start));

867
external/zlib/make_vms.com vendored Normal file
View File

@@ -0,0 +1,867 @@
$! make libz under VMS written by
$! Martin P.J. Zinser
$!
$! In case of problems with the install you might contact me at
$! zinser@zinser.no-ip.info(preferred) or
$! martin.zinser@eurexchange.com (work)
$!
$! Make procedure history for Zlib
$!
$!------------------------------------------------------------------------------
$! Version history
$! 0.01 20060120 First version to receive a number
$! 0.02 20061008 Adapt to new Makefile.in
$! 0.03 20091224 Add support for large file check
$! 0.04 20100110 Add new gzclose, gzlib, gzread, gzwrite
$! 0.05 20100221 Exchange zlibdefs.h by zconf.h.in
$! 0.06 20120111 Fix missing amiss_err, update zconf_h.in, fix new exmples
$! subdir path, update module search in makefile.in
$! 0.07 20120115 Triggered by work done by Alexey Chupahin completly redesigned
$! shared image creation
$! 0.08 20120219 Make it work on VAX again, pre-load missing symbols to shared
$! image
$! 0.09 20120305 SMS. P1 sets builder ("MMK", "MMS", " " (built-in)).
$! "" -> automatic, preference: MMK, MMS, built-in.
$!
$ on error then goto err_exit
$!
$ true = 1
$ false = 0
$ tmpnam = "temp_" + f$getjpi("","pid")
$ tt = tmpnam + ".txt"
$ tc = tmpnam + ".c"
$ th = tmpnam + ".h"
$ define/nolog tconfig 'th'
$ its_decc = false
$ its_vaxc = false
$ its_gnuc = false
$ s_case = False
$!
$! Setup variables holding "config" information
$!
$ Make = "''p1'"
$ name = "Zlib"
$ version = "?.?.?"
$ v_string = "ZLIB_VERSION"
$ v_file = "zlib.h"
$ ccopt = "/include = []"
$ lopts = ""
$ dnsrl = ""
$ aconf_in_file = "zconf.h.in#zconf.h_in#zconf_h.in"
$ conf_check_string = ""
$ linkonly = false
$ optfile = name + ".opt"
$ mapfile = name + ".map"
$ libdefs = ""
$ vax = f$getsyi("HW_MODEL").lt.1024
$ axp = f$getsyi("HW_MODEL").ge.1024 .and. f$getsyi("HW_MODEL").lt.4096
$ ia64 = f$getsyi("HW_MODEL").ge.4096
$!
$! 2012-03-05 SMS.
$! Why is this needed? And if it is needed, why not simply ".not. vax"?
$!
$!!! if axp .or. ia64 then set proc/parse=extended
$!
$ whoami = f$parse(f$environment("Procedure"),,,,"NO_CONCEAL")
$ mydef = F$parse(whoami,,,"DEVICE")
$ mydir = f$parse(whoami,,,"DIRECTORY") - "]["
$ myproc = f$parse(whoami,,,"Name") + f$parse(whoami,,,"type")
$!
$! Check for MMK/MMS
$!
$ if (Make .eqs. "")
$ then
$ If F$Search ("Sys$System:MMS.EXE") .nes. "" Then Make = "MMS"
$ If F$Type (MMK) .eqs. "STRING" Then Make = "MMK"
$ else
$ Make = f$edit( Make, "trim")
$ endif
$!
$ gosub find_version
$!
$ open/write topt tmp.opt
$ open/write optf 'optfile'
$!
$ gosub check_opts
$!
$! Look for the compiler used
$!
$ gosub check_compiler
$ close topt
$ close optf
$!
$ if its_decc
$ then
$ ccopt = "/prefix=all" + ccopt
$ if f$trnlnm("SYS") .eqs. ""
$ then
$ if axp
$ then
$ define sys sys$library:
$ else
$ ccopt = "/decc" + ccopt
$ define sys decc$library_include:
$ endif
$ endif
$!
$! 2012-03-05 SMS.
$! Why /NAMES = AS_IS? Why not simply ".not. vax"? And why not on VAX?
$!
$ if axp .or. ia64
$ then
$ ccopt = ccopt + "/name=as_is/opt=(inline=speed)"
$ s_case = true
$ endif
$ endif
$ if its_vaxc .or. its_gnuc
$ then
$ if f$trnlnm("SYS").eqs."" then define sys sys$library:
$ endif
$!
$! Build a fake configure input header
$!
$ open/write conf_hin config.hin
$ write conf_hin "#undef _LARGEFILE64_SOURCE"
$ close conf_hin
$!
$!
$ i = 0
$FIND_ACONF:
$ fname = f$element(i,"#",aconf_in_file)
$ if fname .eqs. "#" then goto AMISS_ERR
$ if f$search(fname) .eqs. ""
$ then
$ i = i + 1
$ goto find_aconf
$ endif
$ open/read/err=aconf_err aconf_in 'fname'
$ open/write aconf zconf.h
$ACONF_LOOP:
$ read/end_of_file=aconf_exit aconf_in line
$ work = f$edit(line, "compress,trim")
$ if f$extract(0,6,work) .nes. "#undef"
$ then
$ if f$extract(0,12,work) .nes. "#cmakedefine"
$ then
$ write aconf line
$ endif
$ else
$ cdef = f$element(1," ",work)
$ gosub check_config
$ endif
$ goto aconf_loop
$ACONF_EXIT:
$ write aconf ""
$ write aconf "/* VMS specifics added by make_vms.com: */"
$ write aconf "#define VMS 1"
$ write aconf "#include <unistd.h>"
$ write aconf "#include <unixio.h>"
$ write aconf "#ifdef _LARGEFILE"
$ write aconf "# define off64_t __off64_t"
$ write aconf "# define fopen64 fopen"
$ write aconf "# define fseeko64 fseeko"
$ write aconf "# define lseek64 lseek"
$ write aconf "# define ftello64 ftell"
$ write aconf "#endif"
$ write aconf "#if !defined( __VAX) && (__CRTL_VER >= 70312000)"
$ write aconf "# define HAVE_VSNPRINTF"
$ write aconf "#endif"
$ close aconf_in
$ close aconf
$ if f$search("''th'") .nes. "" then delete 'th';*
$! Build the thing plain or with mms
$!
$ write sys$output "Compiling Zlib sources ..."
$ if make.eqs.""
$ then
$ if (f$search( "example.obj;*") .nes. "") then delete example.obj;*
$ if (f$search( "minigzip.obj;*") .nes. "") then delete minigzip.obj;*
$ CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" -
adler32.c zlib.h zconf.h
$ CALL MAKE compress.OBJ "CC ''CCOPT' compress" -
compress.c zlib.h zconf.h
$ CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" -
crc32.c zlib.h zconf.h
$ CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" -
deflate.c deflate.h zutil.h zlib.h zconf.h
$ CALL MAKE gzclose.OBJ "CC ''CCOPT' gzclose" -
gzclose.c zutil.h zlib.h zconf.h
$ CALL MAKE gzlib.OBJ "CC ''CCOPT' gzlib" -
gzlib.c zutil.h zlib.h zconf.h
$ CALL MAKE gzread.OBJ "CC ''CCOPT' gzread" -
gzread.c zutil.h zlib.h zconf.h
$ CALL MAKE gzwrite.OBJ "CC ''CCOPT' gzwrite" -
gzwrite.c zutil.h zlib.h zconf.h
$ CALL MAKE infback.OBJ "CC ''CCOPT' infback" -
infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h
$ CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" -
inffast.c zutil.h zlib.h zconf.h inffast.h
$ CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" -
inflate.c zutil.h zlib.h zconf.h infblock.h
$ CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" -
inftrees.c zutil.h zlib.h zconf.h inftrees.h
$ CALL MAKE trees.OBJ "CC ''CCOPT' trees" -
trees.c deflate.h zutil.h zlib.h zconf.h
$ CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" -
uncompr.c zlib.h zconf.h
$ CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" -
zutil.c zutil.h zlib.h zconf.h
$ write sys$output "Building Zlib ..."
$ CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ
$ write sys$output "Building example..."
$ CALL MAKE example.OBJ "CC ''CCOPT' [.test]example" -
[.test]example.c zlib.h zconf.h
$ call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb
$ write sys$output "Building minigzip..."
$ CALL MAKE minigzip.OBJ "CC ''CCOPT' [.test]minigzip" -
[.test]minigzip.c zlib.h zconf.h
$ call make minigzip.exe -
"LINK minigzip,libz.olb/lib" -
minigzip.obj libz.olb
$ else
$ gosub crea_mms
$ write sys$output "Make ''name' ''version' with ''Make' "
$ 'make'
$ endif
$!
$! Create shareable image
$!
$ gosub crea_olist
$ write sys$output "Creating libzshr.exe"
$ call map_2_shopt 'mapfile' 'optfile'
$ LINK_'lopts'/SHARE=libzshr.exe modules.opt/opt,'optfile'/opt
$ write sys$output "Zlib build completed"
$ delete/nolog tmp.opt;*
$ exit
$AMISS_ERR:
$ write sys$output "No source for config.hin found."
$ write sys$output "Tried any of ''aconf_in_file'"
$ goto err_exit
$CC_ERR:
$ write sys$output "C compiler required to build ''name'"
$ goto err_exit
$ERR_EXIT:
$ set message/facil/ident/sever/text
$ close/nolog optf
$ close/nolog topt
$ close/nolog aconf_in
$ close/nolog aconf
$ close/nolog out
$ close/nolog min
$ close/nolog mod
$ close/nolog h_in
$ write sys$output "Exiting..."
$ exit 2
$!
$!
$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES
$ V = 'F$Verify(0)
$! P1 = What we are trying to make
$! P2 = Command to make it
$! P3 - P8 What it depends on
$
$ If F$Search(P1) .Eqs. "" Then Goto Makeit
$ Time = F$CvTime(F$File(P1,"RDT"))
$arg=3
$Loop:
$ Argument = P'arg
$ If Argument .Eqs. "" Then Goto Exit
$ El=0
$Loop2:
$ File = F$Element(El," ",Argument)
$ If File .Eqs. " " Then Goto Endl
$ AFile = ""
$Loop3:
$ OFile = AFile
$ AFile = F$Search(File)
$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl
$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit
$ Goto Loop3
$NextEL:
$ El = El + 1
$ Goto Loop2
$EndL:
$ arg=arg+1
$ If arg .Le. 8 Then Goto Loop
$ Goto Exit
$
$Makeit:
$ VV=F$VERIFY(0)
$ write sys$output P2
$ 'P2
$ VV='F$Verify(VV)
$Exit:
$ If V Then Set Verify
$ENDSUBROUTINE
$!------------------------------------------------------------------------------
$!
$! Check command line options and set symbols accordingly
$!
$!------------------------------------------------------------------------------
$! Version history
$! 0.01 20041206 First version to receive a number
$! 0.02 20060126 Add new "HELP" target
$ CHECK_OPTS:
$ i = 1
$ OPT_LOOP:
$ if i .lt. 9
$ then
$ cparm = f$edit(p'i',"upcase")
$!
$! Check if parameter actually contains something
$!
$ if f$edit(cparm,"trim") .nes. ""
$ then
$ if cparm .eqs. "DEBUG"
$ then
$ ccopt = ccopt + "/noopt/deb"
$ lopts = lopts + "/deb"
$ endif
$ if f$locate("CCOPT=",cparm) .lt. f$length(cparm)
$ then
$ start = f$locate("=",cparm) + 1
$ len = f$length(cparm) - start
$ ccopt = ccopt + f$extract(start,len,cparm)
$ if f$locate("AS_IS",f$edit(ccopt,"UPCASE")) .lt. f$length(ccopt) -
then s_case = true
$ endif
$ if cparm .eqs. "LINK" then linkonly = true
$ if f$locate("LOPTS=",cparm) .lt. f$length(cparm)
$ then
$ start = f$locate("=",cparm) + 1
$ len = f$length(cparm) - start
$ lopts = lopts + f$extract(start,len,cparm)
$ endif
$ if f$locate("CC=",cparm) .lt. f$length(cparm)
$ then
$ start = f$locate("=",cparm) + 1
$ len = f$length(cparm) - start
$ cc_com = f$extract(start,len,cparm)
if (cc_com .nes. "DECC") .and. -
(cc_com .nes. "VAXC") .and. -
(cc_com .nes. "GNUC")
$ then
$ write sys$output "Unsupported compiler choice ''cc_com' ignored"
$ write sys$output "Use DECC, VAXC, or GNUC instead"
$ else
$ if cc_com .eqs. "DECC" then its_decc = true
$ if cc_com .eqs. "VAXC" then its_vaxc = true
$ if cc_com .eqs. "GNUC" then its_gnuc = true
$ endif
$ endif
$ if f$locate("MAKE=",cparm) .lt. f$length(cparm)
$ then
$ start = f$locate("=",cparm) + 1
$ len = f$length(cparm) - start
$ mmks = f$extract(start,len,cparm)
$ if (mmks .eqs. "MMK") .or. (mmks .eqs. "MMS")
$ then
$ make = mmks
$ else
$ write sys$output "Unsupported make choice ''mmks' ignored"
$ write sys$output "Use MMK or MMS instead"
$ endif
$ endif
$ if cparm .eqs. "HELP" then gosub bhelp
$ endif
$ i = i + 1
$ goto opt_loop
$ endif
$ return
$!------------------------------------------------------------------------------
$!
$! Look for the compiler used
$!
$! Version history
$! 0.01 20040223 First version to receive a number
$! 0.02 20040229 Save/set value of decc$no_rooted_search_lists
$! 0.03 20060202 Extend handling of GNU C
$! 0.04 20090402 Compaq -> hp
$CHECK_COMPILER:
$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc))
$ then
$ its_decc = (f$search("SYS$SYSTEM:DECC$COMPILER.EXE") .nes. "")
$ its_vaxc = .not. its_decc .and. (F$Search("SYS$System:VAXC.Exe") .nes. "")
$ its_gnuc = .not. (its_decc .or. its_vaxc) .and. (f$trnlnm("gnu_cc") .nes. "")
$ endif
$!
$! Exit if no compiler available
$!
$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc))
$ then goto CC_ERR
$ else
$ if its_decc
$ then
$ write sys$output "CC compiler check ... hp C"
$ if f$trnlnm("decc$no_rooted_search_lists") .nes. ""
$ then
$ dnrsl = f$trnlnm("decc$no_rooted_search_lists")
$ endif
$ define/nolog decc$no_rooted_search_lists 1
$ else
$ if its_vaxc then write sys$output "CC compiler check ... VAX C"
$ if its_gnuc
$ then
$ write sys$output "CC compiler check ... GNU C"
$ if f$trnlnm(topt) then write topt "gnu_cc:[000000]gcclib.olb/lib"
$ if f$trnlnm(optf) then write optf "gnu_cc:[000000]gcclib.olb/lib"
$ cc = "gcc"
$ endif
$ if f$trnlnm(topt) then write topt "sys$share:vaxcrtl.exe/share"
$ if f$trnlnm(optf) then write optf "sys$share:vaxcrtl.exe/share"
$ endif
$ endif
$ return
$!------------------------------------------------------------------------------
$!
$! If MMS/MMK are available dump out the descrip.mms if required
$!
$CREA_MMS:
$ write sys$output "Creating descrip.mms..."
$ create descrip.mms
$ open/append out descrip.mms
$ copy sys$input: out
$ deck
# descrip.mms: MMS description file for building zlib on VMS
# written by Martin P.J. Zinser
# <zinser@zinser.no-ip.info or martin.zinser@eurexchange.com>
OBJS = adler32.obj, compress.obj, crc32.obj, gzclose.obj, gzlib.obj\
gzread.obj, gzwrite.obj, uncompr.obj, infback.obj\
deflate.obj, trees.obj, zutil.obj, inflate.obj, \
inftrees.obj, inffast.obj
$ eod
$ write out "CFLAGS=", ccopt
$ write out "LOPTS=", lopts
$ write out "all : example.exe minigzip.exe libz.olb"
$ copy sys$input: out
$ deck
@ write sys$output " Example applications available"
libz.olb : libz.olb($(OBJS))
@ write sys$output " libz available"
example.exe : example.obj libz.olb
link $(LOPTS) example,libz.olb/lib
minigzip.exe : minigzip.obj libz.olb
link $(LOPTS) minigzip,libz.olb/lib
clean :
delete *.obj;*,libz.olb;*,*.opt;*,*.exe;*
# Other dependencies.
adler32.obj : adler32.c zutil.h zlib.h zconf.h
compress.obj : compress.c zlib.h zconf.h
crc32.obj : crc32.c zutil.h zlib.h zconf.h
deflate.obj : deflate.c deflate.h zutil.h zlib.h zconf.h
example.obj : [.test]example.c zlib.h zconf.h
gzclose.obj : gzclose.c zutil.h zlib.h zconf.h
gzlib.obj : gzlib.c zutil.h zlib.h zconf.h
gzread.obj : gzread.c zutil.h zlib.h zconf.h
gzwrite.obj : gzwrite.c zutil.h zlib.h zconf.h
inffast.obj : inffast.c zutil.h zlib.h zconf.h inftrees.h inffast.h
inflate.obj : inflate.c zutil.h zlib.h zconf.h
inftrees.obj : inftrees.c zutil.h zlib.h zconf.h inftrees.h
minigzip.obj : [.test]minigzip.c zlib.h zconf.h
trees.obj : trees.c deflate.h zutil.h zlib.h zconf.h
uncompr.obj : uncompr.c zlib.h zconf.h
zutil.obj : zutil.c zutil.h zlib.h zconf.h
infback.obj : infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h
$ eod
$ close out
$ return
$!------------------------------------------------------------------------------
$!
$! Read list of core library sources from makefile.in and create options
$! needed to build shareable image
$!
$CREA_OLIST:
$ open/read min makefile.in
$ open/write mod modules.opt
$ src_check_list = "OBJZ =#OBJG ="
$MRLOOP:
$ read/end=mrdone min rec
$ i = 0
$SRC_CHECK_LOOP:
$ src_check = f$element(i, "#", src_check_list)
$ i = i+1
$ if src_check .eqs. "#" then goto mrloop
$ if (f$extract(0,6,rec) .nes. src_check) then goto src_check_loop
$ rec = rec - src_check
$ gosub extra_filnam
$ if (f$element(1,"\",rec) .eqs. "\") then goto mrloop
$MRSLOOP:
$ read/end=mrdone min rec
$ gosub extra_filnam
$ if (f$element(1,"\",rec) .nes. "\") then goto mrsloop
$MRDONE:
$ close min
$ close mod
$ return
$!------------------------------------------------------------------------------
$!
$! Take record extracted in crea_olist and split it into single filenames
$!
$EXTRA_FILNAM:
$ myrec = f$edit(rec - "\", "trim,compress")
$ i = 0
$FELOOP:
$ srcfil = f$element(i," ", myrec)
$ if (srcfil .nes. " ")
$ then
$ write mod f$parse(srcfil,,,"NAME"), ".obj"
$ i = i + 1
$ goto feloop
$ endif
$ return
$!------------------------------------------------------------------------------
$!
$! Find current Zlib version number
$!
$FIND_VERSION:
$ open/read h_in 'v_file'
$hloop:
$ read/end=hdone h_in rec
$ rec = f$edit(rec,"TRIM")
$ if (f$extract(0,1,rec) .nes. "#") then goto hloop
$ rec = f$edit(rec - "#", "TRIM")
$ if f$element(0," ",rec) .nes. "define" then goto hloop
$ if f$element(1," ",rec) .eqs. v_string
$ then
$ version = 'f$element(2," ",rec)'
$ goto hdone
$ endif
$ goto hloop
$hdone:
$ close h_in
$ return
$!------------------------------------------------------------------------------
$!
$CHECK_CONFIG:
$!
$ in_ldef = f$locate(cdef,libdefs)
$ if (in_ldef .lt. f$length(libdefs))
$ then
$ write aconf "#define ''cdef' 1"
$ libdefs = f$extract(0,in_ldef,libdefs) + -
f$extract(in_ldef + f$length(cdef) + 1, -
f$length(libdefs) - in_ldef - f$length(cdef) - 1, -
libdefs)
$ else
$ if (f$type('cdef') .eqs. "INTEGER")
$ then
$ write aconf "#define ''cdef' ", 'cdef'
$ else
$ if (f$type('cdef') .eqs. "STRING")
$ then
$ write aconf "#define ''cdef' ", """", '''cdef'', """"
$ else
$ gosub check_cc_def
$ endif
$ endif
$ endif
$ return
$!------------------------------------------------------------------------------
$!
$! Check if this is a define relating to the properties of the C/C++
$! compiler
$!
$ CHECK_CC_DEF:
$ if (cdef .eqs. "_LARGEFILE64_SOURCE")
$ then
$ copy sys$input: 'tc'
$ deck
#include "tconfig"
#define _LARGEFILE
#include <stdio.h>
int main(){
FILE *fp;
fp = fopen("temp.txt","r");
fseeko(fp,1,SEEK_SET);
fclose(fp);
}
$ eod
$ test_inv = false
$ comm_h = false
$ gosub cc_prop_check
$ return
$ endif
$ write aconf "/* ", line, " */"
$ return
$!------------------------------------------------------------------------------
$!
$! Check for properties of C/C++ compiler
$!
$! Version history
$! 0.01 20031020 First version to receive a number
$! 0.02 20031022 Added logic for defines with value
$! 0.03 20040309 Make sure local config file gets not deleted
$! 0.04 20041230 Also write include for configure run
$! 0.05 20050103 Add processing of "comment defines"
$CC_PROP_CHECK:
$ cc_prop = true
$ is_need = false
$ is_need = (f$extract(0,4,cdef) .eqs. "NEED") .or. (test_inv .eq. true)
$ if f$search(th) .eqs. "" then create 'th'
$ set message/nofac/noident/nosever/notext
$ on error then continue
$ cc 'tmpnam'
$ if .not. ($status) then cc_prop = false
$ on error then continue
$! The headers might lie about the capabilities of the RTL
$ link 'tmpnam',tmp.opt/opt
$ if .not. ($status) then cc_prop = false
$ set message/fac/ident/sever/text
$ on error then goto err_exit
$ delete/nolog 'tmpnam'.*;*/exclude='th'
$ if (cc_prop .and. .not. is_need) .or. -
(.not. cc_prop .and. is_need)
$ then
$ write sys$output "Checking for ''cdef'... yes"
$ if f$type('cdef_val'_yes) .nes. ""
$ then
$ if f$type('cdef_val'_yes) .eqs. "INTEGER" -
then call write_config f$fao("#define !AS !UL",cdef,'cdef_val'_yes)
$ if f$type('cdef_val'_yes) .eqs. "STRING" -
then call write_config f$fao("#define !AS !AS",cdef,'cdef_val'_yes)
$ else
$ call write_config f$fao("#define !AS 1",cdef)
$ endif
$ if (cdef .eqs. "HAVE_FSEEKO") .or. (cdef .eqs. "_LARGE_FILES") .or. -
(cdef .eqs. "_LARGEFILE64_SOURCE") then -
call write_config f$string("#define _LARGEFILE 1")
$ else
$ write sys$output "Checking for ''cdef'... no"
$ if (comm_h)
$ then
call write_config f$fao("/* !AS */",line)
$ else
$ if f$type('cdef_val'_no) .nes. ""
$ then
$ if f$type('cdef_val'_no) .eqs. "INTEGER" -
then call write_config f$fao("#define !AS !UL",cdef,'cdef_val'_no)
$ if f$type('cdef_val'_no) .eqs. "STRING" -
then call write_config f$fao("#define !AS !AS",cdef,'cdef_val'_no)
$ else
$ call write_config f$fao("#undef !AS",cdef)
$ endif
$ endif
$ endif
$ return
$!------------------------------------------------------------------------------
$!
$! Check for properties of C/C++ compiler with multiple result values
$!
$! Version history
$! 0.01 20040127 First version
$! 0.02 20050103 Reconcile changes from cc_prop up to version 0.05
$CC_MPROP_CHECK:
$ cc_prop = true
$ i = 1
$ idel = 1
$ MT_LOOP:
$ if f$type(result_'i') .eqs. "STRING"
$ then
$ set message/nofac/noident/nosever/notext
$ on error then continue
$ cc 'tmpnam'_'i'
$ if .not. ($status) then cc_prop = false
$ on error then continue
$! The headers might lie about the capabilities of the RTL
$ link 'tmpnam'_'i',tmp.opt/opt
$ if .not. ($status) then cc_prop = false
$ set message/fac/ident/sever/text
$ on error then goto err_exit
$ delete/nolog 'tmpnam'_'i'.*;*
$ if (cc_prop)
$ then
$ write sys$output "Checking for ''cdef'... ", mdef_'i'
$ if f$type(mdef_'i') .eqs. "INTEGER" -
then call write_config f$fao("#define !AS !UL",cdef,mdef_'i')
$ if f$type('cdef_val'_yes) .eqs. "STRING" -
then call write_config f$fao("#define !AS !AS",cdef,mdef_'i')
$ goto msym_clean
$ else
$ i = i + 1
$ goto mt_loop
$ endif
$ endif
$ write sys$output "Checking for ''cdef'... no"
$ call write_config f$fao("#undef !AS",cdef)
$ MSYM_CLEAN:
$ if (idel .le. msym_max)
$ then
$ delete/sym mdef_'idel'
$ idel = idel + 1
$ goto msym_clean
$ endif
$ return
$!------------------------------------------------------------------------------
$!
$! Write configuration to both permanent and temporary config file
$!
$! Version history
$! 0.01 20031029 First version to receive a number
$!
$WRITE_CONFIG: SUBROUTINE
$ write aconf 'p1'
$ open/append confh 'th'
$ write confh 'p1'
$ close confh
$ENDSUBROUTINE
$!------------------------------------------------------------------------------
$!
$! Analyze the project map file and create the symbol vector for a shareable
$! image from it
$!
$! Version history
$! 0.01 20120128 First version
$! 0.02 20120226 Add pre-load logic
$!
$ MAP_2_SHOPT: Subroutine
$!
$ SAY := "WRITE_ SYS$OUTPUT"
$!
$ IF F$SEARCH("''P1'") .EQS. ""
$ THEN
$ SAY "MAP_2_SHOPT-E-NOSUCHFILE: Error, inputfile ''p1' not available"
$ goto exit_m2s
$ ENDIF
$ IF "''P2'" .EQS. ""
$ THEN
$ SAY "MAP_2_SHOPT: Error, no output file provided"
$ goto exit_m2s
$ ENDIF
$!
$ module1 = "deflate#deflateEnd#deflateInit_#deflateParams#deflateSetDictionary"
$ module2 = "gzclose#gzerror#gzgetc#gzgets#gzopen#gzprintf#gzputc#gzputs#gzread"
$ module3 = "gzseek#gztell#inflate#inflateEnd#inflateInit_#inflateSetDictionary"
$ module4 = "inflateSync#uncompress#zlibVersion#compress"
$ open/read map 'p1
$ if axp .or. ia64
$ then
$ open/write aopt a.opt
$ open/write bopt b.opt
$ write aopt " CASE_SENSITIVE=YES"
$ write bopt "SYMBOL_VECTOR= (-"
$ mod_sym_num = 1
$ MOD_SYM_LOOP:
$ if f$type(module'mod_sym_num') .nes. ""
$ then
$ mod_in = 0
$ MOD_SYM_IN:
$ shared_proc = f$element(mod_in, "#", module'mod_sym_num')
$ if shared_proc .nes. "#"
$ then
$ write aopt f$fao(" symbol_vector=(!AS/!AS=PROCEDURE)",-
f$edit(shared_proc,"upcase"),shared_proc)
$ write bopt f$fao("!AS=PROCEDURE,-",shared_proc)
$ mod_in = mod_in + 1
$ goto mod_sym_in
$ endif
$ mod_sym_num = mod_sym_num + 1
$ goto mod_sym_loop
$ endif
$MAP_LOOP:
$ read/end=map_end map line
$ if (f$locate("{",line).lt. f$length(line)) .or. -
(f$locate("global:", line) .lt. f$length(line))
$ then
$ proc = true
$ goto map_loop
$ endif
$ if f$locate("}",line).lt. f$length(line) then proc = false
$ if f$locate("local:", line) .lt. f$length(line) then proc = false
$ if proc
$ then
$ shared_proc = f$edit(line,"collapse")
$ chop_semi = f$locate(";", shared_proc)
$ if chop_semi .lt. f$length(shared_proc) then -
shared_proc = f$extract(0, chop_semi, shared_proc)
$ write aopt f$fao(" symbol_vector=(!AS/!AS=PROCEDURE)",-
f$edit(shared_proc,"upcase"),shared_proc)
$ write bopt f$fao("!AS=PROCEDURE,-",shared_proc)
$ endif
$ goto map_loop
$MAP_END:
$ close/nolog aopt
$ close/nolog bopt
$ open/append libopt 'p2'
$ open/read aopt a.opt
$ open/read bopt b.opt
$ALOOP:
$ read/end=aloop_end aopt line
$ write libopt line
$ goto aloop
$ALOOP_END:
$ close/nolog aopt
$ sv = ""
$BLOOP:
$ read/end=bloop_end bopt svn
$ if (svn.nes."")
$ then
$ if (sv.nes."") then write libopt sv
$ sv = svn
$ endif
$ goto bloop
$BLOOP_END:
$ write libopt f$extract(0,f$length(sv)-2,sv), "-"
$ write libopt ")"
$ close/nolog bopt
$ delete/nolog/noconf a.opt;*,b.opt;*
$ else
$ if vax
$ then
$ open/append libopt 'p2'
$ mod_sym_num = 1
$ VMOD_SYM_LOOP:
$ if f$type(module'mod_sym_num') .nes. ""
$ then
$ mod_in = 0
$ VMOD_SYM_IN:
$ shared_proc = f$element(mod_in, "#", module'mod_sym_num')
$ if shared_proc .nes. "#"
$ then
$ write libopt f$fao("UNIVERSAL=!AS",-
f$edit(shared_proc,"upcase"))
$ mod_in = mod_in + 1
$ goto vmod_sym_in
$ endif
$ mod_sym_num = mod_sym_num + 1
$ goto vmod_sym_loop
$ endif
$VMAP_LOOP:
$ read/end=vmap_end map line
$ if (f$locate("{",line).lt. f$length(line)) .or. -
(f$locate("global:", line) .lt. f$length(line))
$ then
$ proc = true
$ goto vmap_loop
$ endif
$ if f$locate("}",line).lt. f$length(line) then proc = false
$ if f$locate("local:", line) .lt. f$length(line) then proc = false
$ if proc
$ then
$ shared_proc = f$edit(line,"collapse")
$ chop_semi = f$locate(";", shared_proc)
$ if chop_semi .lt. f$length(shared_proc) then -
shared_proc = f$extract(0, chop_semi, shared_proc)
$ write libopt f$fao("UNIVERSAL=!AS",-
f$edit(shared_proc,"upcase"))
$ endif
$ goto vmap_loop
$VMAP_END:
$ else
$ write sys$output "Unknown Architecture (Not VAX, AXP, or IA64)"
$ write sys$output "No options file created"
$ endif
$ endif
$ EXIT_M2S:
$ close/nolog map
$ close/nolog libopt
$ endsubroutine

115
external/zlib/msdos/Makefile.bor vendored Normal file
View File

@@ -0,0 +1,115 @@
# Makefile for zlib
# Borland C++
# Last updated: 15-Mar-2003
# To use, do "make -fmakefile.bor"
# To compile in small model, set below: MODEL=s
# WARNING: the small model is supported but only for small values of
# MAX_WBITS and MAX_MEM_LEVEL. For example:
# -DMAX_WBITS=11 -DDEF_WBITS=11 -DMAX_MEM_LEVEL=3
# If you wish to reduce the memory requirements (default 256K for big
# objects plus a few K), you can add to the LOC macro below:
# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
# See zconf.h for details about the memory requirements.
# ------------ Turbo C++, Borland C++ ------------
# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added
# to the declaration of LOC here:
LOC = $(LOCAL_ZLIB)
# type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.
CPU_TYP = 0
# memory model: one of s, m, c, l (small, medium, compact, large)
MODEL=l
# replace bcc with tcc for Turbo C++ 1.0, with bcc32 for the 32 bit version
CC=bcc
LD=bcc
AR=tlib
# compiler flags
# replace "-O2" by "-O -G -a -d" for Turbo C++ 1.0
CFLAGS=-O2 -Z -m$(MODEL) $(LOC)
LDFLAGS=-m$(MODEL) -f-
# variables
ZLIB_LIB = zlib_$(MODEL).lib
OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj
OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
# targets
all: $(ZLIB_LIB) example.exe minigzip.exe
.c.obj:
$(CC) -c $(CFLAGS) $*.c
adler32.obj: adler32.c zlib.h zconf.h
compress.obj: compress.c zlib.h zconf.h
crc32.obj: crc32.c zlib.h zconf.h crc32.h
deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
gzread.obj: gzread.c zlib.h zconf.h gzguts.h
gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
inffast.h inffixed.h
inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
inffast.h
inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
inffast.h inffixed.h
inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
uncompr.obj: uncompr.c zlib.h zconf.h
zutil.obj: zutil.c zutil.h zlib.h zconf.h
example.obj: test/example.c zlib.h zconf.h
minigzip.obj: test/minigzip.c zlib.h zconf.h
# the command line is cut to fit in the MS-DOS 128 byte limit:
$(ZLIB_LIB): $(OBJ1) $(OBJ2)
-del $(ZLIB_LIB)
$(AR) $(ZLIB_LIB) $(OBJP1)
$(AR) $(ZLIB_LIB) $(OBJP2)
example.exe: example.obj $(ZLIB_LIB)
$(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
minigzip.exe: minigzip.obj $(ZLIB_LIB)
$(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
test: example.exe minigzip.exe
example
echo hello world | minigzip | minigzip -d
clean:
-del *.obj
-del *.lib
-del *.exe
-del zlib_*.bak
-del foo.gz

104
external/zlib/msdos/Makefile.dj2 vendored Normal file
View File

@@ -0,0 +1,104 @@
# Makefile for zlib. Modified for djgpp v2.0 by F. J. Donahoe, 3/15/96.
# Copyright (C) 1995-1998 Jean-loup Gailly.
# For conditions of distribution and use, see copyright notice in zlib.h
# To compile, or to compile and test, type:
#
# make -fmakefile.dj2; make test -fmakefile.dj2
#
# To install libz.a, zconf.h and zlib.h in the djgpp directories, type:
#
# make install -fmakefile.dj2
#
# after first defining LIBRARY_PATH and INCLUDE_PATH in djgpp.env as
# in the sample below if the pattern of the DJGPP distribution is to
# be followed. Remember that, while <sp>'es around <=> are ignored in
# makefiles, they are *not* in batch files or in djgpp.env.
# - - - - -
# [make]
# INCLUDE_PATH=%\>;INCLUDE_PATH%%\DJDIR%\include
# LIBRARY_PATH=%\>;LIBRARY_PATH%%\DJDIR%\lib
# BUTT=-m486
# - - - - -
# Alternately, these variables may be defined below, overriding the values
# in djgpp.env, as
# INCLUDE_PATH=c:\usr\include
# LIBRARY_PATH=c:\usr\lib
CC=gcc
#CFLAGS=-MMD -O
#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
#CFLAGS=-MMD -g -DDEBUG
CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
-Wstrict-prototypes -Wmissing-prototypes
# If cp.exe is available, replace "copy /Y" with "cp -fp" .
CP=copy /Y
# If gnu install.exe is available, replace $(CP) with ginstall.
INSTALL=$(CP)
# The default value of RM is "rm -f." If "rm.exe" is found, comment out:
RM=del
LDLIBS=-L. -lz
LD=$(CC) -s -o
LDSHARED=$(CC)
INCL=zlib.h zconf.h
LIBS=libz.a
AR=ar rcs
prefix=/usr/local
exec_prefix = $(prefix)
OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \
uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o
OBJA =
# to use the asm code: make OBJA=match.o
TEST_OBJS = example.o minigzip.o
all: example.exe minigzip.exe
check: test
test: all
./example
echo hello world | .\minigzip | .\minigzip -d
%.o : %.c
$(CC) $(CFLAGS) -c $< -o $@
libz.a: $(OBJS) $(OBJA)
$(AR) $@ $(OBJS) $(OBJA)
%.exe : %.o $(LIBS)
$(LD) $@ $< $(LDLIBS)
# INCLUDE_PATH and LIBRARY_PATH were set for [make] in djgpp.env .
.PHONY : uninstall clean
install: $(INCL) $(LIBS)
-@if not exist $(INCLUDE_PATH)\nul mkdir $(INCLUDE_PATH)
-@if not exist $(LIBRARY_PATH)\nul mkdir $(LIBRARY_PATH)
$(INSTALL) zlib.h $(INCLUDE_PATH)
$(INSTALL) zconf.h $(INCLUDE_PATH)
$(INSTALL) libz.a $(LIBRARY_PATH)
uninstall:
$(RM) $(INCLUDE_PATH)\zlib.h
$(RM) $(INCLUDE_PATH)\zconf.h
$(RM) $(LIBRARY_PATH)\libz.a
clean:
$(RM) *.d
$(RM) *.o
$(RM) *.exe
$(RM) libz.a
$(RM) foo.gz
DEPS := $(wildcard *.d)
ifneq ($(DEPS),)
include $(DEPS)
endif

69
external/zlib/msdos/Makefile.emx vendored Normal file
View File

@@ -0,0 +1,69 @@
# Makefile for zlib. Modified for emx 0.9c by Chr. Spieler, 6/17/98.
# Copyright (C) 1995-1998 Jean-loup Gailly.
# For conditions of distribution and use, see copyright notice in zlib.h
# To compile, or to compile and test, type:
#
# make -fmakefile.emx; make test -fmakefile.emx
#
CC=gcc
#CFLAGS=-MMD -O
#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
#CFLAGS=-MMD -g -DDEBUG
CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
-Wstrict-prototypes -Wmissing-prototypes
# If cp.exe is available, replace "copy /Y" with "cp -fp" .
CP=copy /Y
# If gnu install.exe is available, replace $(CP) with ginstall.
INSTALL=$(CP)
# The default value of RM is "rm -f." If "rm.exe" is found, comment out:
RM=del
LDLIBS=-L. -lzlib
LD=$(CC) -s -o
LDSHARED=$(CC)
INCL=zlib.h zconf.h
LIBS=zlib.a
AR=ar rcs
prefix=/usr/local
exec_prefix = $(prefix)
OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \
uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o
TEST_OBJS = example.o minigzip.o
all: example.exe minigzip.exe
test: all
./example
echo hello world | .\minigzip | .\minigzip -d
%.o : %.c
$(CC) $(CFLAGS) -c $< -o $@
zlib.a: $(OBJS)
$(AR) $@ $(OBJS)
%.exe : %.o $(LIBS)
$(LD) $@ $< $(LDLIBS)
.PHONY : clean
clean:
$(RM) *.d
$(RM) *.o
$(RM) *.exe
$(RM) zlib.a
$(RM) foo.gz
DEPS := $(wildcard *.d)
ifneq ($(DEPS),)
include $(DEPS)
endif

112
external/zlib/msdos/Makefile.msc vendored Normal file
View File

@@ -0,0 +1,112 @@
# Makefile for zlib
# Microsoft C 5.1 or later
# Last updated: 19-Mar-2003
# To use, do "make makefile.msc"
# To compile in small model, set below: MODEL=S
# If you wish to reduce the memory requirements (default 256K for big
# objects plus a few K), you can add to the LOC macro below:
# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
# See zconf.h for details about the memory requirements.
# ------------- Microsoft C 5.1 and later -------------
# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added
# to the declaration of LOC here:
LOC = $(LOCAL_ZLIB)
# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.
CPU_TYP = 0
# Memory model: one of S, M, C, L (small, medium, compact, large)
MODEL=L
CC=cl
CFLAGS=-nologo -A$(MODEL) -G$(CPU_TYP) -W3 -Oait -Gs $(LOC)
#-Ox generates bad code with MSC 5.1
LIB_CFLAGS=-Zl $(CFLAGS)
LD=link
LDFLAGS=/noi/e/st:0x1500/noe/farcall/packcode
# "/farcall/packcode" are only useful for `large code' memory models
# but should be a "no-op" for small code models.
# variables
ZLIB_LIB = zlib_$(MODEL).lib
OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
# targets
all: $(ZLIB_LIB) example.exe minigzip.exe
.c.obj:
$(CC) -c $(LIB_CFLAGS) $*.c
adler32.obj: adler32.c zlib.h zconf.h
compress.obj: compress.c zlib.h zconf.h
crc32.obj: crc32.c zlib.h zconf.h crc32.h
deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
gzread.obj: gzread.c zlib.h zconf.h gzguts.h
gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
inffast.h inffixed.h
inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
inffast.h
inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
inffast.h inffixed.h
inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
uncompr.obj: uncompr.c zlib.h zconf.h
zutil.obj: zutil.c zutil.h zlib.h zconf.h
example.obj: test/example.c zlib.h zconf.h
$(CC) -c $(CFLAGS) $*.c
minigzip.obj: test/minigzip.c zlib.h zconf.h
$(CC) -c $(CFLAGS) $*.c
# the command line is cut to fit in the MS-DOS 128 byte limit:
$(ZLIB_LIB): $(OBJ1) $(OBJ2)
if exist $(ZLIB_LIB) del $(ZLIB_LIB)
lib $(ZLIB_LIB) $(OBJ1);
lib $(ZLIB_LIB) $(OBJ2);
example.exe: example.obj $(ZLIB_LIB)
$(LD) $(LDFLAGS) example.obj,,,$(ZLIB_LIB);
minigzip.exe: minigzip.obj $(ZLIB_LIB)
$(LD) $(LDFLAGS) minigzip.obj,,,$(ZLIB_LIB);
test: example.exe minigzip.exe
example
echo hello world | minigzip | minigzip -d
clean:
-del *.obj
-del *.lib
-del *.exe
-del *.map
-del zlib_*.bak
-del foo.gz

100
external/zlib/msdos/Makefile.tc vendored Normal file
View File

@@ -0,0 +1,100 @@
# Makefile for zlib
# Turbo C 2.01, Turbo C++ 1.01
# Last updated: 15-Mar-2003
# To use, do "make -fmakefile.tc"
# To compile in small model, set below: MODEL=s
# WARNING: the small model is supported but only for small values of
# MAX_WBITS and MAX_MEM_LEVEL. For example:
# -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
# If you wish to reduce the memory requirements (default 256K for big
# objects plus a few K), you can add to CFLAGS below:
# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
# See zconf.h for details about the memory requirements.
# ------------ Turbo C 2.01, Turbo C++ 1.01 ------------
MODEL=l
CC=tcc
LD=tcc
AR=tlib
# CFLAGS=-O2 -G -Z -m$(MODEL) -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
CFLAGS=-O2 -G -Z -m$(MODEL)
LDFLAGS=-m$(MODEL) -f-
# variables
ZLIB_LIB = zlib_$(MODEL).lib
OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj
OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
# targets
all: $(ZLIB_LIB) example.exe minigzip.exe
.c.obj:
$(CC) -c $(CFLAGS) $*.c
adler32.obj: adler32.c zlib.h zconf.h
compress.obj: compress.c zlib.h zconf.h
crc32.obj: crc32.c zlib.h zconf.h crc32.h
deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
gzread.obj: gzread.c zlib.h zconf.h gzguts.h
gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
inffast.h inffixed.h
inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
inffast.h
inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
inffast.h inffixed.h
inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
uncompr.obj: uncompr.c zlib.h zconf.h
zutil.obj: zutil.c zutil.h zlib.h zconf.h
example.obj: test/example.c zlib.h zconf.h
minigzip.obj: test/minigzip.c zlib.h zconf.h
# the command line is cut to fit in the MS-DOS 128 byte limit:
$(ZLIB_LIB): $(OBJ1) $(OBJ2)
-del $(ZLIB_LIB)
$(AR) $(ZLIB_LIB) $(OBJP1)
$(AR) $(ZLIB_LIB) $(OBJP2)
example.exe: example.obj $(ZLIB_LIB)
$(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
minigzip.exe: minigzip.obj $(ZLIB_LIB)
$(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
test: example.exe minigzip.exe
example
echo hello world | minigzip | minigzip -d
clean:
-del *.obj
-del *.lib
-del *.exe
-del zlib_*.bak
-del foo.gz

5
external/zlib/nintendods/README vendored Normal file
View File

@@ -0,0 +1,5 @@
This Makefile requires devkitARM (http://www.devkitpro.org/category/devkitarm/) and works inside "contrib/nds". It is based on a devkitARM template.
Eduardo Costa <eduardo.m.costa@gmail.com>
January 3, 2009

69
external/zlib/old/Makefile.emx vendored Normal file
View File

@@ -0,0 +1,69 @@
# Makefile for zlib. Modified for emx/rsxnt by Chr. Spieler, 6/16/98.
# Copyright (C) 1995-1998 Jean-loup Gailly.
# For conditions of distribution and use, see copyright notice in zlib.h
# To compile, or to compile and test, type:
#
# make -fmakefile.emx; make test -fmakefile.emx
#
CC=gcc -Zwin32
#CFLAGS=-MMD -O
#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
#CFLAGS=-MMD -g -DDEBUG
CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
-Wstrict-prototypes -Wmissing-prototypes
# If cp.exe is available, replace "copy /Y" with "cp -fp" .
CP=copy /Y
# If gnu install.exe is available, replace $(CP) with ginstall.
INSTALL=$(CP)
# The default value of RM is "rm -f." If "rm.exe" is found, comment out:
RM=del
LDLIBS=-L. -lzlib
LD=$(CC) -s -o
LDSHARED=$(CC)
INCL=zlib.h zconf.h
LIBS=zlib.a
AR=ar rcs
prefix=/usr/local
exec_prefix = $(prefix)
OBJS = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \
gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o
TEST_OBJS = example.o minigzip.o
all: example.exe minigzip.exe
test: all
./example
echo hello world | .\minigzip | .\minigzip -d
%.o : %.c
$(CC) $(CFLAGS) -c $< -o $@
zlib.a: $(OBJS)
$(AR) $@ $(OBJS)
%.exe : %.o $(LIBS)
$(LD) $@ $< $(LDLIBS)
.PHONY : clean
clean:
$(RM) *.d
$(RM) *.o
$(RM) *.exe
$(RM) zlib.a
$(RM) foo.gz
DEPS := $(wildcard *.d)
ifneq ($(DEPS),)
include $(DEPS)
endif

151
external/zlib/old/Makefile.riscos vendored Normal file
View File

@@ -0,0 +1,151 @@
# Project: zlib_1_03
# Patched for zlib 1.1.2 rw@shadow.org.uk 19980430
# test works out-of-the-box, installs `somewhere' on demand
# Toolflags:
CCflags = -c -depend !Depend -IC: -g -throwback -DRISCOS -fah
C++flags = -c -depend !Depend -IC: -throwback
Linkflags = -aif -c++ -o $@
ObjAsmflags = -throwback -NoCache -depend !Depend
CMHGflags =
LibFileflags = -c -l -o $@
Squeezeflags = -o $@
# change the line below to where _you_ want the library installed.
libdest = lib:zlib
# Final targets:
@.lib: @.o.adler32 @.o.compress @.o.crc32 @.o.deflate @.o.gzio \
@.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil @.o.trees \
@.o.uncompr @.o.zutil
LibFile $(LibFileflags) @.o.adler32 @.o.compress @.o.crc32 @.o.deflate \
@.o.gzio @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil \
@.o.trees @.o.uncompr @.o.zutil
test: @.minigzip @.example @.lib
@copy @.lib @.libc A~C~DF~L~N~P~Q~RS~TV
@echo running tests: hang on.
@/@.minigzip -f -9 libc
@/@.minigzip -d libc-gz
@/@.minigzip -f -1 libc
@/@.minigzip -d libc-gz
@/@.minigzip -h -9 libc
@/@.minigzip -d libc-gz
@/@.minigzip -h -1 libc
@/@.minigzip -d libc-gz
@/@.minigzip -9 libc
@/@.minigzip -d libc-gz
@/@.minigzip -1 libc
@/@.minigzip -d libc-gz
@diff @.lib @.libc
@echo that should have reported '@.lib and @.libc identical' if you have diff.
@/@.example @.fred @.fred
@echo that will have given lots of hello!'s.
@.minigzip: @.o.minigzip @.lib C:o.Stubs
Link $(Linkflags) @.o.minigzip @.lib C:o.Stubs
@.example: @.o.example @.lib C:o.Stubs
Link $(Linkflags) @.o.example @.lib C:o.Stubs
install: @.lib
cdir $(libdest)
cdir $(libdest).h
@copy @.h.zlib $(libdest).h.zlib A~C~DF~L~N~P~Q~RS~TV
@copy @.h.zconf $(libdest).h.zconf A~C~DF~L~N~P~Q~RS~TV
@copy @.lib $(libdest).lib A~C~DF~L~N~P~Q~RS~TV
@echo okay, installed zlib in $(libdest)
clean:; remove @.minigzip
remove @.example
remove @.libc
-wipe @.o.* F~r~cV
remove @.fred
# User-editable dependencies:
.c.o:
cc $(ccflags) -o $@ $<
# Static dependencies:
# Dynamic dependencies:
o.example: c.example
o.example: h.zlib
o.example: h.zconf
o.minigzip: c.minigzip
o.minigzip: h.zlib
o.minigzip: h.zconf
o.adler32: c.adler32
o.adler32: h.zlib
o.adler32: h.zconf
o.compress: c.compress
o.compress: h.zlib
o.compress: h.zconf
o.crc32: c.crc32
o.crc32: h.zlib
o.crc32: h.zconf
o.deflate: c.deflate
o.deflate: h.deflate
o.deflate: h.zutil
o.deflate: h.zlib
o.deflate: h.zconf
o.gzio: c.gzio
o.gzio: h.zutil
o.gzio: h.zlib
o.gzio: h.zconf
o.infblock: c.infblock
o.infblock: h.zutil
o.infblock: h.zlib
o.infblock: h.zconf
o.infblock: h.infblock
o.infblock: h.inftrees
o.infblock: h.infcodes
o.infblock: h.infutil
o.infcodes: c.infcodes
o.infcodes: h.zutil
o.infcodes: h.zlib
o.infcodes: h.zconf
o.infcodes: h.inftrees
o.infcodes: h.infblock
o.infcodes: h.infcodes
o.infcodes: h.infutil
o.infcodes: h.inffast
o.inffast: c.inffast
o.inffast: h.zutil
o.inffast: h.zlib
o.inffast: h.zconf
o.inffast: h.inftrees
o.inffast: h.infblock
o.inffast: h.infcodes
o.inffast: h.infutil
o.inffast: h.inffast
o.inflate: c.inflate
o.inflate: h.zutil
o.inflate: h.zlib
o.inflate: h.zconf
o.inflate: h.infblock
o.inftrees: c.inftrees
o.inftrees: h.zutil
o.inftrees: h.zlib
o.inftrees: h.zconf
o.inftrees: h.inftrees
o.inftrees: h.inffixed
o.infutil: c.infutil
o.infutil: h.zutil
o.infutil: h.zlib
o.infutil: h.zconf
o.infutil: h.infblock
o.infutil: h.inftrees
o.infutil: h.infcodes
o.infutil: h.infutil
o.trees: c.trees
o.trees: h.deflate
o.trees: h.zutil
o.trees: h.zlib
o.trees: h.zconf
o.trees: h.trees
o.uncompr: c.uncompr
o.uncompr: h.zlib
o.uncompr: h.zconf
o.zutil: c.zutil
o.zutil: h.zutil
o.zutil: h.zlib
o.zutil: h.zconf

3
external/zlib/old/README vendored Normal file
View File

@@ -0,0 +1,3 @@
This directory contains files that have not been updated for zlib 1.2.x
(Volunteers are encouraged to help clean this up. Thanks.)

48
external/zlib/old/descrip.mms vendored Normal file
View File

@@ -0,0 +1,48 @@
# descrip.mms: MMS description file for building zlib on VMS
# written by Martin P.J. Zinser <m.zinser@gsi.de>
cc_defs =
c_deb =
.ifdef __DECC__
pref = /prefix=all
.endif
OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj,\
deflate.obj, trees.obj, zutil.obj, inflate.obj, infblock.obj,\
inftrees.obj, infcodes.obj, infutil.obj, inffast.obj
CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF)
all : example.exe minigzip.exe
@ write sys$output " Example applications available"
libz.olb : libz.olb($(OBJS))
@ write sys$output " libz available"
example.exe : example.obj libz.olb
link example,libz.olb/lib
minigzip.exe : minigzip.obj libz.olb
link minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib
clean :
delete *.obj;*,libz.olb;*
# Other dependencies.
adler32.obj : zutil.h zlib.h zconf.h
compress.obj : zlib.h zconf.h
crc32.obj : zutil.h zlib.h zconf.h
deflate.obj : deflate.h zutil.h zlib.h zconf.h
example.obj : zlib.h zconf.h
gzio.obj : zutil.h zlib.h zconf.h
infblock.obj : zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
infcodes.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h
inffast.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
inflate.obj : zutil.h zlib.h zconf.h infblock.h
inftrees.obj : zutil.h zlib.h zconf.h inftrees.h
infutil.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h
minigzip.obj : zlib.h zconf.h
trees.obj : deflate.h zutil.h zlib.h zconf.h
uncompr.obj : zlib.h zconf.h
zutil.obj : zutil.h zlib.h zconf.h

136
external/zlib/old/os2/Makefile.os2 vendored Normal file
View File

@@ -0,0 +1,136 @@
# Makefile for zlib under OS/2 using GCC (PGCC)
# For conditions of distribution and use, see copyright notice in zlib.h
# To compile and test, type:
# cp Makefile.os2 ..
# cd ..
# make -f Makefile.os2 test
# This makefile will build a static library z.lib, a shared library
# z.dll and a import library zdll.lib. You can use either z.lib or
# zdll.lib by specifying either -lz or -lzdll on gcc's command line
CC=gcc -Zomf -s
CFLAGS=-O6 -Wall
#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
#CFLAGS=-g -DDEBUG
#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
# -Wstrict-prototypes -Wmissing-prototypes
#################### BUG WARNING: #####################
## infcodes.c hits a bug in pgcc-1.0, so you have to use either
## -O# where # <= 4 or one of (-fno-ommit-frame-pointer or -fno-force-mem)
## This bug is reportedly fixed in pgcc >1.0, but this was not tested
CFLAGS+=-fno-force-mem
LDFLAGS=-s -L. -lzdll -Zcrtdll
LDSHARED=$(CC) -s -Zomf -Zdll -Zcrtdll
VER=1.1.0
ZLIB=z.lib
SHAREDLIB=z.dll
SHAREDLIBIMP=zdll.lib
LIBS=$(ZLIB) $(SHAREDLIB) $(SHAREDLIBIMP)
AR=emxomfar cr
IMPLIB=emximp
RANLIB=echo
TAR=tar
SHELL=bash
prefix=/usr/local
exec_prefix = $(prefix)
OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
TEST_OBJS = example.o minigzip.o
DISTFILES = README INDEX ChangeLog configure Make*[a-z0-9] *.[ch] descrip.mms \
algorithm.txt zlib.3 msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \
nt/Makefile.nt nt/zlib.dnt contrib/README.contrib contrib/*.txt \
contrib/asm386/*.asm contrib/asm386/*.c \
contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/iostream/*.cpp \
contrib/iostream/*.h contrib/iostream2/*.h contrib/iostream2/*.cpp \
contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32
all: example.exe minigzip.exe
test: all
@LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
echo hello world | ./minigzip | ./minigzip -d || \
echo ' *** minigzip test FAILED ***' ; \
if ./example; then \
echo ' *** zlib test OK ***'; \
else \
echo ' *** zlib test FAILED ***'; \
fi
$(ZLIB): $(OBJS)
$(AR) $@ $(OBJS)
-@ ($(RANLIB) $@ || true) >/dev/null 2>&1
$(SHAREDLIB): $(OBJS) os2/z.def
$(LDSHARED) -o $@ $^
$(SHAREDLIBIMP): os2/z.def
$(IMPLIB) -o $@ $^
example.exe: example.o $(LIBS)
$(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
minigzip.exe: minigzip.o $(LIBS)
$(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
clean:
rm -f *.o *~ example minigzip libz.a libz.so* foo.gz
distclean: clean
zip:
mv Makefile Makefile~; cp -p Makefile.in Makefile
rm -f test.c ztest*.c
v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
zip -ul9 zlib$$v $(DISTFILES)
mv Makefile~ Makefile
dist:
mv Makefile Makefile~; cp -p Makefile.in Makefile
rm -f test.c ztest*.c
d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
rm -f $$d.tar.gz; \
if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \
files=""; \
for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \
cd ..; \
GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \
if test ! -d $$d; then rm -f $$d; fi
mv Makefile~ Makefile
tags:
etags *.[ch]
depend:
makedepend -- $(CFLAGS) -- *.[ch]
# DO NOT DELETE THIS LINE -- make depend depends on it.
adler32.o: zlib.h zconf.h
compress.o: zlib.h zconf.h
crc32.o: zlib.h zconf.h
deflate.o: deflate.h zutil.h zlib.h zconf.h
example.o: zlib.h zconf.h
gzio.o: zutil.h zlib.h zconf.h
infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h
infcodes.o: zutil.h zlib.h zconf.h
infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h
inffast.o: zutil.h zlib.h zconf.h inftrees.h
inffast.o: infblock.h infcodes.h infutil.h inffast.h
inflate.o: zutil.h zlib.h zconf.h infblock.h
inftrees.o: zutil.h zlib.h zconf.h inftrees.h
infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
minigzip.o: zlib.h zconf.h
trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
uncompr.o: zlib.h zconf.h
zutil.o: zutil.h zlib.h zconf.h

51
external/zlib/old/os2/zlib.def vendored Normal file
View File

@@ -0,0 +1,51 @@
;
; Slightly modified version of ../nt/zlib.dnt :-)
;
LIBRARY Z
DESCRIPTION "Zlib compression library for OS/2"
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE MULTIPLE
EXPORTS
adler32
compress
crc32
deflate
deflateCopy
deflateEnd
deflateInit2_
deflateInit_
deflateParams
deflateReset
deflateSetDictionary
gzclose
gzdopen
gzerror
gzflush
gzopen
gzread
gzwrite
inflate
inflateEnd
inflateInit2_
inflateInit_
inflateReset
inflateSetDictionary
inflateSync
uncompress
zlibVersion
gzprintf
gzputc
gzgetc
gzseek
gzrewind
gztell
gzeof
gzsetparams
zError
inflateSyncPoint
get_crc_table
compress2
gzputs
gzgets

160
external/zlib/old/visual-basic.txt vendored Normal file
View File

@@ -0,0 +1,160 @@
See below some functions declarations for Visual Basic.
Frequently Asked Question:
Q: Each time I use the compress function I get the -5 error (not enough
room in the output buffer).
A: Make sure that the length of the compressed buffer is passed by
reference ("as any"), not by value ("as long"). Also check that
before the call of compress this length is equal to the total size of
the compressed buffer and not zero.
From: "Jon Caruana" <jon-net@usa.net>
Subject: Re: How to port zlib declares to vb?
Date: Mon, 28 Oct 1996 18:33:03 -0600
Got the answer! (I haven't had time to check this but it's what I got, and
looks correct):
He has the following routines working:
compress
uncompress
gzopen
gzwrite
gzread
gzclose
Declares follow: (Quoted from Carlos Rios <c_rios@sonda.cl>, in Vb4 form)
#If Win16 Then 'Use Win16 calls.
Declare Function compress Lib "ZLIB.DLL" (ByVal compr As
String, comprLen As Any, ByVal buf As String, ByVal buflen
As Long) As Integer
Declare Function uncompress Lib "ZLIB.DLL" (ByVal uncompr
As String, uncomprLen As Any, ByVal compr As String, ByVal
lcompr As Long) As Integer
Declare Function gzopen Lib "ZLIB.DLL" (ByVal filePath As
String, ByVal mode As String) As Long
Declare Function gzread Lib "ZLIB.DLL" (ByVal file As
Long, ByVal uncompr As String, ByVal uncomprLen As Integer)
As Integer
Declare Function gzwrite Lib "ZLIB.DLL" (ByVal file As
Long, ByVal uncompr As String, ByVal uncomprLen As Integer)
As Integer
Declare Function gzclose Lib "ZLIB.DLL" (ByVal file As
Long) As Integer
#Else
Declare Function compress Lib "ZLIB32.DLL"
(ByVal compr As String, comprLen As Any, ByVal buf As
String, ByVal buflen As Long) As Integer
Declare Function uncompress Lib "ZLIB32.DLL"
(ByVal uncompr As String, uncomprLen As Any, ByVal compr As
String, ByVal lcompr As Long) As Long
Declare Function gzopen Lib "ZLIB32.DLL"
(ByVal file As String, ByVal mode As String) As Long
Declare Function gzread Lib "ZLIB32.DLL"
(ByVal file As Long, ByVal uncompr As String, ByVal
uncomprLen As Long) As Long
Declare Function gzwrite Lib "ZLIB32.DLL"
(ByVal file As Long, ByVal uncompr As String, ByVal
uncomprLen As Long) As Long
Declare Function gzclose Lib "ZLIB32.DLL"
(ByVal file As Long) As Long
#End If
-Jon Caruana
jon-net@usa.net
Microsoft Sitebuilder Network Level 1 Member - HTML Writer's Guild Member
Here is another example from Michael <michael_borgsys@hotmail.com> that he
says conforms to the VB guidelines, and that solves the problem of not
knowing the uncompressed size by storing it at the end of the file:
'Calling the functions:
'bracket meaning: <parameter> [optional] {Range of possible values}
'Call subCompressFile(<path with filename to compress> [, <path with
filename to write to>, [level of compression {1..9}]])
'Call subUncompressFile(<path with filename to compress>)
Option Explicit
Private lngpvtPcnSml As Long 'Stores value for 'lngPercentSmaller'
Private Const SUCCESS As Long = 0
Private Const strFilExt As String = ".cpr"
Private Declare Function lngfncCpr Lib "zlib.dll" Alias "compress2" (ByRef
dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long,
ByVal level As Integer) As Long
Private Declare Function lngfncUcp Lib "zlib.dll" Alias "uncompress" (ByRef
dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long)
As Long
Public Sub subCompressFile(ByVal strargOriFilPth As String, Optional ByVal
strargCprFilPth As String, Optional ByVal intLvl As Integer = 9)
Dim strCprPth As String
Dim lngOriSiz As Long
Dim lngCprSiz As Long
Dim bytaryOri() As Byte
Dim bytaryCpr() As Byte
lngOriSiz = FileLen(strargOriFilPth)
ReDim bytaryOri(lngOriSiz - 1)
Open strargOriFilPth For Binary Access Read As #1
Get #1, , bytaryOri()
Close #1
strCprPth = IIf(strargCprFilPth = "", strargOriFilPth, strargCprFilPth)
'Select file path and name
strCprPth = strCprPth & IIf(Right(strCprPth, Len(strFilExt)) =
strFilExt, "", strFilExt) 'Add file extension if not exists
lngCprSiz = (lngOriSiz * 1.01) + 12 'Compression needs temporary a bit
more space then original file size
ReDim bytaryCpr(lngCprSiz - 1)
If lngfncCpr(bytaryCpr(0), lngCprSiz, bytaryOri(0), lngOriSiz, intLvl) =
SUCCESS Then
lngpvtPcnSml = (1# - (lngCprSiz / lngOriSiz)) * 100
ReDim Preserve bytaryCpr(lngCprSiz - 1)
Open strCprPth For Binary Access Write As #1
Put #1, , bytaryCpr()
Put #1, , lngOriSiz 'Add the the original size value to the end
(last 4 bytes)
Close #1
Else
MsgBox "Compression error"
End If
Erase bytaryCpr
Erase bytaryOri
End Sub
Public Sub subUncompressFile(ByVal strargFilPth As String)
Dim bytaryCpr() As Byte
Dim bytaryOri() As Byte
Dim lngOriSiz As Long
Dim lngCprSiz As Long
Dim strOriPth As String
lngCprSiz = FileLen(strargFilPth)
ReDim bytaryCpr(lngCprSiz - 1)
Open strargFilPth For Binary Access Read As #1
Get #1, , bytaryCpr()
Close #1
'Read the original file size value:
lngOriSiz = bytaryCpr(lngCprSiz - 1) * (2 ^ 24) _
+ bytaryCpr(lngCprSiz - 2) * (2 ^ 16) _
+ bytaryCpr(lngCprSiz - 3) * (2 ^ 8) _
+ bytaryCpr(lngCprSiz - 4)
ReDim Preserve bytaryCpr(lngCprSiz - 5) 'Cut of the original size value
ReDim bytaryOri(lngOriSiz - 1)
If lngfncUcp(bytaryOri(0), lngOriSiz, bytaryCpr(0), lngCprSiz) = SUCCESS
Then
strOriPth = Left(strargFilPth, Len(strargFilPth) - Len(strFilExt))
Open strOriPth For Binary Access Write As #1
Put #1, , bytaryOri()
Close #1
Else
MsgBox "Uncompression error"
End If
Erase bytaryCpr
Erase bytaryOri
End Sub
Public Property Get lngPercentSmaller() As Long
lngPercentSmaller = lngpvtPcnSml
End Property

141
external/zlib/qnx/package.qpg vendored Normal file
View File

@@ -0,0 +1,141 @@
<QPG:Generation>
<QPG:Options>
<QPG:User unattended="no" verbosity="2" listfiles="yes"/>
<QPG:Defaults type="qnx_package"/>
<QPG:Source></QPG:Source>
<QPG:Release number="+"/>
<QPG:Build></QPG:Build>
<QPG:FileSorting strip="yes"/>
<QPG:Package targets="combine"/>
<QPG:Repository generate="yes"/>
<QPG:FinalDir></QPG:FinalDir>
<QPG:Cleanup></QPG:Cleanup>
</QPG:Options>
<QPG:Responsible>
<QPG:Company></QPG:Company>
<QPG:Department></QPG:Department>
<QPG:Group></QPG:Group>
<QPG:Team></QPG:Team>
<QPG:Employee></QPG:Employee>
<QPG:EmailAddress></QPG:EmailAddress>
</QPG:Responsible>
<QPG:Values>
<QPG:Files>
<QPG:Add file="../zconf.h" install="/opt/include/" user="root:sys" permission="644"/>
<QPG:Add file="../zlib.h" install="/opt/include/" user="root:sys" permission="644"/>
<QPG:Add file="../libz.so.1.2.8" install="/opt/lib/" user="root:bin" permission="644"/>
<QPG:Add file="libz.so" install="/opt/lib/" component="dev" filetype="symlink" linkto="libz.so.1.2.8"/>
<QPG:Add file="libz.so.1" install="/opt/lib/" filetype="symlink" linkto="libz.so.1.2.8"/>
<QPG:Add file="../libz.so.1.2.8" install="/opt/lib/" component="slib"/>
</QPG:Files>
<QPG:PackageFilter>
<QPM:PackageManifest>
<QPM:PackageDescription>
<QPM:PackageType>Library</QPM:PackageType>
<QPM:PackageReleaseNotes></QPM:PackageReleaseNotes>
<QPM:PackageReleaseUrgency>Medium</QPM:PackageReleaseUrgency>
<QPM:PackageRepository></QPM:PackageRepository>
<QPM:FileVersion>2.0</QPM:FileVersion>
</QPM:PackageDescription>
<QPM:ProductDescription>
<QPM:ProductName>zlib</QPM:ProductName>
<QPM:ProductIdentifier>zlib</QPM:ProductIdentifier>
<QPM:ProductEmail>alain.bonnefoy@icbt.com</QPM:ProductEmail>
<QPM:VendorName>Public</QPM:VendorName>
<QPM:VendorInstallName>public</QPM:VendorInstallName>
<QPM:VendorURL>www.gzip.org/zlib</QPM:VendorURL>
<QPM:VendorEmbedURL></QPM:VendorEmbedURL>
<QPM:VendorEmail></QPM:VendorEmail>
<QPM:AuthorName>Jean-Loup Gailly,Mark Adler</QPM:AuthorName>
<QPM:AuthorURL>www.gzip.org/zlib</QPM:AuthorURL>
<QPM:AuthorEmbedURL></QPM:AuthorEmbedURL>
<QPM:AuthorEmail>zlib@gzip.org</QPM:AuthorEmail>
<QPM:ProductIconSmall></QPM:ProductIconSmall>
<QPM:ProductIconLarge></QPM:ProductIconLarge>
<QPM:ProductDescriptionShort>A massively spiffy yet delicately unobtrusive compression library.</QPM:ProductDescriptionShort>
<QPM:ProductDescriptionLong>zlib is designed to be a free, general-purpose, legally unencumbered, lossless data compression library for use on virtually any computer hardware and operating system.</QPM:ProductDescriptionLong>
<QPM:ProductDescriptionURL>http://www.gzip.org/zlib</QPM:ProductDescriptionURL>
<QPM:ProductDescriptionEmbedURL></QPM:ProductDescriptionEmbedURL>
</QPM:ProductDescription>
<QPM:ReleaseDescription>
<QPM:ReleaseVersion>1.2.8</QPM:ReleaseVersion>
<QPM:ReleaseUrgency>Medium</QPM:ReleaseUrgency>
<QPM:ReleaseStability>Stable</QPM:ReleaseStability>
<QPM:ReleaseNoteMinor></QPM:ReleaseNoteMinor>
<QPM:ReleaseNoteMajor></QPM:ReleaseNoteMajor>
<QPM:ExcludeCountries>
<QPM:Country></QPM:Country>
</QPM:ExcludeCountries>
<QPM:ReleaseCopyright>No License</QPM:ReleaseCopyright>
</QPM:ReleaseDescription>
<QPM:ContentDescription>
<QPM:ContentTopic xmlmultiple="true">Software Development/Libraries and Extensions/C Libraries</QPM:ContentTopic>
<QPM:ContentKeyword>zlib,compression</QPM:ContentKeyword>
<QPM:TargetOS>qnx6</QPM:TargetOS>
<QPM:HostOS>qnx6</QPM:HostOS>
<QPM:DisplayEnvironment xmlmultiple="true">None</QPM:DisplayEnvironment>
<QPM:TargetAudience xmlmultiple="true">Developer</QPM:TargetAudience>
</QPM:ContentDescription>
</QPM:PackageManifest>
</QPG:PackageFilter>
<QPG:PackageFilter proc="none" target="none">
<QPM:PackageManifest>
<QPM:ProductInstallationDependencies>
<QPM:ProductRequirements></QPM:ProductRequirements>
</QPM:ProductInstallationDependencies>
<QPM:ProductInstallationProcedure>
<QPM:Script xmlmultiple="true">
<QPM:ScriptName></QPM:ScriptName>
<QPM:ScriptType>Install</QPM:ScriptType>
<QPM:ScriptTiming>Post</QPM:ScriptTiming>
<QPM:ScriptBlocking>No</QPM:ScriptBlocking>
<QPM:ScriptResult>Ignore</QPM:ScriptResult>
<QPM:ShortDescription></QPM:ShortDescription>
<QPM:UseBinaries>No</QPM:UseBinaries>
<QPM:Priority>Optional</QPM:Priority>
</QPM:Script>
</QPM:ProductInstallationProcedure>
</QPM:PackageManifest>
<QPM:Launch>
</QPM:Launch>
</QPG:PackageFilter>
<QPG:PackageFilter type="core" component="none">
<QPM:PackageManifest>
<QPM:ProductInstallationProcedure>
<QPM:OrderDependency xmlmultiple="true">
<QPM:Order>InstallOver</QPM:Order>
<QPM:Product>zlib</QPM:Product>
</QPM:OrderDependency>
</QPM:ProductInstallationProcedure>
</QPM:PackageManifest>
<QPM:Launch>
</QPM:Launch>
</QPG:PackageFilter>
<QPG:PackageFilter type="core" component="dev">
<QPM:PackageManifest>
<QPM:ProductInstallationProcedure>
<QPM:OrderDependency xmlmultiple="true">
<QPM:Order>InstallOver</QPM:Order>
<QPM:Product>zlib-dev</QPM:Product>
</QPM:OrderDependency>
</QPM:ProductInstallationProcedure>
</QPM:PackageManifest>
<QPM:Launch>
</QPM:Launch>
</QPG:PackageFilter>
</QPG:Values>
</QPG:Generation>

601
external/zlib/test/example.c vendored Normal file
View File

@@ -0,0 +1,601 @@
/* example.c -- usage example of the zlib compression library
* Copyright (C) 1995-2006, 2011 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#include "zlib.h"
#include <stdio.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); \
} \
}
z_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_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[]));
#ifdef Z_SOLO
void *myalloc OF((void *, unsigned, unsigned));
void myfree OF((void *, void *));
void *myalloc(q, n, m)
void *q;
unsigned n, m;
{
q = Z_NULL;
return calloc(n, m);
}
void myfree(void *q, void *p)
{
q = Z_NULL;
free(p);
}
static alloc_func zalloc = myalloc;
static free_func zfree = myfree;
#else /* !Z_SOLO */
static alloc_func zalloc = (alloc_func)0;
static free_func zfree = (free_func)0;
void test_compress OF((Byte *compr, uLong comprLen,
Byte *uncompr, uLong uncomprLen));
void test_gzio OF((const char *fname,
Byte *uncompr, uLong uncomprLen));
/* ===========================================================================
* 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
}
#endif /* Z_SOLO */
/* ===========================================================================
* 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 = zalloc;
c_stream.zfree = zfree;
c_stream.opaque = (voidpf)0;
err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
CHECK_ERR(err, "deflateInit");
c_stream.next_in = (z_const unsigned char *)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 = zalloc;
d_stream.zfree = zfree;
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 = zalloc;
c_stream.zfree = zfree;
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 = zalloc;
d_stream.zfree = zfree;
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: %lld\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 = zalloc;
c_stream.zfree = zfree;
c_stream.opaque = (voidpf)0;
err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
CHECK_ERR(err, "deflateInit");
c_stream.next_in = (z_const unsigned char *)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 = zalloc;
d_stream.zfree = zfree;
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 = zalloc;
c_stream.zfree = zfree;
c_stream.opaque = (voidpf)0;
err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
CHECK_ERR(err, "deflateInit");
err = deflateSetDictionary(&c_stream,
(const Bytef*)dictionary, (int)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 = (z_const unsigned char *)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 = zalloc;
d_stream.zfree = zfree;
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,
(int)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%llx\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);
}
#ifdef Z_SOLO
argc = strlen(argv[0]);
#else
test_compress(compr, comprLen, uncompr, uncomprLen);
test_gzio((argc > 1 ? argv[1] : TESTFILE),
uncompr, uncomprLen);
#endif
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;
}

671
external/zlib/test/infcover.c vendored Normal file
View File

@@ -0,0 +1,671 @@
/* infcover.c -- test zlib's inflate routines with full code coverage
* Copyright (C) 2011 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* to use, do: ./configure --cover && make cover */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "zlib.h"
/* get definition of internal structure so we can mess with it (see pull()),
and so we can call inflate_trees() (see cover5()) */
#define ZLIB_INTERNAL
#include "inftrees.h"
#include "inflate.h"
#define local static
/* -- memory tracking routines -- */
/*
These memory tracking routines are provided to zlib and track all of zlib's
allocations and deallocations, check for LIFO operations, keep a current
and high water mark of total bytes requested, optionally set a limit on the
total memory that can be allocated, and when done check for memory leaks.
They are used as follows:
z_stream strm;
mem_setup(&strm) initializes the memory tracking and sets the
zalloc, zfree, and opaque members of strm to use
memory tracking for all zlib operations on strm
mem_limit(&strm, limit) sets a limit on the total bytes requested -- a
request that exceeds this limit will result in an
allocation failure (returns NULL) -- setting the
limit to zero means no limit, which is the default
after mem_setup()
mem_used(&strm, "msg") prints to stderr "msg" and the total bytes used
mem_high(&strm, "msg") prints to stderr "msg" and the high water mark
mem_done(&strm, "msg") ends memory tracking, releases all allocations
for the tracking as well as leaked zlib blocks, if
any. If there was anything unusual, such as leaked
blocks, non-FIFO frees, or frees of addresses not
allocated, then "msg" and information about the
problem is printed to stderr. If everything is
normal, nothing is printed. mem_done resets the
strm members to Z_NULL to use the default memory
allocation routines on the next zlib initialization
using strm.
*/
/* these items are strung together in a linked list, one for each allocation */
struct mem_item {
void *ptr; /* pointer to allocated memory */
size_t size; /* requested size of allocation */
struct mem_item *next; /* pointer to next item in list, or NULL */
};
/* this structure is at the root of the linked list, and tracks statistics */
struct mem_zone {
struct mem_item *first; /* pointer to first item in list, or NULL */
size_t total, highwater; /* total allocations, and largest total */
size_t limit; /* memory allocation limit, or 0 if no limit */
int notlifo, rogue; /* counts of non-LIFO frees and rogue frees */
};
/* memory allocation routine to pass to zlib */
local void *mem_alloc(void *mem, unsigned count, unsigned size)
{
void *ptr;
struct mem_item *item;
struct mem_zone *zone = mem;
size_t len = count * (size_t)size;
/* induced allocation failure */
if (zone == NULL || (zone->limit && zone->total + len > zone->limit))
return NULL;
/* perform allocation using the standard library, fill memory with a
non-zero value to make sure that the code isn't depending on zeros */
ptr = malloc(len);
if (ptr == NULL)
return NULL;
memset(ptr, 0xa5, len);
/* create a new item for the list */
item = malloc(sizeof(struct mem_item));
if (item == NULL) {
free(ptr);
return NULL;
}
item->ptr = ptr;
item->size = len;
/* insert item at the beginning of the list */
item->next = zone->first;
zone->first = item;
/* update the statistics */
zone->total += item->size;
if (zone->total > zone->highwater)
zone->highwater = zone->total;
/* return the allocated memory */
return ptr;
}
/* memory free routine to pass to zlib */
local void mem_free(void *mem, void *ptr)
{
struct mem_item *item, *next;
struct mem_zone *zone = mem;
/* if no zone, just do a free */
if (zone == NULL) {
free(ptr);
return;
}
/* point next to the item that matches ptr, or NULL if not found -- remove
the item from the linked list if found */
next = zone->first;
if (next) {
if (next->ptr == ptr)
zone->first = next->next; /* first one is it, remove from list */
else {
do { /* search the linked list */
item = next;
next = item->next;
} while (next != NULL && next->ptr != ptr);
if (next) { /* if found, remove from linked list */
item->next = next->next;
zone->notlifo++; /* not a LIFO free */
}
}
}
/* if found, update the statistics and free the item */
if (next) {
zone->total -= next->size;
free(next);
}
/* if not found, update the rogue count */
else
zone->rogue++;
/* in any case, do the requested free with the standard library function */
free(ptr);
}
/* set up a controlled memory allocation space for monitoring, set the stream
parameters to the controlled routines, with opaque pointing to the space */
local void mem_setup(z_stream *strm)
{
struct mem_zone *zone;
zone = malloc(sizeof(struct mem_zone));
assert(zone != NULL);
zone->first = NULL;
zone->total = 0;
zone->highwater = 0;
zone->limit = 0;
zone->notlifo = 0;
zone->rogue = 0;
strm->opaque = zone;
strm->zalloc = mem_alloc;
strm->zfree = mem_free;
}
/* set a limit on the total memory allocation, or 0 to remove the limit */
local void mem_limit(z_stream *strm, size_t limit)
{
struct mem_zone *zone = strm->opaque;
zone->limit = limit;
}
/* show the current total requested allocations in bytes */
local void mem_used(z_stream *strm, char *prefix)
{
struct mem_zone *zone = strm->opaque;
fprintf(stderr, "%s: %lu allocated\n", prefix, zone->total);
}
/* show the high water allocation in bytes */
local void mem_high(z_stream *strm, char *prefix)
{
struct mem_zone *zone = strm->opaque;
fprintf(stderr, "%s: %lu high water mark\n", prefix, zone->highwater);
}
/* release the memory allocation zone -- if there are any surprises, notify */
local void mem_done(z_stream *strm, char *prefix)
{
int count = 0;
struct mem_item *item, *next;
struct mem_zone *zone = strm->opaque;
/* show high water mark */
mem_high(strm, prefix);
/* free leftover allocations and item structures, if any */
item = zone->first;
while (item != NULL) {
free(item->ptr);
next = item->next;
free(item);
item = next;
count++;
}
/* issue alerts about anything unexpected */
if (count || zone->total)
fprintf(stderr, "** %s: %lu bytes in %d blocks not freed\n",
prefix, zone->total, count);
if (zone->notlifo)
fprintf(stderr, "** %s: %d frees not LIFO\n", prefix, zone->notlifo);
if (zone->rogue)
fprintf(stderr, "** %s: %d frees not recognized\n",
prefix, zone->rogue);
/* free the zone and delete from the stream */
free(zone);
strm->opaque = Z_NULL;
strm->zalloc = Z_NULL;
strm->zfree = Z_NULL;
}
/* -- inflate test routines -- */
/* Decode a hexadecimal string, set *len to length, in[] to the bytes. This
decodes liberally, in that hex digits can be adjacent, in which case two in
a row writes a byte. Or they can delimited by any non-hex character, where
the delimiters are ignored except when a single hex digit is followed by a
delimiter in which case that single digit writes a byte. The returned
data is allocated and must eventually be freed. NULL is returned if out of
memory. If the length is not needed, then len can be NULL. */
local unsigned char *h2b(const char *hex, unsigned *len)
{
unsigned char *in;
unsigned next, val;
in = malloc((strlen(hex) + 1) >> 1);
if (in == NULL)
return NULL;
next = 0;
val = 1;
do {
if (*hex >= '0' && *hex <= '9')
val = (val << 4) + *hex - '0';
else if (*hex >= 'A' && *hex <= 'F')
val = (val << 4) + *hex - 'A' + 10;
else if (*hex >= 'a' && *hex <= 'f')
val = (val << 4) + *hex - 'a' + 10;
else if (val != 1 && val < 32) /* one digit followed by delimiter */
val += 240; /* make it look like two digits */
if (val > 255) { /* have two digits */
in[next++] = val & 0xff; /* save the decoded byte */
val = 1; /* start over */
}
} while (*hex++); /* go through the loop with the terminating null */
if (len != NULL)
*len = next;
in = reallocf(in, next);
return in;
}
/* generic inflate() run, where hex is the hexadecimal input data, what is the
text to include in an error message, step is how much input data to feed
inflate() on each call, or zero to feed it all, win is the window bits
parameter to inflateInit2(), len is the size of the output buffer, and err
is the error code expected from the first inflate() call (the second
inflate() call is expected to return Z_STREAM_END). If win is 47, then
header information is collected with inflateGetHeader(). If a zlib stream
is looking for a dictionary, then an empty dictionary is provided.
inflate() is run until all of the input data is consumed. */
local void inf(char *hex, char *what, unsigned step, int win, unsigned len,
int err)
{
int ret;
unsigned have;
unsigned char *in, *out;
z_stream strm, copy;
gz_header head;
mem_setup(&strm);
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit2(&strm, win);
if (ret != Z_OK) {
mem_done(&strm, what);
return;
}
out = malloc(len); assert(out != NULL);
if (win == 47) {
head.extra = out;
head.extra_max = len;
head.name = out;
head.name_max = len;
head.comment = out;
head.comm_max = len;
ret = inflateGetHeader(&strm, &head); assert(ret == Z_OK);
}
in = h2b(hex, &have); assert(in != NULL);
if (step == 0 || step > have)
step = have;
strm.avail_in = step;
have -= step;
strm.next_in = in;
do {
strm.avail_out = len;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH); assert(err == 9 || ret == err);
if (ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_NEED_DICT)
break;
if (ret == Z_NEED_DICT) {
ret = inflateSetDictionary(&strm, in, 1);
assert(ret == Z_DATA_ERROR);
mem_limit(&strm, 1);
ret = inflateSetDictionary(&strm, out, 0);
assert(ret == Z_MEM_ERROR);
mem_limit(&strm, 0);
((struct inflate_state *)strm.state)->mode = DICT;
ret = inflateSetDictionary(&strm, out, 0);
assert(ret == Z_OK);
ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_BUF_ERROR);
}
ret = inflateCopy(&copy, &strm); assert(ret == Z_OK);
ret = inflateEnd(&copy); assert(ret == Z_OK);
err = 9; /* don't care next time around */
have += strm.avail_in;
strm.avail_in = step > have ? have : step;
have -= strm.avail_in;
} while (strm.avail_in);
free(in);
free(out);
ret = inflateReset2(&strm, -8); assert(ret == Z_OK);
ret = inflateEnd(&strm); assert(ret == Z_OK);
mem_done(&strm, what);
}
/* cover all of the lines in inflate.c up to inflate() */
local void cover_support(void)
{
int ret;
z_stream strm;
mem_setup(&strm);
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit(&strm); assert(ret == Z_OK);
mem_used(&strm, "inflate init");
ret = inflatePrime(&strm, 5, 31); assert(ret == Z_OK);
ret = inflatePrime(&strm, -1, 0); assert(ret == Z_OK);
ret = inflateSetDictionary(&strm, Z_NULL, 0);
assert(ret == Z_STREAM_ERROR);
ret = inflateEnd(&strm); assert(ret == Z_OK);
mem_done(&strm, "prime");
inf("63 0", "force window allocation", 0, -15, 1, Z_OK);
inf("63 18 5", "force window replacement", 0, -8, 259, Z_OK);
inf("63 18 68 30 d0 0 0", "force split window update", 4, -8, 259, Z_OK);
inf("3 0", "use fixed blocks", 0, -15, 1, Z_STREAM_END);
inf("", "bad window size", 0, 1, 0, Z_STREAM_ERROR);
mem_setup(&strm);
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit_(&strm, ZLIB_VERSION - 1, (int)sizeof(z_stream));
assert(ret == Z_VERSION_ERROR);
mem_done(&strm, "wrong version");
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit(&strm); assert(ret == Z_OK);
ret = inflateEnd(&strm); assert(ret == Z_OK);
fputs("inflate built-in memory routines\n", stderr);
}
/* cover all inflate() header and trailer cases and code after inflate() */
local void cover_wrap(void)
{
int ret;
z_stream strm, copy;
unsigned char dict[257];
ret = inflate(Z_NULL, 0); assert(ret == Z_STREAM_ERROR);
ret = inflateEnd(Z_NULL); assert(ret == Z_STREAM_ERROR);
ret = inflateCopy(Z_NULL, Z_NULL); assert(ret == Z_STREAM_ERROR);
fputs("inflate bad parameters\n", stderr);
inf("1f 8b 0 0", "bad gzip method", 0, 31, 0, Z_DATA_ERROR);
inf("1f 8b 8 80", "bad gzip flags", 0, 31, 0, Z_DATA_ERROR);
inf("77 85", "bad zlib method", 0, 15, 0, Z_DATA_ERROR);
inf("8 99", "set window size from header", 0, 0, 0, Z_OK);
inf("78 9c", "bad zlib window size", 0, 8, 0, Z_DATA_ERROR);
inf("78 9c 63 0 0 0 1 0 1", "check adler32", 0, 15, 1, Z_STREAM_END);
inf("1f 8b 8 1e 0 0 0 0 0 0 1 0 0 0 0 0 0", "bad header crc", 0, 47, 1,
Z_DATA_ERROR);
inf("1f 8b 8 2 0 0 0 0 0 0 1d 26 3 0 0 0 0 0 0 0 0 0", "check gzip length",
0, 47, 0, Z_STREAM_END);
inf("78 90", "bad zlib header check", 0, 47, 0, Z_DATA_ERROR);
inf("8 b8 0 0 0 1", "need dictionary", 0, 8, 0, Z_NEED_DICT);
inf("78 9c 63 0", "compute adler32", 0, 15, 1, Z_OK);
mem_setup(&strm);
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit2(&strm, -8);
strm.avail_in = 2;
strm.next_in = (void *)"\x63";
strm.avail_out = 1;
strm.next_out = (void *)&ret;
mem_limit(&strm, 1);
ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR);
ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR);
mem_limit(&strm, 0);
memset(dict, 0, 257);
ret = inflateSetDictionary(&strm, dict, 257);
assert(ret == Z_OK);
mem_limit(&strm, (sizeof(struct inflate_state) << 1) + 256);
ret = inflatePrime(&strm, 16, 0); assert(ret == Z_OK);
strm.avail_in = 2;
strm.next_in = (void *)"\x80";
ret = inflateSync(&strm); assert(ret == Z_DATA_ERROR);
ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_STREAM_ERROR);
strm.avail_in = 4;
strm.next_in = (void *)"\0\0\xff\xff";
ret = inflateSync(&strm); assert(ret == Z_OK);
(void)inflateSyncPoint(&strm);
ret = inflateCopy(&copy, &strm); assert(ret == Z_MEM_ERROR);
mem_limit(&strm, 0);
ret = inflateUndermine(&strm, 1); assert(ret == Z_DATA_ERROR);
(void)inflateMark(&strm);
ret = inflateEnd(&strm); assert(ret == Z_OK);
mem_done(&strm, "miscellaneous, force memory errors");
}
/* input and output functions for inflateBack() */
local unsigned pull(void *desc, unsigned char **buf)
{
static unsigned int next = 0;
static unsigned char dat[] = {0x63, 0, 2, 0};
struct inflate_state *state;
if (desc == Z_NULL) {
next = 0;
return 0; /* no input (already provided at next_in) */
}
state = (void *)((z_stream *)desc)->state;
if (state != Z_NULL)
state->mode = SYNC; /* force an otherwise impossible situation */
return next < sizeof(dat) ? (*buf = dat + next++, 1) : 0;
}
local int push(void *desc, unsigned char *buf, unsigned len)
{
buf += len;
return desc != Z_NULL; /* force error if desc not null */
}
/* cover inflateBack() up to common deflate data cases and after those */
local void cover_back(void)
{
int ret;
z_stream strm;
unsigned char win[32768];
ret = inflateBackInit_(Z_NULL, 0, win, 0, 0);
assert(ret == Z_VERSION_ERROR);
ret = inflateBackInit(Z_NULL, 0, win); assert(ret == Z_STREAM_ERROR);
ret = inflateBack(Z_NULL, Z_NULL, Z_NULL, Z_NULL, Z_NULL);
assert(ret == Z_STREAM_ERROR);
ret = inflateBackEnd(Z_NULL); assert(ret == Z_STREAM_ERROR);
fputs("inflateBack bad parameters\n", stderr);
mem_setup(&strm);
ret = inflateBackInit(&strm, 15, win); assert(ret == Z_OK);
strm.avail_in = 2;
strm.next_in = (void *)"\x03";
ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL);
assert(ret == Z_STREAM_END);
/* force output error */
strm.avail_in = 3;
strm.next_in = (void *)"\x63\x00";
ret = inflateBack(&strm, pull, Z_NULL, push, &strm);
assert(ret == Z_BUF_ERROR);
/* force mode error by mucking with state */
ret = inflateBack(&strm, pull, &strm, push, Z_NULL);
assert(ret == Z_STREAM_ERROR);
ret = inflateBackEnd(&strm); assert(ret == Z_OK);
mem_done(&strm, "inflateBack bad state");
ret = inflateBackInit(&strm, 15, win); assert(ret == Z_OK);
ret = inflateBackEnd(&strm); assert(ret == Z_OK);
fputs("inflateBack built-in memory routines\n", stderr);
}
/* do a raw inflate of data in hexadecimal with both inflate and inflateBack */
local int try(char *hex, char *id, int err)
{
int ret;
unsigned len, size;
unsigned char *in, *out, *win;
char *prefix;
z_stream strm;
/* convert to hex */
in = h2b(hex, &len);
assert(in != NULL);
/* allocate work areas */
size = len << 3;
out = malloc(size);
assert(out != NULL);
win = malloc(32768);
assert(win != NULL);
prefix = malloc(strlen(id) + 6);
assert(prefix != NULL);
/* first with inflate */
strcpy(prefix, id);
strcat(prefix, "-late");
mem_setup(&strm);
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit2(&strm, err < 0 ? 47 : -15);
assert(ret == Z_OK);
strm.avail_in = len;
strm.next_in = in;
do {
strm.avail_out = size;
strm.next_out = out;
ret = inflate(&strm, Z_TREES);
assert(ret != Z_STREAM_ERROR && ret != Z_MEM_ERROR);
if (ret == Z_DATA_ERROR || ret == Z_NEED_DICT)
break;
} while (strm.avail_in || strm.avail_out == 0);
if (err) {
assert(ret == Z_DATA_ERROR);
assert(strcmp(id, strm.msg) == 0);
}
inflateEnd(&strm);
mem_done(&strm, prefix);
/* then with inflateBack */
if (err >= 0) {
strcpy(prefix, id);
strcat(prefix, "-back");
mem_setup(&strm);
ret = inflateBackInit(&strm, 15, win);
assert(ret == Z_OK);
strm.avail_in = len;
strm.next_in = in;
ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL);
assert(ret != Z_STREAM_ERROR);
if (err) {
assert(ret == Z_DATA_ERROR);
assert(strcmp(id, strm.msg) == 0);
}
inflateBackEnd(&strm);
mem_done(&strm, prefix);
}
/* clean up */
free(prefix);
free(win);
free(out);
free(in);
return ret;
}
/* cover deflate data cases in both inflate() and inflateBack() */
local void cover_inflate(void)
{
try("0 0 0 0 0", "invalid stored block lengths", 1);
try("3 0", "fixed", 0);
try("6", "invalid block type", 1);
try("1 1 0 fe ff 0", "stored", 0);
try("fc 0 0", "too many length or distance symbols", 1);
try("4 0 fe ff", "invalid code lengths set", 1);
try("4 0 24 49 0", "invalid bit length repeat", 1);
try("4 0 24 e9 ff ff", "invalid bit length repeat", 1);
try("4 0 24 e9 ff 6d", "invalid code -- missing end-of-block", 1);
try("4 80 49 92 24 49 92 24 71 ff ff 93 11 0",
"invalid literal/lengths set", 1);
try("4 80 49 92 24 49 92 24 f b4 ff ff c3 84", "invalid distances set", 1);
try("4 c0 81 8 0 0 0 0 20 7f eb b 0 0", "invalid literal/length code", 1);
try("2 7e ff ff", "invalid distance code", 1);
try("c c0 81 0 0 0 0 0 90 ff 6b 4 0", "invalid distance too far back", 1);
/* also trailer mismatch just in inflate() */
try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 1", "incorrect data check", -1);
try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 1",
"incorrect length check", -1);
try("5 c0 21 d 0 0 0 80 b0 fe 6d 2f 91 6c", "pull 17", 0);
try("5 e0 81 91 24 cb b2 2c 49 e2 f 2e 8b 9a 47 56 9f fb fe ec d2 ff 1f",
"long code", 0);
try("ed c0 1 1 0 0 0 40 20 ff 57 1b 42 2c 4f", "length extra", 0);
try("ed cf c1 b1 2c 47 10 c4 30 fa 6f 35 1d 1 82 59 3d fb be 2e 2a fc f c",
"long distance and extra", 0);
try("ed c0 81 0 0 0 0 80 a0 fd a9 17 a9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "
"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6", "window end", 0);
inf("2 8 20 80 0 3 0", "inflate_fast TYPE return", 0, -15, 258,
Z_STREAM_END);
inf("63 18 5 40 c 0", "window wrap", 3, -8, 300, Z_OK);
}
/* cover remaining lines in inftrees.c */
local void cover_trees(void)
{
int ret;
unsigned bits;
unsigned short lens[16], work[16];
code *next, table[ENOUGH_DISTS];
/* we need to call inflate_table() directly in order to manifest not-
enough errors, since zlib insures that enough is always enough */
for (bits = 0; bits < 15; bits++)
lens[bits] = (unsigned short)(bits + 1);
lens[15] = 15;
next = table;
bits = 15;
ret = inflate_table(DISTS, lens, 16, &next, &bits, work);
assert(ret == 1);
next = table;
bits = 1;
ret = inflate_table(DISTS, lens, 16, &next, &bits, work);
assert(ret == 1);
fputs("inflate_table not enough errors\n", stderr);
}
/* cover remaining inffast.c decoding and window copying */
local void cover_fast(void)
{
inf("e5 e0 81 ad 6d cb b2 2c c9 01 1e 59 63 ae 7d ee fb 4d fd b5 35 41 68"
" ff 7f 0f 0 0 0", "fast length extra bits", 0, -8, 258, Z_DATA_ERROR);
inf("25 fd 81 b5 6d 59 b6 6a 49 ea af 35 6 34 eb 8c b9 f6 b9 1e ef 67 49"
" 50 fe ff ff 3f 0 0", "fast distance extra bits", 0, -8, 258,
Z_DATA_ERROR);
inf("3 7e 0 0 0 0 0", "fast invalid distance code", 0, -8, 258,
Z_DATA_ERROR);
inf("1b 7 0 0 0 0 0", "fast invalid literal/length code", 0, -8, 258,
Z_DATA_ERROR);
inf("d c7 1 ae eb 38 c 4 41 a0 87 72 de df fb 1f b8 36 b1 38 5d ff ff 0",
"fast 2nd level codes and too far back", 0, -8, 258, Z_DATA_ERROR);
inf("63 18 5 8c 10 8 0 0 0 0", "very common case", 0, -8, 259, Z_OK);
inf("63 60 60 18 c9 0 8 18 18 18 26 c0 28 0 29 0 0 0",
"contiguous and wrap around window", 6, -8, 259, Z_OK);
inf("63 0 3 0 0 0 0 0", "copy direct from output", 0, -8, 259,
Z_STREAM_END);
}
int main(void)
{
fprintf(stderr, "%s\n", zlibVersion());
cover_support();
cover_wrap();
cover_back();
cover_inflate();
cover_trees();
cover_fast();
return 0;
}

659
external/zlib/test/minigzip.c vendored Executable file
View File

@@ -0,0 +1,659 @@
/* minigzip.c -- simulate gzip using the zlib compression library
* Copyright (C) 1995-2006, 2010, 2011 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 "zlib.h"
#include <stdio.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>
# ifdef UNDER_CE
# include <stdlib.h>
# endif
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
#else
# define SET_BINARY_MODE(file)
#endif
#ifdef _MSC_VER
# define snprintf _snprintf
#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
#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)
#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
extern int unlink OF((const char *));
#endif
#endif
#if defined(UNDER_CE)
# include <windows.h>
# define perror(s) pwinerror(s)
/* Map the Windows error number in ERROR to a locale-dependent error
message string and return a pointer to it. Typically, the values
for ERROR come from GetLastError.
The string pointed to shall not be modified by the application,
but may be overwritten by a subsequent call to strwinerror
The strwinerror function does not change the current setting
of GetLastError. */
static char *strwinerror (error)
DWORD error;
{
static char buf[1024];
wchar_t *msgbuf;
DWORD lasterr = GetLastError();
DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL,
error,
0, /* Default language */
(LPVOID)&msgbuf,
0,
NULL);
if (chars != 0) {
/* If there is an \r\n appended, zap it. */
if (chars >= 2
&& msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
chars -= 2;
msgbuf[chars] = 0;
}
if (chars > sizeof (buf) - 1) {
chars = sizeof (buf) - 1;
msgbuf[chars] = 0;
}
wcstombs(buf, msgbuf, chars + 1);
LocalFree(msgbuf);
}
else {
sprintf(buf, "unknown win32 error (%ld)", error);
}
SetLastError(lasterr);
return buf;
}
static void pwinerror (s)
const char *s;
{
if (s && *s)
fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ()));
else
fprintf(stderr, "%s\n", strwinerror(GetLastError ()));
}
#endif /* UNDER_CE */
#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
#ifdef Z_SOLO
/* for Z_SOLO, create simplified gz* functions using deflate and inflate */
#if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)
# include <unistd.h> /* for unlink() */
#endif
void *myalloc OF((void *, unsigned, unsigned));
void myfree OF((void *, void *));
void *myalloc(q, n, m)
void *q;
unsigned n, m;
{
q = Z_NULL;
return calloc(n, m);
}
void myfree(q, p)
void *q, *p;
{
q = Z_NULL;
free(p);
}
typedef struct gzFile_s {
FILE *file;
int write;
int err;
char *msg;
z_stream strm;
} *gzFile;
gzFile gzopen OF((const char *, const char *));
gzFile gzdopen OF((int, const char *));
gzFile gz_open OF((const char *, int, const char *));
gzFile gzopen(path, mode)
const char *path;
const char *mode;
{
return gz_open(path, -1, mode);
}
gzFile gzdopen(fd, mode)
int fd;
const char *mode;
{
return gz_open(NULL, fd, mode);
}
gzFile gz_open(path, fd, mode)
const char *path;
int fd;
const char *mode;
{
gzFile gz;
int ret;
gz = malloc(sizeof(struct gzFile_s));
if (gz == NULL)
return NULL;
gz->write = strchr(mode, 'w') != NULL;
gz->strm.zalloc = myalloc;
gz->strm.zfree = myfree;
gz->strm.opaque = Z_NULL;
if (gz->write)
ret = deflateInit2(&(gz->strm), -1, 8, 15 + 16, 8, 0);
else {
gz->strm.next_in = 0;
gz->strm.avail_in = Z_NULL;
ret = inflateInit2(&(gz->strm), 15 + 16);
}
if (ret != Z_OK) {
free(gz);
return NULL;
}
gz->file = path == NULL ? fdopen(fd, gz->write ? "wb" : "rb") :
fopen(path, gz->write ? "wb" : "rb");
if (gz->file == NULL) {
gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm));
free(gz);
return NULL;
}
gz->err = 0;
gz->msg = "";
return gz;
}
int gzwrite OF((gzFile, const void *, unsigned));
int gzwrite(gz, buf, len)
gzFile gz;
const void *buf;
unsigned len;
{
z_stream *strm;
unsigned char out[BUFLEN];
if (gz == NULL || !gz->write)
return 0;
strm = &(gz->strm);
strm->next_in = (void *)buf;
strm->avail_in = len;
do {
strm->next_out = out;
strm->avail_out = BUFLEN;
(void)deflate(strm, Z_NO_FLUSH);
fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
} while (strm->avail_out == 0);
return len;
}
int gzread OF((gzFile, void *, unsigned));
int gzread(gz, buf, len)
gzFile gz;
void *buf;
unsigned len;
{
int ret;
unsigned got;
unsigned char in[1];
z_stream *strm;
if (gz == NULL || gz->write)
return 0;
if (gz->err)
return 0;
strm = &(gz->strm);
strm->next_out = (void *)buf;
strm->avail_out = len;
do {
got = fread(in, 1, 1, gz->file);
if (got == 0)
break;
strm->next_in = in;
strm->avail_in = 1;
ret = inflate(strm, Z_NO_FLUSH);
if (ret == Z_DATA_ERROR) {
gz->err = Z_DATA_ERROR;
gz->msg = strm->msg;
return 0;
}
if (ret == Z_STREAM_END)
inflateReset(strm);
} while (strm->avail_out);
return len - strm->avail_out;
}
int gzclose OF((gzFile));
int gzclose(gz)
gzFile gz;
{
z_stream *strm;
unsigned char out[BUFLEN];
if (gz == NULL)
return Z_STREAM_ERROR;
strm = &(gz->strm);
if (gz->write) {
strm->next_in = Z_NULL;
strm->avail_in = 0;
do {
strm->next_out = out;
strm->avail_out = BUFLEN;
(void)deflate(strm, Z_FINISH);
fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
} while (strm->avail_out == 0);
deflateEnd(strm);
}
else
inflateEnd(strm);
fclose(gz->file);
free(gz);
return Z_OK;
}
const char *gzerror OF((gzFile, int *));
const char *gzerror(gz, err)
gzFile gz;
int *err;
{
*err = gz->err;
return gz->msg;
}
#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, int keep));
void file_uncompress OF((char *file, int keep));
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, keep)
char *file;
char *mode;
int keep;
{
local char outfile[MAX_NAME_LEN];
FILE *in;
gzFile out;
if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {
fprintf(stderr, "%s: filename too long\n", prog);
exit(1);
}
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX);
#else
strcpy(outfile, file);
strcat(outfile, GZ_SUFFIX);
#endif
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);
if (!keep)
unlink(file);
}
/* ===========================================================================
* Uncompress the given file and remove the original.
*/
void file_uncompress(file, keep)
char *file;
int keep;
{
local char buf[MAX_NAME_LEN];
char *infile, *outfile;
FILE *out;
gzFile in;
size_t len = strlen(file);
if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {
fprintf(stderr, "%s: filename too long\n", prog);
exit(1);
}
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
snprintf(buf, sizeof(buf), "%s", file);
#else
strcpy(buf, file);
#endif
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;
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX);
#else
strcat(infile, GZ_SUFFIX);
#endif
}
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);
if (!keep)
unlink(infile);
}
/* ===========================================================================
* Usage: minigzip [-c] [-d] [-f] [-h] [-k] [-r] [-1 to -9] [files...]
* -c : write to standard output
* -d : decompress
* -f : compress with Z_FILTERED
* -h : compress with Z_HUFFMAN_ONLY
* -k : Keep input files
* -r : compress with Z_RLE
* -1 to -9 : compression level
*/
int main(argc, argv)
int argc;
char *argv[];
{
int copyout = 0;
int uncompr = 0;
int keep = 0;
gzFile file;
char *bname, outmode[20];
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
snprintf(outmode, sizeof(outmode), "%s", "wb6 ");
#else
strcpy(outmode, "wb6 ");
#endif
prog = argv[0];
bname = strrchr(argv[0], '/');
if (bname)
bname++;
else
bname = argv[0];
argc--, argv++;
if (!strcmp(bname, "gunzip"))
uncompr = 1;
else if (!strcmp(bname, "zcat"))
copyout = uncompr = 1;
while (argc > 0) {
if (strcmp(*argv, "-c") == 0)
copyout = 1;
else 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, "-k") == 0)
keep = 1;
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 {
if (copyout) {
SET_BINARY_MODE(stdout);
}
do {
if (uncompr) {
if (copyout) {
file = gzopen(*argv, "rb");
if (file == NULL)
fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv);
else
gz_uncompress(file, stdout);
} else {
file_uncompress(*argv, keep);
}
} else {
if (copyout) {
FILE * in = fopen(*argv, "rb");
if (in == NULL) {
perror(*argv);
} else {
file = gzdopen(fileno(stdout), outmode);
if (file == NULL) error("can't gzdopen stdout");
gz_compress(in, file);
}
} else {
file_compress(*argv, outmode, keep);
}
}
} while (argv++, --argc);
}
return 0;
}

636
external/zlib/ucm.cmake vendored Normal file
View File

@@ -0,0 +1,636 @@
#
# ucm.cmake - useful cmake macros
#
# Copyright (c) 2016 Viktor Kirilov
#
# Distributed under the MIT Software License
# See accompanying file LICENSE.txt or copy at
# https://opensource.org/licenses/MIT
#
# The documentation can be found at the library's page:
# https://github.com/onqtam/ucm
cmake_minimum_required(VERSION 2.8.12)
include(CMakeParseArguments)
# optionally include cotire - the git submodule might not be inited (or the user might have already included it)
if(NOT COMMAND cotire)
include(${CMAKE_CURRENT_LIST_DIR}/../cotire/CMake/cotire.cmake OPTIONAL)
endif()
if(COMMAND cotire AND "1.7.9" VERSION_LESS "${COTIRE_CMAKE_MODULE_VERSION}")
set(ucm_with_cotire 1)
else()
set(ucm_with_cotire 0)
endif()
# option(UCM_UNITY_BUILD "Enable unity build for targets registered with the ucm_add_target() macro" OFF)
# option(UCM_NO_COTIRE_FOLDER "Do not use a cotire folder in the solution explorer for all unity and cotire related targets" ON)
# ucm_add_flags
# Adds compiler flags to CMAKE_<LANG>_FLAGS or to a specific config
macro(ucm_add_flags)
cmake_parse_arguments(ARG "C;CXX;CLEAR_OLD" "" "CONFIG" ${ARGN})
if(NOT ARG_CONFIG)
set(ARG_CONFIG " ")
endif()
foreach(CONFIG ${ARG_CONFIG})
# determine to which flags to add
if(NOT ${CONFIG} STREQUAL " ")
string(TOUPPER ${CONFIG} CONFIG)
set(CXX_FLAGS CMAKE_CXX_FLAGS_${CONFIG})
set(C_FLAGS CMAKE_C_FLAGS_${CONFIG})
else()
set(CXX_FLAGS CMAKE_CXX_FLAGS)
set(C_FLAGS CMAKE_C_FLAGS)
endif()
# clear the old flags
if(${ARG_CLEAR_OLD})
if("${ARG_CXX}" OR NOT "${ARG_C}")
set(${CXX_FLAGS} "")
endif()
if("${ARG_C}" OR NOT "${ARG_CXX}")
set(${C_FLAGS} "")
endif()
endif()
# add all the passed flags
foreach(flag ${ARG_UNPARSED_ARGUMENTS})
if("${ARG_CXX}" OR NOT "${ARG_C}")
set(${CXX_FLAGS} "${${CXX_FLAGS}} ${flag}")
endif()
if("${ARG_C}" OR NOT "${ARG_CXX}")
set(${C_FLAGS} "${${C_FLAGS}} ${flag}")
endif()
endforeach()
endforeach()
endmacro()
# ucm_set_flags
# Sets the CMAKE_<LANG>_FLAGS compiler flags or for a specific config
macro(ucm_set_flags)
ucm_add_flags(CLEAR_OLD ${ARGN})
endmacro()
# ucm_add_linker_flags
# Adds linker flags to CMAKE_<TYPE>_LINKER_FLAGS or to a specific config
macro(ucm_add_linker_flags)
cmake_parse_arguments(ARG "CLEAR_OLD;EXE;MODULE;SHARED;STATIC" "" "CONFIG" ${ARGN})
if(NOT ARG_CONFIG)
set(ARG_CONFIG " ")
endif()
foreach(CONFIG ${ARG_CONFIG})
string(TOUPPER "${CONFIG}" CONFIG)
if(NOT ${ARG_EXE} AND NOT ${ARG_MODULE} AND NOT ${ARG_SHARED} AND NOT ${ARG_STATIC})
set(ARG_EXE 1)
set(ARG_MODULE 1)
set(ARG_SHARED 1)
set(ARG_STATIC 1)
endif()
set(flags_configs "")
if(${ARG_EXE})
if(NOT "${CONFIG}" STREQUAL " ")
list(APPEND flags_configs CMAKE_EXE_LINKER_FLAGS_${CONFIG})
else()
list(APPEND flags_configs CMAKE_EXE_LINKER_FLAGS)
endif()
endif()
if(${ARG_MODULE})
if(NOT "${CONFIG}" STREQUAL " ")
list(APPEND flags_configs CMAKE_MODULE_LINKER_FLAGS_${CONFIG})
else()
list(APPEND flags_configs CMAKE_MODULE_LINKER_FLAGS)
endif()
endif()
if(${ARG_SHARED})
if(NOT "${CONFIG}" STREQUAL " ")
list(APPEND flags_configs CMAKE_SHARED_LINKER_FLAGS_${CONFIG})
else()
list(APPEND flags_configs CMAKE_SHARED_LINKER_FLAGS)
endif()
endif()
if(${ARG_STATIC})
if(NOT "${CONFIG}" STREQUAL " ")
list(APPEND flags_configs CMAKE_STATIC_LINKER_FLAGS_${CONFIG})
else()
list(APPEND flags_configs CMAKE_STATIC_LINKER_FLAGS)
endif()
endif()
# clear the old flags
if(${ARG_CLEAR_OLD})
foreach(flags ${flags_configs})
set(${flags} "")
endforeach()
endif()
# add all the passed flags
foreach(flag ${ARG_UNPARSED_ARGUMENTS})
foreach(flags ${flags_configs})
set(${flags} "${${flags}} ${flag}")
endforeach()
endforeach()
endforeach()
endmacro()
# ucm_set_linker_flags
# Sets the CMAKE_<TYPE>_LINKER_FLAGS linker flags or for a specific config
macro(ucm_set_linker_flags)
ucm_add_linker_flags(CLEAR_OLD ${ARGN})
endmacro()
# ucm_gather_flags
# Gathers all lists of flags for printing or manipulation
macro(ucm_gather_flags with_linker result)
set(${result} "")
# add the main flags without a config
list(APPEND ${result} CMAKE_C_FLAGS)
list(APPEND ${result} CMAKE_CXX_FLAGS)
if(${with_linker})
list(APPEND ${result} CMAKE_EXE_LINKER_FLAGS)
list(APPEND ${result} CMAKE_MODULE_LINKER_FLAGS)
list(APPEND ${result} CMAKE_SHARED_LINKER_FLAGS)
list(APPEND ${result} CMAKE_STATIC_LINKER_FLAGS)
endif()
if("${CMAKE_CONFIGURATION_TYPES}" STREQUAL "" AND NOT "${CMAKE_BUILD_TYPE}" STREQUAL "")
# handle single config generators - like makefiles/ninja - when CMAKE_BUILD_TYPE is set
string(TOUPPER ${CMAKE_BUILD_TYPE} config)
list(APPEND ${result} CMAKE_C_FLAGS_${config})
list(APPEND ${result} CMAKE_CXX_FLAGS_${config})
if(${with_linker})
list(APPEND ${result} CMAKE_EXE_LINKER_FLAGS_${config})
list(APPEND ${result} CMAKE_MODULE_LINKER_FLAGS_${config})
list(APPEND ${result} CMAKE_SHARED_LINKER_FLAGS_${config})
list(APPEND ${result} CMAKE_STATIC_LINKER_FLAGS_${config})
endif()
else()
# handle multi config generators (like msvc, xcode)
foreach(config ${CMAKE_CONFIGURATION_TYPES})
string(TOUPPER ${config} config)
list(APPEND ${result} CMAKE_C_FLAGS_${config})
list(APPEND ${result} CMAKE_CXX_FLAGS_${config})
if(${with_linker})
list(APPEND ${result} CMAKE_EXE_LINKER_FLAGS_${config})
list(APPEND ${result} CMAKE_MODULE_LINKER_FLAGS_${config})
list(APPEND ${result} CMAKE_SHARED_LINKER_FLAGS_${config})
list(APPEND ${result} CMAKE_STATIC_LINKER_FLAGS_${config})
endif()
endforeach()
endif()
endmacro()
# ucm_set_runtime
# Sets the runtime (static/dynamic) for msvc/gcc
macro(ucm_set_runtime)
cmake_parse_arguments(ARG "STATIC;DYNAMIC" "" "" ${ARGN})
if(ARG_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "unrecognized arguments: ${ARG_UNPARSED_ARGUMENTS}")
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" STREQUAL "")
message(AUTHOR_WARNING "ucm_set_runtime() does not support clang yet!")
endif()
ucm_gather_flags(0 flags_configs)
# add/replace the flags
# note that if the user has messed with the flags directly this function might fail
# - for example if with MSVC and the user has removed the flags - here we just switch/replace them
if("${ARG_STATIC}")
foreach(flags ${flags_configs})
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "GNU")
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.4.7) # option "-static-libstdc++" available since GCC 4.5
if(NOT ${flags} MATCHES "-static-libstdc\\+\\+")
set(${flags} "${${flags}} -static-libstdc++")
endif()
endif()
if(NOT ${flags} MATCHES "-static-libgcc")
set(${flags} "${${flags}} -static-libgcc")
endif()
elseif(MSVC)
if(${flags} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${flags} "${${flags}}")
endif()
endif()
endforeach()
elseif("${ARG_DYNAMIC}")
foreach(flags ${flags_configs})
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "GNU")
if(${flags} MATCHES "-static-libstdc\\+\\+")
string(REGEX REPLACE "-static-libstdc\\+\\+" "" ${flags} "${${flags}}")
endif()
if(${flags} MATCHES "-static-libgcc")
string(REGEX REPLACE "-static-libgcc" "" ${flags} "${${flags}}")
endif()
elseif(MSVC)
if(${flags} MATCHES "/MT")
string(REGEX REPLACE "/MT" "/MD" ${flags} "${${flags}}")
endif()
endif()
endforeach()
endif()
endmacro()
# ucm_print_flags
# Prints all compiler flags for all configurations
macro(ucm_print_flags)
ucm_gather_flags(1 flags_configs)
message("")
foreach(flags ${flags_configs})
message("${flags}: ${${flags}}")
endforeach()
message("")
endmacro()
# ucm_count_sources
# Counts the number of source files
macro(ucm_count_sources)
cmake_parse_arguments(ARG "" "RESULT" "" ${ARGN})
if(${ARG_RESULT} STREQUAL "")
message(FATAL_ERROR "Need to pass RESULT and a variable name to ucm_count_sources()")
endif()
set(result 0)
foreach(SOURCE_FILE ${ARG_UNPARSED_ARGUMENTS})
if("${SOURCE_FILE}" MATCHES \\.\(c|C|cc|cp|cpp|CPP|c\\+\\+|cxx|i|ii\)$)
math(EXPR result "${result} + 1")
endif()
endforeach()
set(${ARG_RESULT} ${result})
endmacro()
# ucm_include_file_in_sources
# Includes the file to the source with compiler flags
macro(ucm_include_file_in_sources)
cmake_parse_arguments(ARG "" "HEADER" "" ${ARGN})
if(${ARG_HEADER} STREQUAL "")
message(FATAL_ERROR "Need to pass HEADER and a header file to ucm_include_file_in_sources()")
endif()
foreach(src ${ARG_UNPARSED_ARGUMENTS})
if(${src} MATCHES \\.\(c|C|cc|cp|cpp|CPP|c\\+\\+|cxx\)$)
# get old flags
get_source_file_property(old_compile_flags ${src} COMPILE_FLAGS)
if(old_compile_flags STREQUAL "NOTFOUND")
set(old_compile_flags "")
endif()
# update flags
if(MSVC)
set_source_files_properties(${src} PROPERTIES COMPILE_FLAGS
"${old_compile_flags} /FI\"${CMAKE_CURRENT_SOURCE_DIR}/${ARG_HEADER}\"")
else()
set_source_files_properties(${src} PROPERTIES COMPILE_FLAGS
"${old_compile_flags} -include \"${CMAKE_CURRENT_SOURCE_DIR}/${ARG_HEADER}\"")
endif()
endif()
endforeach()
endmacro()
# ucm_dir_list
# Returns a list of subdirectories for a given directory
macro(ucm_dir_list thedir result)
file(GLOB sub-dir "${thedir}/*")
set(list_of_dirs "")
foreach(dir ${sub-dir})
if(IS_DIRECTORY ${dir})
get_filename_component(DIRNAME ${dir} NAME)
LIST(APPEND list_of_dirs ${DIRNAME})
endif()
endforeach()
set(${result} ${list_of_dirs})
endmacro()
# ucm_trim_front_words
# Trims X times the front word from a string separated with "/" and removes
# the front "/" characters after that (used for filters for visual studio)
macro(ucm_trim_front_words source out num_filter_trims)
set(result "${source}")
set(counter 0)
while(${counter} LESS ${num_filter_trims})
MATH(EXPR counter "${counter} + 1")
# removes everything at the front up to a "/" character
string(REGEX REPLACE "^([^/]+)" "" result "${result}")
# removes all consecutive "/" characters from the front
string(REGEX REPLACE "^(/+)" "" result "${result}")
endwhile()
set(${out} ${result})
endmacro()
# ucm_remove_files
# Removes source files from a list of sources (path is the relative path for it to be found)
macro(ucm_remove_files)
cmake_parse_arguments(ARG "" "FROM" "" ${ARGN})
if("${ARG_UNPARSED_ARGUMENTS}" STREQUAL "")
message(FATAL_ERROR "Need to pass some relative files to ucm_remove_files()")
endif()
if(${ARG_FROM} STREQUAL "")
message(FATAL_ERROR "Need to pass FROM and a variable name to ucm_remove_files()")
endif()
foreach(cur_file ${ARG_UNPARSED_ARGUMENTS})
list(REMOVE_ITEM ${ARG_FROM} ${cur_file})
endforeach()
endmacro()
# ucm_remove_directories
# Removes all source files from the given directories from the sources list
macro(ucm_remove_directories)
cmake_parse_arguments(ARG "" "FROM" "MATCHES" ${ARGN})
if("${ARG_UNPARSED_ARGUMENTS}" STREQUAL "")
message(FATAL_ERROR "Need to pass some relative directories to ucm_remove_directories()")
endif()
if(${ARG_FROM} STREQUAL "")
message(FATAL_ERROR "Need to pass FROM and a variable name to ucm_remove_directories()")
endif()
foreach(cur_dir ${ARG_UNPARSED_ARGUMENTS})
foreach(cur_file ${${ARG_FROM}})
string(REGEX MATCH ${cur_dir} res ${cur_file})
if(NOT "${res}" STREQUAL "")
if("${ARG_MATCHES}" STREQUAL "")
list(REMOVE_ITEM ${ARG_FROM} ${cur_file})
else()
foreach(curr_ptrn ${ARG_MATCHES})
string(REGEX MATCH ${curr_ptrn} res ${cur_file})
if(NOT "${res}" STREQUAL "")
list(REMOVE_ITEM ${ARG_FROM} ${cur_file})
break()
endif()
endforeach()
endif()
endif()
endforeach()
endforeach()
endmacro()
# ucm_add_files_impl
macro(ucm_add_files_impl result trim files)
foreach(cur_file ${files})
SET(${result} ${${result}} ${cur_file})
get_filename_component(FILEPATH ${cur_file} PATH)
ucm_trim_front_words("${FILEPATH}" FILEPATH "${trim}")
# replacing forward slashes with back slashes so filters can be generated (back slash used in parsing...)
STRING(REPLACE "/" "\\" FILTERS "${FILEPATH}")
SOURCE_GROUP("${FILTERS}" FILES ${cur_file})
endforeach()
endmacro()
# ucm_add_files
# Adds files to a list of sources
macro(ucm_add_files)
cmake_parse_arguments(ARG "" "TO;FILTER_POP" "" ${ARGN})
if("${ARG_UNPARSED_ARGUMENTS}" STREQUAL "")
message(FATAL_ERROR "Need to pass some relative files to ucm_add_files()")
endif()
if(${ARG_TO} STREQUAL "")
message(FATAL_ERROR "Need to pass TO and a variable name to ucm_add_files()")
endif()
if("${ARG_FILTER_POP}" STREQUAL "")
set(ARG_FILTER_POP 0)
endif()
ucm_add_files_impl(${ARG_TO} ${ARG_FILTER_POP} "${ARG_UNPARSED_ARGUMENTS}")
endmacro()
# ucm_add_dir_impl
macro(ucm_add_dir_impl result rec trim dirs_in additional_ext)
set(dirs "${dirs_in}")
# handle the "" and "." cases
if("${dirs}" STREQUAL "" OR "${dirs}" STREQUAL ".")
set(dirs "./")
endif()
foreach(cur_dir ${dirs})
# to circumvent some linux/cmake/path issues - barely made it work...
if(cur_dir STREQUAL "./")
set(cur_dir "")
else()
set(cur_dir "${cur_dir}/")
endif()
# since unix is case sensitive - add these valid extensions too
# we don't use "UNIX" but instead "CMAKE_HOST_UNIX" because we might be cross
# compiling (for example emscripten) under windows and UNIX may be set to 1
# Also OSX is case insensitive like windows...
set(additional_file_extensions "")
if(CMAKE_HOST_UNIX AND NOT APPLE)
set(additional_file_extensions
"${cur_dir}*.CPP"
"${cur_dir}*.C"
"${cur_dir}*.H"
"${cur_dir}*.HPP"
)
endif()
foreach(ext ${additional_ext})
list(APPEND additional_file_extensions "${cur_dir}*.${ext}")
endforeach()
# find all sources and set them as result
FILE(GLOB found_sources RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
# https://gcc.gnu.org/onlinedocs/gcc-4.4.1/gcc/Overall-Options.html#index-file-name-suffix-71
# sources
"${cur_dir}*.cpp"
"${cur_dir}*.cxx"
"${cur_dir}*.c++"
"${cur_dir}*.cc"
"${cur_dir}*.cp"
"${cur_dir}*.c"
"${cur_dir}*.i"
"${cur_dir}*.ii"
# headers
"${cur_dir}*.h"
"${cur_dir}*.h++"
"${cur_dir}*.hpp"
"${cur_dir}*.hxx"
"${cur_dir}*.hh"
"${cur_dir}*.inl"
"${cur_dir}*.inc"
"${cur_dir}*.ipp"
"${cur_dir}*.ixx"
"${cur_dir}*.txx"
"${cur_dir}*.tpp"
"${cur_dir}*.tcc"
"${cur_dir}*.tpl"
${additional_file_extensions})
SET(${result} ${${result}} ${found_sources})
# set the proper filters
ucm_trim_front_words("${cur_dir}" cur_dir "${trim}")
# replacing forward slashes with back slashes so filters can be generated (back slash used in parsing...)
STRING(REPLACE "/" "\\" FILTERS "${cur_dir}")
SOURCE_GROUP("${FILTERS}" FILES ${found_sources})
endforeach()
if(${rec})
foreach(cur_dir ${dirs})
ucm_dir_list("${cur_dir}" subdirs)
foreach(subdir ${subdirs})
ucm_add_dir_impl(${result} ${rec} ${trim} "${cur_dir}/${subdir}" "${additional_ext}")
endforeach()
endforeach()
endif()
endmacro()
# ucm_add_dirs
# Adds all files from directories traversing them recursively to a list of sources
# and generates filters according to their location (accepts relative paths only).
# Also this macro trims X times the front word from the filter string for visual studio filters.
macro(ucm_add_dirs)
cmake_parse_arguments(ARG "RECURSIVE" "TO;FILTER_POP" "ADDITIONAL_EXT" ${ARGN})
if(${ARG_TO} STREQUAL "")
message(FATAL_ERROR "Need to pass TO and a variable name to ucm_add_dirs()")
endif()
if("${ARG_FILTER_POP}" STREQUAL "")
set(ARG_FILTER_POP 0)
endif()
ucm_add_dir_impl(${ARG_TO} ${ARG_RECURSIVE} ${ARG_FILTER_POP} "${ARG_UNPARSED_ARGUMENTS}" "${ARG_ADDITIONAL_EXT}")
endmacro()
# ucm_add_target
# Adds a target eligible for cotiring - unity build and/or precompiled header
macro(ucm_add_target)
cmake_parse_arguments(ARG "UNITY" "NAME;TYPE;PCH_FILE;CPP_PER_UNITY" "UNITY_EXCLUDED;SOURCES" ${ARGN})
if(NOT "${ARG_UNPARSED_ARGUMENTS}" STREQUAL "")
message(FATAL_ERROR "Unrecognized options passed to ucm_add_target()")
endif()
if("${ARG_NAME}" STREQUAL "")
message(FATAL_ERROR "Need to pass NAME and a name for the target to ucm_add_target()")
endif()
set(valid_types EXECUTABLE STATIC SHARED MODULE)
list(FIND valid_types "${ARG_TYPE}" is_type_valid)
if(${is_type_valid} STREQUAL "-1")
message(FATAL_ERROR "Need to pass TYPE and the type for the target [EXECUTABLE/STATIC/SHARED/MODULE] to ucm_add_target()")
endif()
if("${ARG_SOURCES}" STREQUAL "")
message(FATAL_ERROR "Need to pass SOURCES and a list of source files to ucm_add_target()")
endif()
# init with the global unity flag
set(do_unity ${UCM_UNITY_BUILD})
# check the UNITY argument
if(NOT ARG_UNITY)
set(do_unity FALSE)
endif()
# if target is excluded through the exclusion list
list(FIND UCM_UNITY_BUILD_EXCLUDE_TARGETS ${ARG_NAME} is_target_excluded)
if(NOT ${is_target_excluded} STREQUAL "-1")
set(do_unity FALSE)
endif()
# unity build only for targets with > 1 source file (otherwise there will be an additional unnecessary target)
if(do_unity) # optimization
ucm_count_sources(${ARG_SOURCES} RESULT num_sources)
if(${num_sources} LESS 2)
set(do_unity FALSE)
endif()
endif()
set(wanted_cotire ${do_unity})
# if cotire cannot be used
if(do_unity AND NOT ucm_with_cotire)
set(do_unity FALSE)
endif()
# inform the developer that the current target might benefit from a unity build
if(NOT ARG_UNITY AND ${UCM_UNITY_BUILD})
ucm_count_sources(${ARG_SOURCES} RESULT num_sources)
if(${num_sources} GREATER 1)
message(AUTHOR_WARNING "Target '${ARG_NAME}' may benefit from a unity build.\nIt has ${num_sources} sources - enable with UNITY flag")
endif()
endif()
# prepare for the unity build
set(orig_target ${ARG_NAME})
if(do_unity)
# the original target will be added with a different name than the requested
set(orig_target ${ARG_NAME}_ORIGINAL)
# exclude requested files from unity build of the current target
foreach(excluded_file "${ARG_UNITY_EXCLUDED}")
set_source_files_properties(${excluded_file} PROPERTIES COTIRE_EXCLUDED TRUE)
endforeach()
endif()
# add the original target
if(${ARG_TYPE} STREQUAL "EXECUTABLE")
add_executable(${orig_target} ${ARG_SOURCES})
else()
add_library(${orig_target} ${ARG_TYPE} ${ARG_SOURCES})
endif()
if(do_unity)
# set the number of unity cpp files to be used for the unity target
if(NOT "${ARG_CPP_PER_UNITY}" STREQUAL "")
set_property(TARGET ${orig_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "${ARG_CPP_PER_UNITY}")
else()
set_property(TARGET ${orig_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "100")
endif()
if(NOT "${ARG_PCH_FILE}" STREQUAL "")
set_target_properties(${orig_target} PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${ARG_PCH_FILE}")
else()
set_target_properties(${orig_target} PROPERTIES COTIRE_ENABLE_PRECOMPILED_HEADER FALSE)
endif()
# add a unity target for the original one with the name intended for the original
set_target_properties(${orig_target} PROPERTIES COTIRE_UNITY_TARGET_NAME ${ARG_NAME})
# this is the library call that does the magic
cotire(${orig_target})
set_target_properties(clean_cotire PROPERTIES FOLDER "CMakePredefinedTargets")
# disable the original target and enable the unity one
get_target_property(unity_target_name ${orig_target} COTIRE_UNITY_TARGET_NAME)
set_target_properties(${orig_target} PROPERTIES EXCLUDE_FROM_ALL 1 EXCLUDE_FROM_DEFAULT_BUILD 1)
set_target_properties(${unity_target_name} PROPERTIES EXCLUDE_FROM_ALL 0 EXCLUDE_FROM_DEFAULT_BUILD 0)
# also set the name of the target output as the original one
set_target_properties(${unity_target_name} PROPERTIES OUTPUT_NAME ${ARG_NAME})
if(UCM_NO_COTIRE_FOLDER)
# reset the folder property so all unity targets dont end up in a single folder in the solution explorer of VS
set_target_properties(${unity_target_name} PROPERTIES FOLDER "")
endif()
set_target_properties(all_unity PROPERTIES FOLDER "CMakePredefinedTargets")
elseif(NOT "${ARG_PCH_FILE}" STREQUAL "")
set(wanted_cotire TRUE)
if(ucm_with_cotire)
set_target_properties(${orig_target} PROPERTIES COTIRE_ADD_UNITY_BUILD FALSE)
set_target_properties(${orig_target} PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${ARG_PCH_FILE}")
cotire(${orig_target})
set_target_properties(clean_cotire PROPERTIES FOLDER "CMakePredefinedTargets")
endif()
endif()
# print a message if the target was requested to be cotired but it couldn't
if(wanted_cotire AND NOT ucm_with_cotire)
if(NOT COMMAND cotire)
message(AUTHOR_WARNING "Target \"${ARG_NAME}\" not cotired because cotire isn't loaded")
else()
message(AUTHOR_WARNING "Target \"${ARG_NAME}\" not cotired because cotire is older than the required version")
endif()
endif()
endmacro()

43
external/zlib/watcom/watcom_f.mak vendored Normal file
View File

@@ -0,0 +1,43 @@
# Makefile for zlib
# OpenWatcom flat model
# Last updated: 28-Dec-2005
# To use, do "wmake -f watcom_f.mak"
C_SOURCE = adler32.c compress.c crc32.c deflate.c &
gzclose.c gzlib.c gzread.c gzwrite.c &
infback.c inffast.c inflate.c inftrees.c &
trees.c uncompr.c zutil.c
OBJS = adler32.obj compress.obj crc32.obj deflate.obj &
gzclose.obj gzlib.obj gzread.obj gzwrite.obj &
infback.obj inffast.obj inflate.obj inftrees.obj &
trees.obj uncompr.obj zutil.obj
CC = wcc386
LINKER = wcl386
CFLAGS = -zq -mf -3r -fp3 -s -bt=dos -oilrtfm -fr=nul -wx
ZLIB_LIB = zlib_f.lib
.C.OBJ:
$(CC) $(CFLAGS) $[@
all: $(ZLIB_LIB) example.exe minigzip.exe
$(ZLIB_LIB): $(OBJS)
wlib -b -c $(ZLIB_LIB) -+adler32.obj -+compress.obj -+crc32.obj
wlib -b -c $(ZLIB_LIB) -+gzclose.obj -+gzlib.obj -+gzread.obj -+gzwrite.obj
wlib -b -c $(ZLIB_LIB) -+deflate.obj -+infback.obj
wlib -b -c $(ZLIB_LIB) -+inffast.obj -+inflate.obj -+inftrees.obj
wlib -b -c $(ZLIB_LIB) -+trees.obj -+uncompr.obj -+zutil.obj
example.exe: $(ZLIB_LIB) example.obj
$(LINKER) -ldos32a -fe=example.exe example.obj $(ZLIB_LIB)
minigzip.exe: $(ZLIB_LIB) minigzip.obj
$(LINKER) -ldos32a -fe=minigzip.exe minigzip.obj $(ZLIB_LIB)
clean: .SYMBOLIC
del *.obj
del $(ZLIB_LIB)
@echo Cleaning done

43
external/zlib/watcom/watcom_l.mak vendored Normal file
View File

@@ -0,0 +1,43 @@
# Makefile for zlib
# OpenWatcom large model
# Last updated: 28-Dec-2005
# To use, do "wmake -f watcom_l.mak"
C_SOURCE = adler32.c compress.c crc32.c deflate.c &
gzclose.c gzlib.c gzread.c gzwrite.c &
infback.c inffast.c inflate.c inftrees.c &
trees.c uncompr.c zutil.c
OBJS = adler32.obj compress.obj crc32.obj deflate.obj &
gzclose.obj gzlib.obj gzread.obj gzwrite.obj &
infback.obj inffast.obj inflate.obj inftrees.obj &
trees.obj uncompr.obj zutil.obj
CC = wcc
LINKER = wcl
CFLAGS = -zq -ml -s -bt=dos -oilrtfm -fr=nul -wx
ZLIB_LIB = zlib_l.lib
.C.OBJ:
$(CC) $(CFLAGS) $[@
all: $(ZLIB_LIB) example.exe minigzip.exe
$(ZLIB_LIB): $(OBJS)
wlib -b -c $(ZLIB_LIB) -+adler32.obj -+compress.obj -+crc32.obj
wlib -b -c $(ZLIB_LIB) -+gzclose.obj -+gzlib.obj -+gzread.obj -+gzwrite.obj
wlib -b -c $(ZLIB_LIB) -+deflate.obj -+infback.obj
wlib -b -c $(ZLIB_LIB) -+inffast.obj -+inflate.obj -+inftrees.obj
wlib -b -c $(ZLIB_LIB) -+trees.obj -+uncompr.obj -+zutil.obj
example.exe: $(ZLIB_LIB) example.obj
$(LINKER) -fe=example.exe example.obj $(ZLIB_LIB)
minigzip.exe: $(ZLIB_LIB) minigzip.obj
$(LINKER) -fe=minigzip.exe minigzip.obj $(ZLIB_LIB)
clean: .SYMBOLIC
del *.obj
del $(ZLIB_LIB)
@echo Cleaning done

397
external/zlib/win32/DLL_FAQ.txt vendored Normal file
View File

@@ -0,0 +1,397 @@
Frequently Asked Questions about ZLIB1.DLL
This document describes the design, the rationale, and the usage
of the official DLL build of zlib, named ZLIB1.DLL. If you have
general questions about zlib, you should see the file "FAQ" found
in the zlib distribution, or at the following location:
http://www.gzip.org/zlib/zlib_faq.html
1. What is ZLIB1.DLL, and how can I get it?
- ZLIB1.DLL is the official build of zlib as a DLL.
(Please remark the character '1' in the name.)
Pointers to a precompiled ZLIB1.DLL can be found in the zlib
web site at:
http://www.zlib.net/
Applications that link to ZLIB1.DLL can rely on the following
specification:
* The exported symbols are exclusively defined in the source
files "zlib.h" and "zlib.def", found in an official zlib
source distribution.
* The symbols are exported by name, not by ordinal.
* The exported names are undecorated.
* The calling convention of functions is "C" (CDECL).
* The ZLIB1.DLL binary is linked to MSVCRT.DLL.
The archive in which ZLIB1.DLL is bundled contains compiled
test programs that must run with a valid build of ZLIB1.DLL.
It is recommended to download the prebuilt DLL from the zlib
web site, instead of building it yourself, to avoid potential
incompatibilities that could be introduced by your compiler
and build settings. If you do build the DLL yourself, please
make sure that it complies with all the above requirements,
and it runs with the precompiled test programs, bundled with
the original ZLIB1.DLL distribution.
If, for any reason, you need to build an incompatible DLL,
please use a different file name.
2. Why did you change the name of the DLL to ZLIB1.DLL?
What happened to the old ZLIB.DLL?
- The old ZLIB.DLL, built from zlib-1.1.4 or earlier, required
compilation settings that were incompatible to those used by
a static build. The DLL settings were supposed to be enabled
by defining the macro ZLIB_DLL, before including "zlib.h".
Incorrect handling of this macro was silently accepted at
build time, resulting in two major problems:
* ZLIB_DLL was missing from the old makefile. When building
the DLL, not all people added it to the build options. In
consequence, incompatible incarnations of ZLIB.DLL started
to circulate around the net.
* When switching from using the static library to using the
DLL, applications had to define the ZLIB_DLL macro and
to recompile all the sources that contained calls to zlib
functions. Failure to do so resulted in creating binaries
that were unable to run with the official ZLIB.DLL build.
The only possible solution that we could foresee was to make
a binary-incompatible change in the DLL interface, in order to
remove the dependency on the ZLIB_DLL macro, and to release
the new DLL under a different name.
We chose the name ZLIB1.DLL, where '1' indicates the major
zlib version number. We hope that we will not have to break
the binary compatibility again, at least not as long as the
zlib-1.x series will last.
There is still a ZLIB_DLL macro, that can trigger a more
efficient build and use of the DLL, but compatibility no
longer dependents on it.
3. Can I build ZLIB.DLL from the new zlib sources, and replace
an old ZLIB.DLL, that was built from zlib-1.1.4 or earlier?
- In principle, you can do it by assigning calling convention
keywords to the macros ZEXPORT and ZEXPORTVA. In practice,
it depends on what you mean by "an old ZLIB.DLL", because the
old DLL exists in several mutually-incompatible versions.
You have to find out first what kind of calling convention is
being used in your particular ZLIB.DLL build, and to use the
same one in the new build. If you don't know what this is all
about, you might be better off if you would just leave the old
DLL intact.
4. Can I compile my application using the new zlib interface, and
link it to an old ZLIB.DLL, that was built from zlib-1.1.4 or
earlier?
- The official answer is "no"; the real answer depends again on
what kind of ZLIB.DLL you have. Even if you are lucky, this
course of action is unreliable.
If you rebuild your application and you intend to use a newer
version of zlib (post- 1.1.4), it is strongly recommended to
link it to the new ZLIB1.DLL.
5. Why are the zlib symbols exported by name, and not by ordinal?
- Although exporting symbols by ordinal is a little faster, it
is risky. Any single glitch in the maintenance or use of the
DEF file that contains the ordinals can result in incompatible
builds and frustrating crashes. Simply put, the benefits of
exporting symbols by ordinal do not justify the risks.
Technically, it should be possible to maintain ordinals in
the DEF file, and still export the symbols by name. Ordinals
exist in every DLL, and even if the dynamic linking performed
at the DLL startup is searching for names, ordinals serve as
hints, for a faster name lookup. However, if the DEF file
contains ordinals, the Microsoft linker automatically builds
an implib that will cause the executables linked to it to use
those ordinals, and not the names. It is interesting to
notice that the GNU linker for Win32 does not suffer from this
problem.
It is possible to avoid the DEF file if the exported symbols
are accompanied by a "__declspec(dllexport)" attribute in the
source files. You can do this in zlib by predefining the
ZLIB_DLL macro.
6. I see that the ZLIB1.DLL functions use the "C" (CDECL) calling
convention. Why not use the STDCALL convention?
STDCALL is the standard convention in Win32, and I need it in
my Visual Basic project!
(For readability, we use CDECL to refer to the convention
triggered by the "__cdecl" keyword, STDCALL to refer to
the convention triggered by "__stdcall", and FASTCALL to
refer to the convention triggered by "__fastcall".)
- Most of the native Windows API functions (without varargs) use
indeed the WINAPI convention (which translates to STDCALL in
Win32), but the standard C functions use CDECL. If a user
application is intrinsically tied to the Windows API (e.g.
it calls native Windows API functions such as CreateFile()),
sometimes it makes sense to decorate its own functions with
WINAPI. But if ANSI C or POSIX portability is a goal (e.g.
it calls standard C functions such as fopen()), it is not a
sound decision to request the inclusion of <windows.h>, or to
use non-ANSI constructs, for the sole purpose to make the user
functions STDCALL-able.
The functionality offered by zlib is not in the category of
"Windows functionality", but is more like "C functionality".
Technically, STDCALL is not bad; in fact, it is slightly
faster than CDECL, and it works with variable-argument
functions, just like CDECL. It is unfortunate that, in spite
of using STDCALL in the Windows API, it is not the default
convention used by the C compilers that run under Windows.
The roots of the problem reside deep inside the unsafety of
the K&R-style function prototypes, where the argument types
are not specified; but that is another story for another day.
The remaining fact is that CDECL is the default convention.
Even if an explicit convention is hard-coded into the function
prototypes inside C headers, problems may appear. The
necessity to expose the convention in users' callbacks is one
of these problems.
The calling convention issues are also important when using
zlib in other programming languages. Some of them, like Ada
(GNAT) and Fortran (GNU G77), have C bindings implemented
initially on Unix, and relying on the C calling convention.
On the other hand, the pre- .NET versions of Microsoft Visual
Basic require STDCALL, while Borland Delphi prefers, although
it does not require, FASTCALL.
In fairness to all possible uses of zlib outside the C
programming language, we choose the default "C" convention.
Anyone interested in different bindings or conventions is
encouraged to maintain specialized projects. The "contrib/"
directory from the zlib distribution already holds a couple
of foreign bindings, such as Ada, C++, and Delphi.
7. I need a DLL for my Visual Basic project. What can I do?
- Define the ZLIB_WINAPI macro before including "zlib.h", when
building both the DLL and the user application (except that
you don't need to define anything when using the DLL in Visual
Basic). The ZLIB_WINAPI macro will switch on the WINAPI
(STDCALL) convention. The name of this DLL must be different
than the official ZLIB1.DLL.
Gilles Vollant has contributed a build named ZLIBWAPI.DLL,
with the ZLIB_WINAPI macro turned on, and with the minizip
functionality built in. For more information, please read
the notes inside "contrib/vstudio/readme.txt", found in the
zlib distribution.
8. I need to use zlib in my Microsoft .NET project. What can I
do?
- Henrik Ravn has contributed a .NET wrapper around zlib. Look
into contrib/dotzlib/, inside the zlib distribution.
9. If my application uses ZLIB1.DLL, should I link it to
MSVCRT.DLL? Why?
- It is not required, but it is recommended to link your
application to MSVCRT.DLL, if it uses ZLIB1.DLL.
The executables (.EXE, .DLL, etc.) that are involved in the
same process and are using the C run-time library (i.e. they
are calling standard C functions), must link to the same
library. There are several libraries in the Win32 system:
CRTDLL.DLL, MSVCRT.DLL, the static C libraries, etc.
Since ZLIB1.DLL is linked to MSVCRT.DLL, the executables that
depend on it should also be linked to MSVCRT.DLL.
10. Why are you saying that ZLIB1.DLL and my application should
be linked to the same C run-time (CRT) library? I linked my
application and my DLLs to different C libraries (e.g. my
application to a static library, and my DLLs to MSVCRT.DLL),
and everything works fine.
- If a user library invokes only pure Win32 API (accessible via
<windows.h> and the related headers), its DLL build will work
in any context. But if this library invokes standard C API,
things get more complicated.
There is a single Win32 library in a Win32 system. Every
function in this library resides in a single DLL module, that
is safe to call from anywhere. On the other hand, there are
multiple versions of the C library, and each of them has its
own separate internal state. Standalone executables and user
DLLs that call standard C functions must link to a C run-time
(CRT) library, be it static or shared (DLL). Intermixing
occurs when an executable (not necessarily standalone) and a
DLL are linked to different CRTs, and both are running in the
same process.
Intermixing multiple CRTs is possible, as long as their
internal states are kept intact. The Microsoft Knowledge Base
articles KB94248 "HOWTO: Use the C Run-Time" and KB140584
"HOWTO: Link with the Correct C Run-Time (CRT) Library"
mention the potential problems raised by intermixing.
If intermixing works for you, it's because your application
and DLLs are avoiding the corruption of each of the CRTs'
internal states, maybe by careful design, or maybe by fortune.
Also note that linking ZLIB1.DLL to non-Microsoft CRTs, such
as those provided by Borland, raises similar problems.
11. Why are you linking ZLIB1.DLL to MSVCRT.DLL?
- MSVCRT.DLL exists on every Windows 95 with a new service pack
installed, or with Microsoft Internet Explorer 4 or later, and
on all other Windows 4.x or later (Windows 98, Windows NT 4,
or later). It is freely distributable; if not present in the
system, it can be downloaded from Microsoft or from other
software provider for free.
The fact that MSVCRT.DLL does not exist on a virgin Windows 95
is not so problematic. Windows 95 is scarcely found nowadays,
Microsoft ended its support a long time ago, and many recent
applications from various vendors, including Microsoft, do not
even run on it. Furthermore, no serious user should run
Windows 95 without a proper update installed.
12. Why are you not linking ZLIB1.DLL to
<<my favorite C run-time library>> ?
- We considered and abandoned the following alternatives:
* Linking ZLIB1.DLL to a static C library (LIBC.LIB, or
LIBCMT.LIB) is not a good option. People are using the DLL
mainly to save disk space. If you are linking your program
to a static C library, you may as well consider linking zlib
in statically, too.
* Linking ZLIB1.DLL to CRTDLL.DLL looks appealing, because
CRTDLL.DLL is present on every Win32 installation.
Unfortunately, it has a series of problems: it does not
work properly with Microsoft's C++ libraries, it does not
provide support for 64-bit file offsets, (and so on...),
and Microsoft discontinued its support a long time ago.
* Linking ZLIB1.DLL to MSVCR70.DLL or MSVCR71.DLL, supplied
with the Microsoft .NET platform, and Visual C++ 7.0/7.1,
raises problems related to the status of ZLIB1.DLL as a
system component. According to the Microsoft Knowledge Base
article KB326922 "INFO: Redistribution of the Shared C
Runtime Component in Visual C++ .NET", MSVCR70.DLL and
MSVCR71.DLL are not supposed to function as system DLLs,
because they may clash with MSVCRT.DLL. Instead, the
application's installer is supposed to put these DLLs
(if needed) in the application's private directory.
If ZLIB1.DLL depends on a non-system runtime, it cannot
function as a redistributable system component.
* Linking ZLIB1.DLL to non-Microsoft runtimes, such as
Borland's, or Cygwin's, raises problems related to the
reliable presence of these runtimes on Win32 systems.
It's easier to let the DLL build of zlib up to the people
who distribute these runtimes, and who may proceed as
explained in the answer to Question 14.
13. If ZLIB1.DLL cannot be linked to MSVCR70.DLL or MSVCR71.DLL,
how can I build/use ZLIB1.DLL in Microsoft Visual C++ 7.0
(Visual Studio .NET) or newer?
- Due to the problems explained in the Microsoft Knowledge Base
article KB326922 (see the previous answer), the C runtime that
comes with the VC7 environment is no longer considered a
system component. That is, it should not be assumed that this
runtime exists, or may be installed in a system directory.
Since ZLIB1.DLL is supposed to be a system component, it may
not depend on a non-system component.
In order to link ZLIB1.DLL and your application to MSVCRT.DLL
in VC7, you need the library of Visual C++ 6.0 or older. If
you don't have this library at hand, it's probably best not to
use ZLIB1.DLL.
We are hoping that, in the future, Microsoft will provide a
way to build applications linked to a proper system runtime,
from the Visual C++ environment. Until then, you have a
couple of alternatives, such as linking zlib in statically.
If your application requires dynamic linking, you may proceed
as explained in the answer to Question 14.
14. I need to link my own DLL build to a CRT different than
MSVCRT.DLL. What can I do?
- Feel free to rebuild the DLL from the zlib sources, and link
it the way you want. You should, however, clearly state that
your build is unofficial. You should give it a different file
name, and/or install it in a private directory that can be
accessed by your application only, and is not visible to the
others (i.e. it's neither in the PATH, nor in the SYSTEM or
SYSTEM32 directories). Otherwise, your build may clash with
applications that link to the official build.
For example, in Cygwin, zlib is linked to the Cygwin runtime
CYGWIN1.DLL, and it is distributed under the name CYGZ.DLL.
15. May I include additional pieces of code that I find useful,
link them in ZLIB1.DLL, and export them?
- No. A legitimate build of ZLIB1.DLL must not include code
that does not originate from the official zlib source code.
But you can make your own private DLL build, under a different
file name, as suggested in the previous answer.
For example, zlib is a part of the VCL library, distributed
with Borland Delphi and C++ Builder. The DLL build of VCL
is a redistributable file, named VCLxx.DLL.
16. May I remove some functionality out of ZLIB1.DLL, by enabling
macros like NO_GZCOMPRESS or NO_GZIP at compile time?
- No. A legitimate build of ZLIB1.DLL must provide the complete
zlib functionality, as implemented in the official zlib source
code. But you can make your own private DLL build, under a
different file name, as suggested in the previous answer.
17. I made my own ZLIB1.DLL build. Can I test it for compliance?
- We prefer that you download the official DLL from the zlib
web site. If you need something peculiar from this DLL, you
can send your suggestion to the zlib mailing list.
However, in case you do rebuild the DLL yourself, you can run
it with the test programs found in the DLL distribution.
Running these test programs is not a guarantee of compliance,
but a failure can imply a detected problem.
**
This document is written and maintained by
Cosmin Truta <cosmint@cs.ubbcluj.ro>

110
external/zlib/win32/Makefile.bor vendored Normal file
View File

@@ -0,0 +1,110 @@
# Makefile for zlib
# Borland C++ for Win32
#
# Usage:
# make -f win32/Makefile.bor
# make -f win32/Makefile.bor LOCAL_ZLIB=-DASMV OBJA=match.obj OBJPA=+match.obj
# ------------ Borland C++ ------------
# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or
# added to the declaration of LOC here:
LOC = $(LOCAL_ZLIB)
CC = bcc32
AS = bcc32
LD = bcc32
AR = tlib
CFLAGS = -a -d -k- -O2 $(LOC)
ASFLAGS = $(LOC)
LDFLAGS = $(LOC)
# variables
ZLIB_LIB = zlib.lib
OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
#OBJA =
OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj
OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
#OBJPA=
# targets
all: $(ZLIB_LIB) example.exe minigzip.exe
.c.obj:
$(CC) -c $(CFLAGS) $<
.asm.obj:
$(AS) -c $(ASFLAGS) $<
adler32.obj: adler32.c zlib.h zconf.h
compress.obj: compress.c zlib.h zconf.h
crc32.obj: crc32.c zlib.h zconf.h crc32.h
deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
gzread.obj: gzread.c zlib.h zconf.h gzguts.h
gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
inffast.h inffixed.h
inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
inffast.h
inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
inffast.h inffixed.h
inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
uncompr.obj: uncompr.c zlib.h zconf.h
zutil.obj: zutil.c zutil.h zlib.h zconf.h
example.obj: test/example.c zlib.h zconf.h
minigzip.obj: test/minigzip.c zlib.h zconf.h
# For the sake of the old Borland make,
# the command line is cut to fit in the MS-DOS 128 byte limit:
$(ZLIB_LIB): $(OBJ1) $(OBJ2) $(OBJA)
-del $(ZLIB_LIB)
$(AR) $(ZLIB_LIB) $(OBJP1)
$(AR) $(ZLIB_LIB) $(OBJP2)
$(AR) $(ZLIB_LIB) $(OBJPA)
# testing
test: example.exe minigzip.exe
example
echo hello world | minigzip | minigzip -d
example.exe: example.obj $(ZLIB_LIB)
$(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
minigzip.exe: minigzip.obj $(ZLIB_LIB)
$(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
# cleanup
clean:
-del $(ZLIB_LIB)
-del *.obj
-del *.exe
-del *.tds
-del zlib.bak
-del foo.gz

182
external/zlib/win32/Makefile.gcc vendored Normal file
View File

@@ -0,0 +1,182 @@
# Makefile for zlib, derived from Makefile.dj2.
# Modified for mingw32 by C. Spieler, 6/16/98.
# Updated for zlib 1.2.x by Christian Spieler and Cosmin Truta, Mar-2003.
# Last updated: Mar 2012.
# Tested under Cygwin and MinGW.
# Copyright (C) 1995-2003 Jean-loup Gailly.
# For conditions of distribution and use, see copyright notice in zlib.h
# To compile, or to compile and test, type from the top level zlib directory:
#
# make -fwin32/Makefile.gcc; make test testdll -fwin32/Makefile.gcc
#
# To use the asm code, type:
# cp contrib/asm?86/match.S ./match.S
# make LOC=-DASMV OBJA=match.o -fwin32/Makefile.gcc
#
# To install libz.a, zconf.h and zlib.h in the system directories, type:
#
# make install -fwin32/Makefile.gcc
#
# BINARY_PATH, INCLUDE_PATH and LIBRARY_PATH must be set.
#
# To install the shared lib, append SHARED_MODE=1 to the make command :
#
# make install -fwin32/Makefile.gcc SHARED_MODE=1
# Note:
# If the platform is *not* MinGW (e.g. it is Cygwin or UWIN),
# the DLL name should be changed from "zlib1.dll".
STATICLIB = libz.a
SHAREDLIB = zlib1.dll
IMPLIB = libz.dll.a
#
# Set to 1 if shared object needs to be installed
#
SHARED_MODE=0
#LOC = -DASMV
#LOC = -DDEBUG -g
PREFIX =
CC = $(PREFIX)gcc
CFLAGS = $(LOC) -O3 -Wall
AS = $(CC)
ASFLAGS = $(LOC) -Wall
LD = $(CC)
LDFLAGS = $(LOC)
AR = $(PREFIX)ar
ARFLAGS = rcs
RC = $(PREFIX)windres
RCFLAGS = --define GCC_WINDRES
STRIP = $(PREFIX)strip
CP = cp -fp
# If GNU install is available, replace $(CP) with install.
INSTALL = $(CP)
RM = rm -f
prefix ?= /usr/local
exec_prefix = $(prefix)
OBJS = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \
gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o
OBJA =
all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) example.exe minigzip.exe example_d.exe minigzip_d.exe
test: example.exe minigzip.exe
./example
echo hello world | ./minigzip | ./minigzip -d
testdll: example_d.exe minigzip_d.exe
./example_d
echo hello world | ./minigzip_d | ./minigzip_d -d
.c.o:
$(CC) $(CFLAGS) -c -o $@ $<
.S.o:
$(AS) $(ASFLAGS) -c -o $@ $<
$(STATICLIB): $(OBJS) $(OBJA)
$(AR) $(ARFLAGS) $@ $(OBJS) $(OBJA)
$(IMPLIB): $(SHAREDLIB)
$(SHAREDLIB): win32/zlib.def $(OBJS) $(OBJA) zlibrc.o
$(CC) -shared -Wl,--out-implib,$(IMPLIB) $(LDFLAGS) \
-o $@ win32/zlib.def $(OBJS) $(OBJA) zlibrc.o
$(STRIP) $@
example.exe: example.o $(STATICLIB)
$(LD) $(LDFLAGS) -o $@ example.o $(STATICLIB)
$(STRIP) $@
minigzip.exe: minigzip.o $(STATICLIB)
$(LD) $(LDFLAGS) -o $@ minigzip.o $(STATICLIB)
$(STRIP) $@
example_d.exe: example.o $(IMPLIB)
$(LD) $(LDFLAGS) -o $@ example.o $(IMPLIB)
$(STRIP) $@
minigzip_d.exe: minigzip.o $(IMPLIB)
$(LD) $(LDFLAGS) -o $@ minigzip.o $(IMPLIB)
$(STRIP) $@
example.o: test/example.c zlib.h zconf.h
$(CC) $(CFLAGS) -I. -c -o $@ test/example.c
minigzip.o: test/minigzip.c zlib.h zconf.h
$(CC) $(CFLAGS) -I. -c -o $@ test/minigzip.c
zlibrc.o: win32/zlib1.rc
$(RC) $(RCFLAGS) -o $@ win32/zlib1.rc
.PHONY: install uninstall clean
install: zlib.h zconf.h $(STATICLIB) $(IMPLIB)
@if test -z "$(DESTDIR)$(INCLUDE_PATH)" -o -z "$(DESTDIR)$(LIBRARY_PATH)" -o -z "$(DESTDIR)$(BINARY_PATH)"; then \
echo INCLUDE_PATH, LIBRARY_PATH, and BINARY_PATH must be specified; \
exit 1; \
fi
-@mkdir -p '$(DESTDIR)$(INCLUDE_PATH)'
-@mkdir -p '$(DESTDIR)$(LIBRARY_PATH)' '$(DESTDIR)$(LIBRARY_PATH)'/pkgconfig
-if [ "$(SHARED_MODE)" = "1" ]; then \
mkdir -p '$(DESTDIR)$(BINARY_PATH)'; \
$(INSTALL) $(SHAREDLIB) '$(DESTDIR)$(BINARY_PATH)'; \
$(INSTALL) $(IMPLIB) '$(DESTDIR)$(LIBRARY_PATH)'; \
fi
-$(INSTALL) zlib.h '$(DESTDIR)$(INCLUDE_PATH)'
-$(INSTALL) zconf.h '$(DESTDIR)$(INCLUDE_PATH)'
-$(INSTALL) $(STATICLIB) '$(DESTDIR)$(LIBRARY_PATH)'
sed \
-e 's|@prefix@|${prefix}|g' \
-e 's|@exec_prefix@|${exec_prefix}|g' \
-e 's|@libdir@|$(LIBRARY_PATH)|g' \
-e 's|@sharedlibdir@|$(LIBRARY_PATH)|g' \
-e 's|@includedir@|$(INCLUDE_PATH)|g' \
-e 's|@VERSION@|'`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' zlib.h`'|g' \
zlib.pc.in > '$(DESTDIR)$(LIBRARY_PATH)'/pkgconfig/zlib.pc
uninstall:
-if [ "$(SHARED_MODE)" = "1" ]; then \
$(RM) '$(DESTDIR)$(BINARY_PATH)'/$(SHAREDLIB); \
$(RM) '$(DESTDIR)$(LIBRARY_PATH)'/$(IMPLIB); \
fi
-$(RM) '$(DESTDIR)$(INCLUDE_PATH)'/zlib.h
-$(RM) '$(DESTDIR)$(INCLUDE_PATH)'/zconf.h
-$(RM) '$(DESTDIR)$(LIBRARY_PATH)'/$(STATICLIB)
clean:
-$(RM) $(STATICLIB)
-$(RM) $(SHAREDLIB)
-$(RM) $(IMPLIB)
-$(RM) *.o
-$(RM) *.exe
-$(RM) foo.gz
adler32.o: zlib.h zconf.h
compress.o: zlib.h zconf.h
crc32.o: crc32.h zlib.h zconf.h
deflate.o: deflate.h zutil.h zlib.h zconf.h
gzclose.o: zlib.h zconf.h gzguts.h
gzlib.o: zlib.h zconf.h gzguts.h
gzread.o: zlib.h zconf.h gzguts.h
gzwrite.o: zlib.h zconf.h gzguts.h
inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
inftrees.o: zutil.h zlib.h zconf.h inftrees.h
trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
uncompr.o: zlib.h zconf.h
zutil.o: zutil.h zlib.h zconf.h

163
external/zlib/win32/Makefile.msc vendored Executable file
View File

@@ -0,0 +1,163 @@
# Makefile for zlib using Microsoft (Visual) C
# zlib is copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
#
# Usage:
# nmake -f win32/Makefile.msc (standard build)
# nmake -f win32/Makefile.msc LOC=-DFOO (nonstandard build)
# nmake -f win32/Makefile.msc LOC="-DASMV -DASMINF" \
# OBJA="inffas32.obj match686.obj" (use ASM code, x86)
# nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF -I." \
# OBJA="inffasx64.obj gvmat64.obj inffas8664.obj" (use ASM code, x64)
# The toplevel directory of the source tree.
#
TOP = .
# optional build flags
LOC =
# variables
STATICLIB = zlib.lib
SHAREDLIB = zlib1.dll
IMPLIB = zdll.lib
CC = cl
AS = ml
LD = link
AR = lib
RC = rc
CFLAGS = -nologo -MD -W3 -O2 -Oy- -Zi -Fd"zlib" $(LOC)
WFLAGS = -DHAS_PCLMUL -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE
ASFLAGS = -coff -Zi $(LOC)
LDFLAGS = -nologo -debug -incremental:no -opt:ref
ARFLAGS = -nologo
RCFLAGS = /dWIN32 /r
OBJS = adler32.obj compress.obj crc32_simd.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj \
gzwrite.obj infback.obj inflate.obj inftrees.obj inffast.obj trees.obj uncompr.obj zutil.obj
OBJA =
# targets
all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \
example.exe minigzip.exe example_d.exe minigzip_d.exe
$(STATICLIB): $(OBJS) $(OBJA)
$(AR) $(ARFLAGS) -out:$@ $(OBJS) $(OBJA)
$(IMPLIB): $(SHAREDLIB)
$(SHAREDLIB): $(TOP)/win32/zlib.def $(OBJS) $(OBJA) zlib1.res
$(LD) $(LDFLAGS) -def:$(TOP)/win32/zlib.def -dll -implib:$(IMPLIB) \
-out:$@ -base:0x5A4C0000 $(OBJS) $(OBJA) zlib1.res
if exist $@.manifest \
mt -nologo -manifest $@.manifest -outputresource:$@;2
example.exe: example.obj $(STATICLIB)
$(LD) $(LDFLAGS) example.obj $(STATICLIB)
if exist $@.manifest \
mt -nologo -manifest $@.manifest -outputresource:$@;1
minigzip.exe: minigzip.obj $(STATICLIB)
$(LD) $(LDFLAGS) minigzip.obj $(STATICLIB)
if exist $@.manifest \
mt -nologo -manifest $@.manifest -outputresource:$@;1
example_d.exe: example.obj $(IMPLIB)
$(LD) $(LDFLAGS) -out:$@ example.obj $(IMPLIB)
if exist $@.manifest \
mt -nologo -manifest $@.manifest -outputresource:$@;1
minigzip_d.exe: minigzip.obj $(IMPLIB)
$(LD) $(LDFLAGS) -out:$@ minigzip.obj $(IMPLIB)
if exist $@.manifest \
mt -nologo -manifest $@.manifest -outputresource:$@;1
{$(TOP)}.c.obj:
$(CC) -c $(WFLAGS) $(CFLAGS) $<
{$(TOP)/test}.c.obj:
$(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) $<
{$(TOP)/contrib/masmx64}.c.obj:
$(CC) -c $(WFLAGS) $(CFLAGS) $<
{$(TOP)/contrib/masmx64}.asm.obj:
$(AS) -c $(ASFLAGS) $<
{$(TOP)/contrib/masmx86}.asm.obj:
$(AS) -c $(ASFLAGS) $<
adler32.obj: $(TOP)/adler32.c $(TOP)/zlib.h $(TOP)/zconf.h
compress.obj: $(TOP)/compress.c $(TOP)/zlib.h $(TOP)/zconf.h
crc32.obj: $(TOP)/crc32.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/crc32.h
deflate.obj: $(TOP)/deflate.c $(TOP)/deflate.h $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h
gzclose.obj: $(TOP)/gzclose.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
gzlib.obj: $(TOP)/gzlib.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
gzread.obj: $(TOP)/gzread.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
gzwrite.obj: $(TOP)/gzwrite.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
infback.obj: $(TOP)/infback.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \
$(TOP)/inffast.h $(TOP)/inffixed.h
inffast.obj: $(TOP)/inffast.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \
$(TOP)/inffast.h
inflate.obj: $(TOP)/inflate.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \
$(TOP)/inffast.h $(TOP)/inffixed.h
inftrees.obj: $(TOP)/inftrees.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h
trees.obj: $(TOP)/trees.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/deflate.h $(TOP)/trees.h
uncompr.obj: $(TOP)/uncompr.c $(TOP)/zlib.h $(TOP)/zconf.h
zutil.obj: $(TOP)/zutil.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h
gvmat64.obj: $(TOP)/contrib\masmx64\gvmat64.asm
inffasx64.obj: $(TOP)/contrib\masmx64\inffasx64.asm
inffas8664.obj: $(TOP)/contrib\masmx64\inffas8664.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h \
$(TOP)/inftrees.h $(TOP)/inflate.h $(TOP)/inffast.h
inffas32.obj: $(TOP)/contrib\masmx86\inffas32.asm
match686.obj: $(TOP)/contrib\masmx86\match686.asm
example.obj: $(TOP)/test/example.c $(TOP)/zlib.h $(TOP)/zconf.h
minigzip.obj: $(TOP)/test/minigzip.c $(TOP)/zlib.h $(TOP)/zconf.h
zlib1.res: $(TOP)/win32/zlib1.rc
$(RC) $(RCFLAGS) /fo$@ $(TOP)/win32/zlib1.rc
# testing
test: example.exe minigzip.exe
example
echo hello world | minigzip | minigzip -d
testdll: example_d.exe minigzip_d.exe
example_d
echo hello world | minigzip_d | minigzip_d -d
# cleanup
clean:
-del $(STATICLIB)
-del $(SHAREDLIB)
-del $(IMPLIB)
-del *.obj
-del *.res
-del *.exp
-del *.exe
-del *.pdb
-del *.manifest
-del foo.gz

103
external/zlib/win32/README-WIN32.txt vendored Normal file
View File

@@ -0,0 +1,103 @@
ZLIB DATA COMPRESSION LIBRARY
zlib 1.2.8 is a general purpose data compression library. All the code is
thread safe. The data format used by the zlib library is described by RFCs
(Request for 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).
All functions of the compression library are documented in the file zlib.h
(volunteer to write man pages welcome, contact zlib@gzip.org). Two compiled
examples are distributed in this package, example and minigzip. The example_d
and minigzip_d flavors validate that the zlib1.dll file is working correctly.
Questions about zlib should be sent to <zlib@gzip.org>. The zlib home page
is http://zlib.net/ . Before reporting a problem, please check this site to
verify that you have the latest version of zlib; otherwise get the latest
version and check whether the problem still exists or not.
PLEASE read DLL_FAQ.txt, and the the zlib FAQ http://zlib.net/zlib_faq.html
before asking for help.
Manifest:
The package zlib-1.2.8-win32-x86.zip will contain the following files:
README-WIN32.txt This document
ChangeLog Changes since previous zlib packages
DLL_FAQ.txt Frequently asked questions about zlib1.dll
zlib.3.pdf Documentation of this library in Adobe Acrobat format
example.exe A statically-bound example (using zlib.lib, not the dll)
example.pdb Symbolic information for debugging example.exe
example_d.exe A zlib1.dll bound example (using zdll.lib)
example_d.pdb Symbolic information for debugging example_d.exe
minigzip.exe A statically-bound test program (using zlib.lib, not the dll)
minigzip.pdb Symbolic information for debugging minigzip.exe
minigzip_d.exe A zlib1.dll bound test program (using zdll.lib)
minigzip_d.pdb Symbolic information for debugging minigzip_d.exe
zlib.h Install these files into the compilers' INCLUDE path to
zconf.h compile programs which use zlib.lib or zdll.lib
zdll.lib Install these files into the compilers' LIB path if linking
zdll.exp a compiled program to the zlib1.dll binary
zlib.lib Install these files into the compilers' LIB path to link zlib
zlib.pdb into compiled programs, without zlib1.dll runtime dependency
(zlib.pdb provides debugging info to the compile time linker)
zlib1.dll Install this binary shared library into the system PATH, or
the program's runtime directory (where the .exe resides)
zlib1.pdb Install in the same directory as zlib1.dll, in order to debug
an application crash using WinDbg or similar tools.
All .pdb files above are entirely optional, but are very useful to a developer
attempting to diagnose program misbehavior or a crash. Many additional
important files for developers can be found in the zlib127.zip source package
available from http://zlib.net/ - review that package's README file for details.
Acknowledgments:
The deflate format used by zlib was defined by Phil Katz. The deflate and
zlib specifications were written by L. Peter Deutsch. Thanks to all the
people who reported problems and suggested various improvements in zlib; they
are too numerous to cite here.
Copyright notice:
(C) 1995-2012 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
If you use the zlib library in a product, we would appreciate *not* receiving
lengthy legal documents to sign. The sources are provided for free but without
warranty of any kind. The library has been entirely written by Jean-loup
Gailly and Mark Adler; it does not include third-party code.
If you redistribute modified sources, we would appreciate that you include in
the file ChangeLog history information documenting your changes. Please read
the FAQ for more information on the distribution of modified source versions.

3
external/zlib/win32/VisualC.txt vendored Normal file
View File

@@ -0,0 +1,3 @@
To build zlib using the Microsoft Visual C++ environment,
use the appropriate project from the projects/ directory.

86
external/zlib/win32/zlib.def vendored Normal file
View File

@@ -0,0 +1,86 @@
; zlib data compression library
EXPORTS
; basic functions
zlibVersion
deflate
deflateEnd
inflate
inflateEnd
; advanced functions
deflateSetDictionary
deflateCopy
deflateReset
deflateParams
deflateTune
deflateBound
deflatePending
deflatePrime
deflateSetHeader
inflateSetDictionary
inflateGetDictionary
inflateSync
inflateCopy
inflateReset
inflateReset2
inflatePrime
inflateMark
inflateGetHeader
inflateBack
inflateBackEnd
zlibCompileFlags
; utility functions
compress
compress2
compressBound
uncompress
gzopen
gzdopen
gzbuffer
gzsetparams
gzread
gzwrite
gzprintf
gzvprintf
gzputs
gzgets
gzputc
gzgetc
gzungetc
gzflush
gzseek
gzrewind
gztell
gzoffset
gzeof
gzdirect
gzclose
gzclose_r
gzclose_w
gzerror
gzclearerr
; large file functions
gzopen64
gzseek64
gztell64
gzoffset64
adler32_combine64
crc32_combine64
; checksum functions
adler32
crc32
adler32_combine
crc32_combine
; various hacks, don't look :)
deflateInit_
deflateInit2_
inflateInit_
inflateInit2_
inflateBackInit_
gzgetc_
zError
inflateSyncPoint
get_crc_table
inflateUndermine
inflateResetKeep
deflateResetKeep
gzopen_w

40
external/zlib/win32/zlib1.rc vendored Normal file
View File

@@ -0,0 +1,40 @@
#include <winver.h>
#include "../zlib.h"
#ifdef GCC_WINDRES
VS_VERSION_INFO VERSIONINFO
#else
VS_VERSION_INFO VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
#endif
FILEVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0
PRODUCTVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#ifdef _DEBUG
FILEFLAGS 1
#else
FILEFLAGS 0
#endif
FILEOS VOS__WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE 0 // not used
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4"
//language ID = U.S. English, char set = Windows, Multilingual
BEGIN
VALUE "FileDescription", "zlib data compression library\0"
VALUE "FileVersion", ZLIB_VERSION "\0"
VALUE "InternalName", "zlib1.dll\0"
VALUE "LegalCopyright", "(C) 1995-2013 Jean-loup Gailly & Mark Adler\0"
VALUE "OriginalFilename", "zlib1.dll\0"
VALUE "ProductName", "zlib\0"
VALUE "ProductVersion", ZLIB_VERSION "\0"
VALUE "Comments", "For more information visit http://www.zlib.net/\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0409, 1252
END
END

151
external/zlib/zlib.3 vendored Normal file
View File

@@ -0,0 +1,151 @@
.TH ZLIB 3 "28 Apr 2013"
.SH NAME
zlib \- compression/decompression library
.SH SYNOPSIS
[see
.I zlib.h
for full description]
.SH DESCRIPTION
The
.I zlib
library is a general purpose data compression library.
The code is thread safe, assuming that the standard library functions
used are thread safe, such as memory allocation routines.
It provides in-memory compression and decompression functions,
including integrity checks of the uncompressed data.
This version of the library supports only one compression method (deflation)
but other algorithms may be added later
with the same stream interface.
.LP
Compression can be done in a single step if the buffers are large enough
or can be done by repeated calls of the compression function.
In the latter case,
the application must provide more input and/or consume the output
(providing more output space) before each call.
.LP
The library also supports reading and writing files in
.IR gzip (1)
(.gz) format
with an interface similar to that of stdio.
.LP
The library does not install any signal handler.
The decoder checks the consistency of the compressed data,
so the library should never crash even in the case of corrupted input.
.LP
All functions of the compression library are documented in the file
.IR zlib.h .
The distribution source includes examples of use of the library
in the files
.I test/example.c
and
.IR test/minigzip.c,
as well as other examples in the
.IR examples/
directory.
.LP
Changes to this version are documented in the file
.I ChangeLog
that accompanies the source.
.LP
.I zlib
is available in Java using the java.util.zip package:
.IP
http://java.sun.com/developer/technicalArticles/Programming/compression/
.LP
A Perl interface to
.IR zlib ,
written by Paul Marquess (pmqs@cpan.org),
is available at CPAN (Comprehensive Perl Archive Network) sites,
including:
.IP
http://search.cpan.org/~pmqs/IO-Compress-Zlib/
.LP
A Python interface to
.IR zlib ,
written by A.M. Kuchling (amk@magnet.com),
is available in Python 1.5 and later versions:
.IP
http://docs.python.org/library/zlib.html
.LP
.I zlib
is built into
.IR tcl:
.IP
http://wiki.tcl.tk/4610
.LP
An experimental package to read and write files in .zip format,
written on top of
.I zlib
by Gilles Vollant (info@winimage.com),
is available at:
.IP
http://www.winimage.com/zLibDll/minizip.html
and also in the
.I contrib/minizip
directory of the main
.I zlib
source distribution.
.SH "SEE ALSO"
The
.I zlib
web site can be found at:
.IP
http://zlib.net/
.LP
The data format used by the zlib library is described by RFC
(Request for Comments) 1950 to 1952 in the files:
.IP
http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format)
.br
http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format)
.br
http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format)
.LP
Mark Nelson wrote an article about
.I zlib
for the Jan. 1997 issue of Dr. Dobb's Journal;
a copy of the article is available at:
.IP
http://marknelson.us/1997/01/01/zlib-engine/
.SH "REPORTING PROBLEMS"
Before reporting a problem,
please check the
.I zlib
web site to verify that you have the latest version of
.IR zlib ;
otherwise,
obtain the latest version and see if the problem still exists.
Please read the
.I zlib
FAQ at:
.IP
http://zlib.net/zlib_faq.html
.LP
before asking for help.
Send questions and/or comments to zlib@gzip.org,
or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
.SH AUTHORS
Version 1.2.8
Copyright (C) 1995-2013 Jean-loup Gailly (jloup@gzip.org)
and Mark Adler (madler@alumni.caltech.edu).
.LP
This software is provided "as-is,"
without any express or implied warranty.
In no event will the authors be held liable for any damages
arising from the use of this software.
See the distribution directory with respect to requirements
governing redistribution.
The deflate format used by
.I zlib
was defined by Phil Katz.
The deflate and
.I zlib
specifications were written by L. Peter Deutsch.
Thanks to all the people who reported problems and suggested various
improvements in
.IR zlib ;
who are too numerous to cite here.
.LP
UNIX manual page by R. P. C. Rodgers,
U.S. National Library of Medicine (rodgers@nlm.nih.gov).
.\" end of man page

0
external/zlib/zlib.3.pdf vendored Normal file
View File

View File

13
external/zlib/zlib.pc.cmakein vendored Normal file
View File

@@ -0,0 +1,13 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=@CMAKE_INSTALL_PREFIX@/bin
libdir=@CMAKE_INSTALL_PREFIX@/lib
sharedlibdir=@CMAKE_INSTALL_PREFIX@/lib
includedir=@CMAKE_INSTALL_PREFIX@/include
Name: zlib
Description: zlib compression library
Version: @ZLIB_VERSION@
Requires:
Libs: -L${libdir} -L${sharedlibdir} -lz
Cflags: -I${includedir}

Some files were not shown because too many files have changed in this diff Show More