PNG (Portable Network Graphics) Specification, Version 1.2


Previous page
Next page
Table of contents

12. 付録:原理

(この付録は正式な PNG 仕様書の一部分ではありません)

この付録は PNG の設計上の決定に隠された理由を与えます。それら決定の多くはかなりの議論を受けています。作者は他のグループが異なる決定をする事をおおいに認めるものでありますが、私たちの選択は擁護でき一貫するものであると信じます。

12.1. なぜ新しいファイルフォーマットなのか?

世の中は本当にまだ違ったグラフィックフォーマットを必要としているのでしょうか。私たちはそう信じます。GIF はもはや自由に使うことができませんが、詳細が以下に議論されているようにそれを直接置き換えることのできる一般的に使われているフォーマットはありません。たとえば、特許に触れない圧縮の仕組みの GIF のように、既存のフォーマットを適応する事もできました。しかし、これはどのようにしても新しいコードが必要になります。すべてが、完全に新しいファイルフォーマットよりも簡単に実装できることはないでしょう。(PNG はどのような場合でも必要になる圧縮エンジン以外は実装が簡単になるように設計されていあます)。私たちはこれが既知の GIF の制限を取り払う新しいフォーマットをデザインする素晴らしい機会だと感じています。

12.2. なぜそのような特徴をしているのか?

PNG に選択された特徴は GIF の特別な長所をこれまで使っていたアプリケーションの必要にこたえることを意図しています。とくに、GIF はそのストリーム性とプログレッシブ表示の能力によってオンライン通信によく適合しいます。PNG はその特性を共有しています。

広く知られている GIF の短所にも対応しました。とくに、PNG はトゥルーカラーをサポートします。わたしたちは PNG と同じくらい有効で可逆圧縮のトゥルーカラーイメージの広く使われているイメージフォーマットを知りません。わたしたちは PNG のトゥルーカラーイメージが実用的に広範囲に使われることを望みます。

透明度コントロールの形式は背景に対してイメージを表示したりほかのイメージと一緒に表示したりするアプリケーションにとって価値があります。GIF はこの目的のために1つの透明色定義を提供しています。透明色の定義と同様に PNG は完全なαチャンネルをサポートしています。これは高い柔軟性のある透明度と圧縮性能の両方を提供します。

伝送エラーに対する頑健さは重要な考慮事項でした。たとえば、インターネットを通じて伝送されるイメージは時としてテキストとして誤って処理され、ファイルの脱落を招きます。PNG はそのようなエラー素早く確実に検出することができるようにデザインされています。

PNG は単一の圧縮技術に完全に依存しないように特別にデザインされました。deflate/inflate 圧縮がこの文書で言及されているとはいえ、PNG はそれ無しでも存在します。

12.3. どうしてそのような特徴をしていないのか?

いくつかの特徴は PNG から慎重に除かれました。それらの選択は PNG の実装を簡略にし、移植性と互換性を助成し、利用者にとって単純で簡単に扱うことができるようなフォーマットにしています。とくに:

PNG をプライベートに拡張することでそれらの特徴が簡単に付け加えられることを注意することは価値があります。しかしわたしたちはそれらを基本の PNG 標準の一部分に含めません。

PNG は1つのファイルに複数のイメージもサポートしません。この拘束はファイルごとに複数の画像を多くのアプリケーションが必要とせずサポートしないという現実を反省したものです。多くの場合、ひとつのイメージは基本的にイメージの連続を並べたものとは異なります。互換性の保証を危うくするよりは、わたしたちは単一のイメージのフォーマットと複数のイメージのフォーマットの間に明確な区別を引きます。PNG はひとつの単一のイメージのフォーマットです。(しかし、Multiple-image extension を参照してください)

12.4. なぜあのフォーマットを使わないのか?

PNG の開発を決定する前にわたしたちは多数の現存するフォーマットを考慮しました。PNG にとって重要であると感じている必要なものあうものはありませんでした。

