@woosh/meep-engine 3.18.0 → 3.19.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.
Files changed (120) hide show
  1. package/build/bundle-worker-image-decoder.js +1 -1
  2. package/editor/view/particles/effect/ParticleCurveEditorView.d.ts.map +1 -1
  3. package/editor/view/particles/effect/ParticleCurveEditorView.js +303 -120
  4. package/editor/view/particles/effect/ParticleGradientEditorView.d.ts.map +1 -1
  5. package/editor/view/particles/effect/ParticleGradientEditorView.js +108 -63
  6. package/editor/view/particles/effect/ParticleGraphEditorView.js +1 -1
  7. package/editor/view/particles/effect/ParticleNodeParametersView.d.ts.map +1 -1
  8. package/editor/view/particles/effect/ParticleNodeParametersView.js +3 -1
  9. package/editor/view/particles/effect/particle-editor.css +60 -30
  10. package/package.json +1 -2
  11. package/samples/engine/README.md +1 -1
  12. package/src/core/binary/compression/decompress_bytes.d.ts +13 -0
  13. package/src/core/binary/compression/decompress_bytes.d.ts.map +1 -0
  14. package/src/core/binary/compression/decompress_bytes.js +28 -0
  15. package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.js +67 -22
  16. package/src/engine/asset/loaders/image/ImageDecoderWorker.js +12 -27
  17. package/src/engine/asset/loaders/image/prototypePNG.js +8 -7
  18. package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
  19. package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +4 -0
  20. package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts +266 -0
  21. package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts.map +1 -0
  22. package/src/engine/graphics/ecs/particles/ParticleEffect.js +455 -0
  23. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.d.ts +58 -0
  24. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.d.ts.map +1 -0
  25. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.js +219 -0
  26. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +178 -25
  27. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -1
  28. package/src/engine/graphics3/GPUParticleEmitterSystem.js +809 -310
  29. package/src/format/image/png/PNGReader.d.ts +7 -6
  30. package/src/format/image/png/PNGReader.d.ts.map +1 -1
  31. package/src/format/image/png/PNGReader.js +13 -12
  32. package/src/format/image/png/chunk/png_chunk_decode_iTXt.d.ts +3 -2
  33. package/src/format/image/png/chunk/png_chunk_decode_iTXt.d.ts.map +1 -1
  34. package/src/format/image/png/chunk/png_chunk_decode_iTXt.js +5 -4
  35. package/src/format/image/png/chunk/png_chunk_decode_zTXt.d.ts +3 -2
  36. package/src/format/image/png/chunk/png_chunk_decode_zTXt.d.ts.map +1 -1
  37. package/src/format/image/png/chunk/png_chunk_decode_zTXt.js +5 -4
  38. package/src/format/image/png/png_inflate.d.ts +3 -3
  39. package/src/format/image/png/png_inflate.d.ts.map +1 -1
  40. package/src/format/image/png/png_inflate.js +29 -39
  41. package/src/format/texture/ktx2/ktx2_read.d.ts +4 -4
  42. package/src/format/texture/ktx2/ktx2_read.d.ts.map +1 -1
  43. package/src/format/texture/ktx2/ktx2_read.js +18 -21
  44. package/src/shade/playground/particle_ecs/README.md +203 -0
  45. package/src/shade/playground/particle_ecs/bonfire_editor.d.ts +39 -0
  46. package/src/shade/playground/particle_ecs/bonfire_editor.d.ts.map +1 -0
  47. package/src/shade/playground/particle_ecs/bonfire_editor.js +315 -0
  48. package/src/shade/playground/particle_ecs/bonfire_effects.d.ts +145 -0
  49. package/src/shade/playground/particle_ecs/bonfire_effects.d.ts.map +1 -0
  50. package/src/shade/playground/particle_ecs/bonfire_effects.js +202 -0
  51. package/src/shade/playground/particle_ecs/bonfire_sprites.d.ts +23 -0
  52. package/src/shade/playground/particle_ecs/bonfire_sprites.d.ts.map +1 -0
  53. package/src/shade/playground/particle_ecs/bonfire_sprites.js +315 -0
  54. package/src/shade/playground/particle_ecs/bonfire_world.d.ts +86 -0
  55. package/src/shade/playground/particle_ecs/bonfire_world.d.ts.map +1 -0
  56. package/src/shade/playground/particle_ecs/bonfire_world.js +303 -0
  57. package/src/shade/playground/particle_ecs/effects/embers.json +1634 -0
  58. package/src/shade/playground/particle_ecs/effects/flame.json +1882 -0
  59. package/src/shade/playground/particle_ecs/effects/smoke.json +1860 -0
  60. package/src/shade/playground/particle_ecs/effects/soot.json +1606 -0
  61. package/src/shade/playground/particle_ecs/index.html +330 -0
  62. package/src/shade/playground/particle_ecs/main.d.ts +2 -0
  63. package/src/shade/playground/particle_ecs/main.d.ts.map +1 -0
  64. package/src/shade/playground/particle_ecs/main.js +566 -0
  65. package/src/shade/playground/particle_ecs/moonlit_environment.d.ts +16 -0
  66. package/src/shade/playground/particle_ecs/moonlit_environment.d.ts.map +1 -0
  67. package/src/shade/playground/particle_ecs/moonlit_environment.js +144 -0
  68. package/src/shade/playground/particle_editor/README.md +5 -4
  69. package/src/shade/playground/profile_hotkey.d.ts +58 -0
  70. package/src/shade/playground/profile_hotkey.d.ts.map +1 -0
  71. package/src/shade/playground/profile_hotkey.js +325 -0
  72. package/src/shade/playground/ssr_variance/README.md +105 -0
  73. package/src/shade/playground/ssr_variance/capture.d.ts +16 -0
  74. package/src/shade/playground/ssr_variance/capture.d.ts.map +1 -0
  75. package/src/shade/playground/ssr_variance/capture.js +96 -0
  76. package/src/shade/playground/ssr_variance/index.html +22 -0
  77. package/src/shade/playground/ssr_variance/main.d.ts +2 -0
  78. package/src/shade/playground/ssr_variance/main.d.ts.map +1 -0
  79. package/src/shade/playground/ssr_variance/main.js +246 -0
  80. package/src/shade/playground/ssr_variance/reference.d.ts +18 -0
  81. package/src/shade/playground/ssr_variance/reference.d.ts.map +1 -0
  82. package/src/shade/playground/ssr_variance/reference.js +78 -0
  83. package/src/shade/playground/ssr_variance/scene.d.ts +11 -0
  84. package/src/shade/playground/ssr_variance/scene.d.ts.map +1 -0
  85. package/src/shade/playground/ssr_variance/scene.js +61 -0
  86. package/src/shade/playground/ssr_variance/statistics.d.ts +44 -0
  87. package/src/shade/playground/ssr_variance/statistics.d.ts.map +1 -0
  88. package/src/shade/playground/ssr_variance/statistics.js +51 -0
  89. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts.map +1 -1
  90. package/src/shade/renderer/loader/gltf/tiny-gltf.js +9 -3
  91. package/src/shade/renderer/loader/usd/usd_decode_image.d.ts +4 -4
  92. package/src/shade/renderer/loader/usd/usd_decode_image.d.ts.map +1 -1
  93. package/src/shade/renderer/loader/usd/usd_decode_image.js +4 -4
  94. package/src/shade/renderer/particles/DESIGN.md +748 -703
  95. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +11 -4
  96. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
  97. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +431 -424
  98. package/src/shade/renderer/postprocess/ssr/SSR.d.ts.map +1 -1
  99. package/src/shade/renderer/postprocess/ssr/SSR.js +2 -1
  100. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.d.ts.map +1 -1
  101. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.js +0 -6
  102. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_sample_history.d.ts.map +1 -1
  103. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_sample_history.js +19 -5
  104. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.d.ts +4 -0
  105. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.d.ts.map +1 -0
  106. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.js +133 -0
  107. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.d.ts +0 -8
  108. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.d.ts.map +1 -1
  109. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.js +16 -113
  110. package/src/shade/renderer/texture/source/texel_data_from_ktx2.d.ts +2 -2
  111. package/src/shade/renderer/texture/source/texel_data_from_ktx2.d.ts.map +1 -1
  112. package/src/shade/renderer/texture/source/texel_data_from_ktx2.js +3 -3
  113. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_warmup.d.ts +0 -20
  114. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_warmup.d.ts.map +0 -1
  115. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_world_sphere.d.ts +0 -14
  116. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_world_sphere.d.ts.map +0 -1
  117. package/src/shade/renderer/particles/shaders/shader_particle_reclaim.d.ts +0 -50
  118. package/src/shade/renderer/particles/shaders/shader_particle_reclaim.d.ts.map +0 -1
  119. package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.d.ts +0 -17
  120. package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.d.ts.map +0 -1
