@woosh/meep-engine 3.29.0 → 3.30.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 (226) hide show
  1. package/build/bundle-worker-image-decoder.js +1 -1
  2. package/build/bundle-worker-terrain.js +1 -1
  3. package/package.json +1 -1
  4. package/src/core/binary/BinaryBuffer.d.ts.map +1 -1
  5. package/src/core/binary/BinaryBuffer.js +14 -2
  6. package/src/core/bvh2/bvh3/BVH.d.ts.map +1 -1
  7. package/src/core/bvh2/bvh3/BVH.js +14 -1
  8. package/src/core/cache/FrequencySketch.d.ts +3 -1
  9. package/src/core/cache/FrequencySketch.d.ts.map +1 -1
  10. package/src/core/cache/FrequencySketch.js +10 -4
  11. package/src/core/cache/wtinylfu/CacheWTinylfu.d.ts.map +1 -1
  12. package/src/core/cache/wtinylfu/CacheWTinylfu.js +24 -2
  13. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.d.ts +20 -0
  14. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.d.ts.map +1 -1
  15. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.js +69 -4
  16. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts +48 -18
  17. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts.map +1 -1
  18. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.js +262 -70
  19. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_fold_limit.d.ts +25 -0
  20. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_fold_limit.d.ts.map +1 -0
  21. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_fold_limit.js +228 -0
  22. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_would_fold.d.ts +13 -0
  23. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_would_fold.d.ts.map +1 -1
  24. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_would_fold.js +10 -128
  25. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_face_bvh.d.ts.map +1 -1
  26. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_face_bvh.js +11 -1
  27. package/src/core/graph/mn_graph_collapse_weighted_edge.js +6 -6
  28. package/src/core/math/lookup/ParameterLookupTable.d.ts.map +1 -1
  29. package/src/core/math/lookup/ParameterLookupTable.js +10 -5
  30. package/src/core/math/noise/sdnoise.d.ts.map +1 -1
  31. package/src/core/math/noise/sdnoise.js +16 -10
  32. package/src/core/model/object/ImmutableObjectPool.d.ts.map +1 -1
  33. package/src/core/model/object/ImmutableObjectPool.js +17 -7
  34. package/src/core/process/executor/ConcurrentExecutor.d.ts +1 -5
  35. package/src/core/process/executor/ConcurrentExecutor.d.ts.map +1 -1
  36. package/src/core/process/executor/ConcurrentExecutor.js +95 -1
  37. package/src/core/process/task/task_find_dependency_cycle.d.ts +17 -0
  38. package/src/core/process/task/task_find_dependency_cycle.d.ts.map +1 -0
  39. package/src/core/process/task/task_find_dependency_cycle.js +81 -0
  40. package/src/core/wfc/WFCCellChoice.d.ts +17 -0
  41. package/src/core/wfc/WFCCellChoice.d.ts.map +1 -0
  42. package/src/core/wfc/WFCCellChoice.js +36 -0
  43. package/src/core/wfc/WFCLattice.d.ts +105 -0
  44. package/src/core/wfc/WFCLattice.d.ts.map +1 -0
  45. package/src/core/wfc/WFCLattice.js +235 -0
  46. package/src/core/wfc/WFCRuleTable.d.ts +172 -0
  47. package/src/core/wfc/WFCRuleTable.d.ts.map +1 -0
  48. package/src/core/wfc/WFCRuleTable.js +334 -0
  49. package/src/core/wfc/WFCState.d.ts +273 -0
  50. package/src/core/wfc/WFCState.d.ts.map +1 -0
  51. package/src/core/wfc/WFCState.js +552 -0
  52. package/src/core/wfc/WFCStatus.d.ts +11 -0
  53. package/src/core/wfc/WFCStatus.d.ts.map +1 -0
  54. package/src/core/wfc/WFCStatus.js +28 -0
  55. package/src/core/wfc/WFCTileWeights.d.ts +48 -0
  56. package/src/core/wfc/WFCTileWeights.d.ts.map +1 -0
  57. package/src/core/wfc/WFCTileWeights.js +86 -0
  58. package/src/core/wfc/WFC_UNRESOLVED.d.ts +12 -0
  59. package/src/core/wfc/WFC_UNRESOLVED.d.ts.map +1 -0
  60. package/src/core/wfc/WFC_UNRESOLVED.js +11 -0
  61. package/src/core/wfc/wfc_estimate_bytes.d.ts +24 -0
  62. package/src/core/wfc/wfc_estimate_bytes.d.ts.map +1 -0
  63. package/src/core/wfc/wfc_estimate_bytes.js +47 -0
  64. package/src/core/wfc/wfc_rule_table_tile_components.d.ts +27 -0
  65. package/src/core/wfc/wfc_rule_table_tile_components.d.ts.map +1 -0
  66. package/src/core/wfc/wfc_rule_table_tile_components.js +80 -0
  67. package/src/core/wfc/wfc_solve.d.ts +21 -0
  68. package/src/core/wfc/wfc_solve.d.ts.map +1 -0
  69. package/src/core/wfc/wfc_solve.js +154 -0
  70. package/src/core/wfc/wfc_state_apply_boundary.d.ts +18 -0
  71. package/src/core/wfc/wfc_state_apply_boundary.d.ts.map +1 -0
  72. package/src/core/wfc/wfc_state_apply_boundary.js +61 -0
  73. package/src/core/wfc/wfc_state_assign.d.ts +11 -0
  74. package/src/core/wfc/wfc_state_assign.d.ts.map +1 -0
  75. package/src/core/wfc/wfc_state_assign.js +36 -0
  76. package/src/core/wfc/wfc_state_ban_bits.d.ts +17 -0
  77. package/src/core/wfc/wfc_state_ban_bits.d.ts.map +1 -0
  78. package/src/core/wfc/wfc_state_ban_bits.js +81 -0
  79. package/src/core/wfc/wfc_state_collapse.d.ts +12 -0
  80. package/src/core/wfc/wfc_state_collapse.d.ts.map +1 -0
  81. package/src/core/wfc/wfc_state_collapse.js +73 -0
  82. package/src/core/wfc/wfc_state_flush_dirty.d.ts +12 -0
  83. package/src/core/wfc/wfc_state_flush_dirty.d.ts.map +1 -0
  84. package/src/core/wfc/wfc_state_flush_dirty.js +39 -0
  85. package/src/core/wfc/wfc_state_propagate.d.ts +14 -0
  86. package/src/core/wfc/wfc_state_propagate.d.ts.map +1 -0
  87. package/src/core/wfc/wfc_state_propagate.js +155 -0
  88. package/src/core/wfc/wfc_state_read.d.ts +11 -0
  89. package/src/core/wfc/wfc_state_read.d.ts.map +1 -0
  90. package/src/core/wfc/wfc_state_read.js +38 -0
  91. package/src/core/wfc/wfc_state_restrict.d.ts +18 -0
  92. package/src/core/wfc/wfc_state_restrict.d.ts.map +1 -0
  93. package/src/core/wfc/wfc_state_restrict.js +39 -0
  94. package/src/core/wfc/wfc_state_set_eligible.d.ts +24 -0
  95. package/src/core/wfc/wfc_state_set_eligible.d.ts.map +1 -0
  96. package/src/core/wfc/wfc_state_set_eligible.js +49 -0
  97. package/src/core/wfc/wfc_state_undo_to.d.ts +13 -0
  98. package/src/core/wfc/wfc_state_undo_to.d.ts.map +1 -0
  99. package/src/core/wfc/wfc_state_undo_to.js +84 -0
  100. package/src/core/wfc/wfc_words_per_cell.d.ts +11 -0
  101. package/src/core/wfc/wfc_words_per_cell.d.ts.map +1 -0
  102. package/src/core/wfc/wfc_words_per_cell.js +16 -0
  103. package/src/engine/ecs/EntityComponentDataset.d.ts +8 -0
  104. package/src/engine/ecs/EntityComponentDataset.d.ts.map +1 -1
  105. package/src/engine/ecs/EntityComponentDataset.js +37 -14
  106. package/src/engine/ecs/fow/FogOfWarRevealerSystem.d.ts +8 -1
  107. package/src/engine/ecs/fow/FogOfWarRevealerSystem.d.ts.map +1 -1
  108. package/src/engine/ecs/fow/FogOfWarRevealerSystem.js +37 -2
  109. package/src/engine/ecs/guid/UUID.d.ts.map +1 -1
  110. package/src/engine/ecs/guid/UUID.js +45 -17
  111. package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.d.ts.map +1 -1
  112. package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.js +3 -1
  113. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts.map +1 -1
  114. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +366 -360
  115. package/src/engine/graphics/texture/sampler/resize/sampler2d_scale_down_linear.d.ts.map +1 -1
  116. package/src/engine/graphics/texture/sampler/resize/sampler2d_scale_down_linear.js +24 -10
  117. package/src/engine/grid/grid2transform/GridPosition2TransformSystem.d.ts.map +1 -1
  118. package/src/engine/grid/grid2transform/GridPosition2TransformSystem.js +24 -5
  119. package/src/engine/interpolation/Interpoland.d.ts +7 -1
  120. package/src/engine/interpolation/Interpoland.d.ts.map +1 -1
  121. package/src/engine/interpolation/Interpoland.js +8 -1
  122. package/src/engine/interpolation/InterpolationSystem.d.ts.map +1 -1
  123. package/src/engine/interpolation/InterpolationSystem.js +3 -0
  124. package/src/engine/interpolation/TransformPoseSerializationAdapter.d.ts +5 -3
  125. package/src/engine/interpolation/TransformPoseSerializationAdapter.d.ts.map +1 -1
  126. package/src/engine/interpolation/TransformPoseSerializationAdapter.js +14 -3
  127. package/src/engine/interpolation/pose_interpoland.d.ts.map +1 -1
  128. package/src/engine/interpolation/pose_interpoland.js +2 -0
  129. package/src/engine/network/orchestrator/NetworkPeer.d.ts.map +1 -1
  130. package/src/engine/network/orchestrator/NetworkPeer.js +15 -10
  131. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
  132. package/src/engine/physics/cloth/ecs/ClothWorld.js +17 -0
  133. package/src/engine/physics/mls-mpm/MLS_MPM.d.ts.map +1 -1
  134. package/src/engine/physics/mls-mpm/MLS_MPM.js +14 -0
  135. package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.d.ts +2 -1
  136. package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.d.ts.map +1 -1
  137. package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.js +1 -1
  138. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.d.ts +1 -0
  139. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.d.ts.map +1 -1
  140. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts +1 -0
  141. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts.map +1 -1
  142. package/src/engine/sound/sopra/definition/clip/SampleAudioClip.d.ts +2 -1
  143. package/src/engine/sound/sopra/definition/clip/SampleAudioClip.d.ts.map +1 -1
  144. package/src/engine/sound/sopra/definition/clip/SampleAudioClip.js +12 -3
  145. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.d.ts +1 -0
  146. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.d.ts.map +1 -1
  147. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts +1 -0
  148. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts.map +1 -1
  149. package/src/engine/sound/sopra/runtime/EventInstance.d.ts.map +1 -1
  150. package/src/engine/sound/sopra/runtime/EventInstance.js +4 -1
  151. package/src/format/image/avif/av1/decode/decode_coefficients.d.ts.map +1 -1
  152. package/src/format/image/avif/av1/decode/decode_coefficients.js +248 -259
  153. package/src/format/image/avif/av1/decode/read_golomb.d.ts +21 -0
  154. package/src/format/image/avif/av1/decode/read_golomb.d.ts.map +1 -0
  155. package/src/format/image/avif/av1/decode/read_golomb.js +49 -0
  156. package/src/format/image/avif/av1/filter/loop_restoration.js +461 -451
  157. package/src/format/image/avif/av1/util/round2.d.ts +19 -2
  158. package/src/format/image/avif/av1/util/round2.d.ts.map +1 -1
  159. package/src/format/image/avif/av1/util/round2.js +51 -27
  160. package/src/format/image/avif/heif/parse_avif_file.js +24 -0
  161. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
  162. package/src/shade/renderer/buffer/table/GPUTypedTable.js +14 -0
  163. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +46 -3
  164. package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +91 -1
  165. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +0 -13
  166. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
  167. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +0 -15
  168. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.js +5 -5
  169. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts +11 -1
  170. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts.map +1 -1
  171. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.js +11 -1
  172. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts +18 -9
  173. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts.map +1 -1
  174. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.js +20 -26
  175. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts +1 -3
  176. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts.map +1 -1
  177. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.js +2 -5
  178. package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +1 -1
  179. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.d.ts.map +1 -1
  180. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.js +14 -1
  181. package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.d.ts.map +1 -1
  182. package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.js +12 -3
  183. package/src/shade/renderer/light/environment/rgbe/RGBE_ReadPixels_RLE.d.ts.map +1 -1
  184. package/src/shade/renderer/light/environment/rgbe/RGBE_ReadPixels_RLE.js +7 -1
  185. package/src/shade/renderer/lightmap/GPULightMap.d.ts.map +1 -1
  186. package/src/shade/renderer/lightmap/GPULightMap.js +349 -336
  187. package/src/shade/renderer/loader/gltf/load_gltf.d.ts.map +1 -1
  188. package/src/shade/renderer/loader/gltf/load_gltf.js +1137 -1128
  189. package/src/shade/renderer/particles/DESIGN.md +14 -5
  190. package/src/shade/renderer/particles/GPUParticleSystem.d.ts +25 -10
  191. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  192. package/src/shade/renderer/particles/GPUParticleSystem.js +182 -38
  193. package/src/shade/renderer/particles/graph/groups/simplex_reference.d.ts.map +1 -1
  194. package/src/shade/renderer/particles/graph/groups/simplex_reference.js +16 -10
  195. package/src/shade/renderer/particles/graph_particles.d.ts +4 -2
  196. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  197. package/src/shade/renderer/particles/graph_particles.js +8 -2
  198. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
  199. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +8 -2
  200. package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts.map +1 -1
  201. package/src/shade/renderer/particles/optimizer/pass_fold_constants.js +10 -4
  202. package/src/shade/renderer/particles/shaders/shader_particle_init_free_list.d.ts +31 -0
  203. package/src/shade/renderer/particles/shaders/shader_particle_init_free_list.d.ts.map +1 -0
  204. package/src/shade/renderer/particles/shaders/shader_particle_init_free_list.js +62 -0
  205. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +13 -0
  206. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
  207. package/src/shade/renderer/particles/vm/ParticleVMReference.js +95 -17
  208. package/src/shade/renderer/rasterize/bucket/rasterization_has_opaque_bucket.d.ts +21 -0
  209. package/src/shade/renderer/rasterize/bucket/rasterization_has_opaque_bucket.d.ts.map +1 -0
  210. package/src/shade/renderer/rasterize/bucket/rasterization_has_opaque_bucket.js +28 -0
  211. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.d.ts.map +1 -1
  212. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +19 -2
  213. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts.map +1 -1
  214. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +19 -2
  215. package/src/shade/renderer/shader/type/WebGPUStruct.d.ts.map +1 -1
  216. package/src/shade/renderer/shader/type/WebGPUStruct.js +12 -0
  217. package/src/shade/renderer/texture/mipmaps/WebGPUMipmapGenerator.d.ts +8 -2
  218. package/src/shade/renderer/texture/mipmaps/WebGPUMipmapGenerator.d.ts.map +1 -1
  219. package/src/shade/renderer/texture/mipmaps/WebGPUMipmapGenerator.js +41 -6
  220. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +2383 -2356
  221. package/src/view/tooltip/DomTooltipManager.d.ts +7 -0
  222. package/src/view/tooltip/DomTooltipManager.d.ts.map +1 -1
  223. package/src/view/tooltip/DomTooltipManager.js +22 -0
  224. package/src/view/tooltip/DomTooltipObserver.d.ts.map +1 -1
  225. package/src/view/tooltip/DomTooltipObserver.js +13 -3
  226. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.js +0 -45
