PNG (Portable Network Graphics) Specification, Version 1.2


Previous page
Next page
Table of contents

9. エンコーダへの勧告

この章はエンコーダの振る舞いに対するいくつかの勧告です。PNG のエンコーダへの唯一絶対的な必要条件はこの章以前で指定されたフォーマットに合致するファイルを生成することです。しかし、最良の結果は以下の勧告によって達成されるでしょう。

9.1. サンプル深度の拡大

PNG で直接表現できないサンプル深度を持つ入力サンプルをエンコードするとき、エンコーダはサンプル深度を PNG で認められるサンプル深度に拡大する必要があります。この上なく正確な拡大手法は一次方程式

   output = ROUND(input * MAXOUTSAMPLE / MAXINSAMPLE)

で、入力サンプルの範囲は 0 から MAXINSAMPLE で、出力の範囲は 0 から MAXOUTSAMPLE2sampledepth-1)までです。

一次の拡大手法の近似は、最大ピットから始まる有効ビットへのシフトと空きビットでの最大ビットへの繰り返しによる「左ビット複製」によって達成できます。この手法は一次の拡大の計算よりよく高速になります。例として、8-bit に拡大される 5-bit のサンプルを仮定します。元のサンプル値が 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
   |=======|  |===|
       |      Leftmost Bits Repeated to Fill Open Bits
       |
   Original Bits

一次方程式の計算による値と一致します。左ビット複製はふつうは一次の拡大と同じ値を与えるか、1より大きいの誤差はありません。

入力値を単純に左シフトし低位ビットを 0 で埋めると、近似値よりはっきりと少なくなります。この考えでは、すべて 1 の最大値を作ることができないので、純白を再現することができません。実際の効果はイメージをわずかに暗くします。この手法は一般には推奨されませんが、とくに 8-bit よりおおきなサンプル深度で扱うときには圧縮の効果は上がります。0 埋めの拡大によって持ち込まれる誤差は高サンプル深度では小さなものなので、エンコーダーによってはそれを使うことを選択することができます。しかし、多くのデコーダはα値がすべて 0 もしくはすべて 1 を特別な場合とするのでαチャンネルデータには 0 埋めは使ってはいけません。拡大されたデータではそれら両方の値がきっちり表現されることが重要です。

エンコーダが sBIT チャンクを書き込んだとき、保存されるサンプルの高位ビットが元のデータと一致するような方法で拡大される必要があります。つまり、sBIT チャンクがサンプル深度 S を指定するとき、保存されるデータの高位の S-bit は元の S-bit の値と一致する必要があります。このことで、デコーダは右シフトによって元のデータを取り戻すことができます。付け加えられる低位ビットに制約はありません。上述のすべての拡大手法はこの制限にあうことに注意してください。

元のデータを拡大するときは、すべてのサンプルに一貫して低位ビットを埋めるように推奨されます。つまり、同じ元の値ならどのような場所でも同じサンプル値を生成するべきです。このことは異なるサンプル値の数を減らすことで圧縮率を高めます。しかし、これは必要条件ではなく、エンコーダによってはそれに従わないことを選択することができます。たとえば、あるエンコーダはファイルサイズの増大を犠牲にする代わりにイメージの表示品質を向上するように低位ビットをディザにするかもしれません。

いくつかのアプリケーションでは元のデータが 2 の累乗の範囲を持たないかもしれません。シフトの方法はこのような場合には働きませんが、一次方程式の拡大はこのような場合でも働きます。sBIT は元のデータが正確に 0..2S-1 の範囲であると示唆するため、このようなイメージでは sBIT チャンクは書き込まれないことが推奨されます。

9.2. エンコーダのγの扱い

あなたがγの問題に精通していないのであれば、Gamma Tutorial を参照してください。

徹底したカラーマネジメント [ICC] の能力のあるエンコーダは Encoders capable of full-fledged color management [ICC] より高度な計算を遂行し、iCCP チャンクを使うことを選択することもできます。イメージのサンプルが sRGB 仕様に準拠していることを識別できるエンコーダは sRGB チャンクを使い、γ扱いを行いません。そうでない場合にこの章が適用されます。

