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   298225 use v5.12;
  15         58  
6 15     15   97 use warnings;
  15         26  
  15         923  
7 15     15   710 use Graphics::Toolkit::Color::Space qw/gamma_correct mult_matrix_vector_3/;
  15         96  
  15         8797  
8              
9             my @D65 = (0.95047, 1, 1.08883); # illuminant
10              
11             sub from_xyz {
12 5     5 0 11 my ($xyz) = shift;
13 5         14 my @xyz = map {$xyz->[$_] * $D65[$_]} 0 .. 2;
  15         40  
14 5         37 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         16 @lms = map {gamma_correct($_, 1/3)} @lms;
  15         32  
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         14 $lab[1] += .5;
24 5         9 $lab[2] += .5;
25 5         24 return \@lab;
26             }
27             sub to_xyz {
28 7     7 0 15 my (@lab) = @{$_[0]};
  7         19  
29 7         17 $lab[1] -= .5;
30 7         11 $lab[2] -= .5;
31 7         39 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 7         25 @lms = map {gamma_correct($_, 3)} @lms;
  21         47  
36              
37 7         27 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 7         22 return [map {$xyz[$_] / $D65[$_]} 0 .. 2];
  21         82  
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             );