diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Image/ExifTool.pm | 127 | ||||
-rw-r--r-- | lib/Image/ExifTool.pod | 79 | ||||
-rw-r--r-- | lib/Image/ExifTool/BuildTagLookup.pm | 7 | ||||
-rw-r--r-- | lib/Image/ExifTool/Panasonic.pm | 4 | ||||
-rw-r--r-- | lib/Image/ExifTool/Pentax.pm | 4 | ||||
-rw-r--r-- | lib/Image/ExifTool/TagLookup.pm | 22 | ||||
-rw-r--r-- | lib/Image/ExifTool/Writer.pl | 41 |
7 files changed, 167 insertions, 117 deletions
diff --git a/lib/Image/ExifTool.pm b/lib/Image/ExifTool.pm index 808f1c94..c32da0b5 100644 --- a/lib/Image/ExifTool.pm +++ b/lib/Image/ExifTool.pm @@ -28,7 +28,7 @@ use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes %mimeType $swapBytes $swapWords $currentByteOrder %unpackStd %jpegMarker %specialTags %fileTypeLookup $testLen $exePath); -$VERSION = '12.02'; +$VERSION = '12.03'; $RELEASE = ''; @ISA = qw(Exporter); %EXPORT_TAGS = ( @@ -2238,6 +2238,7 @@ sub ClearOptions($) GeoSpeedRef => undef, # geotag GPSSpeedRef GlobalTimeShift => undef, # apply time shift to all extracted date/time values # Group# => undef, # return tags for specified groups in family # + HexTagIDs => 0, # use hex tag ID's in family 7 group names HtmlDump => 0, # HTML dump (0-3, higher # = bigger limit) HtmlDumpBase => undef, # base address for HTML dump IgnoreMinorErrors => undef, # ignore minor errors when reading/writing @@ -3297,7 +3298,7 @@ sub GetGroup($$;$) { local $_; my ($self, $tag, $family) = @_; - my ($tagInfo, @groups, @families, $simplify, $byTagInfo, $ex); + my ($tagInfo, @groups, @families, $simplify, $byTagInfo, $ex, $noID); if (ref $tag eq 'HASH') { $tagInfo = $tag; $tag = $$tagInfo{Name}; @@ -3328,6 +3329,7 @@ sub GetGroup($$;$) $simplify = 1 unless $family =~ /^:/; undef $family; foreach (0..2) { $groups[$_] = $$groups{$_}; } + $noID = 1 if @families == 1 and $families[0] != 7; } else { return(($ex && $$ex{"G$family"}) || $$groups{$family}) if $family == 0 or $family == 2; $groups[1] = $$groups{1}; @@ -3339,26 +3341,30 @@ sub GetGroup($$;$) $groups[3] = 'Main'; $groups[4] = ($tag =~ /\((\d+)\)$/) ? "Copy$1" : ''; # handle dynamic group names if necessary - if ($ex and not $byTagInfo) { - $groups[0] = $$ex{G0} if $$ex{G0}; - $groups[1] = $$ex{G1} =~ /^\+(.*)/ ? "$groups[1]$1" : $$ex{G1} if $$ex{G1}; - $groups[3] = 'Doc' . $$ex{G3} if $$ex{G3}; - $groups[5] = $$ex{G5} || $groups[1] if defined $$ex{G5}; - if (defined $$ex{G6}) { - $groups[5] = '' unless defined $groups[5]; # (can't leave a hole in the array) - $groups[6] = $$ex{G6}; - } - } - if ($$self{OPTIONS}{SaveIDGroup}) { - my $id = $$tagInfo{TagID}; - $id = '' unless defined $id; - if ($$self{OPTIONS}{SaveIDGroup} eq '2' and $id =~ /^\d+$/) { - $groups[7] = 'ID_' . sprintf('0x%x', $id); - } else { - $id =~ s/([^-_A-Za-z0-9])/sprintf('%.2x',ord $1)/ge; - $groups[7] = 'ID_' . $id; + unless ($byTagInfo) { + if ($ex) { + $groups[0] = $$ex{G0} if $$ex{G0}; + $groups[1] = $$ex{G1} =~ /^\+(.*)/ ? "$groups[1]$1" : $$ex{G1} if $$ex{G1}; + $groups[3] = 'Doc' . $$ex{G3} if $$ex{G3}; + $groups[5] = $$ex{G5} || $groups[1] if defined $$ex{G5}; + if (defined $$ex{G6}) { + $groups[5] = '' unless defined $groups[5]; # (can't leave a hole in the array) + $groups[6] = $$ex{G6}; + } + } + # generate tag ID group names unless obviously not needed + unless ($noID) { + my $id = $$tagInfo{TagID}; + if (not defined $id) { + $id = ''; # (just to be safe) + } elsif ($id =~ /^\d+$/) { + $id = sprintf('0x%x', $id) if $$self{OPTIONS}{HexTagIDs}; + } else { + $id =~ s/([^-_A-Za-z0-9])/sprintf('%.2x',ord $1)/ge; + } + $groups[7] = 'ID-' . $id; + defined $groups[$_] or $groups[$_] = '' foreach (5,6); } - defined $groups[$_] or $groups[$_] = '' foreach (5,6); } if ($family) { return $groups[$family] || '' if $family > 0; @@ -4206,6 +4212,22 @@ sub ParseArguments($;@) } #------------------------------------------------------------------------------ +# Does group name match the tag ID? +# Inputs: 0) tag ID, 1) group name (with "ID-" removed) +# Returns: true on success +sub IsSameID($$) +{ + my ($id, $grp) = @_; + return 1 if $grp eq $id; # decimal ID's or raw ID's + if ($id =~ /^\d+$/) { # numerical numerical ID's may be in hex + return 1 if $grp =~ s/^0x0*// and $grp eq sprintf('%x', $id); + } else { # other ID's may conform to ExifTool group name conventions + return 1 if $id =~ s/([^-_A-Za-z0-9])/sprintf('%.2x',ord $1)/ge and $grp eq $id; + } + return 0; +} + +#------------------------------------------------------------------------------ # Get list of tags in specified group # Inputs: 0) ExifTool ref, 1) group spec, 2) tag key or reference to list of tag keys # Returns: list of matching tags in list context, or first match in scalar context @@ -4216,40 +4238,41 @@ sub GroupMatches($$$) my ($self, $group, $tagList) = @_; $tagList = [ $tagList ] unless ref $tagList; my ($tag, @matches); - if ($group =~ /:/) { - # check each group name individually (eg. "Author:1IPTC") - my @grps = split ':', lc $group; - my (@fmys, $g); + # check each group name individually (eg. "Author:1IPTC") + my @grps = split ':', $group; + my (@fmys, $g); + for ($g=0; $g<@grps; ++$g) { + if ($grps[$g] =~ s/^(\d*)(id-)?//i) { + $fmys[$g] = $1 if length $1; + if ($2) { + $fmys[$g] = 7; + next; # (don't convert tag ID's to lower case) + } + } + $grps[$g] = lc $grps[$g]; + $grps[$g] = '' if $grps[$g] eq 'copy0'; # accept 'Copy0' for primary tag + } + foreach $tag (@$tagList) { + my @groups = $self->GetGroup($tag, -1); for ($g=0; $g<@grps; ++$g) { - $fmys[$g] = $1 if $grps[$g] =~ s/^(\d+)//; - $grps[$g] = '' if $grps[$g] eq 'copy0'; # accept 'Copy0' for primary tag - } - foreach $tag (@$tagList) { - my @groups = $self->GetGroup($tag, -1); - for ($g=0; $g<@grps; ++$g) { - my $grp = $grps[$g]; - next if $grp eq '*' or $grp eq 'all'; - if (defined $fmys[$g]) { - my $f = $fmys[$g]; - last unless defined $groups[$f] and $grp eq lc $groups[$f]; + my $grp = $grps[$g]; + next if $grp eq '*' or $grp eq 'all'; + my $f; + if (defined($f = $fmys[$g])) { + last unless defined $groups[$f]; + if ($f == 7) { + next if IsSameID($self->GetTagID($tag), $grp); } else { - last unless grep /^$grp$/i, @groups; + next if $grp eq lc $groups[$f]; } - } - if ($g == @grps) { - return $tag unless wantarray; - push @matches, $tag; + last; + } else { + last unless grep /^$grp$/i, @groups; } } - } else { - my $family = ($group =~ s/^(\d+)//) ? $1 : -1; - $group = '' if lc $group eq 'copy0'; # accept 'Copy0' for primary tag - foreach $tag (@$tagList) { - my @groups = $self->GetGroup($tag, $family); - if (grep(/^$group$/i, @groups)) { - return $tag unless wantarray; - push @matches, $tag; - } + if ($g == @grps) { + return $tag unless wantarray; + push @matches, $tag; } } return wantarray ? @matches : $matches[0]; @@ -4708,13 +4731,13 @@ sub AddCompositeTags($;$) my ($module, $prefix, $tagID); unless (ref $add) { ($prefix = $add) =~ s/.*:://; - $prefix .= '::'; $module = $add; $add .= '::Composite'; no strict 'refs'; $add = \%$add; + $prefix .= '-'; } else { - $prefix = 'UserDefined::'; + $prefix = 'UserDefined-'; } my $defaultGroups = $$add{GROUPS}; my $compTable = GetTagTable('Image::ExifTool::Composite'); diff --git a/lib/Image/ExifTool.pod b/lib/Image/ExifTool.pod index 6733ff6d..1d5e219f 100644 --- a/lib/Image/ExifTool.pod +++ b/lib/Image/ExifTool.pod @@ -731,6 +731,11 @@ to be excluded by preceding group name with a '-'. See L</GetGroup> for a description of group families, and L</GetAllGroups [static]> for lists of group names. +=item HexTagIDs + +Use hexadecimal for the family 7 group names of tags with numerical ID's +(instead of decimal). + =item HtmlDump Dump information in hex to dynamic HTML web page. The value may be 0-3 for @@ -1606,7 +1611,8 @@ values in list context. 0) ExifTool object reference -1) Tag name (case sensitive, may be prefixed by family 0 or 1 group name) +1) Tag name (case sensitive, may be prefixed by family 0, 1 or 7 group +names, separated by colons) =item Return Values: @@ -1668,34 +1674,35 @@ in a specified file. 2-N) [optional] List of tag names to set or options hash references. All writable tags are set if none are specified. The tag names are not case -sensitive, and may be prefixed by one or more family 0, 1 or 2 group names -with optional leading family numbers, separated by colons (eg. 'exif:iso'). -A leading '-' indicates tags to be excluded (eg. '-comment'), or a trailing -'#' causes the ValueConv value to be copied (same as setting the Type option -to 'ValueConv' for this tag only). Wildcards ('*' and '?') may be used in -the tag name. A tag name of '*' is commonly used when a group is specified -to copy all tags in the group (eg. 'XMP:*'). A special feature allows tag -names of the form 'DSTTAGE<lt>SRCTAG' (or 'SRCTAGE<gt>DSTTAG') to be -specified to copy information to a tag with a different name or a specified -group. Both 'SRCTAG' and 'DSTTAG' may contain wildcards and/or be prefixed -by a group name (eg. 'fileModifyDateE<lt>modifyDate' or 'xmp:*E<lt>*'), -and/or suffixed by a '#' to disable print conversion. Copied tags may also -be added or deleted from a list with arguments of the form -'DSTTAG+E<lt>SRCTAG' or 'DSTTAG-E<lt>SRCTAG'. Tags are evaluated in order, -so exclusions apply only to tags included earlier in the list. An extension -of this feature allows the tag value to be set from a string containing tag -names with leading '$' symbols (eg. 'CommentE<lt>the file is $filename'). -Braces '{}' may be used around the tag name to separate it from subsequent -text, and a '$$' is used to to represent a '$' symbol. The behaviour for -missing tags in expressions is defined by the L</MissingTagValue> option. -The tag value may be modified via changes to the default input variable ($_) -in a Perl expression placed inside the braces and after a semicolon -following the tag name (see the last example above). A '@' may be added -after the tag name (before the semicolon) to make the expression act on -individual list items instead of the concatenated string for list-type tags. -Braces within the expression must be balanced. Multiple options hash -references may be passed to set different options for different tags. -Options apply to subsequent tags in the argument list. +sensitive, and may be prefixed by one or more family 0, 1, 2 or 7 group +names with optional leading family numbers, separated by colons (eg. +'exif:iso'). A leading '-' indicates tags to be excluded (eg. '-comment'), +or a trailing '#' causes the ValueConv value to be copied (same as setting +the Type option to 'ValueConv' for this tag only). Wildcards ('*' and '?') +may be used in the tag name. A tag name of '*' is commonly used when a +group is specified to copy all tags in the group (eg. 'XMP:*'). A special +feature allows tag names of the form 'DSTTAGE<lt>SRCTAG' (or +'SRCTAGE<gt>DSTTAG') to be specified to copy information to a tag with a +different name or a specified group. Both 'SRCTAG' and 'DSTTAG' may contain +wildcards and/or be prefixed by a group name (eg. +'fileModifyDateE<lt>modifyDate' or 'xmp:*E<lt>*'), and/or suffixed by a '#' +to disable print conversion. Copied tags may also be added or deleted from +a list with arguments of the form 'DSTTAG+E<lt>SRCTAG' or +'DSTTAG-E<lt>SRCTAG'. Tags are evaluated in order, so exclusions apply only +to tags included earlier in the list. An extension of this feature allows +the tag value to be set from a string containing tag names with leading '$' +symbols (eg. 'CommentE<lt>the file is $filename'). Braces '{}' may be used +around the tag name to separate it from subsequent text, and a '$$' is used +to to represent a '$' symbol. The behaviour for missing tags in expressions +is defined by the L</MissingTagValue> option. The tag value may be modified +via changes to the default input variable ($_) in a Perl expression placed +inside the braces and after a semicolon following the tag name (see the last +example above). A '@' may be added after the tag name (before the +semicolon) to make the expression act on individual list items instead of +the concatenated string for list-type tags. Braces within the expression +must be balanced. Multiple options hash references may be passed to set +different options for different tags. Options apply to subsequent tags in +the argument list. By default, this routine will commute information between same-named tags in different groups, allowing information to be translated between images with @@ -2072,6 +2079,14 @@ Family 6 is currently used only for EXIF/TIFF metadata, and gives the format type of the extracted value. Generated only if the L</SaveFormat> option is used when extracting. +Family 7 is used for tag ID's. The group names are "ID-" followed by the +tag ID with characters other than [-_A-Za-z0-9] converted to hex. Numerical +tag ID's are given in hex if the L</HexTagIDs> option is set. When +specifying a family 7 group name, numerical ID's may be in hex or decimal, +and non-numercal ID's may or may not have characters other than +[-_A-Za-z0-9] converted to hex. Note that unlike other group names, family +7 group names are case sensitive (except for the leading "ID-"). + See L</GetAllGroups [static]> for complete lists of group names. =back @@ -2314,6 +2329,12 @@ eg. JPEG-APP1-IFD0-ExifIFD int8u, string, int16u, int32u, rational64u, int8s, undef, int16s, int32s, rational64s, float, double, ifd, unicode, complex, int64u, int64s, ifd64 +=item Family 7 (Tag ID): + +ID-xxx (where xxx is the tag ID. Numerical ID's are given in hex with a +leading "0x" if the HexTagIDs option is set, as are characters in +non-numerical ID's which are not valid in a group name) + =back =head2 GetDeleteGroups [static] diff --git a/lib/Image/ExifTool/BuildTagLookup.pm b/lib/Image/ExifTool/BuildTagLookup.pm index 50825002..b661d7b9 100644 --- a/lib/Image/ExifTool/BuildTagLookup.pm +++ b/lib/Image/ExifTool/BuildTagLookup.pm @@ -35,7 +35,7 @@ use Image::ExifTool::Sony; use Image::ExifTool::Validate; use Image::ExifTool::MacOS; -$VERSION = '3.36'; +$VERSION = '3.37'; @ISA = qw(Exporter); sub NumbersFirst($$); @@ -877,6 +877,11 @@ TagID: foreach $tagID (@keys) { $case{$lc} = $name; } my $format = $$tagInfo{Format}; + # check TagID's to make sure they don't start with 'ID-' + my @grps = $et->GetGroup($tagInfo); + foreach (@grps) { + warn "Group name starts with 'ID-' for $short $name\n" if /^ID-/i; + } # validate Name (must not start with a digit or else XML output will not be valid; # must not start with a dash or exiftool command line may get confused) if ($name !~ /^[_A-Za-z][-\w]+$/ and diff --git a/lib/Image/ExifTool/Panasonic.pm b/lib/Image/ExifTool/Panasonic.pm index e8671dee..82ecee7c 100644 --- a/lib/Image/ExifTool/Panasonic.pm +++ b/lib/Image/ExifTool/Panasonic.pm @@ -37,7 +37,7 @@ use vars qw($VERSION %leicaLensTypes); use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::Exif; -$VERSION = '2.10'; +$VERSION = '2.11'; sub ProcessLeicaLEIC($$$); sub WhiteBalanceConv($;$$); @@ -745,7 +745,7 @@ my %shootingMode = ( 3 => 'Low', 4 => 'Near Empty', 7 => 'Near Full', - 8 => 'Medimu Low', + 8 => 'Medium Low', 256 => 'n/a', }, }, diff --git a/lib/Image/ExifTool/Pentax.pm b/lib/Image/ExifTool/Pentax.pm index 5fdd6b77..e23b8ddb 100644 --- a/lib/Image/ExifTool/Pentax.pm +++ b/lib/Image/ExifTool/Pentax.pm @@ -58,7 +58,7 @@ use Image::ExifTool::Exif; use Image::ExifTool::GPS; use Image::ExifTool::HP; -$VERSION = '3.33'; +$VERSION = '3.34'; sub CryptShutterCount($$); sub PrintFilter($$$); @@ -338,7 +338,7 @@ sub DecodeAFPoints($$$$;$); '8 63' => 'HD PENTAX-D FA 15-30mm F2.8 ED SDM WR', #PH '8 64' => 'HD PENTAX-D FA* 50mm F1.4 SDM AW', #27 '8 65' => 'HD PENTAX-D FA 70-210mm F4 ED SDM WR', #PH - '8 66' => 'HD PEBTAX-D FA 85mm F1.4 ED SDM AW', #James O'Neill + '8 66' => 'HD PENTAX-D FA 85mm F1.4 ED SDM AW', #James O'Neill '8 196' => 'HD PENTAX-DA* 11-18mm F2.8 ED DC AW', #29 '8 197' => 'HD PENTAX-DA 55-300mm F4.5-6.3 ED PLM WR RE', #29 '8 198' => 'smc PENTAX-DA L 18-50mm F4-5.6 DC WR RE', #29 diff --git a/lib/Image/ExifTool/TagLookup.pm b/lib/Image/ExifTool/TagLookup.pm index eff43338..b7513fb5 100644 --- a/lib/Image/ExifTool/TagLookup.pm +++ b/lib/Image/ExifTool/TagLookup.pm @@ -2523,7 +2523,7 @@ my %tagLookup = ( 'filemodifydate' => { 117 => 'FileModifyDate' }, 'filename' => { 117 => 'FileName' }, 'filenameasdelivered' => { 293 => 'FileNameAsDelivered' }, - 'filenumber' => { 55 => 0x1, 61 => 0x8, 94 => 0x1817, 111 => 'Canon::FileNumber', 202 => 0x4, 369 => 0x10 }, + 'filenumber' => { 55 => 0x1, 61 => 0x8, 94 => 0x1817, 111 => 'Canon-FileNumber', 202 => 0x4, 369 => 0x10 }, 'filenumbermemory' => { 176 => 0x1a }, 'filenumbersequence' => { 266 => '12.2', 271 => '3.1', 272 => '4.1', 273 => '4.1', 275 => '11.1', 276 => '4.3', 281 => '5.2' }, 'filepermissions' => { 117 => 'FilePermissions' }, @@ -2571,7 +2571,7 @@ my %tagLookup = ( 'firstphotodate' => { 450 => 'FirstPhotoDate' }, 'firstpublicationdate' => { 293 => 'FirstPublicationDate' }, 'fixtureidentifier' => { 128 => 0x16, 457 => 'FixtureIdentifier' }, - 'flash' => { 111 => 'XMP::Flash', 116 => 0x9209, 148 => 0x22, 177 => 0x1f, 178 => 0x15, 369 => 0x5a, 468 => 'Flash' }, + 'flash' => { 111 => 'XMP-Flash', 116 => 0x9209, 148 => 0x22, 177 => 0x1f, 178 => 0x15, 369 => 0x5a, 468 => 'Flash' }, 'flashaction' => { 393 => 0x3e, 394 => 0x3e, 406 => 0x2017, 411 => [0x2a,0x2c,0x30] }, 'flashaction2' => { 393 => 0x4c, 394 => 0x4c, 411 => 0x77 }, 'flashactionexternal' => { 411 => [0x78,0x7c] }, @@ -3322,7 +3322,7 @@ my %tagLookup = ( 'jpegquality' => { 10 => 0x66, 306 => 0x43, 308 => 0x3034, 406 => 0xb047 }, 'jpegsize' => { 308 => 0x303a }, 'jpgcompression' => { 238 => 0x7d4 }, - 'jpgfromraw' => { 94 => 0x2007, 111 => 'Exif::JpgFromRaw', 311 => 0x2e }, + 'jpgfromraw' => { 94 => 0x2007, 111 => 'Exif-JpgFromRaw', 311 => 0x2e }, 'jpgfromrawlength' => { 116 => [0x117,0x202] }, 'jpgfromrawstart' => { 116 => [0x111,0x201] }, 'jpgrecordedpixels' => { 322 => '14.1' }, @@ -4227,7 +4227,7 @@ my %tagLookup = ( 'originalartist' => { 360 => "\xa9ope" }, 'originalbestqualitysize' => { 116 => 0xc792 }, 'originalcreatedatetime' => { 452 => 'OriginalCreateDateTime' }, - 'originaldecisiondata' => { 111 => 'Canon::OriginalDecisionData' }, + 'originaldecisiondata' => { 111 => 'Canon-OriginalDecisionData' }, 'originaldecisiondataoffset' => { 61 => 0x83 }, 'originaldefaultcropsize' => { 116 => 0xc793 }, 'originaldefaultfinalsize' => { 116 => 0xc791 }, @@ -4245,7 +4245,7 @@ my %tagLookup = ( 'os' => { 466 => 'os' }, 'otherconditions' => { 293 => 'OtherConditions' }, 'otherconstraints' => { 293 => 'OtherConstraints' }, - 'otherimage' => { 111 => 'Exif::OtherImage' }, + 'otherimage' => { 111 => 'Exif-OtherImage' }, 'otherimageinfo' => { 293 => 'OtherImageInfo' }, 'otherimagelength' => { 116 => 0x202 }, 'otherimagestart' => { 116 => 0x201 }, @@ -4669,7 +4669,7 @@ my %tagLookup = ( 'previewcroptop' => { 352 => 0xed }, 'previewdate' => { 364 => 0x0 }, 'previewdatetime' => { 116 => 0xc71b }, - 'previewimage' => { 110 => 0x2000, 111 => 'Exif::PreviewImage', 117 => 'PreviewImage', 119 => 0x4, 162 => 'data', 181 => 0x81, 288 => 0x280, 304 => 0x300, 406 => 0x2001 }, + 'previewimage' => { 110 => 0x2000, 111 => 'Exif-PreviewImage', 117 => 'PreviewImage', 119 => 0x4, 162 => 'data', 181 => 0x81, 288 => 0x280, 304 => 0x300, 406 => 0x2001 }, 'previewimageborders' => { 341 => 0x3e }, 'previewimageheight' => { 70 => 0x4, 138 => 0xfa58 }, 'previewimagelength' => { 70 => 0x2, 110 => 0x3, 116 => [0x117,0x202], 181 => 0x89, 224 => 0x202, 283 => 0x102, 288 => 0x1037, 341 => 0x3, 372 => 0x1e, 377 => 0x3, 383 => [0x1b,0x1d], 396 => 0x202 }, @@ -5096,7 +5096,7 @@ my %tagLookup = ( 'roll' => { 112 => 0x8, 366 => ['roll',"\xa9frl"] }, 'rollangle' => { 237 => 0x350b, 238 => 0x2c24, 246 => 0x36f4, 247 => 0x2efb, 283 => 0x903, 306 => 0x90, 340 => 0x1, 378 => 0x2 }, 'romoperationmode' => { 94 => 0x80d }, - 'rotation' => { 30 => 0x17, 31 => 0x18, 93 => 0x3, 100 => 0x10002, 105 => 0x26e, 111 => 'QuickTime::Rotation', 120 => 0x4, 161 => 'Rotation', 177 => [0x65,0x50], 178 => 0x46, 179 => 0x5a, 182 => 0x10, 237 => 0x3693, 238 => 0xca, 244 => '590.1', 259 => 0x76a43207, 306 => 0x30, 322 => '17.2', 352 => 0xd8, 359 => 'irot', 393 => 0x3f, 394 => 0x3f, 404 => 0x10 }, + 'rotation' => { 30 => 0x17, 31 => 0x18, 93 => 0x3, 100 => 0x10002, 105 => 0x26e, 111 => 'QuickTime-Rotation', 120 => 0x4, 161 => 'Rotation', 177 => [0x65,0x50], 178 => 0x46, 179 => 0x5a, 182 => 0x10, 237 => 0x3693, 238 => 0xca, 244 => '590.1', 259 => 0x76a43207, 306 => 0x30, 322 => '17.2', 352 => 0xd8, 359 => 'irot', 393 => 0x3f, 394 => 0x3f, 404 => 0x10 }, 'routedto' => { 470 => 'RoutedTo' }, 'routing' => { 357 => 'Routing' }, 'routingdestinations' => { 452 => 'RoutingDestinations' }, @@ -5507,9 +5507,9 @@ my %tagLookup = ( 'sublabels3' => { 472 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabels'] }, 'sublabels4' => { 472 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabels'] }, 'sublabels5' => { 472 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabels'] }, - 'subseccreatedate' => { 111 => 'Exif::SubSecCreateDate' }, - 'subsecdatetimeoriginal' => { 111 => 'Exif::SubSecDateTimeOriginal' }, - 'subsecmodifydate' => { 111 => 'Exif::SubSecModifyDate' }, + 'subseccreatedate' => { 111 => 'Exif-SubSecCreateDate' }, + 'subsecdatetimeoriginal' => { 111 => 'Exif-SubSecDateTimeOriginal' }, + 'subsecmodifydate' => { 111 => 'Exif-SubSecModifyDate' }, 'subsectime' => { 116 => 0x9290 }, 'subsectimedigitized' => { 116 => 0x9292 }, 'subsectimeoriginal' => { 116 => 0x9291 }, @@ -5653,7 +5653,7 @@ my %tagLookup = ( 'thumbnailfilename' => { 94 => 0x817 }, 'thumbnailformat' => { 486 => [\'Thumbnails','ThumbnailsFormat'] }, 'thumbnailheight' => { 138 => 0xfa55, 486 => [\'Thumbnails','ThumbnailsHeight'] }, - 'thumbnailimage' => { 6 => 'CNDA', 94 => 0x2008, 111 => 'Exif::ThumbnailImage', 119 => 0x3, 163 => 'data', 288 => 0x100, 366 => 'thmb', 486 => [\'Thumbnails','ThumbnailsImage'] }, + 'thumbnailimage' => { 6 => 'CNDA', 94 => 0x2008, 111 => 'Exif-ThumbnailImage', 119 => 0x3, 163 => 'data', 288 => 0x100, 366 => 'thmb', 486 => [\'Thumbnails','ThumbnailsImage'] }, 'thumbnailimagename' => { 163 => '1Name' }, 'thumbnailimagesize' => { 163 => 'ImageSize' }, 'thumbnailimagetype' => { 163 => '0Type' }, diff --git a/lib/Image/ExifTool/Writer.pl b/lib/Image/ExifTool/Writer.pl index 907076c4..b22e814a 100644 --- a/lib/Image/ExifTool/Writer.pl +++ b/lib/Image/ExifTool/Writer.pl @@ -370,9 +370,9 @@ sub SetNewValue($;$$%) my $lcg = lc $g; # save group/family unless '*' or 'all' push @wantGroup, [ $f, $lcg ] unless $lcg eq '*' or $lcg eq 'all'; - if ($g =~ /^ID_(.*)/i) { # family 7 is this is a tag ID + if ($g =~ s/^ID-//i) { # family 7 is a tag ID return 0 if defined $f and $f ne 7; - $wantGroup[-1] = [ 7, "ID_$1" ]; # case is significant for tag ID's + $wantGroup[-1] = [ 7, $g ]; # group name with 'ID-' removed and case preserved } elsif (defined $f) { $f > 2 and return 0; # only allow family 0, 1 or 2 $family2 = 1 if $f == 2; # set flag indicating family 2 was used @@ -627,15 +627,7 @@ TAG: foreach $tagInfo (@matchingTags) { } next if $lcWant eq lc $grp[2]; } elsif ($fam == 7) { - my $idGrp; - if ($$self{OPTIONS}{HexIDGroup} and $$tagInfo{TagID} =~ /^\d+$/) { - $idGrp = 'ID_' . sprintf('0x%x', $$tagInfo{TagID}); - } else { - $idGrp = 'ID_' . $$tagInfo{TagID}; - } - next if $lcWant eq $idGrp; # also allow raw tag ID - $idGrp =~ s/([^-_A-Za-z0-9])/sprintf('%.2x',ord $1)/ge; - next if $lcWant eq $idGrp; # plain ASCII tag ID group name + next if IsSameID($$tagInfo{TagID}, $lcWant); } elsif ($fam != 1 and not $$tagInfo{AllowGroup}) { next if $lcWant eq lc $grp[$fam]; if ($wgAll and not $fam and $allFam0{$lcWant}) { @@ -1272,6 +1264,7 @@ sub SetNewValuesFromFile($$;@) Filter => $$options{Filter}, FixBase => $$options{FixBase}, GlobalTimeShift => $$options{GlobalTimeShift}, + HexTagIDs => $$options{HexTagIDs}, IgnoreMinorErrors=>$$options{IgnoreMinorErrors}, Lang => $$options{Lang}, LargeFileSupport=> $$options{LargeFileSupport}, @@ -1423,7 +1416,9 @@ sub SetNewValuesFromFile($$;@) foreach (split /:/, $grp) { # save family/groups in list (ignoring 'all' and '*') next unless length($_) and /^(\d+)?(.*)/; - push @fg, [ $1, $2 ] unless $2 eq '*' or $2 eq 'all'; + my ($f, $g) = ($1, $2); + $f = 7 if $g =~ s/^ID-//i; + push @fg, [ $f, $g ] unless $g eq '*' or $g eq 'all'; } } # allow ValueConv to be specified by a '#' on the tag name @@ -1489,10 +1484,12 @@ SET: foreach $set (@setList) { } foreach (@{$$set[0]}) { my ($f, $g) = @$_; - if (defined $f) { - next SET unless defined $grp[$f] and $g eq $grp[$f]; - } else { + if (not defined $f) { next SET unless $grp{$g}; + } elsif ($f == 7) { + next SET unless IsSameID($srcExifTool->GetTagID($tag), $g); + } else { + next SET unless defined $grp[$f] and $g eq $grp[$f]; } } } @@ -1612,21 +1609,25 @@ sub GetNewValue($$;$) $nvHash = $self->GetNewValueHash($tagInfo); } else { # separate group from tag name - $group = $1 if $tag =~ s/(.*)://; + my @groups; + @groups = split ':', $1 if $tag =~ s/(.*)://; my @tagInfoList = FindTagInfo($tag); # decide which tag we want GNV_TagInfo: foreach $tagInfo (@tagInfoList) { my $nvh = $self->GetNewValueHash($tagInfo) or next; - # select tag in specified group if necessary - while ($group and $group ne $$nvh{WriteGroup}) { + # select tag in specified group(s) if necessary + foreach (@groups) { + next if $_ eq $$nvh{WriteGroup}; my @grps = $self->GetGroup($tagInfo); if ($grps[0] eq $$nvh{WriteGroup}) { # check family 1 group only if WriteGroup is not specific - last if $group eq $grps[1]; + next if $_ eq $grps[1]; } else { # otherwise check family 0 group - last if $group eq $grps[0]; + next if $_ eq $grps[0]; } + # also check family 7 + next if /^ID-(.*)/i and IsSameID($$tagInfo{TagID}, $1); # step to next entry in list $nvh = $$nvh{Next} or next GNV_TagInfo; } |