123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516 |
- #------------------------------------------------------------------------------
- # File: Leaf.pm
- #
- # Description: Read Creo Leaf EXIF meta information
- #
- # Revisions: 09/28/2005 - P. Harvey Created
- #------------------------------------------------------------------------------
- package Image::ExifTool::Leaf;
- use strict;
- use vars qw($VERSION);
- use Image::ExifTool qw(:DataAccess :Utils);
- use Image::ExifTool::Exif;
- $VERSION = '1.06';
- sub ProcessLeaf($$$);
- %Image::ExifTool::Leaf::Main = (
- PROCESS_PROC => \&ProcessLeaf,
- GROUPS => { 0 => 'Leaf', 2 => 'Camera' },
- NOTES => q{
- These tags are found in .MOS images from Leaf digital camera backs as
- written by Creo Leaf Capture. They exist within the Leaf-specific directory
- structure of EXIF tag 0x8606. The tables below list observed Leaf tags,
- however ExifTool will extract any tags found in the Leaf directories even if
- they don't appear in these tables.
- },
- icc_camera_profile => {
- Name => 'ICC_Profile',
- SubDirectory => {
- TagTable => 'Image::ExifTool::ICC_Profile::Main',
- },
- },
- icc_rgb_ws_profile => {
- Name => 'RGB_Profile',
- SubDirectory => {
- TagTable => 'Image::ExifTool::ICC_Profile::Main',
- },
- },
- camera_profile => {
- Name => 'CameraProfile',
- SubDirectory => {
- TagTable => 'Image::ExifTool::Leaf::CameraProfile',
- },
- },
- JPEG_preview_data => {
- %Image::ExifTool::previewImageTagInfo,
- Groups => { 2 => 'Preview' },
- },
- JPEG_preview_info => 'PreviewInfo',
- icc_camera_to_tone_space_flow => {
- Name => 'ToneSpaceFlow',
- Description => 'ICC To Tone Space Flow',
- Format => 'int16u',
- },
- icc_camera_to_tone_matrix => {
- Name => 'ToneMatrix',
- Description => 'ICC To Tone Matrix',
- Format => 'int8u',
- Binary => 1,
- },
- PDA_histogram_data => {
- Name => 'PDAHistogram',
- Binary => 1,
- },
- pattern_ratation_angle => {
- Name => 'PatternAngle',
- Description => 'Pattern Rotation Angle',
- Format => 'int16u',
- Notes => '"ratation" is not a typo',
- },
- back_serial_number => {
- Name => 'BackSerial',
- Description => 'Back Serial Number',
- PrintConv => '$val =~ s/ .*//s; $val',
- },
- image_offset => { Format => 'int16u' },
- );
- %Image::ExifTool::Leaf::CameraProfile = (
- PROCESS_PROC => \&ProcessLeaf,
- GROUPS => { 0 => 'Leaf', 2 => 'Camera' },
- CamProf_version => 'CameraProfileVersion',
- CamProf_name => 'CameraName',
- CamProf_type => 'CameraType',
- CamProf_back_type => 'CameraBackType',
- CamProf_back_type => {
- Name => 'CameraBackType',
- },
- CamProf_capture_profile => {
- SubDirectory => {
- TagTable => 'Image::ExifTool::Leaf::CaptureProfile',
- },
- },
- CamProf_image_profile => {
- SubDirectory => {
- TagTable => 'Image::ExifTool::Leaf::ImageProfile',
- },
- },
- );
- %Image::ExifTool::Leaf::CaptureProfile = (
- PROCESS_PROC => \&ProcessLeaf,
- GROUPS => { 0 => 'Leaf', 2 => 'Image' },
- CaptProf_version => {},
- CaptProf_name => {},
- CaptProf_type => {},
- CaptProf_back_type => {},
- CaptProf_serial_number => {
- Name => 'CaptureSerial',
- Description => 'Capture Serial Number',
- PrintConv => '$val =~ s/ .*//s; $val',
- },
- CaptProf_image_offset => {},
- CaptProf_luminance_consts => {},
- CaptProf_xy_offset_info => 'XYOffsetInfo',
- CaptProf_color_matrix => {},
- CaptProf_reconstruction_type=> {},
- CaptProf_image_fields => {},
- CaptProf_image_bounds => {},
- CaptProf_number_of_planes => {},
- CaptProf_raw_data_rotation => {},
- CaptProf_color_averages => {},
- CaptProf_mosaic_pattern => {},
- CaptProf_dark_correction_type=>{},
- CaptProf_right_dark_rect => {},
- CaptProf_left_dark_rect => {},
- CaptProf_center_dark_rect => {},
- CaptProf_CCD_rect => {},
- CaptProf_CCD_valid_rect => {},
- CaptProf_CCD_video_rect => {},
- );
- %Image::ExifTool::Leaf::ImageProfile = (
- PROCESS_PROC => \&ProcessLeaf,
- GROUPS => { 0 => 'Leaf', 2 => 'Image' },
- ImgProf_version => {},
- ImgProf_name => {},
- ImgProf_type => {},
- ImgProf_back_type => {},
- ImgProf_shoot_setup => {
- SubDirectory => {
- TagTable => 'Image::ExifTool::Leaf::ShootSetup',
- },
- },
- ImgProf_image_status => {},
- ImgProf_rotation_angle => {},
- );
- %Image::ExifTool::Leaf::ShootSetup = (
- PROCESS_PROC => \&ProcessLeaf,
- GROUPS => { 0 => 'Leaf', 2 => 'Image' },
- ShootObj_version => {},
- ShootObj_name => {},
- ShootObj_type => {},
- ShootObj_back_type => {},
- ShootObj_capture_setup => {
- SubDirectory => {
- TagTable => 'Image::ExifTool::Leaf::CaptureSetup',
- },
- },
- ShootObj_color_setup => {
- SubDirectory => {
- TagTable => 'Image::ExifTool::Leaf::ColorSetup',
- },
- },
- ShootObj_save_setup => {
- SubDirectory => {
- TagTable => 'Image::ExifTool::Leaf::SaveSetup',
- },
- },
- ShootObj_camera_setup => {
- SubDirectory => {
- TagTable => 'Image::ExifTool::Leaf::CameraSetup',
- },
- },
- ShootObj_look_header => {
- SubDirectory => {
- TagTable => 'Image::ExifTool::Leaf::LookHeader',
- },
- },
- );
- %Image::ExifTool::Leaf::CaptureSetup = (
- PROCESS_PROC => \&ProcessLeaf,
- GROUPS => { 0 => 'Leaf', 2 => 'Image' },
- CaptureObj_version => {},
- CaptureObj_name => {},
- CaptureObj_type => {},
- CaptureObj_back_type => {},
- CaptureObj_neutals => {
- SubDirectory => {
- TagTable => 'Image::ExifTool::Leaf::Neutrals',
- },
- },
- CaptureObj_selection => {
- SubDirectory => {
- TagTable => 'Image::ExifTool::Leaf::Selection',
- },
- },
- CaptureObj_tone_curve => {
- SubDirectory => {
- TagTable => 'Image::ExifTool::Leaf::ToneCurve',
- },
- },
- CaptureObj_sharpness => {
- SubDirectory => {
- TagTable => 'Image::ExifTool::Leaf::Sharpness',
- },
- },
- CaptureObj_single_quality => {},
- CaptureObj_Multi_quality => {},
- );
- %Image::ExifTool::Leaf::Neutrals = (
- PROCESS_PROC => \&ProcessLeaf,
- GROUPS => { 0 => 'Leaf', 2 => 'Image' },
- NeutObj_version => {},
- NeutObj_name => {},
- NeutObj_type => {},
- NeutObj_back_type => {},
- NeutObj_neutrals => {},
- NeutObj_color_casts => {},
- NeutObj_shadow_end_points => {},
- NeutObj_highlight_end_points => {},
- );
- %Image::ExifTool::Leaf::Selection = (
- PROCESS_PROC => \&ProcessLeaf,
- GROUPS => { 0 => 'Leaf', 2 => 'Image' },
- SelObj_version => {},
- SelObj_name => {},
- SelObj_type => {},
- SelObj_back_type => {},
- SelObj_rect => {},
- SelObj_resolution => {},
- SelObj_scale => {},
- SelObj_locks => {},
- SelObj_orientation => {},
- );
- %Image::ExifTool::Leaf::ToneCurve = (
- PROCESS_PROC => \&ProcessLeaf,
- GROUPS => { 0 => 'Leaf', 2 => 'Image' },
- ToneObj_version => {},
- ToneObj_name => {},
- ToneObj_type => {},
- ToneObj_back_type => {},
- ToneObj_npts => {},
- ToneObj_tones => {},
- ToneObj_gamma => {},
- );
- %Image::ExifTool::Leaf::Sharpness = (
- PROCESS_PROC => \&ProcessLeaf,
- GROUPS => { 0 => 'Leaf', 2 => 'Image' },
- SharpObj_version => {},
- SharpObj_name => {},
- SharpObj_type => {},
- SharpObj_back_type => {},
- SharpObj_sharp_method => {},
- SharpObj_data_len => {},
- SharpObj_sharp_info => {},
- );
- %Image::ExifTool::Leaf::ColorSetup = (
- PROCESS_PROC => \&ProcessLeaf,
- GROUPS => { 0 => 'Leaf', 2 => 'Image' },
- ColorObj_version => {},
- ColorObj_name => {},
- ColorObj_type => {},
- ColorObj_back_type => {},
- ColorObj_has_ICC => {},
- ColorObj_input_profile => {},
- ColorObj_output_profile => {},
- ColorObj_color_mode => {},
- ColorObj_color_type => {},
- );
- %Image::ExifTool::Leaf::SaveSetup = (
- PROCESS_PROC => \&ProcessLeaf,
- GROUPS => { 0 => 'Leaf', 2 => 'Other' },
- SaveObj_version => {},
- SaveObj_name => {},
- SaveObj_type => {},
- SaveObj_back_type => {},
- SaveObj_leaf_auto_active=> {},
- SaveObj_leaf_hot_folder => {},
- SaveObj_leaf_output_file_type => {},
- SaveObj_leaf_auto_base_name => {},
- SaveObj_leaf_save_selection => {},
- SaveObj_leaf_open_proc_HDR => {},
- SaveObj_std_auto_active => {},
- SaveObj_std_hot_folder => {},
- SaveObj_std_output_file_type => {},
- SaveObj_std_output_color_mode => {},
- SaveObj_std_output_bit_depth => {},
- SaveObj_std_base_name => {},
- SaveObj_std_save_selection => {},
- SaveObj_std_oxygen => {},
- SaveObj_std_open_in_photoshop => {},
- SaveObj_std_scaled_output => {},
- SaveObj_std_sharpen_output => {},
- );
- %Image::ExifTool::Leaf::CameraSetup = (
- PROCESS_PROC => \&ProcessLeaf,
- GROUPS => { 0 => 'Leaf', 2 => 'Camera' },
- CameraObj_version => {},
- CameraObj_name => {},
- CameraObj_type => {},
- CameraObj_back_type => {},
- CameraObj_ISO_speed => {},
- CameraObj_strobe => {},
- CameraObj_camera_type => {},
- CameraObj_lens_type => {},
- CameraObj_lens_ID => {},
- );
- %Image::ExifTool::Leaf::LookHeader = (
- PROCESS_PROC => \&ProcessLeaf,
- GROUPS => { 0 => 'Leaf', 2 => 'Other' },
- LookHead_version => {},
- LookHead_name => {},
- LookHead_type => {},
- LookHead_back_type => {},
- );
- # tag table for any unknown Leaf directories
- %Image::ExifTool::Leaf::Unknown = (
- PROCESS_PROC => \&ProcessLeaf,
- GROUPS => { 0 => 'Leaf', 2 => 'Unknown' },
- );
- # table for Leaf SubIFD entries
- %Image::ExifTool::Leaf::SubIFD = (
- GROUPS => { 0 => 'MakerNotes', 1 => 'LeafSubIFD', 2 => 'Image'},
- WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
- NOTES => q{
- Leaf writes a TIFF-format sub-IFD inside IFD0 of a MOS image. No tags in
- this sub-IFD are currently known, except for tag 0x8606 which really
- shouldn't be here anyway (so it doesn't appear in the table below) because
- it duplicates a reference to the same data of tag 0x8606 in IFD0.
- },
- );
- # prepare Leaf tables by generating tag 'Name' and table 'NOTES'
- {
- my @tableList = ( 'Image::ExifTool::Leaf::Main' );
- my ($tag, %doneTable);
- # keep prefix in tag name of common tags
- my %keepPrefix = ( Version=>1, Name=>1, Type=>1, BackType=>1 );
- while (@tableList) {
- my $table = shift @tableList;
- next if $doneTable{$table};
- my $prefix = ($table =~ /::Main$/) ? undef : '';
- $doneTable{$table} = 1;
- no strict 'refs';
- $table = \%$table;
- use strict 'refs';
- foreach $tag (keys %$table) {
- my $tagInfo = $$table{$tag};
- next unless ref $tagInfo eq 'HASH';
- next if $tag eq 'GROUPS';
- if (defined $prefix and not $prefix) {
- ($prefix = $tag) =~ s/_.*//;
- }
- unless ($$tagInfo{Name}) {
- my $name;
- ($name = $tag) =~ s/_(.)/\U$1/g;
- if ($prefix) {
- $name =~ s/^$prefix//;
- $name = $prefix . $name if $keepPrefix{$name};
- }
- $$tagInfo{Name} = ucfirst($name);
- }
- next unless $$tagInfo{SubDirectory};
- my $subTable = $tagInfo->{SubDirectory}->{TagTable};
- next unless $subTable =~ /::Leaf::/;
- push @tableList, $subTable;
- }
- next unless $prefix;
- $$table{NOTES} = "All B<Tag ID>'s in the following table have a " .
- "leading '${prefix}_' which\nhas been removed.\n";
- }
- }
- #------------------------------------------------------------------------------
- # Process Leaf information
- # Inputs: 0) ExifTool object reference
- # 1) Reference to directory information hash
- # 2) Pointer to tag table for this directory
- # Returns: 1 on success, otherwise returns 0 and sets a Warning
- sub ProcessLeaf($$$)
- {
- my ($et, $dirInfo, $tagTablePtr) = @_;
- my $dataPt = $$dirInfo{DataPt};
- my $dirStart = $$dirInfo{DirStart} || 0;
- my $dirLen = $$dirInfo{DirLen} || $$dirInfo{DataLen} - $dirStart;
- my $dirEnd = $dirStart + $dirLen;
- my $verbose = $et->Options('Verbose');
- my $pos = $dirStart;
- my $hdrLen = 52; # header length for PKTS information
- my $success;
- $verbose and $et->VerboseDir('Leaf');
- for (;;) {
- last if $pos + $hdrLen > $dirEnd;
- my $header = substr($$dataPt, $pos, $hdrLen);
- last unless substr($header, 0, 4) eq 'PKTS';
- $success = 1;
- my $size = Get32u(\$header, 48);
- $pos += $hdrLen;
- if ($pos + $size > $dirEnd) {
- $et->Warn('Truncated Leaf data');
- last;
- }
- my $tag = substr($header, 8, 40);
- $tag =~ s/\0.*//s;
- next unless $tag;
- my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
- # generate tag info for unknown tags
- my $val;
- if ($tagInfo and $$tagInfo{Format}) {
- $val = ReadValue($dataPt, $pos, $$tagInfo{Format}, undef, $size);
- } else {
- $val = substr($$dataPt, $pos, $size);
- }
- unless ($tagInfo) {
- my $name = ucfirst($tag);
- $name =~ s/_(.)/\U$1/g;
- if ($val =~ /^PKTS\0\0\0\x01/) {
- # also unpack unknown directories
- $tagInfo = {
- Name => $name,
- SubDirectory => { TagTable => 'Image::ExifTool::Leaf::Unknown' },
- };
- } elsif ($tagTablePtr ne \%Image::ExifTool::Leaf::Main or
- $et->Options('Unknown'))
- {
- $tagInfo = {
- Name => $name,
- Writable => 0,
- PrintConv => 'length($val) > 60 ? substr($val,0,55) . "[...]" : $val',
- };
- # make tags in main table unknown because they tend to be binary
- $$tagInfo{Unknown} = 1 if $tagTablePtr eq \%Image::ExifTool::Leaf::Main;
- }
- $tagInfo and AddTagToTable($tagTablePtr, $tag, $tagInfo);
- }
- if ($verbose) {
- $et->VerboseInfo($tag, $tagInfo,
- Table => $tagTablePtr,
- Value => $val,
- DataPt => $dataPt,
- DataPos => $$dirInfo{DataPos},
- Size => $size,
- Start => $pos,
- );
- }
- if ($tagInfo) {
- if ($$tagInfo{SubDirectory}) {
- my %subdirInfo = (
- DataPt => $dataPt,
- DirLen => $size,
- DirStart => $pos,
- DataPos => $$dirInfo{DataPos},
- DirName => 'Leaf PKTS',
- );
- my $subTable = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
- $et->ProcessDirectory(\%subdirInfo, $subTable);
- } else {
- $val =~ tr/\n/ /; # translate newlines to spaces
- $val =~ s/\0+$//; # remove null terminators
- $et->FoundTag($tagInfo, $val);
- }
- }
- $pos += $size;
- }
- $success or $et->Warn('Bad format Leaf data');
- return $success;
- }
- 1; # end
- __END__
- =head1 NAME
- Image::ExifTool::Leaf - Read Creo Leaf EXIF meta information
- =head1 SYNOPSIS
- This module is loaded automatically by Image::ExifTool when required.
- =head1 DESCRIPTION
- This module contains definitions required by Image::ExifTool to interpret
- meta information from Leaf digital camera backs written by Creo Leaf
- Capture.
- =head1 AUTHOR
- Copyright 2003-2016, Phil Harvey (phil at owl.phy.queensu.ca)
- This library is free software; you can redistribute it and/or modify it
- under the same terms as Perl itself.
- =head1 SEE ALSO
- L<Image::ExifTool::TagNames/Leaf Tags>,
- L<Image::ExifTool(3pm)|Image::ExifTool>
- =cut
|