info_teorija_1.Encode.java Source code

Java tutorial

Introduction

Here is the source code for info_teorija_1.Encode.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.io.OutputStream;
import java.util.concurrent.TimeUnit;

import com.google.common.base.Stopwatch;

public class Encode {

    private static BitOutput output = null;
    private static BitInput input = null;

    private static int wordLength = 0;
    private static StringBuffer buffer = new StringBuffer();
    private static int[] byteFreqs = new int[65536];
    private static int bytesLength = 0;

    public static void clear() {
        output = null;
        input = null;
        wordLength = 0;
        buffer = new StringBuffer();
        byteFreqs = new int[65536];
        bytesLength = 0;
    }

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

        /* create input/output buffered file streams */
        FileInputStream inputStream = new FileInputStream(in);
        BufferedInputStream src = new BufferedInputStream(inputStream);
        input = new BitInput(src);

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

        getFrequenciesAndWriteRemainder(in, wordLength);
        System.out.println("getFrequancies " + time.elapsed(TimeUnit.MILLISECONDS));

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

        // build tree
        HuffmanTree tree = HuffmanCode.buildTree(byteFreqs);
        System.out.println("BuildTree " + time.elapsed(TimeUnit.MILLISECONDS));

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

        // generateCodes and fill huffmanTable
        HuffmanCode.genCodes(tree, new StringBuffer());
        System.out.println("genCodes " + time.elapsed(TimeUnit.MILLISECONDS));

        Encode.wordLength = wordLength;

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

        output.writeUnsignedInt(4, wordLength - 1);
        output.writeUnsignedLong(32, bytesLength);

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

        encodeFile();

        System.out.println("encodeFile " + time.elapsed(TimeUnit.MILLISECONDS));
        time.stop();

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

    private static void encodeTree(HuffmanTree tree) throws IOException {
        if (tree instanceof HuffmanLeaf) {

            buffer.append("1");

            for (char c : buffer.toString().toCharArray()) {
                if (c == '1') {
                    output.writeBoolean(true);
                } else
                    output.writeBoolean(false);
            }
            buffer.delete(0, buffer.length());
            output.writeUnsignedInt(wordLength, ((HuffmanLeaf) tree).value);

        } else if (tree instanceof HuffmanNode) {
            buffer.append("0");
            encodeTree(((HuffmanNode) tree).left);
            encodeTree(((HuffmanNode) tree).right);
        }
    }

    private static void encodeFile() throws IOException {
        int count = 0;

        while (count < bytesLength) {
            int b = input.readUnsignedInt(wordLength);

            String temp = HuffmanCode.encodeTable.get(b);

            for (char c : temp.toCharArray()) {
                if (c == '1') {
                    output.writeBoolean(true);
                } else if (c == '0') {
                    output.writeBoolean(false);
                }
            }
            count++;
        }

        output.writeInt(7, 0);
    }

    private static void getFrequenciesAndWriteRemainder(File file, int wordLength) throws IOException {
        FileInputStream stream = new FileInputStream(file);
        BufferedInputStream src = new BufferedInputStream(stream);
        BitInput input = new BitInput(src);
        long len = file.length() * 8;

        while (len > 0 && (len - wordLength) >= 0) {
            int value = input.readUnsignedInt(wordLength);
            ++byteFreqs[value];

            len -= wordLength;
            ++bytesLength;
        }
        if (len > 0) {
            // length of remainder
            int length = (int) len;
            output.writeUnsignedInt(4, length);
            output.writeUnsignedInt(15, input.readUnsignedInt(length));
        } else {
            output.writeUnsignedInt(4, 0);
            output.writeUnsignedInt(15, 0);
        }
    }

}