为什么 GIF Encoding/Decoding 块之间有这么多填充

Why is there so much padding in GIF Encoding/Decoding between blocks

我一直在为我正在处理的项目开发自定义 GIF 解码器,该项目需要尽可能少的 GIF 数据存储在 RAM 中(因此我有效地将所有内容从文件中提取为我需要它,一个字节一个字节)。

我一直在学习以下教程:

http://matthewflickinger.com/lab/whatsinagif/bits_and_bytes.asp

在规范本身的帮助下:

https://www.w3.org/Graphics/GIF/spec-gif89a.txt

我可以用我的解码器制作 non-animating GIF 和交通灯动画示例。但是当我尝试浏览从 www.piskelapp.com 导出的 GIF(使用 gif.js 作为其导出器)时,我在不同的块之间得到了很多填充,在某些情况下不应该根据的填充符合规范。

例如,以下动画 https://www.piskelapp.com/p/agxzfnBpc2tlbC1hcHByEwsSBlBpc2tlbBiAgICA_eOjCgw/edit 的开头如下所示:

47 49 46 38 39 61 20 00 20 00 F7 00 00 00 00 00 4E 4E 4E FF FF 00 00 00 00 00

前 6 个字节应该是 header(ASCII 中的 GIF89a),接下来的 7 个字节应该是逻辑屏幕描述符 (LSD)。鉴于此处的信息,紧随其后的是一系列与 LSD 中的颜色数量相匹配的颜色数据。但事实并非如此,它只是 3 个“00"s, 3 "4E"s, and 2 "FF”后跟一串 00,持续 760 个字节。在 760 之后,我来到图形控制扩展(这是预期的,并用 0x21 表示)。这发生在以下许多块之间,除了我没有在我期望的地方看到任何类型的扩展代码,也没有在正确的位置看到图像描述符(应该以 2C 开头)。

总而言之,我是否遗漏了规范中的某些内容?这一切是什么,看起来像填充物,我该如何规避它?我在使用其他编码器的其他 GIF 文件中看到过其他类型的这种填充,但似乎没有一致的代码可供我查找。该文件适用于 Windows 张照片,因此一定有我遗漏的东西。

答案很简单。 Piskel 使用的 GIF 导出器的实现很差。

它在 GIF89a 规范中明确指出:

"应考虑此处指定的图形交换格式 (sm) 完全的;任何偏离它的行为都应被视为无效,包括但不 仅限于在控制或数据中使用保留或未定义的字段 块,在块内或块之间包含无关数据,使用 未作为格式的一部分具体列出的方法或算法等。"

我要指出的一块是"the inclusion of extraneous data within or between blocks"。在这种情况下,问题是块内的数据,出于某种原因,Piskel 使用的导出器总是用黑色填充所有剩余空间的颜色表(全局和本地)。在发现可能的解码实现错误后我意识到了这一点,这在点击重复的 "black" (#000000) 颜色代码时导致了问题。

更多信息可在规范本身中找到,位于此处:

https://www.w3.org/Graphics/GIF/spec-gif89a.txt