@realsee/hdr-toolbox 1.1.2 → 1.1.4
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 +56 -29
- package/dist/avif-codec.d.ts +43 -0
- package/dist/avif-codec.d.ts.map +1 -0
- package/dist/avif-codec.js +91 -0
- package/dist/avif-codec.js.map +1 -0
- package/dist/avif-container.d.ts +83 -0
- package/dist/avif-container.d.ts.map +1 -0
- package/dist/avif-container.js +368 -0
- package/dist/avif-container.js.map +1 -0
- package/dist/avif-gainmap.d.ts +31 -0
- package/dist/avif-gainmap.d.ts.map +1 -0
- package/dist/avif-gainmap.js +124 -0
- package/dist/avif-gainmap.js.map +1 -0
- package/dist/avif.d.ts +50 -0
- package/dist/avif.d.ts.map +1 -0
- package/dist/avif.js +206 -0
- package/dist/avif.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +32 -37
- package/dist/cli.js.map +1 -1
- package/dist/convert.d.ts +36 -17
- package/dist/convert.d.ts.map +1 -1
- package/dist/convert.js +152 -44
- package/dist/convert.js.map +1 -1
- package/dist/exr.d.ts +4 -3
- package/dist/exr.d.ts.map +1 -1
- package/dist/exr.js +160 -8
- package/dist/exr.js.map +1 -1
- package/dist/hdr-transfer.d.ts +50 -0
- package/dist/hdr-transfer.d.ts.map +1 -0
- package/dist/hdr-transfer.js +147 -0
- package/dist/hdr-transfer.js.map +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/package.json +10 -1
package/README.md
CHANGED
|
@@ -87,39 +87,65 @@ 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. 格式转换(EXR / Radiance HDR、Ultra HDR、AVIF)
|
|
91
91
|
|
|
92
|
-
`convert`
|
|
92
|
+
`convert` 根据扩展名在三类容器之间转换:线性浮点 HDR(`.exr`、`.hdr`/`.pic`)、Ultra HDR JPEG(`.jpg`/`.jpeg`)和 AVIF(`.avif`)。输入和输出可以互换。
|
|
93
93
|
|
|
94
94
|
```bash
|
|
95
|
-
# Ultra HDR → EXR
|
|
95
|
+
# Ultra HDR → EXR / Radiance HDR(按增益图重建线性 HDR)
|
|
96
96
|
hdr-toolbox convert --input examples/ultra-hdr.jpg --output output/ultra-hdr.exr
|
|
97
|
-
|
|
98
|
-
# Ultra HDR → Radiance HDR:同样的重建,写成 RGBE 编码的 .hdr(体积更小)
|
|
99
97
|
hdr-toolbox convert --input examples/ultra-hdr.jpg --output output/ultra-hdr.hdr
|
|
100
98
|
|
|
101
|
-
# EXR / HDR → Ultra HDR
|
|
99
|
+
# EXR / HDR → Ultra HDR(色调映射出 SDR 基图,反算增益图)
|
|
102
100
|
hdr-toolbox convert --input output/ultra-hdr.exr --output output/from-exr.uhdr.jpg
|
|
103
|
-
|
|
101
|
+
|
|
102
|
+
# Ultra HDR → gain map AVIF(默认 --avif-mode gainmap)
|
|
103
|
+
hdr-toolbox convert --input examples/ultra-hdr.jpg --output output/ultra-hdr.avif
|
|
104
|
+
|
|
105
|
+
# Ultra HDR / EXR / HDR → 10-bit PQ AVIF
|
|
106
|
+
hdr-toolbox convert --input examples/ultra-hdr.jpg --output output/ultra-hdr-pq.avif --avif-mode hdr10
|
|
107
|
+
|
|
108
|
+
# AVIF → Ultra HDR / 线性 HDR
|
|
109
|
+
hdr-toolbox convert --input output/ultra-hdr.avif --output output/from-avif.uhdr.jpg
|
|
110
|
+
hdr-toolbox convert --input output/ultra-hdr-pq.avif --output output/from-pq.exr
|
|
104
111
|
```
|
|
105
112
|
|
|
106
|
-
|
|
113
|
+
#### AVIF 的两种输出形式
|
|
114
|
+
|
|
115
|
+
| `--avif-mode` | 内容 | 适用场景 |
|
|
116
|
+
| ----------------- | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- |
|
|
117
|
+
| `gainmap`(默认) | 8-bit SDR 基图 + 8-bit 增益图 + ISO 21496-1 `tmap`,基图为 `pitm`,`tmap` 通过 `dimg` 引用两者并放入 `altr` 分组 | 支持 gain map 的查看器显示 HDR,其余显示 SDR 基图 |
|
|
118
|
+
| `hdr10` | 单张 10-bit PQ(BT.2020,full range,4:2:0),没有 SDR 回退 | 只需要 HDR 的场景 |
|
|
119
|
+
|
|
120
|
+
AVIF 的有损质量由 `--avif-quality` 控制(0-100,默认 90)。
|
|
107
121
|
|
|
108
|
-
|
|
109
|
-
- **Radiance HDR**(RGBE,`.hdr`/`.pic`):读取支持 flat、旧式与新式 RLE 编码;写入新式 RLE。RGBE 的共享指数带来 ~0.4% 的量化,但体积明显小于未压缩 EXR。
|
|
122
|
+
#### AVIF 读取的范围
|
|
110
123
|
|
|
111
|
-
|
|
124
|
+
- 支持 gain map AVIF,以及 10-bit PQ / HLG AVIF(BT.709 或 BT.2020 原色)。
|
|
125
|
+
- 8-bit AVIF 且没有增益图时不含 HDR 数据,会报错拒绝。
|
|
126
|
+
- 不支持分块(`grid`)AVIF,也不支持 HDR 基图(基图余量高于增益图余量)。
|
|
127
|
+
- `tmap` 的三个通道参数可能不同。本工具只取通道 0,与 panorama-viewer 的做法一致,因此高光可能轻微偏色。
|
|
112
128
|
|
|
113
|
-
|
|
129
|
+
#### 编码注意事项
|
|
114
130
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
131
|
+
- 10-bit PQ 输出中,线性值 1.0 对应 SDR 白 203 nit,超过 10000 nit(线性约 49.3)的值被裁剪。
|
|
132
|
+
- EXR / HDR 的数值按原样使用,不做自动曝光。若文件的绝对亮度不符合上述约定,需要先在外部缩放。
|
|
133
|
+
- 从 gain map 输入转为 10-bit PQ 时,重建的增益上限会被限制在 PQ 峰值以内,避免高光被裁剪。
|
|
134
|
+
- AVIF 编码使用 `@jsquash/avif`(WASM,libavif 1.0.1),不依赖系统安装的 libavif。
|
|
135
|
+
- 色度矩阵使用 BT.601,这是 jsquash 的 YUV 转换方式,文件的 `colr` 标签与之保持一致。
|
|
136
|
+
|
|
137
|
+
#### convert 选项
|
|
138
|
+
|
|
139
|
+
| 选项 | 说明 |
|
|
140
|
+
| --------------------- | ------------------------------------------------------------------------ |
|
|
141
|
+
| `--avif-mode` | AVIF 输出形式:`gainmap`(默认)或 `hdr10` |
|
|
142
|
+
| `--avif-quality` | AVIF 有损质量(0-100,默认 90) |
|
|
143
|
+
| `--max-content-boost` | 线性 HDR → gain map:要编码的 HDR 余量,默认取输入峰值 |
|
|
144
|
+
| `--tone-map` | 线性 HDR → gain map:`fusion`(默认,局部)、`reinhard`、`aces` 或 `agx` |
|
|
145
|
+
| `--ev-step` | 曝光融合的档间距(stops,默认 2) |
|
|
146
|
+
| `--exposure-count` | 曝光融合的合成曝光数,奇数(默认 5) |
|
|
147
|
+
| `--sdr-quality` | 生成的 SDR 基图 JPEG 质量(1-100,默认 95) |
|
|
148
|
+
| `--gainmap-quality` | 生成的增益图 JPEG 质量(1-100,默认 95) |
|
|
123
149
|
|
|
124
150
|
> 曝光融合是全图金字塔运算,对大图(如 8K 全景)内存和耗时都明显高于 `reinhard`;离线转换可接受,追求速度可用 `--tone-map reinhard`。
|
|
125
151
|
|
|
@@ -154,19 +180,20 @@ await extractUltraHdr({
|
|
|
154
180
|
});
|
|
155
181
|
```
|
|
156
182
|
|
|
157
|
-
|
|
183
|
+
格式互转使用 `convertHdrImage`,输入、输出格式由扩展名决定(`.exr`、`.hdr`、`.jpg`、`.jpeg`、`.avif`)。旧的 `linearHdrToUltraHdr` / `ultraHdrToLinearHdr`(以及别名 `exrToUltraHdr` / `ultraHdrToExr`)仍然可用:
|
|
158
184
|
|
|
159
185
|
```ts
|
|
160
|
-
import {
|
|
186
|
+
import { readFile } from "node:fs/promises";
|
|
187
|
+
import { convertHdrImage, readAvif } from "@realsee/hdr-toolbox";
|
|
161
188
|
|
|
162
|
-
//
|
|
163
|
-
await
|
|
189
|
+
// 扩展名决定格式;默认输出 gain map AVIF
|
|
190
|
+
await convertHdrImage({ input: "image.uhdr.jpg", output: "image.avif" });
|
|
164
191
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
192
|
+
// 10-bit PQ AVIF
|
|
193
|
+
await convertHdrImage({ input: "image.exr", output: "image-pq.avif", avifMode: "hdr10" });
|
|
194
|
+
|
|
195
|
+
// 直接读取 AVIF:得到 { kind: "gainmap", pair } 或 { kind: "hdr10", image }
|
|
196
|
+
const content = await readAvif(await readFile("image.avif"));
|
|
170
197
|
```
|
|
171
198
|
|
|
172
199
|
底层的编解码函数 `readExr` / `writeExr` 和 `readHdr` / `writeHdr` 也一并导出,都以交错的线性浮点 RGB(`LinearHdrImage`)作为统一的像素表示。
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* libavif (WebAssembly, via `@jsquash/avif`) encode and decode.
|
|
3
|
+
*
|
|
4
|
+
* The bundled libavif is v1.0.1, which has no gain-map API, so the container and
|
|
5
|
+
* `tmap` metadata are handled in `avif-container.ts` and `avif-gainmap.ts`. This
|
|
6
|
+
* module only moves pixels in and out of AV1 image items.
|
|
7
|
+
*
|
|
8
|
+
* In Node the emscripten glue cannot fetch its `.wasm` next to the module, so the
|
|
9
|
+
* binary is read from `node_modules` and compiled up front. The codec loads once,
|
|
10
|
+
* on first use.
|
|
11
|
+
*/
|
|
12
|
+
/** Chroma subsampling codes used by `@jsquash/avif` (1 = 4:2:0, 3 = 4:4:4). */
|
|
13
|
+
export declare const subsample420 = 1;
|
|
14
|
+
export declare const subsample444 = 3;
|
|
15
|
+
export interface Rgba8Pixels {
|
|
16
|
+
width: number;
|
|
17
|
+
height: number;
|
|
18
|
+
/** Interleaved RGBA, 8 bits per channel. */
|
|
19
|
+
data: Uint8ClampedArray;
|
|
20
|
+
}
|
|
21
|
+
export interface RgbaCodePixels {
|
|
22
|
+
width: number;
|
|
23
|
+
height: number;
|
|
24
|
+
/** Interleaved RGBA code values, 0 .. 2^depth - 1. */
|
|
25
|
+
data: Uint16Array;
|
|
26
|
+
depth: number;
|
|
27
|
+
}
|
|
28
|
+
export interface EncodeAvifOptions {
|
|
29
|
+
/** Quality from 0 to 100 (lossy). */
|
|
30
|
+
quality: number;
|
|
31
|
+
subsample: number;
|
|
32
|
+
}
|
|
33
|
+
/** Encode 8-bit RGBA pixels to an AV1 image (a complete AVIF file). */
|
|
34
|
+
export declare function encodeAvif8(pixels: Rgba8Pixels, options: EncodeAvifOptions): Promise<Buffer>;
|
|
35
|
+
/** Encode 10-bit RGBA code values to an AV1 image (a complete AVIF file). */
|
|
36
|
+
export declare function encodeAvif10(pixels: RgbaCodePixels, options: EncodeAvifOptions): Promise<Buffer>;
|
|
37
|
+
/**
|
|
38
|
+
* Decode a complete AVIF file. Returns RGBA at `bitDepth`: `Uint8ClampedArray`
|
|
39
|
+
* for 8 bits, `Uint16Array` code values for 10, 12 or 16 bits.
|
|
40
|
+
*/
|
|
41
|
+
export declare function decodeAvif(bytes: Buffer, bitDepth: 8): Promise<Rgba8Pixels>;
|
|
42
|
+
export declare function decodeAvif(bytes: Buffer, bitDepth: 10 | 12 | 16): Promise<RgbaCodePixels>;
|
|
43
|
+
//# sourceMappingURL=avif-codec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"avif-codec.d.ts","sourceRoot":"","sources":["../src/avif-codec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,+EAA+E;AAC/E,eAAO,MAAM,YAAY,IAAI,CAAC;AAC9B,eAAO,MAAM,YAAY,IAAI,CAAC;AAE9B,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,IAAI,EAAE,iBAAiB,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,qCAAqC;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AA+CD,uEAAuE;AACvE,wBAAsB,WAAW,CAC/B,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,MAAM,CAAC,CASjB;AAED,6EAA6E;AAC7E,wBAAsB,YAAY,CAChC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;AACnF,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* libavif (WebAssembly, via `@jsquash/avif`) encode and decode.
|
|
3
|
+
*
|
|
4
|
+
* The bundled libavif is v1.0.1, which has no gain-map API, so the container and
|
|
5
|
+
* `tmap` metadata are handled in `avif-container.ts` and `avif-gainmap.ts`. This
|
|
6
|
+
* module only moves pixels in and out of AV1 image items.
|
|
7
|
+
*
|
|
8
|
+
* In Node the emscripten glue cannot fetch its `.wasm` next to the module, so the
|
|
9
|
+
* binary is read from `node_modules` and compiled up front. The codec loads once,
|
|
10
|
+
* on first use.
|
|
11
|
+
*/
|
|
12
|
+
import { readFile } from "node:fs/promises";
|
|
13
|
+
import { createRequire } from "node:module";
|
|
14
|
+
import { dirname, join } from "node:path";
|
|
15
|
+
import { default as decodeModule, init as initDecoder } from "@jsquash/avif/decode.js";
|
|
16
|
+
import { default as encodeModule, init as initEncoder } from "@jsquash/avif/encode.js";
|
|
17
|
+
/** Chroma subsampling codes used by `@jsquash/avif` (1 = 4:2:0, 3 = 4:4:4). */
|
|
18
|
+
export const subsample420 = 1;
|
|
19
|
+
export const subsample444 = 3;
|
|
20
|
+
/** The global WebAssembly namespace, typed only as far as this module uses it. */
|
|
21
|
+
const wasm = globalThis.WebAssembly;
|
|
22
|
+
let encoderReady;
|
|
23
|
+
let decoderReady;
|
|
24
|
+
function codecFile(name) {
|
|
25
|
+
const packageJson = createRequire(import.meta.url).resolve("@jsquash/avif/package.json");
|
|
26
|
+
return join(dirname(packageJson), "codec", name);
|
|
27
|
+
}
|
|
28
|
+
async function compileWasm(name) {
|
|
29
|
+
return wasm.compile(await readFile(codecFile(name)));
|
|
30
|
+
}
|
|
31
|
+
function ensureEncoder() {
|
|
32
|
+
encoderReady ??= (async () => {
|
|
33
|
+
await initEncoder((await compileWasm("enc/avif_enc.wasm")));
|
|
34
|
+
})().catch((error) => {
|
|
35
|
+
encoderReady = undefined;
|
|
36
|
+
throw error;
|
|
37
|
+
});
|
|
38
|
+
return encoderReady;
|
|
39
|
+
}
|
|
40
|
+
function ensureDecoder() {
|
|
41
|
+
decoderReady ??= (async () => {
|
|
42
|
+
await initDecoder((await compileWasm("dec/avif_dec.wasm")));
|
|
43
|
+
})().catch((error) => {
|
|
44
|
+
decoderReady = undefined;
|
|
45
|
+
throw error;
|
|
46
|
+
});
|
|
47
|
+
return decoderReady;
|
|
48
|
+
}
|
|
49
|
+
/** Encode 8-bit RGBA pixels to an AV1 image (a complete AVIF file). */
|
|
50
|
+
export async function encodeAvif8(pixels, options) {
|
|
51
|
+
await ensureEncoder();
|
|
52
|
+
const image = { data: pixels.data, width: pixels.width, height: pixels.height };
|
|
53
|
+
const output = await encodeModule(image, {
|
|
54
|
+
bitDepth: 8,
|
|
55
|
+
quality: options.quality,
|
|
56
|
+
subsample: options.subsample,
|
|
57
|
+
});
|
|
58
|
+
return Buffer.from(output);
|
|
59
|
+
}
|
|
60
|
+
/** Encode 10-bit RGBA code values to an AV1 image (a complete AVIF file). */
|
|
61
|
+
export async function encodeAvif10(pixels, options) {
|
|
62
|
+
if (pixels.depth !== 10)
|
|
63
|
+
throw new Error("encodeAvif10 expects 10-bit code values.");
|
|
64
|
+
await ensureEncoder();
|
|
65
|
+
const image = { data: pixels.data, width: pixels.width, height: pixels.height };
|
|
66
|
+
const output = await encodeModule(image, {
|
|
67
|
+
bitDepth: 10,
|
|
68
|
+
quality: options.quality,
|
|
69
|
+
subsample: options.subsample,
|
|
70
|
+
});
|
|
71
|
+
return Buffer.from(output);
|
|
72
|
+
}
|
|
73
|
+
export async function decodeAvif(bytes, bitDepth) {
|
|
74
|
+
await ensureDecoder();
|
|
75
|
+
const arrayBuffer = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
|
|
76
|
+
if (bitDepth === 8) {
|
|
77
|
+
const result = await decodeModule(arrayBuffer, { bitDepth: 8 });
|
|
78
|
+
if (!result)
|
|
79
|
+
throw new Error("AVIF decoding failed.");
|
|
80
|
+
return {
|
|
81
|
+
width: result.width,
|
|
82
|
+
height: result.height,
|
|
83
|
+
data: result.data,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const result = await decodeModule(arrayBuffer, { bitDepth });
|
|
87
|
+
if (!result)
|
|
88
|
+
throw new Error("AVIF decoding failed.");
|
|
89
|
+
return { width: result.width, height: result.height, data: result.data, depth: bitDepth };
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=avif-codec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"avif-codec.js","sourceRoot":"","sources":["../src/avif-codec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AVIF (ISOBMFF / HEIF) container reader and writer.
|
|
3
|
+
*
|
|
4
|
+
* The reader covers the boxes needed to locate image items, their AV1 payloads,
|
|
5
|
+
* their properties (`av1C`, `ispe`, `pixi`, `colr`) and `dimg` references. The
|
|
6
|
+
* writer emits a minimal file with one or more `av01` image items and optional
|
|
7
|
+
* derived `tmap` items (ISO 21496-1 gain maps).
|
|
8
|
+
*/
|
|
9
|
+
export interface IsobmffBox {
|
|
10
|
+
type: string;
|
|
11
|
+
/** Byte offset of the box header in the file. */
|
|
12
|
+
start: number;
|
|
13
|
+
headerSize: number;
|
|
14
|
+
/** Total box size, header included. */
|
|
15
|
+
size: number;
|
|
16
|
+
}
|
|
17
|
+
export interface AvifItem {
|
|
18
|
+
id: number;
|
|
19
|
+
type: string;
|
|
20
|
+
/** Item byte ranges in the file, from `iloc`. */
|
|
21
|
+
extents: Array<{
|
|
22
|
+
offset: number;
|
|
23
|
+
length: number;
|
|
24
|
+
}>;
|
|
25
|
+
constructionMethod: number;
|
|
26
|
+
/** Property boxes associated with the item through `ipma`. */
|
|
27
|
+
properties: IsobmffBox[];
|
|
28
|
+
}
|
|
29
|
+
export interface AvifReference {
|
|
30
|
+
type: string;
|
|
31
|
+
from: number;
|
|
32
|
+
to: number[];
|
|
33
|
+
}
|
|
34
|
+
export interface ParsedAvif {
|
|
35
|
+
buffer: Buffer;
|
|
36
|
+
primaryItemId: number | undefined;
|
|
37
|
+
items: Map<number, AvifItem>;
|
|
38
|
+
references: AvifReference[];
|
|
39
|
+
}
|
|
40
|
+
export interface ColourInfo {
|
|
41
|
+
primaries: number;
|
|
42
|
+
transfer: number;
|
|
43
|
+
matrix: number;
|
|
44
|
+
fullRange: boolean;
|
|
45
|
+
}
|
|
46
|
+
/** Parse an AVIF file's item graph. Throws if the file has no `meta` box. */
|
|
47
|
+
export declare function parseAvif(buffer: Buffer): ParsedAvif;
|
|
48
|
+
/** Return the concatenated payload bytes of an item stored in the file. */
|
|
49
|
+
export declare function itemPayload(parsed: ParsedAvif, item: AvifItem): Buffer;
|
|
50
|
+
/** Return the bytes of the first property of a given type on an item. */
|
|
51
|
+
export declare function itemPropertyBytes(parsed: ParsedAvif, item: AvifItem, type: string): Buffer | undefined;
|
|
52
|
+
/** Bit depth declared by an item's `pixi` property, if present. */
|
|
53
|
+
export declare function itemBitDepth(parsed: ParsedAvif, item: AvifItem): number | undefined;
|
|
54
|
+
/** CICP colour information from an item's `colr` (nclx) property. */
|
|
55
|
+
export declare function itemColourInfo(parsed: ParsedAvif, item: AvifItem): ColourInfo | undefined;
|
|
56
|
+
export interface AvifWriteItem {
|
|
57
|
+
id: number;
|
|
58
|
+
/** `av01` for AV1 image items, `tmap` for ISO 21496-1 gain map metadata. */
|
|
59
|
+
type: "av01" | "tmap";
|
|
60
|
+
payload: Buffer;
|
|
61
|
+
/** Raw property boxes (`av1C`, `ispe`, `pixi`, `colr`, ...). */
|
|
62
|
+
properties?: Buffer[];
|
|
63
|
+
}
|
|
64
|
+
/** An `altr` (alternatives) entity group: readers may pick any one member. */
|
|
65
|
+
export interface AvifAlternativesGroup {
|
|
66
|
+
entities: number[];
|
|
67
|
+
}
|
|
68
|
+
export interface AvifWriteOptions {
|
|
69
|
+
primaryItemId: number;
|
|
70
|
+
items: AvifWriteItem[];
|
|
71
|
+
references?: AvifReference[];
|
|
72
|
+
/** Entity groups written to `grpl`. Gain map AVIF uses one group with the tmap and base items. */
|
|
73
|
+
alternatives?: AvifAlternativesGroup[];
|
|
74
|
+
}
|
|
75
|
+
/** CICP `colr` box with an nclx payload. */
|
|
76
|
+
export declare function colrBox(info: ColourInfo): Buffer;
|
|
77
|
+
/**
|
|
78
|
+
* Serialise an AVIF file. Layout: `ftyp`, `meta` (hdlr, pitm, iloc, iinf, iref,
|
|
79
|
+
* iprp), then `mdat` holding the item payloads in order. Item offsets are
|
|
80
|
+
* absolute file offsets (construction method 0).
|
|
81
|
+
*/
|
|
82
|
+
export declare function writeAvifContainer(options: AvifWriteOptions): Buffer;
|
|
83
|
+
//# sourceMappingURL=avif-container.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"avif-container.d.ts","sourceRoot":"","sources":["../src/avif-container.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,OAAO,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,8DAA8D;IAC9D,UAAU,EAAE,UAAU,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,EAAE,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC7B,UAAU,EAAE,aAAa,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;CACpB;AAiND,6EAA6E;AAC7E,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAiBpD;AAED,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,CAStE;AAED,yEAAyE;AACzE,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,SAAS,CAGpB;AAED,mEAAmE;AACnE,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS,CAKnF;AAED,qEAAqE;AACrE,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,CAWzF;AAMD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,4EAA4E;IAC5E,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,8EAA8E;AAC9E,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;IAC7B,kGAAkG;IAClG,YAAY,CAAC,EAAE,qBAAqB,EAAE,CAAC;CACxC;AA2BD,4CAA4C;AAC5C,wBAAgB,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAShD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAkHpE"}
|