File Coverage

blib/lib/ICC/Profile/sf32.pm
Criterion Covered Total %
statement 40 95 42.1
branch 5 32 15.6
condition 0 36 0.0
subroutine 10 13 76.9
pod 1 7 14.2
total 56 183 30.6


line stmt bran cond sub pod time code
1             package ICC::Profile::sf32;
2              
3 2     2   124188 use strict;
  2         11  
  2         54  
4 2     2   9 use Carp;
  2         3  
  2         134  
5              
6             our $VERSION = 0.22;
7              
8             # revised 2018-08-07
9             #
10             # Copyright © 2004-2019 by William B. Birkett
11              
12             # add development directory
13 2     2   488 use lib 'lib';
  2         640  
  2         10  
14              
15             # inherit from Shared
16 2     2   237 use parent qw(ICC::Shared);
  2         5  
  2         14  
17              
18             # create new sf32 tag object
19             # input may be 1-D array, 2-D array, or Math::Matrix object
20             # parameters: ([ref_to_input])
21             # returns: (ref_to_object)
22             sub new {
23              
24             # get object class
25 1     1 0 813 my $class = shift();
26            
27             # create empty sf32 object
28 1         5 my $self = [
29             {}, # object header
30             [] # s15f16 array
31             ];
32            
33             # if parameter supplied
34 1 50       5 if (@_) {
35            
36             # if one parameter, a reference to a 1-D array
37 0 0 0     0 if (@_ == 1 && ref($_[0]) eq 'ARRAY' && @{$_[0]} == grep {! ref()} @{$_[0]}) {
  0 0 0     0  
  0   0     0  
  0   0     0  
      0        
38            
39             # copy array
40 0         0 $self->[1] = [@{shift()}];
  0         0  
41            
42             # if one parameter, a reference to a 2-D array or Math::Matrix object
43 0         0 } elsif (@_ == 1 && (ref($_[0]) eq 'ARRAY' || UNIVERSAL::isa($_[0], 'Math::Matrix')) && @{$_[0]} == grep {ref() eq 'ARRAY'} @{$_[0]}) {
  0         0  
  0         0  
44            
45             # initialize array
46 0         0 $self->[1] = [];
47            
48             # for each row
49 0         0 for (@{$_[0]}) {
  0         0  
50            
51             # push row values
52 0         0 push(@{$self->[1]}, @{$_});
  0         0  
  0         0  
53            
54             }
55            
56             } else {
57            
58             # error
59 0         0 croak('parameter must an array reference (1-D or 2-D)');
60            
61             }
62            
63             }
64              
65             # bless object
66 1         3 bless($self, $class);
67            
68             # return object reference
69 1         2 return($self);
70              
71             }
72              
73             # create sf32 tag object from ICC profile
74             # parameters: (ref_to_parent_object, file_handle, ref_to_tag_table_entry)
75             # returns: (ref_to_object)
76             sub new_fh {
77              
78             # get object class
79 1     1 0 652 my $class = shift();
80              
81             # create empty sf32 object
82 1         3 my $self = [
83             {}, # object header
84             [] # s15f16 array
85             ];
86              
87             # verify 3 parameters
88 1 50       6 (@_ == 3) or croak('wrong number of parameters');
89              
90             # read sf32 data from profile
91 1         4 _readICCsf32($self, @_);
92              
93             # bless object
94 1         3 bless($self, $class);
95              
96             # return object reference
97 1         10 return($self);
98              
99             }
100              
101             # writes sf32 tag object to ICC profile
102             # parameters: (ref_to_parent_object, file_handle, ref_to_tag_table_entry)
103             sub write_fh {
104              
105             # verify 4 parameters
106 1 50   1 0 3180 (@_ == 4) or croak('wrong number of parameters');
107              
108             # write sf32 data to profile
109 1         5 goto &_writeICCsf32;
110              
111             }
112              
113             # get tag size (for writing to profile)
114             # returns: (tag_size)
115             sub size {
116            
117             # get parameters
118 3     3 0 489 my ($self) = @_;
119            
120             # return size
121 3         6 return(8 + @{$self->[1]} * 4);
  3         30  
122            
123             }
124              
125             # get/set array reference
126             # parameters: ([ref_to_array])
127             # returns: (ref_to_array)
128             sub array {
129              
130             # get object reference
131 0     0 0 0 my $self = shift();
132            
133             # if parameter
134 0 0       0 if (@_) {
135            
136             # verify array reference
137 0 0       0 (ref($_[0]) eq 'ARRAY') or croak('not an array reference');
138            
139             # set array reference
140 0         0 $self->[1] = shift();
141            
142             }
143            
144             # return array reference
145 0         0 return($self->[1]);
146              
147             }
148              
149             # get/set matrix
150             # access array in matrix format
151             # get parameters: (matrix_columns)
152             # set parameters: (matrix_object)
153             # set parameters: (ref_to_2D_array)
154             # returns: (matrix_object)
155             sub matrix {
156              
157             # get object reference
158 0     0 0 0 my $self = shift();
159            
160             # local variables
161 0         0 my ($size, $rows, $cols, $matrix);
162            
163             # if parameter
164 0 0       0 if (@_) {
165            
166             # if one parameter, a scalar
167 0 0 0     0 if (@_ == 1 && ! ref($_[0])) {
    0 0        
      0        
      0        
168            
169             # get array size
170 0         0 $size = @{$self->[1]};
  0         0  
171            
172             # get columns
173 0         0 $cols = shift();
174            
175             # verify matrix dimensions
176 0 0 0     0 ($size && $cols && ($size % $cols == 0)) or croak('invalid matrix dimensions');
      0        
177            
178             # make new empty matrix object
179 0         0 $matrix = Math::Matrix->new([]);
180            
181             # compute rows
182 0         0 $rows = $size/$cols;
183            
184             # for each row
185 0         0 for my $i (0 .. $rows - 1) {
186            
187             # set matrix row
188 0         0 $matrix->[$i] = [@{$self->[1]}[$i * $cols .. ($i + 1) * $cols - 1]];
  0         0  
189            
190             }
191            
192             # return matrix
193 0         0 return($matrix);
194            
195             # if one parameter, a reference to a 2-D array or Math::Matrix object
196 0         0 } elsif (@_ == 1 && (ref($_[0]) eq 'ARRAY' || UNIVERSAL::isa($_[0], 'Math::Matrix')) && @{$_[0]} == grep {ref() eq 'ARRAY'} @{$_[0]}) {
  0         0  
  0         0  
197            
198             # initialize array
199 0         0 $self->[1] = [];
200            
201             # for each row
202 0         0 for (@{$_[0]}) {
  0         0  
203            
204             # push row values
205 0         0 push(@{$self->[1]}, @{$_});
  0         0  
  0         0  
206            
207             }
208            
209             # if an array
210 0 0       0 if (ref($_[0]) eq 'ARRAY') {
211            
212             # return Math::Matrix object
213 0         0 return (Math::Matrix->new(@{$_[0]}));
  0         0  
214            
215             } else {
216            
217             # return copy of parameter (Math::Matrix object)
218 0         0 return(Storable::dclone($_[0]));
219            
220             }
221            
222             } else {
223            
224             # error
225 0         0 croak('parameter must be column width or a 2-D array reference');
226            
227             }
228            
229             }
230            
231             }
232              
233             # print object contents to string
234             # format is an array structure
235             # parameter: ([format])
236             # returns: (string)
237             sub sdump {
238              
239             # get parameters
240 0     0 1 0 my ($self, $p) = @_;
241              
242             # local variables
243 0         0 my ($s, $fmt);
244              
245             # resolve parameter to an array reference
246 0 0       0 $p = defined($p) ? ref($p) eq 'ARRAY' ? $p : [$p] : [];
    0          
247              
248             # get format string
249 0 0 0     0 $fmt = defined($p->[0]) && ! ref($p->[0]) ? $p->[0] : 'undef';
250              
251             # set string to object ID
252 0         0 $s = sprintf("'%s' object, (0x%x)\n", ref($self), $self);
253              
254             # return
255 0         0 return($s);
256              
257             }
258              
259             # read sf32 tag from ICC profile
260             # parameters: (ref_to_object, ref_to_parent_object, file_handle, ref_to_tag_table_entry)
261             sub _readICCsf32 {
262            
263             # get parameters
264 1     1   3 my ($self, $parent, $fh, $tag) = @_;
265            
266             # local variables
267 1         2 my ($buf);
268            
269             # save tag signature
270 1         3 $self->[0]{'signature'} = $tag->[0];
271            
272             # seek start of tag
273 1         11 seek($fh, $tag->[1], 0);
274            
275             # read entire tag
276 1         11 read($fh, $buf, $tag->[2]);
277            
278             # unpack array and convert values
279 1 100       4 $self->[1] = [map {($_ & 0x80000000) ? $_/65536 - 65536 : $_/65536} unpack('x8 N*', $buf)];
  9         27  
280            
281             }
282              
283             # write sf32 tag to ICC profile
284             # parameters: (ref_to_object, ref_to_parent_object, file_handle, ref_to_tag_table_entry)
285             sub _writeICCsf32 {
286              
287             # get parameters
288 1     1   4 my ($self, $parent, $fh, $tag) = @_;
289              
290             # seek start of tag
291 1         9 seek($fh, $tag->[1], 0);
292              
293             # write tag
294 1         4 print $fh pack('a4 x4 N*', 'sf32', map {$_ * 65536} @{$self->[1]});
  9         41  
  1         3  
295              
296             }
297              
298             1;