算术编码压缩算法的误差

时间:2016-12-07 15:59:22

标签: java algorithm

我正在尝试实现算术编码,这是一种压缩算法。这是压缩代码。当我编译它时

线程中的异常" main" java.lang.RuntimeException:无法编译的源代码 - 错误的树类型:arithmetic.FrequencyTable     at arithmetic.ArithmeticCompress.main(ArithmeticCompress.java:35)

它给了我这个错误。

package arithmetic;

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.InputStream;


public class ArithmeticCompress {

public static void main(String[] args) throws IOException {


    File inputFile  = new File("D:\\5.txt");
    File outputFile = new File("D:\\new1.txt");

    // Read input file once to compute symbol frequencies
    //Line no 35
    FrequencyTable freqs = getFrequencies(inputFile);
    freqs.increment(256);  // EOF symbol gets a frequency of 1

    // Read input file again, compress with arithmetic coding, and write output file
    try (InputStream in = new BufferedInputStream(new FileInputStream(inputFile))) {
        try (BitOutputStream out = new BitOutputStream(new BufferedOutputStream(new FileOutputStream(outputFile)))) {
            writeFrequencies(out, freqs);
            compress(freqs, in, out);
        }
    }
}


// Returns a frequency table based on the bytes in the given file.
// Also contains an extra entry for symbol 256, whose frequency is set to 0.
private static FrequencyTable getFrequencies(File file) throws IOException {
    FrequencyTable freqs = new SimpleFrequencyTable(new int[257]);
    try (InputStream input = new BufferedInputStream(new FileInputStream(file))) {
        while (true) {
            int b = input.read();
            if (b == -1)
                break;
            freqs.increment(b);
        }
    }
    return freqs;
}


// To allow unit testing, this method is package-private instead of private.
static void writeFrequencies(BitOutputStream out, FrequencyTable freqs) throws IOException {
    for (int i = 0; i < 256; i++)
        writeInt(out, 32, freqs.get(i));
}


// To allow unit testing, this method is package-private instead of private.
static void compress(FrequencyTable freqs, InputStream in, BitOutputStream out) throws IOException {
    ArithmeticEncoder enc = new ArithmeticEncoder(out);
    while (true) {
        int symbol = in.read();
        if (symbol == -1)
            break;
        enc.write(freqs, symbol);
    }
    enc.write(freqs, 256);  // EOF
    enc.finish();  // Flush remaining code bits
}


// Writes an unsigned integer of the given bit width to the given stream.
private static void writeInt(BitOutputStream out, int numBits, int value) throws IOException {
    if (numBits < 0 || numBits > 32)
        throw new IllegalArgumentException();

    for (int i = numBits - 1; i >= 0; i--)
        out.write((value >>> i) & 1);  
}

}

1 个答案:

答案 0 :(得分:0)

嗯,它有点奇怪,因为这样的源代码甚至不应该编译(因此不应该是任何RuntimeException):因为你的代码引用了类FrequencyTable,但是那个类没有被定义在您的代码中,它甚至没有导入?不确定。但通常,这会导致编译错误,你不应该能够运行这样的代码 - 在这里我想你正在使用一些IDE(比如NetBeans,也许是eclipse),它允许你运行代码,即使它没有编译 - &gt;但它在rutime期间会失败。

我建议您在IDE中完全重建(清理和编译)项目,以显示您在代码中可能出现的错误...