Skip to content

Commit e3958e6

Browse files
committed
fixed LAB tests
1 parent f084522 commit e3958e6

File tree

8 files changed

+166
-106
lines changed

8 files changed

+166
-106
lines changed

Changes

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,3 @@
150150
* = initial release - moved code out of Chart module
151151
* \ created own distro
152152
* ~ small POD fixes
153-
154-
155-
* * added color set method: bowl
156-
* * added getter method: near_names

lib/Graphics/Toolkit/Color/Space/Instance/LAB.pm

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,41 +14,39 @@ my $lab_def = Graphics::Toolkit::Color::Space->new( prefix => 'CIE',
1414

1515
$lab_def->add_converter('RGB', \&to_rgb, \&from_rgb );
1616

17-
my @xyz_range = (0.95047, 1, 1.08883);
17+
my @D65 = (0.95047, 1, 1.08883); # illuminant
18+
my $eta = 0.008856 ;
19+
my $kappa = 903.3 / 100;
1820

1921
sub from_rgb {
2022
my ($r, $g, $b) = @{$_[0]};
21-
my ($x, $y, $z) = mult_matrix([[0.4124564, 0.2126729, 0.0193339],
22-
[0.3575761, 0.7151522, 0.1191920],
23-
[0.1804375, 0.0721750, 0.9503041]],
24-
apply_d65( $r ), apply_d65( $g ), apply_d65( $b ));
25-
say "x y z $x, $y, $z";
26-
$x /= 0.95047;
27-
$z /= 0.108883;
28-
29-
$x = ($x > 0.008856) ? ($x ** (1/3)) : (7.7870689 * $x + 0.137931034);
30-
$y = ($y > 0.008856) ? ($y ** (1/3)) : (7.7870689 * $y + 0.137931034);
31-
$z = ($z > 0.008856) ? ($z ** (1/3)) : (7.7870689 * $z + 0.137931034);
32-
33-
return ((116 * $y) - 16, $a = 500 * ($x - $y), 200 * ($y - $z));
23+
my (@xyz) = mult_matrix([[0.4124564, 0.2126729, 0.0193339],
24+
[0.3575761, 0.7151522, 0.1191920],
25+
[0.1804375, 0.0721750, 0.9503041]], apply_d65($r), apply_d65($g), apply_d65($b));
26+
@xyz = map { $xyz[$_] / $D65[$_] } 0 .. 2;
27+
@xyz = map { $_ > $eta ? ($_ ** (1/3)) : ((($kappa * $_) + .16) / 1.16) } @xyz;
28+
29+
return ((1.16 * $xyz[1]) - .16, ($xyz[0] - $xyz[1] + 1) / 2, (($xyz[1] - $xyz[2] + 1) / 2)); # l a b
3430
}
3531

3632

3733
sub to_rgb {
3834
my ($l, $a, $b) = @{$_[0]};
39-
my $y = ($l + 16) / 116;
40-
my $x = ($a / 500) + $y;
41-
my $z = $y - ($b / 200);
42-
$x = ($x**3 > 0.008856) ? ($x ** 3) : (($x - 0.137931034) / 7.7870689);
43-
$y = ($y**3 > 0.008856) ? ($y ** 3) : (($y - 0.137931034) / 7.7870689);
44-
$z = ($z**3 > 0.008856) ? ($z ** 3) : (($z - 0.137931034) / 7.7870689);
45-
$x *= 0.95047;
46-
$z *= 0.108883;
47-
my ($r, $g, $bl) = mult_matrix([[ 3.2404542, -0.9692660, 0.0556434],
48-
[-1.5371385, 1.8760108, -0.2040259],
49-
[-0.4985314, 0.0415560, 1.0572252]], $x, $y, $z);
50-
51-
return ( remove_d65($r), remove_d65($g), remove_d65($bl));
35+
my $y = ($l + .16) / 1.16;
36+
my $x = $y + (($a * 2)-1);
37+
my $z = $y - (($b * 2)-1);
38+
39+
$x = ($x**3 > $eta) ? ($x ** 3) : ($kappa * (($x * 1.16) - .16));
40+
$y = ($y**3 > ($eta * $kappa)) ? ($y ** 3) : ($kappa * $l);
41+
$z = ($z**3 > $eta) ? ($z ** 3) : ($kappa * (($z * 1.16) - .16));
42+
43+
$x *= $D65[0];
44+
$z *= $D65[2];
45+
my (@rgb) = mult_matrix([[ 3.2404542, -0.9692660, 0.0556434],
46+
[-1.5371385, 1.8760108, -0.2040259],
47+
[-0.4985314, 0.0415560, 1.0572252]], $x, $y, $z);
48+
49+
return ( map { remove_d65($_) } @rgb );
5250
}
5351

5452
$lab_def;

lib/Graphics/Toolkit/Color/Space/Instance/LUV.pm

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,47 @@ use Graphics::Toolkit::Color::Space::Util qw/mult_matrix apply_d65 remove_d65/;
99

1010

1111
# cyan-orange balance, magenta-green balance
12-
my $luv_def = Graphics::Toolkit::Color::Space->new( axis => [qw/L* u* v*/],
13-
prefix => 'CIE',
14-
range => [1, 1, 1] );
12+
my $luv_def = Graphics::Toolkit::Color::Space->new( prefix => 'CIE',
13+
axis => [qw/L* u* v*/],
14+
range => [100, 1, 1] );
1515

1616
$luv_def->add_converter('RGB', \&to_rgb, \&from_rgb );
1717

18+
my @D65 = (0.95047, 1, 1.08883); # illuminant
19+
my $eta = 0.008856 ;
20+
my $kappa = 903.3 / 100;
21+
1822
sub from_rgb {
19-
my ($r, $g, $b) = @_;
20-
return mult_matrix([[0.4124564, 0.2126729, 0.0193339],
21-
[0.3575761, 0.7151522, 0.1191920],
22-
[0.1804375, 0.0721750, 0.9503041]], apply_d65( $r ), apply_d65( $g ), apply_d65( $b ));
23+
my ($r, $g, $b) = @{$_[0]};
24+
my (@xyz) = mult_matrix([[0.4124564, 0.2126729, 0.0193339],
25+
[0.3575761, 0.7151522, 0.1191920],
26+
[0.1804375, 0.0721750, 0.9503041]], apply_d65($r), apply_d65($g), apply_d65($b));
27+
@xyz = map { $xyz[$_] / $D65[$_] } 0 .. 2;
28+
@xyz = map { $_ > $eta ? ($_ ** (1/3)) : ((($kappa * $_) + .16) / 1.16) } @xyz;
29+
30+
return ((1.16 * $xyz[1]) - .16, ($xyz[0] - $xyz[1] + 1) / 2, (($xyz[1] - $xyz[2] + 1) / 2)); # l a b
2331
}
2432

25-
sub to_rgb {
26-
my ($x, $y, $z) = @_;
27-
my ($r, $g, $b) = mult_matrix([[ 3.2404542, -0.9692660, 0.0556434],
28-
[-1.5371385, 1.8760108, -0.2040259],
29-
[-0.4985314, 0.0415560, 1.0572252]], $x, $y, $z);
3033

31-
return ( remove_d65($r), remove_d65($g), remove_d65($b));
34+
sub to_rgb {
35+
my ($l, $a, $b) = @{$_[0]};
36+
my $y = ($l + .16) / 1.16;
37+
my $x = $y + (($a * 2)-1);
38+
my $z = $y - (($b * 2)-1);
39+
40+
$x = ($x**3 > $eta) ? ($x ** 3) : ($kappa * (($x * 1.16) - .16));
41+
$y = ($y**3 > ($eta * $kappa)) ? ($y ** 3) : ($kappa * $l);
42+
$z = ($z**3 > $eta) ? ($z ** 3) : ($kappa * (($z * 1.16) - .16));
43+
44+
$x *= $D65[0];
45+
$z *= $D65[2];
46+
my (@rgb) = mult_matrix([[ 3.2404542, -0.9692660, 0.0556434],
47+
[-1.5371385, 1.8760108, -0.2040259],
48+
[-0.4985314, 0.0415560, 1.0572252]], $x, $y, $z);
49+
50+
return ( map { remove_d65($_) } @rgb );
3251
}
3352

3453
$luv_def;
54+
55+
#say "xyz r : @xyz";

lib/Graphics/Toolkit/Color/Space/Instance/XYZ.pm

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ package Graphics::Toolkit::Color::Space::Instance::XYZ;
77
use Graphics::Toolkit::Color::Space;
88
use Graphics::Toolkit::Color::Space::Util qw/mult_matrix apply_d65 remove_d65/;
99

10-
my @range = (0.95047, 1, 1.08883);
10+
my @D65 = (0.95047, 1, 1.08883);
1111
my $xyz_def = Graphics::Toolkit::Color::Space->new( prefix => 'CIE',
1212
axis => [qw/X Y Z/],
13-
range => [map {$range[$_] * 100} 0 .. 2],
13+
range => [map {$D65[$_] * 100} 0 .. 2],
1414
precision => 3, );
1515

1616
$xyz_def->add_converter('RGB', \&to_rgb, \&from_rgb );
@@ -20,12 +20,12 @@ sub from_rgb {
2020
my (@xyz) = mult_matrix([[0.4124564, 0.2126729, 0.0193339],
2121
[0.3575761, 0.7151522, 0.1191920],
2222
[0.1804375, 0.0721750, 0.9503041]], apply_d65( $r ), apply_d65( $g ), apply_d65( $b ));
23-
map {$xyz[$_] / $range[$_]} 0 .. 2;
23+
map {$xyz[$_] / $D65[$_]} 0 .. 2;
2424
}
2525

2626
sub to_rgb {
2727
my (@xyz) = @{$_[0]};
28-
@xyz = map { $xyz[$_] * $range[$_] } 0 .. 2;
28+
@xyz = map { $xyz[$_] * $D65[$_] } 0 .. 2;
2929
my ($r, $g, $b) = mult_matrix([[ 3.2404542, -0.9692660, 0.0556434],
3030
[-1.5371385, 1.8760108, -0.2040259],
3131
[-0.4985314, 0.0415560, 1.0572252]], @xyz);

lib/Graphics/Toolkit/Color/Space/Util.pm

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,3 @@ sub mult_matrix {
5959

6060

6161
1;
62-
63-
# min(floor(val*256),255)

t/22_lab_space.t

Lines changed: 80 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
use v5.12;
44
use warnings;
5-
use Test::More tests => 57;
5+
use Test::More tests => 92;
66

7-
BEGIN { unshift @INC, 'lib', '../lib'}
7+
BEGIN { unshift @INC, 'lib', '../lib', 't/lib'}
88
my $module = 'Graphics::Toolkit::Color::Space::Instance::LAB';
99

1010
my $space = eval "require $module";
1111
use Graphics::Toolkit::Color::Space::Util ':all';
12+
#use Test::Color ':all';
1213

1314
is( not($@), 1, 'could load the module');
1415
is( ref $space, 'Graphics::Toolkit::Color::Space', 'got tight return value by loading module');
@@ -44,69 +45,96 @@ is( $val->[2], -0.1, 'third value good');
4445
is( $space->format([0,1,0], 'css_string'), 'cielab(0, 1, 0)', 'can format css string');
4546

4647
$val = $space->deconvert( [ 0, 0, 0], 'RGB');
47-
is( ref $val, 'ARRAY', 'deconverted tuple of zeros');
48+
is( ref $val, 'ARRAY', 'deconverted tuple of zeros (black)');
49+
is( int @$val, 3, 'right amount of values');
50+
is( close_enough( $val->[0] , 0), 1, 'first value good');
51+
is( close_enough( $val->[1] , 0.5), 1, 'second value good');
52+
is( close_enough( $val->[2] , 0.5), 1, 'third value good');
53+
54+
$val = $space->denormalize( [0, .5, .5] );
55+
is( ref $val, 'ARRAY', 'denormalized deconverted tuple of zeros');
4856
is( int @$val, 3, 'right amount of values');
4957
is( close_enough( $val->[0] , 0), 1, 'first value good');
5058
is( close_enough( $val->[1] , 0), 1, 'second value good');
5159
is( close_enough( $val->[2] , 0), 1, 'third value good');
5260

53-
$val = $space->convert( [ 0, 0, 0], 'RGB');
54-
is( ref $val, 'ARRAY', 'converted tuple of zeros');
55-
is( int @$val, 3, 'right amount of values');
61+
$val = $space->normalize( [0, 0, 0] );
62+
is( ref $val, 'ARRAY', 'normalized tuple of zeros');
63+
is( int @$val, 3, 'right amount of values');
64+
is( close_enough( $val->[0] , 0), 1, 'first value good');
65+
is( close_enough( $val->[1] , 0.5), 1, 'second value good');
66+
is( close_enough( $val->[2] , 0.5), 1, 'third value good');
67+
68+
$val = $space->convert( [ 0, 0.5, 0.5], 'RGB');
69+
is( ref $val, 'ARRAY', 'converted white to RGB');
70+
is( int @$val, 3, 'right amount of values');
5671
is( close_enough( $val->[0] , 0), 1, 'first value good');
5772
is( close_enough( $val->[1] , 0), 1, 'second value good');
5873
is( close_enough( $val->[2] , 0), 1, 'third value good');
5974

6075
$val = $space->deconvert( [ 1, 1, 1,], 'RGB');
61-
is( ref $val, 'ARRAY', 'deconverted tuple of zeros');
76+
is( ref $val, 'ARRAY', 'deconverted tuple of ones (white)');
77+
is( int @$val, 3, 'right amount of values');
78+
is( close_enough($val->[0], 1), 1, 'first value good');
79+
is( close_enough($val->[1], 0.5), 1, 'second value good');
80+
is( close_enough($val->[2], 0.5), 1, 'third value good');
81+
82+
$val = $space->convert( [ 1, 0.5, 0.5], 'RGB');
83+
is( ref $val, 'ARRAY', 'converted tuple of zeros');
6284
is( int @$val, 3, 'right amount of values');
6385
is( close_enough( $val->[0] , 1), 1, 'first value good');
86+
is( close_enough( $val->[1] , 1), 1, 'second value good');
87+
is( close_enough( $val->[2] , 1), 1, 'third value good');
88+
89+
$val = $space->deconvert( [ 0.5, 0.5, 0.5], 'RGB');
90+
is( ref $val, 'ARRAY', 'converted gray to RGB');
91+
is( int @$val, 3, 'right amount of values');
92+
is( close_enough( $val->[0] , .53389), 1, 'first value good');
93+
is( close_enough( $val->[1] , .5), 1, 'second value good');
94+
is( close_enough( $val->[2] , .5), 1, 'third value good');
95+
96+
$val = $space->denormalize( [0.53389, .5, .5] );
97+
is( ref $val, 'ARRAY', 'denormalized deconverted gray');
98+
is( int @$val, 3, 'right amount of values');
99+
is( close_enough( $val->[0] , 53.389), 1, 'first value good');
64100
is( close_enough( $val->[1] , 0), 1, 'second value good');
65-
is( $val->[2], 1, 'third value good');
66-
67-
68-
exit 0;
101+
is( close_enough( $val->[2] , 0), 1, 'third value good');
69102

70-
my @xyz = $space->deconvert( [ 0.5, 0.5, 0.5], 'RGB');
71-
is( int @xyz, 3, 'converted color grey has three XYZ values');
72-
is( close_enough($xyz[0], 0.20344), 1, 'converted color grey has computed right X value');
73-
is( close_enough($xyz[1], 0.21404), 1, 'converted color grey has computed right Y value');
74-
is( close_enough($xyz[2], 0.23305), 1, 'converted color grey has computed right Z value');
75-
76-
@xyz = $space->deconvert( [ 1, 1, 1], 'RGB');
77-
is( int @xyz, 3, 'converted color white has three XYZ values');
78-
is( close_enough($xyz[0], 0.95047), 1, 'converted color white has computed right X value');
79-
is( close_enough($xyz[1], 1), 1, 'converted color white has computed right Y value');
80-
is( close_enough($xyz[2], 1.08883), 1, 'converted color white has computed right Z value');
81-
82-
@xyz = $space->deconvert( [ 1, 0, 0.5], 'RGB');
83-
is( int @xyz, 3, 'converted color pink has three XYZ values');
84-
is( close_enough($xyz[0], 0.45108), 1, 'converted color pink has computed right X value');
85-
is( close_enough($xyz[1], 0.22821), 1, 'converted color pink has computed right Y value');
86-
is( close_enough($xyz[2], 0.22274), 1, 'converted color pink has computed right Z value');
87-
88-
my @rgb = $space->convert( [0, 0, 0], 'RGB');
89-
is( int @rgb, 3, 'converted back black with 3 values');
90-
is( close_enough($rgb[0], 0), 1, 'right red value');
91-
is( close_enough($rgb[1], 0), 1, 'right green value');
92-
is( close_enough($rgb[2], 0), 1, 'right blue value');
93-
94-
@rgb = $space->convert( [0.20344, 0.21404, 0.23305], 'RGB');
95-
is( int @rgb, 3, 'converted back gray with 3 values');
96-
is( close_enough($rgb[0], 0.5), 1, 'right red value');
97-
is( close_enough($rgb[1], 0.5), 1, 'right green value');
98-
is( close_enough($rgb[2], 0.5), 1, 'right blue value');
99-
100-
@rgb = $space->convert( [0.95047, 1, 1.08883], 'RGB');
101-
is( int @rgb, 3, 'converted back gray with 3 values');
102-
is( close_enough($rgb[0], 1), 1, 'right red value');
103-
is( close_enough($rgb[1], 1), 1, 'right green value');
104-
is( close_enough($rgb[2], 1), 1, 'right blue value');
105-
106-
@rgb = $space->convert( [0.45108, 0.22821, 0.22274], 'RGB');
107-
is( int @rgb, 3, 'converted back gray with 3 values');
108-
is( close_enough($rgb[0], 1 ), 1, 'right red value');
109-
is( close_enough($rgb[1], 0 ), 1, 'right green value');
110-
is( close_enough($rgb[2], 0.5), 1, 'right blue value');
103+
$val = $space->convert( [ 0.53389, .5, .5], 'RGB');
104+
is( ref $val, 'ARRAY', 'converted back gray to RGB');
105+
is( int @$val, 3, 'right amount of values');
106+
is( close_enough( $val->[0] , .5), 1, 'first value good');
107+
is( close_enough( $val->[1] , .5), 1, 'second value good');
108+
is( close_enough( $val->[2] , .5), 1, 'third value good');
109+
110+
111+
$val = $space->deconvert( [ 1, 0, 0.5], 'RGB');
112+
is( ref $val, 'ARRAY', 'converted purple from RGB');
113+
is( int @$val, 3, 'right amount of values');
114+
is( close_enough( $val->[0] , .54878), 1, 'first value good');
115+
is( close_enough( $val->[1] , .584499), 1, 'second value good');
116+
is( close_enough( $val->[2] , .5109), 1, 'third value good');
117+
118+
$val = $space->convert( [ 0.54878, .584499, .5109], 'RGB');
119+
is( ref $val, 'ARRAY', 'converted back gray to RGB');
120+
is( int @$val, 3, 'right amount of values');
121+
is( close_enough( $val->[0] , 1), 1, 'first value good');
122+
is( close_enough( $val->[1] , 0), 1, 'second value good');
123+
is( close_enough( $val->[2] , .5), 1, 'third value good');
124+
125+
126+
$val = $space->deconvert( [ .1, 0.2, 0.9], 'RGB');
127+
is( ref $val, 'ARRAY', 'converted BLUE from RGB');
128+
is( int @$val, 3, 'right amount of values');
129+
is( close_enough( $val->[0] , .34526), 1, 'first value good');
130+
is( close_enough( $val->[1] , .557165), 1, 'second value good');
131+
is( close_enough( $val->[2] , .2757375),1, 'third value good');
132+
133+
$val = $space->convert( [ 0.34526, .557165, .2757375], 'RGB');
134+
is( ref $val, 'ARRAY', 'converted back BLUE to RGB');
135+
is( int @$val, 3, 'right amount of values');
136+
is( close_enough( $val->[0] , .1), 1, 'first value good');
137+
is( close_enough( $val->[1] , .2), 1, 'second value good');
138+
is( close_enough( $val->[2] , .9), 1, 'third value good');
111139

112140
exit 0;

t/23_luv_space.t

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,21 @@ use warnings;
55
use Test::More tests => 40;
66

77
BEGIN { unshift @INC, 'lib', '../lib'}
8-
my $module = 'Graphics::Toolkit::Color::Space::Instance::YIQ';
8+
my $module = 'Graphics::Toolkit::Color::Space::Instance::LUV';
99

1010
my $def = eval "require $module";
1111
use Graphics::Toolkit::Color::Space::Util ':all';
1212

1313
is( not($@), 1, 'could load the module');
1414
is( ref $def, 'Graphics::Toolkit::Color::Space', 'got tight return value by loading module');
15-
is( $def->name, 'YIQ', 'color space has right name');
16-
is( $def->dimensions, 3, 'color space has 3 dimensions');
15+
is( $def->name, 'CIELUV', 'color space has right name');
16+
is( $def->axis, 3, 'color space has 3 dimensions');
1717
is( $def->is_array([0,0,0]), 1, 'vector has 3 elements');
1818
is( $def->is_partial_hash({i => 1, quadrature => 0}), 1, 'found hash with some keys');
1919
is( $def->can_convert('rgb'), 1, 'do only convert from and to rgb');
2020
is( $def->can_convert('yiq'), 0, 'can not convert to itself');
2121
is( $def->format([0,0,0], 'css_string'), 'yiq(0,0,0)', 'can format css string');
22-
my @val = $def->deformat(['YIQ', 1, 0, -0.1]);
22+
my @val = $def->deformat(['LUV', 1, 0, -0.1]);
2323
is( int @val, 3, 'deformated value triplet (vector)');
2424
is( $val[0], 1, 'first value good');
2525
is( $val[1], 0, 'second value good');

t/lib/Test/Color.pm

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
use v5.12;
2+
use warnings;
3+
4+
# utilities for any sub module of the distribution
5+
6+
package Test::Color;
7+
8+
use Exporter 'import';
9+
our @EXPORT_OK = qw/close_enough/;
10+
our %EXPORT_TAGS = (all => [@EXPORT_OK]);
11+
12+
my $half = 0.50000000000008;
13+
my $tolerance = 0.00000000000008;
14+
15+
16+
sub close_enough { abs($_[0] - $_[1]) < 0.008 if defined $_[1]}
17+
18+
19+
1;

0 commit comments

Comments
 (0)