package com.bytezone.diskbrowser.utilities; 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; } // ---------------------------------------------------------------------------------// 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; } // ---------------------------------------------------------------------------------// 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); } }