@@ -49,9 +49,9 @@ export class PNGReader {
49
49
  * chunk = length bytes
50
50
  * crc = 4 bytes
51
51
  *
52
- * @returns {string} chunk type
52
+ * @returns {Promise<string>} chunk type, after any compressed metadata has been decoded
53
53
  */
54
- decodeChunk(): string;
54
+ decodeChunk(): Promise<string>;
55
55
  /**
56
56
  * https://www.w3.org/TR/2003/REC-PNG-20031110/#11sRGB
57
57
  * @param {Uint8Array} chunk
@@ -107,8 +107,9 @@ export class PNGReader {
107
107
  decodeIEND(): void;
108
108
  /**
109
109
  * Uncompress IDAT chunks
110
+ * @returns {Promise<void>}
110
111
  */
111
- decodePixels(): void;
112
+ decodePixels(): Promise<void>;
112
113
  /**
113
114
  * Reconstruct a non-interlaced image.
114
115
  *
@@ -148,10 +149,10 @@ export class PNGReader {
148
149
  */
149
150
  unFilter(filter_type: number, data: Uint8Array, scanline_address: number, output: Uint8Array, bytes_per_pixel: number, output_offset: number, output_offset_previous: number, length: number): void;
150
151
  /**
151
- * Parse the PNG file
152
- * @returns {PNG}
152
+ * Parse the PNG file. Keep this reader and its input buffer unchanged until the promise settles.
153
+ * @returns {Promise<PNG>}
153
154
  */
154
- parse(): PNG;
155
+ parse(): Promise<PNG>;
155
156
  }
