@forgeax/engine-image 0.1.3 → 0.1.4

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.
@@ -762,9 +762,87 @@ async function importImage(ctx: ImportContext): Promise<ImportResult> {
762
762
  return { ok: true, value: { assets: out, sourceDependencies: [] } };
763
763
  }
764
764
 
765
+ /** Bind the image producer to the generic importer runner's decode seam. */
766
+ export const decodeImageForImport: ImportContext['decodeImage'] = async (
767
+ bytes,
768
+ mimeType,
769
+ importSettings,
770
+ ) => {
771
+ const colorSpace =
772
+ importSettings.colorSpace === 'srgb' || importSettings.colorSpace === 'linear'
773
+ ? importSettings.colorSpace
774
+ : 'linear';
775
+ const mipmap = importSettings.mipmap === true;
776
+ const downscaleMaxDimension =
777
+ typeof importSettings.downscaleMaxDimension === 'number' &&
778
+ Number.isInteger(importSettings.downscaleMaxDimension) &&
779
+ importSettings.downscaleMaxDimension > 0
780
+ ? importSettings.downscaleMaxDimension
781
+ : undefined;
782
+ const decoded = parseImage(bytes, mimeType, {
783
+ colorSpace,
784
+ mipmap,
785
+ ...(downscaleMaxDimension === undefined ? {} : { downscaleMaxDimension }),
786
+ });
787
+ if (!decoded.ok) return decoded;
788
+ const tex = decoded.value;
789
+ const requestedCompression =
790
+ importSettings.compressionMode === 'auto' ||
791
+ importSettings.compressionMode === 'etc1s' ||
792
+ importSettings.compressionMode === 'uastc' ||
793
+ importSettings.compressionMode === 'none'
794
+ ? importSettings.compressionMode
795
+ : 'none';
796
+ const resolvedCompression = resolveEncodeMode(requestedCompression, {
797
+ colorSpace,
798
+ isHdr: false,
799
+ });
800
+ let cookedBytes = tex.bytes;
801
+ let mediaType: string = mimeType;
802
+ let assetCodec: { name: string; profile?: string; version?: string } = {
803
+ name: 'rgba8',
804
+ version: '1',
805
+ };
806
+ if (resolvedCompression !== 'none') {
807
+ const encoded = await encodeTextureToKtx2(
808
+ tex.bytes,
809
+ tex.width,
810
+ tex.height,
811
+ requestedCompression,
812
+ { colorSpace, isHdr: false },
813
+ );
814
+ if (!encoded.ok) {
815
+ throw new Error(
816
+ `embedded texture compression failed (${encoded.error.code} / ${encoded.error.mode}): ${encoded.error.reason}`,
817
+ );
818
+ }
819
+ cookedBytes = encoded.value.ktx2;
820
+ mediaType = 'image/ktx2';
821
+ assetCodec = { name: 'basis', profile: encoded.value.mode };
822
+ }
823
+ return {
824
+ ok: true as const,
825
+ value: {
826
+ texture: {
827
+ kind: 'texture' as const,
828
+ data: cookedBytes,
829
+ width: tex.width,
830
+ height: tex.height,
831
+ format: colorSpaceToFormat(colorSpace),
832
+ colorSpace,
833
+ mipmap,
834
+ },
835
+ bytes: cookedBytes,
836
+ mediaType,
837
+ assetCodec,
838
+ },
839
+ };
840
+ };
841
+
765
842
  /**
766
843
  * The image {@link Importer}. Register it into an `ImporterRegistry` so the
767
- * import runner dispatches `meta.importer === 'image'` sidecars here.
844
+ * import runner dispatches `meta.importer === 'image'` sidecars here and can
845
+ * offer the same producer's decoder to importers with embedded images.
768
846
  *
769
847
  * @example
770
848
  * ```ts
@@ -777,4 +855,5 @@ async function importImage(ctx: ImportContext): Promise<ImportResult> {
777
855
  export const imageImporter: Importer = {
778
856
  key: 'image',
779
857
  import: importImage,
858
+ capabilities: { decodeImage: decodeImageForImport },
780
859
  };