@loaders.gl/textures
Version:
Framework-independent loaders for compressed and super compressed (basis) textures
710 lines (691 loc) • 26.2 kB
JavaScript
;
(() => {
// ../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;
warningIssued = true;
} else {
globalThis._loadersgl_.version = "4.4.2";
}
}
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 = {};
function extractLoadLibraryOptions(options = {}) {
const useLocalLibraries = options.useLocalLibraries ?? options.core?.useLocalLibraries;
const CDN = options.CDN ?? options.core?.CDN;
const modules = options.modules;
return {
...useLocalLibraries !== void 0 ? { useLocalLibraries } : {},
...CDN !== void 0 ? { CDN } : {},
...modules !== void 0 ? { modules } : {}
};
}
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?.core) {
throw new Error("loadLibrary: options.core must be pre-normalized");
}
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) {
const { requireFromFile } = globalThis.loaders || {};
try {
const result = await requireFromFile?.(libraryUrl);
if (result || !libraryUrl.includes("/dist/libs/")) {
return result;
}
return await requireFromFile?.(libraryUrl.replace("/dist/libs/", "/src/libs/"));
} catch (error) {
if (libraryUrl.includes("/dist/libs/")) {
try {
return await requireFromFile?.(libraryUrl.replace("/dist/libs/", "/src/libs/"));
} catch {
}
}
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();
}
try {
return await readFileAsArrayBuffer(url);
} catch {
if (url.includes("/dist/libs/")) {
return await readFileAsArrayBuffer(url.replace("/dist/libs/", "/src/libs/"));
}
throw new Error(`Failed to load ArrayBuffer from ${url}`);
}
}
async function loadAsText(url) {
const { readFileAsText } = globalThis.loaders || {};
if (isBrowser || !readFileAsText || url.startsWith("http")) {
const response = await fetch(url);
return await response.text();
}
try {
return await readFileAsText(url);
} catch {
if (url.includes("/dist/libs/")) {
return await readFileAsText(url.replace("/dist/libs/", "/src/libs/"));
}
throw new Error(`Failed to load text from ${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 || {},
core: {
...options.core,
worker: false
}
};
return await parser(data, { ...options }, context, loader);
}
// src/lib/utils/version.ts
var VERSION2 = true ? "4.4.2" : "latest";
// src/crunch-loader.ts
var CrunchLoader = {
dataType: null,
batchType: null,
id: "crunch",
name: "Crunch",
module: "textures",
version: VERSION2,
worker: true,
extensions: ["crn"],
mimeTypes: ["image/crn", "image/x-crn", "application/octet-stream"],
binary: true,
options: {
crunch: {}
}
};
// src/lib/parsers/crunch-module-loader.ts
var CRUNCH_EXTERNAL_LIBRARIES = {
/** Crunch decoder library. It is used as dynamically imported script */
DECODER: "crunch.js"
};
async function loadCrunchModule(options) {
registerJSModules(options.modules);
const crunch = getJSModuleOrNull("crunch");
if (crunch) {
return crunch;
}
return loadCrunch(options);
}
var crunchModule;
async function loadCrunch(options) {
if (crunchModule) {
return crunchModule;
}
let loadCrunchDecoder = await loadLibrary(CRUNCH_EXTERNAL_LIBRARIES.DECODER, "textures", options);
loadCrunchDecoder ||= globalThis.LoadCrunchDecoder;
crunchModule = loadCrunchDecoder();
return crunchModule;
}
// src/lib/gl-extensions.ts
var GL_RGBA32F = 34836;
var GL_COMPRESSED_RGB_S3TC_DXT1_EXT = 33776;
var GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = 33777;
var GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = 33778;
var GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = 33779;
var GL_COMPRESSED_R11_EAC = 37488;
var GL_COMPRESSED_SIGNED_R11_EAC = 37489;
var GL_COMPRESSED_RG11_EAC = 37490;
var GL_COMPRESSED_SIGNED_RG11_EAC = 37491;
var GL_COMPRESSED_RGB8_ETC2 = 37492;
var GL_COMPRESSED_RGBA8_ETC2_EAC = 37493;
var GL_COMPRESSED_SRGB8_ETC2 = 37494;
var GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 37495;
var GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 37496;
var GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 37497;
var GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 35840;
var GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG = 35841;
var GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 35842;
var GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG = 35843;
var GL_COMPRESSED_RGB_ETC1_WEBGL = 36196;
var GL_COMPRESSED_RGB_ATC_WEBGL = 35986;
var GL_COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL = 35987;
var GL_COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL = 34798;
var GL_COMPRESSED_RGBA_ASTC_4x4_KHR = 37808;
var GL_COMPRESSED_RGBA_ASTC_5x4_KHR = 37809;
var GL_COMPRESSED_RGBA_ASTC_5x5_KHR = 37810;
var GL_COMPRESSED_RGBA_ASTC_6x5_KHR = 37811;
var GL_COMPRESSED_RGBA_ASTC_6x6_KHR = 37812;
var GL_COMPRESSED_RGBA_ASTC_8x5_KHR = 37813;
var GL_COMPRESSED_RGBA_ASTC_8x6_KHR = 37814;
var GL_COMPRESSED_RGBA_ASTC_8x8_KHR = 37815;
var GL_COMPRESSED_RGBA_ASTC_10x5_KHR = 37816;
var GL_COMPRESSED_RGBA_ASTC_10x6_KHR = 37817;
var GL_COMPRESSED_RGBA_ASTC_10x8_KHR = 37818;
var GL_COMPRESSED_RGBA_ASTC_10x10_KHR = 37819;
var GL_COMPRESSED_RGBA_ASTC_12x10_KHR = 37820;
var GL_COMPRESSED_RGBA_ASTC_12x12_KHR = 37821;
var GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR = 37840;
var GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR = 37841;
var GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR = 37842;
var GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR = 37843;
var GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR = 37844;
var GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR = 37845;
var GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR = 37846;
var GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR = 37847;
var GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR = 37848;
var GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR = 37849;
var GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR = 37850;
var GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR = 37851;
var GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR = 37852;
var GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR = 37853;
var GL_COMPRESSED_RED_RGTC1_EXT = 36283;
var GL_COMPRESSED_SIGNED_RED_RGTC1_EXT = 36284;
var GL_COMPRESSED_RED_GREEN_RGTC2_EXT = 36285;
var GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT = 36286;
var GL_COMPRESSED_SRGB_S3TC_DXT1_EXT = 35916;
var GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT = 35917;
var GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT = 35918;
var GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT = 35919;
// src/lib/utils/texture-format-map.ts
var WEBGL_TO_TEXTURE_FORMAT = {
[GL_RGBA32F]: "rgba32float",
[GL_COMPRESSED_RGB_S3TC_DXT1_EXT]: "bc1-rgb-unorm-webgl",
[GL_COMPRESSED_SRGB_S3TC_DXT1_EXT]: "bc1-rgb-unorm-srgb-webgl",
[GL_COMPRESSED_RGBA_S3TC_DXT1_EXT]: "bc1-rgba-unorm",
[GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT]: "bc1-rgba-unorm-srgb",
[GL_COMPRESSED_RGBA_S3TC_DXT3_EXT]: "bc2-rgba-unorm",
[GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT]: "bc2-rgba-unorm-srgb",
[GL_COMPRESSED_RGBA_S3TC_DXT5_EXT]: "bc3-rgba-unorm",
[GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT]: "bc3-rgba-unorm-srgb",
[GL_COMPRESSED_RED_RGTC1_EXT]: "bc4-r-unorm",
[GL_COMPRESSED_SIGNED_RED_RGTC1_EXT]: "bc4-r-snorm",
[GL_COMPRESSED_RED_GREEN_RGTC2_EXT]: "bc5-rg-unorm",
[GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT]: "bc5-rg-snorm",
[GL_COMPRESSED_RGB8_ETC2]: "etc2-rgb8unorm",
[GL_COMPRESSED_SRGB8_ETC2]: "etc2-rgb8unorm-srgb",
[GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2]: "etc2-rgb8a1unorm",
[GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2]: "etc2-rgb8a1unorm-srgb",
[GL_COMPRESSED_RGBA8_ETC2_EAC]: "etc2-rgba8unorm",
[GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC]: "etc2-rgba8unorm-srgb",
[GL_COMPRESSED_R11_EAC]: "eac-r11unorm",
[GL_COMPRESSED_SIGNED_R11_EAC]: "eac-r11snorm",
[GL_COMPRESSED_RG11_EAC]: "eac-rg11unorm",
[GL_COMPRESSED_SIGNED_RG11_EAC]: "eac-rg11snorm",
[GL_COMPRESSED_RGBA_ASTC_4x4_KHR]: "astc-4x4-unorm",
[GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR]: "astc-4x4-unorm-srgb",
[GL_COMPRESSED_RGBA_ASTC_5x4_KHR]: "astc-5x4-unorm",
[GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR]: "astc-5x4-unorm-srgb",
[GL_COMPRESSED_RGBA_ASTC_5x5_KHR]: "astc-5x5-unorm",
[GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR]: "astc-5x5-unorm-srgb",
[GL_COMPRESSED_RGBA_ASTC_6x5_KHR]: "astc-6x5-unorm",
[GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR]: "astc-6x5-unorm-srgb",
[GL_COMPRESSED_RGBA_ASTC_6x6_KHR]: "astc-6x6-unorm",
[GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR]: "astc-6x6-unorm-srgb",
[GL_COMPRESSED_RGBA_ASTC_8x5_KHR]: "astc-8x5-unorm",
[GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR]: "astc-8x5-unorm-srgb",
[GL_COMPRESSED_RGBA_ASTC_8x6_KHR]: "astc-8x6-unorm",
[GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR]: "astc-8x6-unorm-srgb",
[GL_COMPRESSED_RGBA_ASTC_8x8_KHR]: "astc-8x8-unorm",
[GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR]: "astc-8x8-unorm-srgb",
[GL_COMPRESSED_RGBA_ASTC_10x5_KHR]: "astc-10x5-unorm",
[GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR]: "astc-10x5-unorm-srgb",
[GL_COMPRESSED_RGBA_ASTC_10x6_KHR]: "astc-10x6-unorm",
[GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR]: "astc-10x6-unorm-srgb",
[GL_COMPRESSED_RGBA_ASTC_10x8_KHR]: "astc-10x8-unorm",
[GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR]: "astc-10x8-unorm-srgb",
[GL_COMPRESSED_RGBA_ASTC_10x10_KHR]: "astc-10x10-unorm",
[GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR]: "astc-10x10-unorm-srgb",
[GL_COMPRESSED_RGBA_ASTC_12x10_KHR]: "astc-12x10-unorm",
[GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR]: "astc-12x10-unorm-srgb",
[GL_COMPRESSED_RGBA_ASTC_12x12_KHR]: "astc-12x12-unorm",
[GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR]: "astc-12x12-unorm-srgb",
[GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG]: "pvrtc-rgb4unorm-webgl",
[GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG]: "pvrtc-rgba4unorm-webgl",
[GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG]: "pvrtc-rgb2unorm-webgl",
[GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG]: "pvrtc-rgba2unorm-webgl",
[GL_COMPRESSED_RGB_ETC1_WEBGL]: "etc1-rgb-unorm-webgl",
[GL_COMPRESSED_RGB_ATC_WEBGL]: "atc-rgb-unorm-webgl",
[GL_COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL]: "atc-rgba-unorm-webgl",
[GL_COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL]: "atc-rgbai-unorm-webgl"
};
var TEXTURE_FORMAT_TO_WEBGL = Object.fromEntries(
Object.entries(WEBGL_TO_TEXTURE_FORMAT).map(([format, textureFormat]) => [
textureFormat,
Number(format)
])
);
function getTextureFormatFromWebGLFormat(format) {
if (format === void 0) {
return void 0;
}
return WEBGL_TO_TEXTURE_FORMAT[format];
}
function getWebGLFormatFromTextureFormat(textureFormat) {
if (textureFormat === void 0) {
return void 0;
}
return TEXTURE_FORMAT_TO_WEBGL[textureFormat];
}
// src/lib/utils/extract-mipmap-images.ts
function extractMipmapImages(data, options) {
const images = new Array(options.mipMapLevels);
const textureFormat = options.textureFormat || getTextureFormatFromWebGLFormat(options.internalFormat);
const format = options.internalFormat || getWebGLFormatFromTextureFormat(options.textureFormat);
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);
const image = {
shape: "texture-level",
compressed: true,
data: levelData,
width: levelWidth,
height: levelHeight,
levelSize
};
if (format !== void 0) {
image.format = format;
}
if (textureFormat) {
image.textureFormat = textureFormat;
}
images[i] = image;
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/parsers/parse-dds.ts
function getDxt1LevelSize(width, height) {
return (width + 3 >> 2) * (height + 3 >> 2) * 8;
}
function getDxtXLevelSize(width, height) {
return (width + 3 >> 2) * (height + 3 >> 2) * 16;
}
// src/lib/parsers/parse-crunch.ts
var CRN_FORMAT = {
cCRNFmtInvalid: -1,
cCRNFmtDXT1: 0,
// cCRNFmtDXT3 is not currently supported when writing to CRN - only DDS.
cCRNFmtDXT3: 1,
cCRNFmtDXT5: 2
// Crunch supports more formats than this.
};
var DXT_FORMAT_MAP = {
[CRN_FORMAT.cCRNFmtDXT1]: {
textureFormat: "bc1-rgb-unorm-webgl",
sizeFunction: getDxt1LevelSize
},
[CRN_FORMAT.cCRNFmtDXT3]: {
textureFormat: "bc2-rgba-unorm",
sizeFunction: getDxtXLevelSize
},
[CRN_FORMAT.cCRNFmtDXT5]: {
textureFormat: "bc3-rgba-unorm",
sizeFunction: getDxtXLevelSize
}
};
var cachedDstSize = 0;
var dst;
async function parseCrunch(data, options) {
const crunchModule2 = await loadCrunchModule(extractLoadLibraryOptions(options));
const srcSize = data.byteLength;
const bytes = new Uint8Array(data);
const src = crunchModule2._malloc(srcSize);
arrayBufferCopy(bytes, crunchModule2.HEAPU8, src, srcSize);
const format = crunchModule2._crn_get_dxt_format(src, srcSize);
assert(Boolean(DXT_FORMAT_MAP[format]), "Unsupported format");
const mipMapLevels = crunchModule2._crn_get_levels(src, srcSize);
const width = crunchModule2._crn_get_width(src, srcSize);
const height = crunchModule2._crn_get_height(src, srcSize);
const sizeFunction = DXT_FORMAT_MAP[format].sizeFunction;
let dstSize = 0;
for (let i = 0; i < mipMapLevels; ++i) {
dstSize += sizeFunction(width >> i, height >> i);
}
if (cachedDstSize < dstSize) {
if (dst) {
crunchModule2._free(dst);
}
dst = crunchModule2._malloc(dstSize);
cachedDstSize = dstSize;
}
crunchModule2._crn_decompress(src, srcSize, dst, dstSize, 0, mipMapLevels);
crunchModule2._free(src);
const image = new Uint8Array(crunchModule2.HEAPU8.buffer, dst, dstSize).slice();
return extractMipmapImages(image, {
mipMapLevels,
width,
height,
sizeFunction,
textureFormat: DXT_FORMAT_MAP[format].textureFormat
});
}
function arrayBufferCopy(srcData, dstData, dstByteOffset, numBytes) {
let i;
const dst32Offset = dstByteOffset / 4;
const tail = numBytes % 4;
const src32 = new Uint32Array(srcData.buffer, 0, (numBytes - tail) / 4);
const dst32 = new Uint32Array(dstData.buffer);
for (i = 0; i < src32.length; i++) {
dst32[dst32Offset + i] = src32[i];
}
for (i = numBytes - tail; i < numBytes; i++) {
dstData[dstByteOffset + i] = srcData[i];
}
}
// src/workers/crunch-worker.ts
var CrunchLoaderWithParser = {
...CrunchLoader,
parse: parseCrunch
};
createLoaderWorker(CrunchLoaderWithParser);
})();