From c52f69cc0616f67d4a0101ce7033a269f8248188 Mon Sep 17 00:00:00 2001 From: morozgrafix Date: Sun, 8 Sep 2024 19:27:13 -0700 Subject: [PATCH] Upgrading to exiftool v12.96 --- bin/Changes | 6 +++ bin/META.json | 2 +- bin/META.yml | 2 +- bin/README | 4 +- bin/exiftool | 4 +- bin/lib/Image/ExifTool.pm | 2 +- bin/lib/Image/ExifTool/Geotag.pm | 4 +- bin/lib/Image/ExifTool/QuickTime.pm | 34 +++++++----- bin/lib/Image/ExifTool/WriteQuickTime.pl | 69 ++++++++++++------------ bin/perl-Image-ExifTool.spec | 2 +- lib/exiftool_vendored/version.rb | 2 +- 11 files changed, 71 insertions(+), 60 deletions(-) diff --git a/bin/Changes b/bin/Changes index 7cdfff7..1e1e781 100644 --- a/bin/Changes +++ b/bin/Changes @@ -7,6 +7,12 @@ 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.) +Sept. 1, 2024 - Version 12.96 + + - More improvements to handling of trailers on video files (and add ability to + write videos which have an unknown trailer) + - Fixed problem geotagging from some newer Google Takeout files + Aug. 30, 2024 - Version 12.95 - Added a couple of new CanonModelID values diff --git a/bin/META.json b/bin/META.json index 4ee3cd4..82b8a0d 100644 --- a/bin/META.json +++ b/bin/META.json @@ -50,5 +50,5 @@ } }, "release_status" : "stable", - "version" : "12.95" + "version" : "12.96" } diff --git a/bin/META.yml b/bin/META.yml index 5415b36..8e95d09 100644 --- a/bin/META.yml +++ b/bin/META.yml @@ -31,4 +31,4 @@ recommends: Time::HiRes: '0' requires: perl: '5.004' -version: '12.95' +version: '12.96' diff --git a/bin/README b/bin/README index d99cb2a..c0e195c 100644 --- a/bin/README +++ b/bin/README @@ -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.95.tar.gz | tar -xf - - cd Image-ExifTool-12.95 + gzip -dc Image-ExifTool-12.96.tar.gz | tar -xf - + cd Image-ExifTool-12.96 ./exiftool t/images/ExifTool.jpg Note: These commands extract meta information from one of the test images. diff --git a/bin/exiftool b/bin/exiftool index c6d3245..995c8dd 100755 --- a/bin/exiftool +++ b/bin/exiftool @@ -11,7 +11,7 @@ use strict; use warnings; require 5.004; -my $version = '12.95'; +my $version = '12.96'; # add our 'lib' directory to the include list BEFORE 'use Image::ExifTool' my $exePath; @@ -5655,7 +5655,7 @@ with this command: produces output like this: - -- Generated by ExifTool 12.95 -- + -- Generated by ExifTool 12.96 -- 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 diff --git a/bin/lib/Image/ExifTool.pm b/bin/lib/Image/ExifTool.pm index aaf7659..3bac9cb 100644 --- a/bin/lib/Image/ExifTool.pm +++ b/bin/lib/Image/ExifTool.pm @@ -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.95'; +$VERSION = '12.96'; $RELEASE = ''; @ISA = qw(Exporter); %EXPORT_TAGS = ( diff --git a/bin/lib/Image/ExifTool/Geotag.pm b/bin/lib/Image/ExifTool/Geotag.pm index 887e9f5..8b03174 100644 --- a/bin/lib/Image/ExifTool/Geotag.pm +++ b/bin/lib/Image/ExifTool/Geotag.pm @@ -31,7 +31,7 @@ use vars qw($VERSION); use Image::ExifTool qw(:Public); use Image::ExifTool::GPS; -$VERSION = '1.77'; +$VERSION = '1.78'; sub JITTER() { return 2 } # maximum time jitter @@ -323,7 +323,7 @@ sub LoadTrackLog($$;$) # Google Takeout JSON format $format = 'JSON'; $sortFixes = 1; # (fixes are not all in order for this format) - } elsif (/"durationMinutesOffsetFromStartTime"\s*:/) { + } elsif (/"(durationMinutesOffsetFromStartTime|startTime)"\s*:/) { $format = 'JSON'; # new Google Takeout JSON format (fixes seem to be in order) $raf->Seek(0,0); # rewind to start of file } else { diff --git a/bin/lib/Image/ExifTool/QuickTime.pm b/bin/lib/Image/ExifTool/QuickTime.pm index 2b2ec86..a84648b 100644 --- a/bin/lib/Image/ExifTool/QuickTime.pm +++ b/bin/lib/Image/ExifTool/QuickTime.pm @@ -48,7 +48,7 @@ use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::Exif; use Image::ExifTool::GPS; -$VERSION = '3.01'; +$VERSION = '3.02'; sub ProcessMOV($$;$); sub ProcessKeys($$$); @@ -9528,7 +9528,7 @@ sub ProcessMOV($$;$) my $dirID = $$dirInfo{DirID} || ''; my $charsetQuickTime = $et->Options('CharsetQuickTime'); my ($buff, $tag, $size, $track, $isUserData, %triplet, $doDefaultLang, $index); - my ($dirEnd, $unkOpt, %saveOptions, $atomCount, $warnStr); + my ($dirEnd, $unkOpt, %saveOptions, $atomCount, $warnStr, $trailer); my $topLevel = not $$et{InQuickTime}; $$et{InQuickTime} = 1; @@ -9557,6 +9557,17 @@ sub ProcessMOV($$;$) $tagTablePtr = GetTagTable('Image::ExifTool::QuickTime::Main'); } ($size, $tag) = unpack('Na4', $buff); + my $fast = $$et{OPTIONS}{FastScan} || 0; + # check for Insta360 trailer + if ($topLevel and not $fast) { + my $pos = $raf->Tell(); + if ($raf->Seek(-40, 2) and $raf->Read($buff, 40) == 40 and + substr($buff, 8) eq '8db42d694ccc418790edff439fe026bf') + { + $trailer = [ 'Insta360', $raf->Tell() - unpack('V',$buff) ]; + } + $raf->Seek($pos,0) or return 0; + } if ($dataPt) { $verbose and $et->VerboseDir($$dirInfo{DirName}); } else { @@ -9595,7 +9606,6 @@ sub ProcessMOV($$;$) # have XMP take priority except for HEIC $$et{PRIORITY_DIR} = 'XMP' unless $fileType and $fileType eq 'HEIC'; } - my $fast = $$et{OPTIONS}{FastScan} || 0; $$raf{NoBuffer} = 1 if $fast; # disable buffering in FastScan mode my $ee = $$et{OPTIONS}{ExtractEmbedded}; @@ -10136,6 +10146,10 @@ ItemID: foreach $id (reverse sort { $a <=> $b } keys %$items) { $dataPos += $size + 8; # point to start of next atom data last if $dirEnd and $dataPos >= $dirEnd; # (note: ignores last value if 0 bytes) $lastPos = $raf->Tell() + $dirBase; + if ($trailer and $lastPos >= $$trailer[1]) { + $et->Warn(sprintf('%s trailer at offset 0x%x', @$trailer), 1); + last; + } $raf->Read($buff, 8) == 8 or last; $lastTag = $tag if $$tagTablePtr{$tag} and $tag ne 'free'; # (Insta360 sometimes puts free block before trailer) ($size, $tag) = unpack('Na4', $buff); @@ -10143,19 +10157,11 @@ ItemID: foreach $id (reverse sort { $a <=> $b } keys %$items) { } if ($warnStr) { # assume this is an unknown trailer if it comes immediately after - # mdat or moov or free and has a tag name we don't recognize - # (Insta360 can write trailer after a 'free' atom) - if (($lastTag eq 'mdat' or $lastTag eq 'moov' or $lastTag eq 'free') and + # mdat or moov and has a tag name we don't recognize + if (($lastTag eq 'mdat' or $lastTag eq 'moov') and (not $$tagTablePtr{$tag} or ref $$tagTablePtr{$tag} eq 'HASH' and $$tagTablePtr{$tag}{Unknown})) { - if ($raf->Seek(-40, 2) and $raf->Read($buff, 40) == 40 and - substr($buff, 8) eq '8db42d694ccc418790edff439fe026bf' and - $lastPos == $raf->Tell() - unpack('V',$buff)) - { - $et->Warn(sprintf('Insta360 trailer at offset 0x%x', $lastPos), 1); - } else { - $et->Warn('Unknown trailer with '.lcfirst($warnStr)); - } + $et->Warn('Unknown trailer with '.lcfirst($warnStr)); } else { $et->Warn($warnStr); } diff --git a/bin/lib/Image/ExifTool/WriteQuickTime.pl b/bin/lib/Image/ExifTool/WriteQuickTime.pl index b35758d..64bf471 100644 --- a/bin/lib/Image/ExifTool/WriteQuickTime.pl +++ b/bin/lib/Image/ExifTool/WriteQuickTime.pl @@ -847,7 +847,7 @@ ($$$) $et or return 1; # allow dummy access to autoload this package my ($mdat, @mdat, @mdatEdit, $edit, $track, $outBuff, $co, $term, $delCount); my (%langTags, $canCreate, $delGrp, %boxPos, %didDir, $writeLast, $err, $atomCount); - my ($tag, $lastTag, $lastPos, $errStr, $copyTrailer, $buf2); + my ($tag, $lastTag, $lastPos, $errStr, $trailer, $buf2); my $outfile = $$dirInfo{OutFile} || return 0; my $raf = $$dirInfo{RAF}; # (will be null for lower-level atoms) my $dataPt = $$dirInfo{DataPt}; # (will be null for top-level atoms) @@ -860,6 +860,16 @@ ($$$) my $createKeys = 0; my ($rtnVal, $rtnErr) = $dataPt ? (undef, undef) : (1, 0); + # check for Insta360 trailer at top level + if ($raf) { + my $pos = $raf->Tell(); + if ($raf->Seek(-40, 2) and $raf->Read($buf2, 40) == 40 and + substr($buf2, 8) eq '8db42d694ccc418790edff439fe026bf') + { + $trailer = [ 'Insta360', $raf->Tell() - unpack('V',$buf2) ]; + } + $raf->Seek($pos, 0) or return 0; + } if ($dataPt) { $raf = File::RandomAccess->new($dataPt); } else { @@ -924,6 +934,11 @@ ($$$) for (;;) { # loop through all atoms at this level $lastPos = $raf->Tell(); + # stop processing if we reached a known trailer + if ($trailer and $lastPos >= $$trailer[1]) { + $errStr = "Corrupted $$trailer[0] trailer" if $lastPos != $$trailer[1]; + last; + } $lastTag = $tag if $$tagTablePtr{$tag}; # keep track of last known tag if (defined $atomCount and --$atomCount < 0 and $dataPt) { # stop processing now and just copy the rest of the atom @@ -1524,38 +1539,18 @@ ($$$) } # ($errStr is set if there was an error that could possibly be due to an unknown trailer) if ($errStr) { - if (($lastTag eq 'mdat' or $lastTag eq 'moov' or ($lastTag eq 'free' and @mdat)) and not $dataPt and - (not $$tagTablePtr{$tag} or ref $$tagTablePtr{$tag} eq 'HASH' and $$tagTablePtr{$tag}{Unknown})) + if (($lastTag eq 'mdat' or $lastTag eq 'moov') and not $dataPt and (not $$tagTablePtr{$tag} or + ref $$tagTablePtr{$tag} eq 'HASH' and $$tagTablePtr{$tag}{Unknown})) { - # identify known trailers - if ($raf->Seek(-40,2) and $raf->Read($buf2,40)==40 and - substr($buf2, 8) eq '8db42d694ccc418790edff439fe026bf' and - $lastPos == $raf->Tell() - unpack('V',$buf2)) - { - $copyTrailer = [ $lastPos, 'Insta360' ]; + # identify other known trailers + $buf2 = ''; + $raf->Seek($lastPos,0) and $raf->Read($buf2,8); + if ($buf2 eq 'CCCCCCCC') { + $trailer = [ 'Kenwood', $lastPos ]; + } elsif ($buf2 =~ /^(gpsa|gps0|gsen|gsea)...\0/s) { + $trailer = [ 'RIFF', $lastPos ]; } else { - $buf2 = ''; - $raf->Seek($lastPos,0) and $raf->Read($buf2,8); - if ($buf2 eq 'CCCCCCCC') { - $copyTrailer = [ $lastPos, 'Kenwood' ]; - } elsif ($buf2 =~ /^(gpsa|gps0|gsen|gsea)...\0/s) { - $copyTrailer = [ $lastPos, 'RIFF' ]; - } - } - # are we deleting the trailer? - my $nvTrail = $et->GetNewValueHash($Image::ExifTool::Extra{Trailer}); - if ($$et{DEL_GROUP}{Trailer} or ($nvTrail and not ($$nvTrail{Value} and $$nvTrail{Value}[0]))) { - $errStr =~ s/ is too large.*//; - if ($copyTrailer) { - $et->Warn("Deleted $$copyTrailer[1] trailer", 1); - undef $copyTrailer; - } else { - $et->Warn('Deleted unknown trailer with ' . lcfirst($errStr), 1); - } - } elsif (not $copyTrailer) { - $et->Warn('Unknown trailer with ' . lcfirst($errStr)); - $et->Error('Use "-trailer=" to delete unknown trailer'); - # (we don't currently copy an unknown trailer due to the chance it could be corrupted data) + $trailer = [ 'Unknown', $lastPos ]; } } else { $et->Error($errStr); @@ -2011,16 +2006,20 @@ ($$$) Write($outfile, $writeLast) or $rtnVal = 0 if $writeLast; # copy trailer if necessary - if ($copyTrailer) { - if ($raf->Seek($$copyTrailer[0])) { - $et->Warn(sprintf('Copying %s trailer from offset 0x%x', $$copyTrailer[1], $lastPos), 1); + if ($rtnVal and $trailer) { + # are we deleting the trailer? + my $nvTrail = $et->GetNewValueHash($Image::ExifTool::Extra{Trailer}); + if ($$et{DEL_GROUP}{Trailer} or ($nvTrail and not ($$nvTrail{Value} and $$nvTrail{Value}[0]))) { + $et->Warn("Deleted $$trailer[0] trailer", 1); + } elsif ($raf->Seek($$trailer[1])) { + $et->Warn(sprintf('Copying %s trailer from offset 0x%x', @$trailer), 1); while ($raf->Read($buf2, 65536)) { Write($outfile, $buf2) or $rtnVal = 0, last; } } else { - $et->Error('Error copying Insta360 trailer'); $rtnVal = 0; } + $rtnVal or $et->Error("Error copying $$trailer[0] trailer"); } return $rtnVal; } diff --git a/bin/perl-Image-ExifTool.spec b/bin/perl-Image-ExifTool.spec index 066e176..4868258 100644 --- a/bin/perl-Image-ExifTool.spec +++ b/bin/perl-Image-ExifTool.spec @@ -1,6 +1,6 @@ Summary: perl module for image data extraction Name: perl-Image-ExifTool -Version: 12.95 +Version: 12.96 Release: 1 License: Artistic/GPL Group: Development/Libraries/Perl diff --git a/lib/exiftool_vendored/version.rb b/lib/exiftool_vendored/version.rb index 75cc6fa..af7e0ee 100644 --- a/lib/exiftool_vendored/version.rb +++ b/lib/exiftool_vendored/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module ExiftoolVendored - VERSION = Gem::Version.new('12.95.0') + VERSION = Gem::Version.new('12.96.0') end