
# CIE LAB color space specific code based on XYZ for Illuminant D65 and Observer 2 degree

package Graphics::Toolkit::Color::Space::Instance::CIELAB;
use v5.12;
use warnings;
use Graphics::Toolkit::Color::Space;

my $eta = 0.008856 ;
my $kappa = 903.3;

sub from_lab {
    my ($lab) = shift;
    my $fy = ($lab->[0] + 0.16) / 1.16;
    my $fx = $fy - 1 + ($lab->[1] * 2);
    my $fz = $fy + 1 - ($lab->[2] * 2);
    my @xyz = map {my $f3 = $_** 3; (abs($f3) > $eta) ? $f3 : (( 116 * $_ - 16 ) / $kappa) } $fx, $fy, $fz;
    return \@xyz;
}
sub to_lab {
    my ($xyz) = shift;
    my @xyz = map {(abs($_) > $eta) ? ($_ ** (1/3)) : ((($kappa * $_) + 16) / 116)} @$xyz;
    my $l = (1.16 * $xyz[1]) - 0.16;
    my $a = ($xyz[0] - $xyz[1] + 1) / 2;
    my $b = ($xyz[1] - $xyz[2] + 1) / 2;
    return ([$l, $a, $b]);
}

Graphics::Toolkit::Color::Space->new (
      alias_name => 'CIELAB',          # space name LAB
          family => 'LAB',
            axis => [qw/L* a* b*/],    # short l a b  -  lightness, cyan-orange balance, magenta-green balance
            role => [qw/L a b/],
           range => [100, [-500, 500], [-200, 200]],
       precision => 3,
         convert => {XYZ => [\&from_lab, \&to_lab, ]},
);
