熵编码(Huffman 和 Arithmetic/ANS)——将代码与非代码混合

Entropy coding (Huffman and Arithmetic/ANS) - mixing codes with non-codes

使用霍夫曼编码,我们只需生成一个符号映射 -> 代码。然后,在运行-length编码的时候,我们用这个map,用一个code来交换一个symbol。这样可以轻松地将代码与我们不想 encode/compress 的其他一些符号混合。例如,在 JPEG 中,我们编码 [前导零的数量,AC 系数的位数] 并将其放入比特流,然后是 AC 系数位表示。这是一个非常方便的属性哈夫曼编码

现在我想问的是,这是否可以用算术编码做类似的事情(在非对称数字系统的上下文中,因为这就是我正在实现的)?我不知道如何解决这个问题。

混合原始位的方法有很多种,例如旁路编码:https://fgiesen.wordpress.com/2015/12/21/rans-in-practice/ 通常,在数据压缩方面获得帮助的最佳地点是 encode.ru 论坛。

当然,假设您在切换到后续位的其他解释之前知道要从算术 code/ANS 中解码多少个符号。这与霍夫曼案例没有什么不同,在霍夫曼案例中,您知道在更改对位的解释之前要读取多少个符号。

@Jarek Duda: 感谢 link。我去了那里,在源代码的帮助下能够实现 write/read 个原始位。不过,我想就规范化的工作原理寻求一些解释。我当前的 WriteRaw 实现如下所示:

uint32 _x;
deque<uint16> _words;

...

void NCommon::ANSCoder32::WriteRaw(uint16 value, uint8 bitsCount)
{
    uint32 freq = 1 << (16 - bitsCount);
    uint32 maxX = ((uint32)1 << 16) * freq;

    if (_x >= maxX)
    {
        _words.push_back(_x & 0xFFFF);
        _x >>= 16;
    }

    _x = (_x << bitsCount) | value;
}

我想出了 freq 和 maxX(基于提供的网站)应该是什么,但不知道为什么要这样定义它们。我真的很欢迎一些解释。