PNG 文件格式的 IDAT 块

2024-04-12

我目前正在开发一种基于 png 文件格式的专有文件格式。到目前为止我已经完成了,只是它不起作用:-p 我实现的 deflate 解压缩器工作起来就像一个魅力,但 png 解码器不想很好地执行,所以我看了一下原始的 png 文件。

该标准规定,在 IDAT 标头之后,紧随其后的是压缩数据。因此,由于数据是压缩流,IDAT 之后的第一个字符是 0x78 == 01111000,这意味着,模式一块(未压缩),并且它不是最终的块。

但奇怪的是 - 我很难想象 PNG 编码器不使用动态哈夫曼编码来压缩过滤后的原始图像数据。 deflate 标准规定,在模式一中将跳过当前字节的其余部分。

因此接下来的四个字节表示未压缩块的大小及其补码。 但0x59FD不是0xECDA的补码。即使我搞砸了字节顺序:0xFD59 也不是 0xDAEC 的补码。

好吧,淘汰字节就在后面。 0x97 被认为是未压缩但仍经过过滤的原始 png 图像数据的第一个字节,因此必须是过滤器类型。但 0x97 == 10010111 不是有效的过滤器类型。如果我搞砸了位打包顺序 11101001 == 0xe9 的事件仍然不是有效的过滤器类型。

我不再关注 RFC 1951,因为到目前为止我可以使用 deflate 解压缩器的实现来膨胀所有类型的文件,所以我怀疑我对 PNG 标准存在一些误解。

我一遍又一遍地阅读 RFC 2083,但是我在这里看到的数据与 RFC 不匹配,这对我来说没有意义,一定是缺少了一块!

当我查看以下字节时,实际上我在附近看不到有效的过滤器类型字节,这让我认为过滤后的 png 数据流毕竟是经过压缩的。

如果 0x78(IDAT 之后的第一个字节)从 MSB 读取到 LSB,则有意义,但 RFC 1951 另有规定。另一个想法(对我来说更有可能)是 IDAT 字符串和压缩 deflate 流的开头之间存在一些数据,但 RFC 2083 另有规定。布局清晰

4字节大小 4字节块名称(IDAT) [大小] 字节(压缩后的 deflate 流) 4字节CRC校验和

因此,IDAT 之后的第一个字节必须是压缩 deflate 流的第一个字节 - 这表示模式 1 未压缩数据块。这意味着 0x97 必须是未压缩但已过滤的 png 图像数据的第一个字节 - 这意味着 0x97 是第一行的过滤器类型 - 这是无效的......

我就是不明白,是我傻还是怎么??

概括: 可能性一: IDAT 和压缩 deflate 流的有效开始之间还有一些其他数据,如果渲染为真,则 RFC2083 或我读过的任何有关图像压缩的书中都没有提到这些数据。

可能性2: 数字 0x78 被解释为 MSB -> LSB,这将指示模式 3 块(动态哈夫曼编码),但这与 RF1951 相矛盾,RF1951 对于位打包非常清楚:(LSB -> MSB)

我已经知道,缺失的部分一定是非常愚蠢的东西,如果 Stack Overflow 中只有一个删除按钮,我会感到迫切需要出卖我的灵魂:-p


两个更正可能会帮助您上路:

  1. 的数量zlib标志中的字节是 2,而不是 1 -- 请参阅RFC 1950 https://www.rfc-editor.org/rfc/rfc1950。第一个是CMF, 下一个FLG.

在您的数据中:

78 DA

---CMF---  ---FLG---
0111.1000  1101.0101
CINF -CM-  +-||
           | |+- FCHECK
           | +-- FDICT
           +---- FLEVEL

CINF为7,表示标准32Kb压缩窗口。
CM是8,表明压缩算法确实是DEFLATE。
FCHECK只是一个校验和;我没有检查它是否正确(但我敢打赌它是正确的)。
FDICT很清楚,意味着没有存储预设词典。
FLEVEL为3,表示最大压缩。

