Frames | No Frames |
1: /* Deflater.java - Compress a data stream 2: Copyright (C) 1999, 2000, 2001, 2004, 2006 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: package java.util.zip; 39: 40: import gnu.gcj.RawData; 41: 42: /** 43: * This is the Deflater class. The deflater class compresses input 44: * with the deflate algorithm described in RFC 1951. It has several 45: * compression levels and three different strategies described below. 46: * 47: * This class is <i>not</i> thread safe. This is inherent in the API, due 48: * to the split of deflate and setInput. 49: * 50: * @author Jochen Hoenicke 51: * @author Tom Tromey 52: */ 53: public class Deflater 54: { 55: /** 56: * The best and slowest compression level. This tries to find very 57: * long and distant string repetitions. 58: */ 59: public static final int BEST_COMPRESSION = 9; 60: /** 61: * The worst but fastest compression level. 62: */ 63: public static final int BEST_SPEED = 1; 64: /** 65: * The default compression level. 66: */ 67: public static final int DEFAULT_COMPRESSION = -1; 68: /** 69: * This level won't compress at all but output uncompressed blocks. 70: */ 71: public static final int NO_COMPRESSION = 0; 72: 73: /** 74: * The default strategy. 75: */ 76: public static final int DEFAULT_STRATEGY = 0; 77: /** 78: * This strategy will only allow longer string repetitions. It is 79: * useful for random data with a small character set. 80: */ 81: public static final int FILTERED = 1; 82: 83: /** 84: * This strategy will not look for string repetitions at all. It 85: * only encodes with Huffman trees (which means, that more common 86: * characters get a smaller encoding. 87: */ 88: public static final int HUFFMAN_ONLY = 2; 89: 90: /** 91: * The compression method. This is the only method supported so far. 92: * There is no need to use this constant at all. 93: */ 94: public static final int DEFLATED = 8; 95: 96: /** Compression level. */ 97: private int level; 98: 99: /** Compression strategy. */ 100: private int strategy; 101: 102: /** The zlib stream. */ 103: private RawData zstream; 104: 105: /** True if finished. */ 106: private boolean is_finished; 107: 108: /** `Flush' flag to pass to next call to deflate. */ 109: private int flush_flag; 110: 111: /** 112: * Creates a new deflater with default compression level. 113: */ 114: public Deflater() 115: { 116: this(DEFAULT_COMPRESSION, false); 117: } 118: 119: /** 120: * Creates a new deflater with given compression level. 121: * @param lvl the compression level, a value between NO_COMPRESSION 122: * and BEST_COMPRESSION, or DEFAULT_COMPRESSION. 123: * @exception IllegalArgumentException if lvl is out of range. 124: */ 125: public Deflater(int lvl) 126: { 127: this(lvl, false); 128: } 129: 130: /** 131: * Creates a new deflater with given compression level. 132: * @param lvl the compression level, a value between NO_COMPRESSION 133: * and BEST_COMPRESSION. 134: * @param nowrap true, iff we should suppress the deflate header at the 135: * beginning and the adler checksum at the end of the output. This is 136: * useful for the GZIP format. 137: * @exception IllegalArgumentException if lvl is out of range. 138: */ 139: public Deflater(int lvl, boolean noHeader) 140: { 141: this.strategy = DEFAULT_STRATEGY; 142: init(lvl, noHeader); 143: setLevel(lvl); 144: } 145: 146: private native void init(int level, boolean noHeader); 147: 148: private native void update(); 149: 150: /** 151: * Resets the deflater. The deflater acts afterwards as if it was 152: * just created with the same compression level and strategy as it 153: * had before. 154: */ 155: public native void reset(); 156: 157: /** 158: * Frees all objects allocated by the compressor. There's no 159: * reason to call this, since you can just rely on garbage 160: * collection. Exists only for compatibility against Sun's JDK, 161: * where the compressor allocates native memory. 162: * If you call any method (even reset) afterwards the behaviour is 163: * <i>undefined</i>. 164: * @deprecated Just clear all references to deflater instead. 165: */ 166: public native void end(); 167: 168: /** 169: * Gets the current adler checksum of the data that was processed so 170: * far. 171: */ 172: public native int getAdler(); 173: 174: /** 175: * Gets the number of input bytes processed so far. 176: */ 177: public native int getTotalIn(); 178: 179: /** 180: * Gets the number of output bytes so far. 181: */ 182: public native int getTotalOut(); 183: 184: /** 185: * Finalizes this object. 186: */ 187: protected void finalize() 188: { 189: end(); 190: } 191: 192: /** 193: * Finishes the deflater with the current input block. It is an error 194: * to give more input after this method was called. This method must 195: * be called to force all bytes to be flushed. 196: */ 197: public native void finish(); 198: 199: /** 200: * Returns true iff the stream was finished and no more output bytes 201: * are available. 202: */ 203: public synchronized boolean finished() 204: { 205: return is_finished; 206: } 207: 208: /** 209: * Returns true, if the input buffer is empty. 210: * You should then call setInput(). <br> 211: * 212: * <em>NOTE</em>: This method can also return true when the stream 213: * was finished. 214: */ 215: public native boolean needsInput(); 216: 217: /** 218: * Sets the data which should be compressed next. This should be only 219: * called when needsInput indicates that more input is needed. 220: * If you call setInput when needsInput() returns false, the 221: * previous input that is still pending will be thrown away. 222: * The given byte array should not be changed, before needsInput() returns 223: * true again. 224: * This call is equivalent to <code>setInput(input, 0, input.length)</code>. 225: * @param input the buffer containing the input data. 226: * @exception IllegalStateException if the buffer was finished() or ended(). 227: */ 228: public void setInput(byte[] input) 229: { 230: setInput(input, 0, input.length); 231: } 232: 233: /** 234: * Sets the data which should be compressed next. This should be 235: * only called when needsInput indicates that more input is needed. 236: * The given byte array should not be changed, before needsInput() returns 237: * true again. 238: * @param input the buffer containing the input data. 239: * @param off the start of the data. 240: * @param len the length of the data. 241: * @exception IllegalStateException if the buffer was finished() or ended() 242: * or if previous input is still pending. 243: */ 244: public native void setInput(byte[] input, int off, int len); 245: 246: /** 247: * Sets the compression level. There is no guarantee of the exact 248: * position of the change, but if you call this when needsInput is 249: * true the change of compression level will occur somewhere near 250: * before the end of the so far given input. 251: * @param lvl the new compression level. 252: */ 253: public synchronized void setLevel(int lvl) 254: { 255: if (lvl != -1 && (lvl < 0 || lvl > 9)) 256: throw new IllegalArgumentException(); 257: level = (lvl == -1) ? 6 : lvl; 258: update(); 259: } 260: 261: /** 262: * Sets the compression strategy. Strategy is one of 263: * DEFAULT_STRATEGY, HUFFMAN_ONLY and FILTERED. For the exact 264: * position where the strategy is changed, the same as for 265: * setLevel() applies. 266: * @param stgy the new compression strategy. 267: */ 268: public synchronized void setStrategy(int stgy) 269: { 270: if (stgy != DEFAULT_STRATEGY && stgy != FILTERED 271: && stgy != HUFFMAN_ONLY) 272: throw new IllegalArgumentException(); 273: strategy = stgy; 274: update(); 275: } 276: 277: /** 278: * Deflates the current input block to the given array. It returns 279: * the number of bytes compressed, or 0 if either 280: * needsInput() or finished() returns true or length is zero. 281: * @param output the buffer where to write the compressed data. 282: */ 283: public int deflate(byte[] output) 284: { 285: return deflate(output, 0, output.length); 286: } 287: 288: /** 289: * Deflates the current input block to the given array. It returns 290: * the number of bytes compressed, or 0 if either 291: * needsInput() or finished() returns true or length is zero. 292: * @param output the buffer where to write the compressed data. 293: * @param offset the offset into the output array. 294: * @param length the maximum number of bytes that may be written. 295: * @exception IllegalStateException if end() was called. 296: * @exception IndexOutOfBoundsException if offset and/or length 297: * don't match the array length. 298: */ 299: public native int deflate(byte[] output, int off, int len); 300: 301: /** 302: * Sets the dictionary which should be used in the deflate process. 303: * This call is equivalent to <code>setDictionary(dict, 0, 304: * dict.length)</code>. 305: * @param dict the dictionary. 306: * @exception IllegalStateException if setInput () or deflate () 307: * were already called or another dictionary was already set. 308: */ 309: public void setDictionary(byte[] dict) 310: { 311: setDictionary(dict, 0, dict.length); 312: } 313: 314: /** 315: * Sets the dictionary which should be used in the deflate process. 316: * The dictionary should be a byte array containing strings that are 317: * likely to occur in the data which should be compressed. The 318: * dictionary is not stored in the compressed output, only a 319: * checksum. To decompress the output you need to supply the same 320: * dictionary again. 321: * @param dict the dictionary. 322: * @param offset an offset into the dictionary. 323: * @param length the length of the dictionary. 324: * @exception IllegalStateException if setInput () or deflate () were 325: * already called or another dictionary was already set. 326: */ 327: public native void setDictionary(byte[] buf, int off, int len); 328: 329: // Classpath's compression library supports flushing, but we 330: // don't. So this is a no-op here. 331: void flush() 332: { 333: } 334: }