Java tutorial
/* * 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); } } }