zoukankan      html  css  js  c++  java
  • 【原创】JPEG图像密写研究(二) 哈夫曼树的建立

    【原创】记录自己研究的过程,仅供参考,欢迎讨论。。。

    在根据JPEG图像文件结构读取完文件后,提取出其中DHT段,利用其中内容建立哈夫曼树,便于之后译码工作。这里需要注意的是文件中的哈夫曼表数量不固定,可能为一个,可能为四个,即是可能需要建立多个哈夫曼树,要注意数据选择,不要选择了其他树的数据。

    下面为DHT段内容:

     DHT,Difine Huffman Table,定义哈夫曼表

    标记代码                                 2字节            固定值0xFFC4

    包含2个具体字段:
     ①数据长度                             2字节            字段①和多个字段②的总长度
                                                                       即不包括标记代码,但包括本字段
     ②哈夫曼表              数据长度-2字节

    a)表ID和表类型            1字节            高4位:类型,只有两个值可选
                                                                         0:DC直流;1:AC交流
                                                            低4位:哈夫曼表ID,
                                                                         注意,DC表和AC表分开编码

    b)不同位数的码字数量    16字节

    c)编码内容       16个不同位数的码字数量之和(字节)

    我们可以从 ①数据长度 得到哈夫曼表的总大小,这样可以保证不会读取出界。每个表的长度也可以从 b)不同位数的码字数量 得到,这16个字节的和就是这个表的长度。c)编码内容 并不是图像的数据内容,而是从小到大每个码字的权值,权值在建树时用不上,但是后面译码离不开它,因此在建树时也要保存每个码字的权值。

    这里以一个哈夫曼表为例,介绍一下建立过程。

    首先,第一个字节为表ID和表类型,这是以后译码需要的东西,保存下来,能和之后的树对应上即可。

    其次,16个字节分别对应从1-16码长的编码个数,即第一个字节记录码长为1的编码个数,第二个为码长为2的编码个数,以此类推。。。因此这16个字节加起来即为所有编码个数,这也是很重要的。读取这16个字节的同时即可建立树,在建树的同时读取对应的权值保存即可,在读完的同时,树也建立完成~

    对于读取到的编码个数,有两种情况,为0或者不为0(废话。。),下面讨论两种情况各自的处理办法:

    • 为0

      为0则说明没有该码长的编码,这就说明树生长到这里没有叶子,产生的均为内节点,则当前的每个节点都继续生长。

      例如,读取的第一个字节为0,则说明码长为1的编码个数为0,这时就需要从根节点继续生长,即根节点产生左右儿子,并且这两个子节点均不是叶节点,再读取下一个字节的时候,这两个节点都需要继续生长。

    • 不为0

      不为0则说明该码长的编码有,假设为1,其他同理,依旧是第一个字节的时候,这时有一个根节点,并且其生长出来的一个儿子是叶节点,即该节点不会再生长,另一个儿子为内节点,读取下个字节的时候继续生长。

    之后不断读取剩下的字节,根据上面进行处理,读完即可建立完树。

    每个码字对应的权值在建树时即可读取,权值的位置可以由编码在16个字节中的位置和已读取的字节数推算出来,这个具体的关系画个图就可以看出来了。

    PS:C/C++中的指针需要初始化,不然很容易内存泄露,后果都懂的,在找到毛病前,我的VS已经未响应了好多次。。。。

    PPS:图像数据中可能会有多个DHT段,如果为了程序的兼容性,需要考虑到多个DHT段的情况,否则最终只记录了一个哈夫曼树的数据~

  • 相关阅读:
    Linux中断的系统调用
    线程的概念
    C++ 虚函数表浅析
    C++虚函数工作原理
    深入浅出单实例Singleton设计模式
    《角斗士》一个帝国的史诗绝唱
    《妖猫传》大唐盛世背后那些事
    程序员之路
    职业规划
    一些重要的算法
  • 原文地址:https://www.cnblogs.com/gungnir2011/p/3615287.html
Copyright © 2011-2022 走看看