GIF Encoder Bug

基友写的一个libgif终于出现了虫子,只要导出一张纯色的gif立刻卒,症状为导出文件正常,然而无法播放,资源管理器无法查看预览和缩略图,所有浏览器包括Edge、IE、Chrome、FF打开它全挂。PS打开正常,扔到QQ里能正常播放但是发送直接提示发送失败,甚是邪门。于是一脸不甘心的探个究竟。

打开gif89a specification,直接上UE,翻到Image Descriptor部分,如图:


按照文档,颜色表标记为0x80,表示为本地颜色表存在|不排序|非交错|颜色表大小为2^(0+1)个,而后6字节为颜色表,0x01起为LZW压缩段落,看上去貌似一切正常。

一脸不死心拽了一个NGif,调试起来,竟然能正常解码!这说明LZW段落没有问题。用GDI+随便加了一个颜色像素点,导出的GIF各种可以播放。试着缩小文件大小,依然导出纯色GIF,诶!GDI+可以正常加载了,windows图片浏览也可以正常查看了。逐渐放大这个值,发现图像大小在286*286时至少可以在IE/GDI+下正常运作,当扩大到287*287时,图片挂掉。但是即使是极小的单色GIF,其他浏览器也无法正常显示。

GDI+和IE或者图片浏览统一用WIC解码,一起挂掉属于必然。LZW段又没有问题,所以问题还是出现在本地颜色表上。

仔细看gif89a描述文档,它是这么说的:


如果没有本地颜色表,颜色表大小的数值需要为0。这和我们上面生成的GIF刚好反过来:我们是存在本地颜色表,但是数值依然为0(来表示实际上颜色表大小为2)。这实质上可能对图像解码造成歧义,导致解码器误认为不存在本地颜色表,直接把后面颜色表部分当成是LZW压缩段而解析失败。当数值为1(表示颜色表大小为4)时,歧义消失,图像可以正常解析。

最后解决办法当然是:


篡改encoder代码,强行使量化后有效颜色大于3(原本是纯色+透明色),使颜色表大小至少为2^2,问题解决。

不过至今不知道为什么WIC的解码器可以识别某个阈值大小下的图像。PS能解析大概是因为啊逗逼的猴子按照文档正直的识别了下来,至于其他主流浏览器,大概直接弃疗了吧╮(╯-╰)╭

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 我以前总要去分个人性的善恶,道德的真假,但总也找不到头绪。原来自私和利他的基因都是存在于我们身上的,人们会表现出什...
    董江阅读 536评论 0 1
  • 近日有好几个朋友问到一个概念,叫做“发展”,说看早期教育类书籍都说到这个词,据说还挺重要,但是不太明白啥意思,感觉...
    亲子蹦跶阅读 10,845评论 2 3
  • 2016年启程的勇敢爱,让我努力去改变去尝试新的东西去涉足新的领域。对于自己的未来有所计划和期待的日子真的很棒。 ...
    苏苏苏苏浅夏阅读 2,206评论 0 1
  • 昏 灯 一 盏 , 老 酒 半 坛 几 位 故 人 围 坐 酒 意 正 酣 笙 歌 又 起 , 月 影 阑 珊 忆...
    自在江湖的少年阅读 1,222评论 0 1