//
package net.sf.zipme;
/**
* This is the Deflater class. The deflater class compresses input
* with the deflate algorithm described in RFC 1951. It has several
* compression levels and three different strategies described below.
* This class is <i>not</i> thread safe. This is inherent in the API, due
* to the split of deflate and setInput.
* @author Jochen Hoenicke
* @author Tom Tromey
*/
public class Deflater {
/**
* The best and slowest compression level. This tries to find very
* long and distant string repetitions.
*/
public static final int BEST_COMPRESSION=9;
/**
* The worst but fastest compression level.
*/
public static final int BEST_SPEED=1;
/**
* The default compression level.
*/
public static final int DEFAULT_COMPRESSION=-1;
/**
* This level won't compress at all but output uncompressed blocks.
*/
public static final int NO_COMPRESSION=0;
/**
* The default strategy.
*/
public static final int DEFAULT_STRATEGY=0;
/**
* This strategy will only allow longer string repetitions. It is
* useful for random data with a small character set.
*/
public static final int FILTERED=1;
/**
* This strategy will not look for string repetitions at all. It
* only encodes with Huffman trees (which means, that more common
* characters get a smaller encoding.
*/
public static final int HUFFMAN_ONLY=2;
/**
* The compression method. This is the only method supported so far.
* There is no need to use this constant at all.
*/
public static final int DEFLATED=8;
public static final int IS_SETDICT=0x01;
public static final int IS_FLUSHING=0x04;
public static final int IS_FINISHING=0x08;
private static final int INIT_STATE=0x00;
private static final int SETDICT_STATE=0x01;
private static final int INIT_FINISHING_STATE=0x08;
private static final int SETDICT_FINISHING_STATE=0x09;
public static final int BUSY_STATE=0x10;
public static final int FLUSHING_STATE=0x14;
public static final int FINISHING_STATE=0x1c;
public static final int FINISHED_STATE=0x1e;
public static final int CLOSED_STATE=0x7f;
/**
* Compression level.
*/
public int level;
/**
* should we include a header.
*/
public boolean noHeader;
/**
* The current state.
*/
public int state;
/**
* The total bytes of output written.
*/
public long totalOut;
/**
* The pending output.
*/
public DeflaterPending pending;
/**
* The deflater engine.
*/
public DeflaterEngine engine;
/**
* Creates a new deflater with default compression level.
*/
public Deflater(){
this(DEFAULT_COMPRESSION,false);
}
/**
* Creates a new deflater with given compression level.
* @param lvl the compression level, a value between NO_COMPRESSION
* and BEST_COMPRESSION, or DEFAULT_COMPRESSION.
* @exception IllegalArgumentException if lvl is out of range.
*/
public Deflater( int lvl){
this(lvl,false);
}
/**
* Creates a new deflater with given compression level.
* @param lvl the compression level, a value between NO_COMPRESSION
* and BEST_COMPRESSION.
* @param nowrap true, iff we should suppress the deflate header at the
* beginning and the adler checksum at the end of the output. This is
* useful for the GZIP format.
* @exception IllegalArgumentException if lvl is out of range.
*/
public Deflater( int lvl, boolean nowrap){
if (lvl == DEFAULT_COMPRESSION) lvl=6;
else if (lvl < NO_COMPRESSION || lvl > BEST_COMPRESSION) throw new IllegalArgumentException();
pending=new DeflaterPending();
this.hook25();
this.noHeader=nowrap;
this.hook24(lvl);
reset();
}
/**
* Resets the deflater. The deflater acts afterwards as if it was
* just created with the same compression level and strategy as it
* had before.
*/
public void reset(){
state=(noHeader ? BUSY_STATE : INIT_STATE);
totalOut=0;
pending.reset();
}
/**
* Frees all objects allocated by the compressor. There's no
* reason to call this, since you can just rely on garbage
* collection. Exists only for compatibility against Sun's JDK,
* where the compressor allocates native memory.
* If you call any method (even reset) afterwards the behaviour is
* <i>undefined</i>.
*/
public void end(){
pending=null;
state=CLOSED_STATE;
}
/**
* Gets the number of output bytes so far.
*/
public int getTotalOut(){
return (int)totalOut;
}
protected void hook24( int lvl){
}
protected void hook25(){
}
}