【原创】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段的情况,否则最终只记录了一个哈夫曼树的数据~
【原创】JPEG图像密写研究(二) 哈夫曼树的建立的更多相关文章
- 【原创】JPEG图像密写研究(三) 数据流译码
[原创]这次更新比较慢,译码过程比想象中复杂一些,更主要是译出来的DCT系数无法确定是否正确,要想验证就需要再进行正向压缩编码,再次形成jpeg图像验证正确,后续工作正在开展,这里就说一说译码的主要思 ...
- JPEG图像密写研究(一) JPEG图像文件结构
[转载]转载自http://www.cnblogs.com/leaven/archive/2010/04/06/1705846.html JPEG压缩编码算法的主要计算步骤如下: (0) 8*8分块. ...
- 哈夫曼树(二)之 C++详解
上一章介绍了哈夫曼树的基本概念,并通过C语言实现了哈夫曼树.本章是哈夫曼树的C++实现. 目录 1. 哈夫曼树的介绍 2. 哈夫曼树的图文解析 3. 哈夫曼树的基本操作 4. 哈夫曼树的完整源码 转载 ...
- word2vec 中的数学原理二 预备知识 霍夫曼树
主要参考: word2vec 中的数学原理详解 自己动手写 word2vec 编码的话,根是不记录在编码中的 这一篇主要讲的就是霍夫曼树(最优二叉树)和编码. ...
- 树(二叉树 & 二叉搜索树 & 哈夫曼树 & 字典树)
树:n(n>=0)个节点的有限集.有且只有一个root,子树的个数没有限制但互不相交.结点拥有的子树个数就是该结点的度(Degree).度为0的是叶结点,除根结点和叶结点,其他的是内部结点.结点 ...
- Java数据结构(十二)—— 霍夫曼树及霍夫曼编码
霍夫曼树 基本介绍和创建 基本介绍 又称哈夫曼树,赫夫曼树 给定n个权值作为n个叶子节点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称为最优二叉树 霍夫曼树是带权路径长度最短的树,权值较 ...
- [原创.数据可视化系列之十二]使用 nodejs通过async await建立同步数据抓取
做数据分析和可视化工作,最重要的一点就是数据抓取工作,之前使用Java和python都做过简单的数据抓取,感觉用的很不顺手. 后来用nodejs发现非常不错,通过js就可以进行数据抓取工作,类似jqu ...
- HDU 3179 二叉搜索树(树的建立)
二叉搜索树 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- 九度OJ 1107 搬水果 -- 哈夫曼树 2011年吉林大学计算机研究生机试真题
题目地址:http://ac.jobdu.com/problem.php?pid=1107 题目描述: 在一个果园里,小明已经将所有的水果打了下来,并按水果的不同种类分成了若干堆,小明决定把所有的水果 ...
随机推荐
- 火星A+B(字符串整形转化,进制)
Description 读入两个不超过25位的火星正整数A和B,计算A+B.需要注意的是:在火星上,整数不是单一进制的,第n位的进制就是第n个素数.例如:地球上的10进制数2,在火星上记为“1,0”, ...
- QF——UI之UIViewController
程序一经启动,AppDelegate的实例就会创建一个充满屏幕的window,它是App唯一的,一个App对应一个window.window是UIWindow类型的,继承于UIView,是种特殊的UI ...
- Gridlayout动态添加
//类似数组[行, 列] //表示起始位置为0,占据2行 GridLayout.Spec rowSpec=GridLayout.spec(0, 2, GridLayout.UNDEFINED); // ...
- 将数据从服务器端同步到手机上, 并且需要离线工作,Couchebase Mobile 也许是目前最好的解决方案:
将数据从服务器端同步到手机上, 并且需要离线工作,Couchebase Mobile 也许是目前最好的解决方案: 原文地址: https://www.infinum.co/the-capsized-e ...
- keyDown keyPress keyUp 事件的区别
keyDown keyPress keyUp 事件的区别 一 触发顺序 显而易见,事件发生的顺序是: keydown --> keypress --> keyup 当按住一个键一段时间后 ...
- genToken- Php file
<?php public function genToken($len = 32, $md5 = true) { # Seed random number generator # Only ne ...
- struts2笔记04-XxxAware接口
1.XxxAware接口 ApplicationAware, RequestAware,SessionAware, ParameterAware. struts2提供了这四个Aware接口用 ...
- 关于RSA加密
RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密. RSA的算法涉及三个参数,n.e1.e2. 其中,n是两个大质数p.q的积,n的二进制 ...
- retain、strong、weak、assign区别
1. 假设你用malloc分配了一块内存,并且把它的地址赋值给了指针a,后来你希望指针b也共享这块内存,于是你又把a赋值给(assign)了b.此时a 和b指向同一块内存,请问当a不再需要这块内存,能 ...
- WPF:构建应用程序
原文 http://www.cnblogs.com/free722/archive/2011/11/13/2247455.html WPF相关的项目内容包含在App.Xaml和Window1.xaml ...