forked from LupusNobilis/java-org.hwo
168 lines
3.2 KiB
Java
168 lines
3.2 KiB
Java
package org.hwo.compressor;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.LinkedList;
|
|
|
|
import org.hwo.Reverse;
|
|
import org.hwo.Unsigned;
|
|
import org.hwo.buffer.BitStream;
|
|
|
|
public class LZW {
|
|
|
|
static short CLEARCODE = (short)256;
|
|
static short ENDOFINFORMATION = (short)257;
|
|
|
|
ArrayList<Byte[]> stringTable;
|
|
ArrayList<Byte> omega;
|
|
|
|
LinkedList<Byte> uncompressed;
|
|
BitStream compressed;
|
|
|
|
private boolean byteOrder;
|
|
|
|
public LZW()
|
|
{
|
|
stringTable = new ArrayList<Byte[]>();
|
|
omega = new ArrayList<Byte>();
|
|
uncompressed = new LinkedList<Byte>();
|
|
compressed = new BitStream();
|
|
}
|
|
|
|
private void initializeStringTable()
|
|
{
|
|
stringTable.clear();
|
|
for (short n=0;n<256;n++)
|
|
stringTable.add(new Byte[]{ (byte)n });
|
|
|
|
stringTable.add(new Byte[0]);
|
|
stringTable.add(new Byte[0]);
|
|
|
|
}
|
|
|
|
private byte getSymbolLength()
|
|
{
|
|
if (stringTable.size() < 511)
|
|
return 9;
|
|
if (stringTable.size() < 1023)
|
|
return 10;
|
|
if (stringTable.size() < 2047)
|
|
return 11;
|
|
return 12;
|
|
}
|
|
|
|
public void compress()
|
|
{
|
|
|
|
}
|
|
|
|
public void decompress()
|
|
{
|
|
short symbol,
|
|
lastsymbol = 0;
|
|
|
|
uncompressed.clear();
|
|
initializeStringTable();
|
|
|
|
try
|
|
{
|
|
|
|
while ( (symbol = compressed.read(getSymbolLength())) != ENDOFINFORMATION)
|
|
{
|
|
if (symbol == CLEARCODE)
|
|
{
|
|
initializeStringTable();
|
|
symbol = compressed.read(getSymbolLength());
|
|
if (symbol == ENDOFINFORMATION)
|
|
break;
|
|
|
|
uncompressed.addAll(Arrays.asList(stringTable.get(symbol)));
|
|
lastsymbol = symbol;
|
|
} else
|
|
{
|
|
if (symbol < stringTable.size())
|
|
{
|
|
Byte[] codeString = stringTable.get(symbol);
|
|
uncompressed.addAll(Arrays.asList(codeString));
|
|
|
|
Byte[] b = stringTable.get(lastsymbol);
|
|
Byte[] nb = Arrays.copyOf(b, b.length + 1 );
|
|
nb[ b.length ] = codeString[0];
|
|
stringTable.add(nb);
|
|
} else
|
|
{
|
|
Byte[] b = stringTable.get(lastsymbol);
|
|
Byte[] nb = Arrays.copyOf(b, b.length + 1 );
|
|
nb[ b.length ] = b[0];
|
|
stringTable.add(nb);
|
|
uncompressed.addAll(Arrays.asList(nb));
|
|
}
|
|
lastsymbol = symbol;
|
|
}
|
|
}
|
|
|
|
|
|
} catch (Exception e)
|
|
{
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public Byte[] getBoxedUncompressedData()
|
|
{
|
|
return uncompressed.toArray(new Byte[0]);
|
|
}
|
|
public byte[] getUncompressedData()
|
|
{
|
|
Byte[] boxed = getBoxedUncompressedData();
|
|
byte[] unboxed = new byte[ boxed.length ];
|
|
|
|
for (int i=0;i<boxed.length;i++)
|
|
unboxed[i] = boxed[i];
|
|
|
|
return unboxed;
|
|
}
|
|
|
|
|
|
public void setUncompressedData(Byte[] data)
|
|
{
|
|
uncompressed.clear();
|
|
uncompressed.addAll(Arrays.asList(data));
|
|
}
|
|
|
|
public Byte[] getBoxedCompressedData()
|
|
{
|
|
byte[] unboxed = compressed.getBuffer();
|
|
Byte[] boxed = new Byte[ unboxed.length ];
|
|
for (int i=0;i<unboxed.length;i++)
|
|
boxed[i] = unboxed[i];
|
|
return boxed;
|
|
}
|
|
public byte[] getCompressedData()
|
|
{
|
|
return compressed.getBuffer();
|
|
}
|
|
|
|
public void setCompressedData(Byte[] data)
|
|
{
|
|
compressed = new BitStream(data);
|
|
}
|
|
public void setCompressedData(byte[] data)
|
|
{
|
|
compressed = new BitStream(data);
|
|
}
|
|
|
|
public boolean isByteOrder() {
|
|
return byteOrder;
|
|
}
|
|
|
|
public void setByteOrder(boolean byteOrder) {
|
|
this.byteOrder = byteOrder;
|
|
this.compressed.setByteOrder(byteOrder);
|
|
}
|
|
|
|
|
|
}
|