| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
# ============================================================================= |
|
2
|
|
|
|
|
|
|
package Color::Model::Munsell::Util; |
|
3
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------- |
|
4
|
|
|
|
|
|
|
$Color::Model::Munsell::Util::VERSION = '0.03'; |
|
5
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------- |
|
6
|
1
|
|
|
1
|
|
30074
|
use warnings; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
33
|
|
|
7
|
1
|
|
|
1
|
|
5
|
use strict; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
38
|
|
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
=head1 NAME |
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
Color::Model::Munsell::Util - Utility functions for Color::Model::Munsell |
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
use Color::Model::Munsell; |
|
16
|
|
|
|
|
|
|
use Color::Model::Munsell::Util; |
|
17
|
|
|
|
|
|
|
use Color::Model::RGB; |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
my $m = Color::Model::Munsell->new("5R 4.5/14"); |
|
20
|
|
|
|
|
|
|
printf("Munsell: %s = RGB: #%s\n", $m, Munsell2RGB($m)); |
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
C gives some utility functions for color |
|
25
|
|
|
|
|
|
|
conversion from Munsell to CIE xyY, XYZ or RGB, etc. |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
=cut |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
# ============================================================================= |
|
30
|
1
|
|
|
1
|
|
5
|
use Carp qw(); |
|
|
1
|
|
|
|
|
6
|
|
|
|
1
|
|
|
|
|
17
|
|
|
31
|
1
|
|
|
1
|
|
5
|
use List::Util qw(first); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
99
|
|
|
32
|
1
|
|
|
1
|
|
4
|
use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
74
|
|
|
33
|
1
|
|
|
1
|
|
4
|
use base qw(Exporter); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
114
|
|
|
34
|
|
|
|
|
|
|
@EXPORT = qw(Munsell2RGB); |
|
35
|
|
|
|
|
|
|
@EXPORT_OK = qw( |
|
36
|
|
|
|
|
|
|
huedegree calc_Yc |
|
37
|
|
|
|
|
|
|
Munsell2xyY Munsell2XYZ Munsell2XYZD65 Munsell2rgb |
|
38
|
|
|
|
|
|
|
); |
|
39
|
|
|
|
|
|
|
|
|
40
|
1
|
|
|
1
|
|
911
|
use Math::VectorReal; |
|
|
1
|
|
|
|
|
3142
|
|
|
|
1
|
|
|
|
|
64
|
|
|
41
|
1
|
|
|
1
|
|
7
|
use Color::Model::Munsell qw(@hue_order %hue_number); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
145
|
|
|
42
|
1
|
|
|
1
|
|
1041
|
use Color::Model::RGB; |
|
|
1
|
|
|
|
|
12869
|
|
|
|
1
|
|
|
|
|
4000
|
|
|
43
|
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
my $_debug = 0; |
|
45
|
0
|
|
|
0
|
|
0
|
sub _debug { warn join(" ",@_); } |
|
46
|
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
# ============================================================================= |
|
48
|
|
|
|
|
|
|
my @_tableAll = (); |
|
49
|
|
|
|
|
|
|
my %_tableC = (); |
|
50
|
|
|
|
|
|
|
my $_tableC_loaded = 0; |
|
51
|
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------- |
|
54
|
|
|
|
|
|
|
sub _table |
|
55
|
|
|
|
|
|
|
{ |
|
56
|
10
|
|
|
10
|
|
24
|
my $v = shift; |
|
57
|
10
|
|
|
|
|
84
|
$v = sprintf('%d',$v); |
|
58
|
10
|
|
|
|
|
32
|
_load_table_C(); |
|
59
|
10
|
50
|
33
|
|
|
87
|
if ( $v && $_tableC{$v} ){ |
|
60
|
|
|
|
|
|
|
# return same value data sorted by chroma |
|
61
|
10
|
|
|
|
|
16
|
return sort { $a->[2] <=> $b->[2] } @{$_tableC{$v}}; |
|
|
35265
|
|
|
|
|
49930
|
|
|
|
10
|
|
|
|
|
341
|
|
|
62
|
|
|
|
|
|
|
} else { |
|
63
|
0
|
0
|
|
|
|
0
|
return wantarray? @_tableAll: \@_tableAll; |
|
64
|
|
|
|
|
|
|
} |
|
65
|
|
|
|
|
|
|
} |
|
66
|
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
sub _load_table_C |
|
68
|
|
|
|
|
|
|
{ |
|
69
|
15
|
100
|
|
15
|
|
50
|
unless ( $_tableC_loaded ){ |
|
70
|
1
|
|
|
|
|
2
|
my $d; |
|
71
|
|
|
|
|
|
|
# append neutral color for convenience |
|
72
|
1
|
|
|
|
|
5
|
foreach my $v ( 0.2, 0.4, 0.6, 0.8, 1..10 ){ |
|
73
|
14
|
|
|
|
|
30
|
$d = [ 'N', $v, 0, _neutralxyY($v) ]; |
|
74
|
14
|
|
|
|
|
55
|
push @_tableAll, $d; |
|
75
|
14
|
|
|
|
|
18
|
push @{$_tableC{$v}}, $d; |
|
|
14
|
|
|
|
|
78
|
|
|
76
|
|
|
|
|
|
|
} |
|
77
|
|
|
|
|
|
|
|
|
78
|
1
|
|
|
|
|
8
|
while (){ |
|
79
|
5000
|
|
|
|
|
9077
|
tr/\r\n//d; |
|
80
|
5000
|
|
|
|
|
19403
|
s/^ +//g; |
|
81
|
5000
|
50
|
|
|
|
26267
|
next unless $_; |
|
82
|
5000
|
100
|
|
|
|
10442
|
next if /^#/; |
|
83
|
4995
|
|
|
|
|
25982
|
my @d = split(/\s+/); |
|
84
|
4995
|
|
|
|
|
10932
|
$d[5] /= 100; # rescale Y to (0,1) |
|
85
|
4995
|
|
|
|
|
15657
|
$d = [ @d ]; |
|
86
|
4995
|
|
|
|
|
10297
|
push @_tableAll, $d; |
|
87
|
4995
|
|
|
|
|
4946
|
push @{$_tableC{$d[1]}}, $d; # key is value |
|
|
4995
|
|
|
|
|
30931
|
|
|
88
|
|
|
|
|
|
|
} |
|
89
|
1
|
|
|
|
|
7
|
$_tableC_loaded++; |
|
90
|
|
|
|
|
|
|
} |
|
91
|
|
|
|
|
|
|
} |
|
92
|
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------- |
|
95
|
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=head1 EXPORT SUBROUTINES |
|
97
|
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
Only subroutine Munsell2RGB is exported by defalut. |
|
99
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
=head2 huedegree() |
|
101
|
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
$n = huedegree( "5R" ); |
|
103
|
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
Return degree number of Hue; considered 10.0RP is 0, 10R to be 10, 10YR 20, |
|
105
|
|
|
|
|
|
|
..., and ends 9.9RP as 99.9. |
|
106
|
|
|
|
|
|
|
If bad formatted hue given, this returns undef. |
|
107
|
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=cut |
|
109
|
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
sub huedegree |
|
111
|
|
|
|
|
|
|
{ |
|
112
|
31
|
50
|
33
|
31
|
1
|
825
|
if ( defined($_[0]) && $_[0] =~ /^(\d{1,2}|\d{1,2}\.\d)(R|YR|Y|GY|G|BG|B|PB|P|RP)$/ ){ |
|
113
|
31
|
|
|
|
|
128
|
my ($n,$c) = ($1,$2); |
|
114
|
31
|
50
|
|
|
|
175
|
if ( $n <= 10 ){ |
|
115
|
31
|
|
|
|
|
220
|
return $hue_number{$2} * 10 + $1; |
|
116
|
|
|
|
|
|
|
} |
|
117
|
|
|
|
|
|
|
} |
|
118
|
0
|
|
|
|
|
0
|
return undef; |
|
119
|
|
|
|
|
|
|
} |
|
120
|
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
# ============================================================================= |
|
123
|
|
|
|
|
|
|
# get xyY with linear interpolation |
|
124
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------- |
|
125
|
|
|
|
|
|
|
my @_Wcxy = (0.310061, 0.316150); |
|
126
|
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
=head2 Munsell2xyY() |
|
128
|
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
Munsell2xyY() returns an array of CIE x, y and Y which are calculated with |
|
130
|
|
|
|
|
|
|
linear interpolation from Munsell-xyY table. |
|
131
|
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
use Color::Model::Munsell::Util qw(Munsell2xyY); |
|
133
|
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
$m = Color::Model::Munsell->new("2.5G 5.5/10"); |
|
135
|
|
|
|
|
|
|
($x, $y, $Y) = Munsell2xyY($m); |
|
136
|
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
This Munsell-xyY table is from MCSL, R.I.T. which condition is using illuminant |
|
138
|
|
|
|
|
|
|
C and the CIE 1931 2 degree observer. |
|
139
|
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
=cut |
|
141
|
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
sub _getHueRange |
|
143
|
|
|
|
|
|
|
{ |
|
144
|
10
|
|
|
10
|
|
18
|
my ($h1, $h2); |
|
145
|
0
|
|
|
|
|
0
|
my ($hueStep, $hueCol); |
|
146
|
10
|
50
|
|
|
|
74
|
if ( $_[0] =~ /^([0-9\.]+)([A-Z]+)$/ ){ |
|
147
|
10
|
|
|
|
|
44
|
($hueStep, $hueCol) = ($1, $2); |
|
148
|
|
|
|
|
|
|
} |
|
149
|
10
|
50
|
|
|
|
74
|
if ( $hueStep < 2.5 ){ |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
150
|
0
|
0
|
|
|
|
0
|
my $pre_hC = ($hueCol eq 'R')? 'RP': $hue_order[$hue_number{$hueCol}-1]; |
|
151
|
0
|
|
|
|
|
0
|
($h1, $h2) = ( "10$pre_hC", "2.5$hueCol" ); |
|
152
|
|
|
|
|
|
|
} elsif ( $hueStep < 5.0 ){ |
|
153
|
0
|
|
|
|
|
0
|
($h1, $h2) = ( "2.5$hueCol", "5$hueCol" ); |
|
154
|
|
|
|
|
|
|
} elsif ( $hueStep < 7.5 ){ |
|
155
|
10
|
|
|
|
|
58
|
($h1, $h2) = ( "5$hueCol", "7.5$hueCol" ); |
|
156
|
|
|
|
|
|
|
} else { |
|
157
|
0
|
|
|
|
|
0
|
($h1, $h2) = ( "7.5$hueCol", "10$hueCol" ); |
|
158
|
|
|
|
|
|
|
} |
|
159
|
10
|
|
|
|
|
39
|
return ($h1, $h2); |
|
160
|
|
|
|
|
|
|
} |
|
161
|
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
sub _neutralxyY |
|
163
|
|
|
|
|
|
|
{ |
|
164
|
14
|
|
|
14
|
|
21
|
my $value = shift; |
|
165
|
14
|
|
|
|
|
26
|
return ( @_Wcxy, calc_Yc($value)/100 ); # White Point of illuminant C |
|
166
|
|
|
|
|
|
|
} |
|
167
|
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
sub _getVectorOnValuePlane |
|
169
|
|
|
|
|
|
|
{ |
|
170
|
10
|
|
|
10
|
|
131
|
my ($h0,$v0,$c0) = @_; |
|
171
|
|
|
|
|
|
|
|
|
172
|
10
|
50
|
|
|
|
33
|
_debug(" * Cheking: $h0 $v0 / $c0\n") if $_debug; |
|
173
|
|
|
|
|
|
|
|
|
174
|
10
|
|
|
|
|
36
|
my ($h1,$h2) = _getHueRange($h0); |
|
175
|
10
|
50
|
|
|
|
26
|
_debug(" - - hue range = [ $h1, $h2 ]\n") if $_debug; |
|
176
|
|
|
|
|
|
|
|
|
177
|
10
|
|
|
|
|
47
|
my @luptable = _table($v0); |
|
178
|
10
|
50
|
|
5100
|
|
486
|
my $eqcheck = first { $_->[0] eq $h0 && $_->[2] eq $c0 } @luptable; |
|
|
5100
|
|
|
|
|
11521
|
|
|
179
|
10
|
50
|
|
|
|
85
|
return vector(@{$eqcheck}[3,4,5]) if ( $eqcheck ); # found just same data! |
|
|
0
|
|
|
|
|
0
|
|
|
180
|
10
|
100
|
|
|
|
47
|
my @h1 = grep { $_->[0] eq 'N' or $_->[0] eq $h1 } @luptable; |
|
|
5100
|
|
|
|
|
21796
|
|
|
181
|
10
|
100
|
|
|
|
81
|
my @h2 = grep { $_->[0] eq 'N' or $_->[0] eq $h2 } @luptable; |
|
|
5100
|
|
|
|
|
19960
|
|
|
182
|
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
# h1,h2 ... hue line ( h1 < h2) |
|
184
|
|
|
|
|
|
|
# c1,c2 ... chroma line (c1 < c2 ) |
|
185
|
|
|
|
|
|
|
# |
|
186
|
|
|
|
|
|
|
# [ on some value-plane ] |
|
187
|
|
|
|
|
|
|
# c1 c2 |
|
188
|
|
|
|
|
|
|
# | P C/ |
|
189
|
|
|
|
|
|
|
# h2 ----+-----+----------/-- - |
|
190
|
|
|
|
|
|
|
# B| | / ) 1-l |
|
191
|
|
|
|
|
|
|
# | *Z / - |
|
192
|
|
|
|
|
|
|
# | / | / ` l |
|
193
|
|
|
|
|
|
|
# | / | / / |
|
194
|
|
|
|
|
|
|
# h1 ----+-----+-----/--- - |
|
195
|
|
|
|
|
|
|
# A Q D |
|
196
|
|
|
|
|
|
|
# ` n ^ 1-n ' |
|
197
|
|
|
|
|
|
|
# |
|
198
|
|
|
|
|
|
|
# ( = vector x ) |
|
199
|
|
|
|
|
|
|
# = (1-n) + n |
|
200
|
|
|
|
|
|
|
# = n |
|
201
|
|
|
|
|
|
|
# = m + (1-m) |
|
202
|
|
|
|
|
|
|
# = (m-mn) + mn + (n-mn) |
|
203
|
|
|
|
|
|
|
# = m + n + mn(--) |
|
204
|
|
|
|
|
|
|
# = m + n + mn(-) |
|
205
|
|
|
|
|
|
|
|
|
206
|
10
|
|
|
|
|
22
|
my ($dA,$dB,$dC,$dD); # lookup data |
|
207
|
0
|
|
|
|
|
0
|
my ($OA,$OB,$OC,$OD); # vectors |
|
208
|
0
|
|
|
|
|
0
|
my ($c1,$c2); # chroma values of two points |
|
209
|
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
# - on line of h1 |
|
211
|
10
|
|
|
80
|
|
159
|
$dD = first { $_->[2] >= $c0 } @h1; |
|
|
80
|
|
|
|
|
142
|
|
|
212
|
10
|
50
|
|
|
|
84
|
unless ( $dD ){ |
|
213
|
|
|
|
|
|
|
# not found, maybe target's chroma is larger than max chroma |
|
214
|
|
|
|
|
|
|
# of lookup table |
|
215
|
0
|
|
|
|
|
0
|
return undef; |
|
216
|
|
|
|
|
|
|
} |
|
217
|
10
|
|
|
|
|
27
|
$OD = vector( @{$dD}[3,4,5] ); |
|
|
10
|
|
|
|
|
114
|
|
|
218
|
10
|
|
|
|
|
365
|
($c1,$c2) = ($dD->[2]-2, $dD->[2]); |
|
219
|
|
|
|
|
|
|
|
|
220
|
10
|
|
|
70
|
|
67
|
$dA = first { $_->[2] == $c1 } @h1; |
|
|
70
|
|
|
|
|
130
|
|
|
221
|
10
|
|
|
|
|
35
|
$OA = vector( @{$dA}[3,4,5] ); |
|
|
10
|
|
|
|
|
46
|
|
|
222
|
|
|
|
|
|
|
|
|
223
|
10
|
50
|
|
|
|
170
|
if ( $_debug ){ |
|
224
|
0
|
|
|
|
|
0
|
_debug(" - - - $h1> OA = ($dA->[0] $dA->[1]/ $dA->[2]) \n"); |
|
225
|
0
|
|
|
|
|
0
|
_debug(" - - - $h1> OD = ($dD->[0] $dD->[1]/ $dD->[2]) \n"); |
|
226
|
|
|
|
|
|
|
} |
|
227
|
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
# - on line of h2 |
|
229
|
10
|
|
|
80
|
|
89
|
$dC = first { $_->[2] >= $c0 } @h2; |
|
|
80
|
|
|
|
|
126
|
|
|
230
|
10
|
50
|
|
|
|
56
|
unless ( $dC ){ |
|
231
|
|
|
|
|
|
|
# not found on lookup table |
|
232
|
0
|
|
|
|
|
0
|
return undef; |
|
233
|
|
|
|
|
|
|
} |
|
234
|
10
|
|
|
|
|
22
|
$OC = vector( @{$dC}[3,4,5] ); |
|
|
10
|
|
|
|
|
32
|
|
|
235
|
10
|
|
|
|
|
182
|
($c1,$c2) = ($dC->[2]-2, $dC->[2]); |
|
236
|
|
|
|
|
|
|
|
|
237
|
10
|
|
|
70
|
|
75
|
$dB = first { $_->[2] == $c1 } @h2; |
|
|
70
|
|
|
|
|
155
|
|
|
238
|
10
|
|
|
|
|
38
|
$OB = vector( @{$dB}[3,4,5] ); |
|
|
10
|
|
|
|
|
43
|
|
|
239
|
|
|
|
|
|
|
|
|
240
|
10
|
50
|
|
|
|
157
|
if ( $_debug ){ |
|
241
|
0
|
|
|
|
|
0
|
_debug(" - - - $h2> OB = ($dB->[0] $dB->[1]/ $dB->[2]) \n"); |
|
242
|
0
|
|
|
|
|
0
|
_debug(" - - - $h2> OC = ($dC->[0] $dC->[1]/ $dC->[2]) \n"); |
|
243
|
|
|
|
|
|
|
} |
|
244
|
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
# calculate ratio |
|
246
|
10
|
|
|
|
|
45
|
my $n = ($c0 - $c1) / ($c2 - $c1); # ratio between chromas |
|
247
|
10
|
|
|
|
|
20
|
my ($h0n, $h1n, $h2n) = map { huedegree($_) } ($h0, $h1, $h2); |
|
|
30
|
|
|
|
|
80
|
|
|
248
|
10
|
|
|
|
|
34
|
my $l = ($h0n - $h1n) / ($h2n - $h1n); # ratio between hues |
|
249
|
10
|
50
|
|
|
|
44
|
if ( $_debug ){ |
|
250
|
0
|
|
|
|
|
0
|
_debug(" - - - Ratio chroma; ($c0 - $1) / ($c2 - $c1) = $n\n"); |
|
251
|
0
|
|
|
|
|
0
|
_debug(" - - - Ratio hue; ($h0n - $h1n) / ($h2n - $h1n) = $l\n"); |
|
252
|
|
|
|
|
|
|
} |
|
253
|
|
|
|
|
|
|
|
|
254
|
10
|
|
|
|
|
158
|
my $AB = $OB - $OA; |
|
255
|
10
|
|
|
|
|
717
|
my $AD = $OD - $OA; |
|
256
|
10
|
|
|
|
|
434
|
my $BC = $OC - $OB; |
|
257
|
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
# return value is a vector with Math::RealVector; |
|
259
|
10
|
|
|
|
|
499
|
my $AZ = $AB*$l + $AD*$n+ ($BC-$AD)*$l*$n; |
|
260
|
10
|
|
|
|
|
2566
|
my $OZ = $OA + $AZ; |
|
261
|
|
|
|
|
|
|
|
|
262
|
10
|
50
|
|
|
|
482
|
_debug(map { sprintf("%s = (%.4f, %.4f, %.4f)\n", $_, eval"\$$_->array()") } qw(OA OB OC OD OZ)) if $_debug; |
|
|
0
|
|
|
|
|
0
|
|
|
263
|
10
|
|
|
|
|
352
|
return $OZ; |
|
264
|
|
|
|
|
|
|
} |
|
265
|
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
sub Munsell2xyY |
|
267
|
|
|
|
|
|
|
{ |
|
268
|
5
|
|
|
5
|
1
|
11
|
my $m = shift; |
|
269
|
5
|
50
|
33
|
|
|
41
|
unless ( defined($m) && ref($m) eq 'Color::Model::Munsell' ){ |
|
270
|
0
|
|
|
|
|
0
|
Carp::croak("Color::Model::Munsell object is not given"); |
|
271
|
|
|
|
|
|
|
} |
|
272
|
5
|
50
|
|
|
|
16
|
_debug("<< Target: $m >>\n") if $_debug; |
|
273
|
5
|
|
|
|
|
28
|
my $v = $m->value; |
|
274
|
|
|
|
|
|
|
|
|
275
|
5
|
50
|
|
|
|
57
|
if ( $m->isneutral ){ |
|
276
|
0
|
|
|
|
|
0
|
my @ret = _neutralxyY($v); |
|
277
|
0
|
0
|
|
|
|
0
|
_debug(sprintf("xyY = (%.6f, %.6f, %.6f)\n",@ret)) if $_debug; |
|
278
|
0
|
|
|
|
|
0
|
return @ret; |
|
279
|
|
|
|
|
|
|
} |
|
280
|
|
|
|
|
|
|
|
|
281
|
5
|
|
|
|
|
53
|
_load_table_C(); |
|
282
|
|
|
|
|
|
|
|
|
283
|
5
|
|
|
|
|
12
|
my ($LZ, $UZ, $Z); |
|
284
|
|
|
|
|
|
|
# get lower value-plane |
|
285
|
5
|
50
|
|
|
|
31
|
my $lv = ($v<1.0)? (int($v*10/2)*2/10): int($v); |
|
286
|
5
|
50
|
|
|
|
21
|
_debug(" - nearest lower value of $m is $lv\n") if $_debug; |
|
287
|
5
|
50
|
|
|
|
14
|
if ( $lv == 0 ){ |
|
288
|
0
|
|
|
|
|
0
|
$LZ = vector( _neutralxyY($v) ); |
|
289
|
|
|
|
|
|
|
} else { |
|
290
|
5
|
|
|
|
|
40
|
$LZ = _getVectorOnValuePlane( $m->hue, $lv, $m->chroma ); |
|
291
|
5
|
50
|
|
|
|
23
|
unless ( defined($LZ) ){ |
|
292
|
0
|
|
|
|
|
0
|
Carp::croak("$m is out of calculatable color space."); |
|
293
|
|
|
|
|
|
|
} |
|
294
|
|
|
|
|
|
|
} |
|
295
|
|
|
|
|
|
|
# get upper value-plane |
|
296
|
5
|
50
|
|
|
|
30
|
my $uv = ($v<1.0)? (int($v*10/2)*2/10+0.2): int($v+1); |
|
297
|
5
|
50
|
|
|
|
15
|
_debug(" - nearest upper value of $m is $uv\n") if $_debug; |
|
298
|
5
|
|
|
|
|
39
|
$UZ = _getVectorOnValuePlane( $m->hue, $uv, $m->chroma ); |
|
299
|
5
|
50
|
|
|
|
24
|
unless ( defined($UZ) ){ |
|
300
|
0
|
|
|
|
|
0
|
Carp::croak("$m is out of calculatable color space."); |
|
301
|
|
|
|
|
|
|
} |
|
302
|
|
|
|
|
|
|
|
|
303
|
5
|
50
|
|
|
|
21
|
_debug(" - value range = [ $lv, $uv ]\n") if $_debug; |
|
304
|
|
|
|
|
|
|
|
|
305
|
5
|
|
|
|
|
18
|
my $s = ($v - $lv) / ($uv - $lv ); # ratio between values; |
|
306
|
5
|
50
|
|
|
|
14
|
_debug(" - value ratio = ($v - $lv) / ($uv - $lv) = $s\n") if $_debug; |
|
307
|
|
|
|
|
|
|
|
|
308
|
5
|
|
|
|
|
19
|
$Z = $UZ*$s + $LZ*(1-$s); |
|
309
|
5
|
50
|
|
|
|
527
|
_debug(sprintf("xyY = (%.6f, %.6f, %.6f)\n",$Z->array())) if $_debug; |
|
310
|
|
|
|
|
|
|
|
|
311
|
5
|
|
|
|
|
18
|
return $Z->array(); # ( xc, yc , Yc ); |
|
312
|
|
|
|
|
|
|
} |
|
313
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------- |
|
314
|
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------- |
|
317
|
|
|
|
|
|
|
# multiply matrix * vector |
|
318
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------- |
|
319
|
|
|
|
|
|
|
sub _mmult |
|
320
|
|
|
|
|
|
|
{ |
|
321
|
5
|
|
|
5
|
|
10
|
my ($m,$v) = @_; |
|
322
|
|
|
|
|
|
|
return ( |
|
323
|
5
|
|
|
|
|
55
|
$$m[0][0]*$$v[0] + $$m[0][1]*$$v[1] + $$m[0][2]*$$v[2], |
|
324
|
|
|
|
|
|
|
$$m[1][0]*$$v[0] + $$m[1][1]*$$v[1] + $$m[1][2]*$$v[2], |
|
325
|
|
|
|
|
|
|
$$m[2][0]*$$v[0] + $$m[2][1]*$$v[1] + $$m[2][2]*$$v[2] |
|
326
|
|
|
|
|
|
|
); |
|
327
|
|
|
|
|
|
|
} |
|
328
|
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
# ============================================================================= |
|
331
|
|
|
|
|
|
|
# get XYZ from Munsell with xyY |
|
332
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------- |
|
333
|
|
|
|
|
|
|
my %_matCAdaptD65 = ( |
|
334
|
|
|
|
|
|
|
'XYZ' => [ |
|
335
|
|
|
|
|
|
|
[ 0.9691356, 0.0000000, 0.0000000], |
|
336
|
|
|
|
|
|
|
[ 0.0000000, 1.0000000, 0.0000000], |
|
337
|
|
|
|
|
|
|
[ 0.0000000, 0.0000000, 0.9209267]], |
|
338
|
|
|
|
|
|
|
'Bradford' => [ |
|
339
|
|
|
|
|
|
|
[ 0.9904476,-0.0071683,-0.0116156], |
|
340
|
|
|
|
|
|
|
[-0.0123712, 1.0155950,-0.0029282], |
|
341
|
|
|
|
|
|
|
[-0.0035635, 0.0067697, 0.9181569]], |
|
342
|
|
|
|
|
|
|
'vonKries' => [ |
|
343
|
|
|
|
|
|
|
[ 0.9972812,-0.0093756,-0.0154171], |
|
344
|
|
|
|
|
|
|
[-0.0010298, 1.0007636, 0.0002084], |
|
345
|
|
|
|
|
|
|
[ 0.0000000, 0.0000000, 0.9209267]] |
|
346
|
|
|
|
|
|
|
); |
|
347
|
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
=head2 Munsell2XYZ() |
|
349
|
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
=head2 Munsell2XYZD65() |
|
351
|
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
Munsell2XYZ( $m ) |
|
353
|
|
|
|
|
|
|
Munsell2XYZD65( $m [, "ChromaticAdaptType" ] ) |
|
354
|
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
Munsell2XYZ() and Munsell2XYZD65() returns an array of CIE X,Y and Z. |
|
356
|
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
$m = Color::Model::Munsell->new("7.5B 6/10"); |
|
358
|
|
|
|
|
|
|
printf("%s -> CIE XYZ (%.f, %.f, %.f)", $m, Munsell2XYZ($m)); |
|
359
|
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
# perform cromatic adaptation from C to D65 |
|
361
|
|
|
|
|
|
|
printf("%s -> CIE XYZ (%.f, %.f, %.f) via Chromatic Adaptation", $m, Munsell2XYZD65($m)); |
|
362
|
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
Munsell2XYZ() simply calculates XYZ from xyY. And Munsell2XYZD65() calculates |
|
364
|
|
|
|
|
|
|
them with chromatic adaptatation to illuminant D65. Adaptation type must be |
|
365
|
|
|
|
|
|
|
"XYZ", "vonKries", "Bradford" or "None". If Omitted, "Bradford" is used. |
|
366
|
|
|
|
|
|
|
Specifying "None" is same as calling Munsell2XYZ(). |
|
367
|
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
=cut |
|
369
|
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
sub Munsell2XYZ |
|
371
|
|
|
|
|
|
|
{ |
|
372
|
4
|
|
|
4
|
1
|
449
|
my $m = shift; # Color::Model::Munsell object |
|
373
|
4
|
50
|
33
|
|
|
30
|
unless ( defined($m) && ref($m) eq 'Color::Model::Munsell' ){ |
|
374
|
0
|
|
|
|
|
0
|
Carp::croak("Munsell2XYZ() needs Color::Model::Munsell object."); |
|
375
|
|
|
|
|
|
|
} |
|
376
|
|
|
|
|
|
|
|
|
377
|
4
|
|
|
|
|
12
|
my ($x,$y,$Y) = Munsell2xyY($m); |
|
378
|
4
|
|
|
|
|
57
|
my $X = ($x * $Y) / $y; # X = (Y/y) * x |
|
379
|
4
|
|
|
|
|
12
|
my $Z = ( (1 - $x - $y) * $Y ) / $y; # Z = ( (1-x-y)/y ) * Y |
|
380
|
4
|
|
|
|
|
45
|
return ($X, $Y, $Z); |
|
381
|
|
|
|
|
|
|
} |
|
382
|
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
sub Munsell2XYZD65 |
|
384
|
|
|
|
|
|
|
{ |
|
385
|
3
|
|
|
3
|
1
|
7
|
my $m = shift; # Color::Model::Munsell object |
|
386
|
3
|
50
|
33
|
|
|
30
|
unless ( defined($m) && ref($m) eq 'Color::Model::Munsell' ){ |
|
387
|
0
|
|
|
|
|
0
|
Carp::croak("Munsell2XYZD65() needs Color::Model::Munsell object."); |
|
388
|
|
|
|
|
|
|
} |
|
389
|
|
|
|
|
|
|
|
|
390
|
3
|
|
100
|
|
|
14
|
my $atype = shift || 'Bradford'; # Chromatic Adaptation type |
|
391
|
3
|
50
|
|
|
|
20
|
unless ( $atype =~ /^(None|XYZ|Bradford|vonKries)$/ ){ |
|
392
|
0
|
|
|
|
|
0
|
Carp::croak(qq(Chromatic Adaptation must be "XYZ", "Bradford" or "vonKries")); |
|
393
|
|
|
|
|
|
|
} |
|
394
|
3
|
50
|
|
|
|
9
|
_debug(" - Chromatic Adaptation = $atype\n") if $_debug; |
|
395
|
|
|
|
|
|
|
|
|
396
|
3
|
|
|
|
|
6
|
my @XYZ; |
|
397
|
3
|
50
|
|
|
|
10
|
if ( $atype ne 'None' ){ |
|
398
|
3
|
|
|
|
|
14
|
@XYZ = _mmult($_matCAdaptD65{$atype}, [ Munsell2XYZ($m) ]); |
|
399
|
|
|
|
|
|
|
} else { |
|
400
|
0
|
|
|
|
|
0
|
@XYZ = Munsell2XYZ($m); |
|
401
|
|
|
|
|
|
|
} |
|
402
|
3
|
50
|
|
|
|
15
|
_debug(sprintf("XYZ = (%.6f, %.6f, %.6F)\n",@XYZ)) if $_debug; |
|
403
|
3
|
|
|
|
|
20
|
return @XYZ; |
|
404
|
|
|
|
|
|
|
} |
|
405
|
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
# ============================================================================= |
|
408
|
|
|
|
|
|
|
# get RGB from XYZ |
|
409
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------- |
|
410
|
|
|
|
|
|
|
my %_matXYZ2rgb = ( |
|
411
|
|
|
|
|
|
|
'AdobeRGB' => [ # D65 |
|
412
|
|
|
|
|
|
|
[ 2.0413690, -0.5649464, -0.3446944], |
|
413
|
|
|
|
|
|
|
[-0.9692660, 1.8760108, 0.0415560], |
|
414
|
|
|
|
|
|
|
[ 0.0134474, -0.1183897, 1.0154096]], |
|
415
|
|
|
|
|
|
|
'AppleRGB' => [ # D65 |
|
416
|
|
|
|
|
|
|
[ 2.9515373, -1.2894116, -0.4738445], |
|
417
|
|
|
|
|
|
|
[-1.0851093, 1.9908566, 0.0372026], |
|
418
|
|
|
|
|
|
|
[ 0.0854934, -0.2694964, 1.0912975]], |
|
419
|
|
|
|
|
|
|
'PAL' => [ # D65 |
|
420
|
|
|
|
|
|
|
[ 3.0628971, -1.3931791, -0.4757517], |
|
421
|
|
|
|
|
|
|
[-0.9692660, 1.8760108, 0.0415560], |
|
422
|
|
|
|
|
|
|
[ 0.0678775, -0.2288548, 1.0693490]], |
|
423
|
|
|
|
|
|
|
'sRGB' => [ # D65 |
|
424
|
|
|
|
|
|
|
[ 3.2404542, -1.5371385, -0.4985314], |
|
425
|
|
|
|
|
|
|
[-0.9692660, 1.8760108, 0.0415560], |
|
426
|
|
|
|
|
|
|
[ 0.0556434, -0.2040259, 1.0572252]], |
|
427
|
|
|
|
|
|
|
'NTSC' => [ # C |
|
428
|
|
|
|
|
|
|
[ 1.9099961, -0.5324542, -0.2882091], |
|
429
|
|
|
|
|
|
|
[-0.9846663, 1.9991710, -0.0283082], |
|
430
|
|
|
|
|
|
|
[ 0.0583056, -0.1183781, 0.8975535]], |
|
431
|
|
|
|
|
|
|
); |
|
432
|
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
=head2 Munsell2rgb() |
|
435
|
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
=head2 Munsell2RGB() |
|
437
|
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
Munsell2rgb( $m [, "RGBModel" [, "ChromaticAdaptType" ]] ) |
|
439
|
|
|
|
|
|
|
Munsell2RGB( $m [, "RGBModel" [, "ChromaticAdaptType" [, $gamma ]]] ) |
|
440
|
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
Munsell2rgb() returns an array of R, G and B values which calculated from |
|
442
|
|
|
|
|
|
|
XYZ with transformation matrix. |
|
443
|
|
|
|
|
|
|
And Munsell2RGB() returns RGB values with C object which applied gamma value. |
|
444
|
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
$m = Color::Model::Munsell->new("7PB 2.5/3"); |
|
446
|
|
|
|
|
|
|
printf("%s -> RGB %s of sRGB", $m, Munsell2RGB($m)); |
|
447
|
|
|
|
|
|
|
printf("%s -> RGB %s of AdobeRGB(1998)", $m, Munsell2RGB($m,"AdobeRGB"), 2.2); |
|
448
|
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
RGBModel must be "sRGB", "AdobeRGB" that means Adobe RGB(1998), "AppleRGB" |
|
450
|
|
|
|
|
|
|
or "NTSC". A gamma value will be used when RGB model is not sRGB. |
|
451
|
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
=cut |
|
453
|
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
sub Munsell2rgb |
|
455
|
|
|
|
|
|
|
{ |
|
456
|
2
|
|
|
2
|
1
|
5
|
my $m = shift; # Color::Model::Munsell object |
|
457
|
2
|
50
|
33
|
|
|
20
|
unless ( defined($m) && ref($m) eq 'Color::Model::Munsell' ){ |
|
458
|
0
|
|
|
|
|
0
|
Carp::croak("Munsell2rgb() needs Color::Model::Munsell object."); |
|
459
|
|
|
|
|
|
|
} |
|
460
|
2
|
|
100
|
|
|
11
|
my $rgbtype = shift || 'sRGB'; # RGB type |
|
461
|
2
|
|
100
|
|
|
10
|
my $atype = shift || 'Bradford'; # Chromatic Adaptation type |
|
462
|
2
|
50
|
|
|
|
15
|
unless ( $rgbtype =~ /^(AdobeRGB|AppleRGB|PAL|sRGB|NTSC)$/ ){ |
|
463
|
0
|
|
|
|
|
0
|
Carp::croak(qq(RGB type must be "AdobeRGB", "AppleRGB", "PAL", "NTSC" or "sRGB")); |
|
464
|
|
|
|
|
|
|
} |
|
465
|
2
|
50
|
|
|
|
8
|
_debug(" - RGB = $rgbtype\n") if $_debug; |
|
466
|
|
|
|
|
|
|
|
|
467
|
2
|
|
|
|
|
3
|
my @XYZ; |
|
468
|
2
|
50
|
|
|
|
9
|
if ( $rgbtype eq 'NTSC' ){ |
|
469
|
0
|
|
|
|
|
0
|
@XYZ = Munsell2XYZ($m); |
|
470
|
|
|
|
|
|
|
} else { |
|
471
|
2
|
|
|
|
|
8
|
@XYZ = Munsell2XYZD65($m, $atype); |
|
472
|
|
|
|
|
|
|
} |
|
473
|
|
|
|
|
|
|
|
|
474
|
2
|
|
|
|
|
13
|
my @rgb = _mmult($_matXYZ2rgb{$rgbtype}, \@XYZ); |
|
475
|
2
|
50
|
|
|
|
8
|
_debug(sprintf("rgb = (%.6f, %.6f, %.6f)\n",@rgb)) if $_debug; |
|
476
|
2
|
|
|
|
|
16
|
return @rgb; |
|
477
|
|
|
|
|
|
|
} |
|
478
|
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
sub Munsell2RGB |
|
480
|
|
|
|
|
|
|
{ |
|
481
|
1
|
|
|
1
|
1
|
4
|
my $m = shift; # Color::Model::Munsell object |
|
482
|
1
|
50
|
33
|
|
|
12
|
unless ( defined($m) && ref($m) eq 'Color::Model::Munsell' ){ |
|
483
|
0
|
|
|
|
|
0
|
Carp::croak("Munsell2RGB() needs Color::Model::Munsell object."); |
|
484
|
|
|
|
|
|
|
} |
|
485
|
1
|
|
50
|
|
|
8
|
my $rgbtype = shift || 'sRGB'; # RGB type |
|
486
|
1
|
|
50
|
|
|
8
|
my $atype = shift || 'Bradford'; # Chromatic Adaptation type |
|
487
|
1
|
|
50
|
|
|
75
|
my $gamma = shift || 2.2; # Gamma value (uses when not sRGB) |
|
488
|
|
|
|
|
|
|
|
|
489
|
1
|
|
|
|
|
3
|
my @RGB; |
|
490
|
1
|
50
|
|
|
|
7
|
if ( $rgbtype eq 'sRGB' ){ |
|
491
|
3
|
50
|
|
|
|
1049
|
@RGB = map { |
|
492
|
1
|
|
|
|
|
4
|
$_ = $_>0.0031308? |
|
493
|
|
|
|
|
|
|
(1.055 * ($_ ** (1/2.4)) - 0.055): |
|
494
|
|
|
|
|
|
|
12.92 * $_; |
|
495
|
3
|
50
|
|
|
|
30
|
$_ = $_<0 ? 0: ( $_>1? 1: $_); |
|
|
|
50
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
} Munsell2rgb($m, 'sRGB', $atype); |
|
497
|
|
|
|
|
|
|
} else { |
|
498
|
0
|
|
|
|
|
0
|
@RGB = map { |
|
499
|
0
|
|
|
|
|
0
|
$_ = $_ ** (1/$gamma); |
|
500
|
0
|
0
|
|
|
|
0
|
$_ = $_<0 ? 0: ( $_>1? 1: $_); |
|
|
|
0
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
} Munsell2rgb($m, $rgbtype, $atype); |
|
502
|
|
|
|
|
|
|
} |
|
503
|
1
|
50
|
|
|
|
21
|
_debug(sprintf("RGB = (%.6f, %.6f, %.6f)\n",@RGB)) if $_debug; |
|
504
|
1
|
|
|
|
|
15
|
return Color::Model::RGB->new(@RGB); |
|
505
|
|
|
|
|
|
|
} |
|
506
|
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
# ============================================================================= |
|
509
|
|
|
|
|
|
|
# Calculation Y of illuminant C |
|
510
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------- |
|
511
|
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
=head2 calc_Yc() |
|
513
|
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
calc_Yc( $m ) |
|
515
|
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
calc_Yc() calculates Y value of illuminant C and 2 degree observer from Munsell |
|
517
|
|
|
|
|
|
|
value with approximate calculation. Argument must be a I object or Munsell value. |
|
518
|
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
$m = Color::Model::Munsell->new("5R 4/14") |
|
520
|
|
|
|
|
|
|
printf "%.4f", calc_Yc( $m ); |
|
521
|
|
|
|
|
|
|
printf "%.4f", calc_Yc( 7.5 ); |
|
522
|
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
=cut |
|
524
|
|
|
|
|
|
|
|
|
525
|
1
|
|
|
1
|
|
11
|
use Scalar::Util qw(looks_like_number); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
229
|
|
|
526
|
|
|
|
|
|
|
|
|
527
|
|
|
|
|
|
|
sub calc_Yc |
|
528
|
|
|
|
|
|
|
{ |
|
529
|
|
|
|
|
|
|
# Yc = 1.1913*V - 0.22532*V^2 + 0.23351*V^3 - 0.020483*V^4 + 0.00081936*V^5 |
|
530
|
|
|
|
|
|
|
# (ref. JIS Z 8721(1993) ) |
|
531
|
|
|
|
|
|
|
|
|
532
|
16
|
|
|
16
|
1
|
49
|
my $m = shift; |
|
533
|
16
|
|
|
|
|
21
|
my $v = undef; |
|
534
|
16
|
50
|
|
|
|
39
|
if ( defined($m) ){ |
|
535
|
16
|
50
|
|
|
|
74
|
if ( ref($m) eq 'Color::Model::Munsell' ){ |
|
|
|
50
|
|
|
|
|
|
|
536
|
0
|
|
|
|
|
0
|
$v = $m->value; |
|
537
|
|
|
|
|
|
|
} elsif ( looks_like_number($m) ){ |
|
538
|
16
|
|
|
|
|
31
|
$v = $m; |
|
539
|
|
|
|
|
|
|
} |
|
540
|
|
|
|
|
|
|
} |
|
541
|
16
|
50
|
|
|
|
36
|
unless ( defined($v) ){ |
|
542
|
0
|
|
|
|
|
0
|
Carp::croak("Bad argument. calc_Yc() needs a number"); |
|
543
|
|
|
|
|
|
|
} |
|
544
|
16
|
|
|
|
|
25
|
my $v2 = $v*$v; |
|
545
|
16
|
|
|
|
|
28
|
my $v3 = $v*$v2; |
|
546
|
16
|
|
|
|
|
18
|
my $v4 = $v2*$v2; |
|
547
|
16
|
|
|
|
|
21
|
my $v5 = $v2*$v3; |
|
548
|
16
|
|
|
|
|
123
|
return 1.1913*$v - 0.22532*$v2 + 0.23351*$v3 - 0.020483*$v4 + 0.00081936*$v5; |
|
549
|
|
|
|
|
|
|
} |
|
550
|
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
=head1 AUTHOR |
|
553
|
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
Takahiro Onodera, C<< >> |
|
555
|
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
=head1 BUGS |
|
557
|
|
|
|
|
|
|
|
|
558
|
|
|
|
|
|
|
Please report any bugs or feature requests to C, or through |
|
559
|
|
|
|
|
|
|
the web interface at L. I will be notified, and then you'll |
|
560
|
|
|
|
|
|
|
automatically be notified of progress on your bug as I make changes. |
|
561
|
|
|
|
|
|
|
|
|
562
|
|
|
|
|
|
|
=head1 SEE ALSO |
|
563
|
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
L, L |
|
565
|
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
=head1 REFERENCES |
|
567
|
|
|
|
|
|
|
|
|
568
|
|
|
|
|
|
|
Munsell Color Science Laboratory, R.I.T - L - Munsell-xyY data are from this site. |
|
569
|
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
BruceLindbloom.com - L - Chromatic adaptation matrixes, transformation matrixes and important knowledge are from this site. |
|
571
|
|
|
|
|
|
|
|
|
572
|
|
|
|
|
|
|
Japanese Industrial Standards(JIS) JIS Z 8721(1993) |
|
573
|
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
=head1 LICENSE AND COPYRIGHT |
|
575
|
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
Copyright 2010 Takahiro Onodera. |
|
577
|
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
|
579
|
|
|
|
|
|
|
under the terms of either: the GNU General Public License as published |
|
580
|
|
|
|
|
|
|
by the Free Software Foundation; or the Artistic License. |
|
581
|
|
|
|
|
|
|
|
|
582
|
|
|
|
|
|
|
=cut |
|
583
|
|
|
|
|
|
|
|
|
584
|
|
|
|
|
|
|
1; # End of Color::Model::Munsell::Util |
|
585
|
|
|
|
|
|
|
__DATA__ |