【原创】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 题目描述: 在一个果园里,小明已经将所有的水果打了下来,并按水果的不同种类分成了若干堆,小明决定把所有的水果 ...
随机推荐
- 网络分析shell脚本(实时流量+连接统计)
介绍一个强大的分析网络的shell脚本,此脚本是从EZHTTP拆分出来的,觉得有必要单独介绍下.脚本运行效果截图: 此脚本包含的功能有: 1.实时监控任意网卡的流量 2.统计10秒内平均流量 3.统计 ...
- poj 2771 最大独立集
这道题又无耻的抄袭了别人的代码. 刚开始以为是最大匹配,把条件不相符的人连一起,然后求最大匹配,感觉麻烦,然后看了别人的解题报告,是把相符的人连一起,然后减去,其实就是最大独立集. 最大独立集=|G| ...
- http request parameter
http request parameter add htmlspecialchars host?vendor_id=1000000&q=Some%20children%20wish%20to ...
- verilog 随笔
不是说你在代码里定义一个reg型变量,综合器就会综合处一个寄存器来,case必须在always块里,always里面的被赋值变量必须是reg型,这是语法的规定,只能遵守.写代码的时候不要加入触发器(不 ...
- 安装solaris_11.2与windows双系统(VM10模拟实现)(一)
感慨:这周刚接触solaris,装solaris很蛋疼,一个字:慢! 在上面安装软件包依然很慢,无线网也很不稳定. 在上面搭建环境更蛋疼,一个字:惨! 什么环境之类的废话就不多说了,一般的电脑都可以. ...
- SQL Server MySQL 中的 in 与 null
例子: create table t(x int,y int); insert into t(x,y) values(1,1),(2,2),(null,null); 查询一: select x,y f ...
- J2SE知识点摘记(二十五)
Set 1.5.1 概述 Java 中的Set和正好和数学上直观的集(set)的概念是相同的.Set最大的特性就是不允许在其中存放的元素是重复的.根据这个特点,我们就可以使用Set 这个 ...
- J2SE知识点摘记(二十二)
Map 1.4.1 概述 数学中的映射关系在Java中就是通过Map来实现的.它表示,里面存储的元素是一个对(pair),我们通过一个对象,可以在这个映射关系中找到另外一个和这个对象相关 ...
- Oracle EBS-SQL (SYS-7):表单个性化查询.sql
SELECT * FROM FND_FORM_CUSTOM_RULES; SELECT * FROM FND_FORM_CUSTOM_ACTIONS; SELECT * FROM FND_FORM_C ...
- 限制**类型物料不能输入BOM
应用 Oracle Bill Of Materiel 层 Level Function 函数名 Funcgtion Name CUX_BOMFDBOM 表单名 Form Name CUXBOMFD ...