-
Notifications
You must be signed in to change notification settings - Fork 2
/
MyComp.java
136 lines (115 loc) · 5.39 KB
/
MyComp.java
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import java.io.*;
import java.util.*;
class MyComp {
public static HashMap<String, Integer> dictionary = new HashMap<>();
public static int dictSize = 256;
public static String P = "",filename="",BP="";
public static byte inputByte;
public static byte[] buffer = new byte[3];
public static boolean isLeft = true;
public static void main(String[] args) {
System.out.println("*****LZW Image Compression*****");
System.out.println("Enter image to compress with extension: ");
Scanner sc = new Scanner(System.in);
filename = sc.next();
try {
File file = new File(filename);
compress();
String[] getFileNameWOExtn = filename.split("\\.");
System.out.println("Compression complete!Check file "+getFileNameWOExtn[0].concat(".lzw")+"!");
}
catch(IOException ie) {
System.out.println("File "+filename+" not found!");
}
}
public static void compress() throws IOException {
int i,byteToInt;
char C;
// Character dictionary
for(i=0;i<256;i++) {
dictionary.put(Character.toString((char)i),i);
}
// Read input file and output file
RandomAccessFile inputFile = new RandomAccessFile(filename,"r");
String[] getFileNameWOExtn = filename.split("\\.");
RandomAccessFile outputFile = new RandomAccessFile(getFileNameWOExtn[0].concat(".lzw"),"rw");
try {
// Read first byte to initialize P
inputByte = inputFile.readByte();
byteToInt = new Byte(inputByte).intValue();
if(byteToInt < 0) byteToInt += 256;
C = (char) byteToInt;
P = ""+C;
while(true) {
inputByte = inputFile.readByte();
byteToInt = new Byte(inputByte).intValue();
if(byteToInt < 0) byteToInt += 256;
C = (char) byteToInt;
// if P+C is present in dictionary
if(dictionary.containsKey(P+C)) {
P = P+C;
}
/*
if P+C is not in dictionary, we obtain the longest string in the dictionary
so far which is stored in P. The value of this string is converted in binary.
This binary number is then padded to make it 12 bits long (for standardization
and avoing overflow or underflow caused using 8 bits). This is then converted
into bytes and stored.
We write in the file every 2 characters.
*/
else {
BP = convertTo12Bit(dictionary.get(P));
if(isLeft) {
buffer[0] = (byte) Integer.parseInt(BP.substring(0,8),2);
buffer[1] = (byte) Integer.parseInt(BP.substring(8,12)+"0000",2);
}
else {
buffer[1] += (byte) Integer.parseInt(BP.substring(0,4),2);
buffer[2] = (byte) Integer.parseInt(BP.substring(4,12),2);
for(i=0;i<buffer.length;i++) {
outputFile.writeByte(buffer[i]);
buffer[i]=0;
}
}
isLeft = !isLeft;
if(dictSize < 4096) dictionary.put(P+C,dictSize++);
P=""+C;
}
}
}
/*
If isLeft is true, we store the current data in BP to buffer[0] and buffer[1]. Then these
buffers are written in the output file.
If isLeft is false, we already have data in the first and half of seccond byte of the
buffer. Hence, we store the current value of BP and write all the 3 bytes to the outputFile.
When the file input is complete, the while loop will still execute due to the condition.
This ensures that the file is read completely but it might throw an error if there is
no input left in the inputFile. So, when an error is thrown, we store the remaining contents
of the buffer.
*/
catch(IOException ie) {
BP = convertTo12Bit(dictionary.get(P));
if(isLeft) {
buffer[0] = (byte) Integer.parseInt(BP.substring(0,8),2);
buffer[1] = (byte) Integer.parseInt(BP.substring(8,12)+"0000",2);
outputFile.writeByte(buffer[0]);
outputFile.writeByte(buffer[1]);
}
else {
buffer[1] += (byte) Integer.parseInt(BP.substring(0,4),2);
buffer[2] = (byte) Integer.parseInt(BP.substring(4,12),2);
for(i=0;i<buffer.length;i++) {
outputFile.writeByte(buffer[i]);
buffer[i]=0;
}
}
inputFile.close();
outputFile.close();
}
}
public static String convertTo12Bit(int i) {
String to12Bit = Integer.toBinaryString(i);
while (to12Bit.length() < 12) to12Bit = "0" + to12Bit;
return to12Bit;
}
}