File Coverage

blib/lib/ICC/Profile/clrt.pm
Criterion Covered Total %
statement 26 82 31.7
branch 4 28 14.2
condition 0 21 0.0
subroutine 7 13 53.8
pod 1 6 16.6
total 38 150 25.3


line stmt bran cond sub pod time code
1             package ICC::Profile::clrt;
2              
3 2     2   101399 use strict;
  2         14  
  2         56  
4 2     2   10 use Carp;
  2         3  
  2         142  
5              
6             our $VERSION = 0.12;
7              
8             # revised 2018-08-07
9             #
10             # Copyright © 2004-2019 by William B. Birkett
11              
12             # add development directory
13 2     2   489 use lib 'lib';
  2         682  
  2         10  
14              
15             # inherit from Shared
16 2     2   664 use parent qw(ICC::Shared);
  2         305  
  2         9  
17              
18             # create new clrt tag object
19             # parameters: ([ref_to_A2B1_tag, [ref_to_array_of_colorant_names]])
20             # returns: (ref_to_object)
21             sub new {
22              
23             # get object class
24 1     1 0 784 my $class = shift();
25            
26             # create empty clrt object
27 1         3 my $self = [
28             {}, # object header
29             [] # colorant array
30             ];
31              
32             # if parameter supplied
33 1 50       5 if (@_) {
34            
35             # new colorant tag from xCLR A2B1 tag
36 0         0 _newICCclrt($self, @_);
37            
38             }
39              
40             # bless object
41 1         2 bless($self, $class);
42            
43             # return object reference
44 1         3 return($self);
45              
46             }
47              
48             # create clrt tag object from ICC profile
49             # parameters: (ref_to_parent_object, file_handle, ref_to_tag_table_entry)
50             # returns: (ref_to_object)
51             sub new_fh {
52              
53             # get object class
54 0     0 0 0 my $class = shift();
55              
56             # create empty clrt object
57 0         0 my $self = [
58             {}, # object header
59             [] # colorant array
60             ];
61              
62             # verify 3 parameters
63 0 0       0 (@_ == 3) or croak('wrong number of parameters');
64              
65             # read clrt data from profile
66 0         0 _readICCclrt($self, @_);
67              
68             # bless object
69 0         0 bless($self, $class);
70              
71             # return object reference
72 0         0 return($self);
73              
74             }
75              
76             # writes clrt tag object to ICC profile
77             # parameters: (ref_to_parent_object, file_handle, ref_to_tag_table_entry)
78             sub write_fh {
79              
80             # verify 4 parameters
81 0 0   0 0 0 (@_ == 4) or croak('wrong number of parameters');
82              
83             # write text data to profile
84 0         0 goto &_writeICCclrt;
85              
86             }
87              
88             # get tag size (for writing to profile)
89             # returns: (tag_size)
90             sub size {
91            
92             # get parameters
93 1     1 0 929 my ($self) = @_;
94            
95             # return size
96 1         3 return(12 + @{$self->[1]} * 38);
  1         5  
97            
98             }
99              
100             # get colorant table entry reference(s)
101             # parameters: (channel)
102             # returns: (ref_to_color_table_entry)
103             # parameters: (list_of_channels)
104             # returns: (list_of_refs_to_color_table_entries)
105             sub channel {
106              
107             # get object reference
108 2     2 0 1015 my $self = shift();
109            
110             # if parameters
111 2 50       9 if (@_) {
112            
113             # if list is wanted
114 2 100       7 if (wantarray) {
115            
116             # return list of colorant table references
117 1         3 return(map {$self->[1][$_]} @_);
  4         9  
118            
119             # single value wanted
120             } else {
121            
122             # return single colorant table reference
123 1         4 return($self->[1][$_[0]]);
124            
125             }
126            
127             }
128            
129             }
130              
131             # print object contents to string
132             # format is an array structure
133             # parameter: ([format])
134             # returns: (string)
135             sub sdump {
136              
137             # get parameters
138 0     0 1   my ($self, $p) = @_;
139              
140             # local variables
141 0           my ($s, $fmt);
142              
143             # resolve parameter to an array reference
144 0 0         $p = defined($p) ? ref($p) eq 'ARRAY' ? $p : [$p] : [];
    0          
145              
146             # get format string
147 0 0 0       $fmt = defined($p->[0]) && ! ref($p->[0]) ? $p->[0] : 'undef';
148              
149             # set string to object ID
150 0           $s = sprintf("'%s' object, (0x%x)\n", ref($self), $self);
151              
152             # return
153 0           return($s);
154              
155             }
156              
157             # new colorant tag from xCLR A2B1 tag
158             # parameters: (ref_to_object, ref_to_A2B1_tag, [ref_to_array_of_colorant_names])
159             sub _newICCclrt {
160            
161             # get parameters
162 0     0     my ($self, $tag, $name) = @_;
163            
164             # local variables
165 0           my ($type, $csi, $cso);
166 0           my ($cnt, $max, @in, @out);
167            
168             # get tag type
169 0           $type = ref($tag);
170            
171             # get input colorspace
172 0           $csi = $tag->[0]{'input_cs'};
173            
174             # get output colorspace
175 0           $cso = $tag->[0]{'output_cs'};
176            
177             # if allowable tag type
178 0 0 0       if (($type eq 'ICC::Profile::mft1' || $type eq 'ICC::Profile::mft2' || $type eq 'ICC::Profile::mAB_') &&
      0        
      0        
      0        
179             ($csi =~ m|^([2-9A-F])CLR$|) && ($cso eq 'Lab ' || $cso eq 'XYZ ')) {
180            
181             # get count from match
182 0           $cnt = hex($1);
183            
184             # get maximum colorant value
185 0 0         $max = $type eq 'ICC::Profile::mft1' ? 255 : 65535;
186            
187             # set transform mask
188 0           $tag->[6] = 0x0f;
189            
190             # for each colorant
191 0           for my $i (0 .. $cnt - 1) {
192            
193             # for each input
194 0           for my $j (0 .. $cnt - 1) {
195            
196             # set input
197 0 0         $in[$j] = $i == $j ? 1 : 0;
198            
199             }
200            
201             # if name array supplied
202 0 0         if (defined($name->[$i])) {
203            
204             # set the colorant name
205 0           $self->[1][$i][0] = $name->[$i];
206            
207             } else {
208            
209             # set the colorant name
210 0           $self->[1][$i][0] = sprintf('colorant_%x', $i + 1);
211            
212             }
213            
214             # transform color value
215 0           @{$self->[1][$i]}[1 .. 3] = map {$_ * $max} $tag->transform(@in);
  0            
  0            
216            
217             }
218            
219             # set the PCS ('Lab ' or 'XYZ ')
220 0           $self->[0]{'pcs'} = $cso;
221            
222             # set the output bit depth
223 0 0 0       $self->[0]{'output_bits'} = ($cso eq 'Lab ' && $type eq 'ICC::Profile::mft1') ? 8 : 16;
224            
225             # set the 16-bit Lab legacy flag
226 0 0 0       $self->[0]{'legacy'} = ($cso eq 'Lab ' && $type eq 'ICC::Profile::mft2') ? 1 : 0;
227            
228             } else {
229            
230             # message
231 0           carp('wrong tag type');
232            
233             }
234            
235             }
236              
237             # read clrt tag from ICC profile
238             # parameters: (ref_to_object, ref_to_parent_object, file_handle, ref_to_tag_table_entry)
239             sub _readICCclrt {
240              
241             # get parameters
242 0     0     my ($self, $parent, $fh, $tag) = @_;
243              
244             # local variables
245 0           my ($buf, $cnt);
246              
247             # save tag signature
248 0           $self->[0]{'signature'} = $tag->[0];
249              
250             # save profile connection space ('Lab ' or 'XYZ ')
251 0           $self->[0]{'pcs'} = $parent->[1][5];
252              
253             # seek start of tag
254 0           seek($fh, $tag->[1], 0);
255              
256             # read signature and color count
257 0           read($fh, $buf, 12);
258              
259             # unpack colorant count
260 0           $cnt = unpack('x8 N', $buf);
261              
262             # for each colorant
263 0           for my $i (0 .. $cnt - 1) {
264            
265             # read colorant record
266 0           read($fh, $buf, 38);
267            
268             # unpack colorant values
269 0           $self->[1][$i] = [unpack('Z32 n3', $buf)];
270            
271             }
272            
273             }
274              
275             # write clrt tag to ICC profile
276             # parameters: (ref_to_object, ref_to_parent_object, file_handle, ref_to_tag_table_entry)
277             sub _writeICCclrt {
278              
279             # get parameters
280 0     0     my ($self, $parent, $fh, $tag) = @_;
281              
282             # seek start of tag
283 0           seek($fh, $tag->[1], 0);
284              
285             # write type signature and colorant count
286 0           print $fh pack('a4 x4 N', 'clrt', scalar(@{$self->[1]}));
  0            
287              
288             # for each colorant record
289 0           for my $rec (@{$self->[1]}) {
  0            
290            
291             # write colorant values
292 0           print $fh pack('Z32 n3', @{$rec});
  0            
293            
294             }
295            
296             }
297              
298             1;