GIF は法的な問題からもはや世界共通の標準としては適切ではありません。GIF の圧縮方法を置き換えるだけでこの問題は回避できますが、GIF はトゥルーカラーイメージ、αチャンネル、γ補正をサポートしません。その仕様は細かな問題も持っています。GIF89 仕様のサブセットのみが現実的に多彩な実装上移動可能ですが、仕様の移動可能な部分を明文化したものはありません。

TIFF (Tagged Image File Format) は単純で移植性のあるというわたしたちの目的のためには複雑すぎます。TIFF のサブセットを定義することによってその欠点は満たされますが、既存のソフトウェアによる TIFF はわたしたちの変異 TIFF 用のプログラムにロードされるかもしれず、ファイルがセーブされているという合理的な仮定をしている利用者は失望することでしょう。そのうえ、TIFF はストリーム処理のためにデザインされておらず、プログレッシブ表示の用意がなく、現在、優良で、法的に問題ない可逆圧縮の方法を提供していません。

IFF も提案されましたが、細かいところで適切ではありません。可能なイメージ表現は機器限定すぎますし、十分に圧縮されません。IFF のチャンク構造全体は PNG が多くを学んだ有用なコンセプトですが、IFF のチャンク構造と逐一同一にしようとはしませんでした。さらに述べられるべき問題はとくに、IFF の FORM は一列に書き込むようにデザインされていないという事実です。

可逆 JPEG はインデックスカラーイメージの保存を提供しないため適切ではありません。そのうえ、可逆のトゥルーカラーの圧縮は PNG よりはたいてい劣ります。

12.5. バイト序列

PNG はなぜネットワークバイトオーダーを使うのかという問いがなされてきました。わたしたちは、1つのバイトオーダーを選択し、それを一貫して使ってきました。どの序列もわずかな妥当性しかありませんでしたが、ネットワークバイトオーダーは相互変換のルーチンがすでにすべての PC を含む TCP/IP ネットワークをサポートするプラットフォームで利用可能であるという強みがありました。その関数は平凡で、リファレンス実装に含まれることになるでしょう。

12.6. インターレース

PNG の2次元インターレースの仕組みは GIF の line-wise インターレースより実装するのは複雑になります。それはファイルサイズにとってもわずかな負荷となります。しかし、最初のイメージを GIF の8倍の早さで実現します(最初のパスは GIF の 1/8 に比較して、ピクセルの 1/64 のみで伝送します)。この最初のイメージはざらざらしたものですが、多くの場面で利用価値があります。たとえば、イメージが利用者が早く見たい WWW のイメージマップだったとき、PNG の最初のパスはクリックするところを決定するのにたいてい十分です。PNG の仕組みはまた、GIF よりも見た目が良好です。なぜなら、水平と垂直の解像度は2倍よりも大きく異なることがなく、これは、スキャンラインを複製することでインターレース GIF が埋められたときに見られる奇妙な「酔っぱらい」を防ぎます。予備試験の結果はインターレース PNG イメージでの小さなテキストが典型的に等価な GIF の約2倍の早さで読みとり可能になることを示しています。つまり、PNG のイメージデータの 25% もしくは5番目のパスが、GIF の 50% もしくは3番目のパスの代わりになるということです。PNG は解像度のバランスしたまま増大するはずです。

12.7. なぜガンマか?

ディスプレイの出力強度に比例したサンプル値の保存において規格化することは自然に見えます(ガンマが 1.0)。しかし、実際には、1 以下のガンマを持つイメージが一般的です。これには3つの立派な理由があります:

実際には、1.0, 1/2.2, 1/1.45 周辺にイメージγ値はすべてみつけられます。GIF や JFIF のような古いイメージの標準たいていこのような事実を計算にいれていません。多様なシステムの間でのイメージの交換はイメージが「暗すぎる」や「明るすぎる」という広く知られた問題を引き起こします。

PNG はビュアがイメージを表示するときはイメージのγを補正することを期待しています。ほかの可能なアプローチはエンコーダがすべてのイメージをエンコード時に一定のγに変換することを求めることです。その方法はビュアの速度をわずかに増すことになりますが、基本的な欠点を持っています:

γが内イメージや間違ってγが記録されたイメージは常に存在しますから、良いビュアはγ調整のコードをとにかく組み込む必要があるでしょう。表示時のγ補正はしたがって正しい方法です。

履歴の記録:この仕様書の Version 1.0 はファイルのサンプルと望ましい表示出力強度の関係、というよりはファイルのサンプルと「元のシーンの強度」(カメラ入力)の間の関係を表現するものとして gAMA チャンクを使っていました。これは Version 1.1 で以下の理由で変更されました:

Version 1.0 でのγ関連の勧告は不正確でしたので、gAMA チャンクに通常の状況で置くべき値が不明瞭でした。表示状況が未知である LUT のない CRT ディスプレイ上で描かれたイメージでは、40000 と 50000 の間のどの値でも議論をすることができました。現実のアプリケーションは 45000 または 45455 を書くことを守っていましたし、現在の仕様書によって後者は勧告されています。

より多くの情報は Gamma Tutorial を参照してください。

12.8. 事前に積算されないα

PNG は可逆に保存できるイメージとは分離された透明度のマスクである「関連づけられない」もしくは「事前に積算されない」αが使われます。ほかの一般的な技法である「積算されるα」はα関数によって積算したピクセル値を保存します。要するに、イメージは黒い背景に対してすでに合成されています。 0 のαによって積算されると常に 0 になるので、透明度のマスクによって隠されるいくらかのイメージデータはこの手法では取り返しのつかない損失となります

いくつかのイメージレンダリング技法は事前に積算されるαでイメージを生成します(α値は実際にはイメージによってピクセルがどのくらい覆われるかを表現します)。この表現は、αが 0 であるところを除いてαでサンプル値を割ることで PNG に変換することができます。その結果は適切にαを扱うビュアによって表示されれば良好に見えるでしょうが、αチャンネルを無視するビュアならば、良好とはいえなくなるでしょう。

それぞれのαの保存形式は特長を持っていますが、わたしたちは、すべての PNG ビュア両方の形式を扱う必要を望みませんでした。わたしたちは可逆で一般的な事前に積算されないαを標準としました。

12.9. フィルタリング

フィルタリングははっきりとトゥルーカラーやグレイスケールのイメージの圧縮サイズを減少させることができるので、PNG はフィルタリングの能力を含んでいます。フィルタリングはときとしてインデックスカラーにも価値がありますが、あまり一般的ではありません。

フィルターアルゴリズムはピクセルごとではなくバイトごとの演算を定義しています。これにより、圧縮性能をごくわずか犠牲にして簡便さとスピードを獲得します。試験は、フィルタリングはたいてい 8 ビットパーサンプル以下のイメージでは効果がないということを示していますので、そのようなイメージのためにピクセルごとのフィルタリングを提供するのは無駄になります。16 ビットパーサンプルのデータでは、MSB は隣接する MSB によって予測され、LSB は隣接する LSB によって予測されるので、バイトごとのフィルタリングはピクセルごとのフィルタリングと近い効果があります。

エンコーダは新しいスキャンラインごとにフィルターを変更することができます。どのような場合もデコーダはすべてのフィルターのでフィルタリングロジックを含む必要があるので、これは、デコーダにとって複雑さを付け加えるものではありません。唯一の負担は、圧縮される前のデータストリームでスキャンラインごとの余分な 1-byte です。わたしたちの試験はすべてのスキャンラインに同じフィルターが選択されたときこの余分なバイトはほとんど無視できるほどに圧縮されることを示していますので、すべてのイメージにとって、固定フィルタリングの仕様と比較してわずかな保存コストしかかかりません。そして、フィルタリングを適応する潜在的なメリットは無視できないほど大きいです。現在までに発見されている単純なフィルタ選択の経験則ですら、固定フィルタより優れている適応フィルタリングのときもあります。とくに、インターレースイメージの連続したパスにフィルターの適応は挙動を変えることができます(固定フィルタはできません)。

