昨天那張全鏈路總表的最後幾列,有兩格我用一句話帶過去就跑了:ProfileToneCurve 那一列的「定義來源」欄寫的是規格未定義行為,HueSatMap 那一列的「是否可逆」欄寫的是。整條 DNG 色彩管線我算到 XYZ D50 就收工,可是 XYZ D50 不是任何人看得到的東西——它是 ICC 的一個中間站,一個 1990 年代印刷業留下來的座標原點。從那裡到你視網膜之間,影像還要被改寫至少四次:一次色適應、一次色調曲線、一次三維查表、一次色域映射。這四次裡面,只有第一次有數學定義,而且連那一次都有五個互不相容的標準答案。

今天把這四次拆開。同樣用真實係數逐步算,同樣附上我自己算錯或說不準的地方。最後會走到 2024–2025 年才長出來的第五次改寫:gain map。ISO 21496-1 在 2025 年正式發布,這是攝影史上第一次,有一份國際標準去規範「同一張照片的兩個不同渲染之間的關係」。它沒有規範任何一個渲染本身——這個區別是今天整篇的重點。

📖 學

座標定好:2026 年 9 月的規格現況

先確認手上的權威文件是哪幾份、有沒有過期。

DNG:最新的公開規格仍然是 Digital Negative (DNG) Specification Version 1.7.1.0,2023 年 9 月。距今三年,Adobe 沒有再發 1.8。我特地去查過有沒有 1.8,查不到任何官方公告。倒是 DNG SDK 有在動:目前最新是 1.7.1 Build 2611,2026 年 6 月 9 日——規格文字凍結、參考實作持續修 bug,這個組合本身就說明了 DNG 現在的狀態:格式定案,實作細節還在磨。(SDK 建置編號與日期我是從二手來源看到的,已標存疑;規格版本與日期則可以在 Adobe helpx 直接對到。)

Gain map:Adobe 的 Gain Map Specification 1.0 draft 15,2024 年 2 月,現在還掛在 Adobe Camera Raw 的說明頁上供下載,附一份專利授權條款。同一頁的最後更新日期是 2025 年 11 月 20 日,Gain Map Demo App 已經到 18.0 build 2389(2025 年 11 月 17 日)

ISO:ISO 21496-1:2025,《Digital photography — Gain map metadata for image conversion — Part 1: Dynamic range conversion》,第一版,16 頁。這份標準把 Apple、Adobe、Google(Android)三套原本各玩各的 gain map 編碼統一掉。Adobe 自己的說明頁現在直接寫「Gain Maps have been standardized in ISO 21496-1」。

一份 16 頁的 ISO 標準,和一份 100 多頁的 DNG 規格,管的是完全不同的兩件事。DNG 管「從感光元件到 XYZ」,ISO 21496-1 管「從一個成品渲染到另一個成品渲染」。中間那一大段——從 XYZ 到成品渲染——到 2026 年為止,沒有任何標準。 這句話是今天的骨架。

第一次改寫:色適應,五個矩陣、五個答案

DNG 的 ForwardMatrix 把你送到 XYZ D50。sRGB、Display P3、Adobe RGB、Rec. 2020 的白點全部是 D65。所以一定要做 D50 → D65 的色適應。

昨天講過 dng_sdk 用的是 Bradford。但 Bradford 只是其中一個選項。我把五個常見的錐體響應矩陣都拿來算了一次 D50 → D65 的完整適應矩陣。用的公式是標準的線性化 von Kries 形式:

A = M⁻¹ · diag( (M·w_dst) / (M·w_src) ) · M

其中 w_src = D50 = (0.9642, 1.0000, 0.8249),w_dst = D65 = (0.95047, 1.00000, 1.08883)。

Bradford(dng_sdk、ICC v4 的 media-relative 適應):

[[ 0.955553, -0.023052,  0.063254],
 [-0.028299,  1.009933,  0.021036],
 [ 0.012318, -0.020518,  1.330429]]

CAT02(CIECAM02 內建):

[[ 0.959914, -0.029297,  0.065726],
 [-0.021182,  0.998846,  0.026158],
 [ 0.001372,  0.004441,  1.312967]]

CAT16(CAM16,2017):

[[ 0.989493, -0.039941,  0.044056],
 [-0.005394,  1.006650, -0.001758],
 [-0.000405,  0.015080,  1.302146]]

Hunt–Pointer–Estévez 錐體軸的純 von Kries:

[[ 0.984491, -0.054650,  0.067734],
 [-0.006003,  1.004790,  0.001210],
 [ 0.000000,  0.000000,  1.319954]]

XYZ scaling(直接在 XYZ 三軸上縮放,也就是 M = I):

[[0.985760, 0.000000, 0.000000],
 [0.000000, 1.000000, 0.000000],
 [0.000000, 0.000000, 1.319954]]

五個矩陣的第三列第三欄都落在 1.302 到 1.330 之間——都在做同一件事:把 Z 軸拉大約 1.31 倍,因為 D65 比 D50 藍。但非對角項差很多:Bradford 的 [0][2] 是 +0.063254,CAT16 是 +0.044056,XYZ scaling 是 0。這些非對角項就是「光譜銳化」的代價與紅利。

差多少?我把八個代表色用 CIELAB D50 座標寫死(也就是它們在 ICC PCS 裡的樣子),各自用五種方法適應到 D65,再換算成 D65 白點下的 CIELAB,和原本的 (L, a, b) 比:

BradfordCAT02CAT16HPE von KriesXYZ scaling
中性灰 L500.000.000.000.000.00
膚色1.551.581.502.250.00
綠葉2.782.663.304.510.00
藍天5.305.185.457.900.00
飽和藍5.955.637.169.980.00
飽和紅1.992.161.822.370.00
洋紅1.841.212.202.670.00
飽和黃4.884.985.497.380.00

(數字是 ΔE*ab,對照組是「Lab 座標不變」。八個測試色的 Lab 值是我為了涵蓋色相環而構造的,不是實測色卡讀值,絕對數字不應引用,趨勢與量級可信。)

更正 1:XYZ scaling 那一整欄的 0.00,不是它最準

第一眼看那張表會得到一個荒謬的結論:XYZ scaling 全部零誤差,所以它完美。

錯。CIELAB 本身就是一個 XYZ scaling 的色適應。 Lab 的定義是 X/Xn、Y/Yn、Z/Zn 三個比值各自開立方根,換白點的時候分母就換掉了——這在數學上等同於在 XYZ 三軸上做 von Kries 縮放。所以「用 XYZ scaling 做色適應,再用 Lab 量誤差」是拿同一把尺量它自己,結果必然是零。

