ByteScope

WebP ファイル形式

Google の WebP。非可逆・可逆どちらの画像も入る RIFF コンテナです。

MIME タイプ
image/webp
拡張子
.webp
カテゴリ
画像

マジックナンバー(ファイル署名)

0x0000000052494646RIFFRIFF container
0x0000000857454250WEBP'WEBP' form type

WebP 形式について

WebP は非可逆・可逆の両モードに加えてアニメーションと透過にも対応し、多くの場合 JPEG や PNG よりも小さくなります。実体は RIFF コンテナで、RIFF の 4 文字、4 バイトの長さ、フォームタイプ WEBP という並びです。その後ろに来るのはチャンクが 1 つ、または複数で、最初に何が来るかがファイルの性格をすべて決めます。単純な非可逆画像なら VP8 チャンク 1 つ、単純な可逆画像なら VP8L チャンク 1 つ、アルファチャンネル・アニメーション・ICC プロファイル・メタデータのいずれかを持つものは VP8X チャンクになり、そこで機能を宣言したうえで、実データを供給するチャンクが後ろに続きます。

ヘッダーの構造(バイト単位)

オフセット長さフィールド意味
04RIFF container tag52 49 46 46、ASCII の RIFF。WebP 固有では決してありません。AVI も WAV もまったく同じ 4 バイトで始まるので、オフセット 8 まで読まない限り形式は何も確定しません。
44RIFF payload sizeこのフィールドより後ろ全体のバイト数をリトルエンディアンで表したもので、ファイルサイズから 8 を引いた値です。たいていのサイズフィールドと違ってこれは正確であることが期待されているので、ディスク上の長さと比べれば 4 バイト読むだけで途中切れや不用意な追記をすぐ捕まえられます。
84WEBP form type57 45 42 50。WebP を他のあらゆる RIFF ファイルから切り分けるのはこのフィールドで、オフセット 0 のタグと合わせたものが実質的なマジックナンバーです。真ん中の 4 バイトだけ可変の 12 バイト、という形になります。
124First chunk FourCCここに来られるのは 3 種類だけで、他は不正です。56 50 38 20 は末尾がスペースの VP8 で、単純な非可逆画像。56 50 38 4C は VP8L で、単純な可逆画像。56 50 38 58 は VP8X で、アルファ・アニメーション・Exif・XMP・ICC プロファイルのいずれかがあるときに使う拡張形です。
164First chunk payload size後続するチャンクデータの長さをリトルエンディアンで表したもので、FourCC とサイズの 8 バイトは含みません。RIFF はすべてのチャンクを偶数長にパディングしますが、そのパディングバイトはここに数えません。奇数長のチャンクで手書きパーサがずれるのは、この細部が原因です。
203VP8 frame tag — simple lossy onlyVP8 ビットストリームを開く 3 バイトのビットフィールド群です。最下位ビットがキーフレームかインターフレームか、続く 3 ビットがプロファイル、1 ビットが show_frame、残り 19 ビットが最初のデータパーティションのサイズです。静止画の WebP では必ずキーフレームになります。
233VP8 key-frame start code — simple lossy only定数 9D 01 2A。この形式が持つ 2 つ目の署名に最も近い存在で、オフセット 23 にこれが見つかれば、非可逆 WebP であることと、最初のチャンクヘッダが期待どおりの大きさだったことの両方が確認できます。
264VP8 width and height — simple lossy onlyリトルエンディアンの 16 ビットが 2 つ、幅のあと高さ。それぞれ下位 14 ビットだけが寸法で、上位 2 ビットは水平・垂直のスケールヒントですが、実装しているものはほぼ皆無です。VP8 フレーム 1 枚の一辺が 16383 画素を超えられないのは、この 14 ビットのせいです。
201VP8L signature byte — simple lossless only定数 2F。その直後に幅マイナス 1 と高さマイナス 1 が 14 ビットずつビットストリームに詰め込まれるので、このページの他のフィールドと違ってバイト境界に載っておらず、シフトなしに hex ダンプから読むことはできません。
204VP8X flags and reserved bytes — extended onlyフラグ 1 バイトと、予約のゼロ 3 バイト。フラグはビット 5 から下へ順に ICC プロファイル、アルファチャンネル、Exif メタデータ、XMP メタデータ、アニメーションの有無を告げます。これは宣言であってデータではありません。各機能の実体は、ファイルの後ろにあるそれぞれのチャンクが供給します。
246VP8X canvas size — extended onlyキャンバス幅マイナス 1 とキャンバス高さマイナス 1 を 24 ビットのリトルエンディアンで 2 つ。VP8 フレーム 1 枚がとりうる大きさをはるかに超えるキャンバスを許します。アニメーションではフレームを合成する土台のキャンバスがこれで、個々のフレームは自分のオフセットとサイズを持ちます。

