JPEG中Huffman解码实例讲解

article/2025/9/29 1:17:13

DHT Huffuman表格式

--------------------------------------------------------------------------
名称      字节数     值       说明
--------------------------------------------------------------------------
段标识       1        FF
段类型       1        C4
段长度       2                    其值=19+n(当只有一个HT表时)
  (以下为段内容)
HT信息      1                    0-3位:HT号
                                             4位: HT类型, 0=DC表,1=AC表
                 5-7位:必须=0
HT位表      16                  这16个数的和应该≤256
HT值表       n                   n=表头16个数的和
--------------------------------------------------------------------------

读取Huffman

FF C4 01 A2 00 00 01 05 01 01 01 01 01 01 00 00 00 00 00 00 00 00 01 02 03 04 05 06 07 08 09 0A 0B

FF C4:Huffman表识别码

01 A2:DHT表长度(01~0B的字节数)

00:4bit=0,为DC表;低3bit=0,HT号为0;表示DC直流0号表

00 01 05 01 01 01 01 01 01 00 00 00 00 00 00 00:DHT不同bits位数的码字数量,数据之和表示叶子节点数目:1+5+1+1+1+1+1+1 = 12;

00 01 02 03 04 05 06 07 08 09 0A 0B:编码内容,即每个叶子节点下的编码值

构建Huffman

读取到Huffman表的数据之后,就需要构建Huffman树了。其具体规则如下:

  (a)第一个编码的数字必定为0;如果第一个编码的位数为1,就被编码为0;如果第一个编码的位数为2,就被编码为00;如果第一个编码的位数为3,就被编码为000。。。

  (b)从第二个编码开始,如果它和它前面编码具有相同的位数,则当前编码是它前面的编码加1;如果它的编码位数比它前面的编码位数大,则当前编码时它前面的编码加1之后再在后面添加若干个0,直到满足编码位数的长度为止。

还是以上面的数据00 01 05 01 01 01 01 01 01 00 00 00 00 00 00 00为例:

第1个字节00表示没有位数为1的编码;

第2个字节01表示位数为2的编码有2个;由于没有位数为1的编码,因此这里位数为2的编码中的第一个为00;

第3个字节05表示位数为3的编码有5个;因此,这里位数为3的编码中的第一个为00+1=01,然后添加1个“0”,得到010;位数为3的编码中的第二个为010+1=011;第三个为011+1=100;第四个为100+1=101;第五个为101+1=110;

第4个字节01表示位数为4的编码有1个;因此,这里位数为4的编码中的第一个为110+1=111,然后添加1个“0”,得到1110;

第5个字节01表示位数为5的编码有1个;因此,这里位数为5的编码中的第一个为1110+1=1111,然后添加1个“0”,得到11110;

依次类推,得到如下Huffman树,表1:

Y(luminance亮度)-DC

 

序号(bits位数)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

相同Bits位的个数

0

1

5

1

1

1

1

1

1

0

0

0

0

0

0

0

说明

没有位数为1的编码

1个2bits

5个3bits

1个4bits

1个5bits

1个6bits

1个7bits

1个8bits

1个9bits

没有位数为10的编码

没有位数为11的编码

没有位数为12的编码

没有位数为13的编码

没有位数为14的编码

没有位数为15的编码

没有位数为16的编码

码字(二进制)

00

(00+1)<<1

==>

010

011

100

101

110

(110+1)<<1

==>

1110

(1110+1)<<1

==>

1111 0

(11110+1)<<1

==>

1111 10

(111110+1)<<1

==>

1111 110

(1111110+1)<<1

==>

1111 1110

(11111110+1)<<1

==>

1111 1111 0

根据Huffman树,建立DHT权值与实际保存数据与DCT量化后数据 表2,查此表可以对jpeg做解码:

序号

Bits位数

码字长度

码字

DHT权值

Size(数值bits宽度)

