File Coverage

blib/lib/ICC/Profile/desc.pm
Criterion Covered Total %
statement 54 90 60.0
branch 6 34 17.6
condition 1 6 16.6
subroutine 10 15 66.6
pod 1 8 12.5
total 72 153 47.0


line stmt bran cond sub pod time code
1             package ICC::Profile::desc;
2              
3 2     2   98478 use strict;
  2         10  
  2         50  
4 2     2   10 use Carp;
  2         3  
  2         114  
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   10 use parent qw(ICC::Shared);
  2         4  
  2         10  
14              
15             # support modules
16 2     2   565 use Encode; # Unicode module
  2         8101  
  2         1727  
17              
18             # create new desc tag object
19             # supported attributes: 'ascii', 'unicode_lang', 'unicode', 'scriptcode_lang', 'scriptcode'
20             # parameters: ()
21             # parameters: (ref_to_attribute_hash)
22             # returns: (ref_to_object)
23             sub new {
24              
25             # get object class
26 1     1 0 687 my $class = shift();
27            
28             # create empty desc object
29 1         3 my $self = [
30             {}, # object header
31             '', # ASCII string
32             0, # Unicode language
33             '', # Unicode string
34             0, # ScriptCode code
35             '' # ScriptCode string
36             ];
37              
38             # if single parameter is a hash reference
39 1 50 33     4 if (@_ == 1 && ref($_[0]) eq 'HASH') {
40              
41             # set object attributes
42 0         0 _newICCdesc($self, @_);
43              
44             }
45              
46             # bless object
47 1         2 bless($self, $class);
48              
49             # return object reference
50 1         2 return($self);
51              
52             }
53              
54             # create desc tag object from ICC profile
55             # parameters: (ref_to_parent_object, file_handle, ref_to_tag_table_entry)
56             # returns: (ref_to_object)
57             sub new_fh {
58              
59             # get object class
60 1     1 0 527 my $class = shift();
61              
62             # create empty desc object
63 1         3 my $self = [
64             {}, # object header
65             '', # ASCII string
66             0, # Unicode language
67             '', # Unicode string
68             0, # ScriptCode language
69             '' # ScriptCode string
70             ];
71              
72             # verify 3 parameters
73 1 50       4 (@_ == 3) or croak('wrong number of parameters');
74              
75             # read desc data from profile
76 1         3 _readICCdesc($self, @_);
77              
78             # bless object
79 1         3 bless($self, $class);
80              
81             # return object reference
82 1         9 return($self);
83              
84             }
85              
86             # writes desc tag object to ICC profile
87             # parameters: (ref_to_parent_object, file_handle, ref_to_tag_table_entry)
88             sub write_fh {
89              
90             # verify 4 parameters
91 1 50   1 0 886 (@_ == 4) or croak('wrong number of parameters');
92              
93             # write desc data to profile
94 1         4 goto &_writeICCdesc;
95              
96             }
97              
98             # get tag size (for writing to profile)
99             # returns: (tag_size)
100             sub size {
101            
102             # get parameters
103 3     3 0 420 my ($self) = @_;
104            
105             # return size
106 3 50       31 return(91 + length($self->[1]) + 2 * length($self->[3]) + (length($self->[3]) > 0 ? 2 : 0));
107            
108             }
109              
110             # get ASCII desc string
111             # parameters: ([desc_string])
112             # returns: (desc_string)
113             sub ASCII {
114              
115             # get object reference
116 0     0 0 0 my $self = shift();
117            
118             # if parameter supplied
119 0 0       0 if (@_) {
120            
121             # save desc string
122 0         0 $self->[1] = shift();
123            
124             }
125            
126             # return desc string
127 0         0 return($self->[1]);
128              
129             }
130              
131             # get Unicode desc string
132             # parameters: ([desc_string, [lang_code]])
133             # returns: (desc_string, [lang_code])
134             sub Unicode {
135              
136             # get object reference
137 0     0 0 0 my $self = shift();
138            
139             # if parameter supplied
140 0 0       0 if (@_) {
141            
142             # save desc string
143 0         0 $self->[3] = shift();
144            
145             # if parameter supplied
146 0 0       0 if (@_) {
147            
148             # save language code
149 0         0 $self->[2] = shift();
150            
151             }
152            
153             }
154            
155             # if language code wanted
156 0 0       0 if (wantarray) {
157            
158             # return desc string and language code
159 0         0 return($self->[3], $self->[2]);
160            
161             } else {
162            
163             # return desc string
164 0         0 return($self->[3]);
165            
166             }
167              
168             }
169              
170             # get ScriptCode desc string
171             # parameters: ([desc_string, [ScriptCode_code]])
172             # returns: (desc_string, [ScriptCode_code])
173             sub ScriptCode {
174              
175             # get object reference
176 0     0 0 0 my $self = shift();
177            
178             # if parameter supplied
179 0 0       0 if (@_) {
180            
181             # save desc string
182 0         0 $self->[5] = shift();
183            
184             # if parameter supplied
185 0 0       0 if (@_) {
186            
187             # save ScriptCode code
188 0         0 $self->[4] = shift();
189            
190             }
191            
192             }
193            
194             # if ScriptCode code wanted
195 0 0       0 if (wantarray) {
196            
197             # return desc string and ScriptCode code
198 0         0 return($self->[5], $self->[4]);
199            
200             } else {
201            
202             # return desc string
203 0         0 return($self->[5]);
204            
205             }
206            
207             }
208              
209             # print object contents to string
210             # format is an array structure
211             # parameter: ([format])
212             # returns: (string)
213             sub sdump {
214              
215             # get parameters
216 0     0 1 0 my ($self, $p) = @_;
217              
218             # local variables
219 0         0 my ($s, $fmt);
220              
221             # resolve parameter to an array reference
222 0 0       0 $p = defined($p) ? ref($p) eq 'ARRAY' ? $p : [$p] : [];
    0          
223              
224             # get format string
225 0 0 0     0 $fmt = defined($p->[0]) && ! ref($p->[0]) ? $p->[0] : 'undef';
226              
227             # set string to object ID
228 0         0 $s = sprintf("'%s' object, (0x%x)\n", ref($self), $self);
229              
230             # return
231 0         0 return($s);
232              
233             }
234              
235             # set object attributes from parameter hash
236             # parameters: (ref_to_object, parameter_hash)
237             sub _newICCdesc {
238            
239             # get parameters
240 0     0   0 my ($self, $pars) = @_;
241            
242             # local variables
243 0         0 my (%desc);
244            
245             # hash of description strings
246 0         0 %desc = ('ascii' => 1, 'unicode_lang' => 2, 'unicode' => 3, 'scriptcode_lang' => 4, 'scriptcode' => 5);
247            
248             # for each parameter key
249 0         0 for my $key (keys(%{$pars})) {
  0         0  
250            
251             # if supported key
252 0 0       0 if (exists($desc{$key})) {
253            
254             # save value
255 0         0 $self->[$desc{$key}] = $pars->{$key};
256            
257             }
258            
259             }
260            
261             }
262              
263             # read desc tag from ICC profile
264             # parameters: (ref_to_object, ref_to_parent_object, file_handle, ref_to_tag_table_entry)
265             sub _readICCdesc {
266            
267             # get parameters
268 1     1   4 my ($self, $parent, $fh, $tag) = @_;
269            
270             # local variables
271 1         2 my ($buf, $cnt);
272            
273             # save tag signature
274 1         2 $self->[0]{'signature'} = $tag->[0];
275            
276             # seek start of tag
277 1         10 seek($fh, $tag->[1], 0);
278            
279             # read first 12 bytes
280 1         8 read($fh, $buf, 12);
281            
282             # unpack ASCII string count
283 1         4 $cnt = unpack('x8 N', $buf);
284            
285             # read ASCII string and Unicode language/count
286 1         3 read($fh, $buf, $cnt + 8);
287            
288             # unpack ASCII string and Unicode language/count
289 1         5 ($self->[1], $self->[2], $cnt) = unpack("Z$cnt N2", $buf);
290            
291             # doulbe Unicode count
292 1         2 $cnt *= 2;
293            
294             # read Unicode string and ScriptCode language/count
295 1         3 read($fh, $buf, $cnt + 3);
296            
297             # unpack Unicode string and ScriptCode language/count
298 1         4 ($self->[3], $self->[4], $cnt) = unpack("a$cnt nC", $buf);
299            
300             # decode Unicode string
301 1         4 $self->[3] = decode('UTF-16BE', $self->[3]);
302            
303             # chop null terminator
304 1         2304 chop($self->[3]);
305            
306             # read ScriptCode string
307 1         4 read($fh, $buf, 67);
308            
309             # unpack ScriptCode string
310 1         5 $self->[5] = unpack("Z$cnt", $buf);
311            
312             }
313              
314             # write desc tag to ICC profile
315             # parameters: (ref_to_object, ref_to_parent_object, file_handle, ref_to_tag_table_entry)
316             sub _writeICCdesc {
317              
318             # get parameters
319 1     1   3 my ($self, $parent, $fh, $tag) = @_;
320              
321             # local variables
322 1         2 my ($cnt, $ufmt);
323              
324             # seek start of tag
325 1         7 seek($fh, $tag->[1], 0);
326              
327             # get ASCII count
328 1         3 $cnt = length($self->[1]) + 1;
329              
330             # write ASCII
331 1         15 print $fh pack("a4 x4 N Z$cnt", 'desc', $cnt, $self->[1]);
332              
333             # get Unicode count
334 1         4 $cnt = length($self->[3]) + 1;
335              
336             # if count > 1
337 1 50       3 if ($cnt > 1) {
338            
339             # make Unicode format string
340 1         3 $ufmt = 'a' . (2 * $cnt);
341            
342             # write Unicode
343 1         6 print $fh pack("N N $ufmt", $self->[2], $cnt, encode('UTF-16BE', ($self->[3] . chr(0))));
344            
345             } else {
346            
347             # write nulls
348 0         0 print $fh pack('x8');
349            
350             }
351            
352             # get ScriptCode count
353 1         50 $cnt = length($self->[5]) + 1;
354            
355             # if count > 1
356 1 50       3 if ($cnt > 1) {
357            
358             # write ScriptCode
359 1         6 print $fh pack('n C Z67', $self->[4], $cnt, $self->[5]);
360            
361             } else {
362            
363             # write nulls
364 0           print $fh pack('x70');
365            
366             }
367            
368             }
369              
370             1;