Source: utils/colormap-utils.js

//@ts-check

/**
 * Convert Hex color map to RGBA color map, 
 * if the alpha channel is missing,
 * it will set to 255 (fully opaque)
 * 
 * @param {string[]} colormap 
 * @returns {number[][]}
 */
export function hexColormapToRGBA(colormap) {
    if (colormap.length === 0) return [];
    if (colormap[0].length !== 7 && colormap[0].length !== 9) throw new Error('Invalid colormap format');
    return colormap.map(color => {
        return [
            parseInt(color.slice(1, 3), 16),
            parseInt(color.slice(3, 5), 16),
            parseInt(color.slice(5, 7), 16),
            color.length === 9 ? parseInt(color.slice(7, 9), 16) : 255
        ];
    });
}

/**
 * Convert RGBA color map to Hex color map the hex color is stored as a single integer
 * @param {number[][]} colormap 
 * @returns {number[]}
 */
export function RGBAToHexColormap(colormap) {
    if (colormap.length === 0) return [];
    if (colormap[0].length !== 3 && colormap[0].length !== 4) throw new Error('Invalid colormap format');
    
    let hexColormap = [];
    colormap.forEach(color => {
        hexColormap.push(
            (color[0] << 16) | (color[1] << 8) | color[2] | (color.length === 4 ? color[3] << 24 : 0xff000000)
        );
    });
    return hexColormap;
}

/**
 * if a colormap has only RGB values,
 * it will add the alpha channel to 255
 * 
 * @param {number[][]} colormap
 * @returns {number[][]}
 */
export function normalizeColorMap(colormap) {
    if (colormap.length === 0) return [];
    if (colormap[0].length !== 3 && colormap[0].length !== 4) throw new Error('Invalid colormap format');
    return colormap.map(color => {
        return color.length === 3 ? [...color, 255] : color;
    });
}

/**
 * if a Hex colormap string[] has only RGB values this function adds the alpha channel to FF
 * @param {string[]} colormap 
 * @returns {string[]}
 */
export function normalizeHexColormap(colormap) {
    if (colormap.length === 0) return [];
    if (colormap[0].length !== 7 && colormap[0].length !== 9) throw new Error('Invalid colormap format');
    return colormap.map(color => {
        return color.length === 7 ? color + 'FF' : color;
    });
}

/**
 * convert a colormap from a string array to an integer array
 * @param {string[]} colormap
 * @returns {number[]}
 */
export function stringHexColormapToInt(colormap) {
    if (colormap.length === 0) return [];
    if (colormap[0].length !== 7 && colormap[0].length !== 9) throw new Error('Invalid colormap format');
    return colormap.map(color => {
        if(color.length === 7) color += 'FF';
        return parseInt(color.slice(1), 16);
    });
}