home *** CD-ROM | disk | FTP | other *** search
- import java.io.PrintStream;
-
- public class LZWCompressor {
- private static final int EOF = -1;
- private boolean interlace;
- private PrintStream pStream;
- private boolean clearFlag = false;
- private int CountDown;
- private int curx;
- private int cury;
- private int Pass;
- private int maxcode;
- private int maxmaxcode = 4096;
- private int n_bits;
- private int[] hashes = new int[5003];
- private int[] codes = new int[5003];
- private int freeEnt;
- private int numberIn = 1;
- private int numberOut;
- private int curAccum;
- private int curBits;
- private int[] masks = new int[17];
- private int offset;
- private int g_init_bits;
- private int clearCode;
- private int EOFCode;
- private int nextByte;
- private byte[] bufferByte;
-
- public void setInterlace(boolean var1) {
- this.interlace = var1;
- }
-
- public boolean isInterlace() {
- return this.interlace;
- }
-
- public void setPrintStream(PrintStream var1) {
- this.pStream = var1;
- }
-
- public PrintStream getPrintStream() {
- return this.pStream;
- }
-
- public LZWCompressor(PrintStream var1, boolean var2) {
- this.setPrintStream(var1);
- this.setInterlace(var2);
- this.masks[0] = 0;
-
- for(int var3 = 1; var3 < 16; ++var3) {
- this.masks[var3] = (1 << var3) - 1;
- }
-
- this.masks[16] = 65535;
- }
-
- void compress(int var1, int var2, int var3, int[] var4) {
- this.Pass = 0;
- this.curBits = 0;
- this.maxmaxcode = 4096;
- this.hashes = new int[5003];
- this.codes = new int[5003];
- this.curAccum = 0;
- this.curx = this.cury = 0;
- this.CountDown = var2 * var3;
- this.g_init_bits = var1;
- this.offset = 0;
- this.numberOut = 0;
- this.clearFlag = false;
- this.numberIn = 1;
- this.maxcode = this.maxCode(this.n_bits = this.g_init_bits);
- this.clearCode = 1 << var1 - 1;
- this.EOFCode = this.clearCode + 1;
- this.freeEnt = this.clearCode + 2;
- this.initBuffer();
- int var8 = this.getNextPixel(var4, var2, var3);
- int var10 = 0;
- this.pStream.write(var1 - 1);
-
- for(int var5 = 5003; var5 < 65536; var5 *= 2) {
- ++var10;
- }
-
- var10 = 8 - var10;
- this.clearHashes();
- this.output(this.clearCode);
-
- int var7;
- while((var7 = this.getNextPixel(var4, var2, var3)) != -1) {
- ++this.numberIn;
- int var11 = (var7 << 12) + var8;
- int var6 = var7 << var10 ^ var8;
- if (this.hashes[var6] == var11) {
- var8 = this.codes[var6];
- } else if (this.hashes[var6] < 0) {
- this.output(var8);
- ++this.numberOut;
- var8 = var7;
- if (this.freeEnt < this.maxmaxcode) {
- this.codes[var6] = this.freeEnt++;
- this.hashes[var6] = var11;
- } else {
- this.clearBlock();
- }
- } else {
- int var9 = 5003 - var6;
- if (var6 == 0) {
- var9 = 1;
- }
-
- if ((var6 = var6 - var9) < 0) {
- var6 += 5003;
- }
-
- if (this.hashes[var6] == var11) {
- var8 = this.codes[var6];
- } else {
- while(this.hashes[var6] > 0) {
- if ((var6 -= var9) < 0) {
- var6 += 5003;
- }
-
- if (this.hashes[var6] == var11) {
- var8 = this.codes[var6];
- break;
- }
- }
-
- if (this.hashes[var6] != var11) {
- this.output(var8);
- ++this.numberOut;
- var8 = var7;
- if (this.freeEnt < this.maxmaxcode) {
- this.codes[var6] = this.freeEnt++;
- this.hashes[var6] = var11;
- } else {
- this.clearBlock();
- }
- }
- }
- }
- }
-
- this.output(var8);
- ++this.numberOut;
- this.output(this.EOFCode);
- }
-
- void output(int var1) {
- this.curAccum &= this.masks[this.curBits];
- if (this.curBits > 0) {
- this.curAccum |= var1 << this.curBits;
- } else {
- this.curAccum = var1;
- }
-
- for(this.curBits += this.n_bits; this.curBits >= 8; this.curBits -= 8) {
- this.writeByte((byte)(this.curAccum & 255));
- this.curAccum >>= 8;
- }
-
- if (this.freeEnt > this.maxcode || this.clearFlag) {
- if (this.clearFlag) {
- this.maxcode = this.maxCode(this.n_bits = this.g_init_bits);
- this.clearFlag = false;
- } else {
- ++this.n_bits;
- if (this.n_bits == 12) {
- this.maxcode = this.maxmaxcode;
- } else {
- this.maxcode = this.maxCode(this.n_bits);
- }
- }
- }
-
- if (var1 == this.EOFCode) {
- while(this.curBits > 0) {
- this.writeByte((byte)(this.curAccum & 255));
- this.curAccum >>= 8;
- this.curBits -= 8;
- }
-
- this.flushBuffer();
- }
-
- }
-
- void bumpPixel(int var1, int var2) {
- ++this.curx;
- if (this.curx == var1) {
- this.curx = 0;
- if (!this.interlace) {
- ++this.cury;
- return;
- }
-
- switch (this.Pass) {
- case 0:
- this.cury += 8;
- if (this.cury >= var2) {
- ++this.Pass;
- this.cury = 4;
- return;
- }
- break;
- case 1:
- this.cury += 8;
- if (this.cury >= var2) {
- ++this.Pass;
- this.cury = 2;
- return;
- }
- break;
- case 2:
- this.cury += 4;
- if (this.cury >= var2) {
- ++this.Pass;
- this.cury = 1;
- return;
- }
- break;
- case 3:
- this.cury += 2;
- return;
- }
- }
-
- }
-
- int getNextPixel(int[] var1, int var2, int var3) {
- if (this.CountDown == 0) {
- return -1;
- } else {
- --this.CountDown;
- int var4 = var1[this.cury * var2 + this.curx];
- this.bumpPixel(var2, var3);
- return var4;
- }
- }
-
- public int maxCode(int var1) {
- return (1 << var1) - 1;
- }
-
- void clearBlock() {
- this.clearHashes();
- this.freeEnt = this.clearCode + 2;
- this.clearFlag = true;
- this.output(this.clearCode);
- }
-
- void clearHashes() {
- for(int var1 = 0; var1 < 5003; ++var1) {
- this.hashes[var1] = -1;
- }
-
- }
-
- void initBuffer() {
- this.nextByte = 0;
- this.bufferByte = new byte[256];
- }
-
- void writeByte(byte var1) {
- this.bufferByte[this.nextByte++] = var1;
- if (this.nextByte >= 254) {
- this.flushBuffer();
- }
-
- }
-
- void flushBuffer() {
- if (this.nextByte > 0) {
- this.pStream.write(this.nextByte);
- this.pStream.write(this.bufferByte, 0, this.nextByte);
- this.nextByte = 0;
- }
-
- }
- }
-