1. はじめに
このセクションは規範的ではありません。
CSS Color 4 は、オープンウェブプラットフォームにワイドカラ―ガマット(WCG)カラースペースを追加します。 設計上、これらはすべて標準ダイナミックレンジ(SDR)カラースペースです。 この仕様は、ハイダイナミックレンジ(HDR)をサポートするための追加機能を定義します。

WCG仕様は数十年にわたり概ね安定していますが、 HDR規格はまだ発展途上であり、 過去10年の間に頻繁に改訂されています。
1.1. 値の定義
この仕様はCSSプロパティ定義規約に従い、 [CSS2]の値定義構文 ([CSS-VALUES-3])を使用します。 この仕様で定義されていない値型は CSS Values & Units [CSS-VALUES-3]で定義されています。 他のCSSモジュールと組み合わせることで、これらの値型の定義が拡張される場合があります。
定義内で記載されたプロパティ固有の値に加えて、 この仕様で定義されるすべてのプロパティは CSS全体のキーワードもプロパティ値として受け付けます。 可読性のため、ここでは繰り返し明記していません。
2. HDR用語集
2.1. ダイナミックレンジの定義
ダイナミックレンジとは、 輝度のうち、最も明るい色と最も暗い色の差です。 ダイナミックレンジは写真用語のストップで測定されます。 1ストップは輝度が2倍になることを意味します。
function DynamicRange( high, low) { return Math. log2( high) - Math. log2( low); }
HDR基準白 (メディアホワイトとも呼ばれる)は、通常の白い背景や 暗い背景上の白いテキストの色です。 画面全体で快適に見られる色です。
標準ダイナミックレンジ(SDR)では、 HDR基準白も 最も明るい色であり、 赤・緑・青全てが最大強度で発色したときの色です。
画面の全体的な輝度はユーザーの好みや標準とは異なる視聴条件に合わせて 調整されることが一般的です。
SDRの場合、画面を明るくしてもダイナミックレンジは変化しません。 なぜなら最も暗い色も同様に明るくなるからです。
ハイダイナミックレンジ (HDR)では、 HDR基準白よりも明るい色を表示できます。 たとえば、HDRディスプレイでHDR基準白が203cd/m²に設定されていても、 小さなハイライトで1000cd/m²を表示できる場合があります。 通常、最も明るい色は 画面のごく一部、かつ限られた時間のみ表示されます。 これは消費電力や発熱による制約のためです。
HDRでは、画面を明るくするとダイナミックレンジが広がりますが、 HDR基準白の輝度は一定です。
SDRとHDRのダイナミックレンジを対数スケールで示した図を追加すること
§ 9 SDRとHDRコンテンツの合成や 色空間変換時には、 SDRコンテンツのHDR基準白を 203cd/m²に固定する必要があります [Rpt_BT.2408]。 これにより合成入力のHDR基準白レベルは 合成後の信号のHDR基準白レベルに合致します。
HDR(またはSDRとHDRの混合)コンテンツを表示する際、 基準マスタリングディスプレイより能力の低いディスプレイや 標準とは異なる視聴環境の場合には、 色再レンダリング (OOTF)が行われます。 これにより、HDR基準白が203 cd/m² より低くも高くも表示される場合があります。
2.2. ヘッドルームの導入
HDRディスプレイが出力できるピーク 輝度レベルは 大きく異なります。
ピークホワイトがHDR基準白よりどれだけ高いかを HDRヘッドルームと呼び、 これはHDR基準白のレベルや ユーザーの好み、 また視聴条件に依存します。
ヘッドルームは通常、写真用語のストップで表されます。 このため、標準ダイナミックレンジ(SDR)は HDRヘッドルームが0ストップであり、 最も明るい白がHDR基準白となります。
暗い視聴環境で HDR基準白を100cd/m2に設定した場合、 HDRヘッドルームは4ストップ(16倍)になります。
Webプラットフォームは現在のところ、 ディスプレイのヘッドルームの値を直接公開していません。 これは視聴条件に依存し、 リアルタイムかつ未量子化のヘッドルーム情報が トラッキングの手段になる可能性があるためです (たとえばユーザーが屋外に移動して日差しが強いことなどが検知できる)。
常に最大限のHDRヘッドルームを使うことが 望ましいとは限りません。 CSSでは、大まかにどれだけのヘッドルームを使用するか コントロールする方法が提供されています。 このレベルは要素ごと、あるいは時間によっても異なる場合があります。
3. ダイナミックレンジの制御
3.1. dynamic-range-limit プロパティ
| 名前: | dynamic-range-limit |
|---|---|
| 値: | standard | no-limit | constrained | <dynamic-range-limit-mix()> |
| 初期値: | no-limit |
| 適用対象: | すべての要素 |
| 継承: | はい |
| パーセンテージ: | 該当なし |
| 算出値: | dynamic-range-limit の算出値を参照 |
| 正規順序: | 文法通り |
| アニメーション型: | dynamic-range-limit-mix()による |
テスト
- standard
- 表示される最大の輝度色が、 HDR基準白(つまりCSS色のwhite)と同じになります。
- no-limit
- 表示される最大ピーク輝度が HDR基準白(つまりCSS色のwhite)よりもはるかに高くなります。正確なレベルは指定されていません。
- constrained
- 表示される最大ピーク輝度が HDR基準白(つまりCSS色のwhite)よりやや高くなり、 SDRとHDRのコンテンツを快適に一緒に表示できるようにします。
3.2. ダイナミックレンジ制限のミックス:dynamic-range-limit-mix()関数
この関数は1つ以上のdynamic-range-limit値を受け取り、 それらを内部的にHDR基準白からのストップ値へ変換し、 指定の比率でミックスした結果にディスプレイを調整します。 プライバシー保護のため、実際の計算結果は外部には公開されません。
dynamic-range-limit-mix() = dynamic-range-limit-mix( [ <'dynamic-range-limit'> && <percentage [0,100]> ]#{2,} )
テスト
3.3. dynamic-range-limit の算出値
指定値がstandard、constrained、またはno-limitである場合、算出値は指定値と同一です。
指定値がdynamic-range-limit-mix()の場合、算出値は以下のアルゴリズムで決定されます。
-
混合するパラメータの算出値を v1 ~ vN とする。
-
混合比率(パーセンテージ)を p1 ~ pN とし、合計が100%になるよう正規化する。
-
寄与率を次のように定義する:
-
v1 ~ vN で standard であるもののパーセンテージを p1_standard ~ pN_standard とする。
-
v1 ~ vN で constrained であるもののパーセンテージを p1_constrained_high ~ pN_constrained_high とする。
-
v1 ~ vN で no-limit であるもののパーセンテージを p1_no_limit ~ pN_no_limit とする。
-
-
重み付き合計を次のように計算する:
-
p_standard = (p1_standard*p1+...+pN_standard*pN)/100
-
p_constrained_high = (p1_constrained_high*p1+...+pN_constrained_high*pN)/100
-
p_no_limit = (p1_no_limit*p1+...+pN_no_limit*pN)/100
-
-
p_standard、p_constrained_high、またはp_no_limitのいずれかが100%の場合、算出値はそれぞれstandard、constrained、no-limit となる。
-
それ以外の場合、算出値はdynamic-range-limit-mix() となり、パラメータは standard、constrained、no-limit(この順)、および割合 p_standard、p_constrained_high、p_no_limitとなり、割合が0%のものは省略する。すべてのパラメータが省略される場合、算出値は初期値となる。
dynamic-range-limit-mix ( high10 % , dynamic-range-limit-mix ( standard25 % , constrained75 % ) 20 % , dynamic-range-limit-mix ( constrained10 % , no-limit30 % ) 20 % )
の算出値は
dynamic-range-limit-mix ( standard10 % , constrained40 % , no-limit50 % )
4. <color> 構文
このモジュールは <color-function> 型を拡張します:
<color-function> = <rgb()> | <rgba()> |
<hsl()> | <hsla()> | <hwb()> |
<lab()> | <lch()> | <oklab()> | <oklch()> |
<ictcp()> | <jzazbz()> | <jzczhz()> |
<alpha()> |
<color()>
ictcp() = ictcp([from <color>]?
[<percentage> | <number> | none]
[<percentage> | <number> | none]
[<percentage> | <number> | none]
[ / [<alpha-value> | none] ]? )
jzazbz() = jzazbz([from <color>]?
[<percentage> | <number> | none]
[<percentage> | <number> | none]
[<percentage> | <number> | none]
[ / [<alpha-value> | none] ]? )
jzczhz() = jzczhz([from <color>]?
[<percentage> | <number> | none]
[<percentage> | <number> | none]
[<hue> | none]
[ / [<alpha-value> | none] ]? )
5. HDR色のヘッドルームによるパラメータ化: hdr-color() 関数
hdr-color() 関数は、HDRヘッドルームに基づいて自動的に値が計算される色の範囲を指定できます。
これは、2つの<color>値を、 それぞれHDRヘッドルームのレベルとともに指定することで実現します。 (2つのヘッドルーム値は異なる必要があります)。 実際の値は、現在のHDRヘッドルーム量に基づいて これら2つの色の間を補間して計算されます。 詳細は § 5.1 ヘッドルームに基づく色の補間 で説明します。
プライバシー保護のため、実際に計算された色や 実際のHDRヘッドルームの値は公開されません。 これはフィンガープリント防止のためです。
その構文は次の通りです:
hdr-color() = color-hdr([ <color> && <number [0,∞]>? ]#{2})
color-hdr ( color ( rec2100-linear0.9 1.0 0.8 ) 0 , color ( rec2100-linear1.8 2.0 1.5 ) 2 );
HDRヘッドルーム <= 0、つまりSDRディスプレイの場合、この色は次のように表示されます:
color ( rec2100-linear0.9 1.0 0.8 )
HDRヘッドルーム >= 2 のディスプレイでは、
color ( rec2100-linear1.8 2.0 1.5 ) 2 );
ヘッドルームが 0 〜 2 の間の場合、色は補間されます。例として、 HDRヘッドルーム 1 のディスプレイの場合は:
X = 243.664, Y = 275.713, Z = 244.000
色は 絶対D65 CIE XYZ で補間されます。
これは xyz-d65 から、各成分に 203 を掛けることで導出されます [Rpt_BT.2408]。 これは、相対単位(白のY=1)から絶対単位(cd/m²、ニットとも呼ばれる)への変換です。 サンプルコード では、この定数を Yw(HDR基準白の輝度)としています。
5.1. ヘッドルームに基づく色の補間
ヘッドルーム H1 の色 c1 とヘッドルーム H2 の色 c2 を ヘッドルーム H で補間し、結果カラ cxyz を得るには、
-
c1xyz を c1 を 絶対D65 CIE XYZ に変換したものとする
-
c2xyz を c2 を 絶対D65 CIE XYZ に変換したものとする
-
w1 = clamp((H - H2) / (H1 - H2), 0, 1)
-
w2 = clamp((H - H1) / (H2 - H1), 0, 1) (なお、 w2 は 1 - w1 です)
-
eps = 0.001
-
cxyz = Array(3)
-
i が 0 〜 2 の間: cxyz[i] = pow(c1xyz[i] + eps, w1 ) * pow(c2xyz[i] + eps, w2 ) - eps
Note: eps は0除算を防ぐためのものであり、とくにSDR色で黒に近い場合の補間で重要です。
c1xyz =[ 173.156 , 195.260 , 178.003 ] c2xyz =[ 342.883 , 389.315 , 334.467 ] w1 =0.5 w2 =0.5 cxyz =[ 243.664 , 275.713 , 244.000 ]
c1xyz =[ 156.285 , 188.337 , 28.015 ] c2xyz =[ 3776.1434 , 4362.407 , 1577.913 ] w1 =0.571 w2 =0.429 cxyz =[ 611.911 , 724.180 , 157.650 ]
c1はすべてのヘッドルーム値 <= 0.5 でそのまま使われ、c2はヘッドルーム値 >= 4 でそのまま使われることに注意してください。
6. デバイス非依存HDR色
CSS Color 4 § 9 デバイス非依存色: CIE LabとLCH、OklabおよびOKLChがデバイス非依存SDR色を指定できるようにするのと同様に、 この仕様ではデバイス非依存HDR色を指定できます。
6.1. ICtCp(アイシーティーシーピー)の紹介
このセクションは規範的ではありません。
ICTCP色空間はCIE Labより知覚的な均一性に優れており、 高ダイナミックレンジ(HDR)やワイドカラ―ガマット(WCG)画像向けの 映像・デジタル写真システムのカラーパイプラインの一部として利用されています。
TとPの下付き文字は、 人間の視覚系のトリタノープ(黄-青軸)および プロタノープ(赤-緑軸)の対立色軸を示しています。 下付き文字を省いて ICtCp と表記されることが多いです。
ICTCPは Dolby Laboratories により、EbnerとFairchildのIPT色空間[Development_ITP]をもとに開発され[What_is_ICtCp]、 [Rec_BT.2100]で Constant Intensity ICTCPシグナルフォーマットとして定義されています。 YCbCrの置換を意図しています[Perrin]。
ヒトの視覚LMS錐体プライマリがベースであり、 Hunt-Pointer-Estevez(HPE)XYZ→LMS変換が使われ、 D65ホワイトポイントへ正規化されます。 その後、BT.2020 RGBのガマットの凹みを緩和するために 4%クロストーク行列が適用されます[What_is_ICtCp]。 これにより、補間誤差が低減し、一定の色相線やJND(MacAdam楕円)の均一性も向上します。
Labが主に低輝度・反射色で評価されているのに対し、 ICTCPは高彩度(WCG)・自己発光・高輝度(HDR)色で評価されています。
そのため、HDRカラーデルタE測定(deltaE ITP)やSDR/HDR混合時のガマットマッピングにも適しています。
両カラースペースの非常に広い原色赤:
color ( rec2100-pq0.58 0 0 ) /* ictcp(44.6% -0.129 0.399) */ color ( rec20201 0 0 ) /* ictcp(44.7% -0.130 0.399) */
ICTCPで2つの色は非常に近く、deltaE ITPは0.487となり、視覚的に差は認められません。
これらの色はsRGB「赤」とは大きく異なります:
color ( rec2100-pq0.58 0 0 ) /* ictcp(44.6% -0.129 0.399) */ red/* ictcp(42.8% -0.116 0.279) */
deltaE ITPは87.7で、見た目でまったく異なる色となります。
6.2. Jzazbz と JzCzhz の紹介
このセクションは規範的ではありません。
Jzazbz色空間[Safdar-PUCS]およびその極座標形式JzCzhzは、 BT.2020のような広色域をより知覚的に均一に表現し、 HDR色など広域の明度を正確に予測し、 明度・彩度・色相間の相互依存を最小化することを目指して設計されました。 特に色相均一性に優れており、CAM16-UCSよりも優れています [Safdar-PUCS]。
CIE Labは[0%, 100%]範囲の明度(HDR基準白に対する相対値)を使い、 Oklabも[0,1.0]範囲の明度(1.0がHDR基準白)を利用します。 これに対し、JzazbzのJz軸は[0,1.0]範囲ですが、 エンコード方式は パーセプチュアルクォンタイザー(PQ)に似ており、 13ストップ以上のダイナミックレンジを表現できます。
6.3. ICtCp
ICtCp色空間は3つの数値パラメータを受け付けます。 Iは強度(LabのLに似るが最大10,000 cd/m2まで)を表し、 CTとCPは 黄青軸(トリタノープ)・赤緑軸(プロタノープ)の反対色軸です(Labのb・aに類似)。
この色空間の特徴:
| x | y | |
| 白色点 | D65 | |
|---|---|---|
| トランスファ関数 | パーセプチュアルクォンタイザー | |
| 白の輝度 | 203 cd/m² | |
| ピーク白輝度 | 10,000 cd/m² | |
| 黒の輝度 | 0.001 cd/m² | |
| 画像状態 | ディスプレイ参照 | |
| パーセンテージ | I, Ct, Cp で指定可 | |
| パーセント基準範囲 | I: 0% = 0.0, 100% = 1.0 Ct, Cp: -100% = -0.5, 100% = 0.5 | |
[Rec_BT.2100]は ICTCPをリニアBT.2100 RGB から変換して定義していますが、 変換はLMS経由であるため、他の色空間も XYZ→LMS変換を経て表現できます [What_is_ICtCp]。 サンプルコードもこの方法を使います。
ictcp(0.58069 0 0)
relative color 構文内のictcp()関数では、許可される成分キーワードは次のとおりです:
-
i は <number> であり、 元の色のI(明度) を必要に応じてictcpへ変換した後の値です。 1.0 は100%に相当します。
-
ct および cp は <number> であり、 元の色のct,Cp軸 を必要に応じてictcpへ変換した後の値です。 0.5は100%、-0.5は-100%に相当します。
6.4. Jzazbz
Jzazbz色空間は3つの数値パラメータを受け付けます。 Jzは明度(LabのLに類似)、 azおよびbzは赤緑軸および黄青軸 (Labのa, bに類似)を表します。
Jzazbz色空間は次の特徴を持ちます:
| x | y | |
| 白色点 | D65 | |
|---|---|---|
| トランスファ関数 | パーセプチュアルクォンタイザー | |
| ピーク白輝度 | 10,000 cd/m² | |
| 黒輝度 | 0.001 cd/m² | |
| 画像状態 | ディスプレイ参照 | |
| パーセンテージ | Jz, az, bzで指定可 | |
| パーセント基準範囲 | Jz: 0% = 0.0, 100% = 1.0 az, bz: -100% = -0.21, 100% = 0.21 | |
Labと異なり、D65白色点が使われることに注意してください。 そのため、ほとんどのRGB空間 (D65白色点を使うもの)では 色順応処理は不要です。
XYZ-D65とJzazbzの変換サンプルコードを提供しています。
jzazbz(0.22207 -0.00016 -0.00012)
relative color構文内のjzazbz()関数で 許可される成分キーワードは次の通りです:
-
jは<number>型で、 元の色のJz(明度) を必要に応じてjzazbzへ変換した値です。 1.0 が100%に相当します。
-
aおよびbは<number>型で、 元の色のaz, bz軸 を必要に応じてjzazbzへ変換した値です。 0.21 が 100%、-0.21 が -100%に相当します。
6.5. JzCzhz
LCH(Labの極座標表現)に類似し、JzCzhzはJzazbzの極座標形です。
JzはJzazbzの値と同じで明度を示し、 Czは彩度(クロマ)を、 hzは色相角を表します。 色相角は正のaz軸から正のbz軸への方向で測定されます。
次の特徴があります:
| x | y | |
| 白色点 | D65 | |
|---|---|---|
| トランスファ関数 | パーセプチュアルクォンタイザー | |
| ピーク白輝度 | 10,000 cd/m² | |
| 黒輝度 | 0.001 cd/m² | |
| 画像状態 | ディスプレイ参照 | |
| パーセンテージ | Jz, Czで指定可 | |
| パーセント基準範囲 | Jz: 0% = 0.0, 100% = 1.0 Cz: 0% = 0.0, 100% = 0.26 | |
| 無効な色相ε | Cz <= 0.0000026 | |
jzazbz(0.17542 -0.1179 0.1092)
同じ色の極座標表現はこちら:
jzczhz(0.17542 0.1614 132.50)
relative color構文内のjzczhz()関数で 許可される成分キーワードは次の通りです:
-
jは<number>型で、 元の色のJz(明度) を必要に応じてjzczhzへ変換した値です。 100が100%に相当します。
-
cは<number>型で、 元の色のCz(クロマ) を必要に応じてjzczhzへ変換した値です。 0.26が100%に相当します。
-
hは<number>型で、 元の色のhz(色相、度単位) を必要に応じてjzczhzへ変換した値で、 [0, 360]範囲に正規化されます。90は90度に相当します。
6.5.1. Jzazbz色をJzCzhz色へ変換
JzCzhzへの変換は簡単です:
- hz = atan2(bz, az) // 度へ変換すること!
- Cz = sqrt(az^2 + bz^2)
- Jzは同じ
加えて、実用的なコードは Cz がε未満の場合 none 値を返すべきです。
6.5.2. JzCzhz色をJzazbz色へ変換
Jzazbzへの変換は簡単です:
- az = Cz cos(H) // まずラジアンに変換すること!
- bz = Cz sin(H) // まずラジアンに変換すること!
- Jzは同じ
また、実用的なコードは hz がnone の値であるかどうかをチェックしてください。
7. あらかじめ定義されたカラースペースとカスタムカラースペースの指定: color() 関数
color() 関数は 特定のカラースペースで (他のカラ―関数のほとんどが動作する暗黙のsRGBではなく)色を指定できます。
この仕様はcolor()関数を拡張し、 HDR用あらかじめ定義されたカラースペースを CSS Color 4 § 10. あらかじめ定義されたカラースペース の規定SDRスペースや CSS Color 5 § 4 相対色の相対カラー構文に加え利用できます。
構文は次の通りです:
<predefined-rgb> = srgb | srgb-linear | display-p3 | display-p3-linear | a98-rgb | prophoto-rgb | rec2020 | rec2100-pq | rec2100-hlg | rec2100-linear
8. HDR用あらかじめ定義されたカラースペース:
CSS Color 4で定義されているSDR カラースペースに加えて、以下のHDRカラースペースが color関数で利用するために定義されています。
これら新しいカラースペースの値のシリアライズは、CSS Color 4 § 15. <color>値のシリアライズ の記述と同一です。
8.1. rec2100-pq
rec2100-pq [Rec_BT.2100] カラースペースは3つの数値パラメータ(赤・緑・青チャンネル)を受け付け、 実際のビット深度(各成分10または12ビット)によらず各値の有効範囲は[0, 1]です。
パーセプチュアルクォンタイザー(PQ)エレクトロオプティカルトランスファ関数が使われます [SMPTE-ST-2084],[Rec_BT.2100]。 PQは基準視聴条件として、 画面の周囲が5 cd/m²であることを前提とします。
ITU-R 2100は4Kおよび8K HDRテレビで利用されます。
主な特徴は以下のとおりです(ディスプレイの原色は[Rec.2020]と同じ):
| x | y | |
| 赤の色度 | 0.708 | 0.292 |
|---|---|---|
| 緑の色度 | 0.170 | 0.797 |
| 青の色度 | 0.131 | 0.046 |
| 白の色度 | D65 | |
| トランスファ関数 | パーセプチュアルクォンタイザー | |
| 白の輝度 | 203 cd/m² | |
| ピーク白輝度 | 10,000 cd/m² | |
| 黒の輝度 | ≤ 0.005 cd/m² | |
| 画像状態 | ディスプレイ参照 | |
| パーセンテージ | R, G, Bで指定可 | |
| パーセント基準範囲 | R, G, B: 0% = 0.0, 100% = 1.0 | |
非基準視聴環境下のナローPQビデオ、 または任意の環境下でのHLGの場合は、 黒レベルを [Rec_BT.814] 付属書のPLUGEテスト信号と手順で調整する必要があります。 CSSでのPQ値(ワイドレンジ)は、黒がコードポイント0に対応します。
color(rec2100-pq 1.0 1.0 1.0);
color(rec2100-pq 0.58 0.58 0.58);
この色はミディアムグレー(18%反射率グレー)カード、17 cd/m²の輝度に相当します。
color(rec2100-pq 0.34 0.34 0.34)
他の例(sRGB赤・緑・青やP3の各主色のエンコードなど)を追加すること
リニアライトRGB信号は以下のようにPQエンコードされます。 PQでエンコードできる最大値(ピーク小面積白)は10,000 cd/m²です。 HDR基準白は203 cd/m²です[Rpt_BT.2408]。
var Er; // 赤・緑・青のいずれかの成分。SDRでは[0, 1]、HDRでは[0, 70程度] var Yw= 203 ; // ディフューズホワイトの輝度、cd/m² var x= Er* Yw/ 10000 ; // ピーク白の輝度は10,000 cd/m²。 const n= 2610 / ( 2 ** 14 ); const m= 2523 / ( 2 ** 5 ); const c1= 3424 / ( 2 ** 12 ); const c2= 2413 / ( 2 ** 7 ); const c3= 2392 / ( 2 ** 7 ); xPQ= ((( c1+ ( c2* ( x** n))) / ( 1 + ( c3* ( x** n)))) ** m);
xPQは「ガンマ補正済み」(OETF適用済み)の信号[0,1]です。
PQエンコード値をリニアライトに変換する場合は次のようになります:
var xPQ; // PQエンコード済みの赤・緑・青成分、[0, 1] const ninv= ( 2 ** 14 ) / 2610 ; const minv= ( 2 ** 5 ) / 2523 ; const c1= 3424 / ( 2 ** 12 ); const c2= 2413 / ( 2 ** 7 ); const c3= 2392 / ( 2 ** 7 ); var x= (((( Math. max((( xPQ** minv) - c1), 0 )) / ( c2- ( c3* ( xPQ** minv)))) ** ninv); var Yw= 203 ; // ディフューズホワイトの輝度、cd/m² var Ea= x* 10000 ; // 輝度 [0, 10,000] var Er= x* 10000 / Yw; // ディフューズホワイトに対する相対輝度 [0, 70程度]
8.2. rec2100-hlg
rec2100-hlg [Rec_BT.2100] カラースペースは3つの数値パラメータ(赤・緑・青チャンネル)を受け付け、 実際のビット深度(各成分10または12ビット)によらず各値の有効範囲は[0, 1]です。
ハイブリッドログガンマ(HLG)エレクトロオプティカルトランスファ関数が使われます [ARIB_STD-B67],[Rec_BT.2100]。 HLGはさまざまな明るさや視聴環境で使用でき、 全体的な明るさはユーザーが調整可能です。 0.75は「ディフューズ」または「メディアホワイト」を表し、 「18%反射率グレー」カードは0.38です[Rec_BT.2390]。
主な特徴は以下のとおりです(ディスプレイの原色は[Rec.2020]と同じ):
| x | y | |
| 赤の色度 | 0.708 | 0.292 |
|---|---|---|
| 緑の色度 | 0.170 | 0.797 |
| 青の色度 | 0.131 | 0.046 |
| 白の色度 | D65 | |
| トランスファ関数 | ハイブリッドログガンマ | |
| 白の輝度 | 視聴条件に依存 | |
| ピーク白輝度 | 基準白の12倍 | |
| 黒の輝度 | 基準白による、本文参照 | |
| 画像状態 | シーン参照 | |
| パーセンテージ | R, G, Bで指定可 | |
| パーセント基準範囲 | R, G, B: 0% = 0.0, 100% = 1.0 | |
ナローHLGビデオ(任意環境)では、 黒レベルは [Rec_BT.814] 付録4のPLUGEテスト信号と手法で調整する必要があります。
CSSでのHLG値(ワイドレンジ)では黒がコードポイント0に対応します。
color(rec2100-hlg 0.75 0.75 0.75);
この色は26〜104cd/m²の中間グレーです。
color(rec2100-hlg 0.38 0.38 0.38)
リニアライトRGB信号は以下のようにHLGエンコードされます[Rec_BT.2390]:
var E; // 赤・緑・青のいずれかの成分、[0, 1] const a= 0.17883277 ; const b= 0.28466892 ; // 1 - (4 * a) const c= 0.55991073 ; // 0.5 - a * Math.log(4 *a) // 負値処理 var sign= E< 0 ? - 1 : 1 ; var abs= Math. abs( E); if ( abs<= 1 / 12 ) { Edash= sign* Math. sqrt( 3 * abs); } else { Edash= a* Math. log( 12 * E- b) + c; }
Edashは「ガンマ補正済み」(OETF適用済み)の信号です。
逆変換(HLGエンコード→リニアライト)は次の通りです[Rec_BT.2390]:
var Edash; // エンコード済みの赤・緑・青成分、[0, 1] const a= 0.17883277 ; const b= 0.28466892 ; // 1 - (4 * a) const c= 0.55991073 ; // 0.5 - a * Math.log(4 *a) if ( Edash<= 0.5 ) { E= ( Edash** 2 ) / 3 ; } else { E= ( Math. exp(( Edash- c) / a) + b) / 12 ; }
8.3. rec2100-linear
rec2100-linear [Rec_BT.2100] カラースペースは3つの数値パラメータ(赤・緑・青チャンネル)を受け付け、 実際のビット深度(各成分10または12ビット)によらず、名目上の範囲は[0, 1]です。
赤・緑・青をすべて1.0にした色は 輝度203cd/m²のHDR基準白を表します。
color ( rec2100-linear1 1 1 )
color(rec2100-linear 1 1 1)
リニアライトのエレクトロオプティカルトランスファ関数が使われます。
主な特徴は以下のとおりです(ディスプレイの原色は[Rec.2020]と同じ):
| x | y | |
| 赤の色度 | 0.708 | 0.292 |
|---|---|---|
| 緑の色度 | 0.170 | 0.797 |
| 青の色度 | 0.131 | 0.046 |
| 白の色度 | D65 | |
| トランスファ関数 | リニア | |
| 白の輝度 | 203 cd/m² | |
| ピーク白輝度 | 10,000 cd/m² | |
| 黒の輝度 | 0.001 cd/m² | |
| 画像状態 | ディスプレイ参照 | |
| パーセンテージ | R, G, Bで指定可 | |
| パーセント基準範囲 | R, G, B: 0% = 0.0, 100% = 1.0 | |
9. SDRとHDRコンテンツの合成
合成はCIE XYZ空間で行うべきです。 これはリニアライトでガマット制限がないためです。 実装ではリニアライトRGB空間で合成しても構いませんが、 ガマット外値(負や100%超)をクリッピングやガマットマッピングせず、 最終的なデバイス空間への転送まで正しく扱う必要があります。
HLGトランスファ関数を用いるHDRでは、 SDRのHDR基準白を 75%HLG値で表示する輝度と 同じ輝度にマッピングしなければなりません。[SMPTE-ST-2084]
詳細はITU Rpt_BT.2408-0 [Rpt_BT.2408] の表3・4も参照。
PQトランスファ関数を用いるHDRでは、 SDRのHDR基準白を PQ値58%で表示する輝度、203cd/m²と 同じ輝度にマッピングすべきです。[SMPTE-ST-2084]
ただし実装では、非基準視聴条件も考慮する色再レンダリング処理を含めても構いません。
10. <color> 値のシリアライズ
10.1. color() 関数の値のシリアライズ
このセクションは CSS Color 4 § 15.5 color()関数値のシリアライズを拡張します。
color()値のシリアライズ形式は、 算出値に基づき、 color()形式を使います。 関数名およびカラースペース名はASCII小文字、
成分値は10進数で、 <number>としてシリアライズされます。 各成分、およびカラースペース名と先頭成分の間は ASCIIスペース" "で区切ります。
あらかじめ定義されたHDRカラースペースの 最低往復精度は下表の通りです:
| HDRカラースペース | 最低ビット数 |
|---|---|
| rec2100-pq, rec2100-hlg | 10 |
| rec2100-linear, jzazbz, jzczhz, ictcp | 16 |
(内部保存にはコンポーネントごと16bit, half-float, float推奨)、 値は+∞方向丸め、 切り捨て不可です。
11. 色変換のサンプルコード
このセクションは規範的ではありません。
テスト
このセクションは規範的ではないため、テストは必要ありません。
明確さのため、行列の乗算にはライブラリを使用します。 (すべての乗算と加算をインラインで書くより可読性が高くなります)。 行列は列優先 順序(column-major order)です。
このコードはまた、CSS Color 4 § 18 色変換のサンプルコードの すべての変換コードが利用可能であることを前提とします。
Jzazbzで使用されるLMSは ICtCpで使用されるものとは異なるため、 正しい方を使用するよう注意してください!
11.1. rec2100-linear のサンプルコード
BT.2020 と BT.2100 のカラースペースは 同じRGB原色と白色点を使用し、 どちらもHDR基準白をコンポーネント値 1.0 に配置します。
// これらの関数は CSS Color 4 の色変換関数を使用します function XYZ_to_lin_2100( XYZ) { // D65 の XYZ 配列をリニアライト BT.2100 RGB に変換 // [0,0,0] が黒、[1,1,1] がメディアホワイト // 1 を超えるコンポーネント値は HDR 色を示す return XYZ_to_lin_2020( XYZ); } function lin_2100_to_XYZ( RGB) { // リニアライト BT.2100 RGB の配列を // D65 XYZ に変換 return lin_2020_to_XYZ( RGB); }
11.2. rec2100-pq のサンプルコード
function XYZ_to_pq_2100( XYZ) { // D65 の XYZ 配列を PQ エンコード BT.2100 RGB に変換 // [0,0,0] が黒、[1,1,1] が 10,000 cd/m^2 の白 // メディアホワイトは [0.5807,0.5807,0.5807](有効数字4桁) let linRGB= XYZ_to_lin_2100( XYZ); return pq_encode( linRGB); } function pq_2100_to_XYZ( RGB) { // PQ エンコード BT.2100 RGB の配列を // D65 XYZ に変換 let linRGB= pq_decode( RGB); return lin_2100_to_XYZ( linRGB); } function pq_encode( RGB) { const Yw= 203 ; // メディアホワイトの絶対輝度(cd/m²) const n= 2610 / ( 2 ** 14 ); const m= 2523 / ( 2 ** 5 ); const c1= 3424 / ( 2 ** 12 ); const c2= 2413 / ( 2 ** 7 ); const c3= 2392 / ( 2 ** 7 ); // 入力:範囲 [0,1] の PQ エンコード成分 // 出力:メディアホワイト相対のリニアライト return RGB. map( function ( val) { let x= Math. max( val* Yw/ 10000 , 0 ); // ピーク白の絶対輝度は 10,000 cd/m² let num= ( c1+ ( c2* ( x** n))); let denom= ( 1 + ( c3* ( x** n))); return (( num/ denom) ** m); }); } function pq_decode( RGB) { const Yw= 203 ; // メディアホワイトの絶対輝度(cd/m²) const ninv= ( 2 ** 14 ) / 2610 ; const minv= ( 2 ** 5 ) / 2523 ; const c1= 3424 / ( 2 ** 12 ); const c2= 2413 / ( 2 ** 7 ); const c3= 2392 / ( 2 ** 7 ); // 入力:範囲 [0,1] の PQ エンコード成分 // 出力:メディアホワイト相対のリニアライト return RGB. map( function ( val) { let x= (( Math. max((( val** minv) - c1), 0 ) / ( c2- ( c3* ( val** minv)))) ** ninv); return ( x* 10000 / Yw); // メディアホワイト相対輝度 [0, 約70] }); }
11.3. rec2100-hlg のサンプルコード
function XYZ_to_hlg_2100( XYZ) { // D65 の XYZ 配列を HLG エンコード BT.2100 RGB に変換 // [0,0,0] が黒、[0.75,0.75,0.75] がメディアホワイト let linRGB= XYZ_to_lin_2100( XYZ); return hlg_encode( linRGB); } function hlg_2100_to_XYZ( RGB) { // PQ エンコード BT.2100 RGB の配列を // D65 XYZ に変換 let linRGB= hlg_decode( RGB); return lin_2100_to_XYZ( linRGB); } function hlg_encode( RGB) { const a= 0.17883277 ; const b= 0.28466892 ; // 1 - (4 * a) const c= 0.55991073 ; // 0.5 - a * Math.log(4 *a) const scale= 3.7743 ; // 18% グレーを HLG 0.38 に、メディアホワイトを 0.75 に return RGB. map( function ( val) { // まずスケールして、リニアライトのメディアホワイトを 1/3 に置く val/= scale; // HLG の OETF // ITU-R BT.2390-10 p.23 // 6.1 The hybrid log-gamma opto-electronic transfer function (OETF) if ( val<= 1 / 12 ) { return spow( 3 * val, 0.5 ); } return a* Math. log( 12 * val- b) + c; }); } function hlg_decode( RGB) { const a= 0.17883277 ; const b= 0.28466892 ; // 1 - (4 * a) const c= 0.55991073 ; // 0.5 - a * Math.log(4 *a) const scale= 3.7743 ; // 18% グレーを HLG 0.38 に、メディアホワイトを 0.75 に return RGB. map( function ( val) { // まず HLG の EOTF // ITU-R BT.2390-10 p.30 // 6.3 The hybrid log-gamma electro-optical transfer function (EOTF) // その後 3 倍してメディアホワイトを 1.0 に if ( val<= 0.5 ) { return ( val** 2 ) / 3 * scale; } return (( Math. exp(( val- c) / a) + b) / 12 ) * scale; }); } function spow( base, exp) { let sign= base< 0 ? - 1 : 1 ; return sign* ( Math. abs( base) ** exp); }
11.4. jzazbz のサンプルコード
上で定義した符号付きべき(spow)関数を使用します。
function XYZ_to_Jzazbz( XYZ) { // D65 の XYZ 配列を JzAzBz に変換 // [0,0,0] が黒で、 // メディアホワイトは [0.2220, -0.00016, -0.0001] const Yw= 203 ; // メディアホワイトの絶対輝度 const M= [ [ 0.41478972 , 0.579999 , 0.0146480 ], [ - 0.2015100 , 1.120649 , 0.0531008 ], [ - 0.0166008 , 0.264800 , 0.6684799 ], ]; const b= 1.15 ; const g= 0.66 ; // まず XYZ をメディアホワイト相対ではなく絶対値に // PQ の最大輝度は 10,000 cd/m² // BT.2048 によればメディアホワイトは Y=203 cd/m² let [ Xa, Ya, Za] = XYZ. map( v=> v* Yw); // つぎに X と Y を調整して、青の曲率を最小化 let Xm= b* Xa- ( b- 1 ) * Za; let Ym= g* Ya- ( g- 1 ) * Xa; // LMS 錐体領域へ let LMS= multiplyMatrices( M, [ Xm, Ym, Za]); return LMStoJzazbz( LMS); } function LMStoJzazbz( LMS) { const M= [ [ 0.5 , 0.5 , 0 ], [ 3.524000 , - 4.066708 , 0.542708 ], [ 0.199076 , 1.096799 , - 1.295875 ], ]; const c1= 3424 / 2 ** 12 ; const c2= 2413 / 2 ** 7 ); const c3= 2392 / 2 ** 7 ; const n= 2610 / 2 ** 14 ; const p= ( 1.7 * 2523 ) / 2 ** 5 ; // 通常の PQ に対して 1.7 倍のスケール const d= - 0.56 ; const d0= 1.6295499532821566e-11 ; // 黒を 0 に戻すための微小シフト // LMS を PQ 符号化 let PQLMS= ( LMS. map( function ( val) { let num= c1+ c2* spow(( val/ 10000 ), n); let denom= 1 + c3* spow(( val/ 10000 ), n); return spow(( num/ denom), p); }) ); // Iz, az, bz を計算 let [ Iz, az, bz] = multiplyMatrices( M, PQLMS); // Iz から Jz を導出 let Jz= (( 1 + d) * Iz) / ( 1 + d* Iz) - d0; return [ Jz, az, bz]; } function Jzazbz_to_XYZ( Jzazbz) { // JzAzBz の配列を D65 XYZ に変換 // [0,0,0] が黒で、 // メディアホワイトは [0.2220, -0.00016, -0.0001] const b= 1.15 ; const g= 0.66 ; const M= [ [ 1.9242264357876067 , - 1.0047923125953657 , 0.037651404030618 ], [ 0.35031676209499907 , 0.7264811939316552 , - 0.06538442294808501 ], [ - 0.09098281098284752 , - 0.3127282905230739 , 1.5227665613052603 ], ]; let LMS= Jzazbz_to_LMS( Jzazbz); // 調整済みの絶対 XYZ let [ Xm, Ym, Za] = multiplyMatrices( LMS, M); // X と Y の調整を戻し、メディアホワイト相対の D65 XYZ を得る let Xa= ( Xm+ ( b- 1 ) * Za) / b; let Ya= ( Ym+ ( g- 1 ) * Xa) / g; return [ Xa, Ya, Za]; } function Jzazbz_to_LMS( Jzazbz) { const d= - 0.56 ; const d0= 1.6295499532821566e-11 ; const c1= 3424 / 2 ** 12 ; const c2= 2413 / 2 ** 7 ; const c3= 2392 / 2 ** 7 ; const pinv= 2 ** 5 / ( 1.7 * 2523 ); const M= [ [ 1 , 0.13860504327153927 , 0.05804731615611883 ], [ 1 , - 0.1386050432715393 , - 0.058047316156118904 ], [ 1 , - 0.09601924202631895 , - 0.81189189605603900 ], ]; let [ Jz, az, bz] = Jzazbz; let Iz= ( Jz+ d0) / ( 1 + d- d* ( Jz+ d0)); // LMS 錐体領域へ let PQLMS= multiplyMatrices([ Iz, az, bz], M); // PQ 符号化からリニアライト LMS に変換 let LMS= ( PQLMS. map( function ( val) { let num= c1- spow( val, pinv); let denom= c3* spow( val, pinv) - c2; let x= 10000 * spow( num/ denom, ninv); return x; // メディアホワイト相対輝度 [0, 約70] }) ); return LMS; }
11.5. ICtCp のサンプルコード
まず rec2100-linear に変換することを要求せず、 (これは[Rec_BT.2100]で定義されている手順) ほかの色変換コードとの互換性のため、 このサンプルコードでは絶対 CIE XYZ から直接進めます。
4% のクロストーク行列と色相回転も XYZ から LMS へのステップに組み込み、 3つの別ステップとして適用しません。
最終結果は同一で、単に手順が少ないだけです。
function XYZ_to_ICtCp( XYZ) { // D65 XYZ の配列を ICtCp に変換 // 以下の行列には 4% のクロストーク成分が含まれ、 // Dolby の "What is ICtCp" 論文の手順に基づく const M= [ [ 0.3592832590121217 , 0.6976051147779502 , - 0.0358915932320290 ], [ - 0.1920808463704993 , 1.1004767970374321 , 0.0753748658519118 ], [ 0.0070797844607479 , 0.0748396662186362 , 0.8433265453898765 ], ]; let LMS= multiplyMatrices( M, XYZ. map( v=> v* Yw)); return LMStoICtCp( LMS); } function LMStoICtCp( LMS) { const c1= 3424 / 4096 ; const c2= 2413 / 128 ; const c3= 2392 / 128 ; const m1= 2610 / 16384 ; const m2= 2523 / 32 ; // この行列には Ebner の LMS 係数、回転、 // および [-0.5, 0.5] 範囲へのスケーリングが含まれる // 有理係数は Fröhlich p.97 と ITU-R BT.2124-0 pp.2-3 に基づく const M= [ [ 2048 / 4096 , 2048 / 4096 , 0 ], [ 6610 / 4096 , - 13613 / 4096 , 7003 / 4096 ], [ 17933 / 4096 , - 17390 / 4096 , - 543 / 4096 ], ]; // PQ の EOTF を適用 // [0, 10,000] が [0, 1] にマップされるようスケーリング // 分母に「1 +」があるため 0 除算は起こらない let PQLMS= LMS. map( function ( val) { let num= c1+ ( c2* (( val/ 10000 ) ** m1)); let denom= 1 + ( c3* (( val/ 10000 ) ** m1)); return ( num/ denom) ** m2; }); // Y'C'bC'r 互換のための回転を含む LMS→IPT 変換 return multiplyMatrices( M, PQLMS); } function ICtCp_to_XYZ( ICtCp) { // ICtCp を絶対 D65 XYZ 配列に変換 const M= [ [ 2.0701522183894223 , - 1.3263473389671563 , 0.2066510476294053 ], [ 0.3647385209748072 , 0.6805660249472273 , - 0.0453045459220347 ], [ - 0.0497472075358123 , - 0.0492609666966131 , 1.1880659249923042 ], ]; let LMS= ICtCptoLMS( ICtCp); return multiplyMatrices( M, LMS); } function ICtCptoLMS( ICtCp) { const c1= 3424 / 4096 ; const c2= 2413 / 128 ; const c3= 2392 / 128 ; const im1= 16384 / 2610 ; const im2= 32 / 2523 ; const M= [ [ 0.9999999999999998 , 0.0086090370379328 , 0.1110296250030260 ], [ 0.9999999999999998 , - 0.0086090370379328 , - 0.1110296250030259 ], [ 0.9999999999999998 , 0.5600313357106791 , - 0.3206271749873188 ], ]; let PQLMS= multiplyMatrices( M, ICtCp); // PQ 符号化を元に戻す(BT.2124-0 付録2 Conversion 3) let LMS= PQLMS. map( function ( val) { let num= Math. max(( val** im2) - c1, 0 ); let denom= ( c2- ( c3* ( val** im2))); return 10000 * (( num/ denom) ** im1); }); return LMS; }
11.6. hdr-color() のサンプルコード
function hdrColor( col1, H1, col2, H2, H) { // col1, col2 は絶対 XYZ の 2 色を表す配列 // H1, H2 は各色のヘッドルーム(ストップ単位、すなわち対数スケール、0 = SDR) // H は利用可能なヘッドルーム // まずヘッドルームが異なることを確認 if ( H1== H2) return 0 ; let w1= clamp(( H- H2) / ( H1- H2), 0 , 1 ); let w2= clamp(( H- H1) / ( H2- H1), 0 , 1 ); let eps= 0.001 ; let cxyz= Array( 3 ); for ( let i= 0 ; i< 3 ; i++ ) { cxyz[ i] = Math. pow( c1xyz[ i] + eps, w1) * Math. pow( c2xyz[ i] + eps, w2) - eps; } return cxyz; } const clamp= ( n, min, max) => Math. min( Math. max( n, min), max)
12. ΔEITP 色差のサンプルコード
このセクションは規範的ではありません。
テスト
このセクションは規範的ではないため、テストは必要ありません。
ΔEITP [Rec_BT.2124] 色差指標は、 HDR または SDR/HDR 混在の文脈において、 2 つのディスプレイ参照色の 知覚的な色差を測るために使用できます。 たとえばディスプレイのキャリブレーションや ガマット/トーンマッピングなどです。
これは ICtCp 色空間におけるユークリッド距離で、 ΔEITP が 1.0 のとき ちょうど知覚可能な差を 1 とするようスケーリングされています。
// deltaE ITP を計算 // スケーリングされた二乗和平方根 // ITU-R BT.2124-0 付録 1 /** * @param {number[]} reference - ICtCp の配列: I は 0..1、Ct/Cp は -1..1 * @param {number[]} sample - ICtCp の配列: I は 0..1、Ct/Cp は -1..1 * @return {number} 参照色からサンプル色がどれだけ異なるか */ function deltaEITP( reference, sample) { let [ I1, Ct1, Cp1] = reference; let [ I2, Ct2, Cp2] = sample; let ΔI= I1- I2; let ΔT= 0.5 * ( Ct1- Ct2); let ΔP= Cp1- Cp2; return 720 * Math. sqrt( ΔI** 2 + ΔT** 2 + ΔP** 2 ); }
プライバシーに関する考慮事項
Web プラットフォームが HDR ヘッドルーム の数値を直接公開しない理由は、 それによって現在の視聴環境が露出し、 プライバシー侵害となるためです。
セキュリティに関する考慮事項
本ドキュメントに関してセキュリティ上の懸念は提起されていません
アクセシビリティに関する考慮事項
非常に明るい色に敏感な人がいるため、 ユーザーエージェントはユーザーの選択で最大輝度を制限できる仕組みを提供すべきです。適切な手法として、 [Rec_BT.2390] のセクション 5.4.1 制限された輝度範囲のディスプレイへのマッピング にあるトー/ニー手順が推奨されます。
dynamic-range-limit プロパティは、ユーザースタイルシートで standard または constrained に設定することもできます。
変更点
変更点(2024年12月17日の 最初の公開草案 以降)
- eps の根拠としての SMPTE-ST-2094-50 への言及を削除 (#12873, #11788)
- hdr-color がアダプティブゲインカーブに類似することを追記
- color 構文に alpha() の RCS を追加 #10689
- 補間用のカラースペースに display-p3-linear を追加 (#12596)
- deltaE ITP の作業例をいくつか追加 (#11250)
- display-p3-linear カラースペースを追加 (#12596)
- hdr-color() で使用する clamp 関数を追加
- hdr-color() のサンプルコードを追加
- eps 係数の目的を説明 (#11788)
- 2つ目の color-hdr() の作業例を追加
- 用語「Absolute D65 CIE XYZ」を定義
- color-hdr() の疑似コードを明確化し、各コンポーネントが個別に計算されることを示した (#11694)
- dynamic-range-limit-mix() を WG の決議に従い「1つ以上」に変更 (#11694)
- dynamic-range-limit-mix() の算出値について、 すべての引数が省略された場合は初期値となることを明確化 (#11678)
- color() の再定義を削除し、代わりに CSS Color 5 の定義へリンク (#11954)
- WG の決議に従い「constrained-high」を「constrained」へ戻した (#11698)
- JzCzhz のクロマに ε を定義(色相欠落時の扱い) (#11706)
- 用語「required conversion」を正しくエクスポートし、一貫して使用
- JzCzhz における誤った負のクロマ参照範囲を削除
- relative ictcp、jzazbz、jzczhz に対して RCS のコンポーネントキーワードを追加 (#11713)
- SDR のみである CSS Color 5 を指すように color() のリンクが戻ってしまうのを防止
- ICtCp の紹介(情報)セクションを追加し、定義を color() から分離 (#11713)
- CSS Color 5 に既存の重複する生成規則を削除 (#11954)
- 参照範囲を BT.2100 のガマット全体を包含するようにした (#11710)
- CSS WG の決議に従い「合計が 0 の場合は無効」という文言を削除 (#11678)
- ヘッドルームの定義として線形(倍率)ではなく対数(ストップ)を一貫して使用 (#11787)
- 「media white」ではなく推奨用語「HDR reference white」を一貫して使用
- 色補間の例を追加 (#11616)
- 補間アルゴリズムを追加 (#11616)
- ヘッドルームでパラメータ化された色の補間に関するセクションを追加 (#11616)
- WG の決議に基づき color-hdr 関数を追加。ISO 21496-1 の情報参照を追加 (#11616)
- Jzazbz のサンプルコードを追加 (#9934)
- サンプルコードに不足していた符号付きべき関数を追加
- rec2100 カラースペースのサンプルコードを追加 (#9934)
- ICtCp のサンプルコードを追加 (#9934)
- Perrin による ICtCp 論文への情報参照を追加
- 新セクション「色変換のサンプルコード」を追加 (#9934)
- Dolby のホワイトペーパー「What is ICtCp」への情報参照を追加 (#9934)
- dynamic-range-limit-mix() の文法と仕様文を明確化 (#11672)
- BT.2124 に基づく ΔEITP 色差指標を追加 (#11250)
- dynamic-range-limit について、high を no-limit に変更 (#11698)
- 記述を修正し、dynamic-range-limit-mix は 2 つ以上の値を取ることを明記 (#11694)
- 絶対/相対 HDR の概念を削除し、代わりにシーン参照・ディスプレイ参照を強調。 media white をアンカーし、カラーの再レンダリングを許容 (#10460)
- 「media white」をより明確に定義
- 解説的な内容を導入セクションに集約