また、翻訳もご覧ください。
Copyright © 1996-2025 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
本書はPNG(ポータブル・ネットワーク・グラフィックス)について説明します。PNGは、ロスレスで移植性に優れ、高効率に圧縮された静止画およびアニメーションラスタ画像の拡張可能なファイルフォーマットです。PNGはGIFの特許フリーな代替となり、TIFFの多くの一般的な用途も置き換えることができます。インデックスカラー、グレースケール、トゥルーカラー画像、およびオプションのアルファチャンネルをサポートします。サンプルのビット深度は1〜16ビットです。
PNGは、ワールド・ワイド・ウェブなどオンラインでの閲覧アプリケーションでの利用を想定して設計されており、プログレッシブ表示オプション付きで完全なストリーム配信に対応しています。PNGは堅牢で、ファイル全体の整合性チェックや、一般的な伝送エラーの簡易検出を提供します。また、異種プラットフォーム間での色再現性向上のためカラースペース情報の格納も可能です。
本仕様では、Internet Media Types「image/png」と「image/apng」の2種類を定義します。
このセクションは、本書が公開された時点での文書のステータスを示します。現在のW3Cの公開文書や本技術レポートの最新版は、W3C 標準・草案インデックス(https://www.w3.org/TR/)でご覧いただけます。
本仕様は国際規格となることを意図していますが、現時点ではまだ国際規格ではありません。本仕様を国際規格として参照することは適切ではありません。
本書は、Portable Network Graphics (PNG) ワーキンググループによって、勧告プロセスを用いて勧告として公開されました。
W3C勧告は、十分な合意形成の後、W3Cとそのメンバーにより承認され、ワーキンググループのメンバーによるロイヤリティフリー・ライセンスでの実装へのコミットメントがあります。
W3Cは本仕様をWebの標準として広く展開することを推奨します。
本書は、W3C特許ポリシーの下で運営されているグループによって作成されました。 W3Cは、グループ成果物に関連してなされた公開特許開示リストを維持しています。このページには、特許開示の方法も記載されています。ある特許について「必須クレーム」を含むと信じる個人は、W3C特許ポリシー第6節に従い、その情報を開示しなければなりません。
この文書は、2023年11月3日版 W3Cプロセス文書に準拠しています。
本仕様の設計目標は以下の通りです:
本仕様は、個々のコンピュータグラフィックス画像やフレームベースアニメーションを、ロスレスで移植性があり圧縮された形でインターネット上で伝送するための、データストリームおよび関連ファイルフォーマットであるPortable Network Graphics(PNG、発音は「ピン」)を規定します。
本仕様で使用する用語の定義は次の通りです。
色度は輝度を問わず色の質を示す指標です。
前景画像は背景に対して合成されると言う。
出典: [RFC1951]
ソフトウェアは画像をフレームバッファに読み込むことで画面に表示させます。
0および2bit depth -
1に対応する画像。
輝度と色度の両方で色を完全に定義できます。正式な定義は[COLORIMETRY]を参照。
0および2bit depth - 1に対応しない画像。
PNGではRGBのみ利用可能であり、ICtCpはサポートされません。
0〜231-1の範囲に制限された4バイトの符号なし整数。
一部言語で4バイト符号なし値の扱いが困難なため、この制限があります。
ネットワークバイト順の2バイト符号なし整数。
スタンダードダイナミックレンジはプライマリ(色域)と独立しており、PNGは広色域SDR形式もサポートします。
deflate系の圧縮方式。
出典: [rfc1950]
この方式のサンプル実装を含むライブラリ名も意味します。
伝送エラーのほとんどを検出できるチェック値の一種。
デコーダは受信データのCRCを計算し、エンコーダが付加したCRCと比較してチェックします。一致しない場合はデータまたはCRCが破損していることを示します。
すべてのPNG画像には1つの静止画像が含まれます。
一部のPNG画像(Animated PNG(APNG)と呼ばれる)には、フレームベースのアニメーションシーケンス、すなわちアニメーション画像も含まれます。これは最初のフレームが—そうである場合も、そうでない場合もあります—静止画像であることがあります。アニメーション非対応の表示装置(プリンタなど)は、アニメーションシーケンスではなく静止画像を表示します。
本仕様はPNGデータストリームを規定し、PNGデータストリームを生成するPNGエンコーダ、PNGデータストリームを解釈するPNGデコーダ、および一つのPNGデータストリームを別のPNGデータストリームに変換するPNGエディタに対していくつかの要件を課します。アプリケーションとPNGエンコーダ/デコーダ/エディタ間のインタフェースは規定しません。エンコーダに提示される、またはデコーダにより出力される画像の正確な形式も規定しません。ここでは4種類の画像を区別します。
この4種類の画像の関係は、Figure 1に示します。
サンプル、チャネル、ピクセル、およびサンプル深度の関係は、Figure 2に示します。
色サンプルが位置付けられるRGBカラースペースは、次の4つの方法のいずれかで指定できます。
ハイエンド用途では、最初の2つの方法が最も柔軟性と制御性を提供します。3つ目の方法は特定の(しかし非常に一般的な)カラースペースを示すのに有効です。4つ目の方法はICCプロファイルが広く採用される以前に標準化されたもので、RGBデータの正確な色度をガンマ補正とともに指定できます(C. ガンマと色度参照)。ただし、色管理対応アプリケーションは通常、最初の3つのいずれかを優先し、色管理非対応アプリケーションは通常、これら4つすべてを無視します。
Table 1は、カラースペース情報を提供するチャンクタイプの一覧で、それぞれに優先度(Priority)を割り当てています。単一の画像にこれらのチャンクタイプが複数含まれる場合、最も小さい優先度番号のチャンクが優先され、番号が大きいチャンクタイプは無視されるべきです。
| チャンクタイプ | 優先度 |
|---|---|
| cICP | 1 |
| iCCP | 2 |
| sRGB | 3 |
| cHRM と gAMA | 4 |
ガンマ補正は、アルファチャネルが存在してもアルファチャネルには適用されません。アルファサンプルは常にフルレンジで、完全不透明に対する線形の割合を表します。
マスタリング用のメタデータを提供してもかまいません。
エンコード対象のPNG画像を作成するために、参照画像に複数の変換を適用します(Figure 3参照)。変換は次の順序で適用され、角括弧は任意であることを示します。
[alpha separation]
indexing or ( [RGB merging] [alpha compaction] )
sample depth scaling
すべてのピクセルが完全透過または完全不透明のいずれかである場合、アルファ分離、アルファ圧縮、および インデックス化の変換により、復元された参照画像のアルファのサンプル深度が元の参照画像と異なる、またはアルファチャネルがなくなることがあります。これはどのピクセルの不透明度の程度にも影響しません。両者の参照画像は等価と見なされ、これらの変換はロスレスと見なされます。それでもアルファのサンプル深度を保持したいエンコーダは、アルファのサンプル深度を変更する変換を行わない選択ができます。
参照画像内のすべてのアルファサンプルが最大値である場合、アルファチャネルは省略でき、よりコンパクトにエンコード可能な等価の画像になります。
異なるピクセル値の数が256以下で、RGBのサンプル深度が8を超えず、かつアルファチャネルが存在しない、またはちょうど8ビット長である、またはすべてのピクセルが完全透過か完全不透明のいずれかである場合、インデックスカラー表現(インデックス化変換により得られる)がエンコードにおいてより効率的となることがあります。 インデックスカラー表現では、各ピクセルはパレットへのインデックスに置き換えられます。パレットは、8ビットのサンプル(赤・緑・青)3つを含むエントリのリストです。アルファチャネルが存在する場合、8ビットのアルファサンプルからなる並行の表(アルファテーブル)も存在します。
PNG画像がインデックスカラーでない場合でも、限られた色数しか表示できないビューアを支援するために、推奨パレットを作成してもかまいません。
インデックスカラー画像では、エンコーダはアルファ値が最大のテーブルエントリが末尾にまとまるようにパレットを並べ替えることができます。この場合、これらのエントリを省いた短縮形式でテーブルをエンコードできます。
インデックスカラーのPNGを作成するエンコーダは、パレットテーブルの実際の長さを超えるインデックス値を挿入してはなりません。これはエラーであり、デコーダのエラー処理はまちまちです。
赤・緑・青のチャネルのサンプル深度が同じで、かつ各ピクセルにおいて赤・緑・青サンプルの値が等しい場合、これら3つのチャネルは単一のグレースケールチャネルに結合できます。
非インデックス画像において、あるRGB(またはグレースケール)値を持つすべてのピクセルが完全に透過で、それ以外のすべてのピクセルが完全に不透明であるような値が存在する場合、アルファチャネルは、その透過となるRGB(またはグレースケール)値を特定するだけで、よりコンパクトに表すことができます。
PNG画像では、すべてのサンプル深度がサポートされているわけではありません(6.1 カラータイプと値参照)。また、すべてのチャネルは同じサンプル深度でなければなりません。PNG画像のすべてのチャネルは、参照画像内のいずれのサンプル深度よりも小さくない最小の許容サンプル深度を使用し、参照画像の可能なサンプル値をPNG画像での次の許容範囲に線形に写像します。Figure 5は、深度3のサンプルが深度4のサンプルにどのように写像されるかを示します。
許容されるサンプル深度を少数に限定することで、デコーダが対処すべきケース数を減らせます。サンプル深度のスケーリングは可逆でデータ損失はありません。これは参照画像のサンプル深度をPNGデータストリームに記録できるためです。サンプル深度の記録がない場合、参照画像のサンプル深度はPNG画像のサンプル深度に等しくなります。12.4 サンプル深度スケーリングおよび13.12 サンプル深度の再スケーリングを参照してください。
参照画像の変換結果は、5種類のPNG画像のいずれかになります(Figure 6参照):
各ピクセルのフォーマットは、PNG画像タイプとビット深度に依存します。インデックスカラー以外のPNG画像タイプでは、ビット深度はピクセルあたりの総ビット数ではなく、サンプルあたりのビット数を指定します。インデックスカラー画像では、ビット深度はパレットインデックスのビット数を指定し、パレット内の色やアルファテーブルのサンプル深度を指定するものではありません。ピクセル内でのサンプルの順序は、PNG画像タイプに応じて次の通りです。
PNG画像をエンコードするプロセスの概念モデルをFigure 7に示します。各ステップは、PNG画像内のピクセルまたはインデックスの配列に対する操作を指します。パレットやアルファテーブルは、この方法ではエンコードされません。
パス抽出(Figure 7参照)は、PNG画像を縮小画像の列に分割します。最初の画像が粗いビューを定義し、後続の画像がそれを順次改善し、最後の画像でPNG画像が完成します。縮小画像の集合はインターレースPNG画像とも呼ばれます。本仕様では2つのインターレース方式を定義します。1つ目はヌル方式で、ピクセルは左から右へ、スキャンラインは上から下へ順に格納されます。2つ目は画像に対して複数回の走査を行い、7つの縮小画像列を生成します。サンプル画像の7つのパスはFigure 7に示します。8. インターレースとパス抽出を参照してください。
スキャンラインと呼ばれる各ピクセル行は、バイト列として表現されます。
PNGでは、圧縮前に画像データにフィルタ処理を適用できます。フィルタ処理はデータの圧縮効率を高める場合があります。フィルタ操作は決定的で可逆かつロスレスです。これにより、伸長後のデータを逆フィルタすることで元のデータを得られます。7.3 フィルタ処理を参照してください。
PNG画像の各パス(複数パスがある場合はそれら)のフィルタ済みスキャンライン列は、定義された圧縮方式のいずれかで圧縮されます(Figure 9参照)。連結されたフィルタ済みスキャンラインが圧縮段階への入力となり、圧縮段階の出力は単一の圧縮データストリームになります。10. 圧縮を参照してください。
チャンク化は、圧縮データストリームを扱いやすいサイズのチャンクに分割するための便利な手段です(Figure 9参照)。各チャンクには独自の冗長性チェックが付与されます。11. チャンク仕様を参照してください。
画像には補助情報を関連付けることができます。デコーダは、補助情報の全部または一部を無視してもかまいません。提供される補助情報の種類は、Table 2に記載しています。
| 情報の種類 | 説明 |
|---|---|
| アニメーション情報 | フレームの連なりと、それに関連するタイミング、位置、処理情報で定義されるアニメーション画像。ビューアが対応している場合に表示されます。プリンタなどの他のケースでは、静止画像が代わりに表示されます。 |
| 背景色 | より適切な選択肢がない場合に画像表示に用いる単色の背景色。 |
| コーディング非依存コードポイント | 伝達関数や色の原色などのメタデータを列挙してカラースペースを識別します。 もとはSDRやHDRビデオ向けですが、静止画像やアニメーション画像にも使用されます。 |
| コンテンツ光度情報 | 画像(または画像列)中で最も明るいピクセルの輝度と、列の中で最も明るいフレームの平均輝度レベル。 |
| EXIF情報 | シャッタースピード、絞り、向きなどのExchangeable image file formatメタデータ。 |
| ガンマと色度 | 望ましい出力強度に対する画像のガンマ値、および画像で使用されるRGB値の色度特性。 |
| ICCプロファイル | 画像内のサンプルが準拠するカラースペース(International Color Consortium(ICC)プロファイルの形)の記述。 |
| 画像ヒストグラム | 各パレットエントリが画像でどの程度使用されるかの推定。 |
| マスタリングディスプレイ色域 | コンテンツの制作に用いられたディスプレイの絶対的な3次元カラーボリューム(マスタリングディスプレイが再現可能な最も明るい色と暗い色を含む)の記述。表示装置上での画像提示に役立ちます。 |
| 物理ピクセル寸法 | PNG画像の提示に用いる意図したピクセルサイズとアスペクト比。 |
| 有効ビット | サンプル内で有効なビット数。 |
| sRGBカラースペース | (International Color Consortiumで定義される)レンダリングインテントと、画像サンプルがこのカラースペースに準拠していることの指示。 |
| 推奨パレット | 表示装置が画像の全色域を表示できない場合に使用できる縮小パレット。 |
| テキストデータ | 画像に関連付けられた(圧縮されている場合がある)テキスト情報。 |
| 時刻 | PNG画像が最後に変更された時刻。 |
| 透過 | PNG画像にアルファチャネルが保持されない場合に、参照画像の再構成を可能にするアルファ情報。 |
PNGデータストリームは、PNGシグネチャ(5.2 PNGシグネチャ参照)に続くチャンクの列(11. チャンク仕様参照)で構成されます。各チャンクには、その機能を指定するチャンクタイプがあります。
チャンクタイプは4バイトの並びで、ISO 646.IRV:1991([ISO646])文字集合として解釈したときに可読ラベルに対応するように選ばれます。最初の4つはクリティカルチャンクと呼ばれ、本仕様の規定に従って理解され、正しく解釈されなければなりません。これらは次の通りです。
残りのチャンクタイプは補助チャンクタイプと呼ばれ、エンコーダは生成でき、デコーダは解釈してもかまいません。
Animated PNG(APNG)は、元の静止のみのPNGフォーマットを拡張し、フレームベースのアニメーション画像をサポートします。これは従来GIFフォーマット([GIF])が用いられてきた単純なアニメーション画像の代替を意図しており、GIFにはない24ビット画像や8ビット透過もサポートします。
APNGはPNGの以前のバージョンとの後方互換性を備えています。非アニメーション対応のPNGデコーダは、APNG特有の補助チャンクを無視して静止画像を表示します。
APNGストリームは、PNG仕様の以前の版で定義された通常のPNGストリームに、アニメーションを記述し追加のフレームデータを提供する3種類のチャンクタイプを追加したものです。
APNGとして認識されるためには、acTLチャンクがストリーム中の任意のIDATチャンクより前に現れなければなりません。acTLの構造は後述します。
各再生の開始時点では、概念的に出力バッファは、IHDRチャンクの幅と高さに基づく寸法の、完全に透過な黒の長方形として完全に初期化されます。
IDATの前に単一のfcTLチャンクが存在することにより、静止画像をアニメーションの最初のフレームとして含めることができます。そうでない場合、静止画像はアニメーションの一部ではありません。
後続フレームはfdATチャンクにエンコードされ、これはIDATチャンクと同じ構造ですが、前にシーケンス番号が付きます。各フレームの配置とレンダリングに関する情報はfcTLチャンクに格納されます。fdATおよびfcTLチャンクの詳細な構造は後述します。
アニメーション全体の境界は、デフォルト画像がアニメーションの一部かどうかに関係なく、IHDRチャンクの幅と高さのパラメータで指定されます。デフォルト画像は、後続フレームに追加のスペースが必要になる場合、完全に透過な黒のピクセルで適切にパディングされるべきです。
各フレームは各再生において同一であるため、アプリケーションがフレームをキャッシュしても安全です。
fcTLおよびfdATチャンクには、ゼロ基準の4バイトのシーケンス番号があります。両チャンクタイプは同じ番号系列を共有します。この番号の目的は、補助チャンクの順序に制限を課さない本仕様において、Animated PNGのシーケンスエラーを検出(および任意に修正)することです。
最初のfcTLチャンクはシーケンス番号0を含み、残りのfcTLおよびfdATチャンクのシーケンス番号は、欠落や重複なしに昇順でなければなりません。
以下の表は、複数フレームを持つ画像や、2番目のフレームに複数のfdATチャンクがある場合のシーケンス番号の使用例を示します。(明瞭さのため、IHDRおよびIENDチャンクは省略しています。)
| シーケンス番号 | チャンク |
|---|---|
| (なし) | acTL |
| 0 | fcTL 最初のフレーム |
| (なし) | IDAT 最初のフレーム/静止画像 |
| 1 | fcTL 2番目のフレーム |
| 2 | 2番目のフレームの最初のfdAT |
| 3 | 2番目のフレームの2番目のfdAT |
| シーケンス番号 | チャンク |
|---|---|
| (なし) | acTL |
| (なし) | IDAT 静止画像 |
| 0 | fcTL 最初のフレーム |
| 1 | 最初のフレームの最初のfdAT |
| 2 | 最初のフレームの2番目のfdAT |
| 3 | fcTL 2番目のフレーム |
| 4 | 2番目のフレームの最初のfdAT |
| 5 | 2番目のフレームの2番目のfdAT |
出力バッファは、PNGのIHDRチャンクの幅と高さパラメータで指定される寸法のピクセル配列です。概念的には、各フレームはキャンバスへ合成される前に出力バッファ内で構築されます。出力バッファの内容はデコーダから参照可能です。出力バッファの四隅はキャンバスの四隅に対応付けられます。
キャンバスは、フレームを表示する出力装置上の領域です。キャンバスの内容は、必ずしもデコーダから参照できるとは限りません。bKGDチャンクが存在する場合、より望ましい背景がないときにキャンバスの塗りつぶしに使用してもよいです。
PNGデータストリームのエラーは、一般に次の2つのクラスに分類されます。
PNGデコーダは、可能な限り早期にエラーを検出し、可能な場合はエラーから回復し、そうでない場合は穏やかに失敗すべきです。エラー処理の考え方については、13.1 エラー処理で詳述します。
この節は参考(非規範)です。
PNG形式はいくつかの拡張ポイントを公開しています。
これらの拡張ポイントの一部はW3Cにより予約されており、他は私的利用に開放されています。
PNGデータストリームは、PNGシグネチャに続くチャンク列で構成されます。これはPNG画像をエンコードした結果です。
「ファイル」ではなくデータストリームという用語を用いるのは、バイト列がファイルの一部に過ぎない場合があるためです。また、バイト列が保存ファイルに全く現れず、「オンザフライ」で生成・消費される可能性を強調するためでもあります。
PNGデータストリームの最初の8バイトは常に、次の16進値を含みます。
89 50 4E 47 0D 0A 1A 0A
このシグネチャは、データストリームの残りが単一のPNG画像を含み、IHDRチャンクで始まりIENDチャンクで終わる一連のチャンクから構成されていることを示します。
このシグネチャにより、PNGデータストリームは他の種類のデータストリームと区別され、いくつかの伝送エラーを早期に検出できるようになります。
各チャンクは3つまたは4つのフィールドで構成されます(Figure 10参照)。各フィールドの意味はTable 5に記載されています。チャンクデータフィールドは空であっても構いません。
| 名称 | 説明 |
|---|---|
| 長さ | PNG 4バイト符号なし整数で、チャンクのデータフィールド内のバイト数を示します。長さはデータフィールドのみを数え、長さ自身、チャンクタイプ、CRCは含みません。ゼロも有効な長さです。エンコーダとデコーダは長さを符号なしとして扱うべきですが、その値は231-1バイトを超えてはなりません。 |
| チャンクタイプ |
チャンクタイプを定義する4バイトの並びです。チャンクタイプの各バイトは、16進値41〜5Aおよび61〜7Aに制限されます。これは、説明やPNGデータストリームの検査の便宜上、ISO
646 [ISO646]の大文字・小文字に対応します(A-Zおよびa-z)。エンコーダおよびデコーダは、チャンクタイプを文字列ではなく固定のバイナリ値として扱わなければなりません。例えば、チャンクタイプIDATをUCS
2文字集合内のそれらの文字に相当するもので表現するのは正しくありません。チャンクタイプの追加の命名規則については、5.4
チャンクの命名規則で述べます。
|
| チャンクデータ | 該当する場合、チャンクタイプに応じたデータバイト。 このフィールドは長さゼロであり得ます。 |
| CRC | チャンク内の直前のバイト(チャンクタイプフィールドおよびチャンクデータフィールドを含むが、長さフィールドは含まない)に対して計算される4バイトのCRCです。CRCはデータの破損チェックに利用できます。データを含まないチャンクでも、CRCは常に存在します。5.5 CRCアルゴリズムを参照してください。 |
チャンクデータの長さは最大値まで任意のバイト数になり得るため、実装者はバイトより大きな境界にチャンクが整列していると仮定してはなりません。
チャンクタイプは、そのバイトをISO 646の文字 [ISO646]として解釈したときに意味のある名称になるように選ばれます。チャンクタイプは、タイプが認識されない場合でもデコーダがチャンクの性質をある程度判断できるように割り当てられています。これらの規則により、PNGデコーダが未知のチャンクに遭遇した際の扱いを決定できるため、PNG形式の安全で柔軟な拡張が可能になります。
命名規則は通常、13. PNGデコーダとビューアで規定されるように、デコーダがチャンクタイプを認識しない場合にのみ関心の対象となります。
チャンクタイプの4つのビット、すなわち各バイトの第5ビット(値32)がプロパティビットとして、チャンクの性質を伝えるために使用されます。この選択により、人間がチャンクタイプの各バイトに対応する文字が大文字(ビット5が0)か小文字(ビット5が1)かによって、割り当てられた性質を読み取れます。
プロパティビットはチャンクタイプ固有の一部であり、したがって任意のチャンクタイプに対して固定です。したがって、CHNKとcHNkは、同じチャンクが異なる性質を持つのではなく、関連のない別個のチャンクタイプです。
プロパティビットの意味はTable 6に定義されています。
| 名称と位置 | 定義 | 説明 |
|---|---|---|
| 補助ビット:1バイト目 | 0(大文字)=クリティカル、 1(小文字)=補助。 |
クリティカルチャンクは、データストリームの内容を正しく表示するために必要です(例:画像ヘッダチャンク(IHDR))。デコーダが画像を抽出しようとして、補助ビットが0の未知のチャンクタイプに遭遇した場合、当該画像に安全に解釈できない情報が含まれていることをユーザに示さなければなりません。 補助チャンクは、データストリームの内容を意味のある形で表示するのに厳密には必要ではありません(例:時刻チャンク(tIME))。補助ビットが1の未知のチャンクタイプに遭遇したデコーダは、そのチャンクを安全に無視して画像の表示を続行できます。 |
| プライベートビット:2バイト目 | 0(大文字)=パブリック、 1(小文字)=プライベート。 |
パブリックチャンクはW3Cが定義のために予約しています。プライベートチャンクの定義は、12.10.1 プライベートチャンクの利用に規定されています。プライベートチャンク名の2文字目は小文字、パブリックチャンク名の2文字目は大文字です。 |
| 予約ビット:3バイト目 | この版のPNGでは0(大文字)。 予約ビットが1の場合、そのデータストリームはこの版のPNGに適合しません。 |
チャンク名の3文字目の大文字・小文字の意味は、将来の拡張のために予約されています。この国際規格では、すべてのチャンク名は3文字目が大文字でなければなりません。 |
| コピー安全ビット:4バイト目 | 0(大文字)=コピー非安全、 1(小文字)=コピー安全。 |
このプロパティビットは純粋なデコーダには関係ありませんが、PNGエディタには必要です。このビットは、修正されているデータストリーム内の未認識チャンクの適切な取り扱いを定義します。PNGエディタの規則は、14.2 PNGエディタの動作でさらに議論します。 |
仮想的なチャンクタイプ「cHNk」のプロパティビットは次のとおりです。
cHNk <-- 32 bit chunk type represented in text form
||||
|||+- Safe-to-copy bit is 1 (lower case letter; bit 5 is 1)
||+-- Reserved bit is 0 (upper case letter; bit 5 is 0)
|+--- Private bit is 0 (upper case letter; bit 5 is 0)
+---- Ancillary bit is 1 (lower case letter; bit 5 is 1)
したがって、この名称は、補助・パブリック・コピー安全なチャンクを表します。
CRCフィールドは、[ISO-3309]および[ITU-T-V.42]で定義される事前・事後条件付きの標準化されたCRC手法を用いて計算されます。採用される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は反転されます(1の補数が取られます)。この値はMSBから順に送信(データストリームに格納)されます。バイトへの分割と順序付けのため、32ビットCRCの最下位ビットは、x31項の係数であると定義されます。
CRCの実用的な計算では、計算を高速化するためにあらかじめ計算されたテーブルがよく用いられます。D. サンプルCRC実装を参照してください。
各チャンクの配置に関する制約はTable 7に一覧し、静止画像についてはFigure 11およびFigure 12に模式的に示します。静止画像が最初のフレームを構成するアニメーション画像については、Figure 13およびFigure 14に、静止画像がアニメーションの一部でない場合はFigure 15およびFigure 16に示します。これらのラティス図は、本仕様によって課される配置上の制約を表します。図中の線は部分順序関係を定義します。上にあるチャンクは下にあるチャンクよりも前に現れなければなりません。水平方向に整列し、他の2種類のチャンク(その水平方向に整列したチャンクよりも上と下にある)に挟まれて現れるチャンクは、それら上位および下位のチャンクタイプの間で、任意の順序で現れて構いません。チャンクタイプに付された上付き文字の意味はTable 8で定義されます。これは、チャンクが必須か任意か、複数回現れ得るかを示します。2つのチャンクタイプの間の縦棒は代替を示します。
| クリティカルチャンク (この順序で現れなければならない。PLTEは任意) |
||
|---|---|---|
| チャンク名 | 複数可 | 順序制約 |
| IHDR | いいえ | 最初でなければならない |
| PLTE | いいえ | 最初のIDATの前 |
| IDAT | はい | 複数のIDATチャンクは連続していなければならない |
| IEND | いいえ | 最後でなければならない |
| 補助チャンク (この順序で現れる必要はない) |
||
| チャンク名 | 複数可 | 順序制約 |
| acTL | いいえ | IDATの前 |
| cHRM | いいえ | PLTEおよびIDATの前 |
| cICP | いいえ | PLTEおよびIDATの前 |
| gAMA | いいえ | PLTEおよびIDATの前 |
| iCCP | いいえ | PLTEおよびIDATの前。iCCPチャンクが存在する場合、sRGBチャンクは存在すべきではありません。 |
| mDCV | いいえ | PLTEおよびIDATの前 |
| cLLI | いいえ | PLTEおよびIDATの前 |
| sBIT | いいえ | PLTEおよびIDATの前 |
| sRGB | いいえ | PLTEおよびIDATの前。sRGBチャンクが存在する場合、iCCPチャンクは存在すべきではありません。 |
| bKGD | いいえ | PLTEの後;IDATの前 |
| hIST | いいえ | PLTEの後;IDATの前 |
| tRNS | いいえ | PLTEの後;IDATの前 |
| eXIf | いいえ | IDATの前 |
| fcTL | はい | 1つはIDATの前に現れてもよい;他はすべてIDATの後でなければならない |
| pHYs | いいえ | IDATの前 |
| sPLT | はい | IDATの前 |
| fdAT | はい | IDATの後 |
| tIME | いいえ | なし |
| iTXt | はい | なし |
| tEXt | はい | なし |
| zTXt | はい | なし |
| 記号 | 意味 |
|---|---|
| + | 1回以上 |
| 1 | 1回のみ |
| ? | 0回または1回 |
| * | 0回以上 |
| | | 代替 |
すべてのチャンク(プライベートおよびパブリック)は、[PNG-EXTENSIONS]に一覧化されるSHOULDです。
パブリックチャンクはW3Cが定義のために予約しています。
パブリックチャンクは、PNGの理念に合致する広範な利用を意図しています。
組織やアプリケーションは、上記の基準を満たす任意のチャンクをPNGワーキンググループにパブリックチャンクとして定義するため提出することが推奨されます。
パブリックチャンクとしての定義は自動的でも即時でもありません。提案されたパブリックチャンクタイプは、そのように定義されるまでは、公的に利用可能なソフトウェアやデータストリームで使用SHALLありません。
新たなクリティカルチャンクタイプの定義は、必要な場合を除き非推奨です。
組織およびアプリケーションは、プライベートおよび実験的な用途のためにプライベートチャンクを定義することMAYです。
プライベートチャンクは、人間のユーザにとってのみ関心のあるテキスト情報を運ぶためだけに定義SHOULD NOTです。代わりにiTXtチャンクを使用SHOULD BEし、対応するキーワードを使用SHOULD BEし、適切なキーワードを定義してください。
プライベートチャンクを[PNG-EXTENSIONS]に一覧化することは、同じプライベートチャンクが異なるアプリケーションで非互換な目的に使われる可能性を減らしますが、完全には排除しません。プライベートチャンクタイプを使用する場合、競合のリスクをさらに減らすために、追加の識別情報をチャンクデータの先頭に保存SHOULD BEです。
画像の表示に絶対不可欠ではない情報を保存するすべてのプライベートチャンクには、クリティカルチャンクタイプではなく補助チャンクタイプを使用SHOULDです。
プライベートクリティカルチャンクは定義SHOULD NOTです。なぜなら、そのようなチャンクを含むPNGデータストリームは移植性がなく、公的に利用可能なソフトウェアやデータストリームで使用SHOULD NOTだからです。プライベートクリティカルチャンクがアプリケーションにとって不可欠な場合は、標準デコーダがデータストリームを処理できないと早い段階で判明するように、データストリームの先頭付近に現れるSHOULDです。
プライベートチャンクの定義に関する追加の指針については、B. プライベートチャンクタイプに関するガイドラインを参照してください。
次のフィールドにおいて、128以上の値はプライベートフィールド値です。
これらのプライベートフィールド値は、本仕様では定義も予約もされていません。
プライベートフィールド値は、実験的またはプライベートな意味のために使用MAYです。
プライベートフィールド値は、PNGデコーダで読み取り不能なデータストリームを生じ得るため(13. PNGデコーダとビューア参照)、公的に利用可能なソフトウェアやデータストリームには出現SHOULD NOTです。
4.5 PNG画像で説明したように、PNG画像には5種類があります。 各タイプに対応して、カラータイプがあり、これは次の値の総和です:1(パレット使用)、2(トゥルーカラー使用)、4(アルファ使用)。グレースケールおよびトゥルーカラー画像は明示的なアルファチャネルを持つことがあります。PNG画像タイプと対応するカラータイプはTable 9に示します。
| PNG画像タイプ | カラータイプ |
|---|---|
| グレースケール | 0 |
| トゥルーカラー | 2 |
| インデックスカラー | 3 |
| グレースケール(アルファ付き) | 4 |
| トゥルーカラー(アルファ付き) | 6 |
各PNG画像タイプで許可されるビット深度とサンプル深度は、画像ヘッダに示します。
グレースケールサンプルは、転送曲線が(gAMA、 sRGB、iCCP、またはcICPにより)示されている場合は輝度を表し、示されていない場合はデバイス依存のグレースケールを表します。 RGBサンプルは、カラースペースが(gAMAとcHRM、sRGB、iCCP、またはcICPにより)示されている場合はキャリブレーション済みの色情報を表し、示されていない場合は非キャリブレーションのデバイス依存色を表します。
サンプル値は必ずしも光強度に比例しません。gAMAチャンクは、サンプル値と表示出力強度の関係を指定します。ビューアは適切に補正することが強く推奨されます。4.3 カラースペース、13.13 デコーダのガンマ処理、およびC. ガンマと色度を参照してください。
PNGデータストリームにおける透明性の表現は、PNG画像タイプに応じて4通りあります(4.4.1 アルファ分離および4.4.4 アルファ圧縮参照)。
画像配列に含まれるアルファチャネルは、他のサンプルと同じサイズの8ビットまたは16ビットのサンプルを持ちます。各ピクセルのアルファサンプルは、そのピクセルのグレースケールまたはRGBサンプルの直後に格納されます。アルファ値0は完全透過を表し、2sampledepth - 1の値は完全不透明を表します。 中間の値は部分的に透過なピクセルを示し、背景画像に合成することで出力画像を得られます。
ピクセル内の色値は、そのピクセルに割り当てられたアルファ値で事前乗算(premultiplied)されていません。この規則は「非関連(unassociated)」あるいは「非プリマルチプライド(non-premultiplied)アルファ」と呼ばれることがあります。(別の一般的な手法として、サンプル値をアルファ値で事前乗算して格納する方法があります。この場合、その画像は事実上黒背景に合成済みです。PNGはプリマルチプライドアルファを使用しません。その結果、画像エディタはPNG画像の透明度を容易に変更できます。)12.3 アルファチャネルの作成および13.16 アルファチャネル処理を参照してください。
1バイトを超える整数はすべてネットワークバイト順(Figure 17参照)でなければなりません。すなわち、最上位バイトが先で、その後に重要度の低いバイトが重要度の降順で続きます(2バイト整数ではMSB LSB、4バイト整数ではMSB B2 B1 LSB)。バイトの最上位ビット(値128)はビット7とし、最下位ビット(値1)はビット0とします。特に断りがない限り値は符号なしです。符号付きと明示された値は、2の補数表現で表されます。
PNG 4バイト符号なし整数は、符号なし4バイト値の扱いが困難な言語に配慮して、0から231-1の範囲に制限されています。
PNG画像(またはパス。8. インターレースとパス抽出参照)は長方形のピクセル配列であり、各スキャンライン内ではピクセルは左から右へ、スキャンラインは上から下へ並びます。各ピクセルのサイズは、ピクセルあたりのビット数によって決まります。
スキャンライン内のピクセルは常に、ピクセル間に無駄なビットが生じないようバイト列に詰められます。スキャンラインは常にバイト境界から始まります。許可されるビット深度とカラータイプは、いずれの場合もパッキングが単純かつ効率的になるよう制限されています。
カラータイプ0(グレースケール)のPNG画像では、各ピクセルは1つのサンプルであり、1バイト未満の精度(1、2、または4ビット)を持つことがあります。これらのサンプルは、スキャンラインの左端のサンプルがバイトの上位ビットになるように、続くサンプルとともにバイトに詰められます。
カラータイプ3(インデックスカラー)のPNG画像では、各ピクセルは単一のパレットインデックスです。これらのインデックスは、カラータイプ0のサンプルと同様にバイトへ詰められます。
1バイトあたり複数のピクセルが含まれる場合、スキャンラインの最後のバイトの下位ビットの一部が未使用となることがあります。これら未使用ビットの内容は規定されません。
インデックスカラーでないPNG画像では、ビット深度16のサンプル値を持つことがあります。これらのサンプル値はネットワークバイト順(MSBが先、LSBが後)です。PNGでは複数サンプルのピクセルは8ビットまたは16ビットのサンプルに限られるため、単一ピクセルの複数サンプルが1バイトに詰められることはありません。
フィルタ方式は、スキャンライン配列に適用され、圧縮効率の向上を目的とした変換です。
PNGは1つのフィルタ方式と、圧縮に備えて画像データを準備するために使用できる複数のフィルタタイプを標準化しています。この変換は、フィルタタイプのバイトを先頭に付けた、同じ長さのバイト列へと変換します(例はFigure 18参照)。
エンコーダは、インターレースPNG画像に対して単一のフィルタ方式のみを使用しなければなりませんが、縮小画像の各スキャンラインごとに異なるフィルタタイプを使用しても構いません。賢いエンコーダはスキャンラインごとにフィルタを切り替えることができます。どのフィルタを使用するかの選択方法はエンコーダに委ねられます。
フィルタタイプのバイトは画像データの一部とは見なされませんが、圧縮ステップに送られるデータストリームには含まれます。9. フィルタ処理を参照してください。
パス抽出(Figure 4.8参照)は、PNG画像を縮小画像(インターレースPNG画像)の列に分割します。最初の画像が粗いビューを定義し、続く画像がこの粗いビューを順次改善し、最後の画像でPNG画像が完成します。これにより、デコーダはインターレースPNG画像をプログレッシブに表示でき、オンザフライ表示時に画像が「フェードイン」することを可能にします。平均すると、インターレースはデータストリームサイズをわずかに増加させますが、より迅速に意味のある表示をユーザに提供できます。
この国際規格では、インターレース方式として0と1の2つを定義します。その他の値は将来の標準化のために予約されています。
インターレース方式0(ヌル方式)では、ピクセルは左から右へ順に抽出され、スキャンラインは上から下へ順に抽出されます。インターレースPNG画像は単一の縮小画像です。
インターレース方式1(Adam7として知られる)では、画像に対して7つの明確なパスを定義します。各パスは参照画像内のピクセルの部分集合を送信します。各ピクセルが送信されるパス(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
Figure 4.8は、インターレース方式1の7つのパスを示します。各パス内では、選択されたピクセルはスキャンライン内で左から右へ送信され、選択されたスキャンラインは上から下へ順に送信されます。例えば、パス2にはスキャンライン0、8、16、…のピクセル4、12、20、…が含まれます(スキャンライン0、ピクセル0は左上隅)。最後のパスにはスキャンライン1、3、5、…がすべて含まれます。送信順序は、各パスで送信されるすべてのスキャンラインが同じピクセル数になるように定義されています。これは一部のフィルタを適切に適用するために必要です。インターレースPNG画像は、7つの縮小画像の列で構成されます。例えば、PNG画像が16×16ピクセルの場合、第3パスは4ピクセルを含む2本のスキャンラインからなる縮小画像になります(Figure 4.8参照)。
スキャンラインが整数個のバイトを完全に満たさない場合、そのパディングは7.2 スキャンラインで定義されるとおりです。
注:参照画像の列数が5未満、または行数が5未満の場合、一部のパスは空になります。
フィルタ処理は、圧縮の改善を目的としてPNG画像を変換します。全体のプロセスはFigure 7に示され、スキャンラインの直列化とフィルタ処理の詳細はFigure 18に示されます。
PNGは複数のフィルタ方式を許容します。インターレース画像のすべての縮小画像は単一のフィルタ方式を使用しなければなりません。本仕様で定義されるのはフィルタ方式0のみです。他のフィルタ方式は将来の標準化のために予約されています。フィルタ方式0は5種類のフィルタタイプを提供し、各縮小画像内のスキャンラインごとに異なるフィルタタイプを使用できます。
PNGは、インターレースPNG画像に適用できるフィルタタイプに追加の制限を課しません。ただし、フィルタタイプはデータの種類によって効果が等しくはありません。12.7 フィルタ選択を参照してください。
フィルタ処理は、スキャンライン内のバイト列を、フィルタタイプを先頭に付けた同じ長さのバイト列へと変換します。フィルタタイプのバイトは非空のスキャンラインにのみ関連付けられます。空のパスにはフィルタタイプのバイトは存在しません。13.10 インターレースとプログレッシブ表示を参照してください。
フィルタは、画像のビット深度やカラータイプに関わらず、ピクセルではなくバイトに対して適用されます。フィルタは、7.2 スキャンラインで説明された表現に従って構成されたスキャンラインのバイト列に対して動作します。画像にアルファチャネルが含まれる場合、アルファデータは画像データと同様にフィルタ処理されます。
フィルタは、新しいバイト値を生成するために、以下のバイトの元の値を使用することがあります。
| 名称 | 定義 |
|---|---|
| x | フィルタ対象のバイト; |
| a | xを含むピクセルの直前のピクセルにおけるxに対応するバイト(ビット深度が8未満の場合はxの直前のバイト); |
| b | 前のスキャンラインにおけるxに対応するバイト; |
| c | bを含むピクセルの直前のピクセルにおけるbに対応するバイト(ビット深度が8未満の場合はbの直前のバイト)。 |
Figure 19は、x、a、b、cの相対位置を示します。
フィルタ方式0は、Table 11に示す5つの基本フィルタタイプを定義します。Orig(y)はバイトyの元の(非フィルタ)値を表します。Filt(y)はフィルタタイプを適用した後の値を表します。Recon(y)は対応する再構成関数を適用した後の値を表します。PaethフィルタタイプのPaethPredictor
[Paeth]は後述します。
フィルタ方式0は、ちょうどこの5つのフィルタタイプの集合を規定しており、これを拡張してはなりません。これにより、デコーダはデータを伸長しなくても、未サポートのフィルタタイプが含まれているかどうかを判断できます。11.2.1 IHDR 画像ヘッダ内のフィルタ方式を確認するだけで十分です。
| タイプ | 名称 | フィルタ関数 | 再構成関数 |
|---|---|---|---|
| 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値の列が、フィルタ済みスキャンラインとして送信されます。
Orig(a) + Orig(b)の和はオーバーフローなし(少なくとも9ビットの算術)で実行されなければなりません。floor()は、除算の結果が小数であれば次に小さい整数に切り下げることを示します。言い換えれば、これは整数除算または右シフト演算です。
Paethフィルタタイプは、3つの隣接ピクセル(左、上、左上)の単純な線形関数を計算し、その値に最も近い隣接ピクセルを予測値として選択します。本仕様で用いるアルゴリズムは、Alan W. Paethによる手法の改変です([Paeth])。
PaethPredictor関数は以下のコードで定義されます。関数のロジックと、バイトa、b、c、xの位置はFigure 20に示します。Prはバイト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
PaethPredictor関数内の計算は、オーバーフローなしで厳密に実行されなければなりません。
比較の実行順序は重要であり、変更してはなりません。この関数は、(垂直、水平、対角の)3方向のうち、画像の勾配が最も小さい方向を見つけようとします。
エンコーダとデコーダは、まったく同一のPaethPredictor関数を使用します。
本国際規格で定義されるPNGの圧縮方式は方式0のみです。その他の圧縮方式の値は将来の標準化のために予約されています。PNG圧縮方式0は、スライディングウィンドウ(deflateストリームに現れる距離の上限)最大32768バイトのdeflate圧縮です。Deflate圧縮はLZ77に由来します。
PNG内のdeflate圧縮データストリームはzlibフォーマットで格納され、その構造は次のとおりです。
| zlib 圧縮方式/フラグコード | 1 byte |
| 追加フラグ/チェックビット | 1 byte |
| 圧縮データブロック | n bytes |
| チェック値 | 4 bytes |
PNG圧縮方式0では、zlibの圧縮方式/フラグコードは方式コード8(deflate圧縮)および32768バイト以下のLZ77ウィンドウサイズを指定しなければなりません。なお、zlibの圧縮方式番号は、IHDRチャンクにおけるPNGの圧縮方式番号と同一ではありません。追加フラグでプリセット辞書を指定してはなりません。
圧縮対象データが16384バイト以下である場合、PNGエンコーダはウィンドウサイズを2の累乗(最小256)に切り上げて設定してもかまいません。これは圧縮率に悪影響を与えることなく、エンコードおよびデコードの両方に必要なメモリを削減します。
zlibデータストリーム内の圧縮データは、一連のブロックとして格納されます。各ブロックは生(非圧縮)データ、固定ハフマン符号で符号化されたLZ77圧縮データ、またはカスタムハフマン符号で符号化されたLZ77圧縮データのいずれかを表します。最終ブロックのマーカビットはそれが最後のブロックであることを示し、デコーダが圧縮データストリームの終端を認識できるようにします。圧縮アルゴリズムと符号化の詳細は、deflate仕様[rfc1951]に記載されています。
zlibデータストリーム末尾に格納されるチェック値は、そのデータストリームが表す非圧縮データに対して計算されます。この計算に用いられるアルゴリズムは、PNGのチャンクCRCフィールド値に用いられるCRC計算と同一ではありません。zlibのチェック値は、主としてdeflateアルゴリズムが正しく実装されていることを相互確認するために有用です。各PNGチャンクのCRCを検証することで、PNGデータストリームが損傷なく伝送されたことに確信が持てます。
フィルタ済みスキャンラインの列は圧縮され、その結果得られたデータストリームはIDATチャンクに分割されます。すべてのIDATチャンクの内容を連結したものが1つのzlibデータストリームとなります。このデータストリームは伸長されるとフィルタ済みの画像データになります。
IDATチャンク間の境界は任意であり、zlibデータストリームのどこにでも置かれ得ることを強調しておくことが重要です。IDATチャンク境界とdeflateブロック境界、またはその他のzlibデータの特徴との間に相関があるとは限りません。例えば、終端のzlibチェック値がIDATチャンクにまたがって分割されることも十分あり得ます。
同様に、画像データの構造(すなわちスキャンライン境界)とdeflateブロック境界やIDATチャンク境界との間に必要な相関はありません。完全なフィルタ済みPNG画像は、複数のIDATチャンクに格納された単一のzlibデータストリームで表現されます。
PNGはiTXt、iCCP、およびzTXtチャンクにおいても圧縮方式0を使用します。画像データとは異なり、これらのデータストリームはチャンクをまたいで分割されません。各チャンクは独立したzlibデータストリームを含みます(10.1 圧縮方式0参照)。
本節では本仕様で使用されるチャンクを定義します。
クリティカルチャンクは、PNGデータストリームからPNG画像を正常にデコードするために絶対に必要なチャンクです。拡張チャンクはクリティカルチャンクとして定義される場合があります(14. エディタ参照)が、この運用は強く非推奨です。
妥当なPNGデータストリームはPNGシグネチャで始まり、直後にIHDRチャンク、続いて1つ以上のIDATチャンクが続き、最後はIENDチャンクで終わらなければなりません。PNGデータストリーム内において、IHDRチャンクとIENDチャンクはそれぞれ1つのみ許可されます。
4バイトのチャンクタイプフィールドには次の16進値が含まれます。
49 48 44 52
IHDRチャンクはPNGデータストリーム内の最初のチャンクでなければなりません。内容は次のとおりです。
| 幅 | 4 bytes |
| 高さ | 4 bytes |
| ビット深度 | 1 byte |
| カラータイプ | 1 byte |
| 圧縮方式 | 1 byte |
| フィルタ方式 | 1 byte |
| インターレース方式 | 1 byte |
幅と高さはピクセル単位の画像寸法を与えます。これらはPNG 4バイト符号なし整数です。0は不正な値です。
ビット深度は、サンプルまたはパレットインデックス(ピクセル単位ではない)あたりのビット数を与える1バイト整数です。有効な値は1、2、4、8、16ですが、すべての値がすべてのカラータイプで許可されるわけではありません。6.1 カラータイプと値を参照してください。
カラータイプは1バイト整数です。
各カラータイプに対するビット深度の制限は、実装を簡素化し、圧縮効率の低い組合せを禁止するために設けられています。許可される組合せはTable 12で定義されます。
| PNG画像タイプ | カラータイプ | 許可されるビット深度 | 解釈 |
|---|---|---|---|
| グレースケール | 0 | 1, 2, 4, 8, 16 | 各ピクセルはグレースケールサンプル |
| トゥルーカラー | 2 | 8, 16 | 各ピクセルは R,G,B 三つ組 |
| インデックスカラー | 3 | 1, 2, 4, 8 | 各ピクセルはパレットインデックス;PLTEチャンクが現れなければならない。 |
| グレースケール(アルファ付き) | 4 | 8, 16 | 各ピクセルはグレースケールサンプルに続いてアルファサンプル。 |
| トゥルーカラー(アルファ付き) | 6 | 8, 16 | 各ピクセルは R,G,B 三つ組に続いてアルファサンプル。 |
サンプル深度は、インデックスカラーPNG画像(カラータイプ3)の場合を除きビット深度と同じです。この場合、サンプル深度は常に8ビットです(4.5 PNG画像参照)。
圧縮方式は、画像データの圧縮に用いられた方式を示す1バイト整数です。本仕様で定義されるのは方式0(最大32768バイトのスライディングウィンドウを用いるdeflate圧縮)のみです。すべての準拠PNG画像はこの方式で圧縮されなければなりません。
フィルタ方式は、圧縮前に画像データに適用された前処理方式を示す1バイト整数です。本仕様で定義されるのはフィルタ方式0(5種類の基本フィルタタイプを用いた適応フィルタリング)のみです。詳細は9. フィルタ処理を参照してください。
インターレース方式は、画像データの伝送順序を示す1バイト整数です。本仕様では2つの値が定義されています:0(非インターレース)および1(Adam7インターレース)。詳細は8. インターレースとパス抽出を参照してください。
4バイトのチャンクタイプフィールドには次の16進値が含まれます。
50 4C 54 45
PLTEチャンクには1~256個のパレットエントリが含まれ、各エントリは次の形式の3バイト系列です。
| 赤 | 1 byte |
| 緑 | 1 byte |
| 青 | 1 byte |
エントリ数はチャンク長から決定されます。チャンク長が3で割り切れない場合はエラーです。
このチャンクはカラータイプ3では現れなければならず、カラータイプ2および6では現れてもかまいません。カラータイプ0および4では現れてはなりません。PLTEチャンクは2個以上存在してはなりません。
カラータイプ3(インデックスカラー)では、PLTEチャンクは必須です。PLTEの最初のエントリはピクセル値0、2番目はピクセル値1、というように参照されます。パレットエントリ数は、画像のビット深度で表現できる範囲(例えばビット深度4では24=16)を超えてはなりません。ビット深度が許す数より少ないエントリ数であってもかまいませんが、その場合、範囲外のピクセル値が画像データ内で見つかった場合はエラーとなります。
カラータイプ2および6(トゥルーカラーおよびトゥルーカラー(アルファ付き))では、PLTEチャンクは任意です。存在する場合、直接表示できないときにトゥルーカラー画像を量子化するための(1~256の)推奨色セットを提供します。ただし、この目的にはPLTEチャンクではなくsPLTチャンクを使用することが推奨されます。PLTEおよびsPLTのいずれのチャンクも存在せず、画像を直接表示できない場合、量子化はビューイングシステム側で行う必要があります。しかし、しばしば色の選択はPNGエンコーダが一度行っておく方が望ましいことがあります(12.5 推奨パレット参照)。
パレットは、画像のビット深度に関わらずサンプルあたり8ビット(1バイト)を使用することに注意してください。特に、16ビットのトゥルーカラー画像を量子化した推奨パレットであっても、パレット自身は8ビット深度です。
パレットエントリがすべて画像で使用されている必要はなく、またすべてが相互に異なる必要もありません。
4バイトのチャンクタイプフィールドには次の16進値が含まれます。
49 44 41 54
IDATチャンクには、圧縮アルゴリズムの出力ストリームである実際の画像データが含まれます。詳細は9. フィルタ処理および10. 圧縮を参照してください。
IDATチャンクは複数存在してもかまいません。その場合、間に他のチャンクを挟まず連続して現れなければなりません。圧縮データストリームは、すべてのIDATチャンクのデータフィールドの内容を連結したものです(データフィールドは長さゼロであり得ることに注意)。
一部の画像では、最後のIDATチャンクの末尾に未使用の余剰バイトが存在する場合があります。これは、使用されたバッファの一部だけでなくバッファ全体を格納した場合に起こり得ます。これは望ましくありません。可能であれば、エンコーダはこれら未使用バイトを含めないべきです。どうしても含める必要がある場合は、それらのバイトをゼロに設定することで偶発的なデータ共有を防げます。デコーダはこれらの末尾バイトを無視すべきです。
4バイトのチャンクタイプフィールドには次の16進値が含まれます。
49 45 4E 44
IENDチャンクはPNGデータストリームの終端を示します。このチャンクのデータフィールドは空です。
本仕様で定義される補助チャンクは、4.8.2 チャンクタイプに示した順序で列挙されています。これはPNGデータストリーム中に現れる順序を意味するものではありません。補助チャンクはデコーダによって無視されてもかまいません。各補助チャンクについて、ここで記述する動作はデコーダがそのチャンクを無視しないことを前提としています。
4バイトのチャンクタイプフィールドには次の16進値が含まれます。
74 52 4E 53
tRNSチャンクは、(インデックスカラー画像に対する)パレットエントリに対応するアルファ値、または(グレースケールおよびトゥルーカラー画像に対する)単一の透過色を指定します。tRNSチャンクの内容は次のとおりです。
| カラータイプ 0 | |
|---|---|
| グレーサンプル値 | 2 bytes |
| カラータイプ 2 | |
| 赤サンプル値 | 2 bytes |
| 緑サンプル値 | 2 bytes |
| 青サンプル値 | 2 bytes |
| カラータイプ 3 | |
| パレットインデックス0のアルファ | 1 byte |
| パレットインデックス1のアルファ | 1 byte |
| …等… | 1 byte |
カラータイプ3(インデックスカラー)の場合、tRNSチャンクはPLTEチャンクの各エントリに対応する1バイトのアルファ値の系列を含みます。各エントリは、対応するパレットインデックスのピクセルが指定のアルファ値を持つものとして扱われることを示します。アルファ値の解釈は8ビットのフルアルファチャネルと同じで、0は完全透過、255は完全不透明を意味し、画像のビット深度に依存しません。tRNSチャンクはパレットエントリ数を超える数のアルファ値を含んではなりませんが、パレットエントリ数より少ない値を含んでいてもかまいません。この場合、残りのすべてのパレットエントリのアルファ値は255と見なされます。一般的なケースとしてパレットインデックス0のみを透過にしたい場合は、1バイトのtRNSチャンクだけで十分であり、すべてのパレットインデックスが不透明である場合にはtRNSチャンクは省略できます。
カラータイプ0または2の場合、画像のビット深度にかかわらずサンプルあたり2バイトが使用されます(7.1 整数とバイト順参照)。指定されたグレーサンプル値またはRGBサンプル値のピクセルは透過(アルファ値0と同等)として扱い、それ以外のピクセルは完全不透明(アルファ値 2bitdepth-1)として扱います。画像のビット深度が16未満の場合は下位ビットが使用されます。エンコーダは残りのビットを0に設定すべきであり、デコーダは値を使用する前に残りのビットを0にマスクしなければなりません。
カラータイプ4および6では、すでにフルアルファチャネルが存在するため、tRNSチャンクを出現させてはなりません。
16ビットのグレースケールまたはトゥルーカラーデータでは、13.12 サンプル深度の再スケーリングで述べるように、tRNSチャンク内の16ビット値全体に一致するピクセルのみが透過になります。デコーダは透過性の判定が終わるまで、サンプル深度の再スケーリングを延期しなければなりません。
4バイトのチャンクタイプフィールドには次の16進値が含まれます。
63 48 52 4D
cHRMチャンクは、PNG画像で使用される赤・緑・青の表示基本色の1931 CIEのx,y色度および参照されるホワイトポイントを指定するために使用できます。詳細はC. ガンマと色度を参照してください。より高度な色管理と制御のためには、iCCPおよびsRGBチャンクが提供されています。
cHRMチャンクの内容は次のとおりです。
| 名称 | サイズ |
|---|---|
| ホワイトポイント x | 4 bytes |
| ホワイトポイント y | 4 bytes |
| 赤 x | 4 bytes |
| 赤 y | 4 bytes |
| 緑 x | 4 bytes |
| 緑 y | 4 bytes |
| 青 x | 4 bytes |
| 青 y | 4 bytes |
各値は、PNG 4バイト符号なし整数としてエンコードされ、xまたはyの値に100000を掛けたものを表します。
0.3127 の値は整数 31270 として格納されます。
cHRMチャンクはすべてのPNGデータストリームで許可されていますが、グレースケール画像では有用性は低くなります。
このチャンクは、デコーダが理解する最優先の色チャンクでない限り無視されます。
4バイトのチャンクタイプフィールドには次の16進値が含まれます。
67 41 4D 41
実際には、望ましい表示出力の強度を指定するだけでは不十分です。望ましい出力が得られる視聴条件も指定する必要があります。gAMAにおける視聴条件は、sRGB仕様 [SRGB] の参照視聴条件です。異なる視聴条件への調整は通常カラーマネジメントシステムによって処理されます。調整が行われない場合でも、誤差は通常小さくなります。高い色忠実度を望むアプリケーションは、sRGBやiCCPチャンクの利用を検討してもよいでしょう。
gAMAチャンクの内容は次のとおりです。
| 画像ガンマ | 4 bytes |
値はPNG 4バイト符号なし整数としてエンコードされ、ガンマ値に100000を掛けたものを表します。
ガンマ値 1/2.2 は整数 45455 として格納されます。
12.1 エンコーダのガンマ処理および13.13 デコーダのガンマ処理も参照してください。
このチャンクは、デコーダが理解する最優先の色チャンクでない限り無視されます。
4バイトのチャンクタイプフィールドには次の16進値が含まれます。
69 43 43 50
iCCPチャンクの内容は次のとおりです。
| プロファイル名 | 1-79 bytes(文字列) |
| ヌル区切り | 1 byte(ヌル文字) |
| 圧縮方式 | 1 byte |
| 圧縮済みプロファイル | n bytes |
プロファイル名は、そのプロファイルを参照するための任意の分かりやすい名称でよく、大文字小文字は区別されます。プロファイル名には印字可能なLatin-1文字と空白のみを含めなければなりません(使用可能なコードポイントは 0x20-7E と 0xA1-FF のみ)。先頭・末尾・連続する空白は許可されません。本仕様で定義される圧縮方式は方式0(deflate圧縮によるzlibデータストリーム。10.3 その他の圧縮の用途参照)のみです。圧縮方式のエントリに続いて、チャンクの残り全体を構成する圧縮済みプロファイルが続きます。このデータストリームを伸長すると、埋め込みICCプロファイルが得られます。
iCCPチャンクが存在する場合、画像サンプルはInternational Color Consortium [ICC][ISO_15076-1]で定義される埋め込みICCプロファイルが表すカラースペースに準拠します。ICCプロファイルのカラースペースは、カラー画像(カラータイプ2、3、6)の場合はRGBカラースペース、グレースケール画像(カラータイプ0、4)の場合はグレースケールカラースペースでなければなりません。iCCPチャンクを書き出すPNGエンコーダは、iCCPチャンクを使用しないアプリケーションとの互換性のため、ICCプロファイルを近似するgAMAおよびcHRMチャンクも併せて書き出すことが推奨されます。
このチャンクは、デコーダが理解する最優先の色チャンクでない限り無視されます。
cICPチャンクが存在しない限り、PNGデータストリームに含める埋め込みプロファイルは、iCCPで明示的に指定するかsRGBチャンクで暗黙的に指定するかのいずれか一つにとどめるのが望ましいです。
4バイトのチャンクタイプフィールドには次の16進値が含まれます。
73 42 49 54
デコーダを簡素化するため、PNGは使用可能なサンプル深度を限定し、さらにサンプル値がサンプル深度における可能な値の全域へスケーリングされるべきであると規定しています。sBITチャンクは元の有効ビット数(サンプル深度以下)を定義します。これにより、データがPNGで直接サポートされないサンプル深度であっても、PNGデコーダは元のデータをロスレスに復元できます。
sBITチャンクの内容は次のとおりです。
| カラータイプ 0 | |
|---|---|
| 有効グレースケールビット数 | 1 byte |
| カラータイプ 2 および 3 | |
| 有効赤ビット数 | 1 byte |
| 有効緑ビット数 | 1 byte |
| 有効青ビット数 | 1 byte |
| カラータイプ 4 | |
| 有効グレースケールビット数 | 1 byte |
| 有効アルファビット数 | 1 byte |
| カラータイプ 6 | |
| 有効赤ビット数 | 1 byte |
| 有効緑ビット数 | 1 byte |
| 有効青ビット数 | 1 byte |
| 有効アルファビット数 | 1 byte |
sBITで指定される各深度は0より大きく、サンプル深度(インデックスカラー画像では8、その他のカラータイプではIHDRで与えられるビット深度)以下でなければなりません。なお、sBITは、tRNSチャンクによって暗示されるアルファチャネルのサンプル深度は提供しません。その場合、アルファチャネルのすべてのサンプルビットは有効と見なされます。sBITチャンクが存在しない場合、すべてのチャネルのすべてのサンプルビットは有効と見なされます。
4バイトのチャンクタイプフィールドには次の16進値が含まれます。
73 52 47 42
sRGBチャンクが存在する場合、画像サンプルは sRGB カラースペース [SRGB] に準拠し、International Color Consortium [ICC] または [ICC-2]で定義される指定のレンダリングインテントを用いて表示されるべきです。
sRGBチャンクの内容は次のとおりです。
| 名称 | サイズ |
|---|---|
| レンダリングインテント | 1 byte |
レンダリングインテントには次の値が定義されています。
| 値 | 名称 | 説明 |
|---|---|---|
| 0 | 知覚(Perceptual) | 写真など、測色的な正確さを犠牲にしても出力デバイスの色域への良好な適応を優先する画像。 |
| 1 | 相対測色(Relative colorimetric) | ロゴなど、出力デバイスのホワイトポイントに相対的な色外観の一致を要する画像。 |
| 2 | 彩度(Saturation) | チャートやグラフなど、色相や明度よりも彩度の保持を優先する画像。 |
| 3 | 絶対測色(Absolute colorimetric) | 別の出力デバイス向け画像のプルーフなど、絶対的な測色の保持を要する画像。 |
sRGBチャンクを書き出すPNGエンコーダは、sRGBチャンクを使用しないデコーダとの互換性のため、gAMAチャンク(および任意でcHRMチャンク)も書き出すことが推奨されます。使用すべき値は次のみです。
| gAMA | |
|---|---|
| ガンマ | 45455 |
| cHRM | |
| ホワイトポイント x | 31270 |
| ホワイトポイント y | 32900 |
| 赤 x | 64000 |
| 赤 y | 33000 |
| 緑 x | 30000 |
| 緑 y | 60000 |
| 青 x | 15000 |
| 青 y | 6000 |
このチャンクは、デコーダが理解する最優先の色チャンクでない限り無視されます。
4バイトのチャンクタイプフィールドには次の16進値が含まれます。
63 49 43 50
存在する場合、cICPチャンクは、[ITU-T-H.273]で規定されるコードポイントを用いて、画像のカラースペース(原色)、伝達関数、行列係数およびスケーリング係数を指定します。ビデオフォーマットのシグナリングは、デコーダやレンダリング時を含めて、画像の処理において使用することがSHOULDです。
cICPチャンクは、上述の特性を識別する4つの1バイト符号なし整数から構成されます。
cICPチャンクの構文は次のとおりです。
| 名称 | サイズ |
|---|---|
| 色度点(Color Primaries) | 1 byte |
| 伝達関数(Transfer Function) | 1 byte |
| 行列係数(Matrix Coefficients) | 1 byte |
| フルレンジフラグ(Video Full Range Flag) | 1 byte |
cICPチャンクの各フィールドは、[ITU-T-H.273]における同名のパラメータに対応します。
PNGで現在サポートされるカラーモデルはRGBのみであるため、
Matrix Coefficientsは0に設定しなければなりません(shall)。
Video Full Range Flagが0(ナローレンジ画像)の場合、推奨される実践は、負の値を含むように、EOTFまたは逆のOETFなどの伝達関数を拡張範囲にわたって定義することです。
これは次のように行います。
out = sign(in) * TransferFunction(abs(in))
cICPチャンクはPLTEおよびIDATチャンクより前に置かなければなりません(MUST)。
このチャンクは、デコーダが理解する場合、最優先の色チャンクです。
sRGBチャンクを用いてsRGB画像を簡潔にシグナルするのと同様に、cICPはDisplay P3画像 [Display-P3] を簡潔にシグナルするためにも使用できます。
4バイトのチャンクタイプフィールドには次の16進値が含まれます。
6D 44 43 56
存在する場合、mDCVチャンクは、[SMPTE-ST-2086]で規定される、コンテンツ制作時点で用いられたマスタリングディスプレイのカラーボリューム(mDCV)を特徴付けます。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チャンクの構文を示します。
| 名称 | サイズ | 除数値 |
|---|---|---|
| マスタリングディスプレイの色度点(CIE 1931 x,y の R,G,B) | 12 bytes | 0.00002 |
| マスタリングディスプレイのホワイトポイント色度(CIE 1931 x,y) | 4 bytes | 0.00002 |
| マスタリングディスプレイの最大輝度(cd/m2) | 4 bytes | 0.0001 |
| マスタリングディスプレイの最小輝度(cd/m2) | 4 bytes | 0.0001 |
色度点は、順にx、yの順で、各々が除数値で割られた x または y の基本色度値を表す、3組のPNG 2バイト符号なし整数としてエンコードされます。並び順は、x色度が最大の原色、次にy色度が最大の原色、最後に残る原色の順です。RGBカラースペースではR、G、Bの順に対応します。
ホワイトポイントは、順にx、yの順で、各々が除数値で割られた x または y のホワイト色度値を表す、1組のPNG 2バイト符号なし整数としてエンコードされます。
最大および最小輝度値は、cd/m2の絶対輝度値を除数値で割った値を表すPNG 4バイト符号なし整数としてエンコードされます。
除数は実際の値から格納値への写像を与えます。例えば、原色およびホワイトポイントに対する単位なしの除数 0.00002 の場合、色度 (0.6800, 0.3200) は {34000, 16000} として格納されます。
mDCVチャンクはPLTEおよびIDATチャンクより前に置かなければなりません(MUST)。
以下に [ITU-R-BT.2100] HDR の mDCV 例を示します。
以下に [Display-P3] のSDRに関する mDCV の例を示します。
4バイトのチャンクタイプフィールドには次の16進値が含まれます。
63 4C 4C 49
存在する場合、cLLIチャンクはHDRコンテンツの2つの特性を識別します:
cLLIチャンクは静的メタデータを追加し、関連コンテンツのトーンマッピングを特定のターゲットディスプレイに最適化する機会を提供します。これは、コンテンツ自体のトーンマッピングをターゲットディスプレイのピーク輝度能力に合わせて調整し、クリッピングを防ぐことで達成されます。トーンマッピングの最適化手法は現時点では主観的です。
MaxCLL(Maximum Content Light Level)は、再生シーケンス全体における単一ピクセルの最大光度(cd/m2、ニトとも)の静的メタデータ値を用います。処理やノイズに起因する誤検出が下流の意図されたトーンマッピングに悪影響を与えるのを防ぐため、しばしばアルゴリズム的なフィルタが用いられます。
MaxFALL(Maximum Frame Average Light Level)は、再生シーケンス全体におけるフレーム平均光度(cd/m2、ニトとも)の最大値を静的メタデータ値で示します。MaxFALLは、まず各フレームのすべてのピクセルの復号輝度値を平均し、その後、最大の値を持つフレームの値を用いて算出します。
MaxCLL と MaxFALL の値は、PNG 4バイト符号なし整数としてエンコードされます。
[CTA-861.3-A] はcLLI値を生成するための計算方法を記述していますが、フィルタリングについては規定していません。[HDR-Static-Meta] は、統計的外れ値やノイズ、リサンプリングフィルタによるリンギングから生じる極端な値を排除する改良手法を記述しており、実装において推奨されます。
[SMPTE-ST-2067-21] セクション7.5は、cLLIの値が不明で未計算の場合に追加情報を提供します。
Issue #319は、cLLIチャンクが存在する場合のトーンマッピング動作について議論しています。
各フレームが分析されます。
MaxCLL または MaxFALL の値がゼロの場合、その値は不明、または現在計算できないことを意味します。
この値が計算不能となる例として、ライブのアニメーションPNGストリームを作成している場合が挙げられます。このとき、ストリームが終了するまで全フレームが利用可能にならないため、値を計算できません。エンコーダは当初ゼロを用い、ストリーム終了時に計算値へ置き換えることを望むかもしれません。
以下にcLLIチャンクの構文を示します。
| 名称 | サイズ | 除数値 |
|---|---|---|
| Maximum Content Light Level(MaxCLL) | 4 bytes | 0.0001 cd/m2 |
| Maximum Frame-Average Light Level(MaxFALL) | 4 bytes | 0.0001 cd/m2 |
PNG は、画像の説明や著作権表示など、画像に関連付けられたテキスト文字列を格納するために、tEXt、iTXt、および zTXt チャンクを提供します。各テキスト文字列が何を表しているかを示すためにキーワードが使用されます。任意の数のそのようなテキストチャンクが出現することができ、同じキーワードを持つ複数のチャンクも許容されます。
次のキーワードは事前定義されており、適切な場面で使用されるべきです。
| Keyword value | Description |
|---|---|
| Title | Short (one line) title or caption for image |
| Author | Name of image's creator |
| Description | Description of image (possibly long) |
| Copyright | Copyright notice |
| Creation Time | Time of original image creation |
| Software | Software used to create the image |
| Disclaimer | Legal disclaimer |
| Warning | Warning of nature of content |
| Source | Device used to create the image |
| Comment | Miscellaneous comment |
| XML:com.adobe.xmp | Extensible Metadata Platform (XMP) information, formatted as required by the XMP specification [XMP]. The use of iTXt, with Compression Flag set to 0, and both Language Tag and Translated Keyword set to the null string, are recommended for XMP compliance. |
| Collection | Name of a collection to which the image belongs. An image may belong to one or more collections, each named by a separate text chunk. |
その他のキーワードは、プライベートまたは一般的な用途のために任意のアプリケーションによって定義されることが MAY あります。
キーワードは SHOULD 以下のようにすることが望まれます。
一般的に有用なキーワードは SHOULD で [PNG-EXTENSIONS] に登録されるべきです。
キーワードには印字可能な Latin-1 [ISO_8859-1] の文字とスペースのみを含めるものとします。すなわち、許可されるコードポイントは 0x20-7E および 0xA1-FF のみです。キーワードの先頭や末尾のスペース、連続するスペースは許可されません。また、視覚的に通常のスペースと区別できない U+00A0 NON-BREAKING SPACE も許可されません。
キーワードは登録されたとおりに正確に綴られるべきであり、デコーダは特定のキーワードを探す際に単純なリテラル比較を使用できるようにします。特にキーワードは大文字小文字を区別するとみなされます。キーワードは長さが 1 〜 79 バイトの範囲でなければなりません。
Creation Time キーワードについては、日付形式は RFC 3339 [rfc3339] の日付時刻形式、または RFC 1123 のセクション 5.2.14 で定義される日付形式のいずれかであることが SHOULD です。RFC3339 の日付時刻形式が推奨されます。実際のフィールドの形式は未定義です。
iTXt チャンクは UTF-8 エンコーディング [rfc3629] を使用し、任意の言語の文字を伝えるために使用できます。iTXt チャンクにはテキスト文字列を圧縮するオプションがあります。Unicode をサポートするため、すべてのテキスト文字列に対して iTXt の使用が推奨されます。また、印字可能な Latin-1 文字集合と U+000A LINE FEED (LF) に制限される tEXt および zTXt チャンクも存在します。zTXt 内のテキスト文字列は、zlib データストリームに圧縮され、deflate 圧縮を用います(10.3 Other uses of compression参照)。
4バイトのチャンクタイプフィールドには次の16進値が含まれます
74 45 58 74
各 tEXt チャンクはキーワードとテキスト文字列を次の形式で含みます。
| Keyword | 1-79 bytes (character string) |
| Null separator | 1 byte (null character) |
| Text string | 0 or more bytes (character string) |
キーワードとテキスト文字列はゼロバイト(ヌル文字)で区切られます。キーワードもテキスト文字列もヌル文字を含んではなりません。テキスト文字列はヌル終端ではなく(チャンク長が終了位置を定義します)、長さはゼロバイトからキーワードとヌル区切り文字の長さを差し引いた最大許容チャンク長まで任意です。
キーワードは 11.3.3.1 Keywords and text strings に記述されたとおり、テキスト文字列が表す情報の種類を示します。
テキストは Latin-1 文字集合に従って解釈されます [ISO_8859-1]。テキスト文字列は任意の Latin-1 文字を含むことができます。テキスト内の改行は単一の linefeed 文字(10)で表すべきです。Latin-1 に定義される文字と linefeed 文字以外の文字は tEXt チャンク内では定義された意味を持ちません。Latin-1 のレパートリー外の文字を含むテキストは iTXt チャンクを使用してエンコードすべきです。
4バイトのチャンクタイプフィールドには次の16進値が含まれます
7A 54 58 74
zTXt と tEXt チャンクは意味的に同等ですが、zTXt は大きなテキストブロックを格納するのに推奨されます。
zTXt チャンクは次を含みます。
| Keyword | 1-79 bytes (character string) |
| Null separator | 1 byte (null character) |
| Compression method | 1 byte |
| Compressed text datastream | n bytes |
キーワードとヌル文字は tEXt チャンクと同じ形式です。キーワードは圧縮されません。圧縮方式フィールドは使用された圧縮方式を定義します。本国際規格で定義される唯一の値は 0(deflate 圧縮)です。他の値は将来の標準化のために予約されています。圧縮方式フィールドの後に、チャンクの残りを構成する圧縮されたテキストデータストリームが続きます。圧縮方式 0 の場合、このデータストリームは zlib データストリーム(deflate 圧縮)です(10.3 Other uses of compression参照)。このデータストリームを伸長すると、同等の tEXt チャンクに格納されるテキストと同一の Latin-1 テキストが得られます。
4バイトのチャンクタイプフィールドには次の16進値が含まれます
69 54 58 74
各 iTXt チャンクは次を含みます。
| Keyword | 1-79 bytes (character string) |
| Null separator | 1 byte (null character) |
| Compression flag | 1 byte |
| Compression method | 1 byte |
| Language tag | 0 or more bytes (character string) |
| Null separator | 1 byte (null character) |
| Translated keyword | 0 or more bytes |
| Null separator | 1 byte (null character) |
| Text | 0 or more bytes |
キーワードは 11.3.3.1 Keywords and text strings に記述されています。
圧縮フラグは、非圧縮テキストであれば 0、圧縮テキストであれば 1 です。圧縮できるのはテキストフィールドのみです。圧縮方式フィールドは使用された圧縮方式を定義します。本仕様で定義される唯一の圧縮方式は 0(zlib データストリームと deflate 圧縮)です(10.3 Other uses of compression参照)。非圧縮テキストの場合、エンコーダは圧縮方式を 0 に設定し、デコーダはそれを無視しなければなりません。
言語タグは [BCP47]
によって定義される正しい言語タグでなければなりません。キーワードとは異なり、言語タグは大文字小文字を区別しません。サブタグは
IANA
language subtag registry に存在する必要があります。言語タグが空の場合、言語は未指定です。言語タグの例には en,
en-GB, es-419, zh-Hans, zh-Hans-CN,
tlh-Cyrl-AQ, ar-AE-u-nu-latn, および x-private などがあります。
翻訳されたキーワードとテキストは両方とも UTF-8 エンコーディング [rfc3629] を使用し、いずれもゼロバイト(ヌル文字)を含んではなりません。テキストは、このチャンク内の他のテキストデータと異なりヌル終端ではなく、長さはチャンク長から導出されます。
翻訳キーワードには改行を含めてはなりません。テキスト内の改行は単一の linefeed(16進 0A)で表すべきです。残りの制御文字(01-09, 0B-1F, 7F-9F)は、翻訳キーワードおよびテキストの両方で使用が推奨されません。UTF-8 では、文字としての 80-9F(使用が推奨されない)と、バイトとしての 80-9F(多くの場合必要となる)の間に差異がある点に注意してください。
翻訳キーワードが空でない場合、それは言語タグで示された言語へのキーワードの翻訳を含むべきであり、キーワードを表示するアプリケーションは翻訳キーワードも併せて表示することが望まれます。
4バイトのチャンクタイプフィールドには次の16進値が含まれます
62 4B 47 44
bKGD チャンクは、画像を提示するためのデフォルトの背景色を指定します。ユーザ指定の背景や、ブラウザのような大きなページの一部としての優先される背景がある場合は、bKGD チャンクは無視されるべきです。bKGD チャンクは次を含みます:
| Color types 0 and 4 | |
|---|---|
| Greyscale | 2 bytes |
| Color types 2 and 6 | |
| Red | 2 bytes |
| Green | 2 bytes |
| Blue | 2 bytes |
| Color type 3 | |
| Palette index | 1 byte |
color type 3(indexed-color)の場合、値は背景として用いる色のパレットインデックスです。
カラータイプ 0 および 4(グレースケール、アルファ付きグレースケール)では、この値は、 0 から (2bitdepth)-1 の範囲で背景として使用する グレーレベルです。カラータイプ 2 および 6 (トゥルーカラー、アルファ付き トゥルーカラー)では、これらの値は、0 から (2bitdepth)-1 の範囲の RGB サンプルとして指定される、背景として使用する色です。いずれの場合も、一貫性を保つため、画像のビット深度にかかわらず サンプルごとに 2 バイトが使用されます。 画像のビット深度が 16 未満の場合は、最下位ビットが使用されます。 エンコーダーはその他のビットを 0 に設定し、デコーダーは値を使用する前に その他のビットを 0 でマスクしなければなりません。
4バイトのチャンクタイプフィールドには次の16進値が含まれます
68 49 53 54
hIST チャンクは一連の 2 バイト符号なし整数を含みます:
| Frequency | 2 bytes (unsigned integer) |
| ...etc... |
hIST チャンクはパレット中の各色の概略的な使用頻度を示します。ヒストグラムチャンクは PLTE チャンクが存在する場合にのみ出現できます。ビューアがパレットのすべての色を提供できない場合、ヒストグラムは表示用に色のサブセットを選択するのに役立つかもしれません。
PLTE の各エントリに対して正確に一つのエントリが存在しなければなりません。各エントリはそのパレットインデックスを持つピクセルの画像内での割合に比例します;正確なスケール係数はエンコーダが選びます。
ヒストグラムのエントリは概算であり、例外としてゼロのエントリは対応するパレットエントリが画像内で全く使用されていないことを示します。ある色のピクセルが存在するならば、そのヒストグラムエントリはゼロであってはなりません。
注:パレットが truecolor 画像を量子化した推奨パレットである場合、デコーダはエンコーダとは異なる方法でピクセルをパレットエントリにマップする可能性があるため、ヒストグラムは必然的に概算になります。この状況では、いかなるエントリも使用され得るため通常ゼロのエントリは現れないはずです。
4バイトのチャンクタイプフィールドには次の16進値が含まれます
70 48 59 73
pHYs チャンクは、画像の表示における意図されたピクセルサイズまたはアスペクト比を指定します。内容は次のとおりです:
| Name | Size |
|---|---|
| Pixels per unit, X axis | 4 bytes (PNG four-byte unsigned integer) |
| Pixels per unit, Y axis | 4 bytes (PNG four-byte unsigned integer) |
| Unit specifier | 1 byte |
unit specifier に対して定義される値は次のとおりです:
| Value | Description |
|---|---|
| 0 | unit is unknown |
| 1 | unit is the metre |
unit specifier が 0 の場合、pHYs チャンクはピクセルのアスペクト比のみを定義し、ピクセルの実際の物理サイズは未指定のままです。
pHYs チャンクが存在しない場合、ピクセルは正方形であると仮定され、各ピクセルの物理サイズは未指定です。
4バイトのチャンクタイプフィールドには次の16進値が含まれます
73 50 4C 54
sPLT チャンクは次を含みます:
| Name | Size |
|---|---|
| Palette name | 1-79 bytes (character string) |
| Null separator | 1 byte (null character) |
| Sample depth | 1 byte |
| Red | 1 or 2 bytes |
| Green | 1 or 2 bytes |
| Blue | 1 or 2 bytes |
| Alpha | 1 or 2 bytes |
| Frequency | 2 bytes |
| ...etc... |
各パレットエントリは 6 バイトまたは 10 バイトで、5 つの符号なし整数(red, blue, green, alpha, frequency)を含みます。
エントリ数は任意です。PNG デコーダは sample depth バイトの後に残るチャンク長からエントリ数を決定します。sPLT の sample depth が 8 の場合、残り長は 6 で割り切れるべきであり、sample depth が 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 の sample depth は 8 または 16 でなければなりません。
赤、緑、青、およびアルファの各サンプルは、画像のビット深度にかかわらず、sPLT のサンプル深度に応じて、それぞれ 1 バイトまたは 2 バイトです。カラーサンプルには アルファが事前乗算されておらず、 どの背景に対しても事前合成されていません。アルファ値 0 は完全な透明を意味します。 アルファ値 255 (sPLT のサンプル深度が 8 の場合)または 65535(sPLT のサンプル 深度が 16 の場合)は、完全な不透明を意味します。sPLT チャンクは、どのカラータイプでも現れることがあります。sPLT 内のエントリーは、PNG 画像と同じガンマ値および色度値を使用しますが、 PNG 画像の色空間で使用される値の範囲外になる場合があります。たとえば、 グレースケール PNG 画像では、 通常、各 sPLT エントリーの赤、緑、および青の値は等しくなりますが、これは 必須ではありません。同様に、PNG 画像が 透明度を使用していない場合でも、sPLT エントリーは不透明でないアルファ値を持つことができます。
各 frequency 値は、そのパレットエントリが RGBA 空間で最も近い一致となるピクセルの割合に比例します(任意の背景に対して composited される前)。正確なスケール係数は PNG エンコーダが選びます;個々の値が 0 〜 65535 の範囲を適度に満たすようにすることが推奨されます。エンコーダはロゴや顔の特徴のような「重要」と考える色の周波数を人工的に大きくすることができます。ゼロは最も重要でない色、またはほとんど使われない色を意味する有効な周波数です。すべての周波数がゼロの場合、それらは意味を持たない、つまり PNG 画像における実際の出現頻度について何も推測できないことを意味します。
複数の sPLT チャンクは許容されますが、それぞれ異なるパレット名を持たなければなりません。
4バイトのチャンクタイプフィールドには次の16進値が含まれます
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 チャンクは 1 個のみ許可されます。
eXIf チャンクは元の image data に関するメタデータを格納します。画像が Exif プロファイル作成後に編集されている場合、このデータはもはや PNG の image data に適用されないかもしれません。デコーダが Exif データの有効性について独立した知識を持たない限り、そのデータは歴史的価値のみと見なすべきであることが推奨されます。eXIf チャンクと他の PNG チャンク内のデータ間の潜在的な矛盾を解決することは本仕様の範囲外です。
PNG 仕様はチャンクサイズを最大 231-1 バイトまで許容しますが、Exif プロファイルが JPEG [JPEG] データストリームに書き込まれる予定がある場合、Exif データ全体の長さを JPEG APP1 マーカー(Exif)セグメントに収まるように 216-9 バイトを超えないように調整する必要があることに注意すべきです。
データの最初の 2 バイトは、リトルエンディアン(Intel)の場合は "II"、ビッグエンディアン(Motorola)の場合は "MM" です。デコーダは最初の 4 バイトをチェックして次の16進値を持つことを確認すべきです:
49 49 2A 00 (ASCII "II", 16-bit little-endian integer 42)
または
4D 4D 00 2A (ASCII "MM", 16-bit big-endian integer 42)
その他の値は将来の定義のために予約されています。
画像編集アプリケーションは、Exif 仕様の付録 E.3 を検討すべきであり [CIPA-DC-008]、画像が変更されたときに Exif データを更新するための要件について議論されている箇所を参照すべきです。エンコーダはこれらの要件に従うべきですが、デコーダは必ずしもそれが実行されていると仮定してはなりません。
エンコーダがサムネイルを更新することを選択する場合もありますが、メイン画像が変更された場合に Exif プロファイル内のサムネイルが更新されているかどうかは保証されません。
4バイトのチャンクタイプフィールドには次の16進値が含まれます
74 49 4D 45
tIME チャンクは、画像の最終変更時刻(初回作成時刻ではありません)を与えます。内容は次のとおりです:
| Name | Size |
|---|---|
| Year | 2 bytes (完全な年; たとえば 1995、95 ではない) |
| Month | 1 byte (1-12) |
| Day | 1 byte (1-31) |
| Hour | 1 byte (0-23) |
| Minute | 1 byte (0-59) |
| Second | 1 byte (0-60)(うるう秒を許容するため) |
ローカル時刻ではなく協定世界時(UTC)を指定するべきです。
tIME チャンクは、image data が変更されるたびに自動的に適用・更新されるタイムスタンプとしての使用を意図しています。
4バイトのチャンクタイプフィールドには次の16進値が含まれます
61 63 54 4C
acTL チャンクはこれがアニメーションPNG画像であることを宣言し、フレーム数およびループ回数を与えます。内容は次のとおりです:
num_frames |
4 bytes |
num_plays |
4 bytes |
各値はPNG four-byte unsigned integerとしてエンコードされます。
num_frames はアニメーション内の総フレーム数を示します。これは fcTL
チャンクの数と等しくなければなりません。0 は無効な値です。単一フレームの PNG の場合は 1 が有効です。この値が実際のフレーム数と一致しない場合はエラーとして扱うべきです。
num_plays はこのアニメーションが再生される回数を示します;0 の場合は無限に再生すべきです。0
でない場合、最後の再生の終了時にアニメーションは最終フレームで停止すべきです。
acTL チャンクは有効な PNG ストリーム内で最初の IDAT チャンクの前に現れなければなりません。
Web 互換性のために、このチャンクの開発と展開の間に長い時間差があり PNG 仕様への組み込みが遅れたことから、このチャンク名は例外的にプライベートチャンクであるかのように定義されています。
4バイトのチャンクタイプフィールドには次の16進値が含まれます
66 63 54 4C
fcTL チャンクは個々のフレームの寸法、位置、表示遅延、および破棄動作を定義します。各フレームに対して正確に1つの fcTL チャンクが必要です。内容は次のとおりです:
| Name | Size |
|---|---|
sequence_number |
4 bytes |
width |
4 bytes |
height |
4 bytes |
x_offset |
4 bytes |
y_offset |
4 bytes |
delay_num |
2 bytes |
delay_den |
2 bytes |
dispose_op |
1 byte |
blend_op |
1 byte |
sequence_number はアニメーションチャンクのシーケンス番号を定義し、0
から始まります。これは PNG four-byte
unsigned integer としてエンコードされます。
width と height は続くフレームの幅と高さを定義します。これらは PNG four-byte unsigned integers
としてエンコードされ、0 より大きくなければなりません。
x_offset と y_offset は続くフレームの x および y 位置を定義します。これらは PNG four-byte unsigned integers
としてエンコードされます。0 は有効な値です。
フレームは x_offset, y_offset, width, height
で定義される領域内にレンダリングされなければなりません。この領域はデフォルト画像の外に出てはならないため、x_offset + width
は IHDR の幅を超えてはならず、同様に y_offset +
height は IHDR の高さを超えてはなりません。
delay_num と delay_den は遅延分数の分子と分母を定義し、現在のフレームを表示する時間(秒)を示します。分母が 0 の場合は
100 として扱われます(すなわち delay_num は 1/100 秒単位を指定します)。分子の値が 0
の場合、デコーダは可能な限り速やかに次のフレームをレンダリングするべきですが、ビューアは合理的な下限を課すことがあります。これらは2バイトの符号なし整数としてエンコードされます。
フレームのタイミングは各フレームのデコードや表示に要する時間に依存しないようにするべきであり、そうすることでデコーダの性能に関わらず同じ速度でアニメーションが再生されます。
dispose_op
はこのフレームのレンダリング後に行う領域の破棄方法を定義します。すなわち遅延終了時(次フレームをレンダリングする前)に出力バッファをどのように変更するかを指定します。これは1バイトの符号なし整数としてエンコードされます。
dispose_op の有効な値は次のとおりです:
| 0 | APNG_DISPOSE_OP_NONE |
| 1 | APNG_DISPOSE_OP_BACKGROUND |
| 2 | APNG_DISPOSE_OP_PREVIOUS |
APNG_DISPOSE_OP_NONEAPNG_DISPOSE_OP_BACKGROUNDAPNG_DISPOSE_OP_PREVIOUS最初の fcTL チャンクが dispose_op に
APNG_DISPOSE_OP_PREVIOUS を使用している場合、それは APNG_DISPOSE_OP_BACKGROUND
として扱うべきです。
blend_op
はフレームが現在の出力バッファ内容にアルファ合成されるか、あるいはその領域を完全に置き換えるかを指定します。これは1バイトの符号なし整数としてエンコードされます。
blend_op の有効な値は次のとおりです:
| 0 | APNG_BLEND_OP_SOURCE |
| 1 | APNG_BLEND_OP_OVER |
blend_op が APNG_BLEND_OP_SOURCE
の場合、アルファを含むフレームのすべての色成分がフレーム領域の現在の内容を上書きします。blend_op が
APNG_BLEND_OP_OVER の場合、フレームはそのアルファに基づいて出力バッファ上に合成され、単純な OVER
演算(Alpha Channel
Processing参照)を使用します。サンプルコードの第2のバリエーションが適用可能である点に注意してください。
最初のフレームについては、再生の開始時に出力バッファがクリアされるため、両方のブレンドモードは機能的に等価であることに注意してください。
デフォルト画像に対応する fcTL チャンク(存在する場合)には次の制約があります:
x_offset と y_offset フィールドは 0 でなければなりません。width と height フィールドは IHDR
チャンクの対応するフィールドと等しくなければなりません。前述のとおり、出力バッファは各再生の開始時に完全に透明な黒で初期化されなければなりません。これは各再生が同一になることを保証するためです。デコーダは結果が同一になる限り明示的なクリア手順を回避してもかまいません。例えば、デフォルト画像がアニメーションに含まれ、かつ
blend_op に APNG_BLEND_OP_SOURCE を使用する場合、出力バッファ全体が上書きされるためクリアは不要です。
Web 互換性のために、このチャンクの開発と展開の間に長い時間差があり PNG 仕様への組み込みが遅れたことから、このチャンク名は例外的にプライベートチャンクであるかのように定義されています。
4バイトのチャンクタイプフィールドには次の16進値が含まれます
66 64 41 54
fdAT チャンクは、静止画像に対する IDAT チャンクと同じ役割をアニメーションに対して果たします。 一連の fdAT チャンクには、 すべてのフレームの画像データ(または、最初のフレームとして 静止画像を含むアニメーションの場合は、 最初のフレームより後にあるすべてのフレームの画像データ)が含まれます。次のものを含みます。
| Name | Size |
|---|---|
sequence_number |
4 bytes |
frame_data |
n bytes |
各フレームに対して少なくとも1つの fdAT チャンクが必要です(ただし、そのフレームが IDAT チャンクで表現される最初のフレームである場合を除く)。
各フレームの圧縮データストリームは、同フレーム内のすべての fdAT チャンクの frame_data
フィールドの内容を sequence_number の昇順で連結したものになります。
シーケンス番号が存在するため、fdAT チャンクは長さゼロであってはなりません;ただし frame_data フィールドはゼロ長であり得ます。
伸長すると、このデータストリームは各スキャンラインの先頭にあるフィルタバイトを含む完全なピクセルデータとなり、すべての IDAT チャンクの非圧縮データと同様です。ビット深度、color type、圧縮方式、filter
method、インターレース方式、およびパレット(存在する場合)は static image と同じです。
各フレームは、ファイル内の最初の IDAT チャンクの前に現れる任意のクリティカルまたは補助チャンクによって指定されたすべてのプロパティを継承します。ただし幅と高さは fcTL チャンクから取得されます。
PNG に pHYs チャンクが存在する場合、APNG
画像とその x_offset および y_offset
の値はメイン画像と同様にスケーリングされなければなりません。概念的には、そのようなスケーリングは出力バッファを canvas にマップする際に行われます。
Web 互換性のために、このチャンクの開発と展開の間に長い時間差があり PNG 仕様への組み込みが遅れたことから、このチャンク名は例外的にプライベートチャンクであるかのように定義されています。
この節はエンコーダの動作に関する要件と推奨事項を示します。PNG エンコーダは、前節で規定された形式に準拠する PNG イメージから PNG データストリームを生成しなければなりません。ここに示す追加の推奨事項に従うことで、通常は最良の結果が得られます。
C. ガンマと色度で、 ガンマに関する問題の簡単な説明を参照してください。
完全なカラーマネジメントに対応する PNG エンコーダーは、ここで説明するものよりも高度な計算を実行し、 iCCP チャンクの使用を 選択する場合があります。画像 サンプルが sRGB 仕様 [SRGB] に準拠していることが分かっている場合、 エンコーダーには、追加のガンマ処理を行わずに sRGB チャンクを書き込むことが強く推奨されます。どちらの場合も、 iCCP または sRGB チャンクを認識しない PNG デコーダーが使用できるように、適切な gAMA チャンクを生成することが 推奨されます。
PNG エンコーダーは、次の事項を決定する必要があります。
gAMA チャンクに書き込む値は、PNG デコーダーを 意図したとおりに動作させる値です。13.13 デコーダーのガンマ処理を参照してください。
適用する変換は、画像サンプルの性質と精度によって異なります。 サンプルが浮動小数点形式または高精度整数形式で光 強度を表す場合(コンピューターグラフィックスレンダラーから取得した場合など)、エンコーダーは、データを PNG データストリームに含める整数 値へ量子化する前に、ガンマ 符号化(指数が 1 未満のべき関数を適用すること)を 実行できます。これにより、特定のサンプル深度でのバンディングアーティファクトが減少するか、同じ視覚品質を維持しながら より小さなサンプルを使用できます。0 から 1 の範囲の 浮動小数点値として表される強度レベルは、 次のようにデータストリームの画像サンプルへ変換できます。
integer_sample = floor((2sampledepth-1) * intensityencoding_exponent + 0.5)
式内の intensity が目的の出力強度である場合、符号化指数は、 gAMA チャンクで 使用するガンマ値です。
PNG エンコーダーが利用できる強度が元のシーンの強度である場合、別の変換が 必要になることがあります。 表示画像に元のソース 画像よりも高いコントラストを持たせることが必要な場合があります。これは、 元のシーンから表示出力までのエンドツーエンドの伝達関数の指数が 1 より大きいことに相当します。この 場合は、次のようになります。
gamma = encoding_exponent/end_to_end_exponent
元の画像が取り込まれた、または計算された条件で このようなコントラスト変更が妥当かどうか分からない場合は、 表示強度が元のシーンの 強度に比例すると想定できます。すなわち、 エンドツーエンド指数は 1 であるため、次のようになります。
gamma = encoding_exponent
画像をデータストリームにのみ書き込む場合、エンコーダーは符号化指数を自由に選択できます。 gAMA チャンク内のガンマ値が 1/2.2 になる値を選択することは、多くの場合妥当です。 これは、一般的なビデオモニターに表示する PNG デコーダーの処理を最小限に抑えられるためです。
一部の画像レンダラーは、画像を PNG データストリームに書き込むと同時に画面上に表示する場合があります。 表示されるピクセルは、 使用中の表示システムおよび観察条件に合わせてガンマ補正し、ユーザーが意図されたシーンを 適切に表現したものを見られるようにする必要があります。
レンダラーが、データストリーム用の独立したガンマ 符号化ステップを省略して、表示されたサンプル値を PNG データストリームに書き込む場合、レンダラーは 表示システムの伝達関数を べき関数で近似し、その指数の逆数を gAMA チャンクに書き込む必要があります。これにより、 PNG デコーダーは、レンダリング時に作成者の画面に表示されたものを再現できます。
ただし、レンダラーが表示装置に適した表示ピクセルを計算し、 データの保存と転送のために別個のガンマ符号化を 実行し、画像の将来の用途により適した値を gAMA チャンクに 設定することも同様に妥当です。
コンピューターグラフィックスレンダラーは、多くの場合ガンマ符号化を実行せず、代わりにサンプル 値をシーンの光強度に直接比例させます。PNG エンコーダーが、すでに整数値へ量子化されたサンプル値を受け取る場合、 それらにガンマ符号化を行っても意味はありません。さらに情報が失われるだけだからです。エンコーダーは、 サンプル値をそのまま PNG データストリームに書き込む必要があります。これは、 gAMA チャンクに 1.0 のガンマ値を含める必要があることを意味しません。これは、 シーンの強度から表示出力の強度までの意図されたエンドツーエンドの伝達関数が 必ずしも線形ではないためです。ただし、意図されたガンマ値は、 おそらく 1.0 から大きく離れてはいません。レンダリングされるシーンが昼光のシーンか 屋内のシーンかなどによって異なる場合があります。
サンプル値がハードウェアから直接取得された場合、正しい gAMA 値は、 原則として、ハードウェアの伝達関数と シーンの照明条件から推測できます。ビデオデジタイザー(「フレームグラバー」)の場合、 sRGB 仕様は最新のビデオ規格との互換性を持つよう設計されているため、サンプルはおそらく sRGB 色空間にあります。イメージスキャナーは、それほど 予測可能ではありません。CCD センサー自体は線形であるため、その出力 サンプルは入力光強度に比例している場合があります。または、スキャナーのハードウェアが、 後続の印刷におけるドットゲインを補正するよう設計されたべき関数(指数は約 0.57)をすでに 適用している場合や、 モニター上に表示するためにサンプルを補正している場合があります。特定のスキャナーの特性を判断するには、 スキャナーのマニュアルを参照するか、 較正済みターゲットをスキャンする必要がある場合があります。 ガンマは サンプルと目的の表示出力との関係を表すものであり、スキャナー入力との関係を表すものではないことに注意する必要があります。
データストリーム形式コンバーターは通常、提供された画像を異なるガンマへ変換しようとすべきではありません。 データは 変換せずに PNG データストリームへ格納し、可能であれば、ソースデータストリーム内の 情報からガンマ値を 推測する必要があります。データストリーム変換時にガンマを変更すると、表現される 強度レベルの集合が再量子化され、ほとんど利点がないまま、さらに丸め誤差が生じます。ほとんどの場合、 入力ファイルから出力ファイルへサンプル値をそのまま コピーする方が適切です。
ソースデータストリームが画像のガンマ特性を記述している場合、データストリームコンバーターには、 gAMA チャンクを書き込むことが強く推奨されます。一部のデータストリーム形式は、 表示指数 (画像サンプルを表示出力へマッピングする関数の指数であり、その逆方向ではない)を指定します。ソース ファイルのガンマ値が 1.0 より大きい場合、それはおそらく表示 指数であり、この値の逆数を PNG のガンマ値に使用する必要があります。ソースファイル形式が、画像サンプルと 表示出力以外の量との関係を記録している場合、PNG のガンマ値の推測は、これよりも複雑になります。
PNG エンコーダーまたはデータストリームコンバーターが、 ある表示システムを使用して画像が十分に表示されたことを認識しており、その 伝達関数を 指数 display_exponent のべき関数で近似できる場合、その画像には 次のガンマ値を持つものとしてマークできます。
gamma = 1/display_exponent
チャンクを省略して PNG デコーダーにおおよそのガンマ値を推測させるよりも、ほぼ 正しい値を持つ gAMA チャンクを書き込む方が適切です。PNG エンコーダーが ガンマ値を推測できない場合は、gAMA チャンクを省略する方が望ましいです。推測が必要な場合は、 PNG デコーダーに委ねる必要があります。
ガンマは、 アルファサンプルには適用されません。アルファは常に線形に表現されます。
13.13 デコーダーのガンマ 処理も参照してください。
色に関する参考は C. Gamma and chromaticity を参照してください。
フルカラーマネジメント対応の PNG エンコーダは、ここで述べるより高度な計算を行い、iCCP チャンクを使用することを選ぶかもしれません。もしイメージサンプルが sRGB 仕様に準拠すると分かっているなら、PNG エンコーダは sRGB チャンクを使用することが強く推奨されます。
ソースの表示原色の色度を決定できる、または画像の起源や実行ハードウェアに基づいて強い推測ができる場合、エンコーダは cHRM チャンクを出力することが強く推奨されます。もしそれを行うなら、gAMA チャンクも併せて書き込むべきです;デコーダは cHRM だけではあまり利用できません。
原色や ホワイトポイント に関してはいくつかの推奨や標準があり、技術に結びつくものもあります。たとえば CCIR 709 [ITU-R-BT.709] や SMPTE-C [SMPTE-170M] などです。
考慮すべきケースは次の三つです:
手描きやデジタル編集された画像の場合、制作時にどのモニタで表示していたかを特定する必要があります。多くの画像編集プログラムは使用中のモニタ種別を指定でき、内部でデバイス非依存空間を使っていることが多いです。そのようなプログラムは有効な cHRM および gAMA チャンクを書き込むのに十分な情報を持っており、自動的にそれらを書き込むことが強く推奨されます。
エンコーダがフルスペクトルレンダリングを行うコンピュータレンダラの一部としてコンパイルされている場合、内部のデバイス非依存色空間から RGB へ変換するために使用したモニタ値を cHRM チャンクに書くべきです。選択した RGB デバイスのガモット外の色はガモット内にマップされるべきです;PNG はガモット外の色を格納しません。
もしコンピュータレンダラがデバイス依存の RGB 空間で直接計算を行うなら、シーン記述とレンダリングパラメータが特定のモニタに合わせて調整されていない限り cHRM チャンクは書くべきではありません。その場合は、そのモニタのデータを使って cHRM チャンクを構築すべきです。
一部のイメージ形式はキャリブレーション情報を格納しており、それを使って cHRM チャンクを埋めることができます。たとえば TIFF 6.0 [TIFF-6.0] はオプションでキャリブレーション情報を持ち、存在するなら cHRM チャンクの構築に使うべきです。
最近の映像機器で作成された映像は、おそらく CCIR 709 の原色と D65 白色点 [ITU-R-BT.709] を使用しており、これらは表 29に示されています。
| 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] があり、これは Table 30 に示されています。
| R | G | B | White | |
|---|---|---|---|---|
| x | 0.630 | 0.310 | 0.155 | 0.3127 |
| y | 0.340 | 0.595 | 0.070 | 0.3290 |
データストリーム形式コンバーターが、提供された画像を異なる RGB 色空間へ変換しようとすることは推奨されません。 データは変換せずに PNG データストリームへ格納し、ソースの 原色の色度が既知の場合は記録する必要があります。データストリーム変換時の色空間変換は、 色域の不一致と丸め誤差が生じるため 適切ではありません。ガンマ変換の場合と同様に、データを 可逆的に格納し、画像が最終的に表示されるときに多くても 1 回だけ変換を行う方が適切です。
13.14 デコーダーのカラー 処理を参照してください。
アルファチャネルは、透明な部分を一時的に隠すマスクとして考えることも、非矩形イメージを構築する手段と考えることもできます。前者の場合、完全に透明なピクセルの色値は将来の利用のために保持するべきです。後者の場合、透明ピクセルは有用なデータを持たず、PNG が要求する矩形イメージ領域を満たすために存在するだけです。この場合、完全に透明なピクセルには圧縮のために同一の色値を割り当てるべきです。
イメージ作者は、デコーダが透明性制御を完全にはサポートしない可能性があることを念頭に置くべきです(13.16 Alpha channel processing を参照)。したがって、可能であれば透明ピクセルに割り当てる色は合理的な背景色にしておくべきです。
完全なアルファチャネルを必要としない、あるいは圧縮効率の面で許容できないアプリケーション向けに、tRNS 透過チャンクも利用可能です。
もしイメージに既知の背景色があるなら、その色は bKGD チャンクに書き込むべきです。透明性を無視するデコーダであっても、bKGD の色を未使用領域の塗りつぶしに使うことができます。
もし元の画像がプリマルチプライド(associated)アルファを持つ場合、それを PNG の非プリマルチプライド形式へ変換するには、各サンプル値を対応するアルファ値で割り、次に画像ビット深度の最大値を掛け、最も近い整数へ丸めればよいです。有効なプリマルチプライドデータでは、サンプル値が対応するアルファ値を超えることはないので、除算の結果は常に 0 〜 1 の範囲になるはずです。もしアルファ値がゼロなら、出力は黒(ゼロ)にしてください。
PNG で直接表現できないサンプル深度を持つ入力サンプルを符号化する場合、 エンコーダーは、PNG で許可されているサンプル深度まで サンプルを拡大しなければなりません。最も正確なスケーリング方法は、次の線形 方程式です。
output = floor((input * MAXOUTSAMPLE / MAXINSAMPLE) + 0.5)
ここで、入力サンプルの範囲は 0 から MAXINSAMPLE、出力の範囲は 0 から MAXOUTSAMPLE (2sampledepth-1)です。
線形スケーリング方法に近い近似値は、「左端ビット複製」によって得られます。これは、有効なビットを 最上位ビットから始まるようにシフトし、最上位のビットを空きビットに繰り返す方法です。この 方法は、多くの場合、線形スケーリングよりも高速に 計算できます。
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
|=======| |===|
| 空きビットを埋めるために左端ビットを反復
|
元のビット
これは、線形方程式で計算された値と一致します。左端ビット複製では通常、線形 スケーリングと同じ 値が得られ、その差が 1 を超えることはありません。
入力値を単純に左シフトし、下位 ビットをゼロで埋める方法では、明らかに精度の低い近似値しか得られません。この方式では、すべてのビットが 1 の 最大値が生成されないため、白を正確に再現できません。その結果、 画像がわずかに暗くなります。この方法は通常推奨されませんが、 特に 8 ビットを超えるサンプル深度を扱う場合には、圧縮率を 改善する効果があります。高いサンプル深度では、 ゼロ埋めスケーリングによって生じる相対誤差が小さいため、一部のエンコーダーはこの方法を使用する場合があります。ただし、アルファチャンネルデータにはゼロ埋めを 使用してはなりません。多くのデコーダーが、すべてゼロおよびすべて 1 のアルファ値を特殊な ケースとして扱うためです。スケーリングされたデータで、これら両方の値を正確に表現することが重要です。
エンコーダーが sBIT チャンクを書き込む場合、 保存されるサンプルの上位ビットが元のデータと一致するように スケーリングする必要があります。すなわち、sBIT チャンクがサンプル深度 S を指定する場合、保存される データの上位 S ビットは、元の S ビットのデータ値と一致しなければなりません。これにより、デコーダーは右シフトして元のデータを復元できます。追加された 下位ビットには 制約がありません。上述したすべてのスケーリング方法が、この制約を満たします。
ソースの画像データを拡大する場合、すべての サンプルで下位ビットを一貫して埋めることが推奨されます。すなわち、同じソース値からは、どのピクセル位置でも同じサンプル値が生成される必要があります。 これにより、異なるサンプル値の数が減少し、 圧縮率が向上します。これは必須要件ではないため、 一部のエンコーダーは この方法に従わない場合があります。たとえば、代わりに下位ビットをディザリングして、ファイルサイズが増加する代わりに 表示画像の品質を 向上させることがあります。
一部の用途では、元のソースデータの範囲が 2 のべき乗でない場合があります。線形 スケーリング方程式は、この 場合にも機能しますが、シフト方法は機能しません。このような画像には sBIT チャンクを書き込まないことが推奨されます。これは、sBIT が、元のデータ範囲が 正確に 0..2S-1 であったことを示唆するためです。
推奨パレットは、任意の PNG データストリームでは sPLT チャンクとして、 またはトゥルーカラー PNG データストリームでは PLTE チャンクとして現れることがあります。いずれの場合も、 推奨パレットは 画像データの不可欠な部分ではありませんが、 インデックスカラー表示ハードウェア上で画像を表示するために使用できます。 推奨パレットは、トゥルーカラーハードウェア上で動作するビューアーには関係ありません。
sPLT チャンクを使用して推奨パレットを提供する場合、 エンコーダーは、すべてをゼロのままにする (未定義を意味する)のではなく、頻度フィールドを使用してパレットエントリーの相対的重要度を示すことが 推奨されます。頻度値は、「最近傍」カウント、すなわち ディザリングを適用しない場合の各 RGBA パレットエントリーのおおよその 使用回数として計算するのが最も簡単です。(これらのカウントは、推奨パレットの作成に伴って 「追加コストなしで」得られることがよくあります。) 推奨パレットには透明度情報が含まれているため、 まだ合成されていない画像に対して計算する必要があります。
インデックスカラー画像の場合でも、sPLT を使用して、 PLTE チャンクに存在するすべての色を表示できないビューアー向けの代替減色パレットを定義できます。PLTE チャンクが bKGD チャンクを伴わずに、カラータイプ 6 の画像に現れる場合、パレットが計算された 条件は規定されていません。
トゥルーカラー PNG データストリームに推奨パレットを含める従来の方法では、PLTE チャンクを使用します。この方法を使用する場合、ヒストグラム(頻度)は 別個の hIST チャンクに現れる必要があります。PLTE チャンクには透明度情報が含まれません。 したがって、カラータイプ 6(アルファ付き トゥルーカラー)の画像では、bKGD チャンクを含め、 指定された背景色に対して合成した後の画像の表示に基づいて パレットとヒストグラムを計算することが推奨されます。この定義は、 小数のアルファ値を持つピクセルに対して有用なパレットエントリーを 生成するために必要です。結果として得られるパレットは、 同じ背景色に対して画像を表示するビューアーにのみ有用である可能性が高くなります。PNG エディターが、カラー タイプ 6 の画像内の bKGD チャンクを変更または削除した場合は、 パレットを削除または再計算することが推奨されます。
カラータイプ 2(トゥルーカラー)の画像では、PLTE および hIST チャンクを、 透明色の指定を無視して、RGB データのみを基準として 計算することが推奨されます。データストリームが透明度を使用する(tRNS チャンクを持つ)場合、ビューアーは結果として得られるパレットを、 使用する予定の背景色に合わせて容易に調整できます( 13.17 ヒストグラムおよび推奨パレットの使用法を参照)。
推奨パレットを提供する場合、sPLT チャンクは、次の点で PLTE チャンクよりも柔軟です。
sPLT チャンクを使用する PNG エンコーダーは、 PLTE および hIST チャンクで表される推奨パレットも書き込むことを選択できます。これは、 sPLT チャンクを認識しないデコーダーとの互換性を確保するためです。
本仕様は 2 種類のインターレース方式(そのうち一つはインターレースなし)を定義します。インターレースはデコーダが画像をプログレッシブに表示するための便利な基盤を提供します(13.10 Interlacing and progressive display を参照)。
color type 3(インデックスカラー)の画像では、フィルタタイプ 0(None)が通常最も効果的です。色数が 256 以下のカラー画像はほとんど常に indexed-color 形式で保存されるべきであり、truecolor 形式ははるかに大きくなる傾向があります。
ビット深度が 8 未満の画像にもフィルタタイプ 0 が推奨されます。低ビット深度のグレースケール画像では、稀に画像をまず 8 ビット表現へ展開してからフィルタを適用することでより良い圧縮が得られることがあります。
truecolor および greyscale の画像では、5 種類のいずれのフィルタが最も効果的かは画像に依存します。固定フィルタを用いるなら Paeth フィルタが最も良いことが多いです。
truecolor および greyscale 画像の最高の圧縮を得るため、もし圧縮効率を速度より重視するなら、各スキャンラインごとにフィルタタイプを選ぶ適応フィルタリングが推奨されます。各画像はそれぞれ最適なフィルタの組合せを持ちます。エンコーダは全てのフィルタの組合せを試して最も圧縮されるものを見つけることもできますが、全探索が許容できない場合、次のような一般的ヒューリスティックが有効です:各スキャンラインについて 5 種類のフィルタすべてを適用して、出力バイトの絶対値の和が最小となるフィルタを選びます(このテストでは出力バイトを符号付き差分として扱ってください)。この方法は単一の固定フィルタを選ぶより通常優れます。
これらの推奨に基づくフィルタ適用は、本仕様で定義されたいずれのインターレース方式と組み合わせても効果的です。
エンコーダは圧縮データストリームを任意に IDAT チャンクへ分割できます。(複数の IDAT チャンクは、エンコーダが固定量のメモリで動作できるようにするために許可されています;通常チャンクサイズはエンコーダのバッファサイズに対応します。)各 IDAT チャンクが 1 バイトのみのデータを含むような PNG データストリームも有効ですが、著しく無駄です。(ゼロ長 の IDAT チャンクも有効ですが、さらに無駄です。)
各テキストチャンクには空でないキーワードを付ける必要があります。もし適切な説明がない場合は汎用キーワード "Comment" を使えます。ユーザ提供のキーワードを使う場合、エンコーダはそのキーワードがキーワードの制限に合致しているかをチェックすべきです。
iTXt チャンクは Unicode の UTF-8 エンコーディングを使うため任意の言語のテキストを格納できます。tEXt および zTXt は Latin-1(ISO 8859-1)を使い、これらのチャンクで使用できる文字の範囲を制限します。エンコーダは文字の範囲を広くしてデータ損失を避けるために iTXt を tEXt や zTXt より優先して使うべきです。エンコーダはローカルのレガシー文字エンコーディングを適切なエンコーディングへ変換してテキストを保存しなければなりません。
iTXt チャンクを作成する際、エンコーダは UTF-8 encode(Encoding Standard)に従うべきです。
エンコーダーは、読みやすくするため、 79 個の Unicode コードポイントを超える単一行のテキストの作成を避けるよう促す必要があります。 サイズが 1024 バイト未満のテキスト項目は、非圧縮テキスト チャンクを使用して出力することが推奨されます。 基本的なタイトルおよび作者のキーワードは、非圧縮テキストチャンクを使用して出力することが推奨されます。大きなテキスト チャンクを 画像 データの後(IDAT チャンクの後)に配置すると、デコーダーが最初に 画像データをデコードするため、状況によっては画像の表示を高速化できます。画像のタイトルなどの小さなテキストチャンクは、 IDAT チャンクの前に現れることが推奨されます。
エンコーダは、他のアプリケーションが理解する必要のない情報を保持するためにプライベートチャンクを使用しても MAY です。
エンコーダは実験的またはプライベート利用のために非予約フィールド値を使用しても MAY です。
すべての補助チャンクは任意であり、エンコーダはそれらを書かなければならないわけではありません。しかし、情報が利用可能な場合は標準的な補助チャンクを書くことが推奨されます。
本節は PNG デコーダおよびビューアの振る舞いに関するいくつかの要件と推奨事項を示します。ビューアは復号された PNG イメージをユーザに提示します。ビューアとデコーダの振る舞いは密接に関連しているため、ここではデコーダとビューアを一緒に扱います。PNG デコーダに対する唯一の絶対的な要件は、前章で規定された形式に準拠する任意のデータストリームを正しく読み取ることができることです。ただし、通常は以下の追加の推奨事項に従うことでより良い結果が得られます。
PNG デコーダは、本国際規格で明示的に定義された、ビット深度、color type、圧縮方式、filter method、およびインターレース方式のすべての有効な組合せをサポートしなければなりません。
PNG データストリームのエラーは大きく二つのクラスに分かれます:伝送エラーと構文エラーです(4.10 Error handling を参照)。
伝送エラーの例としては、バイトコード 13 および/または 10 がデータストリーム全体にわたって追加・削除・変換される「text」や「ascii」モードでの伝送、データストリームが切断される予期しない終了、あるいは記憶装置上の物理エラーでブロック(通常 512 バイト単位)が乱れたりランダムな値になる場合などがあります。構文エラーの例としては、行フィルタの無効な値、無効な圧縮方式、無効なチャンク長、インデックス画像で最初の IDAT チャンクの前に PLTE チャンクがないこと、あるいは複数の gAMA チャンクの存在などがあります。PNG デコーダは次のようにエラーを処理するべきです:
この方針に関連する PNG チャンクのクラスは三種類あります。この分類における「未知のチャンク」とは、デコーダ作成者にとって真に型が不明なチャンク、あるいは作成者が扱いを既定の方法(デフォルトハンドリング)に任せたために「未知」と扱うことにしたチャンクを指します。他のチャンクは「既知のチャンク」と呼ばれます。この定義に基づく三つのクラスは次のとおりです:
チャンク命名規約の説明は 5.4 Chunk naming conventions を参照してください。
PNG チャンクの型は、表示可能なイメージを取り出すために重要かどうか(IHDR, PLTE, IDAT のように)あるいはデータストリーム構造を理解するために重要かどうか(IEND のように)に応じて「critical」または「ancillary」に分類されます。これは特定の種類の重要度であり、あらゆるデコーダに必ずしも関連するとは限りません。例えば注釈(例えば著作権情報)を抽出するだけのプログラムは表示可能なイメージを必要としませんが、UTF-8 を正しくデコードするべきです。別のデコーダは tRNS や gAMA チャンクを実行上必須と考えるかもしれません。
構文エラーは常に既知のチャンクに関するものです。未知チャンクの構文エラーは検出できないためです。PNG デコーダは状況と要件に応じて構文エラーが致命的(回復不能)かどうかを判断しなければなりません。例えば多くのデコーダは無効な IEND チャンクを無視できます;テキスト抽出プログラムは IDAT の欠如を無視できます;画像ビューアはインデックス画像における空の PLTE チャンクからは回復できませんが、truecolor 画像の無効な PLTE を無視することはできます;アルファチャネルを抽出するプログラムは無効な gAMA を無視できますが、複数の tRNS があることを致命的なエラーと見なすかもしれません。構文エラー以外の異常な状況は次のように扱うべきです:
致命的な状態が発生した場合、デコーダは直ちに失敗し、適切であればユーザにエラーを通知し、オプションとしてすでにユーザに表示されている image data の表示を継続すべきです(つまり「優雅に失敗」する)。アプリケーション全体が終了する必要はありません。
致命的でないエラーが発生した場合、デコーダは適切であればユーザに警告を出し、エラーから回復して通常の処理を継続すべきです。
インデックスカラ PNG をデコードする際に範囲外のインデックスが見つかった場合、その処理は歴史的にデコーダ間でばらつきがありました。ピクセルを不透明の黒として表示する は一般的な回復手段であり、本仕様ではこれを必須とします。古い実装では挙動が異なるため、この振る舞いをエンコーダが前提とすることはできません。
CRC を計算しないデコーダは、明らかな構文エラーを破損の兆候と解釈すべきです(13.2 Error checking も参照)。
圧縮チャンク(IDAT, zTXt, iTXt, iCCP)のエラーはバッファオーバーランにつながる可能性があります。deflate の伸長器を実装する者はこの可能性に備えるべきです。
APNG はデータストリームの全体が読み込まれる前にフレームを逐次表示できるように設計されています。したがって一部のエラーはアニメーションの途中まで検出されない可能性があります。いかなるエラーに遭遇した場合でも、デコーダは以後のすべてのフレームを破棄してアニメーションを停止し、静止画像の表示に戻ることを強く推奨します。アニメーションが開始する前にエラーを検出したデコーダは静止画像を表示すべきです。必要に応じてエラーメッセージをユーザに表示してもよいでしょう。
デコーダは順序が乱れた APNG チャンクをエラーとして扱わなければなりません。APNG 対応の PNG editors はシーケンス番号を用いて正しい順序に復元すべきです。
PNG のエラー処理方針は 13.1 Error handling に記述されています。
未知のチャンク型は、それがクリティカルチャンクでない限りエラーとして扱ってはなりません。
チャンク型の妥当性は、4 バイトすべてが 41-5A および 61-7A(16 進)範囲内かどうかを確認することで判定できます;これは未認識チャンク型に対してのみ行えばよいことに注意してください。もし総データストリームサイズが(ファイルシステム情報や HTTP プロトコル等から)既知であれば、チャンク長の妥当性もチェックできます。CRC をチェックしない場合、バイトの欠落/追加や誤ったチャンク長によりデコーダが同期を失い、以後のデータをチャンクヘッダと誤解する可能性があります。
既知長のチャンク(例えば IHDR)に対しては、予期しないチャンク長をエラーとして扱うべきです。本仕様の将来の拡張では既存チャンクへ新フィールドを追加するのではなく、新しいチャンク型を追加して新情報を運ぶ設計となります。
既知チャンクのフィールドにおける予期しない値(例えば IHDR の圧縮方式フィールドでの未確認値)は検出されエラーとして扱われるべきです。ただし、予期しないフィールド値は クリティカル なチャンクでのみ致命的なエラーとして扱うことが推奨されます。補助チャンクの予期しない値は、そのチャンク全体を未知のチャンク型と同様に無視することで扱うことができます(この推奨はチャンクの CRC が検証済みであることを前提とします。CRC をチェックしないデコーダでは、予期しない値を破損したデータストリームの兆候として扱う方が安全です)。
標準的な PNG 画像は圧縮方式 0 で圧縮されなければなりません。IHDR チャンクの圧縮方式フィールドは将来の標準化や独自拡張のために用意されています。デコーダはこのバイトをチェックし、未認識のコードであればエラーを報告すべきです。詳細は 10. Compression を参照してください。
PNG データストリームは明示的に型付けされたチャンクの集合で構成されます。仕様で内容が定義されたチャンクでも、実際には任意のデータ(悪意のあるコードを含む可能性)を含むことがあり得ます。同様に IEND チャンクの後にあるデータも任意のものであり、悪意あるコードを含む場合があります。そのような悪意あるコードが PNG 画像のデコードの結果として受信側のコンピュータ上で実行されるという既知のリスクはありません。しかしながら悪意のあるアプリケーションが無害に見える画像ファイル内にコードを隠し、その後それを実行する可能性はあります。
将来のチャンク型に関連する可能性のあるセキュリティリスクは現時点で特定できません。将来の公開チャンクを定義する際にはセキュリティ問題が考慮されます。未知または未実装のチャンク型には追加のセキュリティリスクはありません。なぜならそのようなチャンクは無視されるか、最大でも別の PNG データストリームへコピーされるだけだからです。
iTXt, tEXt, zTXt チャンクはキーワードと表示用のプレーンテキストを含みます。iCCP および sPLT もキーワードを含み、表示用テキストです。デコーダがこれらのテキストを制御文字、特に ESC(エスケープ)文字をフィルタリングせずに表示すると、一部のシステムや端末で望ましくない動作や安全上の問題を引き起こす可能性があります。デコーダはこのリスクを避けるために制御文字を除去することを推奨します;詳細は 13.7 Text chunk processing を参照してください。
eXIf チャンクについては、Exif 仕様 [CIPA-DC-008] において、タグの「value offset」ポインタが実際にファイル内の有効なアドレスを指すべきという明示的な要件は含まれていません。この要件は暗黙的に示唆されるのみです(Exif IFD 構造を説明するパラグラフ 4.6.2 を参照)。いずれにせよ、デコーダは無効なポインタに遭遇する可能性に備え、それらを適切に処理するべきです。
すべてのチャンクは長さフィールドで始まるため、バッファオーバーフローを試みるような不正なチャンクに対して脆弱でないデコーダを書くのが容易になります。各チャンク末尾の CRC は偶発的な破損に対する強力な防御手段を提供します。PNG シグネチャバイトは一般的なファイル伝送エラーを早期に検出するためのものです。
CRC をチェックしないデコーダはデータ破損に晒される可能性があります。その唯一のありそうな結果は画像内のピクセル表示の誤りです。もっと悪い事態としては、IHDR チャンクの CRC をチェックせず、幅や高さフィールドが破損していると重大な問題が発生することがあります。詳細は 13.2 Error checking を参照してください。
不適切に書かれたデコーダはチャンクが極めて大きく(最大 231-1 バイト)なり得ることからバッファオーバーフローの対象となるかもしれません。しかし、適切に書かれたデコーダは大きなチャンクを問題なく扱います。
一部の画像編集ツールは歴史的に、編集領域のアルファチャネルをゼロに設定するだけで実際の画像データを削除していないまま機密情報を抹消したつもりになることがありました。そのような画像を見た目だけで信頼すると、実際の画像データが容易に復元され得るためプライバシーリスクがあります。
同様に、一部の画像編集ツールは IHDR の幅と高さを書き換えることで切り取り(clipping)を行い、画像データ自体を再エンコードしないため、新しい幅と高さの外側に元のデータが残り復元される可能性があります。
eXIf チャンクを含む画像は、自動的に付加されるデータ(例えば写真の GPS 座標)を含んでいることがあり、ユーザが PNG にそのようなデータが含まれていることに気づいていないとプライバシー上のリスクになり得ます。(Exif を含む他の画像形式、例えば JPEG/JFIF も同様のリスクがあります。)
デコーダはチャンク型を単純な 4 バイトのリテラル比較で認識しなければなりません;チャンク型に対して大文字小文字変換を行うのは誤りです。補助ビットが 1 の未知チャンクに遭遇したデコーダは安全にそのチャンクを無視して画像表示を続行できます。補助ビットが 0(クリティカル)である未知チャンクに遭遇した画像抽出を試みるデコーダは、その画像に安全に解釈できない情報が含まれていることをユーザに示すべきです。
デコーダは未知のチャンク型の性質を指定されたビットを数値的にテストすることで検証すべきです。文字が大文字か小文字かをテストするのは非効率であり、ロケール特有の大文字小文字定義を用いた場合に誤りとなることがあります。
予約ビットが 1 に設定されている場合はエラーを報告すべきではありません。将来の PNG 仕様でこのビットに意味が定義される可能性があるためです。このビットがセットされたチャンクは他の未知チャンク型と同様に扱えば十分です。
チャンク型のプライベートビットは機能的な意味を持たず、W3C によって定義されたチャンクと個別定義のチャンクの衝突を避けるために使用されるものであるため、デコーダはこれをテストする必要はありません。
すべての補助チャンクは任意です;デコーダはそれらを無視できます。しかし、適切かつ可能であればデコーダはこれらのチャンクを解釈することが奨励されます。
非正方ピクセルは表現可能です(11.3.4.3 pHYs Physical pixel dimensions を参照)が、ビューアがそれを考慮する義務はありません;ビューアは任意の PNG データストリームをピクセルが正方形であるかのように提示できます。
表示のピクセルアスペクト比が PNG データストリームで定義された物理ピクセル寸法のアスペクト比と異なる場合、ビューアは適切な表示のために画像をリスケールすることが強く推奨されます。
pHYs チャンクの unit specifier が 0(単位不明)の場合、デコーダの挙動は 2 つの pixels-per-unit
値の比に依存してもよいですが、その大きさには依存すべきではありません。例えば pHYs が
(ppuX, ppuY, unit) = (2, 1, 0) を含む場合、それは (1000, 500, 0)
を含むものと同等です;どちらも画像のピクセルが幅の 2 倍の高さを持つことを示す有効な指示です。
ビューアが画像と表示装置のピクセルアスペクト比の違いを扱う一つの合理的な方法は、画像を水平方向か垂直方向のどちらか一方に拡大することです。スケール係数は次の浮動小数点計算で得られるかもしれません:
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 チャンクを無視することも許容されるため、作成者はすべてのビューアがこのスケーリング方法を使うと仮定すべきではありません。
ピクセルアスペクト比の補正に加えて、ビューアは水平方向および垂直方向の追加スケーリングを行う理由があるかもしれません。例えばディスプレイに収まらないほど大きな画像を縮小したり、高解像度プリンタへ送る際に表示と同じ物理寸法に見えるよう拡大する場合などです。
現実的であれば、PNG デコーダはデータストリーム内で見つかったすべての iTXt、tEXt、および zTXt チャンクをユーザに表示する手段を持つべきです。デコーダが特定のテキストキーワードを認識しなくても、ユーザはそれを理解できるかもしれません。
tEXt および zTXt
を処理する際、デコーダは許可されていない文字に遭遇する可能性があります。一部は安全に表示できます(例えば TAB, FF, CR、16 進で 09, 0C, 0D)が、特に ESC 文字(16 進
1B)は表示ハードウェアやソフトウェアに予期せぬ動作を引き起こす可能性があり安全上の危険をもたらすかもしれません。デコーダは tEXt
または zTXt で見つかった非 Latin-1 文字(改行および場合によっては TAB
を除く)を直接表示しようとすべきではありません。代わりにそれらを無視するか、"\nnn" のような可視表記で表示するべきです。詳細は 13.3 Security
considerations を参照してください。
iTXt チャンクを処理する際、デコーダは UTF-8 decode(Encoding Standard)に従うべきです。
エンコーダは改行を linefeed(16 進 0A)で表すことが推奨されていますが、デコーダはこれに依存すべきではありません。CR, LF, CR-LF といった一般的な改行の組合せすべてを認識し、それぞれを単一の改行として表示するのが最良です。TAB は 8 の倍数の列に整列するために適切な数のスペースに展開できます。
非 Latin-1 のレガシー文字エンコーディングを持つシステム上で動作するデコーダは、Latin-1
文字が正しく表示されるよう文字コードをリマップすべきです。サポートされない文字はシステムに適した置換文字(例えば U+FFFD REPLACEMENT CHARACTER、U+003F QUESTION
MARK、または U+001A SUB)に置き換えるか、"\nn"
のような可視表記にマップするべきです。文字はデコードシステム上で印字可能な文字である場合にのみ表示されるべきです。一部のバイト値はデコードシステム上で制御文字として解釈され得るため、そのようなシステム上で動作するデコーダはこれらの制御文字を表示しないべきです(セキュリティのため)。
デコーダは、エンコーダが 79 文字を超える行を作らないよう推奨されているにもかかわらず、改行間に任意の数の印字文字を含むテキストチャンクを表示できる用意をしておくべきです。
本仕様で用いる圧縮技術は、伸長を開始する前に圧縮データストリーム全体が利用可能であることを要求しません。したがって伸長済みデータ全体が得られる前に表示を開始できます。将来の本仕様のバージョンで用いられる一般的な圧縮手法がこの性質を失う可能性は極めて低いと考えられます。
IDAT チャンク境界は意味的な重要性を持たず、圧縮データストリームの任意の点で現れ得ることを強調することが重要です。image data(例えばスキャンライン境界)と deflate ブロック境界や IDAT チャンク境界との間に必須の相関はありません。完全な image data は、複数の zlib データストリームとして表現され、それがいくつかの IDAT チャンクに格納されます;デコーダがこれ以上のものを仮定するのは誤りです。エンコーダの実装によってはこれらの構造が関連づけられる場合もありますが、デコーダはそれに依存してはなりません。
フィルタの効果を逆にするために、デコーダは同じ行の前のピクセル、前行の現在ピクセルのすぐ上のピクセル、および前行の左隣のピクセルの復号済み値を使う必要がある場合があります。これはデコーダが常に少なくとも 1 行分の image data を保持しておく必要があることを意味します。いくつかのフィルタタイプは前行を参照しないものもありますが、次の行がその参照を使うかもしれないため、デコーダは各スキャンラインをデコードするごとに格納する必要があります。詳細は 7.3 Filtering を参照してください。
デコーダはインターレースされた画像を読み取ることが要求されます。参照画像が 5 列未満または 5 行未満の場合、いくつかのパスは空になります。エンコーダとデコーダはこのケースを正しく扱わなければなりません。特に、フィルタタイプバイトは非空のスキャンラインにのみ関連付けられており、空の縮約画像にはフィルタタイプバイトは存在しません。
低速伝送リンク上で画像を受信する場合、ビューアはインターレース画像を段階的に表示することで知覚的性能を改善できます。これは各縮約画像を受信するごとに、これまで受信したデータに基づく完全画像の近似を表示することを意味します。受信した各ピクセルをまだ伝送されていない右下方向の位置を覆う長方形に拡大して塗りつぶすという単純で見栄えの良い効果が得られます。この処理は以下の 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) は次に送られてくるピクセルを取得し、その色で指定された高さと幅の長方形(左上隅が指定の行と列)を塗ります。row と
column は左上隅を 0,0 とした測度であることに注意してください。
ビューアが受信した画像を背景画像と合成している場合、受信したピクセル位置だけを描画する方が都合がよいかもしれません(visit()
は指定の行と列のピクセルのみを設定し、長方形全体を塗るわけではありません)。これにより新しい画像が徐々に古い画像を置き換える「フェードイン」効果が得られます。この方法の利点は各ピクセルが置き換えられるたびに適切なアルファまたは透過処理が行えることです。上で説明したように長方形を塗る方法は、後に受信されるピクセルが完全または部分的に透明である場合に必要となる背景画像のピクセルを上書きしてしまい得ます。これは背景画像がオフスクリーンに保存されていない場合にのみ問題になります。
PNG のユニバーサルな交換性という目標を達成するために、デコーダはすべての種類の PNG イメージを受け入れなければなりません:indexed-color、 truecolor、および greyscale。indexed-color 表示ハードウェア上で動作するビューアは、表示のために truecolor イメージを indexed-color に縮約できる必要があります。この処理は「カラ量子化(color quantization)」と呼ばれます。
カラ量子化の簡単で高速な方法は、イメージを固定パレットへ縮約することです。均一な色間隔のパレット(いわゆる「カラキューブ」)はピクセルごとの計算を最小にするために通常用いられます。写真のような画像の場合、滑らかなグラデーションに不自然な段差が生じないようにディザリングが推奨されますが、ディザリングは雑味(graininess)を導入するため好ましくない場合もあります。
レンダリング品質は、画像固有に選ばれたパレットを使うことで大幅に改善され得ます。というのも、カラキューブには特定の画像で使われないエントリが多く含まれることが一般的だからです。この方法では、まずパレットを選ぶ作業、次に個々のピクセルを最も近い色にマップする作業が必要になり、作業量が増えます。PNG ではエンコーダが推奨パレットを提供できるようになっていますが、すべてのエンコーダがそれを行うわけではなく、提供された推奨パレットが不適切である可能性もあります(色数が多すぎる/少なすぎるなど)。したがって、高品質なビューアはパレット選択ルーチンを持っている必要があります。個々のピクセルを十分な速度でパレットエントリへマップするためには、大きなルックアップテーブルが通常もっとも実行可能な方法です。
カラ量子化の実装は多数存在します。PNG のサンプル実装である libpng (http://www.libpng.org/pub/png/libpng.html)
にはこの目的のためのコードが含まれています。
デコーダは表示のために 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
Decoder gamma handling に示されています。)
デコーダがサンプルを拡大する必要がある場合(例えば frame buffer のサンプル深度が PNG イメージより大きい場合)、12.4 Sample depth scaling に記述されたように線形スケーリングまたは左ビット複製(left-bit-replication)を使用するべきです。
sBIT チャンクが存在する場合、参照用の image data は sBIT で指定されたサンプル深度へ右シフトして復元できます。線形スケーリングは必ずしも元のデータを再現しないことに注意してください。なぜならエンコーダが上向きスケーリングに線形スケーリングを使ったと要求されているわけではないからです。しかしエンコーダは高位ビットを保つ方法を用いることが要求されているため、右シフトは常に機能します。これはシフト法が線形スケーリングより正確であると言える唯一のケースです。デコーダは sBIT を無視してもかまいません;格納された画像は IHDR チャンクで示されたサンプル深度の有効な PNG データストリームです。しかし sBIT を使って表示用にスケーリングする前の元のサンプルを回復することは、sBIT を無視するよりもより正確な表示をもたらすことが多いです。
tRNS チャンク値とピクセル値を比較して透過ピクセルを検出する場合、比較は正確に行われなければなりません。したがって、透過ピクセル検出はサンプル精度を下げる前に行わなければなりません。
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 の範囲)に変換し、2 行目は目的の表示出力強度に比例する値に変換し、 3 行目は表示 システムの伝達関数を考慮し、4 行目は整数の フレームバッファーサンプルに変換します。ゼロを 任意の正の数で累乗するとゼロになります。
2 行目と 3 行目の間に、実際の観察条件と基準観察条件の 差を考慮して display_output を調整するステップを挿入できます。ただし、この調整では ベイリンググレア、ブラックマッピング、および色の見えモデルを考慮する必要があり、これらはいずれも べき関数では十分に近似できません。このような 計算については、ここでは説明しません。観察条件を無視しても、通常、誤差はわずかです。
表示装置の伝達関数は通常、指数 display_exponent を持つべき関数で近似できます。この場合、2 行目と 3 行目を次のように統合できます。
display_input = sample1.0/(gamma * display_exponent) = sampledecoding_exponent
これにより、べき乗計算を 1 回だけ実行できます。カラー画像では、計算全体を R、G、 および B の値ごとに個別に実行します。
ガンマ値は、gAMA チャンクから直接取得できます。あるいは、 アプリケーションがガンマ値に影響を与えることで、表示画像の外観をユーザーが調整できるようにしてもかまいません。 たとえば、ユーザーがデフォルト値 1.0 のパラメーター user_exponent を手動で設定し、 アプリケーションが 次のように設定できます。
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 チャンクは意味を持ちませんが、 誤って現れる可能性があります。デコーダーは これを無視する必要があり、エディターはこれを破棄してユーザーに警告を発してもかまいません。
ピクセルごとに超越数学演算を実行する必要はありません。代わりに、 あらゆるサンプル値に対して正しい出力値を示すルックアップテーブルを計算できます。これに必要なのは、ピクセルごとに 1 回または 3 回の計算ではなく、 画像ごとに 256 回 (8 ビット精度の場合)の計算だけです。インデックスカラー画像では、画像が透明度を使用し、 不均一な 背景に対して表示される場合を除き、パレットを一度補正すれば十分です。
浮動小数点計算ができない場合、ガンマ補正テーブルは、整数演算 および事前計算された対数表を使用して計算できます。コード例は [PNG-EXTENSIONS] にあります。
入力画像のガンマ値が不明な場合(gAMA、sRGB、および iCCP がすべて存在しない場合)、スタンドアロンの画像ビューアーは、 妥当と思われるデフォルトのガンマ値を選択する必要がありますが、結果が 暗すぎるか 明るすぎる場合は、ユーザーが新しい値を選択できるようにする必要があります。デフォルトのガンマ値は、画像に関する他の情報、たとえば画像が インターネットから取得されたものか ローカルシステムから取得されたものかによって異なる場合があります。一貫性を保つため、HTML などの文書形式や、 SVG などのベクター グラフィックスのビューアーは、埋め込みまたはリンクされた PNG 画像でガンマ値が不明なものを、 他の タグ付けされていない画像と同じように扱う必要があります。
実際には、使用すべき表示指数の値を決定するのが困難なことがよくあります。組み込みの ガンマ 補正がないシステムでは、表示指数はCRTによって完全に決まります。使用する特定の CRTについて詳細な較正測定値が利用できない限り、 2.2 の表示指数を使用する必要があります。
多くの最新のフレームバッファーには、ガンマ 補正を実行するために使用されるルックアップテーブルがあり、このようなシステムでは、 表示指数の値は、ルックアップテーブルとCRTを組み合わせた指数とする必要があります。ビューアーアプリケーション内から ルックアップテーブルの内容を確認できない場合があり、その場合は、 表示システムの指数値をユーザーに 入力してもらう必要があります。残念ながら、ルックアップテーブルに何を 格納すべきかを指定する方法はメーカーごとに異なるため、システムのガンマ値の解釈は システムに依存します。
実際の表示装置の応答は、単一の数値(表示指数)では説明できないほど複雑です。 電圧入力に対するモニターの光出力の実測値を利用できる場合は、 上記の計算の 3 行目と 4 行目を、これらの測定値の参照に置き換えて、目的の明るさに最も近い実際のフレームバッファー値を 求めることができます。
色に関する参照は C. Gamma and chromaticity を参照してください。
多くの場合、PNG データストリーム内の image data はデバイス依存の RGB 値として扱われ、(適切な gamma 補正を除いて)変更せずに表示されます。これは最速の表示方法ですが、ビューアが元の画像の作成者とまったく同じ表示ハードウェアを用いない限り、特に暗色やほぼ中立の色において色は作成者が見たものと完全には一致しません。cHRM チャンクは、単なる gamma 補正よりも緻密な色合わせを可能にする情報を提供します。
cHRM データは image data を RGB から XYZ へ変換し、さらに CIE LAB のような知覚的に線形な色空間へ変換するために使えます。色を CIE LAB 空間で分割すれば最適パレットを生成できます。というのも CIE LAB における 2 色間の幾何学的距離は、人間の見た目での差異と強く相関するからです(RGB や XYZ 空間とは異なります)。得られたパレットを再び RGB へ戻して表示に用いるか、PLTE チャンクへ書き込むことができます。
画像処理アプリケーションの一部として動作するデコーダは、解析のために image data を CIE LAB 空間へ変換することもあるでしょう。
製品設計、科学的可視化、医療、 建築、広告など、色再現の忠実性が重要となる用途では、 PNG デコーダーは画像データをソース RGB から、画像の表示に使用するモニターの表示 RGB 空間へ変換できます。これには、ソース RGB から XYZ へ変換する行列と、 XYZ から表示 RGB へ変換する行列を 計算し、それらを組み合わせて全体的な変換を生成する処理が含まれます。PNG デコーダーは、 色域マッピングの実装を担当します。
プラットフォームにカラーマネジメントシステム(CMS)が備わっている場合、デコーダは image data、gAMA、および cHRM の値を CMS に渡して表示やさらなる処理を行わせることができます。
カラー印刷機能を提供する PNG デコーダは、Level 2 PostScript の機能を使ってキャリブレートされた RGB 空間や XYZ のようなデバイス非依存色空間で image data を指定できます。これは単純な RGB→CMYK 変換よりも良い色忠実度を提供します。PostScript Language Reference マニュアル [PostScript] に例が示されています。そのようなデコーダはソース RGB(cHRM に指定)とターゲットプリンタ間のガモットマッピングを実装する責任があり、PostScript インタプリタが所望の色を生成します。
PNG デコーダは cHRM データを使用して、カラー画像の正確なグレースケール表現を計算できます。RGB からグレイへの変換は単に XYZ の Y(輝度)成分を計算することであり、これは R, G, B の重み付き和です。重みはモニタの種類、すなわち cHRM チャンクの値に依存します。PNG デコーダは cHRM を持たないデータストリームに対してこれを行いたい場合があります。その場合の妥当なデフォルトは CCIR 709 原色です [ITU-R-BT.709]。オリジナルの NTSC 原色は、PNG 画像が本当にそのようなモニタ用に色合わせされていない限り 使用すべきではありません。
bKGD チャンクによって指定された背景色は通常、 画像の周囲にある未使用の 画面領域、および画像内の透明なピクセルを塗りつぶすために使用されます。(したがって、bKGD は、画像で透明度が使用されていない場合でも有効かつ有用です。) bKGD チャンクが存在しない場合、ビューアーは 適切な背景色を決定する必要があります。他に 情報がない場合、8 ビット sRGB 色空間の 153 などの中間グレーが妥当な 選択となります。一般的に使用される透明な 黒色または白色のテキストや暗いドロップシャドウは、いずれもこの 背景上で判読できます。
画像を表示するための特定の背景を持つビューアー(Web ブラウザーなど)は、 bKGD チャンクを無視し、実質的に bKGD を自身の 優先する背景色または背景画像で上書きする必要があります。
bKGD チャンクによって指定された背景色は、 tRNS チャンクによって指定された色とたまたま一致する場合でも(または、 インデックスカラー画像の場合、tRNS チャンクによって透明とマークされたパレットインデックスを参照する場合でも)、 透明であると見なしてはなりません。そうでなければ、合成の対象となる何かが「背景の背後」にあると想定しなければならなくなります。背景 色は、背景として使用されるか、無視されるかのいずれかであり、PNG 画像と 他の何らかの背景との間にある中間レイヤーでは ありません。
実際、bKGD チャンクと tRNS チャンクが同じ色を指定することは一般的です。その場合、透明度処理を実装していないデコーダーでも、 少なくとも半透明のピクセルが存在しない場合には、意図された 表示を生成できるためです。
アルファチャンネルを使用して、前景画像を背景画像に対して合成できます。PNG データストリームは 前景画像と透明度マスクを定義しますが、背景画像は定義しません。PNG デコーダーには、 この最も一般的なケースのサポートは要求されません。 ほとんどのデコーダーは、単一の 背景色に対する合成をサポートできると期待されます。
合成後のサンプル値を計算する式は次のとおりです。
output = alpha * foreground + (1-alpha) * background
ここで、alpha、入力サンプル値、および出力サンプル値は、0 から 1 の範囲の分数として表されます。この 計算は、 強度サンプル(ガンマ符号化されたサンプルではない)を使用して実行する必要があります。カラー画像では、この計算を R、G、および B のサンプルごとに 個別に実行します。
次のコードは、前景画像を背景 画像に対して合成する一般的なケースを示しています。このコードでは、 背景画像の元のピクセルデータが利用可能であり、出力先が表示用のフレームバッファーであると想定しています。 他のバリエーションも可能です。コードの下にあるコメントを参照してください。このコードでは、前景画像と背景画像のサンプル深度およびガンマ値が すべて異なり、表示システムに必ずしも適していない場合にも対応します。実際には、 最初に確認することなく、それらが等しいと 想定してはなりません。
このコードは ISO C [ISO_9899] であり、 以下のコメントで参照するために行番号が追加されています。
01 int foreground[4]; /* 画像ピクセル:R、G、B、A */
02 int background[3]; /* 背景ピクセル:R、G、B */
03 int fbpix[3]; /* フレームバッファーピクセル */
04 int fg_maxsample; /* 前景の最大サンプル値 */
05 int bg_maxsample; /* 背景の最大サンプル値 */
06 int fb_maxsample; /* フレームバッファーの最大サンプル値 */
07 int ialpha;
08 float alpha, compalpha;
09 float gamfg, linfg, gambg, linbg, comppix, gcvideo;
/* データおよびフレームバッファー内の最大サンプル値を取得する */
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;
/*
* アルファの整数表現を取得する。
* 不透明および透明の特殊なケースを確認する。
* 該当する場合、合成は不要である。
*
* ここでは、ガンマのデコード/補正処理全体を
* 浮動小数点で示すが、実際には
* ルックアップテーブルを使用する可能性が高い。
*/
13 ialpha = foreground[3];
14 if (ialpha == 0) {
/*
* 前景画像はここでは透明である。
* 背景画像がすでにフレーム
* バッファーにある場合、何もする必要はない。
*/
15 ;
16 } else if (ialpha == fg_maxsample) {
/*
* 前景ピクセルをフレームバッファーにコピーする。
*/
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 {
/*
* 合成が必要である。
* 浮動小数点のアルファとその補数を取得する。
* 注:アルファは常に線形であり、ガンマは
* これに影響しない。
*/
25 alpha = (float) ialpha / fg_maxsample;
26 compalpha = 1.0 - alpha;
27 for (i = 0; i < 3; i++) {
/*
* 前景と背景を浮動
* 小数点に変換し、ガンマ符号化を元に戻す。
*/
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);
/*
* 合成する。
*/
32 comppix = linfg * alpha + linbg * compalpha;
/*
* 表示用にガンマ補正する。
* 整数のフレームバッファーピクセルに変換する。
*/
33 gcvideo = pow(comppix, 1.0 / display_exponent);
34 fbpix[i] = (int) (gcvideo * fb_maxsample + 0.5);
35 }
36 }
バリエーション:
/*
* 出力データストリームに格納するためにガンマ符号化する。
* 整数のサンプル値に変換する。
*/
gamout = pow(comppix, outfile_gamma);
outpix[i] = (int) (gamout * out_maxsample + 0.5);さらに、
単にピクセルをスキップするのではなく、alpha がゼロの場合にも背景ピクセルを処理する
必要があります。したがって、15
行目を 17~23 行目のコピーで置き換える必要がありますが、前景
ピクセル値ではなく背景ピクセル値を処理します。
/*
* フレームバッファー値を強度サンプルに変換する。
*/
gcvideo = (float) fbpix[i] / fb_maxsample;
linbg = pow(gcvideo, display_exponent);ただし、丸め
誤差が生じる可能性があるため、可能であれば元の背景ピクセルを利用できるようにしておく方が
適切です。
注記 浮動小数点演算では、入力サンプル 値が 0 から 1 の間であることが保証されており、合成によって得られる結果も常に 入力値の間(両端を含む)となるため、オーバーフローやアンダーフローの検査は必要ありません。 整数演算では、オーバーフローや アンダーフローが発生しないことを保証するために、丸め誤差の分析が必要になる場合があります。
完全なアルファチャンネルを持つ PNG 画像を表示する場合、たとえ黒だけであっても、何らかの 背景に対して画像を合成できることが重要です。アルファチャンネルを無視すると、 関連付けられたアルファ表現から変換された PNG 画像が 正しく表示されなくなります。(もちろん、アルファチャンネルが独立した 透明度マスクである場合は、 アルファを無視することも有用な選択肢です。これにより、画像の隠れた部分を復元できます。)
デコーダーが真の合成ロジックを実装していない場合でも、アルファ値がゼロと 1 だけの画像は簡単に処理できます。(これは、グレースケールおよびトゥルーカラーの PNG データストリームで tRNS チャンクを使用する場合には暗黙的に当てはまります。インデックスカラー PNG データストリームでは、tRNS チャンクに 0 と 255 以外の値が含まれているかどうかを簡単に確認できます。)この単純なケースでは、透明なピクセルが 背景色に置き換えられ、それ以外のピクセルは変更されません。
デコーダーの透明度処理能力がこの程度しかない場合、完全なアルファチャンネルを、 ゼロ以外のすべてのアルファ値を完全に不透明として扱うか、ディザリングすることによって処理する必要があります。 どちらの方法でも、関連付けられたアルファ形式から変換された 画像では良好な結果は得られませんが、何もしないよりは適切です。完全なアルファを二値アルファへ ディザリングすることは、 グレースケールを白黒へディザリングすることとよく似ています。ただし、完全に透明なピクセルと完全に不透明なピクセルはすべて、 ディザー処理によって変更されないようにする必要が あります。
インデックスカラーハードウェア上で動作し、トゥルーカラー画像、または パレットがフレームバッファーに対して大きすぎるインデックスカラー画像を 表示しようとするビューアー向けに、エンコーダーが sPLT チャンク内に 1 つ以上の推奨パレットを提供している場合があります。サイズや 場合によっては名前に基づいて、そのいずれかが適切であると判断された場合、 PNG デコーダーはそのパレットを使用できます。デコーダーが必要とするものとは異なるサンプル深度を持つ推奨パレットは、 サンプル深度の再スケーリングを使用して 変換できます(13.12 サンプル深度の再スケーリングを参照)。
背景が単色の場合、ビューアーは画像と推奨 パレットをその色に対して合成し、その後、結果として得られた画像を、結果として得られた RGB パレットに量子化する必要があります。画像が透明度を使用し、背景が 単色でない場合、有用な推奨パレットは存在しない可能性が高くなります。
トゥルーカラー画像では、推奨パレットが PLTE チャンク内にも提供されている場合があります。画像に tRNS チャンクがあり、背景が単 色の場合、ビューアーは 推奨パレットを目的の背景色で使用できるように調整する必要があります。そのためには、 tRNS の色に最も近いパレットエントリーを目的の背景色に置き換えるか、 または、ビューアーが PLTE のエントリー数よりも多くの色を処理できる場合は、背景色のパレットエントリーを追加できます。
カラータイプ 6(アルファ付き トゥルーカラー)の画像では、すべての PLTE チャンクが、 bKGD チャンクによって指定された色の均一な背景に対して画像を表示するように設計されている 必要があります。ビューアーが別の 背景を使用する場合、または bKGD チャンクがない場合は、おそらくパレットを無視する必要があります。ビューアーは、 意図されたものとは異なる背景に対する 表示に推奨パレットを使用できますが、結果があまり良くない場合があります。
ビューアーが透明なトゥルーカラー画像を、均一な 色より複雑な背景に対して表示する場合、推奨パレットが合成画像に最適である可能性は低くなります。この 場合、トゥルーカラー PNG 画像と背景画像に対してトゥルーカラー合成ステップを実行し、 その後、結果として得られた画像を色量子化するのが最善です。
トゥルーカラー PNG データストリームで、PLTE チャンクと sPLT チャンクの両方が現れる場合、PNG デコーダーは、 上述した透明度の意味の違いを考慮しながら、両方によって推奨されたパレットの中から選択 できます。
sPLT および hIST チャンク内の頻度は、 ビューアーが PNG データストリーム内のパレットで使用されている数と同じだけの色を提供できない場合に役立ちます。 ビューアーで不足するのが 数色だけの場合、通常は最も使用頻度の低い色をパレットから削除すれば十分です。色数を 大幅に減らすには、 既存のパレットの部分集合を使用しようとするより、まったく新しい代表色を選択するのが最善です。 これは新しい色量子化ステップを実行することに相当します。ただし、既存の パレットとヒストグラムを 入力データとして使用できるため、IDAT チャンク内の画像データを走査せずに済みます。
推奨パレットが提供されていない場合、デコーダーは、IDAT チャンク内の 画像 データを追加でもう一度処理することにより、独自のパレットを作成できます。あるいは、デフォルトのパレット (おそらくカラーキューブ)を 使用できます。
12.5 推奨 パレットも参照してください。
作者は新しいチャンク型を検討する前に、本仕様や [PNG-EXTENSIONS] にある既存のチャンク型を確認することが奨励されます。PNG-EXTENSIONS にあるチャンク型は、本仕様で定義されたものよりも広くサポートされないことが予想されます。
PNG editors の例として、テキストチャンクを追加・変更するプログラムや、truecolor PNG データストリームに推奨パレットを追加するプログラムが挙げられます。一般的な画像編集ソフトは画像を読み込む際に未認識の情報を破棄するため、通常は PNG editors とは見なされません。
PNG に新しいチャンク型を追加できるようにするためには、すべてのチャンク型に対する並び順の要件について規則を確立する必要があります。さもなければ、PNG editor が未知のチャンクに遭遇したときに何をすべきか分からなくなります。
例: 仮想的な新しい補助チャンク型があって、それは PLTE が存在する場合に PLTE の後に現れることが要求されるとします。プログラムがその新チャンクを認識せずに PLTE を追加しようとすると、誤って新チャンクの後に PLTE を挿入してしまう可能性があります。このような問題は、未知チャンクをすべて破棄するように PNG editors に強制すれば防げますが、それは非常に魅力のない解決策です。代わりに、PNG は補助チャンクにこのような厳しい順序制約を持たせないことを要求します。
この種の問題を将来の拡張を許容しつつ防ぐために、PNG editors の振る舞いとチャンクの並び順に制約が課されています。safe-to-copy ビットは、修正されるデータストリーム内の未認識チャンクの取り扱いを定義します。
チャンクの並び順を決める規則は次の通りです。
これらの規則は入力データストリームから出力データストリームへチャンクをコピーする観点で表現されていますが、データストリームをその場で修正する場合にも明白な方法で適用されます。
また 5.4 Chunk naming conventions を参照してください。
PNG editors が image data を変更しない場合、tIME チャンクを変更してはなりません。tEXt、zTXt、および iTXt チャンクの Creation Time キーワードは、ユーザ提供の時刻として使用できます。
クリティカルチャンクには任意の並び順要件があり得ます。というのも PNG editors は未知のクリティカルチャンクに遭遇した場合に終了することが要求されるからです。例えば IHDR には常に最初に現れるという特定の順序規則があります。PNG エディタ、または PNG を書き出す任意のプログラムは、自身が生成できるクリティカルチャンク型の順序規則を知り、それに従わなければなりません。
補助チャンク型に対する最も厳しい順序規則は次のとおりです:
特定の補助チャンク型に対する実際の順序規則はこれより緩やかであることがあります。例えば標準的な補助チャンク型の順序規則は 5.6 Chunk ordering に示されています。
デコーダは、任意の補助チャンクが他の補助チャンクに対して特定の位置にあると仮定してはなりません。特に、ある私的な補助チャンクが常に IEND の直前に現れると仮定するのは安全ではありません。特定のアプリケーションがいつもその位置に書いている場合でも、PNG editor がその後に別の補助チャンクを挿入する可能性があるためです。ただし、そのチャンクが IDAT と IEND の間のどこかに残ることは安全に仮定できます。
非規範(non-normative)としてマークされた節に加え、本仕様のすべての作成ガイドライン、図、例、および注記は非規範的です。それ以外の本仕様の全内容は規範的です。
本文書中のキーワード MAY、MUST、SHALL、 SHOULD、および SHOULD NOT は、BCP 14 [RFC2119] [RFC8174] に従って解釈されますが、その場合に限り、すなわちここに示すようにすべて大文字で現れるときのみ適用されます。
本節は PNG データストリーム、PNG エンコーダ、PNG デコーダ、および PNG エディタ の適合性を扱います。
本節における仕様の主な目的は次のとおりです:
適合性は PNG データストリームおよび PNG エンコーダ、デコーダ、エディタについて定義されます。
本節は PNG データストリームと実装要件、ならびに PNG エンコーダ、PNG デコーダ、及び PNG エディタ に許容される差異の範囲を扱います。本節はエンコーダ、デコーダ、またはエディタの環境要件、性能要件、またはリソース要件を直接扱うものではありません。
本節の適用範囲は、PNG データストリームの公開される相互交換のための規則に限定されます。
PNG データストリームが本仕様に適合するためには、次の条件を満たしている必要があります。
PNG エンコーダが本仕様に適合するためには、次の条件を満たす必要があります。
PNG デコーダが本仕様に適合するためには、次の条件を満たす必要があります。
PNG エディタ が本仕様に適合するためには、次の条件を満たす必要があります。
これは image/png インターネット・メディアタイプの既存登録を更新するものです。トップレベル型は image です。本付録は BCP 13 および W3CRegMedia に準拠しています。
PNG 文書は明示的に型付けされた「チャンク」の集合で構成されます。PNG 仕様で定義された各チャンク型(gIFx を除く)について、それらのチャンクに関連する唯一の効果は受信者の表示またはプリンタ上で画像をレンダリングさせることです。
gIFx チャンク型はアプリケーション拡張データをカプセル化するために使われ、そのデータの利用はセキュリティリスクを呈する可能性がありますが、既知のリスクは報告されていません。同様に、将来のチャンク型(特に未登録のもの)に関連するセキュリティリスクは評価できません。ただし PNG ワーキンググループは「実行可能」データを含むチャンクが登録チャンクになることを許さない意図を持っています。
テキストチャンクである tEXt、iTXT、および zTXt は、コメント等として表示可能なデータを含みます。いくつかの OS や端末は埋め込まれた制御文字を含むテキスト表示によりキー再割当やファイル作成などの操作を許す場合があるため、その理由からテキストチャンクは直接表示する前に制御文字でフィルタすることが仕様で推奨されています。
PNG 形式はファイル伝送エラーの早期検出を容易にするよう設計されており、チャンク内のデータ整合性を保証するために巡回冗長検査(CRC)を使用します。
この登録は以前のものを更新するものです:
この付録は BCP 13 および W3CRegMedia に準拠しています。
APNG 文書は明示的に型付けされた「チャンク」の集合で構成されます。PNG 仕様で定義された各チャンク型(gIFx を除く)について、それらのチャンクに関連する唯一の効果は受信者の表示上でアニメーション画像をレンダリングさせることです。
gIFx チャンク型はアプリケーション拡張データをカプセル化するために使われ、その利用はセキュリティリスクを呈する可能性がありますが、既知のリスクはありません。同様に将来のチャンク型(特に未登録のもの)に伴うセキュリティリスクは評価できません。ただし PNG ワーキンググループは「実行可能」データを含むチャンクが登録チャンクになることを許さない意図を持っています。
テキストチャンク(tEXt、iTXt、および zTXt)はコメント等として表示可能なデータを含みます。いくつかの OS や端末は埋め込まれた制御文字を含むテキストを表示することでキー再割当やファイル作成などの操作を行わせる可能性があるため、テキストチャンクは直接表示する前に制御文字でフィルタすることが推奨されます。
PNG 形式はファイル伝送エラーの早期検出を容易にするよう設計されており、チャンク内のデータ整合性を確保するために巡回冗長検査(CRC)を用います。
もし静的画像チャンクとアニメーション画像チャンクが混在する APNG ファイルを作成した場合、APNG をサポートしないツールを使う者は静的画像しか見えず、追加コンテンツに気づかないことがあります。この状況は例えばモデレーションを回避するために悪用され得ます。
image/apng は 2015 年以来広く未登録で使用されてきました。Animated PNG は 2022 年まで公式 PNG 仕様の一部ではありませんでした。本登録と PNG 仕様(第3版)は既に広く展開されている現実と公式文書を整合させるものです。
この節は規範的ではありません。
以下は私的チャンクの定義に関するガイドラインです:
この節は規範的ではありません。
gamma value は、画像の取り込みや再現で遭遇する非線形な transfer functions の近似を記述するために用いられる数値パラメータです。gamma value はべき法則の関数における指数です。 例えば次の関数:
intensity = (voltage + constant)exponent
は CRT(Cathode Ray Tube)表示器の非線形性をモデル化するために使われます。本国際規格では、この constant が 0 であると仮定することが多いです。
本規格の目的のために、一般的な画像パイプラインにおいて非線形な transfer functions が現れ、べき法則でモデル化できる可能性のある五つの位置を考えることが便利です。それぞれに関連する特徴的な指数には特定の名前が付けられます。
| input_exponent | イメージセンサの指数。 |
| encoding_exponent | データストリームを書き込むプロセスやデバイスが実行する任意の transfer function の指数。 |
| decoding_exponent | ソフトウェアが image data ストリームを読み取る際に行う任意の transfer function の指数。 |
| LUT_exponent | frame buffer と表示デバイスの間で適用される transfer function の指数(通常はルックアップテーブルによって適用される)。 |
| output_exponent | 表示デバイスの指数。CRT の場合、通常約 2.2 に近い値になります。 |
いくつかの合成された transfer functions、すなわち段階の組合せを記述する追加の概念を定義することが便利です。
| display_exponent |
frame buffer と表示装置の表示面の間で適用される transfer function の指数。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 value を記録するために使用されます。この情報は、デコーダが表示環境に関する追加情報と組み合わせて、望ましい表示出力を達成または近似するために使用され得ます。
この主題に関する追加情報は [GAMMA-FAQ] にあります。
画像エンコーディングに対するカラースペースの影響に関する追加情報は [Kasson] および [Hill] にあります。
chromaticity とカラースペースに関する背景情報は [COLOR-FAQ] にあります。
以下のサンプルコード — 参考情報 — は、PNG チャンクで用いられる CRC(Cyclic Redundancy Check)の実用的な実装を示します。(正式な仕様については ISO 3309 [ISO-3309] や ITU-T V.42 [ITU-T-V.42] を参照してください。)
サンプルコードは ISO C [ISO_9899] のプログラミング言語で書かれています。表 Table 31 のヒントは C 以外のユーザがコードを読みやすくする助けになるでしょう。
| 演算子 | 説明 |
|---|---|
&
|
ビット単位の AND 演算子。 |
^
|
ビット単位の排他的 OR 演算子。 |
>>
|
ビット単位の右シフト演算子。ここでのように符号なし量に適用されると、右シフトは左側にゼロを挿入します。 |
!
|
論理否定演算子。 |
++
|
"n++" は変数 n をインクリメントします。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;
}
この節は規範的ではありません。
この付録は PNG ソフトウェア開発者のためのいくつかのインターネット上のリソースの所在を示します。インターネットの性質上、このリストは不完全であり変更される可能性があります。
ICC プロファイル仕様は次で参照できます: https://www.color.org/
PNG のワールドワイドウェブサイトは http://www.libpng.org/pub/png/ にあります。このページは、
PNG および PNG 関連ツールに関する最新
情報の中心的な場所です。
deflate
に関する追加の文書と移植可能な C コード、および
CRC
アルゴリズムの最適化された実装は、zlib のウェブサイト https://www.zlib.net/
から入手できます。
移植可能な 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
ウェブサイトからアクセスできます。
この節は非規範です。
Video Full Range Flag の説明を改善これまで定義されていたが非公式であった Animated PNG (APNG) 用の 3 つのチャンクが追加されました:
これにより PNG 仕様は広く展開されている業界の実践と整合します。
cICP チャンク(ビデオ信号タイプ識別のための Coding-independent code points)を追加しました。これは [ITU-T-H.273] で定義された画像形式メタデータを含めるもので、PNG が [ITU-R-BT.2100] の High Dynamic Range(HDR)および Wide Color Gamut(WCG)画像を含められるようにします。
画像のカラースペースを定義するチャンクが複数存在する場合の優先順位が明確に定義されました。
以前定義されていた eXIf チャンクは PNG-Extensions 文書から本仕様の本文へ移されました。これはその使用の増加を反映するためです。
HDR コンテンツのトーンマッピング支援のために、マスタリング時に使用された表示の色空間を記述する mDCV チャンクと、ピークおよびフレーム平均輝度レベルを記述する cLLI を追加しました。これにより異種プラットフォーム間でのより正確な色合わせが可能になります。
ICC プロファイルを含む iCCP チャンクは、ICC.1 仕様の任意のバージョンに準拠するプロファイルを含め得ることを明確にしました。PNG Second Edition は当時の v2 のみを参照していましたが、その後業界実務としてより高いバージョンも用いられるようになっています。
インデックスカラー PNG における範囲外インデックスの取り扱いを明確化
未知かつ無効な補助チャンクのエラー回復を明確化
PNG Second Edition Errata の全てを取り込みました。特に、未特定のガンマ値を持つ PNG 画像が HTML や SVG のような形式に埋め込まれた場合、それらは untagged images として扱われるべきであることを明確にしました。
コミュニティからのフィードバックに基づく様々な編集上の明確化
参照を最新版へ更新
マークアップの修正およびリンク修正
ドキュメントソースを ReSpec に合わせて再フォーマット
W3C 推奨 PNG Specification Version 1.0 と PNG Second Edition の間の変更一覧は、PNG Second Edition changelist を参照してください。
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: