@carbonenginejs/runtime-resource 0.13.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/NOTICE +32 -32
- package/README.md +129 -129
- package/dist/CjsMotherLode.js +1271 -1271
- package/dist/CjsResMan.js +3858 -3858
- package/dist/CjsResManFetchProvider.js +94 -94
- package/dist/CjsResManWorkQueue.js +301 -301
- package/dist/_virtual/_rollupPluginBabelHelpers.js +150 -150
- package/dist/format/CjsBlueReader.js +358 -358
- package/dist/format/CjsByteReader.js +310 -310
- package/dist/format/CjsByteWriter.js +242 -242
- package/dist/format/CjsFormat.js +223 -223
- package/dist/format/CjsFormatError.js +41 -41
- package/dist/format/CjsReader.js +22 -22
- package/dist/format/CjsResourceProbe.js +279 -279
- package/dist/format/CjsStringTable.js +268 -268
- package/dist/format/carbonEffect/CjsCarbonEffectReader.js +265 -265
- package/dist/format/carbonEffect/CjsCarbonEffectWriter.js +373 -373
- package/dist/format/carbonEffect/buildCarbonEffectContainer.js +182 -182
- package/dist/format/carbonEffect/carbonEffectBackendBlock.js +321 -321
- package/dist/format/carbonEffect/carbonEffectRecords.js +1147 -1147
- package/dist/format/carbonEffect/carbonEffectResourceTransform.js +197 -197
- package/dist/format/compareUtf8.js +36 -36
- package/dist/format/effect/effectBodyInventory.js +146 -146
- package/dist/format/effect/effectPermutationGraph.js +257 -257
- package/dist/format/effect/sha256.js +114 -114
- package/dist/format/index.js +11 -11
- package/dist/format/payloadContract.js +193 -193
- package/dist/formats/black/CjsBlackFormat.js +310 -310
- package/dist/formats/black/core/CjsBlackBinaryReader.js +260 -260
- package/dist/formats/black/core/CjsBlackPropertyReaders.js +448 -448
- package/dist/formats/black/core/CjsBlackReader.js +764 -764
- package/dist/formats/black/core/CjsBlackSchemaRegistry.js +540 -540
- package/dist/formats/black/core/black-schema-v1-2026-07-23.json.js +4 -4
- package/dist/formats/black/core/blackConstants.js +7 -7
- package/dist/formats/black/core/blackDefinitions.js +10 -10
- package/dist/formats/black/core/blackEnums.js +6 -6
- package/dist/formats/black/core/blackSchema.js +3 -3
- package/dist/formats/black/core/blackVersion.js +22 -22
- package/dist/formats/black/core/helpers.js +199 -199
- package/dist/formats/black/core/schema.js +4 -4
- package/dist/formats/black/index.js +2 -2
- package/dist/formats/bnk/CjsBnkFormat.js +175 -175
- package/dist/formats/bnk/core/busNodes.js +252 -252
- package/dist/formats/bnk/core/effectNodes.js +147 -147
- package/dist/formats/bnk/core/eventAction.js +416 -416
- package/dist/formats/bnk/core/globalSettings.js +215 -215
- package/dist/formats/bnk/core/graph.js +137 -137
- package/dist/formats/bnk/core/helpers.js +512 -512
- package/dist/formats/bnk/core/musicNodes.js +540 -540
- package/dist/formats/bnk/core/nodeBase.js +553 -553
- package/dist/formats/bnk/core/sfxNodes.js +632 -632
- package/dist/formats/bnk/core/soundbanksInfo.js +209 -209
- package/dist/formats/bnk/index.js +2 -2
- package/dist/formats/cmf/CjsCmfFormat.js +497 -497
- package/dist/formats/cmf/core/binary.js +194 -194
- package/dist/formats/cmf/core/buffers.js +237 -237
- package/dist/formats/cmf/core/constants.js +47 -47
- package/dist/formats/cmf/core/gr2Anim.js +453 -453
- package/dist/formats/cmf/core/helpers.js +318 -318
- package/dist/formats/cmf/core/pack.js +276 -276
- package/dist/formats/cmf/core/schema.js +374 -374
- package/dist/formats/cmf/core/shared.js +277 -277
- package/dist/formats/cmf/core/writer.js +571 -571
- package/dist/formats/cmf/index.js +2 -2
- package/dist/formats/dds/CjsDdsFormat.js +200 -200
- package/dist/formats/dds/core/bc6h.js +298 -298
- package/dist/formats/dds/core/bc7.js +272 -272
- package/dist/formats/dds/core/helpers.js +901 -862
- package/dist/formats/dds/core/helpers.js.map +1 -1
- package/dist/formats/dds/index.js +2 -2
- package/dist/formats/dxbc/CjsDxbcFormat.js +187 -142
- package/dist/formats/dxbc/CjsDxbcFormat.js.map +1 -1
- package/dist/formats/dxbc/core/DxbcReader.js +266 -266
- package/dist/formats/dxbc/core/container.js +169 -169
- package/dist/formats/dxbc/core/decoder.js +789 -789
- package/dist/formats/dxbc/core/disassemble.js +240 -0
- package/dist/formats/dxbc/core/disassemble.js.map +1 -0
- package/dist/formats/dxbc/core/errors.js +19 -19
- package/dist/formats/dxbc/core/helpers.js +220 -220
- package/dist/formats/dxbc/core/opcodes.js +45 -45
- package/dist/formats/dxbc/core/program.js +91 -91
- package/dist/formats/dxbc/core/signature.js +172 -172
- package/dist/formats/dxbc/index.js +2 -2
- package/dist/formats/fbx/CjsFbxFormat.js +266 -266
- package/dist/formats/fbx/core/helpers.js +3932 -3932
- package/dist/formats/fbx/index.js +2 -2
- package/dist/formats/flac/CjsFlacFormat.js +142 -142
- package/dist/formats/flac/core/helpers.js +315 -315
- package/dist/formats/flac/index.js +2 -2
- package/dist/formats/gif/CjsGifFormat.js +141 -141
- package/dist/formats/gif/core/helpers.js +380 -380
- package/dist/formats/gif/index.js +2 -2
- package/dist/formats/gltf/CjsGltfFormat.js +252 -290
- package/dist/formats/gltf/CjsGltfFormat.js.map +1 -1
- package/dist/formats/gltf/core/helpers.js +287 -307
- package/dist/formats/gltf/core/helpers.js.map +1 -1
- package/dist/formats/gltf/core/json.js +79 -79
- package/dist/formats/gltf/core/parser.js +679 -679
- package/dist/formats/gltf/core/targets.js +173 -173
- package/dist/formats/gltf/index.js +2 -2
- package/dist/formats/gr2/CjsGr2Format.js +289 -289
- package/dist/formats/gr2/core/bitknit2.js +282 -282
- package/dist/formats/gr2/core/curves.js +1047 -1047
- package/dist/formats/gr2/core/gsf.js +72 -72
- package/dist/formats/gr2/core/helpers.js +352 -352
- package/dist/formats/gr2/core/json.js +622 -622
- package/dist/formats/gr2/core/oodle1.js +388 -388
- package/dist/formats/gr2/core/tangents.js +48 -48
- package/dist/formats/gr2/core/targets.js +361 -361
- package/dist/formats/gr2/index.js +2 -2
- package/dist/formats/hlsl/CjsHlslFormat.js +233 -254
- package/dist/formats/hlsl/CjsHlslFormat.js.map +1 -1
- package/dist/formats/hlsl/core/HlslBinaryUtils.js +15 -15
- package/dist/formats/hlsl/core/HlslEffectReadError.js +19 -19
- package/dist/formats/hlsl/core/HlslEffectStateManager.js +130 -130
- package/dist/formats/hlsl/core/HlslRenderStateSetup.js +37 -37
- package/dist/formats/hlsl/core/HlslResourceSetDescription.js +94 -94
- package/dist/formats/hlsl/core/HlslShaderBytecode.js +44 -44
- package/dist/formats/hlsl/core/analysis.js +51 -51
- package/dist/formats/hlsl/core/carbonDescriptionToRuntime.js +850 -850
- package/dist/formats/hlsl/core/detailMapFamily.js +128 -128
- package/dist/formats/hlsl/core/helpers.js +270 -270
- package/dist/formats/hlsl/core/json.js +284 -284
- package/dist/formats/hlsl/core/localLightFamily.js +133 -133
- package/dist/formats/hlsl/core/metadata.js +327 -327
- package/dist/formats/hlsl/core/render-states.js +280 -280
- package/dist/formats/hlsl/core/tr2/HlslRenderContextEnum.js +43 -43
- package/dist/formats/hlsl/core/tr2/resources/HlslEffectRes.js +320 -320
- package/dist/formats/hlsl/core/tr2/resources/HlslShaderPermutation.js +33 -33
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectBindingManifest.js +423 -416
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectBindingManifest.js.map +1 -1
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectConstant.js +40 -40
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectDescription.js +62 -62
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectLibrary.js +52 -52
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectParameterAnnotation.js +38 -38
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectResource.js +50 -50
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectStageInput.js +86 -86
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectTechnique.js +31 -31
- package/dist/formats/hlsl/core/tr2/shader/HlslPass.js +42 -42
- package/dist/formats/hlsl/core/tr2/shader/HlslSamplerDescription.js +55 -55
- package/dist/formats/hlsl/core/tr2/shader/HlslSamplerSetup.js +29 -29
- package/dist/formats/hlsl/core/tr2/shader/HlslShader.js +220 -220
- package/dist/formats/hlsl/core/tr2/shader/HlslShaderOption.js +30 -30
- package/dist/formats/hlsl/index.js +3 -3
- package/dist/formats/index.js +33 -33
- package/dist/formats/jpeg/CjsJpegFormat.js +212 -212
- package/dist/formats/jpeg/core/helpers.js +402 -402
- package/dist/formats/jpeg/core/jpeg.js +480 -480
- package/dist/formats/jpeg/index.js +2 -2
- package/dist/formats/mp3/CjsMp3Format.js +197 -197
- package/dist/formats/mp3/core/helpers.js +375 -375
- package/dist/formats/mp3/index.js +2 -2
- package/dist/formats/mp4/CjsMp4Format.js +197 -197
- package/dist/formats/mp4/core/helpers.js +484 -484
- package/dist/formats/mp4/index.js +2 -2
- package/dist/formats/obj/CjsObjFormat.js +232 -253
- package/dist/formats/obj/CjsObjFormat.js.map +1 -1
- package/dist/formats/obj/core/helpers.js +553 -573
- package/dist/formats/obj/core/helpers.js.map +1 -1
- package/dist/formats/obj/core/json.js +64 -64
- package/dist/formats/obj/core/parser.js +321 -321
- package/dist/formats/obj/index.js +2 -2
- package/dist/formats/ogg/CjsOggFormat.js +143 -143
- package/dist/formats/ogg/core/helpers.js +410 -410
- package/dist/formats/ogg/core/imdct.js +178 -178
- package/dist/formats/ogg/core/vorbis.js +1017 -1017
- package/dist/formats/ogg/index.js +2 -2
- package/dist/formats/pickle/CjsPickleFormat.js +214 -214
- package/dist/formats/pickle/core/CjsPickleProtocol0Reader.js +551 -551
- package/dist/formats/pickle/index.js +2 -2
- package/dist/formats/png/CjsPngFormat.js +201 -201
- package/dist/formats/png/core/helpers.js +635 -635
- package/dist/formats/png/index.js +2 -2
- package/dist/formats/red/CjsRedFormat.js +263 -263
- package/dist/formats/red/core/CjsRedReader.js +246 -246
- package/dist/formats/red/core/blackDefinitions.js +3 -3
- package/dist/formats/red/core/helpers.js +158 -158
- package/dist/formats/red/core/redGraph.js +71 -71
- package/dist/formats/red/core/schema.js +4 -4
- package/dist/formats/red/index.js +2 -2
- package/dist/formats/stl/CjsStlFormat.js +320 -365
- package/dist/formats/stl/CjsStlFormat.js.map +1 -1
- package/dist/formats/stl/core/helpers.js +241 -261
- package/dist/formats/stl/core/helpers.js.map +1 -1
- package/dist/formats/stl/core/json.js +51 -51
- package/dist/formats/stl/core/stl.js +642 -642
- package/dist/formats/stl/core/targets.js +173 -173
- package/dist/formats/stl/index.js +2 -2
- package/dist/formats/tga/CjsTgaFormat.js +197 -197
- package/dist/formats/tga/core/helpers.js +493 -493
- package/dist/formats/tga/index.js +2 -2
- package/dist/formats/wav/CjsWavFormat.js +198 -198
- package/dist/formats/wav/core/helpers.js +365 -365
- package/dist/formats/wav/index.js +2 -2
- package/dist/formats/webgl/CjsWebglFormat.js +199 -199
- package/dist/formats/webgl/core/buildGlslEffectContainer.js +70 -70
- package/dist/formats/webgl/core/effectPackage.js +900 -900
- package/dist/formats/webgl/core/errors.js +27 -27
- package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js +2820 -2820
- package/dist/formats/webgl/core/glsl/DxbcGlslHelpers.js +89 -89
- package/dist/formats/webgl/core/glsl/DxbcGlslOperandFormatter.js +486 -486
- package/dist/formats/webgl/core/glsl/packedLightFixups.js +98 -98
- package/dist/formats/webgl/core/glslBackendBlock.js +552 -552
- package/dist/formats/webgl/core/glslBackendBodySet.js +243 -243
- package/dist/formats/webgl/core/glslEffectCompleteness.js +85 -85
- package/dist/formats/webgl/core/glslEffectCompleteness.js.map +1 -1
- package/dist/formats/webgl/core/helpers.js +167 -167
- package/dist/formats/webgl/core/inspectGlslEffectContainer.js +122 -122
- package/dist/formats/webgl/core/readGlslEffectContainer.js +202 -256
- package/dist/formats/webgl/core/readGlslEffectContainer.js.map +1 -1
- package/dist/formats/webgl/index.js +2 -2
- package/dist/formats/webgpu/CjsWebgpuFormat.js +357 -357
- package/dist/formats/webgpu/core/buildCarbonEffectContainer.js +89 -89
- package/dist/formats/webgpu/core/carbonWebgpu/CarbonWebgpuContainer.js +354 -354
- package/dist/formats/webgpu/core/carbonWebgpu/containerViews.js +355 -355
- package/dist/formats/webgpu/core/carbonWebgpu/validateContainer.js +90 -90
- package/dist/formats/webgpu/core/effectAnalysis.js +82 -82
- package/dist/formats/webgpu/core/effectBackendBodySet.js +306 -306
- package/dist/formats/webgpu/core/errors.js +20 -20
- package/dist/formats/webgpu/core/helpers.js +443 -443
- package/dist/formats/webgpu/core/ir/analyzeRegisterValues.js +212 -212
- package/dist/formats/webgpu/core/ir/buildControlFlow.js +220 -220
- package/dist/formats/webgpu/core/ir/indexableTemps.js +137 -137
- package/dist/formats/webgpu/core/ir/inferValueTypes.js +449 -449
- package/dist/formats/webgpu/core/ir/lowerDxbcToIr.js +494 -494
- package/dist/formats/webgpu/core/ir/resolveRegisterFlow.js +177 -177
- package/dist/formats/webgpu/core/ir/sourceLanes.js +61 -61
- package/dist/formats/webgpu/core/packageEffect.js +381 -381
- package/dist/formats/webgpu/core/packageEffectSelection.js +164 -164
- package/dist/formats/webgpu/core/packageMetadata.js +17 -17
- package/dist/formats/webgpu/core/schema.js +4 -4
- package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js +263 -263
- package/dist/formats/webgpu/core/wgsl/buildWgslBindingPlan.js +172 -172
- package/dist/formats/webgpu/core/wgsl/buildWgslSet.js +325 -325
- package/dist/formats/webgpu/core/wgsl/emitWgsl.js +356 -356
- package/dist/formats/webgpu/core/wgsl/hoistEscapingValues.js +77 -77
- package/dist/formats/webgpu/core/wgsl/lowerBindingLayout.js +451 -451
- package/dist/formats/webgpu/core/wgsl/lowerComputeProgram.js +735 -735
- package/dist/formats/webgpu/core/wgsl/lowerCreateHistogramsComputeProgram.js +457 -457
- package/dist/formats/webgpu/core/wgsl/lowerFragmentProgram.js +1572 -1572
- package/dist/formats/webgpu/core/wgsl/lowerMergeHistogramsComputeProgram.js +659 -659
- package/dist/formats/webgpu/core/wgsl/lowerParticleClearComputePrograms.js +734 -734
- package/dist/formats/webgpu/core/wgsl/lowerParticleEmitComputeProgram.js +583 -583
- package/dist/formats/webgpu/core/wgsl/lowerSkinVerticesComputeProgram.js +621 -621
- package/dist/formats/webgpu/core/wgsl/lowerSortComputeProgram.js +824 -824
- package/dist/formats/webgpu/core/wgsl/lowerSortInnerComputeProgram.js +697 -697
- package/dist/formats/webgpu/core/wgsl/lowerSortStepComputeProgram.js +559 -559
- package/dist/formats/webgpu/core/wgsl/lowerVertexProgram.js +1328 -1328
- package/dist/formats/webgpu/core/wgsl/particleEmitSemanticDigest.js +110 -110
- package/dist/formats/webgpu/core/wgsl/precisionControls.js +55 -55
- package/dist/formats/webgpu/core/wgsl/selectionPlans.js +717 -717
- package/dist/formats/webgpu/core/wgsl/uniformity.js +78 -78
- package/dist/formats/webgpu/core/wgsl/validateExactComputeIr.js +196 -196
- package/dist/formats/webgpu/core/wgsl/validateHandleOperand.js +37 -37
- package/dist/formats/webgpu/index.js +2 -2
- package/dist/formats/webm/CjsWebmFormat.js +197 -197
- package/dist/formats/webm/core/helpers.js +572 -572
- package/dist/formats/webm/index.js +2 -2
- package/dist/formats/webp/CjsWebpFormat.js +140 -140
- package/dist/formats/webp/core/helpers.js +237 -237
- package/dist/formats/webp/index.js +2 -2
- package/dist/formats/wem/CjsWemFormat.js +250 -250
- package/dist/formats/wem/core/bitStream.js +261 -261
- package/dist/formats/wem/core/codebookLibrary.js +164 -164
- package/dist/formats/wem/core/helpers.js +437 -437
- package/dist/formats/wem/core/packedCodebooksAotuv603.js +30 -30
- package/dist/formats/wem/core/ptadpcm.js +77 -77
- package/dist/formats/wem/core/resolve.js +121 -121
- package/dist/formats/wem/core/wemToOgg.js +485 -485
- package/dist/formats/wem/index.js +2 -2
- package/dist/formats/yaml/CjsYamlFormat.js +134 -134
- package/dist/formats/yaml/core/CjsYamlReader.js +400 -400
- package/dist/formats/yaml/core/helpers.js +196 -196
- package/dist/formats/yaml/index.js +2 -2
- package/dist/index.js +64 -64
- package/dist/resource/CjsLoadingObject.js +19 -19
- package/dist/resource/CjsResource.js +801 -801
- package/dist/resource/ResourceHandlerMode.js +14 -14
- package/dist/resource/Tr2LightProfileRes.js +32 -32
- package/dist/resource/audio/AudioGeometryResData.js +47 -47
- package/dist/resource/audio/CjsAudioBufferRes.js +86 -86
- package/dist/resource/audio/CjsAudioRes.js +213 -213
- package/dist/resource/audio/index.js +4 -4
- package/dist/resource/geometry/MeshDecalData.js +37 -37
- package/dist/resource/geometry/MeshDecalLodData.js +34 -34
- package/dist/resource/geometry/TriGeometryRes.js +570 -467
- package/dist/resource/geometry/TriGeometryRes.js.map +1 -1
- package/dist/resource/geometry/TriGeometryResAreaData.js +59 -59
- package/dist/resource/geometry/TriGeometryResJointData.js +38 -38
- package/dist/resource/geometry/TriGeometryResLodData.js +88 -88
- package/dist/resource/geometry/TriGeometryResMeshData.js +63 -63
- package/dist/resource/geometry/TriGeometryResSkeletonData.js +34 -34
- package/dist/resource/geometry/TriJointBinding.js +38 -38
- package/dist/resource/geometry/TriMorphTargetGeometryConstants.js +46 -46
- package/dist/resource/geometry/TriRtGeometryConstants.js +88 -88
- package/dist/resource/geometry/granny/GStateBindingCallbackData.js +31 -31
- package/dist/resource/geometry/granny/Tr2GrannyIntersectionResult.js +60 -60
- package/dist/resource/geometry/granny/Tr2GrannyStateRes.js +36 -36
- package/dist/resource/geometry/granny/TriGrannyRes.js +35 -35
- package/dist/resource/geometry/granny/enums.js +10 -10
- package/dist/resource/geometry/granny/index.js +6 -6
- package/dist/resource/geometry/index.js +17 -17
- package/dist/resource/index.js +54 -54
- package/dist/resource/resourceBoundary.js +64 -64
- package/dist/resource/shader/Tr2EffectRes.js +336 -336
- package/dist/resource/shader/Tr2MaterialArea.js +31 -31
- package/dist/resource/shader/Tr2MaterialMesh.js +27 -27
- package/dist/resource/shader/Tr2MaterialRes.js +31 -31
- package/dist/resource/shader/Tr2Shader.js +283 -283
- package/dist/resource/shader/Tr2ShaderPermutation.js +43 -43
- package/dist/resource/shader/index.js +17 -17
- package/dist/resource/shader/reflection/Tr2EffectConstant.js +143 -143
- package/dist/resource/shader/reflection/Tr2EffectDefine.js +30 -30
- package/dist/resource/shader/reflection/Tr2EffectDescription.js +114 -114
- package/dist/resource/shader/reflection/Tr2EffectLibrary.js +168 -168
- package/dist/resource/shader/reflection/Tr2EffectParameterAnnotation.js +125 -125
- package/dist/resource/shader/reflection/Tr2EffectResource.js +120 -120
- package/dist/resource/shader/reflection/Tr2EffectStageInput.js +372 -372
- package/dist/resource/shader/reflection/Tr2EffectTechnique.js +78 -78
- package/dist/resource/shader/reflection/Tr2Pass.js +168 -168
- package/dist/resource/shader/reflection/carbonRecordFields.js +159 -159
- package/dist/resource/shader/reflection/shaderStage.js +22 -22
- package/dist/resource/shader/sampler/Tr2SamplerSetup.js +135 -135
- package/dist/resource/texture/CjsTextureArrayRes.js +472 -472
- package/dist/resource/texture/CjsTextureArrayResParameterProxy.js +179 -179
- package/dist/resource/texture/Tr2ImageRes.js +120 -120
- package/dist/resource/texture/Tr2TextureLodManager.js +82 -82
- package/dist/resource/texture/Tr2TextureLodUpdateRequest.js +37 -37
- package/dist/resource/texture/Tr2TexturePackChannel.js +37 -37
- package/dist/resource/texture/Tr2TexturePipeline.js +54 -54
- package/dist/resource/texture/Tr2TexturePipelineParams.js +34 -34
- package/dist/resource/texture/Tr2TexturePipelineStepCompress.js +40 -40
- package/dist/resource/texture/Tr2TexturePipelineStepGenerateMips.js +22 -22
- package/dist/resource/texture/Tr2TexturePipelineStepLimitSize.js +34 -34
- package/dist/resource/texture/Tr2TexturePipelineStepLoad.js +31 -31
- package/dist/resource/texture/Tr2TexturePipelineStepPack.js +43 -43
- package/dist/resource/texture/TriTextureRes.js +359 -359
- package/dist/resource/texture/index.js +15 -15
- package/dist/resource/texture/texturePipelineBehavior.js +308 -308
- package/dist/worker/CjsResManMainThreadLoader.js +89 -89
- package/dist/worker/CjsResManWorker.js +218 -218
- package/dist/worker/CjsResManWorkerLoader.js +437 -437
- package/dist/worker/protocol.js +12 -12
- package/docs/README.md +98 -98
- package/docs/architecture.md +118 -118
- package/docs/concepts/resource-lifecycle.md +226 -226
- package/docs/concepts/shader-resource-model.md +111 -111
- package/docs/concepts/writing-an-engine-adapter.md +115 -115
- package/docs/formats/README.md +138 -138
- package/docs/formats/carbon-effect-container.md +553 -553
- package/docs/formats/dxbc/README.md +68 -68
- package/docs/formats/dxbc/architecture.md +80 -80
- package/docs/formats/dxbc/reference/api.md +105 -77
- package/docs/formats/dxbc/reference/classes/README.md +9 -9
- package/docs/formats/dxbc/reference/decoded-output.md +122 -122
- package/docs/formats/gr2.md +160 -160
- package/docs/formats/hlsl/README.md +54 -54
- package/docs/formats/hlsl/architecture.md +66 -65
- package/docs/formats/hlsl/guides/hydrating-json-output.md +60 -60
- package/docs/formats/hlsl/guides/reading-effects.md +68 -64
- package/docs/formats/hlsl/reference/advanced-analysis.md +61 -61
- package/docs/formats/hlsl/reference/api.md +91 -92
- package/docs/formats/hlsl/reference/classes/README.md +11 -11
- package/docs/formats/hlsl/reference/json-graph.md +97 -97
- package/docs/formats/pickle.md +82 -82
- package/docs/formats/provenance.md +196 -196
- package/docs/formats/stl.md +37 -37
- package/docs/formats/webgl/README.md +115 -115
- package/docs/formats/webgl/architecture.md +69 -69
- package/docs/formats/webgl/carbon-constant-layouts.md +326 -326
- package/docs/formats/webgl/decl-io.md +1234 -1234
- package/docs/formats/webgl/memory-structured.md +890 -890
- package/docs/formats/webgl/reference/classes/README.md +9 -9
- package/docs/formats/webgl/texture-sample.md +964 -964
- package/docs/formats/webgpu/README.md +84 -84
- package/docs/formats/webgpu/architecture.md +95 -95
- package/docs/formats/webgpu/formats/carbon-webgpu.md +215 -215
- package/docs/formats/webgpu/guides/effect-packaging.md +189 -189
- package/docs/formats/webgpu/reference/api.md +196 -196
- package/docs/formats/webgpu/reference/classes/README.md +9 -9
- package/docs/formats/webgpu/reference/wgsl-compatibility.md +1546 -1546
- package/docs/formats/wwise.md +146 -146
- package/docs/reference/classes/README.md +35 -35
- package/docs/reference/classes/audio.md +30 -30
- package/docs/reference/classes/core.md +216 -216
- package/docs/reference/classes/dropped.md +46 -46
- package/docs/reference/classes/formats.md +944 -944
- package/docs/reference/classes/resources.md +456 -456
- package/docs/reference/classes/texture.md +26 -26
- package/docs/reference/events.md +117 -117
- package/docs/reference/motherlode-cache.md +275 -275
- package/docs/reference/queues.md +194 -194
- package/docs/reference/reload.md +107 -107
- package/docs/reference/texture-arrays.md +113 -113
- package/docs/reference/texture-pipeline.md +53 -53
- package/docs/reference/workers.md +142 -142
- package/docs/roadmap.md +150 -150
- package/format-notices/black/LICENSE +21 -21
- package/format-notices/black/NOTICE +47 -47
- package/format-notices/bnk/LICENSE +21 -21
- package/format-notices/bnk/NOTICE +21 -21
- package/format-notices/cmf/LICENSE +21 -21
- package/format-notices/cmf/NOTICE +36 -36
- package/format-notices/dds/LICENSE +21 -21
- package/format-notices/dds/NOTICE +14 -14
- package/format-notices/dxbc/LICENSE +21 -21
- package/format-notices/dxbc/NOTICE +20 -20
- package/format-notices/fbx/LICENSE +21 -21
- package/format-notices/fbx/NOTICE +14 -14
- package/format-notices/flac/LICENSE +21 -21
- package/format-notices/flac/NOTICE +14 -14
- package/format-notices/gif/LICENSE +21 -21
- package/format-notices/gif/NOTICE +14 -14
- package/format-notices/gltf/LICENSE +21 -21
- package/format-notices/gltf/NOTICE +27 -27
- package/format-notices/gr2/LICENSE +21 -21
- package/format-notices/gr2/NOTICE +60 -60
- package/format-notices/gr2/THIRD-PARTY-NOTICES.md +93 -93
- package/format-notices/hlsl/LICENSE +21 -21
- package/format-notices/hlsl/NOTICE +25 -25
- package/format-notices/jpeg/LICENSE +21 -21
- package/format-notices/jpeg/NOTICE +14 -14
- package/format-notices/mp3/LICENSE +21 -21
- package/format-notices/mp3/NOTICE +14 -14
- package/format-notices/mp4/LICENSE +21 -21
- package/format-notices/mp4/NOTICE +14 -14
- package/format-notices/obj/LICENSE +21 -21
- package/format-notices/obj/NOTICE +26 -26
- package/format-notices/ogg/LICENSE +21 -21
- package/format-notices/ogg/NOTICE +28 -28
- package/format-notices/png/LICENSE +21 -21
- package/format-notices/png/NOTICE +14 -14
- package/format-notices/red/LICENSE +21 -21
- package/format-notices/red/NOTICE +31 -31
- package/format-notices/stl/LICENSE +21 -21
- package/format-notices/stl/NOTICE +21 -21
- package/format-notices/tga/LICENSE +21 -21
- package/format-notices/tga/NOTICE +14 -14
- package/format-notices/wav/LICENSE +21 -21
- package/format-notices/wav/NOTICE +14 -14
- package/format-notices/webgl/LICENSE +21 -21
- package/format-notices/webgl/NOTICE +35 -35
- package/format-notices/webgpu/LICENSE +21 -21
- package/format-notices/webgpu/NOTICE +31 -31
- package/format-notices/webm/LICENSE +21 -21
- package/format-notices/webm/NOTICE +14 -14
- package/format-notices/webp/LICENSE +21 -21
- package/format-notices/webp/NOTICE +14 -14
- package/format-notices/wem/LICENSE +57 -57
- package/format-notices/wem/NOTICE +33 -33
- package/format-notices/yaml/LICENSE +21 -21
- package/format-notices/yaml/NOTICE +44 -44
- package/package.json +63 -63
|
@@ -1,388 +1,388 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Granny Oodle1 section decompressor.
|
|
3
|
-
*
|
|
4
|
-
* Ported from nwn2mdk gr2_decompress.cpp (Boost licence), derived from
|
|
5
|
-
* berenm/xoreos-tools granny-decoder, and cross-checked against opengr2. The
|
|
6
|
-
* codec uses an adaptive arithmetic coder over a 7-bit-per-byte stream, drives
|
|
7
|
-
* adaptive frequency windows, and emits an LZ token stream. Sections decode in
|
|
8
|
-
* up to three consecutive segments with fresh dictionaries sharing one bitstream.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
/** Large back-reference sizes selected by Oodle1 size codes 61..64. */
|
|
12
|
-
const OODLE1_BACKREF_SIZES = Object.freeze([128, 192, 256, 512]);
|
|
13
|
-
|
|
14
|
-
/** Number of bytes occupied by the three Oodle1 parameter blocks. */
|
|
15
|
-
const OODLE1_PARAMETER_BYTES = 36;
|
|
16
|
-
|
|
17
|
-
/** Extra bytes appended to the arithmetic stream for decoder lookahead safety. */
|
|
18
|
-
const OODLE1_STREAM_PADDING = 8;
|
|
19
|
-
|
|
20
|
-
/** Extra output bytes reserved because final Oodle1 back-references may overshoot. */
|
|
21
|
-
const OODLE1_OUTPUT_SLACK = 512;
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Arithmetic decoder for the Oodle1 7-bit-per-byte bitstream.
|
|
25
|
-
*/
|
|
26
|
-
class Decoder {
|
|
27
|
-
/**
|
|
28
|
-
* Create an arithmetic decoder over a padded compressed stream.
|
|
29
|
-
*
|
|
30
|
-
* @param {Uint8Array} stream Compressed payload after the parameter header.
|
|
31
|
-
*/
|
|
32
|
-
constructor(stream) {
|
|
33
|
-
this.stream = stream;
|
|
34
|
-
this.pos = 0;
|
|
35
|
-
this.numer = stream[0] >> 1;
|
|
36
|
-
this.denom = 0x80;
|
|
37
|
-
this.nextDenom = 0;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Decode a cumulative value in the range [0, max).
|
|
42
|
-
*
|
|
43
|
-
* @param {number} max Exclusive upper bound for the decoded value.
|
|
44
|
-
* @returns {number} Arithmetic-coded cumulative value.
|
|
45
|
-
*/
|
|
46
|
-
decode(max) {
|
|
47
|
-
while (this.denom <= 0x800000) {
|
|
48
|
-
this.denom = this.denom << 8 >>> 0;
|
|
49
|
-
this.numer = (this.numer << 8 | this.stream[this.pos] << 7 & 0x80 | this.stream[this.pos + 1] >> 1 & 0x7f) >>> 0;
|
|
50
|
-
this.pos++;
|
|
51
|
-
}
|
|
52
|
-
this.nextDenom = Math.floor(this.denom / max);
|
|
53
|
-
return Math.min(Math.floor(this.numer / this.nextDenom), max - 1);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Commit a decoded range and shrink the arithmetic interval.
|
|
58
|
-
*
|
|
59
|
-
* @param {number} max Original range size.
|
|
60
|
-
* @param {number} val Range start to commit.
|
|
61
|
-
* @param {number} err Range width to commit.
|
|
62
|
-
* @returns {number} The committed value.
|
|
63
|
-
*/
|
|
64
|
-
commit(max, val, err) {
|
|
65
|
-
this.numer -= this.nextDenom * val;
|
|
66
|
-
if (val + err < max) this.denom = this.nextDenom * err;else this.denom -= this.nextDenom * val;
|
|
67
|
-
return val;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Decode and immediately commit a single-value range.
|
|
72
|
-
*
|
|
73
|
-
* @param {number} max Exclusive upper bound for the decoded value.
|
|
74
|
-
* @returns {number} Decoded value.
|
|
75
|
-
*/
|
|
76
|
-
decodeCommit(max) {
|
|
77
|
-
return this.commit(max, this.decode(max), 1);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Adaptive weighted symbol window used by Oodle1 dictionaries.
|
|
83
|
-
*/
|
|
84
|
-
class WeighWindow {
|
|
85
|
-
/**
|
|
86
|
-
* Create an adaptive window for values up to a maximum symbol.
|
|
87
|
-
*
|
|
88
|
-
* @param {number} maxValue Maximum symbol value represented by the window.
|
|
89
|
-
* @param {number} countCap Maximum number of weighted entries to retain.
|
|
90
|
-
*/
|
|
91
|
-
constructor(maxValue, countCap) {
|
|
92
|
-
this.weightTotal = 4;
|
|
93
|
-
this.countCap = countCap + 1 & 0xffff;
|
|
94
|
-
this.ranges = [0, 0x4000];
|
|
95
|
-
this.weights = [4];
|
|
96
|
-
this.values = [0];
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Reusable result carrier for {@link WeighWindow#tryDecode}, owned by
|
|
100
|
-
* this instance so repeated decode calls don't allocate a fresh object
|
|
101
|
-
* per symbol (the hottest allocation site in this decoder). Safe to
|
|
102
|
-
* reuse across calls: each result is fully consumed (read, and any
|
|
103
|
-
* `storeValue` follow-up applied) before this same instance's next
|
|
104
|
-
* `tryDecode` call, and every `decompressBlock` call site that needs
|
|
105
|
-
* more than one decoded value at once (`d3`/`d4`/`d5`) always reads
|
|
106
|
-
* from three distinct `WeighWindow` instances, never this one twice.
|
|
107
|
-
*/
|
|
108
|
-
this.result = {
|
|
109
|
-
newIndex: -1,
|
|
110
|
-
value: 0
|
|
111
|
-
};
|
|
112
|
-
this.threshIncrease = 4;
|
|
113
|
-
this.threshRangeRebuild = 8;
|
|
114
|
-
this.threshWeightRebuild = Math.max(256, Math.min(32 * maxValue, 15160));
|
|
115
|
-
this.threshIncreaseCap = maxValue > 64 ? Math.min(2 * maxValue, (this.threshWeightRebuild >> 1) - 32) : 128;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Recompute arithmetic ranges from the current symbol weights.
|
|
120
|
-
*
|
|
121
|
-
* @returns {void}
|
|
122
|
-
*/
|
|
123
|
-
rebuildRanges() {
|
|
124
|
-
const w = this.weights;
|
|
125
|
-
this.ranges.length = w.length + 1;
|
|
126
|
-
const rangeWeight = Math.floor(8 * 0x4000 / this.weightTotal);
|
|
127
|
-
let start = 0;
|
|
128
|
-
for (let i = 0; i < w.length; i++) {
|
|
129
|
-
this.ranges[i] = start;
|
|
130
|
-
start += Math.floor(w[i] * rangeWeight / 8);
|
|
131
|
-
}
|
|
132
|
-
this.ranges[w.length] = 0x4000;
|
|
133
|
-
if (this.threshIncrease > this.threshIncreaseCap >> 1) {
|
|
134
|
-
this.threshRangeRebuild = this.weightTotal + this.threshIncreaseCap;
|
|
135
|
-
} else {
|
|
136
|
-
this.threshIncrease *= 2;
|
|
137
|
-
this.threshRangeRebuild = this.weightTotal + this.threshIncrease;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Decay, compact, and reorder adaptive weights when the table grows stale.
|
|
143
|
-
*
|
|
144
|
-
* @returns {void}
|
|
145
|
-
*/
|
|
146
|
-
rebuildWeights() {
|
|
147
|
-
const w = this.weights,
|
|
148
|
-
v = this.values;
|
|
149
|
-
let total = 0;
|
|
150
|
-
for (let i = 0; i < w.length; i++) {
|
|
151
|
-
w[i] >>= 1;
|
|
152
|
-
total += w[i];
|
|
153
|
-
}
|
|
154
|
-
this.weightTotal = total;
|
|
155
|
-
for (let i = 1; i < w.length; i++) {
|
|
156
|
-
while (i < w.length && w[i] === 0) {
|
|
157
|
-
w[i] = w[w.length - 1];
|
|
158
|
-
w.pop();
|
|
159
|
-
v[i] = v[v.length - 1];
|
|
160
|
-
v.pop();
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
if (w.length > 1) {
|
|
164
|
-
let mi = 1,
|
|
165
|
-
mw = 0;
|
|
166
|
-
for (let i = 1; i < w.length; i++) {
|
|
167
|
-
if (w[i] > mw) {
|
|
168
|
-
mw = w[i];
|
|
169
|
-
mi = i;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
const l = w.length - 1;
|
|
173
|
-
[w[mi], w[l]] = [w[l], w[mi]];
|
|
174
|
-
[v[mi], v[l]] = [v[l], v[mi]];
|
|
175
|
-
}
|
|
176
|
-
if (w.length < this.countCap && w[0] === 0) {
|
|
177
|
-
w[0] = 1;
|
|
178
|
-
this.weightTotal++;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Decode a symbol through this adaptive window.
|
|
184
|
-
*
|
|
185
|
-
* When `newIndex` is non-negative, the caller must decode and store a
|
|
186
|
-
* fresh literal value with {@link WeighWindow#storeValue}. Otherwise `value`
|
|
187
|
-
* is final.
|
|
188
|
-
*
|
|
189
|
-
* @param {Decoder} dec Arithmetic decoder to read from.
|
|
190
|
-
* @returns {{newIndex: number, value: number}} Decoded value or slot requiring a fresh literal.
|
|
191
|
-
*/
|
|
192
|
-
tryDecode(dec) {
|
|
193
|
-
if (this.weightTotal >= this.threshRangeRebuild) {
|
|
194
|
-
if (this.threshRangeRebuild >= this.threshWeightRebuild) this.rebuildWeights();
|
|
195
|
-
this.rebuildRanges();
|
|
196
|
-
}
|
|
197
|
-
const value = dec.decode(0x4000),
|
|
198
|
-
r = this.ranges;
|
|
199
|
-
let lo = 0,
|
|
200
|
-
hi = r.length;
|
|
201
|
-
while (lo < hi) {
|
|
202
|
-
const mid = lo + hi >> 1;
|
|
203
|
-
if (r[mid] <= value) lo = mid + 1;else hi = mid;
|
|
204
|
-
}
|
|
205
|
-
const index = lo - 1;
|
|
206
|
-
dec.commit(0x4000, r[index], r[index + 1] - r[index]);
|
|
207
|
-
this.weights[index]++;
|
|
208
|
-
this.weightTotal++;
|
|
209
|
-
const result = this.result;
|
|
210
|
-
if (index > 0) {
|
|
211
|
-
result.newIndex = -1;
|
|
212
|
-
result.value = this.values[index];
|
|
213
|
-
return result;
|
|
214
|
-
}
|
|
215
|
-
if (this.weights.length >= this.ranges.length && dec.decodeCommit(2) === 1) {
|
|
216
|
-
const i = this.ranges.length + dec.decodeCommit(this.weights.length - this.ranges.length + 1) - 1;
|
|
217
|
-
this.weights[i] += 2;
|
|
218
|
-
this.weightTotal += 2;
|
|
219
|
-
result.newIndex = -1;
|
|
220
|
-
result.value = this.values[i];
|
|
221
|
-
return result;
|
|
222
|
-
}
|
|
223
|
-
this.values.push(0);
|
|
224
|
-
this.weights.push(2);
|
|
225
|
-
this.weightTotal += 2;
|
|
226
|
-
if (this.weights.length === this.countCap) {
|
|
227
|
-
this.weightTotal -= this.weights[0];
|
|
228
|
-
this.weights[0] = 0;
|
|
229
|
-
}
|
|
230
|
-
result.newIndex = this.values.length - 1;
|
|
231
|
-
result.value = 0;
|
|
232
|
-
return result;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* Store a freshly decoded escape value in an adaptive window slot.
|
|
237
|
-
*
|
|
238
|
-
* @param {number} index Slot index returned by {@link WeighWindow#tryDecode}.
|
|
239
|
-
* @param {number} value Value to store.
|
|
240
|
-
* @returns {number} Stored value.
|
|
241
|
-
*/
|
|
242
|
-
storeValue(index, value) {
|
|
243
|
-
this.values[index] = value;
|
|
244
|
-
return value;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
const BACKREF_SIZES = OODLE1_BACKREF_SIZES;
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Per-segment Oodle1 dictionary and adaptive symbol windows.
|
|
251
|
-
*/
|
|
252
|
-
class Dictionary {
|
|
253
|
-
/**
|
|
254
|
-
* Create a dictionary from one decoded Oodle1 parameter block.
|
|
255
|
-
*
|
|
256
|
-
* @param {{decodedValueMax: number, backrefValueMax: number, decodedCount: number, highbitCount: number, sizesCount: number[]}} p Parameter block.
|
|
257
|
-
*/
|
|
258
|
-
constructor(p) {
|
|
259
|
-
this.decodedSize = 0;
|
|
260
|
-
this.backrefSize = 0;
|
|
261
|
-
this.decodedValueMax = p.decodedValueMax;
|
|
262
|
-
this.backrefValueMax = p.backrefValueMax;
|
|
263
|
-
this.lowbitValueMax = Math.min(p.backrefValueMax + 1, 4);
|
|
264
|
-
this.midbitValueMax = Math.min(Math.floor(p.backrefValueMax / 4) + 1, 256);
|
|
265
|
-
this.highbitValueMax = Math.floor(p.backrefValueMax / 1024) + 1;
|
|
266
|
-
this.lowbitWindow = new WeighWindow(this.lowbitValueMax - 1, this.lowbitValueMax);
|
|
267
|
-
this.highbitWindow = new WeighWindow(this.highbitValueMax - 1, p.highbitCount + 1);
|
|
268
|
-
this.midbitWindows = [];
|
|
269
|
-
for (let i = 0; i < this.highbitValueMax; i++) {
|
|
270
|
-
this.midbitWindows.push(new WeighWindow(this.midbitValueMax - 1, this.midbitValueMax));
|
|
271
|
-
}
|
|
272
|
-
this.decodedWindows = [];
|
|
273
|
-
for (let i = 0; i < 4; i++) {
|
|
274
|
-
this.decodedWindows.push(new WeighWindow(this.decodedValueMax - 1, p.decodedCount));
|
|
275
|
-
}
|
|
276
|
-
this.sizeWindows = [];
|
|
277
|
-
for (let i = 0; i < 4; i++) {
|
|
278
|
-
for (let j = 0; j < 16; j++) {
|
|
279
|
-
this.sizeWindows.push(new WeighWindow(64, p.sizesCount[3 - i]));
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
this.sizeWindows.push(new WeighWindow(64, p.sizesCount[0]));
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
/**
|
|
286
|
-
* Decode one literal or back-reference block into the output buffer.
|
|
287
|
-
*
|
|
288
|
-
* Back-references use byte-by-byte overlapping copies so offsets smaller than
|
|
289
|
-
* the copy length behave like the original LZ stream.
|
|
290
|
-
*
|
|
291
|
-
* @param {Decoder} dec Arithmetic decoder shared across all segments.
|
|
292
|
-
* @param {Uint8Array} out Output buffer with slack for overshoot copies.
|
|
293
|
-
* @param {number} pos Current output write offset.
|
|
294
|
-
* @returns {number} Number of bytes produced.
|
|
295
|
-
*/
|
|
296
|
-
decompressBlock(dec, out, pos) {
|
|
297
|
-
const sw = this.sizeWindows[this.backrefSize];
|
|
298
|
-
let d1 = sw.tryDecode(dec);
|
|
299
|
-
if (d1.newIndex >= 0) d1.value = sw.storeValue(d1.newIndex, dec.decodeCommit(65));
|
|
300
|
-
this.backrefSize = d1.value;
|
|
301
|
-
if (this.backrefSize > 0) {
|
|
302
|
-
const size = this.backrefSize < 61 ? this.backrefSize + 1 : BACKREF_SIZES[this.backrefSize - 61],
|
|
303
|
-
range = Math.min(this.backrefValueMax, this.decodedSize);
|
|
304
|
-
let d3 = this.lowbitWindow.tryDecode(dec);
|
|
305
|
-
if (d3.newIndex >= 0) d3.value = this.lowbitWindow.storeValue(d3.newIndex, dec.decodeCommit(this.lowbitValueMax));
|
|
306
|
-
let d4 = this.highbitWindow.tryDecode(dec);
|
|
307
|
-
if (d4.newIndex >= 0) d4.value = this.highbitWindow.storeValue(d4.newIndex, dec.decodeCommit(Math.floor(range / 1024) + 1));
|
|
308
|
-
const mw = this.midbitWindows[d4.value];
|
|
309
|
-
let d5 = mw.tryDecode(dec);
|
|
310
|
-
if (d5.newIndex >= 0) d5.value = mw.storeValue(d5.newIndex, dec.decodeCommit(Math.min(Math.floor(range / 4) + 1, 256)));
|
|
311
|
-
const offset = (d4.value << 10) + (d5.value << 2) + d3.value + 1;
|
|
312
|
-
this.decodedSize += size;
|
|
313
|
-
let src = pos - offset;
|
|
314
|
-
for (let i = 0; i < size; i++) {
|
|
315
|
-
out[pos + i] = out[src + i];
|
|
316
|
-
}
|
|
317
|
-
return size;
|
|
318
|
-
} else {
|
|
319
|
-
const dw = this.decodedWindows[pos & 3];
|
|
320
|
-
let d2 = dw.tryDecode(dec);
|
|
321
|
-
if (d2.newIndex >= 0) d2.value = dw.storeValue(d2.newIndex, dec.decodeCommit(this.decodedValueMax));
|
|
322
|
-
out[pos] = d2.value & 0xff;
|
|
323
|
-
this.decodedSize++;
|
|
324
|
-
return 1;
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
/**
|
|
330
|
-
* Read the three Oodle1 parameter blocks from the compressed section header.
|
|
331
|
-
*
|
|
332
|
-
* Each block is a 12-byte little-endian C bitfield record.
|
|
333
|
-
*
|
|
334
|
-
* @param {Uint8Array} bytes Compressed Oodle1 section bytes.
|
|
335
|
-
* @returns {{decodedValueMax: number, backrefValueMax: number, decodedCount: number, highbitCount: number, sizesCount: number[]}[]} Parsed parameter blocks.
|
|
336
|
-
*/
|
|
337
|
-
function readOodle1Parameters(bytes) {
|
|
338
|
-
const dv = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength),
|
|
339
|
-
params = [];
|
|
340
|
-
for (let i = 0; i < 3; i++) {
|
|
341
|
-
const b = i * 12,
|
|
342
|
-
a = dv.getUint32(b, true),
|
|
343
|
-
c = dv.getUint32(b + 4, true);
|
|
344
|
-
params.push({
|
|
345
|
-
decodedValueMax: a & 0x1ff,
|
|
346
|
-
backrefValueMax: a >>> 9,
|
|
347
|
-
decodedCount: c & 0x1ff,
|
|
348
|
-
highbitCount: c >>> 19 & 0x1fff,
|
|
349
|
-
sizesCount: [bytes[b + 8], bytes[b + 9], bytes[b + 10], bytes[b + 11]]
|
|
350
|
-
});
|
|
351
|
-
}
|
|
352
|
-
return params;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
/**
|
|
356
|
-
* Decompress a Granny Oodle1 (section format 2) block.
|
|
357
|
-
*
|
|
358
|
-
* The compressed stream is padded so the arithmetic decoder's one-byte lookahead
|
|
359
|
-
* never reads out of bounds. Output is allocated with slack because a final
|
|
360
|
-
* back-reference may overshoot before the returned view is trimmed.
|
|
361
|
-
*
|
|
362
|
-
* @param {Uint8Array} bytes Compressed section bytes.
|
|
363
|
-
* @param {number} expandedSize Decompressed byte length.
|
|
364
|
-
* @param {{first16:number, first8:number}} stops Segment stop offsets from the section directory.
|
|
365
|
-
* @returns {Uint8Array} Exactly `expandedSize` bytes.
|
|
366
|
-
*/
|
|
367
|
-
function decompressOodle1(bytes, expandedSize, {
|
|
368
|
-
first16,
|
|
369
|
-
first8
|
|
370
|
-
}) {
|
|
371
|
-
const out = new Uint8Array(expandedSize + OODLE1_OUTPUT_SLACK);
|
|
372
|
-
if (bytes.length === 0 || expandedSize === 0) return out.subarray(0, expandedSize);
|
|
373
|
-
if (bytes.length < OODLE1_PARAMETER_BYTES) throw new Error("Oodle1 block too small for parameter header");
|
|
374
|
-
const params = readOodle1Parameters(bytes);
|
|
375
|
-
const stream = new Uint8Array(bytes.length - OODLE1_PARAMETER_BYTES + OODLE1_STREAM_PADDING);
|
|
376
|
-
stream.set(bytes.subarray(OODLE1_PARAMETER_BYTES));
|
|
377
|
-
const dec = new Decoder(stream);
|
|
378
|
-
const steps = [first16, first8, expandedSize];
|
|
379
|
-
let pos = 0;
|
|
380
|
-
for (let s = 0; s < 3; s++) {
|
|
381
|
-
const dict = new Dictionary(params[s]);
|
|
382
|
-
while (pos < steps[s]) pos += dict.decompressBlock(dec, out, pos);
|
|
383
|
-
}
|
|
384
|
-
return expandedSize === out.length ? out : out.subarray(0, expandedSize);
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
export { OODLE1_BACKREF_SIZES, OODLE1_OUTPUT_SLACK, OODLE1_PARAMETER_BYTES, OODLE1_STREAM_PADDING, decompressOodle1, readOodle1Parameters };
|
|
388
|
-
//# sourceMappingURL=oodle1.js.map
|
|
1
|
+
/**
|
|
2
|
+
* Granny Oodle1 section decompressor.
|
|
3
|
+
*
|
|
4
|
+
* Ported from nwn2mdk gr2_decompress.cpp (Boost licence), derived from
|
|
5
|
+
* berenm/xoreos-tools granny-decoder, and cross-checked against opengr2. The
|
|
6
|
+
* codec uses an adaptive arithmetic coder over a 7-bit-per-byte stream, drives
|
|
7
|
+
* adaptive frequency windows, and emits an LZ token stream. Sections decode in
|
|
8
|
+
* up to three consecutive segments with fresh dictionaries sharing one bitstream.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** Large back-reference sizes selected by Oodle1 size codes 61..64. */
|
|
12
|
+
const OODLE1_BACKREF_SIZES = Object.freeze([128, 192, 256, 512]);
|
|
13
|
+
|
|
14
|
+
/** Number of bytes occupied by the three Oodle1 parameter blocks. */
|
|
15
|
+
const OODLE1_PARAMETER_BYTES = 36;
|
|
16
|
+
|
|
17
|
+
/** Extra bytes appended to the arithmetic stream for decoder lookahead safety. */
|
|
18
|
+
const OODLE1_STREAM_PADDING = 8;
|
|
19
|
+
|
|
20
|
+
/** Extra output bytes reserved because final Oodle1 back-references may overshoot. */
|
|
21
|
+
const OODLE1_OUTPUT_SLACK = 512;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Arithmetic decoder for the Oodle1 7-bit-per-byte bitstream.
|
|
25
|
+
*/
|
|
26
|
+
class Decoder {
|
|
27
|
+
/**
|
|
28
|
+
* Create an arithmetic decoder over a padded compressed stream.
|
|
29
|
+
*
|
|
30
|
+
* @param {Uint8Array} stream Compressed payload after the parameter header.
|
|
31
|
+
*/
|
|
32
|
+
constructor(stream) {
|
|
33
|
+
this.stream = stream;
|
|
34
|
+
this.pos = 0;
|
|
35
|
+
this.numer = stream[0] >> 1;
|
|
36
|
+
this.denom = 0x80;
|
|
37
|
+
this.nextDenom = 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Decode a cumulative value in the range [0, max).
|
|
42
|
+
*
|
|
43
|
+
* @param {number} max Exclusive upper bound for the decoded value.
|
|
44
|
+
* @returns {number} Arithmetic-coded cumulative value.
|
|
45
|
+
*/
|
|
46
|
+
decode(max) {
|
|
47
|
+
while (this.denom <= 0x800000) {
|
|
48
|
+
this.denom = this.denom << 8 >>> 0;
|
|
49
|
+
this.numer = (this.numer << 8 | this.stream[this.pos] << 7 & 0x80 | this.stream[this.pos + 1] >> 1 & 0x7f) >>> 0;
|
|
50
|
+
this.pos++;
|
|
51
|
+
}
|
|
52
|
+
this.nextDenom = Math.floor(this.denom / max);
|
|
53
|
+
return Math.min(Math.floor(this.numer / this.nextDenom), max - 1);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Commit a decoded range and shrink the arithmetic interval.
|
|
58
|
+
*
|
|
59
|
+
* @param {number} max Original range size.
|
|
60
|
+
* @param {number} val Range start to commit.
|
|
61
|
+
* @param {number} err Range width to commit.
|
|
62
|
+
* @returns {number} The committed value.
|
|
63
|
+
*/
|
|
64
|
+
commit(max, val, err) {
|
|
65
|
+
this.numer -= this.nextDenom * val;
|
|
66
|
+
if (val + err < max) this.denom = this.nextDenom * err;else this.denom -= this.nextDenom * val;
|
|
67
|
+
return val;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Decode and immediately commit a single-value range.
|
|
72
|
+
*
|
|
73
|
+
* @param {number} max Exclusive upper bound for the decoded value.
|
|
74
|
+
* @returns {number} Decoded value.
|
|
75
|
+
*/
|
|
76
|
+
decodeCommit(max) {
|
|
77
|
+
return this.commit(max, this.decode(max), 1);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Adaptive weighted symbol window used by Oodle1 dictionaries.
|
|
83
|
+
*/
|
|
84
|
+
class WeighWindow {
|
|
85
|
+
/**
|
|
86
|
+
* Create an adaptive window for values up to a maximum symbol.
|
|
87
|
+
*
|
|
88
|
+
* @param {number} maxValue Maximum symbol value represented by the window.
|
|
89
|
+
* @param {number} countCap Maximum number of weighted entries to retain.
|
|
90
|
+
*/
|
|
91
|
+
constructor(maxValue, countCap) {
|
|
92
|
+
this.weightTotal = 4;
|
|
93
|
+
this.countCap = countCap + 1 & 0xffff;
|
|
94
|
+
this.ranges = [0, 0x4000];
|
|
95
|
+
this.weights = [4];
|
|
96
|
+
this.values = [0];
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Reusable result carrier for {@link WeighWindow#tryDecode}, owned by
|
|
100
|
+
* this instance so repeated decode calls don't allocate a fresh object
|
|
101
|
+
* per symbol (the hottest allocation site in this decoder). Safe to
|
|
102
|
+
* reuse across calls: each result is fully consumed (read, and any
|
|
103
|
+
* `storeValue` follow-up applied) before this same instance's next
|
|
104
|
+
* `tryDecode` call, and every `decompressBlock` call site that needs
|
|
105
|
+
* more than one decoded value at once (`d3`/`d4`/`d5`) always reads
|
|
106
|
+
* from three distinct `WeighWindow` instances, never this one twice.
|
|
107
|
+
*/
|
|
108
|
+
this.result = {
|
|
109
|
+
newIndex: -1,
|
|
110
|
+
value: 0
|
|
111
|
+
};
|
|
112
|
+
this.threshIncrease = 4;
|
|
113
|
+
this.threshRangeRebuild = 8;
|
|
114
|
+
this.threshWeightRebuild = Math.max(256, Math.min(32 * maxValue, 15160));
|
|
115
|
+
this.threshIncreaseCap = maxValue > 64 ? Math.min(2 * maxValue, (this.threshWeightRebuild >> 1) - 32) : 128;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Recompute arithmetic ranges from the current symbol weights.
|
|
120
|
+
*
|
|
121
|
+
* @returns {void}
|
|
122
|
+
*/
|
|
123
|
+
rebuildRanges() {
|
|
124
|
+
const w = this.weights;
|
|
125
|
+
this.ranges.length = w.length + 1;
|
|
126
|
+
const rangeWeight = Math.floor(8 * 0x4000 / this.weightTotal);
|
|
127
|
+
let start = 0;
|
|
128
|
+
for (let i = 0; i < w.length; i++) {
|
|
129
|
+
this.ranges[i] = start;
|
|
130
|
+
start += Math.floor(w[i] * rangeWeight / 8);
|
|
131
|
+
}
|
|
132
|
+
this.ranges[w.length] = 0x4000;
|
|
133
|
+
if (this.threshIncrease > this.threshIncreaseCap >> 1) {
|
|
134
|
+
this.threshRangeRebuild = this.weightTotal + this.threshIncreaseCap;
|
|
135
|
+
} else {
|
|
136
|
+
this.threshIncrease *= 2;
|
|
137
|
+
this.threshRangeRebuild = this.weightTotal + this.threshIncrease;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Decay, compact, and reorder adaptive weights when the table grows stale.
|
|
143
|
+
*
|
|
144
|
+
* @returns {void}
|
|
145
|
+
*/
|
|
146
|
+
rebuildWeights() {
|
|
147
|
+
const w = this.weights,
|
|
148
|
+
v = this.values;
|
|
149
|
+
let total = 0;
|
|
150
|
+
for (let i = 0; i < w.length; i++) {
|
|
151
|
+
w[i] >>= 1;
|
|
152
|
+
total += w[i];
|
|
153
|
+
}
|
|
154
|
+
this.weightTotal = total;
|
|
155
|
+
for (let i = 1; i < w.length; i++) {
|
|
156
|
+
while (i < w.length && w[i] === 0) {
|
|
157
|
+
w[i] = w[w.length - 1];
|
|
158
|
+
w.pop();
|
|
159
|
+
v[i] = v[v.length - 1];
|
|
160
|
+
v.pop();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (w.length > 1) {
|
|
164
|
+
let mi = 1,
|
|
165
|
+
mw = 0;
|
|
166
|
+
for (let i = 1; i < w.length; i++) {
|
|
167
|
+
if (w[i] > mw) {
|
|
168
|
+
mw = w[i];
|
|
169
|
+
mi = i;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const l = w.length - 1;
|
|
173
|
+
[w[mi], w[l]] = [w[l], w[mi]];
|
|
174
|
+
[v[mi], v[l]] = [v[l], v[mi]];
|
|
175
|
+
}
|
|
176
|
+
if (w.length < this.countCap && w[0] === 0) {
|
|
177
|
+
w[0] = 1;
|
|
178
|
+
this.weightTotal++;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Decode a symbol through this adaptive window.
|
|
184
|
+
*
|
|
185
|
+
* When `newIndex` is non-negative, the caller must decode and store a
|
|
186
|
+
* fresh literal value with {@link WeighWindow#storeValue}. Otherwise `value`
|
|
187
|
+
* is final.
|
|
188
|
+
*
|
|
189
|
+
* @param {Decoder} dec Arithmetic decoder to read from.
|
|
190
|
+
* @returns {{newIndex: number, value: number}} Decoded value or slot requiring a fresh literal.
|
|
191
|
+
*/
|
|
192
|
+
tryDecode(dec) {
|
|
193
|
+
if (this.weightTotal >= this.threshRangeRebuild) {
|
|
194
|
+
if (this.threshRangeRebuild >= this.threshWeightRebuild) this.rebuildWeights();
|
|
195
|
+
this.rebuildRanges();
|
|
196
|
+
}
|
|
197
|
+
const value = dec.decode(0x4000),
|
|
198
|
+
r = this.ranges;
|
|
199
|
+
let lo = 0,
|
|
200
|
+
hi = r.length;
|
|
201
|
+
while (lo < hi) {
|
|
202
|
+
const mid = lo + hi >> 1;
|
|
203
|
+
if (r[mid] <= value) lo = mid + 1;else hi = mid;
|
|
204
|
+
}
|
|
205
|
+
const index = lo - 1;
|
|
206
|
+
dec.commit(0x4000, r[index], r[index + 1] - r[index]);
|
|
207
|
+
this.weights[index]++;
|
|
208
|
+
this.weightTotal++;
|
|
209
|
+
const result = this.result;
|
|
210
|
+
if (index > 0) {
|
|
211
|
+
result.newIndex = -1;
|
|
212
|
+
result.value = this.values[index];
|
|
213
|
+
return result;
|
|
214
|
+
}
|
|
215
|
+
if (this.weights.length >= this.ranges.length && dec.decodeCommit(2) === 1) {
|
|
216
|
+
const i = this.ranges.length + dec.decodeCommit(this.weights.length - this.ranges.length + 1) - 1;
|
|
217
|
+
this.weights[i] += 2;
|
|
218
|
+
this.weightTotal += 2;
|
|
219
|
+
result.newIndex = -1;
|
|
220
|
+
result.value = this.values[i];
|
|
221
|
+
return result;
|
|
222
|
+
}
|
|
223
|
+
this.values.push(0);
|
|
224
|
+
this.weights.push(2);
|
|
225
|
+
this.weightTotal += 2;
|
|
226
|
+
if (this.weights.length === this.countCap) {
|
|
227
|
+
this.weightTotal -= this.weights[0];
|
|
228
|
+
this.weights[0] = 0;
|
|
229
|
+
}
|
|
230
|
+
result.newIndex = this.values.length - 1;
|
|
231
|
+
result.value = 0;
|
|
232
|
+
return result;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Store a freshly decoded escape value in an adaptive window slot.
|
|
237
|
+
*
|
|
238
|
+
* @param {number} index Slot index returned by {@link WeighWindow#tryDecode}.
|
|
239
|
+
* @param {number} value Value to store.
|
|
240
|
+
* @returns {number} Stored value.
|
|
241
|
+
*/
|
|
242
|
+
storeValue(index, value) {
|
|
243
|
+
this.values[index] = value;
|
|
244
|
+
return value;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
const BACKREF_SIZES = OODLE1_BACKREF_SIZES;
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Per-segment Oodle1 dictionary and adaptive symbol windows.
|
|
251
|
+
*/
|
|
252
|
+
class Dictionary {
|
|
253
|
+
/**
|
|
254
|
+
* Create a dictionary from one decoded Oodle1 parameter block.
|
|
255
|
+
*
|
|
256
|
+
* @param {{decodedValueMax: number, backrefValueMax: number, decodedCount: number, highbitCount: number, sizesCount: number[]}} p Parameter block.
|
|
257
|
+
*/
|
|
258
|
+
constructor(p) {
|
|
259
|
+
this.decodedSize = 0;
|
|
260
|
+
this.backrefSize = 0;
|
|
261
|
+
this.decodedValueMax = p.decodedValueMax;
|
|
262
|
+
this.backrefValueMax = p.backrefValueMax;
|
|
263
|
+
this.lowbitValueMax = Math.min(p.backrefValueMax + 1, 4);
|
|
264
|
+
this.midbitValueMax = Math.min(Math.floor(p.backrefValueMax / 4) + 1, 256);
|
|
265
|
+
this.highbitValueMax = Math.floor(p.backrefValueMax / 1024) + 1;
|
|
266
|
+
this.lowbitWindow = new WeighWindow(this.lowbitValueMax - 1, this.lowbitValueMax);
|
|
267
|
+
this.highbitWindow = new WeighWindow(this.highbitValueMax - 1, p.highbitCount + 1);
|
|
268
|
+
this.midbitWindows = [];
|
|
269
|
+
for (let i = 0; i < this.highbitValueMax; i++) {
|
|
270
|
+
this.midbitWindows.push(new WeighWindow(this.midbitValueMax - 1, this.midbitValueMax));
|
|
271
|
+
}
|
|
272
|
+
this.decodedWindows = [];
|
|
273
|
+
for (let i = 0; i < 4; i++) {
|
|
274
|
+
this.decodedWindows.push(new WeighWindow(this.decodedValueMax - 1, p.decodedCount));
|
|
275
|
+
}
|
|
276
|
+
this.sizeWindows = [];
|
|
277
|
+
for (let i = 0; i < 4; i++) {
|
|
278
|
+
for (let j = 0; j < 16; j++) {
|
|
279
|
+
this.sizeWindows.push(new WeighWindow(64, p.sizesCount[3 - i]));
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
this.sizeWindows.push(new WeighWindow(64, p.sizesCount[0]));
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Decode one literal or back-reference block into the output buffer.
|
|
287
|
+
*
|
|
288
|
+
* Back-references use byte-by-byte overlapping copies so offsets smaller than
|
|
289
|
+
* the copy length behave like the original LZ stream.
|
|
290
|
+
*
|
|
291
|
+
* @param {Decoder} dec Arithmetic decoder shared across all segments.
|
|
292
|
+
* @param {Uint8Array} out Output buffer with slack for overshoot copies.
|
|
293
|
+
* @param {number} pos Current output write offset.
|
|
294
|
+
* @returns {number} Number of bytes produced.
|
|
295
|
+
*/
|
|
296
|
+
decompressBlock(dec, out, pos) {
|
|
297
|
+
const sw = this.sizeWindows[this.backrefSize];
|
|
298
|
+
let d1 = sw.tryDecode(dec);
|
|
299
|
+
if (d1.newIndex >= 0) d1.value = sw.storeValue(d1.newIndex, dec.decodeCommit(65));
|
|
300
|
+
this.backrefSize = d1.value;
|
|
301
|
+
if (this.backrefSize > 0) {
|
|
302
|
+
const size = this.backrefSize < 61 ? this.backrefSize + 1 : BACKREF_SIZES[this.backrefSize - 61],
|
|
303
|
+
range = Math.min(this.backrefValueMax, this.decodedSize);
|
|
304
|
+
let d3 = this.lowbitWindow.tryDecode(dec);
|
|
305
|
+
if (d3.newIndex >= 0) d3.value = this.lowbitWindow.storeValue(d3.newIndex, dec.decodeCommit(this.lowbitValueMax));
|
|
306
|
+
let d4 = this.highbitWindow.tryDecode(dec);
|
|
307
|
+
if (d4.newIndex >= 0) d4.value = this.highbitWindow.storeValue(d4.newIndex, dec.decodeCommit(Math.floor(range / 1024) + 1));
|
|
308
|
+
const mw = this.midbitWindows[d4.value];
|
|
309
|
+
let d5 = mw.tryDecode(dec);
|
|
310
|
+
if (d5.newIndex >= 0) d5.value = mw.storeValue(d5.newIndex, dec.decodeCommit(Math.min(Math.floor(range / 4) + 1, 256)));
|
|
311
|
+
const offset = (d4.value << 10) + (d5.value << 2) + d3.value + 1;
|
|
312
|
+
this.decodedSize += size;
|
|
313
|
+
let src = pos - offset;
|
|
314
|
+
for (let i = 0; i < size; i++) {
|
|
315
|
+
out[pos + i] = out[src + i];
|
|
316
|
+
}
|
|
317
|
+
return size;
|
|
318
|
+
} else {
|
|
319
|
+
const dw = this.decodedWindows[pos & 3];
|
|
320
|
+
let d2 = dw.tryDecode(dec);
|
|
321
|
+
if (d2.newIndex >= 0) d2.value = dw.storeValue(d2.newIndex, dec.decodeCommit(this.decodedValueMax));
|
|
322
|
+
out[pos] = d2.value & 0xff;
|
|
323
|
+
this.decodedSize++;
|
|
324
|
+
return 1;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Read the three Oodle1 parameter blocks from the compressed section header.
|
|
331
|
+
*
|
|
332
|
+
* Each block is a 12-byte little-endian C bitfield record.
|
|
333
|
+
*
|
|
334
|
+
* @param {Uint8Array} bytes Compressed Oodle1 section bytes.
|
|
335
|
+
* @returns {{decodedValueMax: number, backrefValueMax: number, decodedCount: number, highbitCount: number, sizesCount: number[]}[]} Parsed parameter blocks.
|
|
336
|
+
*/
|
|
337
|
+
function readOodle1Parameters(bytes) {
|
|
338
|
+
const dv = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength),
|
|
339
|
+
params = [];
|
|
340
|
+
for (let i = 0; i < 3; i++) {
|
|
341
|
+
const b = i * 12,
|
|
342
|
+
a = dv.getUint32(b, true),
|
|
343
|
+
c = dv.getUint32(b + 4, true);
|
|
344
|
+
params.push({
|
|
345
|
+
decodedValueMax: a & 0x1ff,
|
|
346
|
+
backrefValueMax: a >>> 9,
|
|
347
|
+
decodedCount: c & 0x1ff,
|
|
348
|
+
highbitCount: c >>> 19 & 0x1fff,
|
|
349
|
+
sizesCount: [bytes[b + 8], bytes[b + 9], bytes[b + 10], bytes[b + 11]]
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
return params;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Decompress a Granny Oodle1 (section format 2) block.
|
|
357
|
+
*
|
|
358
|
+
* The compressed stream is padded so the arithmetic decoder's one-byte lookahead
|
|
359
|
+
* never reads out of bounds. Output is allocated with slack because a final
|
|
360
|
+
* back-reference may overshoot before the returned view is trimmed.
|
|
361
|
+
*
|
|
362
|
+
* @param {Uint8Array} bytes Compressed section bytes.
|
|
363
|
+
* @param {number} expandedSize Decompressed byte length.
|
|
364
|
+
* @param {{first16:number, first8:number}} stops Segment stop offsets from the section directory.
|
|
365
|
+
* @returns {Uint8Array} Exactly `expandedSize` bytes.
|
|
366
|
+
*/
|
|
367
|
+
function decompressOodle1(bytes, expandedSize, {
|
|
368
|
+
first16,
|
|
369
|
+
first8
|
|
370
|
+
}) {
|
|
371
|
+
const out = new Uint8Array(expandedSize + OODLE1_OUTPUT_SLACK);
|
|
372
|
+
if (bytes.length === 0 || expandedSize === 0) return out.subarray(0, expandedSize);
|
|
373
|
+
if (bytes.length < OODLE1_PARAMETER_BYTES) throw new Error("Oodle1 block too small for parameter header");
|
|
374
|
+
const params = readOodle1Parameters(bytes);
|
|
375
|
+
const stream = new Uint8Array(bytes.length - OODLE1_PARAMETER_BYTES + OODLE1_STREAM_PADDING);
|
|
376
|
+
stream.set(bytes.subarray(OODLE1_PARAMETER_BYTES));
|
|
377
|
+
const dec = new Decoder(stream);
|
|
378
|
+
const steps = [first16, first8, expandedSize];
|
|
379
|
+
let pos = 0;
|
|
380
|
+
for (let s = 0; s < 3; s++) {
|
|
381
|
+
const dict = new Dictionary(params[s]);
|
|
382
|
+
while (pos < steps[s]) pos += dict.decompressBlock(dec, out, pos);
|
|
383
|
+
}
|
|
384
|
+
return expandedSize === out.length ? out : out.subarray(0, expandedSize);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
export { OODLE1_BACKREF_SIZES, OODLE1_OUTPUT_SLACK, OODLE1_PARAMETER_BYTES, OODLE1_STREAM_PADDING, decompressOodle1, readOodle1Parameters };
|
|
388
|
+
//# sourceMappingURL=oodle1.js.map
|