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