似た形式との見分け方

紛らわしい形式見分け方
AVIどちらも RIFF ファイルなので先頭 8 バイトは同一です。判定はオフセット 8 のフォームタイプがすべてで、WebP なら 57 45 42 50、AVI なら末尾スペース付きの 41 56 49 20 です。52 49 46 46 だけを見るツールは動画を平気で画像とラベル付けするので、検出器が category を間違えたときはまずここを疑ってください。
WAV同じ RIFF の罠を逆向きに踏むケースで、オフセット 8 が 57 41 56 45 です。わざわざ名指しする価値があるのは、実際に出会う RIFF 形式が WAV・AVI・WebP の 3 つで、音声・動画・画像にまたがっていて、しかも 9 バイト目まで区別がつかないからです。
PNG89 50 4E 47 と 52 49 46 46。アルファ付きの可逆画像という用途で真正面から競合し、可逆 WebP がファイルサイズでおよそ 4 分の 1 勝つのが普通です。ただし透過を持つ可逆 WebP は ALPH チャンクを別に持つ VP8X ファイルなので、構造は上で説明した単純な非可逆形とまったく共通しません。
GIFアニメーション WebP は別形式ではありません。アニメーションフラグを立てた VP8X ファイルに、背景色とループ回数を伝える ANIM チャンクと、フレームごとの ANMF チャンクが入っただけのものです。GIF を数分の一のサイズで置き換え、透過は 1 インデックスではなく完全なアルファになります。多くのプラットフォームがアップロードを変換したうえで .gif の URL のまま配信し続けているのは、そのためです。

よくある壊れ方

  • オフセット 4 の RIFF サイズが古いまま。ここを更新せずに WebP へ追記すると、厳格なリーダーは宣言された長さで読み止め、寛容なリーダーはデータの最後までチャンクを歩き続けます。結果として同じ画像が、あるツールではメタデータを見せて別のツールでは見せなくなります。シェルのリダイレクトでファイルを連結したときの定番の結末です。
  • 途中切れ。12 バイトのコンテナヘッダとチャンクヘッダは残るので寸法は正しく読め、VP8 パーティションが尽きるまで絵の上のほうはデコードできます。下は平坦な灰色や緑のままです。オフセット 4 のサイズフィールドが実際のファイル長を超えるので、4 バイトで確認できます。
  • 奇数長チャンクの後のパディングバイトの欠落。RIFF はチャンクを偶数長にパディングすることを要求しており、書き手が忘れると以降のチャンクヘッダの位置がすべて 1 バイトずれます。最初のチャンクはデコードできるので画像は出て、ICC プロファイルや Exif ブロックだけが黙って消えます。
  • 拡張子が違うまま配信されたりリネームされたりしたもの。SNS やメッセージアプリは WebP を .jpg の名前で渡してくることが日常茶飯事なので、古いデスクトップエディタで開けないファイルはたいてい無傷の WebP です。オフセット 0 の 4 バイトで決着しますし、再エンコードは不要でリネームするだけで足ります。
  • VP8X ヘッダが、ファイルに存在しない機能を約束している場合。アルファフラグが立っているのに ALPH チャンクが続かないと、デコーダの判断が割れます。不透明として描くものもあれば、そのまま拒否するものもあります。バイト配置としては不正な点がないので、バリデータは通してしまいます。