也可以看看尝试理解 PNG 文件中的 zlib/deflate https://stackoverflow.com/questions/26018811/trying-to-understand-zlib-deflate-in-png-files,特别是。博士。阿德勒的回答。

  1. LEN and NLEN仅针对未压缩块设置;这就是你没有找到它们的原因。 (另外,部分原因是您查看了错误的字节。)

下一个byte在流中是EC;按位计算,这是1110 1100 but记住从低位到高位读取位。所以下一位读取的是0, 意义notFINAL,接下来读取的 2 位是10(按这个顺序!),表示常规动态霍夫曼编码数据块。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PNG 文件格式的 IDAT 块 的相关文章

  • 如何通过 C# 检测字符串中的阿拉伯语或波斯语字符?

    我想检测Arabic or Persian字符串中的字符 例如 在字符串中搜索 15 Aspire ES1 533 C4UH 并返回true 并在字符串中搜索 Aspire ES1 533 C4UH 并返回false string patt
  • Windows 上任何单个进程可以寻址的最大内存量

    Windows 版本的内存限制 http msdn microsoft com en us library windows desktop aa366778 28v vs 85 29 aspx回答 Windows 上任何单个进程可以寻址的最
  • Xamarin 中 QR 扫描后的处理对话框

    我在Xamarin应用程序中使用QR码扫描仪 当它扫描QR码时 它会执行一些操作 大约需要一分钟 而在执行操作时 我想在屏幕上显示一个加载对话框 但是 它没有显示在屏幕上 并且在应用程序的其他地方 它运行得很好 Code var expec
  • C 程序的“编译器正确”命令

    这是关于中提到的编译步骤Linux 期刊文章 https www linuxjournal com article 6463 C 程序是使用编译的cpp cc1 as and ld该文章中的命令 我能够执行这些步骤cpp as and ld
  • Oracle ODP.Net 与实体框架 6 - 从表视图中选择时出现 ORA-00955

    我创建了两个应用程序 第一个使用 ODP Net 另一个没有实体 效果很好 static void Main string args OracleConnection con new OracleConnection using conne
  • 与智能指针的返回类型协方差

    在 C 中我们可以这样做 struct Base virtual Base Clone const virtual Base struct Derived Base virtual Derived Clone const overrides
  • 如何查看某个函数以 3 秒的间隔被调用了多少次?

    我想检查我的函数在 3 秒内可以运行多少次 我写了这段代码 include
  • 将supportedRuntime嵌入到exe文件中

    我需要将仅包含supportedRuntime 设置的app config 文件嵌入到我的exe 文件中 我尝试执行构建操作嵌入资源 但它现在没有从配置文件中读取值 并且它不起作用 这是我的配置文件
  • 消息在事务处理时未到达 MSMQ

    我在本地计算机中创建了一个私有 MSMQ 我使用以下 C 代码将消息发送到队列 当我将队列更改为事务性队列时 消息未到达 MSMQ 但是 Send 方法中没有抛出异常 我需要做出什么改变才能使其发挥作用 using System using
  • ASP.NET MVC C#:将多个表/查询中的数据引入视图中

    好吧 我仍在掌握 ASP NET 和 MVC 框架的窍门 并将我的知识从经典的 ASP 和 VB 转换过来 所以请保持温柔 我的第一个视图 home details X 运行良好感谢之前的帮助为我指明了正确的方向 https stackov
  • LINQ 分组依据和选择集合

    我有这个结构 Customer has many Orders has many OrderItems 我想生成一个列表CustomerItems通过 LINQ 给出的子集OrderItems List of new Customer Li
  • HTTP 错误 500.35 - ANCM 同一进程中的多个进程内应用程序 ASP.NET Core 3

    从今天早上开始 没有对项目代码进行任何更改 一个非常简单的 Web API 一个控制器和 3 个方法 使用 Swagger 它不再启动 我收到错误 HTTP 错误 500 35 ANCM 同一进程中有多个进程内应用程序 事件查看器报告最无用
  • 图像处理编程

    我想知道是否有任何方法可以使用某种编程语言检测图像中对象的位置 例如 如果我有一个球的图像 每 100 毫秒更新一次 是否可以通过某些程序使用某些东西来获取球的坐标 看一下OpenCV http opencv willowgarage co
  • AZURE:workerrole 中的异步 Run()

    我有一个异步任务 async Task UploadFiles 我想在 azure 工作者角色的 Run 方法中调用 UploadFiles 上的 等待 但 await 仅适用于声明为异步的方法 那么我可以使 Run 方法异步 如下所示 p
  • 如何为 Blazor MapFallbackToFile() 生成正确的错误

    我有一个项目想要用作 Web API 和 Blazor wasm UI 该 API 也可以从其他项目访问 因此我希望该 API 向消费者提供有用的错误详细信息 我现在通过使用该网站来实现这两个目的MapFallbackToFile 方法 但
  • 多线程文件写入

    我正在尝试使用多个线程写入大文件的不同部分 就像分段文件下载器所做的那样 我的问题是 执行此操作的安全方法是什么 我是否打开文件进行写入 创建线程 将 Stream 对象传递给每个线程 我不希望发生错误 因为多个线程可能同时访问同一个对象
  • 索引 getter 中的 IndexOutOfRangeException

    在我的索引属性中 我检查索引是否超出范围 如果是的话 我抛出一个IndexOutOfBoundsException 当我运行代码分析器 在 VS12 中 时 它抱怨 CA1065 意外位置出现意外异常 参考CA1065的描述 仅 Syste
  • C# StreamReader 使用分隔符保存到数组

    我有一个文本文件 其中包含制表符分隔的数据 我在 C 应用程序中需要的是从文本文件中读取一行并将它们保存到一个数组中 在每个位置将它们分开 t 然后我对下一行做同样的事情 My code StreamReader sr new Stream
  • 实现“计时器”的最佳方法是什么? [复制]

    这个问题在这里已经有答案了 实现计时器的最佳方法是什么 代码示例会很棒 对于这个问题 最佳 被定义为最可靠 失火次数最少 和最精确 如果我指定 15 秒的间隔 我希望每 15 秒调用一次目标方法 而不是每 10 20 秒调用一次 另一方面
  • 提高大型结构列表的二进制序列化性能

    我有一个以 3 个整数保存 3d 坐标的结构 在测试中 我将 100 万个随机点放在一起 List 然后对内存流使用二进制序列化 内存流大小约为 21 MB 这似乎非常低效 因为 1000000 点 3 坐标 4 字节应该至少为 11MB

