I'm working with text files here. My LZW decompression doesn't seem to work correctly. Something is wrong when I try to decompress my compressed file back: I get extra bytes added to the text file after decompression. As of now, I found the sequence of values that's causing the issue, it's the * (star character)
For example, When I have a text file containing this following sentence:
*** Hello ***
Here's how my decompression works (I'm showing only 2 iterations):
#1 iteration
priorword = 42
currword = 256
Added in dict: 256: **
Wrote in file: **
#2 iteration
priorword = 256
currword = 32
Added in dict: 257: **_ (_ means space)
Write in file: **
We know have in file: ****_
What could be wrong here, an extra star gets added because as you can see the original file has three stars.
After decompression, I get: **** Hello **
A star * from the right is added to the left, how could this be?
Decompression method:
public void LZW_Decompress(String input) throws IOException {
// DictSize builds up to 4k, Array_Char holds these values
Array_char = new String[4096];
for (int i = 0; i < 256; i++) {
dictionary.put(i, Character.toString((char) i));
Array_char[i] = Character.toString((char) i);
}
// Read input as uncompressed file & Write out compressed file
RandomAccessFile in = new RandomAccessFile(input, "r");
RandomAccessFile out = new RandomAccessFile(input.replace(
".lzw", ""), "rw");
try {
// Gets the first word in code and outputs its corresponding char
buffer[0] = in.readByte();
buffer[1] = in.readByte();
priorword = getvalue(buffer[0], buffer[1], onleft);
onleft = !onleft;
out.writeBytes(Array_char[priorword]);
// Reads every 3 bytes and generates corresponding characters
while (true) {
if (onleft) {
buffer[0] = in.readByte();
buffer[1] = in.readByte();
currword = getvalue(buffer[0], buffer[1], onleft);
} else {
buffer[2] = in.readByte();
currword = getvalue(buffer[1], buffer[2], onleft);
}
onleft = !onleft;
if (currword >= dictSize) {
if (dictSize < 4096) {
Array_char[dictSize] = Array_char[priorword]
+ Array_char[priorword].charAt(0);
}
dictSize++;
out.writeBytes(Array_char[priorword]
+ Array_char[priorword].charAt(0));
} else {
if (dictSize < 4096) {
Array_char[dictSize] = Array_char[priorword]
+ Array_char[currword].charAt(0);
}
dictSize++;
out.writeBytes(Array_char[currword]);
}
priorword = currword;
}
} catch (EOFException e) {
in.close();
out.close();
}
}