[iOS/OC]iOS10.3.3上APNG不动

0x0背景

原本是放到自己博客的,不怎么用了,把文章同步过来,原文地址[iOS/OC]iOS10.3.3上APNG不动

问题现象:有1张APNG动图,在其他系统上都OK,单单在iOS10.3.3上不动。特别迷,花了一下午的时间排查这个问题。最终咨询了@DreamPiggy ,才把这个问题搞清楚。

0x1原因

APNG的数据块有IHDR、acTL、fcTL、IDAT、fdAT等类型。每帧APNG的图像由1个FCTL,>=1个(通常是1~2个)IDAT图像组成。其中FCTL是每帧的控制信息,IDAT是图像信息。在iOS10.3.3系统中,当每帧APNG的fdAT>=3时,系统解码会出错,导致解码失败,并取第一帧信息作为解码结果,即展示PNG静图。

简单的说,即:
iOS 10.3.3系统BUG,在APNG较大且较复杂时,APNG解码失败,返回首帧PNG静图。

0x2APNG

分析过程中,第一步就是查询APNG的标准,发现这块文档十分匮乏,尤其是中文文档。在此,按个人理解整理一份。

1.APNG结构

一个流传甚广的图如下。PNG的基本结构是PNG签名(PNG Signature)+图像头(IHDR)+数据块(IDAT)+结束块(IEND),4部分组成,而APNG则是在此基础上扩展,主要是增加了acTL控制块保存整体动图控制信息,将N张图片的IDAT取出来作为每一帧的信息,并在每一帧增加fcTL控制卡保存每帧图像的控制信息。

[图片上传失败...(image-90acc5-1537881630217)]

2.手工解码APNG

只知道APNG的结构,当出现APNG相关问题的时候,你还是不知道是怎么回事。下面我以上面有问题的APNG为例,手工解码APNG。从结构上分,APNG有PNG签名、数据块,两种类型。

1)PNG签名

整个文件的前8个byte是PNG签名头,为8950 4e47 0d0a 1a0a,将这8个byte转为ascii就是PNG

[图片上传失败...(image-c96bb8-1537881630218)]

2)数据块类型

数据块(chunk)常见类型有:IHDR、acTL、fcTL、IDAT、fdAT、IEND

基本格式如下:

序号 描述 长度(byte)
1 chunk内容长度 4
2 chunk类型 4
3 chunk内容 由1chunk内容长度决定
4 校验码 4

其中chunk类型将其由hex转为ascii,即为对应的值,如:
[图片上传失败...(image-e3dd5b-1537881630218)]

①IHDR

长度(byte) 内容 意义
4 0000 000d chunk内容长度为13 byte
4 4948 4452 IDHR
13 0000 0465 0000 01ea 0806 0000 00 见下标
4 ad34 f3f4 校验码

IHDR的内容意义如下:

描述 长度(byte) 内容
图片宽度 4 byte 0000 0465
图片高度 4 byte 0000 01ea
图像深度 1 byte 8
颜色类型 1 byte 6
压缩方法 1 byte 0
过滤方式 1 byte 0
扫描方式 1 byte 0

②acTL

长度 内容 意义
4 byte 0000 0008 chunk内容长度为8 byte
4 byte 6163 544c acTL
8 byte 0000 000a 0000 0000 前4byte为帧数,10帧;后4byte为循环次数,无限循环;
4 byte ad34 f3f4 校验码

③fcTL

长度 内容 意义
4 byte 0000 001a chunk内容长度为26 byte
4 byte 6663 544c fcTL
26 byte 00 0000 0000 0004 6500 0001 ea00 0000 0000 0000 0000 0c00 6400 00
4 byte 50 8aec fb 校验码

④IDAT

长度 内容 意义
4 byte 00 0080 00 chunk内容长度为32768 byte
4 byte 4944 4154 IDAT
32768 byte
4 byte 876e ca46 校验码

3)数据块类型补充

在动图中,第1帧称为关键帧,其他帧信息在压缩算法下需要有第1帧计算得来。在APNG中,关键帧就是IDAT,第2帧开始为fdAT。

根据数据块类型可知,通常37byte开始,为acTL数据块,可以以此作为是否为APNG的标识。但是这个不是强制的,你也可以自己定义数据块类型,在IHDR之后添加相应信息。

例如,为APNG添加了签名和时间戳后,在Safari下显示是正常的,在Chrome下就无法正常加载。即:Chrome和Safari对于APNG的标准解读不同,且明显Chrome对APNG的标准支持不完善。

3.参考文章

PNG规范中文解读:png的故事:获取图片信息和像素内容

PNG标准英文文档:PNG (Portable Network Graphics) Specification, Version 1.2
APNG标准英文文档:APNG Specification
APNG介绍:APNG那些事

APNG分析网站:https://animatedpngs.com/
HEX转ascii网站:https://www.rapidtables.com/convert/number/hex-to-ascii.html

0x3问题分析

1.分析图片数据

在有以上的对APNG的知识储备后,就可以开始进行正式的问题分析了。

对多组图片手动解码,分析fdAT数据发现,fdAT在同一帧中连续3次或以上,会导致在iOS10.3.3上解码失败。结论以猜测为主,部分证实,暂无实锤。相关数据就不放了。有兴趣的同学可以自己解析一下看看。

2.ImageIO的符号断点

ImageIO有一个LogDebug函数,添加符号断点后,可以断到这个符号,侧面印证了此时系统APNG解码失败。

0x4总结

有必要总结下。各大厂对图片格式的解读是不一致的,尤其是在动图上,在一些特定场景下就会踩坑。目前我已知的有:

1.本文的问题,APNG的fdAT>=3时,苹果系统(iOS/mac os)解码失败,变为静图;
2.APNG添加签名后,Android解码失败,无法展示;
3.安卓和苹果对GIF的循环次数理解不一致,通常可以在苹果解GIF时循环次数加1,以保持多端一致;

其他隐藏的坑不知道还有多少。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容