// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
/**
 * implementation of Tensor.toDataURL()
 */
export const tensorToDataURL = (tensor, options) => {
    const canvas = typeof document !== 'undefined' ? document.createElement('canvas') : new OffscreenCanvas(1, 1);
    canvas.width = tensor.dims[3];
    canvas.height = tensor.dims[2];
    const pixels2DContext = canvas.getContext('2d');
    if (pixels2DContext != null) {
        // Default values for height and width & format
        let width;
        let height;
        if (options?.tensorLayout !== undefined && options.tensorLayout === 'NHWC') {
            width = tensor.dims[2];
            height = tensor.dims[3];
        }
        else {
            // Default layout is NCWH
            width = tensor.dims[3];
            height = tensor.dims[2];
        }
        const inputformat = options?.format !== undefined ? options.format : 'RGB';
        const norm = options?.norm;
        let normMean;
        let normBias;
        if (norm === undefined || norm.mean === undefined) {
            normMean = [255, 255, 255, 255];
        }
        else {
            if (typeof norm.mean === 'number') {
                normMean = [norm.mean, norm.mean, norm.mean, norm.mean];
            }
            else {
                normMean = [norm.mean[0], norm.mean[1], norm.mean[2], 0];
                if (norm.mean[3] !== undefined) {
                    normMean[3] = norm.mean[3];
                }
            }
        }
        if (norm === undefined || norm.bias === undefined) {
            normBias = [0, 0, 0, 0];
        }
        else {
            if (typeof norm.bias === 'number') {
                normBias = [norm.bias, norm.bias, norm.bias, norm.bias];
            }
            else {
                normBias = [norm.bias[0], norm.bias[1], norm.bias[2], 0];
                if (norm.bias[3] !== undefined) {
                    normBias[3] = norm.bias[3];
                }
            }
        }
        const stride = height * width;
        // Default pointer assignments
        let rTensorPointer = 0, gTensorPointer = stride, bTensorPointer = stride * 2, aTensorPointer = -1;
        // Updating the pointer assignments based on the input image format
        if (inputformat === 'RGBA') {
            rTensorPointer = 0;
            gTensorPointer = stride;
            bTensorPointer = stride * 2;
            aTensorPointer = stride * 3;
        }
        else if (inputformat === 'RGB') {
            rTensorPointer = 0;
            gTensorPointer = stride;
            bTensorPointer = stride * 2;
        }
        else if (inputformat === 'RBG') {
            rTensorPointer = 0;
            bTensorPointer = stride;
            gTensorPointer = stride * 2;
        }
        for (let i = 0; i < height; i++) {
            for (let j = 0; j < width; j++) {
                const R = (tensor.data[rTensorPointer++] - normBias[0]) * normMean[0]; // R value
                const G = (tensor.data[gTensorPointer++] - normBias[1]) * normMean[1]; // G value
                const B = (tensor.data[bTensorPointer++] - normBias[2]) * normMean[2]; // B value
                const A = aTensorPointer === -1 ? 255 : (tensor.data[aTensorPointer++] - normBias[3]) * normMean[3]; // A value
                pixels2DContext.fillStyle = 'rgba(' + R + ',' + G + ',' + B + ',' + A + ')';
                pixels2DContext.fillRect(j, i, 1, 1);
            }
        }
        if ('toDataURL' in canvas) {
            return canvas.toDataURL();
        }
        else {
            throw new Error('toDataURL is not supported');
        }
    }
    else {
        throw new Error('Can not access image data');
    }
};
/**
 * implementation of Tensor.toImageData()
 */
export const tensorToImageData = (tensor, options) => {
    const pixels2DContext = typeof document !== 'undefined'
        ? document.createElement('canvas').getContext('2d')
        : new OffscreenCanvas(1, 1).getContext('2d');
    let image;
    if (pixels2DContext != null) {
        // Default values for height and width & format
        let width;
        let height;
        let channels;
        if (options?.tensorLayout !== undefined && options.tensorLayout === 'NHWC') {
            width = tensor.dims[2];
            height = tensor.dims[1];
            channels = tensor.dims[3];
        }
        else {
            // Default layout is NCWH
            width = tensor.dims[3];
            height = tensor.dims[2];
            channels = tensor.dims[1];
        }
        const inputformat = options !== undefined ? (options.format !== undefined ? options.format : 'RGB') : 'RGB';
        const norm = options?.norm;
        let normMean;
        let normBias;
        if (norm === undefined || norm.mean === undefined) {
            normMean = [255, 255, 255, 255];
        }
        else {
            if (typeof norm.mean === 'number') {
                normMean = [norm.mean, norm.mean, norm.mean, norm.mean];
            }
            else {
                normMean = [norm.mean[0], norm.mean[1], norm.mean[2], 255];
                if (norm.mean[3] !== undefined) {
                    normMean[3] = norm.mean[3];
                }
            }
        }
        if (norm === undefined || norm.bias === undefined) {
            normBias = [0, 0, 0, 0];
        }
        else {
            if (typeof norm.bias === 'number') {
                normBias = [norm.bias, norm.bias, norm.bias, norm.bias];
            }
            else {
                normBias = [norm.bias[0], norm.bias[1], norm.bias[2], 0];
                if (norm.bias[3] !== undefined) {
                    normBias[3] = norm.bias[3];
                }
            }
        }
        const stride = height * width;
        if (options !== undefined) {
            if ((options.format !== undefined && channels === 4 && options.format !== 'RGBA') ||
                (channels === 3 && options.format !== 'RGB' && options.format !== 'BGR')) {
                throw new Error("Tensor format doesn't match input tensor dims");
            }
        }
        // Default pointer assignments
        const step = 4;
        let rImagePointer = 0, gImagePointer = 1, bImagePointer = 2, aImagePointer = 3;
        let rTensorPointer = 0, gTensorPointer = stride, bTensorPointer = stride * 2, aTensorPointer = -1;
        // Updating the pointer assignments based on the input image format
        if (inputformat === 'RGBA') {
            rTensorPointer = 0;
            gTensorPointer = stride;
            bTensorPointer = stride * 2;
            aTensorPointer = stride * 3;
        }
        else if (inputformat === 'RGB') {
            rTensorPointer = 0;
            gTensorPointer = stride;
            bTensorPointer = stride * 2;
        }
        else if (inputformat === 'RBG') {
            rTensorPointer = 0;
            bTensorPointer = stride;
            gTensorPointer = stride * 2;
        }
        image = pixels2DContext.createImageData(width, height);
        for (let i = 0; i < height * width; rImagePointer += step, gImagePointer += step, bImagePointer += step, aImagePointer += step, i++) {
            image.data[rImagePointer] = (tensor.data[rTensorPointer++] - normBias[0]) * normMean[0]; // R value
            image.data[gImagePointer] = (tensor.data[gTensorPointer++] - normBias[1]) * normMean[1]; // G value
            image.data[bImagePointer] = (tensor.data[bTensorPointer++] - normBias[2]) * normMean[2]; // B value
            image.data[aImagePointer] =
                aTensorPointer === -1 ? 255 : (tensor.data[aTensorPointer++] - normBias[3]) * normMean[3]; // A value
        }
    }
    else {
        throw new Error('Can not access image data');
    }
    return image;
};
//# sourceMappingURL=tensor-conversion-impl.js.map