File Coverage

blib/lib/ICC/Profile/sf32.pm
Criterion Covered Total %
statement 37 92 40.2
branch 5 32 15.6
condition 0 36 0.0
subroutine 9 12 75.0
pod 1 7 14.2
total 52 179 29.0


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