Skip to content

Commit

Permalink
Upgrading to exiftool v12.86
Browse files Browse the repository at this point in the history
  • Loading branch information
morozgrafix committed Jun 10, 2024
1 parent 2128920 commit 31cab57
Show file tree
Hide file tree
Showing 20 changed files with 252 additions and 150 deletions.
11 changes: 11 additions & 0 deletions bin/Changes
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ RSS feed: https://exiftool.org/rss.xml
Note: The most recent production release is Version 12.76. (Other versions are
considered development releases, and are not uploaded to MetaCPAN.)

June 7, 2024 - Version 12.86

- Added a new value for a couple of Olympus tags (thanks Herb)
- Improved handling of ID3 user-defined tags
- Decode all JPEG segments from RICO box in Ricoh MOV videos
- Decode a few new values for some tags written by Canon EOS R cameras
- Patched some Olympus WB_RBLevels tags to allow 4 values to be written as per
some newer models
- Fixed issue when writing IPTC date tags with a date/time value containing
subseconds with 4 or more digits

May 21, 2024 - Version 12.85

- Added GeolocationFeatureType tag
Expand Down
2 changes: 1 addition & 1 deletion bin/META.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,5 @@
}
},
"release_status" : "stable",
"version" : "12.85"
"version" : "12.86"
}
2 changes: 1 addition & 1 deletion bin/META.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ recommends:
Time::HiRes: 0
requires:
perl: 5.004
version: 12.85
version: 12.86
4 changes: 2 additions & 2 deletions bin/README
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ your home directory, then you would type the following commands in a
terminal window to extract and run ExifTool:

cd ~/Desktop
gzip -dc Image-ExifTool-12.85.tar.gz | tar -xf -
cd Image-ExifTool-12.85
gzip -dc Image-ExifTool-12.86.tar.gz | tar -xf -
cd Image-ExifTool-12.86
./exiftool t/images/ExifTool.jpg

Note: These commands extract meta information from one of the test images.
Expand Down
5 changes: 5 additions & 0 deletions bin/config_files/example.config
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,11 @@
NewXMPxxxStructX => { Name => 'SomeOtherName', Flat => 1 },
);

# the namespace may be registered so ExifTool generates the expected family 1
# group names when reading if the UserDefined namespace uses a different prefix
require Image::ExifTool::XMP;
Image::ExifTool::XMP::RegisterNamespace(\%Image::ExifTool::UserDefined::xxx);

# Adding a new MIE group requires a few extra definitions
use Image::ExifTool::MIE;
%Image::ExifTool::UserDefined::MIETest = (
Expand Down
4 changes: 2 additions & 2 deletions bin/exiftool
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use strict;
use warnings;
require 5.004;

my $version = '12.85';
my $version = '12.86';

# add our 'lib' directory to the include list BEFORE 'use Image::ExifTool'
my $exePath;
Expand Down Expand Up @@ -5678,7 +5678,7 @@ with this command:
produces output like this:
-- Generated by ExifTool 12.85 --
-- Generated by ExifTool 12.86 --
File: a.jpg - 2003:10:31 15:44:19
(f/5.6, 1/60s, ISO 100)
File: b.jpg - 2006:05:23 11:57:38
Expand Down
71 changes: 44 additions & 27 deletions bin/lib/Image/ExifTool.pm
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes
%jpegMarker %specialTags %fileTypeLookup $testLen $exeDir
%static_vars $advFmtSelf);

