Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .project
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>LZW-Compression</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
</natures>
</projectDescription>
51 changes: 30 additions & 21 deletions LZW Compression/src/LZWObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ public LZWObject( File message) {
super();
this.message = message;
}
// encodes message as a byteArray and outputs said byte array to output.txt
public static void encode() throws IOException {
final long startTime = System.currentTimeMillis();
dictionary = new HashMap<String, Integer>();
FileReader reader = new FileReader(message);
String current = "" + (char)reader.read();
Expand All @@ -44,7 +46,7 @@ public static void encode() throws IOException {
while (reader.ready()) {
if (!dictionary.containsKey(current + next)) {
dictionary.put(current + next, codeOn);
nums.add(codeOn);
nums.add(dictionary.get(current));
codeOn++;
current = next;
next = "" + (char)reader.read();
Expand All @@ -59,44 +61,51 @@ public static void encode() throws IOException {
byte[] bitArray = stringToBinary(stringBits);
FileOutputStream output = new FileOutputStream(new File ("output.txt"));
output.write(bitArray);
System.out.print(System.currentTimeMillis() - startTime);
output.close();
}

// converts a number to a binary string with len number of digits
private static String toBinary(int x, int len)
{
if (len > 0)
{
return String.format("%" + len + "s",
Integer.toBinaryString(x)).replaceAll(" ", "0");
return String.format("%" + len + "s", Integer.toBinaryString(x)).replaceAll(" ", "0");
}

return null;
}
// converts an ArrayList of ints to a String composed of the 9 bit binary representation of each of those ints
private static String allToBinary(ArrayList<Integer> ints) {
StringBuilder str = new StringBuilder();
for (int num : ints) {
str.append(toBinary(num, 9));
}
return str.toString();
}
// converts a string representation of binary values to a byte array
// puts extra 0's at the end of the String to ensure that it can be stored in a byte array (multiple of 8 bits)
private static byte[] stringToBinary(String str) {
while(str.length()%8 !=0)
int zeroes = (str.length() %8);
if (zeroes != 0)
{
str += 0;
String zero = "0000000";
str += zero.substring(0, 8 - zeroes);
}

byte[] bytes = new byte[str.length()/8];
int counter = 0;
for (int i = 0; i < str.length(); i+= 8) {
bytes[counter] = (byte)Integer.parseInt(str.substring(i, i+8), 2);
System.out.println(bytes[counter]);
counter++;
}
return bytes;
}
// takes in a text file of binary and deciphers the binary
// reverses the operations of encode, outputing the original message to a text file
public void decode(String filename, int bitSize) throws IOException
{

reinitializeDictionary();
final long startTime = System.currentTimeMillis();
initializeDecoderDictionary();
String masterString = readFromCompressedFile(filename, bitSize);
int [] integerValues = convertStringToIntegers(masterString, bitSize);
rebuildDictionary(integerValues);
Expand All @@ -112,51 +121,55 @@ public void decode(String filename, int bitSize) throws IOException
output.write(("" + decoderDictionary.get(integerValues[i])).replaceAll("null", "@"));
}
}
System.out.print(System.currentTimeMillis() - startTime);

}

public void reinitializeDictionary()
// initializes decoderDictionary with ASCII
public void initializeDecoderDictionary()
{
decoderDictionary = new HashMap<Integer, String>();
for(int i = 0; i < 256; i++)
{
decoderDictionary.put(i, "" + (char) i);
}
}

// reads the file created by encode and returns a String of appended binary values
public String readFromCompressedFile(String filename, int bitSize) throws IOException
{
FileReader reader = new FileReader(filename);
String decoderMasterString = "";
FileReader reader = new FileReader(filename);
String decoderMasterString = "";
int character;
BufferedReader br = new BufferedReader(reader);
while ((character = br.read()) != -1) {
decoderMasterString += toBinary(character, 8);
decoderMasterString += toBinary(character, 8);
}
decoderMasterString = decoderMasterString.substring(0, decoderMasterString.length() - decoderMasterString.length()%bitSize);
return decoderMasterString;
}

// converts a given binary to string to an integer representation and returns that int
public int [] convertStringToIntegers(String binValueString, int bitSize)
{
int [] encodedValueArray = new int [binValueString.length()/bitSize];
int counter = 0;
for(int i = 0; i < binValueString.length() - bitSize; i += bitSize)
{
encodedValueArray[counter] = Integer.parseInt(binValueString.substring(i, i + bitSize),2);
System.out.println(encodedValueArray[counter]);
counter++;
}
return encodedValueArray;
}


// loops through array of integers representing Strings in the encoder dictionary
// adds LZW combined ASCII values to the decoderDictionary to make it emthe encoder dict
public void rebuildDictionary(int [] numberEntries)
{
String c = "";
for(int i = 0; i < numberEntries.length; i++)
{
String cn = (c + decoderDictionary.get(numberEntries[i])).replaceAll("null", "@");
System.out.println(cn);
if(decoderDictionary.containsValue(cn))
{
c = cn;
Expand All @@ -167,14 +180,10 @@ public void rebuildDictionary(int [] numberEntries)
c = cn.substring(cn.length()-1);
}
}
for(int i = 0; i < numberEntries.length; i++)
{
System.out.println(numberEntries[i]);
}
}

public static void main (String [] args) throws IOException {
LZWObject obj = new LZWObject(new File("lzw-file1.txt"));
LZWObject obj = new LZWObject(new File("lzw-file2.txt"));
obj.encode();
obj.decode("output.txt", 9);
}
Expand Down
Empty file.
1 change: 1 addition & 0 deletions LZW Compression/src/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0��p�� ��<. �â0؜B)��"�r3�Ǥ2ِ�f3ȣ�L�Fc��岹t�k4���3i��w>��'�)��D�ѩ4ZX
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
# LZW-Compression
The algorithm is slightly broken but the handling of the dictionary into binary is optimized properly – 9 bits are stored by 9 bits, not 2 bytes (16 bits); the algorithm needs to be touched up to store traditional ascii characters before doing other things so look out for that. If you fix the algorithm, the conversion into binary will still function properly.
From a functionality perspective:
The encode method has been improved from prior versions although it is still not ideal -- before the encode method did not encode the current value and instead
added the dictionary value (256,257 . . . ) sequentially. Now it at least correctly encodes the current value (edge cases have not been tested).
The decode method appears to be functioning correctly.

https://www.youtube.com/watch?v=iik25wqIuFo watch this for specific information – instructional video on how to make algorithm. I commented on the bottom to explain what was wrong with mine.
From a big O perspective:
A for loop has been eliminated in the encdoe method which caused a decrease in run time from 11587 ---> 45 overall.
Some of this decrease can be attributed to eliminating System.out.println methods that were used by the initial coder to test the code
System.out.println have also been removed from the decode method decreasing the runtime from 4298 --> 14 overalll

From a code clarity persepctive: at least 1 method was renamed to more accurately reflect what the method accomplishes.
I tried very hard to maintain Louis and Tyler's stylistic variable names and method names --- comments were used to explain methods that were oddly named
or carried out numerous operations at the same time.