hdrviz 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,39 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+
8
+ # Build
9
+ build/
10
+ dist/
11
+ *.egg-info/
12
+ .eggs/
13
+ *.egg
14
+
15
+ # Tests
16
+ .pytest_cache/
17
+ .coverage
18
+ htmlcov/
19
+ .tox/
20
+
21
+ # Environments
22
+ .venv/
23
+ venv/
24
+ env/
25
+ .env
26
+
27
+ # Editors
28
+ .idea/
29
+ .vscode/
30
+ *.swp
31
+ *.swo
32
+ *~
33
+
34
+ # OS
35
+ .DS_Store
36
+ Thumbs.db
37
+
38
+ # uv
39
+ uv.lock
hdrviz-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Konstantin Taletskiy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
hdrviz-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,170 @@
1
+ Metadata-Version: 2.4
2
+ Name: hdrviz
3
+ Version: 0.1.0
4
+ Summary: HDR data visualization for the browser, from numpy arrays.
5
+ Project-URL: Homepage, https://github.com/ktaletsk/hdrviz
6
+ Project-URL: Repository, https://github.com/ktaletsk/hdrviz
7
+ Project-URL: Issues, https://github.com/ktaletsk/hdrviz/issues
8
+ Author-email: Konstantin Taletskiy <konstantin@taletskiy.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: anywidget,hdr,jupyter,marimo,numpy,pq,rec2020,smpte-2084,visualization
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Framework :: Jupyter
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: Multimedia :: Graphics
23
+ Classifier: Topic :: Scientific/Engineering :: Visualization
24
+ Requires-Python: >=3.11
25
+ Requires-Dist: anywidget>=0.9
26
+ Requires-Dist: colour-science>=0.4
27
+ Requires-Dist: numpy>=1.24
28
+ Requires-Dist: pillow>=10
29
+ Requires-Dist: traitlets>=5
30
+ Provides-Extra: dev
31
+ Requires-Dist: pytest>=7; extra == 'dev'
32
+ Description-Content-Type: text/markdown
33
+
34
+ <h1>
35
+ <p align="center">
36
+ <img width="150" height="150" alt="logo" src="https://github.com/user-attachments/assets/b82d7db9-6378-45cd-bb12-d3aec6645938" />
37
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000" role="img" aria-label="hdrviz logo">
38
+ <rect width="1000" height="1000" fill="#a83817"/>
39
+ <path d="M 208.74 -0.28 L 213.71 3.93 L 217.84 8.82 L 221.23 14.32 L 223.99 20.35 L 226.22 26.83 L 228.02 33.68 L 229.50 40.83 L 230.75 48.20 L 231.89 55.71 L 233.01 63.28 L 234.21 70.83 L 235.60 78.28 L 237.28 85.56 L 239.36 92.59 L 241.93 99.29 L 245.09 105.59 L 248.85 111.46 L 253.17 116.90 L 257.99 121.93 L 263.29 126.54 L 269.01 130.73 L 275.11 134.53 L 281.54 137.92 L 288.27 140.92 L 295.25 143.53 L 302.44 145.75 L 309.78 147.59 L 317.25 149.06 L 324.78 150.15 L 332.35 150.87 L 339.91 151.24 L 347.42 151.25 L 354.88 150.95 L 362.30 150.37 L 369.69 149.56 L 377.06 148.54 L 384.40 147.37 L 391.72 146.08 L 399.04 144.70 L 406.35 143.28 L 413.67 141.86 L 420.99 140.47 L 428.33 139.16 L 435.69 137.96 L 443.07 136.90 L 450.49 136.04 L 457.93 135.36 L 465.40 134.87 L 472.89 134.54 L 480.38 134.39 L 487.89 134.40 L 495.40 134.56 L 502.91 134.87 L 510.41 135.31 L 517.90 135.90 L 525.37 136.60 L 532.82 137.43 L 540.23 138.37 L 547.62 139.42 L 554.97 140.56 L 562.27 141.83 L 569.51 143.23 L 576.68 144.80 L 583.78 146.55 L 590.79 148.51 L 597.71 150.69 L 604.53 153.12 L 611.23 155.83 L 617.80 158.83 L 624.25 162.14 L 630.55 165.79 L 636.69 169.80 L 642.68 174.19 L 648.50 178.98 L 654.13 184.20 L 659.62 189.75 L 665.10 195.24 L 670.77 200.22 L 676.78 204.22 L 683.29 206.83 L 690.32 208.07 L 697.76 208.26 L 705.52 207.74 L 713.44 206.91 L 721.20 206.49 L 728.42 207.23 L 734.73 209.88 L 739.85 214.53 L 743.58 220.70 L 745.72 227.89 L 746.14 235.61 L 745.54 243.45 L 745.14 251.07 L 746.12 258.12 L 749.21 264.42 L 753.78 270.20 L 759.03 275.77 L 764.13 281.42 L 768.34 287.45 L 771.52 293.88 L 773.85 300.65 L 775.54 307.70 L 776.75 314.94 L 777.67 322.31 L 778.50 329.74 L 779.40 337.16 L 780.49 344.52 L 781.75 351.83 L 783.16 359.09 L 784.72 366.31 L 786.40 373.48 L 788.19 380.61 L 790.06 387.70 L 792.02 394.75 L 794.03 401.78 L 796.09 408.77 L 798.17 415.74 L 800.26 422.68 L 802.35 429.60 L 804.42 436.51 L 806.45 443.39 L 808.47 450.26 L 810.53 457.08 L 812.68 463.86 L 814.98 470.56 L 817.47 477.18 L 820.20 483.71 L 823.24 490.12 L 826.62 496.41 L 830.30 502.59 L 834.18 508.72 L 838.17 514.84 L 842.17 521.00 L 846.08 527.24 L 849.81 533.60 L 853.26 540.14 L 856.34 546.88 L 858.92 553.79 L 860.86 560.75 L 862.03 567.63 L 862.28 574.31 L 861.47 580.68 L 859.46 586.60 L 856.11 591.96 L 851.42 596.72 L 845.66 601.01 L 839.15 605.00 L 832.19 608.84 L 825.10 612.69 L 818.20 616.71 L 811.80 621.07 L 806.21 625.92 L 801.68 631.28 L 797.55 635.13 L 792.48 634.06 L 786.25 628.69 L 779.50 622.78 L 772.74 619.13 L 766.27 619.23 L 760.38 622.98 L 755.36 628.59 L 751.17 634.76 L 747.32 640.96 L 743.31 646.76 L 738.61 651.69 L 732.95 655.56 L 726.64 658.75 L 720.07 661.74 L 713.65 665.01 L 707.61 668.84 L 702.00 673.21 L 696.84 678.05 L 692.14 683.33 L 687.93 688.99 L 684.21 694.98 L 681.02 701.25 L 678.36 707.74 L 676.24 714.41 L 674.57 721.22 L 673.19 728.14 L 671.98 735.13 L 670.79 742.15 L 669.50 749.18 L 667.95 756.18 L 666.04 763.12 L 663.71 769.97 L 661.00 776.74 L 657.92 783.41 L 654.49 789.98 L 650.73 796.43 L 646.66 802.76 L 642.29 808.95 L 637.65 815.01 L 632.75 820.84 L 627.62 826.30 L 622.28 831.25 L 616.76 835.54 L 611.07 839.01 L 605.23 841.51 L 599.28 842.90 L 593.23 843.03 L 587.09 841.85 L 580.87 839.56 L 574.55 836.39 L 568.13 832.57 L 561.60 828.33 L 554.95 823.90 L 548.19 819.52 L 541.30 815.40 L 534.29 811.76 L 527.21 808.68 L 520.13 806.25 L 513.11 804.56 L 506.21 803.68 L 499.49 803.71 L 493.01 804.72 L 486.83 806.80 L 480.96 809.89 L 475.37 813.86 L 470.02 818.53 L 464.87 823.75 L 459.88 829.38 L 455.02 835.24 L 450.25 841.19 L 445.54 847.07 L 440.87 852.78 L 436.31 858.39 L 431.93 863.97 L 427.80 869.60 L 423.99 875.35 L 420.57 881.29 L 417.60 887.51 L 415.16 894.08 L 413.28 901.05 L 411.81 908.32 L 410.55 915.78 L 409.30 923.29 L 407.85 930.74 L 406.00 937.99 L 403.56 944.91 L 400.33 951.41 L 396.40 957.50 L 392.00 963.35 L 387.38 969.08 L 382.76 974.84 L 378.41 980.78 L 374.55 987.03 L 371.42 993.74 L 369.28 1001.05 L 1000.00 1001.05 L 1000.00 0 Z" fill="#e8a020"/>
40
+ <circle cx="435.4" cy="59.6" r="9.6" fill="#ffffff"/>
41
+ <circle cx="314.8" cy="109.7" r="8.5" fill="#ffffff"/>
42
+ <circle cx="557.0" cy="91.6" r="10.9" fill="#ffffff"/>
43
+ <circle cx="671.7" cy="63.5" r="9.3" fill="#ffffff"/>
44
+ <circle cx="750.5" cy="55.3" r="8.7" fill="#ffffff"/>
45
+ <circle cx="943.9" cy="250.1" r="9.0" fill="#ffffff"/>
46
+ <circle cx="807.4" cy="657.9" r="10.1" fill="#ffffff"/>
47
+ <circle cx="908.9" cy="821.6" r="8.3" fill="#ffffff"/>
48
+ <circle cx="932.1" cy="599.6" r="9.3" fill="#ffffff"/>
49
+ <circle cx="979.5" cy="504.5" r="9.7" fill="#ffffff"/>
50
+ <circle cx="923.0" cy="914.5" r="10.3" fill="#ffffff"/>
51
+ <circle cx="854.1" cy="434.8" r="9.7" fill="#ffffff"/>
52
+ <circle cx="550.2" cy="925.4" r="7.7" fill="#ffffff"/>
53
+ <circle cx="885.7" cy="885.5" r="8.0" fill="#ffffff"/>
54
+ <circle cx="715.9" cy="974.6" r="7.3" fill="#ffffff"/>
55
+ <circle cx="937.5" cy="968.3" r="10.5" fill="#ffffff"/>
56
+ <circle cx="618.0" cy="415.4" r="7.4" fill="#0a0202"/>
57
+ <circle cx="787.6" cy="605.2" r="6.6" fill="#0a0202"/>
58
+ <circle cx="589.3" cy="351.2" r="6.9" fill="#0a0202"/>
59
+ <circle cx="675.8" cy="476.2" r="7.1" fill="#0a0202"/>
60
+ <circle cx="541.1" cy="416.6" r="7.5" fill="#0a0202"/>
61
+ <circle cx="698.6" cy="603.6" r="8.8" fill="#0a0202"/>
62
+ <circle cx="729.3" cy="288.9" r="9.6" fill="#0a0202"/>
63
+ <circle cx="763.4" cy="407.3" r="7.6" fill="#0a0202"/>
64
+ <circle cx="569.0" cy="492.0" r="6.2" fill="#0a0202"/>
65
+ <circle cx="554.7" cy="270.1" r="6.6" fill="#0a0202"/>
66
+ <circle cx="547.1" cy="576.0" r="8.5" fill="#0a0202"/>
67
+ <circle cx="473.1" cy="598.0" r="7.4" fill="#0a0202"/>
68
+ <circle cx="535.6" cy="568.3" r="9.4" fill="#0a0202"/>
69
+ <circle cx="718.0" cy="647.2" r="7.9" fill="#0a0202"/>
70
+ <circle cx="670.4" cy="577.1" r="6.1" fill="#0a0202"/>
71
+ <circle cx="472.5" cy="664.9" r="6.1" fill="#0a0202"/>
72
+ <circle cx="583.2" cy="765.1" r="9.5" fill="#0a0202"/>
73
+ <circle cx="653.9" cy="662.5" r="9.1" fill="#0a0202"/>
74
+ <path d="M615.0,48.7 L624.2,90.8 L666.3,100.0 L624.2,109.2 L615.0,151.3 L605.8,109.2 L563.7,100.0 L605.8,90.8 Z" fill="#ffffff"/>
75
+ <path d="M910.0,199.8 L922.6,257.4 L980.2,270.0 L922.6,282.6 L910.0,340.2 L897.4,282.6 L839.8,270.0 L897.4,257.4 Z" fill="#ffffff"/>
76
+ <path d="M965.0,379.9 L971.3,408.7 L1000.1,415.0 L971.3,421.3 L965.0,450.1 L958.7,421.3 L929.9,415.0 L958.7,408.7 Z" fill="#ffffff"/>
77
+ <path d="M590.0,611.4 L598.7,651.3 L638.6,660.0 L598.7,668.7 L590.0,708.6 L581.3,668.7 L541.4,660.0 L581.3,651.3 Z" fill="#ffffff"/>
78
+ <image x="500" y="0" width="500" height="1000" preserveAspectRatio="none" href="data:image/png;base64,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"/>
79
+ <line x1="500" y1="0" x2="500" y2="1000" stroke="#ffffff" stroke-width="4" opacity="0.95"/>
80
+ </svg>
81
+ hdrviz
82
+ </p>
83
+ </h1>
84
+
85
+
86
+ <p align="center">Data visualization in HDR.</p>
87
+
88
+
89
+ ## About
90
+
91
+ `hdrviz` is a minimal Python library (~250 lines) that renders 2D numpy arrays as PQ Rec2020-tagged PNGs for HDR-capable browsers.
92
+
93
+ If your data has more dynamic range than 8-bit color can show — astrophotography, fluorescence microscopy, fractals, log-magnitude FFTs, density maps — `hdrviz` lets displays render the better contrast that's actually in the data.
94
+
95
+ This library is an encoder plus a reference notebook widget. For axes, colorbars, channel mixing, pan/zoom — compose with matplotlib, plotly, or viv.
96
+
97
+ ## Install
98
+
99
+ ```bash
100
+ pip install hdrviz
101
+ ```
102
+
103
+ ## Quick start
104
+
105
+ ```python
106
+ import numpy as np
107
+ import hdrviz as hv
108
+
109
+ data = np.random.RandomState(0).rand(400, 600)
110
+ widget = hv.imshow(data, cmap="inferno-hdr", peak_nits=4000)
111
+ widget # display in a notebook
112
+ ```
113
+
114
+ ## Lower-level API
115
+
116
+ `imshow` is a convenience wrapper over a three-step pipeline: apply a colormap to map normalized data to RGB linear-light luminance in cd/m² (nits), run the SMPTE ST 2084 inverse EOTF (the "PQ encoding," via [colour-science](https://www.colour-science.org/)), and write a PNG with an embedded PQ Rec2020 ICC profile that browsers know how to composite in extended dynamic range.
117
+
118
+ ```python
119
+ from hdrviz import hdr_colormap, encode_hdr_png
120
+
121
+ norm = (arr - arr.min()) / (arr.max() - arr.min())
122
+ rgb_nits = hdr_colormap(norm, cmap_name="inferno-hdr", peak_nits=4000)
123
+ png_bytes = encode_hdr_png(rgb_nits) # PQ Rec2020-tagged PNG
124
+ ```
125
+
126
+ PNG bytes are the deliverable. Serve them from a backend, write them to disk, embed them in custom HTML — anywhere that wants "an HDR image from a numpy array."
127
+
128
+ ## API surface
129
+
130
+ | Symbol | Purpose |
131
+ |---|---|
132
+ | `encode_hdr_png(rgb_nits, icc_profile)` | PNG encoding from linear-light RGB nits |
133
+ | `linear_nits_to_pq(rgb_nits)` | SMPTE ST 2084 inverse EOTF (wraps `colour-science`) |
134
+ | `hdr_colormap(norm, cmap_name, peak_nits)` | apply a named HDR colormap |
135
+ | `extract_icc_from_png(png_bytes)` | pull an ICC profile from a PNG's `iCCP` chunk |
136
+ | `to_data_url(png_bytes)` | inline embedding helper |
137
+ | `COLORMAP_LIBRARY` | seven HDR-aware colormaps (`fire-purple`, `ice`, `twilight-burst`, `matrix-green`, `ember`, `viridis-hdr`, `inferno-hdr`) |
138
+ | `DEFAULT_PQ_REC2020_ICC` | bundled ICC profile (~9 KB, "Rec2020 Gamut with PQ Transfer") |
139
+ | `imshow(arr, cmap, peak_nits, ...)` | quickstart wrapper that returns an `HDRImage` |
140
+ | `class HDRImage(anywidget.AnyWidget)` | reference display widget with an SDR-clamp toggle |
141
+
142
+ ## What hdrviz isn't
143
+
144
+ - **Plotting framework** with axes, ticks, labels, colorbars — compose with matplotlib
145
+ - **Multi-channel mixing, contrast sliders, pan/zoom, multi-resolution tiling** — compose with [viv](https://github.com/hms-dbmi/viv), ideally with HDR PNG tiles encoded by `hdrviz`
146
+ - **Animated or video HDR** — waits for `configureHighDynamicRange()` to ship in stable Chromium
147
+
148
+ ## Demo notebook
149
+
150
+ [`notebook.py`](./notebook.py) is a marimo notebook with introducing the HDR data visualization idea:
151
+
152
+ - A widget that checks your browser's HDR capabilities
153
+ - An interactive Mandelbrot explorer with HDR colormaps and click-to-zoom
154
+ - The Horsehead Nebula photographic plate from the astropy tutorials archive
155
+ - A fluorescence-microscopy frame from `scikit-image.data.cells3d`, where the membrane channel's ~150× native dynamic range is the showstopper
156
+
157
+ ```bash
158
+ git clone https://github.com/ktaletsk/hdrviz
159
+ cd hdrviz
160
+ marimo edit notebook.py --sandbox
161
+ ```
162
+
163
+ ## Browser support
164
+
165
+ Tested and works in Chromium-based browsers.
166
+ Safari mostly works, but had issues with some images not rendering in HDR.
167
+
168
+ ## License
169
+
170
+ MIT — see [LICENSE](./LICENSE).
hdrviz-0.1.0/README.md ADDED
@@ -0,0 +1,137 @@
1
+ <h1>
2
+ <p align="center">
3
+ <img width="150" height="150" alt="logo" src="https://github.com/user-attachments/assets/b82d7db9-6378-45cd-bb12-d3aec6645938" />
4
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000" role="img" aria-label="hdrviz logo">
5
+ <rect width="1000" height="1000" fill="#a83817"/>
6
+ <path d="M 208.74 -0.28 L 213.71 3.93 L 217.84 8.82 L 221.23 14.32 L 223.99 20.35 L 226.22 26.83 L 228.02 33.68 L 229.50 40.83 L 230.75 48.20 L 231.89 55.71 L 233.01 63.28 L 234.21 70.83 L 235.60 78.28 L 237.28 85.56 L 239.36 92.59 L 241.93 99.29 L 245.09 105.59 L 248.85 111.46 L 253.17 116.90 L 257.99 121.93 L 263.29 126.54 L 269.01 130.73 L 275.11 134.53 L 281.54 137.92 L 288.27 140.92 L 295.25 143.53 L 302.44 145.75 L 309.78 147.59 L 317.25 149.06 L 324.78 150.15 L 332.35 150.87 L 339.91 151.24 L 347.42 151.25 L 354.88 150.95 L 362.30 150.37 L 369.69 149.56 L 377.06 148.54 L 384.40 147.37 L 391.72 146.08 L 399.04 144.70 L 406.35 143.28 L 413.67 141.86 L 420.99 140.47 L 428.33 139.16 L 435.69 137.96 L 443.07 136.90 L 450.49 136.04 L 457.93 135.36 L 465.40 134.87 L 472.89 134.54 L 480.38 134.39 L 487.89 134.40 L 495.40 134.56 L 502.91 134.87 L 510.41 135.31 L 517.90 135.90 L 525.37 136.60 L 532.82 137.43 L 540.23 138.37 L 547.62 139.42 L 554.97 140.56 L 562.27 141.83 L 569.51 143.23 L 576.68 144.80 L 583.78 146.55 L 590.79 148.51 L 597.71 150.69 L 604.53 153.12 L 611.23 155.83 L 617.80 158.83 L 624.25 162.14 L 630.55 165.79 L 636.69 169.80 L 642.68 174.19 L 648.50 178.98 L 654.13 184.20 L 659.62 189.75 L 665.10 195.24 L 670.77 200.22 L 676.78 204.22 L 683.29 206.83 L 690.32 208.07 L 697.76 208.26 L 705.52 207.74 L 713.44 206.91 L 721.20 206.49 L 728.42 207.23 L 734.73 209.88 L 739.85 214.53 L 743.58 220.70 L 745.72 227.89 L 746.14 235.61 L 745.54 243.45 L 745.14 251.07 L 746.12 258.12 L 749.21 264.42 L 753.78 270.20 L 759.03 275.77 L 764.13 281.42 L 768.34 287.45 L 771.52 293.88 L 773.85 300.65 L 775.54 307.70 L 776.75 314.94 L 777.67 322.31 L 778.50 329.74 L 779.40 337.16 L 780.49 344.52 L 781.75 351.83 L 783.16 359.09 L 784.72 366.31 L 786.40 373.48 L 788.19 380.61 L 790.06 387.70 L 792.02 394.75 L 794.03 401.78 L 796.09 408.77 L 798.17 415.74 L 800.26 422.68 L 802.35 429.60 L 804.42 436.51 L 806.45 443.39 L 808.47 450.26 L 810.53 457.08 L 812.68 463.86 L 814.98 470.56 L 817.47 477.18 L 820.20 483.71 L 823.24 490.12 L 826.62 496.41 L 830.30 502.59 L 834.18 508.72 L 838.17 514.84 L 842.17 521.00 L 846.08 527.24 L 849.81 533.60 L 853.26 540.14 L 856.34 546.88 L 858.92 553.79 L 860.86 560.75 L 862.03 567.63 L 862.28 574.31 L 861.47 580.68 L 859.46 586.60 L 856.11 591.96 L 851.42 596.72 L 845.66 601.01 L 839.15 605.00 L 832.19 608.84 L 825.10 612.69 L 818.20 616.71 L 811.80 621.07 L 806.21 625.92 L 801.68 631.28 L 797.55 635.13 L 792.48 634.06 L 786.25 628.69 L 779.50 622.78 L 772.74 619.13 L 766.27 619.23 L 760.38 622.98 L 755.36 628.59 L 751.17 634.76 L 747.32 640.96 L 743.31 646.76 L 738.61 651.69 L 732.95 655.56 L 726.64 658.75 L 720.07 661.74 L 713.65 665.01 L 707.61 668.84 L 702.00 673.21 L 696.84 678.05 L 692.14 683.33 L 687.93 688.99 L 684.21 694.98 L 681.02 701.25 L 678.36 707.74 L 676.24 714.41 L 674.57 721.22 L 673.19 728.14 L 671.98 735.13 L 670.79 742.15 L 669.50 749.18 L 667.95 756.18 L 666.04 763.12 L 663.71 769.97 L 661.00 776.74 L 657.92 783.41 L 654.49 789.98 L 650.73 796.43 L 646.66 802.76 L 642.29 808.95 L 637.65 815.01 L 632.75 820.84 L 627.62 826.30 L 622.28 831.25 L 616.76 835.54 L 611.07 839.01 L 605.23 841.51 L 599.28 842.90 L 593.23 843.03 L 587.09 841.85 L 580.87 839.56 L 574.55 836.39 L 568.13 832.57 L 561.60 828.33 L 554.95 823.90 L 548.19 819.52 L 541.30 815.40 L 534.29 811.76 L 527.21 808.68 L 520.13 806.25 L 513.11 804.56 L 506.21 803.68 L 499.49 803.71 L 493.01 804.72 L 486.83 806.80 L 480.96 809.89 L 475.37 813.86 L 470.02 818.53 L 464.87 823.75 L 459.88 829.38 L 455.02 835.24 L 450.25 841.19 L 445.54 847.07 L 440.87 852.78 L 436.31 858.39 L 431.93 863.97 L 427.80 869.60 L 423.99 875.35 L 420.57 881.29 L 417.60 887.51 L 415.16 894.08 L 413.28 901.05 L 411.81 908.32 L 410.55 915.78 L 409.30 923.29 L 407.85 930.74 L 406.00 937.99 L 403.56 944.91 L 400.33 951.41 L 396.40 957.50 L 392.00 963.35 L 387.38 969.08 L 382.76 974.84 L 378.41 980.78 L 374.55 987.03 L 371.42 993.74 L 369.28 1001.05 L 1000.00 1001.05 L 1000.00 0 Z" fill="#e8a020"/>
7
+ <circle cx="435.4" cy="59.6" r="9.6" fill="#ffffff"/>
8
+ <circle cx="314.8" cy="109.7" r="8.5" fill="#ffffff"/>
9
+ <circle cx="557.0" cy="91.6" r="10.9" fill="#ffffff"/>
10
+ <circle cx="671.7" cy="63.5" r="9.3" fill="#ffffff"/>
11
+ <circle cx="750.5" cy="55.3" r="8.7" fill="#ffffff"/>
12
+ <circle cx="943.9" cy="250.1" r="9.0" fill="#ffffff"/>
13
+ <circle cx="807.4" cy="657.9" r="10.1" fill="#ffffff"/>
14
+ <circle cx="908.9" cy="821.6" r="8.3" fill="#ffffff"/>
15
+ <circle cx="932.1" cy="599.6" r="9.3" fill="#ffffff"/>
16
+ <circle cx="979.5" cy="504.5" r="9.7" fill="#ffffff"/>
17
+ <circle cx="923.0" cy="914.5" r="10.3" fill="#ffffff"/>
18
+ <circle cx="854.1" cy="434.8" r="9.7" fill="#ffffff"/>
19
+ <circle cx="550.2" cy="925.4" r="7.7" fill="#ffffff"/>
20
+ <circle cx="885.7" cy="885.5" r="8.0" fill="#ffffff"/>
21
+ <circle cx="715.9" cy="974.6" r="7.3" fill="#ffffff"/>
22
+ <circle cx="937.5" cy="968.3" r="10.5" fill="#ffffff"/>
23
+ <circle cx="618.0" cy="415.4" r="7.4" fill="#0a0202"/>
24
+ <circle cx="787.6" cy="605.2" r="6.6" fill="#0a0202"/>
25
+ <circle cx="589.3" cy="351.2" r="6.9" fill="#0a0202"/>
26
+ <circle cx="675.8" cy="476.2" r="7.1" fill="#0a0202"/>
27
+ <circle cx="541.1" cy="416.6" r="7.5" fill="#0a0202"/>
28
+ <circle cx="698.6" cy="603.6" r="8.8" fill="#0a0202"/>
29
+ <circle cx="729.3" cy="288.9" r="9.6" fill="#0a0202"/>
30
+ <circle cx="763.4" cy="407.3" r="7.6" fill="#0a0202"/>
31
+ <circle cx="569.0" cy="492.0" r="6.2" fill="#0a0202"/>
32
+ <circle cx="554.7" cy="270.1" r="6.6" fill="#0a0202"/>
33
+ <circle cx="547.1" cy="576.0" r="8.5" fill="#0a0202"/>
34
+ <circle cx="473.1" cy="598.0" r="7.4" fill="#0a0202"/>
35
+ <circle cx="535.6" cy="568.3" r="9.4" fill="#0a0202"/>
36
+ <circle cx="718.0" cy="647.2" r="7.9" fill="#0a0202"/>
37
+ <circle cx="670.4" cy="577.1" r="6.1" fill="#0a0202"/>
38
+ <circle cx="472.5" cy="664.9" r="6.1" fill="#0a0202"/>
39
+ <circle cx="583.2" cy="765.1" r="9.5" fill="#0a0202"/>
40
+ <circle cx="653.9" cy="662.5" r="9.1" fill="#0a0202"/>
41
+ <path d="M615.0,48.7 L624.2,90.8 L666.3,100.0 L624.2,109.2 L615.0,151.3 L605.8,109.2 L563.7,100.0 L605.8,90.8 Z" fill="#ffffff"/>
42
+ <path d="M910.0,199.8 L922.6,257.4 L980.2,270.0 L922.6,282.6 L910.0,340.2 L897.4,282.6 L839.8,270.0 L897.4,257.4 Z" fill="#ffffff"/>
43
+ <path d="M965.0,379.9 L971.3,408.7 L1000.1,415.0 L971.3,421.3 L965.0,450.1 L958.7,421.3 L929.9,415.0 L958.7,408.7 Z" fill="#ffffff"/>
44
+ <path d="M590.0,611.4 L598.7,651.3 L638.6,660.0 L598.7,668.7 L590.0,708.6 L581.3,668.7 L541.4,660.0 L581.3,651.3 Z" fill="#ffffff"/>
45
+ <image x="500" y="0" width="500" height="1000" preserveAspectRatio="none" href="data:image/png;base64,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"/>
46
+ <line x1="500" y1="0" x2="500" y2="1000" stroke="#ffffff" stroke-width="4" opacity="0.95"/>
47
+ </svg>
48
+ hdrviz
49
+ </p>
50
+ </h1>
51
+
52
+
53
+ <p align="center">Data visualization in HDR.</p>
54
+
55
+
56
+ ## About
57
+
58
+ `hdrviz` is a minimal Python library (~250 lines) that renders 2D numpy arrays as PQ Rec2020-tagged PNGs for HDR-capable browsers.
59
+
60
+ If your data has more dynamic range than 8-bit color can show — astrophotography, fluorescence microscopy, fractals, log-magnitude FFTs, density maps — `hdrviz` lets displays render the better contrast that's actually in the data.
61
+
62
+ This library is an encoder plus a reference notebook widget. For axes, colorbars, channel mixing, pan/zoom — compose with matplotlib, plotly, or viv.
63
+
64
+ ## Install
65
+
66
+ ```bash
67
+ pip install hdrviz
68
+ ```
69
+
70
+ ## Quick start
71
+
72
+ ```python
73
+ import numpy as np
74
+ import hdrviz as hv
75
+
76
+ data = np.random.RandomState(0).rand(400, 600)
77
+ widget = hv.imshow(data, cmap="inferno-hdr", peak_nits=4000)
78
+ widget # display in a notebook
79
+ ```
80
+
81
+ ## Lower-level API
82
+
83
+ `imshow` is a convenience wrapper over a three-step pipeline: apply a colormap to map normalized data to RGB linear-light luminance in cd/m² (nits), run the SMPTE ST 2084 inverse EOTF (the "PQ encoding," via [colour-science](https://www.colour-science.org/)), and write a PNG with an embedded PQ Rec2020 ICC profile that browsers know how to composite in extended dynamic range.
84
+
85
+ ```python
86
+ from hdrviz import hdr_colormap, encode_hdr_png
87
+
88
+ norm = (arr - arr.min()) / (arr.max() - arr.min())
89
+ rgb_nits = hdr_colormap(norm, cmap_name="inferno-hdr", peak_nits=4000)
90
+ png_bytes = encode_hdr_png(rgb_nits) # PQ Rec2020-tagged PNG
91
+ ```
92
+
93
+ PNG bytes are the deliverable. Serve them from a backend, write them to disk, embed them in custom HTML — anywhere that wants "an HDR image from a numpy array."
94
+
95
+ ## API surface
96
+
97
+ | Symbol | Purpose |
98
+ |---|---|
99
+ | `encode_hdr_png(rgb_nits, icc_profile)` | PNG encoding from linear-light RGB nits |
100
+ | `linear_nits_to_pq(rgb_nits)` | SMPTE ST 2084 inverse EOTF (wraps `colour-science`) |
101
+ | `hdr_colormap(norm, cmap_name, peak_nits)` | apply a named HDR colormap |
102
+ | `extract_icc_from_png(png_bytes)` | pull an ICC profile from a PNG's `iCCP` chunk |
103
+ | `to_data_url(png_bytes)` | inline embedding helper |
104
+ | `COLORMAP_LIBRARY` | seven HDR-aware colormaps (`fire-purple`, `ice`, `twilight-burst`, `matrix-green`, `ember`, `viridis-hdr`, `inferno-hdr`) |
105
+ | `DEFAULT_PQ_REC2020_ICC` | bundled ICC profile (~9 KB, "Rec2020 Gamut with PQ Transfer") |
106
+ | `imshow(arr, cmap, peak_nits, ...)` | quickstart wrapper that returns an `HDRImage` |
107
+ | `class HDRImage(anywidget.AnyWidget)` | reference display widget with an SDR-clamp toggle |
108
+
109
+ ## What hdrviz isn't
110
+
111
+ - **Plotting framework** with axes, ticks, labels, colorbars — compose with matplotlib
112
+ - **Multi-channel mixing, contrast sliders, pan/zoom, multi-resolution tiling** — compose with [viv](https://github.com/hms-dbmi/viv), ideally with HDR PNG tiles encoded by `hdrviz`
113
+ - **Animated or video HDR** — waits for `configureHighDynamicRange()` to ship in stable Chromium
114
+
115
+ ## Demo notebook
116
+
117
+ [`notebook.py`](./notebook.py) is a marimo notebook with introducing the HDR data visualization idea:
118
+
119
+ - A widget that checks your browser's HDR capabilities
120
+ - An interactive Mandelbrot explorer with HDR colormaps and click-to-zoom
121
+ - The Horsehead Nebula photographic plate from the astropy tutorials archive
122
+ - A fluorescence-microscopy frame from `scikit-image.data.cells3d`, where the membrane channel's ~150× native dynamic range is the showstopper
123
+
124
+ ```bash
125
+ git clone https://github.com/ktaletsk/hdrviz
126
+ cd hdrviz
127
+ marimo edit notebook.py --sandbox
128
+ ```
129
+
130
+ ## Browser support
131
+
132
+ Tested and works in Chromium-based browsers.
133
+ Safari mostly works, but had issues with some images not rendering in HDR.
134
+
135
+ ## License
136
+
137
+ MIT — see [LICENSE](./LICENSE).
hdrviz-0.1.0/hdrviz.py ADDED
@@ -0,0 +1,544 @@
1
+ """HDR data visualization for the browser, from numpy arrays.
2
+
3
+ Renders 2D numpy arrays as PQ Rec2020-tagged PNGs that HDR-capable browsers
4
+ composite in extended dynamic range. Includes a small library of HDR-aware
5
+ colormaps and an ``imshow``-style helper.
6
+
7
+ Tested in Chromium-based browsers (Chrome, Brave, Edge) on macOS with HDR
8
+ displays. On non-HDR displays the PNG renders correctly in standard range.
9
+
10
+ Quick start::
11
+
12
+ import numpy as np
13
+ from hdrviz import imshow
14
+
15
+ data = np.random.RandomState(0).rand(400, 600)
16
+ widget = imshow(data, cmap="inferno-hdr", peak_nits=4000)
17
+ widget # display in Jupyter / marimo
18
+
19
+ To toggle HDR rendering on or off (same pixels), set CSS
20
+ ``dynamic-range-limit: standard`` on the ``<img>`` element. The :class:`HDRImage`
21
+ widget exposes a ``clamp_to_sdr`` traitlet for this.
22
+ """
23
+
24
+ # MIT License
25
+ #
26
+ # Copyright (c) 2026 Konstantin Taletskiy
27
+ #
28
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
29
+ # of this software and associated documentation files (the "Software"), to deal
30
+ # in the Software without restriction, including without limitation the rights
31
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
32
+ # copies of the Software, and to permit persons to whom the Software is
33
+ # furnished to do so, subject to the following conditions:
34
+ #
35
+ # The above copyright notice and this permission notice shall be included in
36
+ # all copies or substantial portions of the Software.
37
+ #
38
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
39
+
40
+ from __future__ import annotations
41
+
42
+ import base64
43
+ import io
44
+ import struct
45
+ import zlib
46
+
47
+ import anywidget
48
+ import colour
49
+ import numpy as np
50
+ import traitlets
51
+ from PIL import Image
52
+
53
+ __version__ = "0.1.0"
54
+ __all__ = [
55
+ "DEFAULT_PQ_REC2020_ICC",
56
+ "COLORMAP_LIBRARY",
57
+ "extract_icc_from_png",
58
+ "linear_nits_to_pq",
59
+ "encode_hdr_png",
60
+ "to_data_url",
61
+ "hdr_colormap",
62
+ "imshow",
63
+ "hdr_imshow", # deprecated alias for imshow, removed in 0.2.0
64
+ "HDRImage",
65
+ ]
66
+
67
+
68
+ # Bundled ICC profile: "Rec2020 Gamut with PQ Transfer", 9176 bytes raw.
69
+ # This is the standard color space for HDR10 / HDR PNG / UltraHDR carriers.
70
+ # Pass icc_profile=... to encode_hdr_png to use a different one (e.g. HLG).
71
+ _DEFAULT_ICC_B64 = (
72
+ "AAAj2AAAAAAEQAAAbW50clJHQiBYWVogB+AAAQABAAAAAAAAYWNzcAAAAAAAAAAAAAAAAAAAAAAA"
73
+ "AAAAAAAAAAAAAAEAAPbWAAEAAAAA0y0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
74
+ "AAAAAAAAAAAAAAAAAAAAAAAJZGVzYwAAAPAAAABYclhZWgAAAUgAAAAUZ1hZWgAAAVwAAAAUYlhZ"
75
+ "WgAAAXAAAAAUd3RwdAAAAYQAAAAUY2ljcAAAAZgAAAAMQTJCMAAAAaQAACGoQjJBMAAAI0wAAABQ"
76
+ "Y3BydAAAI5wAAAA8bWx1YwAAAAAAAAABAAAADGVuVVMAAAA8AAAAHABSAGUAYwAyADAAMgAwACAA"
77
+ "RwBhAG0AdQB0ACAAdwBpAHQAaAAgAFAAUQAgAFQAcgBhAG4AcwBmAGUAclhZWiAAAAAAAACsaAAA"
78
+ "R2////+BWFlaIAAAAAAAACppAACs4wAAB61YWVogAAAAAAAAIAcAAAuuAADME1hZWiAAAAAAAAD2"
79
+ "1gABAAAAANMtY2ljcAAAAAAJEAABbUFCIAAAAAADAwAAAAAAIAAAIUgAACF4AAAAUAAAH5hwYXJh"
80
+ "AAAAAAAAAAAAAQAAcGFyYQAAAAAAAAAAAAEAAHBhcmEAAAAAAAAAAAABAAALCwsAAAAAAAAAAAAA"
81
+ "AAAAAgAAAAAAAAAAAAAAAAAMzQAAAAAZmgAAAAAmZgAAAAAzMwAAAABAAAAAAABMzQAAAABZmgAA"
82
+ "AABmZgAAAABzMwAAAACAAAAADM0AAAAADM0MzQAADBgZmgAAC1AmZgAACnQzMwAACYNAAAAACH5M"
83
+ "zQAAB2tZmgAABldmZgAABVNzMwAABHCAAAAAGZoAAAAAGZoMGAAAGZoZmgAAGAomZgAAFk0zMwAA"
84
+ "FGJAAAAAEkpMzQAAEA9ZmgAADctmZgAAC6RzMwAACcCAAAAAJmYAAAAAJmYLUAAAJmYYCgAAJmYm"
85
+ "ZgAAI8ozMwAAIOFAAAAAHatMzQAAGjZZmgAAFqdmZgAAEzlzMwAAEC+AAAAAMzMAAAAAMzMKdAAA"
86
+ "MzMWTQAAMzMjygAAMzMzMwAAL09AAAAAKvdMzQAAJjlZmgAAIUZmZgAAHHBzMwAAGBeAAAAAQAAA"
87
+ "AAAAQAAJgwAAQAAUYgAAQAAg4QAAQAAvTwAAQABAAAAAOo5MzQAANIVZmgAALhxmZgAAJ75zMwAA"
88
+ "Ie2AAAAATM0AAAAATM0IfgAATM0SSgAATM0dqwAATM0q9wAATM06jgAATM1MzQAARYpZmgAAPa1m"
89
+ "ZgAANbJzMwAALkSAAAAAWZoAAAAAWZoHawAAWZoQDwAAWZoaNgAAWZomOQAAWZo0hQAAWZpFigAA"
90
+ "WZpZmgAAUGhmZgAARtlzMwAAPb2AAAAAZmYAAAAAZmYGVwAAZmYNywAAZmYWpwAAZmYhRgAAZmYu"
91
+ "HAAAZmY9rQAAZmZQaAAAZmZmZgAAW31zMwAAUMqAAAAAczMAAAAAczMFUwAAczMLpAAAczMTOQAA"
92
+ "czMccAAAczMnvgAAczM1sgAAczNG2QAAczNbfQAAczNzMwAAZz6AAAAAgAAAAAAAgAAEcAAAgAAJ"
93
+ "wAAAgAAQLwAAgAAYFwAAgAAh7QAAgAAuRAAAgAA9vQAAgABQygAAgABnPgAAgACAAAzNAAAAAAzN"
94
+ "AAAMzQwYAAAZmgtQAAAmZgp0AAAzMwmDAABAAAh+AABMzQdrAABZmgZXAABmZgVTAABzMwRwAACA"
95
+ "AAzNDM0AAAzNDM0MzQwYDBgZmgtQC1AmZgp0CnQzMwmDCYNAAAh+CH5MzQdrB2tZmgZXBldmZgVT"
96
+ "BVNzMwRwBHCAAAwYGZoAAAwYGZoMGAwYGZoZmgtQGAomZgp0Fk0zMwmDFGJAAAh+EkpMzQdrEA9Z"
97
+ "mgZXDctmZgVTC6RzMwRwCcCAAAtQJmYAAAtQJmYLUAtQJmYYCgtQJmYmZgp0I8ozMwmDIOFAAAh+"
98
+ "HatMzQdrGjZZmgZXFqdmZgVTEzlzMwRwEC+AAAp0MzMAAAp0MzMKdAp0MzMWTQp0MzMjygp0MzMz"
99
+ "MwmDL09AAAh+KvdMzQdrJjlZmgZXIUZmZgVTHHBzMwRwGBeAAAmDQAAAAAmDQAAJgwmDQAAUYgmD"
100
+ "QAAg4QmDQAAvTwmDQABAAAh+Oo5MzQdrNIVZmgZXLhxmZgVTJ75zMwRwIe2AAAh+TM0AAAh+TM0I"
101
+ "fgh+TM0SSgh+TM0dqwh+TM0q9wh+TM06jgh+TM1MzQdrRYpZmgZXPa1mZgVTNbJzMwRwLkSAAAdr"
102
+ "WZoAAAdrWZoHawdrWZoQDwdrWZoaNgdrWZomOQdrWZo0hQdrWZpFigdrWZpZmgZXUGhmZgVTRtlz"
103
+ "MwRwPb2AAAZXZmYAAAZXZmYGVwZXZmYNywZXZmYWpwZXZmYhRgZXZmYuHAZXZmY9rQZXZmZQaAZX"
104
+ "ZmZmZgVTW31zMwRwUMqAAAVTczMAAAVTczMFUwVTczMLpAVTczMTOQVTczMccAVTczMnvgVTczM1"
105
+ "sgVTczNG2QVTczNbfQVTczNzMwRwZz6AAARwgAAAAARwgAAEcARwgAAJwARwgAAQLwRwgAAYFwRw"
106
+ "gAAh7QRwgAAuRARwgAA9vQRwgABQygRwgABnPgRwgACAABmaAAAAABmaAAAMGBmaAAAZmhgKAAAm"
107
+ "ZhZNAAAzMxRiAABAABJKAABMzRAPAABZmg3LAABmZgukAABzMwnAAACAABmaDBgAABmaDBgMGBma"
108
+ "DBgZmhgKC1AmZhZNCnQzMxRiCYNAABJKCH5MzRAPB2tZmg3LBldmZgukBVNzMwnABHCAABmaGZoA"
109
+ "ABmaGZoMGBmaGZoZmhgKGAomZhZNFk0zMxRiFGJAABJKEkpMzRAPEA9Zmg3LDctmZgukC6RzMwnA"
110
+ "CcCAABgKJmYAABgKJmYLUBgKJmYYChgKJmYmZhZNI8ozMxRiIOFAABJKHatMzRAPGjZZmg3LFqdm"
111
+ "ZgukEzlzMwnAEC+AABZNMzMAABZNMzMKdBZNMzMWTRZNMzMjyhZNMzMzMxRiL09AABJKKvdMzRAP"
112
+ "JjlZmg3LIUZmZgukHHBzMwnAGBeAABRiQAAAABRiQAAJgxRiQAAUYhRiQAAg4RRiQAAvTxRiQABA"
113
+ "ABJKOo5MzRAPNIVZmg3LLhxmZgukJ75zMwnAIe2AABJKTM0AABJKTM0IfhJKTM0SShJKTM0dqxJK"
114
+ "TM0q9xJKTM06jhJKTM1MzRAPRYpZmg3LPa1mZgukNbJzMwnALkSAABAPWZoAABAPWZoHaxAPWZoQ"
115
+ "DxAPWZoaNhAPWZomORAPWZo0hRAPWZpFihAPWZpZmg3LUGhmZgukRtlzMwnAPb2AAA3LZmYAAA3L"
116
+ "ZmYGVw3LZmYNyw3LZmYWpw3LZmYhRg3LZmYuHA3LZmY9rQ3LZmZQaA3LZmZmZgukW31zMwnAUMqA"
117
+ "AAukczMAAAukczMFUwukczMLpAukczMTOQukczMccAukczMnvgukczM1sgukczNG2QukczNbfQuk"
118
+ "czNzMwnAZz6AAAnAgAAAAAnAgAAEcAnAgAAJwAnAgAAQLwnAgAAYFwnAgAAh7QnAgAAuRAnAgAA9"
119
+ "vQnAgABQygnAgABnPgnAgACAACZmAAAAACZmAAALUCZmAAAYCiZmAAAmZiPKAAAzMyDhAABAAB2r"
120
+ "AABMzRo2AABZmhanAABmZhM5AABzMxAvAACAACZmC1AAACZmC1ALUCZmC1AYCiZmC1AmZiPKCnQz"
121
+ "MyDhCYNAAB2rCH5MzRo2B2tZmhanBldmZhM5BVNzMxAvBHCAACZmGAoAACZmGAoLUCZmGAoYCiZm"
122
+ "GAomZiPKFk0zMyDhFGJAAB2rEkpMzRo2EA9ZmhanDctmZhM5C6RzMxAvCcCAACZmJmYAACZmJmYL"
123
+ "UCZmJmYYCiZmJmYmZiPKI8ozMyDhIOFAAB2rHatMzRo2GjZZmhanFqdmZhM5EzlzMxAvEC+AACPK"
124
+ "MzMAACPKMzMKdCPKMzMWTSPKMzMjyiPKMzMzMyDhL09AAB2rKvdMzRo2JjlZmhanIUZmZhM5HHBz"
125
+ "MxAvGBeAACDhQAAAACDhQAAJgyDhQAAUYiDhQAAg4SDhQAAvTyDhQABAAB2rOo5MzRo2NIVZmhan"
126
+ "LhxmZhM5J75zMxAvIe2AAB2rTM0AAB2rTM0Ifh2rTM0SSh2rTM0dqx2rTM0q9x2rTM06jh2rTM1M"
127
+ "zRo2RYpZmhanPa1mZhM5NbJzMxAvLkSAABo2WZoAABo2WZoHaxo2WZoQDxo2WZoaNho2WZomORo2"
128
+ "WZo0hRo2WZpFiho2WZpZmhanUGhmZhM5RtlzMxAvPb2AABanZmYAABanZmYGVxanZmYNyxanZmYW"
129
+ "pxanZmYhRhanZmYuHBanZmY9rRanZmZQaBanZmZmZhM5W31zMxAvUMqAABM5czMAABM5czMFUxM5"
130
+ "czMLpBM5czMTORM5czMccBM5czMnvhM5czM1shM5czNG2RM5czNbfRM5czNzMxAvZz6AABAvgAAA"
131
+ "ABAvgAAEcBAvgAAJwBAvgAAQLxAvgAAYFxAvgAAh7RAvgAAuRBAvgAA9vRAvgABQyhAvgABnPhAv"
132
+ "gACAADMzAAAAADMzAAAKdDMzAAAWTTMzAAAjyjMzAAAzMy9PAABAACr3AABMzSY5AABZmiFGAABm"
133
+ "ZhxwAABzMxgXAACAADMzCnQAADMzCnQKdDMzCnQWTTMzCnQjyjMzCnQzMy9PCYNAACr3CH5MzSY5"
134
+ "B2tZmiFGBldmZhxwBVNzMxgXBHCAADMzFk0AADMzFk0KdDMzFk0WTTMzFk0jyjMzFk0zMy9PFGJA"
135
+ "ACr3EkpMzSY5EA9ZmiFGDctmZhxwC6RzMxgXCcCAADMzI8oAADMzI8oKdDMzI8oWTTMzI8ojyjMz"
136
+ "I8ozMy9PIOFAACr3HatMzSY5GjZZmiFGFqdmZhxwEzlzMxgXEC+AADMzMzMAADMzMzMKdDMzMzMW"
137
+ "TTMzMzMjyjMzMzMzMy9PL09AACr3KvdMzSY5JjlZmiFGIUZmZhxwHHBzMxgXGBeAAC9PQAAAAC9P"
138
+ "QAAJgy9PQAAUYi9PQAAg4S9PQAAvTy9PQABAACr3Oo5MzSY5NIVZmiFGLhxmZhxwJ75zMxgXIe2A"
139
+ "ACr3TM0AACr3TM0Ifir3TM0SSir3TM0dqyr3TM0q9yr3TM06jir3TM1MzSY5RYpZmiFGPa1mZhxw"
140
+ "NbJzMxgXLkSAACY5WZoAACY5WZoHayY5WZoQDyY5WZoaNiY5WZomOSY5WZo0hSY5WZpFiiY5WZpZ"
141
+ "miFGUGhmZhxwRtlzMxgXPb2AACFGZmYAACFGZmYGVyFGZmYNyyFGZmYWpyFGZmYhRiFGZmYuHCFG"
142
+ "ZmY9rSFGZmZQaCFGZmZmZhxwW31zMxgXUMqAABxwczMAABxwczMFUxxwczMLpBxwczMTORxwczMc"
143
+ "cBxwczMnvhxwczM1shxwczNG2RxwczNbfRxwczNzMxgXZz6AABgXgAAAABgXgAAEcBgXgAAJwBgX"
144
+ "gAAQLxgXgAAYFxgXgAAh7RgXgAAuRBgXgAA9vRgXgABQyhgXgABnPhgXgACAAEAAAAAAAEAAAAAJ"
145
+ "g0AAAAAUYkAAAAAg4UAAAAAvT0AAAABAADqOAABMzTSFAABZmi4cAABmZie+AABzMyHtAACAAEAA"
146
+ "CYMAAEAACYMJg0AACYMUYkAACYMg4UAACYMvT0AACYNAADqOCH5MzTSFB2tZmi4cBldmZie+BVNz"
147
+ "MyHtBHCAAEAAFGIAAEAAFGIJg0AAFGIUYkAAFGIg4UAAFGIvT0AAFGJAADqOEkpMzTSFEA9Zmi4c"
148
+ "DctmZie+C6RzMyHtCcCAAEAAIOEAAEAAIOEJg0AAIOEUYkAAIOEg4UAAIOEvT0AAIOFAADqOHatM"
149
+ "zTSFGjZZmi4cFqdmZie+EzlzMyHtEC+AAEAAL08AAEAAL08Jg0AAL08UYkAAL08g4UAAL08vT0AA"
150
+ "L09AADqOKvdMzTSFJjlZmi4cIUZmZie+HHBzMyHtGBeAAEAAQAAAAEAAQAAJg0AAQAAUYkAAQAAg"
151
+ "4UAAQAAvT0AAQABAADqOOo5MzTSFNIVZmi4cLhxmZie+J75zMyHtIe2AADqOTM0AADqOTM0IfjqO"
152
+ "TM0SSjqOTM0dqzqOTM0q9zqOTM06jjqOTM1MzTSFRYpZmi4cPa1mZie+NbJzMyHtLkSAADSFWZoA"
153
+ "ADSFWZoHazSFWZoQDzSFWZoaNjSFWZomOTSFWZo0hTSFWZpFijSFWZpZmi4cUGhmZie+RtlzMyHt"
154
+ "Pb2AAC4cZmYAAC4cZmYGVy4cZmYNyy4cZmYWpy4cZmYhRi4cZmYuHC4cZmY9rS4cZmZQaC4cZmZm"
155
+ "Zie+W31zMyHtUMqAACe+czMAACe+czMFUye+czMLpCe+czMTOSe+czMccCe+czMnvie+czM1sie+"
156
+ "czNG2Se+czNbfSe+czNzMyHtZz6AACHtgAAAACHtgAAEcCHtgAAJwCHtgAAQLyHtgAAYFyHtgAAh"
157
+ "7SHtgAAuRCHtgAA9vSHtgABQyiHtgABnPiHtgACAAEzNAAAAAEzNAAAIfkzNAAASSkzNAAAdq0zN"
158
+ "AAAq90zNAAA6jkzNAABMzUWKAABZmj2tAABmZjWyAABzMy5EAACAAEzNCH4AAEzNCH4IfkzNCH4S"
159
+ "SkzNCH4dq0zNCH4q90zNCH46jkzNCH5MzUWKB2tZmj2tBldmZjWyBVNzMy5EBHCAAEzNEkoAAEzN"
160
+ "EkoIfkzNEkoSSkzNEkodq0zNEkoq90zNEko6jkzNEkpMzUWKEA9Zmj2tDctmZjWyC6RzMy5ECcCA"
161
+ "AEzNHasAAEzNHasIfkzNHasSSkzNHasdq0zNHasq90zNHas6jkzNHatMzUWKGjZZmj2tFqdmZjWy"
162
+ "EzlzMy5EEC+AAEzNKvcAAEzNKvcIfkzNKvcSSkzNKvcdq0zNKvcq90zNKvc6jkzNKvdMzUWKJjlZ"
163
+ "mj2tIUZmZjWyHHBzMy5EGBeAAEzNOo4AAEzNOo4IfkzNOo4SSkzNOo4dq0zNOo4q90zNOo46jkzN"
164
+ "Oo5MzUWKNIVZmj2tLhxmZjWyJ75zMy5EIe2AAEzNTM0AAEzNTM0IfkzNTM0SSkzNTM0dq0zNTM0q"
165
+ "90zNTM06jkzNTM1MzUWKRYpZmj2tPa1mZjWyNbJzMy5ELkSAAEWKWZoAAEWKWZoHa0WKWZoQD0WK"
166
+ "WZoaNkWKWZomOUWKWZo0hUWKWZpFikWKWZpZmj2tUGhmZjWyRtlzMy5EPb2AAD2tZmYAAD2tZmYG"
167
+ "Vz2tZmYNyz2tZmYWpz2tZmYhRj2tZmYuHD2tZmY9rT2tZmZQaD2tZmZmZjWyW31zMy5EUMqAADWy"
168
+ "czMAADWyczMFUzWyczMLpDWyczMTOTWyczMccDWyczMnvjWyczM1sjWyczNG2TWyczNbfTWyczNz"
169
+ "My5EZz6AAC5EgAAAAC5EgAAEcC5EgAAJwC5EgAAQLy5EgAAYFy5EgAAh7S5EgAAuRC5EgAA9vS5E"
170
+ "gABQyi5EgABnPi5EgACAAFmaAAAAAFmaAAAHa1maAAAQD1maAAAaNlmaAAAmOVmaAAA0hVmaAABF"
171
+ "ilmaAABZmlBoAABmZkbZAABzMz29AACAAFmaB2sAAFmaB2sHa1maB2sQD1maB2saNlmaB2smOVma"
172
+ "B2s0hVmaB2tFilmaB2tZmlBoBldmZkbZBVNzMz29BHCAAFmaEA8AAFmaEA8Ha1maEA8QD1maEA8a"
173
+ "NlmaEA8mOVmaEA80hVmaEA9FilmaEA9ZmlBoDctmZkbZC6RzMz29CcCAAFmaGjYAAFmaGjYHa1ma"
174
+ "GjYQD1maGjYaNlmaGjYmOVmaGjY0hVmaGjZFilmaGjZZmlBoFqdmZkbZEzlzMz29EC+AAFmaJjkA"
175
+ "AFmaJjkHa1maJjkQD1maJjkaNlmaJjkmOVmaJjk0hVmaJjlFilmaJjlZmlBoIUZmZkbZHHBzMz29"
176
+ "GBeAAFmaNIUAAFmaNIUHa1maNIUQD1maNIUaNlmaNIUmOVmaNIU0hVmaNIVFilmaNIVZmlBoLhxm"
177
+ "ZkbZJ75zMz29Ie2AAFmaRYoAAFmaRYoHa1maRYoQD1maRYoaNlmaRYomOVmaRYo0hVmaRYpFilma"
178
+ "RYpZmlBoPa1mZkbZNbJzMz29LkSAAFmaWZoAAFmaWZoHa1maWZoQD1maWZoaNlmaWZomOVmaWZo0"
179
+ "hVmaWZpFilmaWZpZmlBoUGhmZkbZRtlzMz29Pb2AAFBoZmYAAFBoZmYGV1BoZmYNy1BoZmYWp1Bo"
180
+ "ZmYhRlBoZmYuHFBoZmY9rVBoZmZQaFBoZmZmZkbZW31zMz29UMqAAEbZczMAAEbZczMFU0bZczML"
181
+ "pEbZczMTOUbZczMccEbZczMnvkbZczM1skbZczNG2UbZczNbfUbZczNzMz29Zz6AAD29gAAAAD29"
182
+ "gAAEcD29gAAJwD29gAAQLz29gAAYFz29gAAh7T29gAAuRD29gAA9vT29gABQyj29gABnPj29gACA"
183
+ "AGZmAAAAAGZmAAAGV2ZmAAANy2ZmAAAWp2ZmAAAhRmZmAAAuHGZmAAA9rWZmAABQaGZmAABmZlt9"
184
+ "AABzM1DKAACAAGZmBlcAAGZmBlcGV2ZmBlcNy2ZmBlcWp2ZmBlchRmZmBlcuHGZmBlc9rWZmBldQ"
185
+ "aGZmBldmZlt9BVNzM1DKBHCAAGZmDcsAAGZmDcsGV2ZmDcsNy2ZmDcsWp2ZmDcshRmZmDcsuHGZm"
186
+ "Dcs9rWZmDctQaGZmDctmZlt9C6RzM1DKCcCAAGZmFqcAAGZmFqcGV2ZmFqcNy2ZmFqcWp2ZmFqch"
187
+ "RmZmFqcuHGZmFqc9rWZmFqdQaGZmFqdmZlt9EzlzM1DKEC+AAGZmIUYAAGZmIUYGV2ZmIUYNy2Zm"
188
+ "IUYWp2ZmIUYhRmZmIUYuHGZmIUY9rWZmIUZQaGZmIUZmZlt9HHBzM1DKGBeAAGZmLhwAAGZmLhwG"
189
+ "V2ZmLhwNy2ZmLhwWp2ZmLhwhRmZmLhwuHGZmLhw9rWZmLhxQaGZmLhxmZlt9J75zM1DKIe2AAGZm"
190
+ "Pa0AAGZmPa0GV2ZmPa0Ny2ZmPa0Wp2ZmPa0hRmZmPa0uHGZmPa09rWZmPa1QaGZmPa1mZlt9NbJz"
191
+ "M1DKLkSAAGZmUGgAAGZmUGgGV2ZmUGgNy2ZmUGgWp2ZmUGghRmZmUGguHGZmUGg9rWZmUGhQaGZm"
192
+ "UGhmZlt9RtlzM1DKPb2AAGZmZmYAAGZmZmYGV2ZmZmYNy2ZmZmYWp2ZmZmYhRmZmZmYuHGZmZmY9"
193
+ "rWZmZmZQaGZmZmZmZlt9W31zM1DKUMqAAFt9czMAAFt9czMFU1t9czMLpFt9czMTOVt9czMccFt9"
194
+ "czMnvlt9czM1slt9czNG2Vt9czNbfVt9czNzM1DKZz6AAFDKgAAAAFDKgAAEcFDKgAAJwFDKgAAQ"
195
+ "L1DKgAAYF1DKgAAh7VDKgAAuRFDKgAA9vVDKgABQylDKgABnPlDKgACAAHMzAAAAAHMzAAAFU3Mz"
196
+ "AAALpHMzAAATOXMzAAAccHMzAAAnvnMzAAA1snMzAABG2XMzAABbfXMzAABzM2c+AACAAHMzBVMA"
197
+ "AHMzBVMFU3MzBVMLpHMzBVMTOXMzBVMccHMzBVMnvnMzBVM1snMzBVNG2XMzBVNbfXMzBVNzM2c+"
198
+ "BHCAAHMzC6QAAHMzC6QFU3MzC6QLpHMzC6QTOXMzC6QccHMzC6QnvnMzC6Q1snMzC6RG2XMzC6Rb"
199
+ "fXMzC6RzM2c+CcCAAHMzEzkAAHMzEzkFU3MzEzkLpHMzEzkTOXMzEzkccHMzEzknvnMzEzk1snMz"
200
+ "EzlG2XMzEzlbfXMzEzlzM2c+EC+AAHMzHHAAAHMzHHAFU3MzHHALpHMzHHATOXMzHHAccHMzHHAn"
201
+ "vnMzHHA1snMzHHBG2XMzHHBbfXMzHHBzM2c+GBeAAHMzJ74AAHMzJ74FU3MzJ74LpHMzJ74TOXMz"
202
+ "J74ccHMzJ74nvnMzJ741snMzJ75G2XMzJ75bfXMzJ75zM2c+Ie2AAHMzNbIAAHMzNbIFU3MzNbIL"
203
+ "pHMzNbITOXMzNbIccHMzNbInvnMzNbI1snMzNbJG2XMzNbJbfXMzNbJzM2c+LkSAAHMzRtkAAHMz"
204
+ "RtkFU3MzRtkLpHMzRtkTOXMzRtkccHMzRtknvnMzRtk1snMzRtlG2XMzRtlbfXMzRtlzM2c+Pb2A"
205
+ "AHMzW30AAHMzW30FU3MzW30LpHMzW30TOXMzW30ccHMzW30nvnMzW301snMzW31G2XMzW31bfXMz"
206
+ "W31zM2c+UMqAAHMzczMAAHMzczMFU3MzczMLpHMzczMTOXMzczMccHMzczMnvnMzczM1snMzczNG"
207
+ "2XMzczNbfXMzczNzM2c+Zz6AAGc+gAAAAGc+gAAEcGc+gAAJwGc+gAAQL2c+gAAYF2c+gAAh7Wc+"
208
+ "gAAuRGc+gAA9vWc+gABQymc+gABnPmc+gACAAIAAAAAAAIAAAAAEcIAAAAAJwIAAAAAQL4AAAAAY"
209
+ "F4AAAAAh7YAAAAAuRIAAAAA9vYAAAABQyoAAAABnPoAAAACAAIAABHAAAIAABHAEcIAABHAJwIAA"
210
+ "BHAQL4AABHAYF4AABHAh7YAABHAuRIAABHA9vYAABHBQyoAABHBnPoAABHCAAIAACcAAAIAACcAE"
211
+ "cIAACcAJwIAACcAQL4AACcAYF4AACcAh7YAACcAuRIAACcA9vYAACcBQyoAACcBnPoAACcCAAIAA"
212
+ "EC8AAIAAEC8EcIAAEC8JwIAAEC8QL4AAEC8YF4AAEC8h7YAAEC8uRIAAEC89vYAAEC9QyoAAEC9n"
213
+ "PoAAEC+AAIAAGBcAAIAAGBcEcIAAGBcJwIAAGBcQL4AAGBcYF4AAGBch7YAAGBcuRIAAGBc9vYAA"
214
+ "GBdQyoAAGBdnPoAAGBeAAIAAIe0AAIAAIe0EcIAAIe0JwIAAIe0QL4AAIe0YF4AAIe0h7YAAIe0u"
215
+ "RIAAIe09vYAAIe1QyoAAIe1nPoAAIe2AAIAALkQAAIAALkQEcIAALkQJwIAALkQQL4AALkQYF4AA"
216
+ "LkQh7YAALkQuRIAALkQ9vYAALkRQyoAALkRnPoAALkSAAIAAPb0AAIAAPb0EcIAAPb0JwIAAPb0Q"
217
+ "L4AAPb0YF4AAPb0h7YAAPb0uRIAAPb09vYAAPb1QyoAAPb1nPoAAPb2AAIAAUMoAAIAAUMoEcIAA"
218
+ "UMoJwIAAUMoQL4AAUMoYF4AAUMoh7YAAUMouRIAAUMo9vYAAUMpQyoAAUMpnPoAAUMqAAIAAZz4A"
219
+ "AIAAZz4EcIAAZz4JwIAAZz4QL4AAZz4YF4AAZz4h7YAAZz4uRIAAZz49vYAAZz5QyoAAZz5nPoAA"
220
+ "Zz6AAIAAgAAAAIAAgAAEcIAAgAAJwIAAgAAQL4AAgAAYF4AAgAAh7YAAgAAuRIAAgAA9vYAAgABQ"
221
+ "yoAAgABnPoAAgACAAAAAY3VydgAAAAAAAABBAAAAAgAHABEAIAA4AFgAhAC/AQoBaQHhAnYDLQQK"
222
+ "BRUGVAfPCY8LnA4DEMQT+hefG8UgZSWeK3cx5DjQQIRItlF+WrdkfG56eNuDio5UmUOkSK8yukPF"
223
+ "VNBn27HnHPK9/t7//////////////////////////////////////////wAAY3VydgAAAAAAAABB"
224
+ "AAAAAgAHABEAIAA4AFgAhAC/AQoBaQHhAnYDLQQKBRUGVAfPCY8LnA4DEMQT+hefG8UgZSWeK3cx"
225
+ "5DjQQIRItlF+WrdkfG56eNuDio5UmUOkSK8yukPFVNBn27HnHPK9/t7/////////////////////"
226
+ "/////////////////////wAAY3VydgAAAAAAAABBAAAAAgAHABEAIAA4AFgAhAC/AQoBaQHhAnYD"
227
+ "LQQKBRUGVAfPCY8LnA4DEMQT+hefG8UgZSWeK3cx5DjQQIRItlF+WrdkfG56eNuDio5UmUOkSK8y"
228
+ "ukPFVNBn27HnHPK9/t7//////////////////////////////////////////wAAAACsaAAAKmkA"
229
+ "ACAHAABHbwAArOMAAAuu////gQAAB60AAMwTAAAAAAAAAAAAAAAAcGFyYQAAAAAAAAAAAAEAAHBh"
230
+ "cmEAAAAAAAAAAAABAABwYXJhAAAAAAAAAAAAAQAAbUJBIAAAAAADAwAAAAAAIAAAAAAAAAAAAAAA"
231
+ "AAAAAABwYXJhAAAAAAAAAAAAAQAAcGFyYQAAAAAAAAAAAAEAAHBhcmEAAAAAAAAAAAABAABtbHVj"
232
+ "AAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADY="
233
+ )
234
+ DEFAULT_PQ_REC2020_ICC: bytes = base64.b64decode("".join(_DEFAULT_ICC_B64))
235
+
236
+
237
+ def extract_icc_from_png(png_bytes: bytes) -> bytes | None:
238
+ """Return the decompressed ICC profile from a PNG's iCCP chunk, or ``None``."""
239
+ if png_bytes[:8] != b"\x89PNG\r\n\x1a\n":
240
+ return None
241
+ i = 8
242
+ while i < len(png_bytes):
243
+ length = struct.unpack(">I", png_bytes[i : i + 4])[0]
244
+ ctype = png_bytes[i + 4 : i + 8]
245
+ payload = png_bytes[i + 8 : i + 8 + length]
246
+ if ctype == b"iCCP":
247
+ nul = payload.index(b"\x00")
248
+ return zlib.decompress(payload[nul + 2 :])
249
+ if ctype == b"IEND":
250
+ return None
251
+ i += 8 + length + 4
252
+ return None
253
+
254
+
255
+ def linear_nits_to_pq(rgb_nits: np.ndarray) -> np.ndarray:
256
+ """Inverse PQ EOTF (SMPTE ST 2084).
257
+
258
+ Args:
259
+ rgb_nits: Linear luminance in cd/m^2 (nits). Any shape; clipped to [0, 10000].
260
+
261
+ Returns:
262
+ PQ-encoded code values in [0, 1], same shape as input.
263
+ """
264
+ return colour.models.eotf_inverse_ST2084(np.clip(rgb_nits, 0.0, 10000.0))
265
+
266
+
267
+ def encode_hdr_png(
268
+ rgb_nits: np.ndarray,
269
+ icc_profile: bytes = DEFAULT_PQ_REC2020_ICC,
270
+ ) -> bytes:
271
+ """Encode a (H, W, 3) array of linear-light RGB nits as a PQ-tagged PNG.
272
+
273
+ The returned bytes are an 8-bit RGB PNG with an embedded ICC profile (Rec2020
274
+ primaries, PQ transfer by default). HDR-capable browsers will composite this
275
+ in extended dynamic range; SDR browsers render it tone-mapped.
276
+ """
277
+ pq = linear_nits_to_pq(rgb_nits)
278
+ pq8 = np.clip(pq * 255.0 + 0.5, 0, 255).astype(np.uint8)
279
+ img = Image.fromarray(pq8, mode="RGB")
280
+ buf = io.BytesIO()
281
+ img.save(buf, format="PNG", icc_profile=icc_profile)
282
+ return buf.getvalue()
283
+
284
+
285
+ def to_data_url(png_bytes: bytes) -> str:
286
+ """Wrap PNG bytes in a ``data:`` URL suitable for an ``<img src=...>``."""
287
+ return "data:image/png;base64," + base64.b64encode(png_bytes).decode("ascii")
288
+
289
+
290
+ # HDR-aware colormaps. (norm, R, G, B) control points; channel values can
291
+ # exceed 1.0 to push above ``peak_nits`` — that is how the visible glow happens.
292
+ COLORMAP_LIBRARY: dict[str, np.ndarray] = {
293
+ "fire-purple": np.array([
294
+ [0.00, 0.000, 0.000, 0.000],
295
+ [0.05, 0.020, 0.000, 0.060],
296
+ [0.20, 0.080, 0.000, 0.180],
297
+ [0.40, 0.350, 0.020, 0.280],
298
+ [0.55, 0.700, 0.150, 0.150],
299
+ [0.70, 0.950, 0.450, 0.080],
300
+ [0.85, 1.000, 0.850, 0.250],
301
+ [0.95, 1.000, 1.000, 0.700],
302
+ [1.00, 1.000, 1.000, 0.950],
303
+ ]),
304
+ "ice": np.array([
305
+ [0.00, 0.000, 0.000, 0.000],
306
+ [0.10, 0.000, 0.020, 0.080],
307
+ [0.30, 0.020, 0.150, 0.400],
308
+ [0.55, 0.100, 0.500, 0.900],
309
+ [0.75, 0.500, 0.900, 1.000],
310
+ [0.90, 1.000, 1.100, 1.150],
311
+ [1.00, 1.300, 1.300, 1.250],
312
+ ]),
313
+ "twilight-burst": np.array([
314
+ [0.00, 0.000, 0.000, 0.000],
315
+ [0.10, 0.080, 0.000, 0.150],
316
+ [0.30, 0.400, 0.040, 0.500],
317
+ [0.55, 0.900, 0.300, 0.300],
318
+ [0.75, 1.100, 0.700, 0.150],
319
+ [0.90, 1.250, 1.100, 0.450],
320
+ [1.00, 1.300, 1.300, 1.000],
321
+ ]),
322
+ "matrix-green": np.array([
323
+ [0.00, 0.000, 0.000, 0.000],
324
+ [0.20, 0.000, 0.080, 0.020],
325
+ [0.50, 0.040, 0.500, 0.080],
326
+ [0.75, 0.150, 1.000, 0.250],
327
+ [0.90, 0.500, 1.300, 0.500],
328
+ [1.00, 1.000, 1.500, 1.000],
329
+ ]),
330
+ "ember": np.array([
331
+ [0.00, 0.000, 0.000, 0.000],
332
+ [0.30, 0.300, 0.020, 0.000],
333
+ [0.55, 0.700, 0.080, 0.000],
334
+ [0.75, 1.000, 0.350, 0.020],
335
+ [0.88, 1.150, 0.700, 0.150],
336
+ [0.97, 1.250, 1.100, 0.500],
337
+ [1.00, 1.300, 1.250, 0.900],
338
+ ]),
339
+ "viridis-hdr": np.array([
340
+ [0.00, 0.267, 0.005, 0.329],
341
+ [0.20, 0.281, 0.165, 0.476],
342
+ [0.40, 0.254, 0.265, 0.530],
343
+ [0.60, 0.207, 0.372, 0.553],
344
+ [0.80, 0.435, 0.643, 0.422],
345
+ [0.90, 0.770, 0.902, 0.245],
346
+ [0.97, 1.050, 1.150, 0.450],
347
+ [1.00, 1.250, 1.350, 0.700],
348
+ ]),
349
+ "inferno-hdr": np.array([
350
+ [0.00, 0.001, 0.000, 0.014],
351
+ [0.20, 0.218, 0.041, 0.378],
352
+ [0.40, 0.580, 0.149, 0.404],
353
+ [0.60, 0.866, 0.317, 0.226],
354
+ [0.75, 0.988, 0.557, 0.094],
355
+ [0.88, 1.000, 0.860, 0.250],
356
+ [0.97, 1.150, 1.150, 0.620],
357
+ [1.00, 1.300, 1.300, 0.950],
358
+ ]),
359
+ }
360
+
361
+
362
+ def hdr_colormap(
363
+ norm: np.ndarray,
364
+ cmap_name: str = "fire-purple",
365
+ peak_nits: float = 4000.0,
366
+ ) -> np.ndarray:
367
+ """Map normalized [0, 1] values to RGB linear nits via a named colormap.
368
+
369
+ Args:
370
+ norm: Array of values in [0, 1]. Any shape.
371
+ cmap_name: Key from :data:`COLORMAP_LIBRARY`.
372
+ peak_nits: Linear-light scale. A colormap channel value of 1.0 maps to
373
+ this many nits; values above 1.0 push proportionally higher.
374
+
375
+ Returns:
376
+ An array shaped ``norm.shape + (3,)`` in linear cd/m^2 (nits).
377
+ """
378
+ pts = COLORMAP_LIBRARY[cmap_name]
379
+ R = np.interp(norm, pts[:, 0], pts[:, 1]) * peak_nits
380
+ G = np.interp(norm, pts[:, 0], pts[:, 2]) * peak_nits
381
+ B = np.interp(norm, pts[:, 0], pts[:, 3]) * peak_nits
382
+ return np.stack([R, G, B], axis=-1)
383
+
384
+
385
+ def imshow(
386
+ arr: np.ndarray,
387
+ cmap: str = "fire-purple",
388
+ peak_nits: float = 4000.0,
389
+ normalize: str = "linear",
390
+ vmin: float | None = None,
391
+ vmax: float | None = None,
392
+ clip_percentile: tuple[float, float] | None = None,
393
+ interior_mask: np.ndarray | None = None,
394
+ label: str = "",
395
+ ) -> "HDRImage":
396
+ """Render a 2D numpy array as an HDR image. Returns an :class:`HDRImage` widget.
397
+
398
+ Conceptually a tiny ``matplotlib.imshow`` analogue, but pixels are PQ Rec2020-
399
+ encoded so a capable browser composites them in extended dynamic range.
400
+
401
+ Args:
402
+ arr: ``(H, W)`` float-like array. ``NaN``/``Inf`` values are treated as
403
+ interior (rendered black).
404
+ cmap: Key from :data:`COLORMAP_LIBRARY`.
405
+ peak_nits: Luminance scale; cmap channel value 1.0 maps to this.
406
+ normalize: How to map values to [0, 1]:
407
+
408
+ - ``"linear"``: ``(v - vmin) / (vmax - vmin)``
409
+ - ``"log"``: ``log1p((v - vmin) + tiny) / log1p((vmax - vmin) + tiny)``
410
+ - ``"sqrt"``: square root of linear
411
+
412
+ Default is linear; for HDR data viz, prefer linear or pre-stretch your
413
+ data with ``np.log1p``/``np.sqrt`` rather than reaching for log here.
414
+ vmin, vmax: Explicit data range. If unset, derived from data.
415
+ clip_percentile: Optional ``(lo, hi)`` percentile pair to derive
416
+ ``vmin``/``vmax`` robustly (e.g. ``(0.5, 99.5)`` to ignore outliers).
417
+ interior_mask: Optional bool array same shape as ``arr``; ``True`` pixels
418
+ render as black. Useful for fractal interiors, NaN regions, etc.
419
+ label: Caption shown above the rendered image in the widget.
420
+ """
421
+ if arr.ndim != 2:
422
+ raise ValueError(f"hdr_imshow expects a 2D array, got shape {arr.shape}")
423
+ if cmap not in COLORMAP_LIBRARY:
424
+ raise ValueError(
425
+ f"unknown cmap {cmap!r}; choose from {list(COLORMAP_LIBRARY)}"
426
+ )
427
+
428
+ A = np.asarray(arr, dtype=np.float64).copy()
429
+ finite = np.isfinite(A)
430
+ if interior_mask is None:
431
+ interior_mask = np.zeros_like(A, dtype=bool)
432
+ else:
433
+ interior_mask = np.asarray(interior_mask, dtype=bool)
434
+ if interior_mask.shape != A.shape:
435
+ raise ValueError("interior_mask must match arr shape")
436
+
437
+ treat_as_interior = interior_mask | ~finite
438
+ A[~finite] = 0.0
439
+
440
+ sample = A[finite & ~interior_mask]
441
+ if sample.size == 0:
442
+ vmin_eff = 0.0 if vmin is None else float(vmin)
443
+ vmax_eff = 1.0 if vmax is None else float(vmax)
444
+ elif clip_percentile is not None:
445
+ lo, hi = clip_percentile
446
+ vmin_eff = float(np.percentile(sample, lo)) if vmin is None else float(vmin)
447
+ vmax_eff = float(np.percentile(sample, hi)) if vmax is None else float(vmax)
448
+ else:
449
+ vmin_eff = float(sample.min()) if vmin is None else float(vmin)
450
+ vmax_eff = float(sample.max()) if vmax is None else float(vmax)
451
+
452
+ if not np.isfinite(vmin_eff) or not np.isfinite(vmax_eff) or vmax_eff <= vmin_eff:
453
+ vmin_eff, vmax_eff = 0.0, 1.0
454
+
455
+ A_clipped = np.clip(A, vmin_eff, vmax_eff)
456
+ span = vmax_eff - vmin_eff
457
+
458
+ if normalize == "linear":
459
+ norm = (A_clipped - vmin_eff) / span
460
+ elif normalize == "log":
461
+ eps = 1e-9 * span
462
+ norm = np.log1p(A_clipped - vmin_eff + eps) / np.log1p(span + eps)
463
+ elif normalize == "sqrt":
464
+ norm = np.sqrt((A_clipped - vmin_eff) / span)
465
+ else:
466
+ raise ValueError(f"unknown normalize={normalize!r}")
467
+
468
+ norm = np.clip(norm, 0.0, 1.0)
469
+ norm[treat_as_interior] = 0.0
470
+
471
+ rgb_nits = hdr_colormap(norm, cmap_name=cmap, peak_nits=peak_nits)
472
+ rgb_nits[treat_as_interior] = 0.0
473
+
474
+ png = encode_hdr_png(rgb_nits)
475
+ return HDRImage(image_data_url=to_data_url(png), label=label)
476
+
477
+
478
+
479
+ def hdr_imshow(*args, **kwargs):
480
+ """Deprecated alias for :func:`imshow`. Will be removed in 0.2.0.
481
+
482
+ Emits :class:`DeprecationWarning` (silent by default in CPython; surface
483
+ via ``python -W error::DeprecationWarning`` or pytest).
484
+ """
485
+ import warnings
486
+ warnings.warn(
487
+ "hdr_imshow is deprecated, use imshow instead. "
488
+ "This alias will be removed in v0.2.0.",
489
+ DeprecationWarning,
490
+ stacklevel=2,
491
+ )
492
+ return imshow(*args, **kwargs)
493
+
494
+
495
+ class HDRImage(anywidget.AnyWidget):
496
+ """Anywidget that displays an HDR-encoded image with a CSS-clamp toggle.
497
+
498
+ Setting ``clamp_to_sdr=True`` applies ``dynamic-range-limit: standard`` to
499
+ the ``<img>``, making the same pixels render in SDR. This is the cleanest
500
+ A/B for showing HDR's contribution: same image, same display, one CSS
501
+ property apart.
502
+ """
503
+
504
+ image_data_url = traitlets.Unicode("").tag(sync=True)
505
+ label = traitlets.Unicode("").tag(sync=True)
506
+ clamp_to_sdr = traitlets.Bool(False).tag(sync=True)
507
+
508
+ _esm = r'''
509
+ function render({ model, el }) {
510
+ function rebuild() {
511
+ const url = model.get("image_data_url");
512
+ const label = model.get("label");
513
+ const clamp = model.get("clamp_to_sdr");
514
+ el.innerHTML = `
515
+ <style>
516
+ .hi-card { font-family: system-ui, -apple-system, sans-serif; color: inherit;
517
+ border: 1px solid color-mix(in srgb, currentColor 20%, transparent);
518
+ border-radius: 12px; padding: 12px; display: grid; gap: 8px; }
519
+ .hi-label { font-size: 12px; opacity: 0.8; display:flex; gap:8px; align-items:center; }
520
+ .hi-label .tag { font-family: ui-monospace, SFMono-Regular, monospace; font-size: 11px;
521
+ padding: 2px 6px; border-radius: 4px;
522
+ background: color-mix(in srgb, currentColor 10%, transparent); }
523
+ .hi-img-wrap { background:#000; border-radius:8px; overflow:hidden; display:flex;
524
+ justify-content:center; align-items:center; }
525
+ .hi-img-wrap img { max-width:100%; height:auto; display:block; }
526
+ </style>
527
+ <div class="hi-card">
528
+ <div class="hi-label">${label}
529
+ <span class="tag">dynamic-range-limit: ${clamp ? "standard" : "no-limit"}</span>
530
+ </div>
531
+ <div class="hi-img-wrap">
532
+ <img src="${url}" alt="${label}"
533
+ style="${clamp ? "dynamic-range-limit: standard;" : ""}">
534
+ </div>
535
+ </div>
536
+ `;
537
+ }
538
+ rebuild();
539
+ model.on("change:clamp_to_sdr", rebuild);
540
+ model.on("change:image_data_url", rebuild);
541
+ model.on("change:label", rebuild);
542
+ }
543
+ export default { render };
544
+ '''
@@ -0,0 +1,66 @@
1
+ [project]
2
+ name = "hdrviz"
3
+ dynamic = ["version"]
4
+ description = "HDR data visualization for the browser, from numpy arrays."
5
+ authors = [
6
+ {name = "Konstantin Taletskiy", email = "konstantin@taletskiy.com"},
7
+ ]
8
+ license = "MIT"
9
+ license-files = ["LICENSE"]
10
+ readme = "README.md"
11
+ requires-python = ">=3.11"
12
+ keywords = [
13
+ "hdr",
14
+ "visualization",
15
+ "numpy",
16
+ "anywidget",
17
+ "jupyter",
18
+ "marimo",
19
+ "rec2020",
20
+ "pq",
21
+ "smpte-2084",
22
+ ]
23
+ classifiers = [
24
+ "Development Status :: 4 - Beta",
25
+ "Intended Audience :: Science/Research",
26
+ "License :: OSI Approved :: MIT License",
27
+ "Operating System :: OS Independent",
28
+ "Programming Language :: Python :: 3",
29
+ "Programming Language :: Python :: 3.11",
30
+ "Programming Language :: Python :: 3.12",
31
+ "Programming Language :: Python :: 3.13",
32
+ "Programming Language :: Python :: 3.14",
33
+ "Topic :: Scientific/Engineering :: Visualization",
34
+ "Topic :: Multimedia :: Graphics",
35
+ "Framework :: Jupyter",
36
+ ]
37
+ dependencies = [
38
+ "anywidget>=0.9",
39
+ "colour-science>=0.4",
40
+ "numpy>=1.24",
41
+ "pillow>=10",
42
+ "traitlets>=5",
43
+ ]
44
+
45
+ [project.optional-dependencies]
46
+ dev = [
47
+ "pytest>=7",
48
+ ]
49
+
50
+ [project.urls]
51
+ Homepage = "https://github.com/ktaletsk/hdrviz"
52
+ Repository = "https://github.com/ktaletsk/hdrviz"
53
+ Issues = "https://github.com/ktaletsk/hdrviz/issues"
54
+
55
+ [build-system]
56
+ requires = ["hatchling"]
57
+ build-backend = "hatchling.build"
58
+
59
+ [tool.hatch.version]
60
+ path = "hdrviz.py"
61
+
62
+ [tool.hatch.build.targets.wheel]
63
+ only-include = ["hdrviz.py"]
64
+
65
+ [tool.hatch.build.targets.sdist]
66
+ only-include = ["hdrviz.py", "README.md", "LICENSE", "pyproject.toml"]