這是一個典型的循環論證陷阱,而且它在色彩工程裡出現的頻率高得嚇人。任何時候你看到某個方法在某個指標下拿到零誤差,先確認那個指標和那個方法是不是同一個模型的兩種寫法。

那張表真正該讀的是方法之間的差,不是每一欄和零的差:

Bradford vs CAT02Bradford vs CAT16
中性灰 L500.000.00
膚色0.260.28
綠葉1.001.19
藍天0.680.77
飽和藍1.091.68
飽和紅0.210.95
洋紅0.880.98
飽和黃2.532.81

飽和黃在 Bradford 和 CAT16 之間差 2.81 ΔE*ab。這是一個「只是把 D50 換成 D65」的動作,兩個都是國際標準推薦的方法,結果差到肉眼可辨。而中性灰永遠是 0.00——又是那個熟悉的現象:所有方法在中性軸上被強制一致,一離開中性軸就各說各話。昨天在 ForwardMatrix 對比 ColorMatrix 兩條路徑上看到的是同一個模式。

更正 2:「Bradford 最準」沒有依據,而且 CIE 自己已經換掉 CAT02 了

網路上很常見「Bradford 是目前最準的色適應變換」這種說法。它經不起查。

事實序列是這樣的:CIE 在 CIECAM02(2002)裡採用的是 CAT02,不是 Bradford。然後 CAT02 被發現有一個實質的數學缺陷——它會對某些樣本預測出負的三刺激值,也就是把顏色算到光譜軌跡外面去。這不是精度問題,是模型在某些區域直接失效。Li、Luo 等人在 2017 年發表 Comprehensive color solutions: CAM16, CAT16 and CAM16-UCS(Color Research & Application 42, pp. 703–718),提出 CAT16 取代 CAT02,明確地把「避免負三刺激值」寫進最佳化的約束條件裡,同時色差表現不輸原版。

所以以 CIE 這條線來看,順序是 CAT02(2002)→ CAT16(2017),Bradford 根本不在這條線上。

那 Bradford 為什麼無所不在?因為 ICC 規格把它釘死了。ICC 的 media-relative colorimetric 適應要求把 profile 的白點適應到 PCS 的 D50,而規格指定的方法就是線性化 Bradford。這是一個互通性決定,不是精度決定——如果每個 profile 各用各的 CAT,PCS 就不再是共同語言。

於是就出現一個很尷尬的現實:你的照片走的是 Bradford,不是因為 Bradford 最好,是因為 1990 年代末的 ICC 委員會選了它,而換掉它的成本高到沒人想付。 dng_sdk 沿用 ICC 的選擇,Lightroom 沿用 dng_sdk,你沿用 Lightroom。

順帶把 CIELAB 也放進來看:CIELAB 的隱含 CAT 就是最原始的 XYZ scaling,那是 1976 年的東西,連 von Kries 的錐體軸都沒用上。所以「用 ΔE*ab 衡量色適應誤差」這件事本身就自帶偏誤,它偏袒和它同構的方法。

完全適應假設:那個沒有人在用的 D 因子

還有一層更少人談的東西。上面所有矩陣都假設完全適應(D = 1),也就是「觀察者的視覺系統完全補償了光源的顏色」。

CIECAM02 不這樣假設。它有一個適應程度因子:

D = F · ( 1 − (1/3.6) · exp( (−L_A − 42) / 92 ) )

其中 L_A 是適應場的亮度(cd/m²),F 是環境因子(average surround = 1.0,dim = 0.9,dark = 0.8)。算幾個實際數值,F 取 1.0:

L_A (cd/m²)D情境
50.8333昏暗室內
200.8584一般室內夜間
63.660.9119一台 318 cd/m² 螢幕的 20% 平均反射
1000.9407明亮辦公室
318.30.9945高亮度螢幕直視
10001.0000戶外

在一台正常亮度的螢幕前,D 大約是 0.91 到 0.94,不是 1.0。適應是不完全的。 而 ICC 的 PCS、DNG 的 ForwardMatrix、你用的每一個 raw converter,一律用 D = 1。

這代表什麼?代表整條管線在「你會完全適應螢幕的白點」這個假設上運作,而你其實不會。你的視覺系統一部分適應了螢幕,一部分還黏在房間的環境光上。這是為什麼在偏黃的鎢絲燈房間裡看 D65 校正的螢幕,照片會覺得偏藍——不是螢幕錯了,是模型假設你不存在的那個部分。

(這一段的 D 值是我用 CIECAM02 的標準公式自己算的,公式來源是 CIECAM02 的公開描述;我沒有從 CIE 159:2004 原文核對過係數,已標存疑。不過 3.6、42、92 這三個常數在多份獨立文獻裡一致。)

第二次改寫:色調曲線為什麼非有不可

昨天引了 Torger 的觀察:Adobe 的 profile 是為了配合 S 形 tone curve 而預先減飽和的,配上線性曲線看會明顯偏淡。當時我把重點放在「所以矩陣是渲染意圖不是量測」。但這樣講會漏掉一半,而且是比較有價值的那一半:S 曲線不是任性,它有可以算出來的根據。

先算動態範圍。

一台現代全片幅相機,工程動態範圍大約 14 stops。你的輸出媒介呢?

媒介實務同時對比等效 stops
反射式印刷品 / 有環境光的螢幕約 100:16.64
暗房中的良好 SDR 螢幕約 1000:19.97
2000 nit / 0.01 nit HDR 螢幕200000:117.61

在最常見的情況(有環境光,約 100:1),你要把 14 stops 塞進 6.64 stops,壓縮比 6.64 / 14 = 0.475。也就是說,如果你用線性映射,場景裡每差一級曝光,螢幕上只能差 0.475 級。所有的對比都會少掉一半以上。 影像看起來會是灰的、平的、沒有立體感——這正是 Torger 描述的「配上線性曲線就偏淡」。

但這還不是全部。光是壓縮動態範圍不會讓顏色變淡,顏色變淡是另外兩個色彩外觀效應造成的:

  • Stevens 效應:同一個場景,亮度整體降低時,明暗對比的知覺會下降
  • Hunt 效應:同一個顏色,亮度整體降低時,彩度的知覺會下降

螢幕上一張照片的絕對亮度(100–500 cd/m²)遠低於原場景(戶外可以到數萬 cd/m²)。所以即使你把相對亮度關係完美保留,看起來也一定比較平、比較淡。

CIECAM02 把這件事量化在環境參數 c 裡:

環境cc / c_average需要的補償指數
average(明亮環境,如白天室內看印刷品)0.6901.00001.0000
dim(一般看電視/螢幕)0.5900.85511.1695
dark(電影院)0.5250.76091.3143

CIECAM02 的明度是 J = 100·(A/A_w)^(cz),c 越小,同樣的刺激差異被感知成越小的明度差異。要抵銷它,你必須在編碼端把對比乘上 1/(c/c_avg) 的指數。dim 環境需要 1.17,dark 環境需要 1.31。

這正好對上廣播與電影業界那條老規矩:電視的端到端 gamma 約 1.2,電影的端到端 gamma 約 1.5。 拿實際數字驗算一下:BT.709 的相機 OETF 指數約 0.45,BT.1886 的顯示器 EOTF 指數 2.4,端到端就是 0.45 × 2.4 = 1.08;若用常見的 1/2.2 近似,2.4 / 2.2 = 1.09。這個「系統 gamma 大於 1」不是誤差,是刻意保留的對比提升,而它的數量級恰好落在 CIECAM02 的 dim surround 補償值(1.17)附近。

更正 3:「S 曲線是 Adobe 的風格選擇」半對半錯

要不要有一條把對比推回來的曲線,這件事有色彩外觀模型的量化根據,不是風格。 任何一個 raw converter,不管它多想標榜自己「中立」,都必須做這件事,否則輸出必然偏淡偏平。連 dcraw 那種號稱最素的輸出,也套了 sRGB 的轉換函數,而 sRGB 的轉換函數配上實際顯示器的 EOTF 本身就給了大約 1.1 的系統 gamma。

沒有根據的是哪一條曲線。你要在暗部提多少、在高光滾降多長、拐點放在 18% 灰的哪一邊、要不要保護膚色區段——這些完全沒有標準,而它們決定了整台相機看起來的「性格」。

順便把 18% 灰的位置也算清楚,因為這個數字常被講錯。18% 反射率的中性灰,直接用 sRGB 的轉換函數編碼是

V = 1.055 × 0.18^(1/2.4) − 0.055 = 0.461356  →  8-bit 約 118

而攝影師常說「18% 灰應該落在 middle grey,大約 118/255」——這句話成立,但它成立的前提是沒有套任何 tone curve。實際上 Adobe 的預設曲線會把它推到大約 0.46–0.50 之間(視 profile 而定),而 0.50 的編碼值反解回線性是

L = ((0.50 + 0.055) / 1.055)^2.4 = 0.214

也就是 21.4%,比 18% 亮了約 0.25 級。所以「用測光表打 18% 灰,raw 開出來應該正好是 118」這個測試,在任何有預設曲線的軟體裡都不會通過,而且不通過才是正常的

DNG 的 ProfileToneCurve:存了曲線,沒存怎麼用

DNG 用 ProfileToneCurve 存一組控制點(一串成對的浮點數,輸入/輸出)。規格定義了資料怎麼放,沒有定義它應該怎麼套用在 RGB 上

這句話的殺傷力要具體化才看得出來。給定同一條曲線 f,至少有這些套法:

套法行為
三通道各自套 f飽和度上升(暗部拉起來時低通道拉得比高通道多),色相會偏
只在 Lab 的 L 套色相與飽和度理論上不變,但看起來會偏淡
只在 HSV 的 V(= max 通道)套只動最亮通道,飽和度反而下降
在 max 與 min 通道套,中間值內插以維持 RGB-HSL 色相Adobe 據稱的做法
在亮度 Y 套,然後三通道等比縮放保比例,高光容易溢出色域

同一條控制點、五種套法、五個不同的結果。DNG 規格對此完全沉默。所以當你把一顆 DCP 從 Lightroom 搬到 RawTherapee 或 darktable,顏色不一樣,沒有任何一方違規

(Adobe 使用「色相穩定化 RGB 曲線」這個描述,我昨天已經標過存疑,今天沿用同一個標註:這是依 Torger 的公開描述轉述,我沒能從 Adobe 官方文件直接讀到。已標存疑。)

第三次改寫:2.5D 查表的實際結構

ProfileHueSatMapData1/2/3 是一張三維查表,維度由 ProfileHueSatMapDims 三個 LONG 指定:色相分割數、飽和度分割數、明度分割數。每個格點存三個 FLOAT:

( 色相偏移(度), 飽和度乘數, 明度乘數 )

幾個實作上的細節,決定了它和一般 3D LUT 的差別:

色相維度是環狀的。 色相從 0 到 360 度繞一圈,所以查表時第一維要多一個分割點(hue = 360 等於 hue = 0),實作上第一維的索引上界要 +1 才能做插值。這是 DNG 的 3D 表和影片業界那種在 RGB 立方體上取樣的 3D LUT 最大的結構差異:後者三個維度都是有界線段,前者第一維是圓。

它不是在 RGB 上查表,是在 HSV 上查表。 輸入要先從線性 RGB 轉成 HSV 才能索引。這代表查表發生在一個非線性、非均勻、而且在低飽和度時色相數值極不穩定的空間裡——當飽和度趨近 0,色相在數值上會劇烈跳動,但在知覺上完全無關緊要。DNG 靠「飽和度分割數的第一格是 sat = 0」來處理這個奇異點:sat = 0 的那一層必須讓色相偏移不產生任何效果。

編碼欄位。 ProfileHueSatMapEncoding 指定索引查表前要不要先做一次非線性編碼(線性,或 sRGB 轉換函數)。同樣有 ProfileLookTableEncoding。加這個標籤的理由很實際:如果在線性空間索引,絕大多數自然影像的像素會擠在表的最低幾格裡,插值精度全浪費在高光。加上 sRGB 編碼之後取樣點才會分散得比較均勻。

「2.5D」這個叫法哪來的。 因為明度分割數很常等於 1——只有一層,整張表退化成一個 (色相 × 飽和度) 的二維表,明度只是被乘一個常數。所以叫 2.5D:名義上三維,實際上二點五維。昨天講的 hue twist 就是把明度分割數開到大於 1,讓同一色相在不同亮度被推去不同方向。

(關於 Adobe 實際 profile 的常見維度,我看到兩種互相矛盾的說法:一種說常見是 90 × 30 × 1,另一種說常見是 6 × 6 × 3。我沒有實際 dump 過足夠多的 DCP 來確認哪個是主流,已標存疑——但兩種說法都支持「明度維度通常很小或等於 1」這個結論。)

更正 4:HueSatMap 和 LookTable 資料結構一樣,但位置不同,所以效果不同