$VERSION = '12.85';
$VERSION = '12.86';
$RELEASE = '';
@ISA = qw(Exporter);
%EXPORT_TAGS = (
Expand Down Expand Up @@ -6859,32 +6859,42 @@ sub DirStart($$;$)
#------------------------------------------------------------------------------
# Extract metadata from a jpg image
# Inputs: 0) ExifTool object reference, 1) dirInfo ref with RAF set
# 2) tag table ref to process JPEG-like metadata
# Returns: 1 on success, 0 if this wasn't a valid JPEG file
sub ProcessJPEG($$)
sub ProcessJPEG($$;$)
{
local $_;
my ($self, $dirInfo) = @_;
my ($self, $dirInfo, $optionalTagTable) = @_;
my $options = $$self{OPTIONS};
my $verbose = $$options{Verbose};
my $out = $$options{TextOut};
my $fast = $$options{FastScan} || 0;
my $raf = $$dirInfo{RAF};
my $req = $$self{REQ_TAG_LOOKUP};
my $htmlDump = $$self{HTML_DUMP};
my %dumpParms = ( Out => $out );
my ($ch, $s, $length, $hash, $hashsize);
my %dumpParms = ( Out => $out, Prefix => $$self{INDENT} );
my ($ch, $s, $length, $hash, $hashsize, $indent);
my ($success, $wantTrailer, $trailInfo, $foundSOS, $gotSize, %jumbfChunk);
my (@iccChunk, $iccChunkCount, $iccChunksTotal, @flirChunk, $flirCount, $flirTotal);
my ($preview, $scalado, @dqt, $subSampling, $dumpEnd, %extendedXMP);

($indent = $$self{INDENT}) =~ s/ $//;
unless ($raf) {
$raf = File::RandomAccess->new($$dirInfo{DataPt});
$self->VerboseDir('JPEG', undef, length(${$$dirInfo{DataPt}}));
}
# get pointer to hash object if it exists and we are the top-level JPEG or JP2
if ($$self{FILE_TYPE} =~ /^(JPEG|JP2)$/ and not $$self{DOC_NUM}) {
$hash = $$self{ImageDataHash};
$hashsize = 0;
}

# check to be sure this is a valid JPG (or J2C, or EXV) file
return 0 unless $raf->Read($s, 2) == 2 and $s =~ /^\xff[\xd8\x4f\x01]/;
if ($raf->Read($s, 2) == 2 and $s =~ /^\xff[\xd8\x4f\x01]/) {
undef $optionalTagTable;
} else {
return 0 unless $optionalTagTable and $s =~ /^\xff[\xe0-\xef]/;
$raf->Seek(-2, 1) or $self->Error('Seek error'), return 1;
}
if ($s eq "\xff\x01") {
return 0 unless $raf->Read($s, 5) == 5 and $s eq 'Exiv2';
$$self{FILE_TYPE} = 'EXV';
Expand All @@ -6902,7 +6912,7 @@ sub ProcessJPEG($$)
$$raf{NoBuffer} = 1 if $self->Options('FastScan'); # disable buffering in FastScan mode

$dumpParms{MaxLen} = 128 if $verbose < 4;
if ($htmlDump) {
if ($htmlDump and not $optionalTagTable) {
$dumpEnd = $raf->Tell();
my ($n, $t, $m) = $s eq 'Exiv2' ? (7,'EXV','TEM') : (2,'JPEG','SOI');
my $pos = $dumpEnd - $n;
Expand All @@ -6921,6 +6931,7 @@ sub ProcessJPEG($$)
Marker: for (;;) {
# set marker and data pointer for current segment
my $marker = $nextMarker;
last if $marker and $marker < 0;
my $segDataPt = $nextSegDataPt;
my $segPos = $nextSegPos;
my $skipped;
Expand All @@ -6929,12 +6940,17 @@ sub ProcessJPEG($$)
#
# read ahead to the next segment unless we have reached EOI, SOS or SOD
#
unless ($marker and ($marker==0xd9 or ($marker==0xda and not $wantTrailer and not $hash) or
until ($marker and ($marker==0xd9 or ($marker==0xda and not $wantTrailer and not $hash) or
$marker==0x93))
{
# read up to next marker (JPEG markers begin with 0xff)
my $buff;
$raf->ReadLine($buff) or last;
unless ($raf->ReadLine($buff)) {
last Marker unless $optionalTagTable;
$nextMarker = -1;
$success = 1;
last;
}
$skipped = length($buff) - 1;
# JPEG markers can be padded with unlimited 0xff's
for (;;) {
Expand All @@ -6946,21 +6962,21 @@ sub ProcessJPEG($$)
# read segment data if it exists
if (not defined $markerLenBytes{$nextMarker}) {
# read record length word
last unless $raf->Read($s, 2) == 2;
last Marker unless $raf->Read($s, 2) == 2;
my $len = unpack('n',$s); # get data length
last unless defined($len) and $len >= 2;
last Marker unless defined($len) and $len >= 2;
$nextSegPos = $raf->Tell();
$len -= 2; # subtract size of length word
last unless $raf->Read($buff, $len) == $len;
last Marker unless $raf->Read($buff, $len) == $len;
$nextSegDataPt = \$buff; # set pointer to our next data
} elsif ($markerLenBytes{$nextMarker} == 4) {
# handle J2C extensions with 4-byte length word
last unless $raf->Read($s, 4) == 4;
last Marker unless $raf->Read($s, 4) == 4;
my $len = unpack('N',$s); # get data length
last unless defined($len) and $len >= 4;
last Marker unless defined($len) and $len >= 4;
$nextSegPos = $raf->Tell();
$len -= 4; # subtract size of length word
last unless $raf->Seek($len, 1);
last Marker unless $raf->Seek($len, 1);
} elsif ($hash and defined $marker and ($marker == 0x00 or $marker == 0xda or
($marker >= 0xd0 and $marker <= 0xd7)))
{
Expand All @@ -6976,7 +6992,8 @@ sub ProcessJPEG($$)
$hashsize += $skipped + 2;
}
# read second segment too if this was the first
next unless defined $marker;
next Marker unless defined $marker;
last;
}
# set some useful variables for the current segment
my $markerName = JpegMarkerName($marker);
Expand All @@ -6996,7 +7013,7 @@ sub ProcessJPEG($$)
if (($marker & 0xf0) == 0xc0 and ($marker == 0xc0 or $marker & 0x03)) {
$length = length $$segDataPt;
if ($verbose) {
print $out "JPEG $markerName ($length bytes):\n";
print $out "${indent}JPEG $markerName ($length bytes):\n";
HexDump($segDataPt, undef, %dumpParms, Addr=>$segPos) if $verbose>2;
} elsif ($htmlDump) {
$self->HDump($segPos-4, $length+4, "[JPEG $markerName]", undef, 0x08);
Expand Down Expand Up @@ -7039,7 +7056,7 @@ sub ProcessJPEG($$)
next;
} elsif ($marker == 0xd9) { # EOI
pop @$path;
$verbose and print $out "JPEG EOI\n";
$verbose and print $out "${indent}JPEG EOI\n";
my $pos = $raf->Tell();
$$self{TrailerStart} = $pos unless $$self{DOC_NUM};
if ($htmlDump and $dumpEnd) {
Expand Down Expand Up @@ -7100,7 +7117,7 @@ sub ProcessJPEG($$)
# adjust PreviewImageStart to this location
my $actual = $pos + pos($buff) - 4;
if ($start and $start ne $actual and $verbose > 1) {
print $out "(Fixed PreviewImage location: $start -> $actual)\n";
print $out "${indent}(Fixed PreviewImage location: $start -> $actual)\n";
}
# update preview image offsets
if ($start) {
Expand Down Expand Up @@ -7154,7 +7171,7 @@ sub ProcessJPEG($$)
pop @$path;
$foundSOS = 1;
# all done with meta information unless we have a trailer
$verbose and print $out "JPEG SOS\n";
$verbose and print $out "${indent}JPEG SOS\n";
unless ($fast) {
$trailInfo = IdentifyTrailer($raf);
# process trailer now unless we are doing verbose dump
Expand Down Expand Up @@ -7194,7 +7211,7 @@ sub ProcessJPEG($$)
last; # all done parsing file
} elsif ($marker == 0x93) {
pop @$path;
$verbose and print $out "JPEG SOD\n";
$verbose and print $out "${indent}JPEG SOD\n";
$success = 1;
if ($hash and $$self{FILE_TYPE} eq 'JP2') {
my $pos = $raf->Tell();
Expand All @@ -7205,7 +7222,7 @@ sub ProcessJPEG($$)
last; # all done parsing file
} elsif (defined $markerLenBytes{$marker}) {
# handle other stand-alone markers and segments we skipped over
$verbose and $marker and print $out "JPEG $markerName\n";
$verbose and $marker and print $out "${indent}JPEG $markerName\n";
next;
} elsif ($marker == 0xdb and length($$segDataPt) and # DQT
# save the DQT data only if JPEGDigest has been requested
Expand All @@ -7225,7 +7242,7 @@ sub ProcessJPEG($$)
$length = length $$segDataPt;
$appBytes += $length + 4 if ($marker & 0xf0) == 0xe0; # total size of APP segments
if ($verbose) {
print $out "JPEG $markerName ($length bytes):\n";
print $out "${indent}JPEG $markerName ($length bytes):\n";
if ($verbose > 2) {
my %extraParms = ( Addr => $segPos );
$extraParms{MaxLen} = 128 if $verbose == 4;
Expand Down Expand Up @@ -7383,7 +7400,7 @@ sub ProcessJPEG($$)
# some software erroneously writes zeros for the chunk counts)
my $chunkNum = Get8u($segDataPt, 6);
my $chunksTot = Get8u($segDataPt, 7) + 1; # (note the "+ 1"!)
$verbose and printf $out "$$self{INDENT}FLIR chunk %d of %d\n",
$verbose and printf $out "${indent}FLIR chunk %d of %d\n",
$chunkNum + 1, $chunksTot;
if (defined $flirTotal) {
# abort parsing FLIR if the total chunk count is inconsistent
Expand Down Expand Up @@ -7448,7 +7465,7 @@ sub ProcessJPEG($$)
# some software erroneously writes zeros for the chunk counts)
my $chunkNum = Get8u($segDataPt, 12);
my $chunksTot = Get8u($segDataPt, 13);
$verbose and print $out "$$self{INDENT}ICC_Profile chunk $chunkNum of $chunksTot\n";
$verbose and print $out "${indent}ICC_Profile chunk $chunkNum of $chunksTot\n";
if (defined $iccChunksTotal) {
# abort parsing ICC_Profile if the total chunk count is inconsistent
undef $iccChunkCount if $chunksTot != $iccChunksTotal;
Expand Down Expand Up @@ -8001,7 +8018,7 @@ sub ProcessJPEG($$)
}
}
# print verbose hash message if necessary
print $out "$$self{INDENT}(ImageDataHash: $hashsize bytes of JPEG image data)\n" if $hashsize and $verbose;
print $out "${indent}(ImageDataHash: $hashsize bytes of JPEG image data)\n" if $hashsize and $verbose;
# calculate JPEGDigest if requested
if (@dqt) {
require Image::ExifTool::JPEGDigest;
Expand Down
27 changes: 13 additions & 14 deletions bin/lib/Image/ExifTool.pod
Original file line number Diff line number Diff line change
Expand Up @@ -2540,20 +2540,19 @@ RIFF, RMETA, RSRC, RTF, Radiance, Rawzor, Real, Real-CONT, Real-MDPR,
Real-PROP, Real-RA3, Real-RA4, Real-RA5, Real-RJMD, Reconyx, Red, Ricoh,
SPIFF, SR2, SR2DataIFD, SR2SubIFD, SRF#, SVG, Samsung, Sanyo, Scalado,
Sigma, SigmaRaw, Sony, SonyIDC, Stim, SubIFD, System, Theora, Torrent,
Track#, UserData, UserDefined, VCalendar, VCard, VNote, Version0, Vorbis,
WTV, XML, XMP, XMP-DICOM, XMP-Device, XMP-GAudio, XMP-GCamera,
XMP-GCreations, XMP-GDepth, XMP-GFocus, XMP-GImage, XMP-GPano,
XMP-GSpherical, XMP-LImage, XMP-MP, XMP-MP1, XMP-PixelLive, XMP-aas,
XMP-acdsee, XMP-album, XMP-apple-fi, XMP-ast, XMP-aux, XMP-cc, XMP-cell,
XMP-crd, XMP-creatorAtom, XMP-crs, XMP-dc, XMP-dex, XMP-digiKam,
XMP-drone-dji, XMP-dwc, XMP-et, XMP-exif, XMP-exifEX, XMP-expressionmedia,
XMP-extensis, XMP-fpv, XMP-getty, XMP-hdr, XMP-hdrgm, XMP-ics, XMP-iptcCore,
XMP-iptcExt, XMP-lr, XMP-mediapro, XMP-microsoft, XMP-mwg-coll, XMP-mwg-kw,
XMP-mwg-rs, XMP-nine, XMP-panorama, XMP-pdf, XMP-pdfx, XMP-photomech,
XMP-photoshop, XMP-plus, XMP-pmi, XMP-prism, XMP-prl, XMP-prm, XMP-pur,
XMP-rdf, XMP-sdc, XMP-swf, XMP-tiff, XMP-x, XMP-xmp, XMP-xmpBJ, XMP-xmpDM,
XMP-xmpDSA, XMP-xmpMM, XMP-xmpNote, XMP-xmpPLUS, XMP-xmpRights, XMP-xmpTPg,
ZIP, iTunes
Track#, UserData, VCalendar, VCard, VNote, Version0, Vorbis, WTV, XML, XMP,
XMP-DICOM, XMP-Device, XMP-GAudio, XMP-GCamera, XMP-GCreations, XMP-GDepth,
XMP-GFocus, XMP-GImage, XMP-GPano, XMP-GSpherical, XMP-LImage, XMP-MP,
XMP-MP1, XMP-PixelLive, XMP-aas, XMP-acdsee, XMP-album, XMP-apple-fi,
XMP-ast, XMP-aux, XMP-cc, XMP-cell, XMP-crd, XMP-creatorAtom, XMP-crs,
XMP-dc, XMP-dex, XMP-digiKam, XMP-drone-dji, XMP-dwc, XMP-et, XMP-exif,
XMP-exifEX, XMP-expressionmedia, XMP-extensis, XMP-fpv, XMP-getty, XMP-hdr,
XMP-hdrgm, XMP-ics, XMP-iptcCore, XMP-iptcExt, XMP-lr, XMP-mediapro,
XMP-microsoft, XMP-mwg-coll, XMP-mwg-kw, XMP-mwg-rs, XMP-nine, XMP-panorama,
XMP-pdf, XMP-pdfx, XMP-photomech, XMP-photoshop, XMP-plus, XMP-pmi,
XMP-prism, XMP-prl, XMP-prm, XMP-pur, XMP-rdf, XMP-sdc, XMP-swf, XMP-tiff,
XMP-x, XMP-xmp, XMP-xmpBJ, XMP-xmpDM, XMP-xmpDSA, XMP-xmpMM, XMP-xmpNote,
XMP-xmpPLUS, XMP-xmpRights, XMP-xmpTPg, ZIP, iTunes

=item Family 2 (Category):

Expand Down
5 changes: 3 additions & 2 deletions bin/lib/Image/ExifTool/BuildTagLookup.pm
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use Image::ExifTool::Sony;
use Image::ExifTool::Validate;
use Image::ExifTool::MacOS;

$VERSION = '3.56';
$VERSION = '3.57';
@ISA = qw(Exporter);

sub NumbersFirst($$);
Expand Down Expand Up @@ -600,7 +600,8 @@ running ExifTool the old information may be removed permanently using the
DNG => q{
The main DNG tags are found in the EXIF table. The tables below define only
information found within structures of these main DNG tag values. See
L<http://www.adobe.com/products/dng/> for the official DNG specification.
L<https://helpx.adobe.com/camera-raw/digital-negative.html> for the official
DNG specification.
},
MPEG => q{
The MPEG format doesn't specify any file-level meta information. In lieu of
Expand Down
Loading

0 comments on commit 31cab57

Please sign in to comment.