import java.io.*;
import java.util.Hashtable;
import java.util.ArrayList;
public class Encode {
public static void main(String[] args) {
String sourcefilename = args[0];
String lookuptablefilename = args[1];
String encodedfilename = args[2];
ArrayList<Integer> toEncode = readSource(args[0]);
FrequencyTable frequencyTable = new FrequencyTable(toEncode);
HuffTree huffTree = new HuffTree(frequencyTable);
LookupTable lookupTable = huffTree.getLookupTable();
int padding = writeEncodedFile(encodedfilename, toEncode, lookupTable);
lookupTable.setPadding(padding);
saveLookupTable(lookuptablefilename, lookupTable);
printCompressionRatios(sourcefilename, encodedfilename);
}
public static int writeEncodedFile(String encodedfilename, ArrayList<Integer> toEncode, LookupTable lookupTable) {
BitFileWriter writer = new BitFileWriter(encodedfilename);
String out = "";
for(int i = 0; i < toEncode.size(); i++) {
out = (String) lookupTable.findsCodeFromRaw.get(toEncode.get(i));
for(int j = 0; j < out.length(); j++) {
writer.writeBit(Character.toString(out.charAt(j)));
}
}
int padding = writer.finish();
System.out.printf("Padding: %d\n",padding);
return padding;
}
public static ArrayList<Integer> readSource(String sourcefilename) {
FileInputStream sourceStream = null;
try {
sourceStream = new FileInputStream(sourcefilename);
} catch (FileNotFoundException fnfe) {
System.out.printf("File not found.\n");
System.exit(0);
}
ArrayList<Integer> toEncode = new ArrayList<Integer>();
int toEncodeRaw = 0;
try {
while((toEncodeRaw = sourceStream.read()) != -1) {
toEncode.add(toEncodeRaw);
}
} catch (IOException ioe) {
System.out.printf("IOException.\n");
System.exit(0);
}
return toEncode;
}
public static void saveLookupTable(String lookuptablefilename, LookupTable lookupTable) {
try {
FileOutputStream fileOut = new FileOutputStream(lookuptablefilename);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(lookupTable);
out.close();
fileOut.close();
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void printCompressionRatios(String in, String out) {
File inFile = new File(in);
File outFile = new File(out);
long inFileSize = inFile.length();
long outFileSize = outFile.length();
double ratio = outFileSize / (double) inFileSize;
System.out.println("Size of infile: " + inFileSize);
System.out.println("Size of outfile: " + outFileSize);
System.out.println("Compression ratio: " + ratio);
}
}