-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDecompressor.java
More file actions
95 lines (84 loc) · 3.41 KB
/
Decompressor.java
File metadata and controls
95 lines (84 loc) · 3.41 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
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
public class Decompressor {
BinaryTree<Character> huffmanTree;
public Decompressor() {
}
public void decompress(String pathName) throws FileNotFoundException {
if (pathName.indexOf(".txt") == -1) {
throw new FileNotFoundException("Invalid file type!");
}
try {
if (pathName.indexOf("_compressed") == -1) {
return;
}
String decompressedPathName = pathName.substring(0, pathName.indexOf("_compressed")) + ".txt";
BufferedWriter outputFile = new BufferedWriter(
new FileWriter(decompressedPathName));
BufferedBitReader bitReader = new BufferedBitReader(pathName);
System.out.println("reading...");
String leafCount = "";
for (int i = 0; i < 8; i++) {
leafCount += String.valueOf(bitReader.readBit());
}
System.out.println(leafCount);
huffmanTree = buildTree(bitReader, binaryToInt(leafCount));
System.out.println("Built huffman tree with leaf count " +
huffmanTree.countLeaves());
decodeChars(outputFile, bitReader);
outputFile.close();
bitReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public BinaryTree<Character> buildTree(BufferedBitReader bitReader, int leavesLeft) throws IOException {
if (bitReader.readBit() == 1 && leavesLeft > 0) {
String byteStr = "";
for (int i = 0; i < 8; i++) {
byteStr += Integer.toString(bitReader.readBit());
}
return new BinaryTree<Character>((char) binaryToInt(byteStr));
} else {
BinaryTree<Character> leftChild = buildTree(bitReader, leavesLeft--);
BinaryTree<Character> rightChild = buildTree(bitReader, leavesLeft--);
return new BinaryTree<Character>('?', leftChild, rightChild);
}
}
public void decodeChars(BufferedWriter writer, BufferedBitReader bitReader) throws IOException {
int bit = bitReader.readBit();
BinaryTree<Character> currentNode = huffmanTree;
while (bit != -1) {
if (huffmanTree.count() == 1 && bit == 0) {
writer.write(huffmanTree.getData());
bit = bitReader.readBit();
continue;
}
if (bit == 0) {
currentNode = currentNode.getLeft();
}
if (bit == 1) {
currentNode = currentNode.getRight();
}
if (currentNode.isLeaf() == true) {
System.out.print(currentNode.getData());
writer.write(currentNode.getData());
currentNode = huffmanTree;
}
bit = bitReader.readBit();
}
}
public static int binaryToInt(String binary) {
if (binary.contains("-")) {
throw new IllegalArgumentException("convertBinaryToInt(): cannot accept a negative value.");
}
if (binary.length() == 0) {
return 0;
}
int capacity = (int) Math.pow(2, binary.length() - 1);
int bit = Integer.parseInt(binary.substring(0, 1));
return bit * capacity + binaryToInt(binary.substring(1));
}
}