DNG 有兩張結構完全相同的表:ProfileHueSatMapData(習慣稱 base table)和 ProfileLookTableData(look table)。同樣是 (hue, sat, value) 索引、同樣存三個乘數/偏移。

差別在它們在管線裡的位置:base table 在色調曲線之前,look table 在色調曲線之後

這不是形式上的差別。曲線是非線性的,所以「先查表再過曲線」和「先過曲線再查表」給的是不同答案。把一模一樣的一組數字放進 base table 和放進 look table,輸出不會相同。這也解釋了為什麼 RawTherapee 的 DCP 面板要把 “Base table”、“Look table”、“Tone curve”、“Baseline exposure” 四個開關分開列——它們不是同一件事的四個部分,是管線上四個不同位置的四個不同物件。

概念上的分工是:base table 屬於校正(把矩陣沒搞定的殘差修掉),look table 屬於風格(創意調整)。所以 Adobe 的相機描述檔會共用同一份 base table,再換不同的 look table 做出 Adobe Landscape / Portrait / Vivid 那一整組。

(這兩張表在管線裡的先後順序,我是依 dcpTool 與 RawTherapee 文件的描述整理的,已標存疑;我沒有從 DNG 規格原文逐字確認順序。)

查表不可逆。 這一點比想像中嚴重。矩陣可逆,曲線只要單調就可逆,但一張把 (h, s, v) 映到 (h’, s’, v’) 的表沒有任何理由是單射的——兩個不同的輸入色完全可以被映到同一個輸出色。一旦發生,那兩個顏色就永久合併了。這是繼昨天講的光譜投影(27 維核空間)與高光截切之後,第三種不可逆的資訊損失,而且它發生在一個純數位、看起來「只是調個色」的步驟裡。

第四次改寫:色域映射,規格空白最大的一塊

現在你有一個 D65 的 XYZ,而目標色域(sRGB)裝不下它。怎麼辦?

ICC 定義了四種 rendering intent:perceptual、media-relative colorimetric、saturation、ICC-absolute colorimetric。多數人以為這四個名字對應四套明確的演算法。

更正 5:ICC 沒有定義 perceptual intent 要怎麼算

ICC 規格定義的是 profile 裡要有哪些標籤、每個標籤的資料格式、以及 PCS 的定義。至於 perceptual intent 那張 A2B0 查表裡面裝什麼數字,由 profile 製作者自己決定。ICC 沒有規定壓縮策略、沒有規定要保色相還是保明度、沒有規定要不要黑點對映。

後果:同一張圖,用 Adobe 做的 profile 和用某印刷廠做的 profile,兩邊都選 perceptual,出來不一樣,而且兩邊都完全合規。這和昨天講的「DNG 沒有規範去馬賽克」是同一類問題的不同版本——標準規範了容器與介面,放生了演算法。

ICC v4 才第一次試圖收斂這件事,做法是引入 Perceptual Reference Medium (PRM) 和它的色域 PRMG:source profile 的 perceptual 變換負責把影像重新渲染到 PRM,destination profile 的 perceptual 變換負責從 PRM 渲染到目標媒介。這樣中間就有了共同參考。PRMG 的 CIELAB 色域邊界數值有正式給出,是在 ICC.1:2004-10 的第一版修訂裡補上的(初版沒有)。

但注意 ICC 自己的措辭:PRMG 是一個 “fuzzy” gamut——perceptual 變換不需要精確符合這個色域,profile 製作者「應該把它當作目標來考慮」。這是建議,不是要求。所以 v4 把問題從「完全沒有共同參考」改善成「有一個大家應該參考但不強制的共同參考」。這是真的進步,但離「兩家 profile 給同樣結果」還很遠。

還有一個常被當成標準的東西其實不是:黑點補償(BPC)。它處理的是來源媒介的黑比目標媒介的黑更深時,相對色度 intent 會把所有暗部截切成一團死黑的問題。BPC 是 Adobe 提出的擴充,後來被廣泛採用(littleCMS 有實作),但它不是 ICC 相對色度 intent 的規定行為。所以「相對色度 + BPC」和「純相對色度」是兩個不同的東西,而多數軟體的預設值不一樣。

第五次改寫:HDR 打破了「白」這個假設

前面四次改寫全部建立在一個假設上:輸出媒介有一個「白」,而影像裡最亮的東西就是那個白。 紙白、螢幕白,總之有一個上界,而且那個上界就是「白紙的顏色」。這叫 display-referred。

HDR 把這個假設拆了。在一台 1000 nit 的螢幕上,「白紙」不應該是 1000 nit——那會刺眼到無法觀看。白紙應該落在某個舒適的亮度,而 1000 nit 留給高光:金屬反光、太陽、燈泡、水面。

ITU-R BT.2408 給了這個「白紙」一個數字:HDR 參考白(diffuse white)= 203 cd/m²,對應 HLG 訊號的 75%、PQ 訊號的 58%。我用 SMPTE ST 2084 的公式驗算了 PQ 那一邊。

ST 2084 的常數是:

m1 = 2610/16384        = 0.1593017578125
m2 = (2523/4096) × 128 = 78.84375
c1 = 3424/4096         = 0.8359375
c2 = (2413/4096) × 32  = 18.8515625
c3 = (2392/4096) × 32  = 18.6875

它們不是獨立的,滿足 c1 = c3 − c2 + 1(我驗算過,等號在浮點精度內成立)。這個恆等式的作用是保證峰值對到 1.0:當 Y = 1(也就是 10000 cd/m²)時

(c1 + c2) / (1 + c3) = 19.6875 / 19.6875 = 1  →  E' = 1^m2 = 1

另一端,Y = 0 時 E’ = c1^m2 = 0.8359375^78.84375 ≈ 7.3 × 10⁻⁷,實務上就是 0。兩個端點都被釘死,中間才是 Barten 對比敏感度模型決定的形狀。

編碼函數是

E' = ( (c1 + c2·Y^m1) / (1 + c3·Y^m1) )^m2 ,  Y = nits / 10000

實算幾個點:

亮度 (cd/m²)E’10-bit code
0.0050.01507615.4
10.149946153.4
50.247848253.5
100(SDR 白)0.508078519.8
203(BT.2408 參考白)0.580689594.0
10000.751827769.1
40000.902572923.3
100001.0000001023.0

203 nit 算出來是 0.5807,和 BT.2408 說的 58% 對上。而 100 nit(SDR 螢幕的標準白)只到 0.508。

注意 100 到 10000 之間只用掉 0.508 到 1.000 這半段編碼空間。 兩個數量級的亮度,只分配到一半的碼值;而 0 到 100 nit 這一段(絕大多數影像內容所在的地方)拿走了另一半。PQ 是照人眼的對比敏感度門檻(Barten 模型)設計的,所以它把碼值花在人眼分得出來的地方,而人眼在暗部分辨力遠高於亮部。

