返回

H.264解码器亲手实践——解密指数哥伦布熵编码

开发工具

解码无符号指数哥伦布熵编码的历程

无符号指数哥伦布熵编码,顾名思义,它只适用于非负整数的编码。它的基本原理是将一个非负整数表示成两部分:尾数(trailing ones)和前缀(prefix)。解码过程的任务就是从编码后的比特流中分离出这两个部分,从而还原出原始的非负整数。

首先,我们需要确定编码后的比特流中,有多少比特属于尾数。这可以通过查找第一个 0 比特的位置来确定。在这个 0 比特之前的所有比特,都是尾数。尾数的长度,也就是我们所说的 k。

接下来,我们需要确定前缀的长度。这可以通过计算 tail_bits 的长度来确定。前缀的长度,就是 k 减去 tail_bits 的长度。

有了这两个部分,我们就可以还原出原始的非负整数了。原始的非负整数,就是前缀对应的十进制整数,加上尾数对应的十进制整数。

代码实现:解码无符号指数哥伦布熵编码

#include <iostream>
#include <vector>

using namespace std;

int DecodeUE(vector<bool>& bitstream) {
  int k = 0;
  while (bitstream[k] == 1) {
    k++;
  }

  int tail_bits = 0;
  for (int i = k + 1; i < bitstream.size(); i++) {
    tail_bits = (tail_bits << 1) | bitstream[i];
  }

  int value = (1 << k) + tail_bits;
  return value;
}

int main() {
  vector<bool> bitstream = {1, 1, 1, 1, 0, 1, 1, 0, 1};
  int value = DecodeUE(bitstream);

  cout << "The decoded value is: " << value << endl;

  return 0;
}

代码剖析:步步解析解码过程

  1. 确定尾数长度(k):

    int k = 0;
    while (bitstream[k] == 1) {
      k++;
    }
    

    这段代码通过循环来确定 tail_bits 的长度。循环的条件是 bitstream[k] == 1,即只要当前比特是 1,循环就会继续。循环结束后,k 的值就是 tail_bits 的长度。

  2. 计算前缀长度:

    int tail_bits = 0;
    for (int i = k + 1; i < bitstream.size(); i++) {
      tail_bits = (tail_bits << 1) | bitstream[i];
    }
    

    这段代码通过循环来计算 tail_bits 的值。循环的条件是 i < bitstream.size(),即只要还没有遍历完比特流,循环就会继续。循环体中,tail_bits 的值通过左移一位,然后与当前比特进行按位或运算来更新。循环结束后,tail_bits 的值就等于原始的 tail_bits。

  3. 还原原始非负整数:

    int value = (1 << k) + tail_bits;
    

    这段代码通过将前缀对应的十进制整数和尾数对应的十进制整数相加,来还原出原始的非负整数。

  4. 输出解码结果:

    cout << "The decoded value is: " << value << endl;
    

    这段代码将解码后的结果输出到控制台。

结语

通过对无符号指数哥伦布熵编码解码过程的详细讲解和代码实现,我们进一步加深了对指数哥伦布熵编码的理解。在下一小节,我们将继续探索有符号指数哥伦布熵编码的解码实现,敬请期待!