sdfsdfs
This commit is contained in:
130
node_modules/pixi.js/lib/compressed-textures/ktx/parseKTX.mjs
generated
vendored
Normal file
130
node_modules/pixi.js/lib/compressed-textures/ktx/parseKTX.mjs
generated
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
import { KTX } from '../ktx2/const.mjs';
|
||||
|
||||
"use strict";
|
||||
function parseKTX(arrayBuffer, supportedFormats) {
|
||||
const dataView = new DataView(arrayBuffer);
|
||||
if (!validate(dataView)) {
|
||||
throw new Error("Invalid KTX identifier in header");
|
||||
}
|
||||
const {
|
||||
littleEndian,
|
||||
glType,
|
||||
glFormat,
|
||||
glInternalFormat,
|
||||
pixelWidth,
|
||||
pixelHeight,
|
||||
numberOfMipmapLevels,
|
||||
offset
|
||||
} = parseKTXHeader(dataView);
|
||||
const textureFormat = KTX.INTERNAL_FORMAT_TO_TEXTURE_FORMATS[glInternalFormat];
|
||||
if (!textureFormat) {
|
||||
throw new Error(`Unknown texture format ${glInternalFormat}`);
|
||||
}
|
||||
if (!supportedFormats.includes(textureFormat)) {
|
||||
throw new Error(`Unsupported texture format: ${textureFormat}, supportedFormats: ${supportedFormats}`);
|
||||
}
|
||||
const imagePixelByteSize = getImagePixelByteSize(glType, glFormat, glInternalFormat);
|
||||
const imageBuffers = getImageBuffers(
|
||||
dataView,
|
||||
glType,
|
||||
imagePixelByteSize,
|
||||
pixelWidth,
|
||||
pixelHeight,
|
||||
offset,
|
||||
numberOfMipmapLevels,
|
||||
littleEndian
|
||||
);
|
||||
return {
|
||||
format: textureFormat,
|
||||
width: pixelWidth,
|
||||
height: pixelHeight,
|
||||
resource: imageBuffers,
|
||||
alphaMode: "no-premultiply-alpha"
|
||||
};
|
||||
}
|
||||
function getImageBuffers(dataView, glType, imagePixelByteSize, pixelWidth, pixelHeight, offset, numberOfMipmapLevels, littleEndian) {
|
||||
const alignedWidth = pixelWidth + 3 & ~3;
|
||||
const alignedHeight = pixelHeight + 3 & ~3;
|
||||
let imagePixels = pixelWidth * pixelHeight;
|
||||
if (glType === 0) {
|
||||
imagePixels = alignedWidth * alignedHeight;
|
||||
}
|
||||
let mipByteSize = imagePixels * imagePixelByteSize;
|
||||
let mipWidth = pixelWidth;
|
||||
let mipHeight = pixelHeight;
|
||||
let alignedMipWidth = alignedWidth;
|
||||
let alignedMipHeight = alignedHeight;
|
||||
let imageOffset = offset;
|
||||
const imageBuffers = new Array(numberOfMipmapLevels);
|
||||
for (let mipmapLevel = 0; mipmapLevel < numberOfMipmapLevels; mipmapLevel++) {
|
||||
const imageSize = dataView.getUint32(imageOffset, littleEndian);
|
||||
let elementOffset = imageOffset + 4;
|
||||
imageBuffers[mipmapLevel] = new Uint8Array(dataView.buffer, elementOffset, mipByteSize);
|
||||
elementOffset += mipByteSize;
|
||||
imageOffset += imageSize + 4;
|
||||
imageOffset = imageOffset % 4 !== 0 ? imageOffset + 4 - imageOffset % 4 : imageOffset;
|
||||
mipWidth = mipWidth >> 1 || 1;
|
||||
mipHeight = mipHeight >> 1 || 1;
|
||||
alignedMipWidth = mipWidth + 4 - 1 & ~(4 - 1);
|
||||
alignedMipHeight = mipHeight + 4 - 1 & ~(4 - 1);
|
||||
mipByteSize = alignedMipWidth * alignedMipHeight * imagePixelByteSize;
|
||||
}
|
||||
return imageBuffers;
|
||||
}
|
||||
function getImagePixelByteSize(glType, glFormat, glInternalFormat) {
|
||||
let imagePixelByteSize = KTX.INTERNAL_FORMAT_TO_BYTES_PER_PIXEL[glInternalFormat];
|
||||
if (glType !== 0) {
|
||||
if (KTX.TYPES_TO_BYTES_PER_COMPONENT[glType]) {
|
||||
imagePixelByteSize = KTX.TYPES_TO_BYTES_PER_COMPONENT[glType] * KTX.FORMATS_TO_COMPONENTS[glFormat];
|
||||
} else {
|
||||
imagePixelByteSize = KTX.TYPES_TO_BYTES_PER_PIXEL[glType];
|
||||
}
|
||||
}
|
||||
if (imagePixelByteSize === void 0) {
|
||||
throw new Error("Unable to resolve the pixel format stored in the *.ktx file!");
|
||||
}
|
||||
return imagePixelByteSize;
|
||||
}
|
||||
function parseKTXHeader(dataView) {
|
||||
const littleEndian = dataView.getUint32(KTX.FIELDS.ENDIANNESS, true) === KTX.ENDIANNESS;
|
||||
const glType = dataView.getUint32(KTX.FIELDS.GL_TYPE, littleEndian);
|
||||
const glFormat = dataView.getUint32(KTX.FIELDS.GL_FORMAT, littleEndian);
|
||||
const glInternalFormat = dataView.getUint32(KTX.FIELDS.GL_INTERNAL_FORMAT, littleEndian);
|
||||
const pixelWidth = dataView.getUint32(KTX.FIELDS.PIXEL_WIDTH, littleEndian);
|
||||
const pixelHeight = dataView.getUint32(KTX.FIELDS.PIXEL_HEIGHT, littleEndian) || 1;
|
||||
const pixelDepth = dataView.getUint32(KTX.FIELDS.PIXEL_DEPTH, littleEndian) || 1;
|
||||
const numberOfArrayElements = dataView.getUint32(KTX.FIELDS.NUMBER_OF_ARRAY_ELEMENTS, littleEndian) || 1;
|
||||
const numberOfFaces = dataView.getUint32(KTX.FIELDS.NUMBER_OF_FACES, littleEndian);
|
||||
const numberOfMipmapLevels = dataView.getUint32(KTX.FIELDS.NUMBER_OF_MIPMAP_LEVELS, littleEndian);
|
||||
const bytesOfKeyValueData = dataView.getUint32(KTX.FIELDS.BYTES_OF_KEY_VALUE_DATA, littleEndian);
|
||||
if (pixelHeight === 0 || pixelDepth !== 1) {
|
||||
throw new Error("Only 2D textures are supported");
|
||||
}
|
||||
if (numberOfFaces !== 1) {
|
||||
throw new Error("CubeTextures are not supported by KTXLoader yet!");
|
||||
}
|
||||
if (numberOfArrayElements !== 1) {
|
||||
throw new Error("WebGL does not support array textures");
|
||||
}
|
||||
return {
|
||||
littleEndian,
|
||||
glType,
|
||||
glFormat,
|
||||
glInternalFormat,
|
||||
pixelWidth,
|
||||
pixelHeight,
|
||||
numberOfMipmapLevels,
|
||||
offset: KTX.FILE_HEADER_SIZE + bytesOfKeyValueData
|
||||
};
|
||||
}
|
||||
function validate(dataView) {
|
||||
for (let i = 0; i < KTX.FILE_IDENTIFIER.length; i++) {
|
||||
if (dataView.getUint8(i) !== KTX.FILE_IDENTIFIER[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export { parseKTX };
|
||||
//# sourceMappingURL=parseKTX.mjs.map
|
Reference in New Issue
Block a user