WarpPI/desktop/src/main/java/ar/com/hjg/pngj/pixels/CompressorStreamDeflater.java

106 lines
2.5 KiB
Java

package ar.com.hjg.pngj.pixels;
import java.util.zip.Deflater;
import ar.com.hjg.pngj.IDatChunkWriter;
import ar.com.hjg.pngj.PngjOutputException;
/**
* CompressorStream backed by a Deflater.
*
* Note that the Deflater is not disposed after done, you should either recycle
* this with reset() or dispose it with
* close()
*
*/
public class CompressorStreamDeflater extends CompressorStream {
protected Deflater deflater;
protected byte[] buf1; // temporary storage of compressed bytes: only used if idatWriter is null
protected boolean deflaterIsOwn = true;
/**
* if a deflater is passed, it must be already reset. It will not be
* released on close
*/
public CompressorStreamDeflater(IDatChunkWriter idatCw, int maxBlockLen, long totalLen, Deflater def) {
super(idatCw, maxBlockLen, totalLen);
this.deflater = def == null ? new Deflater() : def;
this.deflaterIsOwn = def == null;
}
public CompressorStreamDeflater(IDatChunkWriter idatCw, int maxBlockLen, long totalLen) {
this(idatCw, maxBlockLen, totalLen, null);
}
public CompressorStreamDeflater(IDatChunkWriter idatCw, int maxBlockLen, long totalLen, int deflaterCompLevel, int deflaterStrategy) {
this(idatCw, maxBlockLen, totalLen, new Deflater(deflaterCompLevel));
this.deflaterIsOwn = true;
deflater.setStrategy(deflaterStrategy);
}
@Override
public void mywrite(byte[] data, int off, final int len) {
if (deflater.finished() || done || closed)
throw new PngjOutputException("write beyond end of stream");
deflater.setInput(data, off, len);
bytesIn += len;
while (!deflater.needsInput())
deflate();
}
protected void deflate() {
byte[] buf;
int off, n;
if (idatChunkWriter != null) {
buf = idatChunkWriter.getBuf();
off = idatChunkWriter.getOffset();
n = idatChunkWriter.getAvailLen();
} else {
if (buf1 == null)
buf1 = new byte[4096];
buf = buf1;
off = 0;
n = buf1.length;
}
int len = deflater.deflate(buf, off, n);
if (len > 0) {
if (idatChunkWriter != null)
idatChunkWriter.incrementOffset(len);
bytesOut += len;
}
}
/** automatically called when done */
@Override
public void done() {
if (done)
return;
if (!deflater.finished()) {
deflater.finish();
while (!deflater.finished())
deflate();
}
done = true;
if (idatChunkWriter != null)
idatChunkWriter.close();
}
public void close() {
done();
try {
if (deflaterIsOwn) {
deflater.end();
}
} catch (Exception e) {}
super.close();
}
@Override
public void reset() {
deflater.reset();
super.reset();
}
}