@woosh/meep-engine 3.60.6 → 3.60.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/bundle-worker-terrain.js +1 -1
- package/package.json +1 -1
- package/src/core/binary/BitSet.d.ts.map +1 -1
- package/src/core/binary/BitSet.js +2 -1
- package/src/{format/image/avif/av1/util → core/binary/operations}/ceil_log2.d.ts +2 -2
- package/src/core/binary/operations/ceil_log2.d.ts.map +1 -0
- package/src/{format/image/avif/av1/util → core/binary/operations}/ceil_log2.js +18 -18
- package/src/core/binary/zstd/ZstdReverseBitReader.d.ts.map +1 -1
- package/src/core/binary/zstd/ZstdReverseBitReader.js +225 -223
- package/src/core/binary/zstd/zstd_fse.d.ts.map +1 -1
- package/src/core/binary/zstd/zstd_fse.js +267 -265
- package/src/core/binary/zstd/zstd_huffman.d.ts.map +1 -1
- package/src/core/binary/zstd/zstd_huffman.js +246 -244
- package/src/core/bvh2/binary/2/BinaryUint32BVH.d.ts.map +1 -1
- package/src/core/bvh2/binary/2/BinaryUint32BVH.js +8 -2
- package/src/core/bvh2/bvh3/ebvh_optimize_treelet.d.ts.map +1 -1
- package/src/core/bvh2/bvh3/ebvh_optimize_treelet.js +8 -7
- package/src/core/collection/PairUint32Map.d.ts.map +1 -1
- package/src/core/collection/PairUint32Map.js +2 -2
- package/src/core/collection/Uint32Map.d.ts.map +1 -1
- package/src/core/collection/Uint32Map.js +2 -4
- package/src/core/collection/heap/FibonacciHeap.d.ts.map +1 -1
- package/src/core/collection/heap/FibonacciHeap.js +2 -1
- package/src/core/geom/2d/r-tree/StaticR2Tree.d.ts.map +1 -1
- package/src/core/geom/2d/r-tree/StaticR2Tree.js +8 -2
- package/src/core/geom/3d/shape/util/mesh_compute_triangle_edge_flags.d.ts.map +1 -1
- package/src/core/geom/3d/shape/util/mesh_compute_triangle_edge_flags.js +2 -3
- package/src/engine/graphics/texture/atlas/TextureAtlas.d.ts.map +1 -1
- package/src/engine/graphics/texture/atlas/TextureAtlas.js +13 -14
- package/src/engine/graphics/texture/atlas/sprite_atlas_border.d.ts.map +1 -1
- package/src/engine/graphics/texture/atlas/sprite_atlas_border.js +70 -69
- package/src/engine/graphics/texture/reflection/convolve_equirectangular_reflection.d.ts.map +1 -1
- package/src/engine/graphics/texture/reflection/convolve_equirectangular_reflection.js +2 -1
- package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -1
- package/src/engine/graphics3/GPUParticleEmitterSystem.js +2 -1
- package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts.map +1 -1
- package/src/engine/graphics3/decal/GPUDecalRenderer.js +2 -1
- package/src/engine/graphics3/decal/chunk_decal_record.d.ts +14 -0
- package/src/engine/graphics3/decal/chunk_decal_record.d.ts.map +1 -0
- package/src/engine/graphics3/decal/chunk_decal_record.js +44 -0
- package/src/engine/graphics3/decal/shader_cluster_assign_decals.d.ts.map +1 -1
- package/src/engine/graphics3/decal/shader_cluster_assign_decals.js +2 -15
- package/src/engine/graphics3/decal/shader_cull_decals_frustum.d.ts.map +1 -1
- package/src/engine/graphics3/decal/shader_cull_decals_frustum.js +3 -16
- package/src/engine/graphics3/decal/shader_decal_composite.d.ts.map +1 -1
- package/src/engine/graphics3/decal/shader_decal_composite.js +3 -23
- package/src/engine/graphics3/terrain/TERRAIN_MATERIAL_TEMPLATE.d.ts.map +1 -1
- package/src/engine/graphics3/terrain/TERRAIN_MATERIAL_TEMPLATE.js +2 -1
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/engine/physics/queries/shape_cast.js +2 -2
- package/src/format/image/avif/av1/decode/decode_palette.js +442 -442
- package/src/format/image/avif/av1/entropy/SymbolWriter.d.ts.map +1 -1
- package/src/format/image/avif/av1/entropy/SymbolWriter.js +2 -1
- package/src/generation/foliage/material/foliage_tile.d.ts.map +1 -1
- package/src/generation/foliage/material/foliage_tile.js +2 -1
- package/src/shade/device/mock/SoftwareGPUDevice.d.ts.map +1 -1
- package/src/shade/device/mock/SoftwareGPUDevice.js +6 -13
- package/src/shade/playground/caldera/main.js +3 -2
- package/src/shade/playground/probe_clipmap/README.md +2 -1
- package/src/shade/playground/probe_clipmap/index.html +7 -2
- package/src/shade/playground/probe_clipmap/main.d.ts.map +1 -1
- package/src/shade/playground/probe_clipmap/main.js +17 -7
- package/src/shade/playground/sh_exponential/sh_exp_playground_shaders.d.ts.map +1 -1
- package/src/shade/playground/sh_exponential/sh_exp_playground_shaders.js +7 -13
- package/src/shade/playground/vgeo_scene/main.js +2 -1
- package/src/shade/playground/vsm/VSMDebugOverlay.d.ts.map +1 -1
- package/src/shade/playground/vsm/VSMDebugOverlay.js +3 -1
- package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
- package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
- package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
- package/src/shade/renderer/fluid/pressure/shader_fluid_mg_coarsest.d.ts.map +1 -1
- package/src/shade/renderer/fluid/pressure/shader_fluid_mg_coarsest.js +5 -4
- package/src/shade/renderer/fluid/pressure/shader_fluid_mg_residual_restrict.d.ts.map +1 -1
- package/src/shade/renderer/fluid/pressure/shader_fluid_mg_residual_restrict.js +168 -166
- package/src/shade/renderer/fluid/pressure/shader_fluid_mg_smooth.d.ts.map +1 -1
- package/src/shade/renderer/fluid/pressure/shader_fluid_mg_smooth.js +221 -219
- package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
- package/src/shade/renderer/fow/shader_fog_of_war.d.ts.map +1 -1
- package/src/shade/renderer/fow/shader_fog_of_war.js +8 -19
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +6 -6
- package/src/shade/renderer/geometry/sdf/MeshSDFLayout.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/MeshSDFLayout.js +2 -1
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +2 -1
- package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.js +2 -1
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v1/chunk_brick4_sh3_color_decode_from_storage.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v1/chunk_brick4_sh3_color_decode_from_storage.js +10 -31
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v1/chunk_brick4_sh3_color_encode_to_storage.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v1/chunk_brick4_sh3_color_encode_to_storage.js +9 -15
- package/src/shade/renderer/global_illumination/clipmap/shader_debug_clipmap.d.ts +2 -1
- package/src/shade/renderer/global_illumination/clipmap/shader_debug_clipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/clipmap/shader_debug_clipmap.js +6 -5
- package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_reduce_atlas_to_sh.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_reduce_atlas_to_sh.js +2 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts +15 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +168 -18
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts +98 -57
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.js +168 -77
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts +4 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.js +27 -12
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap.js +12 -7
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.js +8 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_walk.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_walk.js +5 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_batch.js +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_gather.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_gather.js +5 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_resolve.js +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/shader_brick_clipmap_free.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/shader_brick_clipmap_free.js +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/shader_brick_clipmap_movers_command.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/shader_brick_clipmap_movers_command.js +4 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/shader_brick_clipmap_scroll.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/shader_brick_clipmap_scroll.js +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/shader_brick_clipmap_store.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/shader_brick_clipmap_store.js +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/shader_brick_clipmap_take.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/shader_brick_clipmap_take.js +3 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_mesh_cards.js +2 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +114 -41
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +424 -207
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +34 -25
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.js +41 -31
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP_RESAMPLING.d.ts +7 -5
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP_RESAMPLING.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP_RESAMPLING.js +7 -5
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapHitWants.d.ts +47 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapHitWants.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapHitWants.js +84 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.d.ts +48 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.js +101 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts +58 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.js +127 -30
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_cage.d.ts +18 -7
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_cage.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_cage.js +39 -13
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.d.ts +29 -8
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.js +112 -56
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_resample.d.ts +19 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_resample.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_resample.js +35 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.js +9 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.d.ts +3 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.js +5 -5
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts +8 -12
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.js +23 -56
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_admit.d.ts +0 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_admit.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_admit.js +11 -15
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_bounce.d.ts +26 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_bounce.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_bounce.js +173 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_candidate.d.ts +32 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_candidate.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_candidate.js +166 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts +3 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.js +3 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_guide.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_guide.js +3 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.d.ts +6 -12
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.js +15 -65
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_order.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_order.js +7 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.d.ts +4 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.js +24 -17
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_publish.d.ts +7 -5
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_publish.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_publish.js +18 -10
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_ray_layout.d.ts +2 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_ray_layout.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_ray_layout.js +9 -5
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.d.ts +3 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.js +9 -6
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_resample.d.ts +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_resample.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_resample.js +16 -16
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_resample_rays.d.ts +36 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_resample_rays.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_resample_rays.js +233 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.js +7 -5
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +5 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.js +10 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace_command.d.ts +2 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace_command.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace_command.js +12 -6
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts +1 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.js +5 -6
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_hits.d.ts +14 -18
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_hits.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_hits.js +25 -35
- package/src/shade/renderer/gpu_primitive/WEBGPU_GUARANTEED_MAX_UNIFORM_BUFFER_BINDING_SIZE.d.ts +13 -0
- package/src/shade/renderer/gpu_primitive/WEBGPU_GUARANTEED_MAX_UNIFORM_BUFFER_BINDING_SIZE.d.ts.map +1 -0
- package/src/shade/renderer/gpu_primitive/WEBGPU_GUARANTEED_MAX_UNIFORM_BUFFER_BINDING_SIZE.js +12 -0
- package/src/shade/renderer/gpu_primitive/hash_table/cpu_build_hash_table.d.ts +27 -2
- package/src/shade/renderer/gpu_primitive/hash_table/cpu_build_hash_table.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/hash_table/cpu_build_hash_table.js +62 -6
- package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.js +10 -19
- package/src/shade/renderer/gpu_primitive/indirect/chunk_folded_dispatch.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/indirect/chunk_folded_dispatch.js +6 -3
- package/src/shade/renderer/hiz/hzb_pick_alignment.d.ts.map +1 -1
- package/src/shade/renderer/hiz/hzb_pick_alignment.js +149 -148
- package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_environment_cells.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_environment_cells.js +4 -2
- package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_log_floor.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_log_floor.js +6 -5
- package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_project.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_project.js +3 -1
- package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_reference_reflectance.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_reference_reflectance.js +3 -1
- package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_solve.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_solve.js +3 -1
- package/src/shade/renderer/light/world_cluster/WORLD_LIGHT_CLUSTER.d.ts +0 -5
- package/src/shade/renderer/light/world_cluster/WORLD_LIGHT_CLUSTER.d.ts.map +1 -1
- package/src/shade/renderer/light/world_cluster/WORLD_LIGHT_CLUSTER.js +0 -7
- package/src/shade/renderer/light/world_cluster/graph_build_world_light_clusters.d.ts +15 -2
- package/src/shade/renderer/light/world_cluster/graph_build_world_light_clusters.d.ts.map +1 -1
- package/src/shade/renderer/light/world_cluster/graph_build_world_light_clusters.js +51 -16
- package/src/shade/renderer/light/world_cluster/shader_world_cluster_assign_lights.d.ts.map +1 -1
- package/src/shade/renderer/light/world_cluster/shader_world_cluster_assign_lights.js +3 -2
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
- package/src/shade/renderer/postprocess/dof/raymarch/chunk_dof_lds_coc_cache.d.ts +17 -0
- package/src/shade/renderer/postprocess/dof/raymarch/chunk_dof_lds_coc_cache.d.ts.map +1 -0
- package/src/shade/renderer/postprocess/dof/raymarch/chunk_dof_lds_coc_cache.js +81 -0
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.js +5 -48
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.js +4 -44
- package/src/shade/renderer/postprocess/gtao/chunk_integrate_lighting_sample.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/gtao/chunk_integrate_lighting_sample.js +4 -1
- package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.js +8 -7
- package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
- package/src/shade/renderer/postprocess/nss/chunk_nss_luma_derivative.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/chunk_nss_luma_derivative.js +5 -7
- package/src/shade/renderer/postprocess/nss/chunk_nss_tonemap.d.ts +17 -0
- package/src/shade/renderer/postprocess/nss/chunk_nss_tonemap.d.ts.map +1 -0
- package/src/shade/renderer/postprocess/nss/chunk_nss_tonemap.js +56 -0
- package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.js +2 -22
- package/src/shade/renderer/postprocess/nss/shader_nss_preprocess.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/shader_nss_preprocess.js +2 -13
- package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +10 -13
- package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.js +39 -38
- package/src/shade/renderer/rasterize/expand/mesh/shader_prefix_sum_to_command.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/mesh/shader_prefix_sum_to_command.js +7 -12
- package/src/shade/renderer/shader/chunk/clipmap/CLIPMAP_LEVEL_STRUCT.d.ts +8 -6
- package/src/shade/renderer/shader/chunk/clipmap/CLIPMAP_LEVEL_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/clipmap/CLIPMAP_LEVEL_STRUCT.js +10 -7
- package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_key.d.ts +16 -0
- package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_key.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_key.js +35 -0
- package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_select_finest.d.ts +5 -2
- package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_select_finest.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/clipmap/chunk_clipmap_select_finest.js +27 -18
- package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh2_color_get_irradiance_at.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh2_color_get_irradiance_at.js +5 -15
- package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh3_convolve_with_cosine_kernel.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh3_convolve_with_cosine_kernel.js +5 -19
- package/src/shade/renderer/shader/chunk/spherical_harmonics/dering/chunk_sh3_windowing.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/spherical_harmonics/dering/chunk_sh3_windowing.js +3 -22
- package/src/shade/renderer/shadow/map/ShadowmapDrawSelector.d.ts.map +1 -1
- package/src/shade/renderer/shadow/map/ShadowmapDrawSelector.js +2 -1
- package/src/shade/renderer/volumetrics/chunk_volumetrics_sun_shadow_group_list.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/chunk_volumetrics_sun_shadow_group_list.js +154 -152
- package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.js +2 -1
- package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP.d.ts +3 -1
- package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP.js +4 -3
- package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP_STRUCT.d.ts +7 -1
- package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP_STRUCT.js +54 -47
- package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_sample.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_sample.js +371 -370
- package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
- package/src/shade/renderer/water/GPUWaterRenderer.js +2 -1
- package/src/shade/renderer/water/query/GPUWaterQueries.d.ts +1 -1
- package/src/shade/renderer/water/surface/lod/shader_water_lod.d.ts.map +1 -1
- package/src/shade/renderer/water/surface/lod/shader_water_lod.js +12 -14
- package/src/shade/renderer/water/surface/particles/GPUWaterParticles.d.ts.map +1 -1
- package/src/shade/renderer/water/surface/particles/GPUWaterParticles.js +2 -9
- package/src/shade/renderer/water/surface/particles/chunk_water_particle.d.ts.map +1 -1
- package/src/shade/renderer/water/surface/particles/chunk_water_particle.js +2 -1
- package/src/shade/renderer/wind/WIND_FIELD.d.ts +3 -1
- package/src/shade/renderer/wind/WIND_FIELD.d.ts.map +1 -1
- package/src/shade/renderer/wind/WIND_FIELD.js +4 -3
- package/src/shade/renderer/wind/WIND_FIELD_STRUCT.d.ts +8 -2
- package/src/shade/renderer/wind/WIND_FIELD_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/wind/WIND_FIELD_STRUCT.js +11 -4
- package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts +2 -2
- package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts.map +1 -1
- package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.js +13 -4
- package/src/shade/util/texture_mip_extent.d.ts.map +1 -1
- package/src/shade/util/texture_mip_extent.js +88 -87
- package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.js +9 -7
- package/src/format/image/avif/av1/util/ceil_log2.d.ts.map +0 -1
- package/src/shade/renderer/shader/chunk/color/chunk_hash_squirrel3.d.ts +0 -1
- package/src/shade/renderer/shader/chunk/color/chunk_hash_squirrel3.d.ts.map +0 -1
- package/src/shade/renderer/shader/chunk/color/chunk_hash_squirrel3.js +0 -0
|
@@ -1,442 +1,442 @@
|
|
|
1
|
-
import { clamp } from "../../../../../core/math/clamp.js";
|
|
2
|
-
import {
|
|
3
|
-
DC_PRED,
|
|
4
|
-
MI_SIZE,
|
|
5
|
-
PALETTE_COLORS,
|
|
6
|
-
PALETTE_NUM_NEIGHBORS
|
|
7
|
-
} from "../tables/av1_symbols.js";
|
|
8
|
-
import { MI_HEIGHT_LOG2, MI_WIDTH_LOG2 } from "../tables/block_tables.js";
|
|
9
|
-
import { BLOCK_HEIGHT, BLOCK_WIDTH } from "../tables/derived_block_tables.js";
|
|
10
|
-
import { PALETTE_COLOR_CONTEXT, PALETTE_COLOR_HASH_MULTIPLIERS } from "../tables/prediction_tables.js";
|
|
11
|
-
import { ceil_log2 } from "
|
|
12
|
-
import { MAX_PALETTE_SIZE } from "./Av1FrameContext.js";
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Read a block's palettes.
|
|
16
|
-
*
|
|
17
|
-
* Colours are coded as a mixture of cache hits — colours reused from the blocks above and to the
|
|
18
|
-
* left — a literal, and then deltas whose width shrinks as the colours climb towards the top of the
|
|
19
|
-
* range. The V plane is the odd one out: its colours may be delta-coded with a sign and wrap around
|
|
20
|
-
* the range, because chroma has no reason to be monotonic.
|
|
21
|
-
*
|
|
22
|
-
* @param {Av1FrameContext} ctx
|
|
23
|
-
* @see AV1 spec 5.11.46 "Palette mode info syntax"
|
|
24
|
-
*
|
|
25
|
-
* @author Alex Goldring
|
|
26
|
-
* @copyright Company Named Limited (c) 2026
|
|
27
|
-
*/
|
|
28
|
-
export function read_palette_mode_info(ctx) {
|
|
29
|
-
const reader = ctx.reader;
|
|
30
|
-
const cdf = ctx.cdf;
|
|
31
|
-
|
|
32
|
-
const bit_depth = ctx.bit_depth;
|
|
33
|
-
const max_value = (1 << bit_depth) - 1;
|
|
34
|
-
|
|
35
|
-
const bsize_ctx = MI_WIDTH_LOG2[ctx.mi_size] + MI_HEIGHT_LOG2[ctx.mi_size] - 2;
|
|
36
|
-
|
|
37
|
-
if (ctx.y_mode === DC_PRED) {
|
|
38
|
-
let ctx_y = 0;
|
|
39
|
-
|
|
40
|
-
if (ctx.avail_u === 1 && ctx.palette_sizes[0 * ctx.mi_stride * ctx.mi_rows + (ctx.mi_row - 1) * ctx.mi_stride + ctx.mi_col] > 0) {
|
|
41
|
-
ctx_y += 1;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (ctx.avail_l === 1 && ctx.palette_sizes[0 * ctx.mi_stride * ctx.mi_rows + ctx.mi_row * ctx.mi_stride + ctx.mi_col - 1] > 0) {
|
|
45
|
-
ctx_y += 1;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const has_palette_y = reader.read_symbol(cdf.palette_y_mode, (bsize_ctx * 3 + ctx_y) * 3, 2);
|
|
49
|
-
|
|
50
|
-
if (has_palette_y === 1) {
|
|
51
|
-
ctx.palette_size_y = reader.read_symbol(cdf.palette_y_size, bsize_ctx * 8, 7) + 2;
|
|
52
|
-
|
|
53
|
-
const cache_count = build_palette_cache(ctx, 0);
|
|
54
|
-
|
|
55
|
-
let idx = 0;
|
|
56
|
-
|
|
57
|
-
for (let i = 0; i < cache_count && idx < ctx.palette_size_y; i++) {
|
|
58
|
-
if (reader.read_bool() === 1) {
|
|
59
|
-
ctx.palette_colors_y[idx] = ctx.palette_cache[i];
|
|
60
|
-
idx++;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (idx < ctx.palette_size_y) {
|
|
65
|
-
ctx.palette_colors_y[idx] = reader.read_literal(bit_depth);
|
|
66
|
-
idx++;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
let palette_bits = 0;
|
|
70
|
-
|
|
71
|
-
if (idx < ctx.palette_size_y) {
|
|
72
|
-
palette_bits = (bit_depth - 3) + reader.read_literal(2);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
while (idx < ctx.palette_size_y) {
|
|
76
|
-
const delta = reader.read_literal(palette_bits) + 1;
|
|
77
|
-
|
|
78
|
-
ctx.palette_colors_y[idx] = clamp(ctx.palette_colors_y[idx - 1] + delta, 0, max_value);
|
|
79
|
-
|
|
80
|
-
const range = (1 << bit_depth) - ctx.palette_colors_y[idx] - 1;
|
|
81
|
-
|
|
82
|
-
palette_bits = Math.min(palette_bits, ceil_log2(range));
|
|
83
|
-
|
|
84
|
-
idx++;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
sort_palette(ctx.palette_colors_y, ctx.palette_size_y);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (ctx.has_chroma === 1 && ctx.uv_mode === DC_PRED) {
|
|
92
|
-
const has_palette_uv = reader.read_symbol(cdf.palette_uv_mode, (ctx.palette_size_y > 0 ? 1 : 0) * 3, 2);
|
|
93
|
-
|
|
94
|
-
if (has_palette_uv === 1) {
|
|
95
|
-
ctx.palette_size_uv = reader.read_symbol(cdf.palette_uv_size, bsize_ctx * 8, 7) + 2;
|
|
96
|
-
|
|
97
|
-
const cache_count = build_palette_cache(ctx, 1);
|
|
98
|
-
|
|
99
|
-
let idx = 0;
|
|
100
|
-
|
|
101
|
-
for (let i = 0; i < cache_count && idx < ctx.palette_size_uv; i++) {
|
|
102
|
-
if (reader.read_bool() === 1) {
|
|
103
|
-
ctx.palette_colors_u[idx] = ctx.palette_cache[i];
|
|
104
|
-
idx++;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (idx < ctx.palette_size_uv) {
|
|
109
|
-
ctx.palette_colors_u[idx] = reader.read_literal(bit_depth);
|
|
110
|
-
idx++;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
let palette_bits = 0;
|
|
114
|
-
|
|
115
|
-
if (idx < ctx.palette_size_uv) {
|
|
116
|
-
palette_bits = (bit_depth - 3) + reader.read_literal(2);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
while (idx < ctx.palette_size_uv) {
|
|
120
|
-
const delta = reader.read_literal(palette_bits);
|
|
121
|
-
|
|
122
|
-
ctx.palette_colors_u[idx] = clamp(ctx.palette_colors_u[idx - 1] + delta, 0, max_value);
|
|
123
|
-
|
|
124
|
-
const range = (1 << bit_depth) - ctx.palette_colors_u[idx];
|
|
125
|
-
|
|
126
|
-
palette_bits = Math.min(palette_bits, ceil_log2(range));
|
|
127
|
-
|
|
128
|
-
idx++;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
sort_palette(ctx.palette_colors_u, ctx.palette_size_uv);
|
|
132
|
-
|
|
133
|
-
if (reader.read_bool() === 1) {
|
|
134
|
-
const max_val = 1 << bit_depth;
|
|
135
|
-
|
|
136
|
-
const bits = (bit_depth - 4) + reader.read_literal(2);
|
|
137
|
-
|
|
138
|
-
ctx.palette_colors_v[0] = reader.read_literal(bit_depth);
|
|
139
|
-
|
|
140
|
-
for (let i = 1; i < ctx.palette_size_uv; i++) {
|
|
141
|
-
let delta = reader.read_literal(bits);
|
|
142
|
-
|
|
143
|
-
if (delta !== 0 && reader.read_bool() === 1) {
|
|
144
|
-
delta = -delta;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
let value = ctx.palette_colors_v[i - 1] + delta;
|
|
148
|
-
|
|
149
|
-
if (value < 0) {
|
|
150
|
-
value += max_val;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (value >= max_val) {
|
|
154
|
-
value -= max_val;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
ctx.palette_colors_v[i] = clamp(value, 0, max_value);
|
|
158
|
-
}
|
|
159
|
-
} else {
|
|
160
|
-
for (let i = 0; i < ctx.palette_size_uv; i++) {
|
|
161
|
-
ctx.palette_colors_v[i] = reader.read_literal(bit_depth);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Merge the palettes of the blocks above and to the left into `ctx.palette_cache`.
|
|
170
|
-
*
|
|
171
|
-
* Both are already in ascending order, so this is a merge rather than a sort, and duplicates are
|
|
172
|
-
* dropped as they appear.
|
|
173
|
-
*
|
|
174
|
-
* @param {Av1FrameContext} ctx
|
|
175
|
-
* @param {number} plane `0` luma, `1` chroma
|
|
176
|
-
* @returns {number} the number of cached colours
|
|
177
|
-
* @see AV1 spec 5.11.46, `get_palette_cache`
|
|
178
|
-
*/
|
|
179
|
-
function build_palette_cache(ctx, plane) {
|
|
180
|
-
const mi_count = ctx.mi_stride * ctx.mi_rows;
|
|
181
|
-
const size_base = plane * mi_count;
|
|
182
|
-
const colour_base = plane * mi_count * MAX_PALETTE_SIZE;
|
|
183
|
-
|
|
184
|
-
// the above palette is only visible within the same 64-sample row of superblocks
|
|
185
|
-
const above_available = (ctx.mi_row * MI_SIZE) % 64 !== 0;
|
|
186
|
-
|
|
187
|
-
const above_index = (ctx.mi_row - 1) * ctx.mi_stride + ctx.mi_col;
|
|
188
|
-
const left_index = ctx.mi_row * ctx.mi_stride + ctx.mi_col - 1;
|
|
189
|
-
|
|
190
|
-
const above_count = above_available ? ctx.palette_sizes[size_base + above_index] : 0;
|
|
191
|
-
const left_count = ctx.avail_l === 1 ? ctx.palette_sizes[size_base + left_index] : 0;
|
|
192
|
-
|
|
193
|
-
const cache = ctx.palette_cache;
|
|
194
|
-
const colours = ctx.palette_colors;
|
|
195
|
-
|
|
196
|
-
let above_idx = 0;
|
|
197
|
-
let left_idx = 0;
|
|
198
|
-
let n = 0;
|
|
199
|
-
|
|
200
|
-
while (above_idx < above_count && left_idx < left_count) {
|
|
201
|
-
const above_colour = colours[colour_base + above_index * MAX_PALETTE_SIZE + above_idx];
|
|
202
|
-
const left_colour = colours[colour_base + left_index * MAX_PALETTE_SIZE + left_idx];
|
|
203
|
-
|
|
204
|
-
if (left_colour < above_colour) {
|
|
205
|
-
if (n === 0 || left_colour !== cache[n - 1]) {
|
|
206
|
-
cache[n++] = left_colour;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
left_idx++;
|
|
210
|
-
} else {
|
|
211
|
-
if (n === 0 || above_colour !== cache[n - 1]) {
|
|
212
|
-
cache[n++] = above_colour;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
above_idx++;
|
|
216
|
-
|
|
217
|
-
if (left_colour === above_colour) {
|
|
218
|
-
left_idx++;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
while (above_idx < above_count) {
|
|
224
|
-
const value = colours[colour_base + above_index * MAX_PALETTE_SIZE + above_idx];
|
|
225
|
-
|
|
226
|
-
above_idx++;
|
|
227
|
-
|
|
228
|
-
if (n === 0 || value !== cache[n - 1]) {
|
|
229
|
-
cache[n++] = value;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
while (left_idx < left_count) {
|
|
234
|
-
const value = colours[colour_base + left_index * MAX_PALETTE_SIZE + left_idx];
|
|
235
|
-
|
|
236
|
-
left_idx++;
|
|
237
|
-
|
|
238
|
-
if (n === 0 || value !== cache[n - 1]) {
|
|
239
|
-
cache[n++] = value;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
return n;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* @param {Uint16Array} palette
|
|
248
|
-
* @param {number} count
|
|
249
|
-
*/
|
|
250
|
-
function sort_palette(palette, count) {
|
|
251
|
-
// insertion sort: the array is at most eight entries and usually already ordered
|
|
252
|
-
for (let i = 1; i < count; i++) {
|
|
253
|
-
const value = palette[i];
|
|
254
|
-
|
|
255
|
-
let j = i - 1;
|
|
256
|
-
|
|
257
|
-
while (j >= 0 && palette[j] > value) {
|
|
258
|
-
palette[j + 1] = palette[j];
|
|
259
|
-
j--;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
palette[j + 1] = value;
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* Read the colour index maps for a palette block.
|
|
268
|
-
*
|
|
269
|
-
* The map is coded along anti-diagonals so that every sample has its left, above and above-left
|
|
270
|
-
* neighbours already decoded. Samples beyond the visible edge of the frame are not coded at all;
|
|
271
|
-
* they are filled by extending the last coded column and row, which keeps prediction well defined
|
|
272
|
-
* without spending bits on samples nobody sees.
|
|
273
|
-
*
|
|
274
|
-
* @param {Av1FrameContext} ctx
|
|
275
|
-
* @see AV1 spec 5.11.49 "Palette tokens syntax"
|
|
276
|
-
*/
|
|
277
|
-
export function read_palette_tokens(ctx) {
|
|
278
|
-
const reader = ctx.reader;
|
|
279
|
-
|
|
280
|
-
let block_height = BLOCK_HEIGHT[ctx.mi_size];
|
|
281
|
-
let block_width = BLOCK_WIDTH[ctx.mi_size];
|
|
282
|
-
|
|
283
|
-
let onscreen_height = Math.min(block_height, (ctx.mi_rows - ctx.mi_row) * MI_SIZE);
|
|
284
|
-
let onscreen_width = Math.min(block_width, (ctx.mi_cols - ctx.mi_col) * MI_SIZE);
|
|
285
|
-
|
|
286
|
-
const stride = ctx.color_map_stride;
|
|
287
|
-
|
|
288
|
-
if (ctx.palette_size_y > 0) {
|
|
289
|
-
const map = ctx.color_map_y;
|
|
290
|
-
|
|
291
|
-
map[0] = reader.read_ns(ctx.palette_size_y);
|
|
292
|
-
|
|
293
|
-
read_colour_map(ctx, map, stride, onscreen_width, onscreen_height, ctx.palette_size_y, ctx.cdf.palette_y_color);
|
|
294
|
-
|
|
295
|
-
extend_colour_map(map, stride, block_width, block_height, onscreen_width, onscreen_height);
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
if (ctx.palette_size_uv > 0) {
|
|
299
|
-
const map = ctx.color_map_uv;
|
|
300
|
-
|
|
301
|
-
map[0] = reader.read_ns(ctx.palette_size_uv);
|
|
302
|
-
|
|
303
|
-
block_height = block_height >> ctx.subsampling_y;
|
|
304
|
-
block_width = block_width >> ctx.subsampling_x;
|
|
305
|
-
onscreen_height = onscreen_height >> ctx.subsampling_y;
|
|
306
|
-
onscreen_width = onscreen_width >> ctx.subsampling_x;
|
|
307
|
-
|
|
308
|
-
// a 4x4 luma block subsamples to 2x2 chroma, which is smaller than the smallest transform;
|
|
309
|
-
// the map is grown to 4 so the prediction has something to read
|
|
310
|
-
if (block_width < 4) {
|
|
311
|
-
block_width += 2;
|
|
312
|
-
onscreen_width += 2;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
if (block_height < 4) {
|
|
316
|
-
block_height += 2;
|
|
317
|
-
onscreen_height += 2;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
read_colour_map(ctx, map, stride, onscreen_width, onscreen_height, ctx.palette_size_uv, ctx.cdf.palette_uv_color);
|
|
321
|
-
|
|
322
|
-
extend_colour_map(map, stride, block_width, block_height, onscreen_width, onscreen_height);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
/**
|
|
327
|
-
* @param {Av1FrameContext} ctx
|
|
328
|
-
* @param {Uint8Array} map
|
|
329
|
-
* @param {number} stride
|
|
330
|
-
* @param {number} width
|
|
331
|
-
* @param {number} height
|
|
332
|
-
* @param {number} palette_size
|
|
333
|
-
* @param {Uint16Array[]} colour_cdfs
|
|
334
|
-
*/
|
|
335
|
-
function read_colour_map(ctx, map, stride, width, height, palette_size, colour_cdfs) {
|
|
336
|
-
const reader = ctx.reader;
|
|
337
|
-
|
|
338
|
-
const cdf = colour_cdfs[palette_size - 2];
|
|
339
|
-
const stride_symbols = palette_size + 1;
|
|
340
|
-
|
|
341
|
-
for (let i = 1; i < height + width - 1; i++) {
|
|
342
|
-
for (let j = Math.min(i, width - 1); j >= Math.max(0, i - height + 1); j--) {
|
|
343
|
-
const r = i - j;
|
|
344
|
-
|
|
345
|
-
const hash = compute_colour_context(ctx, map, stride, r, j, palette_size);
|
|
346
|
-
const context = PALETTE_COLOR_CONTEXT[hash];
|
|
347
|
-
|
|
348
|
-
const symbol = reader.read_symbol(cdf, context * stride_symbols, palette_size);
|
|
349
|
-
|
|
350
|
-
map[r * stride + j] = ctx.color_order[symbol];
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
/**
|
|
356
|
-
* @param {Uint8Array} map
|
|
357
|
-
* @param {number} stride
|
|
358
|
-
* @param {number} block_width
|
|
359
|
-
* @param {number} block_height
|
|
360
|
-
* @param {number} onscreen_width
|
|
361
|
-
* @param {number} onscreen_height
|
|
362
|
-
*/
|
|
363
|
-
function extend_colour_map(map, stride, block_width, block_height, onscreen_width, onscreen_height) {
|
|
364
|
-
for (let i = 0; i < onscreen_height; i++) {
|
|
365
|
-
for (let j = onscreen_width; j < block_width; j++) {
|
|
366
|
-
map[i * stride + j] = map[i * stride + onscreen_width - 1];
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
for (let i = onscreen_height; i < block_height; i++) {
|
|
371
|
-
for (let j = 0; j < block_width; j++) {
|
|
372
|
-
map[i * stride + j] = map[(onscreen_height - 1) * stride + j];
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
/**
|
|
378
|
-
* Rank the palette colours by how strongly the decoded neighbours vote for them, and return the
|
|
379
|
-
* hash that selects the context.
|
|
380
|
-
*
|
|
381
|
-
* @param {Av1FrameContext} ctx
|
|
382
|
-
* @param {Uint8Array} map
|
|
383
|
-
* @param {number} stride
|
|
384
|
-
* @param {number} r
|
|
385
|
-
* @param {number} c
|
|
386
|
-
* @param {number} n palette size
|
|
387
|
-
* @returns {number} the colour context hash
|
|
388
|
-
* @see AV1 spec 5.11.50 "Palette color context function"
|
|
389
|
-
*/
|
|
390
|
-
function compute_colour_context(ctx, map, stride, r, c, n) {
|
|
391
|
-
const scores = ctx.color_scores;
|
|
392
|
-
const order = ctx.color_order;
|
|
393
|
-
|
|
394
|
-
for (let i = 0; i < PALETTE_COLORS; i++) {
|
|
395
|
-
scores[i] = 0;
|
|
396
|
-
order[i] = i;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
if (c > 0) {
|
|
400
|
-
scores[map[r * stride + c - 1]] += 2;
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
if (r > 0 && c > 0) {
|
|
404
|
-
scores[map[(r - 1) * stride + c - 1]] += 1;
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
if (r > 0) {
|
|
408
|
-
scores[map[(r - 1) * stride + c]] += 2;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
for (let i = 0; i < PALETTE_NUM_NEIGHBORS; i++) {
|
|
412
|
-
let max_score = scores[i];
|
|
413
|
-
let max_idx = i;
|
|
414
|
-
|
|
415
|
-
for (let j = i + 1; j < n; j++) {
|
|
416
|
-
if (scores[j] > max_score) {
|
|
417
|
-
max_score = scores[j];
|
|
418
|
-
max_idx = j;
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
if (max_idx !== i) {
|
|
423
|
-
const max_order = order[max_idx];
|
|
424
|
-
|
|
425
|
-
for (let k = max_idx; k > i; k--) {
|
|
426
|
-
scores[k] = scores[k - 1];
|
|
427
|
-
order[k] = order[k - 1];
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
scores[i] = max_score;
|
|
431
|
-
order[i] = max_order;
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
let hash = 0;
|
|
436
|
-
|
|
437
|
-
for (let i = 0; i < PALETTE_NUM_NEIGHBORS; i++) {
|
|
438
|
-
hash += scores[i] * PALETTE_COLOR_HASH_MULTIPLIERS[i];
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
return hash;
|
|
442
|
-
}
|
|
1
|
+
import { clamp } from "../../../../../core/math/clamp.js";
|
|
2
|
+
import {
|
|
3
|
+
DC_PRED,
|
|
4
|
+
MI_SIZE,
|
|
5
|
+
PALETTE_COLORS,
|
|
6
|
+
PALETTE_NUM_NEIGHBORS
|
|
7
|
+
} from "../tables/av1_symbols.js";
|
|
8
|
+
import { MI_HEIGHT_LOG2, MI_WIDTH_LOG2 } from "../tables/block_tables.js";
|
|
9
|
+
import { BLOCK_HEIGHT, BLOCK_WIDTH } from "../tables/derived_block_tables.js";
|
|
10
|
+
import { PALETTE_COLOR_CONTEXT, PALETTE_COLOR_HASH_MULTIPLIERS } from "../tables/prediction_tables.js";
|
|
11
|
+
import { ceil_log2 } from "../../../../../core/binary/operations/ceil_log2.js";
|
|
12
|
+
import { MAX_PALETTE_SIZE } from "./Av1FrameContext.js";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Read a block's palettes.
|
|
16
|
+
*
|
|
17
|
+
* Colours are coded as a mixture of cache hits — colours reused from the blocks above and to the
|
|
18
|
+
* left — a literal, and then deltas whose width shrinks as the colours climb towards the top of the
|
|
19
|
+
* range. The V plane is the odd one out: its colours may be delta-coded with a sign and wrap around
|
|
20
|
+
* the range, because chroma has no reason to be monotonic.
|
|
21
|
+
*
|
|
22
|
+
* @param {Av1FrameContext} ctx
|
|
23
|
+
* @see AV1 spec 5.11.46 "Palette mode info syntax"
|
|
24
|
+
*
|
|
25
|
+
* @author Alex Goldring
|
|
26
|
+
* @copyright Company Named Limited (c) 2026
|
|
27
|
+
*/
|
|
28
|
+
export function read_palette_mode_info(ctx) {
|
|
29
|
+
const reader = ctx.reader;
|
|
30
|
+
const cdf = ctx.cdf;
|
|
31
|
+
|
|
32
|
+
const bit_depth = ctx.bit_depth;
|
|
33
|
+
const max_value = (1 << bit_depth) - 1;
|
|
34
|
+
|
|
35
|
+
const bsize_ctx = MI_WIDTH_LOG2[ctx.mi_size] + MI_HEIGHT_LOG2[ctx.mi_size] - 2;
|
|
36
|
+
|
|
37
|
+
if (ctx.y_mode === DC_PRED) {
|
|
38
|
+
let ctx_y = 0;
|
|
39
|
+
|
|
40
|
+
if (ctx.avail_u === 1 && ctx.palette_sizes[0 * ctx.mi_stride * ctx.mi_rows + (ctx.mi_row - 1) * ctx.mi_stride + ctx.mi_col] > 0) {
|
|
41
|
+
ctx_y += 1;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (ctx.avail_l === 1 && ctx.palette_sizes[0 * ctx.mi_stride * ctx.mi_rows + ctx.mi_row * ctx.mi_stride + ctx.mi_col - 1] > 0) {
|
|
45
|
+
ctx_y += 1;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const has_palette_y = reader.read_symbol(cdf.palette_y_mode, (bsize_ctx * 3 + ctx_y) * 3, 2);
|
|
49
|
+
|
|
50
|
+
if (has_palette_y === 1) {
|
|
51
|
+
ctx.palette_size_y = reader.read_symbol(cdf.palette_y_size, bsize_ctx * 8, 7) + 2;
|
|
52
|
+
|
|
53
|
+
const cache_count = build_palette_cache(ctx, 0);
|
|
54
|
+
|
|
55
|
+
let idx = 0;
|
|
56
|
+
|
|
57
|
+
for (let i = 0; i < cache_count && idx < ctx.palette_size_y; i++) {
|
|
58
|
+
if (reader.read_bool() === 1) {
|
|
59
|
+
ctx.palette_colors_y[idx] = ctx.palette_cache[i];
|
|
60
|
+
idx++;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (idx < ctx.palette_size_y) {
|
|
65
|
+
ctx.palette_colors_y[idx] = reader.read_literal(bit_depth);
|
|
66
|
+
idx++;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let palette_bits = 0;
|
|
70
|
+
|
|
71
|
+
if (idx < ctx.palette_size_y) {
|
|
72
|
+
palette_bits = (bit_depth - 3) + reader.read_literal(2);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
while (idx < ctx.palette_size_y) {
|
|
76
|
+
const delta = reader.read_literal(palette_bits) + 1;
|
|
77
|
+
|
|
78
|
+
ctx.palette_colors_y[idx] = clamp(ctx.palette_colors_y[idx - 1] + delta, 0, max_value);
|
|
79
|
+
|
|
80
|
+
const range = (1 << bit_depth) - ctx.palette_colors_y[idx] - 1;
|
|
81
|
+
|
|
82
|
+
palette_bits = Math.min(palette_bits, ceil_log2(range));
|
|
83
|
+
|
|
84
|
+
idx++;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
sort_palette(ctx.palette_colors_y, ctx.palette_size_y);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (ctx.has_chroma === 1 && ctx.uv_mode === DC_PRED) {
|
|
92
|
+
const has_palette_uv = reader.read_symbol(cdf.palette_uv_mode, (ctx.palette_size_y > 0 ? 1 : 0) * 3, 2);
|
|
93
|
+
|
|
94
|
+
if (has_palette_uv === 1) {
|
|
95
|
+
ctx.palette_size_uv = reader.read_symbol(cdf.palette_uv_size, bsize_ctx * 8, 7) + 2;
|
|
96
|
+
|
|
97
|
+
const cache_count = build_palette_cache(ctx, 1);
|
|
98
|
+
|
|
99
|
+
let idx = 0;
|
|
100
|
+
|
|
101
|
+
for (let i = 0; i < cache_count && idx < ctx.palette_size_uv; i++) {
|
|
102
|
+
if (reader.read_bool() === 1) {
|
|
103
|
+
ctx.palette_colors_u[idx] = ctx.palette_cache[i];
|
|
104
|
+
idx++;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (idx < ctx.palette_size_uv) {
|
|
109
|
+
ctx.palette_colors_u[idx] = reader.read_literal(bit_depth);
|
|
110
|
+
idx++;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
let palette_bits = 0;
|
|
114
|
+
|
|
115
|
+
if (idx < ctx.palette_size_uv) {
|
|
116
|
+
palette_bits = (bit_depth - 3) + reader.read_literal(2);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
while (idx < ctx.palette_size_uv) {
|
|
120
|
+
const delta = reader.read_literal(palette_bits);
|
|
121
|
+
|
|
122
|
+
ctx.palette_colors_u[idx] = clamp(ctx.palette_colors_u[idx - 1] + delta, 0, max_value);
|
|
123
|
+
|
|
124
|
+
const range = (1 << bit_depth) - ctx.palette_colors_u[idx];
|
|
125
|
+
|
|
126
|
+
palette_bits = Math.min(palette_bits, ceil_log2(range));
|
|
127
|
+
|
|
128
|
+
idx++;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
sort_palette(ctx.palette_colors_u, ctx.palette_size_uv);
|
|
132
|
+
|
|
133
|
+
if (reader.read_bool() === 1) {
|
|
134
|
+
const max_val = 1 << bit_depth;
|
|
135
|
+
|
|
136
|
+
const bits = (bit_depth - 4) + reader.read_literal(2);
|
|
137
|
+
|
|
138
|
+
ctx.palette_colors_v[0] = reader.read_literal(bit_depth);
|
|
139
|
+
|
|
140
|
+
for (let i = 1; i < ctx.palette_size_uv; i++) {
|
|
141
|
+
let delta = reader.read_literal(bits);
|
|
142
|
+
|
|
143
|
+
if (delta !== 0 && reader.read_bool() === 1) {
|
|
144
|
+
delta = -delta;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
let value = ctx.palette_colors_v[i - 1] + delta;
|
|
148
|
+
|
|
149
|
+
if (value < 0) {
|
|
150
|
+
value += max_val;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (value >= max_val) {
|
|
154
|
+
value -= max_val;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
ctx.palette_colors_v[i] = clamp(value, 0, max_value);
|
|
158
|
+
}
|
|
159
|
+
} else {
|
|
160
|
+
for (let i = 0; i < ctx.palette_size_uv; i++) {
|
|
161
|
+
ctx.palette_colors_v[i] = reader.read_literal(bit_depth);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Merge the palettes of the blocks above and to the left into `ctx.palette_cache`.
|
|
170
|
+
*
|
|
171
|
+
* Both are already in ascending order, so this is a merge rather than a sort, and duplicates are
|
|
172
|
+
* dropped as they appear.
|
|
173
|
+
*
|
|
174
|
+
* @param {Av1FrameContext} ctx
|
|
175
|
+
* @param {number} plane `0` luma, `1` chroma
|
|
176
|
+
* @returns {number} the number of cached colours
|
|
177
|
+
* @see AV1 spec 5.11.46, `get_palette_cache`
|
|
178
|
+
*/
|
|
179
|
+
function build_palette_cache(ctx, plane) {
|
|
180
|
+
const mi_count = ctx.mi_stride * ctx.mi_rows;
|
|
181
|
+
const size_base = plane * mi_count;
|
|
182
|
+
const colour_base = plane * mi_count * MAX_PALETTE_SIZE;
|
|
183
|
+
|
|
184
|
+
// the above palette is only visible within the same 64-sample row of superblocks
|
|
185
|
+
const above_available = (ctx.mi_row * MI_SIZE) % 64 !== 0;
|
|
186
|
+
|
|
187
|
+
const above_index = (ctx.mi_row - 1) * ctx.mi_stride + ctx.mi_col;
|
|
188
|
+
const left_index = ctx.mi_row * ctx.mi_stride + ctx.mi_col - 1;
|
|
189
|
+
|
|
190
|
+
const above_count = above_available ? ctx.palette_sizes[size_base + above_index] : 0;
|
|
191
|
+
const left_count = ctx.avail_l === 1 ? ctx.palette_sizes[size_base + left_index] : 0;
|
|
192
|
+
|
|
193
|
+
const cache = ctx.palette_cache;
|
|
194
|
+
const colours = ctx.palette_colors;
|
|
195
|
+
|
|
196
|
+
let above_idx = 0;
|
|
197
|
+
let left_idx = 0;
|
|
198
|
+
let n = 0;
|
|
199
|
+
|
|
200
|
+
while (above_idx < above_count && left_idx < left_count) {
|
|
201
|
+
const above_colour = colours[colour_base + above_index * MAX_PALETTE_SIZE + above_idx];
|
|
202
|
+
const left_colour = colours[colour_base + left_index * MAX_PALETTE_SIZE + left_idx];
|
|
203
|
+
|
|
204
|
+
if (left_colour < above_colour) {
|
|
205
|
+
if (n === 0 || left_colour !== cache[n - 1]) {
|
|
206
|
+
cache[n++] = left_colour;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
left_idx++;
|
|
210
|
+
} else {
|
|
211
|
+
if (n === 0 || above_colour !== cache[n - 1]) {
|
|
212
|
+
cache[n++] = above_colour;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
above_idx++;
|
|
216
|
+
|
|
217
|
+
if (left_colour === above_colour) {
|
|
218
|
+
left_idx++;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
while (above_idx < above_count) {
|
|
224
|
+
const value = colours[colour_base + above_index * MAX_PALETTE_SIZE + above_idx];
|
|
225
|
+
|
|
226
|
+
above_idx++;
|
|
227
|
+
|
|
228
|
+
if (n === 0 || value !== cache[n - 1]) {
|
|
229
|
+
cache[n++] = value;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
while (left_idx < left_count) {
|
|
234
|
+
const value = colours[colour_base + left_index * MAX_PALETTE_SIZE + left_idx];
|
|
235
|
+
|
|
236
|
+
left_idx++;
|
|
237
|
+
|
|
238
|
+
if (n === 0 || value !== cache[n - 1]) {
|
|
239
|
+
cache[n++] = value;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return n;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* @param {Uint16Array} palette
|
|
248
|
+
* @param {number} count
|
|
249
|
+
*/
|
|
250
|
+
function sort_palette(palette, count) {
|
|
251
|
+
// insertion sort: the array is at most eight entries and usually already ordered
|
|
252
|
+
for (let i = 1; i < count; i++) {
|
|
253
|
+
const value = palette[i];
|
|
254
|
+
|
|
255
|
+
let j = i - 1;
|
|
256
|
+
|
|
257
|
+
while (j >= 0 && palette[j] > value) {
|
|
258
|
+
palette[j + 1] = palette[j];
|
|
259
|
+
j--;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
palette[j + 1] = value;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Read the colour index maps for a palette block.
|
|
268
|
+
*
|
|
269
|
+
* The map is coded along anti-diagonals so that every sample has its left, above and above-left
|
|
270
|
+
* neighbours already decoded. Samples beyond the visible edge of the frame are not coded at all;
|
|
271
|
+
* they are filled by extending the last coded column and row, which keeps prediction well defined
|
|
272
|
+
* without spending bits on samples nobody sees.
|
|
273
|
+
*
|
|
274
|
+
* @param {Av1FrameContext} ctx
|
|
275
|
+
* @see AV1 spec 5.11.49 "Palette tokens syntax"
|
|
276
|
+
*/
|
|
277
|
+
export function read_palette_tokens(ctx) {
|
|
278
|
+
const reader = ctx.reader;
|
|
279
|
+
|
|
280
|
+
let block_height = BLOCK_HEIGHT[ctx.mi_size];
|
|
281
|
+
let block_width = BLOCK_WIDTH[ctx.mi_size];
|
|
282
|
+
|
|
283
|
+
let onscreen_height = Math.min(block_height, (ctx.mi_rows - ctx.mi_row) * MI_SIZE);
|
|
284
|
+
let onscreen_width = Math.min(block_width, (ctx.mi_cols - ctx.mi_col) * MI_SIZE);
|
|
285
|
+
|
|
286
|
+
const stride = ctx.color_map_stride;
|
|
287
|
+
|
|
288
|
+
if (ctx.palette_size_y > 0) {
|
|
289
|
+
const map = ctx.color_map_y;
|
|
290
|
+
|
|
291
|
+
map[0] = reader.read_ns(ctx.palette_size_y);
|
|
292
|
+
|
|
293
|
+
read_colour_map(ctx, map, stride, onscreen_width, onscreen_height, ctx.palette_size_y, ctx.cdf.palette_y_color);
|
|
294
|
+
|
|
295
|
+
extend_colour_map(map, stride, block_width, block_height, onscreen_width, onscreen_height);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (ctx.palette_size_uv > 0) {
|
|
299
|
+
const map = ctx.color_map_uv;
|
|
300
|
+
|
|
301
|
+
map[0] = reader.read_ns(ctx.palette_size_uv);
|
|
302
|
+
|
|
303
|
+
block_height = block_height >> ctx.subsampling_y;
|
|
304
|
+
block_width = block_width >> ctx.subsampling_x;
|
|
305
|
+
onscreen_height = onscreen_height >> ctx.subsampling_y;
|
|
306
|
+
onscreen_width = onscreen_width >> ctx.subsampling_x;
|
|
307
|
+
|
|
308
|
+
// a 4x4 luma block subsamples to 2x2 chroma, which is smaller than the smallest transform;
|
|
309
|
+
// the map is grown to 4 so the prediction has something to read
|
|
310
|
+
if (block_width < 4) {
|
|
311
|
+
block_width += 2;
|
|
312
|
+
onscreen_width += 2;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
if (block_height < 4) {
|
|
316
|
+
block_height += 2;
|
|
317
|
+
onscreen_height += 2;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
read_colour_map(ctx, map, stride, onscreen_width, onscreen_height, ctx.palette_size_uv, ctx.cdf.palette_uv_color);
|
|
321
|
+
|
|
322
|
+
extend_colour_map(map, stride, block_width, block_height, onscreen_width, onscreen_height);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* @param {Av1FrameContext} ctx
|
|
328
|
+
* @param {Uint8Array} map
|
|
329
|
+
* @param {number} stride
|
|
330
|
+
* @param {number} width
|
|
331
|
+
* @param {number} height
|
|
332
|
+
* @param {number} palette_size
|
|
333
|
+
* @param {Uint16Array[]} colour_cdfs
|
|
334
|
+
*/
|
|
335
|
+
function read_colour_map(ctx, map, stride, width, height, palette_size, colour_cdfs) {
|
|
336
|
+
const reader = ctx.reader;
|
|
337
|
+
|
|
338
|
+
const cdf = colour_cdfs[palette_size - 2];
|
|
339
|
+
const stride_symbols = palette_size + 1;
|
|
340
|
+
|
|
341
|
+
for (let i = 1; i < height + width - 1; i++) {
|
|
342
|
+
for (let j = Math.min(i, width - 1); j >= Math.max(0, i - height + 1); j--) {
|
|
343
|
+
const r = i - j;
|
|
344
|
+
|
|
345
|
+
const hash = compute_colour_context(ctx, map, stride, r, j, palette_size);
|
|
346
|
+
const context = PALETTE_COLOR_CONTEXT[hash];
|
|
347
|
+
|
|
348
|
+
const symbol = reader.read_symbol(cdf, context * stride_symbols, palette_size);
|
|
349
|
+
|
|
350
|
+
map[r * stride + j] = ctx.color_order[symbol];
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* @param {Uint8Array} map
|
|
357
|
+
* @param {number} stride
|
|
358
|
+
* @param {number} block_width
|
|
359
|
+
* @param {number} block_height
|
|
360
|
+
* @param {number} onscreen_width
|
|
361
|
+
* @param {number} onscreen_height
|
|
362
|
+
*/
|
|
363
|
+
function extend_colour_map(map, stride, block_width, block_height, onscreen_width, onscreen_height) {
|
|
364
|
+
for (let i = 0; i < onscreen_height; i++) {
|
|
365
|
+
for (let j = onscreen_width; j < block_width; j++) {
|
|
366
|
+
map[i * stride + j] = map[i * stride + onscreen_width - 1];
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
for (let i = onscreen_height; i < block_height; i++) {
|
|
371
|
+
for (let j = 0; j < block_width; j++) {
|
|
372
|
+
map[i * stride + j] = map[(onscreen_height - 1) * stride + j];
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Rank the palette colours by how strongly the decoded neighbours vote for them, and return the
|
|
379
|
+
* hash that selects the context.
|
|
380
|
+
*
|
|
381
|
+
* @param {Av1FrameContext} ctx
|
|
382
|
+
* @param {Uint8Array} map
|
|
383
|
+
* @param {number} stride
|
|
384
|
+
* @param {number} r
|
|
385
|
+
* @param {number} c
|
|
386
|
+
* @param {number} n palette size
|
|
387
|
+
* @returns {number} the colour context hash
|
|
388
|
+
* @see AV1 spec 5.11.50 "Palette color context function"
|
|
389
|
+
*/
|
|
390
|
+
function compute_colour_context(ctx, map, stride, r, c, n) {
|
|
391
|
+
const scores = ctx.color_scores;
|
|
392
|
+
const order = ctx.color_order;
|
|
393
|
+
|
|
394
|
+
for (let i = 0; i < PALETTE_COLORS; i++) {
|
|
395
|
+
scores[i] = 0;
|
|
396
|
+
order[i] = i;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
if (c > 0) {
|
|
400
|
+
scores[map[r * stride + c - 1]] += 2;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if (r > 0 && c > 0) {
|
|
404
|
+
scores[map[(r - 1) * stride + c - 1]] += 1;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
if (r > 0) {
|
|
408
|
+
scores[map[(r - 1) * stride + c]] += 2;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
for (let i = 0; i < PALETTE_NUM_NEIGHBORS; i++) {
|
|
412
|
+
let max_score = scores[i];
|
|
413
|
+
let max_idx = i;
|
|
414
|
+
|
|
415
|
+
for (let j = i + 1; j < n; j++) {
|
|
416
|
+
if (scores[j] > max_score) {
|
|
417
|
+
max_score = scores[j];
|
|
418
|
+
max_idx = j;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
if (max_idx !== i) {
|
|
423
|
+
const max_order = order[max_idx];
|
|
424
|
+
|
|
425
|
+
for (let k = max_idx; k > i; k--) {
|
|
426
|
+
scores[k] = scores[k - 1];
|
|
427
|
+
order[k] = order[k - 1];
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
scores[i] = max_score;
|
|
431
|
+
order[i] = max_order;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
let hash = 0;
|
|
436
|
+
|
|
437
|
+
for (let i = 0; i < PALETTE_NUM_NEIGHBORS; i++) {
|
|
438
|
+
hash += scores[i] * PALETTE_COLOR_HASH_MULTIPLIERS[i];
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
return hash;
|
|
442
|
+
}
|