可移植网络图形(PNG)规范(第三版)

W3C 推荐标准

关于本文档的更多信息
本版本:
https://www.w3.org/TR/2025/REC-png-3-20250624/
最新发布版本:
https://www.w3.org/TR/png-3/
最新编辑草案:
https://w3c.github.io/png/
历史记录:
https://www.w3.org/standards/history/png-3/
提交历史
实现报告:
https://w3c.github.io/png/Implementation_Report_3e/
编辑:
Chris Blume (W3C 受邀专家)
(MovieLabs)
Chris Lilley (W3C)
Chris Needham
Leonard Rosenthol (Adobe公司)
Chris Arley Seeger (NBCUniversal有限责任公司(康卡斯特公司子公司))
Simon Thompson (英国广播公司)
Cosmin Truta (W3C 受邀专家)
前任编辑:
Thomas Boutell
Adam M. Costello
David Duce
Tom Lane
Glenn Randers-Pehrson
作者:
Mark Adler
Thomas Boutell
Christian Brunschen
Adam M. Costello
Lee Daniel Crocker
Andreas Dilger
Oliver Fromme
Jean-loup Gailly
Phil Harvey
Chris Herborth
Alex Jakulin
Neal Kettler
Tom Lane
Alexander Lehmann
Chris Lilley (W3C)
Dave Martindale
Owen Mortensen
Stuart Parmenter
Keith S. Pickens
Robert P. Poole
Glenn Randers-Pehrson
Greg Roelofs
Willem van Schaik
Guy Schalnat
Paul Schmidt
Andrew Smith
Michael Stokes
Vladimir Vukicevic
Tim Wegner
Jeremy Wohl
反馈:
GitHub w3c/png (拉取请求, 新建议, 开放议题)
public-png@w3.org 邮件主题请使用 [png-3] … 消息主题 … (邮件存档)
勘误:
https://www.w3.org/2025/06/REC-PNG-20250624-errata

另见 翻译版本


摘要

本文档描述了 PNG(可移植网络图形),一种可扩展的文件格式,用于无损、可移植、高压缩效率地存储静态和动画光栅图像。PNG 提供了无专利的 GIF 替代方案,也可以替代许多常见的 TIFF 用途。支持索引色灰度真彩色图像,以及可选的 alpha 通道。采样深度范围为 1 至 16 位。

PNG 专为在线浏览应用(如万维网)设计,因此完全支持流式传输,并带有渐进式显示选项。PNG 具有很强的鲁棒性,提供完整的文件完整性校验以及常见传输错误的简单检测。同时,PNG 可以存储色彩空间数据,以提升异构平台上的色彩匹配效果。

本规范定义了两种互联网媒体类型:image/png 和 image/apng。

本文档状态

