File Coverage

lib/Graphics/Toolkit/Color/Space/Instance/CIELUV.pm
Criterion Covered Total %
statement 37 37 100.0
branch 14 14 100.0
condition n/a
subroutine 5 5 100.0
pod 0 2 0.0
total 56 58 96.5


line stmt bran cond sub pod time code
1              
2             # CIE LUV color space specific code based on XYZ for Illuminant D65 and Observer 2 degree
3              
4             package Graphics::Toolkit::Color::Space::Instance::CIELUV;
5 15     15   206813 use v5.12;
  15         72  
6 15     15   143 use warnings;
  15         27  
  15         905  
7 15     15   578 use Graphics::Toolkit::Color::Space;
  15         29  
  15         9711  
8              
9             my @D65 = (0.95047, 1, 1.08883); # illuminant
10             my $eta = 0.008856 ;
11             my $kappa = 903.3;
12              
13             sub from_xyz {
14 6     6 0 17 my ($xyz) = shift;
15 6         21 my @XYZ = map { $xyz->[$_] * $D65[$_] } 0 .. 2;
  18         59  
16              
17 6         24 my $color_mix = $XYZ[0] + (15 * $XYZ[1]) + (3 * $XYZ[2]);
18 6 100       23 my $u_color = $color_mix ? (4 * $XYZ[0] / $color_mix) : 0;
19 6 100       24 my $v_color = $color_mix ? (9 * $XYZ[1] / $color_mix) : 0;
20              
21 6         19 my $white_mix = $D65[0] + (15 * $D65[1]) + (3 * $D65[2]); # 19.21696
22 6         13 my $u_white = 0.197839825; # 4 * $D65[0] / $white_mix; #
23 6         11 my $v_white = 0.468336303; # 9 * $D65[1] / $white_mix; #
24              
25 6 100       33 my $l = ($XYZ[1] > $eta) ? (($XYZ[1] ** (1/3)) * 116 - 16) : ($kappa * $XYZ[1]);
26 6         18 my $u = 13 * $l * ($u_color - $u_white);
27 6         18 my $v = 13 * $l * ($v_color - $v_white);
28              
29 6         42 return ([ $l / 100 , ($u+134) / 354, ($v+140) / 262 ]);
30             }
31             sub to_xyz {
32 6     6 0 13 my ($luv) = shift;
33 6         21 my $l = $luv->[0] * 100;
34 6         19 my $u = $luv->[1] * 354 - 134;
35 6         16 my $v = $luv->[2] * 262 - 140;
36              
37 6         20 my $white_mix = $D65[0] + (15 * $D65[1]) + (3 * $D65[2]); # 19.21696
38 6         11 my $u_white = 0.197839825; # 4 * $D65[0] / $white_mix; #
39 6         11 my $v_white = 0.468336303; # 9 * $D65[1] / $white_mix; #
40              
41 6 100       25 my $u_color = $l ? (($u / 13 / $l) + $u_white) : 0;
42 6 100       21 my $v_color = $l ? (($v / 13 / $l) + $v_white) : 0;
43              
44 6 100       31 my $y = ($l > $kappa * $eta) ? ((($l+16) / 116) ** 3) : ($l / $kappa);
45 6 100       21 my $color_mix = $v_color ? (9 * $y / $v_color) : 0;
46 6         35 my $x = $u_color * $color_mix / 4;
47 6         18 my $z = ($color_mix - $x - (15 * $y)) / 3;
48 6         18 my $XYZ = [$x, $y, $z];
49              
50 6         21 return [ map { $XYZ->[$_] / $D65[$_] } 0 .. 2 ];
  18         71  
51             }
52              
53             Graphics::Toolkit::Color::Space->new(
54             alias => 'CIELUV', # space name is LUV
55             axis => [qw/L* u* v*/], # short l u v
56             range => [100, [-134, 220], [-140, 122]],
57             precision => 3,
58             convert => {XYZ => [\&to_xyz, \&from_xyz]},
59             );