-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRLEconverter.java
269 lines (229 loc) · 8.27 KB
/
RLEconverter.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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
package app;
import java.util.Scanner;
import java.io.*;
public class RLEconverter {
private final static int DEFAULT_LEN = 100; // used to create arrays.
/*
* This method reads in an uncompressed ascii image file that contains
* 2 characters. It stores each line of the file in an array.
* It then calls compressLines to get an array that stores the compressed
* version of each uncompressed line from the file. The compressed array
* is then passed to the getCompressedFileStr method which returns a String
* of all compressed lines (the two charcaters are written in the first line)
* in CSV format. This String is written to a text file with the prefix "RLE_"
* added to the original, uncompressed file name.
* Note that dataSize keeps track of the number of lines in the file. The array
* that holds the lines of the file is initialized to the DEFAULT_LEN, which
* is assumed to be << the number of lines in the file.
*/
public void compressFile(String fileName) throws IOException{
Scanner scan = new Scanner(new FileReader(fileName));
String line = null;
String[] decompressed = new String [DEFAULT_LEN];
int dataSize = 0;
while(scan.hasNext()){
line = scan.next();
if(line != null && line.length()>0)
decompressed[dataSize]=line;
dataSize++;
}
scan.close();
char[] fileChars = discoverAllChars(decompressed, dataSize);
String[] compressed = compressLines(decompressed, dataSize, fileChars);
writeFile(getCompressedFileStr(compressed, fileChars), "RLE_"+fileName);
}
/*
* This method implements the RLE compression algorithm. It takes a line of uncompressed data
* from an ascii file and returns the RLE encoding of that line in CSV format.
* The two characters that make up the image file are passed in as a char array, where
* the first cell contains the first character that occurred in the file.
*/
public String compressLine(String line, char[] fileChars){
//TODO: Implement this method
String output= new String();
int len=line.length();
int count=0;
if(line.charAt(0)==(fileChars[0])){
count++;
}
else{
output=output+count+",";
count++;
}
for(int i=1;i<len;i++){
if(i==(len-1)){
count++;
output=output+count;
break;
}
if(line.charAt(i)==line.charAt(i+1)){
count++;
}
else{
count++;
output=output+count+",";
count=0;
}
}
return output;
}
/*
* This method discovers the two ascii characters that make up the image.
* It iterates through all of the lines and writes each compressed line
* to a String array which is returned. The method compressLine is called on
* each line.
* The dataSize is the number of lines in the file, which is likely to be << the length of lines.
*/
public String[] compressLines(String[] lines, int dataSize, char[] fileChars){
//TODO: Implement this method
int count=0;
String [] compressed1= new String[dataSize];
for(String line1 :lines){
if(count>=dataSize){
break;
}
else{
compressed1[count]= this.compressLine(line1, fileChars);
count++;
}
}
return compressed1;
}
/*
* This method assembles the lines of compressed data for
* writing to a file. The first line must be the 2 ascii characters
* in comma-separated format.
*/
public String getCompressedFileStr(String[] compressed, char[] fileChars) {
//TODO: Implement this method
String data1="";
for(char b1: fileChars){
String x= Character.toString(b1) ;
data1=data1+x+",";
}
for( String b: compressed){
data1=data1+b;
}
return data1;
}
/*
* This method reads in an RLE compressed ascii image file that contains
* 2 characters. It stores each line of the file in an array.
* It then calls decompressLines to get an array that stores the decompressed
* version of each compressed line from the file. The first row contains the two
* ascii charcaters used in the original image file. The decompressed array
* is then passed to the getDecompressedFileStr method which returns a String
* of all decompressed lines, thus restoring the original, uncompressed image.
* This String is written to a text file with the prefix "DECOMP_"
* added to the original, compressed file name.
* Note that dataSize keeps track of the number of lines in the file. The array
* that holds the lines of the file is initialized to the DEFAULT_LEN, which
* is assumed to be << the number of lines in the file.
*/
public void decompressFile(String fileName) throws IOException{
Scanner scan = new Scanner(new FileReader(fileName));
String line = null;
String[] compressed = new String [DEFAULT_LEN];
int dataSize =0;
while(scan.hasNext()){
line = scan.next();
if(line != null && line.length()>0)
compressed[dataSize]=line;
dataSize++;
}
scan.close();
String[] decompressed = decompressLines(compressed, dataSize);
writeFile(getDecompressedFileStr(decompressed), "DECOMP_"+fileName);
}
/*
* This method decodes lines that were encoded by the RLE compression algorithm.
* It takes a line of compressed data and returns the decompressed, or original version
* of that line. The two characters that make up the image file are passed in as a char array,
* where the first cell contains the first character that occurred in the file.
*/
public String decompressLine(String line, char[] fileChars){
//TODO: Implement this method
String oString= new String();
String[] numbers = line.split(",");
int count=0;
for(String a: numbers){
int x= Integer.parseInt(a);
if(x==0){
count++;
continue;
}
else{
if(count%2==0){
for(int i=1;i<=x;i++){
oString=oString+fileChars[0];
}
count++;
}
else{
for(int j=1;j<=x;j++){
oString=oString+fileChars[1];
}
count++;
}
}
}
return oString;
}
/*
* This method iterates through all of the compressed lines and writes
* each decompressed line to a String array which is returned.
* The method decompressLine is called on each line. The first line in
* the compressed array passed in are the 2 ascii characters used to make
* up the image.
* The dataSize is the number of lines in the file, which is likely to be << the length of lines.
* The array returned contains only the decompressed lines to be written to the decompressed file.
*/
public String[] decompressLines(String[] lines, int dataSize){
//TODO: Implement this method
String [] decompress = new String[dataSize-1];
String[] nums1 = lines[0].split(",");
char[] fileChar = new char [2];
// process the first line
for(int i = 0; i < nums1.length; i++){
fileChar[i] = nums1[i].charAt(0);
}
// process the remaining lines
for(int j = 1; j < dataSize; j++){
decompress[j-1]= this.decompressLine(lines[j], fileChar);
}
return decompress;
}
/*
* This method assembles the lines of decompressed data for
* writing to a file.
*/
public String getDecompressedFileStr(String[] decompressed){
String data = "";
//TODO: Implement this method
for(String a: decompressed){
data=data+a;
}
return data;
}
// assume the file contains only 2 different ascii characters.
public char[] discoverAllChars(String[] decompressed, int dataSize){
//TODO: Implement this method
char[] characters = new char [2];
characters[0] = decompressed[0].charAt(0);
for(int i = 0; i < dataSize; i++){
char[] line = decompressed[i].toCharArray();
for(int j = 0; j < line.length; j++){
if(line[j] != characters[0]){
characters[1] = line[j];
break;
}
}
}
return characters;
}
public void writeFile(String data, String fileName) throws IOException{
PrintWriter pw = new PrintWriter(fileName);
pw.print(data);
pw.close();
}
}