Additionnal Bits

(实际保存的数据)

DC-value(DCT量化后的数据)

1

2bits

2

00

0x0

0x00

0

0

2

3bits

3

010

0x2

0x01

1

0

1

-1

1

3

3

011

0x3

0x02

2

00,01

10,11

-3,-2

2,3

4

3

100

0x4

0x03

3

000,001,010,011

100,101,110,111

-7,-6,-5,-4

4,5,6,7

5

3

101

0x5

0x04

4

0000,…,0111

1000,…,1111

-15,…,-8

8,…,15

6

3

110

0x6

0x05

5

0000 0,…,01111

1000 0,…,11111

-31,…,-16

16,…,31

7

4bits

4

1110

0xE

0x06

6

0000 00,…,011111

1000 00,…,111111

-64,…,-32

32,…,64

8

5bits

5

1111 0

0x1E

0x07

7

0000 000,…

…,1111 111

-127,…,-64

64,…,127

9

6bits

6

1111 10

0x3E

0x08

8

0000 0000,…

…,1111 1111

-255,…,-128

128,…,255

A

7bits

7

1111 110

0x7E

0x09

9

0000 0000 0,…

…,1111 1111 1

-511,…,-256

256,…,511

B

8bits

8

1111 1111

0xFE

0x0A

A

0000 0000 00,…

…,1111 1111 11

-1023,…,-512

512,…,1023

C

9bits

9

1111 1111 0

0x1FE

0x0B

B

0000 0000 000,…

…,1111 1111 111

-2047,…,-1024

1024,…,2047

高4bits:保留零的个数

低4bits:接着的数据位长

0n

负数

正数

-(1<<(n+1)-1) ~ -(1<<n)

(1<<n) ~ (1<<(n+1)-1)

DHT权值表中,高4bit表示零保留的个数,低4bit表示接着的数据位长。

Huffman:DC实际值 -> Size[编码长度] -> 权值 -> bitstring{.Len;   .value;}

Encode: DC实际值 -> DQT量化 -> ZigZag扫描 ->(Y:DPCM编码,CbCr)->  huffman -> write

 

根据Huffman系数,或者读取Huffman系数,重建Huffman表:

static BYTE std_dc_luminance_nrcodes[17]={0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0};

static BYTE std_dc_luminance_values[12]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};

static BYTE std_dc_chrominance_nrcodes[17]={0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0};

static BYTE std_dc_chrominance_values[12]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};

static BYTE std_ac_luminance_nrcodes[17]={0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d };

static BYTE std_ac_luminance_values[162]=

  { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa };

static BYTE std_ac_chrominance_nrcodes[17]={0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77};

static BYTE std_ac_chrominance_values[162]=

{ 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa };

依照上述重建Huffman表的方法,可得:

DHT-Y-DC

DHT-Y-AC

DHT-CbCr-DC

DHT-CbCr-AC

序号

相同Bits位数的:码字个数

相同bits位数:码字起始

相同bits位数:码字结束

相同Bits位数的:码字个数

相同bits位数:码字起始

相同bits位数:码字结束

相同Bits位数的:码字个数

相同bits位数:码字起始

相同bits位数:码字结束

相同Bits位数的:码字个数

相同bits位数:码字起始

相同bits位数:码字结束

1 

0

0

0

0

0

0

0

0

0

0

0

0

2

1

0

0

2

0

0x1

3

0

0x2

2

0

0x1

3

5

0x2

0x6

1

0x4

0x4

1

0x6

0x6

1

0x4

0x4

4

1

0xE

0xE

3

0xA

0xC

1

0xE

0xE

2

0xA

0xB

5

1

0x1E

0x1E

3

0x1A

0x1C

1

0x1E

0x1E

4

0x18

0x1B

6

1

0x3E

0x3E

2

0x3A

0x3B

1

0x3E

0x3E

4

0x38

0x3B

7

1

0x7E

