有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何从jpeg文件中的FFC4(DHT)头创建哈夫曼树?

我以为我能自己解决这个问题,但我似乎一点进展都没有

好的,背景:

我需要根据jpg文件中FFC4、DHT(Define Huffman Table)头文件提供的信息创建一个哈夫曼代码树。DHT头文件用以下方式定义了哈夫曼表:

1)一系列16字节。每个字节定义有多少个符号具有n个比特数的哈夫曼码,其中n是字节在序列中的位置。(这有意义吗?!!)例如,十六进制的原始数据是:

00 01 05 01 01 01 ... 00

这意味着:

Num of bits:    1   2   3   4   5   6   7 ...  16  
Num of codes:   00  01  05  01  01  01  01 ... 00

2)在16个字节的列表之后是实际的符号本身。例如:

00 01 02 03 04 05 06 07 08 09 0A 0B

3)将这两部分结合起来,我们发现它们是:
00个带1位的代码
01带2位的代码:所以从列表中选择第一个符号:00
05带3位的代码:因此从列表中选取接下来的5个符号:01 02 03 04 05
……等等

4)最后,我们必须根据上述信息计算出实际的哈夫曼代码。如果你是一个数学天才,你可能已经发现,这些代码可以通过简单地增加一个二进制数来计算出来,每一个新代码在一定的位长度上都有合适的位数。当比特长度增加时,只需增加二进制数,然后将其加倍并继续。当你用手画出许多这样的二叉树时,其他人都会很明显

5)这是我用来计算哈夫曼代码并将其存储在数组中的代码:(首先我读取1处的数据,并将其放入数组:dhtBitnum)

            int binaryCode = 0;
            count = 0;
            StringBuffer codeString = new StringBuffer();               

            //populate array with code strings
            for (int numBits=1; numBits<=16; numBits++) {

                //dhtBitnum contains the number of codes that have a certain number of bits
                for (int i=1; i<=dhtBitnum[(numBits-1)]; i++) {

                    //turn the binary number into a string
                    codeString.append(Integer.toBinaryString(binaryCode)); 
                    //prepend 0s until the code string is the right length
                    for(int n=codeString.length(); n<numBits; n++) {
                        codeString.insert(0, "0");
                    }
                    //put the created Huffman code in an array
                    dhtCodes[count]=codeString.toString();
                    binaryCode++;
                    count ++;
                    codeString.delete(0, codeString.length());
                }
                binaryCode = binaryCode << 1;

            }

一旦我生成了哈夫曼代码并按顺序存储,我就可以按顺序添加它们在2)中出现的符号。这可能不是非常优雅,但它似乎至少起到了作用,并创建了正确的表格

6)如果有人仍在关注这一点,你应该获得一枚奖牌

7)现在的问题是,我想把这些信息存储在一个二叉树中,这样我以后就可以有效地解码jpg图像数据,而不是每次都搜索数组。不幸的是,我无法从上述jpg标题中提供的信息中找到一种干净高效的方法来直接实现这一点
我能想到的唯一方法是,首先计算出上面提到的哈夫曼代码,然后实现一些方法,根据需要创建节点,并将符号保存在适当的位置,使用这些代码作为排序地址。然而,这似乎是一种迂回的方式,也复制了我需要的信息,我相信一定有一种更好、更简单的方法

8)因此,如果有人理解我的闲话,我将非常感谢你的建议。我意识到这是一个非常具体的问题,但如果没有其他信息,上面的信息可能会对某人有所帮助。我在这方面还很新,所以请原谅我的无知,易懂的代码尤其受欢迎


共 (2) 个答案

  1. # 1 楼答案

    至于如何直接实现这一点,我不完全确定,因为处理信息需要一段时间,但如果你知道tries,算法应该非常简单。从第七点来看,你似乎没有

    我将添加一个示例:

             °
            / \
           /   \
          °     °
         / \   / \
        a   b  c  d 
    

    在这个简单的trie中,如果我们向左走,我们会假设左边是0,右边是1。因此,如果你遇到模式“00”,这对应于a。模式“10”对应于c。通常情况下,对于哈夫曼树,trie是不平衡的,即

         °
        / \
       a   °
          / \
         b   °
            / \
           c   d
    

    在这种情况下,前缀代码“0”对应于a。代码111对应于a“d”

  2. # 2 楼答案

    正如@wds所说,他试图提供帮助。哈夫曼解码的核心思想是,应该使用代码序列的位来“遍历”trie,当代码为0时向左走,当代码为1时向右走,直到码字结束。然后,您将在trie节点中存储该代码的替换数据