mscTranscoder.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import { Nullable } from '../../types';
  2. import { Transcoder, sourceTextureFormat, transcodeTarget } from './transcoder';
  3. import { KTX2FileReader, IKTX2_ImageDesc } from './KTX2FileReader';
  4. declare var MSC_TRANSCODER: any;
  5. declare function importScripts(...urls: string[]): void;
  6. /**
  7. * @hidden
  8. */
  9. export class MSCTranscoder extends Transcoder {
  10. private _mscBasisTranscoderPromise: Promise<any>;
  11. private _mscBasisModule: any;
  12. private _getMSCBasisTranscoder() {
  13. if (this._mscBasisTranscoderPromise) {
  14. return this._mscBasisTranscoderPromise;
  15. }
  16. this._mscBasisTranscoderPromise = new Promise((resolve) => {
  17. importScripts();
  18. MSC_TRANSCODER().then((basisModule: any) => {
  19. basisModule.initTranscoders();
  20. this._mscBasisModule = basisModule;
  21. resolve();
  22. });
  23. });
  24. return this._mscBasisTranscoderPromise;
  25. }
  26. public static CanTranscode(src: sourceTextureFormat, dst: transcodeTarget): boolean {
  27. return true;
  28. }
  29. public transcode(src: sourceTextureFormat, dst: transcodeTarget, level: number, width: number, height: number, uncompressedByteLength: number, ktx2Reader: KTX2FileReader, imageDesc: Nullable<IKTX2_ImageDesc>, encodedData: Uint8Array): Promise<Nullable<Uint8Array>> {
  30. const isVideo = false;
  31. return this._getMSCBasisTranscoder().then(() => {
  32. const basisModule = this._mscBasisModule;
  33. const TranscodeTarget: any = basisModule.TranscodeTarget;
  34. const TextureFormat: any = basisModule.TextureFormat;
  35. const ImageInfo: any = basisModule.ImageInfo;
  36. const transcoder = src === sourceTextureFormat.UASTC4x4 ? new basisModule.UastcImageTranscoder() : new basisModule.BasisLzEtc1sImageTranscoder();
  37. const texFormat = src === sourceTextureFormat.UASTC4x4 ? TextureFormat.UASTC4x4 : TextureFormat.ETC1S;
  38. const imageInfo = new ImageInfo(texFormat, width, height, level);
  39. const targetFormat = TranscodeTarget[transcodeTarget[dst]]; // works because the labels of the sourceTextureFormat enum are the same than the property names used in TranscodeTarget!
  40. if (!basisModule.isFormatSupported(targetFormat, texFormat)) {
  41. throw new Error(`MSCTranscoder: Transcoding from "${sourceTextureFormat[src]}" to "${transcodeTarget[dst]}" not supported by current transcoder build.`);
  42. }
  43. let result: any;
  44. if (src === sourceTextureFormat.ETC1S) {
  45. const sgd = ktx2Reader.supercompressionGlobalData;
  46. transcoder.decodePalettes(sgd.endpointCount, sgd.endpointsData, sgd.selectorCount, sgd.selectorsData);
  47. transcoder.decodeTables(sgd.tablesData);
  48. imageInfo.flags = imageDesc!.imageFlags;
  49. imageInfo.rgbByteOffset = 0;
  50. imageInfo.rgbByteLength = imageDesc!.rgbSliceByteLength;
  51. imageInfo.alphaByteOffset = imageDesc!.alphaSliceByteOffset > 0 ? imageDesc!.rgbSliceByteLength : 0;
  52. imageInfo.alphaByteLength = imageDesc!.alphaSliceByteLength;
  53. result = transcoder.transcodeImage(targetFormat, encodedData, imageInfo, 0, isVideo);
  54. } else {
  55. imageInfo.flags = 0;
  56. imageInfo.rgbByteOffset = 0;
  57. imageInfo.rgbByteLength = uncompressedByteLength;
  58. imageInfo.alphaByteOffset = 0;
  59. imageInfo.alphaByteLength = 0;
  60. result = transcoder.transcodeImage(targetFormat, encodedData, imageInfo, 0, ktx2Reader.hasAlpha, isVideo);
  61. }
  62. if (result && result.transcodedImage !== undefined) {
  63. const textureData = result.transcodedImage.get_typed_memory_view().slice();
  64. result.transcodedImage.delete();
  65. return textureData;
  66. }
  67. return null;
  68. });
  69. }
  70. }