0x7E

4

0x78

0x7B

1

0x7E

0x7E

3

0x78

0x7A

8

1

0xFE

0xFE

3

0xF8

0xFA

1

0xFE

0xFE

4

0xF6

0xF9

9

1

0x1FE

0x1FE

5

0x1F6

0x1FA

1

0x1FE

0x1FE

7

0x1F4

0x1FA

10

0

0

0

5

0x3F6

0x3FA

1

0x3FE

0x3FE

5

0x3F6

0x3FA

11

0

0

0

4

0x7F6

0x7F9

1

0x7FE

0x7FE

4

0x7F6

0x7F9

12

0

0

0

4

0xFF4

0xFF7

0

0

0

4

0xFF4

0xFF7

13

0

0

0

0

0

0

0

0

0

0

0

0

14

0

0

0

0

0

0

0

0

0

1

0x3FE0

 0x3FE0

15

0

0

0

1

0x7FC0

0x7FC0

0

0

0

2

0x7FC2

0x7FC3

此时,得到Huffman的size(码字bit位数)与code(相同bit位数的编码值)表。由此可进行Huffman的解码过程:

1)        将待解码数据转换成二进制的数据流;

2)        遍历表Huffman_size、Huffman_code,从待解码二进制数据流中寻找到长度与Huffman_size相等,内容与Huffman_code相等的二进制数据段,并记录下表的ID(即:是在表的第几个数据中寻找到的);

3)        将此ID 值除以16,其商为cnt(指之前有cnt个0),其余数即为取数长度Len;

4)        在二进制的数据流中,从与Huffman_code相同的数据流后,开始取数,取数长度为第3步得到的Len,假设取得的数据为data;

5)        根据data的值,转换得到相应的解码数据de_data。(根据最高位,为1则为相应的数,为0则取反后的负值。例,data=100,则解码后数据de_data值为4;data=010,解码后数据de_data为-5;

6)        写上de_data的值,并在前面添加上cnt个0。至此,解码完成。

示例数据讲解

 长度01 A2后面的字节: 00 表示Y-DC, tablenum=0; 10表示Y-AC, tablenum=1;01表示Cb-DC,tablenum=2;11表示Cb-AC,tablenum=3;

后面的数据依次是bits位数的个数表,bits位数表(码表);

根据这个重建Huffman表,得到size与code表;

DHT后面是SOS数据,实际的数据流从E2 E8 A2 8A F9 93 F7 开始

Huffman解码时,每次读取32bit数据,此次前4字节数据为E2 E8 A2 8A,转换城二进制数据为:

1110 0010 1110 1000 1010 0010 10000 1010

首次编码的数据一定是Y-DC,所以这里可跟表2匹配:匹配二进制数据的长度与Huffman_size相等,内容与Huffman_code相等的二进制数据段,记录下Huffman的ID号,此时匹配上的1110, 码字长度为4,对应的DHT权值为6,即后面需要读取6 bits数据(001011)作为该组数据,对应的实际DCT量化后的数据值为-53。【(001011对应10进制数据为11) 故数据为:11- (1<<6)  ==> -53 】,此次计算共用的bit位数为4+6 = 10,所以下一组数据从偏移10bits开始,依次类推,可得出下如下数据:

1110 0010 11    101 0001    010 0     010 1     0000 1010

二进制数据1110 0010 11 101 0001010 0010 10000

1010 后面读byte数据,补足32bit,再做Huffman解码,如:

1010 (F9)(93) (F7)

...
实际数值-53-14-1100...
说明4bits码字,6bits数据3bits码字,4bits数据3bits码字,1bits数据3bits码字,1bits数据2bits数据...

当数据长度不够时,可从后面读取byte的数据以填充,以补足32 bits数据做Huffman解码。 

 Y-AC,Cb-DC,Cb-AC也依次类推得到相应的数据值。