この形式の現在地

WebP はウェブ上の画像配信における今どきの既定形式で、2020 年の Safari 14 で全ブラウザ対応がそろって以来その地位にあります。位置づけとしてちょうど使いやすい真ん中です。同画質の JPEG より 4 分の 1 から 3 分の 1 ほど小さく、可逆モードは PNG に勝ち、アルファもアニメーションも同じコンテナに入り、しかも夜間バッチではなく CDN や画像サーバでその場で変換できる速さでエンコードできます。AVIF のほうが圧縮率は上、スマートフォンが撮るのは HEIC ですが、どちらも WebP ほど安く作れず、あって当然と見なせるほど普及してもいません。制約は現実に存在するので、採用前に知っておく価値があります。チャンネルあたり 8 ビット固定なので HDR も広色域配信もできず、非可逆モードではクロマサブサンプリングが強制で、1 フレームの一辺は 16383 画素までです。1 形式だけでフォールバックの分岐を持ちたくないサイトの写真コンテンツなら、今日の正解はこれです。picture 要素とフォールバックがすでに整っていて圧縮率を最大化したいなら、AVIF を第一、WebP を第二に置くのが定石です。

WebP ファイルをこのサイトで開く

どれもブラウザ内で動きます。ファイルが端末から出ることはありません。

関連する形式

WebP と混同しやすい形式です。先頭バイトを見比べてください。

形式先頭バイト拡張子
PNG89 50 4E 47 0D 0A.png
JPEGFF D8 FF.jpg
WAV52 49 46 46.wav
AVI52 49 46 46.avi

よくある質問

ファイルのマジックナンバーとは何ですか?

ファイル先頭の数バイトで、名前が何であろうとその形式を示すものです。PNG は必ず 89 50 4E 47 で始まり、ZIP は 50 4B 03 04 で始まります。OS もブラウザも file コマンドも、拡張子を信用せずこのバイト列を読みます。だからファイル名を変えても中身の正体は変わりません。

マジックナンバーを自分で確認する方法は?

macOS や Linux なら xxd -l 16 ファイル名 で先頭 16 バイトが表示されます。Windows なら PowerShell で Format-Hex -Path ファイル名 -Count 16 です。あるいはこのサイトのファイル形式判別ツールにドロップすれば、ローカルでバイト列を読んで形式を教えてくれます。アップロードはありません。

2 つの形式が同じマジックナンバーを持つのはなぜ?

一方が他方の上に作られているからです。docx、xlsx、pptx、apk、jar、epub はすべて中身が ZIP アーカイブなので ZIP の署名で始まり、区別するには内部のエントリを見る必要があります。Java の class ファイルと macOS のユニバーサルバイナリはどちらも CA FE BA BE で始まり、直後のフィールドで見分けます。

マジックナンバーがまったくないファイルもある?

あります。XML、HTML、JSON、SVG、CSV といったテキストベースの形式には固定のバイト署名がないため、構造から判別します。先頭の <?xml 宣言、<svg 要素、あるいは { に続く引用符付きのキーなどです。これは確定ではなく推測なので、このリファレンスではそうした形式をプローブ判別として示しています。

マジックナンバーが一致すればそのファイルは安全?

いいえ。わかるのは形式であって、中身が無害かどうかではありません。正規の PDF や docx でも悪意のあるペイロードを含んでいることがあります。特に拡張子とバイト列が食い違うときに真の形式を知るのは有用な第一段階ですが、マルウェアスキャンではありません。

WebP かもしれないファイルをお持ちですか?ファイル形式判別ツールで調べる — マジックナンバーをローカルで読み取ります。アップロードは一切ありません。またはすべての形式を見る。