WebP Container の仕様

はじめに

WebP は、(i)VP8 キーフレーム エンコードを使用して画像データを非可逆圧縮する方法、または(ii)WebP 可逆エンコードを使用する画像形式です。このようなエンコード方式は、JPEG、GIF、PNG などの古い形式よりも効率的です。ネットワーク経由の高速画像転送向けに最適化されています(ウェブサイトなど)。WebP 形式には、他の形式と同等の機能(カラー プロファイル、メタデータ、アニメーションなど)があります。このドキュメントでは、WebP ファイルの構造について説明します。

WebP コンテナ(WebP の RIFF コンテナ)を使用すると、WebP の基本ユースケース(VP8 キーフレームとしてエンコードされた単一の画像を含むファイル)以上の機能サポートが可能になります。WebP コンテナは、以下に対する追加サポートを提供します。

  • 可逆圧縮: WebP 可逆形式を使用して、画像を可逆圧縮できます。

  • メタデータ: イメージには、Exchangeable Image File Format(Exif)または Extensible Metadata Platform(XMP)形式で保存されたメタデータが含まれる場合があります。

  • 透明度: 画像に透明度(アルファ チャンネル)を設定できます。

  • カラー プロファイル: International Color Consortium で規定されている埋め込み ICC プロファイルが画像に含まれている場合があります。

  • アニメーション: 画像に複数のフレームがあり、その間に一時停止があってアニメーションになることがあります。

命名

WebP コンテナを参照する場合は、次のタイプを使用することが推奨されます。

コンテナ形式の名前WebP
ファイル名の拡張子.webp
MIME タイプ画像/WebP
ユニフォーム タイプ IDorg.webmproject.webp

用語と基本事項

このドキュメント内のキーワード「MUST」、「MUST NOT」、「REQUIRED」、「SHALL」、「SHALL NOT」、「SHOULD」、「SHOULD NOT」、「推奨される」、「NOT Recommended」、「MAY」、「optional」は、BCP 14 の RFC 2117、RFC 2817 および大文字の表記法に従って解釈する必要があります。

WebP ファイルには、静止画像(エンコードされたピクセル マトリックス)またはアニメーションが含まれます。必要に応じて、透明度情報、カラー プロファイル、メタデータを含めることもできます。ピクセルのマトリックスを画像のキャンバスと呼びます。

RFC 1166 に記載されているように、チャンク図のビット番号は、最上位ビット(「MSB 0」)の 0 から始まります。

以下は、このドキュメントで使用されている追加の用語です。

