open-ultrahdr 0.1.2 → 0.2.0
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 +3 -1
- package/dist/index.d.mts +30 -147
- package/dist/index.d.ts +30 -147
- package/dist/index.js +60 -59
- package/dist/index.mjs +60 -59
- package/package.json +4 -4
- package/src/index.ts +90 -299
- package/src/types.ts +16 -2
package/README.md
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -85,9 +85,23 @@ interface UltraHdrEncodeOptions {
|
|
|
85
85
|
gainMapQuality: number;
|
|
86
86
|
/** Target HDR capacity (typically 2.0-4.0) */
|
|
87
87
|
targetHdrCapacity: number;
|
|
88
|
-
/**
|
|
88
|
+
/**
|
|
89
|
+
* Whether to include ISO 21496-1 metadata.
|
|
90
|
+
*
|
|
91
|
+
* Currently a no-op: libultrahdr's encoder unconditionally emits ISO
|
|
92
|
+
* 21496-1 metadata and exposes no public toggle. Kept for API stability
|
|
93
|
+
* with prior versions; setting this to `false` will not suppress the
|
|
94
|
+
* metadata block.
|
|
95
|
+
*/
|
|
89
96
|
includeIsoMetadata: boolean;
|
|
90
|
-
/**
|
|
97
|
+
/**
|
|
98
|
+
* Whether to include UltraHDR v1 metadata for Android compatibility.
|
|
99
|
+
*
|
|
100
|
+
* Currently a no-op: libultrahdr's encoder unconditionally emits the v1
|
|
101
|
+
* metadata block and exposes no public toggle. Kept for API stability
|
|
102
|
+
* with prior versions; setting this to `false` will not suppress the
|
|
103
|
+
* metadata block.
|
|
104
|
+
*/
|
|
91
105
|
includeUltrahdrV1: boolean;
|
|
92
106
|
/** Downscale factor for the gain map (1 = same size, 2 = half, 4 = quarter) */
|
|
93
107
|
gainMapScale: number;
|
|
@@ -132,18 +146,18 @@ declare const smallSizeEncodeOptions: UltraHdrEncodeOptions;
|
|
|
132
146
|
/**
|
|
133
147
|
* Open UltraHDR Library
|
|
134
148
|
*
|
|
135
|
-
* TypeScript bindings for the
|
|
136
|
-
*
|
|
137
|
-
*
|
|
149
|
+
* TypeScript bindings for the libultrahdr WASM library. Provides detection,
|
|
150
|
+
* encoding, and decoding of UltraHDR JPEG images implementing the
|
|
151
|
+
* ISO 21496-1 (gain map) specification.
|
|
152
|
+
*
|
|
153
|
+
* Backed by upstream `libultrahdr` compiled to WebAssembly via Emscripten/embind.
|
|
138
154
|
*
|
|
139
155
|
* @example
|
|
140
156
|
* ```typescript
|
|
141
157
|
* import { isUltraHdr, decodeUltraHdr, setLocation } from 'open-ultrahdr';
|
|
142
158
|
*
|
|
143
|
-
* // Set the location for WASM files
|
|
144
159
|
* setLocation('/path/to/wasm/');
|
|
145
160
|
*
|
|
146
|
-
* // Check if an image is UltraHDR
|
|
147
161
|
* const buffer = await file.arrayBuffer();
|
|
148
162
|
* if (await isUltraHdr(buffer)) {
|
|
149
163
|
* const result = await decodeUltraHdr('item-1', buffer);
|
|
@@ -155,187 +169,56 @@ declare const smallSizeEncodeOptions: UltraHdrEncodeOptions;
|
|
|
155
169
|
/**
|
|
156
170
|
* Sets the location/public path for loading WASM files.
|
|
157
171
|
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
172
|
+
* Must be called before using any other functions when the WASM file is not
|
|
173
|
+
* served from the same directory as the JavaScript bundle.
|
|
160
174
|
*
|
|
161
175
|
* @param newLocation - Base URL or path where WASM files are located.
|
|
162
|
-
*
|
|
163
|
-
* @example
|
|
164
|
-
* ```typescript
|
|
165
|
-
* // Set location before any other calls
|
|
166
|
-
* setLocation('/assets/wasm/');
|
|
167
|
-
* ```
|
|
168
176
|
*/
|
|
169
177
|
declare function setLocation(newLocation: string): void;
|
|
170
178
|
/**
|
|
171
|
-
* Sets
|
|
172
|
-
*
|
|
173
|
-
* Use this when the WASM binary is inlined as a base64 data URL
|
|
174
|
-
* at build time. Unlike `setLocation`, this passes the URL directly
|
|
175
|
-
* to the WASM init function without appending a filename.
|
|
179
|
+
* Sets an explicit URL (or `data:` URL) for the WASM file.
|
|
176
180
|
*
|
|
177
|
-
*
|
|
181
|
+
* Useful when bundling the WASM as a base64 data URL.
|
|
178
182
|
*
|
|
179
|
-
* @
|
|
180
|
-
* ```typescript
|
|
181
|
-
* // With a build tool that inlines WASM as base64 data URLs:
|
|
182
|
-
* import wasmDataUrl from 'open-ultrahdr-wasm/pkg/open_ultrahdr_bg.wasm';
|
|
183
|
-
* setWasmUrl(wasmDataUrl);
|
|
184
|
-
* ```
|
|
183
|
+
* @param url - Full URL or data URL pointing to `open_ultrahdr.wasm`.
|
|
185
184
|
*/
|
|
186
185
|
declare function setWasmUrl(url: string): void;
|
|
187
186
|
/**
|
|
188
187
|
* Checks if a buffer contains an UltraHDR image.
|
|
189
|
-
*
|
|
190
|
-
* This is a fast check that looks for gain map metadata without
|
|
191
|
-
* fully decoding the image.
|
|
192
|
-
*
|
|
193
|
-
* @param buffer - JPEG file contents.
|
|
194
|
-
* @return True if the image contains UltraHDR/gain map data.
|
|
195
|
-
*
|
|
196
|
-
* @example
|
|
197
|
-
* ```typescript
|
|
198
|
-
* const buffer = await file.arrayBuffer();
|
|
199
|
-
* if (await isUltraHdr(buffer)) {
|
|
200
|
-
* console.log('This is an UltraHDR image!');
|
|
201
|
-
* }
|
|
202
|
-
* ```
|
|
203
188
|
*/
|
|
204
189
|
declare function isUltraHdr(buffer: ArrayBuffer): Promise<boolean>;
|
|
205
190
|
/**
|
|
206
|
-
* Probes an image to check if it's UltraHDR and extracts component
|
|
207
|
-
*
|
|
208
|
-
* This function efficiently validates if an image is UltraHDR by checking for
|
|
209
|
-
* required components (primary image, gain map, metadata) without full decoding.
|
|
210
|
-
* Returns structured results useful for batch processing and filtering.
|
|
191
|
+
* Probes an image to check if it's UltraHDR and extracts component info.
|
|
211
192
|
*
|
|
212
|
-
*
|
|
213
|
-
* was found, making it useful for diagnostics and filtering workflows.
|
|
214
|
-
*
|
|
215
|
-
* @param buffer - Image file contents.
|
|
216
|
-
* @return Probe result with detailed component information.
|
|
217
|
-
*
|
|
218
|
-
* @example
|
|
219
|
-
* ```typescript
|
|
220
|
-
* const buffer = await file.arrayBuffer();
|
|
221
|
-
* const result = await probeUltraHdr(buffer);
|
|
222
|
-
*
|
|
223
|
-
* if (result.isValid) {
|
|
224
|
-
* console.log('UltraHDR image:', result.width, 'x', result.height);
|
|
225
|
-
* console.log('HDR capacity:', result.hdrCapacity, 'stops');
|
|
226
|
-
* console.log('Gain map:', result.gainMapWidth, 'x', result.gainMapHeight);
|
|
227
|
-
* } else {
|
|
228
|
-
* // Diagnose why it's not a valid UltraHDR
|
|
229
|
-
* if (!result.hasPrimaryImage) console.log('Not a valid JPEG');
|
|
230
|
-
* if (!result.hasGainMap) console.log('Missing gain map');
|
|
231
|
-
* if (!result.hasMetadata) console.log('Missing HDR metadata');
|
|
232
|
-
* }
|
|
233
|
-
* ```
|
|
193
|
+
* Never throws — invalid inputs return a result with all flags set to false.
|
|
234
194
|
*/
|
|
235
195
|
declare function probeUltraHdr(buffer: ArrayBuffer): Promise<UltraHdrProbeResult>;
|
|
236
196
|
/**
|
|
237
197
|
* Decodes an UltraHDR image, extracting all components.
|
|
238
|
-
*
|
|
239
|
-
* @param id - Unique identifier for this operation (for cancellation).
|
|
240
|
-
* @param buffer - UltraHDR JPEG file contents.
|
|
241
|
-
* @return Decoded result with SDR image, gain map, and metadata.
|
|
242
|
-
*
|
|
243
|
-
* @throws Error if the buffer is not a valid UltraHDR JPEG.
|
|
244
|
-
*
|
|
245
|
-
* @example
|
|
246
|
-
* ```typescript
|
|
247
|
-
* const buffer = await file.arrayBuffer();
|
|
248
|
-
* const result = await decodeUltraHdr('upload-1', buffer);
|
|
249
|
-
*
|
|
250
|
-
* // Access components
|
|
251
|
-
* const sdrBlob = new Blob([result.sdrImage], { type: 'image/jpeg' });
|
|
252
|
-
* console.log('Image size:', result.width, 'x', result.height);
|
|
253
|
-
* console.log('HDR capacity:', result.metadata.hdrCapacityMax);
|
|
254
|
-
* ```
|
|
255
198
|
*/
|
|
256
|
-
declare function decodeUltraHdr(
|
|
199
|
+
declare function decodeUltraHdr(_id: ItemId, buffer: ArrayBuffer): Promise<UltraHdrDecodeResult>;
|
|
257
200
|
/**
|
|
258
201
|
* Encodes an UltraHDR JPEG from SDR and HDR inputs.
|
|
259
|
-
*
|
|
260
|
-
* @param id - Unique identifier for this operation.
|
|
261
|
-
* @param sdrBuffer - SDR JPEG image bytes.
|
|
262
|
-
* @param hdrBuffer - HDR linear RGB data (Float32Array, 3 values per pixel).
|
|
263
|
-
* @param options - Encoding options.
|
|
264
|
-
* @return Encoded UltraHDR JPEG as ArrayBuffer.
|
|
265
|
-
*
|
|
266
|
-
* @throws Error if inputs are invalid or dimensions don't match.
|
|
267
|
-
*
|
|
268
|
-
* @example
|
|
269
|
-
* ```typescript
|
|
270
|
-
* const sdrBuffer = await sdrFile.arrayBuffer();
|
|
271
|
-
* const hdrData = await getHdrLinearData(); // Float32Array
|
|
272
|
-
*
|
|
273
|
-
* const ultraHdr = await encodeUltraHdr('encode-1', sdrBuffer, hdrData, {
|
|
274
|
-
* ...defaultEncodeOptions,
|
|
275
|
-
* targetHdrCapacity: 4.0,
|
|
276
|
-
* });
|
|
277
|
-
*
|
|
278
|
-
* // Create downloadable file
|
|
279
|
-
* const blob = new Blob([ultraHdr], { type: 'image/jpeg' });
|
|
280
|
-
* ```
|
|
281
202
|
*/
|
|
282
|
-
declare function encodeUltraHdr(
|
|
203
|
+
declare function encodeUltraHdr(_id: ItemId, sdrBuffer: ArrayBuffer, hdrBuffer: ArrayBuffer, options?: Partial<UltraHdrEncodeOptions>): Promise<ArrayBuffer>;
|
|
283
204
|
/**
|
|
284
205
|
* Extracts the SDR base image from an UltraHDR JPEG.
|
|
285
|
-
*
|
|
286
|
-
* This produces a standard JPEG that can be displayed on any device,
|
|
287
|
-
* without the gain map metadata. Useful for backwards compatibility.
|
|
288
|
-
*
|
|
289
|
-
* @param buffer - UltraHDR JPEG file contents.
|
|
290
|
-
* @return Standard JPEG without gain map.
|
|
291
|
-
*
|
|
292
|
-
* @example
|
|
293
|
-
* ```typescript
|
|
294
|
-
* const ultraHdrBuffer = await file.arrayBuffer();
|
|
295
|
-
* const sdrBuffer = await extractSdrBase(ultraHdrBuffer);
|
|
296
|
-
*
|
|
297
|
-
* // Use the SDR image for non-HDR displays
|
|
298
|
-
* const blob = new Blob([sdrBuffer], { type: 'image/jpeg' });
|
|
299
|
-
* ```
|
|
300
206
|
*/
|
|
301
207
|
declare function extractSdrBase(buffer: ArrayBuffer): Promise<ArrayBuffer>;
|
|
302
208
|
/**
|
|
303
209
|
* Gets gain map metadata from an UltraHDR JPEG.
|
|
304
|
-
*
|
|
305
|
-
* This is faster than `decodeUltraHdr` when you only need the metadata.
|
|
306
|
-
*
|
|
307
|
-
* @param buffer - UltraHDR JPEG file contents.
|
|
308
|
-
* @return Gain map metadata.
|
|
309
|
-
*
|
|
310
|
-
* @throws Error if the buffer doesn't contain gain map metadata.
|
|
311
|
-
*
|
|
312
|
-
* @example
|
|
313
|
-
* ```typescript
|
|
314
|
-
* const metadata = await getMetadata(buffer);
|
|
315
|
-
* console.log('Version:', metadata.version);
|
|
316
|
-
* console.log('HDR headroom:', metadata.hdrCapacityMax, 'stops');
|
|
317
|
-
* ```
|
|
318
210
|
*/
|
|
319
211
|
declare function getMetadata(buffer: ArrayBuffer): Promise<GainMapMetadata>;
|
|
320
212
|
/**
|
|
321
213
|
* Validates gain map metadata.
|
|
322
|
-
*
|
|
323
|
-
* @param metadata - The metadata to validate.
|
|
324
|
-
* @return True if the metadata is valid.
|
|
325
214
|
*/
|
|
326
215
|
declare function validateMetadata(metadata: GainMapMetadata): Promise<boolean>;
|
|
327
216
|
/**
|
|
328
217
|
* Estimates the HDR headroom from metadata.
|
|
329
|
-
*
|
|
330
|
-
* @param metadata - The gain map metadata.
|
|
331
|
-
* @return Maximum additional stops of dynamic range above SDR.
|
|
332
218
|
*/
|
|
333
219
|
declare function estimateHdrHeadroom(metadata: GainMapMetadata): Promise<number>;
|
|
334
220
|
/**
|
|
335
221
|
* Checks if metadata indicates a meaningful HDR image.
|
|
336
|
-
*
|
|
337
|
-
* @param metadata - The gain map metadata.
|
|
338
|
-
* @return True if the gain map provides significant dynamic range extension.
|
|
339
222
|
*/
|
|
340
223
|
declare function isMeaningfulHdr(metadata: GainMapMetadata): Promise<boolean>;
|
|
341
224
|
|
package/dist/index.d.ts
CHANGED
|
@@ -85,9 +85,23 @@ interface UltraHdrEncodeOptions {
|
|
|
85
85
|
gainMapQuality: number;
|
|
86
86
|
/** Target HDR capacity (typically 2.0-4.0) */
|
|
87
87
|
targetHdrCapacity: number;
|
|
88
|
-
/**
|
|
88
|
+
/**
|
|
89
|
+
* Whether to include ISO 21496-1 metadata.
|
|
90
|
+
*
|
|
91
|
+
* Currently a no-op: libultrahdr's encoder unconditionally emits ISO
|
|
92
|
+
* 21496-1 metadata and exposes no public toggle. Kept for API stability
|
|
93
|
+
* with prior versions; setting this to `false` will not suppress the
|
|
94
|
+
* metadata block.
|
|
95
|
+
*/
|
|
89
96
|
includeIsoMetadata: boolean;
|
|
90
|
-
/**
|
|
97
|
+
/**
|
|
98
|
+
* Whether to include UltraHDR v1 metadata for Android compatibility.
|
|
99
|
+
*
|
|
100
|
+
* Currently a no-op: libultrahdr's encoder unconditionally emits the v1
|
|
101
|
+
* metadata block and exposes no public toggle. Kept for API stability
|
|
102
|
+
* with prior versions; setting this to `false` will not suppress the
|
|
103
|
+
* metadata block.
|
|
104
|
+
*/
|
|
91
105
|
includeUltrahdrV1: boolean;
|
|
92
106
|
/** Downscale factor for the gain map (1 = same size, 2 = half, 4 = quarter) */
|
|
93
107
|
gainMapScale: number;
|
|
@@ -132,18 +146,18 @@ declare const smallSizeEncodeOptions: UltraHdrEncodeOptions;
|
|
|
132
146
|
/**
|
|
133
147
|
* Open UltraHDR Library
|
|
134
148
|
*
|
|
135
|
-
* TypeScript bindings for the
|
|
136
|
-
*
|
|
137
|
-
*
|
|
149
|
+
* TypeScript bindings for the libultrahdr WASM library. Provides detection,
|
|
150
|
+
* encoding, and decoding of UltraHDR JPEG images implementing the
|
|
151
|
+
* ISO 21496-1 (gain map) specification.
|
|
152
|
+
*
|
|
153
|
+
* Backed by upstream `libultrahdr` compiled to WebAssembly via Emscripten/embind.
|
|
138
154
|
*
|
|
139
155
|
* @example
|
|
140
156
|
* ```typescript
|
|
141
157
|
* import { isUltraHdr, decodeUltraHdr, setLocation } from 'open-ultrahdr';
|
|
142
158
|
*
|
|
143
|
-
* // Set the location for WASM files
|
|
144
159
|
* setLocation('/path/to/wasm/');
|
|
145
160
|
*
|
|
146
|
-
* // Check if an image is UltraHDR
|
|
147
161
|
* const buffer = await file.arrayBuffer();
|
|
148
162
|
* if (await isUltraHdr(buffer)) {
|
|
149
163
|
* const result = await decodeUltraHdr('item-1', buffer);
|
|
@@ -155,187 +169,56 @@ declare const smallSizeEncodeOptions: UltraHdrEncodeOptions;
|
|
|
155
169
|
/**
|
|
156
170
|
* Sets the location/public path for loading WASM files.
|
|
157
171
|
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
172
|
+
* Must be called before using any other functions when the WASM file is not
|
|
173
|
+
* served from the same directory as the JavaScript bundle.
|
|
160
174
|
*
|
|
161
175
|
* @param newLocation - Base URL or path where WASM files are located.
|
|
162
|
-
*
|
|
163
|
-
* @example
|
|
164
|
-
* ```typescript
|
|
165
|
-
* // Set location before any other calls
|
|
166
|
-
* setLocation('/assets/wasm/');
|
|
167
|
-
* ```
|
|
168
176
|
*/
|
|
169
177
|
declare function setLocation(newLocation: string): void;
|
|
170
178
|
/**
|
|
171
|
-
* Sets
|
|
172
|
-
*
|
|
173
|
-
* Use this when the WASM binary is inlined as a base64 data URL
|
|
174
|
-
* at build time. Unlike `setLocation`, this passes the URL directly
|
|
175
|
-
* to the WASM init function without appending a filename.
|
|
179
|
+
* Sets an explicit URL (or `data:` URL) for the WASM file.
|
|
176
180
|
*
|
|
177
|
-
*
|
|
181
|
+
* Useful when bundling the WASM as a base64 data URL.
|
|
178
182
|
*
|
|
179
|
-
* @
|
|
180
|
-
* ```typescript
|
|
181
|
-
* // With a build tool that inlines WASM as base64 data URLs:
|
|
182
|
-
* import wasmDataUrl from 'open-ultrahdr-wasm/pkg/open_ultrahdr_bg.wasm';
|
|
183
|
-
* setWasmUrl(wasmDataUrl);
|
|
184
|
-
* ```
|
|
183
|
+
* @param url - Full URL or data URL pointing to `open_ultrahdr.wasm`.
|
|
185
184
|
*/
|
|
186
185
|
declare function setWasmUrl(url: string): void;
|
|
187
186
|
/**
|
|
188
187
|
* Checks if a buffer contains an UltraHDR image.
|
|
189
|
-
*
|
|
190
|
-
* This is a fast check that looks for gain map metadata without
|
|
191
|
-
* fully decoding the image.
|
|
192
|
-
*
|
|
193
|
-
* @param buffer - JPEG file contents.
|
|
194
|
-
* @return True if the image contains UltraHDR/gain map data.
|
|
195
|
-
*
|
|
196
|
-
* @example
|
|
197
|
-
* ```typescript
|
|
198
|
-
* const buffer = await file.arrayBuffer();
|
|
199
|
-
* if (await isUltraHdr(buffer)) {
|
|
200
|
-
* console.log('This is an UltraHDR image!');
|
|
201
|
-
* }
|
|
202
|
-
* ```
|
|
203
188
|
*/
|
|
204
189
|
declare function isUltraHdr(buffer: ArrayBuffer): Promise<boolean>;
|
|
205
190
|
/**
|
|
206
|
-
* Probes an image to check if it's UltraHDR and extracts component
|
|
207
|
-
*
|
|
208
|
-
* This function efficiently validates if an image is UltraHDR by checking for
|
|
209
|
-
* required components (primary image, gain map, metadata) without full decoding.
|
|
210
|
-
* Returns structured results useful for batch processing and filtering.
|
|
191
|
+
* Probes an image to check if it's UltraHDR and extracts component info.
|
|
211
192
|
*
|
|
212
|
-
*
|
|
213
|
-
* was found, making it useful for diagnostics and filtering workflows.
|
|
214
|
-
*
|
|
215
|
-
* @param buffer - Image file contents.
|
|
216
|
-
* @return Probe result with detailed component information.
|
|
217
|
-
*
|
|
218
|
-
* @example
|
|
219
|
-
* ```typescript
|
|
220
|
-
* const buffer = await file.arrayBuffer();
|
|
221
|
-
* const result = await probeUltraHdr(buffer);
|
|
222
|
-
*
|
|
223
|
-
* if (result.isValid) {
|
|
224
|
-
* console.log('UltraHDR image:', result.width, 'x', result.height);
|
|
225
|
-
* console.log('HDR capacity:', result.hdrCapacity, 'stops');
|
|
226
|
-
* console.log('Gain map:', result.gainMapWidth, 'x', result.gainMapHeight);
|
|
227
|
-
* } else {
|
|
228
|
-
* // Diagnose why it's not a valid UltraHDR
|
|
229
|
-
* if (!result.hasPrimaryImage) console.log('Not a valid JPEG');
|
|
230
|
-
* if (!result.hasGainMap) console.log('Missing gain map');
|
|
231
|
-
* if (!result.hasMetadata) console.log('Missing HDR metadata');
|
|
232
|
-
* }
|
|
233
|
-
* ```
|
|
193
|
+
* Never throws — invalid inputs return a result with all flags set to false.
|
|
234
194
|
*/
|
|
235
195
|
declare function probeUltraHdr(buffer: ArrayBuffer): Promise<UltraHdrProbeResult>;
|
|
236
196
|
/**
|
|
237
197
|
* Decodes an UltraHDR image, extracting all components.
|
|
238
|
-
*
|
|
239
|
-
* @param id - Unique identifier for this operation (for cancellation).
|
|
240
|
-
* @param buffer - UltraHDR JPEG file contents.
|
|
241
|
-
* @return Decoded result with SDR image, gain map, and metadata.
|
|
242
|
-
*
|
|
243
|
-
* @throws Error if the buffer is not a valid UltraHDR JPEG.
|
|
244
|
-
*
|
|
245
|
-
* @example
|
|
246
|
-
* ```typescript
|
|
247
|
-
* const buffer = await file.arrayBuffer();
|
|
248
|
-
* const result = await decodeUltraHdr('upload-1', buffer);
|
|
249
|
-
*
|
|
250
|
-
* // Access components
|
|
251
|
-
* const sdrBlob = new Blob([result.sdrImage], { type: 'image/jpeg' });
|
|
252
|
-
* console.log('Image size:', result.width, 'x', result.height);
|
|
253
|
-
* console.log('HDR capacity:', result.metadata.hdrCapacityMax);
|
|
254
|
-
* ```
|
|
255
198
|
*/
|
|
256
|
-
declare function decodeUltraHdr(
|
|
199
|
+
declare function decodeUltraHdr(_id: ItemId, buffer: ArrayBuffer): Promise<UltraHdrDecodeResult>;
|
|
257
200
|
/**
|
|
258
201
|
* Encodes an UltraHDR JPEG from SDR and HDR inputs.
|
|
259
|
-
*
|
|
260
|
-
* @param id - Unique identifier for this operation.
|
|
261
|
-
* @param sdrBuffer - SDR JPEG image bytes.
|
|
262
|
-
* @param hdrBuffer - HDR linear RGB data (Float32Array, 3 values per pixel).
|
|
263
|
-
* @param options - Encoding options.
|
|
264
|
-
* @return Encoded UltraHDR JPEG as ArrayBuffer.
|
|
265
|
-
*
|
|
266
|
-
* @throws Error if inputs are invalid or dimensions don't match.
|
|
267
|
-
*
|
|
268
|
-
* @example
|
|
269
|
-
* ```typescript
|
|
270
|
-
* const sdrBuffer = await sdrFile.arrayBuffer();
|
|
271
|
-
* const hdrData = await getHdrLinearData(); // Float32Array
|
|
272
|
-
*
|
|
273
|
-
* const ultraHdr = await encodeUltraHdr('encode-1', sdrBuffer, hdrData, {
|
|
274
|
-
* ...defaultEncodeOptions,
|
|
275
|
-
* targetHdrCapacity: 4.0,
|
|
276
|
-
* });
|
|
277
|
-
*
|
|
278
|
-
* // Create downloadable file
|
|
279
|
-
* const blob = new Blob([ultraHdr], { type: 'image/jpeg' });
|
|
280
|
-
* ```
|
|
281
202
|
*/
|
|
282
|
-
declare function encodeUltraHdr(
|
|
203
|
+
declare function encodeUltraHdr(_id: ItemId, sdrBuffer: ArrayBuffer, hdrBuffer: ArrayBuffer, options?: Partial<UltraHdrEncodeOptions>): Promise<ArrayBuffer>;
|
|
283
204
|
/**
|
|
284
205
|
* Extracts the SDR base image from an UltraHDR JPEG.
|
|
285
|
-
*
|
|
286
|
-
* This produces a standard JPEG that can be displayed on any device,
|
|
287
|
-
* without the gain map metadata. Useful for backwards compatibility.
|
|
288
|
-
*
|
|
289
|
-
* @param buffer - UltraHDR JPEG file contents.
|
|
290
|
-
* @return Standard JPEG without gain map.
|
|
291
|
-
*
|
|
292
|
-
* @example
|
|
293
|
-
* ```typescript
|
|
294
|
-
* const ultraHdrBuffer = await file.arrayBuffer();
|
|
295
|
-
* const sdrBuffer = await extractSdrBase(ultraHdrBuffer);
|
|
296
|
-
*
|
|
297
|
-
* // Use the SDR image for non-HDR displays
|
|
298
|
-
* const blob = new Blob([sdrBuffer], { type: 'image/jpeg' });
|
|
299
|
-
* ```
|
|
300
206
|
*/
|
|
301
207
|
declare function extractSdrBase(buffer: ArrayBuffer): Promise<ArrayBuffer>;
|
|
302
208
|
/**
|
|
303
209
|
* Gets gain map metadata from an UltraHDR JPEG.
|
|
304
|
-
*
|
|
305
|
-
* This is faster than `decodeUltraHdr` when you only need the metadata.
|
|
306
|
-
*
|
|
307
|
-
* @param buffer - UltraHDR JPEG file contents.
|
|
308
|
-
* @return Gain map metadata.
|
|
309
|
-
*
|
|
310
|
-
* @throws Error if the buffer doesn't contain gain map metadata.
|
|
311
|
-
*
|
|
312
|
-
* @example
|
|
313
|
-
* ```typescript
|
|
314
|
-
* const metadata = await getMetadata(buffer);
|
|
315
|
-
* console.log('Version:', metadata.version);
|
|
316
|
-
* console.log('HDR headroom:', metadata.hdrCapacityMax, 'stops');
|
|
317
|
-
* ```
|
|
318
210
|
*/
|
|
319
211
|
declare function getMetadata(buffer: ArrayBuffer): Promise<GainMapMetadata>;
|
|
320
212
|
/**
|
|
321
213
|
* Validates gain map metadata.
|
|
322
|
-
*
|
|
323
|
-
* @param metadata - The metadata to validate.
|
|
324
|
-
* @return True if the metadata is valid.
|
|
325
214
|
*/
|
|
326
215
|
declare function validateMetadata(metadata: GainMapMetadata): Promise<boolean>;
|
|
327
216
|
/**
|
|
328
217
|
* Estimates the HDR headroom from metadata.
|
|
329
|
-
*
|
|
330
|
-
* @param metadata - The gain map metadata.
|
|
331
|
-
* @return Maximum additional stops of dynamic range above SDR.
|
|
332
218
|
*/
|
|
333
219
|
declare function estimateHdrHeadroom(metadata: GainMapMetadata): Promise<number>;
|
|
334
220
|
/**
|
|
335
221
|
* Checks if metadata indicates a meaningful HDR image.
|
|
336
|
-
*
|
|
337
|
-
* @param metadata - The gain map metadata.
|
|
338
|
-
* @return True if the gain map provides significant dynamic range extension.
|
|
339
222
|
*/
|
|
340
223
|
declare function isMeaningfulHdr(metadata: GainMapMetadata): Promise<boolean>;
|
|
341
224
|
|
package/dist/index.js
CHANGED
|
@@ -89,65 +89,61 @@ var smallSizeEncodeOptions = {
|
|
|
89
89
|
};
|
|
90
90
|
|
|
91
91
|
// src/index.ts
|
|
92
|
+
var WASM_FILENAME = "open_ultrahdr.wasm";
|
|
92
93
|
var location = "";
|
|
93
|
-
var
|
|
94
|
+
var explicitWasmUrl = null;
|
|
94
95
|
var wasmInstance = null;
|
|
95
96
|
var initPromise = null;
|
|
97
|
+
var initGeneration = 0;
|
|
96
98
|
function setLocation(newLocation) {
|
|
97
99
|
location = newLocation;
|
|
100
|
+
explicitWasmUrl = null;
|
|
101
|
+
resetCache();
|
|
98
102
|
}
|
|
99
103
|
function setWasmUrl(url) {
|
|
100
|
-
|
|
104
|
+
explicitWasmUrl = url;
|
|
105
|
+
resetCache();
|
|
101
106
|
}
|
|
102
|
-
function
|
|
103
|
-
|
|
107
|
+
function resetCache() {
|
|
108
|
+
initGeneration += 1;
|
|
109
|
+
wasmInstance = null;
|
|
110
|
+
initPromise = null;
|
|
104
111
|
}
|
|
105
|
-
|
|
106
|
-
if (
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
const wasm = await getWasm();
|
|
110
|
-
const wasmMetadata = wasm.createDefaultMetadata();
|
|
111
|
-
wasmMetadata.version = metadata.version;
|
|
112
|
-
wasmMetadata.baseRenditionIsHdr = metadata.baseRenditionIsHdr;
|
|
113
|
-
wasmMetadata.gainMapMin = metadata.gainMapMin;
|
|
114
|
-
wasmMetadata.gainMapMax = metadata.gainMapMax;
|
|
115
|
-
wasmMetadata.gamma = metadata.gamma;
|
|
116
|
-
wasmMetadata.offsetSdr = metadata.offsetSdr;
|
|
117
|
-
wasmMetadata.offsetHdr = metadata.offsetHdr;
|
|
118
|
-
wasmMetadata.hdrCapacityMin = metadata.hdrCapacityMin;
|
|
119
|
-
wasmMetadata.hdrCapacityMax = metadata.hdrCapacityMax;
|
|
120
|
-
return wasmMetadata;
|
|
112
|
+
function joinPath(base, name) {
|
|
113
|
+
if (!base) return name;
|
|
114
|
+
return base.endsWith("/") ? `${base}${name}` : `${base}/${name}`;
|
|
121
115
|
}
|
|
122
116
|
async function getWasm() {
|
|
123
|
-
if (wasmInstance)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (initPromise) {
|
|
127
|
-
return initPromise;
|
|
128
|
-
}
|
|
117
|
+
if (wasmInstance) return wasmInstance;
|
|
118
|
+
if (initPromise) return initPromise;
|
|
119
|
+
const generation = initGeneration;
|
|
129
120
|
initPromise = (async () => {
|
|
130
121
|
try {
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
122
|
+
const wasmModule = await import("open-ultrahdr-wasm");
|
|
123
|
+
const factory = wasmModule.default;
|
|
124
|
+
const isNode = typeof process !== "undefined" && !!process.versions && !!process.versions.node;
|
|
125
|
+
const moduleOptions = {};
|
|
126
|
+
if (explicitWasmUrl) {
|
|
127
|
+
moduleOptions.locateFile = (path) => path.endsWith(".wasm") ? explicitWasmUrl : path;
|
|
134
128
|
} else if (location) {
|
|
135
|
-
|
|
136
|
-
const wasmPath = base + "open_ultrahdr_bg.wasm";
|
|
137
|
-
if (typeof process !== "undefined" && process.versions && process.versions.node) {
|
|
129
|
+
if (isNode) {
|
|
138
130
|
const fs = await import("fs");
|
|
139
|
-
const wasmBytes = await fs.promises.readFile(
|
|
140
|
-
|
|
131
|
+
const wasmBytes = await fs.promises.readFile(joinPath(location, WASM_FILENAME));
|
|
132
|
+
moduleOptions.wasmBinary = new Uint8Array(wasmBytes);
|
|
141
133
|
} else {
|
|
142
|
-
|
|
134
|
+
moduleOptions.locateFile = (path) => path.endsWith(".wasm") ? joinPath(location, WASM_FILENAME) : path;
|
|
143
135
|
}
|
|
144
|
-
} else {
|
|
145
|
-
await UltraHdrWasm.default();
|
|
146
136
|
}
|
|
147
|
-
|
|
148
|
-
|
|
137
|
+
const instance = await factory(moduleOptions);
|
|
138
|
+
if (generation !== initGeneration) {
|
|
139
|
+
return getWasm();
|
|
140
|
+
}
|
|
141
|
+
wasmInstance = instance;
|
|
142
|
+
return instance;
|
|
149
143
|
} catch (err) {
|
|
150
|
-
|
|
144
|
+
if (generation === initGeneration) {
|
|
145
|
+
initPromise = null;
|
|
146
|
+
}
|
|
151
147
|
throw err;
|
|
152
148
|
}
|
|
153
149
|
})();
|
|
@@ -158,27 +154,35 @@ async function isUltraHdr(buffer) {
|
|
|
158
154
|
return wasm.isUltraHdr(new Uint8Array(buffer));
|
|
159
155
|
}
|
|
160
156
|
async function probeUltraHdr(buffer) {
|
|
161
|
-
|
|
162
|
-
|
|
157
|
+
try {
|
|
158
|
+
const wasm = await getWasm();
|
|
159
|
+
return wasm.probeUltraHdr(new Uint8Array(buffer));
|
|
160
|
+
} catch {
|
|
161
|
+
return {
|
|
162
|
+
isValid: false,
|
|
163
|
+
hasPrimaryImage: false,
|
|
164
|
+
hasGainMap: false,
|
|
165
|
+
hasMetadata: false,
|
|
166
|
+
width: 0,
|
|
167
|
+
height: 0,
|
|
168
|
+
gainMapWidth: 0,
|
|
169
|
+
gainMapHeight: 0,
|
|
170
|
+
hdrCapacity: 0,
|
|
171
|
+
metadataVersion: ""
|
|
172
|
+
};
|
|
173
|
+
}
|
|
163
174
|
}
|
|
164
|
-
async function decodeUltraHdr(
|
|
175
|
+
async function decodeUltraHdr(_id, buffer) {
|
|
165
176
|
const wasm = await getWasm();
|
|
166
177
|
return wasm.decodeUltraHdr(new Uint8Array(buffer));
|
|
167
178
|
}
|
|
168
|
-
async function encodeUltraHdr(
|
|
179
|
+
async function encodeUltraHdr(_id, sdrBuffer, hdrBuffer, options) {
|
|
169
180
|
const wasm = await getWasm();
|
|
170
|
-
const
|
|
171
|
-
const mergedOpts = { ...defaultEncodeOptions, ...options };
|
|
172
|
-
wasmOpts.baseQuality = mergedOpts.baseQuality;
|
|
173
|
-
wasmOpts.gainMapQuality = mergedOpts.gainMapQuality;
|
|
174
|
-
wasmOpts.targetHdrCapacity = mergedOpts.targetHdrCapacity;
|
|
175
|
-
wasmOpts.includeIsoMetadata = mergedOpts.includeIsoMetadata;
|
|
176
|
-
wasmOpts.includeUltrahdrV1 = mergedOpts.includeUltrahdrV1;
|
|
177
|
-
wasmOpts.gainMapScale = mergedOpts.gainMapScale;
|
|
181
|
+
const merged = { ...defaultEncodeOptions, ...options };
|
|
178
182
|
const result = wasm.encodeUltraHdr(
|
|
179
183
|
new Uint8Array(sdrBuffer),
|
|
180
184
|
new Float32Array(hdrBuffer),
|
|
181
|
-
|
|
185
|
+
merged
|
|
182
186
|
);
|
|
183
187
|
return result.buffer.slice(
|
|
184
188
|
result.byteOffset,
|
|
@@ -199,18 +203,15 @@ async function getMetadata(buffer) {
|
|
|
199
203
|
}
|
|
200
204
|
async function validateMetadata(metadata) {
|
|
201
205
|
const wasm = await getWasm();
|
|
202
|
-
|
|
203
|
-
return wasm.validateMetadata(wasmMetadata);
|
|
206
|
+
return wasm.validateMetadata(metadata);
|
|
204
207
|
}
|
|
205
208
|
async function estimateHdrHeadroom(metadata) {
|
|
206
209
|
const wasm = await getWasm();
|
|
207
|
-
|
|
208
|
-
return wasm.estimateHdrHeadroom(wasmMetadata);
|
|
210
|
+
return wasm.estimateHdrHeadroom(metadata);
|
|
209
211
|
}
|
|
210
212
|
async function isMeaningfulHdr(metadata) {
|
|
211
213
|
const wasm = await getWasm();
|
|
212
|
-
|
|
213
|
-
return wasm.isMeaningfulHdr(wasmMetadata);
|
|
214
|
+
return wasm.isMeaningfulHdr(metadata);
|
|
214
215
|
}
|
|
215
216
|
// Annotate the CommonJS export names for ESM import in node:
|
|
216
217
|
0 && (module.exports = {
|