背景技术
霍夫曼编码是霍夫曼(Huffman)在1952年提出的一种利用消息符号的统计特性的编码方法,即从下到上的编码方法。霍夫曼编码是目前普遍使用的一种熵编码技术,也是最基础和主要的编码技术之一。
图1所示为霍夫曼编码的一种简单的实现流程,包括如下步骤:
步骤101:把总数为N的信元符号,按每个信元符号出现的概率Pi(i=1,2,...N)由大到小顺序排列,为P1≥P2≥...≥PN;
步骤102:将出现概率最小的两个信元符号的概率相加,合成一个概率;将这个概率与其他信元符号的概率一起重新按大小顺序排列;
步骤103:判断是否概率为1,若是则执行步骤104,否则转至步骤102;
步骤104:用线将信元符号连接起来,逐步从后向前进行编码,每个节点有两个分支,对概率大的赋0,概率小的赋1(也可以对概率大的赋1,概率小的赋0),经过几个节点后到达末节点,也称为端点;
步骤105:将从首节点到端点的0或1按顺序排列起来,就是这个端点所对应的信元符号的码字。
图2所示为霍夫曼编码的码字结构示意图。其中,白色圆圈代表中间节点(Internal Node),灰色圆圈则代表端点(Result Node)。可以看出,该码字的长度是可变的。根据上述编码流程可知,概率最大的信元符号对应最短的码字,而概率最小的信元符号对应最长的码字,这样就可以缩短总的编码长度。
目前常采用二进树搜索法对上述码字进行解码。其基本原理是从首节点开始,每次从码字中读取一个比特,根据0或1判断选择二叉树的分支,然后根据分支结点的值判断是否已经寻找到需要的码字还是需要下一步搜索,已经读取的比特可以丢弃。可以看到,二进树搜索法最坏情况下搜索的次数为霍夫曼码字中最长码字的长度。搜索得到码字后,再查找预先设置的码字与信元符号的对应关系表,就可以得到该码字对应的信元符号。
从分组的角度看二进搜索树的结构,可以认为二进搜索树的分组长度固定为1。解码的时候对码流的搜索是逐比特的,即一次分析一个比特。二进树搜索法的霍夫曼解码方法可以达到很高的解码效率,但是需要存储每一个中间节点以及端点。从图2可以看出,由于每个节点只对应一个比特的码字,但对于每个节点需要分配一定长度的存储空间,因此,现有的二进树搜索法需要消耗较多的存储空间。
具体实施方式
为使本发明的目的、技术方案和优点更加清楚,下面结合附图对本发明作进一步的详细阐述。
本发明实施例对霍夫曼码表中的所***字进行可变长度的分组,根据分组得到的变长度码字片段生成节点,并将所述节点组成变长度分组霍夫曼搜索树;然后,根据所述变长度分组霍夫曼搜索树对霍夫曼编码形成的码流进行搜索。
本发明实施例的变长度分组霍夫曼搜索树的节点存储结构如图3所示。假设存储长度为16比特,包括一个比特的端点标识,用于表示该节点是否为端点,例如值为1表示该节点为端点,值为零表示该节点为中间节点,当然也可以用0表示该节点为中间节点,用1表示该节点为端点。接下来的三个比特用于表示下级节点的码字片段的比特数,称为下一级节点的分组长度(Segmentation Length)。剩下的12比特则用于存储下一级节点的首地址或者下一级节点的首地址偏移量,所述首地址偏移量可以是相对于首节点地址的偏移量,也可以是相对于上一级节点首地址的偏移量,以下统一用首地址表示。用于存储分组长度的比特数不限于上述取值,可根据实际需要进行调整。节点的总存储长度也不限于16比特,可以为其它值,例如为24比特、32比特或64比特等。端点的存储内容包括端点标识、端点的码字片段长度以及信元符号。这样搜索完毕后就直接得到信元符号,而无需再查找码字与信元符号的对应关系表,提高了解码效率。
本发明实施例包括以下两个基本步骤:
A、对霍夫曼码表中的码字进行变长度分组,根据分组得到的变长度码字片段生成节点并将所述节点组成变长度分组霍夫曼搜索树。变长度的分组的方法可有许多种,因此所得到的变长度分组霍夫曼搜索树也可能不唯一。
例如,一种简单的变长度分组的方法如下:第一级节点的长度为码表中的最短码字长度,中间各级的长度为3。各个分支的最后一级根据剩余码字的长度,其长度可以为1,2,或者3。这样就组成了一种分组的方法。
然后在存储空间中生成变长度分组霍夫曼搜索树,具体地说,包括如下步骤:
a、为各级节点分配存储空间。属于同一个上级节点的各个节点,其存储空间是连续的,并且存储空间的大小视当前节点的分组长度而定。比如说如果当前节点的分组长度为2,则长度为2比特的码字片段一共有00、01、10和11共计4种可能,如果一个节点的存储空间为16比特,则需要至少分配4个16比特存储空间;如果当前节点的分组长度为8,则如果节点存储空间为16比特的前提下需要至少分配256个16比特存储空间。
b、对码字分组得到的码字片段分配相应的端点标识。判断该码字片段是否为一个完整码字的最后一个片断,若是则端点标识为真,否则为假,可以分别用0或1表示。
对于端点标识为假的码字片段,将该节点对应的下一级节点分组长度、首地址和端点标识保存到该节点的存储空间;对于端点标识为真的码字片段,则将端点标识、码字片段长度以及信元符号保存在该节点的存储空间。此外,如果该节点为空节点,则仍然保持该存储空间为空。
B、根据所述变长度分组霍夫曼搜索树对码流进行搜索,得到码字对应的信元符号。
本发明实施例根据变长度分组霍夫曼搜索树对霍夫曼编码形成的码流进行解码的流程如图4所示,包括如下步骤:
步骤401:以首节点为当前节点,根据首节点中存储的内容得到第一级节点分组长度和地址。
步骤402:从输入的霍夫曼码流中截取与本级分组长度相同的码字片段,根据得到的码字片段和本级节点的首地址,从本级节点中搜索到当前节点。
例如,若码片字段为“011”,则本级节点首地址之后第一个节点对应的码字片段是“001”,第二个节点对应的码字片段是“010”,第3个节点就是当前节点;同理,若码片字段为“1101”,则本级节点首地址之后存储的第13个节点为当前节点。
步骤403:判断当前节点是否为端点,若是,则转至步骤405,否则转至步骤404。
步骤404:根据当前节点中存储的内容,获得下一级节点分组长度和节点首地址,然后转至步骤402。
步骤405:将端点存储的信元符号作为解码结果输出。
对连续的霍夫曼码流,重复以上步骤401至步骤405的处理过程,直到所以码字都解码完毕。
下面用一个具体的例子对本发明的解码过程进行进一步说明。假设对一组信元符号进行霍夫曼编码,得到如表1所示的霍夫曼码字:
码字 |
长度 |
信元符号 |
0 |
1 |
a1 |
1000 |
4 |
a2 |
1001 |
4 |
a3 |
1010 |
4 |
a4 |
101100 |
6 |
a5 |
101101 |
6 |
a6 |
101111 |
6 |
a7 |
1100 |
4 |
a8 |
11010 |
5 |
a9 |
11011 |
5 |
a10 |
1110 |
4 |
a11 |
1111 |
4 |
a12 |
表1
对表1所示的码字进行变长度分组,第一级节点的长度为码表中的最短码字长度1,中间1级的长度为3,各个分支的最后一级根据剩余码字的长度,其长度为1或2,得到的一种变长度分组霍夫曼搜索树如图5所示。其中,菱形框表示首节点,白色椭圆框表示中间节点,灰色椭圆框表示端点,而黑色椭圆框则表示空节点。
那么为各级节点分配的存储空间,其存储结构为:
对于节点501,其为首节点,因此端点标志设为0;其下级节点502、503长度为1,则下级分组长度设为1,下级节点首地址为节点502的存储地址ADD502,因此节点501的存储结构为:
对于节点502,其为端点,因此端点标志设为0,码字片段长度为1,霍夫曼解码内容为a1,因此节点502的存储结构为:
对于节点503,其为中间节点,下级分组长度为3,下级节点首地址为节点504对应的地址ADD504,则得到节点503的存储结构为:
......
对于节点516,其为端点,码字片段为1,对应的霍夫曼解码内容为a9,即:
......
假设霍夫曼编码得到的二进码流为10011110110110010110010100......,则在解码时,根据图5所示的变长度分组霍夫曼搜索树,首先根据首节点的下一级分组长度为1,下级节点首地址为ADD502,二进制码流的第一个比特为1,将该首地址加1,搜索到节点503;然后,根据节点503的下一级分组长度为3,下级节点首地址为ADD504,且二进制码流的第2至第4比特的内容为001,将首地址ADD504加1,则搜索到节点505,这样就得到了第一个码字1001,相应的得到该码字对应的霍夫曼解码内容为a3。对于之后的码字重复这样的搜索过程,就将上述码流分解为:1,001;1,110;1,101,1;0;0;1,011,00;1,010;0;......。其中逗号为分组边界,分号为码字片段边界。从而解码获得对应的霍夫曼解码内容为a3a11a10a1a1a5a4a1......
从图5可以看出,对于不同级的节点,其分组长度可能不同;对于同一级节点,其分组长度也可能不同。例如节点512和节点517属于同一级,但节点512的分组长度为2比特,而节点517的分组长度为1比特。但是,同一级中具有相同上级节点的那些节点的分组长度都是相同的,例如节点512至节点516。其上级节点507中存储的下一级节点的首地址为节点512的地址,节点512至节点516是连续存储的,因此根据该首地址可以搜索到节点512至节点516中的任何一个节点。
码字101110为空,也就是说码表中不存在该码字,这说明可能码流出现误码或者解码过程出现错误。
如果对上述码流采用传统的二进树搜索,则节点结构如图6所示。与图5进行比较,图5中的节点总数为17(包括首节点和空节点),图6中节点总数为23(不算首节点)。如果每个节点需要相同的存储单元,则图5所示方法需要的存储空间比图6中的少6个存储单元,如果这两种方法的节点单元所需存储空间相同,则该实施例中,变分组霍夫曼解码方法节省了26.1%的存储空间。
另外从比较次数看,二进树的节点级数为6,而变长度分组霍夫曼搜索树为3。如码字1001,在变长度分组霍夫曼搜索树方法中只需要进行2次判断就可以解码成功,而二进搜索树需要进行4次判断才能解码。虽然本发明方案需要额外获取分组信息,但是通过将结果和中间需要的信息耦合到节点中,可以完成高效的解码。
本发明实施例的变分组霍夫曼解码装置如图7所示,包括分组模块701、码表信息检索模块702和搜索模块703。其中,
码表信息检索模块702用于存储变长度分组霍夫曼搜索树的相关信息,包括该变长度分组霍夫曼搜索树的各个节点的信息。若该节点为中间节点,则节点信息包括端点标识、下一级分组长度以及下一级节点首地址信息;若该节点为端点,则节点信息包括端点标识、码字片段长度以及霍夫曼解码内容。所述首地址信息可以是下一级首个节点的物理地址,也可以是下一级首个节点的物理地址的偏移量。码表信息检索模块702中可以进一步包括生成单元,用于生成所述变长度分组霍夫曼搜索树,也就是根据各级节点的分组长度,分配变长度分组霍夫曼搜索树各个节点的存储空间,并将各节点的相关信息存储到各个存储空间。
码表信息检索模块702还包括端点判断单元,用于判断当前节点是端点还是中间节点,若是中间节点,则所述生成单元将该中间节点的端点标识设置为假,并将该节点对应的下一级节点分组长度、首地址存储到所述中间节点的存储空间;若是端点,则所述生成单元将该端点的端点标识设置为真,并将该端点的码字片段长度和端点对应的信元符号存储到所述端点的存储空间。
码表信息检索模块702将所述变长度分组霍夫曼搜索树的相关信息分别发送至分组模块701和搜索模块703。
分组模块701用于接收霍夫曼码流,根据来自搜索模块702的下一级节点的分组长度,对霍夫曼码流进行分组,得到当前需要搜索的码字片段;若首次执行时则根据来自码表信息检索模块702的变长度分组霍夫曼搜索树的首节点指示的分组长度,对霍夫曼码流进行分组并得到当前需要搜索的码字片段。将所得码字片段发送到搜索模块703。
搜索模块703,用于接收来自分组模块701的码字片段,并接收来自码表信息检索模块702的变长度分组霍夫曼搜索树的节点信息,根据所述节点信息中的物理地址或物理地址偏移量,对所述码字片段进行搜索,找到与所述码字片段对应的节点。
搜索模块703中还进一步包括判断单元和输出单元,所述判断单元用于根据所搜索到的节点的端点标识判断所述节点是否为端点,若是通知输出单元将该节点中存储的信元信息提取出来并对外输出。所述输出单元则用于输出所述信元符号。
若判断单元判断该节点不是端点,则搜索模块702将该节点的下一级节点分组长度发送至分组模块701。
以上所述仅为本发明的较佳实施例而已,并不用以限制本发明,凡在本发明的精神和原则之内所作的任何修改、等同替换和改进等,均应包含在本发明的保护范围之内。