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

在根据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段的情况,否则最终只记录了一个哈夫曼树的数据~

【原创】JPEG图像密写研究(二) 哈夫曼树的建立的更多相关文章

  1. 【原创】JPEG图像密写研究(三) 数据流译码

    [原创]这次更新比较慢,译码过程比想象中复杂一些,更主要是译出来的DCT系数无法确定是否正确,要想验证就需要再进行正向压缩编码,再次形成jpeg图像验证正确,后续工作正在开展,这里就说一说译码的主要思 ...

  2. JPEG图像密写研究(一) JPEG图像文件结构

    [转载]转载自http://www.cnblogs.com/leaven/archive/2010/04/06/1705846.html JPEG压缩编码算法的主要计算步骤如下: (0) 8*8分块. ...

  3. 哈夫曼树(二)之 C++详解

    上一章介绍了哈夫曼树的基本概念,并通过C语言实现了哈夫曼树.本章是哈夫曼树的C++实现. 目录 1. 哈夫曼树的介绍 2. 哈夫曼树的图文解析 3. 哈夫曼树的基本操作 4. 哈夫曼树的完整源码 转载 ...

  4. word2vec 中的数学原理二 预备知识 霍夫曼树

    主要参考:    word2vec 中的数学原理详解                 自己动手写 word2vec 编码的话,根是不记录在编码中的 这一篇主要讲的就是霍夫曼树(最优二叉树)和编码.  ...

  5. 树(二叉树 & 二叉搜索树 & 哈夫曼树 & 字典树)

    树:n(n>=0)个节点的有限集.有且只有一个root,子树的个数没有限制但互不相交.结点拥有的子树个数就是该结点的度(Degree).度为0的是叶结点,除根结点和叶结点,其他的是内部结点.结点 ...

  6. Java数据结构(十二)—— 霍夫曼树及霍夫曼编码

    霍夫曼树 基本介绍和创建 基本介绍 又称哈夫曼树,赫夫曼树 给定n个权值作为n个叶子节点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称为最优二叉树 霍夫曼树是带权路径长度最短的树,权值较 ...

  7. [原创.数据可视化系列之十二]使用 nodejs通过async await建立同步数据抓取

    做数据分析和可视化工作,最重要的一点就是数据抓取工作,之前使用Java和python都做过简单的数据抓取,感觉用的很不顺手. 后来用nodejs发现非常不错,通过js就可以进行数据抓取工作,类似jqu ...

  8. HDU 3179 二叉搜索树(树的建立)

    二叉搜索树 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  9. 九度OJ 1107 搬水果 -- 哈夫曼树 2011年吉林大学计算机研究生机试真题

    题目地址:http://ac.jobdu.com/problem.php?pid=1107 题目描述: 在一个果园里,小明已经将所有的水果打了下来,并按水果的不同种类分成了若干堆,小明决定把所有的水果 ...

随机推荐

  1. HTML界面JQuery ajax 返回200,但走Error方法

    原因是JSON拼装的有问题. 都需要放在双引号里面,或者修改dataType的类型为  "html". http://blog.csdn.net/imjcoder/article/ ...

  2. JS 更改表单的提交时间和Input file的样式

    JS转换时间 function renderTime(data) { var da = eval('new ' + data.replace('/', '', 'g').replace('/', '' ...

  3. ecmall 点滴记录

    /* 取得列表数据 */ $model_wish =& m('wish'); $wish= $model_wish->find(array( 'conditions' => 'us ...

  4. QF——iOS的单例模式

    iOS的单例模式: 单例,即为单个实例,确保一个类里只有一个实例,向整个系统提供一个唯一的实例. 甚至为了严格提供唯一的实例,通常只允许该类自己提供实例化的方法,不允许出现其他入口.这时我们通常得重写 ...

  5. Android 内存管理之优化建议

    OOM(OutOfMemory)转:http://hukai.me/android-performance-oom/ 前面我们提到过使用getMemoryClass()的方法可以得到Dalvik He ...

  6. 练习-checkbox 全选 ,反选, 单选,以及取值

    1.方法1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w ...

  7. Enabling Process Accounting on Linux HOWTO

    http://tldp.org/HOWTO/Process-Accounting/index.html

  8. Android LocalActivityManager的用法

    在开发中会碰到在一个activity中的局部(或者是activity的Fragment中)显示其他的activity 的内容,这时就用到了LocalActivityManager类. 假设这个容器是一 ...

  9. java 操作配置文件 .properties

    package com.dms.common; import java.io.File; import java.io.FileInputStream; import java.io.FileNotF ...

  10. csu 1563 Lexicography

    题意:给出一堆字母 问这些字母组成的字符串中第k大的 排列组合,具体看代码 //寒假集训被何柱大大踩好惨(>_<) #include<cstdio> #include<i ...