File Coverage

blib/lib/ICC/Profile/desc.pm
Criterion Covered Total %
statement 57 93 61.2
branch 6 34 17.6
condition 1 6 16.6
subroutine 11 16 68.7
pod 1 8 12.5
total 76 157 48.4


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