12.10. text 文字列

多くのグラフィックファイルフォーマットはイメージと一緒に文字情報を保存する能力を含んでいます。しかし、おおくのアプリケーションはそれ以上を必要としています。いくつかの区別できるテキストを保存できる必要があります。たとえば、医療 X 線写真を保存するための PNG ファイルを使ったデータベースは患者の名前や医者の名前などを当然含む必要があるでしょう。PNG でこれを行う簡単な方法はテキストを保持する新しいプライベートチャンクを発明することです。このようなアプローチの不利な点はほかのアプリケーションがそれらのチャンクになにが入っているか考えることができず、単純にそれらを無視するであろうことです。かわりに、わたしたちは文字情報を標準的な text チャンクに適切なキーワードとともに保存すること推奨しています。text を使うことは PNG ビュアにそのチャンクが人間の利用者が興味を持つかもしれない文字を含んでいることを知らせます。したがって、ほかのビュアでそのファイルを見る人はその文字を見ることができ、キーワードが適切で自己説明的であればそれがなにであるかを理解することすらできます。(この目標のために、わたしたちは人が理解することが困難になる略記ではなく、略さないキーワードを推奨します。キーワードの数バイトを節約することは誤った倹約です。)

ISO 8859-1 (Latin-1) 文字セットは機能性と移植性の間の妥協として選択されました。いくつかのプラットフォームは 7-bit ASCII 文字以上を表示できませんが、ほかは、Latin-1 セットを超えて文字を扱うことができます。Lati 表現は広く利用可能で、かなり移動可能な文字セットであるとわたしたちは感じています。Latin-1 は Microsoft Windows や X Windows のような一般的なプラットフォームで使われている文字セットの直接のサブセットです。単純な文字の配置換えによって Macintosh システム上での扱うことができます。

12.11. iTXt

この部分は iTXt チャンクでのいくつかのデザイン決定の背景の理由を与えます。

Keyword: なぜ Unicode ではないのか?

Unicode は機械と人間の両方に提供されることを意図されたキーワードには装飾的すぎます。Unicode をサポートしないアプリケーションでさえ少なくともキーワードを理解する事ができるでしょう(たとえば、チャンクの選択除去するため)

Keyword: Latin-1 vs. ASCII

UTF-8 はこのチャンクの他の部分で使われ、ASCII は Latin-1 と異なり UTF-8 と互換性があります。キーワードが ASCII であることが苦にならないように、翻訳されたキーワードがあります。では、なぜ、Latin-1 を使うのか? 存在する他のチャンクすべてがキーワードを Latin-1 を使って格納しているからであり、アプリケーションはそれらがすでに含んでいるコードを再利用できます。

圧縮フラグと圧縮手法:なぜそれらをまとめないのか?

わたしたちはいままで無意味な圧縮手法を定義することを慎重に避けてきたので(tEXt/zTXt)、IHDR 中のそれを使うという誘惑はありませんでした。

言語タグ:

テキストによってどの言語が表現されているのかを知ることなく Unicode テキストをどのように翻案するかは常には明らかではありません。複数の iTXt チャンクが異なる言語で同じメッセージを格納することも表現可能であり、デコーダはその利用者に最も適切なものを自動的に選択することができます。

翻訳されたキーワード:

"Description" のような登録されたキーワードはひとつの言語(おそらく英語)で一回だけ登録されるので、自動的に認識することができます。他の言語の話者にわかりやすいように、翻訳が提供される必要があります。

テキスト:Unicode vs. MIME 文字セット名

MIME 文字セット名を含めることはより一般的であり、古い文字セットを使うことができるでしょう。しかし、Unicode のサポートは増えてきていて、Unicode のみが概念的に単純でゆくゆくは素晴らしい相互運用性で優勢になりそうです。

UTF-8 vs. UCS-2 vs. UCS-4

