@woosh/meep-engine 3.64.0 → 3.64.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.
Files changed (52) hide show
  1. package/package.json +1 -1
  2. package/src/engine/graphics/texture/sampler/exr_to_sampler2d.d.ts +27 -0
  3. package/src/engine/graphics/texture/sampler/exr_to_sampler2d.d.ts.map +1 -0
  4. package/src/engine/graphics/texture/sampler/exr_to_sampler2d.js +91 -0
  5. package/src/engine/graphics/texture/sampler/sampler2d_to_exr.d.ts +23 -0
  6. package/src/engine/graphics/texture/sampler/sampler2d_to_exr.d.ts.map +1 -0
  7. package/src/engine/graphics/texture/sampler/sampler2d_to_exr.js +64 -0
  8. package/src/format/image/exr/ExrCompression.d.ts +22 -0
  9. package/src/format/image/exr/ExrCompression.d.ts.map +1 -0
  10. package/src/format/image/exr/ExrCompression.js +27 -0
  11. package/src/format/image/exr/ExrImage.d.ts +32 -0
  12. package/src/format/image/exr/ExrImage.d.ts.map +1 -0
  13. package/src/format/image/exr/ExrImage.js +32 -0
  14. package/src/format/image/exr/ExrPixelType.d.ts +13 -0
  15. package/src/format/image/exr/ExrPixelType.d.ts.map +1 -0
  16. package/src/format/image/exr/ExrPixelType.js +18 -0
  17. package/src/format/image/exr/exr_compare_names.d.ts +16 -0
  18. package/src/format/image/exr/exr_compare_names.d.ts.map +1 -0
  19. package/src/format/image/exr/exr_compare_names.js +25 -0
  20. package/src/format/image/exr/exr_constants.d.ts +49 -0
  21. package/src/format/image/exr/exr_constants.d.ts.map +1 -0
  22. package/src/format/image/exr/exr_constants.js +56 -0
  23. package/src/format/image/exr/exr_read.d.ts +32 -0
  24. package/src/format/image/exr/exr_read.d.ts.map +1 -0
  25. package/src/format/image/exr/exr_read.js +531 -0
  26. package/src/format/image/exr/exr_sample_bits.d.ts +16 -0
  27. package/src/format/image/exr/exr_sample_bits.d.ts.map +1 -0
  28. package/src/format/image/exr/exr_sample_bits.js +21 -0
  29. package/src/format/image/exr/exr_scanlines_per_chunk.d.ts +17 -0
  30. package/src/format/image/exr/exr_scanlines_per_chunk.d.ts.map +1 -0
  31. package/src/format/image/exr/exr_scanlines_per_chunk.js +31 -0
  32. package/src/format/image/exr/exr_write.d.ts +27 -0
  33. package/src/format/image/exr/exr_write.d.ts.map +1 -0
  34. package/src/format/image/exr/exr_write.js +378 -0
  35. package/src/shade/playground/probe_clipmap/index.html +5 -0
  36. package/src/shade/playground/probe_clipmap/main.d.ts.map +1 -1
  37. package/src/shade/playground/probe_clipmap/main.js +34 -1
  38. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +3 -15
  39. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts.map +1 -1
  40. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.js +4 -17
  41. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts +3 -3
  42. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts.map +1 -1
  43. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.js +15 -13
  44. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts +7 -3
  45. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts.map +1 -1
  46. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.js +28 -17
  47. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.d.ts +18 -18
  48. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.d.ts.map +1 -1
  49. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.js +44 -48
  50. package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.d.ts +8 -0
  51. package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.d.ts.map +1 -1
  52. package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.js +21 -3
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "description": "Advanced 3D game engine",
7
7
  "type": "module",
8
8
  "author": "Alexander Goldring",
9
- "version": "3.64.0",
9
+ "version": "3.64.1",
10
10
  "exports": {
11
11
  "./build/*": "./build/*",
12
12
  "./src/*": "./src/*",
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Decode an OpenEXR file into an RGBA sampler.
3
+ *
4
+ * R, G, B and A come from the file's channels of those names, and a luminance image — Y, with A if it
5
+ * has one — reads as grey. A channel the file lacks reads as 0, or as 1 for alpha; channels of other
6
+ * names are left out.
7
+ *
8
+ * The sampler's storage holds every sample it reads exactly: half float when every one of those channels
9
+ * is HALF, 32-bit unsigned integer when every one is UINT, and float when HALF and FLOAT are mixed.
10
+ * Unsigned integers mixed with either float type are refused, since no storage holds both exactly.
11
+ * Samples are copied as numbers, so every value comes through unchanged but a NaN may come back with
12
+ * another payload.
13
+ *
14
+ * {@link sampler2d_to_exr} names channels the way this reads them, so a four-channel sampler makes the
15
+ * round trip unchanged and one of fewer channels comes back as the RGBA it stands for.
16
+ *
17
+ * @param {ArrayBuffer} bytes the whole file; keep unchanged until the promise settles
18
+ * @returns {Promise<Sampler2D>} four channels
19
+ * @throws {Error} when the file has none of R, G, B and Y, or mixes unsigned integers with floats among
20
+ * the channels read, and wherever {@link exr_read} throws
21
+ *
22
+ * @author Alex Goldring
23
+ * @copyright Company Named Limited (c) 2026
24
+ */
25
+ export function exr_to_sampler2d(bytes: ArrayBuffer): Promise<Sampler2D>;
26
+ import { Sampler2D } from "./Sampler2D.js";
27
+ //# sourceMappingURL=exr_to_sampler2d.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exr_to_sampler2d.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/texture/sampler/exr_to_sampler2d.js"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wCARW,WAAW,GACT,QAAQ,SAAS,CAAC,CA4D9B;0BAzFyB,gBAAgB"}
@@ -0,0 +1,91 @@
1
+ import { exr_read } from "../../../../format/image/exr/exr_read.js";
2
+ import { Sampler2D } from "./Sampler2D.js";
3
+ import { sampler2d_copy_channel_data } from "./sampler2d_copy_channel_data.js";
4
+
5
+ /**
6
+ * What each RGBA channel reads as when the file lacks it: no colour, full alpha. OpenEXR's own RGBA
7
+ * interface fills missing channels the same way.
8
+ *
9
+ * @readonly
10
+ * @type {number[]}
11
+ */
12
+ const MISSING_CHANNEL_VALUE = [0, 0, 0, 1];
13
+
14
+ /**
15
+ * Decode an OpenEXR file into an RGBA sampler.
16
+ *
17
+ * R, G, B and A come from the file's channels of those names, and a luminance image — Y, with A if it
18
+ * has one — reads as grey. A channel the file lacks reads as 0, or as 1 for alpha; channels of other
19
+ * names are left out.
20
+ *
21
+ * The sampler's storage holds every sample it reads exactly: half float when every one of those channels
22
+ * is HALF, 32-bit unsigned integer when every one is UINT, and float when HALF and FLOAT are mixed.
23
+ * Unsigned integers mixed with either float type are refused, since no storage holds both exactly.
24
+ * Samples are copied as numbers, so every value comes through unchanged but a NaN may come back with
25
+ * another payload.
26
+ *
27
+ * {@link sampler2d_to_exr} names channels the way this reads them, so a four-channel sampler makes the
28
+ * round trip unchanged and one of fewer channels comes back as the RGBA it stands for.
29
+ *
30
+ * @param {ArrayBuffer} bytes the whole file; keep unchanged until the promise settles
31
+ * @returns {Promise<Sampler2D>} four channels
32
+ * @throws {Error} when the file has none of R, G, B and Y, or mixes unsigned integers with floats among
33
+ * the channels read, and wherever {@link exr_read} throws
34
+ *
35
+ * @author Alex Goldring
36
+ * @copyright Company Named Limited (c) 2026
37
+ */
38
+ export async function exr_to_sampler2d(bytes) {
39
+ const { width, height, channels } = await exr_read(bytes);
40
+
41
+ const find = (name) => channels.find(channel => channel.name === name);
42
+
43
+ const alpha = find("A");
44
+
45
+ let sources = [find("R"), find("G"), find("B"), alpha];
46
+
47
+ if (sources[0] === undefined && sources[1] === undefined && sources[2] === undefined) {
48
+ const luminance = find("Y");
49
+
50
+ if (luminance === undefined) {
51
+ throw new Error(
52
+ `EXR: no R, G, B or Y channel to read as colour; the file has`
53
+ + ` ${channels.map(channel => channel.name).join(", ")}`
54
+ );
55
+ }
56
+
57
+ sources = [luminance, luminance, luminance, alpha];
58
+ }
59
+
60
+ const read = sources.filter(source => source !== undefined);
61
+
62
+ let result;
63
+
64
+ if (read.every(source => source.data instanceof Float16Array)) {
65
+ result = Sampler2D.float16(4, width, height);
66
+ } else if (read.every(source => source.data instanceof Uint32Array)) {
67
+ result = Sampler2D.uint32(4, width, height);
68
+ } else if (read.some(source => source.data instanceof Uint32Array)) {
69
+ const types = [...new Set(read)]
70
+ .map(source => `${source.name} (${source.data instanceof Uint32Array ? "UINT" : source.data instanceof Float16Array ? "HALF" : "FLOAT"})`);
71
+
72
+ throw new Error(
73
+ `EXR: the channels read as colour, ${types.join(", ")}, mix unsigned integers with floats,`
74
+ + ` which no sampler storage holds both of exactly`
75
+ );
76
+ } else {
77
+ result = Sampler2D.float32(4, width, height);
78
+ }
79
+
80
+ for (let c = 0; c < 4; c++) {
81
+ const source = sources[c];
82
+
83
+ if (source === undefined) {
84
+ result.channelFill(c, MISSING_CHANNEL_VALUE[c]);
85
+ } else {
86
+ sampler2d_copy_channel_data(new Sampler2D(source.data, 1, width, height), 0, result, c);
87
+ }
88
+ }
89
+
90
+ return result;
91
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Encode a sampler as an OpenEXR file.
3
+ *
4
+ * Channels are named the way OpenEXR names them: one channel is a luminance image, Y; two are Y and A;
5
+ * three are R, G and B; four are R, G, B and A. {@link exr_to_sampler2d} reads each of those back as RGBA.
6
+ *
7
+ * The sampler's storage is the pixel type: a `Float16Array` is written as HALF, a `Float32Array` as FLOAT,
8
+ * a `Uint32Array` as UINT. Other storage is refused rather than converted, because what its numbers mean
9
+ * — normalised, sRGB-encoded — is not this function's to guess; convert first, for instance with
10
+ * `sampler2d_srgb_u8_to_linear_f16` or `sampler2d_to_f16`. Samples are copied as numbers, so every value
11
+ * is written unchanged but a NaN may be written with another payload.
12
+ *
13
+ * @param {Sampler2D} sampler 1 to 4 channels
14
+ * @param {ExrCompression} compression see {@link exr_write}
15
+ * @returns {Promise<ArrayBuffer>} the whole file
16
+ * @throws {Error} for any other channel count, and wherever {@link exr_write} throws
17
+ *
18
+ * @author Alex Goldring
19
+ * @copyright Company Named Limited (c) 2026
20
+ */
21
+ export function sampler2d_to_exr(sampler: Sampler2D, compression: ExrCompression): Promise<ArrayBuffer>;
22
+ import { Sampler2D } from "./Sampler2D.js";
23
+ //# sourceMappingURL=sampler2d_to_exr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sampler2d_to_exr.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/texture/sampler/sampler2d_to_exr.js"],"names":[],"mappings":"AAmBA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,0CARW,SAAS,gCAEP,QAAQ,WAAW,CAAC,CA8BhC;0BA9DyB,gBAAgB"}
@@ -0,0 +1,64 @@
1
+ import { exr_write } from "../../../../format/image/exr/exr_write.js";
2
+ import { Sampler2D } from "./Sampler2D.js";
3
+ import { sampler2d_copy_channel_data } from "./sampler2d_copy_channel_data.js";
4
+
5
+ /**
6
+ * Channel names by item size, the way OpenEXR names them: luminance, luminance and alpha, colour, colour
7
+ * and alpha.
8
+ *
9
+ * @readonly
10
+ * @type {(string[]|undefined)[]}
11
+ */
12
+ const CHANNEL_NAMES = [
13
+ undefined,
14
+ ["Y"],
15
+ ["Y", "A"],
16
+ ["R", "G", "B"],
17
+ ["R", "G", "B", "A"],
18
+ ];
19
+
20
+ /**
21
+ * Encode a sampler as an OpenEXR file.
22
+ *
23
+ * Channels are named the way OpenEXR names them: one channel is a luminance image, Y; two are Y and A;
24
+ * three are R, G and B; four are R, G, B and A. {@link exr_to_sampler2d} reads each of those back as RGBA.
25
+ *
26
+ * The sampler's storage is the pixel type: a `Float16Array` is written as HALF, a `Float32Array` as FLOAT,
27
+ * a `Uint32Array` as UINT. Other storage is refused rather than converted, because what its numbers mean
28
+ * — normalised, sRGB-encoded — is not this function's to guess; convert first, for instance with
29
+ * `sampler2d_srgb_u8_to_linear_f16` or `sampler2d_to_f16`. Samples are copied as numbers, so every value
30
+ * is written unchanged but a NaN may be written with another payload.
31
+ *
32
+ * @param {Sampler2D} sampler 1 to 4 channels
33
+ * @param {ExrCompression} compression see {@link exr_write}
34
+ * @returns {Promise<ArrayBuffer>} the whole file
35
+ * @throws {Error} for any other channel count, and wherever {@link exr_write} throws
36
+ *
37
+ * @author Alex Goldring
38
+ * @copyright Company Named Limited (c) 2026
39
+ */
40
+ export async function sampler2d_to_exr(sampler, compression) {
41
+ const width = sampler.width;
42
+ const height = sampler.height;
43
+ const item_size = sampler.itemSize;
44
+
45
+ const names = CHANNEL_NAMES[item_size];
46
+
47
+ if (names === undefined) {
48
+ throw new Error(`EXR: a sampler of ${item_size} channels has no OpenEXR naming; 1 to 4 channels do`);
49
+ }
50
+
51
+ const storage = sampler.data.constructor;
52
+
53
+ const channels = new Array(item_size);
54
+
55
+ for (let c = 0; c < item_size; c++) {
56
+ const plane = new Sampler2D(new storage(width * height), 1, width, height);
57
+
58
+ sampler2d_copy_channel_data(sampler, c, plane, 0);
59
+
60
+ channels[c] = { name: names[c], data: plane.data };
61
+ }
62
+
63
+ return exr_write({ width, height, channels }, compression);
64
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * How the pixel data of an OpenEXR file is compressed, by the value its `compression` attribute holds.
3
+ *
4
+ * {@link exr_read } and {@link exr_write } handle {@link None }, {@link ZIPS } and {@link ZIP }. The other
5
+ * methods are listed so that a refusal can name the one a file uses.
6
+ */
7
+ export type ExrCompression = number;
8
+ export namespace ExrCompression {
9
+ let None: number;
10
+ let RLE: number;
11
+ let ZIPS: number;
12
+ let ZIP: number;
13
+ let PIZ: number;
14
+ let PXR24: number;
15
+ let B44: number;
16
+ let B44A: number;
17
+ let DWAA: number;
18
+ let DWAB: number;
19
+ let HTJ2K256: number;
20
+ let HTJ2K32: number;
21
+ }
22
+ //# sourceMappingURL=ExrCompression.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExrCompression.d.ts","sourceRoot":"","sources":["../../../../../src/format/image/exr/ExrCompression.js"],"names":[],"mappings":";;;;;;6BAQU,MAAM"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * How the pixel data of an OpenEXR file is compressed, by the value its `compression` attribute holds.
3
+ *
4
+ * {@link exr_read} and {@link exr_write} handle {@link None}, {@link ZIPS} and {@link ZIP}. The other
5
+ * methods are listed so that a refusal can name the one a file uses.
6
+ *
7
+ * @see https://openexr.com/en/latest/OpenEXRFileLayout.html#compression-methods
8
+ * @readonly
9
+ * @enum {number}
10
+ */
11
+ export const ExrCompression = {
12
+ /** the chunk bytes are the pixel bytes, one scanline per chunk */
13
+ None: 0,
14
+ RLE: 1,
15
+ /** zlib, one scanline per chunk */
16
+ ZIPS: 2,
17
+ /** zlib, sixteen scanlines per chunk */
18
+ ZIP: 3,
19
+ PIZ: 4,
20
+ PXR24: 5,
21
+ B44: 6,
22
+ B44A: 7,
23
+ DWAA: 8,
24
+ DWAB: 9,
25
+ HTJ2K256: 10,
26
+ HTJ2K32: 11,
27
+ };
@@ -0,0 +1,32 @@
1
+ /**
2
+ * One channel of an {@link ExrImage }.
3
+ *
4
+ * The array's class is the channel's pixel type: `Float16Array` is HALF, `Float32Array` is FLOAT and
5
+ * `Uint32Array` is UINT, the three types OpenEXR has. It holds one sample per pixel, row by row, top row
6
+ * first.
7
+ */
8
+ type ExrChannel = {
9
+ name: string;
10
+ /**
11
+ * `width * height` samples
12
+ */
13
+ data: Float16Array | Float32Array | Uint32Array;
14
+ };
15
+ /**
16
+ * The pixels of a scanline OpenEXR image, one plane per channel — what {@link exr_read } returns and
17
+ * {@link exr_write } takes.
18
+ *
19
+ * `width` and `height` are those of the file's data window. Where that window sits, and the display window
20
+ * around it, are not part of the record: {@link exr_read } drops them and {@link exr_write } puts both windows
21
+ * at the origin, exactly covering the pixels.
22
+ *
23
+ * {@link exr_read } returns channels in the order OpenEXR keeps them, sorted by the bytes of their names
24
+ * (see {@link exr_compare_names }), which is the order a file's pixel data holds them in whatever order its
25
+ * channel list names them. {@link exr_write } takes them in any order.
26
+ */
27
+ type ExrImage = {
28
+ width: number;
29
+ height: number;
30
+ channels: ExrChannel[];
31
+ };
32
+ //# sourceMappingURL=ExrImage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExrImage.d.ts","sourceRoot":"","sources":["../../../../../src/format/image/exr/ExrImage.js"],"names":[],"mappings":";;;;;;;;UAQc,MAAM;;;;UACN,eAAa,YAAY,GAAC,WAAW;;;;;;;;;;;;;;;WAgBrC,MAAM;YACN,MAAM;cACN,UAAU,EAAE"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * One channel of an {@link ExrImage}.
3
+ *
4
+ * The array's class is the channel's pixel type: `Float16Array` is HALF, `Float32Array` is FLOAT and
5
+ * `Uint32Array` is UINT, the three types OpenEXR has. It holds one sample per pixel, row by row, top row
6
+ * first.
7
+ *
8
+ * @typedef {object} ExrChannel
9
+ * @property {string} name
10
+ * @property {Float16Array|Float32Array|Uint32Array} data `width * height` samples
11
+ */
12
+
13
+ /**
14
+ * The pixels of a scanline OpenEXR image, one plane per channel — what {@link exr_read} returns and
15
+ * {@link exr_write} takes.
16
+ *
17
+ * `width` and `height` are those of the file's data window. Where that window sits, and the display window
18
+ * around it, are not part of the record: {@link exr_read} drops them and {@link exr_write} puts both windows
19
+ * at the origin, exactly covering the pixels.
20
+ *
21
+ * {@link exr_read} returns channels in the order OpenEXR keeps them, sorted by the bytes of their names
22
+ * (see {@link exr_compare_names}), which is the order a file's pixel data holds them in whatever order its
23
+ * channel list names them. {@link exr_write} takes them in any order.
24
+ *
25
+ * @typedef {object} ExrImage
26
+ * @property {number} width
27
+ * @property {number} height
28
+ * @property {ExrChannel[]} channels
29
+ *
30
+ * @author Alex Goldring
31
+ * @copyright Company Named Limited (c) 2026
32
+ */
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The type of a channel's samples, by the value an OpenEXR channel list stores.
3
+ *
4
+ * In an {@link ExrImage } the type is the class of the channel's array: `Uint32Array`, `Float16Array` or
5
+ * `Float32Array`.
6
+ */
7
+ export type ExrPixelType = number;
8
+ export namespace ExrPixelType {
9
+ let UINT: number;
10
+ let HALF: number;
11
+ let FLOAT: number;
12
+ }
13
+ //# sourceMappingURL=ExrPixelType.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExrPixelType.d.ts","sourceRoot":"","sources":["../../../../../src/format/image/exr/ExrPixelType.js"],"names":[],"mappings":";;;;;;2BAQU,MAAM"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The type of a channel's samples, by the value an OpenEXR channel list stores.
3
+ *
4
+ * In an {@link ExrImage} the type is the class of the channel's array: `Uint32Array`, `Float16Array` or
5
+ * `Float32Array`.
6
+ *
7
+ * @see https://openexr.com/en/latest/OpenEXRFileLayout.html#channel-list
8
+ * @readonly
9
+ * @enum {number}
10
+ */
11
+ export const ExrPixelType = {
12
+ /** 32-bit unsigned integer */
13
+ UINT: 0,
14
+ /** IEEE 754 binary16 */
15
+ HALF: 1,
16
+ /** IEEE 754 binary32 */
17
+ FLOAT: 2,
18
+ };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Order two names the way OpenEXR orders channels: byte by byte, as `strcmp` compares them.
3
+ *
4
+ * A file's pixel data holds its channels in this order whatever order its channel list is in, so this is
5
+ * the order {@link exr_read} lays samples out in and {@link exr_write} writes them in. On UTF-8 bytes it is
6
+ * code point order, which JavaScript's own string comparison is not past U+FFFF.
7
+ *
8
+ * @param {Uint8Array} a a name's bytes, without its terminator
9
+ * @param {Uint8Array} b
10
+ * @returns {number} negative when `a` comes first, positive when `b` does, 0 for the same name
11
+ *
12
+ * @author Alex Goldring
13
+ * @copyright Company Named Limited (c) 2026
14
+ */
15
+ export function exr_compare_names(a: Uint8Array, b: Uint8Array): number;
16
+ //# sourceMappingURL=exr_compare_names.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exr_compare_names.d.ts","sourceRoot":"","sources":["../../../../../src/format/image/exr/exr_compare_names.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,qCAPW,UAAU,KACV,UAAU,GACR,MAAM,CAelB"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Order two names the way OpenEXR orders channels: byte by byte, as `strcmp` compares them.
3
+ *
4
+ * A file's pixel data holds its channels in this order whatever order its channel list is in, so this is
5
+ * the order {@link exr_read} lays samples out in and {@link exr_write} writes them in. On UTF-8 bytes it is
6
+ * code point order, which JavaScript's own string comparison is not past U+FFFF.
7
+ *
8
+ * @param {Uint8Array} a a name's bytes, without its terminator
9
+ * @param {Uint8Array} b
10
+ * @returns {number} negative when `a` comes first, positive when `b` does, 0 for the same name
11
+ *
12
+ * @author Alex Goldring
13
+ * @copyright Company Named Limited (c) 2026
14
+ */
15
+ export function exr_compare_names(a, b) {
16
+ const length = Math.min(a.length, b.length);
17
+
18
+ for (let i = 0; i < length; i++) {
19
+ if (a[i] !== b[i]) {
20
+ return a[i] - b[i];
21
+ }
22
+ }
23
+
24
+ return a.length - b.length;
25
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Numbers fixed by the OpenEXR file layout that both {@link exr_read} and {@link exr_write} need.
3
+ *
4
+ * @see https://openexr.com/en/latest/OpenEXRFileLayout.html
5
+ * @author Alex Goldring
6
+ * @copyright Company Named Limited (c) 2026
7
+ */
8
+ /**
9
+ * The first four bytes of every OpenEXR file, read as a little-endian integer.
10
+ * @type {number}
11
+ */
12
+ export const EXR_MAGIC: number;
13
+ /**
14
+ * The file format version, which is the low byte of the version field.
15
+ * @type {number}
16
+ */
17
+ export const EXR_VERSION: number;
18
+ /**
19
+ * Version field flag: the file holds a single tiled part.
20
+ * @type {number}
21
+ */
22
+ export const EXR_FLAG_TILED: number;
23
+ /**
24
+ * Version field flag: attribute names, attribute type names and channel names may be up to
25
+ * {@link EXR_LONG_NAME_BYTES} long rather than {@link EXR_SHORT_NAME_BYTES}.
26
+ * @type {number}
27
+ */
28
+ export const EXR_FLAG_LONG_NAMES: number;
29
+ /**
30
+ * Version field flag: the file holds deep data.
31
+ * @type {number}
32
+ */
33
+ export const EXR_FLAG_NON_IMAGE: number;
34
+ /**
35
+ * Version field flag: the file holds more than one part.
36
+ * @type {number}
37
+ */
38
+ export const EXR_FLAG_MULTI_PART: number;
39
+ /**
40
+ * Longest name, in bytes and without its terminator, a file without {@link EXR_FLAG_LONG_NAMES} may carry.
41
+ * @type {number}
42
+ */
43
+ export const EXR_SHORT_NAME_BYTES: number;
44
+ /**
45
+ * Longest name, in bytes and without its terminator, any file may carry.
46
+ * @type {number}
47
+ */
48
+ export const EXR_LONG_NAME_BYTES: number;
49
+ //# sourceMappingURL=exr_constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exr_constants.d.ts","sourceRoot":"","sources":["../../../../../src/format/image/exr/exr_constants.js"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;GAGG;AACH,wBAFU,MAAM,CAEkB;AAElC;;;GAGG;AACH,0BAFU,MAAM,CAEa;AAE7B;;;GAGG;AACH,6BAFU,MAAM,CAEoB;AAEpC;;;;GAIG;AACH,kCAFU,MAAM,CAEyB;AAEzC;;;GAGG;AACH,iCAFU,MAAM,CAEwB;AAExC;;;GAGG;AACH,kCAFU,MAAM,CAE0B;AAE1C;;;GAGG;AACH,mCAFU,MAAM,CAEuB;AAEvC;;;GAGG;AACH,kCAFU,MAAM,CAEuB"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Numbers fixed by the OpenEXR file layout that both {@link exr_read} and {@link exr_write} need.
3
+ *
4
+ * @see https://openexr.com/en/latest/OpenEXRFileLayout.html
5
+ * @author Alex Goldring
6
+ * @copyright Company Named Limited (c) 2026
7
+ */
8
+
9
+ /**
10
+ * The first four bytes of every OpenEXR file, read as a little-endian integer.
11
+ * @type {number}
12
+ */
13
+ export const EXR_MAGIC = 20000630;
14
+
15
+ /**
16
+ * The file format version, which is the low byte of the version field.
17
+ * @type {number}
18
+ */
19
+ export const EXR_VERSION = 2;
20
+
21
+ /**
22
+ * Version field flag: the file holds a single tiled part.
23
+ * @type {number}
24
+ */
25
+ export const EXR_FLAG_TILED = 0x200;
26
+
27
+ /**
28
+ * Version field flag: attribute names, attribute type names and channel names may be up to
29
+ * {@link EXR_LONG_NAME_BYTES} long rather than {@link EXR_SHORT_NAME_BYTES}.
30
+ * @type {number}
31
+ */
32
+ export const EXR_FLAG_LONG_NAMES = 0x400;
33
+
34
+ /**
35
+ * Version field flag: the file holds deep data.
36
+ * @type {number}
37
+ */
38
+ export const EXR_FLAG_NON_IMAGE = 0x800;
39
+
40
+ /**
41
+ * Version field flag: the file holds more than one part.
42
+ * @type {number}
43
+ */
44
+ export const EXR_FLAG_MULTI_PART = 0x1000;
45
+
46
+ /**
47
+ * Longest name, in bytes and without its terminator, a file without {@link EXR_FLAG_LONG_NAMES} may carry.
48
+ * @type {number}
49
+ */
50
+ export const EXR_SHORT_NAME_BYTES = 31;
51
+
52
+ /**
53
+ * Longest name, in bytes and without its terminator, any file may carry.
54
+ * @type {number}
55
+ */
56
+ export const EXR_LONG_NAME_BYTES = 255;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Read a scanline OpenEXR file.
3
+ *
4
+ * **What it reads**: a single-part scanline image with full-resolution channels, compressed with
5
+ * {@link ExrCompression.None}, {@link ExrCompression.ZIPS} or {@link ExrCompression.ZIP}, in any of
6
+ * OpenEXR's three pixel types, mixed freely between channels. Samples come back as they are stored — a
7
+ * HALF channel is a `Float16Array` holding the file's exact bits — so reading converts nothing. Chunks are
8
+ * found through the offset table, so the file's line order does not matter.
9
+ *
10
+ * Of the header, only what decoding depends on is read: the channel list, the compression method and the
11
+ * data window. OpenEXR requires five more attributes — display window, line order, pixel aspect ratio,
12
+ * screen window centre and width — and its own reader fills in a default for any a file leaves out;
13
+ * nothing here would use them, so they are skipped like every other attribute.
14
+ *
15
+ * **What it refuses**, by name: tiled, multi-part and deep files; every other compression method;
16
+ * subsampled channels; a header without the channel list, compression or data window, or with one of
17
+ * them of the wrong type; and a file whose chunks do not add up — an offset outside the file, a chunk
18
+ * holding other scanlines than its place in the table says, a chunk whose stored or inflated size
19
+ * disagrees with the scanlines it holds. Every chunk is checked before anything is allocated for the
20
+ * pixels — against its place, its scanline, and what deflate could inflate its stored bytes to — so a file
21
+ * cannot claim more pixel data than its own chunks could hold.
22
+ *
23
+ * @param {ArrayBuffer} bytes the whole file; keep unchanged until the promise settles
24
+ * @returns {Promise<ExrImage>}
25
+ * @throws {Error} naming what is unsupported or malformed
26
+ *
27
+ * @see https://openexr.com/en/latest/OpenEXRFileLayout.html
28
+ * @author Alex Goldring
29
+ * @copyright Company Named Limited (c) 2026
30
+ */
31
+ export function exr_read(bytes: ArrayBuffer): Promise<ExrImage>;
32
+ //# sourceMappingURL=exr_read.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exr_read.d.ts","sourceRoot":"","sources":["../../../../../src/format/image/exr/exr_read.js"],"names":[],"mappings":"AAoBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,gCARW,WAAW,GACT,QAAQ,QAAQ,CAAC,CAqL7B"}