HLG 走完全不同的路。ARIB STD-B67 / BT.2100 的 OETF:

a = 0.17883277
b = 1 − 4a = 0.28466892
c = 0.5 − a·ln(4a) = 0.55991073

E' = √(3E)                    ,  0 ≤ E ≤ 1/12
E' = a·ln(12E − b) + c        ,  E > 1/12

前半段是平方根(正好是傳統攝影機 gamma 的近似),後半段是對數。在 E = 1/12 = 0.08333 的接點上,√(3 × 1/12) = √0.25 = 0.5 ——訊號的下半段完全是傳統的平方根曲線。這就是 HLG 向下相容的機制:一台不懂 HLG 的 SDR 螢幕,把 HLG 訊號當成一般訊號播,下半段(也就是一般亮度的內容)看起來大致正常,只有高光會偏暗。

實算幾個點:

E(場景相對亮度)E’
0.083330.500000
0.10.544089
0.260.746283
0.50.871643
0.750.947099
1.01.000000

E 從 0.5 到 1.0(整整一級光圈)只讓 E’ 從 0.8716 走到 1.0000。高光被壓得很扁——這是對數段的必然。

更正 6:PQ 是絕對編碼,但這不代表你看到的是絕對一致的

「PQ 是絕對的,同一個 code value 在任何螢幕上都是同樣的 nits;HLG 是相對的,會隨螢幕變。」這句話對編碼定義來說沒錯,對你實際看到的東西來說是錯的。

因為 PQ 的定義域到 10000 nit,而沒有任何消費級螢幕做得到 10000 nit。 一台 600 nit 的螢幕收到一個 4000 nit 的像素,它必須自己決定要怎麼辦——直接截切?還是滾降?滾降曲線長什麼樣?這叫 display-side tone mapping,而它完全由螢幕廠商決定,沒有標準。 所以絕對編碼並沒有帶來絕對一致的呈現,它只是把不一致從「編碼階段」推遲到「顯示階段」,而且推到了一個作者完全看不到、也無法控制的地方。

HLG 反而把這件事寫進標準裡。BT.2100 的 HLG OOTF 有一個系統 gamma,明確隨顯示器峰值亮度變化:

γ = 1.2 + 0.42 · log10( L_w / 1000 )
L_w (nits)系統 gamma
4001.0329
5001.0736
10001.2000
20001.3264
40001.4529

1000 nit 是基準,系統 gamma 正好 1.2——就是前面算過的、電視業界那個「端到端 gamma 1.2」。而螢幕越亮,系統 gamma 越高,對比拉得越開。這符合 Stevens 效應:亮度上升,知覺對比本來就會上升,所以要主動加大編碼對比才能讓外觀一致——等一下,方向是反的?

不,方向是對的,只是要想清楚:系統 gamma 補償的是觀看環境,不是螢幕本身。標準假設的是「螢幕越亮的環境,通常環境光也越亮/或觀看距離與沉浸感不同」,而且 OOTF 是從 scene-referred 到 display-referred 的渲染函數,它要做的是在更大的顯示動態範圍上重建原場景的外觀。在更大的範圍上重建,自然需要更大的指數。

(這一段對 HLG OOTF 系統 gamma 方向性的解讀是我自己的整理,BT.2100 原文的論證我沒有逐條核對,已標存疑。公式本身則是標準文字,可以放心。)

Gain map:把「兩個渲染的比值」變成一等公民

現在到 2024–2025 這一段。

Gain map 的想法非常簡單,簡單到有點反高潮:檔案裡放一張基底影像(通常是 SDR)、一張 gain map、一組 metadata。顯示時,依照螢幕的 HDR 能力,把基底影像乘上 gain map 的某個比例。

數學核心是一個逐像素的比值,取 log2:

G(x,y) = log2( ( HDR(x,y) + k_hdr ) / ( SDR(x,y) + k_sdr ) )

兩個 k 是很小的偏移量(常見值 1/64),用來避免除以零、也把可能的負值推進正域讓對數有定義。G = 0 代表這個像素兩個版本一樣,正值代表 HDR 版本比較亮,負值代表比較暗(是的,gain map 可以是負的——HDR 版本裡有些地方會比 SDR 版本暗)。

編碼時把 G 正規化到 [0, 1] 再存成一張影像:

map_min_log2 = log2(min_content_boost)
map_max_log2 = log2(max_content_boost)

log_recovery = ( G − map_min_log2 ) / ( map_max_log2 − map_min_log2 )
clamped      = clamp( log_recovery, 0.0, 1.0 )
recovery     = clamped ^ map_gamma

解碼時,關鍵是那個依螢幕能力算出來的權重:

unclamped_w = ( log2(max_display_boost) − hdr_capacity_min )
              / ( hdr_capacity_max − hdr_capacity_min )
w = clamp( unclamped_w, 0.0, 1.0 )

(若 metadata 標明基底影像本身就是 HDR,則 w = 1 − clamp(…),方向反過來。)

然後

out = ( SDR + k_sdr ) · 2^( w · G ) − k_hdr

我拿一組具體參數走一遍。設 max_content_boost = 4.0(作者說這張圖最多要亮 4 倍)、min_content_boost = 1.0hdr_capacity_min = 0.0hdr_capacity_max = 2.0(以 stops 計,也就是 1 倍到 4 倍),取一個 SDR 值 0.5、該像素的 G = 2.0(滿檔增益),k = 1/64 = 0.015625:

螢幕能力log2w輸出
1.00×0.000.00000.5000
1.50×0.580.29250.7578
2.00×1.000.50001.0156
2.83×1.500.75041.4436
4.00×2.001.00002.0469
8.00×3.001.00002.0469

驗算最後一列:(0.5 + 0.015625) × 2² − 0.015625 = 0.515625 × 4 − 0.015625 = 2.0625 − 0.015625 = 2.046875。對上了。

三件事值得注意。第一,在 1.00× 的螢幕上輸出正好等於原始 SDR 值,一位元不差——這就是向下相容的來源,不懂 gain map 的軟體直接顯示基底影像,得到的是作者親手調過的 SDR 版本,不是某個自動 tone mapping 的產物。第二,8× 螢幕和 4× 螢幕得到完全一樣的結果,因為 w 被 clamp 在 1.0。作者透過 max_content_boost 設下了上界,再亮的螢幕也不會超過作者的意圖。第三,中間的螢幕拿到的是連續內插的結果——這正是 Adobe 說的「adapts dynamically to the current display」。

