File Coverage

lib/Graphics/Toolkit/Color/Space/Instance/OKLAB.pm
Criterion Covered Total %
statement 28 28 100.0
branch n/a
condition n/a
subroutine 5 5 100.0
pod 0 2 0.0
total 33 35 94.2


line stmt bran cond sub pod time code
1              
2             # OK lab color space for Illuminant D65 and Observer 2 degree by Björn Ottosson 2020
3              
4             package Graphics::Toolkit::Color::Space::Instance::OKLAB;
5 15     15   251557 use v5.12;
  15         62  
6 15     15   88 use warnings;
  15         27  
  15         997  
7 15     15   677 use Graphics::Toolkit::Color::Space qw/mult_matrix_vector_3/;
  15         26  
  15         8980  
8              
9             my @D65 = (0.95047, 1, 1.08883); # illuminant
10              
11             sub from_xyz {
12 5     5 0 9 my ($xyz) = shift;
13 5         10 my @xyz = map {$xyz->[$_] * $D65[$_]} 0 .. 2;
  15         38  
14 5         25 my @lms = mult_matrix_vector_3([[ 0.8189330101, 0.3618667424,-0.1288597137],
15             [ 0.0329845436, 0.9293118715, 0.0361456387],
16             [ 0.0482003018, 0.2643662691, 0.6338517070]], @xyz);
17              
18 5         15 @lms = map {$_ ** (1/3)} @lms;
  15         60  
19              
20 5         18 my @lab = mult_matrix_vector_3([[ 0.2104542553, 0.7936177850, -0.0040720468],
21             [ 1.9779984951, -2.4285922050, 0.4505937099],
22             [ 0.0259040371, 0.7827717662, -0.8086757660]], @lms);
23 5         12 $lab[1] += .5;
24 5         8 $lab[2] += .5;
25 5         30 return \@lab;
26             }
27             sub to_xyz {
28 6     6 0 12 my (@lab) = @{$_[0]};
  6         17  
29 6         13 $lab[1] -= .5;
30 6         10 $lab[2] -= .5;
31 6         35 my @lms = mult_matrix_vector_3([[ 1, 0.396338 , 0.215804 ],
32             [ 1, -0.105561 , -0.0638542 ],
33             [ 1, -0.0894842, -1.29149 ]], @lab);
34              
35 6         21 @lms = map {$_ ** 3} @lms;
  18         42  
36              
37 6         25 my @xyz = mult_matrix_vector_3([[ 1.22701 , -0.5578 , 0.281256 ],
38             [-0.0405802, 1.11226 ,-0.0716767],
39             [-0.0763813, -0.421482, 1.58616 ]], @lms);
40 6         21 return [map {$xyz[$_] / $D65[$_]} 0 .. 2];
  18         57  
41             }
42              
43             Graphics::Toolkit::Color::Space->new(
44             name => 'OKLAB', # no alias, short axis name eq long
45             axis => [qw/L a b/], # lightness, cyan-orange balance, magenta-green balance
46             range => [1, [-.5, .5], [-.5, .5]],
47             precision => 3,
48             convert => {XYZ => [\&to_xyz, \&from_xyz]}, #, {to => {in => 1, out => 1}, from => {in => 1, out => 1} }
49             );