info_teorija_1.Decode.java Source code

Java tutorial

Introduction

Here is the source code for info_teorija_1.Decode.java

Source

/*
 *  Copyright 2013 Povilas Versockas
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package info_teorija_1;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

import com.google.common.base.Stopwatch;

public class Decode {
    private static long length = 0;
    private static HuffmanNode tree = null;
    private static int totalHuffmanLeafs = 0;
    private static int currentHuffmanLeafs = 0;
    private static HuffmanNode current = tree;
    private static BitInput input = null;
    private static BitOutput output = null;
    private static int wordLength = 0;

    public static void clear() {
        length = 0;
        tree = null;
        current = tree;
        input = null;
        output = null;
        wordLength = 0;
        totalHuffmanLeafs = 0;
        currentHuffmanLeafs = 0;
    }

    public static void decode(File in, File out) throws IOException {
        Stopwatch total = Stopwatch.createStarted();
        Stopwatch time = Stopwatch.createStarted();

        FileInputStream src = new FileInputStream(in);
        BufferedInputStream inputStream = new BufferedInputStream(src);
        input = new BitInput(inputStream);

        FileOutputStream dst = new FileOutputStream(out);
        BufferedOutputStream outputStream = new BufferedOutputStream(dst);
        output = new BitOutput(outputStream);

        int remainderLength = input.readUnsignedInt(4);
        int remainder = 0;

        if (remainderLength != 0) {
            remainder = input.readUnsignedInt(15);
        } else {
            input.readUnsignedInt(15);
        }

        wordLength = input.readUnsignedInt(4) + 1;
        length = input.readUnsignedLong(32);

        System.out.println("setup() " + time.elapsed(TimeUnit.MILLISECONDS));
        time.stop();
        time = Stopwatch.createStarted();

        while (true) {
            if (totalHuffmanLeafs != 0 && totalHuffmanLeafs == currentHuffmanLeafs) {
                break;
            }
            decodeTree();
        }
        System.out.println("decodeTree() " + time.elapsed(TimeUnit.MILLISECONDS));

        time.stop();
        time = Stopwatch.createStarted();

        HuffmanCode.genCodes(tree, new StringBuffer());
        System.out.println("genCodes() " + time.elapsed(TimeUnit.MILLISECONDS));

        time.stop();
        time = Stopwatch.createStarted();

        decodeFile();
        System.out.println("decodeFile() " + time.elapsed(TimeUnit.MILLISECONDS));
        if (remainderLength != 0)
            output.writeUnsignedInt(remainderLength, remainder);

        inputStream.close();
        outputStream.close();
        System.out.println("total: " + total.elapsed(TimeUnit.MILLISECONDS));

    }

    private static HuffmanTree findFather(HuffmanTree current) {
        if (current instanceof HuffmanNode) {
            HuffmanNode node = (HuffmanNode) current;

            if (node.right != null && node.left != null)
                return findFather(current.father);
            else {
                return current;
            }
        }
        return null;
    }

    private static void decodeTree() throws IOException {
        boolean i = input.readBoolean();
        if (i) {
            currentHuffmanLeafs += 1;

            int value = input.readUnsignedInt(wordLength);
            HuffmanLeaf leaf = new HuffmanLeaf(0, value);
            leaf.father = current;
            if (current.left == null) {
                current.left = leaf;
            } else if (current.right == null) {
                current.right = leaf;
                current = (HuffmanNode) findFather(current.father);

            }

        } else {
            if (current == null) {
                totalHuffmanLeafs += 2;
                current = new HuffmanNode(null, null);
                current.father = null;
                tree = current;

            } else if (current.left == null) {
                totalHuffmanLeafs += 1;
                HuffmanNode node = new HuffmanNode(null, null);
                node.father = current;

                current.left = node;
                current = (HuffmanNode) current.left;

            } else if (current.right == null) {
                totalHuffmanLeafs += 1;
                HuffmanNode node = new HuffmanNode(null, null);
                node.father = current;
                current.right = node;
                current = (HuffmanNode) current.right;

            }
        }

    }

    private static void decodeFile() throws IOException {
        StringBuffer buffer = new StringBuffer();

        int index = 0;
        while (index < length) {

            boolean isSet = input.readBoolean();
            if (isSet) {
                buffer.append('1');
            } else {
                buffer.append('0');
            }

            if (HuffmanCode.decodeTable.containsKey(buffer.toString())) {
                int value = HuffmanCode.decodeTable.get(buffer.toString());
                output.writeInt(wordLength, value);
                buffer.delete(0, buffer.length());
                index++;
            }

        }

    }
}