エンコーダはγに関する2つの決定を行います。最初に、PNG ファイルに入れるイメージのサンプルをどのように変化させるかを決める必要があります。2番目に、gAMA チャンクにどのような値を書き込むかを決める必要があります。

2番目の決定の規則は単純にデコーダがあなたの望むようにするような値を書き込むことです。デコーダへの勧告: Decoder gamma handling を参照してください。

最初の決定はイメージサンプルの性質とその精度に依存します。明度が浮動小数点もしくは高精度の整数で表現されているサンプル(コンピュータがレンダリングしたイメージのような)の時は、エンコーダはファイルに出力する整数値にデータを量子化する前に「γエンコード」(指数が 1 未満の指数関数を適用する)を行うことができます。これで、与えられたサンプル深度でより少ないバンド幅、もしくは同じ視覚品質のままですくないサンプルの結果が得られます。0 から 1 の範囲の浮動小数点の値として表現されれる強度レベルはファイルのイメージのサンプルに次のように変換することができます:

   sample = intensity ^ encoding_exponent
   integer_sample = ROUND(sample * (2^bitdepth - 1))

方程式中の強度(intensity)が望ましい表示出力強度のとき、エンコード指数(encoding_exponent)が gAMA の指定によってファイルに書き込まれるγ値です(the gAMA chunk specification を参照してください)。しかし、エンコーダが利用できる強度が元のシーンの強度のときは、ほかの変換が必要になるかもしれません。ときどき、表示イメージは元のイメージよりも高いコントラストを持つことがあります。すなわち、元のシーンから表示する出力への端と端を接した変換関数は 1. より大きな指数を持ちます。この場合は、

   gamma = encoding_exponent / end_to_end_exponent

オリジナルのイメージがどのようなコントラストの変更があるか保証できるようないかるなる状況下でキャプチャーされたか(計算されたか)がわからないときは、表示強度はオリジナルのシーンの強度に比例すると仮定することができます。言い換えるならば、端と端を接した指数は 1、で、γとエンコード指数は等しい。

イメージがファイルに書き込まれるだけならば、エンコーダはエンコード指数の選択とは関係ありません。gAMA チャンク中のγ値の大本となる値の選択は 1/2.2 が適度な選択です。なぜなら典型的なビデオモニターでデコーダが表示するための仕事が最小となるためです。

イメージレンダラーはイメージを PNG ファイルに書き出すこととスクリーン上に表示することを同時にするかもしれません。表示されるピクセルは表示システムに適切化されるべきであり、そのため、利用者は意図したシーンの正確な表現を見ることになります。

レンダラーが表示したサンプルの値を PNG ファイルに書き出す必要があるとき、ファイル出力に分離されたγエンコードをさけるため、レンダラーは表示システムの変換関数を指数関数で近似するべきで、その指数の逆数を gAMA チャンクに書き込むべきです。このことで PNG デコーダはレンダリングの最中にファイルの作者がスクリーン上に見ていたものを再現することができます。

しかし、レンダラーが表示装置に最適化した表示ピクセルを計算し、ファイルに保存するために分離してγエンコードを行い、イメージで将来使われるのを見越して gAMA チャンクの値を持つために準備することは、同じく適切です。

コンピュータグラフィックスのレンダラーはときとしてγエンコードを行いません。かわりにシーンの明度に直接比例したサンプル値を作ります。PNG エンコーダがすでに整数に量子化された強度のサンプルを受け取ったときは、それらにγエンコードを行う意味はありません。それはさらに情報が劣化するという結果になります。エンコーダは PNG ファイルにサンプル値を書き出すだけにするべきでしょう。これは、gAMA がγ値 1.0 を格納するということを意味しません。なぜなら、シーンの強度から表示出力強度への望ましい端と端が接した変換関数は線形えある必要はないからです。望ましいγ値は 1.0 から離れてはいないかもしれませんが・・・。それは、そのシーンが日中のシーンとしてレンダリングされたのか、屋内のシーンとしてレンダリングされたのかなどに依存します。

