forked from jaydonfaal/uodatedLZW
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathDecoder.java
More file actions
111 lines (95 loc) · 2.77 KB
/
Decoder.java
File metadata and controls
111 lines (95 loc) · 2.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import java.util.*;
import java.io.*;
// Note: there is something wrong with the encoder that I can't quite figure out.
// every file, when encoded then decoded, begins with the binary sequence 10101100111011010000000000000101
// -Peter Shen
public class Decoder {
// name of method is self-explanatory
public static void decode(String inputFile, String outputFile) throws IOException
{
StringBuilder binaryString = new StringBuilder();
FileInputStream in = new FileInputStream(inputFile);
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(outputFile)));
byte[] byteArray = in.readAllBytes();
// converts byte array into a giant binary String
for(int i = 0; i < byteArray.length; i++)
{
binaryString.append(toBinary(byteArray[i]));
}
// sanity check: binary String for accuracy
System.out.println(binaryString);
ArrayList<Integer> binaryValues = new ArrayList<Integer>();
// converts the String of binary to an ArrayList of ints, each 9 digits long
for(int i = 0 ;i <= binaryString.length() - 9; i += 9)
{
binaryValues.add(toBinaryValue(binaryString.substring(i, i+9)));
}
// sanity check: ArrayList for accuracy
System.out.println(binaryValues);
// initial dictionary values
HashMap<Integer, String> map = new HashMap<Integer,String>();
for(int i = 0; i < 256; i++)
map.put(i, "" + (char)i);
// decoding part, involving dictionary and writing to outputFile
int nextKey = 256;
int current = binaryValues.get(0);
String str = map.get(current);
String ch = "" + str.charAt(0);
out.print(str);
for(int i = 1; i < binaryValues.size(); i++)
{
int next = binaryValues.get(i);
// adding keys to dictionary, reverse-engineering compression dictionary following LZW rules
if(!map.containsKey(next))
{
str = map.get(current);
str = str + ch;
}
else
{
str = map.get(next);
}
out.print(str);
ch = "" + str.charAt(0);
map.put(nextKey, map.get(current) + ch);
nextKey++;
current = next;
}
out.println();
out.close();
}
// converts number to a String of binary
public static String toBinary(int num)
{
String current = Integer.toBinaryString(num);
StringBuilder str = new StringBuilder();
while(current.length()+str.length() < 8)
{
str.append("0");
}
if(current.length() > 8)
{
current = current.substring(current.length() - 8);
}
str.append(current);
return str.toString();
}
// converts a binary String into an integer
public static int toBinaryValue(String str)
{
int end = 0;
for(int i = 0; i < 9; i++)
{
if(str.charAt(i) == '1')
{
end += (1 << (8 - i));
}
}
return end;
}
// tester
public static void main (String [] args) throws IOException
{
decode("encoded3.bin", "decoded.txt");
}
}