mscTranscoder.ts 3.9 KB

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