http://chatgpt.dhexx.cn/article/6AJbTX62.shtml

相关文章

哈夫曼树(huffman)

学完了huffman树&#xff0c;讲一下自己对它的理解 huffman树遵循二叉树的原则&#xff0c;每个节点最多有两个子节点&#xff0c;但是每个节点都带有一个权重&#xff0c;如果我们要将一组字符串 “ B D C A F E ” 插入huffman树&#xff0c;每个字符都会带有一个权重&#…

Huffman树和Huffman编码

文章目录 Huffman树的定义带权路径长度WPL Huffman树的构造Huffman树的特点 Huffman编码构造Huffman编码 Huffman树的定义 哈夫曼&#xff08;Huffman&#xff09;树&#xff0c;又称最优二叉树&#xff0c;是一类带权路径长度WPL最短的树。 带权路径长度WPL 要理解带权路径…

Huffman树(哈夫曼树)

哈夫曼树又称最优二叉树&#xff0c;是一种带权路径长度最短的二叉树。所谓树的带权路径长度&#xff0c;就是树中所有的叶结点的权值乘上其到根结点的路径长度&#xff08;若根结点为0层&#xff0c;叶结点到根结点的路径长度为叶结点的层数&#xff09;。树的带权路径长度记为…

虚拟机下安装BackTrack5 (BT5)教程及BT5汉化

isare邀请您访问Backtrack中文网 http://www.backtrack.org.cn/?fromuid50397 isare邀请您访问Backtrack中文网 http://www.backtrack.org.cn/?fromuserisare PS&#xff1a;back track 安装过程中有2点要注意&#xff1a;第一&#xff1a;复制到99%的时候会等大约10来分钟&a…

bt 下载工具 deluge 配置 优化 使用

目录 Ubuntu 18 配置 deluge Deluge 安卓远程客户端 Deluge 性能调优 deluge是基于libtorrentpython的跨平台bt/pt客户端&#xff0c;适合在Linux环境下使用 deluge完全开源免费&#xff0c;对IPv6支持良好&#xff0c;性能优于transmission&#xff1b;在嵌入式设备上使用d…

BT5的U盘完整安装

BT5是什么就不用多说了&#xff0c;从网上看了许多教程&#xff0c;大多是利用unetbootin工具将ISO文件直接解压到U盘上&#xff0c;这样并不能完全使用BT&#xff0c;保存好的文件&#xff0c;重启机器后就没了&#xff0c;其实就是当做光盘使用了&#xff0c;另外还有一个方法…

有哪些好用的BT下载器?

​​​​​​2022年5个好用的 BT/ 磁力链接下载工具推荐 &#xff5c;Windows 、安卓系统 | 科技雷达 A full-featured download manager

BT是如何下载的

BT协议简介 一、BT下载是怎么来的&#xff1f; 在互联网上下载文件的方式大概有这么几种&#xff1a;FTP、HTTP、BT、eMule(电驴)等&#xff0c; 浏览器会直接支持FTP和HTTP下载&#xff0c;BT和eMule下载一般需要专用的下载软件的支持。 接下来分别简单介绍一下他们的区别&…

ed2k下载

ed2k下载 在下载ed2k资源的时候&#xff0c;浏览器一般不能直接下载&#xff0c;这个时候该怎么办呢&#xff1f; 方法一&#xff1a;下载迅雷&#xff0c;直接安装 方法二&#xff1a;使用在线工具&#xff0c;将链接转化为别的形式 https://tool.lu/urlconvert/ 方法三&am…

BT是怎么下载的

