2个稳定版本
1.0.1 | 2024年5月27日 |
---|
724 in 图像
89KB
1.5K SLoC
一个const QOI(相当不错的图像)解码和编码库
一个安全的、无依赖项、no_std流式解码器/编码器库,用于QOI(相当不错的图像)格式。
动机
我想理解QOI规范,并在const上下文中实现解码器和编码器。所有公共和私有函数都是const,包括所有测试。这个项目帮助我更好地理解位操作。
实现
解码器和编码器都维护一个包含64个之前看到的像素的数组和一个单独的前一个像素值。
解码器
这是规范中较容易理解和实现的部分。在解析14字节头之后,将输入字节作为数据块处理的过程是直接的
- 维护输入数据的索引
- 维护处理像素的计数以知道何时完成(最初从头部的宽度和高度计算得出)
- 根据输入字节匹配以确定你正在处理的QOI数据块标签(没有重叠)
- 对于超过1字节的块,从输入中获取额外的字节(相应地调整输入索引)
- 根据块创建或获取RGBA像素值(根据之前的像素运行、之前看到的像素数组中的索引、diff/luma上的位操作或从输入中获取的字节)
对于流式解码器,输出进入一个中间缓冲区,这需要额外的考虑
- 需要跟踪输出缓冲区空间
- 需要在输出缓冲区满时处理调用之间QOI运行块的情况
编码器
我发现这部分较难理解和实现。有一些比较要做
- 比较前一个像素值与当前输入像素值
- 比较当前输入像素值与之前看到的像素数组中的像素值
基于这些比较,选择适当的QOI数据块将像素数据编码进去。顺序如下
- 运行块(如果前一个、当前和索引像素相同)
- 索引块(如果当前和索引像素相同)
- 差分块(如果当前RGB值与之前像素相比在小的可接受范围内,并且alpha相同)
- 亮度块(如果当前RGB值与上一个像素相比在更大的可接受范围内,且alpha值相同)
- rgb块(如果alpha值相同且超出可接受亮度范围)
- rgba块(如果alpha值不同)
对于输入的第一个像素值,需要特别注意
- 之前看到的像素都是零初始化的,这意味着所有RGBA值都是0, 0, 0, 0
- 默认的前一个像素值的RGBA值为0, 0, 0, 255
- 如果遇到第一个像素值为0, 0, 0, 255,将使用上述顺序发出diff块而不是run块,因为它不在已看到的像素中
使用方法
请参阅https://crates.io/crates/const_qoi以及下面的文档部分。
文档
文档可以在这里找到:https://docs.rs/const_qoi