source: gsdl/trunk/perllib/cpan/Image/ExifTool/Leaf.pm@ 16842

Last change on this file since 16842 was 16842, checked in by davidb, 16 years ago

ExifTool added to cpan area to support metadata extraction from files such as JPEG. Primarily targetted as Image files (hence the Image folder name decided upon by the ExifTool author) it also can handle video such as flash and audio such as Wav

File size: 16.2 KB
Line 
1#------------------------------------------------------------------------------
2# File: Leaf.pm
3#
4# Description: Read Creo Leaf EXIF meta information
5#
6# Revisions: 09/28/2005 - P. Harvey Created
7#------------------------------------------------------------------------------
8
9package Image::ExifTool::Leaf;
10
11use strict;
12use vars qw($VERSION);
13use Image::ExifTool qw(:DataAccess :Utils);
14use Image::ExifTool::Exif;
15
16$VERSION = '1.01';
17
18sub ProcessLeaf($$$);
19
20%Image::ExifTool::Leaf::Main = (
21 PROCESS_PROC => \&ProcessLeaf,
22 GROUPS => { 0 => 'Leaf', 2 => 'Camera' },
23 NOTES => q{
24These tags are found in .MOS images from Leaf digital camera backs as
25written by Creo Leaf Capture. They exist within the Leaf-specific directory
26structure of EXIF tag 0x8606. The tables below list observed Leaf tags,
27however ExifTool will extract any tags found in the Leaf directories even if
28they don't appear in these tables.
29 },
30 icc_camera_profile => {
31 Name => 'ICC_Profile',
32 SubDirectory => {
33 TagTable => 'Image::ExifTool::ICC_Profile::Main',
34 },
35 },
36 icc_rgb_ws_profile => {
37 Name => 'RGB_Profile',
38 SubDirectory => {
39 TagTable => 'Image::ExifTool::ICC_Profile::Main',
40 },
41 },
42 camera_profile => {
43 Name => 'CameraProfile',
44 SubDirectory => {
45 TagTable => 'Image::ExifTool::Leaf::CameraProfile',
46 },
47 },
48 JPEG_preview_data => {
49 %Image::ExifTool::previewImageTagInfo,
50 },
51 JPEG_preview_info => 'PreviewInfo',
52 icc_camera_to_tone_space_flow => {
53 Name => 'ToneSpaceFlow',
54 Description => 'ICC To Tone Space Flow',
55 Format => 'int16u',
56 },
57 icc_camera_to_tone_matrix => {
58 Name => 'ToneMatrix',
59 Description => 'ICC To Tone Matrix',
60 Format => 'int8u',
61 Binary => 1,
62 },
63 PDA_histogram_data => {
64 Name => 'PDAHistogram',
65 Binary => 1,
66 },
67 pattern_ratation_angle => {
68 Name => 'PatternAngle',
69 Description => 'Pattern Rotation Angle',
70 Format => 'int16u',
71 Notes => '"ratation" is not a typo',
72 },
73 back_serial_number => {
74 Name => 'BackSerial',
75 Description => 'Back Serial Number',
76 PrintConv => '$val =~ s/ .*//; $val',
77 },
78 image_offset => { Format => 'int16u' },
79);
80
81%Image::ExifTool::Leaf::CameraProfile = (
82 PROCESS_PROC => \&ProcessLeaf,
83 GROUPS => { 0 => 'Leaf', 2 => 'Camera' },
84 CamProf_version => 'CameraProfileVersion',
85 CamProf_name => 'CameraName',
86 CamProf_type => 'CameraType',
87 CamProf_back_type => 'CameraBackType',
88 CamProf_back_type => {
89 Name => 'CameraBackType',
90 },
91 CamProf_capture_profile => {
92 SubDirectory => {
93 TagTable => 'Image::ExifTool::Leaf::CaptureProfile',
94 },
95 },
96 CamProf_image_profile => {
97 SubDirectory => {
98 TagTable => 'Image::ExifTool::Leaf::ImageProfile',
99 },
100 },
101);
102
103%Image::ExifTool::Leaf::CaptureProfile = (
104 PROCESS_PROC => \&ProcessLeaf,
105 GROUPS => { 0 => 'Leaf', 2 => 'Image' },
106 CaptProf_version => {},
107 CaptProf_name => {},
108 CaptProf_type => {},
109 CaptProf_back_type => {},
110 CaptProf_serial_number => {
111 Name => 'CaptureSerial',
112 Description => 'Capture Serial Number',
113 PrintConv => '$val =~ s/ .*//; $val',
114 },
115 CaptProf_image_offset => {},
116 CaptProf_luminance_consts => {},
117 CaptProf_xy_offset_info => 'XYOffsetInfo',
118 CaptProf_color_matrix => {},
119 CaptProf_reconstruction_type=> {},
120 CaptProf_image_fields => {},
121 CaptProf_image_bounds => {},
122 CaptProf_number_of_planes => {},
123 CaptProf_raw_data_rotation => {},
124 CaptProf_color_averages => {},
125 CaptProf_mosaic_pattern => {},
126 CaptProf_dark_correction_type=>{},
127 CaptProf_right_dark_rect => {},
128 CaptProf_left_dark_rect => {},
129 CaptProf_center_dark_rect => {},
130 CaptProf_CCD_rect => {},
131 CaptProf_CCD_valid_rect => {},
132 CaptProf_CCD_video_rect => {},
133);
134
135%Image::ExifTool::Leaf::ImageProfile = (
136 PROCESS_PROC => \&ProcessLeaf,
137 GROUPS => { 0 => 'Leaf', 2 => 'Image' },
138 ImgProf_version => {},
139 ImgProf_name => {},
140 ImgProf_type => {},
141 ImgProf_back_type => {},
142 ImgProf_shoot_setup => {
143 SubDirectory => {
144 TagTable => 'Image::ExifTool::Leaf::ShootSetup',
145 },
146 },
147 ImgProf_image_status => {},
148 ImgProf_rotation_angle => {},
149);
150
151%Image::ExifTool::Leaf::ShootSetup = (
152 PROCESS_PROC => \&ProcessLeaf,
153 GROUPS => { 0 => 'Leaf', 2 => 'Image' },
154 ShootObj_version => {},
155 ShootObj_name => {},
156 ShootObj_type => {},
157 ShootObj_back_type => {},
158 ShootObj_capture_setup => {
159 SubDirectory => {
160 TagTable => 'Image::ExifTool::Leaf::CaptureSetup',
161 },
162 },
163 ShootObj_color_setup => {
164 SubDirectory => {
165 TagTable => 'Image::ExifTool::Leaf::ColorSetup',
166 },
167 },
168 ShootObj_save_setup => {
169 SubDirectory => {
170 TagTable => 'Image::ExifTool::Leaf::SaveSetup',
171 },
172 },
173 ShootObj_camera_setup => {
174 SubDirectory => {
175 TagTable => 'Image::ExifTool::Leaf::CameraSetup',
176 },
177 },
178 ShootObj_look_header => {
179 SubDirectory => {
180 TagTable => 'Image::ExifTool::Leaf::LookHeader',
181 },
182 },
183);
184
185%Image::ExifTool::Leaf::CaptureSetup = (
186 PROCESS_PROC => \&ProcessLeaf,
187 GROUPS => { 0 => 'Leaf', 2 => 'Image' },
188 CaptureObj_version => {},
189 CaptureObj_name => {},
190 CaptureObj_type => {},
191 CaptureObj_back_type => {},
192 CaptureObj_neutals => {
193 SubDirectory => {
194 TagTable => 'Image::ExifTool::Leaf::Neutrals',
195 },
196 },
197 CaptureObj_selection => {
198 SubDirectory => {
199 TagTable => 'Image::ExifTool::Leaf::Selection',
200 },
201 },
202 CaptureObj_tone_curve => {
203 SubDirectory => {
204 TagTable => 'Image::ExifTool::Leaf::ToneCurve',
205 },
206 },
207 CaptureObj_sharpness => {
208 SubDirectory => {
209 TagTable => 'Image::ExifTool::Leaf::Sharpness',
210 },
211 },
212 CaptureObj_single_quality => {},
213 CaptureObj_Multi_quality => {},
214);
215
216%Image::ExifTool::Leaf::Neutrals = (
217 PROCESS_PROC => \&ProcessLeaf,
218 GROUPS => { 0 => 'Leaf', 2 => 'Image' },
219 NeutObj_version => {},
220 NeutObj_name => {},
221 NeutObj_type => {},
222 NeutObj_back_type => {},
223 NeutObj_neutrals => {},
224 NeutObj_color_casts => {},
225 NeutObj_shadow_end_points => {},
226 NeutObj_highlight_end_points => {},
227);
228
229%Image::ExifTool::Leaf::Selection = (
230 PROCESS_PROC => \&ProcessLeaf,
231 GROUPS => { 0 => 'Leaf', 2 => 'Image' },
232 SelObj_version => {},
233 SelObj_name => {},
234 SelObj_type => {},
235 SelObj_back_type => {},
236 SelObj_rect => {},
237 SelObj_resolution => {},
238 SelObj_scale => {},
239 SelObj_locks => {},
240 SelObj_orientation => {},
241);
242
243%Image::ExifTool::Leaf::ToneCurve = (
244 PROCESS_PROC => \&ProcessLeaf,
245 GROUPS => { 0 => 'Leaf', 2 => 'Image' },
246 ToneObj_version => {},
247 ToneObj_name => {},
248 ToneObj_type => {},
249 ToneObj_back_type => {},
250 ToneObj_npts => {},
251 ToneObj_tones => {},
252 ToneObj_gamma => {},
253);
254
255%Image::ExifTool::Leaf::Sharpness = (
256 PROCESS_PROC => \&ProcessLeaf,
257 GROUPS => { 0 => 'Leaf', 2 => 'Image' },
258 SharpObj_version => {},
259 SharpObj_name => {},
260 SharpObj_type => {},
261 SharpObj_back_type => {},
262 SharpObj_sharp_method => {},
263 SharpObj_data_len => {},
264 SharpObj_sharp_info => {},
265);
266
267%Image::ExifTool::Leaf::ColorSetup = (
268 PROCESS_PROC => \&ProcessLeaf,
269 GROUPS => { 0 => 'Leaf', 2 => 'Image' },
270 ColorObj_version => {},
271 ColorObj_name => {},
272 ColorObj_type => {},
273 ColorObj_back_type => {},
274 ColorObj_has_ICC => {},
275 ColorObj_input_profile => {},
276 ColorObj_output_profile => {},
277 ColorObj_color_mode => {},
278 ColorObj_color_type => {},
279);
280
281%Image::ExifTool::Leaf::SaveSetup = (
282 PROCESS_PROC => \&ProcessLeaf,
283 GROUPS => { 0 => 'Leaf', 2 => 'Other' },
284 SaveObj_version => {},
285 SaveObj_name => {},
286 SaveObj_type => {},
287 SaveObj_back_type => {},
288 SaveObj_leaf_auto_active=> {},
289 SaveObj_leaf_hot_folder => {},
290 SaveObj_leaf_output_file_type => {},
291 SaveObj_leaf_auto_base_name => {},
292 SaveObj_leaf_save_selection => {},
293 SaveObj_leaf_open_proc_HDR => {},
294 SaveObj_std_auto_active => {},
295 SaveObj_std_hot_folder => {},
296 SaveObj_std_output_file_type => {},
297 SaveObj_std_output_color_mode => {},
298 SaveObj_std_output_bit_depth => {},
299 SaveObj_std_base_name => {},
300 SaveObj_std_save_selection => {},
301 SaveObj_std_oxygen => {},
302 SaveObj_std_open_in_photoshop => {},
303 SaveObj_std_scaled_output => {},
304 SaveObj_std_sharpen_output => {},
305);
306
307%Image::ExifTool::Leaf::CameraSetup = (
308 PROCESS_PROC => \&ProcessLeaf,
309 GROUPS => { 0 => 'Leaf', 2 => 'Camera' },
310 CameraObj_version => {},
311 CameraObj_name => {},
312 CameraObj_type => {},
313 CameraObj_back_type => {},
314 CameraObj_ISO_speed => {},
315 CameraObj_strobe => {},
316 CameraObj_camera_type => {},
317 CameraObj_lens_type => {},
318 CameraObj_lens_ID => {},
319);
320
321%Image::ExifTool::Leaf::LookHeader = (
322 PROCESS_PROC => \&ProcessLeaf,
323 GROUPS => { 0 => 'Leaf', 2 => 'Other' },
324 LookHead_version => {},
325 LookHead_name => {},
326 LookHead_type => {},
327 LookHead_back_type => {},
328);
329
330# tag table for any unknown Leaf directories
331%Image::ExifTool::Leaf::Unknown = (
332 PROCESS_PROC => \&ProcessLeaf,
333 GROUPS => { 0 => 'Leaf', 2 => 'Unknown' },
334);
335
336# table for Leaf SubIFD entries
337%Image::ExifTool::Leaf::SubIFD = (
338 GROUPS => { 0 => 'EXIF', 1 => 'LeafSubIFD', 2 => 'Image'},
339 WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
340 NOTES => q{
341Leaf also writes a TIFF-format sub-IFD inside IFD0 of a MOS image. No tags
342in this sub-IFD are currently known, except for tag 0x8606 which really
343shouldn't be here anyway (so it doesn't appear in the table below) because
344it duplicates a reference to the same data of tag 0x8606 in IFD0.
345 },
346);
347
348# prepare Leaf tables by generating tag 'Name' and table 'NOTES'
349{
350 my @tableList = ( 'Image::ExifTool::Leaf::Main' );
351 my ($tag, %doneTable);
352 # keep prefix in tag name of common tags
353 my %keepPrefix = ( Version=>1, Name=>1, Type=>1, BackType=>1 );
354 while (@tableList) {
355 my $table = shift @tableList;
356 next if $doneTable{$table};
357 my $prefix = ($table =~ /::Main$/) ? undef : '';
358 $doneTable{$table} = 1;
359 no strict 'refs';
360 $table = \%$table;
361 use strict 'refs';
362 foreach $tag (keys %$table) {
363 my $tagInfo = $$table{$tag};
364 next unless ref $tagInfo eq 'HASH';
365 next if $tag eq 'GROUPS';
366 if (defined $prefix and not $prefix) {
367 ($prefix = $tag) =~ s/_.*//;
368 }
369 unless ($$tagInfo{Name}) {
370 my $name;
371 ($name = $tag) =~ s/_(.)/\U$1/g;
372 if ($prefix) {
373 $name =~ s/^$prefix//;
374 $name = $prefix . $name if $keepPrefix{$name};
375 }
376 $$tagInfo{Name} = ucfirst($name);
377 }
378 next unless $$tagInfo{SubDirectory};
379 my $subTable = $tagInfo->{SubDirectory}->{TagTable};
380 next unless $subTable =~ /::Leaf::/;
381 push @tableList, $subTable;
382 }
383 next unless $prefix;
384 $$table{NOTES} = "All B<Tag ID>'s in the following table have a " .
385 "leading '${prefix}_' which\nhas been removed.\n";
386 }
387}
388
389#------------------------------------------------------------------------------
390# Process Leaf information
391# Inputs: 0) ExifTool object reference
392# 1) Reference to directory information hash
393# 2) Pointer to tag table for this directory
394# Returns: 1 on success, otherwise returns 0 and sets a Warning
395sub ProcessLeaf($$$)
396{
397 my ($exifTool, $dirInfo, $tagTablePtr) = @_;
398 my $dataPt = $$dirInfo{DataPt};
399 my $dirStart = $$dirInfo{DirStart} || 0;
400 my $dirLen = $$dirInfo{DirLen} || $$dirInfo{DataLen} - $dirStart;
401 my $dirEnd = $dirStart + $dirLen;
402 my $verbose = $exifTool->Options('Verbose');
403 my $pos = $dirStart;
404 my $hdrLen = 52; # header length for PKTS information
405 my $success;
406
407 $verbose and $exifTool->VerboseDir('Leaf');
408 for (;;) {
409 last if $pos + $hdrLen > $dirEnd;
410 my $header = substr($$dataPt, $pos, $hdrLen);
411 last unless substr($header, 0, 4) eq 'PKTS';
412 $success = 1;
413 my $size = Get32u(\$header, 48);
414 $pos += $hdrLen;
415 if ($pos + $size > $dirEnd) {
416 $exifTool->Warn('Truncated Leaf data');
417 last;
418 }
419 my $tag = substr($header, 8, 40);
420 $tag =~ s/\0.*//;
421 next unless $tag;
422 my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
423 # generate tag info for unknown tags
424 my $val;
425 if ($tagInfo and $$tagInfo{Format}) {
426 $val = ReadValue($dataPt, $pos, $$tagInfo{Format}, undef, $size);
427 } else {
428 $val = substr($$dataPt, $pos, $size);
429 }
430 unless ($tagInfo) {
431 my $name = ucfirst($tag);
432 $name =~ s/_(.)/\U$1/g;
433 if ($val =~ /^PKTS\0\0\0\x01/) {
434 # also unpack unknown directories
435 $tagInfo = {
436 Name => $name,
437 SubDirectory => { TagTable => 'Image::ExifTool::Leaf::Unknown' },
438 };
439 } elsif ($tagTablePtr ne \%Image::ExifTool::Leaf::Main or
440 $exifTool->Options('Unknown'))
441 {
442 $tagInfo = {
443 Name => $name,
444 Writable => 0,
445 PrintConv => 'length($val) > 60 ? substr($val,0,55) . "[...]" : $val',
446 };
447 # make tags in main table unknown because they tend to be binary
448 $$tagInfo{Unknown} = 1 if $tagTablePtr eq \%Image::ExifTool::Leaf::Main;
449 }
450 $tagInfo and Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
451 }
452 if ($verbose) {
453 $exifTool->VerboseInfo($tag, $tagInfo,
454 Table => $tagTablePtr,
455 Value => $val,
456 DataPt => $dataPt,
457 DataPos => $$dirInfo{DataPos},
458 Size => $size,
459 Start => $pos,
460 );
461 }
462 if ($tagInfo) {
463 if ($$tagInfo{SubDirectory}) {
464 my %subdirInfo = (
465 DataPt => $dataPt,
466 DirLen => $size,
467 DirStart => $pos,
468 DataPos => $$dirInfo{DataPos},
469 DirName => 'Leaf PKTS',
470 );
471 my $subTable = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
472 $exifTool->ProcessDirectory(\%subdirInfo, $subTable);
473 } else {
474 $val =~ tr/\n/ /; # remove newlines from value
475 $exifTool->FoundTag($tagInfo, $val);
476 }
477 }
478 $pos += $size;
479 }
480 $success or $exifTool->Warn('Bad format Leaf data');
481 return $success;
482}
483
4841; # end
485
486__END__
487
488=head1 NAME
489
490Image::ExifTool::Leaf - Read Creo Leaf EXIF meta information
491
492=head1 SYNOPSIS
493
494This module is loaded automatically by Image::ExifTool when required.
495
496=head1 DESCRIPTION
497
498This module contains definitions required by Image::ExifTool to interpret
499meta information from Leaf digital camera backs written by Creo Leaf
500Capture.
501
502=head1 AUTHOR
503
504Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
505
506This library is free software; you can redistribute it and/or modify it
507under the same terms as Perl itself.
508
509=head1 SEE ALSO
510
511L<Image::ExifTool::TagNames/Leaf Tags>,
512L<Image::ExifTool(3pm)|Image::ExifTool>
513
514=cut
Note: See TracBrowser for help on using the repository browser.