リーダー/ライター
WebP ファイルを読み取るコードはリーダー、ファイルを書き込むコードはライターと呼ばれます。
uint16
16 ビット、リトル エンディアン、符号なし整数。
uint24
24 ビット、リトル エンディアン、符号なし整数。
uint32
32 ビット、リトル エンディアン、符号なし整数。
FourCC
4 文字のコード(FourCC)は、4 つの ASCII 文字をリトル エンディアンの順序で連結して作成される uint32 です。つまり、「aaaa」(0x61616161)と「AAAA」(0x41414141)は異なる FourCCs として扱われます。
1 から始まる
-1 でオフセットされた値を格納する符号なし整数フィールド。たとえば、このようなフィールドには値 2524 として保存します。
ChunkHeader('ABCD')
個々のチャンクの FourCCChunk Size ヘッダーの説明に使用されます。「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 4 文字のコード。
チャンクサイズ: 32 ビット(uint32
チャンクのサイズ(バイト単位)。このフィールド、チャンク識別子、パディングは含まれません。
チャンク ペイロード: Chunk Size バイト
データ ペイロード。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 ファイルは、FourCC「WEBP」を含む RIFF ヘッダーで始めなければなりません。ヘッダー内のファイルサイズは、その後のチャンクの合計サイズに、「WEBP」FourCC の 4 バイトを足した値になります。ファイルには、File Size で指定されたデータより後のデータを含めるべきではありません。リーダーは、末尾のデータを無視して、そのようなファイルを解析しても構いません。チャンクのサイズは偶数であるため、RIFF ヘッダーによって指定されるサイズも偶数になります。個々のチャンクの内容については、次のセクションで説明します。

シンプルなファイル形式(非可逆)

このレイアウトは、画像に非可逆エンコードが必要で、拡張形式によって提供される透明度やその他の高度な機能を必要としない場合に使用すべきです。このレイアウトのファイルはサイズが小さく、古いソフトウェアでサポートされています。

Simple 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 データ: Chunk Size バイト
VP8 ビットストリーム データ。

「VP8」FourCC の 4 番目の文字は ASCII スペース(0x20)であることに注意してください。

VP8 ビットストリーム形式の仕様については、VP8 データ形式とデコードのガイドをご覧ください。VP8 フレーム ヘッダーには VP8 フレームの幅と高さが含まれます。これはキャンバスの幅と高さであると想定されます。

VP8 仕様では、画像を Y'CbCr 形式にデコードする方法が記述されています。RGB に変換するには、推奨 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 Lossless Bitstream Format をご覧ください。VP8L ヘッダーには、VP8L 画像の幅と高さが含まれています。これはキャンバスの幅と高さであると想定されます。

拡張ファイル形式

注: 古いリーダーは、拡張形式を使用するファイルに対応していない場合があります。

拡張形式のファイルは以下のものから構成されます。

  • ファイルで使用されている機能に関する情報を含む「VP8X」チャンク。

  • カラー プロファイルを使用した「ICCP」チャンク(省略可)。

  • アニメーション コントロール データを含む「ANIM」チャンク(省略可能)。

  • 画像データ。

  • EXIF メタデータを含むオプションの「EXIF」チャンク。

  • XMP メタデータを含むオプションの「XMP」チャンク。

  • 不明なチャンクのリスト(省略可)。

静止画像の場合、画像データは次の 1 つのフレームで構成されます。

アニメーション画像の場合、画像データは複数のフレームで構成されます。フレームの詳細については、アニメーション セクションをご覧ください。

再構成と色補正に必要なすべてのチャンク(「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 プロファイル(I): 1 ビット
ファイルに「ICCP」チャンクが含まれている場合に設定します。
アルファ(L): 1 ビット
画像のフレームのいずれかに透明度情報(「アルファ」)が含まれているかどうかを設定します。
Exif メタデータ(E): 1 ビット
ファイルに Exif メタデータが含まれている場合に設定します。
XMP メタデータ(X): 1 ビット
ファイルに XMP メタデータが含まれている場合に設定します。
アニメーション(A): 1 ビット
アニメーション画像かどうかを指定します。アニメーションを制御するには、「ANIM」チャンクと「ANMF」チャンクのデータを使用する必要があります。
予約済み(R): 1 ビット
0 でなければなりません。リーダーはこのフィールドを無視しなければなりません。
予約済み: 24 ビット
0 でなければなりません。リーダーはこのフィールドを無視しなければなりません。
キャンバス幅 - 1: 24 ビット
ピクセル単位のキャンバスの幅(1 ベース)。実際のキャンバスの幅は 1 + Canvas Width Minus One です。
キャンバスの高さ - 1: 24 ビット
ピクセル単位のキャンバスの高さ(1 ベース)。実際のキャンバスの高さは 1 + Canvas Height Minus One です。

[キャンバスの幅] と [キャンバスの高さ] の積は 2^32 - 1 以下でなければなりません。

今後の仕様で、さらにフィールドが追加される可能性があります。不明なフィールドは無視されます。

アニメーション

アニメーションは「ANIM」チャンクと「ANMF」チャンクで制御されます。

'ANIM' Chunk:

アニメーション画像の場合、このチャンクにはアニメーションのグローバル パラメータが含まれます。

 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
キャンバスのデフォルトの背景色。[青、緑、赤、アルファ] バイト順で指定します。この色は、キャンバスのフレーム周囲の未使用のスペースと、最初のフレームの透明ピクセルを塗りつぶすために使用することができます。背景色は、Disposal メソッドが 1 の場合にも使用されます。

:

  • 「VP8X」ChunkAlpha フラグが設定されていない場合でも、背景色には不透明でないアルファ値を含んでも構いません。

  • ビューアアプリは、背景色の値をヒントとして扱うべきであり、使用する必要はありません。

  • キャンバスは各ループの開始時にクリアされます。これを実現するために、背景色を使用しても構いません。

ループ回数: 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 です。
フレーム幅 - 1: 24 ビット(uint24
フレームの幅(1 ベース)。フレームの幅は 1 + Frame Width Minus One です。
フレームの高さのマイナス 1: 24 ビット(uint24
フレームの高さ(1 を基準とする)。フレームの高さは 1 + Frame Height Minus One です。
フレーム持続時間: 24 ビット(uint24
次のフレームを表示するまでの待機時間(1 ミリ秒単位)。フレーム持続時間を 0(多くの場合 10 以下)の解釈は実装によって定義されることに注意してください。多くのツールとブラウザでは、GIF と同様の最小再生時間が割り当てられています。
予約済み: 6 ビット
0 でなければなりません。リーダーはこのフィールドを無視しなければなりません。
混合方法(B): 1 ビット

現在のフレームの透明ピクセルを、前のキャンバスの対応するピクセルとブレンドする方法を指定します。

  • 0: アルファ ブレンドを使用します。前のフレームを破棄した後、アルファ ブレンド(下記参照)を使用して現在のフレームをキャンバスにレンダリングします。現在のフレームにアルファ チャンネルがない場合、アルファ値は 255 であると想定し、実質的に長方形を置き換えます。

  • 1: ブレンドしません。前のフレームを破棄した後、現在のフレームを覆っている長方形を上書きして、現在のフレームをキャンバスにレンダリングします。

廃棄方法(D):1 ビット

現在のフレームがキャンバスに表示された後(次のフレームをレンダリングする前)に、そのフレームをどのように扱うかを指定します。

  • 0: 廃棄しないでください。キャンバスはそのままにします。

  • 1: 背景色に配置します。現在のフレームがカバーしているキャンバス上の長方形を、「ANIM」チャンクで指定した背景色で塗りつぶします。

:

  • フレーム処理は、フレーム レクタングル(フレーム Xフレーム Yフレーム幅フレームの高さで定義された長方形)にのみ適用されます。キャンバス全体を覆う場合もあれば、覆っていない場合もあります。

  • アルファ ブレンド:

    R、G、B、A の各チャネルが 8 ビットで、RGB チャネルにアルファが事前乗算されていない場合、「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
    
  • アルファ ブレンドは、画像のカラー プロファイルを考慮して、線形色空間で行うべきです。カラー プロファイルが存在しない場合は、標準の RGB(sRGB)が使用されます。(ガンマが約 2.2 であるため、sRGB も線形化する必要があります)。

フレームデータ: チャンクサイズ - 16 バイト

構成項目:

: 「ANMF」ペイロードであるフレームデータは、RIFF ファイル形式で説明されているように、パディングされた個々のチャンクで構成されます。

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 位置を囲むアルファ値が次のようにラベル付けされているとします。

 C | B |
---+---+
 A | X |

位置 X のアルファ値を計算しようとしています。まず、フィルタリング方法に応じて予測が行われます。

  • メソッド 0: predictor = 0
  • メソッド 1: predictor = A
  • メソッド 2: 予測子 = B
  • メソッド 3: predictor = clip(A + B - C)

ここで、clip(v) は次の値と等しくなります。

  • v < 0 の場合は 0、
  • v > 255 の場合は 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 ロスレス形式を使用して圧縮されます。
アルファ ビットストリーム: チャンクサイズ - 1 バイト

エンコードされたアルファ ビットストリーム。

このオプションのチャンクには、このフレームのエンコードされたアルファデータが含まれます。「VP8L」チャンクを含むフレームには、このチャンクを含むべきではありません。

根拠: 透明性情報はすでに「VP8L」チャンクの一部になっています。

アルファ チャンネル データは、非圧縮の元データとして保存されるか(圧縮方法が「0」の場合)、可逆形式を使用して圧縮されます(圧縮方法が「1」の場合)。

  • 元データ: 長さ = 幅 x 高さのバイト シーケンスで構成され、スキャン順にすべての 8 ビットの透明度値を含みます。

  • 可逆形式の圧縮: バイト シーケンスは、幅 x 高さの暗黙的なディメンションの圧縮されたイメージ ストリーム(WebP Lossless Bitstream Format で説明)です。つまり、この画像ストリームには、画像のサイズを示すヘッダーが含まれていません。

    根拠: ディメンションは他のソースからすでにわかっているため、再度保存すると冗長になり、エラーが発生しやすくなります。

    画像ストリームをアルファ、赤、緑、青(ARGB)の色値にデコードしたら、可逆形式の仕様で説明されているプロセスに従って、ARGB 4 重点の緑チャネルから透明度情報を抽出する必要があります。

    根拠: Green チャンネルは、他のチャンネルとは異なり、仕様で追加の変換ステップが許可され、圧縮率を向上させることができます。

ビットストリーム(VP8/VP8L)

このチャンクには、単一フレームの圧縮されたビットストリーム データが含まれます。

ビットストリーム チャンクは、(i)「VP8」(重要な 4 文字のスペースに注意)を FourCC として使用する「VP8」チャンクか、(ii)「VP8L」を FourCC として使用する「VP8L」チャンクのいずれかです。

「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 bytes
ICC プロファイル。

このチャンクは画像データの前に配置しなければなりません。

このようなチャンクは 1 つまでであるべきです。そのようなチャンクが複数ある場合、リーダーは最初のチャンク以外をすべて無視しても構いません。詳しくは、ICC 仕様をご覧ください。

このチャンクが存在しない場合、sRGB を想定すべきです。

メタデータ

メタデータは「EXIF」チャンクまたは「XMP」チャンクに保存できます。

各タイプのチャンクは最大で 1 つであるべきです(「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 メタデータ: Chunk Size バイト
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 メタデータ: Chunk Size バイト
XMP 形式の画像メタデータ。

'XMP ' FourCC の 4 番目の文字は ASCII スペース(0x20)です。

メタデータの処理に関するその他のガイダンスについては、Metadata Working Group の「メタデータ処理のガイドライン」をご覧ください。

未知のチャンク

FourCC がこのドキュメントで説明するチャンクと異なる RIFF チャンク(RIFF ファイル形式を参照)は、不明なチャンクとみなされます。

根拠: 未知のチャンクを許容することで、将来的な形式への拡張に対応できます。また、アプリケーション固有のデータを保存することも可能になります。

ファイルに不明なチャンクが含まれていても構いません。

リーダーはこれらのチャンクを無視すべきです。ライターは、これらのチャンクを特に変更する予定がない限り、元の順序で保持すべきです。

フレームからキャンバスを組み立てる

ここでは、アニメーション画像の場合にキャンバスを組み立てる方法の概要を説明します。

このプロセスではまず、「VP8X」チャンクで指定された寸法(幅 Canvas Width Minus One + 1 ピクセル、高さ Canvas Height Minus One + 1 ピクセル)を使用してキャンバスを作成します。「ANIM」チャンクの Loop Count フィールドは、アニメーション プロセスを繰り返す回数を制御します。Loop Count 値がゼロでない場合は Loop Count - 1Loop Count がゼロの場合は無限大です。

各ループの反復処理の開始時に、「ANIM」チャンクの背景色またはアプリケーション定義の色を使用してキャンバスが塗りつぶされます。

「ANMF」チャンクには、表示順に指定された個々のフレームが含まれます。各フレームをレンダリングする前に、前のフレームの Disposal method が適用されます。

デコードされたフレームのレンダリングは、キャンバスの左上隅を原点として、デカルト座標(2 * Frame X2 * Frame Y)から開始します。幅 Frame Width Minus One + 1 ピクセル、高さ Frame Height Minus One + 1 ピクセルが Blending method を使用してキャンバスにレンダリングされます。

キャンバスは 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.
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
    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

ファイル レイアウトの例

アルファを使用して非可逆エンコードされた画像は次のようになります。

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)