@carbonenginejs/runtime-resource 0.1.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/FORMAT-PROVENANCE.md +135 -0
- package/LICENSE +21 -0
- package/NOTICE +29 -0
- package/README.md +241 -0
- package/dist/CjsMotherLode.js +56 -0
- package/dist/CjsMotherLode.js.map +1 -0
- package/dist/CjsResMan.js +740 -0
- package/dist/CjsResMan.js.map +1 -0
- package/dist/CjsResManQueue.js +214 -0
- package/dist/CjsResManQueue.js.map +1 -0
- package/dist/CjsResource.js +366 -0
- package/dist/CjsResource.js.map +1 -0
- package/dist/CjsResourceSource.js +59 -0
- package/dist/CjsResourceSource.js.map +1 -0
- package/dist/_virtual/_rollupPluginBabelHelpers.js +153 -0
- package/dist/_virtual/_rollupPluginBabelHelpers.js.map +1 -0
- package/dist/format/CjsFormat.js +178 -0
- package/dist/format/CjsFormat.js.map +1 -0
- package/dist/format/CjsResourceProbe.js +269 -0
- package/dist/format/CjsResourceProbe.js.map +1 -0
- package/dist/format/payloadContract.js +173 -0
- package/dist/format/payloadContract.js.map +1 -0
- package/dist/formats/black/CjsBlackFormat.js +272 -0
- package/dist/formats/black/CjsBlackFormat.js.map +1 -0
- package/dist/formats/black/core/CjsBlackBinaryReader.js +153 -0
- package/dist/formats/black/core/CjsBlackBinaryReader.js.map +1 -0
- package/dist/formats/black/core/CjsBlackPropertyReaders.js +382 -0
- package/dist/formats/black/core/CjsBlackPropertyReaders.js.map +1 -0
- package/dist/formats/black/core/CjsBlackReader.js +760 -0
- package/dist/formats/black/core/CjsBlackReader.js.map +1 -0
- package/dist/formats/black/core/CjsBlackSchemaRegistry.js +433 -0
- package/dist/formats/black/core/CjsBlackSchemaRegistry.js.map +1 -0
- package/dist/formats/black/core/black-schema-v1-2026-07-11.json.js +4 -0
- package/dist/formats/black/core/black-schema-v1-2026-07-11.json.js.map +1 -0
- package/dist/formats/black/core/blackConstants.js +7 -0
- package/dist/formats/black/core/blackConstants.js.map +1 -0
- package/dist/formats/black/core/blackDefinitions.js +10 -0
- package/dist/formats/black/core/blackDefinitions.js.map +1 -0
- package/dist/formats/black/core/blackEnums.js +6 -0
- package/dist/formats/black/core/blackEnums.js.map +1 -0
- package/dist/formats/black/core/blackSchema.js +3 -0
- package/dist/formats/black/core/blackSchema.js.map +1 -0
- package/dist/formats/black/core/blackVersion.js +22 -0
- package/dist/formats/black/core/blackVersion.js.map +1 -0
- package/dist/formats/black/core/helpers.js +182 -0
- package/dist/formats/black/core/helpers.js.map +1 -0
- package/dist/formats/black/core/schema.js +4 -0
- package/dist/formats/black/core/schema.js.map +1 -0
- package/dist/formats/black/index.js +2 -0
- package/dist/formats/black/index.js.map +1 -0
- package/dist/formats/bnk/CjsBnkFormat.js +245 -0
- package/dist/formats/bnk/CjsBnkFormat.js.map +1 -0
- package/dist/formats/bnk/core/helpers.js +354 -0
- package/dist/formats/bnk/core/helpers.js.map +1 -0
- package/dist/formats/bnk/core/soundbanksInfo.js +246 -0
- package/dist/formats/bnk/core/soundbanksInfo.js.map +1 -0
- package/dist/formats/bnk/index.js +3 -0
- package/dist/formats/bnk/index.js.map +1 -0
- package/dist/formats/cmf/CjsCmfFormat.js +491 -0
- package/dist/formats/cmf/CjsCmfFormat.js.map +1 -0
- package/dist/formats/cmf/core/binary.js +118 -0
- package/dist/formats/cmf/core/binary.js.map +1 -0
- package/dist/formats/cmf/core/buffers.js +233 -0
- package/dist/formats/cmf/core/buffers.js.map +1 -0
- package/dist/formats/cmf/core/constants.js +47 -0
- package/dist/formats/cmf/core/constants.js.map +1 -0
- package/dist/formats/cmf/core/gr2Anim.js +453 -0
- package/dist/formats/cmf/core/gr2Anim.js.map +1 -0
- package/dist/formats/cmf/core/helpers.js +287 -0
- package/dist/formats/cmf/core/helpers.js.map +1 -0
- package/dist/formats/cmf/core/pack.js +276 -0
- package/dist/formats/cmf/core/pack.js.map +1 -0
- package/dist/formats/cmf/core/schema.js +364 -0
- package/dist/formats/cmf/core/schema.js.map +1 -0
- package/dist/formats/cmf/core/shared.js +268 -0
- package/dist/formats/cmf/core/shared.js.map +1 -0
- package/dist/formats/cmf/core/writer.js +517 -0
- package/dist/formats/cmf/core/writer.js.map +1 -0
- package/dist/formats/cmf/index.js +2 -0
- package/dist/formats/cmf/index.js.map +1 -0
- package/dist/formats/dds/CjsDdsFormat.js +187 -0
- package/dist/formats/dds/CjsDdsFormat.js.map +1 -0
- package/dist/formats/dds/core/helpers.js +812 -0
- package/dist/formats/dds/core/helpers.js.map +1 -0
- package/dist/formats/dds/index.js +2 -0
- package/dist/formats/dds/index.js.map +1 -0
- package/dist/formats/fbx/CjsFbxFormat.js +260 -0
- package/dist/formats/fbx/CjsFbxFormat.js.map +1 -0
- package/dist/formats/fbx/core/helpers.js +3901 -0
- package/dist/formats/fbx/core/helpers.js.map +1 -0
- package/dist/formats/fbx/index.js +2 -0
- package/dist/formats/fbx/index.js.map +1 -0
- package/dist/formats/flac/CjsFlacFormat.js +81 -0
- package/dist/formats/flac/CjsFlacFormat.js.map +1 -0
- package/dist/formats/flac/core/helpers.js +295 -0
- package/dist/formats/flac/core/helpers.js.map +1 -0
- package/dist/formats/flac/index.js +2 -0
- package/dist/formats/flac/index.js.map +1 -0
- package/dist/formats/gif/CjsGifFormat.js +81 -0
- package/dist/formats/gif/CjsGifFormat.js.map +1 -0
- package/dist/formats/gif/core/helpers.js +360 -0
- package/dist/formats/gif/core/helpers.js.map +1 -0
- package/dist/formats/gif/index.js +2 -0
- package/dist/formats/gif/index.js.map +1 -0
- package/dist/formats/gltf/CjsGltfFormat.js +284 -0
- package/dist/formats/gltf/CjsGltfFormat.js.map +1 -0
- package/dist/formats/gltf/core/helpers.js +292 -0
- package/dist/formats/gltf/core/helpers.js.map +1 -0
- package/dist/formats/gltf/core/json.js +79 -0
- package/dist/formats/gltf/core/json.js.map +1 -0
- package/dist/formats/gltf/core/parser.js +666 -0
- package/dist/formats/gltf/core/parser.js.map +1 -0
- package/dist/formats/gltf/core/targets.js +163 -0
- package/dist/formats/gltf/core/targets.js.map +1 -0
- package/dist/formats/gltf/index.js +2 -0
- package/dist/formats/gltf/index.js.map +1 -0
- package/dist/formats/index.js +23 -0
- package/dist/formats/index.js.map +1 -0
- package/dist/formats/jpeg/CjsJpegFormat.js +200 -0
- package/dist/formats/jpeg/CjsJpegFormat.js.map +1 -0
- package/dist/formats/jpeg/core/helpers.js +350 -0
- package/dist/formats/jpeg/core/helpers.js.map +1 -0
- package/dist/formats/jpeg/core/jpeg.js +377 -0
- package/dist/formats/jpeg/core/jpeg.js.map +1 -0
- package/dist/formats/jpeg/index.js +2 -0
- package/dist/formats/jpeg/index.js.map +1 -0
- package/dist/formats/mp3/CjsMp3Format.js +186 -0
- package/dist/formats/mp3/CjsMp3Format.js.map +1 -0
- package/dist/formats/mp3/core/helpers.js +338 -0
- package/dist/formats/mp3/core/helpers.js.map +1 -0
- package/dist/formats/mp3/index.js +2 -0
- package/dist/formats/mp3/index.js.map +1 -0
- package/dist/formats/mp4/CjsMp4Format.js +185 -0
- package/dist/formats/mp4/CjsMp4Format.js.map +1 -0
- package/dist/formats/mp4/core/helpers.js +449 -0
- package/dist/formats/mp4/core/helpers.js.map +1 -0
- package/dist/formats/mp4/index.js +2 -0
- package/dist/formats/mp4/index.js.map +1 -0
- package/dist/formats/obj/CjsObjFormat.js +247 -0
- package/dist/formats/obj/CjsObjFormat.js.map +1 -0
- package/dist/formats/obj/core/helpers.js +573 -0
- package/dist/formats/obj/core/helpers.js.map +1 -0
- package/dist/formats/obj/core/json.js +64 -0
- package/dist/formats/obj/core/json.js.map +1 -0
- package/dist/formats/obj/core/parser.js +321 -0
- package/dist/formats/obj/core/parser.js.map +1 -0
- package/dist/formats/obj/index.js +2 -0
- package/dist/formats/obj/index.js.map +1 -0
- package/dist/formats/ogg/CjsOggFormat.js +82 -0
- package/dist/formats/ogg/CjsOggFormat.js.map +1 -0
- package/dist/formats/ogg/core/helpers.js +387 -0
- package/dist/formats/ogg/core/helpers.js.map +1 -0
- package/dist/formats/ogg/core/imdct.js +178 -0
- package/dist/formats/ogg/core/imdct.js.map +1 -0
- package/dist/formats/ogg/core/vorbis.js +999 -0
- package/dist/formats/ogg/core/vorbis.js.map +1 -0
- package/dist/formats/ogg/index.js +2 -0
- package/dist/formats/ogg/index.js.map +1 -0
- package/dist/formats/png/CjsPngFormat.js +189 -0
- package/dist/formats/png/CjsPngFormat.js.map +1 -0
- package/dist/formats/png/core/helpers.js +583 -0
- package/dist/formats/png/core/helpers.js.map +1 -0
- package/dist/formats/png/index.js +2 -0
- package/dist/formats/png/index.js.map +1 -0
- package/dist/formats/red/CjsRedFormat.js +247 -0
- package/dist/formats/red/CjsRedFormat.js.map +1 -0
- package/dist/formats/red/core/CjsRedReader.js +201 -0
- package/dist/formats/red/core/CjsRedReader.js.map +1 -0
- package/dist/formats/red/core/blackDefinitions.js +3 -0
- package/dist/formats/red/core/blackDefinitions.js.map +1 -0
- package/dist/formats/red/core/helpers.js +136 -0
- package/dist/formats/red/core/helpers.js.map +1 -0
- package/dist/formats/red/core/redGraph.js +68 -0
- package/dist/formats/red/core/redGraph.js.map +1 -0
- package/dist/formats/red/core/schema.js +4 -0
- package/dist/formats/red/core/schema.js.map +1 -0
- package/dist/formats/red/index.js +2 -0
- package/dist/formats/red/index.js.map +1 -0
- package/dist/formats/stl/CjsStlFormat.js +304 -0
- package/dist/formats/stl/CjsStlFormat.js.map +1 -0
- package/dist/formats/stl/core/helpers.js +257 -0
- package/dist/formats/stl/core/helpers.js.map +1 -0
- package/dist/formats/stl/core/json.js +51 -0
- package/dist/formats/stl/core/json.js.map +1 -0
- package/dist/formats/stl/core/stl.js +544 -0
- package/dist/formats/stl/core/stl.js.map +1 -0
- package/dist/formats/stl/core/targets.js +163 -0
- package/dist/formats/stl/core/targets.js.map +1 -0
- package/dist/formats/stl/index.js +2 -0
- package/dist/formats/stl/index.js.map +1 -0
- package/dist/formats/tga/CjsTgaFormat.js +186 -0
- package/dist/formats/tga/CjsTgaFormat.js.map +1 -0
- package/dist/formats/tga/core/helpers.js +446 -0
- package/dist/formats/tga/core/helpers.js.map +1 -0
- package/dist/formats/tga/index.js +2 -0
- package/dist/formats/tga/index.js.map +1 -0
- package/dist/formats/wav/CjsWavFormat.js +186 -0
- package/dist/formats/wav/CjsWavFormat.js.map +1 -0
- package/dist/formats/wav/core/helpers.js +328 -0
- package/dist/formats/wav/core/helpers.js.map +1 -0
- package/dist/formats/wav/index.js +2 -0
- package/dist/formats/wav/index.js.map +1 -0
- package/dist/formats/webm/CjsWebmFormat.js +185 -0
- package/dist/formats/webm/CjsWebmFormat.js.map +1 -0
- package/dist/formats/webm/core/helpers.js +537 -0
- package/dist/formats/webm/core/helpers.js.map +1 -0
- package/dist/formats/webm/index.js +2 -0
- package/dist/formats/webm/index.js.map +1 -0
- package/dist/formats/webp/CjsWebpFormat.js +80 -0
- package/dist/formats/webp/CjsWebpFormat.js.map +1 -0
- package/dist/formats/webp/core/helpers.js +214 -0
- package/dist/formats/webp/core/helpers.js.map +1 -0
- package/dist/formats/webp/index.js +2 -0
- package/dist/formats/webp/index.js.map +1 -0
- package/dist/formats/wem/CjsWemFormat.js +197 -0
- package/dist/formats/wem/CjsWemFormat.js.map +1 -0
- package/dist/formats/wem/core/bitStream.js +259 -0
- package/dist/formats/wem/core/bitStream.js.map +1 -0
- package/dist/formats/wem/core/codebookLibrary.js +164 -0
- package/dist/formats/wem/core/codebookLibrary.js.map +1 -0
- package/dist/formats/wem/core/helpers.js +336 -0
- package/dist/formats/wem/core/helpers.js.map +1 -0
- package/dist/formats/wem/core/packedCodebooksAotuv603.js +30 -0
- package/dist/formats/wem/core/packedCodebooksAotuv603.js.map +1 -0
- package/dist/formats/wem/core/wemToOgg.js +485 -0
- package/dist/formats/wem/core/wemToOgg.js.map +1 -0
- package/dist/formats/wem/index.js +2 -0
- package/dist/formats/wem/index.js.map +1 -0
- package/dist/formats/yaml/CjsYamlFormat.js +77 -0
- package/dist/formats/yaml/CjsYamlFormat.js.map +1 -0
- package/dist/formats/yaml/core/CjsYamlReader.js +304 -0
- package/dist/formats/yaml/core/CjsYamlReader.js.map +1 -0
- package/dist/formats/yaml/core/helpers.js +160 -0
- package/dist/formats/yaml/core/helpers.js.map +1 -0
- package/dist/formats/yaml/index.js +2 -0
- package/dist/formats/yaml/index.js.map +1 -0
- package/dist/generated/resources/AudioGeometryResData.js +47 -0
- package/dist/generated/resources/AudioGeometryResData.js.map +1 -0
- package/dist/generated/resources/CmfVertexReader.js +46 -0
- package/dist/generated/resources/CmfVertexReader.js.map +1 -0
- package/dist/generated/resources/GStateBindingCallbackData.js +31 -0
- package/dist/generated/resources/GStateBindingCallbackData.js.map +1 -0
- package/dist/generated/resources/MeshDecalData.js +37 -0
- package/dist/generated/resources/MeshDecalData.js.map +1 -0
- package/dist/generated/resources/MeshDecalLodData.js +34 -0
- package/dist/generated/resources/MeshDecalLodData.js.map +1 -0
- package/dist/generated/resources/Tr2AsyncSave.js +46 -0
- package/dist/generated/resources/Tr2AsyncSave.js.map +1 -0
- package/dist/generated/resources/Tr2CmfContents.js +37 -0
- package/dist/generated/resources/Tr2CmfContents.js.map +1 -0
- package/dist/generated/resources/Tr2GrannyIntersectionResult.js +58 -0
- package/dist/generated/resources/Tr2GrannyIntersectionResult.js.map +1 -0
- package/dist/generated/resources/Tr2LoadPrepareFence.js +37 -0
- package/dist/generated/resources/Tr2LoadPrepareFence.js.map +1 -0
- package/dist/generated/resources/Tr2MaterialArea.js +34 -0
- package/dist/generated/resources/Tr2MaterialArea.js.map +1 -0
- package/dist/generated/resources/Tr2MaterialMesh.js +31 -0
- package/dist/generated/resources/Tr2MaterialMesh.js.map +1 -0
- package/dist/generated/resources/Tr2MaterialRes.js +34 -0
- package/dist/generated/resources/Tr2MaterialRes.js.map +1 -0
- package/dist/generated/resources/Tr2ShaderPermutation.js +43 -0
- package/dist/generated/resources/Tr2ShaderPermutation.js.map +1 -0
- package/dist/generated/resources/Tr2TextureLodManager.js +60 -0
- package/dist/generated/resources/Tr2TextureLodManager.js.map +1 -0
- package/dist/generated/resources/Tr2TextureLodUpdateRequest.js +37 -0
- package/dist/generated/resources/Tr2TextureLodUpdateRequest.js.map +1 -0
- package/dist/generated/resources/Tr2TexturePackChannel.js +37 -0
- package/dist/generated/resources/Tr2TexturePackChannel.js.map +1 -0
- package/dist/generated/resources/Tr2TexturePipeline.js +44 -0
- package/dist/generated/resources/Tr2TexturePipeline.js.map +1 -0
- package/dist/generated/resources/Tr2TexturePipelineParams.js +34 -0
- package/dist/generated/resources/Tr2TexturePipelineParams.js.map +1 -0
- package/dist/generated/resources/Tr2TexturePipelineStepCompress.js +40 -0
- package/dist/generated/resources/Tr2TexturePipelineStepCompress.js.map +1 -0
- package/dist/generated/resources/Tr2TexturePipelineStepLimitSize.js +34 -0
- package/dist/generated/resources/Tr2TexturePipelineStepLimitSize.js.map +1 -0
- package/dist/generated/resources/Tr2TexturePipelineStepLoad.js +31 -0
- package/dist/generated/resources/Tr2TexturePipelineStepLoad.js.map +1 -0
- package/dist/generated/resources/Tr2TexturePipelineStepPack.js +43 -0
- package/dist/generated/resources/Tr2TexturePipelineStepPack.js.map +1 -0
- package/dist/generated/resources/TriGeometryResAreaData.js +59 -0
- package/dist/generated/resources/TriGeometryResAreaData.js.map +1 -0
- package/dist/generated/resources/TriGeometryResJointData.js +38 -0
- package/dist/generated/resources/TriGeometryResJointData.js.map +1 -0
- package/dist/generated/resources/TriGeometryResLodData.js +88 -0
- package/dist/generated/resources/TriGeometryResLodData.js.map +1 -0
- package/dist/generated/resources/TriGeometryResMeshData.js +63 -0
- package/dist/generated/resources/TriGeometryResMeshData.js.map +1 -0
- package/dist/generated/resources/TriGeometryResSkeletonData.js +34 -0
- package/dist/generated/resources/TriGeometryResSkeletonData.js.map +1 -0
- package/dist/generated/resources/TriJointBinding.js +38 -0
- package/dist/generated/resources/TriJointBinding.js.map +1 -0
- package/dist/generated/resources/TriMorphTargetGeometryConstants.js +46 -0
- package/dist/generated/resources/TriMorphTargetGeometryConstants.js.map +1 -0
- package/dist/generated/resources/TriRtGeometryConstants.js +88 -0
- package/dist/generated/resources/TriRtGeometryConstants.js.map +1 -0
- package/dist/generated/resources/enums.js +18 -0
- package/dist/generated/resources/enums.js.map +1 -0
- package/dist/generated/resources/index.js +32 -0
- package/dist/generated/resources/index.js.map +1 -0
- package/dist/index.js +52 -0
- package/dist/index.js.map +1 -0
- package/dist/resourcePath.js +18 -0
- package/dist/resourcePath.js.map +1 -0
- package/dist/resourceStates.js +9 -0
- package/dist/resourceStates.js.map +1 -0
- package/dist/resources/Tr2EffectRes.js +71 -0
- package/dist/resources/Tr2EffectRes.js.map +1 -0
- package/dist/resources/Tr2GrannyStateRes.js +44 -0
- package/dist/resources/Tr2GrannyStateRes.js.map +1 -0
- package/dist/resources/Tr2ImageRes.js +114 -0
- package/dist/resources/Tr2ImageRes.js.map +1 -0
- package/dist/resources/Tr2LightProfileRes.js +40 -0
- package/dist/resources/Tr2LightProfileRes.js.map +1 -0
- package/dist/resources/TriGeometryRes.js +216 -0
- package/dist/resources/TriGeometryRes.js.map +1 -0
- package/dist/resources/TriGrannyRes.js +43 -0
- package/dist/resources/TriGrannyRes.js.map +1 -0
- package/dist/resources/TriTextureRes.js +304 -0
- package/dist/resources/TriTextureRes.js.map +1 -0
- package/dist/resources/resourceBoundary.js +47 -0
- package/dist/resources/resourceBoundary.js.map +1 -0
- package/dist/texture/CjsTextureArrayRes.js +406 -0
- package/dist/texture/CjsTextureArrayRes.js.map +1 -0
- package/dist/texture/CjsTextureParameterProxy.js +133 -0
- package/dist/texture/CjsTextureParameterProxy.js.map +1 -0
- package/format-notices/black/LICENSE +21 -0
- package/format-notices/black/NOTICE +47 -0
- package/format-notices/bnk/LICENSE +21 -0
- package/format-notices/bnk/NOTICE +17 -0
- package/format-notices/cmf/LICENSE +21 -0
- package/format-notices/cmf/NOTICE +36 -0
- package/format-notices/dds/LICENSE +21 -0
- package/format-notices/dds/NOTICE +14 -0
- package/format-notices/fbx/LICENSE +21 -0
- package/format-notices/fbx/NOTICE +14 -0
- package/format-notices/flac/LICENSE +21 -0
- package/format-notices/flac/NOTICE +14 -0
- package/format-notices/gif/LICENSE +21 -0
- package/format-notices/gif/NOTICE +14 -0
- package/format-notices/gltf/LICENSE +21 -0
- package/format-notices/gltf/NOTICE +27 -0
- package/format-notices/jpeg/LICENSE +21 -0
- package/format-notices/jpeg/NOTICE +14 -0
- package/format-notices/mp3/LICENSE +21 -0
- package/format-notices/mp3/NOTICE +14 -0
- package/format-notices/mp4/LICENSE +21 -0
- package/format-notices/mp4/NOTICE +14 -0
- package/format-notices/obj/LICENSE +21 -0
- package/format-notices/obj/NOTICE +26 -0
- package/format-notices/ogg/LICENSE +21 -0
- package/format-notices/ogg/NOTICE +28 -0
- package/format-notices/png/LICENSE +21 -0
- package/format-notices/png/NOTICE +14 -0
- package/format-notices/red/LICENSE +21 -0
- package/format-notices/red/NOTICE +31 -0
- package/format-notices/stl/LICENSE +21 -0
- package/format-notices/stl/NOTICE +21 -0
- package/format-notices/tga/LICENSE +21 -0
- package/format-notices/tga/NOTICE +14 -0
- package/format-notices/wav/LICENSE +21 -0
- package/format-notices/wav/NOTICE +14 -0
- package/format-notices/webm/LICENSE +21 -0
- package/format-notices/webm/NOTICE +14 -0
- package/format-notices/webp/LICENSE +21 -0
- package/format-notices/webp/NOTICE +14 -0
- package/format-notices/wem/LICENSE +57 -0
- package/format-notices/wem/NOTICE +33 -0
- package/format-notices/yaml/LICENSE +21 -0
- package/format-notices/yaml/NOTICE +44 -0
- package/package.json +51 -0
- package/resource-lifecycle.md +487 -0
|
@@ -0,0 +1,812 @@
|
|
|
1
|
+
const OUTPUT_IMAGE = "image";
|
|
2
|
+
const OUTPUT_TEXTURE = "texture";
|
|
3
|
+
const OUTPUT_RGBA = "rgba";
|
|
4
|
+
const OUTPUT_RAW = "raw";
|
|
5
|
+
const OUTPUT_JSON = "json";
|
|
6
|
+
const DEFAULT_VALUES = Object.freeze({
|
|
7
|
+
emit: OUTPUT_RAW,
|
|
8
|
+
inputType: "",
|
|
9
|
+
source: ""
|
|
10
|
+
});
|
|
11
|
+
const DDS_HEADER_SIZE = 124;
|
|
12
|
+
const DDS_PIXELFORMAT_OFFSET = 76;
|
|
13
|
+
const DDS_FOURCC = 0x00000004;
|
|
14
|
+
const DDS_RGB = 0x00000040;
|
|
15
|
+
const DDS_ALPHAPIXELS = 0x00000001;
|
|
16
|
+
const DDSCAPS2_CUBEMAP = 0x00000200;
|
|
17
|
+
const DDSCAPS2_VOLUME = 0x00200000;
|
|
18
|
+
const DDS_CUBE_FACE_FLAGS = Object.freeze([["positive-x", 0x00000400], ["negative-x", 0x00000800], ["positive-y", 0x00001000], ["negative-y", 0x00002000], ["positive-z", 0x00004000], ["negative-z", 0x00008000]]);
|
|
19
|
+
const FOURCC_PIXEL_FORMATS = Object.freeze({
|
|
20
|
+
DXT1: "bc1-rgba-unorm",
|
|
21
|
+
DXT3: "bc2-rgba-unorm",
|
|
22
|
+
DXT5: "bc3-rgba-unorm",
|
|
23
|
+
ATI1: "bc4-r-unorm",
|
|
24
|
+
BC4U: "bc4-r-unorm",
|
|
25
|
+
BC4S: "bc4-r-snorm",
|
|
26
|
+
ATI2: "bc5-rg-unorm",
|
|
27
|
+
BC5U: "bc5-rg-unorm",
|
|
28
|
+
BC5S: "bc5-rg-snorm"
|
|
29
|
+
});
|
|
30
|
+
const DXGI_PIXEL_FORMATS = Object.freeze({
|
|
31
|
+
2: "rgba32float",
|
|
32
|
+
6: "rgb32float",
|
|
33
|
+
10: "rgba16float",
|
|
34
|
+
16: "rg32float",
|
|
35
|
+
41: "r32float",
|
|
36
|
+
54: "r16float",
|
|
37
|
+
28: "rgba8unorm",
|
|
38
|
+
29: "rgba8unorm-srgb",
|
|
39
|
+
49: "rg8unorm",
|
|
40
|
+
61: "r8unorm",
|
|
41
|
+
71: "bc1-rgba-unorm",
|
|
42
|
+
72: "bc1-rgba-unorm-srgb",
|
|
43
|
+
74: "bc2-rgba-unorm",
|
|
44
|
+
75: "bc2-rgba-unorm-srgb",
|
|
45
|
+
77: "bc3-rgba-unorm",
|
|
46
|
+
78: "bc3-rgba-unorm-srgb",
|
|
47
|
+
80: "bc4-r-unorm",
|
|
48
|
+
81: "bc4-r-snorm",
|
|
49
|
+
83: "bc5-rg-unorm",
|
|
50
|
+
84: "bc5-rg-snorm",
|
|
51
|
+
87: "bgra8unorm",
|
|
52
|
+
88: "bgrx8unorm",
|
|
53
|
+
91: "bgra8unorm-srgb",
|
|
54
|
+
93: "bgrx8unorm-srgb",
|
|
55
|
+
95: "bc6h-rgb-ufloat",
|
|
56
|
+
96: "bc6h-rgb-float",
|
|
57
|
+
98: "bc7-rgba-unorm",
|
|
58
|
+
99: "bc7-rgba-unorm-srgb"
|
|
59
|
+
});
|
|
60
|
+
const COMPRESSED_PIXEL_FORMATS = new Set(["bc1-rgba-unorm", "bc1-rgba-unorm-srgb", "bc2-rgba-unorm", "bc2-rgba-unorm-srgb", "bc3-rgba-unorm", "bc3-rgba-unorm-srgb", "bc4-r-unorm", "bc4-r-snorm", "bc5-rg-unorm", "bc5-rg-snorm", "bc6h-rgb-ufloat", "bc6h-rgb-float", "bc7-rgba-unorm", "bc7-rgba-unorm-srgb"]);
|
|
61
|
+
const DEBUG_OUTPUTS = Object.freeze({
|
|
62
|
+
png: "pngJson",
|
|
63
|
+
jpeg: "jpegJson",
|
|
64
|
+
jpg: "jpegJson",
|
|
65
|
+
tga: "tgaJson",
|
|
66
|
+
dds: "ddsJson"
|
|
67
|
+
});
|
|
68
|
+
function normalizeValues(base = DEFAULT_VALUES, options = {}, readerName = "CjsImageFormat") {
|
|
69
|
+
const values = {
|
|
70
|
+
...DEFAULT_VALUES,
|
|
71
|
+
...(base || {}),
|
|
72
|
+
...(options || {})
|
|
73
|
+
};
|
|
74
|
+
values.inputType = normalizeInputType(values.inputType);
|
|
75
|
+
values.emit = normalizeEmit(values.emit, values.inputType, readerName);
|
|
76
|
+
return values;
|
|
77
|
+
}
|
|
78
|
+
function normalizeInputType(inputType) {
|
|
79
|
+
if (!inputType) return "";
|
|
80
|
+
const value = String(inputType).replace(/^\./u, "").toLowerCase();
|
|
81
|
+
return value === "jpg" ? "jpeg" : value;
|
|
82
|
+
}
|
|
83
|
+
function normalizeEmit(emit, inputType, readerName) {
|
|
84
|
+
if (emit === undefined || emit === null) return OUTPUT_RAW;
|
|
85
|
+
if (emit === OUTPUT_JSON && inputType) return DEBUG_OUTPUTS[inputType] || OUTPUT_JSON;
|
|
86
|
+
if ([OUTPUT_IMAGE, OUTPUT_TEXTURE, OUTPUT_RGBA, OUTPUT_RAW, OUTPUT_JSON].includes(emit)) return emit;
|
|
87
|
+
if (Object.values(DEBUG_OUTPUTS).includes(emit)) return emit;
|
|
88
|
+
throw new TypeError(`${readerName}: unknown emit value ${JSON.stringify(emit)}`);
|
|
89
|
+
}
|
|
90
|
+
function toBytes(input) {
|
|
91
|
+
if (input instanceof Uint8Array) return input;
|
|
92
|
+
if (input instanceof ArrayBuffer) return new Uint8Array(input);
|
|
93
|
+
if (ArrayBuffer.isView(input)) return new Uint8Array(input.buffer, input.byteOffset, input.byteLength);
|
|
94
|
+
throw new TypeError("Image input must be Uint8Array, ArrayBuffer, or DataView");
|
|
95
|
+
}
|
|
96
|
+
function inspectWithValues(input, values = DEFAULT_VALUES, expectedType = "") {
|
|
97
|
+
const bytes = toBytes(input);
|
|
98
|
+
const detected = inspectBytes(bytes);
|
|
99
|
+
const sourceFormat = expectedType || values.inputType || detected.sourceFormat;
|
|
100
|
+
if (expectedType && detected.sourceFormat && detected.sourceFormat !== expectedType) {
|
|
101
|
+
throw new TypeError(`CjsFormat${capitalize(expectedType)}: expected ${expectedType}, got ${detected.sourceFormat}`);
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
payloadType: sourceFormat === "dds" ? "texture" : "image",
|
|
105
|
+
mediaTypes: sourceFormat === "dds" ? ["texture", "image"] : ["image"],
|
|
106
|
+
sourceFormat,
|
|
107
|
+
byteLength: bytes.byteLength,
|
|
108
|
+
...detected
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function isSupportedWithValues(input, values = DEFAULT_VALUES, expectedType = "") {
|
|
112
|
+
try {
|
|
113
|
+
const metadata = inspectWithValues(input, values, expectedType);
|
|
114
|
+
const hasCompleteTextureData = metadata.isDataComplete !== false;
|
|
115
|
+
const canEmitTexture = metadata.sourceFormat === "dds" && metadata.dataOffset > 0 && !!metadata.pixelFormat && hasCompleteTextureData;
|
|
116
|
+
const canEmitRgba = canDecodeDdsToRgba(metadata) && hasCompleteTextureData;
|
|
117
|
+
const textureUnsupportedReason = !metadata.pixelFormat ? "DDS texture format is not recognized yet." : !hasCompleteTextureData ? `DDS texture data is truncated: expected ${metadata.expectedDataBytes} bytes, got ${metadata.dataBytes}.` : "";
|
|
118
|
+
const variants = metadata.sourceFormat === "dds" ? [{
|
|
119
|
+
kind: "compressed",
|
|
120
|
+
payloadType: "texture",
|
|
121
|
+
codec: metadata.pixelFormat || metadata.textureFormat || "unknown",
|
|
122
|
+
supported: canEmitTexture && metadata.isCompressed,
|
|
123
|
+
nativeOnly: !!metadata.nativeTextureOnly,
|
|
124
|
+
reason: metadata.isCompressed ? textureUnsupportedReason : "DDS is not block-compressed."
|
|
125
|
+
}, {
|
|
126
|
+
kind: "texture",
|
|
127
|
+
payloadType: "texture",
|
|
128
|
+
codec: metadata.pixelFormat || metadata.textureFormat || "unknown",
|
|
129
|
+
supported: canEmitTexture,
|
|
130
|
+
reason: canEmitTexture ? "" : textureUnsupportedReason
|
|
131
|
+
}, {
|
|
132
|
+
kind: "rgba",
|
|
133
|
+
payloadType: "rgba",
|
|
134
|
+
codec: canEmitRgba ? isFloatPixelFormat(metadata.pixelFormat) ? "rgba32float" : "rgba8unorm" : "rgba8unorm",
|
|
135
|
+
supported: canEmitRgba,
|
|
136
|
+
reason: canEmitRgba ? "" : textureUnsupportedReason || (metadata.nativeTextureOnly ? `${metadata.pixelFormat} is available as a native compressed texture only; register a software decoder or alternate representation for RGBA fallback.` : "DDS RGBA decode is not implemented for this pixel format.")
|
|
137
|
+
}, {
|
|
138
|
+
kind: "raw",
|
|
139
|
+
payloadType: "raw",
|
|
140
|
+
codec: "dds",
|
|
141
|
+
supported: true
|
|
142
|
+
}] : [{
|
|
143
|
+
kind: "rgba",
|
|
144
|
+
codec: "rgba8",
|
|
145
|
+
supported: false,
|
|
146
|
+
reason: `${metadata.sourceFormat.toUpperCase()} RGBA decode is not implemented yet.`
|
|
147
|
+
}];
|
|
148
|
+
const preferredVariant = variants.find(v => v.supported && v.kind !== "raw") || variants.find(v => v.supported);
|
|
149
|
+
return {
|
|
150
|
+
format: metadata.sourceFormat,
|
|
151
|
+
source: values.source || "buffer",
|
|
152
|
+
supported: metadata.sourceFormat ? variants.some(v => v.supported && v.kind !== "raw") ? "full" : variants.some(v => v.supported) ? "partial" : "none" : "none",
|
|
153
|
+
confidence: metadata.sourceFormat ? 1 : 0,
|
|
154
|
+
preferred: preferredVariant?.codec || "",
|
|
155
|
+
reason: metadata.sourceFormat ? "Container/header recognized." : "Unrecognized image format.",
|
|
156
|
+
metadata,
|
|
157
|
+
variants,
|
|
158
|
+
warnings: [],
|
|
159
|
+
errors: []
|
|
160
|
+
};
|
|
161
|
+
} catch (error) {
|
|
162
|
+
return {
|
|
163
|
+
format: expectedType || values.inputType || "",
|
|
164
|
+
source: values.source || "buffer",
|
|
165
|
+
supported: "none",
|
|
166
|
+
confidence: 0,
|
|
167
|
+
preferred: "",
|
|
168
|
+
reason: error.message,
|
|
169
|
+
metadata: null,
|
|
170
|
+
variants: [],
|
|
171
|
+
warnings: [],
|
|
172
|
+
errors: [error.message]
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
function readWithValues(input, values = DEFAULT_VALUES, expectedType = "") {
|
|
177
|
+
const bytes = toBytes(input);
|
|
178
|
+
const metadata = inspectWithValues(bytes, values, expectedType);
|
|
179
|
+
if (values.emit === OUTPUT_RAW) {
|
|
180
|
+
return {
|
|
181
|
+
payloadType: "raw",
|
|
182
|
+
sourceFormat: metadata.sourceFormat,
|
|
183
|
+
metadata,
|
|
184
|
+
bytes
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
if (values.emit === OUTPUT_JSON || values.emit === DEBUG_OUTPUTS[metadata.sourceFormat]) {
|
|
188
|
+
return metadata;
|
|
189
|
+
}
|
|
190
|
+
if (values.emit === OUTPUT_TEXTURE && metadata.sourceFormat === "dds") {
|
|
191
|
+
return readDdsTexture(bytes, metadata);
|
|
192
|
+
}
|
|
193
|
+
if ((values.emit === OUTPUT_RGBA || values.emit === OUTPUT_IMAGE) && metadata.sourceFormat === "dds") {
|
|
194
|
+
return readDdsToRgba(bytes, metadata);
|
|
195
|
+
}
|
|
196
|
+
const error = new Error(`${metadata.sourceFormat}: emit "${values.emit}" is not implemented yet`);
|
|
197
|
+
error.code = "CJS_FORMAT_OUTPUT_NOT_IMPLEMENTED";
|
|
198
|
+
error.sourceFormat = metadata.sourceFormat;
|
|
199
|
+
error.emit = values.emit;
|
|
200
|
+
throw error;
|
|
201
|
+
}
|
|
202
|
+
function toJsonValue(value) {
|
|
203
|
+
if (value instanceof Uint8Array) {
|
|
204
|
+
return {
|
|
205
|
+
byteLength: value.byteLength
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
if (Array.isArray(value)) return value.map(toJsonValue);
|
|
209
|
+
if (value && typeof value === "object") {
|
|
210
|
+
const output = {};
|
|
211
|
+
for (const [key, entry] of Object.entries(value)) output[key] = toJsonValue(entry);
|
|
212
|
+
return output;
|
|
213
|
+
}
|
|
214
|
+
return value;
|
|
215
|
+
}
|
|
216
|
+
function inspectBytes(bytes) {
|
|
217
|
+
if (isPNG(bytes)) return inspectPNG(bytes);
|
|
218
|
+
if (isJPEG(bytes)) return inspectJPEG(bytes);
|
|
219
|
+
if (isDDS(bytes)) return inspectDDS(bytes);
|
|
220
|
+
if (isTGA(bytes)) return inspectTGA(bytes);
|
|
221
|
+
return {
|
|
222
|
+
sourceFormat: "",
|
|
223
|
+
width: 0,
|
|
224
|
+
height: 0
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
function isPNG(bytes) {
|
|
228
|
+
return bytes.byteLength >= 24 && bytes[0] === 0x89 && bytes[1] === 0x50 && bytes[2] === 0x4e && bytes[3] === 0x47 && bytes[4] === 0x0d && bytes[5] === 0x0a && bytes[6] === 0x1a && bytes[7] === 0x0a;
|
|
229
|
+
}
|
|
230
|
+
function isJPEG(bytes) {
|
|
231
|
+
return bytes.byteLength >= 4 && bytes[0] === 0xff && bytes[1] === 0xd8;
|
|
232
|
+
}
|
|
233
|
+
function isDDS(bytes) {
|
|
234
|
+
return bytes.byteLength >= DDS_HEADER_SIZE + 4 && bytes[0] === 0x44 && bytes[1] === 0x44 && bytes[2] === 0x53 && bytes[3] === 0x20 && readU32LE(bytes, 4) === DDS_HEADER_SIZE;
|
|
235
|
+
}
|
|
236
|
+
function isTGA(bytes) {
|
|
237
|
+
if (bytes.byteLength < 18) return false;
|
|
238
|
+
const imageType = bytes[2],
|
|
239
|
+
width = readU16LE(bytes, 12),
|
|
240
|
+
height = readU16LE(bytes, 14),
|
|
241
|
+
bpp = bytes[16];
|
|
242
|
+
return width > 0 && height > 0 && [1, 2, 3, 9, 10, 11].includes(imageType) && [8, 16, 24, 32].includes(bpp);
|
|
243
|
+
}
|
|
244
|
+
function inspectPNG(bytes) {
|
|
245
|
+
const colorType = bytes[25],
|
|
246
|
+
bitDepth = bytes[24];
|
|
247
|
+
return {
|
|
248
|
+
sourceFormat: "png",
|
|
249
|
+
width: readU32BE(bytes, 16),
|
|
250
|
+
height: readU32BE(bytes, 20),
|
|
251
|
+
bitDepth,
|
|
252
|
+
colorType,
|
|
253
|
+
channels: pngChannels(colorType),
|
|
254
|
+
pixelFormat: `png-${bitDepth}-${colorType}`,
|
|
255
|
+
isCompressed: false
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
function inspectJPEG(bytes) {
|
|
259
|
+
let offset = 2;
|
|
260
|
+
while (offset + 9 < bytes.byteLength) {
|
|
261
|
+
if (bytes[offset] !== 0xff) {
|
|
262
|
+
offset++;
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
const marker = bytes[offset + 1],
|
|
266
|
+
length = readU16BE(bytes, offset + 2);
|
|
267
|
+
if ([0xc0, 0xc1, 0xc2, 0xc3].includes(marker)) {
|
|
268
|
+
return {
|
|
269
|
+
sourceFormat: "jpeg",
|
|
270
|
+
width: readU16BE(bytes, offset + 7),
|
|
271
|
+
height: readU16BE(bytes, offset + 5),
|
|
272
|
+
channels: bytes[offset + 9],
|
|
273
|
+
marker,
|
|
274
|
+
pixelFormat: "jpeg-ycbcr",
|
|
275
|
+
isCompressed: true
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
offset += Math.max(length + 2, 2);
|
|
279
|
+
}
|
|
280
|
+
return {
|
|
281
|
+
sourceFormat: "jpeg",
|
|
282
|
+
width: 0,
|
|
283
|
+
height: 0,
|
|
284
|
+
channels: 0,
|
|
285
|
+
pixelFormat: "jpeg",
|
|
286
|
+
isCompressed: true
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
function inspectDDS(bytes) {
|
|
290
|
+
const headerSize = readU32LE(bytes, 4);
|
|
291
|
+
const pfOffset = DDS_PIXELFORMAT_OFFSET;
|
|
292
|
+
const pfFlags = readU32LE(bytes, pfOffset + 4);
|
|
293
|
+
const fourCcCode = readU32LE(bytes, pfOffset + 8);
|
|
294
|
+
const fourCc = String.fromCharCode(bytes[84], bytes[85], bytes[86], bytes[87]).replace(/\0+$/u, "");
|
|
295
|
+
const rgbBitCount = readU32LE(bytes, pfOffset + 12);
|
|
296
|
+
const rBitMask = readU32LE(bytes, pfOffset + 16);
|
|
297
|
+
const gBitMask = readU32LE(bytes, pfOffset + 20);
|
|
298
|
+
const bBitMask = readU32LE(bytes, pfOffset + 24);
|
|
299
|
+
const aBitMask = readU32LE(bytes, pfOffset + 28);
|
|
300
|
+
const caps2 = readU32LE(bytes, 112);
|
|
301
|
+
const isCube = !!(caps2 & DDSCAPS2_CUBEMAP);
|
|
302
|
+
const isVolume = !!(caps2 & DDSCAPS2_VOLUME);
|
|
303
|
+
const cubeFaces = getDdsCubeFaces(caps2);
|
|
304
|
+
const hasDx10 = fourCc === "DX10" && bytes.byteLength >= 148;
|
|
305
|
+
const dxgiFormat = hasDx10 ? readU32LE(bytes, 128) : 0;
|
|
306
|
+
const resourceDimension = hasDx10 ? readU32LE(bytes, 132) : 0;
|
|
307
|
+
const arraySize = hasDx10 ? readU32LE(bytes, 140) : 1;
|
|
308
|
+
const dataOffset = hasDx10 ? 148 : 128;
|
|
309
|
+
const pixelFormat = getDdsPixelFormat({
|
|
310
|
+
pfFlags,
|
|
311
|
+
fourCc,
|
|
312
|
+
fourCcCode,
|
|
313
|
+
rgbBitCount,
|
|
314
|
+
rBitMask,
|
|
315
|
+
gBitMask,
|
|
316
|
+
bBitMask,
|
|
317
|
+
aBitMask,
|
|
318
|
+
dxgiFormat
|
|
319
|
+
});
|
|
320
|
+
const width = readU32LE(bytes, 16);
|
|
321
|
+
const height = readU32LE(bytes, 12);
|
|
322
|
+
const depth = readU32LE(bytes, 24);
|
|
323
|
+
const mipCount = Math.max(readU32LE(bytes, 28), 1);
|
|
324
|
+
const dataBytes = Math.max(bytes.byteLength - dataOffset, 0);
|
|
325
|
+
const expectedDataBytes = pixelFormat ? getDdsExpectedDataBytes({
|
|
326
|
+
pixelFormat,
|
|
327
|
+
width,
|
|
328
|
+
height,
|
|
329
|
+
depth,
|
|
330
|
+
mipCount,
|
|
331
|
+
arraySize,
|
|
332
|
+
isCube,
|
|
333
|
+
isVolume
|
|
334
|
+
}) : null;
|
|
335
|
+
return {
|
|
336
|
+
sourceFormat: "dds",
|
|
337
|
+
headerSize,
|
|
338
|
+
width,
|
|
339
|
+
height,
|
|
340
|
+
depth,
|
|
341
|
+
mipCount,
|
|
342
|
+
pitchOrLinearSize: readU32LE(bytes, 20),
|
|
343
|
+
pfFlags,
|
|
344
|
+
fourCc,
|
|
345
|
+
fourCcCode,
|
|
346
|
+
rgbBitCount,
|
|
347
|
+
rBitMask,
|
|
348
|
+
gBitMask,
|
|
349
|
+
bBitMask,
|
|
350
|
+
aBitMask,
|
|
351
|
+
caps2,
|
|
352
|
+
hasDx10,
|
|
353
|
+
dxgiFormat,
|
|
354
|
+
resourceDimension,
|
|
355
|
+
arraySize,
|
|
356
|
+
dataOffset,
|
|
357
|
+
dataBytes,
|
|
358
|
+
expectedDataBytes,
|
|
359
|
+
isDataComplete: expectedDataBytes !== null && dataBytes >= expectedDataBytes,
|
|
360
|
+
missingDataBytes: expectedDataBytes === null ? null : Math.max(expectedDataBytes - dataBytes, 0),
|
|
361
|
+
extraDataBytes: expectedDataBytes === null ? null : Math.max(dataBytes - expectedDataBytes, 0),
|
|
362
|
+
faces: isCube ? 6 : 1,
|
|
363
|
+
cubeFaces,
|
|
364
|
+
isCubeComplete: isCube && cubeFaces.length === 6,
|
|
365
|
+
isCube,
|
|
366
|
+
isVolume,
|
|
367
|
+
dimension: isVolume ? "3d" : isCube ? "cube" : "2d",
|
|
368
|
+
pixelFormat,
|
|
369
|
+
textureFormat: pixelFormat || fourCc || "dds-legacy",
|
|
370
|
+
isCompressed: COMPRESSED_PIXEL_FORMATS.has(pixelFormat),
|
|
371
|
+
nativeTextureOnly: COMPRESSED_PIXEL_FORMATS.has(pixelFormat) && !canDecodeDdsToRgba({
|
|
372
|
+
pixelFormat
|
|
373
|
+
}),
|
|
374
|
+
hasAlpha: !!(pfFlags & DDS_ALPHAPIXELS) || /rgba|bgra/u.test(pixelFormat),
|
|
375
|
+
hasMipMaps: readU32LE(bytes, 28) > 1
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
function readDdsTexture(bytes, metadata) {
|
|
379
|
+
if (!metadata.pixelFormat) {
|
|
380
|
+
const error = new Error("dds: texture format is not recognized yet");
|
|
381
|
+
error.code = "CJS_FORMAT_OUTPUT_NOT_SUPPORTED";
|
|
382
|
+
error.sourceFormat = metadata.sourceFormat;
|
|
383
|
+
throw error;
|
|
384
|
+
}
|
|
385
|
+
const subresources = buildDdsSubresources(bytes, metadata);
|
|
386
|
+
return {
|
|
387
|
+
payloadType: OUTPUT_TEXTURE,
|
|
388
|
+
sourceFormat: "dds",
|
|
389
|
+
width: metadata.width,
|
|
390
|
+
height: metadata.height,
|
|
391
|
+
depth: metadata.depth,
|
|
392
|
+
faces: metadata.faces,
|
|
393
|
+
cubeFaces: metadata.cubeFaces,
|
|
394
|
+
isCubeComplete: metadata.isCubeComplete,
|
|
395
|
+
dimension: metadata.dimension,
|
|
396
|
+
mipCount: metadata.mipCount,
|
|
397
|
+
arraySize: metadata.arraySize,
|
|
398
|
+
pixelFormat: metadata.pixelFormat,
|
|
399
|
+
isCompressed: metadata.isCompressed,
|
|
400
|
+
dataBytes: metadata.dataBytes,
|
|
401
|
+
expectedDataBytes: metadata.expectedDataBytes,
|
|
402
|
+
isDataComplete: metadata.isDataComplete,
|
|
403
|
+
missingDataBytes: metadata.missingDataBytes,
|
|
404
|
+
extraDataBytes: metadata.extraDataBytes,
|
|
405
|
+
subresources,
|
|
406
|
+
metadata,
|
|
407
|
+
data: bytes.subarray(metadata.dataOffset, metadata.dataOffset + subresources.reduce((sum, entry) => sum + entry.byteLength, 0))
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
function canDecodeDdsToRgba(metadata) {
|
|
411
|
+
return ["rgba32float", "rgb32float", "rgba16float", "rg32float", "r32float", "r16float", "rgba8unorm", "rgba8unorm-srgb", "bgra8unorm", "bgra8unorm-srgb", "bgrx8unorm", "bgrx8unorm-srgb", "bgr8unorm", "rg8unorm", "r8unorm", "bc1-rgba-unorm", "bc1-rgba-unorm-srgb", "bc2-rgba-unorm", "bc2-rgba-unorm-srgb", "bc3-rgba-unorm", "bc3-rgba-unorm-srgb", "bc4-r-unorm", "bc4-r-snorm", "bc5-rg-unorm", "bc5-rg-snorm"].includes(metadata.pixelFormat);
|
|
412
|
+
}
|
|
413
|
+
function readDdsToRgba(bytes, metadata) {
|
|
414
|
+
if (!canDecodeDdsToRgba(metadata)) {
|
|
415
|
+
const error = new Error(`dds: RGBA decode is not implemented for ${metadata.pixelFormat || "unknown"}`);
|
|
416
|
+
error.code = "CJS_FORMAT_OUTPUT_NOT_SUPPORTED";
|
|
417
|
+
error.sourceFormat = metadata.sourceFormat;
|
|
418
|
+
throw error;
|
|
419
|
+
}
|
|
420
|
+
const subresource = buildDdsSubresources(bytes, metadata)[0];
|
|
421
|
+
const source = bytes.subarray(metadata.dataOffset + subresource.offset, metadata.dataOffset + subresource.offset + subresource.byteLength);
|
|
422
|
+
const rgba = metadata.pixelFormat.startsWith("bc1-") ? decodeBc1(source, metadata.width, metadata.height, subresource.rowPitch) : metadata.pixelFormat.startsWith("bc2-") ? decodeBc2(source, metadata.width, metadata.height, subresource.rowPitch) : metadata.pixelFormat.startsWith("bc3-") ? decodeBc3(source, metadata.width, metadata.height, subresource.rowPitch) : metadata.pixelFormat.startsWith("bc4-") ? decodeBc4(source, metadata.width, metadata.height, subresource.rowPitch, metadata.pixelFormat.endsWith("-snorm")) : metadata.pixelFormat.startsWith("bc5-") ? decodeBc5(source, metadata.width, metadata.height, subresource.rowPitch, metadata.pixelFormat.endsWith("-snorm")) : isFloatPixelFormat(metadata.pixelFormat) ? decodeFloatUncompressed(source, metadata) : decodeUncompressed(source, metadata);
|
|
423
|
+
const isFloat = isFloatPixelFormat(metadata.pixelFormat);
|
|
424
|
+
return {
|
|
425
|
+
payloadType: OUTPUT_RGBA,
|
|
426
|
+
sourceFormat: "dds",
|
|
427
|
+
width: metadata.width,
|
|
428
|
+
height: metadata.height,
|
|
429
|
+
pixelFormat: isFloat ? "rgba32float" : "rgba8unorm",
|
|
430
|
+
strideBytes: metadata.width * (isFloat ? 16 : 4),
|
|
431
|
+
origin: "top-left",
|
|
432
|
+
colorSpace: isFloat ? "linear" : metadata.pixelFormat.endsWith("-srgb") ? "srgb" : "unknown",
|
|
433
|
+
alphaMode: metadata.hasAlpha ? "straight" : "opaque",
|
|
434
|
+
metadata,
|
|
435
|
+
data: rgba
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
function buildDdsSubresources(bytes, metadata) {
|
|
439
|
+
const subresources = [];
|
|
440
|
+
let offset = 0;
|
|
441
|
+
const layers = Math.max(metadata.arraySize, 1) * (metadata.isCube ? 6 : 1);
|
|
442
|
+
for (let layer = 0; layer < layers; layer++) {
|
|
443
|
+
const arrayIndex = metadata.isCube ? Math.floor(layer / 6) : layer;
|
|
444
|
+
const face = metadata.isCube ? layer % 6 : 0;
|
|
445
|
+
for (let mip = 0; mip < metadata.mipCount; mip++) {
|
|
446
|
+
const width = Math.max(metadata.width >> mip, 1);
|
|
447
|
+
const height = Math.max(metadata.height >> mip, 1);
|
|
448
|
+
const depth = metadata.isVolume ? Math.max(metadata.depth >> mip, 1) : 1;
|
|
449
|
+
const layout = getDdsLevelLayout(metadata.pixelFormat, width, height, depth);
|
|
450
|
+
if (offset + layout.byteLength > bytes.byteLength - metadata.dataOffset) {
|
|
451
|
+
const error = new Error("dds: texture data is truncated");
|
|
452
|
+
error.code = "CJS_FORMAT_TRUNCATED";
|
|
453
|
+
error.sourceFormat = metadata.sourceFormat;
|
|
454
|
+
error.expectedDataBytes = metadata.expectedDataBytes;
|
|
455
|
+
error.dataBytes = metadata.dataBytes;
|
|
456
|
+
error.missingDataBytes = metadata.missingDataBytes;
|
|
457
|
+
throw error;
|
|
458
|
+
}
|
|
459
|
+
subresources.push({
|
|
460
|
+
mip,
|
|
461
|
+
layer,
|
|
462
|
+
arrayIndex,
|
|
463
|
+
face,
|
|
464
|
+
offset,
|
|
465
|
+
byteLength: layout.byteLength,
|
|
466
|
+
rowPitch: layout.rowPitch,
|
|
467
|
+
slicePitch: layout.slicePitch,
|
|
468
|
+
width,
|
|
469
|
+
height,
|
|
470
|
+
depth
|
|
471
|
+
});
|
|
472
|
+
offset += layout.byteLength;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
return subresources;
|
|
476
|
+
}
|
|
477
|
+
function getDdsExpectedDataBytes(metadata) {
|
|
478
|
+
let total = 0;
|
|
479
|
+
const layers = Math.max(metadata.arraySize, 1) * (metadata.isCube ? 6 : 1);
|
|
480
|
+
for (let layer = 0; layer < layers; layer++) {
|
|
481
|
+
for (let mip = 0; mip < metadata.mipCount; mip++) {
|
|
482
|
+
const width = Math.max(metadata.width >> mip, 1);
|
|
483
|
+
const height = Math.max(metadata.height >> mip, 1);
|
|
484
|
+
const depth = metadata.isVolume ? Math.max(metadata.depth >> mip, 1) : 1;
|
|
485
|
+
total += getDdsLevelLayout(metadata.pixelFormat, width, height, depth).byteLength;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
return total;
|
|
489
|
+
}
|
|
490
|
+
function getDdsCubeFaces(caps2) {
|
|
491
|
+
if (!(caps2 & DDSCAPS2_CUBEMAP)) {
|
|
492
|
+
return [];
|
|
493
|
+
}
|
|
494
|
+
return DDS_CUBE_FACE_FLAGS.filter(entry => !!(caps2 & entry[1])).map(entry => entry[0]);
|
|
495
|
+
}
|
|
496
|
+
function getDdsLevelLayout(pixelFormat, width, height, depth) {
|
|
497
|
+
const blockBytes = pixelFormat.startsWith("bc1-") || pixelFormat.startsWith("bc4-") ? 8 : pixelFormat.startsWith("bc") ? 16 : 0;
|
|
498
|
+
if (blockBytes) {
|
|
499
|
+
const blocksWide = Math.max(Math.ceil(width / 4), 1);
|
|
500
|
+
const blocksHigh = Math.max(Math.ceil(height / 4), 1);
|
|
501
|
+
const rowPitch = blocksWide * blockBytes;
|
|
502
|
+
const slicePitch = rowPitch * blocksHigh;
|
|
503
|
+
return {
|
|
504
|
+
rowPitch,
|
|
505
|
+
slicePitch,
|
|
506
|
+
byteLength: slicePitch * depth
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
const bytesPerPixel = {
|
|
510
|
+
"rgba32float": 16,
|
|
511
|
+
"rgb32float": 12,
|
|
512
|
+
"rgba16float": 8,
|
|
513
|
+
"rg32float": 8,
|
|
514
|
+
"r32float": 4,
|
|
515
|
+
"r16float": 2,
|
|
516
|
+
"rgba8unorm": 4,
|
|
517
|
+
"rgba8unorm-srgb": 4,
|
|
518
|
+
"bgra8unorm": 4,
|
|
519
|
+
"bgra8unorm-srgb": 4,
|
|
520
|
+
"bgrx8unorm": 4,
|
|
521
|
+
"bgrx8unorm-srgb": 4,
|
|
522
|
+
"bgr8unorm": 3,
|
|
523
|
+
"rg8unorm": 2,
|
|
524
|
+
"r8unorm": 1
|
|
525
|
+
}[pixelFormat];
|
|
526
|
+
if (!bytesPerPixel) {
|
|
527
|
+
const error = new Error(`dds: cannot calculate subresource layout for ${pixelFormat || "unknown"}`);
|
|
528
|
+
error.code = "CJS_FORMAT_OUTPUT_NOT_SUPPORTED";
|
|
529
|
+
throw error;
|
|
530
|
+
}
|
|
531
|
+
const rowPitch = width * bytesPerPixel;
|
|
532
|
+
const slicePitch = rowPitch * height;
|
|
533
|
+
return {
|
|
534
|
+
rowPitch,
|
|
535
|
+
slicePitch,
|
|
536
|
+
byteLength: slicePitch * depth
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
function decodeUncompressed(source, metadata) {
|
|
540
|
+
const rgba = new Uint8Array(metadata.width * metadata.height * 4);
|
|
541
|
+
const bytesPerPixel = metadata.pixelFormat === "bgr8unorm" ? 3 : metadata.pixelFormat === "rg8unorm" ? 2 : metadata.pixelFormat === "r8unorm" ? 1 : 4;
|
|
542
|
+
for (let pixel = 0; pixel < metadata.width * metadata.height; pixel++) {
|
|
543
|
+
const sourceOffset = pixel * bytesPerPixel;
|
|
544
|
+
const outputOffset = pixel * 4;
|
|
545
|
+
if (metadata.pixelFormat.startsWith("bgra") || metadata.pixelFormat.startsWith("bgrx")) {
|
|
546
|
+
rgba[outputOffset] = source[sourceOffset + 2];
|
|
547
|
+
rgba[outputOffset + 1] = source[sourceOffset + 1];
|
|
548
|
+
rgba[outputOffset + 2] = source[sourceOffset];
|
|
549
|
+
rgba[outputOffset + 3] = metadata.pixelFormat.startsWith("bgrx") ? 255 : source[sourceOffset + 3];
|
|
550
|
+
} else if (metadata.pixelFormat === "bgr8unorm") {
|
|
551
|
+
rgba[outputOffset] = source[sourceOffset + 2];
|
|
552
|
+
rgba[outputOffset + 1] = source[sourceOffset + 1];
|
|
553
|
+
rgba[outputOffset + 2] = source[sourceOffset];
|
|
554
|
+
rgba[outputOffset + 3] = 255;
|
|
555
|
+
} else if (metadata.pixelFormat === "rg8unorm") {
|
|
556
|
+
rgba[outputOffset] = source[sourceOffset];
|
|
557
|
+
rgba[outputOffset + 1] = source[sourceOffset + 1];
|
|
558
|
+
rgba[outputOffset + 2] = 0;
|
|
559
|
+
rgba[outputOffset + 3] = 255;
|
|
560
|
+
} else {
|
|
561
|
+
rgba[outputOffset] = source[sourceOffset];
|
|
562
|
+
rgba[outputOffset + 1] = bytesPerPixel > 1 ? source[sourceOffset + 1] : source[sourceOffset];
|
|
563
|
+
rgba[outputOffset + 2] = bytesPerPixel > 2 ? source[sourceOffset + 2] : source[sourceOffset];
|
|
564
|
+
rgba[outputOffset + 3] = bytesPerPixel > 3 ? source[sourceOffset + 3] : 255;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
return rgba;
|
|
568
|
+
}
|
|
569
|
+
function decodeFloatUncompressed(source, metadata) {
|
|
570
|
+
const rgba = new Float32Array(metadata.width * metadata.height * 4);
|
|
571
|
+
const view = new DataView(source.buffer, source.byteOffset, source.byteLength);
|
|
572
|
+
const bytesPerPixel = {
|
|
573
|
+
"rgba32float": 16,
|
|
574
|
+
"rgb32float": 12,
|
|
575
|
+
"rgba16float": 8,
|
|
576
|
+
"rg32float": 8,
|
|
577
|
+
"r32float": 4,
|
|
578
|
+
"r16float": 2
|
|
579
|
+
}[metadata.pixelFormat];
|
|
580
|
+
for (let pixel = 0; pixel < metadata.width * metadata.height; pixel++) {
|
|
581
|
+
const sourceOffset = pixel * bytesPerPixel;
|
|
582
|
+
const outputOffset = pixel * 4;
|
|
583
|
+
let red, green, blue, alpha;
|
|
584
|
+
if (metadata.pixelFormat === "rgba32float") {
|
|
585
|
+
red = view.getFloat32(sourceOffset, true);
|
|
586
|
+
green = view.getFloat32(sourceOffset + 4, true);
|
|
587
|
+
blue = view.getFloat32(sourceOffset + 8, true);
|
|
588
|
+
alpha = view.getFloat32(sourceOffset + 12, true);
|
|
589
|
+
} else if (metadata.pixelFormat === "rgb32float") {
|
|
590
|
+
red = view.getFloat32(sourceOffset, true);
|
|
591
|
+
green = view.getFloat32(sourceOffset + 4, true);
|
|
592
|
+
blue = view.getFloat32(sourceOffset + 8, true);
|
|
593
|
+
alpha = 1;
|
|
594
|
+
} else if (metadata.pixelFormat === "rgba16float") {
|
|
595
|
+
red = halfToFloat(view.getUint16(sourceOffset, true));
|
|
596
|
+
green = halfToFloat(view.getUint16(sourceOffset + 2, true));
|
|
597
|
+
blue = halfToFloat(view.getUint16(sourceOffset + 4, true));
|
|
598
|
+
alpha = halfToFloat(view.getUint16(sourceOffset + 6, true));
|
|
599
|
+
} else if (metadata.pixelFormat === "rg32float") {
|
|
600
|
+
red = view.getFloat32(sourceOffset, true);
|
|
601
|
+
green = view.getFloat32(sourceOffset + 4, true);
|
|
602
|
+
blue = 0;
|
|
603
|
+
alpha = 1;
|
|
604
|
+
} else {
|
|
605
|
+
red = metadata.pixelFormat === "r16float" ? halfToFloat(view.getUint16(sourceOffset, true)) : view.getFloat32(sourceOffset, true);
|
|
606
|
+
green = red;
|
|
607
|
+
blue = red;
|
|
608
|
+
alpha = 1;
|
|
609
|
+
}
|
|
610
|
+
rgba[outputOffset] = red;
|
|
611
|
+
rgba[outputOffset + 1] = green;
|
|
612
|
+
rgba[outputOffset + 2] = blue;
|
|
613
|
+
rgba[outputOffset + 3] = alpha;
|
|
614
|
+
}
|
|
615
|
+
return rgba;
|
|
616
|
+
}
|
|
617
|
+
function isFloatPixelFormat(pixelFormat) {
|
|
618
|
+
return ["rgba32float", "rgb32float", "rgba16float", "rg32float", "r32float", "r16float"].includes(pixelFormat);
|
|
619
|
+
}
|
|
620
|
+
function halfToFloat(value) {
|
|
621
|
+
const sign = value & 0x8000 ? -1 : 1;
|
|
622
|
+
const exponent = value >>> 10 & 0x1f;
|
|
623
|
+
const mantissa = value & 0x03ff;
|
|
624
|
+
if (exponent === 0) {
|
|
625
|
+
return sign * Math.pow(2, -14) * (mantissa / 1024);
|
|
626
|
+
}
|
|
627
|
+
if (exponent === 0x1f) {
|
|
628
|
+
return mantissa === 0 ? sign * Infinity : NaN;
|
|
629
|
+
}
|
|
630
|
+
return sign * Math.pow(2, exponent - 15) * (1 + mantissa / 1024);
|
|
631
|
+
}
|
|
632
|
+
function decodeBc1(source, width, height, rowPitch) {
|
|
633
|
+
const rgba = new Uint8Array(width * height * 4);
|
|
634
|
+
for (let blockY = 0; blockY < Math.ceil(height / 4); blockY++) {
|
|
635
|
+
for (let blockX = 0; blockX < Math.ceil(width / 4); blockX++) {
|
|
636
|
+
const blockOffset = blockY * rowPitch + blockX * 8;
|
|
637
|
+
const c0 = source[blockOffset] | source[blockOffset + 1] << 8;
|
|
638
|
+
const c1 = source[blockOffset + 2] | source[blockOffset + 3] << 8;
|
|
639
|
+
const colors = decodeBc1Colors(c0, c1);
|
|
640
|
+
const indices = source[blockOffset + 4] | source[blockOffset + 5] << 8 | source[blockOffset + 6] << 16 | source[blockOffset + 7] << 24;
|
|
641
|
+
for (let y = 0; y < 4; y++) {
|
|
642
|
+
for (let x = 0; x < 4; x++) {
|
|
643
|
+
const outputX = blockX * 4 + x;
|
|
644
|
+
const outputY = blockY * 4 + y;
|
|
645
|
+
if (outputX >= width || outputY >= height) continue;
|
|
646
|
+
const color = colors[indices >>> 2 * (y * 4 + x) & 3];
|
|
647
|
+
rgba.set(color, (outputY * width + outputX) * 4);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
return rgba;
|
|
653
|
+
}
|
|
654
|
+
function decodeBc2(source, width, height, rowPitch) {
|
|
655
|
+
return decodeBcAlphaColor(source, width, height, rowPitch, (blockOffset, x, y) => {
|
|
656
|
+
const alphaNibble = source[blockOffset + y * 2 + Math.floor(x / 2)] >>> x % 2 * 4 & 0x0f;
|
|
657
|
+
return alphaNibble * 17;
|
|
658
|
+
}, 8);
|
|
659
|
+
}
|
|
660
|
+
function decodeBc3(source, width, height, rowPitch) {
|
|
661
|
+
return decodeBcAlphaColor(source, width, height, rowPitch, (blockOffset, x, y) => {
|
|
662
|
+
const alpha0 = source[blockOffset],
|
|
663
|
+
alpha1 = source[blockOffset + 1];
|
|
664
|
+
const alphaValues = alpha0 > alpha1 ? [alpha0, alpha1, Math.round((6 * alpha0 + alpha1) / 7), Math.round((5 * alpha0 + 2 * alpha1) / 7), Math.round((4 * alpha0 + 3 * alpha1) / 7), Math.round((3 * alpha0 + 4 * alpha1) / 7), Math.round((2 * alpha0 + 5 * alpha1) / 7), Math.round((alpha0 + 6 * alpha1) / 7)] : [alpha0, alpha1, Math.round((4 * alpha0 + alpha1) / 5), Math.round((3 * alpha0 + 2 * alpha1) / 5), Math.round((2 * alpha0 + 3 * alpha1) / 5), Math.round((alpha0 + 4 * alpha1) / 5), 0, 255];
|
|
665
|
+
let alphaBits = 0n;
|
|
666
|
+
for (let i = 0; i < 6; i++) alphaBits |= BigInt(source[blockOffset + 2 + i]) << BigInt(i * 8);
|
|
667
|
+
return alphaValues[Number(alphaBits >> BigInt((y * 4 + x) * 3) & 7n)];
|
|
668
|
+
}, 8);
|
|
669
|
+
}
|
|
670
|
+
function decodeBc4(source, width, height, rowPitch, signed) {
|
|
671
|
+
const rgba = new Uint8Array(width * height * 4);
|
|
672
|
+
forEachBcPixel(width, height, rowPitch, 8, (blockOffset, x, y, outputOffset) => {
|
|
673
|
+
const value = decodeBc4Value(source, blockOffset, x, y, signed);
|
|
674
|
+
rgba[outputOffset] = value;
|
|
675
|
+
rgba[outputOffset + 1] = value;
|
|
676
|
+
rgba[outputOffset + 2] = value;
|
|
677
|
+
rgba[outputOffset + 3] = 255;
|
|
678
|
+
});
|
|
679
|
+
return rgba;
|
|
680
|
+
}
|
|
681
|
+
function decodeBc5(source, width, height, rowPitch, signed) {
|
|
682
|
+
const rgba = new Uint8Array(width * height * 4);
|
|
683
|
+
forEachBcPixel(width, height, rowPitch, 16, (blockOffset, x, y, outputOffset) => {
|
|
684
|
+
rgba[outputOffset] = decodeBc4Value(source, blockOffset, x, y, signed);
|
|
685
|
+
rgba[outputOffset + 1] = decodeBc4Value(source, blockOffset + 8, x, y, signed);
|
|
686
|
+
rgba[outputOffset + 2] = 0;
|
|
687
|
+
rgba[outputOffset + 3] = 255;
|
|
688
|
+
});
|
|
689
|
+
return rgba;
|
|
690
|
+
}
|
|
691
|
+
function decodeBc4Value(source, blockOffset, x, y, signed) {
|
|
692
|
+
const endpoint0 = signed ? decodeSnormByte(source[blockOffset]) : source[blockOffset];
|
|
693
|
+
const endpoint1 = signed ? decodeSnormByte(source[blockOffset + 1]) : source[blockOffset + 1];
|
|
694
|
+
const values = endpoint0 > endpoint1 ? [endpoint0, endpoint1, (6 * endpoint0 + endpoint1) / 7, (5 * endpoint0 + 2 * endpoint1) / 7, (4 * endpoint0 + 3 * endpoint1) / 7, (3 * endpoint0 + 4 * endpoint1) / 7, (2 * endpoint0 + 5 * endpoint1) / 7, (endpoint0 + 6 * endpoint1) / 7] : [endpoint0, endpoint1, (4 * endpoint0 + endpoint1) / 5, (3 * endpoint0 + 2 * endpoint1) / 5, (2 * endpoint0 + 3 * endpoint1) / 5, (endpoint0 + 4 * endpoint1) / 5, signed ? -1 : 0, signed ? 1 : 255];
|
|
695
|
+
let bits = 0n;
|
|
696
|
+
for (let i = 0; i < 6; i++) bits |= BigInt(source[blockOffset + 2 + i]) << BigInt(i * 8);
|
|
697
|
+
const value = values[Number(bits >> BigInt((y * 4 + x) * 3) & 7n)];
|
|
698
|
+
return signed ? Math.max(0, Math.min(255, Math.round((value + 1) * 127.5))) : Math.round(value);
|
|
699
|
+
}
|
|
700
|
+
function decodeSnormByte(value) {
|
|
701
|
+
const signed = value > 127 ? value - 256 : value;
|
|
702
|
+
return Math.max(-1, signed / 127);
|
|
703
|
+
}
|
|
704
|
+
function forEachBcPixel(width, height, rowPitch, blockBytes, callback) {
|
|
705
|
+
for (let blockY = 0; blockY < Math.ceil(height / 4); blockY++) {
|
|
706
|
+
for (let blockX = 0; blockX < Math.ceil(width / 4); blockX++) {
|
|
707
|
+
const blockOffset = blockY * rowPitch + blockX * blockBytes;
|
|
708
|
+
for (let y = 0; y < 4; y++) {
|
|
709
|
+
for (let x = 0; x < 4; x++) {
|
|
710
|
+
const outputX = blockX * 4 + x;
|
|
711
|
+
const outputY = blockY * 4 + y;
|
|
712
|
+
if (outputX < width && outputY < height) {
|
|
713
|
+
callback(blockOffset, x, y, (outputY * width + outputX) * 4);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
function decodeBcAlphaColor(source, width, height, rowPitch, alphaAt, colorOffset = 0) {
|
|
721
|
+
const rgba = new Uint8Array(width * height * 4);
|
|
722
|
+
for (let blockY = 0; blockY < Math.ceil(height / 4); blockY++) {
|
|
723
|
+
for (let blockX = 0; blockX < Math.ceil(width / 4); blockX++) {
|
|
724
|
+
const blockOffset = blockY * rowPitch + blockX * 16;
|
|
725
|
+
const colorOffsetInBlock = blockOffset + colorOffset;
|
|
726
|
+
const c0 = source[colorOffsetInBlock] | source[colorOffsetInBlock + 1] << 8;
|
|
727
|
+
const c1 = source[colorOffsetInBlock + 2] | source[colorOffsetInBlock + 3] << 8;
|
|
728
|
+
const colors = decodeBc1Colors(c0, c1, true);
|
|
729
|
+
const indices = source[colorOffsetInBlock + 4] | source[colorOffsetInBlock + 5] << 8 | source[colorOffsetInBlock + 6] << 16 | source[colorOffsetInBlock + 7] << 24;
|
|
730
|
+
for (let y = 0; y < 4; y++) {
|
|
731
|
+
for (let x = 0; x < 4; x++) {
|
|
732
|
+
const outputX = blockX * 4 + x;
|
|
733
|
+
const outputY = blockY * 4 + y;
|
|
734
|
+
if (outputX >= width || outputY >= height) continue;
|
|
735
|
+
const color = colors[indices >>> 2 * (y * 4 + x) & 3];
|
|
736
|
+
const outputOffset = (outputY * width + outputX) * 4;
|
|
737
|
+
rgba[outputOffset] = color[0];
|
|
738
|
+
rgba[outputOffset + 1] = color[1];
|
|
739
|
+
rgba[outputOffset + 2] = color[2];
|
|
740
|
+
rgba[outputOffset + 3] = alphaAt(blockOffset, x, y);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
return rgba;
|
|
746
|
+
}
|
|
747
|
+
function decodeBc1Colors(c0, c1, forceFourColor = false) {
|
|
748
|
+
const first = decode565(c0);
|
|
749
|
+
const second = decode565(c1);
|
|
750
|
+
const colors = [first, second];
|
|
751
|
+
if (c0 > c1 || forceFourColor) {
|
|
752
|
+
colors.push([Math.round((2 * first[0] + second[0]) / 3), Math.round((2 * first[1] + second[1]) / 3), Math.round((2 * first[2] + second[2]) / 3), 255], [Math.round((first[0] + 2 * second[0]) / 3), Math.round((first[1] + 2 * second[1]) / 3), Math.round((first[2] + 2 * second[2]) / 3), 255]);
|
|
753
|
+
} else {
|
|
754
|
+
colors.push([Math.round((first[0] + second[0]) / 2), Math.round((first[1] + second[1]) / 2), Math.round((first[2] + second[2]) / 2), 255], [0, 0, 0, 0]);
|
|
755
|
+
}
|
|
756
|
+
return colors;
|
|
757
|
+
}
|
|
758
|
+
function decode565(value) {
|
|
759
|
+
return [Math.round((value >>> 11 & 0x1f) * 255 / 31), Math.round((value >>> 5 & 0x3f) * 255 / 63), Math.round((value & 0x1f) * 255 / 31), 255];
|
|
760
|
+
}
|
|
761
|
+
function getDdsPixelFormat(format) {
|
|
762
|
+
if (format.dxgiFormat) return DXGI_PIXEL_FORMATS[format.dxgiFormat] || "";
|
|
763
|
+
if (format.pfFlags & DDS_FOURCC && format.fourCc) {
|
|
764
|
+
return FOURCC_PIXEL_FORMATS[format.fourCc] || {
|
|
765
|
+
113: "rgba16float",
|
|
766
|
+
116: "rgba32float"
|
|
767
|
+
}[format.fourCcCode] || "";
|
|
768
|
+
}
|
|
769
|
+
if (format.pfFlags & DDS_RGB) {
|
|
770
|
+
if (format.rgbBitCount === 32 && format.rBitMask === 0x000000ff && format.gBitMask === 0x0000ff00 && format.bBitMask === 0x00ff0000 && format.aBitMask === 0xff000000) return "rgba8unorm";
|
|
771
|
+
if (format.rgbBitCount === 32 && format.rBitMask === 0x00ff0000 && format.gBitMask === 0x0000ff00 && format.bBitMask === 0x000000ff && format.aBitMask === 0xff000000) return "bgra8unorm";
|
|
772
|
+
if (format.rgbBitCount === 24 && format.rBitMask === 0x00ff0000 && format.gBitMask === 0x0000ff00 && format.bBitMask === 0x000000ff) return "bgr8unorm";
|
|
773
|
+
}
|
|
774
|
+
return "";
|
|
775
|
+
}
|
|
776
|
+
function inspectTGA(bytes) {
|
|
777
|
+
return {
|
|
778
|
+
sourceFormat: "tga",
|
|
779
|
+
width: readU16LE(bytes, 12),
|
|
780
|
+
height: readU16LE(bytes, 14),
|
|
781
|
+
channels: Math.max(bytes[16] / 8, 1),
|
|
782
|
+
imageType: bytes[2],
|
|
783
|
+
pixelFormat: `tga-${bytes[16]}`,
|
|
784
|
+
isCompressed: [9, 10, 11].includes(bytes[2])
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
function pngChannels(colorType) {
|
|
788
|
+
if (colorType === 0) return 1;
|
|
789
|
+
if (colorType === 2) return 3;
|
|
790
|
+
if (colorType === 3) return 1;
|
|
791
|
+
if (colorType === 4) return 2;
|
|
792
|
+
if (colorType === 6) return 4;
|
|
793
|
+
return 0;
|
|
794
|
+
}
|
|
795
|
+
function readU16BE(bytes, offset) {
|
|
796
|
+
return bytes[offset] << 8 | bytes[offset + 1];
|
|
797
|
+
}
|
|
798
|
+
function readU16LE(bytes, offset) {
|
|
799
|
+
return bytes[offset] | bytes[offset + 1] << 8;
|
|
800
|
+
}
|
|
801
|
+
function readU32BE(bytes, offset) {
|
|
802
|
+
return bytes[offset] * 0x1000000 + (bytes[offset + 1] << 16 | bytes[offset + 2] << 8 | bytes[offset + 3]) >>> 0;
|
|
803
|
+
}
|
|
804
|
+
function readU32LE(bytes, offset) {
|
|
805
|
+
return (bytes[offset] | bytes[offset + 1] << 8 | bytes[offset + 2] << 16 | bytes[offset + 3] * 0x1000000) >>> 0;
|
|
806
|
+
}
|
|
807
|
+
function capitalize(value) {
|
|
808
|
+
return value ? value[0].toUpperCase() + value.slice(1) : "Image";
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
export { DEFAULT_VALUES, OUTPUT_IMAGE, OUTPUT_JSON, OUTPUT_RAW, OUTPUT_RGBA, OUTPUT_TEXTURE, inspectBytes, inspectWithValues, isDDS, isJPEG, isPNG, isSupportedWithValues, isTGA, normalizeEmit, normalizeInputType, normalizeValues, readWithValues, toBytes, toJsonValue };
|
|
812
|
+
//# sourceMappingURL=helpers.js.map
|