package PDL::Graphics::ColorSpace::RGBSpace; use strict; use warnings; use PDL::LiteF; use Carp; =head1 NAME PDL::Graphics::ColorSpace::RGBSpace -- defines RGB space conversion parameters and white points. =head1 DESCRIPTION Sourced from Graphics::ColorObject (Izvorski & Reibenschuh, 2005). =head1 Usage use Data::Dumper; print Dumper $PDL::Graphics::ColorSpace::RGBSpace::RGB_SPACE; print Dumper $PDL::Graphics::ColorSpace::RGBSpace::WHITE_POINT; =cut our $WHITE_POINT = { 'D50' => [ '0.34567', '0.3585' ], 'A' => [ '0.44757', '0.40745' ], 'D75' => [ '0.29902', '0.31485' ], 'D55' => [ '0.33242', '0.34743' ], 'D65' => [ '0.312713', '0.329016' ], 'E' => [ '0.333333', '0.333333' ], 'B' => [ '0.34842', '0.35161' ], 'F11' => [ '0.38054', '0.37691' ], 'F2' => [ '0.37207', '0.37512' ], 'C' => [ '0.310063', '0.316158' ], 'D93' => [ '0.2848', '0.2932' ], 'F7' => [ '0.31285', '0.32918' ] }; our $RGB_SPACE = { 'BruceRGB' => { 'gamma' => '2.2', 'm' => pdl([ [ '0.467384242424242', '0.240995', '0.0219086363636363' ], [ '0.294454030769231', '0.683554', '0.0736135076923076' ], [ '0.18863', '0.075452', '0.993451333333334' ] ]), 'white_point' => $WHITE_POINT->{'D65'}, }, 'Adobe RGB (1998)' => { 'gamma' => '2.2', 'm' => pdl([ [ '0.576700121212121', '0.297361', '0.0270328181818181' ], [ '0.185555704225352', '0.627355', '0.0706878873239437' ], [ '0.1882125', '0.075285', '0.9912525' ] ]), 'white_point' => $WHITE_POINT->{'D65'}, }, 'WideGamut' => { 'gamma' => '2.2', 'm' => pdl([ [ '0.716103566037736', '0.258187', '0' ], [ '0.100929624697337', '0.724938', '0.0517812857142858' ], [ '0.1471875', '0.016875', '0.7734375' ] ]), 'white_point' => $WHITE_POINT->{'D50'}, }, 'NTSC' => { 'gamma' => '2.2', 'm' => pdl([ [ '0.606733727272727', '0.298839', '-1e-16' ], [ '0.173563816901409', '0.586811', '0.0661195492957747' ], [ '0.2001125', '0.11435', '1.1149125' ] ]), 'white_point' => $WHITE_POINT->{'C'}, }, 'Ekta Space PS5' => { 'gamma' => '2.2', 'm' => pdl([ [ '0.59389231147541', '0.260629', '0' ], [ '0.272979942857143', '0.734946', '0.0419969142857143' ], [ '0.09735', '0.004425', '0.783225' ] ]), 'white_point' => $WHITE_POINT->{'D50'}, }, 'PAL/SECAM' => { 'gamma' => '2.2', 'm' => pdl([ [ '0.430586181818182', '0.222021', '0.0201837272727273' ], [ '0.341545083333333', '0.706645', '0.129551583333333' ], [ '0.178335', '0.071334', '0.939231' ] ]), 'white_point' => $WHITE_POINT->{'D65'}, }, 'Apple RGB' => { 'gamma' => '1.8', 'm' => pdl([ [ '0.449694852941176', '0.244634', '0.0251829117647059' ], [ '0.316251294117647', '0.672034', '0.141183613445378' ], [ '0.184520857142857', '0.083332', '0.922604285714286' ] ]), 'white_point' => $WHITE_POINT->{'D65'}, }, 'sRGB' => { 'gamma' => '-1', # mark it for special case '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'}, }, '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([ [ '0.509343882352941', '0.274884', '0.0242544705882353' ], [ '0.320907338842975', '0.658132', '0.108782148760331' ], [ '0.13397', '0.066985', '0.692178333333333' ] ]), 'white_point' => $WHITE_POINT->{'D50'}, }, 'SMPTE-C' => { 'gamma' => '2.2', 'm' => pdl([ [ '0.393555441176471', '0.212395', '0.0187407352941176' ], [ '0.365252420168067', '0.701049', '0.111932193277311' ], [ '0.191659714285714', '0.086556', '0.958298571428571' ] ]), 'white_point' => $WHITE_POINT->{'D65'}, }, 'CIE' => { 'gamma' => '2.2', 'm' => pdl([ [ '0.488716754716981', '0.176204', '0' ], [ '0.310680460251046', '0.812985', '0.0102048326359833' ], [ '0.200604111111111', '0.010811', '0.989807111111111' ] ]), 'white_point' => $WHITE_POINT->{'E'}, }, 'ProPhoto' => { 'gamma' => '1.8', 'm' => pdl([ [ '0.797674285714286', '0.28804', '0' ], [ '0.135191683008091', '0.711874', '0' ], [ '0.031476', '8.6e-05', '0.828438' ] ]), 'white_point' => $WHITE_POINT->{'D50'}, }, 'BestRGB' => { 'gamma' => '2.2', 'm' => pdl([ [ '0.632670026008293', '0.228457', '0' ], [ '0.204555716129032', '0.737352', '0.0095142193548387' ], [ '0.126995142857143', '0.034191', '0.815699571428571' ] ]), 'white_point' => $WHITE_POINT->{'D50'}, }, 'DonRGB4' => { 'gamma' => '2.2', 'm' => pdl([ [ '0.645772', '0.27835', '0.0037113333333334' ], [ '0.193351045751634', '0.68797', '0.0179861437908497' ], [ '0.125097142857143', '0.03368', '0.803508571428572' ] ]), 'white_point' => $WHITE_POINT->{'D50'}, }, 'Beta RGB' => { 'gamma' => '2.2', 'm' => pdl([ [ '0.67125463496144', '0.303273', '1e-16' ], [ '0.1745833659118', '0.663786', '0.0407009558998808' ], [ '0.11838171875', '0.032941', '0.784501144886363' ] ]), 'white_point' => $WHITE_POINT->{'D50'}, }, 'ECI' => { 'gamma' => '1.8', 'm' => pdl([ [ '0.650204545454545', '0.32025', '-1e-16' ], [ '0.178077338028169', '0.602071', '0.067838985915493' ], [ '0.13593825', '0.077679', '0.75737025' ] ]), 'white_point' => $WHITE_POINT->{'D50'}, }, }; $RGB_SPACE->{$_}{white_point} = PDL->topdl($RGB_SPACE->{$_}{white_point}), $RGB_SPACE->{$_}{mstar} = $RGB_SPACE->{$_}{m}->inv for keys %$RGB_SPACE; # aliases $RGB_SPACE->{Adobe} = $RGB_SPACE->{'Adobe RGB (1998)'}; $RGB_SPACE->{'601'} = $RGB_SPACE->{NTSC}; $RGB_SPACE->{Apple} = $RGB_SPACE->{'Apple RGB'}; $RGB_SPACE->{'CIE ITU'} = $RGB_SPACE->{'PAL/SECAM'}; $RGB_SPACE->{PAL} = $RGB_SPACE->{'PAL/SECAM'}; $RGB_SPACE->{'709'} = $RGB_SPACE->{sRGB}; $RGB_SPACE->{SMPTE} = $RGB_SPACE->{'SMPTE-C'}; $RGB_SPACE->{'CIE Rec 709'} = $RGB_SPACE->{sRGB}; $RGB_SPACE->{'CIE Rec 601'} = $RGB_SPACE->{NTSC}; my @NEED_KEYS = grep $_ ne 'mstar', keys %{ $RGB_SPACE->{sRGB} }; sub add_rgb_space { my ($new_space) = @_; my @dup = grep $RGB_SPACE->{$_}, sort keys %$new_space; croak "Already existing RGB space definition with names @dup" if @dup; while (my ($name, $profile) = each %$new_space) { carp "Missing definition for custom RGB space $name: $_" for grep !defined $profile->{$_}, @NEED_KEYS; my $copy = {%$profile}; $copy->{m} = PDL->topdl($copy->{m}); $copy->{mstar} = $copy->{m}->inv if !exists $copy->{mstar}; $copy->{mstar} = PDL->topdl($copy->{mstar}); $copy->{white_point} = PDL->topdl($copy->{white_point}); $RGB_SPACE->{$name} = $copy; } } sub get_space { my ($space) = @_; croak "Please specify RGB Space ('sRGB' for generic JPEG images)!" if !$space; my $spec = ref($space) ? $space : $RGB_SPACE->{$space}; } 1;