156
157
  import { PNG } from './PNG.js';
157
158
  import { BinaryBuffer } from "../../../core/binary/BinaryBuffer.js";
@@ -1 +1 @@
1
- {"version":3,"file":"PNGReader.d.ts","sourceRoot":"","sources":["../../../../../src/format/image/png/PNGReader.js"],"names":[],"mappings":"AAyCA;;;;GAIG;AACH,iCAHW,WAAW,QAgCrB;;IAlCD;;;;OAIG;IACH,mBAHW,WAAW,EAgCrB;IA5BG;;;OAGG;IACH,KAFU,GAAG,CAEO;IAEpB;;;OAGG;IACH,YAFU,UAAU,EAAE,CAEF;IAEpB;;;OAGG;IACH,QAFU,YAAY,CAEU;IAOhC;;;OAGG;IACH,aAFU,OAAO,CAEO;IAG5B;;;;OAIG;IACH,kBAHW,MAAM,GACL,UAAU,CAarB;IAED;;OAEG;IACH,qBAcC;IAED;;;;;;;;;OASG;IACH,eAFa,MAAM,CA4ElB;IAGD;;;OAGG;IACH,kBAFW,UAAU,QAOpB;IAED;;;OAGG;IACH,kBAFW,UAAU,QAapB;IAED;;;OAGG;IACH,kBAFW,UAAU,QASpB;IACD;;;;OAIG;IACH,kBAFW,UAAU,QAwBpB;IAED;;;;;;;;;;;OAWG;IACH,6BAWC;IAED;;;;OAIG;IACH,kBAFW,UAAU,QAIpB;IAED;;OAEG;IACH,6BAGC;IAED;;;OAGG;IACH,kBAFW,UAAU,QAIpB;IAED;;OAEG;IACH,mBACC;IAED;;OAEG;IACH,qBA0BC;IAID;;;;;;;;;OASG;IACH,oBAHW,UAAU,GACR,UAAU,CAkDtB;IAsDD;;;;;;;;;OASG;IACH,qBAHW,UAAU,GACR,UAAU,CAgHtB;IAID;;;;;;;;;;;;;;OAcG;IACH,sBAXW,MAAM,QACN,UAAU,oBACV,MAAM,UACN,UAAU,mBACV,MAAM,iBACN,MAAM,0BACN,MAAM,UACN,MAAM,QAwBhB;IAED;;;OAGG;IACH,SAFa,GAAG,CAqBf;;oBAjoBmB,UAAU;6BAXD,sCAAsC"}
1
+ {"version":3,"file":"PNGReader.d.ts","sourceRoot":"","sources":["../../../../../src/format/image/png/PNGReader.js"],"names":[],"mappings":"AAyCA;;;;GAIG;AACH,iCAHW,WAAW,QAgCrB;;IAlCD;;;;OAIG;IACH,mBAHW,WAAW,EAgCrB;IA5BG;;;OAGG;IACH,KAFU,GAAG,CAEO;IAEpB;;;OAGG;IACH,YAFU,UAAU,EAAE,CAEF;IAEpB;;;OAGG;IACH,QAFU,YAAY,CAEU;IAOhC;;;OAGG;IACH,aAFU,OAAO,CAEO;IAG5B;;;;OAIG;IACH,kBAHW,MAAM,GACL,UAAU,CAarB;IAED;;OAEG;IACH,qBAcC;IAED;;;;;;;;;OASG;IACH,eAFa,QAAQ,MAAM,CAAC,CA4E3B;IAGD;;;OAGG;IACH,kBAFW,UAAU,QAOpB;IAED;;;OAGG;IACH,kBAFW,UAAU,QAapB;IAED;;;OAGG;IACH,kBAFW,UAAU,QASpB;IACD;;;;OAIG;IACH,kBAFW,UAAU,QAwBpB;IAED;;;;;;;;;;;OAWG;IACH,6BAWC;IAED;;;;OAIG;IACH,kBAFW,UAAU,QAIpB;IAED;;OAEG;IACH,6BAGC;IAED;;;OAGG;IACH,kBAFW,UAAU,QAIpB;IAED;;OAEG;IACH,mBACC;IAED;;;OAGG;IACH,gBAFa,QAAQ,IAAI,CAAC,CA4BzB;IAID;;;;;;;;;OASG;IACH,oBAHW,UAAU,GACR,UAAU,CAkDtB;IAsDD;;;;;;;;;OASG;IACH,qBAHW,UAAU,GACR,UAAU,CAgHtB;IAID;;;;;;;;;;;;;;OAcG;IACH,sBAXW,MAAM,QACN,UAAU,oBACV,MAAM,UACN,UAAU,mBACV,MAAM,iBACN,MAAM,0BACN,MAAM,UACN,MAAM,QAwBhB;IAED;;;OAGG;IACH,SAFa,QAAQ,GAAG,CAAC,CAqBxB;;oBAloBmB,UAAU;6BAXD,sCAAsC"}
@@ -120,9 +120,9 @@ PNGReader.prototype.decodeHeader = function () {
120
120
  * chunk = length bytes
121
121
  * crc = 4 bytes
122
122
  *
123
- * @returns {string} chunk type
123
+ * @returns {Promise<string>} chunk type, after any compressed metadata has been decoded
124
124
  */
125
- PNGReader.prototype.decodeChunk = function () {
125
+ PNGReader.prototype.decodeChunk = async function () {
126
126
 
127
127
  const buffer = this.buffer;
128
128
 
@@ -183,10 +183,10 @@ PNGReader.prototype.decodeChunk = function () {
183
183
  this.decodetIME(chunk);
184
184
  break;
185
185
  case 'zTXt':
186
- png_chunk_decode_zTXt(chunk);
186
+ await png_chunk_decode_zTXt(chunk);
187
187
  break;
188
188
  case 'iTXt':
189
- png_chunk_decode_iTXt(chunk);
189
+ await png_chunk_decode_iTXt(chunk);
190
190
  break;
191
191
  default:
192
192
  // skip unknown block
@@ -325,15 +325,16 @@ PNGReader.prototype.decodeIEND = function () {
325
325
  };
326
326
 
327
327
  /**
328
- * Uncompress IDAT chunks
328
+ * Uncompress IDAT chunks
329
+ * @returns {Promise<void>}
329
330
  */
330
- PNGReader.prototype.decodePixels = function () {
331
+ PNGReader.prototype.decodePixels = async function () {
331
332
  const png = this.png;
332
333
 
333
334
  // leniently: a corrupt adler32 trailer over a sound deflate payload is common enough in the
334
335
  // wild that Chrome and libpng both accept it, and a texture that refuses to load is worse than
335
336
  // one whose checksum nobody reads
336
- const decompressed_data = png_inflate(this.dataChunks, true);
337
+ const decompressed_data = await png_inflate(this.dataChunks, true);
337
338
 
338
339
  // https://www.w3.org/TR/png-3/#8InterlaceMethods
339
340
  if (png.getInterlaceMethod() === 0) {
@@ -631,16 +632,16 @@ PNGReader.prototype.unFilter = function (
631
632
  }
632
633
 
633
634
  /**
634
- * Parse the PNG file
635
- * @returns {PNG}
635
+ * Parse the PNG file. Keep this reader and its input buffer unchanged until the promise settles.
636
+ * @returns {Promise<PNG>}
636
637
  */
637
- PNGReader.prototype.parse = function () {
638
+ PNGReader.prototype.parse = async function () {
638
639
 
639
640
  this.decodeHeader();
640
641
 
641
642
  for (; ;) {
642
643
 
643
- const type = this.decodeChunk();
644
+ const type = await this.decodeChunk();
644
645
 
645
646
  if (type === 'IEND') {
646
647
  // reached the end
@@ -649,7 +650,7 @@ PNGReader.prototype.parse = function () {
649
650
 
650
651
  }
651
652
 
652
- this.decodePixels();
653
+ await this.decodePixels();
653
654
 
654
655
  return this.png;
655
656
 
@@ -2,11 +2,12 @@
2
2
  * International textual data
3
3
  * @see https://www.w3.org/TR/2003/REC-PNG-20031110/
4
4
  * @param {Uint8Array} chunk
5
+ * @returns {Promise<{keyword: string, language_tag: string, translated_keyword: string, text: string}>}
5
6
  */
6
- export function png_chunk_decode_iTXt(chunk: Uint8Array): {
7
+ export function png_chunk_decode_iTXt(chunk: Uint8Array): Promise<{
7
8
  keyword: string;
8
9
  language_tag: string;
9
10
  translated_keyword: string;
10
11
  text: string;
11
- };
12
+ }>;
12
13
  //# sourceMappingURL=png_chunk_decode_iTXt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"png_chunk_decode_iTXt.d.ts","sourceRoot":"","sources":["../../../../../../src/format/image/png/chunk/png_chunk_decode_iTXt.js"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,6CAFW,UAAU;;;;;EA8CpB"}
1
+ {"version":3,"file":"png_chunk_decode_iTXt.d.ts","sourceRoot":"","sources":["../../../../../../src/format/image/png/chunk/png_chunk_decode_iTXt.js"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,6CAHW,UAAU;aACU,MAAM;kBAAgB,MAAM;wBAAsB,MAAM;UAAQ,MAAM;GA8CpG"}
@@ -4,9 +4,10 @@ import { png_inflate } from "../png_inflate.js";
4
4
  /**
5
5
  * International textual data
6
6
  * @see https://www.w3.org/TR/2003/REC-PNG-20031110/
7
- * @param {Uint8Array} chunk
7
+ * @param {Uint8Array} chunk
8
+ * @returns {Promise<{keyword: string, language_tag: string, translated_keyword: string, text: string}>}
8
9
  */
9
- export function png_chunk_decode_iTXt(chunk) {
10
+ export async function png_chunk_decode_iTXt(chunk) {
10
11
  const chunk_size = chunk.byteLength;
11
12
  const chunk_buffer = chunk.buffer;
12
13
  const chunk_byte_offset = chunk.byteOffset;
@@ -35,7 +36,7 @@ export function png_chunk_decode_iTXt(chunk) {
35
36
  throw new Error('only compression_method 0 is supported');
36
37
  }
37
38
 
38
- const decoded = png_inflate([new Uint8Array(buffer.data, buffer.position, remaining_bytes)]);
39
+ const decoded = await png_inflate([new Uint8Array(buffer.data, buffer.position, remaining_bytes)]);
39
40
 
40
41
  buffer.fromArrayBuffer(decoded.buffer);
41
42
 
@@ -50,4 +51,4 @@ export function png_chunk_decode_iTXt(chunk) {
50
51
  translated_keyword,
51
52
  text
52
53
  }
53
- }
54
+ }
@@ -2,9 +2,10 @@
2
2
  * Compressed textual data
3
3
  * @see https://www.w3.org/TR/2003/REC-PNG-20031110/#11zTXt
4
4
  * @param {Uint8Array} chunk
5
+ * @returns {Promise<{keyword: string, text: string}>}
5
6
  */
6
- export function png_chunk_decode_zTXt(chunk: Uint8Array): {
7
+ export function png_chunk_decode_zTXt(chunk: Uint8Array): Promise<{
7
8
  keyword: string;
8
9
  text: string;
9
- };
10
+ }>;
10
11
  //# sourceMappingURL=png_chunk_decode_zTXt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"png_chunk_decode_zTXt.d.ts","sourceRoot":"","sources":["../../../../../../src/format/image/png/chunk/png_chunk_decode_zTXt.js"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,6CAFW,UAAU;;;EAmCpB"}
1
+ {"version":3,"file":"png_chunk_decode_zTXt.d.ts","sourceRoot":"","sources":["../../../../../../src/format/image/png/chunk/png_chunk_decode_zTXt.js"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,6CAHW,UAAU;aACU,MAAM;UAAQ,MAAM;GAmClD"}
@@ -4,9 +4,10 @@ import { png_inflate } from "../png_inflate.js";
4
4
  /**
5
5
  * Compressed textual data
6
6
  * @see https://www.w3.org/TR/2003/REC-PNG-20031110/#11zTXt
7
- * @param {Uint8Array} chunk
7
+ * @param {Uint8Array} chunk
8
+ * @returns {Promise<{keyword: string, text: string}>}
8
9
  */
9
- export function png_chunk_decode_zTXt(chunk) {
10
+ export async function png_chunk_decode_zTXt(chunk) {
10
11
  const chunk_size = chunk.byteLength;
11
12
  const chunk_buffer = chunk.buffer;
12
13
  const chunk_byte_offset = chunk.byteOffset;
@@ -26,7 +27,7 @@ export function png_chunk_decode_zTXt(chunk) {
26
27
  const local_offset = buffer.position - chunk_byte_offset;
27
28
  const encoded_chunk = new Uint8Array(chunk_buffer, buffer.position, chunk_size - local_offset);
28
29
 
29
- const decompressed_data = png_inflate([encoded_chunk]);
30
+ const decompressed_data = await png_inflate([encoded_chunk]);
30
31
 
31
32
  buffer.fromArrayBuffer(decompressed_data.buffer);
32
33
 
@@ -39,4 +40,4 @@ export function png_chunk_decode_zTXt(chunk) {
39
40
  keyword: keyword,
40
41
  text: value
41
42
  }
42
- }
43
+ }
@@ -9,12 +9,12 @@
9
9
  * than to an error. That trade is deliberate for image data — see the caller — and wrong for
10
10
  * anything where a silently wrong answer is worse than none.
11
11
  *
12
- * @param {Uint8Array[]} chunks pieces of one zlib stream, in order
12
+ * @param {Uint8Array[]} chunks pieces of one zlib stream, in order; keep unchanged until completion
13
13
  * @param {boolean} [lenient] accept a stream whose adler32 trailer does not check out
14
- * @returns {Uint8Array}
14
+ * @returns {Promise<Uint8Array>}
15
15
  * @throws {Error} if the deflate payload itself cannot be read
16
16
  *
17
17
  * @copyright Company Named Limited (c) 2026
18
18
  */
19
- export function png_inflate(chunks: Uint8Array[], lenient?: boolean): Uint8Array;
19
+ export function png_inflate(chunks: Uint8Array[], lenient?: boolean): Promise<Uint8Array>;
20
20
  //# sourceMappingURL=png_inflate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"png_inflate.d.ts","sourceRoot":"","sources":["../../../../../src/format/image/png/png_inflate.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;GAiBG;AACH,oCAPW,UAAU,EAAE,YACZ,OAAO,GACL,UAAU,CAwCtB"}
1
+ {"version":3,"file":"png_inflate.d.ts","sourceRoot":"","sources":["../../../../../src/format/image/png/png_inflate.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;GAiBG;AACH,oCAPW,UAAU,EAAE,YACZ,OAAO,GACL,QAAQ,UAAU,CAAC,CA8B/B"}
@@ -1,4 +1,4 @@
1
- import zlib from "pako";
1
+ import { decompress_bytes } from "../../../core/binary/compression/decompress_bytes.js";
2
2
 
3
3
  /**
4
4
  * Inflate a zlib-framed stream that arrived as one or more chunks.
@@ -11,49 +11,39 @@ import zlib from "pako";
11
11
  * than to an error. That trade is deliberate for image data — see the caller — and wrong for
12
12
  * anything where a silently wrong answer is worse than none.
13
13
  *
14
- * @param {Uint8Array[]} chunks pieces of one zlib stream, in order
14
+ * @param {Uint8Array[]} chunks pieces of one zlib stream, in order; keep unchanged until completion
15
15
  * @param {boolean} [lenient] accept a stream whose adler32 trailer does not check out
16
- * @returns {Uint8Array}
16
+ * @returns {Promise<Uint8Array>}
17
17
  * @throws {Error} if the deflate payload itself cannot be read
18
18
  *
19
19
  * @copyright Company Named Limited (c) 2026
20
20
  */
21
- export function png_inflate(chunks, lenient = false) {
22
- const chunk_count = chunks.length;
23
-
24
- // the framed form first: it verifies the adler32 trailer, which is the right behaviour for a
25
- // spec-compliant stream
26
- const inflator = new zlib.Inflate();
27
-
28
- for (let i = 0; i < chunk_count; i++) {
29
- inflator.push(chunks[i]);
30
- }
31
-
32
- if (inflator.err === 0) {
33
- if (inflator.result === undefined) {
34
- // pako reports no error but never saw the end of the stream, which means the chunks
35
- // ran out mid-payload
36
- throw new Error("truncated zlib stream: no end marker in the chunks supplied");
37
- }
38
-
39
- return inflator.result;
40
- }
41
-
42
- if (!lenient) {
43
- throw new Error(`failed to inflate zlib stream: ${inflator.msg || inflator.err}`);
44
- }
45
-
46
- // Some real-world encoders emit streams with a corrupt adler32 trailer while the deflate
47
- // payload itself is fine. Chrome and libpng accept those, so mirror that leniency: strip the
48
- // two byte zlib header and inflate as raw deflate, which does not check the trailer.
49
- try {
50
- return zlib.inflateRaw(concatenate(chunks).subarray(2));
51
- } catch (raw_error) {
52
- // the deflate payload is broken too; report pako's original diagnosis rather than the
53
- // fallback's, which only says that raw inflate of a non-raw stream failed
54
- throw new Error(`failed to inflate zlib stream: ${inflator.msg || inflator.err}`);
55
- }
56
- }
21
+ export async function png_inflate(chunks, lenient = false) {
22
+ try {
23
+ return await decompress_bytes(chunks);
24
+ } catch (error) {
25
+ if (lenient) {
26
+ const bytes = concatenate(chunks);
27
+
28
+ // Only abandon the checksum of a zlib-framed stream. PNG forbids a preset dictionary.
29
+ // Native raw deflate rejects trailing bytes, so remove the four-byte Adler32 as well
30
+ // as the two-byte header. A missing trailer or broken payload must still reject.
31
+ const cmf = bytes[0];
32
+ const flg = bytes[1];
33
+
34
+ if (bytes.length >= 6 && (cmf & 0x0f) === 8 && (cmf >>> 4) <= 7
35
+ && ((cmf << 8) | flg) % 31 === 0 && (flg & 0x20) === 0) {
36
+ try {
37
+ return await decompress_bytes([bytes.subarray(2, bytes.length - 4)], "deflate-raw");
38
+ } catch {
39
+ // Keep the framed stream's diagnosis if the raw payload also failed.
40
+ }
41
+ }
42
+ }
43
+
44
+ throw new Error(`failed to inflate zlib stream: ${error?.message || "invalid or truncated data"}`);
45
+ }
46
+ }
57
47
 
58
48
  /**
59
49
  * @param {Uint8Array[]} chunks
@@ -25,7 +25,7 @@
25
25
  * what to do with them to the caller: the engine's adapter refuses what its texture type cannot yet
26
26
  * hold, and a reader that refused for it would be refusing well-formed files on another tier's behalf.
27
27
  *
28
- * Any of them may be wrapped: {@link SupercompressionScheme.ZLIB} is undone by `pako` and
28
+ * Any of them may be wrapped: {@link SupercompressionScheme.ZLIB} is undone by `DecompressionStream` and
29
29
  * {@link SupercompressionScheme.Zstandard} by {@link zstd_decompress}. Wrapping is a property of the
30
30
  * file rather than of the payload, so it is undone before anything looks at what is inside.
31
31
  *
@@ -69,7 +69,7 @@
69
69
  * is the overwhelming majority of a texture file, and copying it to hand it to `writeTexture` would
70
70
  * double the peak memory of every texture load for nothing.
71
71
  *
72
- * @param {ArrayBuffer|Uint8Array} bytes the whole file
72
+ * @param {ArrayBuffer|Uint8Array} bytes the whole file; keep unchanged until the promise settles
73
73
  * @param {TextureFormat|TextureFormat[]} [transcode_target] what a Basis payload should be
74
74
  * transcoded into. Required for such a file and ignored for every other; see above for why it is not
75
75
  * defaulted.
@@ -79,7 +79,7 @@
79
79
  * a caller that names a single three-channel format for a payload that turns out to have alpha gets a
80
80
  * refusal where it could have got its second choice. Given the list, this passes over the targets that
81
81
  * cannot hold what the file contains and takes the first that can
82
- * @returns {TexelPayload}
82
+ * @returns {Promise<TexelPayload>}
83
83
  * @throws {Error} naming the feature, for a file this reader does not read; naming the field, for a
84
84
  * file that is truncated or self-inconsistent
85
85
  *
@@ -87,7 +87,7 @@
87
87
  * @author Alex Goldring
88
88
  * @copyright Company Named Limited (c) 2026
89
89
  */
90
- export function ktx2_read(bytes: ArrayBuffer | Uint8Array, transcode_target?: TextureFormat | TextureFormat[]): TexelPayload;
90
+ export function ktx2_read(bytes: ArrayBuffer | Uint8Array, transcode_target?: TextureFormat | TextureFormat[]): Promise<TexelPayload>;
91
91
  export type Ktx2LevelIndexEntry = {
92
92
  /**
93
93
  * where this level's bytes are, from the start of the file
@@ -1 +1 @@
1
- {"version":3,"file":"ktx2_read.d.ts","sourceRoot":"","sources":["../../../../../src/format/texture/ktx2/ktx2_read.js"],"names":[],"mappings":"AAwEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwFG;AACH,iCAlBW,WAAW,GAAC,UAAU,qBACtB,gBAAc,eAAe,GAS3B,YAAY,CAgLxB;;;;;iBAgda,MAAM;;;;iBACN,MAAM;;;;8BACN,MAAM"}
1
+ {"version":3,"file":"ktx2_read.d.ts","sourceRoot":"","sources":["../../../../../src/format/texture/ktx2/ktx2_read.js"],"names":[],"mappings":"AAwEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwFG;AACH,iCAlBW,WAAW,GAAC,UAAU,qBACtB,gBAAc,eAAe,GAS3B,QAAQ,YAAY,CAAC,CAoLjC;;;;;iBAgda,MAAM;;;;iBACN,MAAM;;;;8BACN,MAAM"}
@@ -1,4 +1,4 @@
1
- import pako from "pako";
1
+ import { decompress_bytes } from "../../../core/binary/compression/decompress_bytes.js";
2
2
  import { assert } from "../../../core/assert.js";
3
3
  import { ByteCursor } from "../../../core/binary/ByteCursor.js";
4
4
  import { align_4 } from "../../../core/binary/align_4.js";
@@ -97,7 +97,7 @@ const SUPPORTED_ORIENTATION = "rdi";
97
97
  * what to do with them to the caller: the engine's adapter refuses what its texture type cannot yet
98
98
  * hold, and a reader that refused for it would be refusing well-formed files on another tier's behalf.
99
99
  *
100
- * Any of them may be wrapped: {@link SupercompressionScheme.ZLIB} is undone by `pako` and
100
+ * Any of them may be wrapped: {@link SupercompressionScheme.ZLIB} is undone by `DecompressionStream` and
101
101
  * {@link SupercompressionScheme.Zstandard} by {@link zstd_decompress}. Wrapping is a property of the
102
102
  * file rather than of the payload, so it is undone before anything looks at what is inside.
103
103
  *
@@ -141,7 +141,7 @@ const SUPPORTED_ORIENTATION = "rdi";
141
141
  * is the overwhelming majority of a texture file, and copying it to hand it to `writeTexture` would
142
142
  * double the peak memory of every texture load for nothing.
143
143
  *
144
- * @param {ArrayBuffer|Uint8Array} bytes the whole file
144
+ * @param {ArrayBuffer|Uint8Array} bytes the whole file; keep unchanged until the promise settles
145
145
  * @param {TextureFormat|TextureFormat[]} [transcode_target] what a Basis payload should be
146
146
  * transcoded into. Required for such a file and ignored for every other; see above for why it is not
147
147
  * defaulted.
@@ -151,7 +151,7 @@ const SUPPORTED_ORIENTATION = "rdi";
151
151
  * a caller that names a single three-channel format for a payload that turns out to have alpha gets a
152
152
  * refusal where it could have got its second choice. Given the list, this passes over the targets that
153
153
  * cannot hold what the file contains and takes the first that can
154
- * @returns {TexelPayload}
154
+ * @returns {Promise<TexelPayload>}
155
155
  * @throws {Error} naming the feature, for a file this reader does not read; naming the field, for a
156
156
  * file that is truncated or self-inconsistent
157
157
  *
@@ -159,7 +159,7 @@ const SUPPORTED_ORIENTATION = "rdi";
159
159
  * @author Alex Goldring
160
160
  * @copyright Company Named Limited (c) 2026
161
161
  */
162
- export function ktx2_read(bytes, transcode_target = undefined) {
162
+ export async function ktx2_read(bytes, transcode_target = undefined) {
163
163
  assert.defined(bytes, 'bytes');
164
164
  assert.notNull(bytes, 'bytes');
165
165
 
@@ -266,9 +266,13 @@ export function ktx2_read(bytes, transcode_target = undefined) {
266
266
 
267
267
  const level_index = read_level_index(cursor, Math.max(level_count, 1));
268
268
 
269
- const levels = level_index.map(
270
- (entry, level) => read_level(cursor, entry, level, supercompression_scheme)
271
- );
269
+ const levels = [];
270
+
271
+ // Keep cursor access and decompression sequential, preserving level order and avoiding
272
+ // simultaneous inflation of every mip. Unwrapped levels still refer directly to the input.
273
+ for (let level = 0; level < level_index.length; level++) {
274
+ levels.push(await read_level(cursor, level_index[level], level, supercompression_scheme));
275
+ }
272
276
 
273
277
  if (uastc) {
274
278
  /*
@@ -825,11 +829,11 @@ function read_level_index(cursor, entry_count) {
825
829
  * @param {Ktx2LevelIndexEntry} entry
826
830
  * @param {number} level `0` is the base
827
831
  * @param {SupercompressionScheme|number} scheme already known to be one of the two supported ones
828
- * @returns {Uint8Array} a view onto the file where the scheme is `None`, its own memory otherwise
832
+ * @returns {Promise<Uint8Array>} a view onto the file where the scheme is `None`, its own memory otherwise
829
833
  * @throws {Error} naming the level, for one that runs past the end of the file or inflates to the
830
834
  * wrong size
831
835
  */
832
- function read_level(cursor, entry, level, scheme) {
836
+ async function read_level(cursor, entry, level, scheme) {
833
837
  const { byte_offset, byte_length, uncompressed_byte_length } = entry;
834
838
 
835
839
  /*
@@ -863,15 +867,8 @@ function read_level(cursor, entry, level, scheme) {
863
867
  }
864
868
 
865
869
  /*
866
- `pako.inflate` rather than `png_inflate`: what that function adds over this call is PNG's two
867
- peculiarities — a stream split across IDAT chunks, and a fallback that abandons the adler32
868
- check because real encoders get it wrong. A KTX2 level is one stream, and a texture payload
869
- whose checksum fails should fail rather than decode to blocks nobody verified.
870
-
871
- What it also adds, and what this has to do for itself: **pako throws a bare string.** Not an
872
- Error — `"incorrect header check"`, with no stack, no `.message`, and nothing saying which file
873
- or which level it came from. Letting that escape would make the one path this reader adds beyond
874
- the plan the one path that does not refuse by name.
870
+ KTX2 requires a strict zlib stream: PNG's lenient checksum fallback does not apply here.
871
+ Await decompression inside the try/catch so native stream failures retain the level context.
875
872
  */
876
873
  let inflated;
877
874
 
@@ -891,10 +888,10 @@ function read_level(cursor, entry, level, scheme) {
891
888
  }
892
889
  } else {
893
890
  try {
894
- inflated = pako.inflate(stored);
891
+ inflated = await decompress_bytes([stored]);
895
892
  } catch (error) {
896
893
  throw new Error(
897
- `KTX2: level ${level} is not a readable zlib stream: ${error?.message ?? error}`
894
+ `KTX2: level ${level} is not a readable zlib stream: ${error?.message || "invalid or truncated data"}`
898
895
  );
899
896
  }
900
897
  }