随机推荐

  • 将 JSON 转换为 PowerShell 对象并将 PowerShell 转换回 JSON

    我将 JSON 从 Azure 资源组导出到 JSON 文件 如下所示 Export AzureRmResourceGroup ResourceGroupName SourceResourceGroupName Path filename
  • cocoa WebView中innerhtml和outerhtml的区别

    我在我的应用程序中使用 cocoa webview 进行富文本编辑 只是与 webkit 中提供的innerHtml 和outerHtml 方法混淆了 谁能解释一下有什么区别 DOMHTMLElement webView mainFrame
  • 为什么优秀的 UI 设计对于一些开发人员来说如此困难? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Java 两个独立键盘的独立输入

    我有两个 USB 键盘插入同一台机器 我正在开发一个 Java 应用程序 是否有办法允许 Java 应用程序分离出它来自哪个 USB 键盘 即是否有类似的东西http docs oracle com javase 6 docs api ja
  • ajax提交表单为什么不能回显$_POST

    我正在使用ajax提交表单进行测试 提交给我自己的页面 new1 php 我想要的是 单击提交按钮后 它将回显名字和姓氏 但我不知道为什么提交后看不到名字和姓氏 这是new1 php页面
  • Zend Framework 2 - 如何包含库中的部分内容

    我写了一个部分 我想在几个模块中使用它 我认为最好的方法是将其放入我的自定义库中 但不幸的是 我无法找到一种方法来包含这个部分 而不使用像这样的非常难看的路径 echo this gt partial vendor myvendor lib
  • HTML5同页导航

    我在 html5 中遇到导航问题 我看了很多教程 我不知道我做错了什么 我想在同一页面上导航
  • Dropbox 是一个有效的快速但肮脏的源代码控制解决方案吗? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • ADB 错误:无法连接到守护程序

    我需要帮助才能让 ADB 在我的 PC win7 64 位 和 Samsung Galaxy S2 上运行 我已经安装了 Kies 附带的驱动程序 我想是在子文件夹 25 escape 下 驱动程序在设备管理器下正确显示为 Samsung
  • Laravel - 如何注册自定义广播者

    我想使用 BroadcastManager 注册自定义广播器 而无需更改内部框架代码 现在我必须在Illuminate Broadcasting BroadcasterManager class protected function cre
  • R:如何使 dump.frames() 包含所有变量,以便稍后使用 debugger() 进行事后调试

    我有以下代码 它会引发错误并使用以下命令写入所有帧的转储dump frames as 提议 e G 通过哈德利 威克姆 http adv r had co nz Exceptions Debugging html a lt 1 b lt H
  • Ruby 比较运算符? == 与 === [重复]

    这个问题在这里已经有答案了 和 有什么区别 什么时候应该使用哪一个 两者都只是在对象上调用的方法 这意味着对象决定哪个意味着什么 然而 Ruby 中有一些关于它们之间差异的约定 通常 比 a b几乎总是为真 如果a b是 阅读此内容的最佳位
  • 如何在 MVC 4 中使用 jQuery 更新 List

    我目前正在尝试使用修改后的索引视图创建设置页面 目标是让用户获得所有设置显示并可以更改一个视图中的所有设置并保存所有设置只需一个按钮 应使用 Ajax 更新设置 我目前的做法 View
  • 如何在 Mockito 中模拟 scala 调用名称

    我试图在mockito 中模拟scala 按名称调用方法 但遇到这个错误 如果匹配器与原始值组合 则可能会出现此异常 不正确 someMethod anyObject 原始字符串 使用匹配器时 所有参数都必须由匹配器提供 例如 正确的 so
  • 为什么迭代器使用“!=”而不是“<”?

    我习惯这样写循环 for std size t index 0 index lt foo size index Do stuff with foo index 但是当我在其他人的代码中看到迭代器循环时 它们看起来像这样 for Foo It
  • Visual Studio 调试器:输入外部函数时中断?

    With 只是我的代码 http msdn microsoft com en us library h5e30exc aspx 关闭并且源位置 服务器 很容易进入代码中没有的函数 但是有没有办法在其中一个函数上设置断点 基本上 我想说 当从
  • 按名称从 css LESS 列表中提取项目

    如果我有一个不太像的列表 colors red f00 green 0f0 blue 00f 我知道我可以循环列表并获取颜色 但如果我想获取特定的颜色怎么办 说我想做 extract colors green 将 0f0 从列表中删除 有没
  • HTML5 Canvas 填充两种颜色

    我需要用两种颜色填充形状 就像棋盘一样 我见过一些 css 的渐变效果 但还没有见过这样的例子 这在 Html5 Canvas 中可能实现吗 你当然可以 事实上 您可以用任何可重复的东西填充任何任意形状 即使是您在画布本身中制作的形状 这是
  • 将内容添加到列表时保持滚动位置 (AngularJS)

    我一直在尝试使用以下方法将一些项目添加到可滚动容器内的列表中ng repeat 最近的应该位于列表的顶部 如果在添加内容时容器的滚动条不在最顶部 我还需要保持滚动位置 这是我的解决方案 但我仍然有问题 Angular 在 dom 中渲染了前
  • PNG 文件格式的 IDAT 块

    我目前正在开发一种基于 png 文件格式的专有文件格式 到目前为止我已经完成了 只是它不起作用 p 我实现的 deflate 解压缩器工作起来就像一个魅力 但 png 解码器不想很好地执行 所以我看了一下原始的 png 文件 该标准规定 在