UCS-2 は先見性がありません。UCS-2 も UCS-4 のどちらも ASCII との互換性がありません。UTF-8 は ASCII の上位互換であり、UCS-4 の下位互換であり、一般に置き換えのための好ましいエンコードです(内部表現に対するものとして)。

12.12. PNG ファイルシグネチャ

PNG ファイルの最初の 8-byte は常に以下の値を格納します:

   (decimal)              137  80  78  71  13  10  26  10
   (hexadecimal)           89  50  4e  47  0d  0a  1a  0a
   (ASCII C notation)    ¥211   P   N   G  ¥r  ¥n ¥032 ¥n

このシグネチャはファイルを PNG ファイルとして認識し、一般的なファイル伝送の問題の即座の発見を提供します。最初の 2-byte は最初の 2-byte でファイルタイプを認識することを期待するシステムで PNG ファイルを区別します。最初のバイトはテキストファイルが PNG ファイルとして誤認されるかもしれないという問題を減らすために非 ASCII 値が選択されています。bit 7 をクリアする不良なファイル伝送を捕まえもします。バイト 2 から 4 はフォーマット名です。CR-LF の連続は改行組を変更するような不良なファイル伝送を捕まえます。control-Z 文字は MS-DOS 下でファイルの表示を停止させます。最後の LF は CR-LF の逆転伝送問題をチェックします。

デコーダは IHDR チャンクの正しいチャンク長とヘッダを含む次の 8-byte をさらに確かめるかもしれません。これは、null byte を脱落させたり変更したりする不良な伝送を捕まえるでしょう。

シグネチャ中や、ファイル中のどこにもにバーションナンバーがないことに注意してください。これは、計画的なものです。チャンク機構は Chunk naming conventions で説明されているようにフォーマットの拡張を扱う良好で柔軟な方法を提供しています。

12.13. チャンクレイアウト

チャンクのデザインはデコーダが認識できないもしくは興味のないチャンクをスキップすることを許しています。長さから決定できるような適切なバイト数をスキップする必要があるだけです。

4-byte の無符号値を簡便に扱うことのできない実装でありうる問題を避けるためチャンク長は 231-1 バイトに制限されています。実際問題としては、チャンクはたいていどんなときもそれよりは大変短くなるでしょう。

分離された CRC はそれぞれのチャンクでイメージの不良な伝送を可能な限り素早く検知します。とくに、イメージの外形寸法のような必須データは使う前に正当であると確認できます。

CRC はデータが生成されてから計算ができるので、チャンク長は CRC からはずします。これは、事前にチャンク長が知ることのできない場合にデータを2度読みすることを避けます。長さが間違っているなら、CRC チェックも間違うので、CRC から長さを除くことでファイル損傷の発見を失敗する余計な危険が発生することはありません。CRC は間違ったバイトのセットで計算され、ファイルから間違った値に対して検査がされます。

12.14. チャンク命名規則

チャンクの命名規則により、安全で、柔軟性のある PNG フォーマットの拡張が可能です。この機構は、全体ではなく特長それぞれに基づいて働くので、フォーマットのバージョンナンバーよりもずっといいです。デコーダは新しいファイルが(未知の必須チャンクを見つけることで指示されるような)未知の必須の特長を使っていないならば、処理することができます。未知の補助チャンクは安全に無視することができます。経験から、フォーマットのバージョンナンバーはそれが助けになるのと同じくらい可搬性を損なうことが示されていたので、わたしたちは、フォーマットのバージョンナンバーを持つことに反対する決定をしました。バージョンナンバーは不必要に高くセットされる傾向があり、古いデコーダが処理できるファイルを拒絶するようになります(たとえば、これは、GIF89 の仕様が現れてから後数年深刻な問題でありました)。しかも、プライベートな拡張は必須、補助のどちらでもでき、標準的なデコーダは適切に反応するでしょう。全体的なバージョンナンバーはプライベートな拡張には助けになりません。