サンプル値がハードウェアの部品から直接得られたとき、γの補正値は原理的にはハードウェアとシーンの明度の状態の変換関数から推測できます。ビデオデジタイザー(「フレーム取り込み」)の場合は、サンプルはおそらく sRGB の色空間にあります。なぜなら sRGB の仕様はビデオの標準と互換性があるように設計されたためです。イメージスキャナーはすこしは予測可能です。それらの出力サンプルは CCD センサーそれ自身が線形であるために入力の明度に比例するか、続く印刷でのドットゲインのためにデザインされた指数関数(指数はだいたい 0.57)がスキャナーのハードウェアによって適用されているか、モニターに表示するためにスキャナーによって補正されているかでしょう。装置の資料に変換動作、または(一致するかもしれない)イメージデータが対象とするディスプレイもしくはプリンタについて記述されているかもしれません。補正された対象をスキャンすることも、装置の動作を決定する補正ソフトを使うこともできます。γはファイルに望ましいスキャナー入力ではなく、望ましい表示出力を関連づけます。

ファイル形式コンバータは通常、与えられたイメージを異なるγに変換しようとするべきではありません。PNG ファイルに変換せずにデータを保存し、可能なら元のファイルの情報からγ値を推測します。ファイルの変換時のγの変更は表現されている強度レベルのセットの再量子化の原因となり、わずかな利益のために深刻な丸め誤差を招きます。ほとんどの場合ただ単に入力から出力ファイルに手を着けずにサンプル値をコピーすることがよいでしょう。

元のファイルフォーマットがイメージのγ特性について記述しているとき、ファイル形式のコンバータは PNG に gAMA チャンクを書き込むことが強く推奨されます。いくつかのファイル形式は表示出力に特化してファイルサンプルを写像する指数関数を指定することに注意してください。元のファイルのγ値が 1.0 より大きいときは、表示システムの指数かもしれません。PNG のγにはその逆数を使うべきでしょう。元のファイルフォーマットが表示出力以外の何らかとイメージサンプルとの間の関係を記録しているときは、PNG のγを推測することはより複雑になるでしょう。

イメージがどのように最初は作られたかに関わりなく、エンコーダもしくはファイル形式のコンバータが、そのイメージが指数 display_exponent の累乗の関数によって近似することのできる変換関数をもつ表示システムを使い満足に表示されていると知っているときは、イメージにγ値を持たせることができます:

   gamma = 1 / display_exponent

チャンクを省略したり PNG のデコーダにγの推測を強いてしまうよりは、適切に近似して gAMA チャンク を書き込む方がよいでしょう。

一方で、エンコーダがγ値を推測する手だてを持たないときは、gAMA チャンクを完全に省略したほうがよいでしょう。イメージのγを推定しなければならないならば、デコーダが推定するままにしておきます。

γはαサンプルには適用されません。αは常に線形で表現されます。

デコーダへの勧告は:Decoder gamma handling を参照してください。

9.3. エンコーダの色の扱い

あなたが色の問題に精通していないのであれば、Color Tutorial を参照してください。

徹底したカラーマネジメント [ICC] 能力のあるエンコーダは、ここに記述されているよりもより高度な計算を行い、iCCP チャンクを使うことを選ぶこともできます。イメージサンプルが sRGB の仕様書 [sRGB] に適合すると認識したエンコーダは sRGB チャンクを使うことを強く推奨されます。そうでない場合、この章が適用されます。

エンコーダが元のディスプレイの基礎の色度を決定でき、もしくはイメージの起源やそれが動いていたハードウェアを基礎とした推測ができるとき、エンコーダは cHRM チャンクを出力することを強く推奨されます。もしそうなら、gAMA チャンクも書き込むべきでしょう。 cHRM があって、gAMA がなければ、デコーダは少ししかできることはありません。

最近のビデオ装置によって作られたビデオは次のような CCIR 709 primaries と D65 white point [ITU-R-BT709] を使っているかもしれません:

            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] です:

            R           G           B         White
   x      0.630       0.310       0.155       0.3127
   y      0.340       0.595       0.070       0.3290

元々の NTSC の色基礎はここ 10 年は使われていません。NTSC の数値が標準的な文書に記載されているとはいえ、それを実際に使うようなイメージに出会うことはないでしょう。

出力として PNG ファイルを生成するスキャナは cHRM チャンクに色度のフィルターを挿入するべきでしょう。

