Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.HashMap;
- import java.util.PriorityQueue;
- public class SimpleHuffProcessor implements IHuffProcessor {
- //Global Variables
- private HuffViewer myViewer;
- private TreeNode myRoot;
- private HashMap<Integer, String> map;
- private int[] arr;
- public int compress(InputStream in, OutputStream out, boolean force) throws IOException {
- if(preprocessCompress(in)<0 && force==false) {
- throw new IOException("Cannot compress since resulting file will " +
- "be bigger. Use force compress if you really want to compress");
- }
- //Initialize variables
- in.reset();
- int count =0;
- BitOutputStream bout= new BitOutputStream(out);
- BitInputStream bin=new BitInputStream(in);
- //Write magic number
- bout.writeBits(BITS_PER_INT, MAGIC_NUMBER);
- count+=BITS_PER_INT;
- //Write Header
- for(int k=0; k<ALPH_SIZE; k ++) {
- bout.writeBits(BITS_PER_INT, arr[k]);
- }
- bout.writeBits(BITS_PER_INT, arr[PSEUDO_EOF]);
- //Write out the characters in compressed form
- int next;
- while((next=bin.readBits(BITS_PER_WORD))!=-1) {
- for(int i =0; i<map.get(next).length(); i ++) {
- if(map.get(next).charAt(i)=='1')
- bout.writeBits(1, 1);
- else
- bout.writeBits(1, 0);
- count++;
- }
- }
- //Write out the EOF
- for(int i=0; i<map.get(PSEUDO_EOF).length(); i ++) {
- if(map.get(PSEUDO_EOF).charAt(i)=='1')
- bout.writeBits(1, 1);
- else
- bout.writeBits(1, 0);
- count++;
- }
- //Close the Input and Output Streams
- bout.close();
- bin.close();
- in.close();
- out.close();
- return count;
- }
- public int preprocessCompress(InputStream in) throws IOException {
- //Initialize variables
- BitInputStream bin=new BitInputStream(in);
- map= new HashMap<Integer,String>();
- int next;
- arr = new int [ALPH_SIZE+1];
- Arrays.fill(arr, 0);
- //Create the frequency count array
- while((next=bin.readBits(8))!=-1)
- arr[next]++;
- arr[PSEUDO_EOF]=1;
- //Add the nodes into a priority queue
- PriorityQueue<TreeNode> pq = new PriorityQueue<TreeNode>();
- for(int i =0; i<arr.length; i ++) {
- if(arr[i]>0)
- pq.add(new TreeNode(i, arr[i]));
- }
- //Create the tree
- while(pq.size()>1) {
- TreeNode n1=pq.poll();
- TreeNode n2=pq.poll();
- TreeNode n3= new TreeNode(-1, n1.myWeight+n2.myWeight, n1, n2);
- pq.add(n3);
- }
- myRoot=pq.poll();
- //Create the map
- int saved= getCode(myRoot,"");
- saved-=arr.length*BITS_PER_INT;
- bin.close();
- in.close();
- return saved;
- }
- //creates the compressed code
- public int getCode(TreeNode n, String prefix) {
- // if node is a leaf
- if(n.myLeft== null && n.myRight==null) {
- if(n.myValue==256) {
- map.put(n.myValue, prefix);
- return -prefix.length();
- }
- map.put(n.myValue, prefix);
- return n.myWeight*(8-prefix.length());
- }
- //Goes left and then right
- int l=getCode(n.myLeft, prefix+"0");
- int r=getCode(n.myRight, prefix+"1");
- return l+r;
- }
- public void setViewer(HuffViewer viewer) {
- myViewer = viewer;
- }
- public int uncompress(InputStream in, OutputStream out) throws IOException {
- BitInputStream bin = new BitInputStream(in);
- BitOutputStream bout= new BitOutputStream(out);
- //reads the first 32 bits and checks for magic number
- int magic= bin.readBits(BITS_PER_INT);
- if(magic!=MAGIC_NUMBER) {
- bin.close();
- bout.close();
- in.close();
- out.close();
- throw new IOException("File not in compressed form.");
- }
- //creates the array of frequencies
- int[] array= new int[ALPH_SIZE+1];
- for(int k =0; k<array.length; k ++) {
- int bits= bin.readBits(BITS_PER_INT);
- array[k]=bits;
- }
- // add the nodes to the priority queue
- PriorityQueue<TreeNode> pq = new PriorityQueue<TreeNode>();
- for(int i =0; i<array.length; i ++) {
- if(array[i]>0)
- pq.add(new TreeNode(i, array[i]));
- }
- // create the tree
- while(pq.size()>1) {
- TreeNode n1=pq.poll();
- TreeNode n2=pq.poll();
- TreeNode n3= new TreeNode(-1, n1.myWeight+n2.myWeight, n1, n2);
- pq.add(n3);
- }
- // get the root
- myRoot=pq.poll();
- // write out the bits
- int count = 0;
- TreeNode current = myRoot;
- while(true) {
- int bits=bin.readBits(1);
- if(bits==-1) {
- bin.close();
- bout.close();
- throw new IOException("error reading bits, no EOF");
- }
- if((bits & 1)==0)
- current=current.myLeft;
- else
- current=current.myRight;
- if(current.myLeft==null && current.myRight==null) {
- if(current.myValue==PSEUDO_EOF) {
- break;
- }
- else {
- bout.writeBits(BITS_PER_WORD, current.myValue);
- current= myRoot;
- count+=BITS_PER_WORD;
- }
- }
- }
- bout.close();
- bin.close();
- in.close();
- out.close();
- return count;
- }
- private void showString(String s){
- myViewer.update(s);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement