"use strict"; (() => { // ../loader-utils/src/lib/env-utils/assert.ts function assert(condition, message) { if (!condition) { throw new Error(message || "loader assertion failed."); } } // ../loader-utils/src/lib/module-utils/js-module-utils.ts function registerJSModules(modules) { globalThis.loaders ||= {}; globalThis.loaders.modules ||= {}; Object.assign(globalThis.loaders.modules, modules); } function getJSModuleOrNull(name) { const module = globalThis.loaders?.modules?.[name]; return module || null; } // ../worker-utils/src/lib/env-utils/version.ts function getVersion() { if (!globalThis._loadersgl_?.version) { globalThis._loadersgl_ = globalThis._loadersgl_ || {}; if (false) { console.warn( "loaders.gl: The __VERSION__ variable is not injected using babel plugin. Latest unstable workers would be fetched from the CDN." ); globalThis._loadersgl_.version = NPM_TAG; } else { globalThis._loadersgl_.version = "4.3.1"; } } return globalThis._loadersgl_.version; } var VERSION = getVersion(); // ../worker-utils/src/lib/env-utils/assert.ts function assert2(condition, message) { if (!condition) { throw new Error(message || "loaders.gl assertion failed."); } } // ../worker-utils/src/lib/env-utils/globals.ts var globals = { self: typeof self !== "undefined" && self, window: typeof window !== "undefined" && window, global: typeof global !== "undefined" && global, document: typeof document !== "undefined" && document }; var self_ = globals.self || globals.window || globals.global || {}; var window_ = globals.window || globals.self || globals.global || {}; var global_ = globals.global || globals.self || globals.window || {}; var document_ = globals.document || {}; var isBrowser = ( // @ts-ignore process.browser typeof process !== "object" || String(process) !== "[object process]" || process.browser ); var isWorker = typeof importScripts === "function"; var isMobile = typeof window !== "undefined" && typeof window.orientation !== "undefined"; var matches = typeof process !== "undefined" && process.version && /v([0-9]*)/.exec(process.version); var nodeVersion = matches && parseFloat(matches[1]) || 0; // ../worker-utils/src/lib/node/worker_threads-browser.ts var parentPort = null; // ../worker-utils/src/lib/worker-utils/get-transfer-list.ts function getTransferList(object, recursive = true, transfers) { const transfersSet = transfers || /* @__PURE__ */ new Set(); if (!object) { } else if (isTransferable(object)) { transfersSet.add(object); } else if (isTransferable(object.buffer)) { transfersSet.add(object.buffer); } else if (ArrayBuffer.isView(object)) { } else if (recursive && typeof object === "object") { for (const key in object) { getTransferList(object[key], recursive, transfersSet); } } return transfers === void 0 ? Array.from(transfersSet) : []; } function isTransferable(object) { if (!object) { return false; } if (object instanceof ArrayBuffer) { return true; } if (typeof MessagePort !== "undefined" && object instanceof MessagePort) { return true; } if (typeof ImageBitmap !== "undefined" && object instanceof ImageBitmap) { return true; } if (typeof OffscreenCanvas !== "undefined" && object instanceof OffscreenCanvas) { return true; } return false; } // ../worker-utils/src/lib/worker-farm/worker-body.ts async function getParentPort() { return parentPort; } var onMessageWrapperMap = /* @__PURE__ */ new Map(); var WorkerBody = class { /** Check that we are actually in a worker thread */ static async inWorkerThread() { return typeof self !== "undefined" || Boolean(await getParentPort()); } /* * (type: WorkerMessageType, payload: WorkerMessagePayload) => any */ static set onmessage(onMessage) { async function handleMessage(message) { const parentPort2 = await getParentPort(); const { type, payload } = parentPort2 ? message : message.data; onMessage(type, payload); } getParentPort().then((parentPort2) => { if (parentPort2) { parentPort2.on("message", (message) => { handleMessage(message); }); parentPort2.on("exit", () => console.debug("Node worker closing")); } else { globalThis.onmessage = handleMessage; } }); } static async addEventListener(onMessage) { let onMessageWrapper = onMessageWrapperMap.get(onMessage); if (!onMessageWrapper) { onMessageWrapper = async (message) => { if (!isKnownMessage(message)) { return; } const parentPort3 = await getParentPort(); const { type, payload } = parentPort3 ? message : message.data; onMessage(type, payload); }; } const parentPort2 = await getParentPort(); if (parentPort2) { console.error("not implemented"); } else { globalThis.addEventListener("message", onMessageWrapper); } } static async removeEventListener(onMessage) { const onMessageWrapper = onMessageWrapperMap.get(onMessage); onMessageWrapperMap.delete(onMessage); const parentPort2 = await getParentPort(); if (parentPort2) { console.error("not implemented"); } else { globalThis.removeEventListener("message", onMessageWrapper); } } /** * Send a message from a worker to creating thread (main thread) * @param type * @param payload */ static async postMessage(type, payload) { const data = { source: "loaders.gl", type, payload }; const transferList = getTransferList(payload); const parentPort2 = await getParentPort(); if (parentPort2) { parentPort2.postMessage(data, transferList); } else { globalThis.postMessage(data, transferList); } } }; function isKnownMessage(message) { const { type, data } = message; return type === "message" && data && typeof data.source === "string" && data.source.startsWith("loaders.gl"); } // ../worker-utils/src/lib/library-utils/library-utils.ts var loadLibraryPromises = {}; async function loadLibrary(libraryUrl, moduleName = null, options = {}, libraryName = null) { if (moduleName) { libraryUrl = getLibraryUrl(libraryUrl, moduleName, options, libraryName); } loadLibraryPromises[libraryUrl] = // eslint-disable-next-line @typescript-eslint/no-misused-promises loadLibraryPromises[libraryUrl] || loadLibraryFromFile(libraryUrl); return await loadLibraryPromises[libraryUrl]; } function getLibraryUrl(library, moduleName, options = {}, libraryName = null) { if (!options.useLocalLibraries && library.startsWith("http")) { return library; } libraryName = libraryName || library; const modules = options.modules || {}; if (modules[libraryName]) { return modules[libraryName]; } if (!isBrowser) { return `modules/${moduleName}/dist/libs/${libraryName}`; } if (options.CDN) { assert2(options.CDN.startsWith("http")); return `${options.CDN}/${moduleName}@${VERSION}/dist/libs/${libraryName}`; } if (isWorker) { return `../src/libs/${libraryName}`; } return `modules/${moduleName}/src/libs/${libraryName}`; } async function loadLibraryFromFile(libraryUrl) { if (libraryUrl.endsWith("wasm")) { return await loadAsArrayBuffer(libraryUrl); } if (!isBrowser) { try { const { requireFromFile } = globalThis.loaders || {}; return await requireFromFile?.(libraryUrl); } catch (error) { console.error(error); return null; } } if (isWorker) { return importScripts(libraryUrl); } const scriptSource = await loadAsText(libraryUrl); return loadLibraryFromString(scriptSource, libraryUrl); } function loadLibraryFromString(scriptSource, id) { if (!isBrowser) { const { requireFromString } = globalThis.loaders || {}; return requireFromString?.(scriptSource, id); } if (isWorker) { eval.call(globalThis, scriptSource); return null; } const script = document.createElement("script"); script.id = id; try { script.appendChild(document.createTextNode(scriptSource)); } catch (e) { script.text = scriptSource; } document.body.appendChild(script); return null; } async function loadAsArrayBuffer(url) { const { readFileAsArrayBuffer } = globalThis.loaders || {}; if (isBrowser || !readFileAsArrayBuffer || url.startsWith("http")) { const response = await fetch(url); return await response.arrayBuffer(); } return await readFileAsArrayBuffer(url); } async function loadAsText(url) { const { readFileAsText } = globalThis.loaders || {}; if (isBrowser || !readFileAsText || url.startsWith("http")) { const response = await fetch(url); return await response.text(); } return await readFileAsText(url); } // ../loader-utils/src/lib/worker-loader-utils/create-loader-worker.ts var requestId = 0; async function createLoaderWorker(loader) { if (!await WorkerBody.inWorkerThread()) { return; } WorkerBody.onmessage = async (type, payload) => { switch (type) { case "process": try { const { input, options = {}, context = {} } = payload; const result = await parseData({ loader, arrayBuffer: input, options, // @ts-expect-error fetch missing context: { ...context, _parse: parseOnMainThread } }); WorkerBody.postMessage("done", { result }); } catch (error) { const message = error instanceof Error ? error.message : ""; WorkerBody.postMessage("error", { error: message }); } break; default: } }; } function parseOnMainThread(arrayBuffer, loader, options, context) { return new Promise((resolve, reject) => { const id = requestId++; const onMessage = (type, payload2) => { if (payload2.id !== id) { return; } switch (type) { case "done": WorkerBody.removeEventListener(onMessage); resolve(payload2.result); break; case "error": WorkerBody.removeEventListener(onMessage); reject(payload2.error); break; default: } }; WorkerBody.addEventListener(onMessage); const payload = { id, input: arrayBuffer, options }; WorkerBody.postMessage("process", payload); }); } async function parseData({ loader, arrayBuffer, options, context }) { let data; let parser; if (loader.parseSync || loader.parse) { data = arrayBuffer; parser = loader.parseSync || loader.parse; } else if (loader.parseTextSync) { const textDecoder = new TextDecoder(); data = textDecoder.decode(arrayBuffer); parser = loader.parseTextSync; } else { throw new Error(`Could not load data with ${loader.name} loader`); } options = { ...options, modules: loader && loader.options && loader.options.modules || {}, worker: false }; return await parser(data, { ...options }, context, loader); } // src/lib/utils/version.ts var VERSION2 = true ? "4.3.1" : "latest"; // ../../node_modules/ktx-parse/dist/ktx-parse.modern.js var KHR_SUPERCOMPRESSION_NONE = 0; var KHR_DF_KHR_DESCRIPTORTYPE_BASICFORMAT = 0; var KHR_DF_VENDORID_KHRONOS = 0; var KHR_DF_VERSION = 2; var KHR_DF_MODEL_UNSPECIFIED = 0; var KHR_DF_FLAG_ALPHA_STRAIGHT = 0; var KHR_DF_TRANSFER_SRGB = 2; var KHR_DF_PRIMARIES_BT709 = 1; var KHR_DF_SAMPLE_DATATYPE_SIGNED = 64; var VK_FORMAT_UNDEFINED = 0; var KTX2Container = class { constructor() { this.vkFormat = VK_FORMAT_UNDEFINED; this.typeSize = 1; this.pixelWidth = 0; this.pixelHeight = 0; this.pixelDepth = 0; this.layerCount = 0; this.faceCount = 1; this.supercompressionScheme = KHR_SUPERCOMPRESSION_NONE; this.levels = []; this.dataFormatDescriptor = [{ vendorId: KHR_DF_VENDORID_KHRONOS, descriptorType: KHR_DF_KHR_DESCRIPTORTYPE_BASICFORMAT, descriptorBlockSize: 0, versionNumber: KHR_DF_VERSION, colorModel: KHR_DF_MODEL_UNSPECIFIED, colorPrimaries: KHR_DF_PRIMARIES_BT709, transferFunction: KHR_DF_TRANSFER_SRGB, flags: KHR_DF_FLAG_ALPHA_STRAIGHT, texelBlockDimension: [0, 0, 0, 0], bytesPlane: [0, 0, 0, 0, 0, 0, 0, 0], samples: [] }]; this.keyValue = {}; this.globalData = null; } }; var BufferReader = class { constructor(data, byteOffset, byteLength, littleEndian) { this._dataView = void 0; this._littleEndian = void 0; this._offset = void 0; this._dataView = new DataView(data.buffer, data.byteOffset + byteOffset, byteLength); this._littleEndian = littleEndian; this._offset = 0; } _nextUint8() { const value = this._dataView.getUint8(this._offset); this._offset += 1; return value; } _nextUint16() { const value = this._dataView.getUint16(this._offset, this._littleEndian); this._offset += 2; return value; } _nextUint32() { const value = this._dataView.getUint32(this._offset, this._littleEndian); this._offset += 4; return value; } _nextUint64() { const left = this._dataView.getUint32(this._offset, this._littleEndian); const right = this._dataView.getUint32(this._offset + 4, this._littleEndian); const value = left + 2 ** 32 * right; this._offset += 8; return value; } _nextInt32() { const value = this._dataView.getInt32(this._offset, this._littleEndian); this._offset += 4; return value; } _nextUint8Array(len) { const value = new Uint8Array(this._dataView.buffer, this._dataView.byteOffset + this._offset, len); this._offset += len; return value; } _skip(bytes) { this._offset += bytes; return this; } _scan(maxByteLength, term = 0) { const byteOffset = this._offset; let byteLength = 0; while (this._dataView.getUint8(this._offset) !== term && byteLength < maxByteLength) { byteLength++; this._offset++; } if (byteLength < maxByteLength) this._offset++; return new Uint8Array(this._dataView.buffer, this._dataView.byteOffset + byteOffset, byteLength); } }; var NUL = new Uint8Array([0]); var KTX2_ID = [ // '´', 'K', 'T', 'X', '2', '0', 'ª', '\r', '\n', '\x1A', '\n' 171, 75, 84, 88, 32, 50, 48, 187, 13, 10, 26, 10 ]; function decodeText(buffer) { return new TextDecoder().decode(buffer); } function read(data) { const id = new Uint8Array(data.buffer, data.byteOffset, KTX2_ID.length); if (id[0] !== KTX2_ID[0] || // '´' id[1] !== KTX2_ID[1] || // 'K' id[2] !== KTX2_ID[2] || // 'T' id[3] !== KTX2_ID[3] || // 'X' id[4] !== KTX2_ID[4] || // ' ' id[5] !== KTX2_ID[5] || // '2' id[6] !== KTX2_ID[6] || // '0' id[7] !== KTX2_ID[7] || // 'ª' id[8] !== KTX2_ID[8] || // '\r' id[9] !== KTX2_ID[9] || // '\n' id[10] !== KTX2_ID[10] || // '\x1A' id[11] !== KTX2_ID[11]) { throw new Error("Missing KTX 2.0 identifier."); } const container = new KTX2Container(); const headerByteLength = 17 * Uint32Array.BYTES_PER_ELEMENT; const headerReader = new BufferReader(data, KTX2_ID.length, headerByteLength, true); container.vkFormat = headerReader._nextUint32(); container.typeSize = headerReader._nextUint32(); container.pixelWidth = headerReader._nextUint32(); container.pixelHeight = headerReader._nextUint32(); container.pixelDepth = headerReader._nextUint32(); container.layerCount = headerReader._nextUint32(); container.faceCount = headerReader._nextUint32(); const levelCount = headerReader._nextUint32(); container.supercompressionScheme = headerReader._nextUint32(); const dfdByteOffset = headerReader._nextUint32(); const dfdByteLength = headerReader._nextUint32(); const kvdByteOffset = headerReader._nextUint32(); const kvdByteLength = headerReader._nextUint32(); const sgdByteOffset = headerReader._nextUint64(); const sgdByteLength = headerReader._nextUint64(); const levelByteLength = levelCount * 3 * 8; const levelReader = new BufferReader(data, KTX2_ID.length + headerByteLength, levelByteLength, true); for (let i = 0; i < levelCount; i++) { container.levels.push({ levelData: new Uint8Array(data.buffer, data.byteOffset + levelReader._nextUint64(), levelReader._nextUint64()), uncompressedByteLength: levelReader._nextUint64() }); } const dfdReader = new BufferReader(data, dfdByteOffset, dfdByteLength, true); const dfd = { vendorId: dfdReader._skip( 4 /* totalSize */ )._nextUint16(), descriptorType: dfdReader._nextUint16(), versionNumber: dfdReader._nextUint16(), descriptorBlockSize: dfdReader._nextUint16(), colorModel: dfdReader._nextUint8(), colorPrimaries: dfdReader._nextUint8(), transferFunction: dfdReader._nextUint8(), flags: dfdReader._nextUint8(), texelBlockDimension: [dfdReader._nextUint8(), dfdReader._nextUint8(), dfdReader._nextUint8(), dfdReader._nextUint8()], bytesPlane: [dfdReader._nextUint8(), dfdReader._nextUint8(), dfdReader._nextUint8(), dfdReader._nextUint8(), dfdReader._nextUint8(), dfdReader._nextUint8(), dfdReader._nextUint8(), dfdReader._nextUint8()], samples: [] }; const sampleStart = 6; const sampleWords = 4; const numSamples = (dfd.descriptorBlockSize / 4 - sampleStart) / sampleWords; for (let i = 0; i < numSamples; i++) { const sample = { bitOffset: dfdReader._nextUint16(), bitLength: dfdReader._nextUint8(), channelType: dfdReader._nextUint8(), samplePosition: [dfdReader._nextUint8(), dfdReader._nextUint8(), dfdReader._nextUint8(), dfdReader._nextUint8()], sampleLower: -Infinity, sampleUpper: Infinity }; if (sample.channelType & KHR_DF_SAMPLE_DATATYPE_SIGNED) { sample.sampleLower = dfdReader._nextInt32(); sample.sampleUpper = dfdReader._nextInt32(); } else { sample.sampleLower = dfdReader._nextUint32(); sample.sampleUpper = dfdReader._nextUint32(); } dfd.samples[i] = sample; } container.dataFormatDescriptor.length = 0; container.dataFormatDescriptor.push(dfd); const kvdReader = new BufferReader(data, kvdByteOffset, kvdByteLength, true); while (kvdReader._offset < kvdByteLength) { const keyValueByteLength = kvdReader._nextUint32(); const keyData = kvdReader._scan(keyValueByteLength); const key = decodeText(keyData); container.keyValue[key] = kvdReader._nextUint8Array(keyValueByteLength - keyData.byteLength - 1); if (key.match(/^ktx/i)) { const text = decodeText(container.keyValue[key]); container.keyValue[key] = text.substring(0, text.lastIndexOf("\0")); } const kvPadding = keyValueByteLength % 4 ? 4 - keyValueByteLength % 4 : 0; kvdReader._skip(kvPadding); } if (sgdByteLength <= 0) return container; const sgdReader = new BufferReader(data, sgdByteOffset, sgdByteLength, true); const endpointCount = sgdReader._nextUint16(); const selectorCount = sgdReader._nextUint16(); const endpointsByteLength = sgdReader._nextUint32(); const selectorsByteLength = sgdReader._nextUint32(); const tablesByteLength = sgdReader._nextUint32(); const extendedByteLength = sgdReader._nextUint32(); const imageDescs = []; for (let i = 0; i < levelCount; i++) { imageDescs.push({ imageFlags: sgdReader._nextUint32(), rgbSliceByteOffset: sgdReader._nextUint32(), rgbSliceByteLength: sgdReader._nextUint32(), alphaSliceByteOffset: sgdReader._nextUint32(), alphaSliceByteLength: sgdReader._nextUint32() }); } const endpointsByteOffset = sgdByteOffset + sgdReader._offset; const selectorsByteOffset = endpointsByteOffset + endpointsByteLength; const tablesByteOffset = selectorsByteOffset + selectorsByteLength; const extendedByteOffset = tablesByteOffset + tablesByteLength; const endpointsData = new Uint8Array(data.buffer, data.byteOffset + endpointsByteOffset, endpointsByteLength); const selectorsData = new Uint8Array(data.buffer, data.byteOffset + selectorsByteOffset, selectorsByteLength); const tablesData = new Uint8Array(data.buffer, data.byteOffset + tablesByteOffset, tablesByteLength); const extendedData = new Uint8Array(data.buffer, data.byteOffset + extendedByteOffset, extendedByteLength); container.globalData = { endpointCount, selectorCount, imageDescs, endpointsData, selectorsData, tablesData, extendedData }; return container; } // src/lib/utils/extract-mipmap-images.ts function extractMipmapImages(data, options) { const images = new Array(options.mipMapLevels); let levelWidth = options.width; let levelHeight = options.height; let offset = 0; for (let i = 0; i < options.mipMapLevels; ++i) { const levelSize = getLevelSize(options, levelWidth, levelHeight, data, i); const levelData = getLevelData(data, i, offset, levelSize); images[i] = { compressed: true, format: options.internalFormat, data: levelData, width: levelWidth, height: levelHeight, levelSize }; levelWidth = Math.max(1, levelWidth >> 1); levelHeight = Math.max(1, levelHeight >> 1); offset += levelSize; } return images; } function getLevelData(data, index, offset, levelSize) { if (!Array.isArray(data)) { return new Uint8Array(data.buffer, data.byteOffset + offset, levelSize); } return data[index].levelData; } function getLevelSize(options, levelWidth, levelHeight, data, index) { if (!Array.isArray(data)) { return options.sizeFunction(levelWidth, levelHeight); } return options.sizeFunction(data[index]); } // src/lib/gl-extensions.ts var GL_EXTENSIONS_CONSTANTS = { // WEBGL_compressed_texture_s3tc COMPRESSED_RGB_S3TC_DXT1_EXT: 33776, COMPRESSED_RGBA_S3TC_DXT1_EXT: 33777, COMPRESSED_RGBA_S3TC_DXT3_EXT: 33778, COMPRESSED_RGBA_S3TC_DXT5_EXT: 33779, // WEBGL_compressed_texture_es3 COMPRESSED_R11_EAC: 37488, COMPRESSED_SIGNED_R11_EAC: 37489, COMPRESSED_RG11_EAC: 37490, COMPRESSED_SIGNED_RG11_EAC: 37491, COMPRESSED_RGB8_ETC2: 37492, COMPRESSED_RGBA8_ETC2_EAC: 37493, COMPRESSED_SRGB8_ETC2: 37494, COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: 37495, COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: 37496, COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: 37497, // WEBGL_compressed_texture_pvrtc COMPRESSED_RGB_PVRTC_4BPPV1_IMG: 35840, COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: 35842, COMPRESSED_RGB_PVRTC_2BPPV1_IMG: 35841, COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: 35843, // WEBGL_compressed_texture_etc1 COMPRESSED_RGB_ETC1_WEBGL: 36196, // WEBGL_compressed_texture_atc COMPRESSED_RGB_ATC_WEBGL: 35986, COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL: 35987, COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL: 34798, // WEBGL_compressed_texture_astc COMPRESSED_RGBA_ASTC_4X4_KHR: 37808, COMPRESSED_RGBA_ASTC_5X4_KHR: 37809, COMPRESSED_RGBA_ASTC_5X5_KHR: 37810, COMPRESSED_RGBA_ASTC_6X5_KHR: 37811, COMPRESSED_RGBA_ASTC_6X6_KHR: 37812, COMPRESSED_RGBA_ASTC_8X5_KHR: 37813, COMPRESSED_RGBA_ASTC_8X6_KHR: 37814, COMPRESSED_RGBA_ASTC_8X8_KHR: 37815, COMPRESSED_RGBA_ASTC_10X5_KHR: 37816, COMPRESSED_RGBA_ASTC_10X6_KHR: 37817, COMPRESSED_RGBA_ASTC_10X8_KHR: 37818, COMPRESSED_RGBA_ASTC_10X10_KHR: 37819, COMPRESSED_RGBA_ASTC_12X10_KHR: 37820, COMPRESSED_RGBA_ASTC_12X12_KHR: 37821, COMPRESSED_SRGB8_ALPHA8_ASTC_4X4_KHR: 37840, COMPRESSED_SRGB8_ALPHA8_ASTC_5X4_KHR: 37841, COMPRESSED_SRGB8_ALPHA8_ASTC_5X5_KHR: 37842, COMPRESSED_SRGB8_ALPHA8_ASTC_6X5_KHR: 37843, COMPRESSED_SRGB8_ALPHA8_ASTC_6X6_KHR: 37844, COMPRESSED_SRGB8_ALPHA8_ASTC_8X5_KHR: 37845, COMPRESSED_SRGB8_ALPHA8_ASTC_8X6_KHR: 37846, COMPRESSED_SRGB8_ALPHA8_ASTC_8X8_KHR: 37847, COMPRESSED_SRGB8_ALPHA8_ASTC_10X5_KHR: 37848, COMPRESSED_SRGB8_ALPHA8_ASTC_10X6_KHR: 37849, COMPRESSED_SRGB8_ALPHA8_ASTC_10X8_KHR: 37850, COMPRESSED_SRGB8_ALPHA8_ASTC_10X10_KHR: 37851, COMPRESSED_SRGB8_ALPHA8_ASTC_12X10_KHR: 37852, COMPRESSED_SRGB8_ALPHA8_ASTC_12X12_KHR: 37853, // EXT_texture_compression_rgtc COMPRESSED_RED_RGTC1_EXT: 36283, COMPRESSED_SIGNED_RED_RGTC1_EXT: 36284, COMPRESSED_RED_GREEN_RGTC2_EXT: 36285, COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: 36286, // WEBGL_compressed_texture_s3tc_srgb COMPRESSED_SRGB_S3TC_DXT1_EXT: 35916, COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: 35917, COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: 35918, COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: 35919 }; // src/lib/utils/ktx-format-helper.ts var VULKAN_TO_WEBGL_FORMAT_MAP = { 131: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_S3TC_DXT1_EXT, 132: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB_S3TC_DXT1_EXT, 133: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_S3TC_DXT1_EXT, 134: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 135: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_S3TC_DXT3_EXT, 136: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 137: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_S3TC_DXT5_EXT, 138: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 139: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RED_RGTC1_EXT, 140: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SIGNED_RED_RGTC1_EXT, 141: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RED_GREEN_RGTC2_EXT, 142: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT, 147: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB8_ETC2, 148: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ETC2, 149: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, 150: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 151: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA8_ETC2_EAC, 152: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, 153: GL_EXTENSIONS_CONSTANTS.COMPRESSED_R11_EAC, 154: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SIGNED_R11_EAC, 155: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RG11_EAC, 156: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SIGNED_RG11_EAC, // @ts-ignore 157: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_4x4_KHR, // @ts-ignore 158: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, // @ts-ignore 159: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_5x4_KHR, // @ts-ignore 160: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_5X4_KHR, // @ts-ignore 161: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_5x5_KHR, // @ts-ignore 162: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, // @ts-ignore 163: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_6x5_KHR, // @ts-ignore 164: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, // @ts-ignore 165: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_6x6_KHR, // @ts-ignore 166: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, // @ts-ignore 167: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_8x5_KHR, // @ts-ignore 168: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, // @ts-ignore 169: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_8x6_KHR, // @ts-ignore 170: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, // @ts-ignore 171: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_8x8_KHR, // @ts-ignore 172: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, // @ts-ignore 173: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_10x5_KHR, // @ts-ignore 174: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, // @ts-ignore 175: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_10x6_KHR, // @ts-ignore 176: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, // @ts-ignore 177: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_10x8_KHR, // @ts-ignore 178: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, // @ts-ignore 179: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_10x10_KHR, // @ts-ignore 180: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, // @ts-ignore 181: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_12x10_KHR, // @ts-ignore 182: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, // @ts-ignore 183: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_12x12_KHR, // @ts-ignore 184: GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, 1000054e3: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, 1000054001: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, // @ts-ignore 1000066e3: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_4x4_KHR, // @ts-ignore 1000066001: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_5x4_KHR, // @ts-ignore 1000066002: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_5x5_KHR, // @ts-ignore 1000066003: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_6x5_KHR, // @ts-ignore 1000066004: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_6x6_KHR, // @ts-ignore 1000066005: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_8x5_KHR, // @ts-ignore 1000066006: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_8x6_KHR, // @ts-ignore 1000066007: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_8x8_KHR, // @ts-ignore 1000066008: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_10x5_KHR, // @ts-ignore 1000066009: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_10x6_KHR, // @ts-ignore 1000066010: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_10x8_KHR, // @ts-ignore 1000066011: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_10x10_KHR, // @ts-ignore 1000066012: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_12x10_KHR, // @ts-ignore 1000066013: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_12x12_KHR }; function mapVkFormatToWebGL(vkFormat) { return VULKAN_TO_WEBGL_FORMAT_MAP[vkFormat]; } // src/lib/parsers/parse-ktx.ts var KTX2_ID2 = [ // '´', 'K', 'T', 'X', '2', '0', 'ª', '\r', '\n', '\x1A', '\n' 171, 75, 84, 88, 32, 50, 48, 187, 13, 10, 26, 10 ]; function isKTX(data) { const id = new Uint8Array(data); const notKTX = id.byteLength < KTX2_ID2.length || id[0] !== KTX2_ID2[0] || // '´' id[1] !== KTX2_ID2[1] || // 'K' id[2] !== KTX2_ID2[2] || // 'T' id[3] !== KTX2_ID2[3] || // 'X' id[4] !== KTX2_ID2[4] || // ' ' id[5] !== KTX2_ID2[5] || // '2' id[6] !== KTX2_ID2[6] || // '0' id[7] !== KTX2_ID2[7] || // 'ª' id[8] !== KTX2_ID2[8] || // '\r' id[9] !== KTX2_ID2[9] || // '\n' id[10] !== KTX2_ID2[10] || // '\x1A' id[11] !== KTX2_ID2[11]; return !notKTX; } function parseKTX(arrayBuffer) { const uint8Array = new Uint8Array(arrayBuffer); const ktx = read(uint8Array); const mipMapLevels = Math.max(1, ktx.levels.length); const width = ktx.pixelWidth; const height = ktx.pixelHeight; const internalFormat = mapVkFormatToWebGL(ktx.vkFormat); return extractMipmapImages(ktx.levels, { mipMapLevels, width, height, sizeFunction: (level) => level.uncompressedByteLength, internalFormat }); } // src/lib/parsers/parse-dds.ts var DDS_CONSTANTS = { MAGIC_NUMBER: 542327876, HEADER_LENGTH: 31, MAGIC_NUMBER_INDEX: 0, HEADER_SIZE_INDEX: 1, HEADER_FLAGS_INDEX: 2, HEADER_HEIGHT_INDEX: 3, HEADER_WIDTH_INDEX: 4, MIPMAPCOUNT_INDEX: 7, HEADER_PF_FLAGS_INDEX: 20, HEADER_PF_FOURCC_INDEX: 21, DDSD_MIPMAPCOUNT: 131072, DDPF_FOURCC: 4 }; var DDS_PIXEL_FORMATS = { DXT1: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_S3TC_DXT1_EXT, DXT3: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_S3TC_DXT3_EXT, DXT5: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_S3TC_DXT5_EXT, "ATC ": GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_ATC_WEBGL, ATCA: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL, ATCI: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL }; var getATCLevelSize = getDxt1LevelSize; var getATCALevelSize = getDxtXLevelSize; var getATCILevelSize = getDxtXLevelSize; var DDS_SIZE_FUNCTIONS = { DXT1: getDxt1LevelSize, DXT3: getDxtXLevelSize, DXT5: getDxtXLevelSize, "ATC ": getATCLevelSize, ATCA: getATCALevelSize, ATCI: getATCILevelSize }; function isDDS(data) { const header = new Uint32Array(data, 0, DDS_CONSTANTS.HEADER_LENGTH); const magic = header[DDS_CONSTANTS.MAGIC_NUMBER_INDEX]; return magic === DDS_CONSTANTS.MAGIC_NUMBER; } function parseDDS(data) { const header = new Int32Array(data, 0, DDS_CONSTANTS.HEADER_LENGTH); const pixelFormatNumber = header[DDS_CONSTANTS.HEADER_PF_FOURCC_INDEX]; assert( Boolean(header[DDS_CONSTANTS.HEADER_PF_FLAGS_INDEX] & DDS_CONSTANTS.DDPF_FOURCC), "DDS: Unsupported format, must contain a FourCC code" ); const fourCC = int32ToFourCC(pixelFormatNumber); const internalFormat = DDS_PIXEL_FORMATS[fourCC]; const sizeFunction = DDS_SIZE_FUNCTIONS[fourCC]; assert(internalFormat && sizeFunction, `DDS: Unknown pixel format ${pixelFormatNumber}`); let mipMapLevels = 1; if (header[DDS_CONSTANTS.HEADER_FLAGS_INDEX] & DDS_CONSTANTS.DDSD_MIPMAPCOUNT) { mipMapLevels = Math.max(1, header[DDS_CONSTANTS.MIPMAPCOUNT_INDEX]); } const width = header[DDS_CONSTANTS.HEADER_WIDTH_INDEX]; const height = header[DDS_CONSTANTS.HEADER_HEIGHT_INDEX]; const dataOffset = header[DDS_CONSTANTS.HEADER_SIZE_INDEX] + 4; const image = new Uint8Array(data, dataOffset); return extractMipmapImages(image, { mipMapLevels, width, height, sizeFunction, internalFormat }); } function getDxt1LevelSize(width, height) { return (width + 3 >> 2) * (height + 3 >> 2) * 8; } function getDxtXLevelSize(width, height) { return (width + 3 >> 2) * (height + 3 >> 2) * 16; } function int32ToFourCC(value) { return String.fromCharCode( value & 255, value >> 8 & 255, value >> 16 & 255, value >> 24 & 255 ); } // src/lib/parsers/parse-pvr.ts var PVR_CONSTANTS = { MAGIC_NUMBER: 55727696, MAGIC_NUMBER_EXTRA: 1347834371, HEADER_LENGTH: 13, HEADER_SIZE: 52, MAGIC_NUMBER_INDEX: 0, PIXEL_FORMAT_INDEX: 2, COLOUR_SPACE_INDEX: 4, HEIGHT_INDEX: 6, WIDTH_INDEX: 7, MIPMAPCOUNT_INDEX: 11, METADATA_SIZE_INDEX: 12 }; var PVR_PIXEL_FORMATS = { 0: [GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_PVRTC_2BPPV1_IMG], 1: [GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG], 2: [GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_PVRTC_4BPPV1_IMG], 3: [GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG], 6: [GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_ETC1_WEBGL], 7: [GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_S3TC_DXT1_EXT], 9: [GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_S3TC_DXT3_EXT], 11: [GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_S3TC_DXT5_EXT], 22: [GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB8_ETC2], 23: [GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA8_ETC2_EAC], 24: [GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2], 25: [GL_EXTENSIONS_CONSTANTS.COMPRESSED_R11_EAC], 26: [GL_EXTENSIONS_CONSTANTS.COMPRESSED_RG11_EAC], 27: [ GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_4X4_KHR, GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_4X4_KHR ], 28: [ GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_5X4_KHR, GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_5X4_KHR ], 29: [ GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_5X5_KHR, GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_5X5_KHR ], 30: [ GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_6X5_KHR, GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_6X5_KHR ], 31: [ GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_6X6_KHR, GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_6X6_KHR ], 32: [ GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_8X5_KHR, GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_8X5_KHR ], 33: [ GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_8X6_KHR, GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_8X6_KHR ], 34: [ GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_8X8_KHR, GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_8X8_KHR ], 35: [ GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_10X5_KHR, GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_10X5_KHR ], 36: [ GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_10X6_KHR, GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_10X6_KHR ], 37: [ GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_10X8_KHR, GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_10X8_KHR ], 38: [ GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_10X10_KHR, GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_10X10_KHR ], 39: [ GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_12X10_KHR, GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_12X10_KHR ], 40: [ GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_12X12_KHR, GL_EXTENSIONS_CONSTANTS.COMPRESSED_SRGB8_ALPHA8_ASTC_12X12_KHR ] }; var PVR_SIZE_FUNCTIONS = { 0: pvrtc2bppSize, 1: pvrtc2bppSize, 2: pvrtc4bppSize, 3: pvrtc4bppSize, 6: dxtEtcSmallSize, 7: dxtEtcSmallSize, 9: dxtEtcAstcBigSize, 11: dxtEtcAstcBigSize, 22: dxtEtcSmallSize, 23: dxtEtcAstcBigSize, 24: dxtEtcSmallSize, 25: dxtEtcSmallSize, 26: dxtEtcAstcBigSize, 27: dxtEtcAstcBigSize, 28: atc5x4Size, 29: atc5x5Size, 30: atc6x5Size, 31: atc6x6Size, 32: atc8x5Size, 33: atc8x6Size, 34: atc8x8Size, 35: atc10x5Size, 36: atc10x6Size, 37: atc10x8Size, 38: atc10x10Size, 39: atc12x10Size, 40: atc12x12Size }; function isPVR(data) { const header = new Uint32Array(data, 0, PVR_CONSTANTS.HEADER_LENGTH); const version = header[PVR_CONSTANTS.MAGIC_NUMBER_INDEX]; return version === PVR_CONSTANTS.MAGIC_NUMBER || version === PVR_CONSTANTS.MAGIC_NUMBER_EXTRA; } function parsePVR(data) { const header = new Uint32Array(data, 0, PVR_CONSTANTS.HEADER_LENGTH); const pvrFormat = header[PVR_CONSTANTS.PIXEL_FORMAT_INDEX]; const colourSpace = header[PVR_CONSTANTS.COLOUR_SPACE_INDEX]; const pixelFormats = PVR_PIXEL_FORMATS[pvrFormat] || []; const internalFormat = pixelFormats.length > 1 && colourSpace ? pixelFormats[1] : pixelFormats[0]; const sizeFunction = PVR_SIZE_FUNCTIONS[pvrFormat]; const mipMapLevels = header[PVR_CONSTANTS.MIPMAPCOUNT_INDEX]; const width = header[PVR_CONSTANTS.WIDTH_INDEX]; const height = header[PVR_CONSTANTS.HEIGHT_INDEX]; const dataOffset = PVR_CONSTANTS.HEADER_SIZE + header[PVR_CONSTANTS.METADATA_SIZE_INDEX]; const image = new Uint8Array(data, dataOffset); return extractMipmapImages(image, { mipMapLevels, width, height, sizeFunction, internalFormat }); } function pvrtc2bppSize(width, height) { width = Math.max(width, 16); height = Math.max(height, 8); return width * height / 4; } function pvrtc4bppSize(width, height) { width = Math.max(width, 8); height = Math.max(height, 8); return width * height / 2; } function dxtEtcSmallSize(width, height) { return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 8; } function dxtEtcAstcBigSize(width, height) { return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 16; } function atc5x4Size(width, height) { return Math.floor((width + 4) / 5) * Math.floor((height + 3) / 4) * 16; } function atc5x5Size(width, height) { return Math.floor((width + 4) / 5) * Math.floor((height + 4) / 5) * 16; } function atc6x5Size(width, height) { return Math.floor((width + 5) / 6) * Math.floor((height + 4) / 5) * 16; } function atc6x6Size(width, height) { return Math.floor((width + 5) / 6) * Math.floor((height + 5) / 6) * 16; } function atc8x5Size(width, height) { return Math.floor((width + 7) / 8) * Math.floor((height + 4) / 5) * 16; } function atc8x6Size(width, height) { return Math.floor((width + 7) / 8) * Math.floor((height + 5) / 6) * 16; } function atc8x8Size(width, height) { return Math.floor((width + 7) / 8) * Math.floor((height + 7) / 8) * 16; } function atc10x5Size(width, height) { return Math.floor((width + 9) / 10) * Math.floor((height + 4) / 5) * 16; } function atc10x6Size(width, height) { return Math.floor((width + 9) / 10) * Math.floor((height + 5) / 6) * 16; } function atc10x8Size(width, height) { return Math.floor((width + 9) / 10) * Math.floor((height + 7) / 8) * 16; } function atc10x10Size(width, height) { return Math.floor((width + 9) / 10) * Math.floor((height + 9) / 10) * 16; } function atc12x10Size(width, height) { return Math.floor((width + 11) / 12) * Math.floor((height + 9) / 10) * 16; } function atc12x12Size(width, height) { return Math.floor((width + 11) / 12) * Math.floor((height + 11) / 12) * 16; } // src/lib/parsers/parse-compressed-texture.ts function parseCompressedTexture(data) { if (isKTX(data)) { return parseKTX(data); } if (isDDS(data)) { return parseDDS(data); } if (isPVR(data)) { return parsePVR(data); } throw new Error("Texture container format not recognized"); } // src/lib/parsers/basis-module-loader.ts var BASIS_EXTERNAL_LIBRARIES = { /** Basis transcoder, javascript wrapper part */ TRANSCODER: "basis_transcoder.js", /** Basis transcoder, compiled web assembly part */ TRANSCODER_WASM: "basis_transcoder.wasm", /** Basis encoder, javascript wrapper part */ ENCODER: "basis_encoder.js", /** Basis encoder, compiled web assembly part */ ENCODER_WASM: "basis_encoder.wasm" }; var loadBasisTranscoderPromise; async function loadBasisTranscoderModule(options) { registerJSModules(options.modules); const basis = getJSModuleOrNull("basis"); if (basis) { return basis; } loadBasisTranscoderPromise ||= loadBasisTranscoder(options); return await loadBasisTranscoderPromise; } async function loadBasisTranscoder(options) { let BASIS = null; let wasmBinary = null; [BASIS, wasmBinary] = await Promise.all([ await loadLibrary(BASIS_EXTERNAL_LIBRARIES.TRANSCODER, "textures", options), await loadLibrary(BASIS_EXTERNAL_LIBRARIES.TRANSCODER_WASM, "textures", options) ]); BASIS = BASIS || globalThis.BASIS; return await initializeBasisTranscoderModule(BASIS, wasmBinary); } function initializeBasisTranscoderModule(BasisModule, wasmBinary) { const options = {}; if (wasmBinary) { options.wasmBinary = wasmBinary; } return new Promise((resolve) => { BasisModule(options).then((module) => { const { BasisFile, initializeBasis } = module; initializeBasis(); resolve({ BasisFile }); }); }); } var loadBasisEncoderPromise; async function loadBasisEncoderModule(options) { const modules = options.modules || {}; if (modules.basisEncoder) { return modules.basisEncoder; } loadBasisEncoderPromise = loadBasisEncoderPromise || loadBasisEncoder(options); return await loadBasisEncoderPromise; } async function loadBasisEncoder(options) { let BASIS_ENCODER = null; let wasmBinary = null; [BASIS_ENCODER, wasmBinary] = await Promise.all([ await loadLibrary(BASIS_EXTERNAL_LIBRARIES.ENCODER, "textures", options), await loadLibrary(BASIS_EXTERNAL_LIBRARIES.ENCODER_WASM, "textures", options) ]); BASIS_ENCODER = BASIS_ENCODER || globalThis.BASIS; return await initializeBasisEncoderModule(BASIS_ENCODER, wasmBinary); } function initializeBasisEncoderModule(BasisEncoderModule, wasmBinary) { const options = {}; if (wasmBinary) { options.wasmBinary = wasmBinary; } return new Promise((resolve) => { BasisEncoderModule(options).then((module) => { const { BasisFile, KTX2File, initializeBasis, BasisEncoder } = module; initializeBasis(); resolve({ BasisFile, KTX2File, BasisEncoder }); }); }); } // src/lib/utils/texture-formats.ts var BROWSER_PREFIXES = ["", "WEBKIT_", "MOZ_"]; var WEBGL_EXTENSIONS = { /* eslint-disable camelcase */ WEBGL_compressed_texture_s3tc: "dxt", WEBGL_compressed_texture_s3tc_srgb: "dxt-srgb", WEBGL_compressed_texture_etc1: "etc1", WEBGL_compressed_texture_etc: "etc2", WEBGL_compressed_texture_pvrtc: "pvrtc", WEBGL_compressed_texture_atc: "atc", WEBGL_compressed_texture_astc: "astc", EXT_texture_compression_rgtc: "rgtc" /* eslint-enable camelcase */ }; var formats = null; function getSupportedGPUTextureFormats(gl) { if (!formats) { gl = gl || getWebGLContext() || void 0; formats = /* @__PURE__ */ new Set(); for (const prefix of BROWSER_PREFIXES) { for (const extension in WEBGL_EXTENSIONS) { if (gl && gl.getExtension(`${prefix}${extension}`)) { const gpuTextureFormat = WEBGL_EXTENSIONS[extension]; formats.add(gpuTextureFormat); } } } } return formats; } function getWebGLContext() { try { const canvas = document.createElement("canvas"); return canvas.getContext("webgl"); } catch (error) { return null; } } // src/lib/parsers/parse-basis.ts var OutputFormat = { etc1: { basisFormat: 0, compressed: true, format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_ETC1_WEBGL }, etc2: { basisFormat: 1, compressed: true }, bc1: { basisFormat: 2, compressed: true, format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_S3TC_DXT1_EXT }, bc3: { basisFormat: 3, compressed: true, format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_S3TC_DXT5_EXT }, bc4: { basisFormat: 4, compressed: true }, bc5: { basisFormat: 5, compressed: true }, "bc7-m6-opaque-only": { basisFormat: 6, compressed: true }, "bc7-m5": { basisFormat: 7, compressed: true }, "pvrtc1-4-rgb": { basisFormat: 8, compressed: true, format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGB_PVRTC_4BPPV1_IMG }, "pvrtc1-4-rgba": { basisFormat: 9, compressed: true, format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG }, "astc-4x4": { basisFormat: 10, compressed: true, format: GL_EXTENSIONS_CONSTANTS.COMPRESSED_RGBA_ASTC_4X4_KHR }, "atc-rgb": { basisFormat: 11, compressed: true }, "atc-rgba-interpolated-alpha": { basisFormat: 12, compressed: true }, rgba32: { basisFormat: 13, compressed: false }, rgb565: { basisFormat: 14, compressed: false }, bgr565: { basisFormat: 15, compressed: false }, rgba4444: { basisFormat: 16, compressed: false } }; async function parseBasis(data, options) { if (options.basis.containerFormat === "auto") { if (isKTX(data)) { const fileConstructors = await loadBasisEncoderModule(options); return parseKTX2File(fileConstructors.KTX2File, data, options); } const { BasisFile } = await loadBasisTranscoderModule(options); return parseBasisFile(BasisFile, data, options); } switch (options.basis.module) { case "encoder": const fileConstructors = await loadBasisEncoderModule(options); switch (options.basis.containerFormat) { case "ktx2": return parseKTX2File(fileConstructors.KTX2File, data, options); case "basis": default: return parseBasisFile(fileConstructors.BasisFile, data, options); } case "transcoder": default: const { BasisFile } = await loadBasisTranscoderModule(options); return parseBasisFile(BasisFile, data, options); } } function parseBasisFile(BasisFile, data, options) { const basisFile = new BasisFile(new Uint8Array(data)); try { if (!basisFile.startTranscoding()) { throw new Error("Failed to start basis transcoding"); } const imageCount = basisFile.getNumImages(); const images = []; for (let imageIndex = 0; imageIndex < imageCount; imageIndex++) { const levelsCount = basisFile.getNumLevels(imageIndex); const levels = []; for (let levelIndex = 0; levelIndex < levelsCount; levelIndex++) { levels.push(transcodeImage(basisFile, imageIndex, levelIndex, options)); } images.push(levels); } return images; } finally { basisFile.close(); basisFile.delete(); } } function transcodeImage(basisFile, imageIndex, levelIndex, options) { const width = basisFile.getImageWidth(imageIndex, levelIndex); const height = basisFile.getImageHeight(imageIndex, levelIndex); const hasAlpha = basisFile.getHasAlpha( /* imageIndex, levelIndex */ ); const { compressed, format, basisFormat } = getBasisOptions(options, hasAlpha); const decodedSize = basisFile.getImageTranscodedSizeInBytes(imageIndex, levelIndex, basisFormat); const decodedData = new Uint8Array(decodedSize); if (!basisFile.transcodeImage(decodedData, imageIndex, levelIndex, basisFormat, 0, 0)) { throw new Error("failed to start Basis transcoding"); } return { // standard loaders.gl image category payload width, height, data: decodedData, compressed, format, // Additional fields // Add levelSize field. hasAlpha }; } function parseKTX2File(KTX2File, data, options) { const ktx2File = new KTX2File(new Uint8Array(data)); try { if (!ktx2File.startTranscoding()) { throw new Error("failed to start KTX2 transcoding"); } const levelsCount = ktx2File.getLevels(); const levels = []; for (let levelIndex = 0; levelIndex < levelsCount; levelIndex++) { levels.push(transcodeKTX2Image(ktx2File, levelIndex, options)); } return [levels]; } finally { ktx2File.close(); ktx2File.delete(); } } function transcodeKTX2Image(ktx2File, levelIndex, options) { const { alphaFlag, height, width } = ktx2File.getImageLevelInfo(levelIndex, 0, 0); const { compressed, format, basisFormat } = getBasisOptions(options, alphaFlag); const decodedSize = ktx2File.getImageTranscodedSizeInBytes( levelIndex, 0, 0, basisFormat ); const decodedData = new Uint8Array(decodedSize); if (!ktx2File.transcodeImage( decodedData, levelIndex, 0, 0, basisFormat, 0, -1, -1 /* channel1 */ )) { throw new Error("Failed to transcode KTX2 image"); } return { // standard loaders.gl image category payload width, height, data: decodedData, compressed, // Additional fields levelSize: decodedSize, hasAlpha: alphaFlag, format }; } function getBasisOptions(options, hasAlpha) { let format = options && options.basis && options.basis.format; if (format === "auto") { format = selectSupportedBasisFormat(); } if (typeof format === "object") { format = hasAlpha ? format.alpha : format.noAlpha; } format = format.toLowerCase(); return OutputFormat[format]; } function selectSupportedBasisFormat() { const supportedFormats = getSupportedGPUTextureFormats(); if (supportedFormats.has("astc")) { return "astc-4x4"; } else if (supportedFormats.has("dxt")) { return { alpha: "bc3", noAlpha: "bc1" }; } else if (supportedFormats.has("pvrtc")) { return { alpha: "pvrtc1-4-rgba", noAlpha: "pvrtc1-4-rgb" }; } else if (supportedFormats.has("etc1")) { return "etc1"; } else if (supportedFormats.has("etc2")) { return "etc2"; } return "rgb565"; } // src/compressed-texture-loader.ts var CompressedTextureWorkerLoader = { dataType: null, batchType: null, name: "Texture Containers", id: "compressed-texture", module: "textures", version: VERSION2, worker: true, extensions: [ "ktx", "ktx2", "dds", // WEBGL_compressed_texture_s3tc, WEBGL_compressed_texture_atc "pvr" // WEBGL_compressed_texture_pvrtc ], mimeTypes: [ "image/ktx2", "image/ktx", "image/vnd-ms.dds", "image/x-dds", "application/octet-stream" ], binary: true, options: { "compressed-texture": { libraryPath: "libs/", useBasis: false } } }; var CompressedTextureLoader = { ...CompressedTextureWorkerLoader, parse: async (arrayBuffer, options) => { if (options?.["compressed-texture"]?.useBasis) { options.basis = { format: { alpha: "BC3", noAlpha: "BC1" }, // @ts-expect-error TODO not allowed to modify inputs ...options.basis, containerFormat: "ktx2", module: "encoder" }; const result = await parseBasis(arrayBuffer, options); return result[0]; } return parseCompressedTexture(arrayBuffer); } }; // src/workers/compressed-texture-worker.ts createLoaderWorker(CompressedTextureLoader); })();