All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.mycomm.itool.compress.huffman.s2.Huffman Maven / Gradle / Ivy

The newest version!
package com.mycomm.itool.compress.huffman.s2;

/**
 * Huffman Tree Class Written By: Mitchell Pomery (21130887) Used to create
 * mappings for use in huffman coding
 *
 */
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.util.PriorityQueue;
import java.util.ArrayList;

public class Huffman //implements CITS2200.Compressor
{

    
    public String compress(InputStream in, OutputStream out) {
        return null;
    }

    public String compress(InputStream in1, InputStream in2, OutputStream out) {
        try {
            WriteBuffer wb = new WriteBuffer(out, true);
            byte[] buffer = new byte[10240];

            //Get frequency of each character in the input
            int searching = in1.read(buffer);
            int[] frequency = new int[256];
            while (searching > 0) {
                for (int i = 0; i < searching; i++) {
                    frequency[(int) buffer[i] + 128]++;
                }
                searching = in1.read(buffer);
            }
            in1.close();
            //Put the frequencies into a priority queue as Huffman trees
            PriorityQueue ph = new PriorityQueue();
            HuffmanTree null_tree = new HuffmanTree();
            for (int i = 0; i < 256; i++) {
                if (frequency[i] > 0) {
                    ph.offer(new HuffmanTree((byte) (i - 128), null_tree,
                            null_tree, frequency[i]));
                }
            }
            //This stops a bug where there is only one sort of byte in a file
            if (ph.size() == 1) {
                ph.offer(new HuffmanTree((byte) 0, null_tree, null_tree, 0));
            }
            //Build a Huffman Tree
            while (ph.size() > 1) {
                HuffmanTree bt_get1 = ph.poll();
                HuffmanTree bt_get2 = ph.poll();
                HuffmanTree add = new HuffmanTree(bt_get1, bt_get2,
                        bt_get1.frequency + bt_get2.frequency);
                ph.offer(add);
            }
            //Get our huffman tree
            HuffmanTree htree = ph.poll();
            //Write our huffman tree to the output
            wb.write(htree.toBooleanArray());
            //Grab a boolean[][] so we can convert the second stream
            boolean[][] huffmantreeArrayList = htree.toArrayList();

            //Convert data to compressed stream
            searching = in2.read(buffer);
            while (searching > 0) {
                for (int i = 0; i < searching; i++) {
                    byte characterByte = buffer[i];
                    boolean[] characterBoolArray
                            = huffmantreeArrayList[(int) characterByte + 128];
                    wb.write(characterBoolArray);
                }
                searching = in2.read(buffer);
            }
            //Flush out output so everything is written
            wb.flush();
            in2.close();
            out.close();
        } catch (IOException ex) {
            System.out.println("IO Exception111");
            System.out.println(ex.getMessage());
        }
        return null;
    }

   
    public String decompress(InputStream in, OutputStream out) {
        try {
            WriteBuffer wb = new WriteBuffer(out, false);

            byte[] buffer = new byte[12288];
            boolean[] bufferbool = new boolean[8];
            boolean[] treeleaf = new boolean[8];
            boolean treefound = false;
            int numLeavesThisLevel = 0;
            int numLeaves = 0;
            int nodesFoundThisLevel = 0;
            int nodesThisLevel = 1;
            boolean treemade = false;
            int numLeavesFound = 0;
            int treeleafposition = 0;

            ArrayList htreebuilder = new ArrayList();
            ArrayList leaves = new ArrayList();
            htreebuilder.add(new HuffmanTree());
            HuffmanTree htree = htreebuilder.get(0);
            HuffmanTree currentTree = htree;
            int position = 0;

            int searching = in.read(buffer);
            while (searching > 0) {
                for (int i = 0; i < (searching - 2); i++) {
                    bufferbool = BitByteConverter.byteToBooleanArray(buffer[i]);
                    for (int j = 0; j < 8; j++) {
                        if (!treefound) {
                            //Make the tree
                            if (bufferbool[j]) {
                                //We have a leaf
                                HuffmanTree lookingat = htreebuilder.get(position);
                                leaves.add(lookingat);

                                numLeavesThisLevel++;
                                numLeaves++;
                            } else {
                                //No Leaf
                                HuffmanTree lookingat = htreebuilder.get(position);
                                lookingat.left = new HuffmanTree();
                                lookingat.right = new HuffmanTree();
                                htreebuilder.add(lookingat.getLeft());
                                htreebuilder.add(lookingat.getRight());

                                nodesFoundThisLevel++;
                            }
                            position++;
                            if ((nodesFoundThisLevel + numLeavesThisLevel) == nodesThisLevel) {
                                nodesThisLevel = nodesFoundThisLevel * 2;
                                nodesFoundThisLevel = 0;
                                numLeavesThisLevel = 0;
                                if (nodesThisLevel == 0) {
                                    treefound = true;
                                }
                            }
                        } else if (!treemade) {
                            //Map characters to the tree
                            treeleaf[treeleafposition] = bufferbool[j];
                            treeleafposition++;
                            if (treeleafposition == 8) {
                                //We have the tree node
                                HuffmanTree leaf = leaves.get(numLeavesFound);
                                leaf.character = BitByteConverter.booleanArrayToByte(treeleaf);
                                leaf.leafnode = true;
                                treeleafposition = 0;
                                numLeavesFound++;

                                if (numLeavesFound == numLeaves) {
                                    treemade = true;
                                }
                            }
                        } else {
                            //Decompress the file
                            if (!bufferbool[j]) {
                                currentTree = currentTree.getLeft();
                            } else {
                                currentTree = currentTree.getRight();
                            }
                            if (currentTree.isLeaf()) {
                                wb.write(currentTree.getCharacter());
                                currentTree = htree;
                            }
                        }
                    }
                }
                //System.out.println("Depressing Loop");
                buffer[0] = buffer[searching - 2];
                buffer[1] = buffer[searching - 1];
                searching = in.read(buffer, 2, buffer.length - 2);
                if (searching != -1) {
                    searching += 2;
                }
            }
            //System.out.println("Breaking Free!");
            //We get to here with only 2 bytes left
            //one of which tells us how much padding there is
            boolean[] paddingBits = BitByteConverter.byteToBooleanArray(buffer[0]);
            boolean[] lastBits = BitByteConverter.byteToBooleanArray(buffer[1]);
            int bytesToIgnore = 0;
            for (int i = 0; i < 8; i++) {
                if (lastBits[i]) {
                    bytesToIgnore++;
                }
            }
            bufferbool = paddingBits;
            for (int j = 0; j < (8 - bytesToIgnore); j++) {
                if (!bufferbool[j]) {
                    currentTree = currentTree.getLeft();
                } else {
                    currentTree = currentTree.getRight();
                }
                if (currentTree.isLeaf()) {
                    wb.write(currentTree.getCharacter());
                    currentTree = htree;
                }
            }
            //Flush and close everything
            wb.flush();
            in.close();
            out.close();
        } catch (IOException ex) {
            System.out.println("IO Exception");
            System.out.println(ex.getMessage());
        }
        return null;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy