From 09e20d494faa8ade63661b9ffc49eb8cd71566fd Mon Sep 17 00:00:00 2001 From: Brian Hinz Date: Sat, 1 Sep 2012 21:15:26 +0000 Subject: [PATCH] upgrade jzlib to 1.1.1 git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4990 3789f03b-4d11-0410-bbf8-ca57d06f2519 --- java/CMakeLists.txt | 2 +- java/com/jcraft/jzlib/Adler32.java | 121 +++-- java/com/jcraft/jzlib/CRC32.java | 179 ++++++++ java/com/jcraft/jzlib/ChangeLog | 91 ++-- java/com/jcraft/jzlib/Checksum.java | 43 ++ java/com/jcraft/jzlib/Deflate.java | 200 +++++++-- java/com/jcraft/jzlib/GZIPHeader.java | 214 +++++++++ java/com/jcraft/jzlib/InfBlocks.java | 122 ++--- java/com/jcraft/jzlib/InfCodes.java | 41 +- java/com/jcraft/jzlib/InfTree.java | 2 - java/com/jcraft/jzlib/Inflate.java | 541 ++++++++++++++++++----- java/com/jcraft/jzlib/JZlib.java | 20 +- java/com/jcraft/jzlib/LICENSE.txt | 2 +- java/com/jcraft/jzlib/README | 19 +- java/com/jcraft/jzlib/StaticTree.java | 11 +- java/com/jcraft/jzlib/Tree.java | 11 +- java/com/jcraft/jzlib/ZInputStream.java | 117 ++--- java/com/jcraft/jzlib/ZOutputStream.java | 131 +++--- java/com/jcraft/jzlib/ZStream.java | 176 +++++++- 19 files changed, 1584 insertions(+), 459 deletions(-) create mode 100644 java/com/jcraft/jzlib/CRC32.java create mode 100644 java/com/jcraft/jzlib/Checksum.java create mode 100644 java/com/jcraft/jzlib/GZIPHeader.java diff --git a/java/CMakeLists.txt b/java/CMakeLists.txt index f3215945..86b96274 100644 --- a/java/CMakeLists.txt +++ b/java/CMakeLists.txt @@ -7,7 +7,7 @@ endif() find_package(Java) -set(DEFAULT_JAVACFLAGS "-source 1.5 -target 1.5 -Xlint:all,-serial,-cast,-unchecked,-fallthrough,-dep-ann") +set(DEFAULT_JAVACFLAGS "-source 1.5 -target 1.5 -Xlint:all,-serial,-cast,-unchecked,-fallthrough,-dep-ann,-deprecation") set(JAVACFLAGS ${DEFAULT_JAVACFLAGS} CACHE STRING "Java compiler flags (Default: ${DEFAULT_JAVACFLAGS})") message(STATUS "Java compiler flags = ${JAVACFLAGS}") diff --git a/java/com/jcraft/jzlib/Adler32.java b/java/com/jcraft/jzlib/Adler32.java index d8b6ef86..a789a5a1 100644 --- a/java/com/jcraft/jzlib/Adler32.java +++ b/java/com/jcraft/jzlib/Adler32.java @@ -1,6 +1,6 @@ /* -*-mode:java; c-basic-offset:2; -*- */ /* -Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. +Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -34,61 +34,106 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jzlib; -final class Adler32{ +final public class Adler32 implements Checksum { // largest prime smaller than 65536 static final private int BASE=65521; // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 static final private int NMAX=5552; - long adler32(long adler, byte[] buf, int index, int len){ - if(buf == null){ return 1L; } + private long s1=1L; + private long s2=0L; - long s1=adler&0xffff; - long s2=(adler>>16)&0xffff; - int k; + public void reset(long init){ + s1=init&0xffff; + s2=(init>>16)&0xffff; + } + + public void reset(){ + s1=1L; + s2=0L; + } + + public long getValue(){ + return ((s2<<16)|s1); + } + + public void update(byte[] buf, int index, int len){ - while(len > 0) { - k=len0) { + int k=NMAX; len-=k; - while(k>=16){ - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - s1+=buf[index++]&0xff; s2+=s1; - k-=16; - } - if(k!=0){ - do{ - s1+=buf[index++]&0xff; s2+=s1; - } - while(--k!=0); + while(k-->0){ + s1+=buf[index++]&0xff; s2+=s1; } s1%=BASE; s2%=BASE; } - return (s2<<16)|s1; + + int k=len2; + len-=k; + while(k-->0){ + s1+=buf[index++]&0xff; s2+=s1; + } + s1%=BASE; + s2%=BASE; + } + + public Adler32 copy(){ + Adler32 foo = new Adler32(); + foo.s1 = this.s1; + foo.s2 = this.s2; + return foo; + } + + // The following logic has come from zlib.1.2. + static long combine(long adler1, long adler2, long len2){ + long BASEL = (long)BASE; + long sum1; + long sum2; + long rem; // unsigned int + + rem = len2 % BASEL; + sum1 = adler1 & 0xffffL; + sum2 = rem * sum1; + sum2 %= BASEL; // MOD(sum2); + sum1 += (adler2 & 0xffffL) + BASEL - 1; + sum2 += ((adler1 >> 16) & 0xffffL) + ((adler2 >> 16) & 0xffffL) + BASEL - rem; + if (sum1 >= BASEL) sum1 -= BASEL; + if (sum1 >= BASEL) sum1 -= BASEL; + if (sum2 >= (BASEL << 1)) sum2 -= (BASEL << 1); + if (sum2 >= BASEL) sum2 -= BASEL; + return sum1 | (sum2 << 16); } - /* +/* private java.util.zip.Adler32 adler=new java.util.zip.Adler32(); - long adler32(long value, byte[] buf, int index, int len){ - if(value==1) {adler.reset();} + public void update(byte[] buf, int index, int len){ if(buf==null) {adler.reset();} else{adler.update(buf, index, len);} + } + public void reset(){ + adler.reset(); + } + public void reset(long init){ + if(init==1L){ + adler.reset(); + } + else{ + System.err.println("unsupported operation"); + } + } + public long getValue(){ return adler.getValue(); } - */ +*/ } diff --git a/java/com/jcraft/jzlib/CRC32.java b/java/com/jcraft/jzlib/CRC32.java new file mode 100644 index 00000000..30457968 --- /dev/null +++ b/java/com/jcraft/jzlib/CRC32.java @@ -0,0 +1,179 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final public class CRC32 implements Checksum { + + /* + * The following logic has come from RFC1952. + */ + private int v = 0; + private static int[] crc_table = null; + static { + crc_table = new int[256]; + for (int n = 0; n < 256; n++) { + int c = n; + for (int k = 8; --k >= 0; ) { + if ((c & 1) != 0) + c = 0xedb88320 ^ (c >>> 1); + else + c = c >>> 1; + } + crc_table[n] = c; + } + } + + public void update (byte[] buf, int index, int len) { + int c = ~v; + while (--len >= 0) + c = crc_table[(c^buf[index++])&0xff]^(c >>> 8); + v = ~c; + } + + public void reset(){ + v = 0; + } + + public void reset(long vv){ + v = (int)(vv&0xffffffffL); + } + + public long getValue(){ + return (long)(v&0xffffffffL); + } + + // The following logic has come from zlib.1.2. + private static final int GF2_DIM = 32; + static long combine(long crc1, long crc2, long len2){ + long row; + long[] even = new long[GF2_DIM]; + long[] odd = new long[GF2_DIM]; + + // degenerate case (also disallow negative lengths) + if (len2 <= 0) + return crc1; + + // put operator for one zero bit in odd + odd[0] = 0xedb88320L; // CRC-32 polynomial + row = 1; + for (int n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + // put operator for two zero bits in even + gf2_matrix_square(even, odd); + + // put operator for four zero bits in odd + gf2_matrix_square(odd, even); + + // apply len2 zeros to crc1 (first square will put the operator for one + // zero byte, eight zero bits, in even) + do { + // apply zeros operator for this bit of len2 + gf2_matrix_square(even, odd); + if ((len2 & 1)!=0) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + // if no more bits set, then done + if (len2 == 0) + break; + + // another iteration of the loop with odd and even swapped + gf2_matrix_square(odd, even); + if ((len2 & 1)!=0) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + // if no more bits set, then done + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; + } + + private static long gf2_matrix_times(long[] mat, long vec){ + long sum = 0; + int index = 0; + while (vec!=0) { + if ((vec & 1)!=0) + sum ^= mat[index]; + vec >>= 1; + index++; + } + return sum; + } + + static final void gf2_matrix_square(long[] square, long[] mat) { + for (int n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); + } + + /* + private java.util.zip.CRC32 crc32 = new java.util.zip.CRC32(); + + public void update(byte[] buf, int index, int len){ + if(buf==null) {crc32.reset();} + else{crc32.update(buf, index, len);} + } + public void reset(){ + crc32.reset(); + } + public void reset(long init){ + if(init==0L){ + crc32.reset(); + } + else{ + System.err.println("unsupported operation"); + } + } + public long getValue(){ + return crc32.getValue(); + } +*/ + public CRC32 copy(){ + CRC32 foo = new CRC32(); + foo.v = this.v; + return foo; + } + + public static int[] getCRC32Table(){ + int[] tmp = new int[crc_table.length]; + System.arraycopy(crc_table, 0, tmp, 0, tmp.length); + return tmp; + } +} diff --git a/java/com/jcraft/jzlib/ChangeLog b/java/com/jcraft/jzlib/ChangeLog index c828fae3..d963cffc 100644 --- a/java/com/jcraft/jzlib/ChangeLog +++ b/java/com/jcraft/jzlib/ChangeLog @@ -1,17 +1,54 @@ ChangeLog of JZlib ==================================================================== -Last modified: Thu Aug 18 16:16:06 UTC 2005 - - -Changes since version 1.0.6: -- change: memory and performance optimizations in the inflate operation. - Many thanks to Paul Wakefield at platx.org(http://www.platx.org), who - suggested above improvements. +Last modified: Mon Feb 20 06:06:07 UTC 2012 + + +Changes since version 1.1.0: +- fixed a bug in DeflaterOutputStream#write() with empty data. 9d4616f +- fixed a bug in processing unwrapped data with InfalterInputStream. d35db2 +- fixed bugs reported in https://github.com/ymnk/jzlib/pull/5 e4aa20 + - comments and filename in GZIPHeader must be in ISO-8859-1 encoding + - fixing a bug in GZIPHeader#setOS(int os) +- some refactoring code. e912088 6900f5 614fdf +- improving the performace of Adler32#update method. 6900f5 +- constructors of Alder32 and CRC32 become public. 30c4cf +- added ZStream#end() and ZStream#finished(). 6b55e3 +- exposed useful constants for jruby. e17ad1 +- updated pom.xml to delete "souceDirectory" + No need to specify sourceDirectory if the project follows maven + standard. +- updated configurations to use sbt 0.11.1 + + +Changes since version 1.0.7: +- supported some new functionalities, which have been introduced since 'zlib' 1.2. + - JZlib#{adler32,crc32}_combine, + - JZlib can handle gzip file format(RFC1952). +- added following classes, + - DeflaterOutputStream + - InflaterInputStream + - GZIPOutputStream + - GZIPInputStream + - Inflater + - Deflater + - ZStream has been deprecated. + Use Inflater and Deflater instead of it. + - GZIPHeader +- re-implemented Z{Input,Output}Stream with {Deflater,Inflater}{I/O}Stream + - those classes have been deprecated. + Use DeflaterOutputStream and InfaterInputStream instead of them. +- com/ -> src/main/java/com/ +- some tests under src/test/scala/ +- pom.xml for mvn, and projects/ for sbt. + + +Changes since version 1.0.6: +- change: memory and performance optimisations in the inflate operation. - change: added the nowrap argument to Z{Input,Output}?Stream. - + Changes since version 1.0.5: -- ZInputStream.read(byte[], int, int) method return sometimes zero +- ZInputStream.read(byte[], int, int) method return sometimes zero instead of -1 at the end of stream. - ZOutputStream.end() method should not declare IOException. - It should be possible to call ZOutputStream.end() method more times @@ -20,64 +57,64 @@ Changes since version 1.0.5: - ZOutputStream.finish() method should not ignore IOException from flush(). Many thanks to Matej Kraus at seznam.cz , who pointed out above problems. - + Changes since version 1.0.4: - a minor bug fix in ZInputStream - + Changes since version 1.0.3: - fixed a bug in closing ZOutputStream. The inflating and deflating processes were not finished successfully. - added 'finish' and 'end' methods to ZOutputStream.java - added 'example/test_stream_deflate_inflate.java' - + Changes since version 1.0.2: - enabled pure Java implementation of adler32 and commented out the dependency on J2SE in Adler32.java for J2ME users. - + Changes since version 1.0.1: - fixed a bug in deflating some trivial data, for example, - large data chunk filled with zero. + large data chunk filled with zero. - added 'version' method to JZlib class. - + Changes since version 1.0.0: - added ZInputStream and ZOutputStream classes. - fixed a typo in LICENSE.txt. - + Changes since version 0.0.9: - fixed a bug in setting a dictionary in the inflation process. - The license was changed to a BSD style license. - Z{Input,Output}Stream classes were deleted. - - + + Changes since version 0.0.8: - fixed a bug in handling a preset dictionary in the inflation process. - + Changes since version 0.0.7: - added methods to control the window size (the size of the history buffer) and to handle the no-wrap option (no zlib header or check), which is the undocumented functionality of zlib. - + Changes since version 0.0.6: - updated InfBlocks.java as zlib did to fix the vulnerability related to the 'double free'. Of course, JZlib is free from such a vulnerability like the 'double free', but JZlib had crashed with NullPointerException - by a specially-crafted block of invalid deflated data. + by a specially-crafted block of invalid deflated data. + - Changes since version 0.0.5: - added 'flush()' method to com.jcraft.jzlib.ZOutputStream. -- fixed to take care when occurring the buffer overflow in +- fixed to take care when occurring the buffer overflow in com.jcraft.jzlib.ZOutputStream. Many thanks to Tim Bendfelt at cs.wisc.edu , who pointed out above problems. - - + + Changes since version 0.0.4: ............................ - fixed a bug in Adler32 class. @@ -87,11 +124,11 @@ Changes since version 0.0.4: - modified ZOutputStream to be extended from OutputStream instead of FileOutputStream. - modified ZStream to be changeable wbits. Give wbits value to - the method 'deflateInit' of ZStream. + the method 'deflateInit' of ZStream. Many thanks to Bryan Keller, who reported bugs and made suggestions. - + Changes since version 0.0.3: ............................ - fixed a bug in the compression level 0. diff --git a/java/com/jcraft/jzlib/Checksum.java b/java/com/jcraft/jzlib/Checksum.java new file mode 100644 index 00000000..1139093c --- /dev/null +++ b/java/com/jcraft/jzlib/Checksum.java @@ -0,0 +1,43 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +interface Checksum { + void update(byte[] buf, int index, int len); + void reset(); + void reset(long init); + long getValue(); + Checksum copy(); +} diff --git a/java/com/jcraft/jzlib/Deflate.java b/java/com/jcraft/jzlib/Deflate.java index 99788020..baaac9be 100644 --- a/java/com/jcraft/jzlib/Deflate.java +++ b/java/com/jcraft/jzlib/Deflate.java @@ -1,6 +1,6 @@ /* -*-mode:java; c-basic-offset:2; -*- */ /* -Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. +Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -35,7 +35,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jzlib; public -final class Deflate{ +final class Deflate implements Cloneable { static final private int MAX_MEM_LEVEL=9; @@ -169,13 +169,13 @@ final class Deflate{ static final private int END_BLOCK=256; - ZStream strm; // pointer back to this zlib stream + ZStream strm; // pointer back to this zlib stream int status; // as the name implies byte[] pending_buf; // output still pending int pending_buf_size; // size of pending_buf int 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 + int wrap = 1; 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 @@ -317,7 +317,10 @@ final class Deflate{ // are always zero. int bi_valid; - Deflate(){ + GZIPHeader gheader = null; + + Deflate(ZStream strm){ + this.strm=strm; dyn_ltree=new short[HEAP_SIZE*2]; dyn_dtree=new short[(2*D_CODES+1)*2]; // distance tree bl_tree=new short[(2*BL_CODES+1)*2]; // Huffman tree for bit lengths @@ -1311,17 +1314,22 @@ final class Deflate{ if (best_len <= lookahead) return best_len; return lookahead; } + + int deflateInit(int level, int bits, int memlevel){ + return deflateInit(level, Z_DEFLATED, bits, memlevel, + Z_DEFAULT_STRATEGY); + } - int deflateInit(ZStream strm, int level, int bits){ - return deflateInit2(strm, level, Z_DEFLATED, bits, DEF_MEM_LEVEL, + int deflateInit(int level, int bits){ + return deflateInit(level, Z_DEFLATED, bits, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); } - int deflateInit(ZStream strm, int level){ - return deflateInit(strm, level, MAX_WBITS); + int deflateInit(int level){ + return deflateInit(level, MAX_WBITS); } - int deflateInit2(ZStream strm, int level, int method, int windowBits, - int memLevel, int strategy){ - int noheader = 0; + private int deflateInit(int level, int method, int windowBits, + int memLevel, int strategy){ + int wrap = 1; // byte[] my_version=ZLIB_VERSION; // @@ -1335,9 +1343,14 @@ final class Deflate{ if (level == Z_DEFAULT_COMPRESSION) level = 6; if (windowBits < 0) { // undocumented feature: suppress zlib header - noheader = 1; + wrap = 0; windowBits = -windowBits; } + else if(windowBits > 15){ + wrap = 2; + windowBits -= 16; + strm.adler=new CRC32(); + } if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || @@ -1348,7 +1361,7 @@ final class Deflate{ strm.dstate = (Deflate)this; - this.noheader = noheader; + this.wrap = wrap; w_bits = windowBits; w_size = 1 << w_bits; w_mask = w_size - 1; @@ -1374,15 +1387,13 @@ final class Deflate{ this.level = level; -//System.out.println("level="+level); - this.strategy = strategy; this.method = (byte)method; - return deflateReset(strm); + return deflateReset(); } - int deflateReset(ZStream strm){ + int deflateReset(){ strm.total_in = strm.total_out = 0; strm.msg = null; // strm.data_type = Z_UNKNOWN; @@ -1390,11 +1401,11 @@ final class Deflate{ pending = 0; pending_out = 0; - if(noheader < 0) { - noheader = 0; // was set to -1 by deflate(..., Z_FINISH); + if(wrap < 0){ + wrap = -wrap; } - status = (noheader!=0) ? BUSY_STATE : INIT_STATE; - strm.adler=strm._adler.adler32(0, null, 0, 0); + status = (wrap==0) ? BUSY_STATE : INIT_STATE; + strm.adler.reset(); last_flush = Z_NO_FLUSH; @@ -1417,7 +1428,7 @@ final class Deflate{ return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; } - int deflateParams(ZStream strm, int _level, int _strategy){ + int deflateParams(int _level, int _strategy){ int err=Z_OK; if(_level == Z_DEFAULT_COMPRESSION){ @@ -1445,14 +1456,14 @@ final class Deflate{ return err; } - int deflateSetDictionary (ZStream strm, byte[] dictionary, int dictLength){ + int deflateSetDictionary (byte[] dictionary, int dictLength){ int length = dictLength; int index=0; if(dictionary == null || status != INIT_STATE) return Z_STREAM_ERROR; - strm.adler=strm._adler.adler32(strm.adler, dictionary, 0, dictLength); + strm.adler.update(dictionary, 0, dictLength); if(length < MIN_MATCH) return Z_OK; if(length > w_size-MIN_LOOKAHEAD){ @@ -1478,7 +1489,7 @@ final class Deflate{ return Z_OK; } - int deflate(ZStream strm, int flush){ + int deflate(int flush){ int old_flush; if(flush>Z_FINISH || flush<0){ @@ -1496,12 +1507,17 @@ final class Deflate{ return Z_BUF_ERROR; } - this.strm = strm; // just in case old_flush = last_flush; last_flush = flush; // Write the zlib header if(status == INIT_STATE) { + if(wrap == 2){ + getGZIPHeader().put(this); + status=BUSY_STATE; + strm.adler.reset(); + } + else{ int header = (Z_DEFLATED+((w_bits-8)<<4))<<8; int level_flags=((level-1)&0xff)>>1; @@ -1516,17 +1532,18 @@ final class Deflate{ // Save the adler32 of the preset dictionary: if(strstart!=0){ - putShortMSB((int)(strm.adler>>>16)); - putShortMSB((int)(strm.adler&0xffff)); + long adler=strm.adler.getValue(); + putShortMSB((int)(adler>>>16)); + putShortMSB((int)(adler&0xffff)); + } + strm.adler.reset(); } - strm.adler=strm._adler.adler32(0, null, 0, 0); } // Flush as much pending output as possible if(pending != 0) { strm.flush_pending(); if(strm.avail_out == 0) { - //System.out.println(" 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, @@ -1608,16 +1625,127 @@ final class Deflate{ } if(flush!=Z_FINISH) return Z_OK; - if(noheader!=0) return Z_STREAM_END; + if(wrap<=0) return Z_STREAM_END; + + if(wrap==2){ + long adler=strm.adler.getValue(); + put_byte((byte)(adler&0xff)); + put_byte((byte)((adler>>8)&0xff)); + put_byte((byte)((adler>>16)&0xff)); + put_byte((byte)((adler>>24)&0xff)); + put_byte((byte)(strm.total_in&0xff)); + put_byte((byte)((strm.total_in>>8)&0xff)); + put_byte((byte)((strm.total_in>>16)&0xff)); + put_byte((byte)((strm.total_in>>24)&0xff)); + + getGZIPHeader().setCRC(adler); + } + else{ + // Write the zlib trailer (adler32) + long adler=strm.adler.getValue(); + putShortMSB((int)(adler>>>16)); + putShortMSB((int)(adler&0xffff)); + } - // Write the zlib trailer (adler32) - putShortMSB((int)(strm.adler>>>16)); - putShortMSB((int)(strm.adler&0xffff)); strm.flush_pending(); // If avail_out is zero, the application will call deflate again // to flush the rest. - noheader = -1; // write the trailer only once! + + if(wrap > 0) wrap = -wrap; // write the trailer only once! return pending != 0 ? Z_OK : Z_STREAM_END; } + + static int deflateCopy(ZStream dest, ZStream src){ + + if(src.dstate == null){ + return Z_STREAM_ERROR; + } + + if(src.next_in!=null){ + dest.next_in = new byte[src.next_in.length]; + System.arraycopy(src.next_in, 0, dest.next_in, 0, src.next_in.length); + } + dest.next_in_index = src.next_in_index; + dest.avail_in = src.avail_in; + dest.total_in = src.total_in; + + if(src.next_out!=null){ + dest.next_out = new byte[src.next_out.length]; + System.arraycopy(src.next_out, 0, dest.next_out ,0 , src.next_out.length); + } + + dest.next_out_index = src.next_out_index; + dest.avail_out = src.avail_out; + dest.total_out = src.total_out; + + dest.msg = src.msg; + dest.data_type = src.data_type; + dest.adler = src.adler.copy(); + + try{ + dest.dstate = (Deflate)src.dstate.clone(); + dest.dstate.strm = dest; + } + catch(CloneNotSupportedException e){ + // + } + return Z_OK; + } + + public Object clone() throws CloneNotSupportedException { + Deflate dest = (Deflate)super.clone(); + + dest.pending_buf = dup(dest.pending_buf); + dest.window = dup(dest.window); + + dest.prev = dup(dest.prev); + dest.head = dup(dest.head); + dest.dyn_ltree = dup(dest.dyn_ltree); + dest.dyn_dtree = dup(dest.dyn_dtree); + dest.bl_tree = dup(dest.bl_tree); + + dest.bl_count = dup(dest.bl_count); + dest.heap = dup(dest.heap); + dest.depth = dup(dest.depth); + + dest.l_desc.dyn_tree = dest.dyn_ltree; + dest.d_desc.dyn_tree = dest.dyn_dtree; + dest.bl_desc.dyn_tree = dest.bl_tree; + + /* + dest.l_desc.stat_desc = StaticTree.static_l_desc; + dest.d_desc.stat_desc = StaticTree.static_d_desc; + dest.bl_desc.stat_desc = StaticTree.static_bl_desc; + */ + + if(dest.gheader!=null){ + dest.gheader = (GZIPHeader)dest.gheader.clone(); + } + + return dest; + } + + private byte[] dup(byte[] buf){ + byte[] foo = new byte[buf.length]; + System.arraycopy(buf, 0, foo, 0, foo.length); + return foo; + } + private short[] dup(short[] buf){ + short[] foo = new short[buf.length]; + System.arraycopy(buf, 0, foo, 0, foo.length); + return foo; + } + private int[] dup(int[] buf){ + int[] foo = new int[buf.length]; + System.arraycopy(buf, 0, foo, 0, foo.length); + return foo; + } + + synchronized GZIPHeader getGZIPHeader(){ + if(gheader==null){ + gheader = new GZIPHeader(); + } + return gheader; + } } diff --git a/java/com/jcraft/jzlib/GZIPHeader.java b/java/com/jcraft/jzlib/GZIPHeader.java new file mode 100644 index 00000000..0405e00b --- /dev/null +++ b/java/com/jcraft/jzlib/GZIPHeader.java @@ -0,0 +1,214 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +import java.io.UnsupportedEncodingException; + +/** + * @see "http://www.ietf.org/rfc/rfc1952.txt" + */ +public class GZIPHeader implements Cloneable { + + public static final byte OS_MSDOS = (byte) 0x00; + public static final byte OS_AMIGA = (byte) 0x01; + public static final byte OS_VMS = (byte) 0x02; + public static final byte OS_UNIX = (byte) 0x03; + public static final byte OS_ATARI = (byte) 0x05; + public static final byte OS_OS2 = (byte) 0x06; + public static final byte OS_MACOS = (byte) 0x07; + public static final byte OS_TOPS20 = (byte) 0x0a; + public static final byte OS_WIN32 = (byte) 0x0b; + public static final byte OS_VMCMS = (byte) 0x04; + public static final byte OS_ZSYSTEM = (byte) 0x08; + public static final byte OS_CPM = (byte) 0x09; + public static final byte OS_QDOS = (byte) 0x0c; + public static final byte OS_RISCOS = (byte) 0x0d; + public static final byte OS_UNKNOWN = (byte) 0xff; + + boolean text = false; + private boolean fhcrc = false; + long time; + int xflags; + int os = 255; + byte[] extra; + byte[] name; + byte[] comment; + int hcrc; + long crc; + boolean done = false; + long mtime = 0; + + public void setModifiedTime(long mtime) { + this.mtime = mtime; + } + + public long getModifiedTime() { + return mtime; + } + + public void setOS(int os) { + if((0<=os && os <=13) || os==255) + this.os=os; + else + throw new IllegalArgumentException("os: "+os); + } + + public int getOS(){ + return os; + } + + public void setName(String name) { + try{ + this.name=name.getBytes("ISO-8859-1"); + } + catch(UnsupportedEncodingException e){ + throw new IllegalArgumentException("name must be in ISO-8859-1 "+name); + } + } + + public String getName(){ + if(name==null) return ""; + try { + return new String(name, "ISO-8859-1"); + } + catch (UnsupportedEncodingException e) { + throw new InternalError(e.toString()); + } + } + + public void setComment(String comment) { + try{ + this.comment=comment.getBytes("ISO-8859-1"); + } + catch(UnsupportedEncodingException e){ + throw new IllegalArgumentException("comment must be in ISO-8859-1 "+name); + } + } + + public String getComment(){ + if(comment==null) return ""; + try { + return new String(comment, "ISO-8859-1"); + } + catch (UnsupportedEncodingException e) { + throw new InternalError(e.toString()); + } + } + + public void setCRC(long crc){ + this.crc = crc; + } + + public long getCRC(){ + return crc; + } + + void put(Deflate d){ + int flag = 0; + if(text){ + flag |= 1; // FTEXT + } + if(fhcrc){ + flag |= 2; // FHCRC + } + if(extra!=null){ + flag |= 4; // FEXTRA + } + if(name!=null){ + flag |= 8; // FNAME + } + if(comment!=null){ + flag |= 16; // FCOMMENT + } + int xfl = 0; + if(d.level == JZlib.Z_BEST_SPEED){ + xfl |= 4; + } + else if (d.level == JZlib.Z_BEST_COMPRESSION){ + xfl |= 2; + } + + d.put_short((short)0x8b1f); // ID1 ID2 + d.put_byte((byte)8); // CM(Compression Method) + d.put_byte((byte)flag); + d.put_byte((byte)mtime); + d.put_byte((byte)(mtime>>8)); + d.put_byte((byte)(mtime>>16)); + d.put_byte((byte)(mtime>>24)); + d.put_byte((byte)xfl); + d.put_byte((byte)os); + + if(extra!=null){ + d.put_byte((byte)extra.length); + d.put_byte((byte)(extra.length>>8)); + d.put_byte(extra, 0, extra.length); + } + + if(name!=null){ + d.put_byte(name, 0, name.length); + d.put_byte((byte)0); + } + + if(comment!=null){ + d.put_byte(comment, 0, comment.length); + d.put_byte((byte)0); + } + } + + @Override + public Object clone() throws CloneNotSupportedException { + GZIPHeader gheader = (GZIPHeader)super.clone(); + byte[] tmp; + if(gheader.extra!=null){ + tmp=new byte[gheader.extra.length]; + System.arraycopy(gheader.extra, 0, tmp, 0, tmp.length); + gheader.extra = tmp; + } + + if(gheader.name!=null){ + tmp=new byte[gheader.name.length]; + System.arraycopy(gheader.name, 0, tmp, 0, tmp.length); + gheader.name = tmp; + } + + if(gheader.comment!=null){ + tmp=new byte[gheader.comment.length]; + System.arraycopy(gheader.comment, 0, tmp, 0, tmp.length); + gheader.comment = tmp; + } + + return gheader; + } +} diff --git a/java/com/jcraft/jzlib/InfBlocks.java b/java/com/jcraft/jzlib/InfBlocks.java index f6997fc6..6793c606 100644 --- a/java/com/jcraft/jzlib/InfBlocks.java +++ b/java/com/jcraft/jzlib/InfBlocks.java @@ -1,6 +1,6 @@ /* -*-mode:java; c-basic-offset:2; -*- */ /* -Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -81,7 +81,15 @@ final class InfBlocks{ int[] bb=new int[1]; // bit length tree depth int[] tb=new int[1]; // bit length decoding tree - InfCodes codes=new InfCodes(); // if CODES, current state + int[] bl=new int[1]; + int[] bd=new int[1]; + + int[][] tl=new int[1][]; + int[][] td=new int[1][]; + int[] tli=new int[1]; // tl_index + int[] tdi=new int[1]; // td_index + + private final InfCodes codes; // if CODES, current state int last; // true if this block is the last block @@ -93,22 +101,24 @@ final class InfBlocks{ int end; // one byte after sliding window int read; // window read pointer int write; // window write pointer - Object checkfn; // check function - long check; // check on output + private boolean check; + + private final InfTree inftree=new InfTree(); - InfTree inftree=new InfTree(); + private final ZStream z; - InfBlocks(ZStream z, Object checkfn, int w){ + InfBlocks(ZStream z, int w){ + this.z=z; + this.codes=new InfCodes(this.z, this); hufts=new int[MANY*3]; window=new byte[w]; end=w; - this.checkfn = checkfn; + this.check = (z.istate.wrap==0) ? false : true; mode = TYPE; - reset(z, null); + reset(); } - void reset(ZStream z, long[] c){ - if(c!=null) c[0]=check; + void reset(){ if(mode==BTREE || mode==DTREE){ } if(mode==CODES){ @@ -118,12 +128,12 @@ final class InfBlocks{ bitk=0; bitb=0; read=write=0; - - if(checkfn != null) - z.adler=check=z._adler.adler32(0L, null, 0, 0); + if(check){ + z.adler.reset(); + } } - int proc(ZStream z, int r){ + int proc(int r){ int t; // temporary storage int b; // bit buffer int k; // bits in bit buffer @@ -150,7 +160,7 @@ final class InfBlocks{ z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p; write=q; - return inflate_flush(z,r); + return inflate_flush(r); }; n--; b|=(z.next_in[p++]&0xff)<>>=(3);k-=(3);} @@ -198,7 +201,7 @@ final class InfBlocks{ bitb=b; bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; write=q; - return inflate_flush(z,r); + return inflate_flush(r); } break; case LENS: @@ -212,7 +215,7 @@ final class InfBlocks{ z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p; write=q; - return inflate_flush(z,r); + return inflate_flush(r); }; n--; b|=(z.next_in[p++]&0xff)<> 5) & 0x1f); if(blens==null || blens.length> 5) & 0x1f), - blens, bl, bd, tl, td, hufts, z); + blens, bl, bd, tli, tdi, hufts, z); if (t != Z_OK){ if (t == Z_DATA_ERROR){ @@ -471,9 +469,9 @@ final class InfBlocks{ bitb=b; bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; write=q; - return inflate_flush(z,r); + return inflate_flush(r); } - codes.init(bl[0], bd[0], hufts, tl[0], hufts, td[0], z); + codes.init(bl[0], bd[0], hufts, tli[0], hufts, tdi[0]); } mode = CODES; case CODES: @@ -481,8 +479,8 @@ final class InfBlocks{ z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p; write=q; - if ((r = codes.proc(this, z, r)) != Z_STREAM_END){ - return inflate_flush(z, r); + if ((r = codes.proc(r)) != Z_STREAM_END){ + return inflate_flush(r); } r = Z_OK; codes.free(z); @@ -497,13 +495,13 @@ final class InfBlocks{ mode = DRY; case DRY: write=q; - r=inflate_flush(z, r); + r=inflate_flush(r); q=write; m=(int)(q z.avail_out) n = z.avail_out; - if (n!=0 && r == Z_BUF_ERROR) r = Z_OK; + if(n > z.avail_out) n = z.avail_out; + if(n!=0 && r == Z_BUF_ERROR) r = Z_OK; // update counters z.avail_out -= n; z.total_out += n; // update check information - if(checkfn != null) - z.adler=check=z._adler.adler32(check, window, q, n); + if(check && n>0){ + z.adler.update(window, q, n); + } // copy as far as end of window System.arraycopy(window, q, z.next_out, p, n); @@ -595,8 +594,9 @@ final class InfBlocks{ z.total_out += n; // update check information - if(checkfn != null) - z.adler=check=z._adler.adler32(check, window, q, n); + if(check && n>0){ + z.adler.update(window, q, n); + } // copy System.arraycopy(window, q, z.next_out, p, n); diff --git a/java/com/jcraft/jzlib/InfCodes.java b/java/com/jcraft/jzlib/InfCodes.java index c768fb1c..aaf69cd4 100644 --- a/java/com/jcraft/jzlib/InfCodes.java +++ b/java/com/jcraft/jzlib/InfCodes.java @@ -89,11 +89,16 @@ final class InfCodes{ int[] dtree; // distance tree int dtree_index; // distance tree - InfCodes(){ + private final ZStream z; + private final InfBlocks s; + InfCodes(ZStream z, InfBlocks s){ + this.z=z; + this.s=s; } + void init(int bl, int bd, int[] tl, int tl_index, - int[] td, int td_index, ZStream z){ + int[] td, int td_index){ mode=START; lbits=(byte)bl; dbits=(byte)bd; @@ -104,7 +109,7 @@ final class InfCodes{ tree=null; } - int proc(InfBlocks s, ZStream z, int r){ + int proc(int r){ int j; // temporary storage int[] t; // temporary pointer int tindex; // temporary pointer @@ -159,7 +164,7 @@ final class InfCodes{ s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; - return s.inflate_flush(z,r); + return s.inflate_flush(r); } n--; b|=(z.next_in[p++]&0xff)<state); + int inflateEnd(){ + if(blocks != null){ + blocks.free(); + } return Z_OK; } - int inflateInit(ZStream z, int w){ + Inflate(ZStream z){ + this.z=z; + } + + int inflateInit(int w){ z.msg = null; blocks = null; - // handle undocumented nowrap option (no zlib header or check) - nowrap = 0; + // handle undocumented wrap option (no zlib header or check) + wrap = 0; if(w < 0){ w = - w; - nowrap = 1; + } + else { + wrap = (w >> 4) + 1; + if(w < 48) + w &= 15; } - // set window size if(w<8 ||w>15){ - inflateEnd(z); + inflateEnd(); return Z_STREAM_ERROR; } + if(blocks != null && wbits != w){ + blocks.free(); + blocks=null; + } + + // set window size wbits=w; - z.istate.blocks=new InfBlocks(z, - z.istate.nowrap!=0 ? null : this, - 1<>4)+8>z.istate.wbits){ - z.istate.mode = BAD; - z.msg="invalid window size"; - z.istate.marker = 5; // can't try inflateSync + } + + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + + if((wrap&2)!=0 && this.need == 0x8b1fL) { // gzip header + z.adler=new CRC32(); + checksum(2, this.need); + + if(gheader==null) + gheader=new GZIPHeader(); + + this.mode = FLAGS; break; } - z.istate.mode=FLAG; - case FLAG: - if(z.avail_in==0)return r;r=f; + flags = 0; - z.avail_in--; z.total_in++; - b = (z.next_in[z.next_in_index++])&0xff; + this.method = ((int)this.need)&0xff; + b=((int)(this.need>>8))&0xff; - if((((z.istate.method << 8)+b) % 31)!=0){ - z.istate.mode = BAD; + if((wrap&1)==0 || // check if zlib header allowed + (((this.method << 8)+b) % 31)!=0){ + this.mode = BAD; z.msg = "incorrect header check"; - z.istate.marker = 5; // can't try inflateSync + // since zlib 1.2, it is allowted to inflateSync for this case. + /* + this.marker = 5; // can't try inflateSync + */ + break; + } + + if((this.method&0xf)!=Z_DEFLATED){ + this.mode = BAD; + z.msg="unknown compression method"; + // since zlib 1.2, it is allowted to inflateSync for this case. + /* + this.marker = 5; // can't try inflateSync + */ break; } + if((this.method>>4)+8>this.wbits){ + this.mode = BAD; + z.msg="invalid window size"; + // since zlib 1.2, it is allowted to inflateSync for this case. + /* + this.marker = 5; // can't try inflateSync + */ + break; + } + + z.adler=new Adler32(); + if((b&PRESET_DICT)==0){ - z.istate.mode = BLOCKS; + this.mode = BLOCKS; break; } - z.istate.mode = DICT4; + this.mode = DICT4; case DICT4: if(z.avail_in==0)return r;r=f; z.avail_in--; z.total_in++; - z.istate.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; - z.istate.mode=DICT3; + this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; + this.mode=DICT3; case DICT3: if(z.avail_in==0)return r;r=f; z.avail_in--; z.total_in++; - z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; - z.istate.mode=DICT2; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; + this.mode=DICT2; case DICT2: if(z.avail_in==0)return r;r=f; z.avail_in--; z.total_in++; - z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; - z.istate.mode=DICT1; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; + this.mode=DICT1; case DICT1: if(z.avail_in==0)return r;r=f; z.avail_in--; z.total_in++; - z.istate.need += (z.next_in[z.next_in_index++]&0xffL); - z.adler = z.istate.need; - z.istate.mode = DICT0; + this.need += (z.next_in[z.next_in_index++]&0xffL); + z.adler.reset(this.need); + this.mode = DICT0; return Z_NEED_DICT; case DICT0: - z.istate.mode = BAD; + this.mode = BAD; z.msg = "need dictionary"; - z.istate.marker = 0; // can try inflateSync + this.marker = 0; // can try inflateSync return Z_STREAM_ERROR; case BLOCKS: - - r = z.istate.blocks.proc(z, r); + r = this.blocks.proc(r); if(r == Z_DATA_ERROR){ - z.istate.mode = BAD; - z.istate.marker = 0; // can try inflateSync + this.mode = BAD; + this.marker = 0; // can try inflateSync break; } if(r == Z_OK){ @@ -235,100 +298,280 @@ final class Inflate{ return r; } r = f; - z.istate.blocks.reset(z, z.istate.was); - if(z.istate.nowrap!=0){ - z.istate.mode=DONE; + this.was=z.adler.getValue(); + this.blocks.reset(); + if(this.wrap==0){ + this.mode=DONE; break; } - z.istate.mode=CHECK4; + this.mode=CHECK4; case CHECK4: if(z.avail_in==0)return r;r=f; z.avail_in--; z.total_in++; - z.istate.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; - z.istate.mode=CHECK3; + this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; + this.mode=CHECK3; case CHECK3: if(z.avail_in==0)return r;r=f; z.avail_in--; z.total_in++; - z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; - z.istate.mode = CHECK2; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; + this.mode = CHECK2; case CHECK2: if(z.avail_in==0)return r;r=f; z.avail_in--; z.total_in++; - z.istate.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; - z.istate.mode = CHECK1; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; + this.mode = CHECK1; case CHECK1: if(z.avail_in==0)return r;r=f; z.avail_in--; z.total_in++; - z.istate.need+=(z.next_in[z.next_in_index++]&0xffL); + this.need+=(z.next_in[z.next_in_index++]&0xffL); - if(((int)(z.istate.was[0])) != ((int)(z.istate.need))){ - z.istate.mode = BAD; + if(flags!=0){ // gzip + this.need = ((this.need&0xff000000)>>24 | + (this.need&0x00ff0000)>>8 | + (this.need&0x0000ff00)<<8 | + (this.need&0x0000ffff)<<24)&0xffffffffL; + } + + if(((int)(this.was)) != ((int)(this.need))){ z.msg = "incorrect data check"; - z.istate.marker = 5; // can't try inflateSync + // chack is delayed + /* + this.mode = BAD; + this.marker = 5; // can't try inflateSync break; + */ + } + else if(flags!=0 && gheader!=null){ + gheader.crc = this.need; } - z.istate.mode = DONE; + this.mode = LENGTH; + case LENGTH: + if (wrap!=0 && flags!=0) { + + try { r=readBytes(4, r, f); } + catch(Return e){ return e.r; } + + if(z.msg!=null && z.msg.equals("incorrect data check")){ + this.mode = BAD; + this.marker = 5; // can't try inflateSync + break; + } + + if (this.need != (z.total_out & 0xffffffffL)) { + z.msg = "incorrect length check"; + this.mode = BAD; + break; + } + z.msg = null; + } + else { + if(z.msg!=null && z.msg.equals("incorrect data check")){ + this.mode = BAD; + this.marker = 5; // can't try inflateSync + break; + } + } + + this.mode = DONE; case DONE: return Z_STREAM_END; case BAD: return Z_DATA_ERROR; + + case FLAGS: + + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + + flags = ((int)this.need)&0xffff; + + if ((flags & 0xff) != Z_DEFLATED) { + z.msg = "unknown compression method"; + this.mode = BAD; + break; + } + if ((flags & 0xe000)!=0) { + z.msg = "unknown header flags set"; + this.mode = BAD; + break; + } + + if ((flags & 0x0200)!=0){ + checksum(2, this.need); + } + + this.mode = TIME; + + case TIME: + try { r=readBytes(4, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null) + gheader.time = this.need; + if ((flags & 0x0200)!=0){ + checksum(4, this.need); + } + this.mode = OS; + case OS: + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null){ + gheader.xflags = ((int)this.need)&0xff; + gheader.os = (((int)this.need)>>8)&0xff; + } + if ((flags & 0x0200)!=0){ + checksum(2, this.need); + } + this.mode = EXLEN; + case EXLEN: + if ((flags & 0x0400)!=0) { + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null){ + gheader.extra = new byte[((int)this.need)&0xffff]; + } + if ((flags & 0x0200)!=0){ + checksum(2, this.need); + } + } + else if(gheader!=null){ + gheader.extra=null; + } + this.mode = EXTRA; + + case EXTRA: + if ((flags & 0x0400)!=0) { + try { + r=readBytes(r, f); + if(gheader!=null){ + byte[] foo = tmp_string.toByteArray(); + tmp_string=null; + if(foo.length == gheader.extra.length){ + System.arraycopy(foo, 0, gheader.extra, 0, foo.length); + } + else{ + z.msg = "bad extra field length"; + this.mode = BAD; + break; + } + } + } + catch(Return e){ return e.r; } + } + else if(gheader!=null){ + gheader.extra=null; + } + this.mode = NAME; + case NAME: + if ((flags & 0x0800)!=0) { + try { + r=readString(r, f); + if(gheader!=null){ + gheader.name=tmp_string.toByteArray(); + } + tmp_string=null; + } + catch(Return e){ return e.r; } + } + else if(gheader!=null){ + gheader.name=null; + } + this.mode = COMMENT; + case COMMENT: + if ((flags & 0x1000)!=0) { + try { + r=readString(r, f); + if(gheader!=null){ + gheader.comment=tmp_string.toByteArray(); + } + tmp_string=null; + } + catch(Return e){ return e.r; } + } + else if(gheader!=null){ + gheader.comment=null; + } + this.mode = HCRC; + case HCRC: + if ((flags & 0x0200)!=0) { + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null){ + gheader.hcrc=(int)(this.need&0xffff); + } + if(this.need != (z.adler.getValue()&0xffffL)){ + this.mode = BAD; + z.msg = "header crc mismatch"; + this.marker = 5; // can't try inflateSync + break; + } + } + z.adler = new CRC32(); + + this.mode = BLOCKS; + break; default: return Z_STREAM_ERROR; } } } + int inflateSetDictionary(byte[] dictionary, int dictLength){ + if(z==null || (this.mode != DICT0 && this.wrap != 0)){ + return Z_STREAM_ERROR; + } - int inflateSetDictionary(ZStream z, byte[] dictionary, int dictLength){ int index=0; int length = dictLength; - if(z==null || z.istate == null|| z.istate.mode != DICT0) - return Z_STREAM_ERROR; - if(z._adler.adler32(1L, dictionary, 0, dictLength)!=z.adler){ - return Z_DATA_ERROR; + if(this.mode==DICT0){ + long adler_need=z.adler.getValue(); + z.adler.reset(); + z.adler.update(dictionary, 0, dictLength); + if(z.adler.getValue()!=adler_need){ + return Z_DATA_ERROR; + } } - z.adler = z._adler.adler32(0, null, 0, 0); + z.adler.reset(); - if(length >= (1<= (1<0){ + if(z.avail_in==0){ throw new Return(r); }; r=f; + z.avail_in--; z.total_in++; + this.need = this.need | + ((z.next_in[z.next_in_index++]&0xff)<<((n-need_bytes)*8)); + need_bytes--; + } + if(n==2){ + this.need&=0xffffL; + } + else if(n==4) { + this.need&=0xffffffffL; + } + need_bytes=-1; + return r; + } + class Return extends Exception{ + int r; + Return(int r){this.r=r; } + } + + private java.io.ByteArrayOutputStream tmp_string = null; + private int readString(int r, int f) throws Return{ + if(tmp_string == null){ + tmp_string=new java.io.ByteArrayOutputStream(); + } + int b=0; + do { + if(z.avail_in==0){ throw new Return(r); }; r=f; + z.avail_in--; z.total_in++; + b = z.next_in[z.next_in_index]; + if(b!=0) tmp_string.write(z.next_in, z.next_in_index, 1); + z.adler.update(z.next_in, z.next_in_index, 1); + z.next_in_index++; + }while(b!=0); + return r; + } + + private int readBytes(int r, int f) throws Return{ + if(tmp_string == null){ + tmp_string=new java.io.ByteArrayOutputStream(); + } + int b=0; + while(this.need>0){ + if(z.avail_in==0){ throw new Return(r); }; r=f; + z.avail_in--; z.total_in++; + b = z.next_in[z.next_in_index]; + tmp_string.write(z.next_in, z.next_in_index, 1); + z.adler.update(z.next_in, z.next_in_index, 1); + z.next_in_index++; + this.need--; + } + return r; + } + + private void checksum(int n, long v){ + for(int i=0; i>=8; + } + z.adler.update(crcbuf, 0, n); + } + + public GZIPHeader getGZIPHeader(){ + return gheader; + } + + boolean inParsingHeader(){ + switch(mode){ + case HEAD: + case DICT4: + case DICT3: + case DICT2: + case DICT1: + case FLAGS: + case TIME: + case OS: + case EXLEN: + case EXTRA: + case NAME: + case COMMENT: + case HCRC: + return true; + default: + return false; + } } } diff --git a/java/com/jcraft/jzlib/JZlib.java b/java/com/jcraft/jzlib/JZlib.java index b84d7a1f..8fd98ea7 100644 --- a/java/com/jcraft/jzlib/JZlib.java +++ b/java/com/jcraft/jzlib/JZlib.java @@ -1,6 +1,6 @@ /* -*-mode:java; c-basic-offset:2; -*- */ /* -Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -35,9 +35,12 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jzlib; final public class JZlib{ - private static final String version="1.0.2"; + private static final String version="1.1.0"; public static String version(){return version;} + static final public int MAX_WBITS=15; // 32K LZ77 window + static final public int DEF_WBITS=MAX_WBITS; + // compression levels static final public int Z_NO_COMPRESSION=0; static final public int Z_BEST_SPEED=1; @@ -64,4 +67,17 @@ final public class JZlib{ static final public int Z_MEM_ERROR=-4; static final public int Z_BUF_ERROR=-5; static final public int Z_VERSION_ERROR=-6; + + // The three kinds of block type + static final public byte Z_BINARY = 0; + static final public byte Z_ASCII = 1; + static final public byte Z_UNKNOWN = 2; + + public static long adler32_combine(long adler1, long adler2, long len2){ + return Adler32.combine(adler1, adler2, len2); + } + + public static long crc32_combine(long crc1, long crc2, long len2){ + return CRC32.combine(crc1, crc2, len2); + } } diff --git a/java/com/jcraft/jzlib/LICENSE.txt b/java/com/jcraft/jzlib/LICENSE.txt index cdce5007..6859c59d 100644 --- a/java/com/jcraft/jzlib/LICENSE.txt +++ b/java/com/jcraft/jzlib/LICENSE.txt @@ -2,7 +2,7 @@ JZlib 0.0.* were released under the GNU LGPL license. Later, we have switched over to a BSD-style license. ------------------------------------------------------------------------------ -Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. +Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/java/com/jcraft/jzlib/README b/java/com/jcraft/jzlib/README index 45027db9..69aec563 100644 --- a/java/com/jcraft/jzlib/README +++ b/java/com/jcraft/jzlib/README @@ -6,7 +6,7 @@ http://www.jcraft.com/jzlib/ -Last modified: Fri Feb 14 13:31:26 UTC 2003 +Last modified: Mon Sep 19 15:28:43 UTC 2011 Description =========== @@ -25,7 +25,7 @@ Documentation Directories & Files in the Source Tree ====================================== -* com/ has source trees of JZlib. +* src/main/java has source trees of JZlib. * example/ has some samples, which demonstrate the usages. * misc/ has some stuffs. At present, this directory includes a patch file for MindTerm v.1.2.1, which adds the packet compression @@ -40,7 +40,7 @@ Features * JZlib does not support gzip file handling supports. * The performance has not been estimated yet, but it will be not so bad in deflating/inflating data stream on the low bandwidth network. -* JZlib is licensed under BSD style license. +* JZlib is under BSD style license. * Any invention has not been done in developing JZlib. So, if zlib is patent free, JZlib is also not covered by any patents. @@ -73,6 +73,18 @@ so this problem will not be solved forever. This is our motivation to hack JZlib. +Building Jar File +================= +Use 'sbt'(https://github.com/harrah/xsbt/wiki), + % sbt package +or + % mvn package +or + % cd src/main/java + % javac -target 1.5 com/jcraft/jzlib/*.java + % jar -cvf jzlib.jar com/jcraft/jzlib/*.class + + A unofficial patch for MindTerm v.1.2.1 ======================================= A unofficial patch file for MindTerm v.1.2.1 has included in 'misc' directory. @@ -84,7 +96,6 @@ Copyrights & Disclaimers ======================== JZlib is copyrighted by ymnk, JCraft,Inc. and is licensed through BSD style license. Read the LICENSE.txt file for the complete license. -ZInputStream and ZOutputStream classes were contributed by Lapo Luchini. Credits diff --git a/java/com/jcraft/jzlib/StaticTree.java b/java/com/jcraft/jzlib/StaticTree.java index 0f7f5779..e35931c3 100644 --- a/java/com/jcraft/jzlib/StaticTree.java +++ b/java/com/jcraft/jzlib/StaticTree.java @@ -134,12 +134,11 @@ final class StaticTree{ int elems; // max number of elements in the tree int max_length; // max bit length for the codes - StaticTree(short[] static_tree, - int[] extra_bits, - int extra_base, - int elems, - int max_length - ){ + private StaticTree(short[] static_tree, + int[] extra_bits, + int extra_base, + int elems, + int max_length){ this.static_tree=static_tree; this.extra_bits=extra_bits; this.extra_base=extra_base; diff --git a/java/com/jcraft/jzlib/Tree.java b/java/com/jcraft/jzlib/Tree.java index 81038978..40b6ba87 100644 --- a/java/com/jcraft/jzlib/Tree.java +++ b/java/com/jcraft/jzlib/Tree.java @@ -317,17 +317,18 @@ final class Tree{ // 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. - static void gen_codes(short[] tree, // the tree to decorate - int max_code, // largest code with non zero frequency - short[] bl_count // number of codes at each bit length - ){ - short[] next_code=new short[MAX_BITS+1]; // next code value for each bit length + static short[] next_code=new short[MAX_BITS+1]; // next code value for each bit length + synchronized static void gen_codes(short[] tree, // the tree to decorate + int max_code, // largest code with non zero frequency + short[] bl_count // number of codes at each bit length + ){ short 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. + next_code[0]=0; for (bits = 1; bits <= MAX_BITS; bits++) { next_code[bits] = code = (short)((code + bl_count[bits-1]) << 1); } diff --git a/java/com/jcraft/jzlib/ZInputStream.java b/java/com/jcraft/jzlib/ZInputStream.java index 3f97c448..0054645e 100644 --- a/java/com/jcraft/jzlib/ZInputStream.java +++ b/java/com/jcraft/jzlib/ZInputStream.java @@ -1,6 +1,6 @@ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -Copyright (c) 2001 Lapo Luchini. +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -17,8 +17,8 @@ modification, are permitted provided that the following conditions are met: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS -OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF @@ -26,91 +26,71 @@ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ package com.jcraft.jzlib; import java.io.*; +/** + * ZInputStream + * + * @deprecated use DeflaterOutputStream or InflaterInputStream + */ +@Deprecated public class ZInputStream extends FilterInputStream { - protected ZStream z=new ZStream(); - protected int bufsize=512; protected int flush=JZlib.Z_NO_FLUSH; - protected byte[] buf=new byte[bufsize], - buf1=new byte[1]; protected boolean compress; - protected InputStream in=null; - public ZInputStream(InputStream in) { + protected Deflater deflater; + protected InflaterInputStream iis; + + public ZInputStream(InputStream in) throws IOException { this(in, false); } - public ZInputStream(InputStream in, boolean nowrap) { + public ZInputStream(InputStream in, boolean nowrap) throws IOException { super(in); - this.in=in; - z.inflateInit(nowrap); + iis = new InflaterInputStream(in); compress=false; - z.next_in=buf; - z.next_in_index=0; - z.avail_in=0; } - public ZInputStream(InputStream in, int level) { + public ZInputStream(InputStream in, int level) throws IOException { super(in); this.in=in; - z.deflateInit(level); + deflater = new Deflater(); + deflater.init(level); compress=true; - z.next_in=buf; - z.next_in_index=0; - z.avail_in=0; } - /*public int available() throws IOException { - return inf.finished() ? 0 : 1; - }*/ - + private byte[] buf1 = new byte[1]; public int read() throws IOException { - if(read(buf1, 0, 1)==-1) - return(-1); + if(read(buf1, 0, 1)==-1) return -1; return(buf1[0]&0xFF); } - private boolean nomoreinput=false; + private byte[] buf = new byte[512]; public int read(byte[] b, int off, int len) throws IOException { - if(len==0) - return(0); - int err; - z.next_out=b; - z.next_out_index=off; - z.avail_out=len; - do { - if((z.avail_in==0)&&(!nomoreinput)) { // if buffer is empty and more input is avaiable, refill it - z.next_in_index=0; - z.avail_in=in.read(buf, 0, bufsize);//(bufsize0) + return deflater.next_out_index; + if(err == JZlib.Z_STREAM_END) + return 0; + if(err == JZlib.Z_STREAM_ERROR || + err == JZlib.Z_DATA_ERROR){ + throw new ZStreamException("deflating: "+deflater.msg); + } } - if(compress) - err=z.deflate(flush); - else - err=z.inflate(flush); - if(nomoreinput&&(err==JZlib.Z_BUF_ERROR)) - return(-1); - if(err!=JZlib.Z_OK && err!=JZlib.Z_STREAM_END) - throw new ZStreamException((compress ? "de" : "in")+"flating: "+z.msg); - if((nomoreinput||err==JZlib.Z_STREAM_END)&&(z.avail_out==len)) - return(-1); - } - while(z.avail_out==len&&err==JZlib.Z_OK); - //System.err.print("("+(len-z.avail_out)+")"); - return(len-z.avail_out); + } + else{ + return iis.read(b, off, len); + } } public long skip(long n) throws IOException { @@ -122,28 +102,25 @@ public class ZInputStream extends FilterInputStream { } public int getFlushMode() { - return(flush); + return flush; } public void setFlushMode(int flush) { this.flush=flush; } - /** - * Returns the total number of bytes input so far. - */ public long getTotalIn() { - return z.total_in; + if(compress) return deflater.total_in; + else return iis.getTotalIn(); } - /** - * Returns the total number of bytes output so far. - */ public long getTotalOut() { - return z.total_out; + if(compress) return deflater.total_out; + else return iis.getTotalOut(); } public void close() throws IOException{ - in.close(); + if(compress) deflater.end(); + else iis.close(); } } diff --git a/java/com/jcraft/jzlib/ZOutputStream.java b/java/com/jcraft/jzlib/ZOutputStream.java index afee65b3..32074aa4 100644 --- a/java/com/jcraft/jzlib/ZOutputStream.java +++ b/java/com/jcraft/jzlib/ZOutputStream.java @@ -1,6 +1,6 @@ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -Copyright (c) 2001 Lapo Luchini. +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -17,8 +17,8 @@ modification, are permitted provided that the following conditions are met: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS -OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF @@ -26,72 +26,79 @@ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ package com.jcraft.jzlib; import java.io.*; -public class ZOutputStream extends OutputStream { +/** + * ZOutputStream + * + * @deprecated use DeflaterOutputStream or InflaterInputStream + */ +@Deprecated +public class ZOutputStream extends FilterOutputStream { - protected ZStream z=new ZStream(); protected int bufsize=512; protected int flush=JZlib.Z_NO_FLUSH; - protected byte[] buf=new byte[bufsize], - buf1=new byte[1]; + protected byte[] buf=new byte[bufsize]; protected boolean compress; protected OutputStream out; + private boolean end=false; + + private DeflaterOutputStream dos; + private Inflater inflater; - public ZOutputStream(OutputStream out) { - super(); + public ZOutputStream(OutputStream out) throws IOException { + super(out); this.out=out; - z.inflateInit(); + inflater = new Inflater(); + inflater.init(); compress=false; } - public ZOutputStream(OutputStream out, int level) { + public ZOutputStream(OutputStream out, int level) throws IOException { this(out, level, false); } - public ZOutputStream(OutputStream out, int level, boolean nowrap) { - super(); + + public ZOutputStream(OutputStream out, int level, boolean nowrap) throws IOException { + super(out); this.out=out; - z.deflateInit(level, nowrap); + Deflater deflater = new Deflater(level, nowrap); + dos = new DeflaterOutputStream(out, deflater); compress=true; } + private byte[] buf1 = new byte[1]; public void write(int b) throws IOException { buf1[0]=(byte)b; write(buf1, 0, 1); } public void write(byte b[], int off, int len) throws IOException { - if(len==0) + if(len==0) return; + if(compress){ + dos.write(b, off, len); + } + else { + inflater.setInput(b, off, len, true); + int err = JZlib.Z_OK; + while(inflater.avail_in>0){ + inflater.setOutput(buf, 0, buf.length); + err = inflater.inflate(flush); + if(inflater.next_out_index>0) + out.write(buf, 0, inflater.next_out_index); + if(err != JZlib.Z_OK) + break; + } + if(err != JZlib.Z_OK) + throw new ZStreamException("inflating: "+inflater.msg); return; - int err; - z.next_in=b; - z.next_in_index=off; - z.avail_in=len; - do{ - z.next_out=buf; - z.next_out_index=0; - z.avail_out=bufsize; - if(compress) - err=z.deflate(flush); - else - err=z.inflate(flush); - if(err!=JZlib.Z_OK) - throw new ZStreamException((compress?"de":"in")+"flating: "+z.msg); - out.write(buf, 0, bufsize-z.avail_out); - } - while(z.avail_in>0 || z.avail_out==0); + } } public int getFlushMode() { - return(flush); + return flush; } public void setFlushMode(int flush) { @@ -100,28 +107,28 @@ public class ZOutputStream extends OutputStream { public void finish() throws IOException { int err; - do{ - z.next_out=buf; - z.next_out_index=0; - z.avail_out=bufsize; - if(compress){ err=z.deflate(JZlib.Z_FINISH); } - else{ err=z.inflate(JZlib.Z_FINISH); } - if(err!=JZlib.Z_STREAM_END && err != JZlib.Z_OK) - throw new ZStreamException((compress?"de":"in")+"flating: "+z.msg); - if(bufsize-z.avail_out>0){ - out.write(buf, 0, bufsize-z.avail_out); + if(compress){ + int tmp = flush; + int flush = JZlib.Z_FINISH; + try{ + write("".getBytes(), 0, 0); } + finally { flush = tmp; } + } + else{ + dos.finish(); } - while(z.avail_in>0 || z.avail_out==0); flush(); } - public void end() { - if(z==null) - return; - if(compress){ z.deflateEnd(); } - else{ z.inflateEnd(); } - z.free(); - z=null; + public synchronized void end() { + if(end) return; + if(compress){ + try { dos.finish(); } catch(Exception e){} + } + else{ + inflater.end(); + } + end=true; } public void close() throws IOException { try{ @@ -135,18 +142,14 @@ public class ZOutputStream extends OutputStream { } } - /** - * Returns the total number of bytes input so far. - */ public long getTotalIn() { - return z.total_in; + if(compress) return dos.getTotalIn(); + else return inflater.total_in; } - /** - * Returns the total number of bytes output so far. - */ public long getTotalOut() { - return z.total_out; + if(compress) return dos.getTotalOut(); + else return inflater.total_out; } public void flush() throws IOException { diff --git a/java/com/jcraft/jzlib/ZStream.java b/java/com/jcraft/jzlib/ZStream.java index 334475e9..dd0a5256 100644 --- a/java/com/jcraft/jzlib/ZStream.java +++ b/java/com/jcraft/jzlib/ZStream.java @@ -1,6 +1,6 @@ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. +Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -34,7 +34,13 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jzlib; -final public class ZStream{ +/** + * ZStream + * + * @deprecated Not for public use in the future. + */ +@Deprecated +public class ZStream{ static final private int MAX_WBITS=15; // 32K LZ77 window static final private int DEF_WBITS=MAX_WBITS; @@ -74,8 +80,15 @@ final public class ZStream{ int data_type; // best guess about the data type: ascii or binary - public long adler; - Adler32 _adler=new Adler32(); + Checksum adler; + + public ZStream(){ + this(new Adler32()); + } + + public ZStream(Checksum adler){ + this.adler=adler; + } public int inflateInit(){ return inflateInit(DEF_WBITS); @@ -88,29 +101,37 @@ final public class ZStream{ } public int inflateInit(int w, boolean nowrap){ - istate=new Inflate(); - return istate.inflateInit(this, nowrap?-w:w); + istate=new Inflate(this); + return istate.inflateInit(nowrap?-w:w); } public int inflate(int f){ if(istate==null) return Z_STREAM_ERROR; - return istate.inflate(this, f); + return istate.inflate(f); } public int inflateEnd(){ if(istate==null) return Z_STREAM_ERROR; - int ret=istate.inflateEnd(this); - istate = null; + int ret=istate.inflateEnd(); +// istate = null; return ret; } public int inflateSync(){ if(istate == null) return Z_STREAM_ERROR; - return istate.inflateSync(this); + return istate.inflateSync(); + } + public int inflateSyncPoint(){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSyncPoint(); } public int inflateSetDictionary(byte[] dictionary, int dictLength){ if(istate == null) return Z_STREAM_ERROR; - return istate.inflateSetDictionary(this, dictionary, dictLength); + return istate.inflateSetDictionary(dictionary, dictLength); + } + public boolean inflateFinished(){ + return istate.mode==12 /*DONE*/; } public int deflateInit(int level){ @@ -122,15 +143,19 @@ final public class ZStream{ public int deflateInit(int level, int bits){ return deflateInit(level, bits, false); } + public int deflateInit(int level, int bits, int memlevel){ + dstate=new Deflate(this); + return dstate.deflateInit(level, bits, memlevel); + } public int deflateInit(int level, int bits, boolean nowrap){ - dstate=new Deflate(); - return dstate.deflateInit(this, level, nowrap?-bits:bits); + dstate=new Deflate(this); + return dstate.deflateInit(level, nowrap?-bits:bits); } public int deflate(int flush){ if(dstate==null){ return Z_STREAM_ERROR; } - return dstate.deflate(this, flush); + return dstate.deflate(flush); } public int deflateEnd(){ if(dstate==null) return Z_STREAM_ERROR; @@ -140,12 +165,12 @@ final public class ZStream{ } public int deflateParams(int level, int strategy){ if(dstate==null) return Z_STREAM_ERROR; - return dstate.deflateParams(this, level, strategy); + return dstate.deflateParams(level, strategy); } public int deflateSetDictionary (byte[] dictionary, int dictLength){ if(dstate == null) return Z_STREAM_ERROR; - return dstate.deflateSetDictionary(this, dictionary, dictLength); + return dstate.deflateSetDictionary(dictionary, dictLength); } // Flush as much pending output as possible. All deflate() output goes @@ -162,9 +187,9 @@ final public class ZStream{ next_out.length<=next_out_index || dstate.pending_buf.length<(dstate.pending_out+len) || next_out.length<(next_out_index+len)){ - System.out.println(dstate.pending_buf.length+", "+dstate.pending_out+ - ", "+next_out.length+", "+next_out_index+", "+len); - System.out.println("avail_out="+avail_out); + //System.out.println(dstate.pending_buf.length+", "+dstate.pending_out+ + // ", "+next_out.length+", "+next_out_index+", "+len); + //System.out.println("avail_out="+avail_out); } System.arraycopy(dstate.pending_buf, dstate.pending_out, @@ -193,8 +218,8 @@ final public class ZStream{ avail_in-=len; - if(dstate.noheader==0) { - adler=_adler.adler32(adler, next_in, next_in_index, len); + if(dstate.wrap!=0) { + adler.update(next_in, next_in_index, len); } System.arraycopy(next_in, next_in_index, buf, start, len); next_in_index += len; @@ -202,10 +227,117 @@ final public class ZStream{ return len; } + public long getAdler(){ + return adler.getValue(); + } + public void free(){ next_in=null; next_out=null; msg=null; - _adler=null; } + + public void setOutput(byte[] buf){ + setOutput(buf, 0, buf.length); + } + + public void setOutput(byte[] buf, int off, int len){ + next_out = buf; + next_out_index = off; + avail_out = len; + } + + public void setInput(byte[] buf){ + setInput(buf, 0, buf.length, false); + } + + public void setInput(byte[] buf, boolean append){ + setInput(buf, 0, buf.length, append); + } + + public void setInput(byte[] buf, int off, int len, boolean append){ + if(len<=0 && append && next_in!=null) return; + + if(avail_in>0 && append){ + byte[] tmp = new byte[avail_in+len]; + System.arraycopy(next_in, next_in_index, tmp, 0, avail_in); + System.arraycopy(buf, off, tmp, avail_in, len); + next_in=tmp; + next_in_index=0; + avail_in+=len; + } + else{ + next_in=buf; + next_in_index=off; + avail_in=len; + } + } + + public byte[] getNextIn(){ + return next_in; + } + + public void setNextIn(byte[] next_in){ + this.next_in = next_in; + } + + public int getNextInIndex(){ + return next_in_index; + } + + public void setNextInIndex(int next_in_index){ + this.next_in_index = next_in_index; + } + + public int getAvailIn(){ + return avail_in; + } + + public void setAvailIn(int avail_in){ + this.avail_in = avail_in; + } + + public byte[] getNextOut(){ + return next_out; + } + + public void setNextOut(byte[] next_out){ + this.next_out = next_out; + } + + public int getNextOutIndex(){ + return next_out_index; + } + + public void setNextOutIndex(int next_out_index){ + this.next_out_index = next_out_index; + } + + public int getAvailOut(){ + return avail_out; + + } + + public void setAvailOut(int avail_out){ + this.avail_out = avail_out; + } + + public long getTotalOut(){ + return total_out; + } + + public long getTotalIn(){ + return total_in; + } + + public String getMessage(){ + return msg; + } + + /** + * Those methods are expected to be override by Inflater and Deflater. + * In the future, they will become abstract methods. + */ + public int end(){ return Z_OK; } + public boolean finished(){ return false; } } -- 2.39.5