Thursday 30 June 2016

LZW Compression & Decompression

LZW Compression & Decompression

Description:    This Java code is an implementation of Lempel Ziv’s algorithm for data compression and decompression. This is a simple LZW algorithm exampleThe 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.


Download LZW Compression & Decompression Code



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

Recent Posts