1. 背景
- 2023年9月にリリース予定の Safari 17 の Beta Release Notes を確認すると「Added support for JPEG XL」の記述があった[1]
- JPEG XL は BT.2100 PQ や BT.2100 HLG などの HDRの色空間をサポートした画像フォーマットである
- そのため筆者は「iPhone や iPad で簡単に静止画の HDR表示が試せるのでは?」と考えた
- そこで実際に試すことにした
2. 目的
- HDR画像を JPEG XL形式で作成する
- 併せて JPEG XL における色空間に関するパラメータを調査する
- 作成した JPEG XL ファイルを使い iPad の Safari 17 Beta で HDR表示を試す
3. 結論
- BT.2100 PQ や BT.2100 HLG などの HDRの色空間の画像ファイルの生成に成功した
- 作成したファイルは リンク先 からダウンロード可能
- JPEG XL における色空間に関するパラメータとして以下の存在を確認した
color_space
,white_point
,primaries
,rendering_intent
,transfer_function
intensity_target
,min_nits
,linear_below
- 第5世代 iPad Pro を使い Safari 17 Beta にて JPEG XL の HDR表示を試したが失敗した
※1 筆者は macOS の Safari 17 は HDR表示をサポートすると予想しているが、手元に macOS の機材が無いため未確認である
確認に使用した機材やツールのバージョンは以下の通りである。
機材 or ツール名 | バージョン |
---|---|
iPad Pro | 12.9-inch, 5th generation |
iPadOS | 17.0 Beta (21A5326a) |
libjxl (JPEG XL のライブラリ) | v0.9.0 ff8a9c1c |
4. 詳細
4.1. JPEG XL フォーマットについて
全体概要に関しては libjxl の JPEG XL Format Overview を参照。
カラーマネジメントの概要に関しては libjxl の Color Management を参照。
4.2. HDR画像を JPEG XL フォーマットで保存する方法
筆者は PNG 形式の HDR画像をcjxl
コマンドで JPEG XL形式に変換することで実現した。具体的な手順を以下に示す。
まず JPEG XL のリファレンス実装である libjxl をビルドした (※2)。
次にビルドで生成したcjxl
を使い事前に作成した PNG画像を JPEG XL形式に変換した。その際に-x color_space
オプションを使用して HDRに関するパラメータを指定した[2][3] (※3)。
cjxl
コマンドを使った具体例を以下に示す。以下の例では BT.2100-HLG、BT.2100-PQ、P3D65-PQ の3種類の HDR画像を生成している。
# BT.2100-HLG cjxl BT2100_HLG.png BT2100_HLG.jxl -x color_space=RGB_D65_202_Rel_HLG # BT.2100-PQ cjxl BT2100_PQ.png BT2100_HLG.jxl -x color_space=RGB_D65_202_Rel_PeQ # P3D65-PQ (ST 2084) cjxl P3D65_PQ.png P3D65_PQ.jxl -x color_space=RGB_D65_DCI_Rel_PeQ
ここで -x color_space
オプションについて補足をする。指定するRGB_D65_202_Rel_HLG
やRGB_D65_202_Rel_PeQ
といった文字列は色空間に関するパラメータを並べたものである。
左からそれぞれcolor_space
,white_point
,primaries
,rendering_intent
,transfer_function
を意味する。これらに関しては次節で詳しく述べる。
cjxl
コマンドで正しく HDR画像が生成できたかは jxlinfo
コマンドで確認できる。動作例は 付録1 を参照。
また cjxl
コマンドの その他のオプションに関しては 付録2 を参照して頂きたい。
※2 ビルドが面倒であれば公式がリリースしている ビルド済みバイナリ を使っても良い ※3 静止画では ICC Profile を使って色空間の指定をするのが一般的だが、現行の ICC v4 では HDR空間を正しく扱えないため CICP を使用している。CICPに関しては AVIF の過去記事 を参照
4.3. JPEG XL における色空間に関するパラメータの調査結果
調査の結果 8種類のパラメータの存在を確認した。各パラメータの意味を以下の表に示す。
加えて-x color_space
オプションで指定可能な3文字のパラメータに関しても ソースコードを参考に 実際の値との対応関係を記載した[4]。
パラメータ名 | 説明 | -x color_space オプションでの3文字表記との関係[4] |
---|---|---|
color_space |
色空間。RGB, XYB など | RGB : RGBGra : GrayXYB : XYBCS? : Unknown |
white_point |
白色点。D65, DCI-P3 など | D65 : D65Cst : CustomEER : E光源の白色点DCI : DCI-P3 |
primaries |
色域。sRGB, BT.2020 など | SRG : sRGB202 : BT.2020DCI : DCI-P3Cst : Custom |
transfer_function |
OETF。PQ, HLG など | SRG : sRGBLin : Linear709 : BT.709PeQ : PQ (ST 2084)HLG : HLGDCI : Gamma 2.6TF? : Unknown |
rendering_intent |
Rendering intent。詳細は ICC の Specification 参照 | Per : PerceptualRel : RelativeSat : SaturationAbs : Absolute |
intensity_target |
画像内の輝度レベルの上限値をnits で示したもの[5] | - |
min_nits |
画像内の輝度レベルの下限値を示したもの[5] | - |
linear_below |
tome mapping の実行時に変更を加えない上限の輝度レベル[5] | - |
なお、2023年9月9日の時点では min_nits
, linear_below
の値をcjxl
コマンドで設定できなかった(筆者はソースコードの初期値を変えてリビルドすることで対応した)。
また、後半の 3変数intensity_target
, min_nits
, linear_below
がデコード時の画面描画時に必ず参照されるのかは不明である (ISO/IEC 18181 を読めば分かるのかもしれないが筆者には購入するほどのモチベは無かった…)。
4.4. iPad の Safari 17 での表示確認
作成した JPEG XLファイルを iPadOS 17 Beta の Safari 17 Beta にて表示した。確認に使用した画像の一覧を以下の表に示す。
結果は冒頭で述べた通り HDR表示はできなかった。一方で HDR to SDR 変換は働いており、画像データに埋め込んだ色情報は正しく認識されているようである(HLGの結果がかなり怪しいが…)。 なお、作成した JPEG XL データが本当に HDR表示に対応したものかは、別途 Adobe Camera Raw を使って確認済みである(詳細は省略)。
Primaries, Transfer function | JPEG XL (対応ブラウザで確認下さい[6]) | 参考としての PNG (カラマネ無し) |
---|---|---|
BT.709, sRGB | ||
BT.709, BT.709 (※4) | ||
DCI-P3, PQ | ||
BT.20020, PQ | ||
BT.2020, HLG (※5) |
※4 モニター側の EOTF が BT.1886 であると想定し画像データは Gamma 1/2.4 の OETF でエンコードした ※5 モニター側の OOTF (Gamma = 1.2) が適用された場合に適切な色となるよう事前に画像データへ Inverse OOTF を適用した
5. 感想
この記事を通じて AVIF に続き JPEG XL に関しても HDRの画像を生成できるようになった。
色々と試していて思ったが tone mapping, gamut mapping がやはり鬼門だと思う。HDR/WCG は表示デバイスごとに表示性能の差があまりにも大きくて、 一体全体どう変換するのが最適なのか未だに分からない。
様々な実装が提案されているが国際標準に至るものはなく、輝度や色度が制限されたモニターにおける「正しい HDR表示」をどう定義すれば良いのか本当に分からない。 一方で、この分野における技術的な興味は尽きてないので引き続き色々と最新情報を確認していきたい(全然確認が追いついていないが…)。
6. 付録
6.1. 付録1 jxlinfo
コマンドの紹介
JPEG XL ファイルの色空間に関する情報を調べるにはjxlinfo
が便利である(libjxl をビルドすると生成される)。
例として jxlinfo ./img/D65_202_PeQ.jxl
を実行した際の具体的な出力を以下に示す。
JPEG XL file format container (ISO/IEC 18181-2) JPEG XL image, 1920x1080, (possibly) lossless, 16-bit RGB intensity_target: 10000.000000 nits min_nits: 0.000000 relative_to_max_display: 0 linear_below: 0.000000 Color space: RGB, D65, Rec.2100 primaries, PQ transfer function, rendering intent: Relative
6.2. 付録2 cjxl
コマンドの Usage
参考情報として cjxl -v
コマンドの実行結果を以下に添付する。
JPEG XL encoder v0.9.0 ff8a9c1c [AVX2,SSE4,SSE2] Usage: cjxl INPUT OUTPUT [OPTIONS...] INPUT the input can be PNG, APNG, GIF, JPEG, EXR, PPM, PFM, PAM, PGX, or JXL OUTPUT the compressed JXL output file Basic options: -d DISTANCE, --distance=DISTANCE Target visual distance in JND units, lower = higher quality. 0.0 = mathematically lossless. Default for already-lossy input (JPEG/GIF). 1.0 = visually lossless. Default for other input. Recommended range: 0.5 .. 3.0. Allowed range: 0.0 ... 25.0. Mutually exclusive with --quality. -q QUALITY, --quality=QUALITY Quality setting, higher value = higher quality. This is internally mapped to --distance. 100 = mathematically lossless. 90 = visually lossless. Quality values roughly match libjpeg quality. Recommended range: 68 .. 96. Allowed range: 0 .. 100. Mutually exclusive with --distance. -e EFFORT, --effort=EFFORT Encoder effort setting. Range: 1 .. 9. Default: 7. Higher numbers allow more computation at the expense of time. For lossless, generally it will produce smaller files. For lossy, higher effort should more accurately reach the target quality. -V, --version Print encoder library version number and exit. --quiet Be more silent -v, --verbose Verbose output; can be repeated and also applies to help (!). Advanced options: -a A_DISTANCE, --alpha_distance=A_DISTANCE Target visual distance for the alpha channel, lower = higher quality. 0.0 = mathematically lossless. 1.0 = visually lossless. Default is to use the same value as for the color image. Recommended range: 0.5 .. 3.0. Allowed range: 0.0 ... 25.0. -p, --progressive Enable (more) progressive/responsive decoding. --group_order=0|1 Order in which 256x256 groups are stored in the codestream for progressive rendering. 0 = scanline order, 1 = center-first order. Default: 0. --container=0|1 0 = Avoid the container format unless it is needed (default) 1 = Force using the container format even if it is not needed. --compress_boxes=0|1 Disable/enable Brotli compression for metadata boxes. Default is 1 (enabled). --brotli_effort=B_EFFORT Brotli effort setting. Range: 0 .. 11. Default: 9. Higher number is more effort (slower). -m 0|1, --modular=0|1 Use modular mode (default = encoder chooses, 0 = enforce VarDCT, 1 = enforce modular mode). -j 0|1, --lossless_jpeg=0|1 If the input is JPEG, losslessly transcode JPEG, rather than using reencode pixels. --num_threads=N Number of worker threads (-1 == use machine default, 0 == do not use multithreading). --photon_noise_iso=ISO_FILM_SPEED Adds noise to the image emulating photographic film or sensor noise. Higher number = grainier image, e.g. 100 gives a low amount of noise, 3200 gives a lot of noise. Default is 0. --intensity_target=N Upper bound on the intensity level present in the image, in nits. Default is 0, which means 'choose a sensible default value based on the color encoding. -x key=value, --dec-hints=key=value This is useful for 'raw' formats like PPM that cannot store colorspace information and metadata, or to strip or modify metadata in formats that do. The key 'color_space' indicates an enumerated ColorEncoding, for example: -x color_space=RGB_D65_SRG_Per_SRG is sRGB with perceptual rendering intent -x color_space=RGB_D65_202_Rel_PeQ is Rec.2100 PQ with relative rendering intent The key 'icc_pathname' refers to a binary file containing an ICC profile. The keys 'exif', 'xmp', and 'jumbf' refer to a binary file containing metadata; existing metadata of the same type will be overwritten. Specific metadata can be stripped using e.g. -x strip=exif -h, --help Prints this help message. Add -v (up to a total of 4 times) to see more options.
7. 参考資料
[1] Apple Developer Documentation, "Safari 17 Beta Release Notes", https://developer.apple.com/documentation/safari-release-notes/safari-17-release-notes
[2] libjxl/libjxl, "libjxl/doc/color_management.md", https://github.com/libjxl/libjxl/blob/main/doc/color_management.md
[3] libjxl/libjxl, "libjxl/tools/cjxl_main.cc", https://github.com/libjxl/libjxl/blob/ff8a9c1c/tools/cjxl_main.cc#L215-L232
[4] libjxl/libjxl, "libjxl/lib/jxl/color_encoding_internal.cc", https://github.com/libjxl/libjxl/blob/ff8a9c1c/lib/jxl/color_encoding_internal.cc
[5] libjxl/libjxl, "libjxl/lib/include/jxl/codestream_header.h" https://github.com/libjxl/libjxl/blob/ff8a9c1c/lib/include/jxl/codestream_header.h#L130-L155
[6] Can I use, "JPEG XL image format", https://caniuse.com/jpegxl