BT协议简介 一、BT下载是怎么来的? 在互联网上下载文件的方式大概有这么几种:FTP、HTTP、BT、eMule(电驴)等, 浏览器会直接支持FTP和HTTP下载,BT和eMule下载一般需要专用的下载软件的支持。 接下来分别简单介绍一下他们的区别: FTP 是 File Transfer Protocol(文件…

最好用的bt下载器qbittorrent下载安装使用教程

qBittorrent绝对是我心目中BT下载工具中的NO.1&#xff0c;虽说我平时也会用迅雷下载国内的某些资源&#xff0c;但是仍然不妨碍它是我心目中的主力下载神器&#xff01;它可以说是我最早接触的除迅雷之外的一款BT下载神器。它是完全免费的种子和磁力链接下载工具&#xff0c;最…

BT5 WIFI破解

实验环境 VMwareWorkstation 9.0 BackTrack5 R3-GNOME-32 工具说明 VMware&#xff1a;著名的虚拟机软件&#xff0c;本实验采用虚拟机环境下安装BackTrack。 BackTrack&#xff1a;是一个基于Ubuntu GNU/Linux的发行版本&#xff0c;主要用做数字取证和入侵测试。其无线安全审…

BT5下载地址

http://www.backtrack-linux.org/downloads/ 下载方法&#xff1a; 1,先填写好网页里的三个框,如: Your Name(你的名字): ABC Email Address(邮箱): ABC163.com Country(国家): china 2,然后点"download" 3,按照自己的…

最全BT介绍

BitTorrent 简介 riba2534 2021年04月11日 19:26 阅读 851 关注 BitTorrent 简介 从 P2P 说起 经常在网上飙车的老司机应该都知道 BT 下载&#xff0c;但是有时候拿到了种子却下载不动&#xff0c;会不会很抓狂&#xff0c;是不是还觉得是自己网不行&#xff0c;那作为一…

034_Unicode标准

1. Unicode标准 1.1. 由于ASCII字符集、ISO字符集、GBK字符集列出的字符集都有容量限制, 而且不兼容多语言环境, Unicode联盟开发了Unicode标准。 1.2. Unicode标准涵盖了世界上的所有字符、标点和符号。 1.3. 不论是何种平台、程序或语言, Unicode都能够进行文本数据的处理…

24.字符编码

1.字符编码 1.1简介 字符编码只与文本文件和字符串有关。 字符编码&#xff1a;记录人类字符与二进制数的对应关系。计算机只能识别二进制&#xff0c;但是通过字符编码可以展示出各式各样的语言字符。1.2发展过程 1.计算机是美国人发明的&#xff0c;为了能够让加计算机能够…

汉字编码

http://blog.csdn.net/zzidea/article/details/8497532 C语言编程&#xff0c;基本的类型有字符型&#xff0c;整数型&#xff0c;浮点型。这些类型是我们对事物进行描述所必不可少的东西。即基础&#xff0c;又非常核心。所以必须掌握。 一、 字符集 ASCII GB2…

《Qt5:键盘事件》

QKeyEvent类用来描述了一个键盘事件。常用的键盘事件有两种&#xff1a;按键按下和按键释放&#xff0c;一般按键按下事件用的多一点&#xff0c;下面为键盘按下和释放事件的声明&#xff1a; public:void keyPressEvent(QKeyEvent *event);void keyReleaseEvent(QKeyEvent *ev…

小伙 这样你就可以在Mac 中运行 Office 办公软件了

小伙 这样你就可以在Mac 中运行 Office 办公软件了 请参考以下步骤&#xff1a; 1、打开已经安装好的 CrossOver&#xff0c;点击“安装 Windows 应用程序”&#xff0c;在选择应用中的搜索框中输入“office”&#xff0c;接下来在下拉列表中会出现非常多的已经列出的相关软件&…

Unicode 编码表

正则查找: 中文文字中文符号表情符号... [^\x00-\xff] 其中 \x00-\xff 匹配 ASCII 代码中十六进制代码为 00-ff 的字符&#xff0c; 加个取反 ^ &#xff0c;则就表示表示匹配非单字节的字符&#xff0c;例如汉字&#xff0c;汉字符号等字符集。 中文文字&#xff08;简体繁体…