@realsee/hdr-toolbox 1.0.3 → 1.1.1
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.
- package/README.md +54 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +41 -1
- package/dist/cli.js.map +1 -1
- package/dist/convert.d.ts +64 -0
- package/dist/convert.d.ts.map +1 -0
- package/dist/convert.js +157 -0
- package/dist/convert.js.map +1 -0
- package/dist/exr.d.ts +26 -0
- package/dist/exr.d.ts.map +1 -0
- package/dist/exr.js +291 -0
- package/dist/exr.js.map +1 -0
- package/dist/hdr.d.ts +6 -0
- package/dist/hdr.d.ts.map +1 -0
- package/dist/hdr.js +263 -0
- package/dist/hdr.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/tonemap.d.ts +46 -0
- package/dist/tonemap.d.ts.map +1 -0
- package/dist/tonemap.js +369 -0
- package/dist/tonemap.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -87,7 +87,43 @@ hdr-toolbox cube-to-equirect \
|
|
|
87
87
|
|
|
88
88
|
SDR 文件名为 `<prefix>_[r,l,u,d,f,b].jpg`。gain map 同时兼容 `<prefix>_<face>_gainmap.jpg` 和示例里的 `<prefix>_<face>.gainmap.jpg`。配置自动读取输入目录下的 `<prefix>_gainmap_cfg.json`(找不到时回退 `<prefix>_gainmap_cfg.xmp`)。六面必须是同尺寸、正方形且边长为 2 的幂。输出尺寸是面宽的 4×2 倍。
|
|
89
89
|
|
|
90
|
-
### 4.
|
|
90
|
+
### 4. 线性 HDR(EXR / Radiance HDR)↔ Ultra HDR
|
|
91
|
+
|
|
92
|
+
`convert` 在线性浮点 HDR 文件和 Ultra HDR JPEG 之间互转,方向由输入/输出扩展名推断:一侧是线性 HDR(`.exr` 或 `.hdr`/`.pic`),另一侧是 Ultra HDR(`.jpg`/`.jpeg`)。
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# Ultra HDR → EXR:按增益图重建线性 HDR,写成 32-bit float EXR
|
|
96
|
+
hdr-toolbox convert --input examples/ultra-hdr.jpg --output output/ultra-hdr.exr
|
|
97
|
+
|
|
98
|
+
# Ultra HDR → Radiance HDR:同样的重建,写成 RGBE 编码的 .hdr(体积更小)
|
|
99
|
+
hdr-toolbox convert --input examples/ultra-hdr.jpg --output output/ultra-hdr.hdr
|
|
100
|
+
|
|
101
|
+
# EXR / HDR → Ultra HDR:色调映射出 SDR 基图,反算增益图,封装成 Ultra HDR
|
|
102
|
+
hdr-toolbox convert --input output/ultra-hdr.exr --output output/from-exr.uhdr.jpg
|
|
103
|
+
hdr-toolbox convert --input output/ultra-hdr.hdr --output output/from-hdr.uhdr.jpg
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
支持两种线性 HDR 容器:
|
|
107
|
+
|
|
108
|
+
- **EXR**(OpenEXR):读取支持 HALF/FLOAT 通道、NO_COMPRESSION 与 ZIP/ZIPS 压缩;写入固定为单层、未压缩的 scanline FLOAT RGB,任意 EXR 读取器都能打开。
|
|
109
|
+
- **Radiance HDR**(RGBE,`.hdr`/`.pic`):读取支持 flat、旧式与新式 RLE 编码;写入新式 RLE。RGBE 的共享指数带来 ~0.4% 的量化,但体积明显小于未压缩 EXR。
|
|
110
|
+
|
|
111
|
+
`Ultra HDR → 线性 HDR` 按 Adobe/Android 增益图恢复公式逐像素重建,在满显示余量(weight = 1)下还原完整 HDR 意图:`hdr = (sdr_linear + offset_sdr) * 2^lerp(log2(min), log2(max), gain^(1/gamma)) - offset_hdr`。
|
|
112
|
+
|
|
113
|
+
`线性 HDR → Ultra HDR` 先把线性 HDR 色调映射成 SDR 基图,再把 `HDR/SDR` 比值编码成增益图。默认用**曝光融合**(`fusion`):从单张 HDR 合成多档虚拟曝光,按 Mertens 权重(对比度 × 饱和度 × 曝光适中度)在拉普拉斯金字塔上融合——这是一种隐式的局部色调映射,能同时保住暗部和高光细节且不产生光晕。也可切回全局 `reinhard` 曲线。可选项(仅此方向生效):
|
|
114
|
+
|
|
115
|
+
| 选项 | 说明 |
|
|
116
|
+
| --------------------- | --------------------------------------------------------- |
|
|
117
|
+
| `--tone-map` | SDR 色调映射:`fusion`(默认,局部)或 `reinhard`(全局) |
|
|
118
|
+
| `--ev-step` | 曝光融合的档间距(stops,默认 2) |
|
|
119
|
+
| `--exposure-count` | 曝光融合的合成曝光数,奇数(默认 5) |
|
|
120
|
+
| `--max-content-boost` | 要编码的线性 HDR 余量,默认取输入中的最大线性值 |
|
|
121
|
+
| `--sdr-quality` | SDR 基图 JPEG 质量(1-100,默认 95) |
|
|
122
|
+
| `--gainmap-quality` | 增益图 JPEG 质量(1-100,默认 95) |
|
|
123
|
+
|
|
124
|
+
> 曝光融合是全图金字塔运算,对大图(如 8K 全景)内存和耗时都明显高于 `reinhard`;离线转换可接受,追求速度可用 `--tone-map reinhard`。
|
|
125
|
+
|
|
126
|
+
### 5. equirect Ultra HDR → cubemap
|
|
91
127
|
|
|
92
128
|
```bash
|
|
93
129
|
hdr-toolbox equirect-to-cube \
|
|
@@ -118,6 +154,23 @@ await extractUltraHdr({
|
|
|
118
154
|
});
|
|
119
155
|
```
|
|
120
156
|
|
|
157
|
+
线性 HDR 互转(EXR / Radiance HDR,方向中立的函数名;旧的 `exrToUltraHdr` / `ultraHdrToExr` 作为别名保留):
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
import { linearHdrToUltraHdr, ultraHdrToLinearHdr } from "@realsee/hdr-toolbox";
|
|
161
|
+
|
|
162
|
+
// 输出格式由扩展名推断:.exr 或 .hdr
|
|
163
|
+
await ultraHdrToLinearHdr({ input: "image.uhdr.jpg", output: "image.hdr" });
|
|
164
|
+
|
|
165
|
+
await linearHdrToUltraHdr({
|
|
166
|
+
input: "image.exr",
|
|
167
|
+
output: "image.uhdr.jpg",
|
|
168
|
+
maxContentBoost: 8, // 可选,不填则按输入峰值自动推断
|
|
169
|
+
});
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
底层的编解码函数 `readExr` / `writeExr` 和 `readHdr` / `writeHdr` 也一并导出,都以交错的线性浮点 RGB(`LinearHdrImage`)作为统一的像素表示。
|
|
173
|
+
|
|
121
174
|
## 校验
|
|
122
175
|
|
|
123
176
|
```bash
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,wBAAgB,aAAa,IAAI,OAAO,CAkJvC"}
|
package/dist/cli.js
CHANGED
|
@@ -2,14 +2,19 @@
|
|
|
2
2
|
import { Command } from "commander";
|
|
3
3
|
import { realpathSync } from "node:fs";
|
|
4
4
|
import { pathToFileURL } from "node:url";
|
|
5
|
+
import { linearHdrToUltraHdr, ultraHdrToLinearHdr } from "./convert.js";
|
|
5
6
|
import { cubeToEquirectUltraHdr, equirectUltraHdrToCube } from "./panorama.js";
|
|
6
7
|
import { composeUltraHdr, extractUltraHdr } from "./ultrahdr.js";
|
|
8
|
+
/** Linear HDR float containers accepted on one side of `convert`. */
|
|
9
|
+
function isLinearHdrPath(path) {
|
|
10
|
+
return /\.(exr|hdr|pic)$/i.test(path);
|
|
11
|
+
}
|
|
7
12
|
export function createProgram() {
|
|
8
13
|
const program = new Command();
|
|
9
14
|
program
|
|
10
15
|
.name("hdr-toolbox")
|
|
11
16
|
.description("Compose, extract, and convert Android Ultra HDR JPEG images")
|
|
12
|
-
.version("1.
|
|
17
|
+
.version("1.1.1");
|
|
13
18
|
program
|
|
14
19
|
.command("compose")
|
|
15
20
|
.description("Compose an SDR image, gain map image (avif/png/jpg/jpeg), and JSON/XMP config into Ultra HDR")
|
|
@@ -68,6 +73,41 @@ export function createProgram() {
|
|
|
68
73
|
prefix: options.prefix,
|
|
69
74
|
});
|
|
70
75
|
});
|
|
76
|
+
program
|
|
77
|
+
.command("convert")
|
|
78
|
+
.description("Convert between a linear HDR file (.exr or .hdr) and an Ultra HDR JPEG (direction inferred from extensions)")
|
|
79
|
+
.requiredOption("-i, --input <path>", "input image (.exr, .hdr, or Ultra HDR .jpg/.jpeg)")
|
|
80
|
+
.requiredOption("-o, --output <path>", "output image (.exr, .hdr, or Ultra HDR .jpg/.jpeg)")
|
|
81
|
+
.option("--max-content-boost <ratio>", "HDR→Ultra HDR: linear HDR headroom to encode")
|
|
82
|
+
.option("--sdr-quality <quality>", "HDR→Ultra HDR: SDR base JPEG quality (1-100)")
|
|
83
|
+
.option("--gainmap-quality <quality>", "HDR→Ultra HDR: gain map JPEG quality (1-100)")
|
|
84
|
+
.option("--tone-map <operator>", "HDR→Ultra HDR: SDR tone map (fusion | aces | agx | reinhard; default fusion)")
|
|
85
|
+
.option("--ev-step <stops>", "HDR→Ultra HDR: exposure-fusion EV spacing (default 2)")
|
|
86
|
+
.option("--exposure-count <n>", "HDR→Ultra HDR: exposure-fusion exposure count, odd (default 5)")
|
|
87
|
+
.action(async (options) => {
|
|
88
|
+
const inputIsLinearHdr = isLinearHdrPath(options.input);
|
|
89
|
+
const outputIsLinearHdr = isLinearHdrPath(options.output);
|
|
90
|
+
if (inputIsLinearHdr === outputIsLinearHdr)
|
|
91
|
+
throw new Error("convert needs exactly one linear HDR side: use a .exr/.hdr input with an Ultra HDR JPEG output, or vice versa.");
|
|
92
|
+
if (inputIsLinearHdr) {
|
|
93
|
+
if (options.toneMap !== undefined &&
|
|
94
|
+
!["fusion", "aces", "agx", "reinhard"].includes(options.toneMap))
|
|
95
|
+
throw new Error(`Unsupported tone map "${options.toneMap}". Use "fusion", "aces", "agx" or "reinhard".`);
|
|
96
|
+
await linearHdrToUltraHdr({
|
|
97
|
+
input: options.input,
|
|
98
|
+
output: options.output,
|
|
99
|
+
maxContentBoost: options.maxContentBoost === undefined ? undefined : Number(options.maxContentBoost),
|
|
100
|
+
sdrQuality: options.sdrQuality === undefined ? undefined : Number(options.sdrQuality),
|
|
101
|
+
gainMapQuality: options.gainmapQuality === undefined ? undefined : Number(options.gainmapQuality),
|
|
102
|
+
toneMap: options.toneMap,
|
|
103
|
+
evStep: options.evStep === undefined ? undefined : Number(options.evStep),
|
|
104
|
+
exposureCount: options.exposureCount === undefined ? undefined : Number(options.exposureCount),
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
await ultraHdrToLinearHdr({ input: options.input, output: options.output });
|
|
109
|
+
}
|
|
110
|
+
});
|
|
71
111
|
return program;
|
|
72
112
|
}
|
|
73
113
|
function isMainModule() {
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEjE,qEAAqE;AACrE,SAAS,eAAe,CAAC,IAAY;IACnC,OAAO,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAC9B,OAAO;SACJ,IAAI,CAAC,aAAa,CAAC;SACnB,WAAW,CAAC,6DAA6D,CAAC;SAC1E,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpB,OAAO;SACJ,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CACV,8FAA8F,CAC/F;SACA,cAAc,CAAC,cAAc,EAAE,0CAA0C,CAAC;SAC1E,cAAc,CAAC,kBAAkB,EAAE,uCAAuC,CAAC;SAC3E,cAAc,CAAC,qBAAqB,EAAE,iCAAiC,CAAC;SACxE,cAAc,CAAC,qBAAqB,EAAE,uBAAuB,CAAC;SAC9D,MAAM,CAAC,KAAK,EAAE,OAAyE,EAAE,EAAE;QAC1F,MAAM,eAAe,CAAC;YACpB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,mEAAmE,CAAC;SAChF,cAAc,CAAC,oBAAoB,EAAE,sBAAsB,CAAC;SAC5D,cAAc,CAAC,cAAc,EAAE,yCAAyC,CAAC;SACzE,cAAc,CAAC,kBAAkB,EAAE,8CAA8C,CAAC;SAClF,cAAc,CAAC,qBAAqB,EAAE,+BAA+B,CAAC;SACtE,MAAM,CACL,uBAAuB,EACvB,8FAA8F,CAC/F;SACA,MAAM,CACL,KAAK,EAAE,OAMN,EAAE,EAAE;QACH,MAAM,eAAe,CAAC;YACpB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;IACL,CAAC,CACF,CAAC;IAEJ,OAAO;SACJ,OAAO,CAAC,kBAAkB,CAAC;SAC3B,WAAW,CAAC,6EAA6E,CAAC;SAC1F,cAAc,CAAC,wBAAwB,EAAE,iDAAiD,CAAC;SAC3F,MAAM,CAAC,qBAAqB,EAAE,2BAA2B,EAAE,GAAG,CAAC;SAC/D,cAAc,CAAC,qBAAqB,EAAE,uCAAuC,CAAC;SAC9E,MAAM,CAAC,KAAK,EAAE,OAA6D,EAAE,EAAE;QAC9E,MAAM,sBAAsB,CAAC;YAC3B,cAAc,EAAE,OAAO,CAAC,QAAQ;YAChC,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,kBAAkB,CAAC;SAC3B,WAAW,CAAC,4EAA4E,CAAC;SACzF,cAAc,CAAC,oBAAoB,EAAE,sCAAsC,CAAC;SAC5E,cAAc,CAAC,yBAAyB,EAAE,kBAAkB,CAAC;SAC7D,MAAM,CAAC,qBAAqB,EAAE,kCAAkC,EAAE,GAAG,CAAC;SACtE,MAAM,CAAC,KAAK,EAAE,OAA6D,EAAE,EAAE;QAC9E,MAAM,sBAAsB,CAAC;YAC3B,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,eAAe,EAAE,OAAO,CAAC,SAAS;YAClC,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CACV,6GAA6G,CAC9G;SACA,cAAc,CAAC,oBAAoB,EAAE,mDAAmD,CAAC;SACzF,cAAc,CAAC,qBAAqB,EAAE,oDAAoD,CAAC;SAC3F,MAAM,CAAC,6BAA6B,EAAE,8CAA8C,CAAC;SACrF,MAAM,CAAC,yBAAyB,EAAE,8CAA8C,CAAC;SACjF,MAAM,CAAC,6BAA6B,EAAE,8CAA8C,CAAC;SACrF,MAAM,CACL,uBAAuB,EACvB,8EAA8E,CAC/E;SACA,MAAM,CAAC,mBAAmB,EAAE,uDAAuD,CAAC;SACpF,MAAM,CACL,sBAAsB,EACtB,gEAAgE,CACjE;SACA,MAAM,CACL,KAAK,EAAE,OASN,EAAE,EAAE;QACH,MAAM,gBAAgB,GAAG,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACxD,MAAM,iBAAiB,GAAG,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC1D,IAAI,gBAAgB,KAAK,iBAAiB;YACxC,MAAM,IAAI,KAAK,CACb,gHAAgH,CACjH,CAAC;QACJ,IAAI,gBAAgB,EAAE,CAAC;YACrB,IACE,OAAO,CAAC,OAAO,KAAK,SAAS;gBAC7B,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC;gBAEhE,MAAM,IAAI,KAAK,CACb,yBAAyB,OAAO,CAAC,OAAO,+CAA+C,CACxF,CAAC;YACJ,MAAM,mBAAmB,CAAC;gBACxB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,eAAe,EACb,OAAO,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC;gBACrF,UAAU,EAAE,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC;gBACrF,cAAc,EACZ,OAAO,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC;gBACnF,OAAO,EAAE,OAAO,CAAC,OAA6D;gBAC9E,MAAM,EAAE,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;gBACzE,aAAa,EACX,OAAO,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC;aAClF,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,MAAM,mBAAmB,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC,CACF,CAAC;IAEJ,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,YAAY;IACnB,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IAC9B,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,aAAa,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,IAAI,YAAY,EAAE,EAAE,CAAC;IACnB,aAAa,EAAE;SACZ,UAAU,EAAE;SACZ,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;QACxB,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC9D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/** Linear HDR float container formats that `convert` reads and writes. */
|
|
2
|
+
export type LinearHdrFormat = "exr" | "hdr";
|
|
3
|
+
/**
|
|
4
|
+
* SDR tone-mapping operator for the Ultra HDR base image.
|
|
5
|
+
* - `"fusion"` (default): exposure-fusion local tone map; keeps shadow and
|
|
6
|
+
* highlight detail at once with no halos.
|
|
7
|
+
* - `"aces"`: global ACES Filmic curve (high contrast, cinematic).
|
|
8
|
+
* - `"agx"`: global AgX curve (gentle, neutral highlight roll-off).
|
|
9
|
+
* - `"reinhard"`: cheap global Reinhard curve.
|
|
10
|
+
*/
|
|
11
|
+
export type ToneMapOperator = "fusion" | "aces" | "agx" | "reinhard";
|
|
12
|
+
export interface UltraHdrToLinearHdrOptions {
|
|
13
|
+
input: string;
|
|
14
|
+
output: string;
|
|
15
|
+
/** Linear HDR output format; defaults to the output path extension. */
|
|
16
|
+
format?: LinearHdrFormat;
|
|
17
|
+
}
|
|
18
|
+
export interface LinearHdrToUltraHdrOptions {
|
|
19
|
+
input: string;
|
|
20
|
+
output: string;
|
|
21
|
+
/** Linear HDR input format; defaults to the input path extension. */
|
|
22
|
+
format?: LinearHdrFormat;
|
|
23
|
+
/** JPEG quality for the generated SDR base image (1-100, default 95). */
|
|
24
|
+
sdrQuality?: number;
|
|
25
|
+
/** JPEG quality for the generated gain map image (1-100, default 95). */
|
|
26
|
+
gainMapQuality?: number;
|
|
27
|
+
/** Linear ratio of HDR headroom to encode (max_content_boost, default auto). */
|
|
28
|
+
maxContentBoost?: number;
|
|
29
|
+
/** SDR tone-mapping operator (default "fusion"). */
|
|
30
|
+
toneMap?: ToneMapOperator;
|
|
31
|
+
/** Exposure fusion: spacing between synthetic exposures in stops (default 2). */
|
|
32
|
+
evStep?: number;
|
|
33
|
+
/** Exposure fusion: number of synthetic exposures, odd (default 5). */
|
|
34
|
+
exposureCount?: number;
|
|
35
|
+
}
|
|
36
|
+
/** Back-compat alias for {@link UltraHdrToLinearHdrOptions}. */
|
|
37
|
+
export type UltraHdrToExrOptions = UltraHdrToLinearHdrOptions;
|
|
38
|
+
/** Back-compat alias for {@link LinearHdrToUltraHdrOptions}. */
|
|
39
|
+
export type ExrToUltraHdrOptions = LinearHdrToUltraHdrOptions;
|
|
40
|
+
/** Resolves a linear HDR format from an explicit option, then the path extension. */
|
|
41
|
+
export declare function resolveLinearHdrFormat(explicit: LinearHdrFormat | undefined, path: string): LinearHdrFormat;
|
|
42
|
+
/**
|
|
43
|
+
* Reconstructs a linear-light HDR image from an Ultra HDR JPEG and writes it as
|
|
44
|
+
* a linear float EXR or Radiance HDR file (chosen by the output extension).
|
|
45
|
+
*
|
|
46
|
+
* Applies the Adobe/Android gain map recovery per channel:
|
|
47
|
+
* logBoost = lerp(log2(min), log2(max), gain^(1/gamma))
|
|
48
|
+
* hdr = (sdr_linear + offsetSdr) * 2^logBoost - offsetHdr
|
|
49
|
+
* at full display headroom (weight = 1), so the output captures the complete HDR
|
|
50
|
+
* intent rather than a headroom-limited rendition.
|
|
51
|
+
*/
|
|
52
|
+
export declare function ultraHdrToLinearHdr(options: UltraHdrToLinearHdrOptions): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Builds an Ultra HDR JPEG from a linear float EXR or Radiance HDR file (chosen
|
|
55
|
+
* by the input extension). Tone maps the HDR data to an SDR base, derives a gain
|
|
56
|
+
* map as the per-pixel quotient between HDR and SDR, and composes the three into
|
|
57
|
+
* an Ultra HDR container.
|
|
58
|
+
*/
|
|
59
|
+
export declare function linearHdrToUltraHdr(options: LinearHdrToUltraHdrOptions): Promise<void>;
|
|
60
|
+
/** @deprecated Use {@link ultraHdrToLinearHdr}; retained for compatibility. */
|
|
61
|
+
export declare const ultraHdrToExr: typeof ultraHdrToLinearHdr;
|
|
62
|
+
/** @deprecated Use {@link linearHdrToUltraHdr}; retained for compatibility. */
|
|
63
|
+
export declare const exrToUltraHdr: typeof linearHdrToUltraHdr;
|
|
64
|
+
//# sourceMappingURL=convert.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../src/convert.ts"],"names":[],"mappings":"AAWA,0EAA0E;AAC1E,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,KAAK,CAAC;AAE5C;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,UAAU,CAAC;AAErE,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAED,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gFAAgF;IAChF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,iFAAiF;IACjF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,gEAAgE;AAChE,MAAM,MAAM,oBAAoB,GAAG,0BAA0B,CAAC;AAC9D,gEAAgE;AAChE,MAAM,MAAM,oBAAoB,GAAG,0BAA0B,CAAC;AAE9D,qFAAqF;AACrF,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,eAAe,GAAG,SAAS,EACrC,IAAI,EAAE,MAAM,GACX,eAAe,CAQjB;AAwBD;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAqC5F;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAuE5F;AAED,+EAA+E;AAC/E,eAAO,MAAM,aAAa,4BAAsB,CAAC;AACjD,+EAA+E;AAC/E,eAAO,MAAM,aAAa,4BAAsB,CAAC"}
|
package/dist/convert.js
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, extname } from "node:path";
|
|
3
|
+
import sharp from "sharp";
|
|
4
|
+
import { readExr, writeExr } from "./exr.js";
|
|
5
|
+
import { readHdr, writeHdr } from "./hdr.js";
|
|
6
|
+
import { acesSdr, agxSdr, exposureFusion, reinhardSdr } from "./tonemap.js";
|
|
7
|
+
import { composeUltraHdrBuffers, extractUltraHdrBuffers } from "./ultrahdr.js";
|
|
8
|
+
import { normalizeGainMapConfig } from "./xmp.js";
|
|
9
|
+
/** Resolves a linear HDR format from an explicit option, then the path extension. */
|
|
10
|
+
export function resolveLinearHdrFormat(explicit, path) {
|
|
11
|
+
if (explicit)
|
|
12
|
+
return explicit;
|
|
13
|
+
const extension = extname(path).replace(/^\./, "").toLowerCase();
|
|
14
|
+
if (extension === "exr")
|
|
15
|
+
return "exr";
|
|
16
|
+
if (extension === "hdr" || extension === "pic")
|
|
17
|
+
return "hdr";
|
|
18
|
+
throw new Error(`Unable to infer a linear HDR format from "${path}". Use a .exr or .hdr extension.`);
|
|
19
|
+
}
|
|
20
|
+
function decodeLinearHdr(buffer, format) {
|
|
21
|
+
return format === "exr" ? readExr(buffer) : readHdr(buffer);
|
|
22
|
+
}
|
|
23
|
+
function encodeLinearHdr(image, format) {
|
|
24
|
+
return format === "exr" ? writeExr(image) : writeHdr(image);
|
|
25
|
+
}
|
|
26
|
+
/** Decode an 8-bit sRGB-encoded value (0-1) to linear light. */
|
|
27
|
+
function srgbToLinear(value) {
|
|
28
|
+
return value <= 0.04045 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4;
|
|
29
|
+
}
|
|
30
|
+
async function decodeRgb(jpeg) {
|
|
31
|
+
const { data, info } = await sharp(jpeg)
|
|
32
|
+
.toColorspace("srgb")
|
|
33
|
+
.removeAlpha()
|
|
34
|
+
.raw()
|
|
35
|
+
.toBuffer({ resolveWithObject: true });
|
|
36
|
+
return { data, width: info.width, height: info.height };
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Reconstructs a linear-light HDR image from an Ultra HDR JPEG and writes it as
|
|
40
|
+
* a linear float EXR or Radiance HDR file (chosen by the output extension).
|
|
41
|
+
*
|
|
42
|
+
* Applies the Adobe/Android gain map recovery per channel:
|
|
43
|
+
* logBoost = lerp(log2(min), log2(max), gain^(1/gamma))
|
|
44
|
+
* hdr = (sdr_linear + offsetSdr) * 2^logBoost - offsetHdr
|
|
45
|
+
* at full display headroom (weight = 1), so the output captures the complete HDR
|
|
46
|
+
* intent rather than a headroom-limited rendition.
|
|
47
|
+
*/
|
|
48
|
+
export async function ultraHdrToLinearHdr(options) {
|
|
49
|
+
const format = resolveLinearHdrFormat(options.format, options.output);
|
|
50
|
+
const extracted = extractUltraHdrBuffers(await readFile(options.input));
|
|
51
|
+
const config = normalizeGainMapConfig(extracted.config);
|
|
52
|
+
const sdr = await decodeRgb(extracted.sdr);
|
|
53
|
+
const gain = await decodeRgb(extracted.gainMap);
|
|
54
|
+
const width = sdr.width;
|
|
55
|
+
const height = sdr.height;
|
|
56
|
+
const output = new Float32Array(width * height * 3);
|
|
57
|
+
const logMin = Math.log2(config.minContentBoost);
|
|
58
|
+
const logMax = Math.log2(config.maxContentBoost);
|
|
59
|
+
const inverseGamma = 1 / config.gamma;
|
|
60
|
+
// The gain map is often downsampled; map SDR coordinates onto it by ratio.
|
|
61
|
+
const gainScaleX = gain.width / width;
|
|
62
|
+
const gainScaleY = gain.height / height;
|
|
63
|
+
for (let y = 0; y < height; y++) {
|
|
64
|
+
const gainY = Math.min(gain.height - 1, Math.floor(y * gainScaleY));
|
|
65
|
+
for (let x = 0; x < width; x++) {
|
|
66
|
+
const gainX = Math.min(gain.width - 1, Math.floor(x * gainScaleX));
|
|
67
|
+
const sdrIndex = (y * width + x) * 3;
|
|
68
|
+
const gainIndex = (gainY * gain.width + gainX) * 3;
|
|
69
|
+
for (let channel = 0; channel < 3; channel++) {
|
|
70
|
+
const sdrLinear = srgbToLinear(sdr.data[sdrIndex + channel] / 255);
|
|
71
|
+
const gainValue = gain.data[gainIndex + channel] / 255;
|
|
72
|
+
const logRecovery = gainValue ** inverseGamma;
|
|
73
|
+
const logBoost = logMin + (logMax - logMin) * logRecovery;
|
|
74
|
+
const hdr = (sdrLinear + config.offsetSdr) * 2 ** logBoost - config.offsetHdr;
|
|
75
|
+
output[sdrIndex + channel] = hdr;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
await mkdir(dirname(options.output), { recursive: true });
|
|
80
|
+
await writeFile(options.output, encodeLinearHdr({ width, height, data: output }, format));
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Builds an Ultra HDR JPEG from a linear float EXR or Radiance HDR file (chosen
|
|
84
|
+
* by the input extension). Tone maps the HDR data to an SDR base, derives a gain
|
|
85
|
+
* map as the per-pixel quotient between HDR and SDR, and composes the three into
|
|
86
|
+
* an Ultra HDR container.
|
|
87
|
+
*/
|
|
88
|
+
export async function linearHdrToUltraHdr(options) {
|
|
89
|
+
const format = resolveLinearHdrFormat(options.format, options.input);
|
|
90
|
+
const { width, height, data } = decodeLinearHdr(await readFile(options.input), format);
|
|
91
|
+
// Determine the HDR headroom from the brightest linear value so the gain map
|
|
92
|
+
// range covers the content without clipping.
|
|
93
|
+
let peak = 1;
|
|
94
|
+
for (let index = 0; index < data.length; index++) {
|
|
95
|
+
if (data[index] > peak)
|
|
96
|
+
peak = data[index];
|
|
97
|
+
}
|
|
98
|
+
const maxContentBoost = Math.max(1.0001, options.maxContentBoost ?? Math.min(peak, 2 ** 14));
|
|
99
|
+
const logMax = Math.log2(maxContentBoost);
|
|
100
|
+
// Build the SDR base with the chosen tone map. Both operators return
|
|
101
|
+
// interleaved 8-bit sRGB; the gain map is then derived from this quantised
|
|
102
|
+
// base so HDR reconstruction stays consistent with what actually ships.
|
|
103
|
+
const toneMap = options.toneMap ?? "fusion";
|
|
104
|
+
const sdrPixels = toneMap === "reinhard"
|
|
105
|
+
? reinhardSdr(data, width, height)
|
|
106
|
+
: toneMap === "aces"
|
|
107
|
+
? acesSdr(data, width, height)
|
|
108
|
+
: toneMap === "agx"
|
|
109
|
+
? agxSdr(data, width, height)
|
|
110
|
+
: exposureFusion(data, width, height, {
|
|
111
|
+
evStep: options.evStep,
|
|
112
|
+
exposureCount: options.exposureCount,
|
|
113
|
+
});
|
|
114
|
+
const gainPixels = Buffer.alloc(width * height * 3);
|
|
115
|
+
const offset = 0.015625;
|
|
116
|
+
for (let pixel = 0; pixel < width * height; pixel++) {
|
|
117
|
+
const base = pixel * 3;
|
|
118
|
+
for (let channel = 0; channel < 3; channel++) {
|
|
119
|
+
const hdr = Math.max(0, data[base + channel]);
|
|
120
|
+
const sdrLinear = srgbToLinear(sdrPixels[base + channel] / 255);
|
|
121
|
+
// Gain is the ratio of HDR to SDR light, encoded in log2 space and
|
|
122
|
+
// normalised to [0,1] against the chosen max boost.
|
|
123
|
+
const ratio = (hdr + offset) / (sdrLinear + offset);
|
|
124
|
+
const logBoost = Math.log2(Math.max(1, ratio));
|
|
125
|
+
const normalized = logMax > 0 ? Math.min(1, logBoost / logMax) : 0;
|
|
126
|
+
gainPixels[base + channel] = Math.round(normalized * 255);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const sdrQuality = options.sdrQuality ?? 95;
|
|
130
|
+
const gainMapQuality = options.gainMapQuality ?? 95;
|
|
131
|
+
const [sdrJpeg, gainMapJpeg] = await Promise.all([
|
|
132
|
+
sharp(sdrPixels, { raw: { width, height, channels: 3 } })
|
|
133
|
+
.jpeg({ quality: sdrQuality })
|
|
134
|
+
.toBuffer(),
|
|
135
|
+
sharp(gainPixels, { raw: { width, height, channels: 3 } })
|
|
136
|
+
.jpeg({ quality: gainMapQuality })
|
|
137
|
+
.toBuffer(),
|
|
138
|
+
]);
|
|
139
|
+
const config = {
|
|
140
|
+
maxContentBoost,
|
|
141
|
+
minContentBoost: 1,
|
|
142
|
+
gamma: 1,
|
|
143
|
+
offsetSdr: offset,
|
|
144
|
+
offsetHdr: offset,
|
|
145
|
+
hdrCapacityMin: 1,
|
|
146
|
+
hdrCapacityMax: maxContentBoost,
|
|
147
|
+
useBaseColorSpace: true,
|
|
148
|
+
};
|
|
149
|
+
const container = await composeUltraHdrBuffers(sdrJpeg, gainMapJpeg, config);
|
|
150
|
+
await mkdir(dirname(options.output), { recursive: true });
|
|
151
|
+
await writeFile(options.output, container);
|
|
152
|
+
}
|
|
153
|
+
/** @deprecated Use {@link ultraHdrToLinearHdr}; retained for compatibility. */
|
|
154
|
+
export const ultraHdrToExr = ultraHdrToLinearHdr;
|
|
155
|
+
/** @deprecated Use {@link linearHdrToUltraHdr}; retained for compatibility. */
|
|
156
|
+
export const exrToUltraHdr = linearHdrToUltraHdr;
|
|
157
|
+
//# sourceMappingURL=convert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convert.js","sourceRoot":"","sources":["../src/convert.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC5E,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAE/E,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AA8ClD,qFAAqF;AACrF,MAAM,UAAU,sBAAsB,CACpC,QAAqC,EACrC,IAAY;IAEZ,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IACjE,IAAI,SAAS,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IACtC,IAAI,SAAS,KAAK,KAAK,IAAI,SAAS,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IAC7D,MAAM,IAAI,KAAK,CACb,6CAA6C,IAAI,kCAAkC,CACpF,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,MAAc,EAAE,MAAuB;IAC9D,OAAO,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,eAAe,CAAC,KAAqB,EAAE,MAAuB;IACrE,OAAO,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC9D,CAAC;AAED,gEAAgE;AAChE,SAAS,YAAY,CAAC,KAAa;IACjC,OAAO,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,GAAG,CAAC;AAC7E,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,IAAY;IACnC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC;SACrC,YAAY,CAAC,MAAM,CAAC;SACpB,WAAW,EAAE;SACb,GAAG,EAAE;SACL,QAAQ,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;AAC1D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAmC;IAC3E,MAAM,MAAM,GAAG,sBAAsB,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACtE,MAAM,SAAS,GAAG,sBAAsB,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACxE,MAAM,MAAM,GAAG,sBAAsB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACxD,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAEhD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;IACxB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IAC1B,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;IAEpD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IACjD,MAAM,YAAY,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC;IACtC,2EAA2E;IAC3E,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACtC,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IAExC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC;QACpE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC;YACnE,MAAM,QAAQ,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;YACrC,MAAM,SAAS,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;YACnD,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;gBAC7C,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;gBACnE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,GAAG,GAAG,CAAC;gBACvD,MAAM,WAAW,GAAG,SAAS,IAAI,YAAY,CAAC;gBAC9C,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,WAAW,CAAC;gBAC1D,MAAM,GAAG,GAAG,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC;gBAC9E,MAAM,CAAC,QAAQ,GAAG,OAAO,CAAC,GAAG,GAAG,CAAC;YACnC,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,MAAM,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;AAC5F,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAmC;IAC3E,MAAM,MAAM,GAAG,sBAAsB,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IACrE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;IAEvF,6EAA6E;IAC7E,6CAA6C;IAC7C,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QACjD,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI;YAAE,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7C,CAAC;IACD,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC7F,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAE1C,qEAAqE;IACrE,2EAA2E;IAC3E,wEAAwE;IACxE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,QAAQ,CAAC;IAC5C,MAAM,SAAS,GACb,OAAO,KAAK,UAAU;QACpB,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC;QAClC,CAAC,CAAC,OAAO,KAAK,MAAM;YAClB,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC;YAC9B,CAAC,CAAC,OAAO,KAAK,KAAK;gBACjB,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC;gBAC7B,CAAC,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE;oBAClC,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,aAAa,EAAE,OAAO,CAAC,aAAa;iBACrC,CAAC,CAAC;IAEb,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,QAAQ,CAAC;IAExB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QACpD,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC;QACvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;YAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC;YAC9C,MAAM,SAAS,GAAG,YAAY,CAAC,SAAS,CAAC,IAAI,GAAG,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;YAChE,mEAAmE;YACnE,oDAAoD;YACpD,MAAM,KAAK,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,GAAG,MAAM,CAAC,CAAC;YACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;YAC/C,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACnE,UAAU,CAAC,IAAI,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC;IAC5C,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,EAAE,CAAC;IACpD,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC/C,KAAK,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;aACtD,IAAI,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;aAC7B,QAAQ,EAAE;QACb,KAAK,CAAC,UAAU,EAAE,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;aACvD,IAAI,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC;aACjC,QAAQ,EAAE;KACd,CAAC,CAAC;IAEH,MAAM,MAAM,GAAkB;QAC5B,eAAe;QACf,eAAe,EAAE,CAAC;QAClB,KAAK,EAAE,CAAC;QACR,SAAS,EAAE,MAAM;QACjB,SAAS,EAAE,MAAM;QACjB,cAAc,EAAE,CAAC;QACjB,cAAc,EAAE,eAAe;QAC/B,iBAAiB,EAAE,IAAI;KACxB,CAAC;IAEF,MAAM,SAAS,GAAG,MAAM,sBAAsB,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;IAC7E,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,MAAM,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAC7C,CAAC;AAED,+EAA+E;AAC/E,MAAM,CAAC,MAAM,aAAa,GAAG,mBAAmB,CAAC;AACjD,+EAA+E;AAC/E,MAAM,CAAC,MAAM,aAAa,GAAG,mBAAmB,CAAC"}
|
package/dist/exr.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal OpenEXR reader/writer for linear scanline RGB(A) images.
|
|
3
|
+
*
|
|
4
|
+
* This is intentionally small: it is only meant to move linear floating point
|
|
5
|
+
* HDR pixels in and out of the UltraHDR converter, not to be a general EXR
|
|
6
|
+
* implementation. On read it accepts single-part scanline files with HALF or
|
|
7
|
+
* FLOAT channels and NO_COMPRESSION, ZIPS or ZIP compression. On write it emits
|
|
8
|
+
* a single-part scanline FLOAT RGB file with NO_COMPRESSION, which every EXR
|
|
9
|
+
* reader understands.
|
|
10
|
+
*/
|
|
11
|
+
/** An in-memory linear HDR image: interleaved RGB, 3 floats per pixel, top row first. */
|
|
12
|
+
export interface LinearHdrImage {
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
data: Float32Array;
|
|
16
|
+
}
|
|
17
|
+
/** @deprecated Use {@link LinearHdrImage}; kept as an alias for compatibility. */
|
|
18
|
+
export type ExrImage = LinearHdrImage;
|
|
19
|
+
/** Reads a linear RGB EXR into interleaved float RGB, dropping any alpha. */
|
|
20
|
+
export declare function readExr(buffer: Buffer): LinearHdrImage;
|
|
21
|
+
/**
|
|
22
|
+
* Writes interleaved linear float RGB as an uncompressed single-part scanline
|
|
23
|
+
* EXR. Channels are emitted alphabetically (B, G, R) as the format requires.
|
|
24
|
+
*/
|
|
25
|
+
export declare function writeExr(image: LinearHdrImage): Buffer;
|
|
26
|
+
//# sourceMappingURL=exr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exr.d.ts","sourceRoot":"","sources":["../src/exr.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,yFAAyF;AACzF,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,YAAY,CAAC;CACpB;AAED,kFAAkF;AAClF,MAAM,MAAM,QAAQ,GAAG,cAAc,CAAC;AA0ItC,6EAA6E;AAC7E,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CA0FtD;AASD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAsFtD"}
|