source: main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Leaf.pm@ 34921

Last change on this file since 34921 was 34921, checked in by anupama, 3 years ago

Committing the improvements to EmbeddedMetaPlugin's processing of Keywords vs other metadata fields. Keywords were literally stored as arrays of words rather than phrases in PDFs (at least in Diego's sample PDF), whereas other meta fields like Subjects and Creators stored them as arrays of phrases. To get both to work, Kathy updated EXIF to a newer version, to retrieve the actual EXIF values stored in the PDF. And Kathy and Dr Bainbridge came up with a new option that I added called apply_join_before_split_to_metafields that's a regex which can list the metadata fields to apply the join_before_split to and whcih previously always got applied to all metadata fields. Now it's applied to any *Keywords metafields by default, as that's the metafield we have experience of that behaves differently to the others, as it stores by word instead of phrases. Tested on Diego's sample PDF. Diego has double-checked it to works on his sample PDF too, setting the split char to ; and turning on the join_before_split and leaving apply_join_before_split_to_metafields at its default of .*Keywords. File changes are strings.properties for the tooltip, the plugin introducing the option and working with it and Kathy's EXIF updates affecting cpan/File and cpan/Image.

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