URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/rtos/ecos-2.0/packages/services/compress/zlib
- from Rev 27 to Rev 174
- ↔ Reverse comparison
Rev 27 → Rev 174
/v2_0/cdl/compress_zlib.cdl
0,0 → 1,149
# ==================================================================== |
# |
# compress_zlib.cdl |
# |
# Zlib compress/decompress configuration data |
# |
# ==================================================================== |
#####ECOSGPLCOPYRIGHTBEGIN#### |
## ------------------------------------------- |
## This file is part of eCos, the Embedded Configurable Operating System. |
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
## |
## eCos is free software; you can redistribute it and/or modify it under |
## the terms of the GNU General Public License as published by the Free |
## Software Foundation; either version 2 or (at your option) any later version. |
## |
## eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
## WARRANTY; without even the implied warranty of MERCHANTABILITY or |
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
## for more details. |
## |
## You should have received a copy of the GNU General Public License along |
## with eCos; if not, write to the Free Software Foundation, Inc., |
## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
## |
## As a special exception, if other files instantiate templates or use macros |
## or inline functions from this file, or you compile this file and link it |
## with other works to produce a work based on this file, this file does not |
## by itself cause the resulting work to be covered by the GNU General Public |
## License. However the source code for this file must still be made available |
## in accordance with section (3) of the GNU General Public License. |
## |
## This exception does not invalidate any other reasons why a work based on |
## this file might be covered by the GNU General Public License. |
## |
## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
## at http://sources.redhat.com/ecos/ecos-license/ |
## ------------------------------------------- |
#####ECOSGPLCOPYRIGHTEND#### |
# ==================================================================== |
######DESCRIPTIONBEGIN#### |
# |
# Author(s): jskov |
# Contributors: |
# Date: 2001-03-06 |
# |
#####DESCRIPTIONEND#### |
# |
# ==================================================================== |
|
cdl_package CYGPKG_COMPRESS_ZLIB { |
display "Zlib compress and decompress package" |
description " |
This package provides support for compression and |
decompression." |
include_dir cyg/compress |
|
requires CYGPKG_ISOINFRA |
requires CYGPKG_CRC |
|
compile infblock.c infcodes.c inffast.c inflate.c |
compile inftrees.c infutil.c adler32.c |
compile zutil.c deflate.c trees.c compress.c uncompr.c |
|
cdl_interface CYGINT_COMPRESS_ZLIB_LOCAL_ALLOC { |
display "Override memory allocation routines." |
} |
|
cdl_option CYGSEM_COMPRESS_ZLIB_NEEDS_MALLOC { |
display "Does this library need malloc?" |
flavor bool |
active_if { CYGINT_COMPRESS_ZLIB_LOCAL_ALLOC == 0 } |
requires CYGPKG_MEMALLOC |
no_define |
default_value 1 |
description " |
This pseudo-option will force the memalloc library to be |
required iff the application does not provide it's own |
infrastructure." |
} |
|
|
# ==================================================================== |
|
cdl_component CYGPKG_COMPRESS_ZLIB_OPTIONS { |
display "Common memory allocator package build options" |
flavor none |
no_define |
description " |
Package specific build options including control over |
compiler flags used only in building this package, |
and details of which tests are built." |
|
cdl_option CYGPKG_COMPRESS_ZLIB_CFLAGS_ADD { |
display "Additional compiler flags" |
flavor data |
no_define |
default_value { "-D__ECOS__ -DNO_ERRNO_H" } |
description " |
This option modifies the set of compiler flags for |
building this package. These flags are used in addition |
to the set of global flags." |
} |
|
cdl_option CYGPKG_COMPRESS_ZLIB_CFLAGS_REMOVE { |
display "Suppressed compiler flags" |
flavor data |
no_define |
default_value { "-Wstrict-prototypes" } |
description " |
This option modifies the set of compiler flags for |
building this package. These flags are removed from |
the set of global flags if present." |
} |
|
cdl_option CYGPKG_COMPRESS_ZLIB_LDFLAGS_ADD { |
display "Additional compiler flags" |
flavor data |
no_define |
default_value { "" } |
description " |
This option modifies the set of compiler flags for |
building this package. These flags are used in addition |
to the set of global flags." |
} |
|
cdl_option CYGPKG_COMPRESS_ZLIB_LDFLAGS_REMOVE { |
display "Suppressed compiler flags" |
flavor data |
no_define |
default_value { "" } |
description " |
This option modifies the set of compiler flags for |
building this package. These flags are removed from |
the set of global flags if present." |
} |
|
} |
|
cdl_option CYGPKG_COMPRESS_ZLIB_TESTS { |
display "zlib tests" |
flavor data |
no_define |
calculated { "tests/zlib1.c tests/zlib2.c" } |
} |
} |
|
# ==================================================================== |
# EOF compress_zlib.cdl |
/v2_0/tests/zlib1.c
0,0 → 1,231
//================================================================= |
// |
// zlib1.c |
// |
// zlib compression/decompression test 1 |
// |
//========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//========================================================================== |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): jskov |
// Contributors: jskov |
// Date: 2001-03-09 |
// Description: Tests zlib compress/decompress functionality. |
//####DESCRIPTIONEND#### |
|
|
#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL |
|
#include <cyg/kernel/kapi.h> |
|
#include <cyg/infra/testcase.h> |
|
#ifdef CYGFUN_KERNEL_API_C |
|
#include <cyg/compress/zlib.h> |
#include <stdlib.h> |
|
#define NTHREADS 1 |
#define STACKSIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL > 8192 ? CYGNUM_HAL_STACK_SIZE_TYPICAL : 8192) |
|
static cyg_handle_t thread[NTHREADS]; |
|
static cyg_thread thread_obj[NTHREADS]; |
static char stack[NTHREADS][STACKSIZE]; |
|
static char license_txt[] = |
"Red Hat eCos Public License v1.1 |
|
|
1. DEFINITIONS |
|
1.1. \"Contributor\" means each entity that creates or |
contributes to the creation of Modifications. |
|
1.2. \"Contributor Version\" means the combination of the |
Original Code, prior Modifications used by a |
Contributor, and the Modifications made by that |
particular Contributor. |
|
1.3. \"Covered Code\" means the Original Code or |
Modifications or the combination of the Original Code |
and Modifications, in each case including portions |
thereof. |
|
1.4. \"Electronic Distribution Mechanism\" means a |
mechanism generally accepted in the software development |
community for the electronic transfer of data. |
|
1.5. \"Executable\" means Covered Code in any form other |
than Source Code. |
1.6. \"Initial Developer\" means the individual or entity |
identified as the Initial Developer in the Source Code |
notice required by Exhibit A. |
|
1.7. \"Larger Work\" means a work which combines Covered |
Code or portions thereof with code not governed by the |
terms of this License. |
|
1.8. \"License\" means this document. |
|
1.9. \"Modifications\" means any addition to or deletion |
from the substance or structure of either the Original |
Code or any previous Modifications. When Covered Code is |
released as a series of files, a Modification is: |
|
A. Any addition to or deletion from the |
contents of a file containing Original Code or |
previous Modifications. |
|
B. Any new file that contains any part of the |
Original Code or previous Modifications. |
|
1.10. \"Original Code\" means Source Code of computer |
software code which is described in the Source Code |
notice required by Exhibit A as Original Code, and |
which, at the time of its release under this License is |
not already Covered Code governed by this License. |
|
1.11. \"Source Code\" means the preferred form of the |
Covered Code for making modifications to it, including |
all modules it contains, plus any associated interface |
definition files, scripts used to control compilation |
and installation of an Executable, or a list of source |
code differential comparisons against either the |
Original Code or another well known, available Covered |
Code of the Contributor's choice. The Source Code can be |
in a compressed or archival form, provided the |
appropriate decompression or de-archiving software is |
widely available for no charge. |
|
1.12. \"You\" means an individual or a legal entity |
exercising rights under, and complying with all of the |
terms of, this License or a future version of this |
License issued under Section 6.1. For legal entities, |
\"You\" includes any entity which controls, is controlled |
by, or is under common control with You. For purposes of |
this definition, \"control\" means (a) the power, direct |
or indirect, to cause the direction or management of |
such entity, whether by contract or otherwise, or (b) |
ownership of fifty percent (50%) or more of the |
outstanding shares or beneficial ownership of such |
entity. |
|
1.13. \"Red Hat Branded Code\" is code that Red Hat |
distributes and/or permits others to distribute under |
different terms than the Red Hat eCos Public License. |
Red Hat's Branded Code may contain part or all of the |
Covered Code. |
"; |
|
static void entry0( cyg_addrword_t data ) |
{ |
int i; |
unsigned long len; |
int err; |
int buf_size = sizeof(license_txt)+512; |
unsigned char* packed = malloc(buf_size); |
unsigned char* unpacked = malloc(buf_size); |
|
if (NULL == packed || NULL == unpacked) |
CYG_TEST_NA("Not enough memory for buffers"); |
|
CYG_TEST_INFO("Compressing"); |
|
len = buf_size; |
err = compress(packed, &len, license_txt, sizeof(license_txt)); |
|
if (Z_OK != err) |
CYG_TEST_NA("Not enough memory for compression"); |
|
|
CYG_TEST_INFO("Decompressing"); |
err = uncompress(unpacked, &buf_size, packed, len); |
|
switch (err) { |
case Z_OK: |
break; |
case Z_MEM_ERROR: |
CYG_TEST_NA("Not enough memory for decompression"); |
break; |
case Z_BUF_ERROR: |
CYG_TEST_FAIL_FINISH("Decompressed data larger than original"); |
break; |
case Z_DATA_ERROR: |
CYG_TEST_FAIL_FINISH("Decompression failed"); |
break; |
default: |
CYG_TEST_FAIL_FINISH("Unknown decompression error"); |
break; |
} |
|
for (i = 0; i < sizeof(license_txt)-1; i++) { |
if (license_txt[i] != unpacked[i]) |
CYG_TEST_FAIL_FINISH("Verify failed"); |
} |
|
CYG_TEST_PASS_FINISH("zlib1 OK"); |
} |
|
void zlib1_main( void ) |
{ |
CYG_TEST_INIT(); |
|
cyg_thread_create(4, entry0 , (cyg_addrword_t)0, "zlib1", |
(void *)stack[0], STACKSIZE,&thread[0], &thread_obj[0]); |
cyg_thread_resume(thread[0]); |
|
cyg_scheduler_start(); |
|
CYG_TEST_FAIL_FINISH("Not reached"); |
} |
|
externC void |
cyg_start( void ) |
{ |
zlib1_main(); |
} |
|
#else /* def CYGFUN_KERNEL_API_C */ |
externC void |
cyg_start( void ) |
{ |
CYG_TEST_INIT(); |
CYG_TEST_NA("Kernel C API layer disabled"); |
} |
#endif /* def CYGFUN_KERNEL_API_C */ |
|
// EOF zlib1.c |
/v2_0/tests/zlib2.c
0,0 → 1,309
//================================================================= |
// |
// zlib2.c |
// |
// zlib decompression test 2 |
// |
//========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//========================================================================== |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): jskov |
// Contributors: jskov |
// Date: 2001-03-09 |
// Description: Tests zlib compression of gz compressed image. |
//####DESCRIPTIONEND#### |
|
|
#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL |
|
#include <cyg/kernel/kapi.h> |
|
#include <cyg/infra/testcase.h> |
|
#ifdef CYGFUN_KERNEL_API_C |
|
#include <cyg/compress/zlib.h> |
#include <stdlib.h> |
|
#define NTHREADS 1 |
#define STACKSIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL > 8192 ? CYGNUM_HAL_STACK_SIZE_TYPICAL : 8192) |
|
static cyg_handle_t thread[NTHREADS]; |
|
static cyg_thread thread_obj[NTHREADS]; |
static char stack[NTHREADS][STACKSIZE]; |
|
|
unsigned char gzip_test[] = { |
0x1f, 0x8b, 0x08, 0x08, 0x23, 0xce, 0xa8, 0x3a, 0x00, 0x03, 0x61, 0x00, 0x8d, 0x56, 0xdb, 0x6e, |
0xe3, 0x36, 0x10, 0x7d, 0xe7, 0x57, 0x10, 0x01, 0x8a, 0x66, 0x01, 0xd7, 0xdd, 0xb4, 0xdd, 0xed, |
0xe5, 0x2d, 0x9b, 0x64, 0xd1, 0x00, 0x7b, 0x29, 0x92, 0x45, 0x17, 0x7d, 0xa4, 0xa9, 0x91, 0x4d, |
0x44, 0x22, 0x55, 0x92, 0xb2, 0x93, 0xbf, 0xdf, 0x33, 0x43, 0x49, 0x96, 0x9c, 0x06, 0xa8, 0x9f, |
0x4c, 0x91, 0x9c, 0x39, 0x33, 0x73, 0xe6, 0x0c, 0xef, 0xa8, 0xd2, 0x7f, 0x9a, 0xac, 0xe9, 0x2a, |
0x24, 0xfd, 0x57, 0xbf, 0x69, 0x9c, 0xd5, 0x1f, 0x9c, 0x25, 0x9f, 0x48, 0xef, 0x2f, 0xd6, 0x17, |
0x0a, 0xbf, 0x8b, 0xb5, 0xbe, 0xbe, 0x79, 0x7f, 0xfb, 0xe9, 0xf6, 0xcb, 0xed, 0xe7, 0x4f, 0xf7, |
0xbc, 0xc6, 0x97, 0xb3, 0xab, 0xe0, 0x73, 0x74, 0x9b, 0x3e, 0x87, 0x78, 0xa6, 0x5b, 0x32, 0x3e, |
0x69, 0x32, 0x76, 0xa7, 0xc9, 0x67, 0x97, 0x9f, 0x74, 0xde, 0xc1, 0xaa, 0x8d, 0x64, 0x32, 0x25, |
0x1d, 0xa2, 0xb2, 0xe3, 0x71, 0x2c, 0x73, 0xc0, 0x36, 0x95, 0x5d, 0x17, 0xbc, 0x0e, 0xb5, 0xfe, |
0x18, 0x2a, 0x57, 0x3b, 0x2b, 0xeb, 0xb4, 0x66, 0x1f, 0x3f, 0x2d, 0x7d, 0xe8, 0xbf, 0x29, 0x26, |
0x6c, 0x8e, 0xbe, 0xc4, 0x40, 0x68, 0x37, 0xce, 0x4f, 0x36, 0xf0, 0x49, 0x7d, 0x8e, 0x6e, 0x8b, |
0x4f, 0x8d, 0xbe, 0x0a, 0x15, 0xad, 0x74, 0x17, 0x1d, 0xae, 0x2e, 0x8c, 0xeb, 0x3e, 0x21, 0xe6, |
0xcd, 0x93, 0x36, 0x6a, 0x66, 0x7e, 0xa5, 0x8d, 0xaf, 0xc4, 0xe8, 0xf2, 0x70, 0x6b, 0x2a, 0xe2, |
0xc3, 0x1c, 0x8e, 0xea, 0x4c, 0xcc, 0xce, 0xf6, 0x8d, 0x89, 0x7a, 0x76, 0x55, 0xd0, 0xfe, 0x2c, |
0x68, 0xf7, 0x14, 0x61, 0x9b, 0x5d, 0xcf, 0x61, 0x2e, 0x30, 0x71, 0x2e, 0x96, 0x2e, 0x00, 0xf0, |
0xbf, 0x83, 0x59, 0x5e, 0x54, 0x0c, 0x70, 0x71, 0x73, 0xa5, 0x9d, 0x2f, 0x39, 0xb7, 0x06, 0xe5, |
0x72, 0xde, 0x36, 0x7d, 0xe5, 0xfc, 0x56, 0x77, 0x21, 0xca, 0x01, 0x05, 0x23, 0x91, 0x42, 0x2d, |
0x08, 0x7f, 0x01, 0xc2, 0x9b, 0x86, 0x6c, 0x8e, 0xc1, 0xa3, 0xc8, 0xd7, 0x2e, 0x95, 0x00, 0xd8, |
0xdf, 0x47, 0xb2, 0x3b, 0xe3, 0x5d, 0x6a, 0x47, 0xd8, 0x46, 0xb5, 0xe3, 0x27, 0xbd, 0x25, 0x4f, |
0xd1, 0x34, 0x0d, 0x32, 0x66, 0x2d, 0x75, 0x19, 0x11, 0xc2, 0x2f, 0xe3, 0x4b, 0xa1, 0xce, 0x07, |
0x13, 0x49, 0x57, 0xb4, 0xa7, 0x26, 0x74, 0x2d, 0x6a, 0x8f, 0x42, 0xb7, 0x6d, 0xef, 0x99, 0x02, |
0xf5, 0x10, 0x19, 0x1d, 0xbd, 0xe6, 0x08, 0xeb, 0x35, 0x45, 0x8e, 0xb0, 0x32, 0xd9, 0x08, 0xb2, |
0x37, 0x8c, 0xec, 0x91, 0x6c, 0x9f, 0xcd, 0xa6, 0x99, 0x32, 0x37, 0xcf, 0x26, 0x3b, 0x34, 0x5e, |
0x2c, 0xb6, 0x3a, 0x70, 0x54, 0x08, 0xcd, 0x78, 0x7d, 0x1f, 0xfa, 0x68, 0x49, 0x8e, 0xac, 0x61, |
0xe8, 0x2d, 0x0c, 0xdd, 0xc2, 0xb5, 0x43, 0xca, 0xae, 0x0b, 0x24, 0x8a, 0xf3, 0x4a, 0x38, 0x5f, |
0xb9, 0xbd, 0xab, 0x7a, 0xec, 0x03, 0x5b, 0x61, 0xaa, 0x72, 0x15, 0xff, 0xa9, 0x1d, 0x7c, 0x99, |
0x72, 0xec, 0x99, 0x8d, 0x31, 0xe0, 0x99, 0x3f, 0xe5, 0x03, 0xb8, 0x40, 0x3a, 0xd2, 0xbf, 0xbd, |
0x8b, 0x85, 0x51, 0x37, 0x8f, 0x3b, 0xb7, 0x71, 0x59, 0x5f, 0x4a, 0x58, 0xbf, 0x02, 0xcd, 0x07, |
0x13, 0xb7, 0xb8, 0xfe, 0x35, 0xc4, 0x87, 0x29, 0xb5, 0xfa, 0x80, 0x95, 0x3e, 0xec, 0x1c, 0x17, |
0x4e, 0x8a, 0x4e, 0x53, 0xb4, 0x6a, 0xa0, 0xc8, 0x54, 0x42, 0x3d, 0x94, 0x50, 0x1f, 0x5c, 0xe6, |
0xe3, 0xd8, 0x85, 0x63, 0xbd, 0xe5, 0xe3, 0xbe, 0x78, 0x65, 0xda, 0x67, 0x8a, 0x6d, 0x2a, 0xb4, |
0x71, 0x69, 0x6c, 0x60, 0x41, 0xf1, 0x1b, 0xa3, 0x28, 0xeb, 0x63, 0x26, 0x70, 0xa6, 0x0a, 0xb6, |
0xe7, 0x7a, 0xc9, 0xa1, 0xdf, 0x71, 0x68, 0x41, 0xad, 0x09, 0x2c, 0x92, 0x6e, 0xaa, 0xca, 0x09, |
0x4b, 0xd0, 0xb6, 0x40, 0x56, 0xa1, 0x9c, 0xbc, 0x54, 0x75, 0x0c, 0x6d, 0xa1, 0x41, 0xbf, 0x49, |
0xd9, 0x78, 0x2b, 0xc0, 0xc1, 0xaa, 0xde, 0xe6, 0x1e, 0xa4, 0x00, 0x1a, 0x72, 0x0c, 0x7f, 0xc1, |
0xe5, 0x29, 0x42, 0x36, 0xdd, 0x45, 0xda, 0xbb, 0xd0, 0xa7, 0x93, 0xf6, 0xd7, 0x5f, 0x77, 0xe4, |
0x4f, 0x08, 0x90, 0x54, 0x84, 0x63, 0x93, 0x4a, 0x95, 0x8c, 0x4e, 0x14, 0x1d, 0x49, 0xc8, 0xb5, |
0x6b, 0x08, 0xbd, 0x60, 0x16, 0x46, 0x70, 0xe1, 0x0f, 0xa5, 0x34, 0xff, 0x2e, 0xd7, 0xfa, 0xf2, |
0xe5, 0x30, 0xf4, 0x18, 0x46, 0x39, 0xcc, 0x32, 0x85, 0xac, 0x88, 0x61, 0x23, 0xa6, 0xe5, 0x93, |
0x71, 0x9e, 0x1b, 0xeb, 0x59, 0x27, 0xcb, 0x9d, 0x17, 0xa2, 0x18, 0xdc, 0xbf, 0x2b, 0xee, 0x3d, |
0x1d, 0x8a, 0xb9, 0x22, 0x8c, 0xc5, 0x66, 0x49, 0x30, 0xcb, 0xca, 0xa8, 0x5f, 0x72, 0xe5, 0xd4, |
0xcd, 0xcb, 0x1e, 0x20, 0xc5, 0xaf, 0x51, 0xbb, 0xc5, 0x85, 0xb1, 0x76, 0x33, 0xb2, 0xb2, 0x75, |
0x50, 0xad, 0x83, 0xfa, 0x46, 0x35, 0x75, 0xad, 0xb0, 0xa9, 0xf0, 0x90, 0x09, 0x41, 0xc9, 0x42, |
0x10, 0x8e, 0xdd, 0xfd, 0x7f, 0xc9, 0xce, 0xf5, 0x38, 0x91, 0x5d, 0x48, 0x95, 0x12, 0xc3, 0xf8, |
0x9b, 0xc5, 0x58, 0x76, 0xad, 0xa0, 0x70, 0x48, 0xed, 0x50, 0x48, 0xdd, 0xfb, 0x4a, 0xc8, 0x71, |
0x64, 0x2c, 0x97, 0x99, 0xe9, 0x6d, 0x1a, 0x8c, 0x86, 0xea, 0x69, 0x49, 0x81, 0x25, 0xe7, 0x4f, |
0x68, 0x7e, 0xc1, 0x23, 0x69, 0x86, 0x78, 0xde, 0xf5, 0xc8, 0x1e, 0x24, 0x87, 0xed, 0x14, 0xfd, |
0x28, 0x99, 0x5e, 0xd8, 0x66, 0xa9, 0x6a, 0xcd, 0x03, 0xd7, 0xb8, 0x5d, 0x88, 0x33, 0xc8, 0xe2, |
0xf2, 0xea, 0xa8, 0xad, 0x0a, 0x42, 0xc8, 0x47, 0x7a, 0x70, 0x0e, 0x3b, 0x53, 0x21, 0x31, 0x6a, |
0x9a, 0x7e, 0xe8, 0x97, 0x94, 0x82, 0x75, 0xa6, 0xe8, 0x24, 0x12, 0x5e, 0x1b, 0x4b, 0xaa, 0xa2, |
0xda, 0xf9, 0xc2, 0xbf, 0x81, 0xaf, 0x9c, 0xed, 0x2e, 0x0f, 0xe3, 0x08, 0x6e, 0x64, 0x40, 0x86, |
0x46, 0xea, 0xe4, 0x1a, 0x71, 0x2f, 0x92, 0x0f, 0xe3, 0x19, 0x4e, 0xa7, 0xc1, 0x00, 0xd9, 0x3b, |
0x8a, 0xe5, 0x4a, 0x3a, 0x49, 0x37, 0x10, 0x73, 0xde, 0x4b, 0x92, 0x00, 0x25, 0x85, 0x45, 0x14, |
0x88, 0x9a, 0xa5, 0xcd, 0x14, 0xa3, 0x26, 0xba, 0xc4, 0x21, 0x99, 0x2d, 0x03, 0xce, 0xb3, 0xe6, |
0x54, 0xcf, 0x08, 0x67, 0xbc, 0xa8, 0xac, 0x3e, 0x10, 0xc2, 0x7d, 0xf0, 0xe1, 0xe0, 0x51, 0xc9, |
0xbd, 0x01, 0x2e, 0x38, 0x3d, 0x11, 0xab, 0x32, 0xab, 0x66, 0x03, 0xf1, 0xfb, 0xa4, 0xed, 0x2e, |
0xa0, 0x38, 0x6b, 0xfd, 0x65, 0xc9, 0x23, 0x0c, 0x2a, 0xaf, 0x37, 0xa4, 0x58, 0xce, 0x05, 0x53, |
0xa4, 0xc4, 0xe1, 0xb3, 0xc7, 0x68, 0x77, 0x6e, 0x0f, 0x08, 0x5c, 0x23, 0x1e, 0xdc, 0x01, 0x42, |
0x4d, 0x32, 0x92, 0x95, 0xe9, 0xb0, 0xc4, 0x28, 0x47, 0x4e, 0x41, 0xd3, 0xf1, 0x9e, 0xe4, 0x83, |
0x1b, 0xf9, 0x87, 0x72, 0x97, 0x8b, 0x37, 0x71, 0x1b, 0x44, 0x3a, 0xe0, 0x3e, 0x0f, 0xad, 0x09, |
0x36, 0x17, 0xd9, 0x23, 0xd1, 0x3b, 0x16, 0xe5, 0xc2, 0x1a, 0x7e, 0x64, 0xfc, 0x13, 0xfa, 0xa3, |
0xdc, 0x9d, 0x8c, 0x08, 0xa4, 0x96, 0xb6, 0xf8, 0x3b, 0x8c, 0x0a, 0x7a, 0xa4, 0x68, 0x5d, 0x62, |
0x4f, 0xc8, 0xd8, 0x8e, 0xab, 0xc7, 0x1c, 0x2e, 0x8f, 0x07, 0xc6, 0xd5, 0x3c, 0xf1, 0x9e, 0x68, |
0x35, 0x13, 0x65, 0xa0, 0xda, 0xa8, 0xce, 0xab, 0x25, 0xd9, 0xc5, 0x7e, 0xdd, 0x8b, 0x58, 0xee, |
0xcb, 0xeb, 0x66, 0x94, 0x70, 0x75, 0x6c, 0x88, 0xd4, 0x23, 0x0b, 0xa5, 0x55, 0xee, 0x31, 0x47, |
0xf9, 0xd0, 0x5b, 0x7e, 0x80, 0xbd, 0xc7, 0xf5, 0x19, 0x38, 0x88, 0xe1, 0x4a, 0x95, 0x58, 0x0a, |
0x59, 0xa9, 0xb0, 0x71, 0x78, 0x8e, 0x8d, 0xe3, 0x46, 0x38, 0xc6, 0x2f, 0x87, 0x34, 0x2e, 0x1a, |
0x14, 0x72, 0xf3, 0x24, 0x44, 0x72, 0x43, 0x3c, 0x1c, 0x4a, 0x0b, 0x3f, 0x23, 0x25, 0x25, 0x1e, |
0x98, 0x2e, 0x4e, 0xbb, 0x3e, 0x76, 0x21, 0x89, 0xf6, 0xaa, 0x32, 0x4a, 0x26, 0x6e, 0xaf, 0xf4, |
0xd9, 0x70, 0x67, 0xcc, 0xe8, 0xb9, 0x79, 0x55, 0x7a, 0x30, 0x1c, 0x38, 0x4f, 0x15, 0xd4, 0xc3, |
0x66, 0xc5, 0xbe, 0x7c, 0xf9, 0xbf, 0x12, 0xee, 0x1b, 0x74, 0x81, 0x9c, 0x2b, 0x1f, 0x87, 0xd2, |
0xb6, 0xc6, 0x9b, 0x2d, 0xf1, 0x94, 0x62, 0x5f, 0xa9, 0x9f, 0x5e, 0x97, 0x2b, 0xc4, 0x43, 0x42, |
0x50, 0x68, 0x81, 0x78, 0x34, 0x36, 0xf3, 0x0d, 0x61, 0xed, 0xc1, 0xa5, 0xd2, 0x18, 0xe7, 0x9b, |
0x57, 0x0a, 0xd4, 0x45, 0x6a, 0x77, 0xae, 0x2b, 0xa3, 0xa2, 0x46, 0x2e, 0x30, 0xd0, 0x2d, 0xdb, |
0x3c, 0x7f, 0xf3, 0xfa, 0xbb, 0x57, 0xe2, 0x27, 0xc4, 0x91, 0xc7, 0x2a, 0xf4, 0x99, 0x87, 0x99, |
0xbc, 0xa3, 0x12, 0x98, 0x22, 0xaf, 0x57, 0x70, 0xd6, 0x23, 0x48, 0xcb, 0xad, 0xb4, 0x30, 0xc8, |
0x98, 0x54, 0xc1, 0x54, 0x08, 0xc5, 0xef, 0xc0, 0xbb, 0xe1, 0x4d, 0xfd, 0x0e, 0x8f, 0x9d, 0x6a, |
0x7a, 0x0f, 0x4a, 0xc6, 0xab, 0x41, 0xff, 0x87, 0x23, 0xaa, 0x1a, 0x5f, 0x61, 0x52, 0xad, 0xea, |
0x47, 0x4e, 0x2f, 0xc8, 0xc2, 0x2a, 0x29, 0xa1, 0x88, 0x00, 0x1d, 0x0f, 0x95, 0xf2, 0xa8, 0xa9, |
0xb5, 0x75, 0x61, 0x96, 0xbc, 0x85, 0x38, 0x7b, 0x77, 0x2f, 0xbf, 0xe6, 0xd7, 0x6a, 0xd8, 0x44, |
0x77, 0xce, 0x81, 0x21, 0xc9, 0x4f, 0xa3, 0x8a, 0x0d, 0x93, 0x28, 0xce, 0xb9, 0x3b, 0x97, 0xc9, |
0xb5, 0xfa, 0x06, 0x64, 0xed, 0xaa, 0x07, 0x2f, 0x0c, 0x00}; |
|
unsigned char gzip_test_ref[] = |
"Red Hat eCos Public License v1.1 |
|
|
|
1. DEFINITIONS |
|
1.1. \"Contributor\" means each entity that creates or |
contributes to the creation of Modifications. |
|
1.2. \"Contributor Version\" means the combination of the |
Original Code, prior Modifications used by a |
Contributor, and the Modifications made by that |
particular Contributor. |
|
1.3. \"Covered Code\" means the Original Code or |
Modifications or the combination of the Original Code |
and Modifications, in each case including portions |
thereof. |
|
1.4. \"Electronic Distribution Mechanism\" means a |
mechanism generally accepted in the software development |
community for the electronic transfer of data. |
|
1.5. \"Executable\" means Covered Code in any form other |
than Source Code. |
1.6. \"Initial Developer\" means the individual or entity |
identified as the Initial Developer in the Source Code |
notice required by Exhibit A. |
|
1.7. \"Larger Work\" means a work which combines Covered |
Code or portions thereof with code not governed by the |
terms of this License. |
|
1.8. \"License\" means this document. |
|
1.9. \"Modifications\" means any addition to or deletion |
from the substance or structure of either the Original |
Code or any previous Modifications. When Covered Code is |
released as a series of files, a Modification is: |
|
A. Any addition to or deletion from the |
contents of a file containing Original Code or |
previous Modifications. |
|
B. Any new file that contains any part of the |
Original Code or previous Modifications. |
|
1.10. \"Original Code\" means Source Code of computer |
software code which is described in the Source Code |
notice required by Exhibit A as Original Code, and |
which, at the time of its release under this License is |
not already Covered Code governed by this License. |
|
1.11. \"Source Code\" means the preferred form of the |
Covered Code for making modifications to it, including |
all modules it contains, plus any associated interface |
definition files, scripts used to control compilation |
and installation of an Executable, or a list of source |
code differential comparisons against either the |
Original Code or another well known, available Covered |
Code of the Contributor's choice. The Source Code can be |
in a compressed or archival form, provided the |
appropriate decompression or de-archiving software is |
widely available for no charge. |
|
1.12. \"You\" means an individual or a legal entity |
exercising rights under, and complying with all of the |
terms of, this License or a future version of this |
License issued under Section 6.1. For legal entities, |
\"You\" includes any entity which controls, is controlled |
by, or is under common control with You. For purposes of |
this definition, \"control\" means (a) the power, direct |
or indirect, to cause the direction or management of |
such entity, whether by contract or otherwise, or (b) |
ownership of fifty percent (50%) or more of the |
outstanding shares or beneficial ownership of such |
entity. |
|
1.13. \"Red Hat Branded Code\" is code that Red Hat |
distributes and/or permits others to distribute under |
different terms than the Red Hat eCos Public License. |
Red Hat's Branded Code may contain part or all of the |
Covered Code. |
"; |
|
static void entry0( cyg_addrword_t data ) |
{ |
int i; |
unsigned long len; |
int err; |
int buf_size = sizeof(gzip_test_ref)+512; |
unsigned char* unpacked = malloc(buf_size); |
|
if (NULL == unpacked) |
CYG_TEST_NA("Not enough memory for buffers"); |
|
CYG_TEST_INFO("Decompressing"); |
len = buf_size; |
err = uncompress(unpacked, &len, gzip_test, sizeof(gzip_test)); |
|
switch (err) { |
case Z_OK: |
break; |
case Z_MEM_ERROR: |
CYG_TEST_NA("Not enough memory for decompression"); |
break; |
case Z_BUF_ERROR: |
CYG_TEST_FAIL_FINISH("Decompressed data larger than original"); |
break; |
case Z_DATA_ERROR: |
CYG_TEST_FAIL_FINISH("Decompression failed"); |
break; |
default: |
CYG_TEST_FAIL_FINISH("Unknown decompression error"); |
break; |
} |
|
for (i = 0; i < sizeof(gzip_test_ref)-1; i++) { |
if (gzip_test_ref[i] != unpacked[i]) |
CYG_TEST_FAIL_FINISH("Verify failed"); |
} |
|
CYG_TEST_PASS_FINISH("zlib2 OK"); |
} |
|
void zlib2_main( void ) |
{ |
CYG_TEST_INIT(); |
|
cyg_thread_create(4, entry0 , (cyg_addrword_t)0, "zlib1", |
(void *)stack[0], STACKSIZE,&thread[0], &thread_obj[0]); |
cyg_thread_resume(thread[0]); |
|
cyg_scheduler_start(); |
|
CYG_TEST_FAIL_FINISH("Not reached"); |
} |
|
externC void |
cyg_start( void ) |
{ |
zlib2_main(); |
} |
|
#else /* def CYGFUN_KERNEL_API_C */ |
externC void |
cyg_start( void ) |
{ |
CYG_TEST_INIT(); |
CYG_TEST_NA("Kernel C API layer disabled"); |
} |
#endif /* def CYGFUN_KERNEL_API_C */ |
|
// EOF zlib1.c |
/v2_0/include/zconf.h
0,0 → 1,288
/* zconf.h -- configuration of the zlib compression library |
* Copyright (C) 1995-1998 Jean-loup Gailly. |
* For conditions of distribution and use, see copyright notice in zlib.h |
*/ |
|
/* @(#) $Id: zconf.h,v 1.1.1.1 2004-02-14 13:35:40 phoenix Exp $ */ |
|
#ifndef _ZCONF_H |
#define _ZCONF_H |
|
/* |
* If you *really* need a unique prefix for all types and library functions, |
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. |
*/ |
#ifdef Z_PREFIX |
# define deflateInit_ z_deflateInit_ |
# define deflate z_deflate |
# define deflateEnd z_deflateEnd |
# define inflateInit_ z_inflateInit_ |
# define inflate z_inflate |
# define inflateEnd z_inflateEnd |
# define deflateInit2_ z_deflateInit2_ |
# define deflateSetDictionary z_deflateSetDictionary |
# define deflateCopy z_deflateCopy |
# define deflateReset z_deflateReset |
# define deflateParams z_deflateParams |
# define inflateInit2_ z_inflateInit2_ |
# define inflateSetDictionary z_inflateSetDictionary |
# define inflateSync z_inflateSync |
# define inflateSyncPoint z_inflateSyncPoint |
# define inflateReset z_inflateReset |
# define compress z_compress |
# define compress2 z_compress2 |
# define uncompress z_uncompress |
# define adler32 z_adler32 |
# define crc32 z_crc32 |
# define get_crc_table z_get_crc_table |
|
# define Byte z_Byte |
# define uInt z_uInt |
# define uLong z_uLong |
# define Bytef z_Bytef |
# define charf z_charf |
# define intf z_intf |
# define uIntf z_uIntf |
# define uLongf z_uLongf |
# define voidpf z_voidpf |
# define voidp z_voidp |
#endif |
|
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) |
# define WIN32 |
#endif |
#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) |
# ifndef __32BIT__ |
# define __32BIT__ |
# endif |
#endif |
#if defined(__MSDOS__) && !defined(MSDOS) |
# define MSDOS |
#endif |
|
/* |
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more |
* than 64k bytes at a time (needed on systems with 16-bit int). |
*/ |
#if defined(MSDOS) && !defined(__32BIT__) |
# define MAXSEG_64K |
#endif |
#ifdef MSDOS |
# define UNALIGNED_OK |
#endif |
|
#ifndef __ECOS__ |
#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) |
# define STDC |
#endif |
#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__) |
# ifndef STDC |
# define STDC |
# endif |
#endif |
#endif // __ECOS__ |
|
#ifndef STDC |
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ |
# define const |
# endif |
#endif |
|
/* Some Mac compilers merge all .h files incorrectly: */ |
#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) |
# define NO_DUMMY_DECL |
#endif |
|
/* Old Borland C incorrectly complains about missing returns: */ |
#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500) |
# define NEED_DUMMY_RETURN |
#endif |
|
|
/* Maximum value for memLevel in deflateInit2 */ |
#ifndef MAX_MEM_LEVEL |
# ifdef MAXSEG_64K |
# define MAX_MEM_LEVEL 8 |
# else |
# define MAX_MEM_LEVEL 9 |
# endif |
#endif |
|
/* Maximum value for windowBits in deflateInit2 and inflateInit2. |
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files |
* created by gzip. (Files created by minigzip can still be extracted by |
* gzip.) |
*/ |
#ifndef MAX_WBITS |
# define MAX_WBITS 15 /* 32K LZ77 window */ |
#endif |
|
/* The memory requirements for deflate are (in bytes): |
(1 << (windowBits+2)) + (1 << (memLevel+9)) |
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) |
plus a few kilobytes for small objects. For example, if you want to reduce |
the default memory requirements from 256K to 128K, compile with |
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" |
Of course this will generally degrade compression (there's no free lunch). |
|
The memory requirements for inflate are (in bytes) 1 << windowBits |
that is, 32K for windowBits=15 (default value) plus a few kilobytes |
for small objects. |
*/ |
|
/* Type declarations */ |
|
#ifndef OF /* function prototypes */ |
# ifdef STDC |
# define OF(args) args |
# else |
# define OF(args) () |
# endif |
#endif |
|
/* The following definitions for FAR are needed only for MSDOS mixed |
* model programming (small or medium model with some far allocations). |
* This was tested only with MSC; for other MSDOS compilers you may have |
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model, |
* just define FAR to be empty. |
*/ |
#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) |
/* MSC small or medium model */ |
# define SMALL_MEDIUM |
# ifdef _MSC_VER |
# define FAR _far |
# else |
# define FAR far |
# endif |
#endif |
#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) |
# ifndef __32BIT__ |
# define SMALL_MEDIUM |
# define FAR _far |
# endif |
#endif |
|
/* Compile with -DZLIB_DLL for Windows DLL support */ |
#if defined(ZLIB_DLL) |
# if defined(_WINDOWS) || defined(WINDOWS) |
# ifdef FAR |
# undef FAR |
# endif |
# include <windows.h> |
# define ZEXPORT WINAPI |
# ifdef WIN32 |
# define ZEXPORTVA WINAPIV |
# else |
# define ZEXPORTVA FAR _cdecl _export |
# endif |
# endif |
# if defined (__BORLANDC__) |
# if (__BORLANDC__ >= 0x0500) && defined (WIN32) |
# include <windows.h> |
# define ZEXPORT __declspec(dllexport) WINAPI |
# define ZEXPORTRVA __declspec(dllexport) WINAPIV |
# else |
# if defined (_Windows) && defined (__DLL__) |
# define ZEXPORT _export |
# define ZEXPORTVA _export |
# endif |
# endif |
# endif |
#endif |
|
#if defined (__BEOS__) |
# if defined (ZLIB_DLL) |
# define ZEXTERN extern __declspec(dllexport) |
# else |
# define ZEXTERN extern __declspec(dllimport) |
# endif |
#endif |
|
#ifndef ZEXPORT |
# define ZEXPORT |
#endif |
#ifndef ZEXPORTVA |
# define ZEXPORTVA |
#endif |
#ifndef ZEXTERN |
# define ZEXTERN extern |
#endif |
|
#ifndef FAR |
# define FAR |
#endif |
|
#if !defined(MACOS) && !defined(TARGET_OS_MAC) |
typedef unsigned char Byte; /* 8 bits */ |
#endif |
typedef unsigned int uInt; /* 16 bits or more */ |
typedef unsigned long uLong; /* 32 bits or more */ |
|
#ifdef SMALL_MEDIUM |
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ |
# define Bytef Byte FAR |
#else |
typedef Byte FAR Bytef; |
#endif |
typedef char FAR charf; |
typedef int FAR intf; |
typedef uInt FAR uIntf; |
typedef uLong FAR uLongf; |
|
#ifdef STDC |
typedef void FAR *voidpf; |
typedef void *voidp; |
#else |
typedef Byte FAR *voidpf; |
typedef Byte *voidp; |
#endif |
|
#ifdef HAVE_UNISTD_H |
# include <sys/types.h> /* for off_t */ |
# include <unistd.h> /* for SEEK_* and off_t */ |
# define z_off_t off_t |
#endif |
#ifndef SEEK_SET |
# define SEEK_SET 0 /* Seek from beginning of file. */ |
# define SEEK_CUR 1 /* Seek from current position. */ |
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ |
#endif |
#ifndef z_off_t |
# define z_off_t long |
#endif |
|
/* MVS linker does not support external names larger than 8 bytes */ |
#if defined(__MVS__) |
# pragma map(deflateInit_,"DEIN") |
# pragma map(deflateInit2_,"DEIN2") |
# pragma map(deflateEnd,"DEEND") |
# pragma map(inflateInit_,"ININ") |
# pragma map(inflateInit2_,"ININ2") |
# pragma map(inflateEnd,"INEND") |
# pragma map(inflateSync,"INSY") |
# pragma map(inflateSetDictionary,"INSEDI") |
# pragma map(inflate_blocks,"INBL") |
# pragma map(inflate_blocks_new,"INBLNE") |
# pragma map(inflate_blocks_free,"INBLFR") |
# pragma map(inflate_blocks_reset,"INBLRE") |
# pragma map(inflate_codes_free,"INCOFR") |
# pragma map(inflate_codes,"INCO") |
# pragma map(inflate_fast,"INFA") |
# pragma map(inflate_flush,"INFLU") |
# pragma map(inflate_mask,"INMA") |
# pragma map(inflate_set_dictionary,"INSEDI2") |
# pragma map(inflate_copyright,"INCOPY") |
# pragma map(inflate_trees_bits,"INTRBI") |
# pragma map(inflate_trees_dynamic,"INTRDY") |
# pragma map(inflate_trees_fixed,"INTRFI") |
# pragma map(inflate_trees_free,"INTRFR") |
#endif |
|
#ifdef __ECOS__ |
#include <pkgconf/compress_zlib.h> |
#if CYGINT_COMPRESS_ZLIB_LOCAL_ALLOC != 0 |
#define MY_ZCALLOC |
#endif |
#endif |
|
#endif /* _ZCONF_H */ |
/v2_0/include/zlib.h
0,0 → 1,895
/* zlib.h -- interface of the 'zlib' general purpose compression library |
version 1.1.3, July 9th, 1998 |
|
Copyright (C) 1995-1998 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 |
|
|
The data format used by the zlib library is described by RFCs (Request for |
Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt |
(zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). |
*/ |
|
#ifndef _ZLIB_H |
#define _ZLIB_H |
|
#include "zconf.h" |
|
#ifdef __cplusplus |
extern "C" { |
#endif |
|
#define ZLIB_VERSION "1.1.3" |
|
/* |
The 'zlib' compression library 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 will be added later and will have the same |
stream interface. |
|
Compression can be done in a single step if the buffers are large |
enough (for example if an input file is mmap'ed), 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. |
|
The library also supports reading and writing files in gzip (.gz) format |
with an interface similar to that of stdio. |
|
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 case of corrupted input. |
*/ |
|
typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); |
typedef void (*free_func) OF((voidpf opaque, voidpf address)); |
|
struct internal_state; |
|
typedef struct z_stream_s { |
Bytef *next_in; /* next input byte */ |
uInt avail_in; /* number of bytes available at next_in */ |
uLong total_in; /* total nb of input bytes read so far */ |
|
Bytef *next_out; /* next output byte should be put there */ |
uInt avail_out; /* remaining free space at next_out */ |
uLong total_out; /* total nb of bytes output so far */ |
|
char *msg; /* last error message, NULL if no error */ |
struct internal_state FAR *state; /* not visible by applications */ |
|
alloc_func zalloc; /* used to allocate the internal state */ |
free_func zfree; /* used to free the internal state */ |
voidpf opaque; /* private data object passed to zalloc and zfree */ |
|
int data_type; /* best guess about the data type: ascii or binary */ |
uLong adler; /* adler32 value of the uncompressed data */ |
uLong reserved; /* reserved for future use */ |
} z_stream; |
|
typedef z_stream FAR *z_streamp; |
|
/* |
The application must update next_in and avail_in when avail_in has |
dropped to zero. It must update next_out and avail_out when avail_out |
has dropped to zero. The application must initialize zalloc, zfree and |
opaque before calling the init function. All other fields are set by the |
compression library and must not be updated by the application. |
|
The opaque value provided by the application will be passed as the first |
parameter for calls of zalloc and zfree. This can be useful for custom |
memory management. The compression library attaches no meaning to the |
opaque value. |
|
zalloc must return Z_NULL if there is not enough memory for the object. |
If zlib is used in a multi-threaded application, zalloc and zfree must be |
thread safe. |
|
On 16-bit systems, the functions zalloc and zfree must be able to allocate |
exactly 65536 bytes, but will not be required to allocate more than this |
if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, |
pointers returned by zalloc for objects of exactly 65536 bytes *must* |
have their offset normalized to zero. The default allocation function |
provided by this library ensures this (see zutil.c). To reduce memory |
requirements and avoid any allocation of 64K objects, at the expense of |
compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). |
|
The fields total_in and total_out can be used for statistics or |
progress reports. After compression, total_in holds the total size of |
the uncompressed data and may be saved for use in the decompressor |
(particularly if the decompressor wants to decompress everything in |
a single step). |
*/ |
|
/* constants */ |
|
#define Z_NO_FLUSH 0 |
#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ |
#define Z_SYNC_FLUSH 2 |
#define Z_FULL_FLUSH 3 |
#define Z_FINISH 4 |
/* Allowed flush values; see deflate() below for details */ |
|
#define Z_OK 0 |
#define Z_STREAM_END 1 |
#define Z_NEED_DICT 2 |
#define Z_ERRNO (-1) |
#define Z_STREAM_ERROR (-2) |
#define Z_DATA_ERROR (-3) |
#define Z_MEM_ERROR (-4) |
#define Z_BUF_ERROR (-5) |
#define Z_VERSION_ERROR (-6) |
/* Return codes for the compression/decompression functions. Negative |
* values are errors, positive values are used for special but normal events. |
*/ |
|
#define Z_NO_COMPRESSION 0 |
#define Z_BEST_SPEED 1 |
#define Z_BEST_COMPRESSION 9 |
#define Z_DEFAULT_COMPRESSION (-1) |
/* compression levels */ |
|
#define Z_FILTERED 1 |
#define Z_HUFFMAN_ONLY 2 |
#define Z_DEFAULT_STRATEGY 0 |
/* compression strategy; see deflateInit2() below for details */ |
|
#define Z_BINARY 0 |
#define Z_ASCII 1 |
#define Z_UNKNOWN 2 |
/* Possible values of the data_type field */ |
|
#define Z_DEFLATED 8 |
/* The deflate compression method (the only one supported in this version) */ |
|
#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ |
|
#define zlib_version zlibVersion() |
/* for compatibility with versions < 1.0.2 */ |
|
/* basic functions */ |
|
ZEXTERN const char * ZEXPORT zlibVersion OF((void)); |
/* The application can compare zlibVersion and ZLIB_VERSION for consistency. |
If the first character differs, the library code actually used is |
not compatible with the zlib.h header file used by the application. |
This check is automatically made by deflateInit and inflateInit. |
*/ |
|
/* |
ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); |
|
Initializes the internal stream state for compression. The fields |
zalloc, zfree and opaque must be initialized before by the caller. |
If zalloc and zfree are set to Z_NULL, deflateInit updates them to |
use default allocation functions. |
|
The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: |
1 gives best speed, 9 gives best compression, 0 gives no compression at |
all (the input data is simply copied a block at a time). |
Z_DEFAULT_COMPRESSION requests a default compromise between speed and |
compression (currently equivalent to level 6). |
|
deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not |
enough memory, Z_STREAM_ERROR if level is not a valid compression level, |
Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible |
with the version assumed by the caller (ZLIB_VERSION). |
msg is set to null if there is no error message. deflateInit does not |
perform any compression: this will be done by deflate(). |
*/ |
|
|
ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); |
/* |
deflate compresses as much data as possible, and stops when the input |
buffer becomes empty or the output buffer becomes full. It may introduce some |
output latency (reading input without producing any output) except when |
forced to flush. |
|
The detailed semantics are as follows. deflate performs one or both of the |
following actions: |
|
- Compress more input starting at next_in and update next_in and avail_in |
accordingly. If not all input can be processed (because there is not |
enough room in the output buffer), next_in and avail_in are updated and |
processing will resume at this point for the next call of deflate(). |
|
- Provide more output starting at next_out and update next_out and avail_out |
accordingly. This action is forced if the parameter flush is non zero. |
Forcing flush frequently degrades the compression ratio, so this parameter |
should be set only when necessary (in interactive applications). |
Some output may be provided even if flush is not set. |
|
Before the call of deflate(), the application should ensure that at least |
one of the actions is possible, by providing more input and/or consuming |
more output, and updating avail_in or avail_out accordingly; avail_out |
should never be zero before the call. The application can consume the |
compressed output when it wants, for example when the output buffer is full |
(avail_out == 0), or after each call of deflate(). If deflate returns Z_OK |
and with zero avail_out, it must be called again after making room in the |
output buffer because there might be more output pending. |
|
If the parameter flush is set to Z_SYNC_FLUSH, all pending output is |
flushed to the output buffer and the output is aligned on a byte boundary, so |
that the decompressor can get all input data available so far. (In particular |
avail_in is zero after the call if enough output space has been provided |
before the call.) Flushing may degrade compression for some compression |
algorithms and so it should be used only when necessary. |
|
If flush is set to Z_FULL_FLUSH, all output is flushed as with |
Z_SYNC_FLUSH, and the compression state is reset so that decompression can |
restart from this point if previous compressed data has been damaged or if |
random access is desired. Using Z_FULL_FLUSH too often can seriously degrade |
the compression. |
|
If deflate returns with avail_out == 0, this function must be called again |
with the same value of the flush parameter and more output space (updated |
avail_out), until the flush is complete (deflate returns with non-zero |
avail_out). |
|
If the parameter flush is set to Z_FINISH, pending input is processed, |
pending output is flushed and deflate returns with Z_STREAM_END if there |
was enough output space; if deflate returns with Z_OK, this function must be |
called again with Z_FINISH and more output space (updated avail_out) but no |
more input data, until it returns with Z_STREAM_END or an error. After |
deflate has returned Z_STREAM_END, the only possible operations on the |
stream are deflateReset or deflateEnd. |
|
Z_FINISH can be used immediately after deflateInit if all the compression |
is to be done in a single step. In this case, avail_out must be at least |
0.1% larger than avail_in plus 12 bytes. If deflate does not return |
Z_STREAM_END, then it must be called again as described above. |
|
deflate() sets strm->adler to the adler32 checksum of all input read |
so far (that is, total_in bytes). |
|
deflate() may update data_type if it can make a good guess about |
the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered |
binary. This field is only for information purposes and does not affect |
the compression algorithm in any manner. |
|
deflate() returns Z_OK if some progress has been made (more input |
processed or more output produced), Z_STREAM_END if all input has been |
consumed and all output has been produced (only when flush is set to |
Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example |
if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible |
(for example avail_in or avail_out was zero). |
*/ |
|
|
ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); |
/* |
All dynamically allocated data structures for this stream are freed. |
This function discards any unprocessed input and does not flush any |
pending output. |
|
deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the |
stream state was inconsistent, Z_DATA_ERROR if the stream was freed |
prematurely (some input or output was discarded). In the error case, |
msg may be set but then points to a static string (which must not be |
deallocated). |
*/ |
|
|
/* |
ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); |
|
Initializes the internal stream state for decompression. The fields |
next_in, avail_in, zalloc, zfree and opaque must be initialized before by |
the caller. If next_in is not Z_NULL and avail_in is large enough (the exact |
value depends on the compression method), inflateInit determines the |
compression method from the zlib header and allocates all data structures |
accordingly; otherwise the allocation will be deferred to the first call of |
inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to |
use default allocation functions. |
|
inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough |
memory, Z_VERSION_ERROR if the zlib library version is incompatible with the |
version assumed by the caller. msg is set to null if there is no error |
message. inflateInit does not perform any decompression apart from reading |
the zlib header if present: this will be done by inflate(). (So next_in and |
avail_in may be modified, but next_out and avail_out are unchanged.) |
*/ |
|
|
ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); |
/* |
inflate decompresses as much data as possible, and stops when the input |
buffer becomes empty or the output buffer becomes full. It may some |
introduce some output latency (reading input without producing any output) |
except when forced to flush. |
|
The detailed semantics are as follows. inflate performs one or both of the |
following actions: |
|
- Decompress more input starting at next_in and update next_in and avail_in |
accordingly. If not all input can be processed (because there is not |
enough room in the output buffer), next_in is updated and processing |
will resume at this point for the next call of inflate(). |
|
- Provide more output starting at next_out and update next_out and avail_out |
accordingly. inflate() provides as much output as possible, until there |
is no more input data or no more space in the output buffer (see below |
about the flush parameter). |
|
Before the call of inflate(), the application should ensure that at least |
one of the actions is possible, by providing more input and/or consuming |
more output, and updating the next_* and avail_* values accordingly. |
The application can consume the uncompressed output when it wants, for |
example when the output buffer is full (avail_out == 0), or after each |
call of inflate(). If inflate returns Z_OK and with zero avail_out, it |
must be called again after making room in the output buffer because there |
might be more output pending. |
|
If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much |
output as possible to the output buffer. The flushing behavior of inflate is |
not specified for values of the flush parameter other than Z_SYNC_FLUSH |
and Z_FINISH, but the current implementation actually flushes as much output |
as possible anyway. |
|
inflate() should normally be called until it returns Z_STREAM_END or an |
error. However if all decompression is to be performed in a single step |
(a single call of inflate), the parameter flush should be set to |
Z_FINISH. In this case all pending input is processed and all pending |
output is flushed; avail_out must be large enough to hold all the |
uncompressed data. (The size of the uncompressed data may have been saved |
by the compressor for this purpose.) The next operation on this stream must |
be inflateEnd to deallocate the decompression state. The use of Z_FINISH |
is never required, but can be used to inform inflate that a faster routine |
may be used for the single inflate() call. |
|
If a preset dictionary is needed at this point (see inflateSetDictionary |
below), inflate sets strm-adler to the adler32 checksum of the |
dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise |
it sets strm->adler to the adler32 checksum of all output produced |
so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or |
an error code as described below. At the end of the stream, inflate() |
checks that its computed adler32 checksum is equal to that saved by the |
compressor and returns Z_STREAM_END only if the checksum is correct. |
|
inflate() returns Z_OK if some progress has been made (more input processed |
or more output produced), Z_STREAM_END if the end of the compressed data has |
been reached and all uncompressed output has been produced, Z_NEED_DICT if a |
preset dictionary is needed at this point, Z_DATA_ERROR if the input data was |
corrupted (input stream not conforming to the zlib format or incorrect |
adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent |
(for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not |
enough memory, Z_BUF_ERROR if no progress is possible or if there was not |
enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR |
case, the application may then call inflateSync to look for a good |
compression block. |
*/ |
|
|
ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); |
/* |
All dynamically allocated data structures for this stream are freed. |
This function discards any unprocessed input and does not flush any |
pending output. |
|
inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state |
was inconsistent. In the error case, msg may be set but then points to a |
static string (which must not be deallocated). |
*/ |
|
/* Advanced functions */ |
|
/* |
The following functions are needed only in some special applications. |
*/ |
|
/* |
ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, |
int level, |
int method, |
int windowBits, |
int memLevel, |
int strategy)); |
|
This is another version of deflateInit with more compression options. The |
fields next_in, zalloc, zfree and opaque must be initialized before by |
the caller. |
|
The method parameter is the compression method. It must be Z_DEFLATED in |
this version of the library. |
|
The windowBits parameter is the base two logarithm of the window size |
(the size of the history buffer). It should be in the range 8..15 for this |
version of the library. Larger values of this parameter result in better |
compression at the expense of memory usage. The default value is 15 if |
deflateInit is used instead. |
|
The memLevel parameter specifies how much memory should be allocated |
for the internal compression state. memLevel=1 uses minimum memory but |
is slow and reduces compression ratio; memLevel=9 uses maximum memory |
for optimal speed. The default value is 8. See zconf.h for total memory |
usage as a function of windowBits and memLevel. |
|
The strategy parameter is used to tune the compression algorithm. Use the |
value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a |
filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no |
string match). Filtered data consists mostly of small values with a |
somewhat random distribution. In this case, the compression algorithm is |
tuned to compress them better. The effect of Z_FILTERED is to force more |
Huffman coding and less string matching; it is somewhat intermediate |
between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects |
the compression ratio but not the correctness of the compressed output even |
if it is not set appropriately. |
|
deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough |
memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid |
method). msg is set to null if there is no error message. deflateInit2 does |
not perform any compression: this will be done by deflate(). |
*/ |
|
ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, |
const Bytef *dictionary, |
uInt dictLength)); |
/* |
Initializes the compression dictionary from the given byte sequence |
without producing any compressed output. This function must be called |
immediately after deflateInit, deflateInit2 or deflateReset, before any |
call of deflate. The compressor and decompressor must use exactly the same |
dictionary (see inflateSetDictionary). |
|
The dictionary should consist of strings (byte sequences) that are likely |
to be encountered later in the data to be compressed, with the most commonly |
used strings preferably put towards the end of the dictionary. Using a |
dictionary is most useful when the data to be compressed is short and can be |
predicted with good accuracy; the data can then be compressed better than |
with the default empty dictionary. |
|
Depending on the size of the compression data structures selected by |
deflateInit or deflateInit2, a part of the dictionary may in effect be |
discarded, for example if the dictionary is larger than the window size in |
deflate or deflate2. Thus the strings most likely to be useful should be |
put at the end of the dictionary, not at the front. |
|
Upon return of this function, strm->adler is set to the Adler32 value |
of the dictionary; the decompressor may later use this value to determine |
which dictionary has been used by the compressor. (The Adler32 value |
applies to the whole dictionary even if only a subset of the dictionary is |
actually used by the compressor.) |
|
deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a |
parameter is invalid (such as NULL dictionary) or the stream state is |
inconsistent (for example if deflate has already been called for this stream |
or if the compression method is bsort). deflateSetDictionary does not |
perform any compression: this will be done by deflate(). |
*/ |
|
ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, |
z_streamp source)); |
/* |
Sets the destination stream as a complete copy of the source stream. |
|
This function can be useful when several compression strategies will be |
tried, for example when there are several ways of pre-processing the input |
data with a filter. The streams that will be discarded should then be freed |
by calling deflateEnd. Note that deflateCopy duplicates the internal |
compression state which can be quite large, so this strategy is slow and |
can consume lots of memory. |
|
deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not |
enough memory, Z_STREAM_ERROR if the source stream state was inconsistent |
(such as zalloc being NULL). msg is left unchanged in both source and |
destination. |
*/ |
|
ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); |
/* |
This function is equivalent to deflateEnd followed by deflateInit, |
but does not free and reallocate all the internal compression state. |
The stream will keep the same compression level and any other attributes |
that may have been set by deflateInit2. |
|
deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source |
stream state was inconsistent (such as zalloc or state being NULL). |
*/ |
|
ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, |
int level, |
int strategy)); |
/* |
Dynamically update the compression level and compression strategy. The |
interpretation of level and strategy is as in deflateInit2. This can be |
used to switch between compression and straight copy of the input data, or |
to switch to a different kind of input data requiring a different |
strategy. If the compression level is changed, the input available so far |
is compressed with the old level (and may be flushed); the new level will |
take effect only at the next call of deflate(). |
|
Before the call of deflateParams, the stream state must be set as for |
a call of deflate(), since the currently available input may have to |
be compressed and flushed. In particular, strm->avail_out must be non-zero. |
|
deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source |
stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR |
if strm->avail_out was zero. |
*/ |
|
/* |
ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, |
int windowBits)); |
|
This is another version of inflateInit with an extra parameter. The |
fields next_in, avail_in, zalloc, zfree and opaque must be initialized |
before by the caller. |
|
The windowBits parameter is the base two logarithm of the maximum window |
size (the size of the history buffer). It should be in the range 8..15 for |
this version of the library. The default value is 15 if inflateInit is used |
instead. If a compressed stream with a larger window size is given as |
input, inflate() will return with the error code Z_DATA_ERROR instead of |
trying to allocate a larger window. |
|
inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough |
memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative |
memLevel). msg is set to null if there is no error message. inflateInit2 |
does not perform any decompression apart from reading the zlib header if |
present: this will be done by inflate(). (So next_in and avail_in may be |
modified, but next_out and avail_out are unchanged.) |
*/ |
|
ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, |
const Bytef *dictionary, |
uInt dictLength)); |
/* |
Initializes the decompression dictionary from the given uncompressed byte |
sequence. This function must be called immediately after a call of inflate |
if this call returned Z_NEED_DICT. The dictionary chosen by the compressor |
can be determined from the Adler32 value returned by this call of |
inflate. The compressor and decompressor must use exactly the same |
dictionary (see deflateSetDictionary). |
|
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a |
parameter is invalid (such as NULL dictionary) or the stream state is |
inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the |
expected one (incorrect Adler32 value). inflateSetDictionary does not |
perform any decompression: this will be done by subsequent calls of |
inflate(). |
*/ |
|
ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); |
/* |
Skips invalid compressed data until a full flush point (see above the |
description of deflate with Z_FULL_FLUSH) can be found, or until all |
available input is skipped. No output is provided. |
|
inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR |
if no more input was provided, Z_DATA_ERROR if no flush point has been found, |
or Z_STREAM_ERROR if the stream structure was inconsistent. In the success |
case, the application may save the current current value of total_in which |
indicates where valid compressed data was found. In the error case, the |
application may repeatedly call inflateSync, providing more input each time, |
until success or end of the input data. |
*/ |
|
ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); |
/* |
This function is equivalent to inflateEnd followed by inflateInit, |
but does not free and reallocate all the internal decompression state. |
The stream will keep attributes that may have been set by inflateInit2. |
|
inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source |
stream state was inconsistent (such as zalloc or state being NULL). |
*/ |
|
|
/* utility functions */ |
|
/* |
The following utility functions are implemented on top of the |
basic stream-oriented functions. To simplify the interface, some |
default options are assumed (compression level and memory usage, |
standard memory allocation functions). The source code of these |
utility functions can easily be modified if you need special options. |
*/ |
|
ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, |
const Bytef *source, uLong sourceLen)); |
/* |
Compresses the source buffer into the destination buffer. sourceLen is |
the byte length of the source buffer. Upon entry, destLen is the total |
size of the destination buffer, which must be at least 0.1% larger than |
sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the |
compressed buffer. |
This function can be used to compress a whole file at once if the |
input file is mmap'ed. |
compress returns Z_OK if success, Z_MEM_ERROR if there was not |
enough memory, Z_BUF_ERROR if there was not enough room in the output |
buffer. |
*/ |
|
ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, |
const Bytef *source, uLong sourceLen, |
int level)); |
/* |
Compresses the source buffer into the destination buffer. The level |
parameter has the same meaning as in deflateInit. sourceLen is the byte |
length of the source buffer. Upon entry, destLen is the total size of the |
destination buffer, which must be at least 0.1% larger than sourceLen plus |
12 bytes. Upon exit, destLen is the actual size of the compressed buffer. |
|
compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough |
memory, Z_BUF_ERROR if there was not enough room in the output buffer, |
Z_STREAM_ERROR if the level parameter is invalid. |
*/ |
|
ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, |
const Bytef *source, uLong sourceLen)); |
|
/* |
Decompresses the source buffer into the destination buffer. sourceLen is |
the byte length of the source buffer. Upon entry, destLen is the total |
size of the destination buffer, which must be large enough to hold the |
entire uncompressed data. (The size of the uncompressed data must have |
been saved previously by the compressor and transmitted to the decompressor |
by some mechanism outside the scope of this compression library.) |
Upon exit, destLen is the actual size of the compressed buffer. |
This function can be used to decompress a whole file at once if the |
input file is mmap'ed. |
|
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not |
enough memory, Z_BUF_ERROR if there was not enough room in the output |
buffer, or Z_DATA_ERROR if the input data was corrupted. |
*/ |
|
|
typedef voidp gzFile; |
|
ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); |
/* |
Opens a gzip (.gz) file for reading or writing. The mode parameter |
is as in fopen ("rb" or "wb") but can also include a compression level |
("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for |
Huffman only compression as in "wb1h". (See the description |
of deflateInit2 for more information about the strategy parameter.) |
|
gzopen can be used to read a file which is not in gzip format; in this |
case gzread will directly read from the file without decompression. |
|
gzopen returns NULL if the file could not be opened or if there was |
insufficient memory to allocate the (de)compression state; errno |
can be checked to distinguish the two cases (if errno is zero, the |
zlib error is Z_MEM_ERROR). */ |
|
ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); |
/* |
gzdopen() associates a gzFile with the file descriptor fd. File |
descriptors are obtained from calls like open, dup, creat, pipe or |
fileno (in the file has been previously opened with fopen). |
The mode parameter is as in gzopen. |
The next call of gzclose on the returned gzFile will also close the |
file descriptor fd, just like fclose(fdopen(fd), mode) closes the file |
descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). |
gzdopen returns NULL if there was insufficient memory to allocate |
the (de)compression state. |
*/ |
|
ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); |
/* |
Dynamically update the compression level or strategy. See the description |
of deflateInit2 for the meaning of these parameters. |
gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not |
opened for writing. |
*/ |
|
ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); |
/* |
Reads the given number of uncompressed bytes from the compressed file. |
If the input file was not in gzip format, gzread copies the given number |
of bytes into the buffer. |
gzread returns the number of uncompressed bytes actually read (0 for |
end of file, -1 for error). */ |
|
ZEXTERN int ZEXPORT gzwrite OF((gzFile file, |
const voidp buf, unsigned len)); |
/* |
Writes the given number of uncompressed bytes into the compressed file. |
gzwrite returns the number of uncompressed bytes actually written |
(0 in case of error). |
*/ |
|
ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); |
/* |
Converts, formats, and writes the args to the compressed file under |
control of the format string, as in fprintf. gzprintf returns the number of |
uncompressed bytes actually written (0 in case of error). |
*/ |
|
ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); |
/* |
Writes the given null-terminated string to the compressed file, excluding |
the terminating null character. |
gzputs returns the number of characters written, or -1 in case of error. |
*/ |
|
ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); |
/* |
Reads bytes from the compressed file until len-1 characters are read, or |
a newline character is read and transferred to buf, or an end-of-file |
condition is encountered. The string is then terminated with a null |
character. |
gzgets returns buf, or Z_NULL in case of error. |
*/ |
|
ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); |
/* |
Writes c, converted to an unsigned char, into the compressed file. |
gzputc returns the value that was written, or -1 in case of error. |
*/ |
|
ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); |
/* |
Reads one byte from the compressed file. gzgetc returns this byte |
or -1 in case of end of file or error. |
*/ |
|
ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); |
/* |
Flushes all pending output into the compressed file. The parameter |
flush is as in the deflate() function. The return value is the zlib |
error number (see function gzerror below). gzflush returns Z_OK if |
the flush parameter is Z_FINISH and all output could be flushed. |
gzflush should be called only when strictly necessary because it can |
degrade compression. |
*/ |
|
ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, |
z_off_t offset, int whence)); |
/* |
Sets the starting position for the next gzread or gzwrite on the |
given compressed file. The offset represents a number of bytes in the |
uncompressed data stream. The whence parameter is defined as in lseek(2); |
the value SEEK_END is not supported. |
If the file is opened for reading, this function is emulated but can be |
extremely slow. If the file is opened for writing, only forward seeks are |
supported; gzseek then compresses a sequence of zeroes up to the new |
starting position. |
|
gzseek returns the resulting offset location as measured in bytes from |
the beginning of the uncompressed stream, or -1 in case of error, in |
particular if the file is opened for writing and the new starting position |
would be before the current position. |
*/ |
|
ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); |
/* |
Rewinds the given file. This function is supported only for reading. |
|
gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) |
*/ |
|
ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); |
/* |
Returns the starting position for the next gzread or gzwrite on the |
given compressed file. This position represents a number of bytes in the |
uncompressed data stream. |
|
gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) |
*/ |
|
ZEXTERN int ZEXPORT gzeof OF((gzFile file)); |
/* |
Returns 1 when EOF has previously been detected reading the given |
input stream, otherwise zero. |
*/ |
|
ZEXTERN int ZEXPORT gzclose OF((gzFile file)); |
/* |
Flushes all pending output if necessary, closes the compressed file |
and deallocates all the (de)compression state. The return value is the zlib |
error number (see function gzerror below). |
*/ |
|
ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); |
/* |
Returns the error message for the last error which occurred on the |
given compressed file. errnum is set to zlib error number. If an |
error occurred in the file system and not in the compression library, |
errnum is set to Z_ERRNO and the application may consult errno |
to get the exact error code. |
*/ |
|
/* checksum functions */ |
|
/* |
These functions are not related to compression but are exported |
anyway because they might be useful in applications using the |
compression library. |
*/ |
|
ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); |
|
/* |
Update a running Adler-32 checksum with the bytes buf[0..len-1] and |
return the updated checksum. If buf is NULL, this function returns |
the required initial value for the checksum. |
An Adler-32 checksum is almost as reliable as a CRC32 but can be computed |
much faster. Usage example: |
|
uLong adler = adler32(0L, Z_NULL, 0); |
|
while (read_buffer(buffer, length) != EOF) { |
adler = adler32(adler, buffer, length); |
} |
if (adler != original_adler) error(); |
*/ |
|
#ifndef __ECOS__ |
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); |
#endif // __ECOS__ |
/* |
Update a running crc with the bytes buf[0..len-1] and return the updated |
crc. If buf is NULL, this function returns the required initial value |
for the crc. Pre- and post-conditioning (one's complement) is performed |
within this function so it shouldn't be done by the application. |
Usage example: |
|
uLong crc = crc32(0L, Z_NULL, 0); |
|
while (read_buffer(buffer, length) != EOF) { |
crc = crc32(crc, buffer, length); |
} |
if (crc != original_crc) error(); |
*/ |
|
/* various hacks, don't look :) */ |
|
/* deflateInit and inflateInit are macros to allow checking the zlib version |
* and the compiler's view of z_stream: |
*/ |
ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, |
const char *version, int stream_size)); |
ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, |
const char *version, int stream_size)); |
ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, |
int windowBits, int memLevel, |
int strategy, const char *version, |
int stream_size)); |
ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, |
const char *version, int stream_size)); |
#define deflateInit(strm, level) \ |
deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) |
#define inflateInit(strm) \ |
inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) |
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ |
deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ |
(strategy), ZLIB_VERSION, sizeof(z_stream)) |
#define inflateInit2(strm, windowBits) \ |
inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) |
|
|
#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) |
struct internal_state {int dummy;}; /* hack for buggy compilers */ |
#endif |
|
ZEXTERN const char * ZEXPORT zError OF((int err)); |
ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); |
ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); |
|
#ifdef __cplusplus |
} |
#endif |
|
#endif /* _ZLIB_H */ |
/v2_0/ChangeLog
0,0 → 1,101
2002-10-10 Andrew Lunn <andrew.lunn@ascom.ch> |
|
* include/zutil.h: |
* include/zlib.h: |
* src/inflate.c (inflate): Use the CRC function from the CRC |
package. |
* src/crc32.c: Removed. |
|
2002-09-09 Mark Salter <msalter@redhat.com> |
|
* inflate.c (inflate): Fix CRC calculation over multiple invocations |
with same output buffer. |
|
2002-02-18 Jesper Skov <jskov@redhat.com> |
|
* src/infblock.c: Applied fix for double-free which could cause a |
zlib crash. Fixed indentation. |
|
2001-10-15 Gary Thomas <gthomas@redhat.com> |
|
* include/zconf.h: |
* cdl/compress_zlib.cdl: |
Define new interface CYGINT_COMPRESS_ZLIB_LOCAL_ALLOC which allows |
users of this code (applications) to provide their own allocators. |
|
2001-04-02 Jesper Skov <jskov@redhat.com> |
|
* tests/zlib2.c: Removed BAD_CRC state. |
|
2001-03-12 Jesper Skov <jskov@redhat.com> |
|
* src/inflate.c: Remove BAD_CRC state. Do separate CRC for |
gzippped data. |
* include/zlib.h: Removed Z_BAD_CRC hack. Rename crc32 function. |
* src/crc32.c: Include zlib.h header from |
include/cyg/compress. Rename function. |
* cdl/compress_zlib.cdl: Build the crc32.c file. |
|
2001-03-09 Jesper Skov <jskov@redhat.com> |
|
* src/compress.c: Include zlib.h header from include/cyg/compress. |
* src/uncompr.c: Same. |
* tests/zlib1.c: Added. |
* tests/zlib2.c: Added. |
* cdl/compress_zlib.cdl: Compile tests. Compile |
files holding compress/uncompress functions. |
|
* cdl/compress_zlib.cdl: Don't warn about prototypes when building. |
|
2001-03-08 Jesper Skov <jskov@redhat.com> |
|
* cdl/compress_zlib.cdl: Add isoinfra requirement. |
|
* include/zconf.h: Override STDC check. |
|
* include/zlib.h: Added new BAD_CRC return type. Comment out crc32 |
declaration. |
|
* src/inflate.c: Added additional states to allow for gzip header |
decoding. |
|
* src/adler32.c: Include zlib.h header from include/cyg/compress. |
* src/zutil.h: Same. |
|
* Import zlib 1.1.3 sources, but leave out some sub |
directories. See src/README.eCos for details. |
|
//=========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//=========================================================================== |
/v2_0/src/Make_vms.com
0,0 → 1,115
$! make libz under VMS |
$! written by Martin P.J. Zinser <m.zinser@gsi.de> |
$! |
$! Look for the compiler used |
$! |
$ ccopt = "" |
$ if f$getsyi("HW_MODEL").ge.1024 |
$ then |
$ ccopt = "/prefix=all"+ccopt |
$ comp = "__decc__=1" |
$ if f$trnlnm("SYS").eqs."" then define sys sys$library: |
$ else |
$ if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs."" |
$ then |
$ comp = "__vaxc__=1" |
$ if f$trnlnm("SYS").eqs."" then define sys sys$library: |
$ else |
$ if f$trnlnm("SYS").eqs."" then define sys decc$library_include: |
$ ccopt = "/decc/prefix=all"+ccopt |
$ comp = "__decc__=1" |
$ endif |
$ endif |
$! |
$! Build the thing plain or with mms |
$! |
$ write sys$output "Compiling Zlib sources ..." |
$ if f$search("SYS$SYSTEM:MMS.EXE").eqs."" |
$ then |
$ dele example.obj;*,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 gzio.OBJ "CC ''CCOPT' gzio" - |
gzio.c zutil.h zlib.h zconf.h |
$ CALL MAKE infblock.OBJ "CC ''CCOPT' infblock" - |
infblock.c zutil.h zlib.h zconf.h infblock.h |
$ CALL MAKE infcodes.OBJ "CC ''CCOPT' infcodes" - |
infcodes.c zutil.h zlib.h zconf.h inftrees.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 infutil.OBJ "CC ''CCOPT' infutil" - |
infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.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' example" - |
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' minigzip" - |
minigzip.c zlib.h zconf.h |
$ call make minigzip.exe - |
"LINK minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib" - |
minigzip.obj libz.olb |
$ else |
$ mms/macro=('comp') |
$ endif |
$ write sys$output "Zlib build completed" |
$ exit |
$! |
$! |
$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 |
/v2_0/src/infcodes.h
0,0 → 1,27
/* infcodes.h -- header to use infcodes.c |
* Copyright (C) 1995-1998 Mark Adler |
* For conditions of distribution and use, see copyright notice in zlib.h |
*/ |
|
/* WARNING: this file should *not* be used by applications. It is |
part of the implementation of the compression library and is |
subject to change. Applications should only use zlib.h. |
*/ |
|
struct inflate_codes_state; |
typedef struct inflate_codes_state FAR inflate_codes_statef; |
|
extern inflate_codes_statef *inflate_codes_new OF(( |
uInt, uInt, |
inflate_huft *, inflate_huft *, |
z_streamp )); |
|
extern int inflate_codes OF(( |
inflate_blocks_statef *, |
z_streamp , |
int)); |
|
extern void inflate_codes_free OF(( |
inflate_codes_statef *, |
z_streamp )); |
|
/v2_0/src/configure
0,0 → 1,212
#!/bin/sh |
# configure script for zlib. This script is needed only if |
# you wish to build a shared library and your system supports them, |
# of if you need special compiler, flags or install directory. |
# Otherwise, you can just use directly "make test; make install" |
# |
# To create a shared library, use "configure --shared"; by default a static |
# library is created. If the primitive shared library support provided here |
# does not work, use ftp://prep.ai.mit.edu/pub/gnu/libtool-*.tar.gz |
# |
# 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) |
# LDSHARED is the command to be used to create a shared library |
|
# 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. |
|
LIBS=libz.a |
SHAREDLIB=libz.so |
VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h` |
AR=${AR-"ar rc"} |
RANLIB=${RANLIB-"ranlib"} |
prefix=${prefix-/usr/local} |
exec_prefix=${exec_prefix-'${prefix}'} |
libdir=${libdir-'${exec_prefix}/lib'} |
includedir=${includedir-'${prefix}/include'} |
shared_ext='.so' |
shared=0 |
gcc=0 |
old_cc="$CC" |
old_cflags="$CFLAGS" |
|
while test $# -ge 1 |
do |
case "$1" in |
-h* | --h*) |
echo 'usage:' |
echo ' configure [--shared] [--prefix=PREFIX] [--exec_prefix=EXPREFIX]' |
echo ' [--libdir=LIBDIR] [--includedir=INCLUDEDIR]' |
exit 0;; |
-p*=* | --p*=*) prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; |
-e*=* | --e*=*) exec_prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; |
-l*=* | --libdir=*) libdir=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; |
-i*=* | --includedir=*) includedir=`echo $1 | sed 's/[-a-z_]*=//'`;shift;; |
-p* | --p*) prefix="$2"; shift; shift;; |
-e* | --e*) exec_prefix="$2"; shift; shift;; |
-l* | --l*) libdir="$2"; shift; shift;; |
-i* | --i*) includedir="$2"; shift; shift;; |
-s* | --s*) shared=1; shift;; |
esac |
done |
|
test=ztest$$ |
cat > $test.c <<EOF |
extern int getchar(); |
int hello() {return getchar();} |
EOF |
|
test -z "$CC" && echo Checking for gcc... |
cc=${CC-gcc} |
cflags=${CFLAGS-"-O3"} |
# to force the asm version use: CFLAGS="-O3 -DASMV" ./configure |
case "$cc" in |
*gcc*) gcc=1;; |
esac |
|
if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) 2>/dev/null; then |
CC="$cc" |
SFLAGS=${CFLAGS-"-fPIC -O3"} |
CFLAGS="$cflags" |
case `(uname -s || echo unknown) 2>/dev/null` in |
Linux | linux) LDSHARED=${LDSHARED-"gcc -shared -Wl,-soname,libz.so.1"};; |
*) LDSHARED=${LDSHARED-"gcc -shared"};; |
esac |
else |
# find system name and corresponding cc options |
CC=${CC-cc} |
case `(uname -sr || echo unknown) 2>/dev/null` in |
HP-UX*) SFLAGS=${CFLAGS-"-O +z"} |
CFLAGS=${CFLAGS-"-O"} |
# LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"} |
LDSHARED=${LDSHARED-"ld -b"} |
shared_ext='.sl' |
SHAREDLIB='libz.sl';; |
IRIX*) SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."} |
CFLAGS=${CFLAGS-"-ansi -O2"} |
LDSHARED=${LDSHARED-"cc -shared"};; |
OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"} |
CFLAGS=${CFLAGS-"-O -std1"} |
LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,$SHAREDLIB -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"};; |
OSF1*) SFLAGS=${CFLAGS-"-O -std1"} |
CFLAGS=${CFLAGS-"-O -std1"} |
LDSHARED=${LDSHARED-"cc -shared"};; |
QNX*) SFLAGS=${CFLAGS-"-4 -O"} |
CFLAGS=${CFLAGS-"-4 -O"} |
LDSHARED=${LDSHARED-"cc"} |
RANLIB=${RANLIB-"true"} |
AR="cc -A";; |
SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "} |
CFLAGS=${CFLAGS-"-O3"} |
LDSHARED=${LDSHARED-"cc -dy -KPIC -G"};; |
SunOS\ 5*) SFLAGS=${CFLAGS-"-fast -xcg89 -KPIC -R."} |
CFLAGS=${CFLAGS-"-fast -xcg89"} |
LDSHARED=${LDSHARED-"cc -G"};; |
SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"} |
CFLAGS=${CFLAGS-"-O2"} |
LDSHARED=${LDSHARED-"ld"};; |
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"};; |
# send working options for other systems to support@gzip.org |
*) SFLAGS=${CFLAGS-"-O"} |
CFLAGS=${CFLAGS-"-O"} |
LDSHARED=${LDSHARED-"cc -shared"};; |
esac |
fi |
|
if test $shared -eq 1; then |
echo Checking for shared library support... |
# we must test in two steps (cc then ld), required at least on SunOS 4.x |
if test "`($CC -c $SFLAGS $test.c) 2>&1`" = "" && |
test "`($LDSHARED -o $test$shared_ext $test.o) 2>&1`" = ""; then |
CFLAGS="$SFLAGS" |
LIBS="$SHAREDLIB.$VER" |
echo Building shared library $SHAREDLIB.$VER with $CC. |
elif test -z "$old_cc" -a -z "$old_cflags"; then |
echo No shared library suppport. |
shared=0; |
else |
echo 'No shared library suppport; try without defining CC and CFLAGS' |
shared=0; |
fi |
fi |
if test $shared -eq 0; then |
LDSHARED="$CC" |
echo Building static library $LIBS version $VER with $CC. |
fi |
|
cat > $test.c <<EOF |
#include <unistd.h> |
int main() { return 0; } |
EOF |
if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then |
CFLAGS="$CFLAGS -DHAVE_UNISTD_H" |
echo "Checking for unistd.h... Yes." |
else |
echo "Checking for unistd.h... No." |
fi |
|
cat > $test.c <<EOF |
#include <errno.h> |
int main() { return 0; } |
EOF |
if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then |
echo "Checking for errno.h... Yes." |
else |
echo "Checking for errno.h... No." |
CFLAGS="$CFLAGS -DNO_ERRNO_H" |
fi |
|
cat > $test.c <<EOF |
#include <sys/types.h> |
#include <sys/mman.h> |
#include <sys/stat.h> |
caddr_t hello() { |
return mmap((caddr_t)0, (off_t)0, PROT_READ, MAP_SHARED, 0, (off_t)0); |
} |
EOF |
if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then |
CFLAGS="$CFLAGS -DUSE_MMAP" |
echo Checking for mmap support... Yes. |
else |
echo Checking for mmap support... No. |
fi |
|
CPP=${CPP-"$CC -E"} |
case $CFLAGS in |
*ASMV*) |
if test "`nm $test.o | grep _hello`" = ""; then |
CPP="$CPP -DNO_UNDERLINE" |
echo Checking for underline in external names... No. |
else |
echo Checking for underline in external names... Yes. |
fi;; |
esac |
|
rm -f $test.[co] $test$shared_ext |
|
# udpate Makefile |
sed < Makefile.in " |
/^CC *=/s%=.*%=$CC% |
/^CFLAGS *=/s%=.*%=$CFLAGS% |
/^CPP *=/s%=.*%=$CPP% |
/^LDSHARED *=/s%=.*%=$LDSHARED% |
/^LIBS *=/s%=.*%=$LIBS% |
/^SHAREDLIB *=/s%=.*%=$SHAREDLIB% |
/^AR *=/s%=.*%=$AR% |
/^RANLIB *=/s%=.*%=$RANLIB% |
/^VER *=/s%=.*%=$VER% |
/^prefix *=/s%=.*%=$prefix% |
/^exec_prefix *=/s%=.*%=$exec_prefix% |
/^libdir *=/s%=.*%=$libdir% |
/^includedir *=/s%=.*%=$includedir% |
" > Makefile |
/v2_0/src/inffixed.h
0,0 → 1,151
/* inffixed.h -- table for decoding fixed codes |
* Generated automatically by the maketree.c program |
*/ |
|
/* 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. |
*/ |
|
local uInt fixed_bl = 9; |
local uInt fixed_bd = 5; |
local inflate_huft fixed_tl[] = { |
{{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, |
{{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, |
{{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, |
{{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224}, |
{{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144}, |
{{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208}, |
{{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176}, |
{{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240}, |
{{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, |
{{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200}, |
{{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168}, |
{{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232}, |
{{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152}, |
{{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216}, |
{{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184}, |
{{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248}, |
{{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, |
{{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196}, |
{{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164}, |
{{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228}, |
{{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148}, |
{{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212}, |
{{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180}, |
{{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244}, |
{{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, |
{{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204}, |
{{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172}, |
{{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236}, |
{{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156}, |
{{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220}, |
{{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188}, |
{{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252}, |
{{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, |
{{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194}, |
{{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162}, |
{{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226}, |
{{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146}, |
{{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210}, |
{{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178}, |
{{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242}, |
{{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, |
{{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202}, |
{{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170}, |
{{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234}, |
{{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154}, |
{{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218}, |
{{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186}, |
{{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250}, |
{{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, |
{{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198}, |
{{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166}, |
{{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230}, |
{{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150}, |
{{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214}, |
{{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182}, |
{{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246}, |
{{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, |
{{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206}, |
{{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174}, |
{{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238}, |
{{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158}, |
{{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222}, |
{{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190}, |
{{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254}, |
{{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, |
{{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193}, |
{{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161}, |
{{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225}, |
{{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145}, |
{{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209}, |
{{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177}, |
{{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241}, |
{{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, |
{{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201}, |
{{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169}, |
{{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233}, |
{{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153}, |
{{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217}, |
{{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185}, |
{{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249}, |
{{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, |
{{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197}, |
{{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165}, |
{{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229}, |
{{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149}, |
{{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213}, |
{{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181}, |
{{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245}, |
{{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, |
{{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205}, |
{{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173}, |
{{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237}, |
{{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157}, |
{{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221}, |
{{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189}, |
{{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253}, |
{{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, |
{{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195}, |
{{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163}, |
{{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227}, |
{{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147}, |
{{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211}, |
{{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179}, |
{{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243}, |
{{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, |
{{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203}, |
{{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171}, |
{{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235}, |
{{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155}, |
{{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219}, |
{{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187}, |
{{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251}, |
{{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, |
{{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199}, |
{{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167}, |
{{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231}, |
{{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151}, |
{{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215}, |
{{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183}, |
{{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247}, |
{{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, |
{{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207}, |
{{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175}, |
{{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239}, |
{{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159}, |
{{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223}, |
{{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191}, |
{{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255} |
}; |
local inflate_huft fixed_td[] = { |
{{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, |
{{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, |
{{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, |
{{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577}, |
{{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145}, |
{{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577}, |
{{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289}, |
{{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577} |
}; |
/v2_0/src/Makefile.in
0,0 → 1,174
# Makefile for zlib |
# Copyright (C) 1995-1998 Jean-loup Gailly. |
# For conditions of distribution and use, see copyright notice in zlib.h |
|
# To compile and test, type: |
# ./configure; make test |
# The call of configure is optional if you don't have special requirements |
# If you wish to build zlib as a shared library, use: ./configure -s |
|
# 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 |
|
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 |
|
LDFLAGS=-L. -lz |
LDSHARED=$(CC) |
CPP=$(CC) -E |
|
VER=1.1.3 |
LIBS=libz.a |
SHAREDLIB=libz.so |
|
AR=ar rc |
RANLIB=ranlib |
TAR=tar |
SHELL=/bin/sh |
|
prefix = /usr/local |
exec_prefix = ${prefix} |
libdir = ${exec_prefix}/lib |
includedir = ${prefix}/include |
|
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 |
|
OBJA = |
# to use the asm code: make OBJA=match.o |
|
TEST_OBJS = example.o minigzip.o |
|
DISTFILES = README FAQ INDEX ChangeLog configure Make*[a-z0-9] *.[ch] *.mms \ |
algorithm.txt zlib.3 msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \ |
nt/Make*[a-z0-9] nt/zlib.dnt amiga/Make*.??? os2/M*.os2 os2/zlib.def \ |
contrib/RE*.contrib contrib/*.txt contrib/asm386/*.asm contrib/asm386/*.c \ |
contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/asm[56]86/*.?86 \ |
contrib/asm[56]86/*.S contrib/iostream/*.cpp \ |
contrib/iostream/*.h contrib/iostream2/*.h contrib/iostream2/*.cpp \ |
contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32 \ |
contrib/minizip/[CM]*[pe] contrib/minizip/*.[ch] contrib/minizip/*.[td]?? \ |
contrib/delphi*/*.??? |
|
all: example minigzip |
|
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 |
|
libz.a: $(OBJS) $(OBJA) |
$(AR) $@ $(OBJS) $(OBJA) |
-@ ($(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 |
|
$(SHAREDLIB).$(VER): $(OBJS) |
$(LDSHARED) -o $@ $(OBJS) |
rm -f $(SHAREDLIB) $(SHAREDLIB).1 |
ln -s $@ $(SHAREDLIB) |
ln -s $@ $(SHAREDLIB).1 |
|
example: example.o $(LIBS) |
$(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) |
|
minigzip: minigzip.o $(LIBS) |
$(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) |
|
install: $(LIBS) |
-@if [ ! -d $(includedir) ]; then mkdir $(includedir); fi |
-@if [ ! -d $(libdir) ]; then mkdir $(libdir); fi |
cp zlib.h zconf.h $(includedir) |
chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h |
cp $(LIBS) $(libdir) |
cd $(libdir); chmod 755 $(LIBS) |
-@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1 |
cd $(libdir); if test -f $(SHAREDLIB).$(VER); then \ |
rm -f $(SHAREDLIB) $(SHAREDLIB).1; \ |
ln -s $(SHAREDLIB).$(VER) $(SHAREDLIB); \ |
ln -s $(SHAREDLIB).$(VER) $(SHAREDLIB).1; \ |
(ldconfig || true) >/dev/null 2>&1; \ |
fi |
# The ranlib in install is needed on NeXTSTEP which checks file times |
# ldconfig is for Linux |
|
uninstall: |
cd $(includedir); \ |
v=$(VER); \ |
if test -f zlib.h; then \ |
v=`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`; \ |
rm -f zlib.h zconf.h; \ |
fi; \ |
cd $(libdir); rm -f libz.a; \ |
if test -f $(SHAREDLIB).$$v; then \ |
rm -f $(SHAREDLIB).$$v $(SHAREDLIB) $(SHAREDLIB).1; \ |
fi |
|
clean: |
rm -f *.o *~ example minigzip libz.a libz.so* foo.gz so_locations \ |
_match.s maketree |
|
distclean: clean |
|
zip: |
mv Makefile Makefile~; cp -p Makefile.in Makefile |
rm -f test.c ztest*.c contrib/minizip/test.zip |
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 contrib/minizip/test.zip |
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 |
/v2_0/src/deflate.c
0,0 → 1,1350
/* deflate.c -- compress data using the deflation algorithm |
* Copyright (C) 1995-1998 Jean-loup Gailly. |
* For conditions of distribution and use, see copyright notice in zlib.h |
*/ |
|
/* |
* ALGORITHM |
* |
* The "deflation" process depends on being able to identify portions |
* of the input text which are identical to earlier input (within a |
* sliding window trailing behind the input currently being processed). |
* |
* The most straightforward technique turns out to be the fastest for |
* most input files: try all possible matches and select the longest. |
* The key feature of this algorithm is that insertions into the string |
* dictionary are very simple and thus fast, and deletions are avoided |
* completely. Insertions are performed at each input character, whereas |
* string matches are performed only when the previous match ends. So it |
* is preferable to spend more time in matches to allow very fast string |
* insertions and avoid deletions. The matching algorithm for small |
* strings is inspired from that of Rabin & Karp. A brute force approach |
* is used to find longer strings when a small match has been found. |
* A similar algorithm is used in comic (by Jan-Mark Wams) and freeze |
* (by Leonid Broukhis). |
* A previous version of this file used a more sophisticated algorithm |
* (by Fiala and Greene) which is guaranteed to run in linear amortized |
* time, but has a larger average cost, uses more memory and is patented. |
* However the F&G algorithm may be faster for some highly redundant |
* files if the parameter max_chain_length (described below) is too large. |
* |
* ACKNOWLEDGEMENTS |
* |
* The idea of lazy evaluation of matches is due to Jan-Mark Wams, and |
* I found it in 'freeze' written by Leonid Broukhis. |
* Thanks to many people for bug reports and testing. |
* |
* REFERENCES |
* |
* Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". |
* Available in ftp://ds.internic.net/rfc/rfc1951.txt |
* |
* A description of the Rabin and Karp algorithm is given in the book |
* "Algorithms" by R. Sedgewick, Addison-Wesley, p252. |
* |
* Fiala,E.R., and Greene,D.H. |
* Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 |
* |
*/ |
|
/* @(#) $Id: deflate.c,v 1.1.1.1 2004-02-14 13:35:39 phoenix Exp $ */ |
|
#include "deflate.h" |
|
const char deflate_copyright[] = |
" deflate 1.1.3 Copyright 1995-1998 Jean-loup Gailly "; |
/* |
If you use the zlib library in a product, an acknowledgment is welcome |
in the documentation of your product. If for some reason you cannot |
include such an acknowledgment, I would appreciate that you keep this |
copyright string in the executable of your product. |
*/ |
|
/* =========================================================================== |
* Function prototypes. |
*/ |
typedef enum { |
need_more, /* block not completed, need more input or more output */ |
block_done, /* block flush performed */ |
finish_started, /* finish started, need only more output at next deflate */ |
finish_done /* finish done, accept no more input or output */ |
} block_state; |
|
typedef block_state (*compress_func) OF((deflate_state *s, int flush)); |
/* Compression function. Returns the block state after the call. */ |
|
local void fill_window OF((deflate_state *s)); |
local block_state deflate_stored OF((deflate_state *s, int flush)); |
local block_state deflate_fast OF((deflate_state *s, int flush)); |
local block_state deflate_slow OF((deflate_state *s, int flush)); |
local void lm_init OF((deflate_state *s)); |
local void putShortMSB OF((deflate_state *s, uInt b)); |
local void flush_pending OF((z_streamp strm)); |
local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); |
#ifdef ASMV |
void match_init OF((void)); /* asm code initialization */ |
uInt longest_match OF((deflate_state *s, IPos cur_match)); |
#else |
local uInt longest_match OF((deflate_state *s, IPos cur_match)); |
#endif |
|
#ifdef DEBUG |
local void check_match OF((deflate_state *s, IPos start, IPos match, |
int length)); |
#endif |
|
/* =========================================================================== |
* Local data |
*/ |
|
#define NIL 0 |
/* Tail of hash chains */ |
|
#ifndef TOO_FAR |
# define TOO_FAR 4096 |
#endif |
/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ |
|
#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) |
/* Minimum amount of lookahead, except at the end of the input file. |
* See deflate.c for comments about the MIN_MATCH+1. |
*/ |
|
/* Values for max_lazy_match, good_match and max_chain_length, depending on |
* the desired pack level (0..9). The values given below have been tuned to |
* exclude worst case performance for pathological files. Better values may be |
* found for specific files. |
*/ |
typedef struct config_s { |
ush good_length; /* reduce lazy search above this match length */ |
ush max_lazy; /* do not perform lazy search above this match length */ |
ush nice_length; /* quit search above this match length */ |
ush max_chain; |
compress_func func; |
} config; |
|
local const config configuration_table[10] = { |
/* good lazy nice chain */ |
/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ |
/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */ |
/* 2 */ {4, 5, 16, 8, deflate_fast}, |
/* 3 */ {4, 6, 32, 32, deflate_fast}, |
|
/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ |
/* 5 */ {8, 16, 32, 32, deflate_slow}, |
/* 6 */ {8, 16, 128, 128, deflate_slow}, |
/* 7 */ {8, 32, 128, 256, deflate_slow}, |
/* 8 */ {32, 128, 258, 1024, deflate_slow}, |
/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */ |
|
/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 |
* For deflate_fast() (levels <= 3) good is ignored and lazy has a different |
* meaning. |
*/ |
|
#define EQUAL 0 |
/* result of memcmp for equal strings */ |
|
struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ |
|
/* =========================================================================== |
* Update a hash value with the given input byte |
* IN assertion: all calls to to UPDATE_HASH are made with consecutive |
* input characters, so that a running hash key can be computed from the |
* previous key instead of complete recalculation each time. |
*/ |
#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask) |
|
|
/* =========================================================================== |
* Insert string str in the dictionary and set match_head to the previous head |
* of the hash chain (the most recent string with same hash key). Return |
* the previous length of the hash chain. |
* If this file is compiled with -DFASTEST, the compression level is forced |
* to 1, and no hash chains are maintained. |
* IN assertion: all calls to to INSERT_STRING are made with consecutive |
* input characters and the first MIN_MATCH bytes of str are valid |
* (except for the last MIN_MATCH-1 bytes of the input file). |
*/ |
#ifdef FASTEST |
#define INSERT_STRING(s, str, match_head) \ |
(UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ |
match_head = s->head[s->ins_h], \ |
s->head[s->ins_h] = (Pos)(str)) |
#else |
#define INSERT_STRING(s, str, match_head) \ |
(UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ |
s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ |
s->head[s->ins_h] = (Pos)(str)) |
#endif |
|
/* =========================================================================== |
* Initialize the hash table (avoiding 64K overflow for 16 bit systems). |
* prev[] will be initialized on the fly. |
*/ |
#define CLEAR_HASH(s) \ |
s->head[s->hash_size-1] = NIL; \ |
zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); |
|
/* ========================================================================= */ |
int ZEXPORT deflateInit_(strm, level, version, stream_size) |
z_streamp strm; |
int level; |
const char *version; |
int stream_size; |
{ |
return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, |
Z_DEFAULT_STRATEGY, version, stream_size); |
/* To do: ignore strm->next_in if we use it as window */ |
} |
|
/* ========================================================================= */ |
int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, |
version, stream_size) |
z_streamp strm; |
int level; |
int method; |
int windowBits; |
int memLevel; |
int strategy; |
const char *version; |
int stream_size; |
{ |
deflate_state *s; |
int noheader = 0; |
static const char* my_version = ZLIB_VERSION; |
|
ushf *overlay; |
/* We overlay pending_buf and d_buf+l_buf. This works since the average |
* output size for (length,distance) codes is <= 24 bits. |
*/ |
|
if (version == Z_NULL || version[0] != my_version[0] || |
stream_size != sizeof(z_stream)) { |
return Z_VERSION_ERROR; |
} |
if (strm == Z_NULL) return Z_STREAM_ERROR; |
|
strm->msg = Z_NULL; |
if (strm->zalloc == Z_NULL) { |
strm->zalloc = zcalloc; |
strm->opaque = (voidpf)0; |
} |
if (strm->zfree == Z_NULL) strm->zfree = zcfree; |
|
if (level == Z_DEFAULT_COMPRESSION) level = 6; |
#ifdef FASTEST |
level = 1; |
#endif |
|
if (windowBits < 0) { /* undocumented feature: suppress zlib header */ |
noheader = 1; |
windowBits = -windowBits; |
} |
if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || |
windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || |
strategy < 0 || strategy > Z_HUFFMAN_ONLY) { |
return Z_STREAM_ERROR; |
} |
s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); |
if (s == Z_NULL) return Z_MEM_ERROR; |
strm->state = (struct internal_state FAR *)s; |
s->strm = strm; |
|
s->noheader = noheader; |
s->w_bits = windowBits; |
s->w_size = 1 << s->w_bits; |
s->w_mask = s->w_size - 1; |
|
s->hash_bits = memLevel + 7; |
s->hash_size = 1 << s->hash_bits; |
s->hash_mask = s->hash_size - 1; |
s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); |
|
s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); |
s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); |
s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); |
|
s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ |
|
overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); |
s->pending_buf = (uchf *) overlay; |
s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); |
|
if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || |
s->pending_buf == Z_NULL) { |
strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); |
deflateEnd (strm); |
return Z_MEM_ERROR; |
} |
s->d_buf = overlay + s->lit_bufsize/sizeof(ush); |
s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; |
|
s->level = level; |
s->strategy = strategy; |
s->method = (Byte)method; |
|
return deflateReset(strm); |
} |
|
/* ========================================================================= */ |
int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) |
z_streamp strm; |
const Bytef *dictionary; |
uInt dictLength; |
{ |
deflate_state *s; |
uInt length = dictLength; |
uInt n; |
IPos hash_head = 0; |
|
if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || |
strm->state->status != INIT_STATE) return Z_STREAM_ERROR; |
|
s = strm->state; |
strm->adler = adler32(strm->adler, dictionary, dictLength); |
|
if (length < MIN_MATCH) return Z_OK; |
if (length > MAX_DIST(s)) { |
length = MAX_DIST(s); |
#ifndef USE_DICT_HEAD |
dictionary += dictLength - length; /* use the tail of the dictionary */ |
#endif |
} |
zmemcpy(s->window, dictionary, length); |
s->strstart = length; |
s->block_start = (long)length; |
|
/* Insert all strings in the hash table (except for the last two bytes). |
* s->lookahead stays null, so s->ins_h will be recomputed at the next |
* call of fill_window. |
*/ |
s->ins_h = s->window[0]; |
UPDATE_HASH(s, s->ins_h, s->window[1]); |
for (n = 0; n <= length - MIN_MATCH; n++) { |
INSERT_STRING(s, n, hash_head); |
} |
if (hash_head) hash_head = 0; /* to make compiler happy */ |
return Z_OK; |
} |
|
/* ========================================================================= */ |
int ZEXPORT deflateReset (strm) |
z_streamp strm; |
{ |
deflate_state *s; |
|
if (strm == Z_NULL || strm->state == Z_NULL || |
strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR; |
|
strm->total_in = strm->total_out = 0; |
strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ |
strm->data_type = Z_UNKNOWN; |
|
s = (deflate_state *)strm->state; |
s->pending = 0; |
s->pending_out = s->pending_buf; |
|
if (s->noheader < 0) { |
s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ |
} |
s->status = s->noheader ? BUSY_STATE : INIT_STATE; |
strm->adler = 1; |
s->last_flush = Z_NO_FLUSH; |
|
_tr_init(s); |
lm_init(s); |
|
return Z_OK; |
} |
|
/* ========================================================================= */ |
int ZEXPORT deflateParams(strm, level, strategy) |
z_streamp strm; |
int level; |
int strategy; |
{ |
deflate_state *s; |
compress_func func; |
int err = Z_OK; |
|
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; |
s = strm->state; |
|
if (level == Z_DEFAULT_COMPRESSION) { |
level = 6; |
} |
if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { |
return Z_STREAM_ERROR; |
} |
func = configuration_table[s->level].func; |
|
if (func != configuration_table[level].func && strm->total_in != 0) { |
/* Flush the last buffer: */ |
err = deflate(strm, Z_PARTIAL_FLUSH); |
} |
if (s->level != level) { |
s->level = level; |
s->max_lazy_match = configuration_table[level].max_lazy; |
s->good_match = configuration_table[level].good_length; |
s->nice_match = configuration_table[level].nice_length; |
s->max_chain_length = configuration_table[level].max_chain; |
} |
s->strategy = strategy; |
return err; |
} |
|
/* ========================================================================= |
* Put a short in the pending buffer. The 16-bit value is put in MSB order. |
* IN assertion: the stream state is correct and there is enough room in |
* pending_buf. |
*/ |
local void putShortMSB (s, b) |
deflate_state *s; |
uInt b; |
{ |
put_byte(s, (Byte)(b >> 8)); |
put_byte(s, (Byte)(b & 0xff)); |
} |
|
/* ========================================================================= |
* Flush as much pending output as possible. All deflate() output goes |
* through this function so some applications may wish to modify it |
* to avoid allocating a large strm->next_out buffer and copying into it. |
* (See also read_buf()). |
*/ |
local void flush_pending(strm) |
z_streamp strm; |
{ |
unsigned len = strm->state->pending; |
|
if (len > strm->avail_out) len = strm->avail_out; |
if (len == 0) return; |
|
zmemcpy(strm->next_out, strm->state->pending_out, len); |
strm->next_out += len; |
strm->state->pending_out += len; |
strm->total_out += len; |
strm->avail_out -= len; |
strm->state->pending -= len; |
if (strm->state->pending == 0) { |
strm->state->pending_out = strm->state->pending_buf; |
} |
} |
|
/* ========================================================================= */ |
int ZEXPORT deflate (strm, flush) |
z_streamp strm; |
int flush; |
{ |
int old_flush; /* value of flush param for previous deflate call */ |
deflate_state *s; |
|
if (strm == Z_NULL || strm->state == Z_NULL || |
flush > Z_FINISH || flush < 0) { |
return Z_STREAM_ERROR; |
} |
s = strm->state; |
|
if (strm->next_out == Z_NULL || |
(strm->next_in == Z_NULL && strm->avail_in != 0) || |
(s->status == FINISH_STATE && flush != Z_FINISH)) { |
ERR_RETURN(strm, Z_STREAM_ERROR); |
} |
if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); |
|
s->strm = strm; /* just in case */ |
old_flush = s->last_flush; |
s->last_flush = flush; |
|
/* Write the zlib header */ |
if (s->status == INIT_STATE) { |
|
uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; |
uInt level_flags = (s->level-1) >> 1; |
|
if (level_flags > 3) level_flags = 3; |
header |= (level_flags << 6); |
if (s->strstart != 0) header |= PRESET_DICT; |
header += 31 - (header % 31); |
|
s->status = BUSY_STATE; |
putShortMSB(s, header); |
|
/* Save the adler32 of the preset dictionary: */ |
if (s->strstart != 0) { |
putShortMSB(s, (uInt)(strm->adler >> 16)); |
putShortMSB(s, (uInt)(strm->adler & 0xffff)); |
} |
strm->adler = 1L; |
} |
|
/* Flush as much pending output as possible */ |
if (s->pending != 0) { |
flush_pending(strm); |
if (strm->avail_out == 0) { |
/* Since avail_out is 0, deflate will be called again with |
* more output space, but possibly with both pending and |
* avail_in equal to zero. There won't be anything to do, |
* but this is not an error situation so make sure we |
* return OK instead of BUF_ERROR at next call of deflate: |
*/ |
s->last_flush = -1; |
return Z_OK; |
} |
|
/* Make sure there is something to do and avoid duplicate consecutive |
* flushes. For repeated and useless calls with Z_FINISH, we keep |
* returning Z_STREAM_END instead of Z_BUFF_ERROR. |
*/ |
} else if (strm->avail_in == 0 && flush <= old_flush && |
flush != Z_FINISH) { |
ERR_RETURN(strm, Z_BUF_ERROR); |
} |
|
/* User must not provide more input after the first FINISH: */ |
if (s->status == FINISH_STATE && strm->avail_in != 0) { |
ERR_RETURN(strm, Z_BUF_ERROR); |
} |
|
/* Start a new block or continue the current one. |
*/ |
if (strm->avail_in != 0 || s->lookahead != 0 || |
(flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { |
block_state bstate; |
|
bstate = (*(configuration_table[s->level].func))(s, flush); |
|
if (bstate == finish_started || bstate == finish_done) { |
s->status = FINISH_STATE; |
} |
if (bstate == need_more || bstate == finish_started) { |
if (strm->avail_out == 0) { |
s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ |
} |
return Z_OK; |
/* If flush != Z_NO_FLUSH && avail_out == 0, the next call |
* of deflate should use the same flush parameter to make sure |
* that the flush is complete. So we don't have to output an |
* empty block here, this will be done at next call. This also |
* ensures that for a very small output buffer, we emit at most |
* one empty block. |
*/ |
} |
if (bstate == block_done) { |
if (flush == Z_PARTIAL_FLUSH) { |
_tr_align(s); |
} else { /* FULL_FLUSH or SYNC_FLUSH */ |
_tr_stored_block(s, (char*)0, 0L, 0); |
/* For a full flush, this empty block will be recognized |
* as a special marker by inflate_sync(). |
*/ |
if (flush == Z_FULL_FLUSH) { |
CLEAR_HASH(s); /* forget history */ |
} |
} |
flush_pending(strm); |
if (strm->avail_out == 0) { |
s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ |
return Z_OK; |
} |
} |
} |
Assert(strm->avail_out > 0, "bug2"); |
|
if (flush != Z_FINISH) return Z_OK; |
if (s->noheader) return Z_STREAM_END; |
|
/* Write the zlib trailer (adler32) */ |
putShortMSB(s, (uInt)(strm->adler >> 16)); |
putShortMSB(s, (uInt)(strm->adler & 0xffff)); |
flush_pending(strm); |
/* If avail_out is zero, the application will call deflate again |
* to flush the rest. |
*/ |
s->noheader = -1; /* write the trailer only once! */ |
return s->pending != 0 ? Z_OK : Z_STREAM_END; |
} |
|
/* ========================================================================= */ |
int ZEXPORT deflateEnd (strm) |
z_streamp strm; |
{ |
int status; |
|
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; |
|
status = strm->state->status; |
if (status != INIT_STATE && status != BUSY_STATE && |
status != FINISH_STATE) { |
return Z_STREAM_ERROR; |
} |
|
/* Deallocate in reverse order of allocations: */ |
TRY_FREE(strm, strm->state->pending_buf); |
TRY_FREE(strm, strm->state->head); |
TRY_FREE(strm, strm->state->prev); |
TRY_FREE(strm, strm->state->window); |
|
ZFREE(strm, strm->state); |
strm->state = Z_NULL; |
|
return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; |
} |
|
/* ========================================================================= |
* Copy the source state to the destination state. |
* To simplify the source, this is not supported for 16-bit MSDOS (which |
* doesn't have enough memory anyway to duplicate compression states). |
*/ |
int ZEXPORT deflateCopy (dest, source) |
z_streamp dest; |
z_streamp source; |
{ |
#ifdef MAXSEG_64K |
return Z_STREAM_ERROR; |
#else |
deflate_state *ds; |
deflate_state *ss; |
ushf *overlay; |
|
|
if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { |
return Z_STREAM_ERROR; |
} |
|
ss = source->state; |
|
*dest = *source; |
|
ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); |
if (ds == Z_NULL) return Z_MEM_ERROR; |
dest->state = (struct internal_state FAR *) ds; |
*ds = *ss; |
ds->strm = dest; |
|
ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); |
ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); |
ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); |
overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); |
ds->pending_buf = (uchf *) overlay; |
|
if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || |
ds->pending_buf == Z_NULL) { |
deflateEnd (dest); |
return Z_MEM_ERROR; |
} |
/* following zmemcpy do not work for 16-bit MSDOS */ |
zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); |
zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); |
zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); |
zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); |
|
ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); |
ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); |
ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; |
|
ds->l_desc.dyn_tree = ds->dyn_ltree; |
ds->d_desc.dyn_tree = ds->dyn_dtree; |
ds->bl_desc.dyn_tree = ds->bl_tree; |
|
return Z_OK; |
#endif |
} |
|
/* =========================================================================== |
* Read a new buffer from the current input stream, update the adler32 |
* and total number of bytes read. All deflate() input goes through |
* this function so some applications may wish to modify it to avoid |
* allocating a large strm->next_in buffer and copying from it. |
* (See also flush_pending()). |
*/ |
local int read_buf(strm, buf, size) |
z_streamp strm; |
Bytef *buf; |
unsigned size; |
{ |
unsigned len = strm->avail_in; |
|
if (len > size) len = size; |
if (len == 0) return 0; |
|
strm->avail_in -= len; |
|
if (!strm->state->noheader) { |
strm->adler = adler32(strm->adler, strm->next_in, len); |
} |
zmemcpy(buf, strm->next_in, len); |
strm->next_in += len; |
strm->total_in += len; |
|
return (int)len; |
} |
|
/* =========================================================================== |
* Initialize the "longest match" routines for a new zlib stream |
*/ |
local void lm_init (s) |
deflate_state *s; |
{ |
s->window_size = (ulg)2L*s->w_size; |
|
CLEAR_HASH(s); |
|
/* Set the default configuration parameters: |
*/ |
s->max_lazy_match = configuration_table[s->level].max_lazy; |
s->good_match = configuration_table[s->level].good_length; |
s->nice_match = configuration_table[s->level].nice_length; |
s->max_chain_length = configuration_table[s->level].max_chain; |
|
s->strstart = 0; |
s->block_start = 0L; |
s->lookahead = 0; |
s->match_length = s->prev_length = MIN_MATCH-1; |
s->match_available = 0; |
s->ins_h = 0; |
#ifdef ASMV |
match_init(); /* initialize the asm code */ |
#endif |
} |
|
/* =========================================================================== |
* Set match_start to the longest match starting at the given string and |
* return its length. Matches shorter or equal to prev_length are discarded, |
* in which case the result is equal to prev_length and match_start is |
* garbage. |
* IN assertions: cur_match is the head of the hash chain for the current |
* string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 |
* OUT assertion: the match length is not greater than s->lookahead. |
*/ |
#ifndef ASMV |
/* For 80x86 and 680x0, an optimized version will be provided in match.asm or |
* match.S. The code will be functionally equivalent. |
*/ |
#ifndef FASTEST |
local uInt longest_match(s, cur_match) |
deflate_state *s; |
IPos cur_match; /* current match */ |
{ |
unsigned chain_length = s->max_chain_length;/* max hash chain length */ |
register Bytef *scan = s->window + s->strstart; /* current string */ |
register Bytef *match; /* matched string */ |
register int len; /* length of current match */ |
int best_len = s->prev_length; /* best match length so far */ |
int nice_match = s->nice_match; /* stop if match long enough */ |
IPos limit = s->strstart > (IPos)MAX_DIST(s) ? |
s->strstart - (IPos)MAX_DIST(s) : NIL; |
/* Stop when cur_match becomes <= limit. To simplify the code, |
* we prevent matches with the string of window index 0. |
*/ |
Posf *prev = s->prev; |
uInt wmask = s->w_mask; |
|
#ifdef UNALIGNED_OK |
/* Compare two bytes at a time. Note: this is not always beneficial. |
* Try with and without -DUNALIGNED_OK to check. |
*/ |
register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; |
register ush scan_start = *(ushf*)scan; |
register ush scan_end = *(ushf*)(scan+best_len-1); |
#else |
register Bytef *strend = s->window + s->strstart + MAX_MATCH; |
register Byte scan_end1 = scan[best_len-1]; |
register Byte scan_end = scan[best_len]; |
#endif |
|
/* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. |
* It is easy to get rid of this optimization if necessary. |
*/ |
Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); |
|
/* Do not waste too much time if we already have a good match: */ |
if (s->prev_length >= s->good_match) { |
chain_length >>= 2; |
} |
/* Do not look for matches beyond the end of the input. This is necessary |
* to make deflate deterministic. |
*/ |
if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; |
|
Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); |
|
do { |
Assert(cur_match < s->strstart, "no future"); |
match = s->window + cur_match; |
|
/* Skip to next match if the match length cannot increase |
* or if the match length is less than 2: |
*/ |
#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) |
/* This code assumes sizeof(unsigned short) == 2. Do not use |
* UNALIGNED_OK if your compiler uses a different size. |
*/ |
if (*(ushf*)(match+best_len-1) != scan_end || |
*(ushf*)match != scan_start) continue; |
|
/* It is not necessary to compare scan[2] and match[2] since they are |
* always equal when the other bytes match, given that the hash keys |
* are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at |
* strstart+3, +5, ... up to strstart+257. We check for insufficient |
* lookahead only every 4th comparison; the 128th check will be made |
* at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is |
* necessary to put more guard bytes at the end of the window, or |
* to check more often for insufficient lookahead. |
*/ |
Assert(scan[2] == match[2], "scan[2]?"); |
scan++, match++; |
do { |
} while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && |
*(ushf*)(scan+=2) == *(ushf*)(match+=2) && |
*(ushf*)(scan+=2) == *(ushf*)(match+=2) && |
*(ushf*)(scan+=2) == *(ushf*)(match+=2) && |
scan < strend); |
/* The funny "do {}" generates better code on most compilers */ |
|
/* Here, scan <= window+strstart+257 */ |
Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); |
if (*scan == *match) scan++; |
|
len = (MAX_MATCH - 1) - (int)(strend-scan); |
scan = strend - (MAX_MATCH-1); |
|
#else /* UNALIGNED_OK */ |
|
if (match[best_len] != scan_end || |
match[best_len-1] != scan_end1 || |
*match != *scan || |
*++match != scan[1]) continue; |
|
/* The check at best_len-1 can be removed because it will be made |
* again later. (This heuristic is not always a win.) |
* It is not necessary to compare scan[2] and match[2] since they |
* are always equal when the other bytes match, given that |
* the hash keys are equal and that HASH_BITS >= 8. |
*/ |
scan += 2, match++; |
Assert(*scan == *match, "match[2]?"); |
|
/* We check for insufficient lookahead only every 8th comparison; |
* the 256th check will be made at strstart+258. |
*/ |
do { |
} while (*++scan == *++match && *++scan == *++match && |
*++scan == *++match && *++scan == *++match && |
*++scan == *++match && *++scan == *++match && |
*++scan == *++match && *++scan == *++match && |
scan < strend); |
|
Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); |
|
len = MAX_MATCH - (int)(strend - scan); |
scan = strend - MAX_MATCH; |
|
#endif /* UNALIGNED_OK */ |
|
if (len > best_len) { |
s->match_start = cur_match; |
best_len = len; |
if (len >= nice_match) break; |
#ifdef UNALIGNED_OK |
scan_end = *(ushf*)(scan+best_len-1); |
#else |
scan_end1 = scan[best_len-1]; |
scan_end = scan[best_len]; |
#endif |
} |
} while ((cur_match = prev[cur_match & wmask]) > limit |
&& --chain_length != 0); |
|
if ((uInt)best_len <= s->lookahead) return (uInt)best_len; |
return s->lookahead; |
} |
|
#else /* FASTEST */ |
/* --------------------------------------------------------------------------- |
* Optimized version for level == 1 only |
*/ |
local uInt longest_match(s, cur_match) |
deflate_state *s; |
IPos cur_match; /* current match */ |
{ |
register Bytef *scan = s->window + s->strstart; /* current string */ |
register Bytef *match; /* matched string */ |
register int len; /* length of current match */ |
register Bytef *strend = s->window + s->strstart + MAX_MATCH; |
|
/* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. |
* It is easy to get rid of this optimization if necessary. |
*/ |
Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); |
|
Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); |
|
Assert(cur_match < s->strstart, "no future"); |
|
match = s->window + cur_match; |
|
/* Return failure if the match length is less than 2: |
*/ |
if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; |
|
/* The check at best_len-1 can be removed because it will be made |
* again later. (This heuristic is not always a win.) |
* It is not necessary to compare scan[2] and match[2] since they |
* are always equal when the other bytes match, given that |
* the hash keys are equal and that HASH_BITS >= 8. |
*/ |
scan += 2, match += 2; |
Assert(*scan == *match, "match[2]?"); |
|
/* We check for insufficient lookahead only every 8th comparison; |
* the 256th check will be made at strstart+258. |
*/ |
do { |
} while (*++scan == *++match && *++scan == *++match && |
*++scan == *++match && *++scan == *++match && |
*++scan == *++match && *++scan == *++match && |
*++scan == *++match && *++scan == *++match && |
scan < strend); |
|
Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); |
|
len = MAX_MATCH - (int)(strend - scan); |
|
if (len < MIN_MATCH) return MIN_MATCH - 1; |
|
s->match_start = cur_match; |
return len <= s->lookahead ? len : s->lookahead; |
} |
#endif /* FASTEST */ |
#endif /* ASMV */ |
|
#ifdef DEBUG |
/* =========================================================================== |
* Check that the match at match_start is indeed a match. |
*/ |
local void check_match(s, start, match, length) |
deflate_state *s; |
IPos start, match; |
int length; |
{ |
/* check that the match is indeed a match */ |
if (zmemcmp(s->window + match, |
s->window + start, length) != EQUAL) { |
fprintf(stderr, " start %u, match %u, length %d\n", |
start, match, length); |
do { |
fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); |
} while (--length != 0); |
z_error("invalid match"); |
} |
if (z_verbose > 1) { |
fprintf(stderr,"\\[%d,%d]", start-match, length); |
do { putc(s->window[start++], stderr); } while (--length != 0); |
} |
} |
#else |
# define check_match(s, start, match, length) |
#endif |
|
/* =========================================================================== |
* Fill the window when the lookahead becomes insufficient. |
* Updates strstart and lookahead. |
* |
* IN assertion: lookahead < MIN_LOOKAHEAD |
* OUT assertions: strstart <= window_size-MIN_LOOKAHEAD |
* At least one byte has been read, or avail_in == 0; reads are |
* performed for at least two bytes (required for the zip translate_eol |
* option -- not supported here). |
*/ |
local void fill_window(s) |
deflate_state *s; |
{ |
register unsigned n, m; |
register Posf *p; |
unsigned more; /* Amount of free space at the end of the window. */ |
uInt wsize = s->w_size; |
|
do { |
more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); |
|
/* Deal with !@#$% 64K limit: */ |
if (more == 0 && s->strstart == 0 && s->lookahead == 0) { |
more = wsize; |
|
} else if (more == (unsigned)(-1)) { |
/* Very unlikely, but possible on 16 bit machine if strstart == 0 |
* and lookahead == 1 (input done one byte at time) |
*/ |
more--; |
|
/* If the window is almost full and there is insufficient lookahead, |
* move the upper half to the lower one to make room in the upper half. |
*/ |
} else if (s->strstart >= wsize+MAX_DIST(s)) { |
|
zmemcpy(s->window, s->window+wsize, (unsigned)wsize); |
s->match_start -= wsize; |
s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ |
s->block_start -= (long) wsize; |
|
/* Slide the hash table (could be avoided with 32 bit values |
at the expense of memory usage). We slide even when level == 0 |
to keep the hash table consistent if we switch back to level > 0 |
later. (Using level 0 permanently is not an optimal usage of |
zlib, so we don't care about this pathological case.) |
*/ |
n = s->hash_size; |
p = &s->head[n]; |
do { |
m = *--p; |
*p = (Pos)(m >= wsize ? m-wsize : NIL); |
} while (--n); |
|
n = wsize; |
#ifndef FASTEST |
p = &s->prev[n]; |
do { |
m = *--p; |
*p = (Pos)(m >= wsize ? m-wsize : NIL); |
/* If n is not on any hash chain, prev[n] is garbage but |
* its value will never be used. |
*/ |
} while (--n); |
#endif |
more += wsize; |
} |
if (s->strm->avail_in == 0) return; |
|
/* If there was no sliding: |
* strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && |
* more == window_size - lookahead - strstart |
* => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) |
* => more >= window_size - 2*WSIZE + 2 |
* In the BIG_MEM or MMAP case (not yet supported), |
* window_size == input_size + MIN_LOOKAHEAD && |
* strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. |
* Otherwise, window_size == 2*WSIZE so more >= 2. |
* If there was sliding, more >= WSIZE. So in all cases, more >= 2. |
*/ |
Assert(more >= 2, "more < 2"); |
|
n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); |
s->lookahead += n; |
|
/* Initialize the hash value now that we have some input: */ |
if (s->lookahead >= MIN_MATCH) { |
s->ins_h = s->window[s->strstart]; |
UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); |
#if MIN_MATCH != 3 |
Call UPDATE_HASH() MIN_MATCH-3 more times |
#endif |
} |
/* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, |
* but this is not important since only literal bytes will be emitted. |
*/ |
|
} while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); |
} |
|
/* =========================================================================== |
* Flush the current block, with given end-of-file flag. |
* IN assertion: strstart is set to the end of the current match. |
*/ |
#define FLUSH_BLOCK_ONLY(s, eof) { \ |
_tr_flush_block(s, (s->block_start >= 0L ? \ |
(charf *)&s->window[(unsigned)s->block_start] : \ |
(charf *)Z_NULL), \ |
(ulg)((long)s->strstart - s->block_start), \ |
(eof)); \ |
s->block_start = s->strstart; \ |
flush_pending(s->strm); \ |
Tracev((stderr,"[FLUSH]")); \ |
} |
|
/* Same but force premature exit if necessary. */ |
#define FLUSH_BLOCK(s, eof) { \ |
FLUSH_BLOCK_ONLY(s, eof); \ |
if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ |
} |
|
/* =========================================================================== |
* Copy without compression as much as possible from the input stream, return |
* the current block state. |
* This function does not insert new strings in the dictionary since |
* uncompressible data is probably not useful. This function is used |
* only for the level=0 compression option. |
* NOTE: this function should be optimized to avoid extra copying from |
* window to pending_buf. |
*/ |
local block_state deflate_stored(s, flush) |
deflate_state *s; |
int flush; |
{ |
/* Stored blocks are limited to 0xffff bytes, pending_buf is limited |
* to pending_buf_size, and each stored block has a 5 byte header: |
*/ |
ulg max_block_size = 0xffff; |
ulg max_start; |
|
if (max_block_size > s->pending_buf_size - 5) { |
max_block_size = s->pending_buf_size - 5; |
} |
|
/* Copy as much as possible from input to output: */ |
for (;;) { |
/* Fill the window as much as possible: */ |
if (s->lookahead <= 1) { |
|
Assert(s->strstart < s->w_size+MAX_DIST(s) || |
s->block_start >= (long)s->w_size, "slide too late"); |
|
fill_window(s); |
if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; |
|
if (s->lookahead == 0) break; /* flush the current block */ |
} |
Assert(s->block_start >= 0L, "block gone"); |
|
s->strstart += s->lookahead; |
s->lookahead = 0; |
|
/* Emit a stored block if pending_buf will be full: */ |
max_start = s->block_start + max_block_size; |
if (s->strstart == 0 || (ulg)s->strstart >= max_start) { |
/* strstart == 0 is possible when wraparound on 16-bit machine */ |
s->lookahead = (uInt)(s->strstart - max_start); |
s->strstart = (uInt)max_start; |
FLUSH_BLOCK(s, 0); |
} |
/* Flush if we may have to slide, otherwise block_start may become |
* negative and the data will be gone: |
*/ |
if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { |
FLUSH_BLOCK(s, 0); |
} |
} |
FLUSH_BLOCK(s, flush == Z_FINISH); |
return flush == Z_FINISH ? finish_done : block_done; |
} |
|
/* =========================================================================== |
* Compress as much as possible from the input stream, return the current |
* block state. |
* This function does not perform lazy evaluation of matches and inserts |
* new strings in the dictionary only for unmatched strings or for short |
* matches. It is used only for the fast compression options. |
*/ |
local block_state deflate_fast(s, flush) |
deflate_state *s; |
int flush; |
{ |
IPos hash_head = NIL; /* head of the hash chain */ |
int bflush; /* set if current block must be flushed */ |
|
for (;;) { |
/* Make sure that we always have enough lookahead, except |
* at the end of the input file. We need MAX_MATCH bytes |
* for the next match, plus MIN_MATCH bytes to insert the |
* string following the next match. |
*/ |
if (s->lookahead < MIN_LOOKAHEAD) { |
fill_window(s); |
if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { |
return need_more; |
} |
if (s->lookahead == 0) break; /* flush the current block */ |
} |
|
/* Insert the string window[strstart .. strstart+2] in the |
* dictionary, and set hash_head to the head of the hash chain: |
*/ |
if (s->lookahead >= MIN_MATCH) { |
INSERT_STRING(s, s->strstart, hash_head); |
} |
|
/* Find the longest match, discarding those <= prev_length. |
* At this point we have always match_length < MIN_MATCH |
*/ |
if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { |
/* To simplify the code, we prevent matches with the string |
* of window index 0 (in particular we have to avoid a match |
* of the string with itself at the start of the input file). |
*/ |
if (s->strategy != Z_HUFFMAN_ONLY) { |
s->match_length = longest_match (s, hash_head); |
} |
/* longest_match() sets match_start */ |
} |
if (s->match_length >= MIN_MATCH) { |
check_match(s, s->strstart, s->match_start, s->match_length); |
|
_tr_tally_dist(s, s->strstart - s->match_start, |
s->match_length - MIN_MATCH, bflush); |
|
s->lookahead -= s->match_length; |
|
/* Insert new strings in the hash table only if the match length |
* is not too large. This saves time but degrades compression. |
*/ |
#ifndef FASTEST |
if (s->match_length <= s->max_insert_length && |
s->lookahead >= MIN_MATCH) { |
s->match_length--; /* string at strstart already in hash table */ |
do { |
s->strstart++; |
INSERT_STRING(s, s->strstart, hash_head); |
/* strstart never exceeds WSIZE-MAX_MATCH, so there are |
* always MIN_MATCH bytes ahead. |
*/ |
} while (--s->match_length != 0); |
s->strstart++; |
} else |
#endif |
{ |
s->strstart += s->match_length; |
s->match_length = 0; |
s->ins_h = s->window[s->strstart]; |
UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); |
#if MIN_MATCH != 3 |
Call UPDATE_HASH() MIN_MATCH-3 more times |
#endif |
/* If lookahead < MIN_MATCH, ins_h is garbage, but it does not |
* matter since it will be recomputed at next deflate call. |
*/ |
} |
} else { |
/* No match, output a literal byte */ |
Tracevv((stderr,"%c", s->window[s->strstart])); |
_tr_tally_lit (s, s->window[s->strstart], bflush); |
s->lookahead--; |
s->strstart++; |
} |
if (bflush) FLUSH_BLOCK(s, 0); |
} |
FLUSH_BLOCK(s, flush == Z_FINISH); |
return flush == Z_FINISH ? finish_done : block_done; |
} |
|
/* =========================================================================== |
* Same as above, but achieves better compression. We use a lazy |
* evaluation for matches: a match is finally adopted only if there is |
* no better match at the next window position. |
*/ |
local block_state deflate_slow(s, flush) |
deflate_state *s; |
int flush; |
{ |
IPos hash_head = NIL; /* head of hash chain */ |
int bflush; /* set if current block must be flushed */ |
|
/* Process the input block. */ |
for (;;) { |
/* Make sure that we always have enough lookahead, except |
* at the end of the input file. We need MAX_MATCH bytes |
* for the next match, plus MIN_MATCH bytes to insert the |
* string following the next match. |
*/ |
if (s->lookahead < MIN_LOOKAHEAD) { |
fill_window(s); |
if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { |
return need_more; |
} |
if (s->lookahead == 0) break; /* flush the current block */ |
} |
|
/* Insert the string window[strstart .. strstart+2] in the |
* dictionary, and set hash_head to the head of the hash chain: |
*/ |
if (s->lookahead >= MIN_MATCH) { |
INSERT_STRING(s, s->strstart, hash_head); |
} |
|
/* Find the longest match, discarding those <= prev_length. |
*/ |
s->prev_length = s->match_length, s->prev_match = s->match_start; |
s->match_length = MIN_MATCH-1; |
|
if (hash_head != NIL && s->prev_length < s->max_lazy_match && |
s->strstart - hash_head <= MAX_DIST(s)) { |
/* To simplify the code, we prevent matches with the string |
* of window index 0 (in particular we have to avoid a match |
* of the string with itself at the start of the input file). |
*/ |
if (s->strategy != Z_HUFFMAN_ONLY) { |
s->match_length = longest_match (s, hash_head); |
} |
/* longest_match() sets match_start */ |
|
if (s->match_length <= 5 && (s->strategy == Z_FILTERED || |
(s->match_length == MIN_MATCH && |
s->strstart - s->match_start > TOO_FAR))) { |
|
/* If prev_match is also MIN_MATCH, match_start is garbage |
* but we will ignore the current match anyway. |
*/ |
s->match_length = MIN_MATCH-1; |
} |
} |
/* If there was a match at the previous step and the current |
* match is not better, output the previous match: |
*/ |
if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { |
uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; |
/* Do not insert strings in hash table beyond this. */ |
|
check_match(s, s->strstart-1, s->prev_match, s->prev_length); |
|
_tr_tally_dist(s, s->strstart -1 - s->prev_match, |
s->prev_length - MIN_MATCH, bflush); |
|
/* Insert in hash table all strings up to the end of the match. |
* strstart-1 and strstart are already inserted. If there is not |
* enough lookahead, the last two strings are not inserted in |
* the hash table. |
*/ |
s->lookahead -= s->prev_length-1; |
s->prev_length -= 2; |
do { |
if (++s->strstart <= max_insert) { |
INSERT_STRING(s, s->strstart, hash_head); |
} |
} while (--s->prev_length != 0); |
s->match_available = 0; |
s->match_length = MIN_MATCH-1; |
s->strstart++; |
|
if (bflush) FLUSH_BLOCK(s, 0); |
|
} else if (s->match_available) { |
/* If there was no match at the previous position, output a |
* single literal. If there was a match but the current match |
* is longer, truncate the previous match to a single literal. |
*/ |
Tracevv((stderr,"%c", s->window[s->strstart-1])); |
_tr_tally_lit(s, s->window[s->strstart-1], bflush); |
if (bflush) { |
FLUSH_BLOCK_ONLY(s, 0); |
} |
s->strstart++; |
s->lookahead--; |
if (s->strm->avail_out == 0) return need_more; |
} else { |
/* There is no previous match to compare with, wait for |
* the next step to decide. |
*/ |
s->match_available = 1; |
s->strstart++; |
s->lookahead--; |
} |
} |
Assert (flush != Z_NO_FLUSH, "no flush?"); |
if (s->match_available) { |
Tracevv((stderr,"%c", s->window[s->strstart-1])); |
_tr_tally_lit(s, s->window[s->strstart-1], bflush); |
s->match_available = 0; |
} |
FLUSH_BLOCK(s, flush == Z_FINISH); |
return flush == Z_FINISH ? finish_done : block_done; |
} |
/v2_0/src/zutil.c
0,0 → 1,225
/* zutil.c -- target dependent utility functions for the compression library |
* Copyright (C) 1995-1998 Jean-loup Gailly. |
* For conditions of distribution and use, see copyright notice in zlib.h |
*/ |
|
/* @(#) $Id: zutil.c,v 1.1.1.1 2004-02-14 13:35:37 phoenix Exp $ */ |
|
#include "zutil.h" |
|
struct internal_state {int dummy;}; /* for buggy compilers */ |
|
#ifndef STDC |
extern void exit OF((int)); |
#endif |
|
const char *z_errmsg[10] = { |
"need dictionary", /* Z_NEED_DICT 2 */ |
"stream end", /* Z_STREAM_END 1 */ |
"", /* Z_OK 0 */ |
"file error", /* Z_ERRNO (-1) */ |
"stream error", /* Z_STREAM_ERROR (-2) */ |
"data error", /* Z_DATA_ERROR (-3) */ |
"insufficient memory", /* Z_MEM_ERROR (-4) */ |
"buffer error", /* Z_BUF_ERROR (-5) */ |
"incompatible version",/* Z_VERSION_ERROR (-6) */ |
""}; |
|
|
const char * ZEXPORT zlibVersion() |
{ |
return ZLIB_VERSION; |
} |
|
#ifdef DEBUG |
|
# ifndef verbose |
# define verbose 0 |
# endif |
int z_verbose = verbose; |
|
void z_error (m) |
char *m; |
{ |
fprintf(stderr, "%s\n", m); |
exit(1); |
} |
#endif |
|
/* exported to allow conversion of error code to string for compress() and |
* uncompress() |
*/ |
const char * ZEXPORT zError(err) |
int err; |
{ |
return ERR_MSG(err); |
} |
|
|
#ifndef HAVE_MEMCPY |
|
void zmemcpy(dest, source, len) |
Bytef* dest; |
const Bytef* source; |
uInt len; |
{ |
if (len == 0) return; |
do { |
*dest++ = *source++; /* ??? to be unrolled */ |
} while (--len != 0); |
} |
|
int zmemcmp(s1, s2, len) |
const Bytef* s1; |
const Bytef* s2; |
uInt len; |
{ |
uInt j; |
|
for (j = 0; j < len; j++) { |
if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; |
} |
return 0; |
} |
|
void zmemzero(dest, len) |
Bytef* dest; |
uInt len; |
{ |
if (len == 0) return; |
do { |
*dest++ = 0; /* ??? to be unrolled */ |
} while (--len != 0); |
} |
#endif |
|
#ifdef __TURBOC__ |
#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__) |
/* Small and medium model in Turbo C are for now limited to near allocation |
* with reduced MAX_WBITS and MAX_MEM_LEVEL |
*/ |
# define MY_ZCALLOC |
|
/* Turbo C malloc() does not allow dynamic allocation of 64K bytes |
* and farmalloc(64K) returns a pointer with an offset of 8, so we |
* must fix the pointer. Warning: the pointer must be put back to its |
* original form in order to free it, use zcfree(). |
*/ |
|
#define MAX_PTR 10 |
/* 10*64K = 640K */ |
|
local int next_ptr = 0; |
|
typedef struct ptr_table_s { |
voidpf org_ptr; |
voidpf new_ptr; |
} ptr_table; |
|
local ptr_table table[MAX_PTR]; |
/* This table is used to remember the original form of pointers |
* to large buffers (64K). Such pointers are normalized with a zero offset. |
* Since MSDOS is not a preemptive multitasking OS, this table is not |
* protected from concurrent access. This hack doesn't work anyway on |
* a protected system like OS/2. Use Microsoft C instead. |
*/ |
|
voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) |
{ |
voidpf buf = opaque; /* just to make some compilers happy */ |
ulg bsize = (ulg)items*size; |
|
/* If we allocate less than 65520 bytes, we assume that farmalloc |
* will return a usable pointer which doesn't have to be normalized. |
*/ |
if (bsize < 65520L) { |
buf = farmalloc(bsize); |
if (*(ush*)&buf != 0) return buf; |
} else { |
buf = farmalloc(bsize + 16L); |
} |
if (buf == NULL || next_ptr >= MAX_PTR) return NULL; |
table[next_ptr].org_ptr = buf; |
|
/* Normalize the pointer to seg:0 */ |
*((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; |
*(ush*)&buf = 0; |
table[next_ptr++].new_ptr = buf; |
return buf; |
} |
|
void zcfree (voidpf opaque, voidpf ptr) |
{ |
int n; |
if (*(ush*)&ptr != 0) { /* object < 64K */ |
farfree(ptr); |
return; |
} |
/* Find the original pointer */ |
for (n = 0; n < next_ptr; n++) { |
if (ptr != table[n].new_ptr) continue; |
|
farfree(table[n].org_ptr); |
while (++n < next_ptr) { |
table[n-1] = table[n]; |
} |
next_ptr--; |
return; |
} |
ptr = opaque; /* just to make some compilers happy */ |
Assert(0, "zcfree: ptr not found"); |
} |
#endif |
#endif /* __TURBOC__ */ |
|
|
#if defined(M_I86) && !defined(__32BIT__) |
/* Microsoft C in 16-bit mode */ |
|
# define MY_ZCALLOC |
|
#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) |
# define _halloc halloc |
# define _hfree hfree |
#endif |
|
voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) |
{ |
if (opaque) opaque = 0; /* to make compiler happy */ |
return _halloc((long)items, size); |
} |
|
void zcfree (voidpf opaque, voidpf ptr) |
{ |
if (opaque) opaque = 0; /* to make compiler happy */ |
_hfree(ptr); |
} |
|
#endif /* MSC */ |
|
|
#ifndef MY_ZCALLOC /* Any system without a special alloc function */ |
|
#ifndef STDC |
extern voidp calloc OF((uInt items, uInt size)); |
extern void free OF((voidpf ptr)); |
#endif |
|
voidpf zcalloc (opaque, items, size) |
voidpf opaque; |
unsigned items; |
unsigned size; |
{ |
if (opaque) items += size - size; /* make compiler happy */ |
return (voidpf)calloc(items, size); |
} |
|
void zcfree (opaque, ptr) |
voidpf opaque; |
voidpf ptr; |
{ |
free(ptr); |
if (opaque) return; /* make compiler happy */ |
} |
|
#endif /* MY_ZCALLOC */ |
/v2_0/src/gzio.c
0,0 → 1,875
/* gzio.c -- IO on .gz files |
* Copyright (C) 1995-1998 Jean-loup Gailly. |
* For conditions of distribution and use, see copyright notice in zlib.h |
* |
* Compile this file with -DNO_DEFLATE to avoid the compression code. |
*/ |
|
/* @(#) $Id: gzio.c,v 1.1.1.1 2004-02-14 13:35:38 phoenix Exp $ */ |
|
#include <stdio.h> |
|
#include "zutil.h" |
|
struct internal_state {int dummy;}; /* for buggy compilers */ |
|
#ifndef Z_BUFSIZE |
# ifdef MAXSEG_64K |
# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ |
# else |
# define Z_BUFSIZE 16384 |
# endif |
#endif |
#ifndef Z_PRINTF_BUFSIZE |
# define Z_PRINTF_BUFSIZE 4096 |
#endif |
|
#define ALLOC(size) malloc(size) |
#define TRYFREE(p) {if (p) free(p);} |
|
static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ |
|
/* gzip flag byte */ |
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ |
#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ |
#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ |
#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ |
#define COMMENT 0x10 /* bit 4 set: file comment present */ |
#define RESERVED 0xE0 /* bits 5..7: reserved */ |
|
typedef struct gz_stream { |
z_stream stream; |
int z_err; /* error code for last stream operation */ |
int z_eof; /* set if end of input file */ |
FILE *file; /* .gz file */ |
Byte *inbuf; /* input buffer */ |
Byte *outbuf; /* output buffer */ |
uLong crc; /* crc32 of uncompressed data */ |
char *msg; /* error message */ |
char *path; /* path name for debugging only */ |
int transparent; /* 1 if input file is not a .gz file */ |
char mode; /* 'w' or 'r' */ |
long startpos; /* start of compressed data in file (header skipped) */ |
} gz_stream; |
|
|
local gzFile gz_open OF((const char *path, const char *mode, int fd)); |
local int do_flush OF((gzFile file, int flush)); |
local int get_byte OF((gz_stream *s)); |
local void check_header OF((gz_stream *s)); |
local int destroy OF((gz_stream *s)); |
local void putLong OF((FILE *file, uLong x)); |
local uLong getLong OF((gz_stream *s)); |
|
/* =========================================================================== |
Opens a gzip (.gz) file for reading or writing. The mode parameter |
is as in fopen ("rb" or "wb"). The file is given either by file descriptor |
or path name (if fd == -1). |
gz_open return NULL if the file could not be opened or if there was |
insufficient memory to allocate the (de)compression state; errno |
can be checked to distinguish the two cases (if errno is zero, the |
zlib error is Z_MEM_ERROR). |
*/ |
local gzFile gz_open (path, mode, fd) |
const char *path; |
const char *mode; |
int fd; |
{ |
int err; |
int level = Z_DEFAULT_COMPRESSION; /* compression level */ |
int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ |
char *p = (char*)mode; |
gz_stream *s; |
char fmode[80]; /* copy of mode, without the compression level */ |
char *m = fmode; |
|
if (!path || !mode) return Z_NULL; |
|
s = (gz_stream *)ALLOC(sizeof(gz_stream)); |
if (!s) return Z_NULL; |
|
s->stream.zalloc = (alloc_func)0; |
s->stream.zfree = (free_func)0; |
s->stream.opaque = (voidpf)0; |
s->stream.next_in = s->inbuf = Z_NULL; |
s->stream.next_out = s->outbuf = Z_NULL; |
s->stream.avail_in = s->stream.avail_out = 0; |
s->file = NULL; |
s->z_err = Z_OK; |
s->z_eof = 0; |
s->crc = crc32(0L, Z_NULL, 0); |
s->msg = NULL; |
s->transparent = 0; |
|
s->path = (char*)ALLOC(strlen(path)+1); |
if (s->path == NULL) { |
return destroy(s), (gzFile)Z_NULL; |
} |
strcpy(s->path, path); /* do this early for debugging */ |
|
s->mode = '\0'; |
do { |
if (*p == 'r') s->mode = 'r'; |
if (*p == 'w' || *p == 'a') s->mode = 'w'; |
if (*p >= '0' && *p <= '9') { |
level = *p - '0'; |
} else if (*p == 'f') { |
strategy = Z_FILTERED; |
} else if (*p == 'h') { |
strategy = Z_HUFFMAN_ONLY; |
} else { |
*m++ = *p; /* copy the mode */ |
} |
} while (*p++ && m != fmode + sizeof(fmode)); |
if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; |
|
if (s->mode == 'w') { |
#ifdef NO_DEFLATE |
err = Z_STREAM_ERROR; |
#else |
err = deflateInit2(&(s->stream), level, |
Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); |
/* windowBits is passed < 0 to suppress zlib header */ |
|
s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); |
#endif |
if (err != Z_OK || s->outbuf == Z_NULL) { |
return destroy(s), (gzFile)Z_NULL; |
} |
} else { |
s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); |
|
err = inflateInit2(&(s->stream), -MAX_WBITS); |
/* windowBits is passed < 0 to tell that there is no zlib header. |
* Note that in this case inflate *requires* an extra "dummy" byte |
* after the compressed stream in order to complete decompression and |
* return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are |
* present after the compressed stream. |
*/ |
if (err != Z_OK || s->inbuf == Z_NULL) { |
return destroy(s), (gzFile)Z_NULL; |
} |
} |
s->stream.avail_out = Z_BUFSIZE; |
|
errno = 0; |
s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); |
|
if (s->file == NULL) { |
return destroy(s), (gzFile)Z_NULL; |
} |
if (s->mode == 'w') { |
/* Write a very simple .gz header: |
*/ |
fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], |
Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); |
s->startpos = 10L; |
/* We use 10L instead of ftell(s->file) to because ftell causes an |
* fflush on some systems. This version of the library doesn't use |
* startpos anyway in write mode, so this initialization is not |
* necessary. |
*/ |
} else { |
check_header(s); /* skip the .gz header */ |
s->startpos = (ftell(s->file) - s->stream.avail_in); |
} |
|
return (gzFile)s; |
} |
|
/* =========================================================================== |
Opens a gzip (.gz) file for reading or writing. |
*/ |
gzFile ZEXPORT gzopen (path, mode) |
const char *path; |
const char *mode; |
{ |
return gz_open (path, mode, -1); |
} |
|
/* =========================================================================== |
Associate a gzFile with the file descriptor fd. fd is not dup'ed here |
to mimic the behavio(u)r of fdopen. |
*/ |
gzFile ZEXPORT gzdopen (fd, mode) |
int fd; |
const char *mode; |
{ |
char name[20]; |
|
if (fd < 0) return (gzFile)Z_NULL; |
sprintf(name, "<fd:%d>", fd); /* for debugging */ |
|
return gz_open (name, mode, fd); |
} |
|
/* =========================================================================== |
* Update the compression level and strategy |
*/ |
int ZEXPORT gzsetparams (file, level, strategy) |
gzFile file; |
int level; |
int strategy; |
{ |
gz_stream *s = (gz_stream*)file; |
|
if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; |
|
/* Make room to allow flushing */ |
if (s->stream.avail_out == 0) { |
|
s->stream.next_out = s->outbuf; |
if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { |
s->z_err = Z_ERRNO; |
} |
s->stream.avail_out = Z_BUFSIZE; |
} |
|
return deflateParams (&(s->stream), level, strategy); |
} |
|
/* =========================================================================== |
Read a byte from a gz_stream; update next_in and avail_in. Return EOF |
for end of file. |
IN assertion: the stream s has been sucessfully opened for reading. |
*/ |
local int get_byte(s) |
gz_stream *s; |
{ |
if (s->z_eof) return EOF; |
if (s->stream.avail_in == 0) { |
errno = 0; |
s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); |
if (s->stream.avail_in == 0) { |
s->z_eof = 1; |
if (ferror(s->file)) s->z_err = Z_ERRNO; |
return EOF; |
} |
s->stream.next_in = s->inbuf; |
} |
s->stream.avail_in--; |
return *(s->stream.next_in)++; |
} |
|
/* =========================================================================== |
Check the gzip header of a gz_stream opened for reading. Set the stream |
mode to transparent if the gzip magic header is not present; set s->err |
to Z_DATA_ERROR if the magic header is present but the rest of the header |
is incorrect. |
IN assertion: the stream s has already been created sucessfully; |
s->stream.avail_in is zero for the first time, but may be non-zero |
for concatenated .gz files. |
*/ |
local void check_header(s) |
gz_stream *s; |
{ |
int method; /* method byte */ |
int flags; /* flags byte */ |
uInt len; |
int c; |
|
/* Check the gzip magic header */ |
for (len = 0; len < 2; len++) { |
c = get_byte(s); |
if (c != gz_magic[len]) { |
if (len != 0) s->stream.avail_in++, s->stream.next_in--; |
if (c != EOF) { |
s->stream.avail_in++, s->stream.next_in--; |
s->transparent = 1; |
} |
s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END; |
return; |
} |
} |
method = get_byte(s); |
flags = get_byte(s); |
if (method != Z_DEFLATED || (flags & RESERVED) != 0) { |
s->z_err = Z_DATA_ERROR; |
return; |
} |
|
/* Discard time, xflags and OS code: */ |
for (len = 0; len < 6; len++) (void)get_byte(s); |
|
if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ |
len = (uInt)get_byte(s); |
len += ((uInt)get_byte(s))<<8; |
/* len is garbage if EOF but the loop below will quit anyway */ |
while (len-- != 0 && get_byte(s) != EOF) ; |
} |
if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ |
while ((c = get_byte(s)) != 0 && c != EOF) ; |
} |
if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ |
while ((c = get_byte(s)) != 0 && c != EOF) ; |
} |
if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ |
for (len = 0; len < 2; len++) (void)get_byte(s); |
} |
s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; |
} |
|
/* =========================================================================== |
* Cleanup then free the given gz_stream. Return a zlib error code. |
Try freeing in the reverse order of allocations. |
*/ |
local int destroy (s) |
gz_stream *s; |
{ |
int err = Z_OK; |
|
if (!s) return Z_STREAM_ERROR; |
|
TRYFREE(s->msg); |
|
if (s->stream.state != NULL) { |
if (s->mode == 'w') { |
#ifdef NO_DEFLATE |
err = Z_STREAM_ERROR; |
#else |
err = deflateEnd(&(s->stream)); |
#endif |
} else if (s->mode == 'r') { |
err = inflateEnd(&(s->stream)); |
} |
} |
if (s->file != NULL && fclose(s->file)) { |
#ifdef ESPIPE |
if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ |
#endif |
err = Z_ERRNO; |
} |
if (s->z_err < 0) err = s->z_err; |
|
TRYFREE(s->inbuf); |
TRYFREE(s->outbuf); |
TRYFREE(s->path); |
TRYFREE(s); |
return err; |
} |
|
/* =========================================================================== |
Reads the given number of uncompressed bytes from the compressed file. |
gzread returns the number of bytes actually read (0 for end of file). |
*/ |
int ZEXPORT gzread (file, buf, len) |
gzFile file; |
voidp buf; |
unsigned len; |
{ |
gz_stream *s = (gz_stream*)file; |
Bytef *start = (Bytef*)buf; /* starting point for crc computation */ |
Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ |
|
if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; |
|
if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; |
if (s->z_err == Z_STREAM_END) return 0; /* EOF */ |
|
next_out = (Byte*)buf; |
s->stream.next_out = (Bytef*)buf; |
s->stream.avail_out = len; |
|
while (s->stream.avail_out != 0) { |
|
if (s->transparent) { |
/* Copy first the lookahead bytes: */ |
uInt n = s->stream.avail_in; |
if (n > s->stream.avail_out) n = s->stream.avail_out; |
if (n > 0) { |
zmemcpy(s->stream.next_out, s->stream.next_in, n); |
next_out += n; |
s->stream.next_out = next_out; |
s->stream.next_in += n; |
s->stream.avail_out -= n; |
s->stream.avail_in -= n; |
} |
if (s->stream.avail_out > 0) { |
s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out, |
s->file); |
} |
len -= s->stream.avail_out; |
s->stream.total_in += (uLong)len; |
s->stream.total_out += (uLong)len; |
if (len == 0) s->z_eof = 1; |
return (int)len; |
} |
if (s->stream.avail_in == 0 && !s->z_eof) { |
|
errno = 0; |
s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); |
if (s->stream.avail_in == 0) { |
s->z_eof = 1; |
if (ferror(s->file)) { |
s->z_err = Z_ERRNO; |
break; |
} |
} |
s->stream.next_in = s->inbuf; |
} |
s->z_err = inflate(&(s->stream), Z_NO_FLUSH); |
|
if (s->z_err == Z_STREAM_END) { |
/* Check CRC and original size */ |
s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); |
start = s->stream.next_out; |
|
if (getLong(s) != s->crc) { |
s->z_err = Z_DATA_ERROR; |
} else { |
(void)getLong(s); |
/* The uncompressed length returned by above getlong() may |
* be different from s->stream.total_out) in case of |
* concatenated .gz files. Check for such files: |
*/ |
check_header(s); |
if (s->z_err == Z_OK) { |
uLong total_in = s->stream.total_in; |
uLong total_out = s->stream.total_out; |
|
inflateReset(&(s->stream)); |
s->stream.total_in = total_in; |
s->stream.total_out = total_out; |
s->crc = crc32(0L, Z_NULL, 0); |
} |
} |
} |
if (s->z_err != Z_OK || s->z_eof) break; |
} |
s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); |
|
return (int)(len - s->stream.avail_out); |
} |
|
|
/* =========================================================================== |
Reads one byte from the compressed file. gzgetc returns this byte |
or -1 in case of end of file or error. |
*/ |
int ZEXPORT gzgetc(file) |
gzFile file; |
{ |
unsigned char c; |
|
return gzread(file, &c, 1) == 1 ? c : -1; |
} |
|
|
/* =========================================================================== |
Reads bytes from the compressed file until len-1 characters are |
read, or a newline character is read and transferred to buf, or an |
end-of-file condition is encountered. The string is then terminated |
with a null character. |
gzgets returns buf, or Z_NULL in case of error. |
|
The current implementation is not optimized at all. |
*/ |
char * ZEXPORT gzgets(file, buf, len) |
gzFile file; |
char *buf; |
int len; |
{ |
char *b = buf; |
if (buf == Z_NULL || len <= 0) return Z_NULL; |
|
while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ; |
*buf = '\0'; |
return b == buf && len > 0 ? Z_NULL : b; |
} |
|
|
#ifndef NO_DEFLATE |
/* =========================================================================== |
Writes the given number of uncompressed bytes into the compressed file. |
gzwrite returns the number of bytes actually written (0 in case of error). |
*/ |
int ZEXPORT gzwrite (file, buf, len) |
gzFile file; |
const voidp buf; |
unsigned len; |
{ |
gz_stream *s = (gz_stream*)file; |
|
if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; |
|
s->stream.next_in = (Bytef*)buf; |
s->stream.avail_in = len; |
|
while (s->stream.avail_in != 0) { |
|
if (s->stream.avail_out == 0) { |
|
s->stream.next_out = s->outbuf; |
if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { |
s->z_err = Z_ERRNO; |
break; |
} |
s->stream.avail_out = Z_BUFSIZE; |
} |
s->z_err = deflate(&(s->stream), Z_NO_FLUSH); |
if (s->z_err != Z_OK) break; |
} |
s->crc = crc32(s->crc, (const Bytef *)buf, len); |
|
return (int)(len - s->stream.avail_in); |
} |
|
/* =========================================================================== |
Converts, formats, and writes the args to the compressed file under |
control of the format string, as in fprintf. gzprintf returns the number of |
uncompressed bytes actually written (0 in case of error). |
*/ |
#ifdef STDC |
#include <stdarg.h> |
|
int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...) |
{ |
char buf[Z_PRINTF_BUFSIZE]; |
va_list va; |
int len; |
|
va_start(va, format); |
#ifdef HAS_vsnprintf |
(void)vsnprintf(buf, sizeof(buf), format, va); |
#else |
(void)vsprintf(buf, format, va); |
#endif |
va_end(va); |
len = strlen(buf); /* some *sprintf don't return the nb of bytes written */ |
if (len <= 0) return 0; |
|
return gzwrite(file, buf, (unsigned)len); |
} |
#else /* not ANSI C */ |
|
int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, |
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) |
gzFile file; |
const char *format; |
int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, |
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; |
{ |
char buf[Z_PRINTF_BUFSIZE]; |
int len; |
|
#ifdef HAS_snprintf |
snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, |
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); |
#else |
sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, |
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); |
#endif |
len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */ |
if (len <= 0) return 0; |
|
return gzwrite(file, buf, len); |
} |
#endif |
|
/* =========================================================================== |
Writes c, converted to an unsigned char, into the compressed file. |
gzputc returns the value that was written, or -1 in case of error. |
*/ |
int ZEXPORT gzputc(file, c) |
gzFile file; |
int c; |
{ |
unsigned char cc = (unsigned char) c; /* required for big endian systems */ |
|
return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1; |
} |
|
|
/* =========================================================================== |
Writes the given null-terminated string to the compressed file, excluding |
the terminating null character. |
gzputs returns the number of characters written, or -1 in case of error. |
*/ |
int ZEXPORT gzputs(file, s) |
gzFile file; |
const char *s; |
{ |
return gzwrite(file, (char*)s, (unsigned)strlen(s)); |
} |
|
|
/* =========================================================================== |
Flushes all pending output into the compressed file. The parameter |
flush is as in the deflate() function. |
*/ |
local int do_flush (file, flush) |
gzFile file; |
int flush; |
{ |
uInt len; |
int done = 0; |
gz_stream *s = (gz_stream*)file; |
|
if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; |
|
s->stream.avail_in = 0; /* should be zero already anyway */ |
|
for (;;) { |
len = Z_BUFSIZE - s->stream.avail_out; |
|
if (len != 0) { |
if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { |
s->z_err = Z_ERRNO; |
return Z_ERRNO; |
} |
s->stream.next_out = s->outbuf; |
s->stream.avail_out = Z_BUFSIZE; |
} |
if (done) break; |
s->z_err = deflate(&(s->stream), flush); |
|
/* Ignore the second of two consecutive flushes: */ |
if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; |
|
/* deflate has finished flushing only when it hasn't used up |
* all the available space in the output buffer: |
*/ |
done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); |
|
if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; |
} |
return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; |
} |
|
int ZEXPORT gzflush (file, flush) |
gzFile file; |
int flush; |
{ |
gz_stream *s = (gz_stream*)file; |
int err = do_flush (file, flush); |
|
if (err) return err; |
fflush(s->file); |
return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; |
} |
#endif /* NO_DEFLATE */ |
|
/* =========================================================================== |
Sets the starting position for the next gzread or gzwrite on the given |
compressed file. The offset represents a number of bytes in the |
gzseek returns the resulting offset location as measured in bytes from |
the beginning of the uncompressed stream, or -1 in case of error. |
SEEK_END is not implemented, returns error. |
In this version of the library, gzseek can be extremely slow. |
*/ |
z_off_t ZEXPORT gzseek (file, offset, whence) |
gzFile file; |
z_off_t offset; |
int whence; |
{ |
gz_stream *s = (gz_stream*)file; |
|
if (s == NULL || whence == SEEK_END || |
s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) { |
return -1L; |
} |
|
if (s->mode == 'w') { |
#ifdef NO_DEFLATE |
return -1L; |
#else |
if (whence == SEEK_SET) { |
offset -= s->stream.total_in; |
} |
if (offset < 0) return -1L; |
|
/* At this point, offset is the number of zero bytes to write. */ |
if (s->inbuf == Z_NULL) { |
s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ |
zmemzero(s->inbuf, Z_BUFSIZE); |
} |
while (offset > 0) { |
uInt size = Z_BUFSIZE; |
if (offset < Z_BUFSIZE) size = (uInt)offset; |
|
size = gzwrite(file, s->inbuf, size); |
if (size == 0) return -1L; |
|
offset -= size; |
} |
return (z_off_t)s->stream.total_in; |
#endif |
} |
/* Rest of function is for reading only */ |
|
/* compute absolute position */ |
if (whence == SEEK_CUR) { |
offset += s->stream.total_out; |
} |
if (offset < 0) return -1L; |
|
if (s->transparent) { |
/* map to fseek */ |
s->stream.avail_in = 0; |
s->stream.next_in = s->inbuf; |
if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; |
|
s->stream.total_in = s->stream.total_out = (uLong)offset; |
return offset; |
} |
|
/* For a negative seek, rewind and use positive seek */ |
if ((uLong)offset >= s->stream.total_out) { |
offset -= s->stream.total_out; |
} else if (gzrewind(file) < 0) { |
return -1L; |
} |
/* offset is now the number of bytes to skip. */ |
|
if (offset != 0 && s->outbuf == Z_NULL) { |
s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); |
} |
while (offset > 0) { |
int size = Z_BUFSIZE; |
if (offset < Z_BUFSIZE) size = (int)offset; |
|
size = gzread(file, s->outbuf, (uInt)size); |
if (size <= 0) return -1L; |
offset -= size; |
} |
return (z_off_t)s->stream.total_out; |
} |
|
/* =========================================================================== |
Rewinds input file. |
*/ |
int ZEXPORT gzrewind (file) |
gzFile file; |
{ |
gz_stream *s = (gz_stream*)file; |
|
if (s == NULL || s->mode != 'r') return -1; |
|
s->z_err = Z_OK; |
s->z_eof = 0; |
s->stream.avail_in = 0; |
s->stream.next_in = s->inbuf; |
s->crc = crc32(0L, Z_NULL, 0); |
|
if (s->startpos == 0) { /* not a compressed file */ |
rewind(s->file); |
return 0; |
} |
|
(void) inflateReset(&s->stream); |
return fseek(s->file, s->startpos, SEEK_SET); |
} |
|
/* =========================================================================== |
Returns the starting position for the next gzread or gzwrite on the |
given compressed file. This position represents a number of bytes in the |
uncompressed data stream. |
*/ |
z_off_t ZEXPORT gztell (file) |
gzFile file; |
{ |
return gzseek(file, 0L, SEEK_CUR); |
} |
|
/* =========================================================================== |
Returns 1 when EOF has previously been detected reading the given |
input stream, otherwise zero. |
*/ |
int ZEXPORT gzeof (file) |
gzFile file; |
{ |
gz_stream *s = (gz_stream*)file; |
|
return (s == NULL || s->mode != 'r') ? 0 : s->z_eof; |
} |
|
/* =========================================================================== |
Outputs a long in LSB order to the given file |
*/ |
local void putLong (file, x) |
FILE *file; |
uLong x; |
{ |
int n; |
for (n = 0; n < 4; n++) { |
fputc((int)(x & 0xff), file); |
x >>= 8; |
} |
} |
|
/* =========================================================================== |
Reads a long in LSB order from the given gz_stream. Sets z_err in case |
of error. |
*/ |
local uLong getLong (s) |
gz_stream *s; |
{ |
uLong x = (uLong)get_byte(s); |
int c; |
|
x += ((uLong)get_byte(s))<<8; |
x += ((uLong)get_byte(s))<<16; |
c = get_byte(s); |
if (c == EOF) s->z_err = Z_DATA_ERROR; |
x += ((uLong)c)<<24; |
return x; |
} |
|
/* =========================================================================== |
Flushes all pending output if necessary, closes the compressed file |
and deallocates all the (de)compression state. |
*/ |
int ZEXPORT gzclose (file) |
gzFile file; |
{ |
int err; |
gz_stream *s = (gz_stream*)file; |
|
if (s == NULL) return Z_STREAM_ERROR; |
|
if (s->mode == 'w') { |
#ifdef NO_DEFLATE |
return Z_STREAM_ERROR; |
#else |
err = do_flush (file, Z_FINISH); |
if (err != Z_OK) return destroy((gz_stream*)file); |
|
putLong (s->file, s->crc); |
putLong (s->file, s->stream.total_in); |
#endif |
} |
return destroy((gz_stream*)file); |
} |
|
/* =========================================================================== |
Returns the error message for the last error which occured on the |
given compressed file. errnum is set to zlib error number. If an |
error occured in the file system and not in the compression library, |
errnum is set to Z_ERRNO and the application may consult errno |
to get the exact error code. |
*/ |
const char* ZEXPORT gzerror (file, errnum) |
gzFile file; |
int *errnum; |
{ |
char *m; |
gz_stream *s = (gz_stream*)file; |
|
if (s == NULL) { |
*errnum = Z_STREAM_ERROR; |
return (const char*)ERR_MSG(Z_STREAM_ERROR); |
} |
*errnum = s->z_err; |
if (*errnum == Z_OK) return (const char*)""; |
|
m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); |
|
if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); |
|
TRYFREE(s->msg); |
s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); |
strcpy(s->msg, s->path); |
strcat(s->msg, ": "); |
strcat(s->msg, m); |
return (const char*)s->msg; |
} |
/v2_0/src/deflate.h
0,0 → 1,318
/* deflate.h -- internal compression state |
* Copyright (C) 1995-1998 Jean-loup Gailly |
* 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. |
*/ |
|
/* @(#) $Id: deflate.h,v 1.1.1.1 2004-02-14 13:35:39 phoenix Exp $ */ |
|
#ifndef _DEFLATE_H |
#define _DEFLATE_H |
|
#include "zutil.h" |
|
/* =========================================================================== |
* Internal compression state. |
*/ |
|
#define LENGTH_CODES 29 |
/* number of length codes, not counting the special END_BLOCK code */ |
|
#define LITERALS 256 |
/* number of literal bytes 0..255 */ |
|
#define L_CODES (LITERALS+1+LENGTH_CODES) |
/* number of Literal or Length codes, including the END_BLOCK code */ |
|
#define D_CODES 30 |
/* number of distance codes */ |
|
#define BL_CODES 19 |
/* number of codes used to transfer the bit lengths */ |
|
#define HEAP_SIZE (2*L_CODES+1) |
/* maximum heap size */ |
|
#define MAX_BITS 15 |
/* All codes must not exceed MAX_BITS bits */ |
|
#define INIT_STATE 42 |
#define BUSY_STATE 113 |
#define FINISH_STATE 666 |
/* Stream status */ |
|
|
/* Data structure describing a single value and its code string. */ |
typedef struct ct_data_s { |
union { |
ush freq; /* frequency count */ |
ush code; /* bit string */ |
} fc; |
union { |
ush dad; /* father node in Huffman tree */ |
ush len; /* length of bit string */ |
} dl; |
} FAR ct_data; |
|
#define Freq fc.freq |
#define Code fc.code |
#define Dad dl.dad |
#define Len dl.len |
|
typedef struct static_tree_desc_s static_tree_desc; |
|
typedef struct tree_desc_s { |
ct_data *dyn_tree; /* the dynamic tree */ |
int max_code; /* largest code with non zero frequency */ |
static_tree_desc *stat_desc; /* the corresponding static tree */ |
} FAR tree_desc; |
|
typedef ush Pos; |
typedef Pos FAR Posf; |
typedef unsigned IPos; |
|
/* A Pos is an index in the character window. We use short instead of int to |
* save space in the various tables. IPos is used only for parameter passing. |
*/ |
|
typedef struct internal_state { |
z_streamp strm; /* pointer back to this zlib stream */ |
int status; /* as the name implies */ |
Bytef *pending_buf; /* output still pending */ |
ulg pending_buf_size; /* size of pending_buf */ |
Bytef *pending_out; /* next pending byte to output to the stream */ |
int pending; /* nb of bytes in the pending buffer */ |
int noheader; /* suppress zlib header and adler32 */ |
Byte data_type; /* UNKNOWN, BINARY or ASCII */ |
Byte method; /* STORED (for zip only) or DEFLATED */ |
int last_flush; /* value of flush param for previous deflate call */ |
|
/* used by deflate.c: */ |
|
uInt w_size; /* LZ77 window size (32K by default) */ |
uInt w_bits; /* log2(w_size) (8..16) */ |
uInt w_mask; /* w_size - 1 */ |
|
Bytef *window; |
/* Sliding window. Input bytes are read into the second half of the window, |
* and move to the first half later to keep a dictionary of at least wSize |
* bytes. With this organization, matches are limited to a distance of |
* wSize-MAX_MATCH bytes, but this ensures that IO is always |
* performed with a length multiple of the block size. Also, it limits |
* the window size to 64K, which is quite useful on MSDOS. |
* To do: use the user input buffer as sliding window. |
*/ |
|
ulg window_size; |
/* Actual size of window: 2*wSize, except when the user input buffer |
* is directly used as sliding window. |
*/ |
|
Posf *prev; |
/* Link to older string with same hash index. To limit the size of this |
* array to 64K, this link is maintained only for the last 32K strings. |
* An index in this array is thus a window index modulo 32K. |
*/ |
|
Posf *head; /* Heads of the hash chains or NIL. */ |
|
uInt ins_h; /* hash index of string to be inserted */ |
uInt hash_size; /* number of elements in hash table */ |
uInt hash_bits; /* log2(hash_size) */ |
uInt hash_mask; /* hash_size-1 */ |
|
uInt hash_shift; |
/* Number of bits by which ins_h must be shifted at each input |
* step. It must be such that after MIN_MATCH steps, the oldest |
* byte no longer takes part in the hash key, that is: |
* hash_shift * MIN_MATCH >= hash_bits |
*/ |
|
long block_start; |
/* Window position at the beginning of the current output block. Gets |
* negative when the window is moved backwards. |
*/ |
|
uInt match_length; /* length of best match */ |
IPos prev_match; /* previous match */ |
int match_available; /* set if previous match exists */ |
uInt strstart; /* start of string to insert */ |
uInt match_start; /* start of matching string */ |
uInt lookahead; /* number of valid bytes ahead in window */ |
|
uInt prev_length; |
/* Length of the best match at previous step. Matches not greater than this |
* are discarded. This is used in the lazy match evaluation. |
*/ |
|
uInt max_chain_length; |
/* To speed up deflation, hash chains are never searched beyond this |
* length. A higher limit improves compression ratio but degrades the |
* speed. |
*/ |
|
uInt max_lazy_match; |
/* Attempt to find a better match only when the current match is strictly |
* smaller than this value. This mechanism is used only for compression |
* levels >= 4. |
*/ |
# define max_insert_length max_lazy_match |
/* Insert new strings in the hash table only if the match length is not |
* greater than this length. This saves time but degrades compression. |
* max_insert_length is used only for compression levels <= 3. |
*/ |
|
int level; /* compression level (1..9) */ |
int strategy; /* favor or force Huffman coding*/ |
|
uInt good_match; |
/* Use a faster search when the previous match is longer than this */ |
|
int nice_match; /* Stop searching when current match exceeds this */ |
|
/* used by trees.c: */ |
/* Didn't use ct_data typedef below to supress compiler warning */ |
struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ |
struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ |
struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ |
|
struct tree_desc_s l_desc; /* desc. for literal tree */ |
struct tree_desc_s d_desc; /* desc. for distance tree */ |
struct tree_desc_s bl_desc; /* desc. for bit length tree */ |
|
ush bl_count[MAX_BITS+1]; |
/* number of codes at each bit length for an optimal tree */ |
|
int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ |
int heap_len; /* number of elements in the heap */ |
int heap_max; /* element of largest frequency */ |
/* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. |
* The same heap array is used to build all trees. |
*/ |
|
uch depth[2*L_CODES+1]; |
/* Depth of each subtree used as tie breaker for trees of equal frequency |
*/ |
|
uchf *l_buf; /* buffer for literals or lengths */ |
|
uInt lit_bufsize; |
/* Size of match buffer for literals/lengths. There are 4 reasons for |
* limiting lit_bufsize to 64K: |
* - frequencies can be kept in 16 bit counters |
* - if compression is not successful for the first block, all input |
* data is still in the window so we can still emit a stored block even |
* when input comes from standard input. (This can also be done for |
* all blocks if lit_bufsize is not greater than 32K.) |
* - if compression is not successful for a file smaller than 64K, we can |
* even emit a stored file instead of a stored block (saving 5 bytes). |
* This is applicable only for zip (not gzip or zlib). |
* - creating new Huffman trees less frequently may not provide fast |
* adaptation to changes in the input data statistics. (Take for |
* example a binary file with poorly compressible code followed by |
* a highly compressible string table.) Smaller buffer sizes give |
* fast adaptation but have of course the overhead of transmitting |
* trees more frequently. |
* - I can't count above 4 |
*/ |
|
uInt last_lit; /* running index in l_buf */ |
|
ushf *d_buf; |
/* Buffer for distances. To simplify the code, d_buf and l_buf have |
* the same number of elements. To use different lengths, an extra flag |
* array would be necessary. |
*/ |
|
ulg opt_len; /* bit length of current block with optimal trees */ |
ulg static_len; /* bit length of current block with static trees */ |
uInt matches; /* number of string matches in current block */ |
int last_eob_len; /* bit length of EOB code for last block */ |
|
#ifdef DEBUG |
ulg compressed_len; /* total bit length of compressed file mod 2^32 */ |
ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ |
#endif |
|
ush bi_buf; |
/* Output buffer. bits are inserted starting at the bottom (least |
* significant bits). |
*/ |
int bi_valid; |
/* Number of valid bits in bi_buf. All bits above the last valid bit |
* are always zero. |
*/ |
|
} FAR deflate_state; |
|
/* Output a byte on the stream. |
* IN assertion: there is enough room in pending_buf. |
*/ |
#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} |
|
|
#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) |
/* Minimum amount of lookahead, except at the end of the input file. |
* See deflate.c for comments about the MIN_MATCH+1. |
*/ |
|
#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) |
/* In order to simplify the code, particularly on 16 bit machines, match |
* distances are limited to MAX_DIST instead of WSIZE. |
*/ |
|
/* in trees.c */ |
void _tr_init OF((deflate_state *s)); |
int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); |
void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, |
int eof)); |
void _tr_align OF((deflate_state *s)); |
void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, |
int eof)); |
|
#define d_code(dist) \ |
((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) |
/* Mapping from a distance to a distance code. dist is the distance - 1 and |
* must not have side effects. _dist_code[256] and _dist_code[257] are never |
* used. |
*/ |
|
#ifndef DEBUG |
/* Inline versions of _tr_tally for speed: */ |
|
#if defined(GEN_TREES_H) || !defined(STDC) |
extern uch _length_code[]; |
extern uch _dist_code[]; |
#else |
extern const uch _length_code[]; |
extern const uch _dist_code[]; |
#endif |
|
# define _tr_tally_lit(s, c, flush) \ |
{ uch cc = (c); \ |
s->d_buf[s->last_lit] = 0; \ |
s->l_buf[s->last_lit++] = cc; \ |
s->dyn_ltree[cc].Freq++; \ |
flush = (s->last_lit == s->lit_bufsize-1); \ |
} |
# define _tr_tally_dist(s, distance, length, flush) \ |
{ uch len = (length); \ |
ush dist = (distance); \ |
s->d_buf[s->last_lit] = dist; \ |
s->l_buf[s->last_lit++] = len; \ |
dist--; \ |
s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ |
s->dyn_dtree[d_code(dist)].Freq++; \ |
flush = (s->last_lit == s->lit_bufsize-1); \ |
} |
#else |
# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) |
# define _tr_tally_dist(s, distance, length, flush) \ |
flush = _tr_tally(s, distance, length) |
#endif |
|
#endif |
/v2_0/src/infutil.c
0,0 → 1,87
/* inflate_util.c -- data and routines common to blocks and codes |
* Copyright (C) 1995-1998 Mark Adler |
* For conditions of distribution and use, see copyright notice in zlib.h |
*/ |
|
#include "zutil.h" |
#include "infblock.h" |
#include "inftrees.h" |
#include "infcodes.h" |
#include "infutil.h" |
|
struct inflate_codes_state {int dummy;}; /* for buggy compilers */ |
|
/* And'ing with mask[n] masks the lower n bits */ |
uInt inflate_mask[17] = { |
0x0000, |
0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, |
0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff |
}; |
|
|
/* copy as much as possible from the sliding window to the output area */ |
int inflate_flush(s, z, r) |
inflate_blocks_statef *s; |
z_streamp z; |
int r; |
{ |
uInt n; |
Bytef *p; |
Bytef *q; |
|
/* local copies of source and destination pointers */ |
p = z->next_out; |
q = s->read; |
|
/* compute number of bytes to copy as far as end of window */ |
n = (uInt)((q <= s->write ? s->write : s->end) - q); |
if (n > z->avail_out) n = z->avail_out; |
if (n && r == Z_BUF_ERROR) r = Z_OK; |
|
/* update counters */ |
z->avail_out -= n; |
z->total_out += n; |
|
/* update check information */ |
if (s->checkfn != Z_NULL) |
z->adler = s->check = (*s->checkfn)(s->check, q, n); |
|
/* copy as far as end of window */ |
zmemcpy(p, q, n); |
p += n; |
q += n; |
|
/* see if more to copy at beginning of window */ |
if (q == s->end) |
{ |
/* wrap pointers */ |
q = s->window; |
if (s->write == s->end) |
s->write = s->window; |
|
/* compute bytes to copy */ |
n = (uInt)(s->write - q); |
if (n > z->avail_out) n = z->avail_out; |
if (n && r == Z_BUF_ERROR) r = Z_OK; |
|
/* update counters */ |
z->avail_out -= n; |
z->total_out += n; |
|
/* update check information */ |
if (s->checkfn != Z_NULL) |
z->adler = s->check = (*s->checkfn)(s->check, q, n); |
|
/* copy */ |
zmemcpy(p, q, n); |
p += n; |
q += n; |
} |
|
/* update pointers */ |
z->next_out = p; |
s->read = q; |
|
/* done */ |
return r; |
} |
/v2_0/src/zutil.h
0,0 → 1,225
/* zutil.h -- internal interface and configuration of the compression library |
* Copyright (C) 1995-1998 Jean-loup Gailly. |
* 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. |
*/ |
|
/* @(#) $Id: zutil.h,v 1.1.1.1 2004-02-14 13:35:38 phoenix Exp $ */ |
|
#ifndef _Z_UTIL_H |
#define _Z_UTIL_H |
|
#ifdef __ECOS__ |
#include <cyg/compress/zlib.h> |
#include <cyg/crc/crc.h> |
#else |
#include "zlib.h" |
#endif // __ECOS__ |
|
#ifdef STDC |
# include <stddef.h> |
# include <string.h> |
# include <stdlib.h> |
#endif |
#ifdef NO_ERRNO_H |
extern int errno; |
#else |
# include <errno.h> |
#endif |
|
#ifndef local |
# define local static |
#endif |
/* compile with -Dlocal if your debugger can't find static symbols */ |
|
typedef unsigned char uch; |
typedef uch FAR uchf; |
typedef unsigned short ush; |
typedef ush FAR ushf; |
typedef unsigned long ulg; |
|
extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ |
/* (size given to avoid silly warnings with Visual C++) */ |
|
#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] |
|
#define ERR_RETURN(strm,err) \ |
return (strm->msg = (char*)ERR_MSG(err), (err)) |
/* To be used only when the state is known to be valid */ |
|
/* common constants */ |
|
#ifndef DEF_WBITS |
# define DEF_WBITS MAX_WBITS |
#endif |
/* default windowBits for decompression. MAX_WBITS is for compression only */ |
|
#if MAX_MEM_LEVEL >= 8 |
# define DEF_MEM_LEVEL 8 |
#else |
# define DEF_MEM_LEVEL MAX_MEM_LEVEL |
#endif |
/* default memLevel */ |
|
#define STORED_BLOCK 0 |
#define STATIC_TREES 1 |
#define DYN_TREES 2 |
/* The three kinds of block type */ |
|
#define MIN_MATCH 3 |
#define MAX_MATCH 258 |
/* The minimum and maximum match lengths */ |
|
#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ |
|
/* target dependencies */ |
|
#ifdef MSDOS |
# define OS_CODE 0x00 |
# if defined(__TURBOC__) || defined(__BORLANDC__) |
# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) |
/* Allow compilation with ANSI keywords only enabled */ |
void _Cdecl farfree( void *block ); |
void *_Cdecl farmalloc( unsigned long nbytes ); |
# else |
# include <alloc.h> |
# endif |
# else /* MSC or DJGPP */ |
# include <malloc.h> |
# endif |
#endif |
|
#ifdef OS2 |
# define OS_CODE 0x06 |
#endif |
|
#ifdef WIN32 /* Window 95 & Windows NT */ |
# define OS_CODE 0x0b |
#endif |
|
#if defined(VAXC) || defined(VMS) |
# define OS_CODE 0x02 |
# define F_OPEN(name, mode) \ |
fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") |
#endif |
|
#ifdef AMIGA |
# define OS_CODE 0x01 |
#endif |
|
#if defined(ATARI) || defined(atarist) |
# define OS_CODE 0x05 |
#endif |
|
#if defined(MACOS) || defined(TARGET_OS_MAC) |
# define OS_CODE 0x07 |
# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os |
# include <unix.h> /* for fdopen */ |
# else |
# ifndef fdopen |
# define fdopen(fd,mode) NULL /* No fdopen() */ |
# endif |
# endif |
#endif |
|
#ifdef __50SERIES /* Prime/PRIMOS */ |
# define OS_CODE 0x0F |
#endif |
|
#ifdef TOPS20 |
# define OS_CODE 0x0a |
#endif |
|
#if defined(_BEOS_) || defined(RISCOS) |
# define fdopen(fd,mode) NULL /* No fdopen() */ |
#endif |
|
#if (defined(_MSC_VER) && (_MSC_VER > 600)) |
# define fdopen(fd,type) _fdopen(fd,type) |
#endif |
|
|
/* Common defaults */ |
|
#ifndef OS_CODE |
# define OS_CODE 0x03 /* assume Unix */ |
#endif |
|
#ifndef F_OPEN |
# define F_OPEN(name, mode) fopen((name), (mode)) |
#endif |
|
/* functions */ |
|
#ifdef HAVE_STRERROR |
extern char *strerror OF((int)); |
# define zstrerror(errnum) strerror(errnum) |
#else |
# define zstrerror(errnum) "" |
#endif |
|
#if defined(pyr) |
# define NO_MEMCPY |
#endif |
#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) |
/* Use our own functions for small and medium model with MSC <= 5.0. |
* You may have to use the same strategy for Borland C (untested). |
* The __SC__ check is for Symantec. |
*/ |
# define NO_MEMCPY |
#endif |
#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) |
# define HAVE_MEMCPY |
#endif |
#ifdef HAVE_MEMCPY |
# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ |
# define zmemcpy _fmemcpy |
# define zmemcmp _fmemcmp |
# define zmemzero(dest, len) _fmemset(dest, 0, len) |
# else |
# define zmemcpy memcpy |
# define zmemcmp memcmp |
# define zmemzero(dest, len) memset(dest, 0, len) |
# endif |
#else |
extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); |
extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); |
extern void zmemzero OF((Bytef* dest, uInt len)); |
#endif |
|
/* Diagnostic functions */ |
#ifdef DEBUG |
# include <stdio.h> |
extern int z_verbose; |
extern void z_error OF((char *m)); |
# define Assert(cond,msg) {if(!(cond)) z_error(msg);} |
# define Trace(x) {if (z_verbose>=0) fprintf x ;} |
# define Tracev(x) {if (z_verbose>0) fprintf x ;} |
# define Tracevv(x) {if (z_verbose>1) fprintf x ;} |
# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} |
# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} |
#else |
# define Assert(cond,msg) |
# define Trace(x) |
# define Tracev(x) |
# define Tracevv(x) |
# define Tracec(c,x) |
# define Tracecv(c,x) |
#endif |
|
|
typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf, |
uInt len)); |
voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); |
void zcfree OF((voidpf opaque, voidpf ptr)); |
|
#define ZALLOC(strm, items, size) \ |
(*((strm)->zalloc))((strm)->opaque, (items), (size)) |
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) |
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} |
|
#endif /* _Z_UTIL_H */ |
/v2_0/src/infutil.h
0,0 → 1,98
/* infutil.h -- types and macros common to blocks and codes |
* Copyright (C) 1995-1998 Mark Adler |
* For conditions of distribution and use, see copyright notice in zlib.h |
*/ |
|
/* WARNING: this file should *not* be used by applications. It is |
part of the implementation of the compression library and is |
subject to change. Applications should only use zlib.h. |
*/ |
|
#ifndef _INFUTIL_H |
#define _INFUTIL_H |
|
typedef enum { |
TYPE, /* get type bits (3, including end bit) */ |
LENS, /* get lengths for stored */ |
STORED, /* processing stored block */ |
TABLE, /* get table lengths */ |
BTREE, /* get bit lengths tree for a dynamic block */ |
DTREE, /* get length, distance trees for a dynamic block */ |
CODES, /* processing fixed or dynamic block */ |
DRY, /* output remaining window bytes */ |
DONE, /* finished last block, done */ |
BAD} /* got a data error--stuck here */ |
inflate_block_mode; |
|
/* inflate blocks semi-private state */ |
struct inflate_blocks_state { |
|
/* mode */ |
inflate_block_mode mode; /* current inflate_block mode */ |
|
/* mode dependent information */ |
union { |
uInt left; /* if STORED, bytes left to copy */ |
struct { |
uInt table; /* table lengths (14 bits) */ |
uInt index; /* index into blens (or border) */ |
uIntf *blens; /* bit lengths of codes */ |
uInt bb; /* bit length tree depth */ |
inflate_huft *tb; /* bit length decoding tree */ |
} trees; /* if DTREE, decoding info for trees */ |
struct { |
inflate_codes_statef |
*codes; |
} decode; /* if CODES, current state */ |
} sub; /* submode */ |
uInt last; /* true if this block is the last block */ |
|
/* mode independent information */ |
uInt bitk; /* bits in bit buffer */ |
uLong bitb; /* bit buffer */ |
inflate_huft *hufts; /* single malloc for tree space */ |
Bytef *window; /* sliding window */ |
Bytef *end; /* one byte after sliding window */ |
Bytef *read; /* window read pointer */ |
Bytef *write; /* window write pointer */ |
check_func checkfn; /* check function */ |
uLong check; /* check on output */ |
|
}; |
|
|
/* defines for inflate input/output */ |
/* update pointers and return */ |
#define UPDBITS {s->bitb=b;s->bitk=k;} |
#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} |
#define UPDOUT {s->write=q;} |
#define UPDATE {UPDBITS UPDIN UPDOUT} |
#define LEAVE {UPDATE return inflate_flush(s,z,r);} |
/* get bytes and bits */ |
#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} |
#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} |
#define NEXTBYTE (n--,*p++) |
#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}} |
#define DUMPBITS(j) {b>>=(j);k-=(j);} |
/* output bytes */ |
#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q) |
#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} |
#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} |
#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} |
#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} |
#define OUTBYTE(a) {*q++=(Byte)(a);m--;} |
/* load local pointers */ |
#define LOAD {LOADIN LOADOUT} |
|
/* masks for lower bits (size given to avoid silly warnings with Visual C++) */ |
extern uInt inflate_mask[17]; |
|
/* copy as much as possible from the sliding window to the output area */ |
extern int inflate_flush OF(( |
inflate_blocks_statef *, |
z_streamp , |
int)); |
|
struct internal_state {int dummy;}; /* for buggy compilers */ |
|
#endif |
/v2_0/src/trees.c
0,0 → 1,1214
/* trees.c -- output deflated data using Huffman coding |
* Copyright (C) 1995-1998 Jean-loup Gailly |
* For conditions of distribution and use, see copyright notice in zlib.h |
*/ |
|
/* |
* ALGORITHM |
* |
* The "deflation" process uses several Huffman trees. The more |
* common source values are represented by shorter bit sequences. |
* |
* Each code tree is stored in a compressed form which is itself |
* a Huffman encoding of the lengths of all the code strings (in |
* ascending order by source values). The actual code strings are |
* reconstructed from the lengths in the inflate process, as described |
* in the deflate specification. |
* |
* REFERENCES |
* |
* Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". |
* Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc |
* |
* Storer, James A. |
* Data Compression: Methods and Theory, pp. 49-50. |
* Computer Science Press, 1988. ISBN 0-7167-8156-5. |
* |
* Sedgewick, R. |
* Algorithms, p290. |
* Addison-Wesley, 1983. ISBN 0-201-06672-6. |
*/ |
|
/* @(#) $Id: trees.c,v 1.1.1.1 2004-02-14 13:35:38 phoenix Exp $ */ |
|
/* #define GEN_TREES_H */ |
|
#include "deflate.h" |
|
#ifdef DEBUG |
# include <ctype.h> |
#endif |
|
/* =========================================================================== |
* Constants |
*/ |
|
#define MAX_BL_BITS 7 |
/* Bit length codes must not exceed MAX_BL_BITS bits */ |
|
#define END_BLOCK 256 |
/* end of block literal code */ |
|
#define REP_3_6 16 |
/* repeat previous bit length 3-6 times (2 bits of repeat count) */ |
|
#define REPZ_3_10 17 |
/* repeat a zero length 3-10 times (3 bits of repeat count) */ |
|
#define REPZ_11_138 18 |
/* repeat a zero length 11-138 times (7 bits of repeat count) */ |
|
local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ |
= {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; |
|
local const int extra_dbits[D_CODES] /* extra bits for each distance code */ |
= {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; |
|
local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ |
= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; |
|
local const uch bl_order[BL_CODES] |
= {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; |
/* The lengths of the bit length codes are sent in order of decreasing |
* probability, to avoid transmitting the lengths for unused bit length codes. |
*/ |
|
#define Buf_size (8 * 2*sizeof(char)) |
/* Number of bits used within bi_buf. (bi_buf might be implemented on |
* more than 16 bits on some systems.) |
*/ |
|
/* =========================================================================== |
* Local data. These are initialized only once. |
*/ |
|
#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ |
|
#if defined(GEN_TREES_H) || !defined(STDC) |
/* non ANSI compilers may not accept trees.h */ |
|
local ct_data static_ltree[L_CODES+2]; |
/* The static literal tree. Since the bit lengths are imposed, there is no |
* need for the L_CODES extra codes used during heap construction. However |
* The codes 286 and 287 are needed to build a canonical tree (see _tr_init |
* below). |
*/ |
|
local ct_data static_dtree[D_CODES]; |
/* The static distance tree. (Actually a trivial tree since all codes use |
* 5 bits.) |
*/ |
|
uch _dist_code[DIST_CODE_LEN]; |
/* Distance codes. The first 256 values correspond to the distances |
* 3 .. 258, the last 256 values correspond to the top 8 bits of |
* the 15 bit distances. |
*/ |
|
uch _length_code[MAX_MATCH-MIN_MATCH+1]; |
/* length code for each normalized match length (0 == MIN_MATCH) */ |
|
local int base_length[LENGTH_CODES]; |
/* First normalized length for each code (0 = MIN_MATCH) */ |
|
local int base_dist[D_CODES]; |
/* First normalized distance for each code (0 = distance of 1) */ |
|
#else |
# include "trees.h" |
#endif /* GEN_TREES_H */ |
|
struct static_tree_desc_s { |
const ct_data *static_tree; /* static tree or NULL */ |
const intf *extra_bits; /* extra bits for each code or NULL */ |
int extra_base; /* base index for extra_bits */ |
int elems; /* max number of elements in the tree */ |
int max_length; /* max bit length for the codes */ |
}; |
|
local static_tree_desc static_l_desc = |
{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; |
|
local static_tree_desc static_d_desc = |
{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; |
|
local static_tree_desc static_bl_desc = |
{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; |
|
/* =========================================================================== |
* Local (static) routines in this file. |
*/ |
|
local void tr_static_init OF((void)); |
local void init_block OF((deflate_state *s)); |
local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); |
local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); |
local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); |
local void build_tree OF((deflate_state *s, tree_desc *desc)); |
local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); |
local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); |
local int build_bl_tree OF((deflate_state *s)); |
local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, |
int blcodes)); |
local void compress_block OF((deflate_state *s, ct_data *ltree, |
ct_data *dtree)); |
local void set_data_type OF((deflate_state *s)); |
local unsigned bi_reverse OF((unsigned value, int length)); |
local void bi_windup OF((deflate_state *s)); |
local void bi_flush OF((deflate_state *s)); |
local void copy_block OF((deflate_state *s, charf *buf, unsigned len, |
int header)); |
|
#ifdef GEN_TREES_H |
local void gen_trees_header OF((void)); |
#endif |
|
#ifndef DEBUG |
# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) |
/* Send a code of the given tree. c and tree must not have side effects */ |
|
#else /* DEBUG */ |
# define send_code(s, c, tree) \ |
{ if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ |
send_bits(s, tree[c].Code, tree[c].Len); } |
#endif |
|
/* =========================================================================== |
* Output a short LSB first on the stream. |
* IN assertion: there is enough room in pendingBuf. |
*/ |
#define put_short(s, w) { \ |
put_byte(s, (uch)((w) & 0xff)); \ |
put_byte(s, (uch)((ush)(w) >> 8)); \ |
} |
|
/* =========================================================================== |
* Send a value on a given number of bits. |
* IN assertion: length <= 16 and value fits in length bits. |
*/ |
#ifdef DEBUG |
local void send_bits OF((deflate_state *s, int value, int length)); |
|
local void send_bits(s, value, length) |
deflate_state *s; |
int value; /* value to send */ |
int length; /* number of bits */ |
{ |
Tracevv((stderr," l %2d v %4x ", length, value)); |
Assert(length > 0 && length <= 15, "invalid length"); |
s->bits_sent += (ulg)length; |
|
/* If not enough room in bi_buf, use (valid) bits from bi_buf and |
* (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) |
* unused bits in value. |
*/ |
if (s->bi_valid > (int)Buf_size - length) { |
s->bi_buf |= (value << s->bi_valid); |
put_short(s, s->bi_buf); |
s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); |
s->bi_valid += length - Buf_size; |
} else { |
s->bi_buf |= value << s->bi_valid; |
s->bi_valid += length; |
} |
} |
#else /* !DEBUG */ |
|
#define send_bits(s, value, length) \ |
{ int len = length;\ |
if (s->bi_valid > (int)Buf_size - len) {\ |
int val = value;\ |
s->bi_buf |= (val << s->bi_valid);\ |
put_short(s, s->bi_buf);\ |
s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ |
s->bi_valid += len - Buf_size;\ |
} else {\ |
s->bi_buf |= (value) << s->bi_valid;\ |
s->bi_valid += len;\ |
}\ |
} |
#endif /* DEBUG */ |
|
|
#define MAX(a,b) (a >= b ? a : b) |
/* the arguments must not have side effects */ |
|
/* =========================================================================== |
* Initialize the various 'constant' tables. |
*/ |
local void tr_static_init() |
{ |
#if defined(GEN_TREES_H) || !defined(STDC) |
static int static_init_done = 0; |
int n; /* iterates over tree elements */ |
int bits; /* bit counter */ |
int length; /* length value */ |
int code; /* code value */ |
int dist; /* distance index */ |
ush bl_count[MAX_BITS+1]; |
/* number of codes at each bit length for an optimal tree */ |
|
if (static_init_done) return; |
|
/* For some embedded targets, global variables are not initialized: */ |
static_l_desc.static_tree = static_ltree; |
static_l_desc.extra_bits = extra_lbits; |
static_d_desc.static_tree = static_dtree; |
static_d_desc.extra_bits = extra_dbits; |
static_bl_desc.extra_bits = extra_blbits; |
|
/* Initialize the mapping length (0..255) -> length code (0..28) */ |
length = 0; |
for (code = 0; code < LENGTH_CODES-1; code++) { |
base_length[code] = length; |
for (n = 0; n < (1<<extra_lbits[code]); n++) { |
_length_code[length++] = (uch)code; |
} |
} |
Assert (length == 256, "tr_static_init: length != 256"); |
/* Note that the length 255 (match length 258) can be represented |
* in two different ways: code 284 + 5 bits or code 285, so we |
* overwrite length_code[255] to use the best encoding: |
*/ |
_length_code[length-1] = (uch)code; |
|
/* Initialize the mapping dist (0..32K) -> dist code (0..29) */ |
dist = 0; |
for (code = 0 ; code < 16; code++) { |
base_dist[code] = dist; |
for (n = 0; n < (1<<extra_dbits[code]); n++) { |
_dist_code[dist++] = (uch)code; |
} |
} |
Assert (dist == 256, "tr_static_init: dist != 256"); |
dist >>= 7; /* from now on, all distances are divided by 128 */ |
for ( ; code < D_CODES; code++) { |
base_dist[code] = dist << 7; |
for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { |
_dist_code[256 + dist++] = (uch)code; |
} |
} |
Assert (dist == 256, "tr_static_init: 256+dist != 512"); |
|
/* Construct the codes of the static literal tree */ |
for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; |
n = 0; |
while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; |
while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; |
while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; |
while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; |
/* Codes 286 and 287 do not exist, but we must include them in the |
* tree construction to get a canonical Huffman tree (longest code |
* all ones) |
*/ |
gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); |
|
/* The static distance tree is trivial: */ |
for (n = 0; n < D_CODES; n++) { |
static_dtree[n].Len = 5; |
static_dtree[n].Code = bi_reverse((unsigned)n, 5); |
} |
static_init_done = 1; |
|
# ifdef GEN_TREES_H |
gen_trees_header(); |
# endif |
#endif /* defined(GEN_TREES_H) || !defined(STDC) */ |
} |
|
/* =========================================================================== |
* Genererate the file trees.h describing the static trees. |
*/ |
#ifdef GEN_TREES_H |
# ifndef DEBUG |
# include <stdio.h> |
# endif |
|
# define SEPARATOR(i, last, width) \ |
((i) == (last)? "\n};\n\n" : \ |
((i) % (width) == (width)-1 ? ",\n" : ", ")) |
|
void gen_trees_header() |
{ |
FILE *header = fopen("trees.h", "w"); |
int i; |
|
Assert (header != NULL, "Can't open trees.h"); |
fprintf(header, |
"/* header created automatically with -DGEN_TREES_H */\n\n"); |
|
fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); |
for (i = 0; i < L_CODES+2; i++) { |
fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, |
static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); |
} |
|
fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); |
for (i = 0; i < D_CODES; i++) { |
fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, |
static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); |
} |
|
fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); |
for (i = 0; i < DIST_CODE_LEN; i++) { |
fprintf(header, "%2u%s", _dist_code[i], |
SEPARATOR(i, DIST_CODE_LEN-1, 20)); |
} |
|
fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); |
for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { |
fprintf(header, "%2u%s", _length_code[i], |
SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); |
} |
|
fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); |
for (i = 0; i < LENGTH_CODES; i++) { |
fprintf(header, "%1u%s", base_length[i], |
SEPARATOR(i, LENGTH_CODES-1, 20)); |
} |
|
fprintf(header, "local const int base_dist[D_CODES] = {\n"); |
for (i = 0; i < D_CODES; i++) { |
fprintf(header, "%5u%s", base_dist[i], |
SEPARATOR(i, D_CODES-1, 10)); |
} |
|
fclose(header); |
} |
#endif /* GEN_TREES_H */ |
|
/* =========================================================================== |
* Initialize the tree data structures for a new zlib stream. |
*/ |
void _tr_init(s) |
deflate_state *s; |
{ |
tr_static_init(); |
|
s->l_desc.dyn_tree = s->dyn_ltree; |
s->l_desc.stat_desc = &static_l_desc; |
|
s->d_desc.dyn_tree = s->dyn_dtree; |
s->d_desc.stat_desc = &static_d_desc; |
|
s->bl_desc.dyn_tree = s->bl_tree; |
s->bl_desc.stat_desc = &static_bl_desc; |
|
s->bi_buf = 0; |
s->bi_valid = 0; |
s->last_eob_len = 8; /* enough lookahead for inflate */ |
#ifdef DEBUG |
s->compressed_len = 0L; |
s->bits_sent = 0L; |
#endif |
|
/* Initialize the first block of the first file: */ |
init_block(s); |
} |
|
/* =========================================================================== |
* Initialize a new block. |
*/ |
local void init_block(s) |
deflate_state *s; |
{ |
int n; /* iterates over tree elements */ |
|
/* Initialize the trees. */ |
for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; |
for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; |
for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; |
|
s->dyn_ltree[END_BLOCK].Freq = 1; |
s->opt_len = s->static_len = 0L; |
s->last_lit = s->matches = 0; |
} |
|
#define SMALLEST 1 |
/* Index within the heap array of least frequent node in the Huffman tree */ |
|
|
/* =========================================================================== |
* Remove the smallest element from the heap and recreate the heap with |
* one less element. Updates heap and heap_len. |
*/ |
#define pqremove(s, tree, top) \ |
{\ |
top = s->heap[SMALLEST]; \ |
s->heap[SMALLEST] = s->heap[s->heap_len--]; \ |
pqdownheap(s, tree, SMALLEST); \ |
} |
|
/* =========================================================================== |
* Compares to subtrees, using the tree depth as tie breaker when |
* the subtrees have equal frequency. This minimizes the worst case length. |
*/ |
#define smaller(tree, n, m, depth) \ |
(tree[n].Freq < tree[m].Freq || \ |
(tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) |
|
/* =========================================================================== |
* Restore the heap property by moving down the tree starting at node k, |
* exchanging a node with the smallest of its two sons if necessary, stopping |
* when the heap property is re-established (each father smaller than its |
* two sons). |
*/ |
local void pqdownheap(s, tree, k) |
deflate_state *s; |
ct_data *tree; /* the tree to restore */ |
int k; /* node to move down */ |
{ |
int v = s->heap[k]; |
int j = k << 1; /* left son of k */ |
while (j <= s->heap_len) { |
/* Set j to the smallest of the two sons: */ |
if (j < s->heap_len && |
smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { |
j++; |
} |
/* Exit if v is smaller than both sons */ |
if (smaller(tree, v, s->heap[j], s->depth)) break; |
|
/* Exchange v with the smallest son */ |
s->heap[k] = s->heap[j]; k = j; |
|
/* And continue down the tree, setting j to the left son of k */ |
j <<= 1; |
} |
s->heap[k] = v; |
} |
|
/* =========================================================================== |
* Compute the optimal bit lengths for a tree and update the total bit length |
* for the current block. |
* IN assertion: the fields freq and dad are set, heap[heap_max] and |
* above are the tree nodes sorted by increasing frequency. |
* OUT assertions: the field len is set to the optimal bit length, the |
* array bl_count contains the frequencies for each bit length. |
* The length opt_len is updated; static_len is also updated if stree is |
* not null. |
*/ |
local void gen_bitlen(s, desc) |
deflate_state *s; |
tree_desc *desc; /* the tree descriptor */ |
{ |
ct_data *tree = desc->dyn_tree; |
int max_code = desc->max_code; |
const ct_data *stree = desc->stat_desc->static_tree; |
const intf *extra = desc->stat_desc->extra_bits; |
int base = desc->stat_desc->extra_base; |
int max_length = desc->stat_desc->max_length; |
int h; /* heap index */ |
int n, m; /* iterate over the tree elements */ |
int bits; /* bit length */ |
int xbits; /* extra bits */ |
ush f; /* frequency */ |
int overflow = 0; /* number of elements with bit length too large */ |
|
for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; |
|
/* In a first pass, compute the optimal bit lengths (which may |
* overflow in the case of the bit length tree). |
*/ |
tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ |
|
for (h = s->heap_max+1; h < HEAP_SIZE; h++) { |
n = s->heap[h]; |
bits = tree[tree[n].Dad].Len + 1; |
if (bits > max_length) bits = max_length, overflow++; |
tree[n].Len = (ush)bits; |
/* We overwrite tree[n].Dad which is no longer needed */ |
|
if (n > max_code) continue; /* not a leaf node */ |
|
s->bl_count[bits]++; |
xbits = 0; |
if (n >= base) xbits = extra[n-base]; |
f = tree[n].Freq; |
s->opt_len += (ulg)f * (bits + xbits); |
if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); |
} |
if (overflow == 0) return; |
|
Trace((stderr,"\nbit length overflow\n")); |
/* This happens for example on obj2 and pic of the Calgary corpus */ |
|
/* Find the first bit length which could increase: */ |
do { |
bits = max_length-1; |
while (s->bl_count[bits] == 0) bits--; |
s->bl_count[bits]--; /* move one leaf down the tree */ |
s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ |
s->bl_count[max_length]--; |
/* The brother of the overflow item also moves one step up, |
* but this does not affect bl_count[max_length] |
*/ |
overflow -= 2; |
} while (overflow > 0); |
|
/* Now recompute all bit lengths, scanning in increasing frequency. |
* h is still equal to HEAP_SIZE. (It is simpler to reconstruct all |
* lengths instead of fixing only the wrong ones. This idea is taken |
* from 'ar' written by Haruhiko Okumura.) |
*/ |
for (bits = max_length; bits != 0; bits--) { |
n = s->bl_count[bits]; |
while (n != 0) { |
m = s->heap[--h]; |
if (m > max_code) continue; |
if (tree[m].Len != (unsigned) bits) { |
Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); |
s->opt_len += ((long)bits - (long)tree[m].Len) |
*(long)tree[m].Freq; |
tree[m].Len = (ush)bits; |
} |
n--; |
} |
} |
} |
|
/* =========================================================================== |
* Generate the codes for a given tree and bit counts (which need not be |
* optimal). |
* IN assertion: the array bl_count contains the bit length statistics for |
* the given tree and the field len is set for all tree elements. |
* OUT assertion: the field code is set for all tree elements of non |
* zero code length. |
*/ |
local void gen_codes (tree, max_code, bl_count) |
ct_data *tree; /* the tree to decorate */ |
int max_code; /* largest code with non zero frequency */ |
ushf *bl_count; /* number of codes at each bit length */ |
{ |
ush next_code[MAX_BITS+1]; /* next code value for each bit length */ |
ush code = 0; /* running code value */ |
int bits; /* bit index */ |
int n; /* code index */ |
|
/* The distribution counts are first used to generate the code values |
* without bit reversal. |
*/ |
for (bits = 1; bits <= MAX_BITS; bits++) { |
next_code[bits] = code = (code + bl_count[bits-1]) << 1; |
} |
/* Check that the bit counts in bl_count are consistent. The last code |
* must be all ones. |
*/ |
Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, |
"inconsistent bit counts"); |
Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); |
|
for (n = 0; n <= max_code; n++) { |
int len = tree[n].Len; |
if (len == 0) continue; |
/* Now reverse the bits */ |
tree[n].Code = bi_reverse(next_code[len]++, len); |
|
Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", |
n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); |
} |
} |
|
/* =========================================================================== |
* Construct one Huffman tree and assigns the code bit strings and lengths. |
* Update the total bit length for the current block. |
* IN assertion: the field freq is set for all tree elements. |
* OUT assertions: the fields len and code are set to the optimal bit length |
* and corresponding code. The length opt_len is updated; static_len is |
* also updated if stree is not null. The field max_code is set. |
*/ |
local void build_tree(s, desc) |
deflate_state *s; |
tree_desc *desc; /* the tree descriptor */ |
{ |
ct_data *tree = desc->dyn_tree; |
const ct_data *stree = desc->stat_desc->static_tree; |
int elems = desc->stat_desc->elems; |
int n, m; /* iterate over heap elements */ |
int max_code = -1; /* largest code with non zero frequency */ |
int node; /* new node being created */ |
|
/* Construct the initial heap, with least frequent element in |
* heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. |
* heap[0] is not used. |
*/ |
s->heap_len = 0, s->heap_max = HEAP_SIZE; |
|
for (n = 0; n < elems; n++) { |
if (tree[n].Freq != 0) { |
s->heap[++(s->heap_len)] = max_code = n; |
s->depth[n] = 0; |
} else { |
tree[n].Len = 0; |
} |
} |
|
/* The pkzip format requires that at least one distance code exists, |
* and that at least one bit should be sent even if there is only one |
* possible code. So to avoid special checks later on we force at least |
* two codes of non zero frequency. |
*/ |
while (s->heap_len < 2) { |
node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); |
tree[node].Freq = 1; |
s->depth[node] = 0; |
s->opt_len--; if (stree) s->static_len -= stree[node].Len; |
/* node is 0 or 1 so it does not have extra bits */ |
} |
desc->max_code = max_code; |
|
/* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, |
* establish sub-heaps of increasing lengths: |
*/ |
for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); |
|
/* Construct the Huffman tree by repeatedly combining the least two |
* frequent nodes. |
*/ |
node = elems; /* next internal node of the tree */ |
do { |
pqremove(s, tree, n); /* n = node of least frequency */ |
m = s->heap[SMALLEST]; /* m = node of next least frequency */ |
|
s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ |
s->heap[--(s->heap_max)] = m; |
|
/* Create a new node father of n and m */ |
tree[node].Freq = tree[n].Freq + tree[m].Freq; |
s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1); |
tree[n].Dad = tree[m].Dad = (ush)node; |
#ifdef DUMP_BL_TREE |
if (tree == s->bl_tree) { |
fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", |
node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); |
} |
#endif |
/* and insert the new node in the heap */ |
s->heap[SMALLEST] = node++; |
pqdownheap(s, tree, SMALLEST); |
|
} while (s->heap_len >= 2); |
|
s->heap[--(s->heap_max)] = s->heap[SMALLEST]; |
|
/* At this point, the fields freq and dad are set. We can now |
* generate the bit lengths. |
*/ |
gen_bitlen(s, (tree_desc *)desc); |
|
/* The field len is now set, we can generate the bit codes */ |
gen_codes ((ct_data *)tree, max_code, s->bl_count); |
} |
|
/* =========================================================================== |
* Scan a literal or distance tree to determine the frequencies of the codes |
* in the bit length tree. |
*/ |
local void scan_tree (s, tree, max_code) |
deflate_state *s; |
ct_data *tree; /* the tree to be scanned */ |
int max_code; /* and its largest code of non zero frequency */ |
{ |
int n; /* iterates over all tree elements */ |
int prevlen = -1; /* last emitted length */ |
int curlen; /* length of current code */ |
int nextlen = tree[0].Len; /* length of next code */ |
int count = 0; /* repeat count of the current code */ |
int max_count = 7; /* max repeat count */ |
int min_count = 4; /* min repeat count */ |
|
if (nextlen == 0) max_count = 138, min_count = 3; |
tree[max_code+1].Len = (ush)0xffff; /* guard */ |
|
for (n = 0; n <= max_code; n++) { |
curlen = nextlen; nextlen = tree[n+1].Len; |
if (++count < max_count && curlen == nextlen) { |
continue; |
} else if (count < min_count) { |
s->bl_tree[curlen].Freq += count; |
} else if (curlen != 0) { |
if (curlen != prevlen) s->bl_tree[curlen].Freq++; |
s->bl_tree[REP_3_6].Freq++; |
} else if (count <= 10) { |
s->bl_tree[REPZ_3_10].Freq++; |
} else { |
s->bl_tree[REPZ_11_138].Freq++; |
} |
count = 0; prevlen = curlen; |
if (nextlen == 0) { |
max_count = 138, min_count = 3; |
} else if (curlen == nextlen) { |
max_count = 6, min_count = 3; |
} else { |
max_count = 7, min_count = 4; |
} |
} |
} |
|
/* =========================================================================== |
* Send a literal or distance tree in compressed form, using the codes in |
* bl_tree. |
*/ |
local void send_tree (s, tree, max_code) |
deflate_state *s; |
ct_data *tree; /* the tree to be scanned */ |
int max_code; /* and its largest code of non zero frequency */ |
{ |
int n; /* iterates over all tree elements */ |
int prevlen = -1; /* last emitted length */ |
int curlen; /* length of current code */ |
int nextlen = tree[0].Len; /* length of next code */ |
int count = 0; /* repeat count of the current code */ |
int max_count = 7; /* max repeat count */ |
int min_count = 4; /* min repeat count */ |
|
/* tree[max_code+1].Len = -1; */ /* guard already set */ |
if (nextlen == 0) max_count = 138, min_count = 3; |
|
for (n = 0; n <= max_code; n++) { |
curlen = nextlen; nextlen = tree[n+1].Len; |
if (++count < max_count && curlen == nextlen) { |
continue; |
} else if (count < min_count) { |
do { send_code(s, curlen, s->bl_tree); } while (--count != 0); |
|
} else if (curlen != 0) { |
if (curlen != prevlen) { |
send_code(s, curlen, s->bl_tree); count--; |
} |
Assert(count >= 3 && count <= 6, " 3_6?"); |
send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); |
|
} else if (count <= 10) { |
send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); |
|
} else { |
send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); |
} |
count = 0; prevlen = curlen; |
if (nextlen == 0) { |
max_count = 138, min_count = 3; |
} else if (curlen == nextlen) { |
max_count = 6, min_count = 3; |
} else { |
max_count = 7, min_count = 4; |
} |
} |
} |
|
/* =========================================================================== |
* Construct the Huffman tree for the bit lengths and return the index in |
* bl_order of the last bit length code to send. |
*/ |
local int build_bl_tree(s) |
deflate_state *s; |
{ |
int max_blindex; /* index of last bit length code of non zero freq */ |
|
/* Determine the bit length frequencies for literal and distance trees */ |
scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); |
scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); |
|
/* Build the bit length tree: */ |
build_tree(s, (tree_desc *)(&(s->bl_desc))); |
/* opt_len now includes the length of the tree representations, except |
* the lengths of the bit lengths codes and the 5+5+4 bits for the counts. |
*/ |
|
/* Determine the number of bit length codes to send. The pkzip format |
* requires that at least 4 bit length codes be sent. (appnote.txt says |
* 3 but the actual value used is 4.) |
*/ |
for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { |
if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; |
} |
/* Update opt_len to include the bit length tree and counts */ |
s->opt_len += 3*(max_blindex+1) + 5+5+4; |
Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", |
s->opt_len, s->static_len)); |
|
return max_blindex; |
} |
|
/* =========================================================================== |
* Send the header for a block using dynamic Huffman trees: the counts, the |
* lengths of the bit length codes, the literal tree and the distance tree. |
* IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. |
*/ |
local void send_all_trees(s, lcodes, dcodes, blcodes) |
deflate_state *s; |
int lcodes, dcodes, blcodes; /* number of codes for each tree */ |
{ |
int rank; /* index in bl_order */ |
|
Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); |
Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, |
"too many codes"); |
Tracev((stderr, "\nbl counts: ")); |
send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ |
send_bits(s, dcodes-1, 5); |
send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ |
for (rank = 0; rank < blcodes; rank++) { |
Tracev((stderr, "\nbl code %2d ", bl_order[rank])); |
send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); |
} |
Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); |
|
send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ |
Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); |
|
send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ |
Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); |
} |
|
/* =========================================================================== |
* Send a stored block |
*/ |
void _tr_stored_block(s, buf, stored_len, eof) |
deflate_state *s; |
charf *buf; /* input block */ |
ulg stored_len; /* length of input block */ |
int eof; /* true if this is the last block for a file */ |
{ |
send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ |
#ifdef DEBUG |
s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; |
s->compressed_len += (stored_len + 4) << 3; |
#endif |
copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ |
} |
|
/* =========================================================================== |
* Send one empty static block to give enough lookahead for inflate. |
* This takes 10 bits, of which 7 may remain in the bit buffer. |
* The current inflate code requires 9 bits of lookahead. If the |
* last two codes for the previous block (real code plus EOB) were coded |
* on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode |
* the last real code. In this case we send two empty static blocks instead |
* of one. (There are no problems if the previous block is stored or fixed.) |
* To simplify the code, we assume the worst case of last real code encoded |
* on one bit only. |
*/ |
void _tr_align(s) |
deflate_state *s; |
{ |
send_bits(s, STATIC_TREES<<1, 3); |
send_code(s, END_BLOCK, static_ltree); |
#ifdef DEBUG |
s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ |
#endif |
bi_flush(s); |
/* Of the 10 bits for the empty block, we have already sent |
* (10 - bi_valid) bits. The lookahead for the last real code (before |
* the EOB of the previous block) was thus at least one plus the length |
* of the EOB plus what we have just sent of the empty static block. |
*/ |
if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { |
send_bits(s, STATIC_TREES<<1, 3); |
send_code(s, END_BLOCK, static_ltree); |
#ifdef DEBUG |
s->compressed_len += 10L; |
#endif |
bi_flush(s); |
} |
s->last_eob_len = 7; |
} |
|
/* =========================================================================== |
* Determine the best encoding for the current block: dynamic trees, static |
* trees or store, and output the encoded block to the zip file. |
*/ |
void _tr_flush_block(s, buf, stored_len, eof) |
deflate_state *s; |
charf *buf; /* input block, or NULL if too old */ |
ulg stored_len; /* length of input block */ |
int eof; /* true if this is the last block for a file */ |
{ |
ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ |
int max_blindex = 0; /* index of last bit length code of non zero freq */ |
|
/* Build the Huffman trees unless a stored block is forced */ |
if (s->level > 0) { |
|
/* Check if the file is ascii or binary */ |
if (s->data_type == Z_UNKNOWN) set_data_type(s); |
|
/* Construct the literal and distance trees */ |
build_tree(s, (tree_desc *)(&(s->l_desc))); |
Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, |
s->static_len)); |
|
build_tree(s, (tree_desc *)(&(s->d_desc))); |
Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, |
s->static_len)); |
/* At this point, opt_len and static_len are the total bit lengths of |
* the compressed block data, excluding the tree representations. |
*/ |
|
/* Build the bit length tree for the above two trees, and get the index |
* in bl_order of the last bit length code to send. |
*/ |
max_blindex = build_bl_tree(s); |
|
/* Determine the best encoding. Compute first the block length in bytes*/ |
opt_lenb = (s->opt_len+3+7)>>3; |
static_lenb = (s->static_len+3+7)>>3; |
|
Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", |
opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, |
s->last_lit)); |
|
if (static_lenb <= opt_lenb) opt_lenb = static_lenb; |
|
} else { |
Assert(buf != (char*)0, "lost buf"); |
opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ |
} |
|
#ifdef FORCE_STORED |
if (buf != (char*)0) { /* force stored block */ |
#else |
if (stored_len+4 <= opt_lenb && buf != (char*)0) { |
/* 4: two words for the lengths */ |
#endif |
/* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. |
* Otherwise we can't have processed more than WSIZE input bytes since |
* the last block flush, because compression would have been |
* successful. If LIT_BUFSIZE <= WSIZE, it is never too late to |
* transform a block into a stored block. |
*/ |
_tr_stored_block(s, buf, stored_len, eof); |
|
#ifdef FORCE_STATIC |
} else if (static_lenb >= 0) { /* force static trees */ |
#else |
} else if (static_lenb == opt_lenb) { |
#endif |
send_bits(s, (STATIC_TREES<<1)+eof, 3); |
compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); |
#ifdef DEBUG |
s->compressed_len += 3 + s->static_len; |
#endif |
} else { |
send_bits(s, (DYN_TREES<<1)+eof, 3); |
send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, |
max_blindex+1); |
compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); |
#ifdef DEBUG |
s->compressed_len += 3 + s->opt_len; |
#endif |
} |
Assert (s->compressed_len == s->bits_sent, "bad compressed size"); |
/* The above check is made mod 2^32, for files larger than 512 MB |
* and uLong implemented on 32 bits. |
*/ |
init_block(s); |
|
if (eof) { |
bi_windup(s); |
#ifdef DEBUG |
s->compressed_len += 7; /* align on byte boundary */ |
#endif |
} |
Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, |
s->compressed_len-7*eof)); |
} |
|
/* =========================================================================== |
* Save the match info and tally the frequency counts. Return true if |
* the current block must be flushed. |
*/ |
int _tr_tally (s, dist, lc) |
deflate_state *s; |
unsigned dist; /* distance of matched string */ |
unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ |
{ |
s->d_buf[s->last_lit] = (ush)dist; |
s->l_buf[s->last_lit++] = (uch)lc; |
if (dist == 0) { |
/* lc is the unmatched char */ |
s->dyn_ltree[lc].Freq++; |
} else { |
s->matches++; |
/* Here, lc is the match length - MIN_MATCH */ |
dist--; /* dist = match distance - 1 */ |
Assert((ush)dist < (ush)MAX_DIST(s) && |
(ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && |
(ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); |
|
s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; |
s->dyn_dtree[d_code(dist)].Freq++; |
} |
|
#ifdef TRUNCATE_BLOCK |
/* Try to guess if it is profitable to stop the current block here */ |
if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { |
/* Compute an upper bound for the compressed length */ |
ulg out_length = (ulg)s->last_lit*8L; |
ulg in_length = (ulg)((long)s->strstart - s->block_start); |
int dcode; |
for (dcode = 0; dcode < D_CODES; dcode++) { |
out_length += (ulg)s->dyn_dtree[dcode].Freq * |
(5L+extra_dbits[dcode]); |
} |
out_length >>= 3; |
Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", |
s->last_lit, in_length, out_length, |
100L - out_length*100L/in_length)); |
if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; |
} |
#endif |
return (s->last_lit == s->lit_bufsize-1); |
/* We avoid equality with lit_bufsize because of wraparound at 64K |
* on 16 bit machines and because stored blocks are restricted to |
* 64K-1 bytes. |
*/ |
} |
|
/* =========================================================================== |
* Send the block data compressed using the given Huffman trees |
*/ |
local void compress_block(s, ltree, dtree) |
deflate_state *s; |
ct_data *ltree; /* literal tree */ |
ct_data *dtree; /* distance tree */ |
{ |
unsigned dist; /* distance of matched string */ |
int lc; /* match length or unmatched char (if dist == 0) */ |
unsigned lx = 0; /* running index in l_buf */ |
unsigned code; /* the code to send */ |
int extra; /* number of extra bits to send */ |
|
if (s->last_lit != 0) do { |
dist = s->d_buf[lx]; |
lc = s->l_buf[lx++]; |
if (dist == 0) { |
send_code(s, lc, ltree); /* send a literal byte */ |
Tracecv(isgraph(lc), (stderr," '%c' ", lc)); |
} else { |
/* Here, lc is the match length - MIN_MATCH */ |
code = _length_code[lc]; |
send_code(s, code+LITERALS+1, ltree); /* send the length code */ |
extra = extra_lbits[code]; |
if (extra != 0) { |
lc -= base_length[code]; |
send_bits(s, lc, extra); /* send the extra length bits */ |
} |
dist--; /* dist is now the match distance - 1 */ |
code = d_code(dist); |
Assert (code < D_CODES, "bad d_code"); |
|
send_code(s, code, dtree); /* send the distance code */ |
extra = extra_dbits[code]; |
if (extra != 0) { |
dist -= base_dist[code]; |
send_bits(s, dist, extra); /* send the extra distance bits */ |
} |
} /* literal or match pair ? */ |
|
/* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ |
Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow"); |
|
} while (lx < s->last_lit); |
|
send_code(s, END_BLOCK, ltree); |
s->last_eob_len = ltree[END_BLOCK].Len; |
} |
|
/* =========================================================================== |
* Set the data type to ASCII or BINARY, using a crude approximation: |
* binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. |
* IN assertion: the fields freq of dyn_ltree are set and the total of all |
* frequencies does not exceed 64K (to fit in an int on 16 bit machines). |
*/ |
local void set_data_type(s) |
deflate_state *s; |
{ |
int n = 0; |
unsigned ascii_freq = 0; |
unsigned bin_freq = 0; |
while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; |
while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; |
while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; |
s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); |
} |
|
/* =========================================================================== |
* Reverse the first len bits of a code, using straightforward code (a faster |
* method would use a table) |
* IN assertion: 1 <= len <= 15 |
*/ |
local unsigned bi_reverse(code, len) |
unsigned code; /* the value to invert */ |
int len; /* its bit length */ |
{ |
register unsigned res = 0; |
do { |
res |= code & 1; |
code >>= 1, res <<= 1; |
} while (--len > 0); |
return res >> 1; |
} |
|
/* =========================================================================== |
* Flush the bit buffer, keeping at most 7 bits in it. |
*/ |
local void bi_flush(s) |
deflate_state *s; |
{ |
if (s->bi_valid == 16) { |
put_short(s, s->bi_buf); |
s->bi_buf = 0; |
s->bi_valid = 0; |
} else if (s->bi_valid >= 8) { |
put_byte(s, (Byte)s->bi_buf); |
s->bi_buf >>= 8; |
s->bi_valid -= 8; |
} |
} |
|
/* =========================================================================== |
* Flush the bit buffer and align the output on a byte boundary |
*/ |
local void bi_windup(s) |
deflate_state *s; |
{ |
if (s->bi_valid > 8) { |
put_short(s, s->bi_buf); |
} else if (s->bi_valid > 0) { |
put_byte(s, (Byte)s->bi_buf); |
} |
s->bi_buf = 0; |
s->bi_valid = 0; |
#ifdef DEBUG |
s->bits_sent = (s->bits_sent+7) & ~7; |
#endif |
} |
|
/* =========================================================================== |
* Copy a stored block, storing first the length and its |
* one's complement if requested. |
*/ |
local void copy_block(s, buf, len, header) |
deflate_state *s; |
charf *buf; /* the input data */ |
unsigned len; /* its length */ |
int header; /* true if block header must be written */ |
{ |
bi_windup(s); /* align on byte boundary */ |
s->last_eob_len = 8; /* enough lookahead for inflate */ |
|
if (header) { |
put_short(s, (ush)len); |
put_short(s, (ush)~len); |
#ifdef DEBUG |
s->bits_sent += 2*16; |
#endif |
} |
#ifdef DEBUG |
s->bits_sent += (ulg)len<<3; |
#endif |
while (len--) { |
put_byte(s, *buf++); |
} |
} |
/v2_0/src/algorithm.txt
0,0 → 1,213
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 real question is, given a Huffman tree, how to decode fast. The most |
important realization 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 set it |
for the maximum speed. |
|
inflate() sends new trees relatively often, so it is possibly set for a |
smaller first level table than an application that has only one tree for |
all the data. 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. It would be |
interesting to see if optimizing the first level table for other |
applications gave values within a bit or two of the flat code size. |
|
|
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 two 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 to 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 |
ftp://ds.internic.net/rfc/rfc1951.txt |
/v2_0/src/minigzip.c
0,0 → 1,320
/* minigzip.c -- simulate gzip using the zlib compression library |
* Copyright (C) 1995-1998 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: minigzip.c,v 1.1.1.1 2004-02-14 13:35:40 phoenix Exp $ */ |
|
#include <stdio.h> |
#include "zlib.h" |
|
#ifdef STDC |
# include <string.h> |
# include <stdlib.h> |
#else |
extern void exit OF((int)); |
#endif |
|
#ifdef USE_MMAP |
# include <sys/types.h> |
# include <sys/mman.h> |
# include <sys/stat.h> |
#endif |
|
#if defined(MSDOS) || defined(OS2) || defined(WIN32) |
# include <fcntl.h> |
# include <io.h> |
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) |
#else |
# define SET_BINARY_MODE(file) |
#endif |
|
#ifdef VMS |
# define unlink delete |
# define GZ_SUFFIX "-gz" |
#endif |
#ifdef RISCOS |
# define unlink remove |
# define GZ_SUFFIX "-gz" |
# define fileno(file) file->__file |
#endif |
#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os |
# include <unix.h> /* for fileno */ |
#endif |
|
#ifndef WIN32 /* unlink already in stdio.h for WIN32 */ |
extern int unlink OF((const char *)); |
#endif |
|
#ifndef GZ_SUFFIX |
# define GZ_SUFFIX ".gz" |
#endif |
#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) |
|
#define BUFLEN 16384 |
#define MAX_NAME_LEN 1024 |
|
#ifdef MAXSEG_64K |
# define local static |
/* Needed for systems with limitation on stack size. */ |
#else |
# define local |
#endif |
|
char *prog; |
|
void error OF((const char *msg)); |
void gz_compress OF((FILE *in, gzFile out)); |
#ifdef USE_MMAP |
int gz_compress_mmap OF((FILE *in, gzFile out)); |
#endif |
void gz_uncompress OF((gzFile in, FILE *out)); |
void file_compress OF((char *file, char *mode)); |
void file_uncompress OF((char *file)); |
int main OF((int argc, char *argv[])); |
|
/* =========================================================================== |
* Display error message and exit |
*/ |
void error(msg) |
const char *msg; |
{ |
fprintf(stderr, "%s: %s\n", prog, msg); |
exit(1); |
} |
|
/* =========================================================================== |
* Compress input to output then close both files. |
*/ |
|
void gz_compress(in, out) |
FILE *in; |
gzFile out; |
{ |
local char buf[BUFLEN]; |
int len; |
int err; |
|
#ifdef USE_MMAP |
/* Try first compressing with mmap. If mmap fails (minigzip used in a |
* pipe), use the normal fread loop. |
*/ |
if (gz_compress_mmap(in, out) == Z_OK) return; |
#endif |
for (;;) { |
len = fread(buf, 1, sizeof(buf), in); |
if (ferror(in)) { |
perror("fread"); |
exit(1); |
} |
if (len == 0) break; |
|
if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err)); |
} |
fclose(in); |
if (gzclose(out) != Z_OK) error("failed gzclose"); |
} |
|
#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */ |
|
/* Try compressing the input file at once using mmap. Return Z_OK if |
* if success, Z_ERRNO otherwise. |
*/ |
int gz_compress_mmap(in, out) |
FILE *in; |
gzFile out; |
{ |
int len; |
int err; |
int ifd = fileno(in); |
caddr_t buf; /* mmap'ed buffer for the entire input file */ |
off_t buf_len; /* length of the input file */ |
struct stat sb; |
|
/* Determine the size of the file, needed for mmap: */ |
if (fstat(ifd, &sb) < 0) return Z_ERRNO; |
buf_len = sb.st_size; |
if (buf_len <= 0) return Z_ERRNO; |
|
/* Now do the actual mmap: */ |
buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); |
if (buf == (caddr_t)(-1)) return Z_ERRNO; |
|
/* Compress the whole file at once: */ |
len = gzwrite(out, (char *)buf, (unsigned)buf_len); |
|
if (len != (int)buf_len) error(gzerror(out, &err)); |
|
munmap(buf, buf_len); |
fclose(in); |
if (gzclose(out) != Z_OK) error("failed gzclose"); |
return Z_OK; |
} |
#endif /* USE_MMAP */ |
|
/* =========================================================================== |
* Uncompress input to output then close both files. |
*/ |
void gz_uncompress(in, out) |
gzFile in; |
FILE *out; |
{ |
local char buf[BUFLEN]; |
int len; |
int err; |
|
for (;;) { |
len = gzread(in, buf, sizeof(buf)); |
if (len < 0) error (gzerror(in, &err)); |
if (len == 0) break; |
|
if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { |
error("failed fwrite"); |
} |
} |
if (fclose(out)) error("failed fclose"); |
|
if (gzclose(in) != Z_OK) error("failed gzclose"); |
} |
|
|
/* =========================================================================== |
* Compress the given file: create a corresponding .gz file and remove the |
* original. |
*/ |
void file_compress(file, mode) |
char *file; |
char *mode; |
{ |
local char outfile[MAX_NAME_LEN]; |
FILE *in; |
gzFile out; |
|
strcpy(outfile, file); |
strcat(outfile, GZ_SUFFIX); |
|
in = fopen(file, "rb"); |
if (in == NULL) { |
perror(file); |
exit(1); |
} |
out = gzopen(outfile, mode); |
if (out == NULL) { |
fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); |
exit(1); |
} |
gz_compress(in, out); |
|
unlink(file); |
} |
|
|
/* =========================================================================== |
* Uncompress the given file and remove the original. |
*/ |
void file_uncompress(file) |
char *file; |
{ |
local char buf[MAX_NAME_LEN]; |
char *infile, *outfile; |
FILE *out; |
gzFile in; |
int len = strlen(file); |
|
strcpy(buf, file); |
|
if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { |
infile = file; |
outfile = buf; |
outfile[len-3] = '\0'; |
} else { |
outfile = file; |
infile = buf; |
strcat(infile, GZ_SUFFIX); |
} |
in = gzopen(infile, "rb"); |
if (in == NULL) { |
fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); |
exit(1); |
} |
out = fopen(outfile, "wb"); |
if (out == NULL) { |
perror(file); |
exit(1); |
} |
|
gz_uncompress(in, out); |
|
unlink(infile); |
} |
|
|
/* =========================================================================== |
* Usage: minigzip [-d] [-f] [-h] [-1 to -9] [files...] |
* -d : decompress |
* -f : compress with Z_FILTERED |
* -h : compress with Z_HUFFMAN_ONLY |
* -1 to -9 : compression level |
*/ |
|
int main(argc, argv) |
int argc; |
char *argv[]; |
{ |
int uncompr = 0; |
gzFile file; |
char outmode[20]; |
|
strcpy(outmode, "wb6 "); |
|
prog = argv[0]; |
argc--, argv++; |
|
while (argc > 0) { |
if (strcmp(*argv, "-d") == 0) |
uncompr = 1; |
else if (strcmp(*argv, "-f") == 0) |
outmode[3] = 'f'; |
else if (strcmp(*argv, "-h") == 0) |
outmode[3] = 'h'; |
else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' && |
(*argv)[2] == 0) |
outmode[2] = (*argv)[1]; |
else |
break; |
argc--, argv++; |
} |
if (argc == 0) { |
SET_BINARY_MODE(stdin); |
SET_BINARY_MODE(stdout); |
if (uncompr) { |
file = gzdopen(fileno(stdin), "rb"); |
if (file == NULL) error("can't gzdopen stdin"); |
gz_uncompress(file, stdout); |
} else { |
file = gzdopen(fileno(stdout), outmode); |
if (file == NULL) error("can't gzdopen stdout"); |
gz_compress(stdin, file); |
} |
} else { |
do { |
if (uncompr) { |
file_uncompress(*argv); |
} else { |
file_compress(*argv, outmode); |
} |
} while (argv++, --argc); |
} |
exit(0); |
return 0; /* to avoid warning */ |
} |
/v2_0/src/INDEX
0,0 → 1,86
ChangeLog history of changes |
INDEX this file |
FAQ Frequently Asked Questions about zlib |
Make_vms.com script for Vax/VMS |
Makefile makefile for Unix (generated by configure) |
Makefile.in makefile for Unix (template for configure) |
Makefile.riscos makefile for RISCOS |
README guess what |
algorithm.txt description of the (de)compression algorithm |
configure configure script for Unix |
descrip.mms makefile for Vax/VMS |
zlib.3 mini man page for zlib (volunteers to write full |
man pages from zlib.h welcome. write to jloup@gzip.org) |
|
amiga/Makefile.sas makefile for Amiga SAS/C |
amiga/Makefile.pup makefile for Amiga powerUP SAS/C PPC |
|
msdos/Makefile.w32 makefile for Microsoft Visual C++ 32-bit |
msdos/Makefile.b32 makefile for Borland C++ 32-bit |
msdos/Makefile.bor makefile for Borland C/C++ 16-bit |
msdos/Makefile.dj2 makefile for DJGPP 2.x |
msdos/Makefile.emx makefile for EMX 0.9c (32-bit DOS/OS2) |
msdos/Makefile.msc makefile for Microsoft C 16-bit |
msdos/Makefile.tc makefile for Turbo C |
msdos/Makefile.wat makefile for Watcom C |
msdos/zlib.def definition file for Windows DLL |
msdos/zlib.rc definition file for Windows DLL |
|
nt/Makefile.nt makefile for Windows NT |
nt/zlib.dnt definition file for Windows NT DLL |
nt/Makefile.emx makefile for EMX 0.9c/RSXNT 1.41 (Win32 Intel) |
nt/Makefile.gcc makefile for Windows NT using GCC (mingw32) |
|
|
zlib public header files (must be kept): |
zconf.h |
zlib.h |
|
private source files used to build the zlib library: |
adler32.c |
compress.c |
crc32.c |
deflate.c |
deflate.h |
gzio.c |
infblock.c |
infblock.h |
infcodes.c |
infcodes.h |
inffast.c |
inffast.h |
inflate.c |
inftrees.c |
inftrees.h |
infutil.c |
infutil.h |
maketree.c |
trees.c |
uncompr.c |
zutil.c |
zutil.h |
|
source files for sample programs: |
example.c |
minigzip.c |
|
unsupported contribution by third parties |
|
contrib/asm386/ by Gilles Vollant <info@winimage.com> |
386 asm code replacing longest_match(). |
|
contrib/minizip/ by Gilles Vollant <info@winimage.com> |
Mini zip and unzip based on zlib |
See http://www.winimage.com/zLibDll/unzip.html |
|
contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu> |
A C++ I/O streams interface to the zlib gz* functions |
|
|
Another C++ I/O streams interface |
|
contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es> |
A very simple tar.gz extractor using zlib |
|
contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl> |
How to use compress(), uncompress() and the gz* functions from VB. |
/v2_0/src/trees.h
0,0 → 1,128
/* header created automatically with -DGEN_TREES_H */ |
|
local const ct_data static_ltree[L_CODES+2] = { |
{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, |
{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, |
{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, |
{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, |
{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, |
{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, |
{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, |
{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, |
{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, |
{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, |
{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, |
{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, |
{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, |
{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, |
{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, |
{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, |
{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, |
{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, |
{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, |
{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, |
{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, |
{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, |
{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, |
{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, |
{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, |
{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, |
{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, |
{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, |
{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, |
{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, |
{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, |
{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, |
{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, |
{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, |
{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, |
{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, |
{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, |
{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, |
{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, |
{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, |
{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, |
{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, |
{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, |
{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, |
{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, |
{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, |
{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, |
{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, |
{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, |
{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, |
{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, |
{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, |
{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, |
{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, |
{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, |
{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, |
{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, |
{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} |
}; |
|
local const ct_data static_dtree[D_CODES] = { |
{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, |
{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, |
{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, |
{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, |
{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, |
{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} |
}; |
|
const uch _dist_code[DIST_CODE_LEN] = { |
0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, |
8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, |
10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, |
11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, |
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, |
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, |
13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, |
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, |
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, |
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, |
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, |
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, |
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, |
18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, |
23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, |
24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, |
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, |
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, |
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, |
27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, |
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, |
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, |
28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, |
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, |
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, |
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 |
}; |
|
const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { |
0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, |
13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, |
17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, |
19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, |
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, |
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, |
23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, |
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, |
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, |
26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, |
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 |
}; |
|
local const int base_length[LENGTH_CODES] = { |
0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, |
64, 80, 96, 112, 128, 160, 192, 224, 0 |
}; |
|
local const int base_dist[D_CODES] = { |
0, 1, 2, 3, 4, 6, 8, 12, 16, 24, |
32, 48, 64, 96, 128, 192, 256, 384, 512, 768, |
1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 |
}; |
|
/v2_0/src/infblock.c
0,0 → 1,403
/* infblock.c -- interpret and process block types to last block |
* Copyright (C) 1995-1998 Mark Adler |
* For conditions of distribution and use, see copyright notice in zlib.h |
*/ |
|
#include "zutil.h" |
#include "infblock.h" |
#include "inftrees.h" |
#include "infcodes.h" |
#include "infutil.h" |
|
struct inflate_codes_state {int dummy;}; /* for buggy compilers */ |
|
/* simplify the use of the inflate_huft type with some defines */ |
#define exop word.what.Exop |
#define bits word.what.Bits |
|
/* Table for deflate from PKZIP's appnote.txt. */ |
local const uInt border[] = { /* Order of the bit length code lengths */ |
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; |
|
/* |
Notes beyond the 1.93a appnote.txt: |
|
1. Distance pointers never point before the beginning of the output |
stream. |
2. Distance pointers can point back across blocks, up to 32k away. |
3. There is an implied maximum of 7 bits for the bit length table and |
15 bits for the actual data. |
4. If only one code exists, then it is encoded using one bit. (Zero |
would be more efficient, but perhaps a little confusing.) If two |
codes exist, they are coded using one bit each (0 and 1). |
5. There is no way of sending zero distance codes--a dummy must be |
sent if there are none. (History: a pre 2.0 version of PKZIP would |
store blocks with no distance codes, but this was discovered to be |
too harsh a criterion.) Valid only for 1.93a. 2.04c does allow |
zero distance codes, which is sent as one code of zero bits in |
length. |
6. There are up to 286 literal/length codes. Code 256 represents the |
end-of-block. Note however that the static length tree defines |
288 codes just to fill out the Huffman codes. Codes 286 and 287 |
cannot be used though, since there is no length base or extra bits |
defined for them. Similarily, there are up to 30 distance codes. |
However, static trees define 32 codes (all 5 bits) to fill out the |
Huffman codes, but the last two had better not show up in the data. |
7. Unzip can check dynamic Huffman blocks for complete code sets. |
The exception is that a single code would not be complete (see #4). |
8. The five bits following the block type is really the number of |
literal codes sent minus 257. |
9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits |
(1+6+6). Therefore, to output three times the length, you output |
three codes (1+1+1), whereas to output four times the same length, |
you only need two codes (1+3). Hmm. |
10. In the tree reconstruction algorithm, Code = Code + Increment |
only if BitLength(i) is not zero. (Pretty obvious.) |
11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) |
12. Note: length code 284 can represent 227-258, but length code 285 |
really is 258. The last length deserves its own, short code |
since it gets used a lot in very redundant files. The length |
258 is special since 258 - 3 (the min match length) is 255. |
13. The literal/length and distance code bit lengths are read as a |
single stream of lengths. It is possible (and advantageous) for |
a repeat code (16, 17, or 18) to go across the boundary between |
the two sets of lengths. |
*/ |
|
|
void inflate_blocks_reset(s, z, c) |
inflate_blocks_statef *s; |
z_streamp z; |
uLongf *c; |
{ |
if (c != Z_NULL) |
*c = s->check; |
if (s->mode == BTREE || s->mode == DTREE) |
ZFREE(z, s->sub.trees.blens); |
if (s->mode == CODES) |
inflate_codes_free(s->sub.decode.codes, z); |
s->mode = TYPE; |
s->bitk = 0; |
s->bitb = 0; |
s->read = s->write = s->window; |
if (s->checkfn != Z_NULL) |
z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0); |
Tracev((stderr, "inflate: blocks reset\n")); |
} |
|
|
inflate_blocks_statef *inflate_blocks_new(z, c, w) |
z_streamp z; |
check_func c; |
uInt w; |
{ |
inflate_blocks_statef *s; |
|
if ((s = (inflate_blocks_statef *)ZALLOC |
(z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) |
return s; |
if ((s->hufts = |
(inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL) |
{ |
ZFREE(z, s); |
return Z_NULL; |
} |
if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) |
{ |
ZFREE(z, s->hufts); |
ZFREE(z, s); |
return Z_NULL; |
} |
s->end = s->window + w; |
s->checkfn = c; |
s->mode = TYPE; |
Tracev((stderr, "inflate: blocks allocated\n")); |
inflate_blocks_reset(s, z, Z_NULL); |
return s; |
} |
|
|
int inflate_blocks(s, z, r) |
inflate_blocks_statef *s; |
z_streamp z; |
int r; |
{ |
uInt t; /* temporary storage */ |
uLong b; /* bit buffer */ |
uInt k; /* bits in bit buffer */ |
Bytef *p; /* input data pointer */ |
uInt n; /* bytes available there */ |
Bytef *q; /* output window write pointer */ |
uInt m; /* bytes to end of window or read pointer */ |
|
/* copy input/output information to locals (UPDATE macro restores) */ |
LOAD |
|
/* process input based on current state */ |
while (1) switch (s->mode) |
{ |
case TYPE: |
NEEDBITS(3) |
t = (uInt)b & 7; |
s->last = t & 1; |
switch (t >> 1) |
{ |
case 0: /* stored */ |
Tracev((stderr, "inflate: stored block%s\n", |
s->last ? " (last)" : "")); |
DUMPBITS(3) |
t = k & 7; /* go to byte boundary */ |
DUMPBITS(t) |
s->mode = LENS; /* get length of stored block */ |
break; |
case 1: /* fixed */ |
Tracev((stderr, "inflate: fixed codes block%s\n", |
s->last ? " (last)" : "")); |
{ |
uInt bl, bd; |
inflate_huft *tl, *td; |
|
inflate_trees_fixed(&bl, &bd, &tl, &td, z); |
s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); |
if (s->sub.decode.codes == Z_NULL) |
{ |
r = Z_MEM_ERROR; |
LEAVE |
} |
} |
DUMPBITS(3) |
s->mode = CODES; |
break; |
case 2: /* dynamic */ |
Tracev((stderr, "inflate: dynamic codes block%s\n", |
s->last ? " (last)" : "")); |
DUMPBITS(3) |
s->mode = TABLE; |
break; |
case 3: /* illegal */ |
DUMPBITS(3) |
s->mode = BAD; |
z->msg = (char*)"invalid block type"; |
r = Z_DATA_ERROR; |
LEAVE |
} |
break; |
case LENS: |
NEEDBITS(32) |
if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) |
{ |
s->mode = BAD; |
z->msg = (char*)"invalid stored block lengths"; |
r = Z_DATA_ERROR; |
LEAVE |
} |
s->sub.left = (uInt)b & 0xffff; |
b = k = 0; /* dump bits */ |
Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); |
s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); |
break; |
case STORED: |
if (n == 0) |
LEAVE |
NEEDOUT |
t = s->sub.left; |
if (t > n) t = n; |
if (t > m) t = m; |
zmemcpy(q, p, t); |
p += t; n -= t; |
q += t; m -= t; |
if ((s->sub.left -= t) != 0) |
break; |
Tracev((stderr, "inflate: stored end, %lu total out\n", |
z->total_out + (q >= s->read ? q - s->read : |
(s->end - s->read) + (q - s->window)))); |
s->mode = s->last ? DRY : TYPE; |
break; |
case TABLE: |
NEEDBITS(14) |
s->sub.trees.table = t = (uInt)b & 0x3fff; |
#ifndef PKZIP_BUG_WORKAROUND |
if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) |
{ |
s->mode = BAD; |
z->msg = (char*)"too many length or distance symbols"; |
r = Z_DATA_ERROR; |
LEAVE |
} |
#endif |
t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); |
if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) |
{ |
r = Z_MEM_ERROR; |
LEAVE |
} |
DUMPBITS(14) |
s->sub.trees.index = 0; |
Tracev((stderr, "inflate: table sizes ok\n")); |
s->mode = BTREE; |
case BTREE: |
while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) |
{ |
NEEDBITS(3) |
s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; |
DUMPBITS(3) |
} |
while (s->sub.trees.index < 19) |
s->sub.trees.blens[border[s->sub.trees.index++]] = 0; |
s->sub.trees.bb = 7; |
t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, |
&s->sub.trees.tb, s->hufts, z); |
if (t != Z_OK) |
{ |
r = t; |
if (r == Z_DATA_ERROR) |
{ |
ZFREE(z, s->sub.trees.blens); |
s->mode = BAD; |
} |
LEAVE |
} |
s->sub.trees.index = 0; |
Tracev((stderr, "inflate: bits tree ok\n")); |
s->mode = DTREE; |
case DTREE: |
while (t = s->sub.trees.table, |
s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) |
{ |
inflate_huft *h; |
uInt i, j, c; |
|
t = s->sub.trees.bb; |
NEEDBITS(t) |
h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); |
t = h->bits; |
c = h->base; |
if (c < 16) |
{ |
DUMPBITS(t) |
s->sub.trees.blens[s->sub.trees.index++] = c; |
} |
else /* c == 16..18 */ |
{ |
i = c == 18 ? 7 : c - 14; |
j = c == 18 ? 11 : 3; |
NEEDBITS(t + i) |
DUMPBITS(t) |
j += (uInt)b & inflate_mask[i]; |
DUMPBITS(i) |
i = s->sub.trees.index; |
t = s->sub.trees.table; |
if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || |
(c == 16 && i < 1)) |
{ |
ZFREE(z, s->sub.trees.blens); |
s->mode = BAD; |
z->msg = (char*)"invalid bit length repeat"; |
r = Z_DATA_ERROR; |
LEAVE |
} |
c = c == 16 ? s->sub.trees.blens[i - 1] : 0; |
do { |
s->sub.trees.blens[i++] = c; |
} while (--j); |
s->sub.trees.index = i; |
} |
} |
s->sub.trees.tb = Z_NULL; |
{ |
uInt bl, bd; |
inflate_huft *tl, *td; |
inflate_codes_statef *c; |
|
bl = 9; /* must be <= 9 for lookahead assumptions */ |
bd = 6; /* must be <= 9 for lookahead assumptions */ |
t = s->sub.trees.table; |
t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), |
s->sub.trees.blens, &bl, &bd, &tl, &td, |
s->hufts, z); |
if (t != Z_OK) |
{ |
if (t == (uInt)Z_DATA_ERROR) |
{ |
ZFREE(z, s->sub.trees.blens); |
s->mode = BAD; |
} |
r = t; |
LEAVE |
} |
ZFREE(z, s->sub.trees.blens); |
Tracev((stderr, "inflate: trees ok\n")); |
if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) |
{ |
r = Z_MEM_ERROR; |
LEAVE |
} |
s->sub.decode.codes = c; |
} |
s->mode = CODES; |
case CODES: |
UPDATE |
if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) |
return inflate_flush(s, z, r); |
r = Z_OK; |
inflate_codes_free(s->sub.decode.codes, z); |
LOAD |
Tracev((stderr, "inflate: codes end, %lu total out\n", |
z->total_out + (q >= s->read ? q - s->read : |
(s->end - s->read) + (q - s->window)))); |
if (!s->last) |
{ |
s->mode = TYPE; |
break; |
} |
s->mode = DRY; |
case DRY: |
FLUSH |
if (s->read != s->write) |
LEAVE |
s->mode = DONE; |
case DONE: |
r = Z_STREAM_END; |
LEAVE |
case BAD: |
r = Z_DATA_ERROR; |
LEAVE |
default: |
r = Z_STREAM_ERROR; |
LEAVE |
} |
} |
|
|
int inflate_blocks_free(s, z) |
inflate_blocks_statef *s; |
z_streamp z; |
{ |
inflate_blocks_reset(s, z, Z_NULL); |
ZFREE(z, s->window); |
ZFREE(z, s->hufts); |
ZFREE(z, s); |
Tracev((stderr, "inflate: blocks freed\n")); |
return Z_OK; |
} |
|
|
void inflate_set_dictionary(s, d, n) |
inflate_blocks_statef *s; |
const Bytef *d; |
uInt n; |
{ |
zmemcpy(s->window, d, n); |
s->read = s->write = s->window + n; |
} |
|
|
/* Returns true if inflate is currently at the end of a block generated |
* by Z_SYNC_FLUSH or Z_FULL_FLUSH. |
* IN assertion: s != Z_NULL |
*/ |
int inflate_blocks_sync_point(s) |
inflate_blocks_statef *s; |
{ |
return s->mode == LENS; |
} |
/v2_0/src/inffast.c
0,0 → 1,170
/* inffast.c -- process literals and length/distance pairs fast |
* Copyright (C) 1995-1998 Mark Adler |
* For conditions of distribution and use, see copyright notice in zlib.h |
*/ |
|
#include "zutil.h" |
#include "inftrees.h" |
#include "infblock.h" |
#include "infcodes.h" |
#include "infutil.h" |
#include "inffast.h" |
|
struct inflate_codes_state {int dummy;}; /* for buggy compilers */ |
|
/* simplify the use of the inflate_huft type with some defines */ |
#define exop word.what.Exop |
#define bits word.what.Bits |
|
/* macros for bit input with no checking and for returning unused bytes */ |
#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}} |
#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;} |
|
/* Called with number of bytes left to write in window at least 258 |
(the maximum string length) and number of input bytes available |
at least ten. The ten bytes are six bytes for the longest length/ |
distance pair plus four bytes for overloading the bit buffer. */ |
|
int inflate_fast(bl, bd, tl, td, s, z) |
uInt bl, bd; |
inflate_huft *tl; |
inflate_huft *td; /* need separate declaration for Borland C++ */ |
inflate_blocks_statef *s; |
z_streamp z; |
{ |
inflate_huft *t; /* temporary pointer */ |
uInt e; /* extra bits or operation */ |
uLong b; /* bit buffer */ |
uInt k; /* bits in bit buffer */ |
Bytef *p; /* input data pointer */ |
uInt n; /* bytes available there */ |
Bytef *q; /* output window write pointer */ |
uInt m; /* bytes to end of window or read pointer */ |
uInt ml; /* mask for literal/length tree */ |
uInt md; /* mask for distance tree */ |
uInt c; /* bytes to copy */ |
uInt d; /* distance back to copy from */ |
Bytef *r; /* copy source pointer */ |
|
/* load input, output, bit values */ |
LOAD |
|
/* initialize masks */ |
ml = inflate_mask[bl]; |
md = inflate_mask[bd]; |
|
/* do until not enough input or output space for fast loop */ |
do { /* assume called with m >= 258 && n >= 10 */ |
/* get literal/length code */ |
GRABBITS(20) /* max bits for literal/length code */ |
if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) |
{ |
DUMPBITS(t->bits) |
Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? |
"inflate: * literal '%c'\n" : |
"inflate: * literal 0x%02x\n", t->base)); |
*q++ = (Byte)t->base; |
m--; |
continue; |
} |
do { |
DUMPBITS(t->bits) |
if (e & 16) |
{ |
/* get extra bits for length */ |
e &= 15; |
c = t->base + ((uInt)b & inflate_mask[e]); |
DUMPBITS(e) |
Tracevv((stderr, "inflate: * length %u\n", c)); |
|
/* decode distance base of block to copy */ |
GRABBITS(15); /* max bits for distance code */ |
e = (t = td + ((uInt)b & md))->exop; |
do { |
DUMPBITS(t->bits) |
if (e & 16) |
{ |
/* get extra bits to add to distance base */ |
e &= 15; |
GRABBITS(e) /* get extra bits (up to 13) */ |
d = t->base + ((uInt)b & inflate_mask[e]); |
DUMPBITS(e) |
Tracevv((stderr, "inflate: * distance %u\n", d)); |
|
/* do the copy */ |
m -= c; |
if ((uInt)(q - s->window) >= d) /* offset before dest */ |
{ /* just copy */ |
r = q - d; |
*q++ = *r++; c--; /* minimum count is three, */ |
*q++ = *r++; c--; /* so unroll loop a little */ |
} |
else /* else offset after destination */ |
{ |
e = d - (uInt)(q - s->window); /* bytes from offset to end */ |
r = s->end - e; /* pointer to offset */ |
if (c > e) /* if source crosses, */ |
{ |
c -= e; /* copy to end of window */ |
do { |
*q++ = *r++; |
} while (--e); |
r = s->window; /* copy rest from start of window */ |
} |
} |
do { /* copy all or what's left */ |
*q++ = *r++; |
} while (--c); |
break; |
} |
else if ((e & 64) == 0) |
{ |
t += t->base; |
e = (t += ((uInt)b & inflate_mask[e]))->exop; |
} |
else |
{ |
z->msg = (char*)"invalid distance code"; |
UNGRAB |
UPDATE |
return Z_DATA_ERROR; |
} |
} while (1); |
break; |
} |
if ((e & 64) == 0) |
{ |
t += t->base; |
if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0) |
{ |
DUMPBITS(t->bits) |
Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? |
"inflate: * literal '%c'\n" : |
"inflate: * literal 0x%02x\n", t->base)); |
*q++ = (Byte)t->base; |
m--; |
break; |
} |
} |
else if (e & 32) |
{ |
Tracevv((stderr, "inflate: * end of block\n")); |
UNGRAB |
UPDATE |
return Z_STREAM_END; |
} |
else |
{ |
z->msg = (char*)"invalid literal/length code"; |
UNGRAB |
UPDATE |
return Z_DATA_ERROR; |
} |
} while (1); |
} while (m >= 258 && n >= 10); |
|
/* not enough input or output--restore pointers and return */ |
UNGRAB |
UPDATE |
return Z_OK; |
} |
/v2_0/src/compress.c
0,0 → 1,72
/* compress.c -- compress a memory buffer |
* Copyright (C) 1995-1998 Jean-loup Gailly. |
* For conditions of distribution and use, see copyright notice in zlib.h |
*/ |
|
/* @(#) $Id: compress.c,v 1.1.1.1 2004-02-14 13:35:37 phoenix Exp $ */ |
|
#ifdef __ECOS__ |
#include <cyg/compress/zlib.h> |
#else |
#include "zlib.h" |
#endif // __ECOS__ |
|
/* =========================================================================== |
Compresses the source buffer into the destination buffer. The level |
parameter has the same meaning as in deflateInit. sourceLen is the byte |
length of the source buffer. Upon entry, destLen is the total size of the |
destination buffer, which must be at least 0.1% larger than sourceLen plus |
12 bytes. Upon exit, destLen is the actual size of the compressed buffer. |
|
compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough |
memory, Z_BUF_ERROR if there was not enough room in the output buffer, |
Z_STREAM_ERROR if the level parameter is invalid. |
*/ |
int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) |
Bytef *dest; |
uLongf *destLen; |
const Bytef *source; |
uLong sourceLen; |
int level; |
{ |
z_stream stream; |
int err; |
|
stream.next_in = (Bytef*)source; |
stream.avail_in = (uInt)sourceLen; |
#ifdef MAXSEG_64K |
/* Check for source > 64K on 16-bit machine: */ |
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; |
#endif |
stream.next_out = dest; |
stream.avail_out = (uInt)*destLen; |
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; |
|
stream.zalloc = (alloc_func)0; |
stream.zfree = (free_func)0; |
stream.opaque = (voidpf)0; |
|
err = deflateInit(&stream, level); |
if (err != Z_OK) return err; |
|
err = deflate(&stream, Z_FINISH); |
if (err != Z_STREAM_END) { |
deflateEnd(&stream); |
return err == Z_OK ? Z_BUF_ERROR : err; |
} |
*destLen = stream.total_out; |
|
err = deflateEnd(&stream); |
return err; |
} |
|
/* =========================================================================== |
*/ |
int ZEXPORT compress (dest, destLen, source, sourceLen) |
Bytef *dest; |
uLongf *destLen; |
const Bytef *source; |
uLong sourceLen; |
{ |
return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); |
} |
/v2_0/src/example.c
0,0 → 1,556
/* example.c -- usage example of the zlib compression library |
* Copyright (C) 1995-1998 Jean-loup Gailly. |
* For conditions of distribution and use, see copyright notice in zlib.h |
*/ |
|
/* @(#) $Id: example.c,v 1.1.1.1 2004-02-14 13:35:37 phoenix Exp $ */ |
|
#include <stdio.h> |
#include "zlib.h" |
|
#ifdef STDC |
# include <string.h> |
# include <stdlib.h> |
#else |
extern void exit OF((int)); |
#endif |
|
#if defined(VMS) || defined(RISCOS) |
# define TESTFILE "foo-gz" |
#else |
# define TESTFILE "foo.gz" |
#endif |
|
#define CHECK_ERR(err, msg) { \ |
if (err != Z_OK) { \ |
fprintf(stderr, "%s error: %d\n", msg, err); \ |
exit(1); \ |
} \ |
} |
|
const char hello[] = "hello, hello!"; |
/* "hello world" would be more standard, but the repeated "hello" |
* stresses the compression code better, sorry... |
*/ |
|
const char dictionary[] = "hello"; |
uLong dictId; /* Adler32 value of the dictionary */ |
|
void test_compress OF((Byte *compr, uLong comprLen, |
Byte *uncompr, uLong uncomprLen)); |
void test_gzio OF((const char *out, const char *in, |
Byte *uncompr, int uncomprLen)); |
void test_deflate OF((Byte *compr, uLong comprLen)); |
void test_inflate OF((Byte *compr, uLong comprLen, |
Byte *uncompr, uLong uncomprLen)); |
void test_large_deflate OF((Byte *compr, uLong comprLen, |
Byte *uncompr, uLong uncomprLen)); |
void test_large_inflate OF((Byte *compr, uLong comprLen, |
Byte *uncompr, uLong uncomprLen)); |
void test_flush OF((Byte *compr, uLong *comprLen)); |
void test_sync OF((Byte *compr, uLong comprLen, |
Byte *uncompr, uLong uncomprLen)); |
void test_dict_deflate OF((Byte *compr, uLong comprLen)); |
void test_dict_inflate OF((Byte *compr, uLong comprLen, |
Byte *uncompr, uLong uncomprLen)); |
int main OF((int argc, char *argv[])); |
|
/* =========================================================================== |
* Test compress() and uncompress() |
*/ |
void test_compress(compr, comprLen, uncompr, uncomprLen) |
Byte *compr, *uncompr; |
uLong comprLen, uncomprLen; |
{ |
int err; |
uLong len = 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(out, in, uncompr, uncomprLen) |
const char *out; /* compressed output file */ |
const char *in; /* compressed input file */ |
Byte *uncompr; |
int uncomprLen; |
{ |
int err; |
int len = strlen(hello)+1; |
gzFile file; |
z_off_t pos; |
|
file = gzopen(out, "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(in, "rb"); |
if (file == NULL) { |
fprintf(stderr, "gzopen error\n"); |
} |
strcpy((char*)uncompr, "garbage"); |
|
uncomprLen = gzread(file, uncompr, (unsigned)uncomprLen); |
if (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); |
} |
|
gzgets(file, (char*)uncompr, uncomprLen); |
uncomprLen = strlen((char*)uncompr); |
if (uncomprLen != 6) { /* "hello!" */ |
fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err)); |
exit(1); |
} |
if (strcmp((char*)uncompr, hello+7)) { |
fprintf(stderr, "bad gzgets after gzseek\n"); |
exit(1); |
} else { |
printf("gzgets() after gzseek: %s\n", (char *)uncompr); |
} |
|
gzclose(file); |
} |
|
/* =========================================================================== |
* Test deflate() with small buffers |
*/ |
void test_deflate(compr, comprLen) |
Byte *compr; |
uLong comprLen; |
{ |
z_stream c_stream; /* compression stream */ |
int err; |
int len = strlen(hello)+1; |
|
c_stream.zalloc = (alloc_func)0; |
c_stream.zfree = (free_func)0; |
c_stream.opaque = (voidpf)0; |
|
err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); |
CHECK_ERR(err, "deflateInit"); |
|
c_stream.next_in = (Bytef*)hello; |
c_stream.next_out = compr; |
|
while (c_stream.total_in != (uLong)len && c_stream.total_out < comprLen) { |
c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ |
err = deflate(&c_stream, Z_NO_FLUSH); |
CHECK_ERR(err, "deflate"); |
} |
/* Finish the stream, still forcing small buffers: */ |
for (;;) { |
c_stream.avail_out = 1; |
err = deflate(&c_stream, Z_FINISH); |
if (err == Z_STREAM_END) break; |
CHECK_ERR(err, "deflate"); |
} |
|
err = deflateEnd(&c_stream); |
CHECK_ERR(err, "deflateEnd"); |
} |
|
/* =========================================================================== |
* Test inflate() with small buffers |
*/ |
void test_inflate(compr, comprLen, uncompr, uncomprLen) |
Byte *compr, *uncompr; |
uLong comprLen, uncomprLen; |
{ |
int err; |
z_stream d_stream; /* decompression stream */ |
|
strcpy((char*)uncompr, "garbage"); |
|
d_stream.zalloc = (alloc_func)0; |
d_stream.zfree = (free_func)0; |
d_stream.opaque = (voidpf)0; |
|
d_stream.next_in = compr; |
d_stream.avail_in = 0; |
d_stream.next_out = uncompr; |
|
err = inflateInit(&d_stream); |
CHECK_ERR(err, "inflateInit"); |
|
while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) { |
d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ |
err = inflate(&d_stream, Z_NO_FLUSH); |
if (err == Z_STREAM_END) break; |
CHECK_ERR(err, "inflate"); |
} |
|
err = inflateEnd(&d_stream); |
CHECK_ERR(err, "inflateEnd"); |
|
if (strcmp((char*)uncompr, hello)) { |
fprintf(stderr, "bad inflate\n"); |
exit(1); |
} else { |
printf("inflate(): %s\n", (char *)uncompr); |
} |
} |
|
/* =========================================================================== |
* Test deflate() with large buffers and dynamic change of compression level |
*/ |
void test_large_deflate(compr, comprLen, uncompr, uncomprLen) |
Byte *compr, *uncompr; |
uLong comprLen, uncomprLen; |
{ |
z_stream c_stream; /* compression stream */ |
int err; |
|
c_stream.zalloc = (alloc_func)0; |
c_stream.zfree = (free_func)0; |
c_stream.opaque = (voidpf)0; |
|
err = deflateInit(&c_stream, Z_BEST_SPEED); |
CHECK_ERR(err, "deflateInit"); |
|
c_stream.next_out = compr; |
c_stream.avail_out = (uInt)comprLen; |
|
/* At this point, uncompr is still mostly zeroes, so it should compress |
* very well: |
*/ |
c_stream.next_in = uncompr; |
c_stream.avail_in = (uInt)uncomprLen; |
err = deflate(&c_stream, Z_NO_FLUSH); |
CHECK_ERR(err, "deflate"); |
if (c_stream.avail_in != 0) { |
fprintf(stderr, "deflate not greedy\n"); |
exit(1); |
} |
|
/* Feed in already compressed data and switch to no compression: */ |
deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); |
c_stream.next_in = compr; |
c_stream.avail_in = (uInt)comprLen/2; |
err = deflate(&c_stream, Z_NO_FLUSH); |
CHECK_ERR(err, "deflate"); |
|
/* Switch back to compressing mode: */ |
deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); |
c_stream.next_in = uncompr; |
c_stream.avail_in = (uInt)uncomprLen; |
err = deflate(&c_stream, Z_NO_FLUSH); |
CHECK_ERR(err, "deflate"); |
|
err = deflate(&c_stream, Z_FINISH); |
if (err != Z_STREAM_END) { |
fprintf(stderr, "deflate should report Z_STREAM_END\n"); |
exit(1); |
} |
err = deflateEnd(&c_stream); |
CHECK_ERR(err, "deflateEnd"); |
} |
|
/* =========================================================================== |
* Test inflate() with large buffers |
*/ |
void test_large_inflate(compr, comprLen, uncompr, uncomprLen) |
Byte *compr, *uncompr; |
uLong comprLen, uncomprLen; |
{ |
int err; |
z_stream d_stream; /* decompression stream */ |
|
strcpy((char*)uncompr, "garbage"); |
|
d_stream.zalloc = (alloc_func)0; |
d_stream.zfree = (free_func)0; |
d_stream.opaque = (voidpf)0; |
|
d_stream.next_in = compr; |
d_stream.avail_in = (uInt)comprLen; |
|
err = inflateInit(&d_stream); |
CHECK_ERR(err, "inflateInit"); |
|
for (;;) { |
d_stream.next_out = uncompr; /* discard the output */ |
d_stream.avail_out = (uInt)uncomprLen; |
err = inflate(&d_stream, Z_NO_FLUSH); |
if (err == Z_STREAM_END) break; |
CHECK_ERR(err, "large inflate"); |
} |
|
err = inflateEnd(&d_stream); |
CHECK_ERR(err, "inflateEnd"); |
|
if (d_stream.total_out != 2*uncomprLen + comprLen/2) { |
fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out); |
exit(1); |
} else { |
printf("large_inflate(): OK\n"); |
} |
} |
|
/* =========================================================================== |
* Test deflate() with full flush |
*/ |
void test_flush(compr, comprLen) |
Byte *compr; |
uLong *comprLen; |
{ |
z_stream c_stream; /* compression stream */ |
int err; |
int len = strlen(hello)+1; |
|
c_stream.zalloc = (alloc_func)0; |
c_stream.zfree = (free_func)0; |
c_stream.opaque = (voidpf)0; |
|
err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); |
CHECK_ERR(err, "deflateInit"); |
|
c_stream.next_in = (Bytef*)hello; |
c_stream.next_out = compr; |
c_stream.avail_in = 3; |
c_stream.avail_out = (uInt)*comprLen; |
err = deflate(&c_stream, Z_FULL_FLUSH); |
CHECK_ERR(err, "deflate"); |
|
compr[3]++; /* force an error in first compressed block */ |
c_stream.avail_in = len - 3; |
|
err = deflate(&c_stream, Z_FINISH); |
if (err != Z_STREAM_END) { |
CHECK_ERR(err, "deflate"); |
} |
err = deflateEnd(&c_stream); |
CHECK_ERR(err, "deflateEnd"); |
|
*comprLen = c_stream.total_out; |
} |
|
/* =========================================================================== |
* Test inflateSync() |
*/ |
void test_sync(compr, comprLen, uncompr, uncomprLen) |
Byte *compr, *uncompr; |
uLong comprLen, uncomprLen; |
{ |
int err; |
z_stream d_stream; /* decompression stream */ |
|
strcpy((char*)uncompr, "garbage"); |
|
d_stream.zalloc = (alloc_func)0; |
d_stream.zfree = (free_func)0; |
d_stream.opaque = (voidpf)0; |
|
d_stream.next_in = compr; |
d_stream.avail_in = 2; /* just read the zlib header */ |
|
err = inflateInit(&d_stream); |
CHECK_ERR(err, "inflateInit"); |
|
d_stream.next_out = uncompr; |
d_stream.avail_out = (uInt)uncomprLen; |
|
inflate(&d_stream, Z_NO_FLUSH); |
CHECK_ERR(err, "inflate"); |
|
d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */ |
err = inflateSync(&d_stream); /* but skip the damaged part */ |
CHECK_ERR(err, "inflateSync"); |
|
err = inflate(&d_stream, Z_FINISH); |
if (err != Z_DATA_ERROR) { |
fprintf(stderr, "inflate should report DATA_ERROR\n"); |
/* Because of incorrect adler32 */ |
exit(1); |
} |
err = inflateEnd(&d_stream); |
CHECK_ERR(err, "inflateEnd"); |
|
printf("after inflateSync(): hel%s\n", (char *)uncompr); |
} |
|
/* =========================================================================== |
* Test deflate() with preset dictionary |
*/ |
void test_dict_deflate(compr, comprLen) |
Byte *compr; |
uLong comprLen; |
{ |
z_stream c_stream; /* compression stream */ |
int err; |
|
c_stream.zalloc = (alloc_func)0; |
c_stream.zfree = (free_func)0; |
c_stream.opaque = (voidpf)0; |
|
err = deflateInit(&c_stream, Z_BEST_COMPRESSION); |
CHECK_ERR(err, "deflateInit"); |
|
err = deflateSetDictionary(&c_stream, |
(const Bytef*)dictionary, sizeof(dictionary)); |
CHECK_ERR(err, "deflateSetDictionary"); |
|
dictId = c_stream.adler; |
c_stream.next_out = compr; |
c_stream.avail_out = (uInt)comprLen; |
|
c_stream.next_in = (Bytef*)hello; |
c_stream.avail_in = (uInt)strlen(hello)+1; |
|
err = deflate(&c_stream, Z_FINISH); |
if (err != Z_STREAM_END) { |
fprintf(stderr, "deflate should report Z_STREAM_END\n"); |
exit(1); |
} |
err = deflateEnd(&c_stream); |
CHECK_ERR(err, "deflateEnd"); |
} |
|
/* =========================================================================== |
* Test inflate() with a preset dictionary |
*/ |
void test_dict_inflate(compr, comprLen, uncompr, uncomprLen) |
Byte *compr, *uncompr; |
uLong comprLen, uncomprLen; |
{ |
int err; |
z_stream d_stream; /* decompression stream */ |
|
strcpy((char*)uncompr, "garbage"); |
|
d_stream.zalloc = (alloc_func)0; |
d_stream.zfree = (free_func)0; |
d_stream.opaque = (voidpf)0; |
|
d_stream.next_in = compr; |
d_stream.avail_in = (uInt)comprLen; |
|
err = inflateInit(&d_stream); |
CHECK_ERR(err, "inflateInit"); |
|
d_stream.next_out = uncompr; |
d_stream.avail_out = (uInt)uncomprLen; |
|
for (;;) { |
err = inflate(&d_stream, Z_NO_FLUSH); |
if (err == Z_STREAM_END) break; |
if (err == Z_NEED_DICT) { |
if (d_stream.adler != dictId) { |
fprintf(stderr, "unexpected dictionary"); |
exit(1); |
} |
err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary, |
sizeof(dictionary)); |
} |
CHECK_ERR(err, "inflate with dict"); |
} |
|
err = inflateEnd(&d_stream); |
CHECK_ERR(err, "inflateEnd"); |
|
if (strcmp((char*)uncompr, hello)) { |
fprintf(stderr, "bad inflate with dict\n"); |
exit(1); |
} else { |
printf("inflate with dictionary: %s\n", (char *)uncompr); |
} |
} |
|
/* =========================================================================== |
* Usage: example [output.gz [input.gz]] |
*/ |
|
int main(argc, argv) |
int argc; |
char *argv[]; |
{ |
Byte *compr, *uncompr; |
uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */ |
uLong uncomprLen = comprLen; |
static const char* myVersion = ZLIB_VERSION; |
|
if (zlibVersion()[0] != myVersion[0]) { |
fprintf(stderr, "incompatible zlib version\n"); |
exit(1); |
|
} else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) { |
fprintf(stderr, "warning: different zlib version\n"); |
} |
|
compr = (Byte*)calloc((uInt)comprLen, 1); |
uncompr = (Byte*)calloc((uInt)uncomprLen, 1); |
/* compr and uncompr are cleared to avoid reading uninitialized |
* data and to ensure that uncompr compresses well. |
*/ |
if (compr == Z_NULL || uncompr == Z_NULL) { |
printf("out of memory\n"); |
exit(1); |
} |
test_compress(compr, comprLen, uncompr, uncomprLen); |
|
test_gzio((argc > 1 ? argv[1] : TESTFILE), |
(argc > 2 ? argv[2] : TESTFILE), |
uncompr, (int)uncomprLen); |
|
test_deflate(compr, comprLen); |
test_inflate(compr, comprLen, uncompr, uncomprLen); |
|
test_large_deflate(compr, comprLen, uncompr, uncomprLen); |
test_large_inflate(compr, comprLen, uncompr, uncomprLen); |
|
test_flush(compr, &comprLen); |
test_sync(compr, comprLen, uncompr, uncomprLen); |
comprLen = uncomprLen; |
|
test_dict_deflate(compr, comprLen); |
test_dict_inflate(compr, comprLen, uncompr, uncomprLen); |
|
exit(0); |
return 0; /* to avoid warning */ |
} |
/v2_0/src/Makefile
0,0 → 1,174
# Makefile for zlib |
# Copyright (C) 1995-1998 Jean-loup Gailly. |
# For conditions of distribution and use, see copyright notice in zlib.h |
|
# To compile and test, type: |
# ./configure; make test |
# The call of configure is optional if you don't have special requirements |
# If you wish to build zlib as a shared library, use: ./configure -s |
|
# 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 |
|
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 |
|
LDFLAGS=-L. -lz |
LDSHARED=$(CC) |
CPP=$(CC) -E |
|
VER=1.1.3 |
LIBS=libz.a |
SHAREDLIB=libz.so |
|
AR=ar rc |
RANLIB=ranlib |
TAR=tar |
SHELL=/bin/sh |
|
prefix = /usr/local |
exec_prefix = ${prefix} |
libdir = ${exec_prefix}/lib |
includedir = ${prefix}/include |
|
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 |
|
OBJA = |
# to use the asm code: make OBJA=match.o |
|
TEST_OBJS = example.o minigzip.o |
|
DISTFILES = README FAQ INDEX ChangeLog configure Make*[a-z0-9] *.[ch] *.mms \ |
algorithm.txt zlib.3 msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \ |
nt/Make*[a-z0-9] nt/zlib.dnt amiga/Make*.??? os2/M*.os2 os2/zlib.def \ |
contrib/RE*.contrib contrib/*.txt contrib/asm386/*.asm contrib/asm386/*.c \ |
contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/asm[56]86/*.?86 \ |
contrib/asm[56]86/*.S contrib/iostream/*.cpp \ |
contrib/iostream/*.h contrib/iostream2/*.h contrib/iostream2/*.cpp \ |
contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32 \ |
contrib/minizip/[CM]*[pe] contrib/minizip/*.[ch] contrib/minizip/*.[td]?? \ |
contrib/delphi*/*.??? |
|
all: example minigzip |
|
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 |
|
libz.a: $(OBJS) $(OBJA) |
$(AR) $@ $(OBJS) $(OBJA) |
-@ ($(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 |
|
$(SHAREDLIB).$(VER): $(OBJS) |
$(LDSHARED) -o $@ $(OBJS) |
rm -f $(SHAREDLIB) $(SHAREDLIB).1 |
ln -s $@ $(SHAREDLIB) |
ln -s $@ $(SHAREDLIB).1 |
|
example: example.o $(LIBS) |
$(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) |
|
minigzip: minigzip.o $(LIBS) |
$(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) |
|
install: $(LIBS) |
-@if [ ! -d $(includedir) ]; then mkdir $(includedir); fi |
-@if [ ! -d $(libdir) ]; then mkdir $(libdir); fi |
cp zlib.h zconf.h $(includedir) |
chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h |
cp $(LIBS) $(libdir) |
cd $(libdir); chmod 755 $(LIBS) |
-@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1 |
cd $(libdir); if test -f $(SHAREDLIB).$(VER); then \ |
rm -f $(SHAREDLIB) $(SHAREDLIB).1; \ |
ln -s $(SHAREDLIB).$(VER) $(SHAREDLIB); \ |
ln -s $(SHAREDLIB).$(VER) $(SHAREDLIB).1; \ |
(ldconfig || true) >/dev/null 2>&1; \ |
fi |
# The ranlib in install is needed on NeXTSTEP which checks file times |
# ldconfig is for Linux |
|
uninstall: |
cd $(includedir); \ |
v=$(VER); \ |
if test -f zlib.h; then \ |
v=`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`; \ |
rm -f zlib.h zconf.h; \ |
fi; \ |
cd $(libdir); rm -f libz.a; \ |
if test -f $(SHAREDLIB).$$v; then \ |
rm -f $(SHAREDLIB).$$v $(SHAREDLIB) $(SHAREDLIB).1; \ |
fi |
|
clean: |
rm -f *.o *~ example minigzip libz.a libz.so* foo.gz so_locations \ |
_match.s maketree |
|
distclean: clean |
|
zip: |
mv Makefile Makefile~; cp -p Makefile.in Makefile |
rm -f test.c ztest*.c contrib/minizip/test.zip |
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 contrib/minizip/test.zip |
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 |
/v2_0/src/infblock.h
0,0 → 1,39
/* infblock.h -- header to use infblock.c |
* Copyright (C) 1995-1998 Mark Adler |
* For conditions of distribution and use, see copyright notice in zlib.h |
*/ |
|
/* WARNING: this file should *not* be used by applications. It is |
part of the implementation of the compression library and is |
subject to change. Applications should only use zlib.h. |
*/ |
|
struct inflate_blocks_state; |
typedef struct inflate_blocks_state FAR inflate_blocks_statef; |
|
extern inflate_blocks_statef * inflate_blocks_new OF(( |
z_streamp z, |
check_func c, /* check function */ |
uInt w)); /* window size */ |
|
extern int inflate_blocks OF(( |
inflate_blocks_statef *, |
z_streamp , |
int)); /* initial return code */ |
|
extern void inflate_blocks_reset OF(( |
inflate_blocks_statef *, |
z_streamp , |
uLongf *)); /* check value on output */ |
|
extern int inflate_blocks_free OF(( |
inflate_blocks_statef *, |
z_streamp)); |
|
extern void inflate_set_dictionary OF(( |
inflate_blocks_statef *s, |
const Bytef *d, /* dictionary */ |
uInt n)); /* dictionary length */ |
|
extern int inflate_blocks_sync_point OF(( |
inflate_blocks_statef *s)); |
/v2_0/src/Makefile.riscos
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 |
/v2_0/src/inffast.h
0,0 → 1,17
/* inffast.h -- header to use inffast.c |
* Copyright (C) 1995-1998 Mark Adler |
* For conditions of distribution and use, see copyright notice in zlib.h |
*/ |
|
/* WARNING: this file should *not* be used by applications. It is |
part of the implementation of the compression library and is |
subject to change. Applications should only use zlib.h. |
*/ |
|
extern int inflate_fast OF(( |
uInt, |
uInt, |
inflate_huft *, |
inflate_huft *, |
inflate_blocks_statef *, |
z_streamp )); |
/v2_0/src/descrip.mms
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 |
/v2_0/src/README.eCos
0,0 → 1,17
Note that these are not the complete zlib sources - the following |
directories have been deleted since they are irrelevant for the |
eCos support: |
|
amiga/ |
contrib/ |
msdos/ |
nt/ |
os2/ |
|
See the main site http://www.info-zip.org/pub/infozip/zlib/ for |
places to download the complete sources. |
|
Additionally, local changes has been made to the remaining files. Code |
changes are marked by __ECOS__ (comments or definitions). Finally, the |
headers zlib.h and zconf.h have been moved out of the directory into |
../include. |
/v2_0/src/ChangeLog
0,0 → 1,471
|
ChangeLog file for zlib |
|
Changes in 1.1.3 (9 July 1998) |
- fix "an inflate input buffer bug that shows up on rare but persistent |
occasions" (Mark) |
- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) |
- fix gzseek(..., SEEK_SET) in write mode |
- fix crc check after a gzeek (Frank Faubert) |
- fix miniunzip when the last entry in a zip file is itself a zip file |
(J Lillge) |
- add contrib/asm586 and contrib/asm686 (Brian Raiter) |
See http://www.muppetlabs.com/~breadbox/software/assembly.html |
- add support for Delphi 3 in contrib/delphi (Bob Dellaca) |
- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) |
- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) |
- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) |
- added a FAQ file |
|
- Support gzdopen on Mac with Metrowerks (Jason Linhart) |
- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) |
- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) |
- avoid some warnings with Borland C (Tom Tanner) |
- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) |
- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant) |
- allow several arguments to configure (Tim Mooney, Frodo Looijaard) |
- use libdir and includedir in Makefile.in (Tim Mooney) |
- support shared libraries on OSF1 V4 (Tim Mooney) |
- remove so_locations in "make clean" (Tim Mooney) |
- fix maketree.c compilation error (Glenn, Mark) |
- Python interface to zlib now in Python 1.5 (Jeremy Hylton) |
- new Makefile.riscos (Rich Walker) |
- initialize static descriptors in trees.c for embedded targets (Nick Smith) |
- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) |
- add the OS/2 files in Makefile.in too (Andrew Zabolotny) |
- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) |
- fix maketree.c to allow clean compilation of inffixed.h (Mark) |
- fix parameter check in deflateCopy (Gunther Nikl) |
- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) |
- Many portability patches by Christian Spieler: |
. zutil.c, zutil.h: added "const" for zmem* |
. Make_vms.com: fixed some typos |
. Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists |
. msdos/Makefile.msc: remove "default rtl link library" info from obj files |
. msdos/Makefile.*: use model-dependent name for the built zlib library |
. msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: |
new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) |
- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) |
- replace __far with _far for better portability (Christian Spieler, Tom Lane) |
- fix test for errno.h in configure (Tim Newsham) |
|
Changes in 1.1.2 (19 March 98) |
- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) |
See http://www.winimage.com/zLibDll/unzip.html |
- preinitialize the inflate tables for fixed codes, to make the code |
completely thread safe (Mark) |
- some simplifications and slight speed-up to the inflate code (Mark) |
- fix gzeof on non-compressed files (Allan Schrum) |
- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) |
- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) |
- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) |
- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) |
- do not wrap extern "C" around system includes (Tom Lane) |
- mention zlib binding for TCL in README (Andreas Kupries) |
- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) |
- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) |
- allow "configure --prefix $HOME" (Tim Mooney) |
- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) |
- move Makefile.sas to amiga/Makefile.sas |
|
Changes in 1.1.1 (27 Feb 98) |
- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) |
- remove block truncation heuristic which had very marginal effect for zlib |
(smaller lit_bufsize than in gzip 1.2.4) and degraded a little the |
compression ratio on some files. This also allows inlining _tr_tally for |
matches in deflate_slow. |
- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) |
|
Changes in 1.1.0 (24 Feb 98) |
- do not return STREAM_END prematurely in inflate (John Bowler) |
- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) |
- compile with -DFASTEST to get compression code optimized for speed only |
- in minigzip, try mmap'ing the input file first (Miguel Albrecht) |
- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain |
on Sun but significant on HP) |
|
- add a pointer to experimental unzip library in README (Gilles Vollant) |
- initialize variable gcc in configure (Chris Herborth) |
|
Changes in 1.0.9 (17 Feb 1998) |
- added gzputs and gzgets functions |
- do not clear eof flag in gzseek (Mark Diekhans) |
- fix gzseek for files in transparent mode (Mark Diekhans) |
- do not assume that vsprintf returns the number of bytes written (Jens Krinke) |
- replace EXPORT with ZEXPORT to avoid conflict with other programs |
- added compress2 in zconf.h, zlib.def, zlib.dnt |
- new asm code from Gilles Vollant in contrib/asm386 |
- simplify the inflate code (Mark): |
. Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new() |
. ZALLOC the length list in inflate_trees_fixed() instead of using stack |
. ZALLOC the value area for huft_build() instead of using stack |
. Simplify Z_FINISH check in inflate() |
|
- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 |
- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) |
- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with |
the declaration of FAR (Gilles VOllant) |
- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) |
- read_buf buf parameter of type Bytef* instead of charf* |
- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) |
- do not redeclare unlink in minigzip.c for WIN32 (John Bowler) |
- fix check for presence of directories in "make install" (Ian Willis) |
|
Changes in 1.0.8 (27 Jan 1998) |
- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant) |
- fix gzgetc and gzputc for big endian systems (Markus Oberhumer) |
- added compress2() to allow setting the compression level |
- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) |
- use constant arrays for the static trees in trees.c instead of computing |
them at run time (thanks to Ken Raeburn for this suggestion). To create |
trees.h, compile with GEN_TREES_H and run "make test". |
- check return code of example in "make test" and display result |
- pass minigzip command line options to file_compress |
- simplifying code of inflateSync to avoid gcc 2.8 bug |
|
- support CC="gcc -Wall" in configure -s (QingLong) |
- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn) |
- fix test for shared library support to avoid compiler warnings |
- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant) |
- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit) |
- do not use fdopen for Metrowerks on Mac (Brad Pettit)) |
- add checks for gzputc and gzputc in example.c |
- avoid warnings in gzio.c and deflate.c (Andreas Kleinert) |
- use const for the CRC table (Ken Raeburn) |
- fixed "make uninstall" for shared libraries |
- use Tracev instead of Trace in infblock.c |
- in example.c use correct compressed length for test_sync |
- suppress +vnocompatwarnings in configure for HPUX (not always supported) |
|
Changes in 1.0.7 (20 Jan 1998) |
- fix gzseek which was broken in write mode |
- return error for gzseek to negative absolute position |
- fix configure for Linux (Chun-Chung Chen) |
- increase stack space for MSC (Tim Wegner) |
- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant) |
- define EXPORTVA for gzprintf (Gilles Vollant) |
- added man page zlib.3 (Rick Rodgers) |
- for contrib/untgz, fix makedir() and improve Makefile |
|
- check gzseek in write mode in example.c |
- allocate extra buffer for seeks only if gzseek is actually called |
- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant) |
- add inflateSyncPoint in zconf.h |
- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def |
|
Changes in 1.0.6 (19 Jan 1998) |
- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and |
gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) |
- Fix a deflate bug occuring only with compression level 0 (thanks to |
Andy Buckler for finding this one). |
- In minigzip, pass transparently also the first byte for .Z files. |
- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() |
- check Z_FINISH in inflate (thanks to Marc Schluper) |
- Implement deflateCopy (thanks to Adam Costello) |
- make static libraries by default in configure, add --shared option. |
- move MSDOS or Windows specific files to directory msdos |
- suppress the notion of partial flush to simplify the interface |
(but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) |
- suppress history buffer provided by application to simplify the interface |
(this feature was not implemented anyway in 1.0.4) |
- next_in and avail_in must be initialized before calling inflateInit or |
inflateInit2 |
- add EXPORT in all exported functions (for Windows DLL) |
- added Makefile.nt (thanks to Stephen Williams) |
- added the unsupported "contrib" directory: |
contrib/asm386/ by Gilles Vollant <info@winimage.com> |
386 asm code replacing longest_match(). |
contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu> |
A C++ I/O streams interface to the zlib gz* functions |
|
Another C++ I/O streams interface |
contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es> |
A very simple tar.gz file extractor using zlib |
contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl> |
How to use compress(), uncompress() and the gz* functions from VB. |
- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression |
level) in minigzip (thanks to Tom Lane) |
|
- use const for rommable constants in deflate |
- added test for gzseek and gztell in example.c |
- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) |
- add undocumented function zError to convert error code to string |
(for Tim Smithers) |
- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code. |
- Use default memcpy for Symantec MSDOS compiler. |
- Add EXPORT keyword for check_func (needed for Windows DLL) |
- add current directory to LD_LIBRARY_PATH for "make test" |
- create also a link for libz.so.1 |
- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) |
- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) |
- added -soname for Linux in configure (Chun-Chung Chen, |
- assign numbers to the exported functions in zlib.def (for Windows DLL) |
- add advice in zlib.h for best usage of deflateSetDictionary |
- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) |
- allow compilation with ANSI keywords only enabled for TurboC in large model |
- avoid "versionString"[0] (Borland bug) |
- add NEED_DUMMY_RETURN for Borland |
- use variable z_verbose for tracing in debug mode (L. Peter Deutsch). |
- allow compilation with CC |
- defined STDC for OS/2 (David Charlap) |
- limit external names to 8 chars for MVS (Thomas Lund) |
- in minigzip.c, use static buffers only for 16-bit systems |
- fix suffix check for "minigzip -d foo.gz" |
- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) |
- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) |
- added makelcc.bat for lcc-win32 (Tom St Denis) |
- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) |
- Avoid expanded $Id: ChangeLog,v 1.1.1.1 2004-02-14 13:35:39 phoenix Exp $. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. |
- check for unistd.h in configure (for off_t) |
- remove useless check parameter in inflate_blocks_free |
- avoid useless assignment of s->check to itself in inflate_blocks_new |
- do not flush twice in gzclose (thanks to Ken Raeburn) |
- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h |
- use NO_ERRNO_H instead of enumeration of operating systems with errno.h |
- work around buggy fclose on pipes for HP/UX |
- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson) |
- fix configure if CC is already equal to gcc |
|
Changes in 1.0.5 (3 Jan 98) |
- Fix inflate to terminate gracefully when fed corrupted or invalid data |
- Use const for rommable constants in inflate |
- Eliminate memory leaks on error conditions in inflate |
- Removed some vestigial code in inflate |
- Update web address in README |
|
Changes in 1.0.4 (24 Jul 96) |
- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF |
bit, so the decompressor could decompress all the correct data but went |
on to attempt decompressing extra garbage data. This affected minigzip too. |
- zlibVersion and gzerror return const char* (needed for DLL) |
- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) |
- use z_error only for DEBUG (avoid problem with DLLs) |
|
Changes in 1.0.3 (2 Jul 96) |
- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS |
small and medium models; this makes the library incompatible with previous |
versions for these models. (No effect in large model or on other systems.) |
- return OK instead of BUF_ERROR if previous deflate call returned with |
avail_out as zero but there is nothing to do |
- added memcmp for non STDC compilers |
- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) |
- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) |
- better check for 16-bit mode MSC (avoids problem with Symantec) |
|
Changes in 1.0.2 (23 May 96) |
- added Windows DLL support |
- added a function zlibVersion (for the DLL support) |
- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) |
- Bytef is define's instead of typedef'd only for Borland C |
- avoid reading uninitialized memory in example.c |
- mention in README that the zlib format is now RFC1950 |
- updated Makefile.dj2 |
- added algorithm.doc |
|
Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] |
- fix array overlay in deflate.c which sometimes caused bad compressed data |
- fix inflate bug with empty stored block |
- fix MSDOS medium model which was broken in 0.99 |
- fix deflateParams() which could generated bad compressed data. |
- Bytef is define'd instead of typedef'ed (work around Borland bug) |
- added an INDEX file |
- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), |
Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) |
- speed up adler32 for modern machines without auto-increment |
- added -ansi for IRIX in configure |
- static_init_done in trees.c is an int |
- define unlink as delete for VMS |
- fix configure for QNX |
- add configure branch for SCO and HPUX |
- avoid many warnings (unused variables, dead assignments, etc...) |
- no fdopen for BeOS |
- fix the Watcom fix for 32 bit mode (define FAR as empty) |
- removed redefinition of Byte for MKWERKS |
- work around an MWKERKS bug (incorrect merge of all .h files) |
|
Changes in 0.99 (27 Jan 96) |
- allow preset dictionary shared between compressor and decompressor |
- allow compression level 0 (no compression) |
- add deflateParams in zlib.h: allow dynamic change of compression level |
and compression strategy. |
- test large buffers and deflateParams in example.c |
- add optional "configure" to build zlib as a shared library |
- suppress Makefile.qnx, use configure instead |
- fixed deflate for 64-bit systems (detected on Cray) |
- fixed inflate_blocks for 64-bit systems (detected on Alpha) |
- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) |
- always return Z_BUF_ERROR when deflate() has nothing to do |
- deflateInit and inflateInit are now macros to allow version checking |
- prefix all global functions and types with z_ with -DZ_PREFIX |
- make falloc completely reentrant (inftrees.c) |
- fixed very unlikely race condition in ct_static_init |
- free in reverse order of allocation to help memory manager |
- use zlib-1.0/* instead of zlib/* inside the tar.gz |
- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith |
-Wconversion -Wstrict-prototypes -Wmissing-prototypes" |
- allow gzread on concatenated .gz files |
- deflateEnd now returns Z_DATA_ERROR if it was premature |
- deflate is finally (?) fully deterministic (no matches beyond end of input) |
- Document Z_SYNC_FLUSH |
- add uninstall in Makefile |
- Check for __cpluplus in zlib.h |
- Better test in ct_align for partial flush |
- avoid harmless warnings for Borland C++ |
- initialize hash_head in deflate.c |
- avoid warning on fdopen (gzio.c) for HP cc -Aa |
- include stdlib.h for STDC compilers |
- include errno.h for Cray |
- ignore error if ranlib doesn't exist |
- call ranlib twice for NeXTSTEP |
- use exec_prefix instead of prefix for libz.a |
- renamed ct_* as _tr_* to avoid conflict with applications |
- clear z->msg in inflateInit2 before any error return |
- initialize opaque in example.c, gzio.c, deflate.c and inflate.c |
- fixed typo in zconf.h (_GNUC__ => __GNUC__) |
- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) |
- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) |
- in fcalloc, normalize pointer if size > 65520 bytes |
- don't use special fcalloc for 32 bit Borland C++ |
- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... |
- use Z_BINARY instead of BINARY |
- document that gzclose after gzdopen will close the file |
- allow "a" as mode in gzopen. |
- fix error checking in gzread |
- allow skipping .gz extra-field on pipes |
- added reference to Perl interface in README |
- put the crc table in FAR data (I dislike more and more the medium model :) |
- added get_crc_table |
- added a dimension to all arrays (Borland C can't count). |
- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast |
- guard against multiple inclusion of *.h (for precompiled header on Mac) |
- Watcom C pretends to be Microsoft C small model even in 32 bit mode. |
- don't use unsized arrays to avoid silly warnings by Visual C++: |
warning C4746: 'inflate_mask' : unsized array treated as '__far' |
(what's wrong with far data in far model?). |
- define enum out of inflate_blocks_state to allow compilation with C++ |
|
Changes in 0.95 (16 Aug 95) |
- fix MSDOS small and medium model (now easier to adapt to any compiler) |
- inlined send_bits |
- fix the final (:-) bug for deflate with flush (output was correct but |
not completely flushed in rare occasions). |
- default window size is same for compression and decompression |
(it's now sufficient to set MAX_WBITS in zconf.h). |
- voidp -> voidpf and voidnp -> voidp (for consistency with other |
typedefs and because voidnp was not near in large model). |
|
Changes in 0.94 (13 Aug 95) |
- support MSDOS medium model |
- fix deflate with flush (could sometimes generate bad output) |
- fix deflateReset (zlib header was incorrectly suppressed) |
- added support for VMS |
- allow a compression level in gzopen() |
- gzflush now calls fflush |
- For deflate with flush, flush even if no more input is provided. |
- rename libgz.a as libz.a |
- avoid complex expression in infcodes.c triggering Turbo C bug |
- work around a problem with gcc on Alpha (in INSERT_STRING) |
- don't use inline functions (problem with some gcc versions) |
- allow renaming of Byte, uInt, etc... with #define. |
- avoid warning about (unused) pointer before start of array in deflate.c |
- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c |
- avoid reserved word 'new' in trees.c |
|
Changes in 0.93 (25 June 95) |
- temporarily disable inline functions |
- make deflate deterministic |
- give enough lookahead for PARTIAL_FLUSH |
- Set binary mode for stdin/stdout in minigzip.c for OS/2 |
- don't even use signed char in inflate (not portable enough) |
- fix inflate memory leak for segmented architectures |
|
Changes in 0.92 (3 May 95) |
- don't assume that char is signed (problem on SGI) |
- Clear bit buffer when starting a stored block |
- no memcpy on Pyramid |
- suppressed inftest.c |
- optimized fill_window, put longest_match inline for gcc |
- optimized inflate on stored blocks. |
- untabify all sources to simplify patches |
|
Changes in 0.91 (2 May 95) |
- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h |
- Document the memory requirements in zconf.h |
- added "make install" |
- fix sync search logic in inflateSync |
- deflate(Z_FULL_FLUSH) now works even if output buffer too short |
- after inflateSync, don't scare people with just "lo world" |
- added support for DJGPP |
|
Changes in 0.9 (1 May 95) |
- don't assume that zalloc clears the allocated memory (the TurboC bug |
was Mark's bug after all :) |
- let again gzread copy uncompressed data unchanged (was working in 0.71) |
- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented |
- added a test of inflateSync in example.c |
- moved MAX_WBITS to zconf.h because users might want to change that. |
- document explicitly that zalloc(64K) on MSDOS must return a normalized |
pointer (zero offset) |
- added Makefiles for Microsoft C, Turbo C, Borland C++ |
- faster crc32() |
|
Changes in 0.8 (29 April 95) |
- added fast inflate (inffast.c) |
- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this |
is incompatible with previous versions of zlib which returned Z_OK. |
- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) |
(actually that was not a compiler bug, see 0.81 above) |
- gzread no longer reads one extra byte in certain cases |
- In gzio destroy(), don't reference a freed structure |
- avoid many warnings for MSDOS |
- avoid the ERROR symbol which is used by MS Windows |
|
Changes in 0.71 (14 April 95) |
- Fixed more MSDOS compilation problems :( There is still a bug with |
TurboC large model. |
|
Changes in 0.7 (14 April 95) |
- Added full inflate support. |
- Simplified the crc32() interface. The pre- and post-conditioning |
(one's complement) is now done inside crc32(). WARNING: this is |
incompatible with previous versions; see zlib.h for the new usage. |
|
Changes in 0.61 (12 April 95) |
- workaround for a bug in TurboC. example and minigzip now work on MSDOS. |
|
Changes in 0.6 (11 April 95) |
- added minigzip.c |
- added gzdopen to reopen a file descriptor as gzFile |
- added transparent reading of non-gziped files in gzread. |
- fixed bug in gzread (don't read crc as data) |
- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose). |
- don't allocate big arrays in the stack (for MSDOS) |
- fix some MSDOS compilation problems |
|
Changes in 0.5: |
- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but |
not yet Z_FULL_FLUSH. |
- support decompression but only in a single step (forced Z_FINISH) |
- added opaque object for zalloc and zfree. |
- added deflateReset and inflateReset |
- added a variable zlib_version for consistency checking. |
- renamed the 'filter' parameter of deflateInit2 as 'strategy'. |
Added Z_FILTERED and Z_HUFFMAN_ONLY constants. |
|
Changes in 0.4: |
- avoid "zip" everywhere, use zlib instead of ziplib. |
- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush |
if compression method == 8. |
- added adler32 and crc32 |
- renamed deflateOptions as deflateInit2, call one or the other but not both |
- added the method parameter for deflateInit2. |
- added inflateInit2 |
- simplied considerably deflateInit and inflateInit by not supporting |
user-provided history buffer. This is supported only in deflateInit2 |
and inflateInit2. |
|
Changes in 0.3: |
- prefix all macro names with Z_ |
- use Z_FINISH instead of deflateEnd to finish compression. |
- added Z_HUFFMAN_ONLY |
- added gzerror() |
/v2_0/src/README
0,0 → 1,148
zlib 1.1.3 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 |
ftp://ds.internic.net/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate |
format) and rfc1952.txt (gzip format). These documents are also available in |
other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html |
|
All functions of the compression library are documented in the file zlib.h |
(volunteer to write man pages welcome, contact jloup@gzip.org). A usage |
example of the library is given in the file example.c which also tests that |
the library is working correctly. Another example is given in the file |
minigzip.c. The compression library itself is composed of all source files |
except example.c and minigzip.c. |
|
To compile all files and run the test program, follow the instructions |
given at the top of Makefile. In short "make test; make install" |
should work for most machines. For Unix: "configure; make test; make install" |
For MSDOS, use one of the special makefiles such as Makefile.msc. |
For VMS, use Make_vms.com or descrip.mms. |
|
Questions about zlib should be sent to <zlib@quest.jpl.nasa.gov>, or to |
Gilles Vollant <info@winimage.com> for the Windows DLL version. |
The zlib home page is http://www.cdrom.com/pub/infozip/zlib/ |
The official zlib ftp site is ftp://ftp.cdrom.com/pub/infozip/zlib/ |
Before reporting a problem, please check those sites to verify that |
you have the latest version of zlib; otherwise get the latest version and |
check whether the problem still exists or not. |
|
Mark Nelson <markn@tiny.com> wrote an article about zlib for the Jan. 1997 |
issue of Dr. Dobb's Journal; a copy of the article is available in |
http://web2.airmail.net/markn/articles/zlibtool/zlibtool.htm |
|
The changes made in version 1.1.3 are documented in the file ChangeLog. |
The main changes since 1.1.2 are: |
|
- fix "an inflate input buffer bug that shows up on rare but persistent |
occasions" (Mark) |
- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) |
- fix gzseek(..., SEEK_SET) in write mode |
- fix crc check after a gzeek (Frank Faubert) |
- fix miniunzip when the last entry in a zip file is itself a zip file |
(J Lillge) |
- add contrib/asm586 and contrib/asm686 (Brian Raiter) |
See http://www.muppetlabs.com/~breadbox/software/assembly.html |
- add support for Delphi 3 in contrib/delphi (Bob Dellaca) |
- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) |
- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) |
- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) |
- added a FAQ file |
|
plus many changes for portability. |
|
Unsupported third party contributions are provided in directory "contrib". |
|
A Java implementation of zlib is available in the Java Development Kit 1.1 |
http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html |
See the zlib home page http://www.cdrom.com/pub/infozip/zlib/ for details. |
|
A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk> |
is in the CPAN (Comprehensive Perl Archive Network) sites, such as: |
ftp://ftp.cis.ufl.edu/pub/perl/CPAN/modules/by-module/Compress/Compress-Zlib* |
|
A Python interface to zlib written by A.M. Kuchling <amk@magnet.com> |
is available in Python 1.5 and later versions, see |
http://www.python.org/doc/lib/module-zlib.html |
|
A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com> |
is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html |
|
An experimental package to read and write files in .zip format, |
written on top of zlib by Gilles Vollant <info@winimage.com>, is |
available at http://www.winimage.com/zLibDll/unzip.html |
and also in the contrib/minizip directory of zlib. |
|
|
Notes for some targets: |
|
- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc |
and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL |
The zlib DLL support was initially done by Alessandro Iacopetti and is |
now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL |
home page at http://www.winimage.com/zLibDll |
|
From Visual Basic, you can call the DLL functions which do not take |
a structure as argument: compress, uncompress and all gz* functions. |
See contrib/visual-basic.txt for more information, or get |
http://www.tcfb.com/dowseware/cmp-z-it.zip |
|
- For 64-bit Irix, deflate.c must be compiled without any optimization. |
With -O, one libpng test fails. The test works in 32 bit mode (with |
the -n32 compiler flag). The compiler bug has been reported to SGI. |
|
- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 |
it works when compiled with cc. |
|
- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 |
is necessary to get gzprintf working correctly. This is done by configure. |
|
- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works |
with other compilers. Use "make test" to check your compiler. |
|
- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers. |
|
- For Turbo C the small model is supported only with reduced performance to |
avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 |
|
- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html |
Per Harald Myrvang <perm@stud.cs.uit.no> |
|
|
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-1998 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. |
/v2_0/src/inftrees.c
0,0 → 1,455
/* inftrees.c -- generate Huffman trees for efficient decoding |
* Copyright (C) 1995-1998 Mark Adler |
* For conditions of distribution and use, see copyright notice in zlib.h |
*/ |
|
#include "zutil.h" |
#include "inftrees.h" |
|
#if !defined(BUILDFIXED) && !defined(STDC) |
# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */ |
#endif |
|
const char inflate_copyright[] = |
" inflate 1.1.3 Copyright 1995-1998 Mark Adler "; |
/* |
If you use the zlib library in a product, an acknowledgment is welcome |
in the documentation of your product. If for some reason you cannot |
include such an acknowledgment, I would appreciate that you keep this |
copyright string in the executable of your product. |
*/ |
struct internal_state {int dummy;}; /* for buggy compilers */ |
|
/* simplify the use of the inflate_huft type with some defines */ |
#define exop word.what.Exop |
#define bits word.what.Bits |
|
|
local int huft_build OF(( |
uIntf *, /* code lengths in bits */ |
uInt, /* number of codes */ |
uInt, /* number of "simple" codes */ |
const uIntf *, /* list of base values for non-simple codes */ |
const uIntf *, /* list of extra bits for non-simple codes */ |
inflate_huft * FAR*,/* result: starting table */ |
uIntf *, /* maximum lookup bits (returns actual) */ |
inflate_huft *, /* space for trees */ |
uInt *, /* hufts used in space */ |
uIntf * )); /* space for values */ |
|
/* Tables for deflate from PKZIP's appnote.txt. */ |
local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ |
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, |
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; |
/* see note #13 above about 258 */ |
local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ |
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, |
3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */ |
local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ |
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, |
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, |
8193, 12289, 16385, 24577}; |
local const uInt cpdext[30] = { /* Extra bits for distance codes */ |
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, |
7, 7, 8, 8, 9, 9, 10, 10, 11, 11, |
12, 12, 13, 13}; |
|
/* |
Huffman code decoding is performed using a multi-level table lookup. |
The fastest way to decode is to simply build a lookup table whose |
size is determined by the longest code. However, the time it takes |
to build this table can also be a factor if the data being decoded |
is not very long. The most common codes are necessarily the |
shortest codes, so those codes dominate the decoding time, and hence |
the speed. The idea is you can have a shorter table that decodes the |
shorter, more probable codes, and then point to subsidiary tables for |
the longer codes. The time it costs to decode the longer codes is |
then traded against the time it takes to make longer tables. |
|
This results of this trade are in the variables lbits and dbits |
below. lbits is the number of bits the first level table for literal/ |
length codes can decode in one step, and dbits is the same thing for |
the distance codes. Subsequent tables are also less than or equal to |
those sizes. These values may be adjusted either when all of the |
codes are shorter than that, in which case the longest code length in |
bits is used, or when the shortest code is *longer* than the requested |
table size, in which case the length of the shortest code in bits is |
used. |
|
There are two different values for the two tables, since they code a |
different number of possibilities each. The literal/length table |
codes 286 possible values, or in a flat code, a little over eight |
bits. The distance table codes 30 possible values, or a little less |
than five bits, flat. The optimum values for speed end up being |
about one bit more than those, so lbits is 8+1 and dbits is 5+1. |
The optimum values may differ though from machine to machine, and |
possibly even between compilers. Your mileage may vary. |
*/ |
|
|
/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ |
#define BMAX 15 /* maximum bit length of any code */ |
|
local int huft_build(b, n, s, d, e, t, m, hp, hn, v) |
uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ |
uInt n; /* number of codes (assumed <= 288) */ |
uInt s; /* number of simple-valued codes (0..s-1) */ |
const uIntf *d; /* list of base values for non-simple codes */ |
const uIntf *e; /* list of extra bits for non-simple codes */ |
inflate_huft * FAR *t; /* result: starting table */ |
uIntf *m; /* maximum lookup bits, returns actual */ |
inflate_huft *hp; /* space for trees */ |
uInt *hn; /* hufts used in space */ |
uIntf *v; /* working area: values in order of bit length */ |
/* Given a list of code lengths and a maximum table size, make a set of |
tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR |
if the given code set is incomplete (the tables are still built in this |
case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of |
lengths), or Z_MEM_ERROR if not enough memory. */ |
{ |
|
uInt a; /* counter for codes of length k */ |
uInt c[BMAX+1]; /* bit length count table */ |
uInt f; /* i repeats in table every f entries */ |
int g; /* maximum code length */ |
int h; /* table level */ |
register uInt i; /* counter, current code */ |
register uInt j; /* counter */ |
register int k; /* number of bits in current code */ |
int l; /* bits per table (returned in m) */ |
uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */ |
register uIntf *p; /* pointer into c[], b[], or v[] */ |
inflate_huft *q; /* points to current table */ |
struct inflate_huft_s r; /* table entry for structure assignment */ |
inflate_huft *u[BMAX]; /* table stack */ |
register int w; /* bits before this table == (l * h) */ |
uInt x[BMAX+1]; /* bit offsets, then code stack */ |
uIntf *xp; /* pointer into x */ |
int y; /* number of dummy codes added */ |
uInt z; /* number of entries in current table */ |
|
|
/* Generate counts for each bit length */ |
p = c; |
#define C0 *p++ = 0; |
#define C2 C0 C0 C0 C0 |
#define C4 C2 C2 C2 C2 |
C4 /* clear c[]--assume BMAX+1 is 16 */ |
p = b; i = n; |
do { |
c[*p++]++; /* assume all entries <= BMAX */ |
} while (--i); |
if (c[0] == n) /* null input--all zero length codes */ |
{ |
*t = (inflate_huft *)Z_NULL; |
*m = 0; |
return Z_OK; |
} |
|
|
/* Find minimum and maximum length, bound *m by those */ |
l = *m; |
for (j = 1; j <= BMAX; j++) |
if (c[j]) |
break; |
k = j; /* minimum code length */ |
if ((uInt)l < j) |
l = j; |
for (i = BMAX; i; i--) |
if (c[i]) |
break; |
g = i; /* maximum code length */ |
if ((uInt)l > i) |
l = i; |
*m = l; |
|
|
/* Adjust last length count to fill out codes, if needed */ |
for (y = 1 << j; j < i; j++, y <<= 1) |
if ((y -= c[j]) < 0) |
return Z_DATA_ERROR; |
if ((y -= c[i]) < 0) |
return Z_DATA_ERROR; |
c[i] += y; |
|
|
/* Generate starting offsets into the value table for each length */ |
x[1] = j = 0; |
p = c + 1; xp = x + 2; |
while (--i) { /* note that i == g from above */ |
*xp++ = (j += *p++); |
} |
|
|
/* Make a table of values in order of bit lengths */ |
p = b; i = 0; |
do { |
if ((j = *p++) != 0) |
v[x[j]++] = i; |
} while (++i < n); |
n = x[g]; /* set n to length of v */ |
|
|
/* Generate the Huffman codes and for each, make the table entries */ |
x[0] = i = 0; /* first Huffman code is zero */ |
p = v; /* grab values in bit order */ |
h = -1; /* no tables yet--level -1 */ |
w = -l; /* bits decoded == (l * h) */ |
u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ |
q = (inflate_huft *)Z_NULL; /* ditto */ |
z = 0; /* ditto */ |
|
/* go through the bit lengths (k already is bits in shortest code) */ |
for (; k <= g; k++) |
{ |
a = c[k]; |
while (a--) |
{ |
/* here i is the Huffman code of length k bits for value *p */ |
/* make tables up to required level */ |
while (k > w + l) |
{ |
h++; |
w += l; /* previous table always l bits */ |
|
/* compute minimum size table less than or equal to l bits */ |
z = g - w; |
z = z > (uInt)l ? l : z; /* table size upper limit */ |
if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ |
{ /* too few codes for k-w bit table */ |
f -= a + 1; /* deduct codes from patterns left */ |
xp = c + k; |
if (j < z) |
while (++j < z) /* try smaller tables up to z bits */ |
{ |
if ((f <<= 1) <= *++xp) |
break; /* enough codes to use up j bits */ |
f -= *xp; /* else deduct codes from patterns */ |
} |
} |
z = 1 << j; /* table entries for j-bit table */ |
|
/* allocate new table */ |
if (*hn + z > MANY) /* (note: doesn't matter for fixed) */ |
return Z_MEM_ERROR; /* not enough memory */ |
u[h] = q = hp + *hn; |
*hn += z; |
|
/* connect to last table, if there is one */ |
if (h) |
{ |
x[h] = i; /* save pattern for backing up */ |
r.bits = (Byte)l; /* bits to dump before this table */ |
r.exop = (Byte)j; /* bits in this table */ |
j = i >> (w - l); |
r.base = (uInt)(q - u[h-1] - j); /* offset to this table */ |
u[h-1][j] = r; /* connect to last table */ |
} |
else |
*t = q; /* first table is returned result */ |
} |
|
/* set up table entry in r */ |
r.bits = (Byte)(k - w); |
if (p >= v + n) |
r.exop = 128 + 64; /* out of values--invalid code */ |
else if (*p < s) |
{ |
r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ |
r.base = *p++; /* simple code is just the value */ |
} |
else |
{ |
r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ |
r.base = d[*p++ - s]; |
} |
|
/* fill code-like entries with r */ |
f = 1 << (k - w); |
for (j = i >> w; j < z; j += f) |
q[j] = r; |
|
/* backwards increment the k-bit code i */ |
for (j = 1 << (k - 1); i & j; j >>= 1) |
i ^= j; |
i ^= j; |
|
/* backup over finished tables */ |
mask = (1 << w) - 1; /* needed on HP, cc -O bug */ |
while ((i & mask) != x[h]) |
{ |
h--; /* don't need to update q */ |
w -= l; |
mask = (1 << w) - 1; |
} |
} |
} |
|
|
/* Return Z_BUF_ERROR if we were given an incomplete table */ |
return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; |
} |
|
|
int inflate_trees_bits(c, bb, tb, hp, z) |
uIntf *c; /* 19 code lengths */ |
uIntf *bb; /* bits tree desired/actual depth */ |
inflate_huft * FAR *tb; /* bits tree result */ |
inflate_huft *hp; /* space for trees */ |
z_streamp z; /* for messages */ |
{ |
int r; |
uInt hn = 0; /* hufts used in space */ |
uIntf *v; /* work area for huft_build */ |
|
if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL) |
return Z_MEM_ERROR; |
r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, |
tb, bb, hp, &hn, v); |
if (r == Z_DATA_ERROR) |
z->msg = (char*)"oversubscribed dynamic bit lengths tree"; |
else if (r == Z_BUF_ERROR || *bb == 0) |
{ |
z->msg = (char*)"incomplete dynamic bit lengths tree"; |
r = Z_DATA_ERROR; |
} |
ZFREE(z, v); |
return r; |
} |
|
|
int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z) |
uInt nl; /* number of literal/length codes */ |
uInt nd; /* number of distance codes */ |
uIntf *c; /* that many (total) code lengths */ |
uIntf *bl; /* literal desired/actual bit depth */ |
uIntf *bd; /* distance desired/actual bit depth */ |
inflate_huft * FAR *tl; /* literal/length tree result */ |
inflate_huft * FAR *td; /* distance tree result */ |
inflate_huft *hp; /* space for trees */ |
z_streamp z; /* for messages */ |
{ |
int r; |
uInt hn = 0; /* hufts used in space */ |
uIntf *v; /* work area for huft_build */ |
|
/* allocate work area */ |
if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) |
return Z_MEM_ERROR; |
|
/* build literal/length tree */ |
r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v); |
if (r != Z_OK || *bl == 0) |
{ |
if (r == Z_DATA_ERROR) |
z->msg = (char*)"oversubscribed literal/length tree"; |
else if (r != Z_MEM_ERROR) |
{ |
z->msg = (char*)"incomplete literal/length tree"; |
r = Z_DATA_ERROR; |
} |
ZFREE(z, v); |
return r; |
} |
|
/* build distance tree */ |
r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v); |
if (r != Z_OK || (*bd == 0 && nl > 257)) |
{ |
if (r == Z_DATA_ERROR) |
z->msg = (char*)"oversubscribed distance tree"; |
else if (r == Z_BUF_ERROR) { |
#ifdef PKZIP_BUG_WORKAROUND |
r = Z_OK; |
} |
#else |
z->msg = (char*)"incomplete distance tree"; |
r = Z_DATA_ERROR; |
} |
else if (r != Z_MEM_ERROR) |
{ |
z->msg = (char*)"empty distance tree with lengths"; |
r = Z_DATA_ERROR; |
} |
ZFREE(z, v); |
return r; |
#endif |
} |
|
/* done */ |
ZFREE(z, v); |
return Z_OK; |
} |
|
|
/* build fixed tables only once--keep them here */ |
#ifdef BUILDFIXED |
local int fixed_built = 0; |
#define FIXEDH 544 /* number of hufts used by fixed tables */ |
local inflate_huft fixed_mem[FIXEDH]; |
local uInt fixed_bl; |
local uInt fixed_bd; |
local inflate_huft *fixed_tl; |
local inflate_huft *fixed_td; |
#else |
#include "inffixed.h" |
#endif |
|
|
int inflate_trees_fixed(bl, bd, tl, td, z) |
uIntf *bl; /* literal desired/actual bit depth */ |
uIntf *bd; /* distance desired/actual bit depth */ |
inflate_huft * FAR *tl; /* literal/length tree result */ |
inflate_huft * FAR *td; /* distance tree result */ |
z_streamp z; /* for memory allocation */ |
{ |
#ifdef BUILDFIXED |
/* build fixed tables if not already */ |
if (!fixed_built) |
{ |
int k; /* temporary variable */ |
uInt f = 0; /* number of hufts used in fixed_mem */ |
uIntf *c; /* length list for huft_build */ |
uIntf *v; /* work area for huft_build */ |
|
/* allocate memory */ |
if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) |
return Z_MEM_ERROR; |
if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) |
{ |
ZFREE(z, c); |
return Z_MEM_ERROR; |
} |
|
/* literal table */ |
for (k = 0; k < 144; k++) |
c[k] = 8; |
for (; k < 256; k++) |
c[k] = 9; |
for (; k < 280; k++) |
c[k] = 7; |
for (; k < 288; k++) |
c[k] = 8; |
fixed_bl = 9; |
huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, |
fixed_mem, &f, v); |
|
/* distance table */ |
for (k = 0; k < 30; k++) |
c[k] = 5; |
fixed_bd = 5; |
huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, |
fixed_mem, &f, v); |
|
/* done */ |
ZFREE(z, v); |
ZFREE(z, c); |
fixed_built = 1; |
} |
#endif |
*bl = fixed_bl; |
*bd = fixed_bd; |
*tl = fixed_tl; |
*td = fixed_td; |
return Z_OK; |
} |
/v2_0/src/zlib.3
0,0 → 1,107
.TH ZLIB 3 "9 July 1998" |
.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. |
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 will be added later and will have the same stream interface. |
.LP |
Compression can be done in a single step if the buffers are large enough |
(for example if an input file is mmap'ed), |
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 |
.I gzip |
(.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 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 |
the files |
.I example.c |
and |
.IR minigzip.c . |
.LP |
A Java implementation of |
.IR zlib |
is available in the Java Development Kit 1.1 |
.IP |
http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html |
.LP |
A Perl interface to |
.IR zlib , |
written by Paul Marquess (pmarquess@bfsec.bt.co.uk) |
is available at CPAN (Comprehensive Perl Archive Network) sites, |
such as: |
.IP |
ftp://ftp.cis.ufl.edu/pub/perl/CPAN/modules/by-module/Compress/Compress-Zlib* |
.LP |
A Python interface to |
.IR zlib |
written by A.M. Kuchling <amk@magnet.com> |
is available from the Python Software Association sites, such as: |
.IP |
ftp://ftp.python.org/pub/python/contrib/Encoding/zlib*.tar.gz |
.SH "SEE ALSO" |
Questions about zlib should be sent to: |
.IP |
zlib@quest.jpl.nasa.gov |
or, if this fails, to the author addresses given below. |
The zlib home page is: |
.IP |
http://www.cdrom.com/pub/infozip/zlib/ |
.LP |
The data format used by the zlib library is described by RFC |
(Request for Comments) 1950 to 1952 in the files: |
.IP |
ftp://ds.internic.net/rfc/rfc1950.txt (zlib format) |
.br |
rfc1951.txt (deflate format) |
.br |
rfc1952.txt (gzip format) |
.LP |
These documents are also available in other formats from: |
.IP |
ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html |
.SH AUTHORS |
Version 1.1.3 |
Copyright (C) 1995-1998 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 |
/v2_0/src/inflate.c
0,0 → 1,547
/* inflate.c -- zlib interface to inflate modules |
* Copyright (C) 1995-1998 Mark Adler |
* For conditions of distribution and use, see copyright notice in zlib.h |
*/ |
|
#include "zutil.h" |
#include "infblock.h" |
|
struct inflate_blocks_state {int dummy;}; /* for buggy compilers */ |
|
typedef enum { |
METHOD, /* waiting for method byte */ |
#ifdef __ECOS__ |
GZ_HDR2, |
GZ_METHOD, |
GZ_FLAG, |
GZ_TIME, |
GZ_EXTRA, |
GZ_EXTRA_HI, |
GZ_EXTRA_ZAP, |
GZ_NAME, |
GZ_COMMENT, |
GZ_HEAD_CRC_LO, |
GZ_HEAD_CRC_HI, |
GZ_DONE, |
#endif // __ECOS__ |
FLAG, /* waiting for flag byte */ |
DICT4, /* four dictionary check bytes to go */ |
DICT3, /* three dictionary check bytes to go */ |
DICT2, /* two dictionary check bytes to go */ |
DICT1, /* one dictionary check byte to go */ |
DICT0, /* waiting for inflateSetDictionary */ |
BLOCKS, /* decompressing blocks */ |
CHECK4, /* four check bytes to go */ |
CHECK3, /* three check bytes to go */ |
CHECK2, /* two check bytes to go */ |
CHECK1, /* one check byte to go */ |
DONE, /* finished check, done */ |
BAD} /* got an error--stay here */ |
inflate_mode; |
|
/* inflate private state */ |
struct internal_state { |
|
/* mode */ |
inflate_mode mode; /* current inflate mode */ |
#ifdef __ECOS__ |
inflate_mode gz_mode; |
uInt gz_flag; |
int gz_cnt; |
unsigned char* gz_start; |
uLong gz_sum; |
#endif |
|
/* mode dependent information */ |
union { |
uInt method; /* if FLAGS, method byte */ |
struct { |
uLong was; /* computed check value */ |
uLong need; /* stream check value */ |
} check; /* if CHECK, check values to compare */ |
uInt marker; /* if BAD, inflateSync's marker bytes count */ |
} sub; /* submode */ |
|
/* mode independent information */ |
int nowrap; /* flag for no wrapper */ |
uInt wbits; /* log2(window size) (8..15, defaults to 15) */ |
inflate_blocks_statef |
*blocks; /* current inflate_blocks state */ |
|
}; |
|
#ifdef __ECOS__ |
/* gzip flag byte */ |
#define _GZ_ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ |
#define _GZ_HEAD_CRC 0x02 /* bit 1 set: header CRC present */ |
#define _GZ_EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ |
#define _GZ_ORIG_NAME 0x08 /* bit 3 set: original file name present */ |
#define _GZ_COMMENT 0x10 /* bit 4 set: file comment present */ |
#define _GZ_RESERVED 0xE0 /* bits 5..7: reserved */ |
#endif // __ECOS__ |
|
|
int ZEXPORT inflateReset(z) |
z_streamp z; |
{ |
if (z == Z_NULL || z->state == Z_NULL) |
return Z_STREAM_ERROR; |
z->total_in = z->total_out = 0; |
z->msg = Z_NULL; |
z->state->mode = z->state->nowrap ? BLOCKS : METHOD; |
inflate_blocks_reset(z->state->blocks, z, Z_NULL); |
Tracev((stderr, "inflate: reset\n")); |
return Z_OK; |
} |
|
|
int ZEXPORT inflateEnd(z) |
z_streamp z; |
{ |
if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) |
return Z_STREAM_ERROR; |
if (z->state->blocks != Z_NULL) |
inflate_blocks_free(z->state->blocks, z); |
ZFREE(z, z->state); |
z->state = Z_NULL; |
Tracev((stderr, "inflate: end\n")); |
return Z_OK; |
} |
|
|
int ZEXPORT inflateInit2_(z, w, version, stream_size) |
z_streamp z; |
int w; |
const char *version; |
int stream_size; |
{ |
if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || |
stream_size != sizeof(z_stream)) |
return Z_VERSION_ERROR; |
|
/* initialize state */ |
if (z == Z_NULL) |
return Z_STREAM_ERROR; |
z->msg = Z_NULL; |
if (z->zalloc == Z_NULL) |
{ |
z->zalloc = zcalloc; |
z->opaque = (voidpf)0; |
} |
if (z->zfree == Z_NULL) z->zfree = zcfree; |
if ((z->state = (struct internal_state FAR *) |
ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) |
return Z_MEM_ERROR; |
z->state->blocks = Z_NULL; |
|
/* handle undocumented nowrap option (no zlib header or check) */ |
z->state->nowrap = 0; |
if (w < 0) |
{ |
w = - w; |
z->state->nowrap = 1; |
} |
|
/* set window size */ |
if (w < 8 || w > 15) |
{ |
inflateEnd(z); |
return Z_STREAM_ERROR; |
} |
z->state->wbits = (uInt)w; |
|
/* create inflate_blocks state */ |
if ((z->state->blocks = |
inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) |
== Z_NULL) |
{ |
inflateEnd(z); |
return Z_MEM_ERROR; |
} |
Tracev((stderr, "inflate: allocated\n")); |
|
/* reset state */ |
inflateReset(z); |
return Z_OK; |
} |
|
|
int ZEXPORT inflateInit_(z, version, stream_size) |
z_streamp z; |
const char *version; |
int stream_size; |
{ |
return inflateInit2_(z, DEF_WBITS, version, stream_size); |
} |
|
|
#define NEEDBYTE {if(z->avail_in==0)return r;r=f;} |
#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) |
|
int ZEXPORT inflate(z, f) |
z_streamp z; |
int f; |
{ |
int r; |
uInt b; |
|
if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL) |
return Z_STREAM_ERROR; |
f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; |
r = Z_BUF_ERROR; |
while (1) switch (z->state->mode) |
{ |
case METHOD: |
#ifdef __ECOS__ |
// "Clear" gz_mode - if DONE at exit, this was a zlib stream. |
z->state->gz_mode = DONE; |
#endif |
NEEDBYTE |
if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) |
{ |
#ifdef __ECOS__ |
if (0x1f == z->state->sub.method) { |
z->state->mode = GZ_HDR2; |
break; |
} |
// This is a hack to get a reasonable error message in |
// RedBoot if the user tries to decompress raw data. |
z->state->mode = BAD; |
z->msg = (char*)"incorrect gzip header"; |
z->state->sub.marker = 5; /* can't try inflateSync */ |
#else |
z->state->mode = BAD; |
z->msg = (char*)"unknown compression method"; |
z->state->sub.marker = 5; /* can't try inflateSync */ |
#endif // __ECOS__ |
break; |
} |
if ((z->state->sub.method >> 4) + 8 > z->state->wbits) |
{ |
z->state->mode = BAD; |
z->msg = (char*)"invalid window size"; |
z->state->sub.marker = 5; /* can't try inflateSync */ |
break; |
} |
z->state->mode = FLAG; |
#ifdef __ECOS__ |
break; |
case GZ_HDR2: |
NEEDBYTE; |
b = NEXTBYTE; |
if (0x8b != b) { |
z->state->mode = BAD; |
z->msg = (char*)"incorrect gzip header"; |
z->state->sub.marker = 5; /* can't try inflateSync */ |
break; |
} |
z->state->mode = GZ_METHOD; |
case GZ_METHOD: |
NEEDBYTE |
if ((z->state->sub.method = NEXTBYTE) != Z_DEFLATED) |
{ |
z->state->mode = BAD; |
z->msg = (char*)"unknown compression method"; |
z->state->sub.marker = 5; /* can't try inflateSync */ |
break; |
} |
if ((z->state->sub.method >> 4) + 8 > z->state->wbits) |
{ |
z->state->mode = BAD; |
z->msg = (char*)"invalid window size"; |
z->state->sub.marker = 5; /* can't try inflateSync */ |
break; |
} |
z->state->mode = GZ_FLAG; |
case GZ_FLAG: |
NEEDBYTE |
z->state->gz_flag = NEXTBYTE; |
z->state->mode = GZ_TIME; |
z->state->gz_cnt = 6; // for GZ_TIME |
case GZ_TIME: |
// Discard time, xflags and OS code |
while (z->state->gz_cnt-- > 0) { |
NEEDBYTE; |
b = NEXTBYTE; |
} |
z->state->mode = GZ_EXTRA; |
case GZ_EXTRA: |
if (!(z->state->gz_flag & _GZ_EXTRA_FIELD)) { |
z->state->mode = GZ_NAME; |
break; |
} |
|
NEEDBYTE; |
z->state->gz_cnt = NEXTBYTE; |
z->state->mode = GZ_EXTRA_HI; |
case GZ_EXTRA_HI: |
NEEDBYTE; |
z->state->gz_cnt += (((uInt)NEXTBYTE)<<8); |
z->state->mode = GZ_EXTRA_ZAP; |
case GZ_EXTRA_ZAP: |
// Discard extra field |
while (z->state->gz_cnt-- > 0) { |
NEEDBYTE; |
b = NEXTBYTE; |
} |
z->state->mode = GZ_NAME; |
case GZ_NAME: |
if (!(z->state->gz_flag & _GZ_ORIG_NAME)) { |
z->state->mode = GZ_COMMENT; |
break; |
} |
// Skip the name |
do { |
NEEDBYTE; |
b = NEXTBYTE; |
} while (0 != b); |
z->state->mode = GZ_COMMENT; |
case GZ_COMMENT: |
if (!(z->state->gz_flag & _GZ_COMMENT)) { |
z->state->mode = GZ_HEAD_CRC_LO; |
break; |
} |
// Skip the comment |
do { |
NEEDBYTE; |
b = NEXTBYTE; |
} while (0 != b); |
z->state->mode = GZ_HEAD_CRC_LO; |
case GZ_HEAD_CRC_LO: |
if (!(z->state->gz_flag & _GZ_HEAD_CRC)) { |
z->state->mode = GZ_DONE; |
break; |
} |
// skip lo byte |
NEEDBYTE; |
b = NEXTBYTE; |
z->state->mode = GZ_HEAD_CRC_HI; |
case GZ_HEAD_CRC_HI: |
// skip hi byte |
NEEDBYTE; |
b = NEXTBYTE; |
z->state->mode = GZ_DONE; |
case GZ_DONE: |
// Remember where output is written to and flag that this is a |
// gz stream by setting the gz_mode. |
z->state->gz_start = z->next_out; |
z->state->gz_mode = BLOCKS; |
z->state->gz_sum = 0; |
|
// Depending on the flag select correct next step |
// (clone of code in FLAG) |
if (!(z->state->gz_flag & PRESET_DICT)) |
z->state->mode = BLOCKS; |
else |
z->state->mode = DICT4; |
break; |
#endif // __ECOS__ |
case FLAG: |
NEEDBYTE |
b = NEXTBYTE; |
if (((z->state->sub.method << 8) + b) % 31) |
{ |
z->state->mode = BAD; |
z->msg = (char*)"incorrect header check"; |
z->state->sub.marker = 5; /* can't try inflateSync */ |
break; |
} |
Tracev((stderr, "inflate: zlib header ok\n")); |
if (!(b & PRESET_DICT)) |
{ |
z->state->mode = BLOCKS; |
break; |
} |
z->state->mode = DICT4; |
case DICT4: |
NEEDBYTE |
z->state->sub.check.need = (uLong)NEXTBYTE << 24; |
z->state->mode = DICT3; |
case DICT3: |
NEEDBYTE |
z->state->sub.check.need += (uLong)NEXTBYTE << 16; |
z->state->mode = DICT2; |
case DICT2: |
NEEDBYTE |
z->state->sub.check.need += (uLong)NEXTBYTE << 8; |
z->state->mode = DICT1; |
case DICT1: |
NEEDBYTE |
z->state->sub.check.need += (uLong)NEXTBYTE; |
z->adler = z->state->sub.check.need; |
z->state->mode = DICT0; |
return Z_NEED_DICT; |
case DICT0: |
z->state->mode = BAD; |
z->msg = (char*)"need dictionary"; |
z->state->sub.marker = 0; /* can try inflateSync */ |
return Z_STREAM_ERROR; |
case BLOCKS: |
#ifdef __ECOS__ |
if (z->state->gz_mode != DONE) |
z->state->gz_start = z->next_out; |
#endif |
r = inflate_blocks(z->state->blocks, z, r); |
if (r == Z_DATA_ERROR) |
{ |
z->state->mode = BAD; |
z->state->sub.marker = 0; /* can try inflateSync */ |
break; |
} |
if (r == Z_OK) |
r = f; |
#ifdef __ECOS__ |
if (z->state->gz_mode != DONE) |
z->state->gz_sum = cyg_ether_crc32_accumulate(z->state->gz_sum, |
z->state->gz_start, |
z->next_out - |
z->state->gz_start); |
#endif |
if (r != Z_STREAM_END) |
return r; |
r = f; |
inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); |
if (z->state->nowrap) |
{ |
z->state->mode = DONE; |
break; |
} |
z->state->mode = CHECK4; |
case CHECK4: |
NEEDBYTE |
z->state->sub.check.need = (uLong)NEXTBYTE << 24; |
z->state->mode = CHECK3; |
case CHECK3: |
NEEDBYTE |
z->state->sub.check.need += (uLong)NEXTBYTE << 16; |
z->state->mode = CHECK2; |
case CHECK2: |
NEEDBYTE |
z->state->sub.check.need += (uLong)NEXTBYTE << 8; |
z->state->mode = CHECK1; |
case CHECK1: |
NEEDBYTE |
z->state->sub.check.need += (uLong)NEXTBYTE; |
|
#ifdef __ECOS__ |
if (z->state->gz_mode != DONE) { |
// Byte swap CRC since it is read in the opposite order as |
// written by gzip. |
unsigned long c = z->state->gz_sum; |
z->state->sub.check.was = (((c & 0xff000000) >> 24) | ((c & 0x00ff0000) >> 8) |
| ((c & 0x0000ff00) << 8) | ((c & 0x000000ff) << 24)); |
|
} |
#endif |
|
if (z->state->sub.check.was != z->state->sub.check.need) |
{ |
z->state->mode = BAD; |
z->msg = (char*)"incorrect data check"; |
z->state->sub.marker = 5; /* can't try inflateSync */ |
break; |
} |
Tracev((stderr, "inflate: zlib check ok\n")); |
z->state->mode = DONE; |
case DONE: |
return Z_STREAM_END; |
case BAD: |
return Z_DATA_ERROR; |
default: |
return Z_STREAM_ERROR; |
} |
#ifdef NEED_DUMMY_RETURN |
return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ |
#endif |
} |
|
|
int ZEXPORT inflateSetDictionary(z, dictionary, dictLength) |
z_streamp z; |
const Bytef *dictionary; |
uInt dictLength; |
{ |
uInt length = dictLength; |
|
if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0) |
return Z_STREAM_ERROR; |
|
if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR; |
z->adler = 1L; |
|
if (length >= ((uInt)1<<z->state->wbits)) |
{ |
length = (1<<z->state->wbits)-1; |
dictionary += dictLength - length; |
} |
inflate_set_dictionary(z->state->blocks, dictionary, length); |
z->state->mode = BLOCKS; |
return Z_OK; |
} |
|
|
int ZEXPORT inflateSync(z) |
z_streamp z; |
{ |
uInt n; /* number of bytes to look at */ |
Bytef *p; /* pointer to bytes */ |
uInt m; /* number of marker bytes found in a row */ |
uLong r, w; /* temporaries to save total_in and total_out */ |
|
/* set up */ |
if (z == Z_NULL || z->state == Z_NULL) |
return Z_STREAM_ERROR; |
if (z->state->mode != BAD) |
{ |
z->state->mode = BAD; |
z->state->sub.marker = 0; |
} |
if ((n = z->avail_in) == 0) |
return Z_BUF_ERROR; |
p = z->next_in; |
m = z->state->sub.marker; |
|
/* search */ |
while (n && m < 4) |
{ |
static const Byte mark[4] = {0, 0, 0xff, 0xff}; |
if (*p == mark[m]) |
m++; |
else if (*p) |
m = 0; |
else |
m = 4 - m; |
p++, n--; |
} |
|
/* restore */ |
z->total_in += p - z->next_in; |
z->next_in = p; |
z->avail_in = n; |
z->state->sub.marker = m; |
|
/* return no joy or set up to restart on a new block */ |
if (m != 4) |
return Z_DATA_ERROR; |
r = z->total_in; w = z->total_out; |
inflateReset(z); |
z->total_in = r; z->total_out = w; |
z->state->mode = BLOCKS; |
return Z_OK; |
} |
|
|
/* Returns true if inflate is currently at the end of a block generated |
* by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP |
* implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH |
* but removes the length bytes of the resulting empty stored block. When |
* decompressing, PPP checks that at the end of input packet, inflate is |
* waiting for these length bytes. |
*/ |
int ZEXPORT inflateSyncPoint(z) |
z_streamp z; |
{ |
if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL) |
return Z_STREAM_ERROR; |
return inflate_blocks_sync_point(z->state->blocks); |
} |
/v2_0/src/uncompr.c
0,0 → 1,62
/* uncompr.c -- decompress a memory buffer |
* Copyright (C) 1995-1998 Jean-loup Gailly. |
* For conditions of distribution and use, see copyright notice in zlib.h |
*/ |
|
/* @(#) $Id: uncompr.c,v 1.1.1.1 2004-02-14 13:35:37 phoenix Exp $ */ |
|
#ifdef __ECOS__ |
#include <cyg/compress/zlib.h> |
#else |
#include "zlib.h" |
#endif // __ECOS__ |
|
/* =========================================================================== |
Decompresses the source buffer into the destination buffer. sourceLen is |
the byte length of the source buffer. Upon entry, destLen is the total |
size of the destination buffer, which must be large enough to hold the |
entire uncompressed data. (The size of the uncompressed data must have |
been saved previously by the compressor and transmitted to the decompressor |
by some mechanism outside the scope of this compression library.) |
Upon exit, destLen is the actual size of the compressed buffer. |
This function can be used to decompress a whole file at once if the |
input file is mmap'ed. |
|
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not |
enough memory, Z_BUF_ERROR if there was not enough room in the output |
buffer, or Z_DATA_ERROR if the input data was corrupted. |
*/ |
int ZEXPORT uncompress (dest, destLen, source, sourceLen) |
Bytef *dest; |
uLongf *destLen; |
const Bytef *source; |
uLong sourceLen; |
{ |
z_stream stream; |
int err; |
|
stream.next_in = (Bytef*)source; |
stream.avail_in = (uInt)sourceLen; |
/* Check for source > 64K on 16-bit machine: */ |
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; |
|
stream.next_out = dest; |
stream.avail_out = (uInt)*destLen; |
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; |
|
stream.zalloc = (alloc_func)0; |
stream.zfree = (free_func)0; |
|
err = inflateInit(&stream); |
if (err != Z_OK) return err; |
|
err = inflate(&stream, Z_FINISH); |
if (err != Z_STREAM_END) { |
inflateEnd(&stream); |
return err == Z_OK ? Z_BUF_ERROR : err; |
} |
*destLen = stream.total_out; |
|
err = inflateEnd(&stream); |
return err; |
} |
/v2_0/src/inftrees.h
0,0 → 1,58
/* inftrees.h -- header to use inftrees.c |
* Copyright (C) 1995-1998 Mark Adler |
* For conditions of distribution and use, see copyright notice in zlib.h |
*/ |
|
/* WARNING: this file should *not* be used by applications. It is |
part of the implementation of the compression library and is |
subject to change. Applications should only use zlib.h. |
*/ |
|
/* Huffman code lookup table entry--this entry is four bytes for machines |
that have 16-bit pointers (e.g. PC's in the small or medium model). */ |
|
typedef struct inflate_huft_s FAR inflate_huft; |
|
struct inflate_huft_s { |
union { |
struct { |
Byte Exop; /* number of extra bits or operation */ |
Byte Bits; /* number of bits in this code or subcode */ |
} what; |
uInt pad; /* pad structure to a power of 2 (4 bytes for */ |
} word; /* 16-bit, 8 bytes for 32-bit int's) */ |
uInt base; /* literal, length base, distance base, |
or table offset */ |
}; |
|
/* Maximum size of dynamic tree. The maximum found in a long but non- |
exhaustive search was 1004 huft structures (850 for length/literals |
and 154 for distances, the latter actually the result of an |
exhaustive search). The actual maximum is not known, but the |
value below is more than safe. */ |
#define MANY 1440 |
|
extern int inflate_trees_bits OF(( |
uIntf *, /* 19 code lengths */ |
uIntf *, /* bits tree desired/actual depth */ |
inflate_huft * FAR *, /* bits tree result */ |
inflate_huft *, /* space for trees */ |
z_streamp)); /* for messages */ |
|
extern int inflate_trees_dynamic OF(( |
uInt, /* number of literal/length codes */ |
uInt, /* number of distance codes */ |
uIntf *, /* that many (total) code lengths */ |
uIntf *, /* literal desired/actual bit depth */ |
uIntf *, /* distance desired/actual bit depth */ |
inflate_huft * FAR *, /* literal/length tree result */ |
inflate_huft * FAR *, /* distance tree result */ |
inflate_huft *, /* space for trees */ |
z_streamp)); /* for messages */ |
|
extern int inflate_trees_fixed OF(( |
uIntf *, /* literal desired/actual bit depth */ |
uIntf *, /* distance desired/actual bit depth */ |
inflate_huft * FAR *, /* literal/length tree result */ |
inflate_huft * FAR *, /* distance tree result */ |
z_streamp)); /* for memory allocation */ |
/v2_0/src/FAQ
0,0 → 1,72
|
Frequently Asked Questions about zlib |
|
|
If your question is not there, please check the zlib home page |
http://www.cdrom.com/pub/infozip/zlib/ which may have more recent information. |
|
|
1) I need a Windows DLL |
2) I need a Visual Basic interface to zlib |
3) compress() returns Z_BUF_ERROR |
4) deflate or inflate returns Z_BUF_ERROR |
5) Where is the zlib documentation (man pages, etc...)? |
6) Why don't you use GNU autoconf, libtool, etc...? |
7) There is a bug in zlib. |
8) I get "undefined reference to gzputc" |
|
|
|
1) I need a Windows DLL |
|
The zlib sources can be compiled without change to produce a DLL. |
If you want a precompiled DLL, see http://www.winimage.com/zLibDll |
|
|
2) I need a Visual Basic interface to zlib |
|
See http://www.tcfb.com/dowseware/cmp-z-it.zip |
http://web2.airmail.net/markn/articles/zlibtool/zlibtool.htm |
and contrib/visual-basic.txt |
|
3) compress() returns Z_BUF_ERROR |
|
Make sure that before the call of compress, the length of the |
compressed buffer is equal to the total size of the compressed buffer |
and not zero. For Visual Basic, check that this parameter is passed |
by reference ("as any"), not by value ("as long"). |
|
|
4) deflate or inflate returns Z_BUF_ERROR |
|
Make sure that before the call avail_in and avail_out are not zero. |
|
|
5) Where is the zlib documentation (man pages, etc...)? |
|
It's in zlib.h for the moment. Volunteers to transform this |
to man pages, please contact jloup@gzip.org. Examples of zlib usage |
are in the files example.c and minigzip.c. |
|
|
6) Why don't you use GNU autoconf, libtool, etc...? |
|
Because we would like to keep zlib as a very small and simple package. |
zlib is rather portable and doesn't need much configuration. |
|
|
7) There is a bug in zlib. |
|
Most of the time, such problems are due to an incorrect usage |
of zlib. Please try to reproduce the problem with a small |
program and send us the corresponding source at zlib@quest.jpl.nasa.gov |
Do not send multi-megabyte data files without prior agreement. |
|
|
8) I get "undefined reference to gzputc" |
|
If "make test" produces something like |
example.o(.text+0x174): |
check that you don't have old files libz.* in /usr/lib, /usr/local/lib |
or /usr/X11R6/lib. Remove old versions then do "make install". |
|
/v2_0/src/infcodes.c
0,0 → 1,257
/* infcodes.c -- process literals and length/distance pairs |
* Copyright (C) 1995-1998 Mark Adler |
* For conditions of distribution and use, see copyright notice in zlib.h |
*/ |
|
#include "zutil.h" |
#include "inftrees.h" |
#include "infblock.h" |
#include "infcodes.h" |
#include "infutil.h" |
#include "inffast.h" |
|
/* simplify the use of the inflate_huft type with some defines */ |
#define exop word.what.Exop |
#define bits word.what.Bits |
|
typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ |
START, /* x: set up for LEN */ |
LEN, /* i: get length/literal/eob next */ |
LENEXT, /* i: getting length extra (have base) */ |
DIST, /* i: get distance next */ |
DISTEXT, /* i: getting distance extra */ |
COPY, /* o: copying bytes in window, waiting for space */ |
LIT, /* o: got literal, waiting for output space */ |
WASH, /* o: got eob, possibly still output waiting */ |
END, /* x: got eob and all data flushed */ |
BADCODE} /* x: got error */ |
inflate_codes_mode; |
|
/* inflate codes private state */ |
struct inflate_codes_state { |
|
/* mode */ |
inflate_codes_mode mode; /* current inflate_codes mode */ |
|
/* mode dependent information */ |
uInt len; |
union { |
struct { |
inflate_huft *tree; /* pointer into tree */ |
uInt need; /* bits needed */ |
} code; /* if LEN or DIST, where in tree */ |
uInt lit; /* if LIT, literal */ |
struct { |
uInt get; /* bits to get for extra */ |
uInt dist; /* distance back to copy from */ |
} copy; /* if EXT or COPY, where and how much */ |
} sub; /* submode */ |
|
/* mode independent information */ |
Byte lbits; /* ltree bits decoded per branch */ |
Byte dbits; /* dtree bits decoder per branch */ |
inflate_huft *ltree; /* literal/length/eob tree */ |
inflate_huft *dtree; /* distance tree */ |
|
}; |
|
|
inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) |
uInt bl, bd; |
inflate_huft *tl; |
inflate_huft *td; /* need separate declaration for Borland C++ */ |
z_streamp z; |
{ |
inflate_codes_statef *c; |
|
if ((c = (inflate_codes_statef *) |
ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) |
{ |
c->mode = START; |
c->lbits = (Byte)bl; |
c->dbits = (Byte)bd; |
c->ltree = tl; |
c->dtree = td; |
Tracev((stderr, "inflate: codes new\n")); |
} |
return c; |
} |
|
|
int inflate_codes(s, z, r) |
inflate_blocks_statef *s; |
z_streamp z; |
int r; |
{ |
uInt j; /* temporary storage */ |
inflate_huft *t; /* temporary pointer */ |
uInt e; /* extra bits or operation */ |
uLong b; /* bit buffer */ |
uInt k; /* bits in bit buffer */ |
Bytef *p; /* input data pointer */ |
uInt n; /* bytes available there */ |
Bytef *q; /* output window write pointer */ |
uInt m; /* bytes to end of window or read pointer */ |
Bytef *f; /* pointer to copy strings from */ |
inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ |
|
/* copy input/output information to locals (UPDATE macro restores) */ |
LOAD |
|
/* process input and output based on current state */ |
while (1) switch (c->mode) |
{ /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ |
case START: /* x: set up for LEN */ |
#ifndef SLOW |
if (m >= 258 && n >= 10) |
{ |
UPDATE |
r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); |
LOAD |
if (r != Z_OK) |
{ |
c->mode = r == Z_STREAM_END ? WASH : BADCODE; |
break; |
} |
} |
#endif /* !SLOW */ |
c->sub.code.need = c->lbits; |
c->sub.code.tree = c->ltree; |
c->mode = LEN; |
case LEN: /* i: get length/literal/eob next */ |
j = c->sub.code.need; |
NEEDBITS(j) |
t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); |
DUMPBITS(t->bits) |
e = (uInt)(t->exop); |
if (e == 0) /* literal */ |
{ |
c->sub.lit = t->base; |
Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? |
"inflate: literal '%c'\n" : |
"inflate: literal 0x%02x\n", t->base)); |
c->mode = LIT; |
break; |
} |
if (e & 16) /* length */ |
{ |
c->sub.copy.get = e & 15; |
c->len = t->base; |
c->mode = LENEXT; |
break; |
} |
if ((e & 64) == 0) /* next table */ |
{ |
c->sub.code.need = e; |
c->sub.code.tree = t + t->base; |
break; |
} |
if (e & 32) /* end of block */ |
{ |
Tracevv((stderr, "inflate: end of block\n")); |
c->mode = WASH; |
break; |
} |
c->mode = BADCODE; /* invalid code */ |
z->msg = (char*)"invalid literal/length code"; |
r = Z_DATA_ERROR; |
LEAVE |
case LENEXT: /* i: getting length extra (have base) */ |
j = c->sub.copy.get; |
NEEDBITS(j) |
c->len += (uInt)b & inflate_mask[j]; |
DUMPBITS(j) |
c->sub.code.need = c->dbits; |
c->sub.code.tree = c->dtree; |
Tracevv((stderr, "inflate: length %u\n", c->len)); |
c->mode = DIST; |
case DIST: /* i: get distance next */ |
j = c->sub.code.need; |
NEEDBITS(j) |
t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); |
DUMPBITS(t->bits) |
e = (uInt)(t->exop); |
if (e & 16) /* distance */ |
{ |
c->sub.copy.get = e & 15; |
c->sub.copy.dist = t->base; |
c->mode = DISTEXT; |
break; |
} |
if ((e & 64) == 0) /* next table */ |
{ |
c->sub.code.need = e; |
c->sub.code.tree = t + t->base; |
break; |
} |
c->mode = BADCODE; /* invalid code */ |
z->msg = (char*)"invalid distance code"; |
r = Z_DATA_ERROR; |
LEAVE |
case DISTEXT: /* i: getting distance extra */ |
j = c->sub.copy.get; |
NEEDBITS(j) |
c->sub.copy.dist += (uInt)b & inflate_mask[j]; |
DUMPBITS(j) |
Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); |
c->mode = COPY; |
case COPY: /* o: copying bytes in window, waiting for space */ |
#ifndef __TURBOC__ /* Turbo C bug for following expression */ |
f = (uInt)(q - s->window) < c->sub.copy.dist ? |
s->end - (c->sub.copy.dist - (q - s->window)) : |
q - c->sub.copy.dist; |
#else |
f = q - c->sub.copy.dist; |
if ((uInt)(q - s->window) < c->sub.copy.dist) |
f = s->end - (c->sub.copy.dist - (uInt)(q - s->window)); |
#endif |
while (c->len) |
{ |
NEEDOUT |
OUTBYTE(*f++) |
if (f == s->end) |
f = s->window; |
c->len--; |
} |
c->mode = START; |
break; |
case LIT: /* o: got literal, waiting for output space */ |
NEEDOUT |
OUTBYTE(c->sub.lit) |
c->mode = START; |
break; |
case WASH: /* o: got eob, possibly more output */ |
if (k > 7) /* return unused byte, if any */ |
{ |
Assert(k < 16, "inflate_codes grabbed too many bytes") |
k -= 8; |
n++; |
p--; /* can always return one */ |
} |
FLUSH |
if (s->read != s->write) |
LEAVE |
c->mode = END; |
case END: |
r = Z_STREAM_END; |
LEAVE |
case BADCODE: /* x: got error */ |
r = Z_DATA_ERROR; |
LEAVE |
default: |
r = Z_STREAM_ERROR; |
LEAVE |
} |
#ifdef NEED_DUMMY_RETURN |
return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ |
#endif |
} |
|
|
void inflate_codes_free(c, z) |
inflate_codes_statef *c; |
z_streamp z; |
{ |
ZFREE(z, c); |
Tracev((stderr, "inflate: codes free\n")); |
} |
/v2_0/src/adler32.c
0,0 → 1,52
/* adler32.c -- compute the Adler-32 checksum of a data stream |
* Copyright (C) 1995-1998 Mark Adler |
* For conditions of distribution and use, see copyright notice in zlib.h |
*/ |
|
/* @(#) $Id: adler32.c,v 1.1.1.1 2004-02-14 13:35:37 phoenix Exp $ */ |
|
#ifdef __ECOS__ |
#include <cyg/compress/zlib.h> |
#else |
#include "zlib.h" |
#endif // __ECOS__ |
|
#define BASE 65521L /* largest prime smaller than 65536 */ |
#define NMAX 5552 |
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ |
|
#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} |
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); |
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); |
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); |
#define DO16(buf) DO8(buf,0); DO8(buf,8); |
|
/* ========================================================================= */ |
uLong ZEXPORT adler32(adler, buf, len) |
uLong adler; |
const Bytef *buf; |
uInt len; |
{ |
unsigned long s1 = adler & 0xffff; |
unsigned long s2 = (adler >> 16) & 0xffff; |
int k; |
|
if (buf == Z_NULL) return 1L; |
|
while (len > 0) { |
k = len < NMAX ? len : NMAX; |
len -= k; |
while (k >= 16) { |
DO16(buf); |
buf += 16; |
k -= 16; |
} |
if (k != 0) do { |
s1 += *buf++; |
s2 += s1; |
} while (--k); |
s1 %= BASE; |
s2 %= BASE; |
} |
return (s2 << 16) | s1; |
} |
/v2_0/src/maketree.c
0,0 → 1,85
/* maketree.c -- make inffixed.h table for decoding fixed codes |
* Copyright (C) 1998 Mark Adler |
* For conditions of distribution and use, see copyright notice in zlib.h |
*/ |
|
/* WARNING: this file should *not* be used by applications. It is |
part of the implementation of the compression library and is |
subject to change. Applications should only use zlib.h. |
*/ |
|
/* This program is included in the distribution for completeness. |
You do not need to compile or run this program since inffixed.h |
is already included in the distribution. To use this program |
you need to compile zlib with BUILDFIXED defined and then compile |
and link this program with the zlib library. Then the output of |
this program can be piped to inffixed.h. */ |
|
#include <stdio.h> |
#include <stdlib.h> |
#include "zutil.h" |
#include "inftrees.h" |
|
/* simplify the use of the inflate_huft type with some defines */ |
#define exop word.what.Exop |
#define bits word.what.Bits |
|
/* generate initialization table for an inflate_huft structure array */ |
void maketree(uInt b, inflate_huft *t) |
{ |
int i, e; |
|
i = 0; |
while (1) |
{ |
e = t[i].exop; |
if (e && (e & (16+64)) == 0) /* table pointer */ |
{ |
fprintf(stderr, "maketree: cannot initialize sub-tables!\n"); |
exit(1); |
} |
if (i % 4 == 0) |
printf("\n "); |
printf(" {{{%u,%u}},%u}", t[i].exop, t[i].bits, t[i].base); |
if (++i == (1<<b)) |
break; |
putchar(','); |
} |
puts(""); |
} |
|
/* create the fixed tables in C initialization syntax */ |
void main(void) |
{ |
int r; |
uInt bl, bd; |
inflate_huft *tl, *td; |
z_stream z; |
|
z.zalloc = zcalloc; |
z.opaque = (voidpf)0; |
z.zfree = zcfree; |
r = inflate_trees_fixed(&bl, &bd, &tl, &td, &z); |
if (r) |
{ |
fprintf(stderr, "inflate_trees_fixed error %d\n", r); |
return; |
} |
puts("/* inffixed.h -- table for decoding fixed codes"); |
puts(" * Generated automatically by the maketree.c program"); |
puts(" */"); |
puts(""); |
puts("/* WARNING: this file should *not* be used by applications. It is"); |
puts(" part of the implementation of the compression library and is"); |
puts(" subject to change. Applications should only use zlib.h."); |
puts(" */"); |
puts(""); |
printf("local uInt fixed_bl = %d;\n", bl); |
printf("local uInt fixed_bd = %d;\n", bd); |
printf("local inflate_huft fixed_tl[] = {"); |
maketree(bl, tl); |
puts(" };"); |
printf("local inflate_huft fixed_td[] = {"); |
maketree(bd, td); |
puts(" };"); |
} |