View Raw SPL
rgb2lab2(r, g, b)
{
        local rgb, ll, aa, bb, m, xyz, xyz_norm, xw, yw, zw;
        local nr = -1;

        if (argc == 1)
        {
                if (length(r) == 3)
                {
                        nr = 3;
                        r = transpose(r);
                }

                if (numcols(r) == 3)
                {
                        g = col(r, 2);
                        b = col(r, 3);
                        r = col(r, 1);
                }
                else        
                {
                        /* assume image */
                        (r, g, b) = getrgb(r);

                        nr = numrows(r);
                }
        }
        else if (argc != 3)
        {
                error(sprintf("%s - 1 or 3 input arguments required", __FUNC__));
        }

        if (max(r) > 1 || max(g) > 1 || max(b) > 1)         
        {
                r /= 255;
                g /= 255;
                b /= 255;
        }

        rgb = ravel(r[..], g[..], b[..]);

        /* 1. Convert RGB to XYZ */
        rgb = (rgb > 0.04045) ?  ((rgb + 0.055) / 1.055)^2.4 : rgb / 12.92;

        m = {{0.4124, 0.3576, 0.1805},
             {0.2126, 0.7152, 0.0722},
             {0.0193, 0.1192, 0.9505}};

        m = m'; //

        xyz = rgb *^ m;

        /* Convert XYZ to XYZ' */
        (xw, yw, zw) = (95.047, 100.000, 108.883);  // D65 white point
        xyz_norm = xyz / transpose({xw, yw, zw});

          /* 3. Calculate L*, a*, and b* */
        ll = 116 * rgb2lab2_cie(xyz_norm[.., 2]) - 16;
        aa = 500 * (rgb2lab2_cie(xyz_norm[.., 1]) - rgb2lab2_cie(xyz_norm[.., 2]));
        bb = 200 * (rgb2lab2_cie(xyz_norm[.., 2]) - rgb2lab2_cie(xyz_norm[.., 3]));

        if (outargc <= 1)
        {
                /* cast to series */
                ll = {ll};
                aa = {aa};
                bb = {bb};
        }

        /* label */
        if (nr == 3)
        {
                setvunits(ll, "LAB");
        }
        else
        {
                if (isarray(ll)) setvunits(ll, "L");
                if (isarray(aa)) setvunits(aa, "A*");
                if (isarray(bb)) setvunits(bb, "B*");

                if (nr > 1)
                {
                        ll = ravel(ll, nr);
                        aa = ravel(aa, nr);
                        bb = ravel(bb, nr);
                }
        }

        if (outargc > 1)
        {
                return(ll, aa, bb);
        }
        else if (nr == 3)
        {
                return({ll, aa, bb});
        }
        else
        {
                return(ravel(ll, aa, bb));
        }
}



rgb2lab2_f(t)
{
        local f;

        f = (t > 0.008856) ? t ^ (1/3) : 7.787 * t + 16/116;

        return(f);
}


rgb2lab2_cie(t)
{
        local epsilon, kappa, f;

        epsilon = 216.0 / 24389.0;
        kappa = 24389.0 / 27.0;

        f = (t > epsilon) ? t ^ (1/3) : (kappa * t + 16) / 116;

        return(f);
}