当前栏目
超快的PNG图像解码器!速度提升2.75倍,比老大哥libpng还安全
本文经AI新媒体量子位(公众号ID:QbitAI)授权转载,转载请联系出处。
提到PNG,大多数人都不会感到陌生。
这种位图格式在图像领域使用频率仅次于JPEG。
然而在“解码PNG”这件事上,23年来主流的工具是一个叫做libpng的标准库。
但最近,一款号称“世界上最快的PNG图像解码器”诞生了,速度是“老大哥”的1.22-2.75倍!
![最快的PNG图像解码器!速度提升2.75倍,比老大哥libpng还安全](https://s6.51cto.com/oss/202104/13/1502b5d8c8112decea8b40f516b2589e.jpg)
除了速度方面的优势之外,更重要的一点,极其安全。
超快的PNG图像解码器
与用C语言为底层的libpng不同,这款PNG图像解码器采用的是Wuffs。
Wuffs是一种内存安全的编程语言(也是用这种语言编写的标准库),用于安全处理不受信任的文件格式。
包括解析、解码和编码图像,音频,视频,字体等。
Wuffs不是一种通用编程语言。它是用来编写库的,完整的程序需要将Wuffs与另一种编程语言结合使用。
尤其是需要同时考虑性能和安全性的时候。
ps. 机智的你发现了吗,Wuffs其实就是Wrangling Untrusted File Formats Safely的缩写。
不过它以前叫Puffs,至于为什么将Puffs(parsing)改为Wuffs(wrangling),留给你们自己去想象~
那么,解码速度快至2.75倍,怎么做到的?
Wuffs通过SIMD加速方案,8字节宽的输入和复制,一次将整个图像进行位扭曲和zlib解压缩到一个大的中间缓冲区来实现高性能。此法替代了此前的一次一行(小块重复压缩)的方式。
这“一包带走”的操作需要更多的中间存储,但能解码的图像数量也更多了。
具体咋回事儿呢?
我们知道,PNG图像格式编/解码基于以下三方面:
- CRC-32和Adler-32两种校验和算法
- DEFLATE压缩
- 二维过滤
Wuffs对这其中的每一步都进行了优化。
首先,对两种校验和算法施以SIMD加速技术。
SIMD是一种采用一个控制器来控制多个处理器,同时对一组数据中的每一个分别执行相同的操作从而实现空间上的并行性的技术。
其次,0.2版本Wuffs具有与zlib库一样的DEFLATE实现,而0.3版Wuffs为现代CPU(具有64位未对齐加载和存储)添加了两个重要的优化:8字节区块输入和8字节区块输出。
DEFLATE是同时使用了LZ77算法与哈夫曼编码的一个无损数据压缩算法。
对于Wuffs,8字节区块输入设计的每个内部循环一次读取64位可使DEFLATE微基准加速多达1.3倍。
而8字节区块输出设计将副本长度舍入为8的倍数可以使DEFLATE微基准提高多达1.48倍。
此外,DEFLATE涉及写入目标缓冲区和写入缓冲区边界的问题。
(经典的“缓冲区溢出”安全漏洞,类似于从悬崖上奔跑,如何不落入鲨鱼口中)。
此方面,Wuffs使用和libpng相似的蓝/红双重实现技术。
蓝/红双重实现技术:一种快速的“蓝色”解压缩(在距缓冲区末端至少258个字节或更多字节 时)以及一种缓慢的“红色”解压缩(反之)技术。
以前面的从悬崖上奔跑做比喻,就是在离崖边还远时尽可能得快跑,离崖边很近时减速刹车。
![最快的PNG图像解码器!速度提升2.75倍,比老大哥libpng还安全](https://s2.51cto.com/oss/202104/13/fd74ee05c31958b80141ccde504ab8d7.jpg)
但同样的技术,为什么Wuffs更快?
因为它能一次将几乎所有内容(eg. 300×200 RGB图像的像素的99%以上)解压缩到一个大的中间缓冲区中,而不是一次只压缩一行到一个小的、可重复使用的中间缓冲区中。
如图所示,几乎所有内容现在都在“蓝色”区域中解码。
这本身就比“红色”区域快。
而且在蓝色代码和红色代码之间交替时,Wuffs也避免了任何指令高速缓存或分支预测变慢的情况。
![最快的PNG图像解码器!速度提升2.75倍,比老大哥libpng还安全](https://s3.51cto.com/oss/202104/13/f3170a1a95e806e40db42ccbe08c0ab8.jpg)
最后,虽然Wuffs和libpng都具有PNG二维过滤的SIMD实现。
但是因为libpng将任何自分配的像素行缓冲区对齐到最适合SIMD的边界时,对齐这步操作会影响SIMD指令的选择和性能。
而Wuffs对缓冲区对齐的承诺较少,部分原因是Wuffs不具有分配内存的能力,但主要还是因为一次全部解压缩时,zlib压缩要求放弃例如每行开头4字节的对齐。
为什么说最安全?
与Go或Rust不同,Wuffs的内存安全是在编译时强制执行的,而不是通过插入运行时再检查。
( ps.运行时安全检查也可能会影响性能。)
此外,在处理不受信任的(第三方)PNG图像时,沙盒和多进程体系结构可以提供额外的深度防御。
在上一节描述的三步优化技术也可用来给现有的libpng、Go/Rust PNG库等打补丁。
然后就有网友说这样一来Wuffs还是不是最快的就难说了……但开发者表示至少在安全性方面,Wuffs No.1没得说。
![最快的PNG图像解码器!速度提升2.75倍,比老大哥libpng还安全](https://s3.51cto.com/oss/202104/13/aad300aacbc1d9731b8866b69ef3179f.jpg)
最后,Wuffs版本0.3.0-beta.1刚刚发布,但从目前的功能来看,它还不支持颜色空间或伽马校正。
相关文章
- Vue 创建项目及目录介绍
- Vue组件之动态组件
- Vue组件插槽的使用
- 自定义事件子组件与父组件通信
- Vue 父子组件通信传值(子组件中使用父组件中的数据)
- JavaScript获取每个月的天数
- 用vue写一个日历插件
- 前端面经(2)
- css盒子可控大小-resize
- Vue组件的data必须是一个函数、单个根元素、局部组件
- Vue 组件介绍及使用
- vue.js客服系统实时聊天项目开发(十七)解决url get传参后进行base64解密问题
- vue.js客服系统实时聊天项目开发(二十)vue项目框架目录结构
- vue.js客服系统实时聊天项目开发(二十二)vue项目中router.js路由介绍
- 网站在线客服系统实时语音视频聊天实战开发,判断MediaStream对象是视频流还是音频流
- CSS 实现水平和垂直居中的三种方法
- vue 获取 DOM 元素的方法
- vue3如何获取绑定在组件上的 textarea DOM元素
- vite中导入基础样式文件,以供在全局下直接使用全局 less 变量
- vue嵌套路由子路由 path 注意