@@ -1,259 +1,248 @@
1
- import {
2
- BR_CDF_SIZE,
3
- COEFF_BASE_RANGE,
4
- DCT_DCT,
5
- NUM_BASE_LEVELS,
6
- SIG_COEF_CONTEXTS,
7
- SIG_COEF_CONTEXTS_EOB,
8
- TX_16X64,
9
- TX_32X32,
10
- TX_64X16,
11
- TX_CLASS_2D
12
- } from "../tables/av1_symbols.js";
13
- import {
14
- ADJUSTED_TX_SIZE,
15
- TX_HEIGHT,
16
- TX_HEIGHT_LOG2,
17
- TX_SIZE_SQR,
18
- TX_SIZE_SQR_UP,
19
- TX_WIDTH,
20
- TX_WIDTH_LOG2
21
- } from "../tables/block_tables.js";
22
- import {
23
- get_all_zero_ctx,
24
- get_coeff_base_ctx,
25
- get_coeff_br_ctx,
26
- get_dc_sign_ctx
27
- } from "../entropy/coefficient_context.js";
28
- import { get_scan } from "./get_scan.js";
29
- import { compute_tx_type, get_tx_class } from "./transform_type.js";
30
- import { read_transform_type } from "./read_transform_type.js";
31
-
32
- /**
33
- * Decode the coefficients of one transform block.
34
- *
35
- * Fills `ctx.quant` with the quantised levels by raster position within the block and returns the
36
- * end-of-block position, which is zero when the block is empty. Also updates the level and DC-sign
37
- * contexts that the next block's `all_zero` and `dc_sign` decisions read.
38
- *
39
- * @param {Av1FrameContext} ctx
40
- * @param {number} plane
41
- * @param {number} start_x left edge of the transform block in plane samples
42
- * @param {number} start_y top edge of the transform block in plane samples
43
- * @param {number} tx_size
44
- * @returns {number} the end-of-block position
45
- * @see AV1 spec 5.11.39 "Coefficients syntax"
46
- *
47
- * @author Alex Goldring
48
- * @copyright Company Named Limited (c) 2026
49
- */
50
- export function decode_coefficients(ctx, plane, start_x, start_y, tx_size) {
51
- const reader = ctx.reader;
52
- const cdf = ctx.cdf;
53
-
54
- const x4 = start_x >> 2;
55
- const y4 = start_y >> 2;
56
- const w4 = TX_WIDTH[tx_size] >> 2;
57
- const h4 = TX_HEIGHT[tx_size] >> 2;
58
-
59
- const tx_size_ctx = (TX_SIZE_SQR[tx_size] + TX_SIZE_SQR_UP[tx_size] + 1) >> 1;
60
- const plane_type = plane > 0 ? 1 : 0;
61
-
62
- const seg_eob = tx_size === TX_16X64 || tx_size === TX_64X16
63
- ? 512
64
- : Math.min(1024, TX_WIDTH[tx_size] * TX_HEIGHT[tx_size]);
65
-
66
- const quant = ctx.quant;
67
-
68
- quant.fill(0, 0, seg_eob);
69
-
70
- let eob = 0;
71
- let cul_level = 0;
72
- let dc_category = 0;
73
-
74
- const all_zero_ctx = get_all_zero_ctx(ctx, plane, x4, y4, w4, h4, tx_size);
75
-
76
- const all_zero = reader.read_symbol(cdf.txb_skip, (tx_size_ctx * 13 + all_zero_ctx) * 3, 2);
77
-
78
- if (all_zero === 1) {
79
- if (plane === 0) {
80
- for (let i = 0; i < w4; i++) {
81
- for (let j = 0; j < h4; j++) {
82
- ctx.tx_types[(y4 + j) * ctx.mi_stride + x4 + i] = DCT_DCT;
83
- }
84
- }
85
- }
86
- } else {
87
- if (plane === 0) {
88
- read_transform_type(ctx, x4, y4, tx_size);
89
- }
90
-
91
- const tx_type = compute_tx_type(ctx, plane, tx_size, x4, y4);
92
-
93
- ctx.plane_tx_type = tx_type;
94
-
95
- const tx_class = get_tx_class(tx_type);
96
- const scan = get_scan(tx_size, tx_type);
97
-
98
- const eob_multisize = Math.min(TX_WIDTH_LOG2[tx_size], 5) + Math.min(TX_HEIGHT_LOG2[tx_size], 5) - 4;
99
-
100
- const eob_class_ctx = tx_class === TX_CLASS_2D ? 0 : 1;
101
-
102
- let eob_pt;
103
-
104
- if (eob_multisize === 0) {
105
- eob_pt = reader.read_symbol(cdf.eob_pt_16, ((plane_type * 2) + eob_class_ctx) * 6, 5) + 1;
106
- } else if (eob_multisize === 1) {
107
- eob_pt = reader.read_symbol(cdf.eob_pt_32, ((plane_type * 2) + eob_class_ctx) * 7, 6) + 1;
108
- } else if (eob_multisize === 2) {
109
- eob_pt = reader.read_symbol(cdf.eob_pt_64, ((plane_type * 2) + eob_class_ctx) * 8, 7) + 1;
110
- } else if (eob_multisize === 3) {
111
- eob_pt = reader.read_symbol(cdf.eob_pt_128, ((plane_type * 2) + eob_class_ctx) * 9, 8) + 1;
112
- } else if (eob_multisize === 4) {
113
- eob_pt = reader.read_symbol(cdf.eob_pt_256, ((plane_type * 2) + eob_class_ctx) * 10, 9) + 1;
114
- } else if (eob_multisize === 5) {
115
- eob_pt = reader.read_symbol(cdf.eob_pt_512, plane_type * 11, 10) + 1;
116
- } else {
117
- eob_pt = reader.read_symbol(cdf.eob_pt_1024, plane_type * 12, 11) + 1;
118
- }
119
-
120
- eob = eob_pt < 2 ? eob_pt : (1 << (eob_pt - 2)) + 1;
121
-
122
- let eob_shift = Math.max(-1, eob_pt - 3);
123
-
124
- if (eob_shift >= 0) {
125
- const extra = reader.read_symbol(
126
- cdf.eob_extra,
127
- ((tx_size_ctx * 2 + plane_type) * 9 + (eob_pt - 3)) * 3,
128
- 2
129
- );
130
-
131
- if (extra === 1) {
132
- eob += 1 << eob_shift;
133
- }
134
-
135
- for (let i = 1; i < Math.max(0, eob_pt - 2); i++) {
136
- eob_shift = Math.max(0, eob_pt - 2) - 1 - i;
137
-
138
- if (reader.read_bool() === 1) {
139
- eob += 1 << eob_shift;
140
- }
141
- }
142
- }
143
-
144
- const adjusted = ADJUSTED_TX_SIZE[tx_size];
145
- const bwl = TX_WIDTH_LOG2[adjusted];
146
- const adjusted_width = 1 << bwl;
147
- const adjusted_height = TX_HEIGHT[adjusted];
148
-
149
- const br_cdf_size_ctx = Math.min(tx_size_ctx, TX_32X32);
150
-
151
- for (let c = eob - 1; c >= 0; c--) {
152
- const pos = scan[c];
153
-
154
- let level;
155
-
156
- if (c === eob - 1) {
157
- const eob_ctx = get_coeff_base_ctx(quant, tx_class, bwl, adjusted_width, adjusted_height, pos, c, 1, tx_size)
158
- - SIG_COEF_CONTEXTS + SIG_COEF_CONTEXTS_EOB;
159
-
160
- level = reader.read_symbol(
161
- cdf.coeff_base_eob,
162
- ((tx_size_ctx * 2 + plane_type) * SIG_COEF_CONTEXTS_EOB + eob_ctx) * 4,
163
- 3
164
- ) + 1;
165
- } else {
166
- const base_ctx = get_coeff_base_ctx(quant, tx_class, bwl, adjusted_width, adjusted_height, pos, c, 0, tx_size);
167
-
168
- level = reader.read_symbol(
169
- cdf.coeff_base,
170
- ((tx_size_ctx * 2 + plane_type) * SIG_COEF_CONTEXTS + base_ctx) * 5,
171
- 4
172
- );
173
- }
174
-
175
- if (level > NUM_BASE_LEVELS) {
176
- const br_ctx = get_coeff_br_ctx(quant, tx_class, bwl, adjusted_width, adjusted_height, pos);
177
-
178
- for (let idx = 0; idx < COEFF_BASE_RANGE / (BR_CDF_SIZE - 1); idx++) {
179
- const coeff_br = reader.read_symbol(
180
- cdf.coeff_br,
181
- ((br_cdf_size_ctx * 2 + plane_type) * 21 + br_ctx) * 5,
182
- 4
183
- );
184
-
185
- level += coeff_br;
186
-
187
- if (coeff_br < BR_CDF_SIZE - 1) {
188
- break;
189
- }
190
- }
191
- }
192
-
193
- quant[pos] = level;
194
- }
195
-
196
- const dc_sign_ctx = get_dc_sign_ctx(ctx, plane, x4, y4, w4, h4);
197
-
198
- for (let c = 0; c < eob; c++) {
199
- const pos = scan[c];
200
-
201
- let sign = 0;
202
-
203
- if (quant[pos] !== 0) {
204
- if (c === 0) {
205
- sign = reader.read_symbol(cdf.dc_sign, (plane_type * 3 + dc_sign_ctx) * 3, 2);
206
- } else {
207
- sign = reader.read_bool();
208
- }
209
- }
210
-
211
- if (quant[pos] > NUM_BASE_LEVELS + COEFF_BASE_RANGE) {
212
- let length = 0;
213
-
214
- do {
215
- length++;
216
- } while (reader.read_bool() === 0);
217
-
218
- let x = 1;
219
-
220
- for (let i = length - 2; i >= 0; i--) {
221
- x = (x << 1) | reader.read_bool();
222
- }
223
-
224
- quant[pos] = x + COEFF_BASE_RANGE + NUM_BASE_LEVELS;
225
- }
226
-
227
- if (pos === 0 && quant[pos] > 0) {
228
- dc_category = sign !== 0 ? 1 : 2;
229
- }
230
-
231
- quant[pos] = quant[pos] & 0xfffff;
232
-
233
- cul_level += quant[pos];
234
-
235
- if (sign !== 0) {
236
- quant[pos] = -quant[pos];
237
- }
238
- }
239
-
240
- cul_level = Math.min(63, cul_level);
241
- }
242
-
243
- const above_level = ctx.above_level_context[plane];
244
- const above_dc = ctx.above_dc_context[plane];
245
- const left_level = ctx.left_level_context[plane];
246
- const left_dc = ctx.left_dc_context[plane];
247
-
248
- for (let i = 0; i < w4; i++) {
249
- above_level[x4 + i] = cul_level;
250
- above_dc[x4 + i] = dc_category;
251
- }
252
-
253
- for (let i = 0; i < h4; i++) {
254
- left_level[y4 + i] = cul_level;
255
- left_dc[y4 + i] = dc_category;
256
- }
257
-
258
- return eob;
259
- }
1
+ import {
2
+ BR_CDF_SIZE,
3
+ COEFF_BASE_RANGE,
4
+ DCT_DCT,
5
+ NUM_BASE_LEVELS,
6
+ SIG_COEF_CONTEXTS,
7
+ SIG_COEF_CONTEXTS_EOB,
8
+ TX_16X64,
9
+ TX_32X32,
10
+ TX_64X16,
11
+ TX_CLASS_2D
12
+ } from "../tables/av1_symbols.js";
13
+ import {
14
+ ADJUSTED_TX_SIZE,
15
+ TX_HEIGHT,
16
+ TX_HEIGHT_LOG2,
17
+ TX_SIZE_SQR,
18
+ TX_SIZE_SQR_UP,
19
+ TX_WIDTH,
20
+ TX_WIDTH_LOG2
21
+ } from "../tables/block_tables.js";
22
+ import {
23
+ get_all_zero_ctx,
24
+ get_coeff_base_ctx,
25
+ get_coeff_br_ctx,
26
+ get_dc_sign_ctx
27
+ } from "../entropy/coefficient_context.js";
28
+ import { get_scan } from "./get_scan.js";
29
+ import { compute_tx_type, get_tx_class } from "./transform_type.js";
30
+ import { read_transform_type } from "./read_transform_type.js";
31
+ import { read_golomb } from "./read_golomb.js";
32
+
33
+ /**
34
+ * Decode the coefficients of one transform block.
35
+ *
36
+ * Fills `ctx.quant` with the quantised levels by raster position within the block and returns the
37
+ * end-of-block position, which is zero when the block is empty. Also updates the level and DC-sign
38
+ * contexts that the next block's `all_zero` and `dc_sign` decisions read.
39
+ *
40
+ * @param {Av1FrameContext} ctx
41
+ * @param {number} plane
42
+ * @param {number} start_x left edge of the transform block in plane samples
43
+ * @param {number} start_y top edge of the transform block in plane samples
44
+ * @param {number} tx_size
45
+ * @returns {number} the end-of-block position
46
+ * @see AV1 spec 5.11.39 "Coefficients syntax"
47
+ *
48
+ * @author Alex Goldring
49
+ * @copyright Company Named Limited (c) 2026
50
+ */
51
+ export function decode_coefficients(ctx, plane, start_x, start_y, tx_size) {
52
+ const reader = ctx.reader;
53
+ const cdf = ctx.cdf;
54
+
55
+ const x4 = start_x >> 2;
56
+ const y4 = start_y >> 2;
57
+ const w4 = TX_WIDTH[tx_size] >> 2;
58
+ const h4 = TX_HEIGHT[tx_size] >> 2;
59
+
60
+ const tx_size_ctx = (TX_SIZE_SQR[tx_size] + TX_SIZE_SQR_UP[tx_size] + 1) >> 1;
61
+ const plane_type = plane > 0 ? 1 : 0;
62
+
63
+ const seg_eob = tx_size === TX_16X64 || tx_size === TX_64X16
64
+ ? 512
65
+ : Math.min(1024, TX_WIDTH[tx_size] * TX_HEIGHT[tx_size]);
66
+
67
+ const quant = ctx.quant;
68
+
69
+ quant.fill(0, 0, seg_eob);
70
+
71
+ let eob = 0;
72
+ let cul_level = 0;
73
+ let dc_category = 0;
74
+
75
+ const all_zero_ctx = get_all_zero_ctx(ctx, plane, x4, y4, w4, h4, tx_size);
76
+
77
+ const all_zero = reader.read_symbol(cdf.txb_skip, (tx_size_ctx * 13 + all_zero_ctx) * 3, 2);
78
+
79
+ if (all_zero === 1) {
80
+ if (plane === 0) {
81
+ for (let i = 0; i < w4; i++) {
82
+ for (let j = 0; j < h4; j++) {
83
+ ctx.tx_types[(y4 + j) * ctx.mi_stride + x4 + i] = DCT_DCT;
84
+ }
85
+ }
86
+ }
87
+ } else {
88
+ if (plane === 0) {
89
+ read_transform_type(ctx, x4, y4, tx_size);
90
+ }
91
+
92
+ const tx_type = compute_tx_type(ctx, plane, tx_size, x4, y4);
93
+
94
+ ctx.plane_tx_type = tx_type;
95
+
96
+ const tx_class = get_tx_class(tx_type);
97
+ const scan = get_scan(tx_size, tx_type);
98
+
99
+ const eob_multisize = Math.min(TX_WIDTH_LOG2[tx_size], 5) + Math.min(TX_HEIGHT_LOG2[tx_size], 5) - 4;
100
+
101
+ const eob_class_ctx = tx_class === TX_CLASS_2D ? 0 : 1;
102
+
103
+ let eob_pt;
104
+
105
+ if (eob_multisize === 0) {
106
+ eob_pt = reader.read_symbol(cdf.eob_pt_16, ((plane_type * 2) + eob_class_ctx) * 6, 5) + 1;
107
+ } else if (eob_multisize === 1) {
108
+ eob_pt = reader.read_symbol(cdf.eob_pt_32, ((plane_type * 2) + eob_class_ctx) * 7, 6) + 1;
109
+ } else if (eob_multisize === 2) {
110
+ eob_pt = reader.read_symbol(cdf.eob_pt_64, ((plane_type * 2) + eob_class_ctx) * 8, 7) + 1;
111
+ } else if (eob_multisize === 3) {
112
+ eob_pt = reader.read_symbol(cdf.eob_pt_128, ((plane_type * 2) + eob_class_ctx) * 9, 8) + 1;
113
+ } else if (eob_multisize === 4) {
114
+ eob_pt = reader.read_symbol(cdf.eob_pt_256, ((plane_type * 2) + eob_class_ctx) * 10, 9) + 1;
115
+ } else if (eob_multisize === 5) {
116
+ eob_pt = reader.read_symbol(cdf.eob_pt_512, plane_type * 11, 10) + 1;
117
+ } else {
118
+ eob_pt = reader.read_symbol(cdf.eob_pt_1024, plane_type * 12, 11) + 1;
119
+ }
120
+
121
+ eob = eob_pt < 2 ? eob_pt : (1 << (eob_pt - 2)) + 1;
122
+
123
+ let eob_shift = Math.max(-1, eob_pt - 3);
124
+
125
+ if (eob_shift >= 0) {
126
+ const extra = reader.read_symbol(
127
+ cdf.eob_extra,
128
+ ((tx_size_ctx * 2 + plane_type) * 9 + (eob_pt - 3)) * 3,
129
+ 2
130
+ );
131
+
132
+ if (extra === 1) {
133
+ eob += 1 << eob_shift;
134
+ }
135
+
136
+ for (let i = 1; i < Math.max(0, eob_pt - 2); i++) {
137
+ eob_shift = Math.max(0, eob_pt - 2) - 1 - i;
138
+
139
+ if (reader.read_bool() === 1) {
140
+ eob += 1 << eob_shift;
141
+ }
142
+ }
143
+ }
144
+
145
+ const adjusted = ADJUSTED_TX_SIZE[tx_size];
146
+ const bwl = TX_WIDTH_LOG2[adjusted];
147
+ const adjusted_width = 1 << bwl;
148
+ const adjusted_height = TX_HEIGHT[adjusted];
149
+
150
+ const br_cdf_size_ctx = Math.min(tx_size_ctx, TX_32X32);
151
+
152
+ for (let c = eob - 1; c >= 0; c--) {
153
+ const pos = scan[c];
154
+
155
+ let level;
156
+
157
+ if (c === eob - 1) {
158
+ const eob_ctx = get_coeff_base_ctx(quant, tx_class, bwl, adjusted_width, adjusted_height, pos, c, 1, tx_size)
159
+ - SIG_COEF_CONTEXTS + SIG_COEF_CONTEXTS_EOB;
160
+
161
+ level = reader.read_symbol(
162
+ cdf.coeff_base_eob,
163
+ ((tx_size_ctx * 2 + plane_type) * SIG_COEF_CONTEXTS_EOB + eob_ctx) * 4,
164
+ 3
165
+ ) + 1;
166
+ } else {
167
+ const base_ctx = get_coeff_base_ctx(quant, tx_class, bwl, adjusted_width, adjusted_height, pos, c, 0, tx_size);
168
+
169
+ level = reader.read_symbol(
170
+ cdf.coeff_base,
171
+ ((tx_size_ctx * 2 + plane_type) * SIG_COEF_CONTEXTS + base_ctx) * 5,
172
+ 4
173
+ );
174
+ }
175
+
176
+ if (level > NUM_BASE_LEVELS) {
177
+ const br_ctx = get_coeff_br_ctx(quant, tx_class, bwl, adjusted_width, adjusted_height, pos);
178
+
179
+ for (let idx = 0; idx < COEFF_BASE_RANGE / (BR_CDF_SIZE - 1); idx++) {
180
+ const coeff_br = reader.read_symbol(
181
+ cdf.coeff_br,
182
+ ((br_cdf_size_ctx * 2 + plane_type) * 21 + br_ctx) * 5,
183
+ 4
184
+ );
185
+
186
+ level += coeff_br;
187
+
188
+ if (coeff_br < BR_CDF_SIZE - 1) {
189
+ break;
190
+ }
191
+ }
192
+ }
193
+
194
+ quant[pos] = level;
195
+ }
196
+
197
+ const dc_sign_ctx = get_dc_sign_ctx(ctx, plane, x4, y4, w4, h4);
198
+
199
+ for (let c = 0; c < eob; c++) {
200
+ const pos = scan[c];
201
+
202
+ let sign = 0;
203
+
204
+ if (quant[pos] !== 0) {
205
+ if (c === 0) {
206
+ sign = reader.read_symbol(cdf.dc_sign, (plane_type * 3 + dc_sign_ctx) * 3, 2);
207
+ } else {
208
+ sign = reader.read_bool();
209
+ }
210
+ }
211
+
212
+ if (quant[pos] > NUM_BASE_LEVELS + COEFF_BASE_RANGE) {
213
+ quant[pos] = read_golomb(reader) + COEFF_BASE_RANGE + NUM_BASE_LEVELS;
214
+ }
215
+
216
+ if (pos === 0 && quant[pos] > 0) {
217
+ dc_category = sign !== 0 ? 1 : 2;
218
+ }
219
+
220
+ quant[pos] = quant[pos] & 0xfffff;
221
+
222
+ cul_level += quant[pos];
223
+
224
+ if (sign !== 0) {
225
+ quant[pos] = -quant[pos];
226
+ }
227
+ }
228
+
229
+ cul_level = Math.min(63, cul_level);
230
+ }
231
+
232
+ const above_level = ctx.above_level_context[plane];
233
+ const above_dc = ctx.above_dc_context[plane];
234
+ const left_level = ctx.left_level_context[plane];
235
+ const left_dc = ctx.left_dc_context[plane];
236
+
237
+ for (let i = 0; i < w4; i++) {
238
+ above_level[x4 + i] = cul_level;
239
+ above_dc[x4 + i] = dc_category;
240
+ }
241
+
242
+ for (let i = 0; i < h4; i++) {
243
+ left_level[y4 + i] = cul_level;
244
+ left_dc[y4 + i] = dc_category;
245
+ }
246
+
247
+ return eob;
248
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Exp-Golomb escape for coefficient levels above `NUM_BASE_LEVELS + COEFF_BASE_RANGE`: a unary
3
+ * length prefix, then that many suffix bits.
4
+ *
5
+ * The length loop is bounded, and that is the whole point of this function existing. Once a
6
+ * {@link SymbolReader} runs past the end of its payload, `symbol_max_bits` goes negative, the reader
7
+ * stops consuming bytes and `read_bits` returns 0, which pins the symbol value to the half of the
8
+ * interval that `read_bool` decodes as 0 — so an unbounded `do { length++ } while (read_bool() === 0)`
9
+ * spins forever, with no allocation and no I/O for anything else to notice. A tile cut short by a
10
+ * partial download or a fuzzer is enough, and this is the entry point for untrusted image data.
11
+ *
12
+ * @param {SymbolReader} reader
13
+ * @returns {number}
14
+ * @throws {Error} if the length prefix runs past {@link MAX_LENGTH}, which means the stream is corrupt
15
+ * @see AV1 spec 5.11.39 "Coefficients syntax"
16
+ *
17
+ * @author Alex Goldring
18
+ * @copyright Company Named Limited (c) 2026
19
+ */
20
+ export function read_golomb(reader: SymbolReader): number;
21
+ //# sourceMappingURL=read_golomb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read_golomb.d.ts","sourceRoot":"","sources":["../../../../../../../src/format/image/avif/av1/decode/read_golomb.js"],"names":[],"mappings":"AAWA;;;;;;;;;;;;;;;;;;GAkBG;AACH,mDAPa,MAAM,CAyBlB"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Upper bound on the unary length prefix, matching libaom's `read_golomb`.
3
+ *
4
+ * The specification leaves the bound as a conformance requirement on the encoder, which a decoder
5
+ * reading untrusted bytes cannot assume. libaom caps the same loop at 20 and raises
6
+ * `AOM_CODEC_CORRUPT_FRAME`; a coefficient level needs nowhere near that many bits, so the cap
7
+ * rejects only streams that are already malformed.
8
+ * @type {number}
9
+ */
10
+ const MAX_LENGTH = 20;
11
+
12
+ /**
13
+ * Exp-Golomb escape for coefficient levels above `NUM_BASE_LEVELS + COEFF_BASE_RANGE`: a unary
14
+ * length prefix, then that many suffix bits.
15
+ *
16
+ * The length loop is bounded, and that is the whole point of this function existing. Once a
17
+ * {@link SymbolReader} runs past the end of its payload, `symbol_max_bits` goes negative, the reader
18
+ * stops consuming bytes and `read_bits` returns 0, which pins the symbol value to the half of the
19
+ * interval that `read_bool` decodes as 0 — so an unbounded `do { length++ } while (read_bool() === 0)`
20
+ * spins forever, with no allocation and no I/O for anything else to notice. A tile cut short by a
21
+ * partial download or a fuzzer is enough, and this is the entry point for untrusted image data.
22
+ *
23
+ * @param {SymbolReader} reader
24
+ * @returns {number}
25
+ * @throws {Error} if the length prefix runs past {@link MAX_LENGTH}, which means the stream is corrupt
26
+ * @see AV1 spec 5.11.39 "Coefficients syntax"
27
+ *
28
+ * @author Alex Goldring
29
+ * @copyright Company Named Limited (c) 2026
30
+ */
31
+ export function read_golomb(reader) {
32
+ let length = 0;
33
+
34
+ do {
35
+ length++;
36
+
37
+ if (length > MAX_LENGTH) {
38
+ throw new Error(`golomb length prefix exceeded ${MAX_LENGTH} bits, stream is corrupt`);
39
+ }
40
+ } while (reader.read_bool() === 0);
41
+
42
+ let x = 1;
43
+
44
+ for (let i = length - 2; i >= 0; i--) {
45
+ x = (x << 1) | reader.read_bool();
46
+ }
47
+
48
+ return x;
49
+ }