Interleaving/multiplexing 压缩流
Interleaving/multiplexing compressed streams
我正在寻找一个好的压缩算法或库,它可以让我将多个压缩数据流交织成一个数据流,没有性能或压缩损失。
更多背景:我一直在研究一种专用于特定应用程序的压缩格式。这种压缩格式对数据执行一堆特定领域的分析,然后将压缩数据输出为一堆流,每个流都被压缩(通常使用 LZW,但这不是一成不变的)。其中一个流,主流,包含一堆令牌。主流中的每个令牌都包含我需要推断哪个辅助流包含我的下一个 令牌 的信息,我需要从该辅助流中读取多少解压缩字节,以及我需要什么与此令牌有关。
到目前为止一切顺利,但我不想将我的最终数据作为一堆串联的流发送,因为这需要我接收整个数据才能对其进行有意义的处理。相反,我想将它们作为单个流发送,我可以在收到它时对其进行解码和处理。所以这基本上想发送一些类似的东西:
- 一个来自主流的token(用主流的字典压缩);
- 好的,这是令牌 "FooBar",我知道一个令牌 "FooBar" 后面总是跟着两个来自流 "Foo" 的令牌,一个来自流 "Bar" 的令牌;
- 来自流 "Foo" 的两个标记(使用用于流 "Foo" 的字典压缩);
- 来自流 "Bar" 的一个标记(使用用于流 "Bar" 的字典压缩);
- 来自主流的一个令牌(回到主流的压缩);
- ...
这里的复杂之处在于,任何有趣的压缩算法都不会简单地将一个令牌转换为一个或多个具有明确定义的令牌结尾的字节。有时,单个令牌将是多个数据包。有时,一个数据包将包含许多令牌。对我来说幸运的是,我的代币大小很容易预测。另一方面,为了 space 效率,我不能写每个数据包的大小或每次添加一个数据包的数量。
那么,我如何才能 multiplex/interleave 将所有压缩流合并为一个流而不需要添加大量元数据?我的印象是,这基本上是多媒体格式解决的那种问题,但我对这个话题的领域知识为零。有什么建议吗?我对算法、图书馆和论文感兴趣。
例如,使用 zlib,您可以为三个流同时拥有三个 deflate 运行 实例。使用 deflate,您可以一次压缩一个 deflate 块(使用 Z_BLOCK),并使用 Z_SYNC_FLUSH 将其带到具有空存储块的字节边界。您可以交错这些放气块,因为它们是用 one-byte header 生成的,每个标识它来自三个流中的哪一个。然后你的解压器读入这些 deflate 块并用三个 inflate 实例解压它们,当它可用时从相应的未压缩数据块中提取你的令牌。
我正在寻找一个好的压缩算法或库,它可以让我将多个压缩数据流交织成一个数据流,没有性能或压缩损失。
更多背景:我一直在研究一种专用于特定应用程序的压缩格式。这种压缩格式对数据执行一堆特定领域的分析,然后将压缩数据输出为一堆流,每个流都被压缩(通常使用 LZW,但这不是一成不变的)。其中一个流,主流,包含一堆令牌。主流中的每个令牌都包含我需要推断哪个辅助流包含我的下一个 令牌 的信息,我需要从该辅助流中读取多少解压缩字节,以及我需要什么与此令牌有关。
到目前为止一切顺利,但我不想将我的最终数据作为一堆串联的流发送,因为这需要我接收整个数据才能对其进行有意义的处理。相反,我想将它们作为单个流发送,我可以在收到它时对其进行解码和处理。所以这基本上想发送一些类似的东西:
- 一个来自主流的token(用主流的字典压缩);
- 好的,这是令牌 "FooBar",我知道一个令牌 "FooBar" 后面总是跟着两个来自流 "Foo" 的令牌,一个来自流 "Bar" 的令牌;
- 来自流 "Foo" 的两个标记(使用用于流 "Foo" 的字典压缩);
- 来自流 "Bar" 的一个标记(使用用于流 "Bar" 的字典压缩);
- 来自主流的一个令牌(回到主流的压缩);
- ...
这里的复杂之处在于,任何有趣的压缩算法都不会简单地将一个令牌转换为一个或多个具有明确定义的令牌结尾的字节。有时,单个令牌将是多个数据包。有时,一个数据包将包含许多令牌。对我来说幸运的是,我的代币大小很容易预测。另一方面,为了 space 效率,我不能写每个数据包的大小或每次添加一个数据包的数量。
那么,我如何才能 multiplex/interleave 将所有压缩流合并为一个流而不需要添加大量元数据?我的印象是,这基本上是多媒体格式解决的那种问题,但我对这个话题的领域知识为零。有什么建议吗?我对算法、图书馆和论文感兴趣。
例如,使用 zlib,您可以为三个流同时拥有三个 deflate 运行 实例。使用 deflate,您可以一次压缩一个 deflate 块(使用 Z_BLOCK),并使用 Z_SYNC_FLUSH 将其带到具有空存储块的字节边界。您可以交错这些放气块,因为它们是用 one-byte header 生成的,每个标识它来自三个流中的哪一个。然后你的解压器读入这些 deflate 块并用三个 inflate 实例解压它们,当它可用时从相应的未压缩数据块中提取你的令牌。