更正 7:gain map 不是 tone mapping,也不是 HDR 影像格式

它常被講成「一種 HDR 格式」或「一種 tone mapping 方法」,兩個都不準。

它是一份配方,不是一個渲染。 gain map 本身不含任何影像內容,它是兩張已經渲染好的影像之間的逐像素比值。所有前面談過的問題——色適應選哪個 CAT、曲線怎麼套、查表怎麼插值、色域怎麼壓——在製作那張基底 SDR 影像時已經全部發生過一遍,在製作那個隱含的 HDR 版本時又發生過一遍。gain map 一點都沒有解決「沒有標準」的問題。

那它解決了什麼?它解決的是誰來做那個決定。在 gain map 之前,一張 HDR 圖丟到一台能力不足的螢幕上,由播放端(作業系統、瀏覽器、螢幕韌體)自己決定怎麼壓;作者既看不到也管不到。有了 gain map,作者事先把「最亮的樣子」和「最暗的樣子」都做好,播放端只剩下在兩者之間內插的權力。

它把不確定性從播放端搬回作者端。 這在攝影上是很大的事——它是這幾十年來,第一個把「呈現的控制權」還給作者的顯示技術。Adobe 自己列的好處裡,「provides creative control to the image author instead of leaving the tone mapping to platform-specific behavior」這一條才是重點,其他幾條(GPU 友善、支援局部調整、向下相容)都是工程上的附加價值。

ISO 21496-1 相對於三套私有格式,改了什麼

三套前身:Apple 的(用在 iPhone 的 HEIC/JPG,文件化程度最低,有幾個獨有的 metadata 欄位)、Adobe 的(Gain Map Spec 1.0)、Google 的 Ultra HDR(和 Adobe 的幾乎相同,多一個指向輔助影像的 GContainer 標頭)。

ISO 21496-1 最接近 Adobe / Android 那一支。最重要的結構性改變是:metadata 從 XMP 搬進了 codestream。

這聽起來像實作細節,實際上很要命。XMP 是一段可以被任何工具讀寫、複製、遺留的 XML。一個不懂 gain map 的編輯軟體,可能會在改動影像之後保留原本的 XMP——於是 metadata 描述的是舊的像素,而像素已經變了。放進 codestream 之後,metadata 和影像資料綁在同一個編碼流裡,要嘛一起在、要嘛一起不在。

代價是:任何不使用開源函式庫或作業系統 API 的應用程式,要支援 ISO gain map 就得動編解碼器層,而不是加一段 XML 解析。這是實質的開發成本,也是為什麼支援度的擴散需要時間。

實務上目前的相容性大致是:Chromium 系瀏覽器支援 ISO 的 JPG gain map(同時保留對 Adobe/Google 舊格式的支援);macOS Sequoia 與 iOS/iPadOS 18 以後的 Apple 系統支援 ISO JPG gain map;Adobe 的 Lightroom Classic 14 / Camera Raw 17 以後在勾選 HDR output 與 maximize compatibility 時輸出 ISO gain map,涵蓋 JPG、AVIF、JXL、TIF。Safari / WebKit 是最大的缺口——iPhone 和 iPad 上所有瀏覽器都用 WebKit,硬體早就支援 HDR,但瀏覽器裡看不到。(這份相容性清單來自 2025 年 1 月的一篇整理,到 2026 年 9 月的今天多半已經有變化,已標存疑。)

DNG 這邊怎麼接 HDR

DNG 1.7.0.0(2023 年 6 月)為了 HDR 加了三樣東西:

  • ProfileDynamicRange:讓一顆 camera profile 宣告自己是 HDR profile。
  • ProfileGroupName:把一組相關的 profile 歸在一起。
  • ColorimetricReference 加了一個新值,代表 HDR output-referred

ProfileDynamicRange 帶出一個具體的技術問題,而這個問題非常能說明「舊管線接 HDR」有多麻煩:色調曲線和查表都定義在正規化的 [0, 1] 上,但 HDR 的像素值會超過 1.0。 曲線在 1.0 之後沒有定義,查表在 1.0 之後沒有格點。

規格的處理方式是引入一組編碼/解碼函數:先把超範圍(overrange)的值用一個壓縮函數映進 [0, 1],套用曲線與查表,再用反函數展開回去。這樣既保留了既有 profile 的資料結構,又能處理超過 1.0 的值,而且合成與 HDR 合併時的超範圍細節不會被截掉。

(我沒能取得 DNG 1.7.x 規格原文來核對那組編碼/解碼函數的確切形式——我試過直接下載 PDF,沙箱網路被擋,轉手來源只描述了機制沒有給公式。已標存疑:上述是機制描述,不是公式引用。)

更正 8:「HDR 照片 = 更亮的照片」是錯的,而且錯得會害你調壞圖

最後一個要更正的觀念。

HDR 的重點不是整張圖更亮,是動態範圍更大——也就是最亮和最暗之間的距離拉開。BT.2408 把 diffuse white 釘在 203 nit,和 SDR 的 100 nit 只差 1.02 級(我算過:log2(203/100) = 1.0215)。一張正確的 HDR 照片,它的「白紙」只比 SDR 亮一級左右。

真正變大的是上面那一段:

螢幕峰值相對 203 nit 參考白的餘裕
100 nit−1.02 stops
203 nit0.00 stops
600 nit1.56 stops
1000 nit2.30 stops
1600 nit2.98 stops
4000 nit4.30 stops

一台 1000 nit 的螢幕,在正確的參考白之上有 2.30 級的高光餘裕。這 2.30 級要留給什麼?留給鏡面反光、光源本身、雲隙的太陽、水面的閃光——那些在真實世界裡本來就比白紙亮好幾級的東西。

把整張圖無差別推亮,結果是白紙變成 1000 nit,刺眼、疲勞、而且高光餘裕被浪費掉了,因為你已經沒有空間再放比白紙更亮的東西。這是目前 HDR 照片最常見的失敗模式,也是為什麼社群平台上很多「HDR 照片」看起來只是刺眼而不是真實。

Greg Benz 那句「great HDR requires a great SDR」講的就是這件事的另一面:gain map 的基底 SDR 影像必須本身就是一張完成度很高的照片,因為在能力不足的螢幕上,觀眾看到的就是它,一位元不差。

全鏈路第二段總表

昨天那張表停在 XYZ D50。接下去是這樣:

階段輸入輸出定義來源是否可逆
色適應 D50 → D65XYZ D50XYZ D65ICC(指定 Bradford);CIE 另有 CAT02/CAT16是(3×3)
HueSatMap(base table)線性 RGB → HSVHSVDNG Ch.6(結構);插值細節部分未定義
ProfileToneCurveRGBRGBDNG Ch.4(資料);套用方式完全未定義是(單調時)
LookTableHSVHSVDNG Ch.4(結構)
色域映射 / rendering intentXYZ目標色域內的 XYZICC 定義介面,不定義演算法;v4 有 PRMG 建議
黑點補償XYZXYZAdobe 擴充,非 ICC 規定部分
輸出矩陣 XYZ → 線性 RGBXYZ D65linear sRGB / P3 / 2020IEC / ITU
轉換函數(sRGB / PQ / HLG)linear編碼值IEC 61966-2-1 / ST 2084 / BT.2100
顯示端 tone mapping(PQ 超出螢幕能力時)編碼值螢幕實際亮度無標準,螢幕廠商自訂
gain map 套用基底 + map + metadata目標渲染ISO 21496-1:2025是(有 metadata 時)

把兩張表接起來,從光子到眼睛一共十九個階段。有明確國際標準規範演算法本身的只有:線性化與減黑階(DNG Ch.5)、矩陣轉換(DNG Ch.6)、色適應的矩陣形式(ICC 指定 Bradford)、轉換函數(IEC/SMPTE/ITU)、gain map 的套用(ISO 21496-1)。

其餘的——去馬賽克、色調曲線的套用方式、查表的插值細節、色域映射策略、顯示端 tone mapping——全部沒有。

而那些沒有規格的地方,正好就是不可逆的地方。 這不是巧合。可逆的變換是數學,大家算出來會一樣,所以可以寫進標準;不可逆的變換是取捨,取捨反映價值判斷,價值判斷寫不進標準。相機廠所謂的「色彩科學」護城河,就築在這幾個空白上,一格都不多。

🧠 記

D50 → D65 的色適應有五個標準答案,飽和黃在 Bradford 與 CAT16 之間差 2.81 ΔE*ab,中性灰永遠差 0.00。所有方法在中性軸上被強制一致,離開中性軸就各說各話——和昨天兩條 DNG 路徑的模式一模一樣。

用 CIELAB 衡量色適應誤差是循環論證。 CIELAB 的隱含色適應就是 XYZ scaling,所以 XYZ scaling 必然拿零誤差。看到零誤差先查指標和方法是不是同一個模型。

Bradford 不是最準,是 ICC 釘死的。 CIE 這條線是 CAT02(2002)→ CAT16(2017),換掉 CAT02 的理由是它會預測出負的三刺激值。Bradford 之所以無所不在,是互通性決定不是精度決定。

整條管線假設完全適應(D = 1),但實際上不是。 CIECAM02 的 D 因子在 L_A = 100 cd/m² 時是 0.9407,不是 1。你在偏色房間裡看校正螢幕會覺得偏色,是模型假設你不存在的那部分。

S 曲線有量化根據,不是純風格。 14 stops 塞進 6.64 stops,壓縮比 0.475;再加上 Stevens 與 Hunt 效應,CIECAM02 的 dim surround 需要 1.17 的補償指數。沒有根據的是哪一條曲線,不是要不要曲線。

18% 灰在無曲線的 sRGB 編碼下是 118/255,套上 Adobe 預設曲線會被推到 21.4% 線性亮度,亮了約 0.25 級。「打 18% 灰應該出來 118」這個測試在有曲線的軟體裡不會過,而且不過才正常。

同一條 ProfileToneCurve 至少有五種合法套法,結果各不相同,DNG 規格對此沉默。這是不同 raw converter 差異最大的單一來源。

base table 在曲線前,look table 在曲線後。 結構完全一樣的兩張表,放的位置不同,效果就不同——因為曲線是非線性的。

查表不可逆,而且它會合併顏色。 這是繼光譜投影(27 維)與高光截切之後的第三種永久損失,發生在一個看起來只是「調個色」的步驟裡。

ICC 不定義 perceptual intent 的演算法。 它定義標籤格式與 PCS。v4 的 PRMG 是一個「fuzzy gamut」建議,不是要求。黑點補償是 Adobe 擴充,不是 ICC 規定。

PQ 的常數滿足 c1 = c3 − c2 + 1。 203 nit(BT.2408 參考白)編碼為 0.5807,10-bit 594;100 nit 是 0.5081。100 到 10000 nit 只用掉一半碼值空間。

HLG 在 E = 1/12 的接點上 E’ 正好是 0.5,下半段就是平方根曲線——這是它向下相容的機制。系統 gamma γ = 1.2 + 0.42·log10(Lw/1000),1000 nit 時正好 1.2。

PQ 是絕對編碼,但呈現不絕對。 沒有螢幕做得到 10000 nit,超出的部分由螢幕自己 tone map,完全沒有標準。絕對編碼只是把不一致推遲到你看不見的地方。

gain map = log2((HDR + k_hdr)/(SDR + k_sdr)),解碼權重 w = clamp((log2(max_display_boost) − hdr_capacity_min)/(hdr_capacity_max − hdr_capacity_min), 0, 1)。1.00× 螢幕輸出等於原始 SDR 一位元不差;超過 max_content_boost 的螢幕被 clamp 住。

gain map 是配方不是渲染。 它沒有解決「沒有標準」,它把決定權從播放端搬回作者端。ISO 21496-1:2025 最大的結構改變是 metadata 從 XMP 搬進 codestream。

HDR ≠ 更亮。 BT.2408 的 diffuse white 是 203 nit,只比 SDR 的 100 nit 亮 1.02 級。一台 1000 nit 螢幕的高光餘裕是 2.30 級,那是留給反光與光源的,不是留給白紙的。

✍️ 實踐

把五個 CAT 矩陣自己算一遍,然後選一個。 二十行 numpy:定義五個錐體響應矩陣、用 A = M⁻¹·diag((M·w_dst)/(M·w_src))·M 算 D50→D65、拿你常拍的顏色跑一次 ΔE。做完這件事你會知道一件很實用的事——如果你主要拍人像,五個方法差不到 0.3 ΔE,完全不用管;如果你拍的是飽和度極高的東西(演唱會燈光、霓虹、花卉特寫),差到 2–3 ΔE,那就值得去查你的軟體用的是哪一個。

測一次你的軟體把 18% 灰放在哪。 拍一張灰卡填滿畫面,分別用(a)dcraw 線性輸出、(b)你的軟體的預設 profile 加預設曲線、(c)你的軟體的預設 profile 加線性曲線,讀三個數字。三者的差就是「曲線」和「profile 預先減飽和」各自貢獻了多少。這個實驗做過一次,你對「這台相機比較亮/比較暗」這類說法會免疫。

