pixi-basis-ktx2
Version:
Loader for the *.basis & *.ktx2 supercompressed texture file format. This package also ships with the transcoder!
114 lines • 5.12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TranscoderWorkerWrapperBasis = TranscoderWorkerWrapperBasis;
/**
* This wraps the transcoder web-worker functionality; it can be converted into a string to get the source code. It expects
* you to prepend the transcoder JavaScript code so that the `BASIS` namespace is available.
*
* The transcoder worker responds to two types of messages: "init" and "transcode". You must always send the first "init"
* {@link IInitializeTranscoderMessage} message with the WebAssembly binary; if the transcoder is successfully initialized,
* the web-worker will respond by sending another {@link ITranscodeResponse} message with `success: true`.
* @ignore
*/
function TranscoderWorkerWrapperBasis() {
let basisBinding;
const messageHandlers = {
init: (message) => {
if (!self.BASIS) {
console.warn('jsSource was not prepended?');
return {
type: 'init',
success: false,
};
}
void self.BASIS({ wasmBinary: message.wasmSource }).then((basisLibrary) => {
basisLibrary.initializeBasis();
basisBinding = basisLibrary;
self.postMessage({
type: 'init',
success: true,
});
});
return null;
},
transcode(message) {
const basisData = message.basisData;
const BASIS = basisBinding;
const data = basisData;
const basisFile = new BASIS.BasisFile(data);
const imageCount = basisFile.getNumImages();
const hasAlpha = basisFile.getHasAlpha();
const basisFormat = hasAlpha ? message.rgbaFormat : message.rgbFormat;
const basisFallbackFormat = 14; // BASIS_FORMATS.cTFRGB565 (cannot import values into web-worker!)
const imageArray = new Array(imageCount);
let fallbackMode = false;
if (!basisFile.startTranscoding()) {
basisFile.close();
basisFile.delete();
return {
type: 'transcode',
requestID: message.requestID,
success: false,
imageArray: undefined,
};
}
for (let i = 0; i < imageCount; i++) {
const levels = basisFile.getNumLevels(i);
const imageResource = {
imageID: i,
levelArray: new Array(),
};
for (let j = 0; j < levels; j++) {
const format = !fallbackMode ? basisFormat : basisFallbackFormat;
const width = basisFile.getImageWidth(i, j);
const height = basisFile.getImageHeight(i, j);
const byteSize = basisFile.getImageTranscodedSizeInBytes(i, j, format);
// Level 0 is texture's actual width, height
if (j === 0) {
const alignedWidth = (width + 3) & ~3;
const alignedHeight = (height + 3) & ~3;
imageResource.width = alignedWidth;
imageResource.height = alignedHeight;
}
const imageBuffer = new Uint8Array(byteSize);
if (!basisFile.transcodeImage(imageBuffer, i, j, format, false, false)) {
if (fallbackMode) {
// We failed in fallback mode as well!
console.error(`Basis failed to transcode image ${i}, level ${j}!`);
return { type: 'transcode', requestID: message.requestID, success: false };
}
/* eslint-disable-next-line max-len */
console.warn(`Basis failed to transcode image ${i}, level ${j}! Retrying to an uncompressed texture format!`);
i = -1;
fallbackMode = true;
break;
}
imageResource.levelArray.push({
levelID: j,
levelWidth: width,
levelHeight: height,
levelBuffer: imageBuffer,
});
}
imageArray[i] = imageResource;
}
basisFile.close();
basisFile.delete();
return {
type: 'transcode',
requestID: message.requestID,
success: true,
basisFormat: !fallbackMode ? basisFormat : basisFallbackFormat,
imageArray,
};
},
};
self.onmessage = (e) => {
const msg = e.data;
const response = messageHandlers[msg.type](msg);
if (response) {
self.postMessage(response);
}
};
}
//# sourceMappingURL=TranscoderWorkerWrapperBasis.js.map