手書き、もしくは電子的に編集されたイメージの場合は、制作時に彼らが見ていたモニターを決める必要があります。多くのイメージ編集プログラムはあなたが使っているモニターの形式を指定することができます。これは、それらが装置に依存しない内部で働いているためです。そのようなプログラムは妥当な cHRMgAMA チャンクを書き込むのに十分な情報を持ち、自動的にそうするべきでしょう。

エンコーダが全スペクトルレンダリングを行うコンピュータイメージレンダラーの一部としてコンパイルされているときは、内部の装置に依存しない色空間から RGB に変換するときに使われるモニター値が cHRM チャンクに書き込まれるべきでしょう。選択された RGB 装置の範囲外にある色は切り捨てられるか、さもなければ、範囲内に強制的に丸め込まれるでしょう。PNG は範囲外の色は保存できません。

コンピュータイメージレンダラーが装置に依存した RGB 空間で直接計算を行うときは、cHRM は、シーンの表現やレンダリングのパラメータが特定のモニターに調整されること無しに書き込むべきではありません。この場合、そのモニター(認識できるのなら)へのデータを構築するために cHRM チャンクを使うべきでしょう。

イメージの実際の起源が未知の場合はよく、とくにほかのフォーマットで生成されたとき、あります。いくつかのイメージフォーマットは cHRM チャンクを満たして使うことのできる校正情報を保存します。たとえば、CCIR 709 primaries と D65 white point を使うすべての PhotoCD イメージは、PhotoCD ファイルを変換するとき、cHRM チャンクにそれらの値を書き込めます。PhotoCD は SMPTE-170M 変換関数も使います。(PhotoCD は RGB の範囲外の色も保存でき、そのため、そのデータは PNG フォーマットに書き込む前に範囲外の配置が必要になります)。TIFF 6.0 のファイルは任意で校正情報を保存でき、存在するのなら、cHRM を校正するために使えます。GIF やそのほかのフォーマットは校正情報を保存するしません。

ファイル形式コンバータが与えられたイメージを異なる RGB 色空間に変換しようとすることは推奨されません。ファイルのコンバート時の色空間の変換は、範囲の不適合や丸め誤差により悪い考えです。γの変換と同様、データをもれなく保存し、イメージが表示されるときの変換の一回に負わせるのがよいでしょう。

デコーダへの勧告は:Decoder color handling を参照してください。

9.4. αチャンネルの生成

αチャンネルはイメージの透明な部分を一時的に隠すマスク、または、非矩形のイメージを構成する手法としてとらえることができます。最初の場合では、完全に透明なピクセルのカラー値は将来の使用のために保存されるべきでしょう。2番目の場合では、透明なピクセルは利用価値のあるデータを運ぶことはありませんし、それは、単純に PNG で必要とされる矩形のイメージを埋め尽くすだけです。この場合、完全に透明なピクセルには、よりよい圧縮のために同じカラー値をすべてに割り当てるべきでしょう。

イメージの製作者はデコーダが透明度の制御を無視する可能性があることを心に留めておくべきでしょう。したがって、透明なピクセルに割り当てられた色はいつでも適切な背景色であるべきでしょう。

完全なαチャンネルを必要としない、もしくは、圧縮効率を犠牲にすることのできないアプリケーションには tRNS 透明度チャンクも利用可能です。

イメージが既知の背景色を持っているときは、その色を bKGD チャンクに書き込むべきでしょう。透明度を無視するデコーダであっても、使っていないスクリーン領域を bKGD 色で塗りつぶすことができます。

オリジナルのイメージが事前に積算された(関連づけられたともよびます)αデータを持つときは、それぞれのサンプル値から一致するα値を分離することで、PNG の事前に積算されない形式に変換してください。そのとき、イメージのビット深度による最大値まで増大させ、近似の整数に丸めます。正当な事前に積算されたデータでは、サンプル値がその対応するα値を越えることはありませんので、この分割の結果の範囲は常に、0 から 1 までのになります。α値が 0 のとき、出力は黒( 0 ) になります。

9.5. 推奨パレット

推奨パレットは sPLT チャンクとして PNG ファイル中に現れ、トゥルーカラーの PNG ファイル中では PLTE として現れます。どちらの場合も、推奨パレットはイメージデータの必要不可欠な部分ではありませんが、インデックスカラーの表示装置上での表示に使うことができます。推奨パレットはトゥルーカラーの装置で動くビュアには関係のないものです。

