import { AbstractTextureLoader } from '../loader.js';
import { getDevice } from '../../../app/api.js';

/**
 * TGA image loader
 * @internal
 */ class TGALoader extends AbstractTextureLoader {
    supportMIMEType(mimeType) {
        return mimeType === 'image/tga' || mimeType === 'image/x-tga';
    }
    parseTGA(content, sRGB, noMipmap, texture) {
        const arrayBuffer = content instanceof ArrayBuffer ? content : content.buffer;
        const offset = content instanceof ArrayBuffer ? 0 : content.byteOffset;
        const dataView = new DataView(arrayBuffer, offset);
        const p = [
            0,
            0,
            0,
            0
        ];
        parse: {
            let skip = 0;
            const idLength = dataView.getUint8(0);
            skip += idLength;
            const colorMapType = dataView.getUint8(1);
            if (colorMapType !== 0 && colorMapType !== 1) {
                break parse;
            }
            const dataTypeCode = dataView.getUint8(2);
            if (dataTypeCode !== 2 && dataTypeCode !== 10) {
                break parse;
            }
            const colorMapLength = dataView.getUint16(5, true);
            skip += colorMapLength * colorMapType;
            const width = dataView.getUint16(12, true);
            const height = dataView.getUint16(14, true);
            const bpp = dataView.getUint8(16);
            if (bpp !== 16 && bpp !== 24 && bpp !== 32) {
                break parse;
            }
            let dataOffset = 18 + skip;
            const bytesPerPixel = bpp / 8;
            const pixels = new Uint8Array(width * height * 4);
            let n = 0;
            while(n < width * height){
                if (dataTypeCode === 2) {
                    for(let i = 0; i < bytesPerPixel; i++){
                        p[i] = dataView.getUint8(dataOffset++);
                    }
                    this.mergeBytes(pixels, n * 4, p, bytesPerPixel);
                    n++;
                } else {
                    const t = dataView.getUint8(dataOffset++);
                    for(let i = 0; i < bytesPerPixel; i++){
                        p[i] = dataView.getUint8(dataOffset++);
                    }
                    const j = t & 0x7f;
                    this.mergeBytes(pixels, n * 4, p, bytesPerPixel);
                    n++;
                    if (t & 0x80) {
                        for(let i = 0; i < j; i++){
                            this.mergeBytes(pixels, n * 4, p, bytesPerPixel);
                            n++;
                        }
                    } else {
                        for(let i = 0; i < j; i++){
                            for(let k = 0; k < bytesPerPixel; k++){
                                p[i] = dataView.getUint8(dataOffset++);
                            }
                            this.mergeBytes(pixels, n * 4, p, bytesPerPixel);
                            n++;
                        }
                    }
                }
            }
            const opt = {
                texture
            };
            if (noMipmap) {
                opt.mipmapping = false;
            }
            const tex = getDevice().createTexture2D(sRGB ? 'rgba8unorm-srgb' : 'rgba8unorm', width, height, opt);
            tex.update(pixels, 0, 0, width, height);
            return tex;
        }
        console.error('Unsupported TGA file format');
        return null;
    }
    mergeBytes(dest, offset, pixel, numBytes) {
        if (numBytes === 4) {
            dest[offset + 0] = pixel[2];
            dest[offset + 1] = pixel[1];
            dest[offset + 2] = pixel[0];
            dest[offset + 3] = pixel[3];
        } else if (numBytes === 3) {
            dest[offset + 0] = pixel[2];
            dest[offset + 1] = pixel[1];
            dest[offset + 2] = pixel[0];
            dest[offset + 3] = 255;
        } else if (numBytes === 2) {
            dest[offset + 0] = (pixel[1] & 0x7c) << 1;
            dest[offset + 1] = (pixel[1] & 0x03) << 6 | (pixel[0] & 0xe0) >> 2;
            dest[offset + 2] = (pixel[0] & 0x1f) << 3;
            dest[offset + 3] = pixel[1] & 0x80;
        }
    }
    async load(mimeType, data, srgb, samplerOptions, texture) {
        return new Promise((resolve)=>{
            resolve(this.parseTGA(data, srgb, samplerOptions?.mipFilter === 'none', texture));
        });
    }
}

export { TGALoader };
//# sourceMappingURL=tga_Loader.js.map
