File Coverage

blib/lib/Image/IPTCInfo/TemplateFile.pm
Criterion Covered Total %
statement 59 75 78.6
branch 17 32 53.1
condition 10 24 41.6
subroutine 6 7 85.7
pod 0 4 0.0
total 92 142 64.7


line stmt bran cond sub pod time code
1             package Image::IPTCInfo::TemplateFile;
2 1     1   9815 use strict;
  1         3  
  1         46  
3 1     1   6 use Carp;
  1         2  
  1         72  
4            
5             =head1 NAME
6            
7             Image::IPTCInfo::TemplateFile - Template files for IPTC IIM Text
8            
9             =cut
10            
11 1     1   5 use vars '$VERSION';
  1         6  
  1         1141  
12             $VERSION = "0.2";
13            
14             =head1 VERSION
15            
16             This is version 0.2 - keywords and supplemental categories were
17             not saved in the previous version.
18            
19             =cut
20            
21             require Image::IPTCInfo;
22             # our @ISA = 'Image::IPTCInfo';
23            
24             =head1 DEPENDENCIES
25            
26             Image::IPTCInfo
27            
28             =head1 DESCRIPTION
29            
30             Based on C by Josh Carter (josh@multipart-mixed.com),
31             this allows the loading of data from an IPTC template file, such as
32             used by FotoStation(TM).
33            
34             =head1 CONSTRUCTOR
35            
36             Pass an array, hash reference, array reference, or list.
37            
38             The IPTC text content can be obtained from a (clsoed) file,
39             an file handle, or can be passe directly to the constructor.
40            
41             =over 4
42            
43             =item TO INSTANTIATE DIRECTLY
44            
45             To load IPTC data "manually", supply to the constructor any or all of
46             the datafields whose names are defined as in the parent module
47             (L). Note that both the 'list' items
48             "supplemental category" (I) and "keywords" can be supplied
49             as either a comma-delimited list or array references.
50            
51             Exmaple:
52            
53             Image::IPTCInfo::TemplateFile->new (
54             'caption/abstract' => 'The caption",
55             'keywords' => 'keyword1,keyword2, keywordN',
56             )
57            
58             =item TO INSTANTIATE FROM A TEMPLATE FILE
59            
60             Supply a C paramter, the path to a template file to open.
61             This file should be just the first IPTC code: record 2, dataset 0,
62             such as generated by this module or FotoStation(TM).
63            
64             =item TO INSTANTIATE FROM A FILE HANDLE
65            
66             Supply the paramter C as an open filehandle,
67             from which we'll load, and then close.
68             The file should already be at the start of the first
69             IPTC code: record 2, dataset 0.
70            
71             =back
72            
73             When called, the constructor parses the template, filling
74             a hash with the fields defined in C, a
75             reference to which becomes this object.
76            
77             If no info is found, the object will be empty.
78            
79             =cut
80            
81 4     4 0 1917 sub new { my $class = shift;
82 4         7 my $self;
83 4 50 33     36 if (ref $_[0] eq 'HASH'){
    50          
    50          
84 0         0 $self = shift;
85             } elsif (ref $_[0] eq 'ARRAY') {
86 0         0 $self = { @{$_[0]} };
  0         0  
87             } elsif (not ref $_[0] and $#_>0) {
88 4         13 $self = {@_};
89             } else {
90 0         0 croak "You must supply a FILE or filepath argument in a hash, list or array";
91             }
92 4   50     16 bless $self,$class || __PACKAGE__;
93 4 100       16 if ($self->{filepath}){
94 2         75 open $self->{FILE},$self->{filepath};
95 2         8 binmode $self->{FILE};
96             }
97 4 100       12 if ($self->{FILE}){
98 3         10 $self->collect;
99 3         33 close $self->{FILE};
100 3         11 delete $self->{FILE};
101 3         6 delete $self->{filepath};
102             }
103 4         11 return $self;
104             }
105            
106            
107 3     3 0 4 sub collect { my $self = shift;
108 3         4 while (1) {
109 19         22 my $header;
110 19         79 read($self->{FILE}, $header, 5);
111 19         78 my ($tag, $record, $dataset, $length) = unpack("CCCn", $header);
112            
113             # bail if we're past end of IIM record 2 data
114 19 50 66     136 return unless (defined $tag and $tag == 0x1c) && (defined $record and $record == 2);
      33        
      66        
115            
116 16         57 my $value;
117 16         34 read($self->{FILE}, $value, $length);
118            
119             #warn "tag : " . $tag . "\n";
120             #warn "record : " . $record . "\n";
121             #warn "dataset : " . $dataset . " - ",
122             # ($Image::IPTCInfo::listdatasets{$dataset}||$Image::IPTCInfo::datasets{$dataset}),"\n";
123             #warn "length : " . $length . "\n";
124             #warn "value : $value\n\n";
125            
126             # try to extract first into _listdata (keywords, categories)
127             # and, if unsuccessful, into _data. Discard unknown tags
128 16 100       97 if (exists $Image::IPTCInfo::listdatasets{$dataset}){
    100          
129 4         6 push @{$self->{$Image::IPTCInfo::listdatasets{$dataset}}}, $value;
  4         15  
130             }
131             elsif (exists $Image::IPTCInfo::datasets{$dataset}) {
132 8         28 $self->{$Image::IPTCInfo::datasets{$dataset}} = $value;
133             }
134             # else discard
135             }
136             }
137            
138            
139             =head1 METHOD add_to_Image_IPTC_Info
140            
141             Transfers the data from the calling object to
142             an C object supplied in the
143             only paramter.
144            
145             Returns true or C if no object was supplied.
146            
147             =cut
148            
149 0     0 0 0 sub add_to_Image_IPTC_Info { my ($self,$object) = (shift,shift);
150 0 0 0     0 return undef unless defined $object and ref $object;
151 0         0 foreach my $i (keys %Image::IPTCInfo::listdatasets){
152 0         0 $object->{_listdata}->{$i} = $self->{$i};
153             }
154 0         0 foreach my $i (keys %Image::IPTCInfo::datasets){
155 0         0 $object->{_data} = $self->{$i};
156             }
157 0         0 return 1;
158             }
159            
160            
161 1     1 0 182 sub as_blob { my $self = shift;
162 1         2 my $out;
163            
164             # First, we need to build a mapping of datanames to dataset
165             # numbers if we haven't already.
166 1 50       6 unless (scalar(keys %Image::IPTCInfo::datanames)){
167 1         14 foreach my $dataset (keys %Image::IPTCInfo::datasets){
168 63         85 my $dataname = $Image::IPTCInfo::datasets{$dataset};
169 63         136 $Image::IPTCInfo::datanames{$dataname} = $dataset;
170             }
171             }
172             # Ditto for the lists
173 1 50       8 unless (scalar(keys %Image::IPTCInfo::listdatanames)){
174 1         4 foreach my $dataset (keys %Image::IPTCInfo::listdatasets) {
175 3         4 my $dataname = $Image::IPTCInfo::listdatasets{$dataset};
176 3         8 $Image::IPTCInfo::listdatanames{$dataname} = $dataset;
177             }
178             }
179            
180             # Print record version
181             # tag - record - dataset - len (short) - 2 (short)
182 1         3 $out .= pack("CCCnn", 0x1c, 2, 0, 2, 2);
183            
184             # Iterate over data sets
185 1         4 foreach my $key (keys %$self){
186 1         3 my $dataset = $Image::IPTCInfo::datanames{$key};
187 1 50 33     10 if (not $dataset or $dataset == 0) {
188 0 0       0 warn "PackedIIMData: illegal dataname $key" if $^W;
189 0         0 next;
190             }
191 1   50     9 $out .= pack("CCCn", 0x1c, 0x02, $dataset, (length($self->{$key} || 0 ) ));
192 1   50     6 $out .= $self->{$key} || "";
193             }
194            
195             # Do the same for list data sets
196             # foreach my $key (keys %{$self->{_listdata}}){
197 1         4 foreach my $key ( keys %Image::IPTCInfo::listdatanames ){
198 3         6 my $dataset = $Image::IPTCInfo::listdatanames{$key};
199 3 50       8 if ($dataset == 0){
200 0 0       0 warn "PackedIIMData: illegal dataname $key" if $^W;
201 0         0 next;
202             }
203            
204             #foreach my $value (@{$self->{_listdata}->{$key}}){
205 3 50       8 if ( not ref $self->{$key} ){
206 3         10 $self->{$key} = [split/\s*,\s*/, $self->{$key}];
207             }
208            
209 3         5 foreach my $value (@{$self->{$key}}){
  3         9  
210 0         0 $out .= pack("CCCn", 0x1c, 0x02, $dataset, length($value))
211             . $value;
212             }
213             }
214 1         4 return $out;
215             }
216            
217             1;
218             __END__