2 个版本
0.1.1 | 2022 年 7 月 7 日 |
---|---|
0.1.0 | 2022 年 7 月 6 日 |
637 在 压缩 分类中
每月下载 659 次
在 2 个crate中使用了它(通过 optivorbis)
32KB
342 行
该crate实现了Vorbis I规范中定义的位打包约定,第2节。
概述
Vorbis位打包约定是一种简单有效的手段,用于在字节导向的传输中高效地写入和读取任意宽度的整数序列。它可以概括为连续存储这些整数的二进制表示的位,尽可能避免填充或对齐到字节。
与大多数通用序列化格式不同,Vorbis位打包不添加任何头部或字段分隔开销:位打包流是一系列原始的无结构位,没有内在的解释。任何位序列都是有效的位打包流。因此,编码器和解码器有责任就解释数据的某些协议达成一致。
位打包是小端序:最低有效位首先写入流。当只处理完整的字节时,位打包等同于按小端序读写它们。
支持的数据类型
任何数据类型都可以转换为整数,因此位打包约定可以推广到非整数数据类型。然而,该crate将其范围限制在Vorbis流中使用的类型,最多32位宽
- 无符号整数,0到32位宽。读取0位宽的整数始终成功并返回0。
- 有符号整数,采用二进制补码表示,0到32位宽。
- Vorbis
float32
,一种自定义的浮点数格式,可以精确转换为[f64
],但不能反过来。 - 布尔标志,1位长。
这些类型可以自由地用作实现新数据类型的基础。例如,64位整数可以实现在两个32位整数相结合的形式。
#![no_std]
兼容性
默认情况下,该crate依赖于Rust标准库,但启用可选的 no-std
功能时,它与 #![no_std]
环境兼容。
示例
以下代码重新创建了Vorbis I规范位打包示例。
use std::io::Cursor;
use vorbis_bitpack::{bitpacked_integer_width, BitpackReader, BitpackWriter};
let mut buf = Vec::new();
// Write bitpacked integers
let mut bitpacker = BitpackWriter::new(&mut buf);
bitpacker.write_unsigned_integer(12, bitpacked_integer_width!(4))?;
bitpacker.write_signed_integer(-1, bitpacked_integer_width!(3))?;
bitpacker.write_unsigned_integer(17, bitpacked_integer_width!(7))?;
bitpacker.write_unsigned_integer(6969, bitpacked_integer_width!(13))?;
drop(bitpacker); // Pads and writes the incomplete last byte
// Read them back
let mut bitpacker = BitpackReader::new(Cursor::new(&mut buf));
assert_eq!(bitpacker.read_unsigned_integer(bitpacked_integer_width!(4))?, 12);
assert_eq!(bitpacker.read_signed_integer(bitpacked_integer_width!(3))?, -1);
assert_eq!(bitpacker.read_unsigned_integer(bitpacked_integer_width!(7))?, 17);
assert_eq!(bitpacker.read_unsigned_integer(bitpacked_integer_width!(13))?, 6969);
// The buffer should have all the integer bits concatenated together as tightly
// as possible
assert_eq!(buf, [0b1_111_1100, 0b01_001000, 0b11001110, 0b00000_110]);
依赖关系
~0–25MB
估计约为 ~302K SLoC