package com.bytezone.diskbrowser; import java.util.ArrayList; import java.util.List; class LZW { static protected final String[] st = new String[0x1000]; static protected final int TRACK_LENGTH = 0x1000; protected final List chunks = new ArrayList (); protected int volume; protected byte runLengthChar; protected int crc; protected int crcBase; private int buffer; // one character buffer private int bitsLeft; // unused bits left in buffer private int ptr; private int startPtr; protected byte[] bytes; static { for (int i = 0; i < 256; i++) st[i] = "" + (char) i; } public void setBuffer (byte[] buffer, int ptr) { bytes = buffer; startPtr = this.ptr = ptr; bitsLeft = 0; } public int bytesRead () { return ptr - startPtr; } private void fillBuffer () { buffer = bytes[ptr++] & 0xFF; bitsLeft = 8; } private boolean readBoolean () { if (bitsLeft == 0) fillBuffer (); bitsLeft--; boolean bit = ((buffer << bitsLeft) & 0x80) == 0x80; return bit; } protected int readInt (int width) { if (width < 8 || width > 12) throw new RuntimeException ("Illegal value of r = " + width); int x = 0; for (int i = 0, weight = 1; i < width; i++, weight <<= 1) if (readBoolean ()) x |= weight; return x; } protected byte[] undoRLE (byte[] inBuffer, int inPtr, int length) { byte[] outBuffer = new byte[TRACK_LENGTH]; int outPtr = 0; int max = inPtr + length; while (inPtr < max) { byte b = inBuffer[inPtr++]; if (b == runLengthChar) { b = inBuffer[inPtr++]; int rpt = inBuffer[inPtr++] & 0xFF; while (rpt-- >= 0) outBuffer[outPtr++] = b; } else outBuffer[outPtr++] = b; } assert outPtr == TRACK_LENGTH; return outBuffer; } public byte[] getData () { byte[] buffer = new byte[chunks.size () * TRACK_LENGTH]; int trackNumber = 0; for (byte[] track : chunks) System.arraycopy (track, 0, buffer, trackNumber++ * TRACK_LENGTH, TRACK_LENGTH); if (crc != NuFX.getCRC (buffer, crcBase)) System.out.println ("\n*** LZW CRC mismatch ***"); return buffer; } protected int width (int maximumValue) { return 32 - Integer.numberOfLeadingZeros (maximumValue); } }