【问题标题】:How to create Huffman tree from FFC4 (DHT) header in jpeg file?如何从 jpeg 文件中的 FFC4 (DHT) 标头创建 Huffman 树?
【发布时间】:2010-10-14 08:04:49
【问题描述】:

我以为我可以自己解决这个问题,但我似乎根本没有前进。

好的,背景:

我需要根据 jpg 文件中的 FFC4、DHT(定义霍夫曼表)标题提供的信息创建一个霍夫曼代码树。 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) 因此,如果有人理解我的胡言乱语,我将非常感谢您提供一些建议。我意识到这是一个非常具体的问题,但如果没有别的,上面的信息可能对某人有帮助。我在这方面还很陌生,所以请原谅我的无知,特别欢迎易于理解的代码!

【问题讨论】:

  • 这对我帮助很大。谢谢你,你是国王:D

标签: java jpeg huffman-code


【解决方案1】:

至于如何直接实现这一点我不完全确定,因为处理信息需要一段时间,但如果您了解tries,算法应该非常简单。从第 7 点开始,您似乎没有?

我将添加一个示例:

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

在这个简单的 trie 中,如果我们向左走,我们会假设左边是 0,右边是 1。所以如果你遇到模式 '00' 这对应于一个 a。模式“10”对应于 c。通常对于霍夫曼树,特里树将是不平衡的,即

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

在这种情况下,前缀代码“0”对应一个a。将代码 111 转换为“d”。

【讨论】:

  • 感谢 wds,在另一个类似问题的帖子中向我提到了尝试。我不确定我是否理解它们和二叉树之间的区别。问题是我在直接从 DHT 标头信息中有效地创建 trie/tree 时遇到了问题。
  • 别担心,我意识到对于任何具体答案来说,这可能是一个太深奥的问题。我有点希望我可能会遇到一个拥有自己解码器的 jpg 大师,他可以按照我的方式抛出一些现成的代码!
  • 嗯,您能否编辑您的问题以解释您如何知道例如两位的符号被编码为 00 而不是 11?那我大概能想出一个算法。
【解决方案2】:

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

【讨论】:

  • 我认为我有点简洁,所以我只是添加了一个示例来引出这一点。 :)
猜你喜欢
  • 1970-01-01
  • 2012-07-20
  • 1970-01-01
  • 1970-01-01
  • 2010-12-06
  • 1970-01-01
  • 1970-01-01
  • 2012-02-17
  • 1970-01-01
相关资源
最近更新 更多