/** * Sets the compression level. There is no guarantee of the exact position of the change, but if * you call this when needsInput is true the change of compression level will occur somewhere near * before the end of the so far given input. * * @param lvl the new compression level. */ public void setLevel(int lvl) { if (lvl == DEFAULT_COMPRESSION) lvl = 6; else if (lvl < NO_COMPRESSION || lvl > BEST_COMPRESSION) throw new IllegalArgumentException(); if (level != lvl) { level = lvl; engine.setLevel(lvl); } }
/** * Sets the dictionary which should be used in the deflate process. The dictionary should be a * byte array containing strings that are likely to occur in the data which should be compressed. * The dictionary is not stored in the compressed output, only a checksum. To decompress the * output you need to supply the same dictionary again. * * @param dict the dictionary. * @param offset an offset into the dictionary. * @param length the length of the dictionary. * @exception IllegalStateException if setInput () or deflate () were already called or another * dictionary was already set. */ public void setDictionary(byte[] dict, int offset, int length) { if (state != INIT_STATE) throw new IllegalStateException(); state = SETDICT_STATE; engine.setDictionary(dict, offset, length); }
/** * Deflates the current input block to the given array. It returns the number of bytes compressed, * or 0 if either needsInput() or finished() returns true or length is zero. * * @param output the buffer where to write the compressed data. * @param offset the offset into the output array. * @param length the maximum number of bytes that may be written. * @exception IllegalStateException if end() was called. * @exception IndexOutOfBoundsException if offset and/or length don't match the array length. */ public int deflate(byte[] output, int offset, int length) { int origLength = length; if (state == CLOSED_STATE) throw new IllegalStateException("Deflater closed"); if (state < BUSY_STATE) { /* output header */ int header = (DEFLATED + ((DeflaterConstants.MAX_WBITS - 8) << 4)) << 8; int level_flags = (level - 1) >> 1; if (level_flags < 0 || level_flags > 3) level_flags = 3; header |= level_flags << 6; if ((state & IS_SETDICT) != 0) /* Dictionary was set */ header |= DeflaterConstants.PRESET_DICT; header += 31 - (header % 31); pending.writeShortMSB(header); if ((state & IS_SETDICT) != 0) { int chksum = engine.getAdler(); engine.resetAdler(); pending.writeShortMSB(chksum >> 16); pending.writeShortMSB(chksum & 0xffff); } state = BUSY_STATE | (state & (IS_FLUSHING | IS_FINISHING)); } for (; ; ) { int count = pending.flush(output, offset, length); offset += count; totalOut += count; length -= count; if (length == 0 || state == FINISHED_STATE) break; if (!engine.deflate((state & IS_FLUSHING) != 0, (state & IS_FINISHING) != 0)) { if (state == BUSY_STATE) /* We need more input now */ return origLength - length; else if (state == FLUSHING_STATE) { if (level != NO_COMPRESSION) { /* We have to supply some lookahead. 8 bit lookahead * are needed by the zlib inflater, and we must fill * the next byte, so that all bits are flushed. */ int neededbits = 8 + ((-pending.getBitCount()) & 7); while (neededbits > 0) { /* write a static tree block consisting solely of * an EOF: */ pending.writeBits(2, 10); neededbits -= 10; } } state = BUSY_STATE; } else if (state == FINISHING_STATE) { pending.alignToByte(); /* We have completed the stream */ if (!noHeader) { int adler = engine.getAdler(); pending.writeShortMSB(adler >> 16); pending.writeShortMSB(adler & 0xffff); } state = FINISHED_STATE; } } } return origLength - length; }
/** * Sets the compression strategy. Strategy is one of DEFAULT_STRATEGY, HUFFMAN_ONLY and FILTERED. * For the exact position where the strategy is changed, the same as for setLevel() applies. * * @param stgy the new compression strategy. */ public void setStrategy(int stgy) { if (stgy != DEFAULT_STRATEGY && stgy != FILTERED && stgy != HUFFMAN_ONLY) throw new IllegalArgumentException(); engine.setStrategy(stgy); }
/** * Sets the data which should be compressed next. This should be only called when needsInput * indicates that more input is needed. The given byte array should not be changed, before * needsInput() returns true again. * * @param input the buffer containing the input data. * @param off the start of the data. * @param len the length of the data. * @exception IllegalStateException if the buffer was finished() or ended() or if previous input * is still pending. */ public void setInput(byte[] input, int off, int len) { if (input == null) throw new NullPointerException(); if (off < 0 || len < 0 || off > input.length - len) throw new ArrayIndexOutOfBoundsException(); engine.setInput(input, off, len); }
/** * Returns true, if the input buffer is empty. You should then call setInput(). <br> * <em>NOTE</em>: This method can also return true when the stream was finished. */ public boolean needsInput() { return engine.needsInput(); }
/** * Gets the number of input bytes processed so far. * * @since 1.5 */ public long getBytesRead() { return engine.getTotalIn(); }
/** Gets the number of input bytes processed so far. */ public int getTotalIn() { return (int) engine.getTotalIn(); }
/** Gets the current adler checksum of the data that was processed so far. */ public int getAdler() { return engine.getAdler(); }
/** * 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(); engine.reset(); }