【原创】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 题目描述: 在一个果园里,小明已经将所有的水果打了下来,并按水果的不同种类分成了若干堆,小明决定把所有的水果 ...
随机推荐
- Java 获取 文件md5校验码
讯雷下载的核心思想是校验文件的md5值,两个文件若md5相同则为同一文件. 当得到用户下载某个文件的请求后它根据数据库中保留的文件md5比对出拥有此文件的url, 将用户请求挂接到此url上并仿造一个 ...
- linux查看与设置主机名
1.设置主机名 通过编辑/etc/sysconfig/network文件中的HOSTNAME字段就可以修改主机名.如下所示: [root@zijuan /]# vim /etc/sysc ...
- binaryTree:普通二叉树
#ifndef _Tree_H #define _Tree_H typedef int ElementType; typedef struct TreeNode { ElementType Eleme ...
- 利用jQuery接受和处理xml数据
使用jQuery+Servlet接受和处理xml数据,模拟判断用户名是否存在,效果如下: 服务器端 package com.ljq.test; import javax.servlet.http.Ht ...
- 学习zepto.js(原型方法)
学习zepto.js(原型方法)[1] 转载 新的一周,新的开始,今天来学习一下zepto里边的原型方法,就是通过$.进行调用的方法,也是可以通过$.fn进行扩展的方法: $.camelCase(): ...
- Android学习笔记27:网格视图GridView的使用
网格视图GridView的排列方式与矩阵类似,当屏幕上有很多元素(文字.图片或其他元素)需要按矩阵格式进行显示时,就可以使用GridView控件来实现. 本文将以一个具体的实例来说明如何使用GridV ...
- PostCss 从0开始
PostCss 摘自 http://ju.outofmemory.cn/entry/215105 http://www.w3cplus.com/PostCSS/postcss-deep-dive-pr ...
- HTML5学习笔记之Input类型
Input类型——email email类型用于包含email地址的输入域,在输入地址时会自动验证email域的值 例:Email:<input type="email" n ...
- ios jsbrige
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- 基于Java图片数据库Neo4j 3.0.0发布 全新的内部架构
基于Java图片数据库Neo4j 3.0.0发布 全新的内部架构 Neo4j 3.0.0 正式发布,这是 Neo4j 3.0 系列的第一个版本.此版本对内部架构进行了全新的设计;提供给开发者更强大的生 ...