sPLT が推奨パレットを提供するために使われるとき、エンコーダはパレットエントリの相対的な重要度を示す頻度フィールドをすべて 0 のまま(未定義)にしておくよりは、使うことを推奨されます。頻度値はディザが適用されていないのであればそれぞれの RGBA のパレットエントリを使った近似値 "nearest neighbor" カウントとして簡単に計算します。(それらのカウントは推奨パレットの生成の結果としてただで利用可能になります)。推奨パレットは透明度の情報も含むので、合成されないイメージとして計算されるべきです。

インデックスカラーイメージでも、sPLTPLTE チャンクで与えられたすべての色を表示することのできないビュアにとっては代用の減色パレット定義として利用可能です。

トゥルーカラーの PNG ファイルに推奨パレットを含むための古い手法は PLTE チャンクを使います。この手法が使われるときは、ヒストグラム(頻度)は分離された hIST チャンクに現れるべきです。PLTE は透明度の情報も含まないので、カラータイプが 6 (αチャンネル付きトゥルーカラー)のイメージでは、bKGD チャンクが現れ、パレットとヒストグラムはイメージが指定された背景色に対して合成されたものを参照として計算することが推奨されます。この定義は分数のα値を持つピクセルにとって利用価値のあるパレットエントリが生成されることを保証するために必要です。その結果のパレットはもしかすると同じ背景色に対してイメージを表示するビュアのみに利用価値のあるものになるかもしれません。PNG エディタはカラータイプが 6 のイメージで bKGD チャンクを変更したり削除したりしたとき、パレットを消去したり再計算したりすることが推奨されます。

イメージのカラータイプが 2 (αチャンネルなしトゥルーカラー)のときは、RGB データのみを参照し、透明色の指定を無視して PLTEhIST を計算することが推奨されます。ファイルが透明色を使っている(tRNS チャンクを持つ)とき、ビュアは意図する背景色をつかって簡単にその結果のパレットを順応させることができます。背景色を使った tRNS 色に最も近いパレットエントリを入れ替える必要があるだけです。(ファイルの bKGD 色に一致するかもしれませんししないかもしれません)

カラータイプが 6 のイメージで bKGD なしに PLTE が現れるときは、パレットが計算された状況は指定されません。

推奨パレットを提供するためには、sPLTPLTE よりも以下の場合ではより柔軟です:

sPLT を使うエンコーダは PLTE/hIST の推奨パレットも、sPLT を認識しないデコーダへの後方互換のために、書き込むことを選択できます。

9.6. フィルターの選択

カラータイプが 3 (インデックスカラー)のイメージでは、フィルター形式 0 (None)がたいてい効果的です。256 色以下のイメージはほとんどいつもインデックスカラーのフォーマットで保存されていることに注意してください。トゥルーカラーのフォーマットではより大きくなるでしょう

フィルター形式 0 は 8 ビット未満のビット深度のイメージにも推奨されます。低ビット深度のグレイスケールイメージのときは、8-bit の表現に拡張してフィルターを適用したほうがよいかもしれませんが、それはまれなことです。

トゥルーカラーやグレイスケールイメージのときは、5つのフィルターのいくつかは効果的であると示されるかもしれません。エンコーダが固定フィルターを使うときは、Peath フィルターが最良のようです。

トゥルーカラーやグレイスケールイメージの最良の圧縮のためには、フィルターがスキャンラインごとに選択される最適化フィルターの手法が推奨されます。以下の単純な発見が初期のテストでよい結果を残しました。5種類すべてのフィルターを使い出力を計算し、出力の絶対値の和が最小になるフィルターを選択する。(Consider the output bytes as signed differences for this test)。この手法はたいていどんな単一の固定フィルター選択よりも効率的です。しかし、PNG に関する多くの経験によりよりよい発見的手法が見つかるでしょう。

これらの勧告によるフィルターは非インターレースイメージよりもインターレースイメージにより効果的です。

9.7. text チャンクの処理

