如何从头开始完全实现 PNG 解码器
How to implement a PNG decoder completely from scratch
出于学习目的,我开始使用 PNG encoding/decoding 库,所以我想手动实现它的每个部分。
我用了很长时间,但现在有点卡住了。以下是我已经成功实施的事情:
- 我可以加载 PNG 二进制文件并浏览其字节
- 我可以读取元数据的签名和 IHDR 块
- 我可以读取 IDAT 块并将图像数据连接到缓冲区中
- 我可以从上述图像数据中读取和解释 zlib headers
这就是我卡住的地方。我依稀知道这里的步骤是:
- 根据其headers
提取zlib压缩数据
- 弄清楚使用的过滤方法并"undo"它们以获取原始数据
- 如果一切顺利,现在我有
[<R of 1st pixel>, <G of 1st pixel>, <B of 1st pixel>, <R of 2nd pixel>, <G of 2nd pixel>, etc...]
形式的原始 RGB 数据
我的问题是:
- 是否有关于 zlib 提取的任何 easy-to-understand 实现(可能有示例)或指南,因为我发现官方规范很难理解
- 同一个文件可以使用多种过滤方式吗?如何弄清楚这些?如何找出这些不同过滤部分的"borders"?
- 我对最终数据的理解是否正确? alpha 通道或何时使用调色板呢?
是的。您可以查看 puff.c,这是一个 inflate 实现,其明确目的是作为如何解码 deflate 流的指南。
图像的每一行可以使用不同的过滤器,在解压行的第一个字节中指定。
是的,如果你做对了,那么你将得到一个像素序列,其中每个像素都是一个灰度值,G,具有 alpha 通道,GA,RGB(红色-绿-蓝,按此顺序)或 RGBA。
出于学习目的,我开始使用 PNG encoding/decoding 库,所以我想手动实现它的每个部分。
我用了很长时间,但现在有点卡住了。以下是我已经成功实施的事情:
- 我可以加载 PNG 二进制文件并浏览其字节
- 我可以读取元数据的签名和 IHDR 块
- 我可以读取 IDAT 块并将图像数据连接到缓冲区中
- 我可以从上述图像数据中读取和解释 zlib headers
这就是我卡住的地方。我依稀知道这里的步骤是:
- 根据其headers 提取zlib压缩数据
- 弄清楚使用的过滤方法并"undo"它们以获取原始数据
- 如果一切顺利,现在我有
[<R of 1st pixel>, <G of 1st pixel>, <B of 1st pixel>, <R of 2nd pixel>, <G of 2nd pixel>, etc...]
形式的原始 RGB 数据
我的问题是:
- 是否有关于 zlib 提取的任何 easy-to-understand 实现(可能有示例)或指南,因为我发现官方规范很难理解
- 同一个文件可以使用多种过滤方式吗?如何弄清楚这些?如何找出这些不同过滤部分的"borders"?
- 我对最终数据的理解是否正确? alpha 通道或何时使用调色板呢?
是的。您可以查看 puff.c,这是一个 inflate 实现,其明确目的是作为如何解码 deflate 流的指南。
图像的每一行可以使用不同的过滤器,在解压行的第一个字节中指定。
是的,如果你做对了,那么你将得到一个像素序列,其中每个像素都是一个灰度值,G,具有 alpha 通道,GA,RGB(红色-绿-蓝,按此顺序)或 RGBA。