image - 伪代码:如何从位和字节解码 PNG 文件?

标签 image algorithm bitmap png pseudocode

我一直试图通过对我在 GIMP 中创建的 .png 文件进行逆向工程来解决这个问题。它是 4x4 像素。我的目标是解码文件中的原始像素,目的是将其反转以进行编码。

这是文件的完整十六进制转储:

89504E47 0D0A1A0A 0000000D 49484452 00000004 00000004  
08020000 00269309 29000000 3F494441 54081D01 3400CBFF  
01CC96B1 134FE120 C0CECDF1 5101FFA5 60000000 000000E0  
403201DF E59286DF 6D000000 00000004 EDB11F00 2E007A21  
93EDB11F 3063136F 4733525A 00000000 49454E44 AE426082  

根据spec ,我们从前 8 个字节的 PNG 签名开始。

89504E47 0D0A1A0A

然后我们有重复的“ block ”结构,这个文件有 3 个“ block ”,标题 (IHDR),图像数据 (IDAT),然后是结尾“ block ”(IEND)。

每个chunk被安排成:前4个字节为chunk数据的长度,接下来的4个字节为数据类型,然后n个字节为实际数据,然后4个字节为循环冗余校验(CRC) ) 的数据类型和实际数据部分。

通过...

0000000D

是 block 的数据长度(13 字节)。

49484452

是 block 的类型(IHDR)。

00000004 00000004 08020000 00

是chunk的数据(4字节宽,高;1字节位深,颜色类型,压缩方式,过滤方式,交错方式)。

269309 29

是数据和类型的 CRC(设法从 here 中获取代码来解决这个问题。

000000 3F

是下一个chunk的数据长度(63字节)。

494441 54

是 block 的类型(IDAT)。

081D01 3400CBFF 01CC96B1 134FE120 C0CECDF1 5101FFA5 60000000 000000E0 403201DF E59286DF 6D000000 00000004 EDB11F00 2E007A21 93EDB11F 3063136F

是chunk的实际数据(压缩过滤后的图像数据)。

所以我的实际问题是如何将最后一部分解码为原始像素?

根据spec ,我必须首先解压缩数据(膨胀?)然后取消过滤(??)留下像素扫描线(我的目标)。

如果这可以用伪代码来解释,那就太棒了!否则我熟悉 Swift 而不是 C...

最佳答案

本书为程序员讲解解码的过程:

https://www.amazon.com/Compressed-Image-File-Formats-JPEG/dp/0201604434

整个过程非常复杂,无法适应 SO 答案的空间。 PNG 使用两种不同的压缩方法:LZ 和霍夫曼编码。

关于image - 伪代码:如何从位和字节解码 PNG 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50638365/

相关文章:

html - 如何设置不同大小的图像以占据它们之间的所有空间

algorithm - 列表性能优化

python - 找到包含所有数字的最小长度子数组

android自定义位图覆盖与mapsforge

java - android 不压缩保存位图

具有多个过滤器的图像搜索

c++ - 使用openCV从一个图像中减去另一个图像

c# - Image.FromStream() 方法返回 Invalid Argument 异常

c++ - 数组升序嵌套循环问题

android - 缩放位图以适合 Canvas