本节描述了本文档发布时的状态。当前 W3C 发布的文档及本技术报告的最新修订版可在 W3C 标准与草案索引(https://www.w3.org/TR/)中找到。

本规范旨在成为国际标准,但目前尚未成为国际标准。引用本规范为国际标准并不合适。

本文档由可移植网络图形(PNG)工作组作为推荐标准,并通过推荐流程发布。

W3C 推荐标准是在广泛共识基础上,由 W3C 及其成员认可的规范,并且工作组成员承诺为实现提供免版税许可

W3C 推荐将本规范广泛部署为 Web 的标准。

本文档由遵循 W3C 专利政策的工作组制定。 W3C 维护一份 与工作组成果相关的专利公开公开列表; 该页面还包含专利披露说明。任何个人如实际知晓某项专利且认为其包含 必要权利要求, 必须按照 W3C 专利政策第6节进行披露。

本文档受 2023年11月3日 W3C流程文档管理。

1. 简介

本规范的设计目标如下:

  1. 可移植性:编码、解码和传输应与软件和硬件平台无关。
  2. 完整性:应能够表示真彩色索引色灰度图像,并且每种情况都可以选择透明度、色彩空间信息以及如文本注释等辅助信息。
  3. 串行编码与解码:应能串行地产生和读取数据流,使数据流格式可用于通过串行通信通道动态生成和显示图像。
  4. 渐进式展现:应当能够传输数据流,使得最初可以显示整幅图的大致效果,并随着数据流的接收逐步增强。
  5. 对传输错误的鲁棒性:应能够可靠地检测数据流传输错误。
  6. 无损性:滤波和压缩应保留所有信息。
  7. 性能:任何滤波、压缩和渐进式图像展现应以高效解码和显示为目标。快速编码不是首要目标,解码速度更为重要。可牺牲编码速度以提高解码速度。
  8. 压缩:图像应在满足其他设计目标的前提下有效压缩。
  9. 简洁性:开发者应能够轻松实现该标准。
  10. 互操作性:任何符合标准的 PNG 解码器都应能读取所有符合标准的 PNG 数据流。
  11. 灵活性:应允许未来扩展和私有扩展,同时不影响标准 PNG 数据流的互操作性。
  12. 无法律限制:不应使用非自由可用的算法。

2. 范围

本规范规定了一种数据流及其相关文件格式——可移植网络图形(PNG,发音“ping”),用于无损、可移植、压缩的单幅计算机图像或基于帧的动画,在互联网上进行传输。

3. 术语、定义与缩略语

为本规范起见,采用如下定义。

字节(byte)
八位字节(octet)
8 位二进制整数,取值范围 [0, 255],最高有效位为第 7 位,最低有效位为第 0 位。
字节序
多字节数据值的字节排列顺序。
色度(chromaticity)
在 [COLORIMETRY] 指定的 xyY 空间中的 xy 一对值。

色度是颜色质量的一种度量,与其亮度无关。

合成(动词 composite)
通过合并前景图像和背景图像并利用透明度信息确定背景应显示的位置及程度,形成一幅图像。

前景图像被称为已合成到背景之上。

数据流(datastream)
字节组成的序列。
deflate
LZ77 压缩方法家族成员。

来源:[RFC1951]

帧(frame)
对于静态 PNG,静态图像 被视为第一帧(也是唯一一帧)。 对于动画 PNG,每个组成基于帧的动画序列的图像都是一帧。 因此,对于动画 PNG,当静态图像不是第一帧时,静态图像不被视为一帧。
帧缓冲区(frame buffer)
大多数类型计算机显示器用于显示图像的最终数字存储区域。

软件通过将图像加载到帧缓冲区来实现屏幕显示。

全透明黑(fully transparent black)
红、绿、蓝和 alpha 分量均为零的像素。
伽玛值(gamma value)
伽玛传递函数的指数值。
伽玛(gamma)
幂律传递函数
高动态范围(HDR
一种能够存储动态范围较高(接近或超过人眼瞬时动态范围,约 12-14 级(stop))的图像格式。PNG 支持两种HDR格式,HLGPQ [ITU-R-BT.2100]。
混合对数伽玛(HLG
[ITU-R-BT.2100] 表 5 所定义的传递函数。(一种相对场景参考系统。)
全范围图像(full-range image)
参考黑和白分别对应采样值 02bit depth - 1 的图像。
图像数据(image data)
图像中的一维扫描线数组。
隔行 PNG 图像(interlaced PNG image)
通过通道提取,由PNG 图像生成的一系列缩减图像
无损(lossless)
允许完全按位重建原始数据的数据压缩方法。
亮度(luminance)
可见光强度的客观测量,考虑了人眼对不同波长的敏感度。

亮度和色度共同完全定义了一种测量颜色。正式定义见 [COLORIMETRY]。

LZ77
见 [Ziv-Lempel] 所述的数据压缩算法。
窄范围图像(narrow-range image)
参考黑和白不分别对应采样值 02bit depth - 1 的图像。
网络字节序(network byte order)
字节序,最高有效字节(MSB)在前,然后是次高有效字节,依次递减(例如,二字节整数为 MSB LSB,四字节整数为 MSB B2 B1 LSB)。
感知量化器(PQ
传递函数,定义见 [ITU-R-BT.2100] 表 4。(一种绝对显示参考系统。)

PNG 只支持 RGB,不支持 ICtCp。

PNG 解码器
PNG 数据流重建参考图像并生成对应输出图像的过程或设备。
PNG 编辑器
修改现有PNG 数据流的过程或设备,尽可能保留未修改的辅助信息,并遵循排序规则,即使对于未知块类型也同样适用。
PNG 编码器
源图像构建参考图像,并生成表示该参考图像的PNG 数据流的过程或设备。
PNG 文件
以文件形式存储的PNG 数据流
PNG 四字节无符号整数

范围为 0 到 231-1 的四字节无符号整数。

此限制是为了适应难以处理无符号四字节值的编程语言。

PNG 两字节无符号整数

以网络字节序存储的两字节无符号整数。

采样值(sample)
图像中通道像素的交点。
采样深度(sample depth)
表示采样值所用的比特数。
扫描线(scanline)
图像或隔行 PNG 图像中的一行像素
标准动态范围(SDR
能够存储动态范围较低(5-8 )的图像格式。例如 [SRGB]、 [Display-P3]、[ITU-R-BT.709]。

标准动态范围与主色度无关,也即与色域无关。PNG 支持广色域SDR格式。

级(stop)
场景亮度变化一倍(二倍)的单位。
传递函数(transfer function)
描述图像亮度与采样值之间关系的函数。
白点(white point)
计算机显示设备名义白色值的色度
zlib

deflate 风格的压缩方法。

来源:[rfc1950]

也指包含该方法示例实现的库的名称。

循环冗余校验码(Cyclic Redundancy Code)
CRC

检测大多数传输错误的一种校验值类型。

解码器为接收数据计算 CRC 并与编码器计算并追加到数据后的 CRC 比较。不匹配表示数据或 CRC 在传输中已损坏。

阴极射线管(Cathode Ray Tube)
CRT
一种真空管,内含一个或多个电子枪,通过操控电子束在荧光屏上显示图像。
电光传递函数(Electro-Optical Transfer Function)
EOTF
电或数字域与光能量之间的传递函数。它定义了显示器对于给定输入信号发射的光量。
最低有效字节(Least Significant Byte)
LSB
字节值中的最低有效字节。
最高有效字节(Most Significant Byte)
MSB
字节值中的最高有效字节。
光电传递函数(Opto-Electrical Transfer Function)
OETF
光能量与电或数字域之间的传递函数。它定义了场景中产生某一输出信号所需的光量。

4. 基本概念

4.1 静态与动画图像

所有 PNG 图像都包含一个静态图像

某些 PNG 图像——称为动画 PNGAPNG)——还包含一个基于帧的动画序列,即动画图像。其第一帧可以是(但不一定是)静态图像。不支持动画的显示设备(如打印机)将显示静态图像,而非动画序列。

静态图像以及动画图像的每个独立帧,都对应一个参考图像,并以PNG 图像的形式存储。

4.2 图像

本规范规定了 PNG 数据流,并对生成 PNG 数据流的 PNG 编码器、解释 PNG 数据流的 PNG 解码器以及将一个 PNG 数据流转换为另一个的PNG 编辑器提出了一些要求。它不规定应用与 PNG 编码器、解码器或编辑器之间的接口。并未规定图像呈现给编码器或由解码器输出的精确形式。图像区分为四类。

源图像(Source image)
源图像是呈现给 PNG 编码器的图像。
参考图像(Reference image)
参考图像仅在概念上存在,是一个由矩形像素构成的矩形数组,所有像素具有相同的宽和高,并且都包含相同数量的无符号整数采样值,或为三个(红、绿、蓝),或为四个(红、绿、蓝、alpha)。某一类(红、绿、蓝或 alpha)的所有采样值构成的数组称为 通道。每个通道的采样深度范围为 1 至 16,即该通道中每个采样所使用的位数。不同通道可具有不同的采样深度。红、绿和蓝采样决定像素颜色的红、绿、蓝分量强度;若它们全为零,则像素为黑色;若它们都取最大值(2sampledepth-1),则像素为白色。alpha采样决定像素的不透明度,零表示完全透明,最大值表示完全不透明。在三通道参考图像中,所有像素完全不透明。(四通道参考图像也可能所有像素完全不透明;不同在于后者具有特定的 alpha 采样深度,而前者没有。)每一水平像素行称为一条扫描线。每条扫描线内像素从左到右排序,扫描线从上到下排序。每个参考图像都可以被PNG 数据流精确表示,且每个PNG 数据流都可以转换为一个参考图像。PNG 编码器可以将源图像直接转换为 PNG 图像,但从概念上讲,它首先将源图像转换为参考图像,然后将参考图像转换为 PNG 图像。根据源图像类型,从源图像到参考图像的转换可能需要信息损失。该转换超出本国际标准的范围。然而,参考图像总能从 PNG 数据流精确恢复。
PNG 图像(PNG image)
PNG 图像由参考图像经过一系列转换获得:Alpha 分离索引RGB 合并Alpha 压缩以及采样深度缩放。定义了五种 PNG 图像类型(见6.1 颜色类型与取值)。(如果 PNG 编码器确实将源图像直接转换为 PNG 图像,且源图像格式已与 PNG 图像格式相似,编码器可能无需执行其中某些转换。)尽管 PNG 图像并未明确支持 1 至 16 位范围内的所有采样深度,但可记录参考图像中每个通道的有效位数。PNG 图像中的所有通道具有相同的采样深度。PNG 编码器从 PNG 图像生成 PNG 数据流。PNG 解码器读取 PNG 数据流并重建 PNG 图像。
输出图像(Delivered image)
输出图像由解码 PNG 数据流得到的 PNG 图像构建而成。未对输出图像规定具体格式。查看器应尽可能以接近原始源图像外观的方式向用户呈现图像。

四类图像之间的关系如1所示。

1 源图像、参考图像、PNG 图像与显示图像之间的关系

采样值、通道、像素与采样深度之间的关系如2所示。

2 采样值、采样深度、像素与通道之间的关系

4.3 色彩空间

颜色采样所处的 RGB 色彩空间可通过以下四种方式之一指定:

  1. 通过 CICP 图像格式信令元数据;
  2. 通过 ICC 配置文件;
  3. 当采样符合该色彩空间时,明确指定色彩空间为 sRGB;
  4. 通过指定伽玛值以及图像中所用红、绿、蓝三基色的 1931 CIE x,y 色度,并指定参考白点

对于高端应用,前两种方法提供了最大的灵活性与可控性。第三种方法可指示一种特定但极为常见的色彩空间。第四种方法在 ICC 配置文件被广泛采用之前已标准化,能精确指定 RGB 数据的色度以及应应用的伽玛校正(见C. 伽玛与色度)。然而,具有色彩管理的应用更倾向于前三种方法之一,而无色彩管理的应用通常会忽略全部四种方法。

1列出了提供色彩空间信息的块类型及其对应的优先级编号。若单个图像同时包含多种此类块类型,则应以优先级编号最低的块为准,忽略编号更高的块类型。

1 颜色块优先级
块类型 优先级
cICP 1
iCCP 2
sRGB 3
cHRMgAMA 4

伽玛校正不适用于(若存在的)alpha 通道。Alpha 采样始终为全范围,表示相对于完全不透明的线性比例。

还可以提供母版制作相关的元数据。

4.4 参考图像到 PNG 图像的转换

简介

为生成将被编码的 PNG 图像,需要对参考图像应用若干转换(见3)。转换按以下顺序进行,方括号表示该转换为可选:

[Alpha 分离]
索引 或 ( [RGB 合并] [Alpha 压缩] )
采样深度缩放

当每个像素非完全透明即完全不透明时,Alpha 分离Alpha 压缩索引转换可能导致恢复的参考图像的 alpha 采样深度不同于原参考图像,或不再具有 alpha 通道。这不会影响任何像素的不透明程度。两者被视为等效参考图像,这些转换被视为无损。若编码器希望保留 alpha 采样深度,可选择不执行会改变 alpha 采样深度的转换。

3 参考图像到 PNG 图像的转换

4.4.1 Alpha 分离

若参考图像中的所有 alpha 采样均为最大值,则可省略 alpha 通道,从而得到一个等效图像,并可更紧凑地编码。

4.4.2 索引

如果不同像素值的数量不超过 256,且 RGB 采样深度不大于 8,并且 alpha 通道不存在或恰为 8 位,或每个像素非完全透明即完全不透明,那么通过索引转换得到的替代索引色表示,可能更高效地进行编码。 在索引色表示中,每个像素被一个调色板索引取代。调色板 是一个条目列表,每个条目包含三个 8 位采样值(红、绿、蓝)。如果存在 alpha 通道,还存在一个并行的 8 位 alpha 采样表,称为alpha 表

4 索引色图像

即使 PNG 图像不是索引色,也可以构建建议的调色板,以帮助那些只能显示有限颜色数量的查看器。

对于索引色图像,编码器可以重新排列调色板,使具有最大 alpha 值的表项分组到末尾。在这种情况下,表可以以缩短的形式编码,不包含这些表项。

创建索引色 PNG 的编码器不得插入大于调色板表实际长度的索引值;这样做是错误的,不同解码器对该错误的处理会有所不同。

4.4.3 RGB 合并

若红、绿、蓝通道具有相同的采样深度,且对于每个像素,红、绿、蓝采样值都相等,则可将这三条通道合并为单条灰度通道。

4.4.4 Alpha 压缩

对于非索引图像,如果存在某个 RGB(或灰度)值,使得所有具有该值的像素完全透明,而所有其他像素完全不透明,则可仅通过标识该透明的 RGB(或灰度)值来更紧凑地表示 alpha 通道。

4.4.5 采样深度缩放

在 PNG 图像中,并非所有采样深度都受支持(见6.1 颜色类型与取值),并且所有通道应具有相同的采样深度。PNG 图像的所有通道使用不小于参考图像中任何采样深度的、最小的允许采样深度,并将参考图像中的可能采样值线性映射到 PNG 图像的下一允许范围。5展示了如何将深度为 3 的采样映射到深度为 4 的采样。

5 采样值缩放

仅允许少数采样深度可减少解码器需要处理的情况。采样深度缩放是可逆且无损的,因为可在 PNG 数据流中记录参考图像的采样深度。如果未记录采样深度,则参考图像的采样深度等于 PNG 图像的采样深度。参见12.4 采样深度缩放13.12 采样深度重缩放

6 可能的 PNG 图像像素类型

4.5 PNG 图像

参考图像的转换会得到五种 PNG 图像类型之一(见6):

真彩色(含 alpha)
每个像素由四个采样组成:红、绿、蓝和alpha
灰度(含 alpha)
每个像素由两个采样组成:一个灰度采样和一个alpha采样。
真彩色
每个像素由三个采样组成:红、绿、蓝。可选的 alpha 通道可以作为单个红、绿、蓝采样三元组来指定:图像中其红、绿、蓝采样与 alpha 通道的红、绿、蓝采样完全相同的像素为完全透明;其他像素为完全不透明。若不存在 alpha 通道,所有像素完全不透明。
灰度
每个像素由单个灰度采样构成,表示整体亮度(从黑到白)。可选的 alpha 通道可以作为单个灰度采样来指定:图像中其灰度采样与 alpha 通道的灰度采样完全相同的像素为完全透明;其他像素为完全不透明。若不存在 alpha 通道,所有像素完全不透明。
索引色
每个像素由调色板索引组成(若存在,还包括关联的 alpha 值表中的索引)。

每个像素的格式取决于 PNG 图像类型和位深。对于索引色之外的 PNG 图像类型,位深指定的是每个采样所占的位数,而不是每个像素的总位数。对于索引色图像,位深指定的是每个调色板索引的位数,而不是调色板或 alpha 表中颜色的采样深度。像素内采样的出现顺序取决于 PNG 图像类型,如下所示。

  1. 真彩色(含 alpha):红、绿、蓝、alpha。
  2. 灰度(含 alpha):灰度、alpha。
  3. 真彩色:红、绿、蓝。
  4. 灰度:灰度。
  5. 索引色:调色板索引。

4.6 PNG 图像编码

简介

PNG 图像编码过程的概念模型见7。这些步骤指的是对 PNG 图像中像素或索引数组的操作。调色板alpha 表不以这种方式编码。

  1. 通道提取:为支持渐进显示,可将 PNG 图像像素重排为多个较小图像,称为缩减图像或轮次(pass)。
  2. 扫描线序列化:按扫描线对图像进行序列化。像素在扫描线中从左到右排序,扫描线从上到下排序。
  3. 滤波:将每条扫描线使用定义的某种滤波类型转换为滤波后的扫描线,以为图像压缩做准备。
  4. 压缩:对图像中的所有滤波后的扫描线进行压缩。
  5. 分块:将压缩后的图像划分为易于处理的块。每个块都添加错误检测码。
  6. 数据流构建:将这些块插入数据流。

4.6.1 通道提取

通道提取(见7)将一幅 PNG 图像拆分为一系列缩减图像,第一幅提供粗略视图,随后的图像逐步增强该视图,直至最后一幅完成 PNG 图像。缩减图像集合也称为隔行 PNG 图像。本规范定义了两种隔行方法。第一种为空方法;像素按从左到右、扫描线按从上到下顺序存储。第二种通过对图像进行多次扫描,生成包含七幅缩减图像的序列。样例图像的七个轮次见7。参见8. 隔行与通道提取

7 PNG 图像编码
8 通道提取

4.6.2 扫描线序列化

每一行像素(称为扫描线)以字节序列的形式表示。

4.6.3 滤波

PNG 允许在压缩前对图像数据进行滤波。滤波可改善数据的可压缩性。滤波操作是确定性的、可逆的、无损的。这允许在解压缩后进行反向滤波以获得原始数据。参见7.3 滤波

4.6.4 压缩

PNG 图像一个或多个轮次中的滤波扫描线序列,会通过定义的压缩方法之一进行压缩(见9)。连接起来的滤波扫描线形成压缩阶段的输入。压缩阶段的输出是单个压缩数据流。参见10. 压缩

4.6.5 分块

分块将压缩后的数据流便捷地拆分为可管理的块(见9)。每个块都有其自身的冗余校验。参见11. 块规范

9 压缩与分块

4.7 附加信息

图像可以关联辅助信息。解码器可忽略全部或部分辅助信息。提供的辅助信息类型如2所述。

2 辅助信息类型
信息类型 说明
动画信息 动画图像,定义为由帧序列构成并带有关联的计时、位置与处理信息,若查看器具备能力则应显示。在其他情况(如打印机)下,将显示静态图像
背景色 当没有更合适的选项时,用于呈现图像的纯色背景。
编码无关代码点 通过枚举诸如传递函数与三基色等元数据来标识色彩空间。 最初用于SDRHDR视频,也用于静态与动画图像。
内容光等级信息 图像(或图像序列)中最亮像素的亮度,以及序列中最亮帧的平均亮度水平。
EXIF 信息 可交换图像文件格式元数据,如快门速度、光圈与方向等。
伽玛与色度 图像相对于期望输出强度的伽玛值,以及图像所用 RGB 值的色度特性。
ICC 配置文件 描述图像中采样所遵循的色彩空间(以国际色彩联盟(ICC)配置文件的形式)。
图像直方图 估计图像对每个调色板项的使用频率。
母版显示色彩体积 描述用于制作内容的显示器的绝对三维色域体积,包括母版显示器可复现的最亮与最暗颜色。这有助于在显示设备上呈现图像。
物理像素尺寸 呈现 PNG 图像时使用的像素尺寸与纵横比。
有效位数 采样值中有效位的数量。
sRGB 色彩空间 一种渲染意图(由国际色彩联盟定义)以及图像采样符合该色彩空间的指示。
建议调色板 在显示设备无法显示图像完整色域时可使用的缩减调色板。
文本数据 与图像关联的文本信息(可被压缩)。
时间 PNG 图像上次修改的时间。
透明度 当 PNG 图像不保留 alpha 通道时,允许重建参考图像的 alpha 信息。

4.8 PNG 数据流

4.8.1

PNG 数据流由 PNG 签名(见5.2 PNG 签名)后接一串块(见11. 块规范)组成。每个块有其块类型以指明其功能。

4.8.2 块类型

块类型是四字节序列,选择时使其在 ISO 646.IRV:1991 [ISO646] 字符集下可对应为可读标签。前四种称为关键块,必须根据本规范的规定被理解并正确解释。这些是:

  1. IHDR:图像头,是 PNG 数据流中的第一个块。
  2. PLTE:与索引 PNG 图像相关的调色板表。
  3. IDAT:图像数据块。
  4. IEND:图像终结块,是 PNG 数据流中的最后一个块。

其余块类型称为辅助块类型,编码器可以生成,解码器可以解释。

  1. 透明度信息:tRNS(见11.3.1 透明信息)。
  2. 色彩空间信息:cHRMgAMAiCCPsBITsRGBcICPmDCV(见 11.3.2 色彩空间信息)。
  3. 文本信息:iTXttEXtzTXt(见11.3.3 文本信息)。
  4. 杂项信息:bKGDhISTpHYssPLTeXIf(见11.3.4 杂项信息)。
  5. 时间信息:tIME(见11.3.5 时间戳信息)。
  6. 动画信息:acTLfcTLfdAT(见11.3.6 动画信息)。

4.9 APNG:基于帧的动画

简介

动画 PNG(APNG)在原始仅静态的 PNG 格式基础上扩展,增加了对基于的动画图像的支持。它旨在替代传统上使用 GIF 格式 [GIF] 的简单动画图像,同时增加对 24 位图像和 8 位透明度的支持,而 GIF 不具备这些。

APNG与早期版本的 PNG 向后兼容;非动画的 PNG 解码器将忽略与APNG相关的辅助块,并显示静态图像

4.9.1 结构

APNG流是按照先前 PNG 规范版本定义的普通 PNG 流,并增加了三个描述动画并提供额外帧数据的块类型。

要被识别为APNG,流中必须在任一IDAT块之前出现一个acTL块。acTL结构如下所述

从概念上讲,每次播放开始时,输出缓冲区应完全初始化为一个全透明黑矩形,其宽、高来自IHDR块。

若在IDAT之前存在单个fcTL块,则可将静态图像作为动画的第一帧包含在内。否则,静态图像不属于动画的一部分。

后续帧编码在fdAT块中,其结构与IDAT块相同,但在前面增加了一个序列号。每个帧的放置与渲染信息存储在fcTL块中。fdATfcTL块的完整布局如下所述

整个动画的边界由IHDR块的宽与高参数指定,无论默认图像是否属于动画。若后续帧需要额外空间,默认图像应使用全透明黑像素进行适当填充。

每一帧在每次播放时都是相同的,因此应用缓存这些帧是安全的。

4.9.2 序列号

fcTLfdAT块具有从零开始的 4 字节序列号。两种块类型共享该序列号。该编号用于在动画 PNG 中检测(并可选地纠正)序列错误,因为本规范未对辅助块施加排序约束。

第一个fcTL块应包含序列号 0,剩余fcTLfdAT块的序列号应按升序排列,不得有缺失或重复。

下表展示了对于多帧图像以及第二帧包含多个fdAT块时序列号的使用。(为清晰起见,表中省略了IHDRIEND块)。

3 当静态图像同时为第一帧时
序列号
(无) acTL
0 fcTL 第一帧
(无) IDAT 第一帧 / 静态图像
1 fcTL 第二帧
2 第二帧的第一个 fdAT
3 第二帧的第二个 fdAT
4 当静态图像不是动画的一部分时
序列号
(无) acTL
(无) IDAT 静态图像
0 fcTL 第一帧
1 第一帧的第一个 fdAT
2 第一帧的第二个 fdAT
3 fcTL 第二帧
4 第二帧的第一个 fdAT
5 第二帧的第二个 fdAT

4.9.3 输出缓冲区

输出缓冲区是一个像素数组,其尺寸由 PNG IHDR块的宽与高参数指定。从概念上讲,每一帧都会先在输出缓冲区中构建,然后再合成画布上。输出缓冲区的内容对解码器可用。输出缓冲区的四个角映射到画布的四个角。

4.9.4 画布

画布是输出设备上用于显示帧的区域。画布的内容不一定对解码器可用。若存在bKGD块,且没有更合适的背景,可用其填充画布。

4.10 错误处理

PNG 数据流中的错误大致分为两类:

  1. 传输错误或计算机文件系统损坏,往往会破坏数据流的大部分或全部内容;
  2. 语法错误,表现为块中的无效值,或缺失、放错位置的块。语法错误不仅可能由编码错误引起,也可能由使用注册或私有值而解码器不识别这些值所致。

PNG 解码器应尽早检测错误,尽可能从错误中恢复,否则应优雅失败。错误处理理念详见13.1 错误处理

4.11 扩展

本节为非规范性内容。

PNG 格式提供了多个扩展点:

其中一些扩展点由W3C保留,其他则可供私有使用。

5. 数据流结构

5.1 PNG 数据流

PNG 数据流 由一个 PNG 签名后接一系列块组成。它是对PNG 图像编码的结果。

使用“数据流(datastream)”这一术语而非“文件(file)”,是为了描述可能只是文件一部分的字节序列。该术语也用来强调这些字节序列可能是“即时”生成与消费的,完全不会以存储文件的形式出现。

5.2 PNG 签名

PNG 数据流的前 8 个字节始终包含以下十六进制值:


89 50 4E 47 0D 0A 1A 0A

该签名表明数据流的其余部分包含一个单一的 PNG 图像,由一系列块组成,以IHDR块开始,以IEND块结束。

该签名可将 PNG 数据流与其他类型的数据流区分开来,并允许及早检测某些传输错误。

5.3 块布局

每个块(chunk)由三个或四个字段组成(见10)。各字段含义见 5。块数据字段可以为空。

10 块组成部分
5 块字段
名称 说明
Length(长度) 一个PNG 四字节无符号整数,给出块数据字段中的字节数。长度计算数据字段,包括自身、块类型或 CRC。长度为零也是有效的。尽管编码器和解码器应将长度视为无符号整数,其值不得超过 231-1 字节。
Chunk Type(块类型) 用四个字节表示的块类型。块类型的每个字节仅限于十六进制值 41 到 5A 和 61 到 7A。这些分别对应 ISO 646 [ISO646] 的大写和小写字母 (A-Za-z),以便于描述和检查 PNG 数据流。编码器与解码器应将块类型视为固定的二进制值,而不是字符字符串。例如,用 UCS 2 字符集中的这些字母的等价物来表示块类型IDAT是不正确的。关于块类型的更多命名约定见5.4 块命名约定
Chunk Data(块数据) 与块类型相对应的数据字节(如果有)。 该字段可以为零长度。
CRC 一个四字节的CRC,在块中先前的字节上计算,包括块类型字段和块数据字段,但包括长度字段。CRC可用于检查数据是否损坏。即使块不包含数据,CRC也始终存在。参见5.5 CRC 算法

块数据长度可以是任意不超过最大值的字节数;因此,实现者不能假定块在大于字节的任何边界上对齐。

5.4 块命名约定

当按 ISO 646 字母 [ISO646] 解释块类型的字节时,块类型应是有意义的名称。块类型的分配使得解码器即使在不识别该类型时也能判断出块的一些属性。这些规则允许对 PNG 格式进行安全、灵活的扩展,因为它允许 PNG 解码器在遇到未知块时决定如何处理。

当解码器不识别块类型时(见 13. PNG 解码器与查看器),命名规则通常才会引起兴趣。

块类型的四个位——属性位,即每个字节的第 5 位(值 32)——用于传达块属性。这一选择意味着人们可以根据块类型每个字节对应的字母是大写(第 5 位为 0)还是小写(第 5 位为 1)来读取已分配的属性。

属性位是块类型的内在组成部分,因此对于任何块类型都是固定的。因此, CHNKcHNk 将是无关的块类型,而不是同一块具有不同属性。

属性位的语义见6

6 属性位的语义
名称与位置 定义 说明
辅助位:第一个字节 0(大写)= 关键(critical),
1(小写)= 辅助(ancillary)。
关键块对于成功显示数据流内容是必要的,例如图像头块(IHDR)。解码器在尝试提取图像时,如遇到未知块类型且其辅助位为 0,应向用户指示图像包含其无法安全解释的信息。
辅助块并非为了有意义地显示数据流内容而严格必需,例如时间块(tIME)。解码器在遇到未知块类型且其辅助位为 1 时,可以安全地忽略该块并继续显示图像。
私有位:第二个字节 0(大写)= 公有(public),
1(小写)= 私有(private)。
公有块保留由W3C定义。私有块的定义见12.10.1 私有块的使用。私有块名称的第二个字母为小写,而公有块名称的第二个字母为大写。
保留位:第三个字节 在本版本 PNG 中为 0(大写)。
如果保留位为 1,则数据流不符合本版本 PNG。
块名第三个字母大小写的意义被保留以便未来扩展。在本国际标准中,所有块名的第三个字母均应为大写。
可安全复制位:第四个字节 0(大写)= 不可安全复制,
1(小写)= 可安全复制。
该属性位对纯解码器而言并不重要,但对PNG 编辑器是必需的。该位定义了在修改中的数据流内未识别块的正确处理方式。关于PNG 编辑器的规则详见14.2 PNG 编辑器的行为

假设的块类型“cHNk”具有如下属性位:

cHNk  <-- 以文本形式表示的 32 位块类型
||||
|||+- 可安全复制位为 1(小写字母;位 51)
||+-- 保留位为 0     (大写字母;位 50)
|+--- 私有位为 0      (大写字母;位 50)
+---- 辅助位为 1    (小写字母;位 51

因此,该名称表示一个辅助、公有、可安全复制的块。

5.5 CRC 算法

CRC 字段使用标准化的、带有预处理与后处理的 CRC 方法计算,如 [ISO-3309] 与 [ITU-T-V.42] 所定义。所采用的 CRC 多项式——与 GZIP 文件格式规范 [RFC1952] 中使用的相同——为

x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1

在 PNG 中,32 位 CRC 以全 1 初始化,然后按从最低有效位(1)到最高有效位(128)的顺序处理每个字节中的数据。在处理完所有数据字节后,CRC 取反(取其反码)。该值以MSB(最高有效字节)优先的顺序传输(存储在数据流中)。为便于分解为字节与排序,32 位 CRC 的最低有效位被定义为 x31 项的系数。

实际计算 CRC 时常使用预计算表来加速计算。参见D. CRC 示例实现

5.6 块排序

各个块的位置约束列于7,并通过图示展示:静态图像见1112;静态图像作为第一帧的动画图像见1314;静态图像不属于动画的动画图像见1516。这些格状图表示本规范对位置施加的约束。图中的线定义了偏序关系。更上方的块必须出现在更下方的块之前。水平方向对齐且位于两个其他块类型(高于与低于这组水平对齐块)之间的块,可以以任意顺序出现在这两类更高与更低的块类型之间。与块类型相关联的上标在8中定义,表示该块是必选、可选或可出现多次。两种块类型之间的竖线表示二者为可选关系(择一)。

7 块排序规则
关键块
(必须按此顺序出现,PLTE 为可选)
块名 可多次出现 排序约束
IHDR 必须为首个
PLTE 在第一个 IDAT 之前
IDAT 多个 IDAT 块必须连续
IEND 必须为最后一个
辅助块
(不必按此顺序出现)
块名 可多次出现 排序约束
acTL IDAT 之前
cHRM PLTEIDAT 之前
cICP PLTEIDAT 之前
gAMA PLTEIDAT 之前
iCCP PLTEIDAT 之前。若存在 iCCP 块,则不应出现 sRGB 块。
mDCV PLTEIDAT 之前。
cLLI PLTEIDAT 之前。
sBIT PLTEIDAT 之前
sRGB PLTEIDAT 之前。若存在 sRGB 块,则不应出现 iCCP 块。
bKGD PLTE 之后;在 IDAT 之前
hIST PLTE 之后;在 IDAT 之前
tRNS PLTE 之后;在 IDAT 之前
eXIf IDAT 之前
fcTL 可有一个出现在 IDAT 之前;其余均应在 IDAT 之后
pHYs IDAT 之前
sPLT IDAT 之前
fdAT IDAT 之后
tIME
iTXt
tEXt
zTXt
8 格状图中使用符号的含义
符号 含义
+ 一个或多个
1 仅一个
? 零个或一个
* 零个或多个
| 或(备选)
11 格状图:包含 PLTE 的静态 PNG 图像
12 格状图:不包含 PLTE 的静态 PNG 图像
13 格状图:包含 PLTE 的动画 PNG 图像,静态图像作为第一帧
14 格状图:不包含 PLTE 的动画 PNG 图像,静态图像作为第一帧
15 格状图:包含 PLTE 的动画 PNG 图像,静态图像不属于动画
16 格状图:不包含 PLTE 的动画 PNG 图像,静态图像不属于动画

5.7 块定义

5.7.1 通用

所有块(私有与公有)SHOULD 列出于 [PNG-EXTENSIONS]。

5.7.2 公有块的定义

公有块保留由W3C定义。

公有块旨在与 PNG 的理念保持一致并被广泛使用。

鼓励组织与应用提交符合上述标准的任何块,由PNG 工作组定义为公有块。

定义为公有块既非自动也非即时。拟议的公有块类型在被如此定义之前,SHALL 不得用于公开可用的软件或数据流中。

除非必要,不鼓励定义新的关键块类型。

5.7.3 私有块的定义

组织与应用MAY 定义用于私有和实验用途的私有块。

不应仅为了承载与人类用户相关的文本信息而定义私有块,SHOULD NOT。相反,应使用 iTXtSHOULD BE 使用,并且对应的关键字 SHOULD BE 使用并定义合适的关键字。

将私有块列于 [PNG-EXTENSIONS] 可以降低(但不能消除)不同应用将同一私有块用于不兼容目的的可能性。如果使用了某一私有块类型,为进一步降低冲突风险,额外的标识信息SHOULD BE 存储在块数据的开头。

对于所有不绝对必要用于查看图像的信息,SHOULD 使用辅助块类型,而非关键块类型。

不应定义私有关键块,SHOULD NOT,因为包含此类块的 PNG 数据流不可移植,且SHOULD NOT 用于公开可用的软件或数据流。如果应用确实必须使用某个私有关键块,它SHOULD 出现在数据流靠前的位置,以便标准解码器无需读取很远就能发现它无法处理该数据流。

关于定义私有块的更多指南,参见B. 私有块类型指南

5.8 私有字段值

以下字段中大于或等于 128 的取值是私有字段值

这些私有字段值既未被本规范定义,也未被保留。

私有字段值MAY 用于实验性或私有语义。

私有字段值SHOULD NOT 出现在公开可用的软件或数据流中,因为它们可能导致数据流对 PNG 解码器不可读,详见13. PNG 解码器与查看器

6. 参考图像到 PNG 图像的转换

6.1 颜色类型与取值

4.5 PNG 图像所述,PNG 图像共有五种类型。与每种类型相对应的是颜色类型,其值为下列数值之和:1(使用调色板)、2(使用真彩色)与 4(使用 alpha)。灰度真彩色图像可以具有显式的 alpha 通道。PNG 图像类型与对应的颜色类型9

9 PNG 图像类型与颜色类型
PNG 图像类型 颜色类型
灰度 0
真彩色 2
索引色 3
灰度(含 alpha) 4
真彩色(含 alpha) 6

各 PNG 图像类型允许的位深与采样深度见图像头

若指明了传递曲线(通过 gAMAsRGBiCCPcICP),灰度采样表示亮度;否则表示设备相关的灰度。若指明了色彩空间(通过 gAMAcHRMsRGBiCCPcICP),RGB 采样表示经校准的颜色信息;否则表示未校准的设备相关颜色。

采样值不一定与光强度成正比;gAMA 块指明采样值与显示输出强度之间的关系。强烈建议查看器进行适当补偿。参见4.3 色彩空间13.13 解码器伽玛处理C. 伽玛与色度

6.2 Alpha 表示

在 PNG 数据流中,透明度可依据 PNG 图像类型以四种方式之一表示(见4.4.1 Alpha 分离4.4.4 Alpha 压缩)。

  1. 真彩色(含 alpha)灰度(含 alpha):alpha 通道是图像数组的一部分。
  2. 真彩色灰度:一个 tRNS 块包含一个像素值,用于区分完全透明像素与完全不透明像素。
  3. 索引色:一个 tRNS 块包含 alpha 表,为每个调色板条目关联一个 alpha 采样。
  4. 真彩色灰度索引色:不存在 tRNS 块,所有像素完全不透明。

包含于图像数组中的 alpha 通道采用 8 位或 16 位采样,其大小与其他采样相同。每个像素的 alpha 采样紧随该像素的灰度或 RGB 采样之后存储。alpha 值为 0 表示完全透明,值为 2sampledepth - 1 表示完全不透明。中间值表示部分透明像素,可与背景图像进行合成以生成输出图像。

像素中的颜色值不会与分配给该像素的 alpha 值预乘。此规则有时称为“非关联(unassociated)”或“非预乘(non-premultiplied)” alpha。(另一种常见方法是存储被 alpha 值预乘的采样值;实际上,此类图像已相对于黑色背景完成合成。PNG 使用预乘 alpha。因此,图像编辑器可以方便地对 PNG 图像的透明度进行修改。)参见12.3 Alpha 通道创建13.16 Alpha 通道处理

7. 将 PNG 图像编码为 PNG 数据流

7.1 整数与字节序

所有需要多个字节表示的整数均应采用网络字节序(如17所示):最高有效字节在前,随后各字节按重要性递减顺序排列(两字节整数为 MSB LSB,四字节整数为 MSB B2 B1 LSB)。一个字节的最高位(值 128)标号为位 7;最低位(值 1)标号为位 0。除非另有说明,取值均为无符号。明示为有符号的取值采用二进制补码表示。

PNG 四字节无符号整数限定在 0 至 231-1 的范围内,以适应某些难以处理无符号四字节值的语言。

17 PNG 中的整数表示

7.2 扫描线

PNG 图像(或轮次,见8. 隔行与通道提取)是一个矩形像素数组,每条扫描线内像素从左到右排列,扫描线从上到下排列。每个像素的大小由每像素位数决定。

扫描线内的像素始终紧密打包为字节序列,像素之间没有浪费的比特。扫描线总是在字节边界上开始。允许的位深与颜色类型受到限制,以确保在所有情况下打包均简单高效。

颜色类型为 0(灰度)的 PNG 图像中,每个像素是一个采样,精度可以小于一个字节(1、2 或 4 位)。这些采样按字节打包,每字节的高位为该扫描线最左侧的采样,随后是该扫描线的其他采样。

颜色类型为 3(索引色)的 PNG 图像中,每个像素是一个调色板索引。这些索引的打包方式与颜色类型 0 的采样相同。

当每字节包含多个像素时,扫描线最后一个字节的一些低位可能未使用。这些未使用比特的内容未作规定。

索引色的 PNG 图像,其采样值的位深可以为 16。此类采样值采用网络字节序MSB 在前,LSB 在后)。PNG 仅允许在 8 位与 16 位采样时使用多采样像素,因此同一像素的多个采样不会被打包到同一个字节中。

7.3 滤波

滤波方法是一种作用于扫描线数组的变换,旨在提高其可压缩性。

PNG 标准化了一种滤波方法以及若干可用于为图像数据做压缩准备的滤波类型。它将字节序列变换为等长的字节序列,并在前面加上一个滤波类型字节(示例见18)。

对于隔行 PNG 图像,编码器应仅使用单一滤波方法,但可以对缩减图像中的每条扫描线使用不同的滤波类型。智能的编码器可以在相邻扫描线之间切换滤波器。选择使用何种滤波器的方法由编码器自行决定。

滤波类型字节不视为图像数据的一部分,但会被包含在发送至压缩步骤的数据流中。参见9. 滤波

18 序列化与滤波一条扫描线

8. 隔行与通道提取

简介

通道提取(见图 4.8)将一幅 PNG 图像拆分为一系列缩减图像(即隔行 PNG 图像),第一幅给出粗略视图,后续图像逐步增强该视图,直到最后一幅完成整幅 PNG 图像。这使解码器能够对隔行 PNG 图像进行渐进式显示,并允许图像在即时显示时“淡入”。平均而言,隔行会略微增大数据流大小,但可以更快地为用户提供有意义的显示。

8.1 隔行方法

本国际标准定义了两种隔行方法,方法 0 与方法 1。隔行方法的其他取值保留用于未来标准化。

在隔行方法 0(空方法)中,像素按从左到右依次提取,扫描线按从上到下依次提取。隔行 PNG 图像是一幅单一的缩减图像。

隔行方法 1(Adam7)定义了对图像的七个不同轮次。每个轮次传输参考图像中像素的一个子集。每个像素被传输的轮次(编号 1 至 7)通过将以下 8×8 模式在整幅图像上自左上角开始复制来定义:

1 6 4 6 2 6 4 6
7 7 7 7 7 7 7 7
5 6 5 6 5 6 5 6
7 7 7 7 7 7 7 7
3 6 4 6 3 6 4 6
7 7 7 7 7 7 7 7
5 6 5 6 5 6 5 6
7 7 7 7 7 7 7 7

图 4.8展示了隔行方法 1 的七个轮次。在每个轮次内,选定像素在扫描线内自左向右传输,选定扫描线按从上到下顺序传输。例如,轮次 2 包含扫描线 0、8、16 等的像素 4、12、20 等(其中扫描线 0、像素 0 为左上角)。最后一个轮次包含扫描线 1、3、5 等的所有像素。传输顺序的定义确保同一轮次中传输的所有扫描线具有相同的像素数;这对某些滤波器的正确应用是必要的。隔行 PNG 图像由七幅缩减图像构成。例如,若 PNG 图像为 16×16 像素,则第三个轮次将是两条扫描线组成的缩减图像,每条包含四个像素(见图 4.8)。

未能填满整数个字节的扫描线按照7.2 扫描线中的定义进行填充。

如果参考图像的列数少于五列或行数少于五行,某些轮次将为空。

9. 滤波

9.1 滤波方法与滤波类型

滤波会对 PNG 图像进行变换,目标是提升压缩效果。整体流程见7,而对单条扫描线的序列化与滤波细节见18

PNG 允许若干种滤波方法。隔行图像中的所有缩减图像应使用单一滤波方法。本规范仅定义滤波方法 0。其他滤波方法保留供未来标准化使用。滤波方法 0 提供五种滤波类型,每个缩减图像中的各条扫描线可以使用不同的滤波类型。

PNG 对可应用于隔行 PNG 图像的滤波类型不作额外限制。然而,各滤波类型对不同数据的效果并不相同。参见12.7 滤波选择

滤波将扫描线中的字节序列变换为等长的字节序列,并在前面加上滤波类型字节。仅非空扫描线才具有滤波类型字节。空轮次中不包含滤波类型字节。参见13.10 隔行与渐进显示

9.2 滤波方法 0 的滤波类型

无论图像的位深或颜色类型为何,滤波均作用于字节而非像素。滤波在已按7.2 扫描线描述形式表示的扫描线字节序列上进行。若图像包含 alpha 通道,alpha 数据与图像数据以相同方式进行滤波。

滤波器可使用以下字节的原始取值来生成新字节值:

10 命名的滤波字节
名称 定义
x 当前被滤波的字节;
a 位于包含 x 的像素之前那个像素中与 x 对应的字节(当位深小于 8 时,为紧邻 x 之前的字节);
b 上一条扫描线中与 x 对应的字节;
c 位于包含 b 的像素之前那个像素中与 b 对应的字节(当位深小于 8 时,为紧邻 b 之前的字节)。
19 相对于 x 的滤波字节 a、b 与 c 的位置

19展示了字节 xabc 的相对位置。

滤波方法 0 定义的五种基本滤波类型列于11Orig(y) 表示字节 y 的原始(未滤波)值。Filt(y) 表示应用某种滤波类型后的值。Recon(y) 表示应用对应重建函数后的值。Paeth 滤波类型中的 PaethPredictor [Paeth] 定义如下。

滤波方法 0 严格规定为这五种滤波类型,且不得扩展。这样可确保解码器无需解压数据便能判断是否包含不受支持的滤波类型:只需检查滤波方法是否为11.2.1 IHDR 图像头中的方法 0。

11 滤波类型
类型 名称 滤波函数 重建函数
0 None Filt(x) = Orig(x) Recon(x) = Filt(x)
1 Sub Filt(x) = Orig(x) - Orig(a) Recon(x) = Filt(x) + Recon(a)
2 Up Filt(x) = Orig(x) - Orig(b) Recon(x) = Filt(x) + Recon(b)
3 Average Filt(x) = Orig(x) - floor((Orig(a) + Orig(b)) / 2) Recon(x) = Filt(x) + floor((Recon(a) + Recon(b)) / 2)
4 Paeth Filt(x) = Orig(x) - PaethPredictor(Orig(a), Orig(b), Orig(c)) Recon(x) = Filt(x) + PaethPredictor(Recon(a), Recon(b), Recon(c))

对于所有滤波器,扫描线中第一个像素“左侧”的字节应视为 0。对于引用上一条扫描线的滤波器,在缩减图像的第一条扫描线上,上一条扫描线的全部字节以及该扫描线第一个像素“左侧”的字节均应视为 0。

要逆转滤波效果,需要使用同一扫描线中前一像素的解码值、上一条扫描线上当前像素正上方像素的解码值,以及位于上方像素左侧的像素的解码值。

使用 256 模的无符号算术,以确保输入与输出均适合于字节。滤波对每个字节应用,无论位深为何。Filt 值序列作为滤波后的扫描线进行传输。

9.3 滤波类型 3:Average

求和 Orig(a) + Orig(b) 应在无溢出的情况下进行(至少使用九位算术)。floor() 表示若结果为小数,则向下取整为下一个较小的整数;换言之,是整数除法或右移操作。

9.4 滤波类型 4:Paeth

Paeth 滤波类型对三个相邻像素(左、上、左上)的值进行简单线性组合,然后选择与该计算值最接近的相邻像素作为预测值。本规范所用算法源自 Alan W. Paeth 的技术改编自 [Paeth]。

PaethPredictor 函数定义如下代码。该函数的逻辑以及字节 abcx 的位置见20Pr 是字节 x 的预测值。

p = a + b - c
pa = abs(p - a)
pb = abs(p - b)
pc = abs(p - c)
if pa <= pb and pa <= pc then Pr = a
else if pb <= pc then Pr = b
else Pr = c
return Pr
20 PaethPredictor 函数

PaethPredictor 函数中的计算应精确执行,不得产生溢出。

比较的执行顺序至关重要,不得更改。该函数试图确定在三个方向(垂直、水平或对角)中,图像的梯度在哪个方向最小。

编码器与解码器均使用完全相同的 PaethPredictor 函数。

10. 压缩

10.1 压缩方法 0

本国际标准仅定义了 PNG 压缩方法 0。压缩方法的其他取值保留供未来标准化使用。PNG 压缩方法 0 为deflate 压缩,使用的滑动窗口(这是 deflate 流中出现的距离的上界)最大为 32768 字节。Deflate 压缩源自 LZ77

PNG 中的经 deflate 压缩的数据流以 zlib 格式存储,其结构为:

zlib 压缩方法/标志码 1 字节
附加标志/校验位 1 字节
压缩数据块 n 字节
校验值 4 字节

zlib 的规范见 [rfc1950]。

对于 PNG 压缩方法 0,zlib 的压缩方法/标志码应指定方法码 8(deflate 压缩)且 LZ77 窗口大小不超过 32768 字节。zlib 的压缩方法编号与 IHDR 块中的 PNG 压缩方法编号并不相同。附加标志不得指定预置字典。

若待压缩的数据不超过 16384 字节,PNG 编码器可以将窗口大小上取整为 2 的幂(最小为 256)。这将在不不利影响压缩比的情况下减少编码与解码所需内存。

zlib 数据流中的压缩数据以一系列数据块的形式存储,每个数据块可以表示原始(未压缩)数据、使用固定哈夫曼码编码的 LZ77 压缩数据,或使用自定义哈夫曼码编码的 LZ77 压缩数据。最终数据块中的标记位将其标识为最后一个数据块,从而使解码器能够识别压缩数据流的结束。有关压缩算法与编码的更多细节见 deflate 规范 [rfc1951]。

zlib 数据流末尾存储的校验值是基于该数据流所表示的未压缩数据计算的。用于计算该值的算法不同于 PNG 块 CRC 字段值所使用的 CRC 计算。zlib 校验值主要用于交叉检验 deflate 算法是否被正确实现。校验单独的 PNG 块 CRC 能够增强对 PNG 数据流未在传输中损坏的信心。

10.2 滤波后扫描线序列的压缩

对滤波后的扫描线序列进行压缩,所得数据流被拆分为 IDAT 块。所有 IDAT 块内容的串联构成一个 zlib 数据流。该数据流解压缩得到滤波后的图像数据

需要强调的是,IDAT 块之间的边界是任意的,可以落在 zlib 数据流中的任意位置。IDAT 块边界与 deflate 数据块边界或 zlib 数据的任何其他特征之间并无必然关联。例如,终止性的 zlib 校验值完全可能被拆分到不同的 IDAT 块中。

同样,图像数据的结构(即扫描线边界)与 deflate 数据块边界或 IDAT 块边界之间也没有要求上的关联。完整的、经过滤波的 PNG 图像由一个单一的 zlib 数据流表示,而该数据流被存放在若干个 IDAT 块中。

10.3 压缩的其他用法

PNG 还在 iTXtiCCPzTXt 块中使用压缩方法 0。与图像数据不同,此类数据流不会跨多个块拆分;每个此类块都包含一个独立的 zlib 数据流(见 10.1 压缩方法 0)。

11. 块规范

11.1 通用

本条款定义了本规范中使用的各块。

11.2 关键块

简介

关键块(critical chunk)是指从 PNG 数据流中成功解码 PNG 图像所绝对必需的块。扩展块可以被定义为关键块(见 14. 编辑器),但强烈不建议这样做。

有效的 PNG 数据流应以 PNG 签名开始,其后紧跟一个 IHDR 块,然后是一个或多个 IDAT 块,并以一个 IEND 块结束。一个 PNG 数据流中只允许有一个 IHDR 块和一个 IEND 块。

11.2.1 IHDR 图像头

四字节的块类型字段包含以下十六进制值:

49 48 44 52

IHDR 块应为 PNG 数据流中的第一个块。其包含:

宽度 4 字节
高度 4 字节
位深 1 字节
颜色类型 1 字节
压缩方法 1 字节
滤波方法 1 字节
隔行方法 1 字节

宽度与高度给出图像的像素尺寸。它们是PNG 四字节无符号整数。取值 0 无效。

位深是一个单字节整数,给出每个采样或每个调色板索引(而非每像素)的位数。有效取值为 1、2、4、8 与 16,尽管并非所有颜色类型都允许所有取值。见 6.1 颜色类型与取值

颜色类型是一个单字节整数。

对每种颜色类型施加位深限制,以简化实现并禁止压缩效果不佳的组合。允许的组合定义见 12

Table 12 允许的颜色类型与位深组合
PNG 图像类型 颜色类型 允许的位深 解释
灰度 0 1, 2, 4, 8, 16 每个像素是一个灰度采样
真彩色 2 8, 16 每个像素是一个 R,G,B 三元组
索引色 3 1, 2, 4, 8 每个像素是一个调色板索引;必须出现 PLTE 块。
灰度(含 alpha) 4 8, 16 每个像素是一个灰度采样,后跟一个 alpha 采样。
真彩色(含 alpha) 6 8, 16 每个像素是一个 R,G,B 三元组,后跟一个 alpha 采样。

索引色 PNG 图像(颜色类型 3)外,采样深度与位深相同;在索引色图像中,采样深度始终为 8 位(见 4.5 PNG 图像)。

压缩方法是一个单字节整数,指示用于压缩图像数据的方法。本规范仅定义压缩方法 0(deflate 压缩,滑动窗口最大 32768 字节)。所有符合规范的 PNG 图像均应使用该方案进行压缩。

滤波方法是一个单字节整数,指示在压缩前应用于图像数据的预处理方法。本规范仅定义 滤波方法 0(包含五种基本滤波类型的自适应滤波)。详见 9. 滤波

隔行方法是一个单字节整数,指示图像数据的传输顺序。本规范定义了两个取值:0(不隔行)与 1(Adam7 隔行)。详见 8. 隔行与通道提取

11.2.2 PLTE 调色板

四字节的块类型字段包含以下十六进制值:

50 4C 54 45

PLTE 块包含 1 到 256 个调色板条目,每个条目为以下三字节序列:

1 字节
绿 1 字节
1 字节

条目数量由块长度决定。块长度若不能被 3 整除则为错误。

对于颜色类型 3,本块必须出现;对于颜色类型 2 和 6,本块可以出现;对于颜色类型 0 和 4,本块不得出现。不得存在多于一个的 PLTE 块。

对于颜色类型 3(索引色),PLTE 块为必需。PLTE 中的第一个条目由像素值 0 引用,第二个由像素值 1 引用,依此类推。调色板条目的数量不得超过图像位深所能表示的范围(例如,位深为 4 时为 24 = 16)。允许条目数量少于位深所允许的最大数量。在这种情况下,若在图像数据中发现超出范围的像素值,则为错误。

对于颜色类型 2 与 6(真彩色真彩色(含 alpha)),PLTE 块是可选的。若存在,它提供一个建议的颜色集合(1 到 256 种),当图像无法直接显示时,可将 真彩色图像量化到这些颜色。然而,建议使用 sPLT 块来实现该目的,而非 PLTE 块。若既无 PLTE 块也无 sPLT 块且图像无法直接显示,则量化需由查看系统完成。然而,通常更可取的是由 PNG 编码器一次性完成颜色选择。(见 12.5 建议调色板。)

请注意,调色板每个采样使用 8 位(1 字节),与图像位深无关。尤其是,即使它是对 16 位真彩色图像的建议量化,调色板本身仍为 8 位深。

图像并不要求必须使用所有调色板条目,也不要求所有条目互不相同。

11.2.3 IDAT 图像数据

四字节的块类型字段包含以下十六进制值:

49 44 41 54

IDAT 块包含实际的图像数据,即压缩算法的输出流。详见 9. 滤波10. 压缩

可以存在多个 IDAT 块;若存在,必须连续出现,中间不得夹杂其他块。压缩数据流即为所有 IDAT 块数据字段内容的串联 (注意数据字段可能为零长度)。

某些图像在最后一个 IDAT 块的末尾存在未使用的尾随字节。这可能发生在存储了整个缓冲区而非仅使用部分缓冲区的情况下。这是不理想的。更可取的是,编码器不包含这些未使用的字节;若必须包含,将这些字节置零可避免意外的数据泄露。解码器应忽略这些尾随字节。

11.2.4 IEND 图像结尾

四字节的块类型字段包含以下十六进制值:

49 45 4E 44

IEND 块标记 PNG 数据流的结束。该块的数据字段为空。

11.3 辅助块

简介

本规范中定义的辅助块按4.8.2 块类型的顺序列出。该顺序并非它们在 PNG 数据流中出现的顺序。解码器可以忽略辅助块。对每个辅助块而言,下述行为均假定解码器未忽略该块。

11.3.1 透明信息

11.3.1.1 tRNS 透明度

四字节的块类型字段包含以下十六进制值

74 52 4E 53

tRNS 块为索引色图像指定与调色板条目关联的 alpha 值,或为灰度真彩色图像指定单一透明颜色。tRNS 块包含:

颜色类型 0
灰度采样值 2 字节
颜色类型 2
红色采样值 2 字节
绿色采样值 2 字节
蓝色采样值 2 字节
颜色类型 3
调色板索引 0 的 Alpha 1 字节
调色板索引 1 的 Alpha 1 字节
……等等…… 1 字节

对于颜色类型 3(索引色),tRNS 块包含一系列与 PLTE 块条目一一对应的单字节 alpha 值。每个条目表明对应调色板索引的像素应被视为具有指定的 alpha 值。Alpha 值与 8 位完整 alpha 通道的解释相同:0 为完全透明,255 为完全不透明,与图像位深无关。tRNS 块所含 alpha 值数量不得多于调色板条目数,但可以少于调色板条目数。此时,所有其余调色板条目的 alpha 值视为 255。常见情况下仅需将调色板索引 0 设为透明,则仅需一个单字节的 tRNS 块;若所有调色板索引均不透明,可省略 tRNS 块。

对于颜色类型 0 或 2,每个采样均使用两个字节,不受图像位深影响(见7.1 整数与字节序)。与指定灰度采样值或 RGB 采样值相同的像素视为透明(等同于 alpha 值 0);所有其他像素视为完全不透明(alpha 值为 2bitdepth-1)。若图像位深小于 16,则使用最低有效位。编码器应将其他位设为 0,解码器在使用前必须将其他位掩蔽为 0。

对于颜色类型 4 与 6,不得出现 tRNS 块,因为已存在完整的 alpha 通道。

注:对于 16 位 灰度真彩色 数据, 如 13.12 样本深度重缩放 所述, 只有 与完整 16 位值相匹配的像素tRNS 块中被视为透明。解码器必须在对像素进行透明性检测之后再进行任何样本深度重缩放。

11.3.2 色彩空间信息

11.3.2.1 cHRM 主色度与白点

四字节的块类型字段包含以下十六进制值

63 48 52 4D

cHRM 块可用于指定PNG 图像所用显示设备的红、绿、蓝三基色的 1931 CIE x,y 色度,以及参考白点。更多信息见C. 伽玛与色度iCCPsRGB 块为色彩管理与控制提供了更完善的支持。

cHRM 块包含:

Table 13 cHRM 块组成
名称 大小
白点 x 4 字节
白点 y 4 字节
红色 x 4 字节
红色 y 4 字节
绿色 x 4 字节
绿色 y 4 字节
蓝色 x 4 字节
蓝色 y 4 字节

每个值以PNG 四字节无符号整数编码,表示 xy 值乘以 100000。

值 0.3127 将存储为整数 31270。

cHRM 块允许出现在所有 PNG 数据流中,尽管对灰度图像意义较小。

除非该块是解码器所理解的优先级最高的颜色块,否则应忽略本块。

11.3.2.2 gAMA 图像伽玛

四字节的块类型字段包含以下十六进制值

67 41 4D 41

gAMA 块指定伽玛值

实际上,仅指定期望的显示输出强度是不够的,还需要指定期望输出所对应的观看条件。对于 gAMA,参考观看条件为 sRGB 规范 [SRGB] 的参考观看条件。对不同观看条件的调整通常由色彩管理系统处理。若未进行调整,误差通常很小。需要高保真色彩的应用可考虑使用 sRGBiCCP 块。

gAMA 块包含:

图像伽玛 4 字节

该值以PNG 四字节无符号整数编码,表示伽玛值乘以 100000。

伽玛值 1/2.2 将存储为整数 45455。

更多信息见12.1 编码器伽玛处理13.13 解码器伽玛处理

除非该块是解码器所理解的优先级最高的颜色块,否则应忽略本块。

11.3.2.3 iCCP 内嵌 ICC 配置文件

四字节的块类型字段包含以下十六进制值

69 43 43 50

iCCP 块包含:

配置文件名称 1-79 字节(字符串)
空字符分隔符 1 字节(空字符)
压缩方法 1 字节
压缩的配置文件数据 n 字节

配置文件名称可以是用于引用该配置文件的任意便捷名称,区分大小写。名称只能包含可打印的 Latin-1 字符与空格(仅允许码位 0x20-7E 与 0xA1-FF)。不允许前导、尾随及连续空格。本规范仅定义压缩方法 0(zlib 数据流,使用 deflate 压缩,见10.3 压缩的其他用法)。压缩方法条目之后是占据块剩余部分的压缩配置文件数据。解压该数据流可得到内嵌的 ICC 配置文件。

若存在 iCCP 块,则图像采样符合国际色彩联盟 [ICC][ISO_15076-1] 定义的内嵌 ICC 配置文件所表示的色彩空间。ICC 配置文件的色彩空间对于彩色图像(颜色类型 2、3、6)应为 RGB 色彩空间;对于灰度图像(颜色类型 0、4)应为灰度色彩空间。建议写入 iCCP 块的 PNG 编码器同时写入可近似 ICC 配置文件的 gAMAcHRM 块,以便兼容不使用 iCCP 块的应用。

除非该块是解码器所理解的优先级最高的颜色块,否则应忽略本块。

除非存在 cICP 块,PNG 数据流中至多应包含一个内嵌配置文件,可通过 iCCP 显式指定,或通过 sRGB 块隐式指定。

11.3.2.4 sBIT 有效位

四字节的块类型字段包含以下十六进制值

73 42 49 54

为简化解码器,PNG 规定仅可使用某些采样深度,并进一步规定采样值应缩放至该采样深度下可能值的全范围。sBIT 块定义原始的有效位数(可小于或等于采样深度)。这使得即使数据的采样深度并非 PNG 直接支持,PNG 解码器也能无损恢复原始数据。

sBIT 块包含:

Table 14 sBIT 块内容
颜色类型 0
灰度有效位数 1 字节
颜色类型 2 与 3
红色有效位数 1 字节
绿色有效位数 1 字节
蓝色有效位数 1 字节
颜色类型 4
灰度有效位数 1 字节
Alpha 有效位数 1 字节
颜色类型 6
红色有效位数 1 字节
绿色有效位数 1 字节
蓝色有效位数 1 字节
Alpha 有效位数 1 字节

sBIT 中指定的每个位数应大于 0 且不大于采样深度(索引色图像的采样深度为 8,其他颜色类型的采样深度为 IHDR 中给定的位深)。注意,sBIT 不会为由 tRNS 块隐含的 alpha 通道提供采样深度;此种情况下,alpha 通道的所有采样位均应视为有效。若不存在 sBIT 块,则所有通道的全部采样位均应视为有效。

11.3.2.5 sRGB 标准 RGB 色彩空间

四字节的块类型字段包含以下十六进制值

73 52 47 42

若存在 sRGB 块,则图像采样符合 sRGB 色彩空间 [SRGB],并应使用国际色彩联盟 [ICC] 或 [ICC-2] 定义的指定渲染意图进行显示。

sRGB 块包含:

Table 15 sRGB 块内容
名称 大小
渲染意图 1 字节

渲染意图的取值定义如下:

Table 16 渲染意图取值
名称 说明
0 感知(Perceptual) 适用于偏好良好适配输出设备色域、而牺牲比色精度的图像,如照片。
1 相对比色(Relative colorimetric) 适用于要求匹配色外观(相对于输出设备白点)的图像,如标志。
2 饱和(Saturation) 适用于偏好保持饱和度、而牺牲色相与明度的图像,如图表与曲线图。
3 绝对比色(Absolute colorimetric) 适用于要求保持绝对比色的图像,如为其他输出设备(打样)生成的预览。

建议写入 sRGB 块的 PNG 编码器同时写入 gAMA 块(可选再写入 cHRM 块),以兼容不使用 sRGB 块的解码器。仅应使用下列取值。

Table 17 sRGB 的 gAMA 与 cHRM 取值
gAMA
Gamma 45455
cHRM
白点 x 31270
白点 y 32900
红色 x 64000
红色 y 33000
绿色 x 30000
绿色 y 60000
蓝色 x 15000
蓝色 y 6000

除非该块是解码器所理解的优先级最高的颜色块,否则应忽略本块。

建议 PNG 数据流中不要同时出现 sRGBiCCP 块。

11.3.2.6 cICP 视频信号类型标识的编码无关代码点

四字节的块类型字段包含以下十六进制值

63 49 43 50

若存在,cICP 块使用 [ITU-T-H.273] 中的代码点指定图像的色彩空间(主色),传递函数、矩阵系数与缩放因子。处理图像时(包括解码或渲染)应(SHOULD)使用该视频格式信令。

cICP 块由四个 1 字节无符号整数组成,用以标识上述特性。

下表给出了 cICP 块的语法:

Table 18 cICP 块组成
名称 大小
色度学原色(Color Primaries) 1 字节
传递函数(Transfer Function) 1 字节
矩阵系数(Matrix Coefficients) 1 字节
视频全范围标志(Video Full Range Flag) 1 字节

cICP 块的每个字段均对应于 [ITU-T-H.273] 中同名参数。

PNG 当前仅支持 RGB 颜色模型,因此Matrix Coefficients 应设置为 0

Video Full Range Flag0窄范围图像),建议将诸如EOTF 或逆OETF 等传递函数定义在扩展范围上,以包含负值。方法如下:

out = sign(in) * TransferFunction(abs(in))

cICP必须(MUST)出现在 PLTEIDAT 块之前。

若解码器能够理解该块,则该块为优先级最高的颜色块

类似于使用 sRGB 块紧凑地标识 sRGB 图像,cICP 也可用于紧凑地标识 Display P3 图像 [Display-P3]。

11.3.2.7 mDCV 母版显示色彩体积

四字节的块类型字段包含以下十六进制值

6D 44 43 56

若存在,mDCV 块表征内容创作阶段所使用的母版显示色彩体积(mDCV),其定义见 [SMPTE-ST-2086]。mDCV 块提供具有参考意义的静态元数据,使目标(消费者)显示设备可基于其固有能力与原始母版显示能力的比较,潜在地优化其色调映射决策。

mDCV 通常与 PQ [ITU-R-BT.2100] 传递函数及附加的 cLLI 元数据配合使用,此配置通常称为 [HDR10](PQ + ST 2086 静态元数据、MaxFALL 与 MaxCLL)。 mDCV 块也可与 HLG [ITU-R-BT.2100] 以及 SDR 图像格式(例如 [ITU-R-BT.709])配合使用。

由于 mDCV 最初作为补充的静态元数据,用于在视频显示目标上优化图像的色调映射,因此使用 mDCV 时必须配套 cICP 块,以明确图像内容的基本特性。色度学原色与白点特性可由 cICP 块格式推导。关于其在使用 HDR [ITU-R-BT.2100] 与 SDR [ITU-R-BT.709] 图像时最常见的用例,见 [ITU-T-Series-H-Supplement-19]。 基本(cICP)特性加上补充(mDCV)静态元数据,可为优化色调映射提供有价值的信息。

Issue #319 讨论了存在 mDCV 块时的色调映射行为。

对于SDR 图像,若 mDCV 显示的最小/最大亮度未知,默认特性可由 [ITU-T-Series-H-Supplement-19] 表 11 的数值或相关SDR 规范推导。目前并无发布的、标准化的方法可将 SDR 图像信号从其默认观看条件(显示亮度与环境照明)转换为 mDCV 块所指示的条件。

下表给出了 mDCV 块的语法:

Table 19 mDCV 块组成
名称 大小 除数
母版显示色度学原色(CIE 1931 x,y 的 R、G、B) 12 字节 0.00002
母版显示白点色度(CIE 1931 x,y 4 字节 0.00002
母版显示最大亮度(cd/m2 4 字节 0.0001
母版显示最小亮度(cd/m2 4 字节 0.0001

色度学原色编码为三个成对的PNG 两字节无符号整数,顺序为 xy,每个值表示对应原色的 x 或 y 色度值除以除数后的结果。排序从 x 色度最大的原色开始,其次为 y 色度最大的原色,最后为剩余的原色。对 RGB 色彩空间而言,这对应 R、G、B 的顺序。

白点编码为一对PNG 两字节无符号整数,顺序为 xy,每个值表示白点 x 或 y 色度值除以除数后的结果。

最大与最小亮度编码为PNG 四字节无符号整数,表示以 cd/m2 为单位的绝对亮度值除以除数后的结果。

除数用于将实际值映射为存储值。例如,原色与白点的无单位除数 0.00002 会将色度 (0.6800, 0.3200) 存储为 {34000, 16000}。

mDCV必须(MUST)出现在 PLTEIDAT 块之前。

下面给出 [ITU-R-BT.2100] HDR 的 mDCV 示例。

下面给出 [Display-P3] SDR 的 mDCV 示例。

11.3.2.8 cLLI 内容光等级信息

四字节的块类型字段包含以下十六进制值

63 4C 4C 49

若存在,cLLI 块标识HDR 内容的两个特性:

cLLI 块添加静态元数据,为将相关内容映射到特定目标显示器进行色调映射优化提供可能。这通过根据目标显示器的峰值亮度能力对内容自身的色调映射进行定制来实现,以防止裁剪。目前色调映射优化的方法是主观的。

MaxCLL(最大内容光等级)使用静态元数据值表示整个回放序列中任一单个像素的最大光等级(单位 cd/m2,也称尼特)。通常会使用算法滤波以消除由处理或噪声导致的不真实值,避免对下游目标色调映射产生不利影响。

MaxFALL(最大帧平均光等级)使用静态元数据值表示整个回放序列中平均光等级(单位 cd/m2,也称尼特)的最大值。其计算方法是先对每帧的所有像素解码后的亮度值进行平均,再取平均值最高的那一帧的数值。

MaxCLL 与 MaxFALL 值以PNG 四字节无符号整数编码。

[CTA-861.3-A] 描述了生成 cLLI 值的计算方法,但未规定任何滤波。[HDR-Static-Meta] 描述了一种改进方法,可剔除统计离群、噪声或重采样滤波器振铃导致的极端值,推荐在实际实现中采用。

[SMPTE-ST-2067-21] 第 7.5 节在 cLLI 值未知且未计算的情况下,提供了额外信息。

Issue #319 讨论了存在 cLLI 块时的色调映射行为。

需要对每个进行分析。

MaxCLL 或 MaxFALL 任一值为零表示该值未知或当前无法计算。

例如在创建直播的 APNG 流时,在流结束前无法获得全部帧来计算这些数值,因此无法计算。编码器可选择初始设置为 0,并在流结束时以计算得到的数值替换。

下表给出了 cLLI 块的语法:

Table 20 cLLI 块组成
名称 大小 除数
最大内容光等级(MaxCLL) 4 字节 0.0001 cd/m2
最大帧平均光等级(MaxFALL) 4 字节 0.0001 cd/m2

11.3.3 文本信息

简介

PNG 提供了 tEXtiTXtzTXt 块,用于存储与图像关联的文本字符串,例如图像描述或版权声明。关键字用于指示每个文本字符串的含义。可以出现任意数量的此类文本块,并允许出现多个具有相同关键字的块。

11.3.3.1 关键字与文本字符串

下列关键字是预定义的,应在适当情况下使用。

21 预定义关键字
关键字值 说明
Title 图像的简短(单行)标题或说明
Author 图像创建者姓名
Description 图像描述(可能较长)
Copyright 版权声明
Creation Time 原始图像创建时间
Software 用于创建图像的软件
Disclaimer 法律免责声明
Warning 内容性质的警告
Source 用于创建图像的设备
Comment 其他备注
XML:com.adobe.xmp 可扩展元数据平台(XMP)信息,按 XMP 规范要求的格式 [XMP]。建议为符合 XMP 要求使用 iTXt,将 Compression Flag 设为 0,并将 Language Tag 与 Translated Keyword 均设为空字符串。
Collection 图像所属集合的名称。图像可以属于一个或多个集合,每个集合由单独的文本块命名。

其他关键字 MAY 由任何应用为私有或通用用途定义。

关键字 SHOULD 满足以下条件。

  • 应当相当自解释,以便其他人工用户能够理解该块包含的内容;并且
  • 选择时应尽量减少不同应用因不兼容用途使用相同关键字的可能性。

应将具有一般性意义的关键字 SHOULD 列入 [PNG-EXTENSIONS]。

关键字只能包含可打印的 Latin-1 [ISO_8859-1] 字符和空格;即仅允许码位 0x20-7E 与 0xA1-FF。为减少人工误读关键字的概率,关键字中不允许前导空格、尾随空格和连续空格,也不允许 U+00A0 NO-BREAK SPACE(因其在视觉上与普通空格无法区分)。

关键字应按注册时的拼写精确表示,以便解码器在查找特定关键字时能够使用简单的字面比较。特别地,关键字视为区分大小写。关键字长度限制为 1 到 79 字节。

对于 Creation Time 关键字,日期格式 SHOULD 使用 RFC 3339 [rfc3339] 的日期-时间格式,或 RFC 1123 第 5.2.14 节中定义的日期格式 [rfc1123]。优先采用 RFC3339 日期-时间格式。该字段的实际格式未作严格定义。

iTXt 块使用 UTF-8 编码 [rfc3629],可用于传递任何语言的字符。iTXt 块可选择对文本字符串进行压缩。由于支持 Unicode,建议对所有文本字符串使用 iTXt。此外还有 tEXtzTXt 块,其内容仅限于可打印的 Latin-1 字符集和 U+000A LINE FEED (LF)。zTXt 中的文本字符串通过 zlib 数据流使用 deflate 压缩(见 10.3 压缩的其他用法)。解压后得到的文本与等价的 tEXt 块中的文本在内容上相同。

11.3.3.2 tEXt 文本数据

四字节的块类型字段包含以下十六进制值

74 45 58 74

每个 tEXt 块包含一个关键字和一个文本字符串,其格式为:

关键字 1-79 字节(字符串)
空字符分隔符 1 字节(空字符)
文本字符串 0 或更多字节(字符串)

关键字与文本字符串之间用零字节(空字符)分隔。关键字与文本字符串均不得包含空字符。文本字符串以空字符结尾(块的长度定义了结束位置)。文本字符串的长度可以从零字节到最大允许块大小减去关键字与空字符分隔符的长度。

关键字指示文本字符串表示的信息类型,详见 11.3.3.1 关键字与文本字符串

文本按 Latin-1 字符集解释 [ISO_8859-1]。文本字符串可以包含任意 Latin-1 字符。文本字符串中的换行应使用单个换行符(十进制 10)表示。除 Latin-1 定义的字符以及换行符之外的字符在 tEXt 块中无定义含义。包含 ISO/IEC 8859-1 范围之外字符的文本应使用 iTXt 块进行编码。

11.3.3.3 zTXt 压缩文本数据

四字节的块类型字段包含以下十六进制值

7A 54 58 74

zTXttEXt 块在语义上等价,但建议使用 zTXt 来存储大量文本。

一个 zTXt 块包含:

关键字 1-79 字节(字符串)
空字符分隔符 1 字节(空字符)
压缩方法 1 字节
压缩的文本数据流 n 字节

关键字和空字符与 tEXt 块中的相同。关键字不被压缩。压缩方法字段定义所用的压缩方法。本国际标准中定义的唯一值为 0(deflate 压缩)。其他值保留以供未来标准化。压缩方法字段之后是构成块其余部分的压缩文本数据流。对于压缩方法 0,该数据流为带 deflate 压缩的 zlib 数据流(参见 10.3 压缩的其他用法)。解压该数据流将得到与等价 tEXt 块中相同的 Latin-1 文本。

11.3.3.4 iTXt 国际文本数据

四字节的块类型字段包含以下十六进制值

69 54 58 74

一个 iTXt 块包含:

关键字 1-79 字节(字符串)
空字符分隔符 1 字节(空字符)
压缩标志 1 字节
压缩方法 1 字节
语言标签 0 或更多字节(字符串)
空字符分隔符 1 字节(空字符)
翻译后的关键字 0 或更多字节
空字符分隔符 1 字节(空字符)
文本 0 或更多字节

关键字详见 11.3.3.1 关键字与文本字符串

压缩标志为 0 表示未压缩文本,1 表示压缩文本。只有文本字段可以被压缩。压缩方法字段定义所用的压缩方法。本规范中定义的唯一压缩方法为 0(带 deflate 压缩的 zlib 数据流,见 deflate)。对于未压缩文本,编码器应将压缩方法设为 0,解码器应忽略该字段。

语言标签应为 [BCP47] 定义的良构语言标签。与关键字不同,语言标签不区分大小写。子标签必须出现在 IANA 语言子标签注册表中(https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry)。若语言标签为空,则语言未指定。语言标签示例:enen-GBes-419zh-Hanszh-Hans-CNtlh-Cyrl-AQar-AE-u-nu-latnx-private

翻译后的关键字与文本均使用 UTF-8 编码 [rfc3629],且均不得包含零字节(空字符)。与该块中的其他文本数据不同,此处的文本不以空字符结尾;其长度由块长度推导得出。

翻译后的关键字中不应出现换行。在文本中,换行应由单个换行符(十六进制 0A)表示。其余控制字符(01-09、0B-1F、7F-9F)在翻译后的关键字和文本中均不推荐使用。在 UTF-8 中,字符 80-9F(不推荐)与字节序列 80-9F(在某些情况下是必要的)是不同的概念。

若翻译后的关键字非空,则应包含将关键字翻译为语言标签所指示语言的翻译,显示关键字的应用应同时显示翻译后的关键字。

11.3.4 杂项信息

11.3.4.1 bKGD 背景色

四字节的块类型字段包含以下十六进制值

62 4B 47 44

bKGD 块指定用于呈现图像的默认背景颜色。如果存在任何其它更优先的背景(例如用户指定的或页面(如浏览器)的一部分),应忽略 bKGD 块。bKGD 块包含:

22 bKGD 块内容
颜色类型 0 与 4
灰度 2 字节
颜色类型 2 与 6
2 字节
绿 2 字节
2 字节
颜色类型 3
调色板索引 1 字节

对于 color type 3(indexed-color),该值为应作为背景使用的调色板索引。

对于 color types 0 与 4(greyscalegreyscale with alpha),该值为用作背景的灰度级,范围为 0 到 (2bitdepth) - 1。对于 color types 2 与 6(truecolortruecolor with alpha),这些值为用作背景的颜色,作为 RGB 采样,范围为 0 到 (2bitdepth) - 1。在每种情况下,为一致起见,每个采样使用两字节,且不受图像位深影响。如果图像位深小于 16,则使用最低有效位。编码器应将其他位设为 0,解码器在使用前必须将其他位掩蔽为 0。

11.3.4.2 hIST 图像直方图

四字节的块类型字段包含以下十六进制值

68 49 53 54

hIST 块包含一系列两字节无符号整数:

频率 2 字节(无符号整数)
……等等……  

hIST 块给出调色板中每种颜色的近似使用频率。只有当出现 PLTE 块时,才可出现直方图块。如果查看器无法提供调色板中列出的所有颜色,直方图可以帮助其决定如何为显示选择颜色子集。

对于 PLTE 块中的每个条目,应恰好存在一个直方图条目。每个条目与图像中具有该调色板索引的像素所占比例成正比;缩放因子由编码器自行选择。

直方图条目为近似值,唯一例外是零条目表示相应调色板条目在图像中根本未被使用。若存在该颜色的像素,则该直方图条目应为非零。

注:当调色板是对 truecolor 图像的建议量化时,直方图必然是近似的,因为解码器映射像素到调色板条目的方式可能与编码器不同。在这种情况下,通常不应出现零条目,因为任何条目都有可能被使用。

11.3.4.3 pHYs 物理像素尺寸

四字节的块类型字段包含以下十六进制值

70 48 59 73

pHYs 块指定用于显示图像的目标像素大小或纵横比。它包含:

23 pHYs 块内容
名称 大小
X 轴每单位像素数 4 字节(PNG 四字节无符号整数
Y 轴每单位像素数 4 字节(PNG 四字节无符号整数
单位说明符 1 字节

单位说明符的定义值如下:

24 单位说明符取值
说明
0 单位未知
1 单位为米

当单位说明符为 0 时,pHYs 块仅定义像素纵横比;像素的实际尺寸未被指定。

如果未存在 pHYs 块,则假定像素为方形,且每个像素的物理尺寸未被指定。

11.3.4.4 sPLT 建议调色板

四字节的块类型字段包含以下十六进制值

73 50 4C 54

sPLT 块包含:

25 sPLT 块内容
名称 大小
调色板名称 1-79 字节(字符串)
空字符分隔符 1 字节(空字符)
样本深度 1 字节
1 或 2 字节
绿 1 或 2 字节
1 或 2 字节
Alpha 1 或 2 字节
频率 2 字节
……等等……  

每个调色板条目为六字节或十字节,包含五个无符号整数(red、blue、green、alpha 与 frequency)。

条目数可以是任意数量。PNG 解码器根据样本深度字节之后剩余的块长度确定条目数。如果 sPLT 的样本深度为 8,则剩余长度应能被 6 整除;若样本深度为 16,则应能被 10 整除。条目应按频率降序排列。并不要求所有条目都被图像使用,也不要求条目互不相同。

调色板名称可以是引用该调色板的任意便捷名称(例如 "256 color including Macintosh default"、"256 color including Windows-3.1 default"、"Optimal 512")。当 PNG 数据流中出现多个建议调色板时,调色板名称可帮助选择适当的建议调色板。

调色板名称区分大小写,并遵循与 tEXt 块关键字参数相同的限制。调色板名称仅应包含可打印的 Latin-1 字符和空格(仅允许码位 0x20-7E 与 0xA1-FF)。不允许前导、尾随或连续空格。

sPLT 的样本深度应为 8 或 16。

红、绿、蓝与 alpha 采样的长度为 1 或 2 字节,取决于 sPLT 的样本深度,与图像位深无关。颜色样本未被 alpha 预乘,也未与任何背景预合成。alpha 值为 0 表示完全透明。alpha 值为 255(当样本深度为 8)或 65535(当样本深度为 16)表示完全不透明。sPLT 块可出现在任何 color type 中。sPLT 条目使用与 PNG 图像相同的 gamma valuechromaticity 值,但条目值可能超出图像色彩空间的使用范围;例如,在灰度 PNG 图像中,每个 sPLT 条目通常会具有相等的 R、G、B 值,但这并非必须。同样,即便 PNG 图像不使用透明度,sPLT 条目也可以具有非不透明的 alpha 值。

每个频率值与图像中在 RGBA 空间内最接近该调色板条目的像素所占比例成正比,且该计算在将图像与任何背景进行 合成 之前完成。确切缩放因子由 PNG 编码器选择;建议使单个值的范围合理地填充 0 到 65535 的区间。PNG 编码器可人为地增加被认为“重要”的颜色的频率,例如用于标志或肖像面部特征的颜色。频率为零是有效的,表示该颜色“最不重要”或很少(或从未)被使用。当所有频率均为零时,这些值无意义,不能从中推断颜色在图像中出现的实际频率。

允许多个 sPLT 块,但每个块的调色板名称必须不同。

11.3.4.5 eXIf 可交换图像文件(Exif)配置文件

四字节的块类型字段包含以下十六进制值

65 58 49 66

eXIf 块的数据段包含按 [CIPA-DC-008] 中“4.7.2 Interoperability Structure of APP1 in Compressed Data” 指定的格式的 Exif 配置文件,但不包括 JPEG APP1 标记、长度以及 4.7.2(C) 中描述的 “Exif ID code”(即 "Exif", NULL 与填充字节)。

eXIf 块的大小仅受 PNG 规范强加的 231-1 字节最大值约束。一个 PNG 数据流中仅允许存在一个 eXIf 块。

eXIf 块包含关于原始 图像数据 的元数据。如果图像在 Exif 配置文件创建后被编辑,则这些数据可能不再适用于 PNG 的 图像数据。建议除非解码器具有独立证据确认 Exif 数据仍然有效,否则应将这些数据视为仅具历史价值。本规范不负责解决 eXIf 块与其他 PNG 块中的数据之间可能存在的冲突。

11.3.4.5.1 eXIf 一般建议

尽管 PNG 规范允许块大小达到 231-1 字节,但应用程序作者应注意:如果 Exif 配置文件还将被写入 JPEG [JPEG] 数据流,则需调整 eXIf 块数据的总长度,使其不超过 216-9 字节,以便能够放入 JPEG 的 APP1 标记(Exif)段中。

11.3.4.5.2 eXIf 解码器建议

数据的前两个字节为 "II" 表示小端(Intel)字节序,或 "MM" 表示大端(Motorola)字节序。解码器应检查前四个字节以确保它们为以下十六进制值之一:

49 49 2A 00 (ASCII "II", 16 位小端整数 42)

4D 4D 00 2A (ASCII "MM", 16 位大端整数 42)

所有其他值保留以供未来定义。

11.3.4.5.3 eXIf 编码器建议

图像编辑应用应考虑 Exif 规范中第 E.3 节的建议 [CIPA-DC-008],其中讨论了图像更改时更新 Exif 数据的要求。编码器应遵循这些要求,但解码器不应假定这些更新已被执行。

尽管编码器可以选择更新 Exif 中的缩略图,但不应期望当主图像更改时,Exif 配置文件中存在的任何缩略图已被更新或未被更新。

11.3.5 时间戳信息

11.3.5.1 tIME 图像最后修改时间

四字节的块类型字段包含以下十六进制值

74 49 4D 45

tIME 块给出图像的最后修改时间(不是图像最初创建时间)。它包含:

Table 26 tIME 块内容
名称 大小
Year 2 字节(完整,例如 1995,不是 95)
Month 1 字节(1-12)
Day 1 字节(1-31)
Hour 1 字节(0-23)
Minute 1 字节(0-59)
Second 1 字节(0-60)(以允许闰秒)

应指定世界协调时(UTC),而不是本地时间。

tIME 块用于作为自动应用的时间戳,每当 image data 被更改时会更新。

11.3.6 动画信息

11.3.6.1 acTL 动画控制块

四字节的块类型字段包含以下十六进制值

61 63 54 4C

acTL 块声明这是一个动画 PNG 图片,给出帧数以及循环播放的次数。它包含:

num_frames 4 字节
num_plays 4 字节

每个值均按 PNG four-byte unsigned integer 编码。

num_frames 指示动画中的总帧数。此值必须等于 fcTL 块的数量。0 不是有效值。1 为有效值,表示单帧 PNG。如果该值与实际帧数不一致,应将其视为错误。

num_plays 指示该动画应播放的次数;若为 0,则应无限循环播放。若非零,则动画在最后一次播放结束时应停留在最后一帧。

acTL 块必须出现在有效 PNG 流中的第一个 IDAT 块之前。

Note

出于 Web 兼容性考虑,由于该块的开发与部署与其并入 PNG 规范之间间隔较长,该块名特例地按私有块定义。

11.3.6.2 fcTL 帧控制块

四字节的块类型字段包含以下十六进制值

66 63 54 4C

fcTL 块定义单个帧的尺寸、位置、延迟和处置。每个帧精确需要一个 fcTL 块。它包含:

Table 27 fcTL 块内容
名称 大小
sequence_number 4 字节
width 4 字节
height 4 字节
x_offset 4 字节
y_offset 4 字节
delay_num 2 字节
delay_den 2 字节
dispose_op 1 字节
blend_op 1 字节

sequence_number 定义动画块的 序列号,从 0 开始。它按 PNG four-byte unsigned integer 编码。

widthheight 定义后续帧的宽度与高度。它们按 PNG four-byte unsigned integers 编码,且必须大于零。

x_offsety_offset 定义后续帧的位置。它们按 PNG four-byte unsigned integers 编码,0 为有效值。

帧必须在由 x_offsety_offsetwidthheight 定义的区域内渲染。该区域不得超出默认图像;因此 x_offset 加上 width 不得大于 IHDR 中的宽度;同样 y_offset 加上 height 不得大于 IHDR 中的高度。

delay_numdelay_den 定义延迟分数的分子與分母;表示显示当前帧的时间(以秒为单位)。若分母为 0,则视为 100(即 delay_num 指定 1/100 秒)。若分子为 0,解码器应尽快渲染下一帧,但查看器可以施加合理的下限。它们按两字节无符号整数编码。

帧定时应独立于解码与显示每帧所需的时间,以确保动画在不同解码器实现上的播放速率一致。

dispose_op 定义在渲染该帧之后应对该帧区域进行的处置类型;换言之,它指定在延迟结束(渲染下一帧之前)应如何更改输出缓冲区。它按一字节无符号整数编码。

dispose_op 的有效取值如下:

0 APNG_DISPOSE_OP_NONE
1 APNG_DISPOSE_OP_BACKGROUND
2 APNG_DISPOSE_OP_PREVIOUS
APNG_DISPOSE_OP_NONE
在渲染下一帧之前对此帧不做处置;输出缓冲区内容保持不变。
APNG_DISPOSE_OP_BACKGROUND
在渲染下一帧之前,先将该帧在输出缓冲区中的区域清除为完全透明的黑色。
APNG_DISPOSE_OP_PREVIOUS
在渲染下一帧之前,将该帧在输出缓冲区中的区域恢复为先前的内容。

如果第一个 fcTL 块使用的 dispose_opAPNG_DISPOSE_OP_PREVIOUS,则应将其视为 APNG_DISPOSE_OP_BACKGROUND

blend_op 指定该帧是应基于 alpha 与当前输出缓冲区内容进行 alpha 混合,还是应完全替换输出缓冲区中该区域。它按一字节无符号整数编码。

blend_op 的有效取值如下:

0 APNG_BLEND_OP_SOURCE
1 APNG_BLEND_OP_OVER

blend_opAPNG_BLEND_OP_SOURCE,则该帧的所有颜色分量(包括 alpha)覆盖帧输出缓冲区当前内容的相应区域。若 blend_opAPNG_BLEND_OP_OVER,则该帧应基于其 alpha 使用简单的 OVER 操作将其合成(composited)到输出缓冲区,如在 Alpha Channel Processing 中所述。注意示例代码的第二种变体适用。

注意对于第一帧,由于在每次播放开始时输出缓冲区会被清除,两种混合模式在功能上等价。

对应于默认图像的 fcTL 块(如果存在)具有如下限制:

  • x_offsety_offset 字段必须为 0。
  • widthheight 字段必须等于 IHDR 块中的对应字段。

如前所述,输出缓冲区必须在每次播放开始时完全初始化为完全透明的黑色,以确保每次播放的结果相同。解码器只要能保证结果相同,便可以避免显式的清除步骤。例如,如果默认图像包含在动画中且使用 blend_opAPNG_BLEND_OP_SOURCE,则无需清除,因为整个输出缓冲区将被覆盖。

Note

出于 Web 兼容性考虑,由于该块的开发与部署与其并入 PNG 规范之间间隔较长,该块名特例地按私有块定义。

11.3.6.3 fdAT 帧数据块

四字节的块类型字段包含以下十六进制值

66 64 41 54

fdAT 块对动画而言的作用与静态图像的 IDAT 块相同;一组 fdAT 块包含所有帧(或者当动画将静态图像作为第一帧时,包含第一帧之后的所有帧)的 图像数据。它包含:

Table 28 fdAT 块内容
名称 大小
sequence_number 4 字节
frame_data n 字节

除非第一帧由 IDAT 块表示,否则每个帧至少需要一个 fdAT 块。

每帧的压缩数据流为该帧内所有 fdAT 块的 frame_data 字段内容按 sequence number 升序连接而成。

由于有序号,fdAT不得为零长度;但其 frame_data 字段可以为零长度。

解压后,该数据流为完整的像素数据,包含每条扫描线开头的滤波字节,类似于所有 IDAT 块的未压缩数据。它使用与静态图像相同的位深、color type、压缩方法、filter method、隔行方法以及调色板(如有)。

每个帧继承位于文件中第一个 IDAT 块之前的所有关键或辅助块所指定的属性,但宽度和高度来自对应的 fcTL 块。

如果 PNG 中存在 pHYs 块,则 APNG 图像及其 x_offsety_offset 值必须以与主图像相同的方式进行缩放。概念上,此类缩放在将输出缓冲区映射到 canvas 时发生。

Note

出于 Web 兼容性考虑,由于该块的开发与部署与其并入 PNG 规范之间间隔较长,该块名特例地按私有块定义。

12. PNG 编码器

简介

本条款给出了对编码器行为的要求和建议。PNG 编码器应当从一个 PNG 图像生成一个符合前述条款中所规定格式的 PNG 数据流。遵循此处给出的额外建议通常能得到更好的结果。

12.1 编码器伽玛处理

有关 C. 伽玛与色度 中的简要介绍,请参阅 gamma 相关问题。

具备完整色彩管理能力的 PNG 编码器将比此处描述的执行更复杂的计算,并可能选择使用 iCCP 块。如果已知图像采样符合 sRGB 规范 [SRGB], 强烈建议编码器写入 sRGB 块,而无需进行额外的 gamma 处理。在这两种情况下,建议生成一个适当的 gAMA 块,以供不识别 iCCPsRGB 块的 PNG 解码器使用。

PNG 编码器必须确定:

  1. gAMA 块中写入什么值;
  2. 如何将提供的图像采样转换为要写入 PNG 数据流的值。

写入 gAMA 块的值应当是能使 PNG 解码器按期望方式工作的那个值。参见 13.13 解码器伽玛处理

要应用的变换取决于图像样本的性质及其精度。如果样本以浮点或高精度整数形式表示光强(例如来自计算机图形渲染器),编码器可以在量化为整数并写入 PNG 数据流之前执行 伽玛编码(应用指数小于 1 的幂函数)。这样在给定采样深度下可减少条带伪影,或在保持相同视觉质量的同时使用更小的采样。取值范围 0 到 1 的浮点强度可以按下式转换为数据流中的图像采样:

integer_sample = floor((2sampledepth-1) * intensityencoding_exponent + 0.5)

如果上述方程中的 intensity 是期望的输出强度,则 encoding_exponent 即为应在 gAMA 块中使用的 gamma value

如果编码器可获得的是场景的原始强度,可能需要另一个变换。有时要求显示图像相对于原始源具有更高的对比度,这对应于从原始场景到显示输出的端到端 传递函数 的指数大于 1。在这种情况下:

gamma = encoding_exponent/end_to_end_exponent

如果无法确定原始图像捕获或计算的条件是否需要这种对比度变化,则可假定显示强度与原始场景强度成比例,即端到端指数为 1,因此:

gamma = encoding_exponent

如果图像仅写入数据流,编码器可以自由选择 encoding_exponent。通常将 gAMA 块中的 gamma 值设为 1/2.2 是一个合理选择,因为这会将解码器在典型视频监视器上显示时的工作量最小化。

一些图像渲染器可能同时将图像写入 PNG 数据流并在屏幕上显示。屏幕上显示的像素应根据正在使用的显示系统与观看条件进行 gamma 校正,以便用户看到与原始场景相符的正确表现。

如果渲染器想将已显示的采样值写入 PNG 数据流,从而避免对数据流进行单独的 伽玛编码,渲染器应通过幂函数近似显示系统的 传递函数,并将该幂函数的倒数写入 gAMA 块。这将允许 PNG 解码器重现渲染器在渲染期间在屏幕上显示的内容。

然而,渲染器也可以为显示设备计算合适的显示像素,并为数据存储与传输执行单独的 伽玛编码,并在 gAMA 块中写入更适合图像未来使用的值。

计算机图形渲染器通常不执行 伽玛编码,而是直接使样本值与场景光强成正比。如果 PNG 编码器接收到的样本值已经被量化为整数,则对它们再做 伽玛编码 没有意义;那只会造成额外的信息损失。编码器应将这些样本值直接写入 PNG 数据流。这并不意味着 gAMA 块应当包含 gamma value 为 1.0,因为从场景强度到显示输出强度的期望端到端 传递函数 不一定是线性的。不过,期望的 gamma value 可能接近 1.0。其值可能取决于场景是日光场景还是室内场景等因素。

当样本值直接来自硬件时,正确的 gAMA 值原则上可以从硬件的 传递函数 以及场景的照明条件推断出来。对于视频采集卡(“帧抓取器”),样本很可能处于 sRGB 色彩空间,因为 sRGB 规范设计时考虑了与现代视频标准的兼容性。图像扫描仪则更难预测:它们的输出可能与输入光强成正比(CCD 传感器本身是线性的),也可能在硬件层面上应用了用于补偿印刷点增益的幂函数(大约 0.57 的指数),或者已对样本进行显示校正。确定特定扫描仪的特性可能需要参考其手册或扫描一个校准目标。应记住 gamma 关系的是样本与期望显示输出之间的关系,而不是与扫描仪输入之间的关系。

数据流格式转换器通常不应试图将提供的图像转换为不同的 gamma。数据应在无转换情况下存储在 PNG 数据流中,并应尽可能从源数据流中推断出应写入的 gamma value。在数据流转换时改变 gamma 会导致所表示的强度级集合被重新量化,从而引入更多舍入误差而收益甚微。通常最好直接将输入样本值从输入复制到输出文件,而不进行转换。

如果源数据流描述了图像的 gamma 特性,强烈鼓励数据流转换器写入一个 gAMA 块。有些数据流格式指定的是显示指数(从图像样本映射到显示输出的函数的指数,而不是反方向)。如果源文件的 gamma value 大于 1.0,则它很可能是显示指数,应对该值取倒数以用于 PNG 的 gamma value。如果源文件格式记录的是图像样本与显示输出以外量之间的关系,则推断 PNG 的 gamma value 将更为复杂。

如果 PNG 编码器或数据流转换器知道图像在一个其 传递函数 可用幂函数近似且其指数为 display_exponent 的显示系统上已满意地显示过,则可以将图像标记为具有下列 gamma value

gamma = 1/display_exponent

写入一个近似正确的 gAMA 块要比省略该块并迫使 PNG 解码器猜测一个近似的 gamma value 更好。如果 PNG 编码器无法推断出 gamma value,则最好省略 gAMA 块。如果必须进行猜测,应将该任务留给 PNG 解码器。

gamma 不适用于 alpha 采样;alpha 始终以线性方式表示。

另见 13.13 解码器伽玛处理

12.2 编码器色彩处理

关于色彩问题的参考,请参阅 C. 伽玛与色度

具备完整色彩管理能力的 PNG 编码器将执行比此处描述的更复杂的计算,并可能选择使用 iCCP 块。如果已知图像采样符合 sRGB 规范 [SRGB],强烈建议 PNG 编码器使用 sRGB 块。

如果编码器能确定源显示器三基色的色度,或能根据图像的来源或运行它的硬件做出有力的猜测,强烈建议编码器输出 cHRM 块。如果写入了 cHRM 块,也应写入 gAMA 块;若没有 gAMA 块,解码器几乎无法利用 cHRM 块。

有关基色和 白点 的若干建议与标准,其中一些与特定技术相关,例如 CCIR 709 标准 [ITU-R-BT.709] 和 SMPTE-C 标准 [SMPTE-170M]。

需要考虑三种情况:

  1. 编码器是生成系统的一部分;
  2. 源图像由相机或扫描仪捕获;
  3. PNG 数据流是从其他格式转换生成的。

对于手绘或数字编辑的图像,有必要确定在创作过程中它们是在哪种显示器上被查看的。许多图像编辑程序允许指定所使用的显示器类型,这通常是因为它们在内部使用某种设备无关空间。此类程序拥有足够信息来写入有效的 cHRMgAMA 块,并强烈建议自动执行此操作。

如果编码器作为执行全光谱渲染的计算机图像渲染器的一部分进行编译,则用于将内部设备无关颜色空间转换为 RGB 的监视器值应写入 cHRM 块。任何超出所选 RGB 设备色域的颜色应映射到色域内;PNG 不存储超出色域的颜色。

如果计算机图像渲染器直接在设备相关的 RGB 空间中进行计算,则除非场景描述和渲染参数已针对特定显示器调整,否则不应写入 cHRM 块。在那种情况下,应使用该监视器的数据构造 cHRM 块。

一些图像格式存储校准信息,可用于填充 cHRM 块。例如,TIFF 6.0 文件 [TIFF-6.0] 可选择地存储校准信息,若存在此类信息,应使用其构造 cHRM 块。

使用近期视频设备创建的视频很可能采用 CCIR 709 基色和 D65 白点 [ITU-R-BT.709],其值列于 29

Table 29 CCIR 709 基色与 D65 白点
  R G B White
x 0.640 0.300 0.150 0.3127
y 0.330 0.600 0.060 0.3290

一个较旧但仍然流行的视频标准是 SMPTE-C [SMPTE-170M],其值见 30

Table 30 SMPTE-C 视频标准
  R G B White
x 0.630 0.310 0.155 0.3127
y 0.340 0.595 0.070 0.3290

建议数据流格式转换器尝试将提供的图像转换为不同的 RGB 色彩空间。数据应在 PNG 数据流中不经转换地存储,并应记录源基色的色度(如果已知)。在数据流转换时进行色彩空间变换通常不可取,原因是色域不匹配和舍入误差。与 gamma 转换类似,最好无损地存储数据,并在图像最终显示时最多执行一次转换。

另见 13.14 解码器色彩处理

12.3 Alpha 通道创建

Alpha 通道可以被看作是暂时隐藏图像透明部分的掩码,或者用来构造非矩形图像。在第一种情况下,完全透明像素的颜色值应当保留以备将来使用。在第二种情况下,透明像素不携带有用数据,仅用于填充 PNG 所需的矩形图像区域。在这种情况下,为获得最佳压缩,应将所有完全透明像素赋予相同的颜色值。

图像作者应记住,解码器可能不会完全支持透明控制(见 13.16 Alpha 通道处理)。因此,在可行的情况下,分配给透明像素的颜色应当尽量是合理的背景颜色。

对于不需要完整 alpha 通道或无法承受压缩效率代价的应用,也可以使用 tRNS 透明块。

如果图像有已知的背景色,应将该颜色写入 bKGD 块。即便忽略透明性的解码器也可以使用 bKGD 颜色来填充未用的屏幕区域。

如果原始图像具有预乘(也称为“关联”)alpha 数据,可以通过将每个样本值除以相应的 alpha 值,然后乘以图像位深的最大值,并四舍五入到最近的整数,将其转换为 PNG 的非预乘格式。在有效的预乘数据中,样本值从不超过相应的 alpha 值,因此除法结果应始终在 0 到 1 的范围内。如果 alpha 值为零,则输出黑色(零值)。

12.4 样本深度缩放

当编码输入样本的样本深度不能被 PNG 直接表示时,编码器应将样本缩放到 PNG 允许的样本深度。最精确的缩放方法是线性方程:

output = floor((input * MAXOUTSAMPLE / MAXINSAMPLE) + 0.5)

其中输入样本的范围为 0 到 MAXINSAMPLE,输出范围为 0 到 MAXOUTSAMPLE (即 2sampledepth-1)。

“左位复制”(left bit replication)可以近似线性缩放:将有效位移到最高有效位开始,并将最高有效位复制到开放的位中。该方法通常比线性缩放计算更快。

假设将 5 位样本扩展到 8 位。如果源样本值为 27(范围 0-31),则原始位为:

4 3 2 1 0
---------
1 1 0 1 1

左位复制得到的值为 222:

7 6 5 4 3  2 1 0
----------------
1 1 0 1 1  1 1 0
|=======|  |===|
    |      Leftmost Bits Repeated to Fill Open Bits
    |
Original Bits

该值与线性方程计算的值一致。左位复制通常与线性缩放给出相同的值,并且误差不会超过 1。

另一种不太精确的近似是简单地左移输入值并用零填充低位。该方案无法精确生成纯白(全 1)的最大值;其总体效果是使图像略微变暗。通常不推荐此方法,但在处理大于 8 位的样本深度时它有助于改善压缩。由于在高样本深度时零填充引入的相对误差较小,一些编码器可能选择使用它。但对于 alpha 通道数据不得使用零填充,因为许多解码器会将全零与全一的 alpha 值视为特殊情况。因此必须在缩放数据中精确表示这两个值。

当编码器写入 sBIT 块时,要求按这样的方式进行缩放:已存储样本的高位应与原始数据匹配。也就是说,如果 sBIT 块指定了 S 位的样本深度,则存储数据的高 S 位应与原始 S 位数据值一致。这样解码器可以通过右移恢复原始数据。低位没有约束。以上所有缩放方法都满足此限制。

在扩展源 图像数据 时,建议一致地填充低位;即相同的源值应在任何像素位置生成相同的样本值。这可以通过减少不同样本值的数量来改善压缩。这并非强制要求,某些编码器可能不遵循此建议,例如它们可能对低位执行抖动以提高显示图像质量,但代价是增大文件体积。

在某些应用中,原始源数据的范围可能不是 2 的幂次。线性缩放方程对这种情况仍然适用,而移位方法则不适用。建议在此类图像上不要写入 sBIT 块,因为 sBIT 暗示原始数据范围正好是 0..2S-1。

12.5 建议调色板

建议调色板可以作为 sPLT 块出现在任意 PNG 数据流中,或者作为 PLTE 块出现在 truecolor PNG 数据流中。在任一情况下,建议调色板并非 图像数据 的必需部分,但可用于在索引色显示硬件上呈现图像。对于运行在 truecolor 硬件上的查看器,建议调色板没有意义。

当使用 sPLT 块提供建议调色板时,建议编码器使用频率字段来指示调色板条目的相对重要性,而不是将它们全部置为零(表示未定义)。频率值最容易通过“最近邻”计数计算得到,即在不使用抖动的情况下每个 RGBA 调色板条目的近似使用量。(在构建建议调色板的过程中,通常可以“免费”获得这些计数。)由于建议调色板包含透明信息,应针对未合成的图像来计算它。

即使对于索引色图像,sPLT 也可用于为无法显示所有 PLTE 块中颜色的查看器定义替代的简化调色板。如果 PLTE 出现在没有 bKGD 块的 color type 6 的图像中,则未指定计算调色板时所处的环境。

truecolor PNG 数据流中包含建议调色板的旧方法是使用 PLTE 块。如果使用此方法,应在单独的 hIST 块中给出直方图(频率)。PLTE 块不包含透明信息。因此,对于 color type 6(truecolor with alpha)的图像,建议出现 bKGD 块,并以在与指定背景色合成后的图像为参考来计算调色板和直方图。这一定义是为了确保为具有分数 alpha 值的像素生成有用的调色板条目。所得的调色板可能仅对在相同背景色下呈现图像的查看器有用。建议 PNG 编辑器 在更改或删除 bKGD 块时删除或重新计算该调色板(对于 color type 6 的图像)。

对于 color type 2(truecolor)的图像,建议以仅参考 RGB 数据(忽略任何透明颜色规范)来计算 PLTEhIST 块。如果数据流使用透明性(有 tRNS 块),查看器可以轻松地根据其目标背景色调整所得调色板(参见 13.17 直方图与建议调色板的使用)。

在提供建议调色板方面,sPLT 块相对于 PLTE 块有下列优点:

  1. 使用 sPLT 可以提供多个建议调色板。PNG 解码器可以基于名称或条目数量选择合适的调色板。
  2. color type 6(truecolor with alpha)的数据流中,PLTE 块表示已相对于 bKGD 颜色进行合成的调色板,因此仅对针对该背景色显示有用。sPLT 块提供未合成的调色板,更适合解码器选择其自身背景进行显示时使用。
  3. 因为 sPLT 为辅助块,PNG 编辑器 可以添加或修改建议调色板而不必丢弃未知的不可安全复制块。
  4. 尽管 sPLT 块被允许在 color types 0、3 与 4(greyscaleindexed-color)的数据流中使用,但在这些情况下 PLTE 块无法用于提供简化调色板。
  5. sPLT 块中可以包含多于 256 个条目。

使用 sPLT 块的 PNG 编码器也可以选择同时写入由 PLTEhIST 表示的建议调色板,以便与不识别 sPLT 块的解码器兼容。

12.6 隔行

本规范定义了两种隔行方法,其中一种是不隔行。隔行为解码器提供了一个便于渐进式显示图像的基础,如 13.10 隔行与渐进显示 所述。

12.7 滤波选择

对于 color type 3(索引色)图像,滤波类型 0(None)通常是最有效的。具有 256 色或更少颜色的彩色图像几乎总是应以 indexed-color 格式存储;以 truecolor 格式存储可能会大得多。

对于位深小于 8 的图像,也推荐使用滤波类型 0。对于低位深灰度图像,在极少数情况下,先将图像扩展到 8 位再应用滤波可能得到更好的压缩。

对于 truecolorgreyscale 图像,五种滤波器中的任何一种都可能是最有效的。如果编码器使用固定滤波,Paeth 滤波类型最有可能表现最好。

为了在 truecolorgreyscale 图像上获得最佳压缩,并且当压缩效率比压缩速度更重要时,建议使用自适应滤波:为每条扫描线选择滤波类型。每幅图像最佳的滤波集合各不相同。编码器可以尝试所有滤波组合以找到对给定图像压缩效果最佳的方案。然而,当无法进行穷尽式搜索时,以下启发式方法通常效果足够好:对每条扫描线分别用五种滤波器生成输出,并选择能使输出字节绝对值之和最小的滤波器(在此测试中将输出字节视为有符号差值)。这种方法通常优于任何单一固定滤波类型的选择。

根据这些建议进行的滤波在与本规范定义的任一隔行方法配合时均有效。

12.8 压缩

编码器可以按任意方式将压缩后的数据流划分为 IDAT 块。(允许多个 IDAT 块,以便编码器在固定内存量下工作;通常块大小对应编码器的缓冲区大小。)一个 PNG 数据流中每个 IDAT 块仅包含一个数据字节的情况是有效的,尽管极其浪费空间。(零长度IDAT 块也是有效的,但更加浪费。)

12.9 文本块处理

每个文本块必须提供非空关键字。如果没有更合适的描述,可以使用通用关键字 "Comment"。如果使用用户提供的关键字,编码器应检查其是否符合关键字的限制。

iTXt 块使用 Unicode 的 UTF-8 编码,因此可以存储任何语言的文本。tEXtzTXt 块使用 Latin-1(ISO 8859-1)字符编码,这限制了这些块中可用字符的范围。编码器应优先使用 iTXt,而不是 tEXtzTXt,以允许广泛字符而不丢失数据。编码器必须在存储文本时将使用本地传统字符编码的字符转换为相应的目标编码(参见 legacy character encodings)。

创建 iTXt 块时,编码器应遵循 Encoding Standard 中的 UTF-8 encode 规范。

编码器应劝阻创建长度超过 79 个 Unicode code points 的单行文本,以便易于阅读。建议将小于 1024 字节的文本项以未压缩文本块输出。建议将基本的标题和作者关键字使用未压缩的文本块输出。将大文本块放在 图像数据 之后(即 IDAT 块之后)在某些情况下可以加快图像显示,因为解码器会先解码 图像数据。建议将小文本块(例如图像标题)放在 IDAT 块之前。

12.10 分块(Chunking)

12.10.1 使用私有块

编码器 MAY 使用私有块来携带不必被其他应用理解的信息。

12.10.2 使用非保留字段值

编码器 MAY 使用非保留的字段值进行实验或私用。

12.10.3 辅助块

所有辅助块均为可选,编码器无需写入它们。不过,当相关信息可用时,鼓励编码器写入标准的辅助块。

13. PNG 解码器与查看器

简介

本条款给出了一些关于 PNG 解码器行为与查看器行为的要求与建议。查看器将解码后的 PNG 图像呈现给用户。由于查看器与解码器行为密切相关,这里将二者一并讨论。对 PNG 解码器的唯一绝对要求是它必须能成功读取任何符合前述章节中指定格式的数据流。然而,遵循下列附加建议通常会得到更好的效果。

PNG 解码器应支持本国际标准中明确定义的所有有效的位深、颜色类型、压缩方法、滤波方法和隔行方法的组合。

13.1 错误处理

PNG 数据流中的错误大致可分为两类:传输错误与语法错误(见 4.10 错误处理)。

传输错误的例子包括以“文本”或“ascii”模式传输,在此模式下字节码 13 和/或 10 可能在整个数据流中被添加、删除或转换;意外终止,即数据流被截断;或存储设备的物理错误,其中一个或多个块(通常为每块 512 字节)会出现损坏或随机值。语法错误的例子包括行滤波器的无效值、无效的压缩方法、无效的块长度、在索引图像中第一个 IDAT 块之前缺少 PLTE 块,或存在多个 gAMA 块。PNG 解码器应如下处理错误:

  1. 尽早检测到错误,利用 PNG 签名字节和每个块的 CRC。解码器应验证 PNG 签名的全部八个字节是否正确。如果接下来的八个字节以正确的块长度开始一个 IHDR 块,则可进一步增强对数据流完整性的信心。在处理块数据之前应检查校验和(CRC)。有时这并不现实,例如当流式 PNG 解码器正在处理一个大型 IDAT 块时。在这种情况下,应在到达该块结尾时检查 CRC
  2. 在可能的情况下从错误中恢复;否则优雅地失败。对图像处理影响很小或没有影响的错误可以被忽略,而那些影响关键数据的错误应以适合应用的方式处理。
  3. 提供有助于理解的错误描述信息,包括可恢复错误的说明。

与此理念相关的三类 PNG 块如下。这里定义的“未知块”要么是解码器作者确实不知道其类型的块,要么是作者选择将其视为未知的块(因为对该块类型的默认处理对程序目的已足够)。其他块称为“已知块”。在此定义下,三类为:

  1. 已知块,这必然包括本规范中定义的所有关键块(IHDRPLTEIDATIEND
  2. 未知的关键块(块类型第一个字节的位 5 为 0)
  3. 未知的辅助块(块类型第一个字节的位 5 为 1)

有关块命名约定的描述,请参阅 5.4 块命名约定

PNG 块类型根据它们对提取可查看图像(例如 IHDRPLTEIDAT)或对理解数据流结构(例如 IEND)的重要性,被标记为“关键”或“辅助”。这是一类特定的关键性,并不一定适用于每一种解码器。例如,仅用于提取文本注释(如版权信息)的程序并不需要可查看图像,但应能正确 解码 UTF-8。另一个解码器可能认为 tRNSgAMA 块对其正确执行是必需的。

语法错误总是牵涉到已知块,因为在未知块中不能检测出语法错误。PNG 解码器必须根据其需求和情形判断语法错误是否为致命(不可恢复)的。例如,大多数解码器可以忽略一个无效的 IEND 块;文本提取程序可以忽略缺少 IDAT;图像查看器无法从索引图像中空的 PLTE 块中恢复,但可以忽略真彩色图像中无效的 PLTE 块;提取 alpha 通道的程序可以忽略无效的 gAMA 块,但可能认为存在两个 tRNS 块是致命错误。除语法错误外的异常情况应如下处理:

  1. 遇到未知的辅助块从来都不是错误。该块可以简单地被忽略。
  2. 遇到未知的关键块对于任何试图从数据流提取图像的解码器而言都是致命情况。若解码器忽略了关键块,则无法知道它提取的图像是否为编码器意图的图像。
  3. PNG 签名不匹配、CRC 不匹配或意外的流结尾表示数据流已损坏,可视为致命错误。解码器可以尝试从数据流中挽救一些内容,但损坏的程度无法预知。

当发生致命情形时,解码器应立即失败、在适当时向用户报告错误,并可选择继续显示用户已见到的任何 图像数据(即“优雅失败”)。整个应用程序无需终止。

当发生非致命错误时,解码器应在适当时向用户发出警告、从错误中恢复并继续正常处理。

在解码索引色 PNG 时,如果遇到越界的索引,解码器历来在处理此错误上有不同做法。将像素显示为不透明的黑色 是一种常见的错误恢复策略,并且本规范现已要求如此。旧的实现可能有所不同,因此编码器不应依赖解码器会有相同的行为。

不计算 CRC 的解码器应将明显的语法错误解释为数据损坏的迹象(另见 13.2 错误检查)。

压缩块(IDATzTXtiTXtiCCP)中的错误可能导致缓冲区溢出。deflate 解压器的实现者应防范此类可能性。

APNG 的设计允许在未读取完整个 数据流 之前逐帧增量显示。这意味着有些错误可能直到动画部分播放期间才被检测到。强烈建议在遇到任何错误时,解码器应丢弃所有后续帧、停止动画并恢复显示静态图像。若在动画开始前检测到错误,应显示静态图像。如适当,可向用户显示错误信息。

解码器应将乱序的 APNG 块视为错误。了解 APNG 的 PNG 编辑器 应使用序列号将其恢复到正确顺序。

13.2 错误检查

PNG 的错误处理理念见 13.1 错误处理

除非未知块是关键块,否则未知块类型不应被视为错误。

可通过检查四个字节是否都在 41-5A 和 61-7A(十六进制)范围内来检验块类型的合理性;注意仅需对未识别的块类型执行此检查。如果已知整个数据流大小(来自文件系统信息、HTTP 协议等),也可以检查块长度是否合理。如果不检查 CRC,丢失/添加字节或错误的块长度可能导致解码器步调错乱并将后续数据误解释为块头。

对于已知长度的块,例如 IHDR,解码器应将意外的块长度视为错误。本规范的将来扩展不会向现有块添加新字段;相反,会添加新的块类型来承载新信息。

应检查并将已知块字段中出现的意外值(例如 IHDR 块中的意外压缩方法)视为错误。然而,建议仅在关键块中将意外字段值视为致命错误。辅助块中的意外字段值可以通过忽略整个块并将其视为未知块来处理。(该建议假定块的 CRC 已通过验证。在不检查 CRC 的解码器中,将任何意外值视为数据流损坏的迹象更为安全。)

标准 PNG 图像应使用压缩方法 0 进行压缩。IHDR 块中的压缩方法字段保留以供将来标准化或专有变体使用。解码器应检查该字节并在其含有未识别的代码时报告错误。详情见 10. 压缩

13.3 安全注意事项

PNG 数据流由一系列明确定义类型的块组成。规范定义内容的块实际上可以包含任何东西,包括恶意代码。同样,IEND 块之后可能还存在数据,这些数据也可以包含任何内容,包括恶意代码。已知不存在因仅仅解码 PNG 图像而在接收者计算机上执行此类恶意代码的风险。然而,恶意应用可能将此类代码隐藏在看似无害的图像文件中,然后执行它。

与未来块类型相关的潜在安全风险目前无法详尽规定。定义将来公共块时会考虑安全问题。未知或未实现的块类型没有额外的安全风险,因为此类块将被忽略,或者至多被复制到另一个 PNG 数据流中。

iTXttEXtzTXt 块包含要作为纯文本显示的关键字与数据。iCCPsPLT 块也包含意在显示为纯文本的关键字。如果解码器在显示这些文本时不过滤控制字符,尤其是 ESC(转义)字符,某些系统或终端可能会出现不期望或不安全的行为。建议解码器过滤控制字符以避免此类风险;参见 13.7 文本块处理

对于 eXIf 块,Exif 规范 [CIPA-DC-008] 并未明确要求标签的“值偏移”指针必须实际指向文件内的有效地址。该要求只是隐含的(参见描述 Exif IFD 结构的第 4.6.2 段)。无论如何,解码器应准备好遇到无效指针并适当处理它们。

每个块都以长度字段开始,这使得编写对试图通过伪造块溢出缓冲区的攻击免疫的解码器更容易。每个块末尾的 CRC 为防止意外损坏提供了稳健的防御。PNG 签名字节可早期检测常见的文件传输错误。

未检查 CRC 的解码器可能遭受数据损坏。此类损坏最可能的后果是图像内像素显示错误。更糟的是,如果不检查 CRCIHDR 块被破坏,其宽度或高度字段被篡改,可能导致更严重的问题。参见 13.2 错误检查

不良实现的解码器可能容易发生缓冲区溢出,因为块可以非常大,最大可达 231-1 字节。但正确编写的解码器能够处理大型块而不会遇到问题。

13.4 隐私注意事项

一些图像编辑工具历史上通过仅将被编辑区域的 alpha 通道设为零来执行“涂黑”处理,而没有同时删除实际图像数据。仅依赖图像视觉外观的用户因此面临隐私风险,因为实际图像数据可能被轻易恢复。

同样,一些图像编辑工具历史上通过重写 IHDR 中的宽度和高度来执行裁剪,而不重新编码图像数据,导致图像数据超出新宽度和高度并可能被恢复。

包含 eXIf 块的图像可能包含自动添加的数据,例如照片的 GPS 坐标,如果用户不知道 PNG 图像包含这些数据,则可能构成隐私风险。(其他包含 Exif 的图像格式,如 JPEG/JFIF,也存在相同的隐私风险。)

13.5 分块(Chunking)

解码器应通过四字节的逐字面比较识别块类型;对块类型执行大小写转换是不正确的。解码器在遇到未知且辅助位为 1 的块时可以安全地忽略该块并继续显示图像。若在遇到未知且辅助位为 0(表示关键块)的块时,试图提取图像的解码器应向用户指示该图像包含不能安全解释的信息。

解码器应通过数值测试指定位来测试未知块类型的属性。测试字符是大写还是小写既效率低下且错误(若使用依赖于区域设置的大小写定义时)。

解码器不应在保留位被设为 1 时标记为错误,因为 PNG 规范的将来某个版本可能会为该位定义含义。将该位设为 1 的块与其他未知块类型以相同方式对待即可。

解码器无需测试块类型的私有位,因为该位没有功能意义,用于避免 W3C 定义的块与私人定义的块之间发生冲突。

所有辅助块都是可选的;解码器可以忽略它们。然而,解码器在适当且可行时应被鼓励解释这些块。

13.6 像素尺寸

可以表示非方形像素(见 11.3.4.3 pHYs 物理像素尺寸),但查看器并不被要求对其进行校正;查看器可以将任何 PNG 数据流当作其像素为方形进行呈现。

当显示器的像素纵横比与 PNG 数据流中定义的物理像素尺寸的纵横比不同时,强烈建议查看器对图像进行重缩放以便正确显示。

pHYs 块的单位说明符为 0(单位未知)时,解码器的行为可依赖于两个像素每单位值的比率,但不应依赖它们的大小。例如,包含 (ppuX, ppuY, unit) = (2, 1, 0)pHYs 块等价于包含 (1000, 500, 0) 的块;两者同样有效地表明图像像素的高度是宽度的两倍。

查看器处理图像与显示像素纵横比不一致的一种合理方法是仅沿水平方向或垂直方向扩展图像,而不是同时扩展两个方向。缩放因子可以使用以下浮点计算得到:

image_ratio = pHYs_ppuY / pHYs_ppuX
display_ratio = display_ppuY / display_ppuX
scale_factor_X = max(1.0, image_ratio/display_ratio)
scale_factor_Y = max(1.0, display_ratio/image_ratio)

由于保持图像面积等其他方法也合理,并且忽略 pHYs 块也是允许的,因此作者不应假定所有查看应用都会使用此缩放方法。

除为像素纵横比作校正之外,查看器可能还会出于其他原因对图像在横向和纵向上进行额外缩放。例如,查看器可能希望将过大的图像缩小以适配显示器,或将发送到高分辨率打印机的图像放大以便它们在打印后看起来与在显示器上相同大小。

13.7 文本块处理

如果可行,PNG 解码器应提供一种方式向用户显示数据流中发现的所有 iTXttEXtzTXt 块。即使解码器不识别某个文本关键字,用户也可能理解其含义。

在处理 tEXtzTXt 块时,解码器可能会遇到不允许的字符。有些字符可以安全显示(例如 TAB、FF 与 CR,分别为十六进制 09、0C 与 0D),但其他字符,尤其是 ESC(十六进制 1B),可能构成安全隐患(因为显示硬件或软件可能会执行意外动作)。解码器不应尝试直接显示在 tEXtzTXt 块中遇到的非 Latin-1 字符(换行与可能的 TAB 除外)。相反,应忽略这些字符或以可见记号显示,例如 "\nn"。参见 13.3 安全注意事项

在处理 iTXt 块时,解码器应遵循 Encoding Standard 中的 UTF-8 decode

尽管建议编码器将换行表示为行结束符(十六进制 0A),但建议解码器不要依赖此约定;最好识别所有常见的换行组合(CR、LF 与 CR-LF)并将其显示为单个换行符。TAB 可扩展为足够的空格以到达列的 8 的倍数。

在使用非 Latin-1 的本地 传统字符编码 的系统上运行的解码器应重新映射字符码以便正确显示 Latin-1 字符。不受支持的字符应被替换为系统适当的替代字符(例如 U+FFFD REPLACEMENT CHARACTER、U+003F QUESTION MARK 或 U+001A SUB),或映射为可见记号如 "\nn"。仅当字符在解码系统上为可打印字符时才应显示。某些字节值可能被解码系统解释为控制字符;出于安全考虑,在此类系统上运行的解码器不应显示这些控制字符。

解码器应准备显示包含任意数量打印字符(在换行字符之间)的文本块,尽管建议编码器避免创建超过 79 个字符的行。

13.8 解压缩

本规范使用的压缩技术并不要求在开始解压之前获取完整的压缩数据流。因此可以在整个解压数据流可用之前开始显示。极不可能在本规范将来的版本中采用不具备此特性的通用压缩方法。

需要强调的是,IDAT 块边界没有语义意义,可以出现在压缩数据流中的任意位置。图像数据的结构(例如扫描线边界)与 deflate 块边界或 IDAT 块边界之间没有必然关联。完整的图像数据由单一的 zlib 数据流表示,并存储在若干个 IDAT 块中;假定超过此点的关系是错误的。某些编码器实现可能会产生这些结构相关的数据流,但解码器不得依赖于此。

13.9 滤波

为了还原滤波的效果,解码器可能需要使用同一行上前一个像素的解码值、上一行中当前像素上方的像素,以及上方像素的左侧像素。这意味着解码器至少需要始终保存一行扫描线长度的 图像数据。尽管某些滤波类型不引用上一扫描线,解码器仍需在解码时始终存储每条扫描线,因为下一条扫描线可能使用引用它的滤波类型。详见 7.3 滤波

13.10 隔行与渐进显示

解码器必须能够读取隔行图像。如果参考图像少于五列或少于五行,则某些通道将为空。编码器和解码器应正确处理此情况。特别地,滤波类型字节仅与非空扫描线相关;在空的缩小图像中不存在滤波类型字节。

在慢速传输链接上接收图像时,查看器可以通过渐进显示隔行图像来改善感知性能。这意味着当接收到每个缩小图像时,基于至今接收到的数据显示对完整图像的近似。一种简单而令人满意的效果是将每个接收到的像素扩展为一个矩形,覆盖尚未传输的位于该像素下方和右侧的位置。该过程可以由下述 ISO C 代码描述 [ISO_9899]:

/*
    variables declared and initialized elsewhere in the code:
        height, width
    functions or macros defined elsewhere in the code:
        visit(), min()
 */

int starting_row[7]  = { 0, 0, 4, 0, 2, 0, 1 };
int starting_col[7]  = { 0, 4, 0, 2, 0, 1, 0 };
int row_increment[7] = { 8, 8, 8, 4, 4, 2, 2 };
int col_increment[7] = { 8, 8, 4, 4, 2, 2, 1 };
int block_height[7]  = { 8, 8, 4, 4, 2, 2, 1 };
int block_width[7]   = { 8, 4, 4, 2, 2, 1, 1 };

int pass;
long row, col;

pass = 0;
while (pass < 7)
{
    row = starting_row[pass];
    while (row < height)
    {
        col = starting_col[pass];
        while (col < width)
        {
            visit(row, col,
                  min(block_height[pass], height - row),
                  min(block_width[pass], width - col));
            col = col + col_increment[pass];
        }
        row = row + row_increment[pass];
    }
    pass = pass + 1;
}

函数 visit(row,column,height,width) 获取下一个传输的像素并绘制一个指定高度与宽度的矩形,该矩形的左上角位于指定的行与列,用像素指示的颜色填充。注意行与列以左上角的 (0,0) 为起点计数。

如果查看器将接收到的图像与背景图像合并,可能更方便只绘制接收到的像素位置(即 visit() 函数仅设置指定行列的像素,而不是整个矩形)。这会产生一种“渐显”效果,随着新图像逐步替换旧图像而显现。该方法的一个优点是可以在每个像素被替换时执行正确的 alpha 或透明度处理。如前所述,按上述方式绘制矩形会覆盖背景图像的像素;如果以后接收到的那些位置的像素是完全或部分透明的,则这些背景像素可能需要被保留。这仅在背景图像未在屏外存储时成为问题。

13.11 真彩色图像处理

为了实现 PNG 的通用可互换性目标,解码器应接受所有类型的 PNG 图像:索引色真彩色,以及 灰度。运行在索引色显示硬件上的查看器需要能够将 真彩色 图像降级为索引色以便显示。该过程称为“色彩量化”。

一种简单且快速的色彩量化方法是将图像减少到一个固定的调色板。通常使用均匀色彩间隔的调色板(“色彩立方体”)以最小化每像素的计算。对于照片类图像,建议使用抖动以避免本应为平滑渐变区域出现难看的阶梯状轮廓;不过抖动会引入颗粒感,可能令人不悦。

通过使用为特定图像专门挑选的调色板,可以显著提高渲染质量,因为色彩立方体通常包含许多在特定图像中未被使用的条目。这种方法需要更多工作:首先是选择调色板,其次是将单个像素映射到最近的可用颜色。PNG 允许编码器提供建议调色板,但并非所有编码器都会这样做,而且建议调色板在任何情况下可能都不适用(颜色数量可能过多或过少)。因此,高质量的查看器需要具备调色板选择例程。使用大型查找表通常是以足够速度将单个像素映射到调色板条目的最可行方法。

有许多色彩量化的实现可用。PNG 示例实现 libpng (http://www.libpng.org/pub/png/libpng.html) 包含用于该目的的代码。

13.12 样本深度重缩放

解码器可能希望将 PNG 数据缩减到更低的样本深度(数据精度)以供显示。例如,16 位数据需要被降至 8 位以用于大多数现有显示硬件。将 8 位数据降至 5 位也很常见。

最精确的缩放由线性方程实现

output = floor((input * MAXOUTSAMPLE / MAXINSAMPLE) + 0.5)

其中

MAXINSAMPLE = (2sampledepth)-1
MAXOUTSAMPLE = (2desired_sampledepth)-1

稍微不那么精确的一种转换方法是简单地右移 (sampledepth - desired_sampledepth) 位。例如,要将 16 位样本降至 8 位,可以丢弃低位字节。在许多情况下,移位方法对于显示来说足够精确,而且速度要快得多。(但如果正在进行 gamma 校正,则样本重缩放可以并入 gamma 校正的查找表,如 13.13 解码器伽玛处理 中所示。)

如果解码器需要将样本放大(例如,若 帧缓冲区 的样本深度大于 PNG 图像),则应使用线性缩放或在 12.4 样本深度缩放 中所述的左位复制方法。

当存在 sBIT 块时,可以通过右移到 sBIT 指定的样本深度来恢复参考的 图像数据。注意线性缩放不必然重现原始数据,因为编码器并非必须使用线性缩放将数据放大。然而,编码器必须使用一种保留高位的方法,所以右移总是有效。这是移位在某些情况下被认为比线性缩放更精确的唯一情形。解码器不必关注 sBIT 块;已存储的图像是一个有效的由 IHDR 指示的样本深度的 PNG 数据流;不过,在缩放到适合显示之前利用 sBIT 恢复原始样本通常能比忽略 sBIT 得到更准确的显示。

当将像素值与 tRNS 块值比较以检测透明像素时,应精确进行比较。因此,透明像素检测应在降低样本精度之前完成。

13.13 解码器伽玛处理

有关 gamma 问题的简要介绍,请参见 C. 伽玛与色度

具备完整色彩管理能力的查看器会执行比此处描述的更复杂的计算。

为了使图像显示程序产生正确的色调再现,必须考虑样本与显示输出之间的关系,以及显示系统的 传递函数。这可以通过计算来实现:

sample = integer_sample / (2sampledepth - 1.0)
display_output = sample1.0/gamma
display_input = inverse_display_transfer(display_output)
framebuf_sample = floor((display_input * MAX_FRAMEBUF_SAMPLE)+0.5)

其中 integer_sample 是来自数据流的样本值,framebuf_sample 是写入 帧缓冲区 的值,MAX_FRAMEBUF_SAMPLE 是帧缓冲区样本的最大值(8 位为 255,5 位为 31,等等)。第一行将整数样本转换为归一化的浮点值(范围 0.0 到 1.0),第二行转换为与期望显示输出强度成比例的值,第三行考虑显示系统的 传递函数,第四行将其转换为整数帧缓冲样本。零的任何正次幂仍为零。

可以在第二行和第三行之间插入一步,用以调整 display_output,以考虑实际观看条件与参考观看条件之间的差异。然而,这种调整需要考虑眩光、黑电平映射和色彩外观模型,这些均不能很好地用幂函数近似描述。此类计算在此不作说明。如果忽略观看条件,误差通常很小。

显示的 传递函数 通常可用指数 display_exponent 的幂函数近似,在这种情况下第二行和第三行可以合并为:

display_input = sample1.0/(gamma * display_exponent) = sampledecoding_exponent

从而只需执行一次幂运算。对于彩色图像,上述计算需要分别对 R、G 和 B 值执行。

gamma value 可以直接从 gAMA 块取得。或者,应用程序可允许用户通过影响 gamma value 来调整显示图像的外观。例如,用户可以手动设置参数 user_exponent(默认为 1.0),应用可以设置:

gamma = gamma_from_file / user_exponent
decoding_exponent = 1.0 / (gamma * display_exponent)
   = user_exponent / (gamma_from_file * display_exponent)

用户将 user_exponent 设大于 1 可使中间调变暗,设小于 1 可使其变亮。

包含零的 gAMA 块是没有意义的,但可能误写。解码器应忽略它,编辑器可丢弃并向用户发出警告。

并非必须对每个像素执行超越函数运算。可以预先计算一个查找表,为每个可能的样本值给出正确的输出值。对于 8 位精度,这只需对图像进行 256 次计算,而不是每像素或每色度进行计算。对于索引色图像,对调色板进行一次性校正就足够,除非图像使用透明度且在非均一背景上显示。

如果无法使用浮点运算,gamma 校正表可用整数算术和预计算的对数表来构建。示例代码见 [PNG-EXTENSIONS]。

当输入图像的 gamma value 未知时(缺少 gAMAsRGBiCCP),独立的图像查看器应选择一个可能的默认 gamma value,但应允许用户在结果过暗或过亮时选择新的值。默认的 gamma value 可能取决于关于图像的其他信息,例如它是来自互联网还是本地系统。为一致起见,文档格式(如 HTML)或矢量图形(如 SVG)的查看器在处理嵌入或链接的未知 gamma value 的 PNG 图像时,应与处理其他未标记图像的方式保持一致。

在实践中,确定应使用何种 display_exponent 常常很困难。在没有内建 gamma 校正的系统中,显示指数完全由 CRT 决定。除非有针对特定 CRT 的详细校准测量,否则应使用 2.2 的显示指数。

许多现代 帧缓冲 具有用于执行 gamma 校正的查找表,在这些系统上显示指数值应为查找表与 CRT 的组合指数。查看器应用内部可能无法得知查找表的内容,因而可能需要向用户询问显示系统的指数值。不幸的是,不同厂商使用不同方式来指定查找表内容,因此系统 gamma value 的解释与系统相关。

真实显示器的响应实际上比单个数值(显示指数)所能描述的要复杂得多。如果有监视器的实际测量数据(输出亮度随电压的变化),上述计算中的第三行和第四行可以被这些测量值的查表替换,以找到最接近所需亮度的实际 帧缓冲 值。

13.14 解码器色彩处理

有关色彩问题的参考,请参见 C. 伽玛与色度

在许多情况下,PNG 数据流中的 图像数据 会被视为设备相关的 RGB 值并直接显示(仅做适当的 gamma 校正)。这提供了最快的 PNG 显示方式。但除非查看器使用与原始图像作者完全相同的显示硬件,否则颜色不会与作者看到的完全一致,尤其是较暗或接近中性颜色时。cHRM 块提供了比单纯 gamma 校正更接近的颜色匹配信息。

cHRM 数据可用于将 图像数据 从 RGB 转换为 XYZ,继而进入感知线性的色彩空间(例如 CIE LAB)。颜色可以在该空间中被划分以生成最优调色板,因为在 CIE LAB 中两种颜色的几何距离与它们在视觉上的差异高度相关(不同于例如 RGB 或 XYZ 空间)。将得到的颜色调色板再转换回 RGB 空间后,可用于显示或写入 PLTE 块。

作为图像处理应用一部分的解码器也可能将 图像数据 转换到 CIE LAB 空间以便分析。

在对色彩一致性要求极高的应用(如产品设计、科学可视化、医学、建筑或广告)中,PNG 解码器可以将 图像数据 从源 RGB 转换为用于查看图像的显示器的显示 RGB 空间。这涉及计算从源 RGB 到 XYZ 的矩阵,以及从 XYZ 到显示 RGB 的矩阵,然后合并以产生总体变换。PNG 解码器负责实现色域映射。

在具有色彩管理系统(CMS)的平台上运行的解码器可以将 图像数据gAMAcHRM 值传递给 CMS 以供显示或进一步处理。

提供颜色打印功能的 PNG 解码器可以使用 PostScript Level 2 中的功能,在校准的 RGB 空间或设备无关的色彩空间(如 XYZ)中指定 图像数据。这将比简单的 RGB 到 CMYK 转换提供更好的色彩保真度。PostScript 语言参考手册 [PostScript] 给出示例。此类解码器负责在源 RGB(在 cHRM 块中指定)与目标打印机之间实现色域映射。随后由 PostScript 解释器负责产生所需颜色。

PNG 解码器可以使用 cHRM 数据来计算颜色图像的准确灰度表示。将 RGB 转换为灰度只是计算 XYZ 的 Y(亮度)分量,这是 R、G、B 值的加权和。权重取决于显示器类型,即 cHRM 块中的值。对于没有 cHRM 块的 PNG 数据流,解码器可能希望进行此转换。在这种情况下,使用 CCIR 709 基色 [ITU-R-BT.709] 作为合理的默认值是可行的。原始的 NTSC 基色 应被使用,除非 PNG 图像确实是为那类显示器进行过色彩平衡的。

13.15 背景色

bKGD 块给出的背景色通常用于填充图像周围未被占用的屏幕空间,以及图像内的任何透明像素。(因此,即便图像不使用透明度,bKGD 也是有效且有用的。)如果不存在 bKGD 块,查看器需要选择一个合适的背景色。若无其他信息可用,使用例如 8 位 sRGB 色彩空间中的中灰(如 153)是一个合理的选择。透明的黑色或白色文字以及常见的深色投影在该背景上都应具有良好可读性。

具有特定背景以呈现图像的查看器(例如网页浏览器)应忽略 bKGD 块,从而以其首选的背景颜色或背景图像覆盖 bKGD

bKGD 块给出的背景色不应被视为透明,即使它恰好与 tRNS 块给出的颜色相匹配(或者在索引色图像的情况下,引用了被 tRNS 标记为透明的调色板索引)。否则就必须设想“在背景之后”还有某个东西用于与之进行 合成。背景颜色要么被用作背景,要么被忽略;它不是 PNG 图像与其他背景之间的中间层。

事实上,bKGDtRNS 块常常指定相同的颜色,因为这样在没有实现透明处理的解码器上,当不存在部分透明像素时,显示效果会符合预期。

13.16 Alpha 通道处理

Alpha 通道可用于将前景图像与背景图像进行 合成。PNG 数据流定义前景图像和透明度掩码,但不定义背景图像。PNG 解码器要求支持这种最一般的情况。期望大多数解码器至少能支持相对于单一背景色的合成。

用于计算合成样本值的方程为:

output = alpha * foreground + (1-alpha) * background

其中 alpha 以及输入与输出样本值均以 0 到 1 的分数表示。该计算应在强度样本上执行(而非 gamma 编码的样本)。对于彩色图像,该计算应分别对 R、G、B 样本执行。

下面的代码演示了将前景图像相对于背景图像进行合成的一般情况。它假设背景图像的原始像素数据可用,且输出目标为用于显示的 帧缓冲区。还存在其他变体;见代码下方的注释。该代码允许前景图像与背景图像的样本深度和 gamma 值 各不相同,且未必适合显示系统。实践中在未先检查之前不应做出相等性的假设。

该代码为 ISO C [ISO_9899],在注释中加入了行号以便参考。

01  int foreground[4];  /* image pixel: R, G, B, A */
02  int background[3];  /* background pixel: R, G, B */
03  int fbpix[3];       /* frame buffer pixel */
04  int fg_maxsample;   /* foreground max sample */
05  int bg_maxsample;   /* background max sample */
06  int fb_maxsample;   /* frame buffer max sample */
07  int ialpha;
08  float alpha, compalpha;
09  float gamfg, linfg, gambg, linbg, comppix, gcvideo;

    /* Get max sample values in data and frame buffer */
10  fg_maxsample = (1 << fg_sample_depth) - 1;
11  bg_maxsample = (1 << bg_sample_depth) - 1;
12  fb_maxsample = (1 << frame_buffer_sample_depth) - 1;
    /*
     * Get integer version of alpha.
     * Check for opaque and transparent special cases;
     * no compositing needed if so.
     *
     * We show the whole gamma decode/correct process in
     * floating point, but it would more likely be done
     * with lookup tables.
     */
13  ialpha = foreground[3];

14  if (ialpha == 0) {
        /*
         * Foreground image is transparent here.
         * If the background image is already in the frame
         * buffer, there is nothing to do.
         */
15      ;
16  } else if (ialpha == fg_maxsample) {
        /*
         * Copy foreground pixel to frame buffer.
         */
17      for (i = 0; i < 3; i++) {
18          gamfg = (float) foreground[i] / fg_maxsample;
19          linfg = pow(gamfg, 1.0 / fg_gamma);
20          comppix = linfg;
21          gcvideo = pow(comppix, 1.0 / display_exponent);
22          fbpix[i] = (int) (gcvideo * fb_maxsample + 0.5);
23      }
24  } else {
        /*
         * Compositing is necessary.
         * Get floating-point alpha and its complement.
         * Note: alpha is always linear; gamma does not
         * affect it.
         */
25      alpha = (float) ialpha / fg_maxsample;
26      compalpha = 1.0 - alpha;

27      for (i = 0; i < 3; i++) {
            /*
             * Convert foreground and background to floating
             * point, then undo gamma encoding.
             */
28          gamfg = (float) foreground[i] / fg_maxsample;
29          linfg = pow(gamfg, 1.0 / fg_gamma);
30          gambg = (float) background[i] / bg_maxsample;
31          linbg = pow(gambg, 1.0 / bg_gamma);
            /*
             * Composite.
             */
32          comppix = linfg * alpha + linbg * compalpha;
            /*
             * Gamma correct for display.
             * Convert to integer frame buffer pixel.
             */
33          gcvideo = pow(comppix, 1.0 / display_exponent);
34          fbpix[i] = (int) (gcvideo * fb_maxsample + 0.5);
35      }
36  }

变体:

  1. 如果输出目标是另一个 PNG 数据流而不是 帧缓冲区,则第 21、22、33 和 34 行应按下列方式修改
    /*
     * Gamma encode for storage in output datastream.
     * Convert to integer sample value.
     */
    gamout = pow(comppix, outfile_gamma);
    outpix[i] = (int) (gamout * out_maxsample + 0.5);
    此外,当 alpha 为零时,需要处理背景像素而非仅跳过像素。因此,第 15 行需要被用处理背景像素(而非前景像素值)的第 17-23 行的拷贝替换。
  2. 如果输出文件、前景文件与背景文件的样本深度都相同,且三者的 gamma 值 也匹配,则无合成代码(第 14-23 行)在 alpha 为 1 时可简化为从输入文件复制像素值到输出文件,在 alpha 为 0 时复制背景到输出。由于在图像中绝大多数像素的 alpha 通常为零或一,这将节省大量计算。对大多数像素不需要进行 gamma 运算。
  3. 当样本深度与 gamma 值 都匹配时,看似可以跳过 gamma 解码/编码(第 28-31 行、33-34 行),而仅用第 32 行对 gamma 编码的样本值执行合成。尽管这对图像质量影响不大,但如果将零和一的 alpha 视为特殊情况(如此处建议),节省的时间并不显著。
  4. 如果背景图像的原始像素值不可得,只有通过显示背景图像留下的处理后 帧缓冲 像素可用,则第 30 和 31 行需要通过例如如下代码从帧缓冲像素值中提取强度:
    /*
     * Convert frame buffer value into intensity sample.
     */
    gcvideo = (float) fbpix[i] / fb_maxsample;
    linbg = pow(gcvideo, display_exponent);
    不过这可能产生一些四舍五入误差,因此如果可能,最好使用原始背景像素。
  5. 注意第 18-22 行执行的计算与在没有 alpha 通道时做的 gamma 运算是完全相同的。如果无 alpha 情况使用查找表处理,这里也可复用同一查找表。第 28-31 行与 33-34 行也可以用(不同的)查找表来完成。
  6. 可以使用整数算术替代浮点,只要在整个过程中注意保持足够的精度以避免溢出或下溢。

注:在浮点运算中不需要进行溢出或下溢检查,因为输入样本值保证在 0 和 1 之间,合成结果也总是在输入值之间(含端点)。使用整数算术时,可能需要进行一些舍入误差分析以保证没有溢出或下溢。

在显示具有完整 alpha 通道的 PNG 图像时,将图像与某个背景(即使只是黑色)合成 是很重要的。忽略 alpha 通道会使那些从关联 alpha 表现转换而来的 PNG 图像看起来错误。(当然,如果 alpha 通道是单独的透明掩码,则忽略 alpha 是一个有用的选项:它允许恢复被隐藏的图像部分。)

即便解码器未实现真实合成逻辑,也可以简单地处理只包含零和一 alpha 值的图像。(对于使用 tRNS 块的 灰度真彩色 PNG 数据流,这在隐含上为真;对于 索引色 PNG 数据流,检查 tRNS 块是否仅包含 0 与 255 之外的值是容易的。)在这种简单情形下,透明像素被替换为背景色,其他像素保持不变。

如果解码器仅具备此程度的透明处理能力,它应通过将所有非零 alpha 值视为完全不透明,或通过抖动处理来应对完整 alpha 通道。对于从关联 alpha 格式转换而来的图像,这两种方法都不会产生很好结果,但总比什么都不做要好。将完整 alpha 抖动为二值 alpha 很类似于将灰度抖动为黑白,除了所有完全透明与完全不透明的像素都应在抖动过程中保持不变。

13.17 直方图与建议调色板的使用

对于运行在索引色硬件上的查看器,若试图显示一幅 truecolor 图像,或一幅其调色板对 frame buffer 来说过大的索引色图像,编码器可能在 sPLT 块中提供了一个或多个建议调色板。如果根据大小或名称等判断某个建议调色板适用,PNG 解码器可以采用该调色板。样本深度与解码器需求不符的建议调色板可以通过样本深度重缩放进行转换(见 13.12 样本深度重缩放)。

当背景为纯色时,查看器应将图像与建议调色板相对于该颜色进行 合成,然后对合成后的图像进行 RGB 调色板量化。当图像使用透明度且背景并非纯色时,通常没有哪个建议调色板是有用的。

对于 truecolor 图像,建议调色板也可能以 PLTE 块的形式提供。如果图像具有 tRNS 块且背景为纯色,查看器需要使建议调色板适应其所需的背景色。为此,应将最接近 tRNS 颜色的调色板条目替换为所需的背景色;或者如果查看器能处理比 PLTE 条目更多的颜色,则可以添加一个用于背景色的调色板条目。

对于 color type 6(truecolor with alpha)的图像,任何 PLTE 块都应该是针对以 bKGD 块指定的颜色作为统一背景时的显示而设计的。若查看器打算使用不同的背景,或 bKGD 块缺失,则查看器可能应忽略该调色板。查看器可以在不同于其原意的背景下使用建议调色板,但结果可能不佳。

如果查看器将透明的 truecolor 图像呈现在比统一颜色更复杂的背景上,则建议调色板很可能不会对合成(composite)图像达到最优。在这种情况下,最好对 truecolor PNG 图像和背景图像先执行一次 truecolor 合成步骤,然后对合成结果进行颜色量化。

truecolor PNG 数据流中,如果同时出现 PLTEsPLT 块,PNG 解码器可以在两者建议的调色板之间进行选择,但应注意上文所述的不同透明语义。

sPLThIST 块中的频率信息在查看器不能提供与 PNG 数据流中调色板相同数量颜色时很有用。如果查看器仅缺少少数颜色,通常将使用频率最低的颜色从调色板中删除即可。要大幅减少颜色数量,最好选择全新的代表颜色,而不是试图使用现有调色板的子集。这等同于执行一次新的颜色量化步骤;不过现有的调色板和直方图可以作为输入数据,从而避免对 IDAT 块中的 image data 进行扫描。

如果未提供建议调色板,解码器可以自行生成,不过需要对 IDAT 块中的 image data 做一次额外遍历。或者,也可以使用一个默认调色板(可能是一个色彩立方体)。

另见 12.5 建议调色板

14. 编辑器

14.1 额外的块类型

在考虑引入新的块类型之前,建议作者先查阅本规范以及 [PNG-EXTENSIONS] 中已有的块类型。位于 [PNG-EXTENSIONS] 的块类型预期比本规范定义的块得到的支持更少。

14.2 PNG 编辑器的行为

两个 PNG 编辑器 的示例是:一个添加或修改文本块的程序,以及一个向 truecolor PNG 数据流添加建议调色板的程序。普通的图像编辑器通常不是 PNG 编辑器,因为它们在读取图像时通常会丢弃所有无法识别的信息。

为了允许向 PNG 添加新的块类型,有必要为所有块类型建立关于顺序要求的规则。否则,当 PNG 编辑器 遇到未知块时就不知道该如何处理。

示例:考虑一个假设的新辅助块类型,它是可安全复制的,并且如果存在 PLTE,则该新块需要出现在 PLTE 之后。如果某程序尝试插入一个 PLTE 块但不识别新块,它可能会将 PLTE 插入到错误的位置(即新块之后)。通过要求 PNG 编辑器 丢弃所有未知块可以防止这种问题,但这并不是一个令人满意的方案。因此,PNG 要求此类辅助块不要有此类严格的顺序依赖。

为在允许未来扩展的同时防止此类问题,PNG 对 PNG 编辑器 的行为以及块的允许顺序施加了约束。safe-to-copy 位定义了在修改数据流时对无法识别块的正确处理。

  1. 如果某块的 safe-to-copy 位为 1,则无论 PNG 编辑器 是否识别该块类型,也无论对数据流的修改范围如何,该块均可以被复制到修改后的 PNG 数据流中。
  2. 如果某块的 safe-to-copy 位为 0,则表示该块依赖于 image data。如果程序对任何 关键块进行了任何修改(包括添加、修改、删除或重排关键块),则不应将无法识别的非安全块复制到输出的 PNG 数据流中。(当然,如果程序确实识别该块,它可以选择输出适当修改后的版本。)
  3. 如果 PNG 编辑器 仅添加、删除、修改或重排了 辅助 块,则它始终被允许复制所有无法识别的辅助块。这意味着辅助块不应依赖于其他辅助块。
  4. PNG 编辑器 在遇到无法识别的关键块类型时应终止,因为无法确定在修改包含该块的数据流后能否得到一个有效的数据流。(简单地丢弃该块不足以保证安全,因为该块可能对其他块的解释有未知影响。)safe/unsafe 机制旨在用于辅助块。关键块的 safe-to-copy 位始终为 0。

针对块顺序的规则如下。

  1. 在复制未知的、unsafe-to-copy 的辅助块时,PNG 编辑器 不得将该块相对于任何关键块移动。它可以在相同一对关键块之间的其他辅助块之间自由地重新定位该块。(这是明确的,因为如果编辑器在保留未知的 unsafe-to-copy 块时不会添加、删除、修改或重排关键块。)
  2. 在复制未知的、safe-to-copy 的辅助块时,PNG 编辑器 不得将该块从 IDAT 之前移到 IDAT 之后,或反之。任何其他重排都是允许的。(这是明确的,因为 IDAT 总是存在。)
  3. 在复制已知的辅助块类型时,编辑器只需遵守该特定块类型存在的具体块顺序规则。然而,它总是可以选择应用上面的一般规则。

这些规则以从输入数据流向输出数据流复制块来表达,但如果在原地修改 PNG 数据流,规则以显而易见的方式同样适用。

另见 5.4 块命名约定

那些不改变 image dataPNG 编辑器 不应更改 tIME 块。tEXtzTXtiTXt 块中的 Creation Time 关键字可用于用户提供的时间。

14.3 块的排序

14.3.1 关键块的排序

关键块可能具有任意的排序要求,因为 PNG 编辑器 被要求在遇到未知关键块时终止。例如 IHDR 有明确的排序规则:它必须始终出现在首位。能生成某个关键块类型的 PNG 编辑器或任何写 PNG 的程序都应了解并遵循该关键块的排序规则。

14.3.2 辅助块的排序

对某个辅助块类型最严格的排序规则是:

  1. unsafe-to-copy 的块相对于关键块可能有排序要求。
  2. safe-to-copy 的块相对于 IDAT 可能有排序要求。

任何特定辅助块类型的实际排序规则可能更宽松。参见例如标准辅助块类型在 5.6 块排序 中的排序规则。

解码器不得对任何辅助块的位置做出超过块排序规则规定的假设。特别地,绝不可假定某一特定辅助块类型相对于其他辅助块有某种特定位置。

示例:假定某私有辅助块总是写在 IEND 之前,将其视为不变的位置是不安全的。即便某应用总是在该位置写入该块,某个 PNG 编辑器 也可能在其后插入其他辅助块。但可以安全地假定该块仍将位于 IDATIEND 之间的某处。

15. 一致性

除了被标记为非规范性的章节外,本规范中的所有创作指南、图表、示例和注释均为非规范性。规范性内容为本规范中未被标记为非规范性的其他所有部分。

文档中出现的关键字 MAYMUSTSHALLSHOULDSHOULD NOT 应按 BCP 14 [RFC2119] [RFC8174] 中所述的方式解释,但仅当这些关键字以全大写形式出现时才按此解释,如本文所示。

15.1 一致性

15.2 简介

15.2.1 目标

本条款讨论 PNG 数据流、PNG 编码器、PNG 解码器以及 PNG 编辑器 的一致性。

本条款规范的主要目标是:

  1. 通过消除对本规范的任意子集或扩展来促进互操作性;
  2. 促进一致的一致性测试开发;
  3. 促进 PNG 编码器、解码器和编辑器之间的一致结果;
  4. 便于自动化测试生成。

15.2.2 范围

一致性定义针对 PNG 数据流以及 PNG 编码器、解码器和编辑器。

本条款涉及 PNG 数据流和实现要求,包括 PNG 编码器、PNG 解码器以及 PNG 编辑器 可允许的差异范围。本条款不直接涉及编码器、解码器或编辑器的环境、性能或资源需求。

本条款的范围限于开放交换 PNG 数据流的规则。

15.3 一致性条件

15.3.1 PNG 数据流一致性

PNG 数据流在满足以下条件时视为符合本规范。

  1. PNG 数据流以 PNG 签名作为首个内容(参见 5.2 PNG 签名)。
  2. 关于本国际标准中定义的块类型:
    • PNG 数据流在 PNG 签名之后立即包含第一个块为 IHDR 块;
    • PNG 数据流的最后一个块为 IEND 块。
  3. IEND 块之后不得有任何块或其他内容。
  4. 其中包含的所有块均符合本规范中相应块类型的规范。PNG 数据流应遵守本规范中定义的块类型之间的关系。
  5. PNG 数据流中块的顺序应遵守本国际标准中规定的排序关系。
  6. PNG 数据流中的所有字段值应遵守本规范所规定的关系,从而产生本规范所定义的结构。
  7. PNG 数据流中不得出现本规范未指定的块,除非按照本规范定义的新块类型创建规则定义的块。
  8. PNG 数据流应按照本国际标准的规则进行编码。

15.3.2 PNG 编码器一致性

PNG 编码器在满足以下条件时视为符合本规范。

  1. 该 PNG 编码器生成的所有 PNG 数据流均为符合性的 PNG 数据流。
  2. 在对具有无法由 PNG 直接表示的样本深度的输入样本进行编码时,编码器将样本缩放到 PNG 允许的下一较高样本深度。数据按使高位位与原始数据匹配的方式进行缩放。
  3. 私有字段值 在对任何方法或类型字段进行实验性或私有定义时可被使用。

15.3.3 PNG 解码器一致性

PNG 解码器在满足以下条件时视为符合本规范。

  1. 它能够读取任何符合本国际标准的 PNG 数据流,包括那些类型可能无法识别的公共和私有块。
  2. 它支持所有标准化的关键块,以及符合本国际标准的任何 PNG 数据流中的所有标准化压缩、滤波和隔行方法与类型。
  3. 对未知块类型的处理应按 5.4 块命名约定 中的描述进行。未知块类型应被视为错误,除非它是关键块。
  4. 已知块字段中出现的意外值(例如 IHDR 块中出现意外的压缩方法)应被视为错误并处理。
  5. 应处理所有类型的 PNG 图像(索引色、真彩色灰度带 alpha 的真彩色带 alpha 的灰度)。例如,运行在索引色显示硬件上的查看器的一部分的解码器,应将 真彩色 图像降为索引格式以便显示。
  6. 当遇到辅助位为 0 的未知块时,如果解码器正在尝试提取图像,则应产生错误。
  7. 当块类型的保留位被设置时,应将其视为未知块类型进行处理。
  8. 支持 11.2.1 IHDR Image header 中定义的所有有效的位深与 颜色类型 组合。
  9. 如果在 IHDR 块的位深、颜色类型、压缩方法、滤波方法或隔行方法字节中遇到无法识别的值,应报告错误。
  10. 在处理 tRNS 块中对 16 位 灰度真彩色 数据时,应对样本值的两个字节都进行评估以确定像素是否透明。
  11. 在处理由压缩方法 0 压缩的图像时,解码器仅假定完整的 图像数据 由一个压缩数据流表示,并存储在若干 IDAT 块中。
  12. 除非块排序规则另有规定,否则不得对任何辅助块的位置做出假设。

15.3.4 PNG 编辑器一致性

PNG 编辑器 在满足以下条件时视为符合本规范。

  1. 它符合 PNG 编码器的要求。
  2. 它符合 PNG 解码器的要求。
  3. 它能够编码它所解码的所有块。
  4. 它在 5.6 块排序 规则范围内保留所呈现的块的顺序。
  5. 它正确处理 safe-to-copy 位信息,并在 safe-to-copy 规则允许时保留未知块。
  6. 除非用户明确允许有损操作或编辑器发出警告,否则它应保留重构参考图像所需的所有信息(使参考图像能够被精确重建),但如果 alpha 通道仅包含零和最大值,则 alpha 通道的样本深度无需保留。允许执行诸如更改 颜色类型 或重新排列 索引色 数据流中的调色板等操作,前提是新的数据流以无损方式表示相同的参考图像。

A. Internet 媒体类型

A.1 image/png

本附录更新了现有的 image/png Internet 媒体类型,归入顶级类型 image。本附录符合 BCP 13W3CRegMedia 的要求。

媒体类型名称:
image
媒体子类型名称:
png
必需参数:
可选参数:
编码注意事项:
二进制
安全注意事项:

PNG 文档由一组明确定义类型的“块”组成。对于 PNG 规范中定义的每一种块类型(除 gIFx 外),这些块产生的唯一影响是导致图像在接收方的显示器或打印机上呈现。

gIFx 块类型用于封装应用扩展数据,对该数据的某些使用可能存在安全风险,尽管目前未知具体风险。同样,未来未注册的块类型的安全风险也无法评估。然而,PNG 工作组的意图是禁止包含“可执行”数据的块成为已注册的块。

文本块 tEXtiTXTzTXt 包含可作为注释等显示的数据。某些操作系统或终端可能允许显示内嵌控制字符的文本数据来执行诸如重新映射键、创建文件等操作。因此,规范建议在直接显示前对文本块进行控制字符过滤。

PNG 格式专为便于及早检测文件传输错误而设计,并使用循环冗余校验来确保其块中数据的完整性。

互操作性注意事项:
整个规范中使用网络字节顺序。
已发布规范:
Portable Network Graphics (PNG) Specification, https://www.w3.org/TR/PNG/
使用此媒体的应用:
PNG 在所有 Web 浏览器、图像查看器和图像创建工具中被广泛实现
片段标识符注意事项:
不适用
使用限制:
不适用
是否为临时注册?(仅标准树):
附加信息:
该类型的已弃用别名:
不适用
魔术数字:
89 50 4E 47 0D 0A 1A 0A
文件扩展名:
.png
Macintosh 文件类型代码:
PNGf
对象标识符:
不适用
一般性说明:

此注册更新了早先的注册:

  1. 早先的注册指向一个已过期的 Internet 草案。本次更新指向一个 W3C 推荐。
  2. 早先的联系人已故。新的联系人电子邮件为 PNG 工作组的公开归档 W3C 邮件列表。
  3. 变更控制者为 W3C
如需更多信息的联系人:
名称:
PNG Working Group
电子邮件:
public-png@w3.org
预期用途:
通用
作者/变更控制者:
W3C

A.2 image/apng

本附录符合 BCP 13W3CRegMedia 的要求。

媒体类型名称:
image
媒体子类型名称:
apng
必需参数:
不适用
可选参数:
不适用
编码注意事项:
二进制
安全注意事项:

APNG 文档由一组明确定义类型的“块”组成。对于 PNG 规范中定义的每一种块类型(除 gIFx 外),这些块产生的影响仅是导致动画图像在接收方的显示器上呈现。

gIFx 块用于封装应用扩展数据,对该数据的某些使用可能存在安全风险,尽管目前未知具体风险。同样,未来未注册的块类型的安全风险也无法评估。不过,PNG 工作组意图禁止包含“可执行”数据的块成为已注册块。

文本块 tEXtiTXtzTXt 包含可作为注释等显示的数据。某些操作系统或终端可能允许显示内嵌控制字符的文本数据来执行诸如重新映射键、创建文件等操作。因此,规范建议在直接显示前对文本块进行控制字符过滤。

PNG 格式专为便于及早检测文件传输错误而设计,并使用循环冗余校验来确保其块中数据的完整性。

如果创建了包含不相关静态图像块和动画图像块的 APNG 文件,那么使用不支持 APNG 的工具的人只会看到静态图像而不会意识到有附加内容。这可能被用于例如规避审核。

互操作性注意事项:
已发布规范:
Portable Network Graphics (PNG) Specification, https://www.w3.org/TR/png/
使用此媒体的应用:
Animated PNG (APNG) 在所有 Web 浏览器中被广泛实现,并且在图像查看器、动画与图像创建工具中日益可用
片段标识符注意事项:
不适用
使用限制:
不适用
是否为临时注册?(仅标准树):
附加信息:
该类型的已弃用别名:
image/vnd.mozilla.apng
魔术数字:
89 50 4E 47 0D 0A 1A 0A
文件扩展名:
.apng
对象标识符:
不适用
一般性说明:

image/apng 自 2015 年起已被广泛非注册使用。动画 PNG 在 2022 年之前并非官方 PNG 规范的一部分。本次注册以及 PNG 规范(第 3 版)将官方文档与已广泛部署的现实对齐。

如需更多信息的联系人:
名称:
PNG Working Group
电子邮件:
public-png@w3.org
预期用途:
通用
作者/变更控制者:
W3C

B. 私有块类型指导原则

本节为非规范性内容。

下面规定了定义私有块的指导原则:

  1. 不要定义会重定义已有块含义或改变对现有标准化块解释的新块,例如,不要新增一个块来声明 RGB 与 alpha 值实际表示 CMYK。
  2. 尽量减少私有块的使用以提高可移植性。
  3. 避免定义依赖于整个数据流内容的块。如果必须定义此类块,请将它们设为关键块。
  4. 对于可以用 Latin-1 表示的文本信息,避免定义新块类型。使用带有合适关键字以标识信息类型的 tEXtzTXt 块。对于不能用 Latin-1 表示但可用 UTF-8 表示的文本信息,使用带有合适关键字的 iTXt 块。
  5. 将相互依赖的辅助信息组合到单个块中。这样可避免引入块排序关系的需要。
  6. 避免定义私有的关键块。

C. 伽玛与色度

本节为非规范性内容。

一个 gamma value(伽玛值)是用来描述在图像采集与重现中遇到的某些非线性 传递函数 近似的数值参数。伽玛值 是幂律函数中的指数。 例如下列函数:

intensity = (voltage + constant)exponent

用于建模 CRT 显示器的非线性。正如本国际标准中通常假定的那样,常数常被认为为零。

为本规范之目的,便于考虑一般图像管线中可能出现并可用幂律建模的五个位置处的非线性 传递函数。与每个位置相关的特征性指数被赋予特定名称。

input_exponent 图像传感器的指数。
encoding_exponent 由写入数据流的过程或设备执行的任何 传递函数 的指数。
decoding_exponent 由读取 图像数据 的软件执行的任何 传递函数 的指数。
LUT_exponent 应用于 帧缓冲 与显示设备之间的 传递函数 的指数(通常通过查找表应用)。
output_exponent 显示设备的指数。对于 CRT,通常接近 2.2。

定义一些额外实体以描述若干复合 传递函数(或阶段组合)是很方便的。

display_exponent 应用于 帧缓冲 与显示设备显示表面之间的 传递函数 的指数。
display_exponent = LUT_exponent * output_exponent
gamma 将显示输出强度映射到 PNG 数据流中的样本的函数的指数。
gamma = 1.0 / (decoding_exponent * display_exponent)
end_to_end_exponent 将图像传感器输入强度映射到显示输出强度的函数的指数。通常在 1.0 到 1.5 的范围内。

PNG 的 gAMA 块用于记录 伽玛值。解码器可以结合关于显示环境的额外信息使用这些信息以实现或近似期望的显示输出。

关于该主题的更多资料可见 [GAMMA-FAQ]。

关于色彩空间对图像编码影响的更多资料可见 [Kasson] 与 [Hill]。

关于 色度 与色彩空间的背景信息可见 [COLOR-FAQ]。

D. 示例 CRC 实现

下面的示例代码(仅供参考)表示在 PNG 块中使用的 CRC(循环冗余校验) 的一种实用实现。(正式规范另见 ISO 3309 [ISO-3309] 或 ITU-T V.42 [ITU-T-V.42])。

示例代码使用 ISO C [ISO_9899] 编程语言。表 31 中的提示可帮助非 C 用户更容易阅读代码。

Table 31 读取 ISO C 代码的提示
运算符 说明
& 按位与运算符。
^ 按位异或运算符。
>> 按位右移运算符。当应用于无符号量时(如此处),右移在左侧插入零。
! 逻辑非运算符。
++ "n++" 将变量 n 增加 1。在 "for" 循环中,该操作在变量测试之后执行。
0xNNN 0x 引入一个十六进制(基数 16)常量。后缀 L 表示 long 类型(至少 32 位)。

/* Table of CRCs of all 8-bit messages. */
unsigned long crc_table[256];

/* Flag: has the table been computed? Initially false. */
int crc_table_computed = 0;

/* Make the table for a fast CRC. */
void make_crc_table(void)
{
  unsigned long c;
  int n, k;

  for (n = 0; n < 256; n++) {
    c = (unsigned long) n;
    for (k = 0; k < 8; k++) {
      if (c & 1)
        c = 0xedb88320L ^ (c >> 1);
      else
        c = c >> 1;
    }
    crc_table[n] = c;
  }
  crc_table_computed = 1;
}
/* Update a running CRC with the bytes buf[0..len-1]--the CRC
   should be initialized to all 1's, and the transmitted value
   is the 1's complement of the final running CRC (see the
   crc() routine below). */

unsigned long update_crc(unsigned long crc, unsigned char *buf,
                         int len)
{
  unsigned long c = crc;
  int n;

  if (!crc_table_computed)
    make_crc_table();
  for (n = 0; n < len; n++) {
    c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
  }
  return c;
}

/* Return the CRC of the bytes buf[0..len-1]. */
unsigned long crc(unsigned char *buf, int len)
{
  return update_crc(0xffffffffL, buf, len) ^ 0xffffffffL;
}

E. 在线资源

本节为非规范性内容。

简介

本附录给出了一些面向 PNG 软件开发者的互联网资源位置。由于互联网的特性,列举并不完整且可能发生变化。

E.1 ICC 配置文件规范

ICC 配置文件规范可在: https://www.color.org/ 获取

E.2 PNG 网站

PNG 的万维网主页位于 http://www.libpng.org/pub/png/。该页面是获取有关 PNG 及相关工具的当前信息的中心位置。

关于 deflate 的额外文档和可移植 C 代码,以及一个优化的 CRC 算法实现,可从 zlib 网站获取: https://www.zlib.net/

E.3 示例实现与测试图像

可移植 C 的示例实现 libpng 可在 http://www.libpng.org/pub/png/libpng.html 获取。libpng 的示例查看器与编码器应用可在 http://www.libpng.org/pub/png/book/sources.html 获取,并在 PNG: The Definitive Guide [ROELOFS] 中有详细描述。测试图像也可从 PNG 网站访问。

F. 更改记录

本节为非规范性内容。

F.1 自 2025 年 5 月 15 日拟议推荐稿以来的更改(Proposed Recommendation of 15 May 2025)

F.2 自 2025 年 3 月 13 日候选推荐快照以来的更改(Candidate Recommendation Snapshot of 13 March 2025)

F.3 自 2025 年 1 月 21 日候选推荐草案以来的更改(第三版,Candidate Recommendation Draft of 21 January 2025 (Third Edition))

F.4 自 2024 年 7 月 18 日候选推荐草案以来的更改(第三版,Candidate Recommendation Draft of 18 July 2024 (Third Edition))

F.5 自 2023 年 9 月 21 日候选推荐快照以来的更改(第三版,Candidate Recommendation Snapshot of 21 September 2023 (Third Edition))

F.6 自 2023 年 7 月 20 日工作草案以来的更改(第三版,Working Draft of 20 July 2023 (Third Edition))

F.7 自 2022 年 10 月 25 日首次公开工作草案以来的更改(第三版,First Public Working Draft of 25 October 2022 (Third Edition))

F.8 自 2003 年 11 月 10 日 W3C 推荐以来的更改(PNG 第二版,W3C Recommendation of 10 November 2003)

F.9 第一版与第二版之间的更改

有关 W3C 推荐文档 PNG 规范 1.0PNG 第二版 之间更改的列表,请参见 PNG 第二版 更改列表

G. 参考文献

G.1 规范性参考文献

[BCP47]
用于标识语言的标签。A. Phillips(编);M. Davis(编)。IETF。2009 年 9 月。最佳现行实践。网址:https://www.rfc-editor.org/rfc/rfc5646
[CIPA-DC-008]
可交换 图像文件格式:Exif 版本 2.32。相机与影像产品协会。2019-05-17。网址:https://www.cipa.jp/std/documents/download_e.html?DC-008-Translation-2019-E
[COLORIMETRY]
色度学,第四版(CIE 015:2018)。CIE。2018。网址:http://www.cie.co.at/publications/colorimetry-4th-edition
[Display-P3]
Display P3。Apple, Inc. ICC。2022-02。网址:https://www.color.org/chardata/rgb/DisplayP3.xalter
[ENCODING]
编码规范(Encoding Standard)。Anne van Kesteren。 WHATWG。持续更新的标准。网址:https://encoding.spec.whatwg.org/
[ICC]
ICC.1:2022(配置文件版本 4.4.0.0)。国际色彩联盟。2022 年 5 月。网址:http://www.color.org/specification/ICC.1-2022-05.pdf
[ICC-2]
规范 ICC.2:2019(配置文件版本 5.0.0 - iccMAX)。国际色彩联盟。2019。网址:https://www.color.org/specification/ICC.2-2019.pdf
[ISO_15076-1]
ISO 15076-1:2010 图像技术 色彩管理 — 架构、配置文件格式与数据结构 — 第 1 部分:基于 ICC.1:2010。ISO。2010-12。网址:https://www.iso.org/standard/54754.html
[ISO_8859-1]
ISO/IEC 8859-1:1998,信息技术 — 8 位单字节图形字符集 — 第 1 部分:拉丁字母第 1 集。。ISO。1998。
[ISO_9899]
ISO/IEC 9899:2018 信息技术 — 编程语言 — C。ISO。2018-6。网址:https://www.iso.org/standard/74528.html
[ISO-3309]
ISO/IEC 3309:1993,信息技术 — 系统间电信与信息交换 — 高层数据链路控制(HDLC)过程 — 帧结构。。ISO。1993 年。
[ISO646]
信息技术 — 用于信息交换的 ISO 7 位编码字符集。国际标准化组织(ISO)。1991 年 12 月。已发布。网址:https://www.iso.org/standard/4777.html
[ITU-R-BT.2100]
ITU-R BT.2100,系列 BT:广播服务(电视)。用于制作与国际节目交换的高动态范围电视图像参数值。ITU。2018-07。网址:https://www.itu.int/rec/R-REC-BT.2100
[ITU-R-BT.709]
ITU-R BT.709,系列 BT:广播服务(电视)。用于 HDTV 制作与国际节目交换的参数值。ITU。2015-06。网址:https://www.itu.int/rec/R-REC-BT.709
[ITU-T-H.273]
ITU-T H.273,系列 H:视听与多媒体系统 — 视听服务基础设施 — 运动视频编码。用于视频信号类型识别的编码无关代码点。ITU。2024-07-14。网址:https://www.itu.int/rec/T-REC-H.273
[ITU-T-Series-H-Supplement-19]
系列 H:视听与多媒体系统 — 视频信号类型代码点的使用。ITU。2021-04。网址:https://www.itu.int/ITU-T/recommendations/rec.aspx?rec=14652
[ITU-T-V.42]
ITU-T V.42,系列 V:电话网络上的数据通信 — 使用异步到同步转换的 DCE 的差错纠正程序。ITU。2002-03-29。网址:https://www.itu.int/rec/T-REC-V.42-200203-I/en
[JPEG]
JPEG 文件交换格式(JFIF)。 Eric Hamilton。C-Cube Microsystems。Milpitas, CA, USA。1992 年 9 月。网址:https://www.w3.org/Graphics/JPEG/jfif3.pdf
[Paeth]
图像文件压缩简易法,收录于 Graphics Gems II,第 93–100 页。Paeth, A.W.。Academic Press。1991。网址:https://www.sciencedirect.com/science/article/pii/B9780080507545500293
[PNG-EXTENSIONS]
PNG 第三版规范扩展(版本 1.6.0)。W3C。2021。网址:https://w3c.github.io/png/extensions/Overview.html
[rfc1123]
互联网主机要求 — 应用与支持。R. Braden(编)。IETF。1989 年 10 月。互联网标准。网址:https://www.rfc-editor.org/rfc/rfc1123
[rfc1950]
ZLIB 压缩数据格式规范 版本 3.3。P. Deutsch;J-L. Gailly。IETF。1996 年 5 月。信息性文档。网址:https://www.rfc-editor.org/rfc/rfc1950
[RFC1951]
DEFLATE 压缩数据格式规范 版本 1.3。P. Deutsch。IETF。1996 年 5 月。信息性文档。网址:https://www.rfc-editor.org/rfc/rfc1951
[RFC1952]
GZIP 文件格式规范 版本 4.3。P. Deutsch。IETF。1996 年 5 月。信息性文档。网址:https://www.rfc-editor.org/rfc/rfc1952
[RFC2119]
用于 RFC 中指示要求级别的关键字。S. Bradner。IETF。1997 年 3 月。最佳现行实践。网址:https://www.rfc-editor.org/rfc/rfc2119
[rfc3339]
互联网的日期与时间:时间戳。G. Klyne;C. Newman。IETF。2002 年 7 月。拟定标准。网址:https://www.rfc-editor.org/rfc/rfc3339
[rfc3629]
UTF-8:ISO 10646 的一种转换格式。F. Yergeau。IETF。2003 年 11 月。互联网标准。网址:https://www.rfc-editor.org/rfc/rfc3629
[RFC8174]
RFC 2119 关键字大小写二义性的说明。B. Leiba。IETF。2017 年 5 月。最佳现行实践。网址:https://www.rfc-editor.org/rfc/rfc8174
[SMPTE-170M]
电视 — 复合模拟视频信号 — 用于制作的 NTSC(SMPTE-170M)。电影与电视工程学会(SMPTE)。2004-11-30。网址:https://standards.globalspec.com/std/892300/SMPTE%20ST%20170M
[SMPTE-ST-2086]
支持高亮度与宽色域图像的母带显示色彩体积元数据。SMPTE。2018-04-27。网址:https://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=8353899
[SRGB]
多媒体系统与设备 — 色度测量与管理 — 第 2-1 部分:色彩管理 — 默认 RGB 色彩空间 — sRGB。IEC。网址:https://webstore.iec.ch/publication/6169
[XMP]
可扩展元数据平台(XMP)规范 — 第 1 部分。Adobe Systems Inc. ISO/IEC。2019 年 4 月。网址:https://www.iso.org/standard/75163.html
[Ziv-Lempel]
顺序数据压缩的通用算法,《IEEE 信息论学报》,第 IT-23 卷,第 3 期,第 337–343 页。J. Ziv;A. Lempel。IEEE。1977-05。网址:https://ieeexplore.ieee.org/document/1055714

G.2 信息性参考文献

[COLOR-FAQ]
色彩常见问题(Color FAQ)。Poynton, C. 2009-10-19。网址: https://poynton.ca/ColorFAQ.html
[CTA-861.3-A]
HDR 静态元数据扩展(CTA-861.3-A)。消费者技术协会(CTA)。2015-01。网址:https://shop.cta.tech/products/cta-861-3
[EBU-R-103]
数字电视系统中的视频信号容差。欧洲广播联盟(EBU)。2020-05。网址:https://tech.ebu.ch/docs/r/r103.pdf
[GAMMA-FAQ]
伽玛常见问题(Gamma FAQ)。Poynton, C. 1998-08-04。网址: https://poynton.ca/GammaFAQ.html
[GIF]
图形交换格式(GIF89a)规范。CompuServe Inc. 1990-07-31。网址:https://www.w3.org/Graphics/GIF/spec-gif89a.txt
[HDR-Static-Meta]
关于 HDR 静态内容元数据的计算与使用。Smith, Michael D.; Zink, Michael。SMPTE。2021-08-05。网址:https://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=9508136
[HDR10]
HDR10 媒体配置文件。网址:https://en.wikipedia.org/wiki/HDR10
[Hill]
基于 CIELAB 色差公式的色彩空间量化比较分析。Hill, B.; Roger, Th.; Vorhagen, F.W. 1997-04。网址:https://dl.acm.org/doi/10.1145/248210.248212
[ITU-R-BT.2020]
超高清电视系统的参数值,用于制作与国际节目交换。ITU。网址: https://www.itu.int/rec/R-REC-BT.2020
[ITU-R-BT.2390]
用于制作与国际节目交换的高动态范围电视。ITU。网址:https://www.itu.int/dms_pub/itu-r/opb/rep/R-REP-BT.2390-11-2023-PDF-E.pdf
[Kasson]
选定计算机交换色彩空间的分析。Kasson, J.; W. Plouffe。1992。网址:https://dl.acm.org/doi/abs/10.1145/146443.146479
[PostScript]
PostScript 语言参考手册。Adobe Systems Inc.。Addison-Wesley。1990 年。
[ROELOFS]
PNG:权威指南。Roelofs, G. O'Reilly & Associates Inc. 1999-06-11。网址:http://www.libpng.org/pub/png/pngbook.html
[SMPTE-RP-177]
基本电视色彩方程的推导。SMPTE。1993-11-01。网址:https://standards.globalspec.com/std/1284890/smpte-rp-177
[SMPTE-RP-2077]
全范围图像映射。SMPTE。2013-01-01。网址:https://doi.org/10.5594/SMPTE.RP2077.2013
[SMPTE-ST-2067-21]
可互操作母带格式 — 应用 #2E。SMPTE。2023-02-20。网址:https://doi.org/10.5594/SMPTE.ST2067-21.2023
[TIFF-6.0]
TIFF 修订版 6.0。1992-06-03。网址:https://www.loc.gov/preservation/digital/formats/fdd/fdd000022.shtml