空ではないキーワードがそれぞれの text チャンク(iTXt, tEXt, zTXt)に与えられる必要があります。一般的なキーワード "Comment" は利用できるテキストの説明によりよいものがないときに使うことができます。利用者提供のキーワードが使われるときはキーワードの制限に適しているかチェックします。

tEXt もしくは zTXt チャンクに保存されるテキストは Latin-1 の文字集合が使われることが期待されます。エンコーダはそのシステムの文字集合が Latin-1 でないとき文字コードの配置を変えて与えるべきでしょう。Latin-1 に定義されていないキャラクタを保存したいエンコーダは iTXt チャンクを使うべきでしょう。

エンコーダは読みやすいようにテキストの1行が 79 文字を越えないように生成するべきです。

サイズが 1K (1024-byte) より少ないテキストの要素は圧縮されない text チャンクで出力することが推奨されます。特に、基本的なタイトルや作者のキーワードに関連付いたテキストは常に圧縮されないチャンクで出力されることが推奨されます。一方で、長ったらしい権利放棄文などは、圧縮の理想にかなっています。

大きな text チャンクをイメージデータ(IDAT)の後ろに置くことは、デコーダがイメージデータを得るのにテキストを読み込まないため、いくつかの局面でイメージの表示速度を上げることができます。しかし、イメージのタイトルのような小さな text チャンクは IDAT チャンクの前に現れることが推奨されます。

9.8. プライベートチャンクの使用

アプリケーションは PNG のプライベートチャンクを他のアプリケーションが理解する必要のない情報を伝えるために使うことができます。そのようなチャンクは将来の公開チャンクの定義と衝突することがないように、2番目の文字が小文字として命名される必要があります。しかし、ほかのアプリケーションが同じプライベートチャンクの名前を使わないという保証がないことに注意してください。プライベートチャンク形式を使うときは、チャンクデータの先頭に追加の識別情報を保存するのが賢明です。

イメージを表示する絶対に必要な情報を保存しないすべてのプライベートチャンクには、必須チャンク形式ではなく、補助チャンク形式(最初の文字が小文字)を使います。プライベートな必須チャンクを作ることは、それらが PNG ファイルを移植性のあるものではなくすため勧められません。そのようなチャンクは公開され利用可能なソフトウェアやファイルでは使われるべきではありません。プライベートな必須チャンクがあなたのアプリケーションに必須であるときは、それがファイルの最初のほうに現れることが推奨されます。 そうすれば、標準的なデコーダはそのファイルを扱うことができないと悟るまで延々と読み込む必要がなくなります。

あなたの開発したチャンク形式を外部の人間に知らしめたいときは、PNG 仕様書の管理者に提案されるチャンク名と特殊目的の公開チャンクのリストについかするための定義を提出するために連絡をとってください( Additional chunk types を参照してください)。提案された公開チャンク名(2番目の文字が大文字)は登録が認可されるまでは公開され利用可能なソフトウェアやファイルで使うことができないことに注意してください。

人間の利用者と関係のある文書情報を含む補助チャンクの場合は、そのために特殊なチャンク形式をつくるべきではありません。かわりに text チャンクを使い、適切なキーワードを定義してください。この方法で、あなたのソフトウェアを使っていない利用者がその情報を利用可能になります。

text チャンク中のキーワードは、ほかの利用者にそのチャンクが含む内容を理解させるために、合理的で自己説明的であるべきです。一般的に利用されるようであれば、新しいキーワードは PNG 仕様書の管理者によって登録されることが可能です。しかし、最初は登録されることなくキーワードをつかうことができます。

9.9. プライベートな形式と手法コード

この仕様書はあるフィールドのとりうる値のうちひとうだけの意味を定義しています。たとえば、圧縮手法は 0 やフィルター形式は 0 から 4 までが定義されています。それらのフィールドにおいて 127 より大きな数は開発試験ときやプライベートな定義の値として使われます 128 より小さい数はこの仕様書の将来の公開される拡張の可能性のために予約されています。プライベートな形式コードを使うということはそのファイルが標準的なデコーダによって読めなくなるということに注意してください。そのようなコードは実験目的以外では全く推奨されませんし、公開され利用可能なソフトウェアやファイルに現れるべきではありません。


Previous page
Next page
Table of contents