Skip to content

Commit

Permalink
add rgb_{to,from}_linear, lsRGB space
Browse files Browse the repository at this point in the history
  • Loading branch information
mohawk2 committed Jan 12, 2023
1 parent 73e4f76 commit ee606be
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 5 deletions.
3 changes: 2 additions & 1 deletion Changes
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
- no need to supply mstar for add_rgb_space
- can supply add_rgb_space-format hash-ref to the relevant functions
- add rgb_to_lab and lab_to_rgb
- add rgb_to_lab, lab_to_rgb, rgb_{to,from}_linear
- add lsRGB colour space

0.201 2022-02-14
- more accurate dependencies
Expand Down
21 changes: 21 additions & 0 deletions ColorSpace/RGBSpace.pm
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,27 @@ our $RGB_SPACE = {
]),
'white_point' => $WHITE_POINT->{'D65'},
},
'lsRGB' => {
'gamma' => 1.0,
'm' => pdl([
[
'0.412423757575757',
'0.212656',
'0.0193323636363636'
],
[
'0.357579',
'0.715158',
'0.119193'
],
[
'0.180465',
'0.072186',
'0.950449'
]
]),
'white_point' => $WHITE_POINT->{'D65'},
},
'ColorMatch' => {
'gamma' => '1.8',
'm' => pdl([
Expand Down
68 changes: 68 additions & 0 deletions color_space.pd
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ Some conversions require specifying the RGB space which includes gamma curve and
SMPTE-C [SMPTE]
WideGamut
sRGB [709] [CIE Rec 709]
lsRGB

You can also add custom RGB space definitions via the function add_rgb_space.
Alternatively, as of 0.202 you can directly supply the function with a
Expand Down Expand Up @@ -667,6 +668,73 @@ BADDOC
);


pp_def('rgb_to_linear',
Pars => 'rgb(c=3); gamma(); [o]out(c=3)',
HandleBad => 1,
GenericTypes=>['D'],
Code => '
PDL_IF_BAD(if ($ISBAD(rgb(c=>0)) || $ISBAD(rgb(c=>1)) || $ISBAD(rgb(c=>2))) {
loop (c) %{ $SETBAD(out()); %}
}
else,) {
rgb2linear( $P(rgb), $gamma(), $P(out) );
}
',
Doc => <<'DOCUMENTATION',
=for ref

Converts an RGB color triple (presumably with gamma) to an RGB color triple
with linear values.

=for usage

Usage:

my $rgb_linear = rgb_to_linear( $gammaed, 2.2 );
DOCUMENTATION
BadDoc => <<BADDOC,
=for bad

If C<rgb_to_linear> encounters a bad value in any of the R, G, or B
values the output ndarray will be marked as bad and the associated R,
G, and B values will all be marked as bad.
BADDOC
);


pp_def('rgb_from_linear',
Pars => 'rgb(c=3); gamma(); [o]out(c=3)',
HandleBad => 1,
GenericTypes=>['D'],
Code => '
PDL_IF_BAD(if ($ISBAD(rgb(c=>0)) || $ISBAD(rgb(c=>1)) || $ISBAD(rgb(c=>2))) {
loop (c) %{ $SETBAD(out()); %}
}
else,) {
rgb2gamma( $P(rgb), $gamma(), $P(out) );
}
',
Doc => <<'DOCUMENTATION',
=for ref

Converts an RGB color triple (presumably linear) to an RGB color triple
with the specified gamma.

=for usage

Usage:

my $gammaed = rgb_from_linear( $rgb_linear, 2.2 );
DOCUMENTATION
BadDoc => <<BADDOC,
=for bad

If C<rgb_from_linear> encounters a bad value in any of the R, G, or B
values the output ndarray will be marked as bad and the associated R,
G, and B values will all be marked as bad.
BADDOC
);


pp_addpm(<<'EOD');

Expand Down
18 changes: 14 additions & 4 deletions t/color_space.t
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,27 @@ sub tapprox {
ok( tapprox( $a_rgb_bad, $rgb), 'hsv_to_rgb with bad value' ) or diag($a_rgb_bad, $rgb);
}

# rgb_to_xyz
# rgb_to_xyz and rgb_{to,from}_linear
{
my $rgb = pdl( [255,255,255],[0,0,0],[255,10,50],[1,48,199] ) / 255;
my $xyz = pdl( [0.950467757575757, 1, 1.08897436363636],
[0,0,0],
[0.419265223936783, 0.217129144548417, 0.0500096992920757],
[0.113762127389896, 0.0624295703768394, 0.546353858701224] );
[0,0,0],
[0.419265223936783, 0.217129144548417, 0.0500096992920757],
[0.113762127389896, 0.0624295703768394, 0.546353858701224] );
my $linear_ans = pdl( [1,1,1],[0,0,0],
[1, 0.0030352698, 0.031896033],
[0.00030352698, 0.029556834, 0.57112483] );

my $a_xyz = rgb_to_xyz( $rgb, 'sRGB' );
ok( tapprox( $a_xyz, $xyz), 'rgb_to_xyz sRGB' ) or diag($a_xyz, $xyz);

my $rgb_linear = rgb_to_linear($rgb, -1);
ok( tapprox( $rgb_linear, $linear_ans), 'rgb_to_linear sRGB' ) or diag($rgb_linear, $linear_ans);
my $rgb_regamma = rgb_from_linear($rgb_linear, -1);
ok( tapprox( $rgb_regamma, $rgb), 're-rgb_from_linear sRGB' ) or diag($rgb_regamma, $rgb);
my $a2_xyz = rgb_to_xyz( $rgb_linear, 'lsRGB' );
ok( tapprox( $a2_xyz, $xyz), 'rgb_to_xyz lsRGB' ) or diag($a2_xyz, $xyz);

my $a_rgb = xyz_to_rgb( $xyz, 'sRGB' );
ok( tapprox( $a_rgb, $rgb), 'xyz_to_rgb sRGB' ) or diag($a_rgb, $rgb);

Expand Down

0 comments on commit ee606be

Please sign in to comment.