dmolony-DiskBrowser/src/com/bytezone/diskbrowser/nufx/LZW2.java

127 lines
3.7 KiB
Java
Raw Normal View History

2021-05-21 02:57:03 +00:00
package com.bytezone.diskbrowser.nufx;
import com.bytezone.diskbrowser.utilities.Utility;
2015-06-01 09:35:51 +00:00
2020-02-07 23:26:38 +00:00
// -----------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
class LZW2 extends LZW
2020-02-07 23:26:38 +00:00
// -----------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
{
private int nextEntry = 0x100;
private String prev = "";
private int codeWord;
2020-02-07 23:26:38 +00:00
// ---------------------------------------------------------------------------------//
2021-04-17 04:41:36 +00:00
public LZW2 (byte[] buffer, int crc, int eof)
2020-02-07 23:26:38 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
{
2021-05-01 23:38:24 +00:00
super (buffer);
2015-06-01 09:35:51 +00:00
this.crc = crc;
2021-04-18 03:30:50 +00:00
this.v3eof = eof;
2021-05-02 04:45:26 +00:00
}
// ---------------------------------------------------------------------------------//
@Override
void unpack ()
// ---------------------------------------------------------------------------------//
{
2015-06-01 09:35:51 +00:00
crcBase = 0xFFFF;
codeWord = 0;
volume = buffer[0] & 0xFF;
runLengthChar = (byte) (buffer[1] & 0xFF);
int ptr = 2;
2021-05-01 23:38:24 +00:00
while (ptr < buffer.length - 1)
2015-06-01 09:35:51 +00:00
{
int rleLength = Utility.getShort (buffer, ptr);
2015-06-01 09:35:51 +00:00
boolean lzwPerformed = (rleLength & 0x8000) != 0;
ptr += 2;
if (lzwPerformed)
{
rleLength &= 0x0FFF; // remove the LZW flag
if (rleLength == 0)
rleLength = TRACK_LENGTH;
int chunkLength = Utility.getShort (buffer, ptr);
2015-06-01 09:35:51 +00:00
ptr += 2;
2021-05-01 23:38:24 +00:00
setBuffer (ptr); // prepare to read n-bit integers
2015-06-01 09:35:51 +00:00
byte[] lzwBuffer = undoLZW (rleLength);
2021-04-27 11:26:09 +00:00
if ((chunkLength - 4) != bytesRead ())
System.out.printf ("Invalid chunk length%n");
2015-06-01 09:35:51 +00:00
if (rleLength == TRACK_LENGTH) // no run length encoding
chunks.add (lzwBuffer);
else
chunks.add (undoRLE (lzwBuffer, 0, lzwBuffer.length));
ptr += bytesRead (); // since the setBuffer()
}
else
{
nextEntry = 0x100;
if (rleLength == 0)
rleLength = TRACK_LENGTH;
if (rleLength == TRACK_LENGTH) // no run length encoding
{
byte[] originalBuffer = new byte[TRACK_LENGTH];
System.arraycopy (buffer, ptr, originalBuffer, 0, originalBuffer.length);
chunks.add (originalBuffer);
}
else
chunks.add (undoRLE (buffer, ptr, rleLength));
ptr += rleLength;
}
}
}
2020-02-07 23:26:38 +00:00
// ---------------------------------------------------------------------------------//
2021-05-01 23:38:24 +00:00
byte[] undoLZW (int rleLength)
2020-02-07 23:26:38 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
{
byte[] lzwBuffer = new byte[rleLength]; // must fill this array from buffer
int ptr = 0;
while (ptr < rleLength)
{
codeWord = readInt (width (nextEntry + 1));
if (codeWord == 0x100) // clear the table
{
nextEntry = 0x100;
codeWord = readInt (9);
prev = "";
}
String s = (nextEntry == codeWord) ? prev + prev.charAt (0) : st[codeWord];
if (nextEntry < st.length)
st[nextEntry++] = prev + s.charAt (0);
for (int i = 0; i < s.length (); i++)
lzwBuffer[ptr++] = (byte) s.charAt (i);
prev = s;
}
return lzwBuffer;
}
2020-02-07 23:26:38 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
@Override
public String toString ()
2020-02-07 23:26:38 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
{
StringBuilder text = new StringBuilder ();
text.append (String.format (" volume ............ %,d%n", volume));
text.append (String.format (" RLE char .......... $%02X", runLengthChar));
return text.toString ();
}
}