無視されると、意図されるイメージの重要な部分が欠けるので、ベクトルグラフィックのための仮想的なチャンクは必須チャンクになるでしょう。イメージがなにを表現しているのかを理解すること無しに他のアプリケーションはそのイメージを表示することができないので、フラクタルイメージのためのマンデルブロ座標を運ぶチャンクは補助になるでしょう。一般的にチャンク形式はそのチャンクを解釈すること無しに意図したイメージを適切な表現で表示できないときのみ必須になるでしょう。

公開/プライベートの属性ビットはどこかで使われているかもしれない独自のチャンクと新しく定義される公開チャンクの形式名が衝突しないことを保証します。しかし、これは、他の誰かが、同じチャンク名を異なる目的で使っているかもしれないという可能性からプライベートチャンクの利用者を守ることはしません。プライベートチャンク形式のはじめのデータに本物であることを確認する情報を付け加えることは良い考えです。

PNG ファイルが変更されたとき、特定の補助チャンクは他のチャンクの変更を反映して変更する必要があるかもしれません。たとえば、イメージデータが変更されたとき、ヒストグラムのチャンクは変更される必要があります。ファイルエディタがヒストグラムのチャンクを認識しないときは、むやみにそれらを新しい出力ファイルにコピーする事は正確ではありません。そのようなチャンクは落とされるべきでしょう。安全/危険の属性ビットで補助チャンクを適切に特長づけることができます。

すべての可能な変更のシナリオが安全/危険の記号によってカバーされるわけではありません。とくに、ファイルの内容全体に依存するようなチャンクはサポートされません。(そのようなチャンクの例としてはファイル中に位置する IDAT チャンクのインデックスがあります。コメントチャンクを追加することで不注意にインデックスを中断させます)。そのようなチャンクの定義は推奨されません。特別なアプリケーションのために絶対に必要ならば、ほかのアプリケーションへの可搬性を当然失いつつも、そのようなチャンクを必須チャンクとできます。一般的に、補助チャンクは必須チャンクに依存することができますが、ほかの補助チャンクに依存することはできません。互いに依存する情報はひとつのチャンクに納められることが期待されます。

いくつかの状況ではほかの依存する補助チャンクをつくることがやむを得ないかもしれません。チャンクの属性ビットがこの場合を表現するためには足りないとはいえ、簡単な解決手法が利用可能です。依存しているチャンクで、依存するチャンクの CRC を記録します。チャンクがほかのプログラムによって変更されたかどうかを見極めることができます。

同じ技法が他の目的のためにも利用可能です。たとえば、プログラムが特定の順序のパレットに頼っているとき、 PLTE チャンクの CRC をプライベートチャンクに保存することができます。ファイルを再び読み込んだとき、この値が一致したなら、パレットが変更されていないという高い信頼性が与えられます。この技法が使われるときはプライベートチャンクの複写危険にマークをする必要がないことに注意してください。したがって、そのようなプライベートチャンクはほかのファイルの編集を生き残ることができます。

12.15. パレットヒストグラム

ビュアはイメージのパレットに列挙された色数を提供できないかもしれません。(たとえば、いくつかの色はウィンドウシステムによって予約されています)。最良の結果を実現するために、このような状況では、それぞれのパレットインデックスが実際に現れる頻度についての情報を持つことはディザのための最良のパレットを選択したり使用の少ない色を落としたりする助けになります。イメージはたいてい一回生成されて何回も表示されるので、エンコーダがそれを提供することが強制ではないとはいえ、エンコーダがこの情報を計算することは理にかなっています。

ほかのイメージフォーマットはたいてい使用頻度の順番で現れるようにパレットエントリを定義することでこの問題を扱ってきました。ほとんどそれだけの情報しか与えないので、それは劣った解決方法です。ビュアは最後の数色を落とすことでどのくらいの損傷があるかどうかを決定することができません。しっかりと色数を減らす必要のあるビュアの場合、ソートされたパレットもディザのためのターゲットパレットを選択するために十分な情報をあたえません。パレットヒストグラムはイメージデータを2度読みすることなくそのようなターゲットパレットを選択するために必要とされる情報を提供します。


Previous page
Next page
Table of contents