用 dcpTool 把 DCP 轉成 XML,直接看 HueSatMap 的維度。 dcpTool -d in.dcp out.xml,然後看 <HueSatDeltas> 的 dims 是多少、value divisions 是不是 1。順便看一下 sat = 0 那一層的色相偏移是不是全零(理論上必須是)。這是驗證前面所有敘述最快的方法,而且用你自己相機的 profile。

建一張 HDR 測試圖,自己算 gain map。 用同一個 raw 檔出兩個版本:一個 SDR、一個 HDR,然後逐像素算 log2((HDR+1/64)/(SDR+1/64))。把這張 map 存出來看它的直方圖——你會發現絕大多數像素落在 0 附近,只有高光區域有顯著正值。這解釋了為什麼 gain map 可以降取樣並重壓縮而不太傷畫質:它本來就是一張低頻、稀疏的影像

先把 SDR 版本做完,再做 HDR。 這是 gain map 工作流最重要的紀律。基底那張圖是所有能力不足的裝置(以及所有不支援 gain map 的軟體)唯一會看到的東西。先讓它獨立成立,再加高光餘裕。反過來做——先調一張漂亮的 HDR 再自動生 SDR——基底會是一張自動 tone map 的產物,通常很難看。

檢查你的 HDR 圖有沒有把白紙推太亮。 一個粗略但有效的自檢:在你的 HDR 編輯環境裡,找出畫面裡的「白襯衫/白牆/白紙」,確認它落在螢幕峰值以下大約 2 到 2.5 級的位置(1000 nit 螢幕就是 180–250 nit 附近)。如果它已經貼在峰值,你的高光餘裕是零,那張圖只是亮,不是 HDR。

輸出時明確選 ISO gain map。 在 Lightroom Classic / Camera Raw 裡,匯出時勾選 HDR output 與 maximize compatibility,格式選 JPG(相容性最高)或 AVIF。不要依賴預設值——不同版本、不同平台(桌機/行動/雲端)的預設不一樣,而輸出成哪一種 gain map 格式決定了它在 Apple 裝置上能不能正確顯示。

在 Chromium 和 Safari 各看一次。 這是目前最快能暴露 gain map 相容性問題的測試:Chromium 系支援 ISO JPG gain map,WebKit 在行動裝置上的支援長期是缺口。如果你的照片要放在自己的網站上,這兩個結果的差距就是你的觀眾實際會看到的差距。

🔗 延伸學習

💬 問 AI

我在研究「DNG 的 XYZ D50 之後到顯示器之間」這一段的色彩處理,想確認幾個具體的技術點,請盡量引用規格條文、標準編號或參考實作的原始碼:
 
1. 色適應變換的選擇。我算出 D50→D65 的完整適應矩陣在 Bradford / CAT02 / CAT16 / HPE von Kries / XYZ scaling 五者之間,對飽和黃可以差到 ΔE*ab 2.8。ICC 規格是在哪一條明確指定 media-relative 適應必須用線性化 Bradford 的?有沒有任何主流 raw converter 或 CMM 是用 CAT02 或 CAT16 而不是 Bradford?如果有,它們怎麼處理和 ICC PCS 的相容性?
 
2. 完全適應假設。ICC PCS 與 DNG 的 ForwardMatrix 都隱含 D = 1(完全適應),但 CIECAM02 的 D 因子在 L_A = 100 cd/m² 時只有 0.94。有沒有文獻量化過「假設 D = 1 但實際 D ≈ 0.94」在典型觀看條件下造成的色差?有沒有任何實務系統會去補償這一段?
 
3. ProfileToneCurve 的套用方式。DNG 規格只定義了控制點的資料格式,沒有定義怎麼套用在 RGB 上。我列了至少五種合法套法(三通道各自套 / Lab 的 L / HSV 的 V / max-min 色相穩定化 / 亮度 Y 加等比縮放)。請問:(a) Adobe「色相穩定化 RGB 曲線」的說法有沒有官方出處,還是只有 Anders Torger 的二手描述?(b) RawTherapee、darktable、Capture One、DxO 各自實際是怎麼實作的,原始碼在哪個檔案?(c) 有沒有人做過同一顆 DCP 在不同軟體下的 ΔE 實測?
 
4. HueSatMap 的實際插值演算法。dng_sdk 的 dng_hue_sat_map 在色相維度做環狀插值、飽和度與明度維度做線性插值,這個描述正確嗎?具體是三線性還是分階段處理?另外,Adobe 實際出貨的 DCP,ProfileHueSatMapDims 的典型值到底是多少(我看到 90×30×1 和 6×6×3 兩種互相矛盾的說法)?有沒有人做過大量 DCP 的統計?
 
5. base table 與 look table 在管線裡的先後位置。我的理解是 HueSatMap 在 tone curve 之前、LookTable 在 tone curve 之後,所以同一組數字放在兩個標籤裡效果不同。這個順序是 DNG 規格明文規定的,還是只是 dng_sdk 的實作慣例?規格原文在哪一節?
 
6. DNG 1.7.0.0 的 ProfileDynamicRange 與 overrange 處理。規格為了把定義在 [0,1] 的 tone curve 與 LUT 套用到超過 1.0 的 HDR 像素值,引入了一組 encoding/decoding 函數。這組函數的確切數學形式是什麼?在規格的哪一節?它和 Adobe 在 Camera Raw 裡實際用的 HDR 處理是同一套嗎?
 
7. ISO 21496-1:2025 相對於 Adobe Gain Map Spec 1.0 draft 15 的實質技術差異。除了「metadata 從 XMP 搬到 codestream」之外,在數學上(offset k 值、gamma 編碼、多通道 vs 單通道 gain map、色彩空間的定義)有沒有不相容之處?一張 Adobe 格式的 gain map 能不能無損轉成 ISO 格式?有沒有現成的轉換工具?
 
8. PQ 的顯示端 tone mapping。既然沒有螢幕做得到 10000 nit,超出峰值的內容由螢幕自行處理。有沒有任何標準或業界共識(例如 SMPTE ST 2094 系列的動態 metadata、HDR10+ 或 Dolby Vision)實際規範了這個滾降?在靜態照片(不是影片)的情境下,這些動態 metadata 方案有被採用嗎?
 
請針對每一點標明你的把握程度,查不到出處的請直接說查不到,不要用推測填空。特別是第 3、4、5、6 點,我懷疑很多流傳的說法都是輾轉引用而沒有規格原文支撐。