Description: This Java code is an implementation of Lempel Ziv’s algorithm for data compression and decompression. This is a simple LZW algorithm example. The input file is a text file containing simple English text. The program compresses this text file using LZW compression algorithm and can decompress a compressed file (compressed by this program) using LZW decompression algorithm. Hash Maps are used for storing dictionary of unique strings.
Java
Code
package compression;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.stream.Stream;
/**
*
*
@author www.hazacs.com
*/
public class Compression {
/**
* @param args the command line arguments
*/
public static String readFile(String fileName){
try {
FileInputStream fis = new
FileInputStream(fileName);
byte[] data = new byte[100000];
fis.read(data);
fis.close();
String fileText = new String(data, "UTF-8");
if (fileText.indexOf(0)!=-1)
fileText=fileText.substring(0, fileText.indexOf(0));
return fileText;
}
catch(FileNotFoundException ex) {
System.out.println("Unable to open file '" +fileName + "'");
}
catch(IOException ex) {
System.out.println("Error reading file '"+ fileName + "'");
}
return null;
}
public static void writeFile(String fileName,String data) {
try {
PrintWriter writer = new PrintWriter(fileName, "UTF-8");
writer.println(data);
writer.close();
}
catch(FileNotFoundException ex) {
System.out.println("Unable to open file '" +fileName + "'");
}
catch(IOException ex) {
System.out.println("Error reading file '"+ fileName + "'");
}
}
public static String convertToBinary(String text){
String binary="";
for(int i=0;i<text.length()&&text.charAt(i)!=0;i++){
String b=Integer.toBinaryString(text.charAt(i));
for(int j=b.length()+1;j<=8;j++)
b = "0"+b;
binary=binary.concat(b);
}
return binary;
}
public static String Encode(String binary) {
HashMap hm=new HashMap();
int count=1;
for(int i=0;i<binary.length();i++){
for(int j=i+1;j<=binary.length();j++){
String temp=binary.substring(i, j);
if(!hm.containsKey(temp)){
hm.put(temp, count++);
i=j-1;
break;
}
if(j==binary.length()){
hm.put(temp+"?", count++);
}
}
}
String array[]=new String[hm.size()];
Iterator it = hm.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
if(pair.getValue().toString().equals("1")){
array[Integer.parseInt(pair.getValue().toString())-1]=pair.getKey().toString();
}
else{
String temp1=pair.getKey().toString(),temp2;
if(temp1.charAt(temp1.length()-1)=='?'){
temp2=temp1.substring(0, temp1.length()-1);
}
else{
temp2=temp1.substring(0,temp1.length()-1);
}
int x=0;
if(hm.get(temp2)!=null)
x=Integer.parseInt(hm.get(temp1).toString(),10)-Integer.parseInt(hm.get(temp2).toString(),10);
temp2=String.valueOf(temp1.charAt(temp1.length()-1));
String tempBinary=Integer.toBinaryString(x);
Double d=new Double(Math.ceil(Math.log(Integer.parseInt(pair.getValue().toString()))/Math.log(2)));
int logOfBlockNo=d.intValue();
int tempBinaryLength=tempBinary.length();
for(int i=0;i<logOfBlockNo-tempBinaryLength;i++)
tempBinary = "0"+tempBinary;
array[Integer.parseInt(pair.getValue().toString())-1]=tempBinary+temp2;
}
}
String finalResult="";
for(int y=0;y<array.length;y++){
finalResult=finalResult.concat(array[y]);
if (array[y].charAt(array[y].length()-1)=='?')
break;
}
return finalResult;
}
public static String Decode(String text) {
ArrayList<String> list=new ArrayList<String>();
list.add(text.substring(0,1));
for(int blockNo=2,i=1;i<text.length();blockNo++){
Double d=new Double(Math.ceil(Math.log(blockNo)/Math.log(2)));
int logOfBlockNo=d.intValue();
String temp;
if(i+logOfBlockNo+1<=text.length()){
temp=text.substring(i, i+logOfBlockNo+1);
}
else{
temp=text.substring(i, text.length());
}
i=i+logOfBlockNo+1;
if(i>=text.length())
list.add(temp);
else{
int ty;
if(temp.length()==1){
ty=Integer.parseInt(temp.substring(0, temp.length()), 2);
}
else{
ty=Integer.parseInt(temp.substring(0, temp.length()-1), 2);
}
if(ty!=0){
int in=blockNo-1-ty;
String ss=list.get(in);
list.add(ss+temp.substring(temp.length()-1, temp.length()));
}
else
list.add(temp.substring(temp.length()-1, temp.length()));
}
}
String finalBinary="";
for(int i=0;i<list.size();i++){
finalBinary=finalBinary.concat(list.get(i));
}
String resultString="";
for(int i=0;i+8<finalBinary.length();i+=8){
char c=(char)Integer.parseInt(finalBinary.substring(i, i+8), 2);
resultString=resultString.concat(String.valueOf(c));
}
System.out.println(resultString);
return resultString;
}
public static void main(String [] args) {
Scanner input = new Scanner(System.in);
System.out.print("What do
you want to do?\n1) Encode 2) Decode\nEnter option: ");
int choice = input.nextInt();
while(choice!=1 && choice!=2){
System.out.println("\nEnter valid option i.e. enter either 1 or
2\n");
System.out.print("What do you want to do?\n1) Encode 2) Decode\nEnter
option: ");
choice = input.nextInt();
}
if(choice==1){
String fileText=readFile("fileToEncode.txt");
String bin=convertToBinary(fileText);
String res=Encode(bin);
System.out.println("\nEncoded result: "+res+"\n");
writeFile("Encoding Result.txt",res);
}
else if(choice==2){
String fileText=readFile("fileToDecode.txt");
String res=Decode(fileText);
System.out.println("\nDecoded result: "+res+"\n");
writeFile("Decoding Result.txt",res);
}
}
}
No comments
Post a Comment