簡介
WebP 是一種圖片格式,可使用 (i) VP8 關鍵影格編碼以有損方式壓縮圖片資料,或 (ii) WebP 無損編碼。這些編碼方案應比 JPEG、GIF 和 PNG 等舊格式更有效率。最適合透過網路快速傳輸圖片 (例如網站)。WebP 格式與其他格式具有相同的功能 (色彩設定檔、中繼資料、動畫等)。本文說明 WebP 檔案的結構。
WebP 容器 (即 WebP 的 RIFF 容器) 可支援的功能超越 WebP 的基本用途 (即包含以 VP8 關鍵影格編碼的單一圖片的檔案)。WebP 容器可為下列項目提供額外支援:
無損壓縮:使用 WebP 無損格式,可對圖片進行無損壓縮。
中繼資料:圖片的中繼資料可能以可交換影像檔案格式 (Exif) 或可擴充中繼資料平台 (XMP) 格式儲存。
透明度:圖片可能具有透明度,也就是 Alpha 色版。
色彩設定檔:圖片可能會嵌入 國際色彩聯盟所述的 ICC 設定檔。
動畫:圖片可能含有多個影格之間出現暫停點,形成動畫。
命名
建議您在參照 WebP 容器時使用下列類型:
容器格式名稱 | WebP |
副檔名 | .webp |
MIME 類型 | image/webp |
統一類型 ID | org.webmproject.webp |
術語和基本概念
本文件中的關鍵字「MUST」、「MUST NOT」、「REQUIRED」、「SHALL」、「SHALL NOT」、「SHOULD」、「SHOULD NOT」、「RECOMMENDED」、「NOT RECOMMENDED」、「MAY」和「OPTIONAL」應按照 BCP 14 RFC 2119 RFC 8174 的說明解讀,前提是這些關鍵字必須以大寫顯示,如上所示。
WebP 檔案包含靜態圖片 (也就是像素的編碼矩陣) 或動畫。視需要,也可以包含透明度資訊、色彩設定檔和中繼資料。我們將像素矩陣稱為圖片的畫布。
如 RFC 1166 所述,區塊圖表中的位元編號從 0
開始,代表最高位元 (MSB 0)。
以下是本文件中使用的其他術語:
- Reader/Writer
- 讀取 WebP 檔案的程式碼稱為「讀取器」,而寫入 WebP 檔案的程式碼則稱為「寫入器」。
- uint16
- 16 位元的小端序整數。
- uint24
- 24 位元小端序無符號整數。
- uint32
- 32 位元、小端序、未簽署的整數。
- FourCC
- 四字元代碼 (FourCC) 是透過以小端序連結四個 ASCII 字元所建立的 uint32。也就是說,系統會將「aaaa」(0x61616161) 和「AAAA」(0x41414141) 視為不同的 FourCCs。
- 1 位元
- 一個無符號整數欄位,儲存值時會加上
-1
的偏移量,例如,這樣的欄位會將值 25 儲存為 24。 - ChunkHeader('ABCD')
- 用於描述個別區塊的 FourCC 和 區塊大小標頭,其中「ABCD」是區塊的 FourCC。這個元素的大小為 8 個位元組。
RIFF 檔案格式
WebP 檔案格式是以 RIFF (Resource Interchange File Format) 文件格式為基礎。
RIFF 檔案的基本元素是區塊。其中包括:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Chunk FourCC |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Chunk Size |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: Chunk Payload :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- 區塊 FourCC:32 位元
- 用於區塊識別的 ASCII 四字元碼。
- 區塊大小:32 位元 (uint32)
- 區塊大小 (以位元組為單位),不含此欄位、區塊 ID 或填充資料。
- 區塊酬載:區塊大小位元組
- 資料酬載。如果「Chunk Size」為奇數,會加入一個邊框間距位元組 (必須符合 RIFF 必須使用
0
)。
注意:RIFF 有個慣例,就是全大寫的片段 FourCC 是適用於任何 RIFF 檔案格式的標準片段,而特定檔案格式的 FourCC 則全為小寫。WebP 則不遵循這項慣例。
WebP 檔案標頭
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 'R' | 'I' | 'F' | 'F' |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| File Size |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 'W' | 'E' | 'B' | 'P' |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- 'RIFF':32 位元
- ASCII 字元「R」「I」「F」「F」。
- 檔案大小:32 位元 (uint32)
- 檔案大小 (以位元組為單位,從偏移 8 開始)。這個欄位的最大值為 2^32 減去 10 個位元組,因此整個檔案的大小最多為 4 GiB 減去 2 個位元組。
- 'WEBP':32 位元
- ASCII 字元「W」、「E」、「B」、「P」。
WebP 檔案開頭必須是 RIFF 標頭,且 FourCC 為「WEBP」。標頭中的檔案大小是後續區塊的總大小,加上 'WEBP' FourCC 的 4
位元組。檔案不應包含 檔案大小 指定的資料後面的任何資料。讀取器可以剖析這類檔案,並忽略結尾資料。由於任何區塊的大小都是偶數,因此 RIFF 標頭提供的大小也是偶數。我們將在以下各節中說明個別區塊的內容。
簡易檔案格式 (有損)
如果圖片需要 lossy 編碼,且不需要延伸格式提供透明度或其他進階功能,則應使用這個版面配置。採用這種版面的檔案較小,且舊版軟體也支援。
簡易 WebP (有損) 檔案格式:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| WebP file header (12 bytes) |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: 'VP8 ' Chunk :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
「VP8」區塊:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('VP8 ') |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: VP8 data :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- VP8 資料:區塊大小位元組
- VP8 位元串流資料。
請注意,「VP8」的第四個字元是 ASCII 空格 (0x20),
如需 VP8 位元串流格式規格說明,請參閱「VP8 資料格式和解碼指南」。請注意,VP8 影格標頭包含 VP8 影格寬度和高度。假設這是畫布的寬度和高度。
VP8 規格說明如何將圖片解碼為 Y'CbCr 格式。如要轉換為 RGB,請使用 Recommendation BT.601。應用程式可以使用其他轉換方法,但不同解碼器的視覺結果可能不同。
簡易檔案格式 (無損)
注意:舊版閱讀器可能不支援無損格式的檔案。
如果圖片需要無損編碼 (搭配選用的透明度管道),且不需要擴充格式提供的進階功能,則應使用此版面配置。
簡易 WebP (無損) 檔案格式:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| WebP file header (12 bytes) |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: 'VP8L' Chunk :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
'VP8L' 區塊:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('VP8L') |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: VP8L data :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- VP8L 資料:區塊大小位元組
- VP8L 位元串流資料。
如要查看 VP8L 位元串流的目前規格,請參閱 WebP 無損位元串流格式。請注意,VP8L 標頭包含 VP8L 圖片的寬度和高度。假設這是畫布的寬度和高度。
擴充檔案格式
注意:舊版閱讀器可能不支援使用擴充格式的檔案。
擴充格式檔案包含:
包含檔案中所用功能資訊的「VP8X」區塊。
選用的「ICCP」區塊,其中包含色彩設定檔。
可選的「ANIM」區塊,包含動畫控制項資料。
圖片資料。
選用的「EXIF」區塊,含有 EXIF 中繼資料。
含有 XMP 中繼資料的選用「XMP」區塊。
選用的未知區塊清單。
對於靜態圖片,圖片資料包含單一影格,而影格由下列項目組成:
對於動畫圖片,圖片資料包含多個影格。如要進一步瞭解影格,請參閱「動畫」一節。
重建和色彩校正所需的所有片段 (即 'VP8X'、'ICCP'、'ANIM'、'ANMF'、'ALPH'、'VP8 ' 和 'VP8L') 必須依先前所述的順序出現。如果重建和色彩校正所需的區塊順序不正確,讀取器應會失敗。
理由:重建作業所需的區塊應先出現在檔案中,讓讀取器在收到所有資料之前能開始解碼圖片。應用程式可能會根據實作方式,調整中繼資料和自訂區塊的順序。
擴充的 WebP 檔案標頭:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| WebP file header (12 bytes) |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('VP8X') |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Rsv|I|L|E|X|A|R| Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Canvas Width Minus One | ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
... Canvas Height Minus One |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- 保留 (Rsv):2 位元
- 必須為
0
。讀者必須忽略這個欄位。 - ICC 色彩描述檔:1 位元
- 設定檔案是否包含「ICCP」區塊。
- Alpha (L):1 位元
- 如果圖片的任何影格含有透明度資訊 (「alpha」),請設定此屬性。
- EXIF 中繼資料 (E):1 位元
- 如果檔案包含 EXIF 中繼資料,請設定這個值。
- XMP 中繼資料 (X):1 位元
- 設定檔案是否包含 XMP 中繼資料。
- 動畫 (A):1 位元
- 如果這是動畫圖片,請設為該圖片。應使用「ANIM」和「ANMF」區塊中的資料來控制動畫。
- 保留 (R):1 位元
- 必須為
0
。讀者必須忽略這個欄位。 - 保留:24 位元
- 必須為
0
。讀者必須忽略這個欄位。 - 畫布寬度減一:24 位元
- 以 1 為基底的畫布寬度 (以像素為單位)。實際的畫布寬度為
1 + Canvas Width Minus One
。 - Canvas 高度減一:24 位元
- 以 1 為基底的畫布高度 (以像素為單位)。實際的畫布高度為
1 + Canvas Height Minus One
。
Canvas Width 和 Canvas Height 的產品不得超過 2^32 - 1
。
未來的規格可能會新增更多欄位。系統一律會忽略不明欄位。
動畫
動畫是由「ANIM」和「ANMF」區塊所控制。
'ANIM' 區塊:
如果是動畫圖片,這個區塊會包含動畫的全域參數。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('ANIM') |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Background Color |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Loop Count |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- 背景顏色:32 位元 (uint32)
- 以位元組順序 [藍、綠、紅、透明度] 顯示的畫布預設背景顏色。這個顏色可用於填滿畫布上影格周圍未使用的空間,以及第一個影格的透明像素。當處置方法為
1
時,系統也會使用背景顏色。
注意事項:
即使 'VP8X' Chunk 中的 Alpha 標記未設為預設值,背景顏色仍可包含不透明的 Alpha 值。
檢視器應用程式應將背景顏色值視為提示,但不一定要使用該值。
在每個迴圈開始時,畫布都會清除。您可以使用背景顏色來達成這項目標。
- 迴圈計數:16 位元 (uint16)
- 動畫循環播放的次數。如果是
0
,則表示無限。
如果「VP8X」區塊中設定了「Animation」標記,則必須顯示這個區塊。如果未設定 Animation 旗標,且此區塊存在,則必須忽略該區塊。
「ANMF」區塊:
對於動畫圖片,這個區塊包含單一影格資訊。如未設定動畫旗標,則「不應」顯示這個區塊。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('ANMF') |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Frame X | ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
... Frame Y | Frame Width Minus One ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
... | Frame Height Minus One |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Frame Duration | Reserved |B|D|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: Frame Data :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- 影格 X:24 位元 (uint24)
- 影格左上角的 X 座標為
Frame X * 2
。 - 影格 Y:24 位元 (uint24)
- 影格左上角的 Y 座標為
Frame Y * 2
。 - Frame 寬度減一:24 位元 (uint24)
- 影格的寬度,以 1 為基底。頁框寬度為
1 + Frame Width Minus One
。 - 影格高度減一:24 位元 (uint24)
- 影格的高度,以 1 為單位。框架高度為
1 + Frame Height Minus One
。 - 影格時長:24 位元 (uint24)
- 顯示下一個影格前等待的時間,以 1 毫秒為單位。請注意,實作方式會定義 0 (通常 <= 10) 的 Frame Duration 解讀方式。許多工具和瀏覽器都會指派與 GIF 相似的最低時間長度。
- 保留:6 位元
- 必須為
0
。讀者必須忽略這個欄位。 - 混合方法 (B):1 位元
指出如何將目前影格的透明像素與前一個畫布的對應像素混合:
0
:使用 Alpha 混合。處置先前的影格後,請使用 Alpha 混合功能在畫布上算繪目前的圖格 (請參閱下方說明)。如果目前的框架沒有 Alpha 通道,則假設 Alpha 值為 255,實際上會取代矩形。1
:不混合。處理前一個影格後,請覆寫目前影格所涵蓋的矩形,在畫布上算繪目前影格。
- 處置方法 (D):1 位元
指出如何處理在畫布上顯示目前的框架後 (在算繪下一個框架之前):
0
:請勿處置。讓畫布保持原狀。1
:Dispose 至背景顏色。使用 'ANIM' 區塊中指定的背景顏色,填滿畫布上由目前影格覆蓋的矩形。
注意事項:
影格處置作業只適用於影格矩形,也就是由「影格 X」、「影格 Y」、「影格寬度」和「影格高度」定義的矩形。不一定會覆蓋整個畫布。
Alpha 混合:
鑒於每個 R、G、B 和 A 管道都是 8 位元,而 RGB 管道並未預先乘上 Alpha 值,因此將「dst」與「src」混合的公式如下:
blend.A = src.A + dst.A * (1 - src.A / 255) if blend.A = 0 then blend.RGB = 0 else blend.RGB = (src.RGB * src.A + dst.RGB * dst.A * (1 - src.A / 255)) / blend.A
您應在線性色彩空間中進行 Alpha 混合,並考量圖片的色彩設定檔。如果沒有色彩設定檔,系統會假設為標準 RGB (sRGB)。(請注意,由於伽瑪值約為 2.2,因此 sRGB 也需要線性化)。
注意:如RIFF 檔案格式所述,'ANMF' 酬載 (影格資料) 包含個別填充區塊。
Alpha 值
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('ALPH') |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Rsv| P | F | C | Alpha Bitstream... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- 保留 (Rsv):2 位元
- 必須為
0
。讀者必須忽略這個欄位。 - 預先處理 (P):2 位元
這些資訊位元用於在壓縮期間執行預處理作業時發出訊號。解碼器可以使用這項資訊,例如在顯示前對值進行抖動或平滑漸層。
0
:不進行預先處理。1
:降低層級。
解碼器不必以任何特定方式使用這類資訊。
- 篩選方法 (F):2 位元
使用的篩選方法如下:
0
:無。1
:水平篩選器。2
:垂直篩選器。3
:漸層濾鏡。
針對每個像素,系統會使用下列計算方式進行篩選。假設目前 X
位置周圍的 Alpha 值有以下標籤:
C | B |
---+---+
A | X |
我們要計算位於 X
位置的 alpha 值。首先,系統會根據篩選方法進行預測:
- 方法
0
:預測者 = 0 - 方法
1
:預測器 = A - 方法
2
:預測器 = B - 方法
3
:預測器 = 截斷(A + B - C)
其中 clip(v)
等於:
- 0 如果 v < 0,
- 255 (如果 v 大於 255),或
- v 否則
最終值是將已解壓縮的值 X
新增至預測器,並使用模數 256 算術將 [256..511] 範圍包裝進 [0..255] 一範圍:
alpha = (predictor + X) % 256
最左和最上方的像素位置有特殊情況。舉例來說,位置 (0, 0) 的左上方值會使用 0 做為預測值。如果是其他情況:
- 針對水平或漸層篩選方法,位置 (0, y) 的最左側像素會透過上述位置 (0, y-1) 進行預測。
- 對於垂直或漸層篩選方法,位置 (x, 0) 的最高像素是根據左側位置 (x-1, 0) 進行預測。
- 壓縮方法 (C):2 位元
使用的壓縮方法:
0
:不壓縮。1
:使用 WebP 無損格式壓縮。
- Alpha 位元流:區塊大小位元組 -
1
已編碼的 Alpha 位元串流。
這個選用區塊包含此影格已編碼的 alpha 資料。包含 'VP8L' 區塊的框架不應包含此區塊。
理由:透明度資訊已包含在「VP8L」區塊中。
當壓縮方法為「0」時,會以未壓縮的原始資料形式儲存 Alpha 通道資料;當壓縮方法為「1」時,則會以無損格式壓縮。
原始資料:這包含長度 = 寬度 * 高度的位元組序列,其中包含按照掃描順序排列的所有 8 位元透明度值。
無損格式壓縮:位元組序列是隱含寬 x 高尺寸的壓縮圖片串流 (如「WebP 無損位元組串流格式」所述)。也就是說,這個圖片串流不含任何描述圖片尺寸的標頭。
原因:維度已從其他來源取得,因此再次儲存維度會造成重複,且容易發生錯誤。
一旦圖片串流經過解碼,並轉換為 Alpha、紅、綠、藍 (ARGB) 顏色值,就必須依照無損格式規格所述的程序,從 ARGB 四元組的綠頻道中擷取透明度資訊。
理由:綠色管道允許規格中額外的轉換步驟 (與其他管道不同),可提高壓縮率。
Bitstream (VP8/VP8L)
這個區塊包含單一影格的壓縮位元流資料。
位元串區塊可以是 (i)「VP8」區塊,使用「VP8」(請注意第四個字元的空格) 做為 FourCC,或 (ii)「VP8L」區塊,使用「VP8L」做為 FourCC。
請參閱「簡易檔案格式 (有損)」和「簡易檔案格式 (無損)」章節,瞭解「VP8」和「VP8L」區塊的格式。
色彩設定檔
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('ICCP') |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: Color Profile :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- 色彩剖析:Chunk Size 位元組
- ICC 色彩描述檔。
此區塊必須出現在圖片資料之前。
最多應有一個這類區塊。如果畫面上有多個這類區塊,讀者可能會只忽略第一個區塊。詳情請參閱 ICC 規格。
如果沒有這個區塊,系統應假設為 sRGB。
中繼資料
中繼資料可以儲存在「EXIF」或「XMP」區塊中。
每種類型最多只能有一個區塊 (「EXIF」和「XMP」)。如果有多個這類區塊,讀者可能會只忽略第一個區塊。
這些區塊的定義如下:
「EXIF」區塊:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('EXIF') |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: Exif Metadata :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Exif 中繼資料:區塊大小位元組
- Exif 格式的圖片中繼資料。
「XMP」區塊:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('XMP ') |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: XMP Metadata :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- XMP 中繼資料:區塊大小位元組
- XMP 格式的圖片中繼資料。
請注意,「XMP」FourCC 中的第四個字元是 ASCII 空格 (0x20)。
如需處理中繼資料的更多指引,請參閱中繼資料工作小組的「處理中繼資料指南」。
不明區塊
RIFF 區塊 (請參閱「RIFF 檔案格式」一節) 與本文件中描述的任何區塊不同,而系統會將 RIFF 區塊視為「不明區塊」。
理由:允許未知的區塊可為日後的這種格式提供佈建,並允許儲存任何應用程式特定資料。
一個檔案可能包含未知區塊:
- 放在檔案結尾,如 Extended WebP 檔案標頭一節所述,或者
- 在「ANMF」區塊結尾處,如動畫一節所述。
讀者應忽略這些區塊。編寫程式碼時,應以原始順序保留這些區塊 (除非特別想修改這些區塊)。
從 Frame 組合 Canvas
以下概略說明讀取器在動畫圖片的情況下,如何組合畫布。
這個程序會先使用 'VP8X' 區塊中指定的尺寸建立畫布,寬度為 Canvas Width Minus One + 1
像素,高度為 Canvas Height Minus
One + 1
像素。「ANIM」區塊的 Loop Count
欄位可控制重複動畫程序重複執行的次數。如果 Loop Count
值不為零,則為 Loop Count - 1
;如果 Loop Count
為零,則為無限大。
在每個迴圈疊代開始時,系統會使用「ANIM」區塊的背景顏色或應用程式定義的顏色填滿畫布。
「ANMF」區塊包含以顯示順序提供的個別影格。每個影格轉譯前,系統都會套用前一個影格的 Disposal method
。
解碼影格的算繪作業會從笛卡兒座標 (2 *
Frame X
、2 * Frame Y
) 開始,並以畫布的左上角做為原點。使用 Blending method
將寬度為 Frame Width Minus One + 1
像素、高度為 Frame Height Minus One + 1
像素的圖形算繪到畫布上。
畫布會顯示 Frame Duration
毫秒。這樣會持續到「ANMF」區塊提供的所有影格顯示為止。接著開始新的迴圈迭代,如果所有迭代都已完成,則會將畫布保留在最終狀態。
以下虛擬程式碼說明算繪程序。符號 VP8X.field 代表「VP8X」區塊中具有相同說明的欄位。
VP8X.flags.hasAnimation MUST be TRUE
canvas ← new image of size VP8X.canvasWidth x VP8X.canvasHeight with
background color ANIM.background_color or
application-defined color.
loop_count ← ANIM.loopCount
dispose_method ← Dispose to background color
if loop_count == 0:
loop_count = ∞
frame_params ← nil
next chunk in image_data is ANMF MUST be TRUE
for loop = 0..loop_count - 1
clear canvas to ANIM.background_color or application-defined color
until eof or non-ANMF chunk
frame_params.frameX = Frame X
frame_params.frameY = Frame Y
frame_params.frameWidth = Frame Width Minus One + 1
frame_params.frameHeight = Frame Height Minus One + 1
frame_params.frameDuration = Frame Duration
frame_right = frame_params.frameX + frame_params.frameWidth
frame_bottom = frame_params.frameY + frame_params.frameHeight
VP8X.canvasWidth >= frame_right MUST be TRUE
VP8X.canvasHeight >= frame_bottom MUST be TRUE
for subchunk in 'Frame Data':
if subchunk.tag == "ALPH":
alpha subchunks not found in 'Frame Data' earlier MUST be
TRUE
frame_params.alpha = alpha_data
else if subchunk.tag == "VP8 " OR subchunk.tag == "VP8L":
bitstream subchunks not found in 'Frame Data' earlier MUST
be TRUE
frame_params.bitstream = bitstream_data
apply dispose_method.
render frame with frame_params.alpha and frame_params.bitstream
on canvas with top-left corner at (frame_params.frameX,
frame_params.frameY), using Blending method
frame_params.blendingMethod.
canvas contains the decoded image.
Show the contents of the canvas for
frame_params.frameDuration * 1 ms.
dispose_method = frame_params.disposeMethod
檔案版面配置範例
含有 Alpha 的失真編碼圖片可能如下所示:
RIFF/WEBP
+- VP8X (descriptions of features used)
+- ALPH (alpha bitstream)
+- VP8 (bitstream)
無損編碼圖片看起來可能會像這樣:
RIFF/WEBP
+- VP8X (descriptions of features used)
+- VP8L (lossless bitstream)
+- XYZW (unknown chunk)
含有 ICC 設定檔和 XMP 中繼資料的無損圖片可能如下所示:
RIFF/WEBP
+- VP8X (descriptions of features used)
+- ICCP (color profile)
+- VP8L (lossless bitstream)
+- XMP (metadata)
含有 EXIF 中繼資料的動畫圖片可能如下所示:
RIFF/WEBP
+- VP8X (descriptions of features used)
+- ANIM (global animation parameters)
+- ANMF (frame1 parameters + data)
+- ANMF (frame2 parameters + data)
+- ANMF (frame3 parameters + data)
+- ANMF (frame4 parameters + data)
+- EXIF (metadata)