diff --git a/bin/Changes b/bin/Changes index 74af982..5188b86 100644 --- a/bin/Changes +++ b/bin/Changes @@ -7,6 +7,28 @@ 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.) +July 24, 2024 - Version 12.92 + + - Removed -w from exiftool shebang + +July 24, 2024 - Version 12.91 + + - Fixed 2 test files that were causing failed tests (ExifTool itself is + unchanged) + +July 24, 2024 - Version 12.90 + + - Added support for reading Samsung trailer from PNG images + - Decode two more formats of timed GPS from MP4 videos + - Decode a few more Samung trailer tags (thanks Neal Krawetz) + - Decode Canon AntiFlicker tag + - Drop Nikon ShotInfo record when copying MakerNotes from NEF to JPG if it is + larger than 50000 bytes (then MakerNotes would be too large for a single + JPEG segment) + - Changed exiftool shebang from "#!/usr/bin/perl" to "#!/usr/bin/env perl" + - Revert change of 12.84 to iterate through sub-documents with the -p option + only if -ee is used + July 12, 2024 - Version 12.89 - Added new Sony lenses and updated decoding of some tags (thanks Jos Roost) @@ -15,9 +37,7 @@ July 12, 2024 - Version 12.89 July 11, 2024 - Version 12.88 - "New Windows/MacOS packages" - - - -NOTE: The install procedure for the Windows executable has changed! + - NOTE: The install procedure for the Windows executable has changed! - Windows EXE version now uses Oliver Betz's bundle with Strawberry Perl and comes in 32- and 64-bit versions - MacOS distribution now uses a flattened package @@ -105,6 +125,8 @@ Apr. 23, 2024 - Version 12.84 cities - Allow coordinates to be entered without comma separator for the Geolocation feature as long as both coordinates have a decimal point + - Changed -p option to iterate through sub-documents if they exist even if -ee + isn't used - Fixed long-standing bug in Windows version that didn't properly handle dates older than 50 years when writing FileModifyDate or FileCreateDate - Fixed API TimeZone option to work in Windows diff --git a/bin/META.json b/bin/META.json index 9d3563f..745d10a 100644 --- a/bin/META.json +++ b/bin/META.json @@ -50,5 +50,5 @@ } }, "release_status" : "stable", - "version" : "12.89" + "version" : "12.92" } diff --git a/bin/META.yml b/bin/META.yml index f91e4b0..a993120 100644 --- a/bin/META.yml +++ b/bin/META.yml @@ -31,4 +31,4 @@ recommends: Time::HiRes: '0' requires: perl: '5.004' -version: '12.89' +version: '12.92' diff --git a/bin/README b/bin/README index b5564a7..4620208 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.89.tar.gz | tar -xf - - cd Image-ExifTool-12.89 + gzip -dc Image-ExifTool-12.92.tar.gz | tar -xf - + cd Image-ExifTool-12.92 ./exiftool t/images/ExifTool.jpg Note: These commands extract meta information from one of the test images. diff --git a/bin/build_geolocation b/bin/build_geolocation index 9e3b842..b8c10b8 100755 --- a/bin/build_geolocation +++ b/bin/build_geolocation @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl #------------------------------------------------------------------------------- # File: build_geolocation # diff --git a/bin/exiftool b/bin/exiftool index b8bab02..44e926c 100755 --- a/bin/exiftool +++ b/bin/exiftool @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl #------------------------------------------------------------------------------ # File: exiftool # @@ -11,7 +11,7 @@ use strict; use warnings; require 5.004; -my $version = '12.89'; +my $version = '12.92'; # add our 'lib' directory to the include list BEFORE 'use Image::ExifTool' my $exePath; @@ -2310,8 +2310,8 @@ sub GetImageInfo($$) # output using print format file (-p) option my ($type, $doc, $grp, $lastDoc, $cache); $fileTrailer = ''; - # repeat for each sub-document if necessary - if ($$et{DOC_COUNT}) { + # repeat for each embedded document if necessary (only if -ee used) + if ($et->Options('ExtractEmbedded')) { # (cache tag keys if there are sub-documents) $lastDoc = $$et{DOC_COUNT} and $cache = { }; } else { @@ -5684,7 +5684,7 @@ with this command: produces output like this: - -- Generated by ExifTool 12.89 -- + -- Generated by ExifTool 12.92 -- 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 9782d28..3f99f07 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.89'; +$VERSION = '12.92'; $RELEASE = ''; @ISA = qw(Exporter); %EXPORT_TAGS = ( diff --git a/bin/lib/Image/ExifTool/Canon.pm b/bin/lib/Image/ExifTool/Canon.pm index f5bb7f2..64e0213 100644 --- a/bin/lib/Image/ExifTool/Canon.pm +++ b/bin/lib/Image/ExifTool/Canon.pm @@ -88,7 +88,7 @@ sub ProcessCTMD($$$); sub ProcessExifInfo($$$); sub SwapWords($); -$VERSION = '4.78'; +$VERSION = '4.79'; # Note: Removed 'USM' from 'L' lenses since it is redundant - PH # (or is it? Ref 32 shows 5 non-USM L-type lenses) @@ -6403,6 +6403,8 @@ my %ciMaxFocal = ( 12 => 'Flexizone Multi (9 point)', #PH (750D, 9 points) 13 => 'Flexizone Single', #PH (EOS M default, live view) (R7 calls this '1-point AF', ref github268) 14 => 'Large Zone AF', #PH/forum6237 (7DmkII) + 16 => 'Large Zone AF (vertical)', #forum16223 + 17 => 'Large Zone AF (horizontal)', #forum16223 19 => 'Flexible Zone AF 1', #github268 (R7) 20 => 'Flexible Zone AF 2', #github268 (R7) 21 => 'Flexible Zone AF 3', #github268 (R7) @@ -6921,6 +6923,10 @@ my %ciMaxFocal = ( Name => 'FlashExposureLock', PrintConv => \%offOn, }, + 32 => { #forum16257 + Name => 'AntiFlicker', + PrintConv => \%offOn, + }, 0x3d => { #IB Name => 'RFLensType', Format => 'int16u', @@ -9123,19 +9129,19 @@ my %filterConv = ( 2 => 'Disable', }, }, - 18 => { #52 + 18 => { #52/forum16223 Name => 'AFStatusViewfinder', - Condition => '$$self{Model} =~ /1D X/', - Notes => '1D X only', + Condition => '$$self{Model} =~ /EOS-1D X|EOS R/', + Notes => '1D X and R models', PrintConv => { 0 => 'Show in Field of View', 1 => 'Show Outside View', }, }, - 19 => { #52 + 19 => { #52/forum16223 Name => 'InitialAFPointInServo', - Condition => '$$self{Model} =~ /1D X/', - Notes => '1D X only', + Condition => '$$self{Model} =~ /EOS-1D X|EOS R/', + Notes => '1D X and R models', PrintConv => { 0 => 'Initial AF Point Selected', 1 => 'Manual AF Point', diff --git a/bin/lib/Image/ExifTool/Nikon.pm b/bin/lib/Image/ExifTool/Nikon.pm index 21ac671..cd63072 100644 --- a/bin/lib/Image/ExifTool/Nikon.pm +++ b/bin/lib/Image/ExifTool/Nikon.pm @@ -65,7 +65,7 @@ use Image::ExifTool::Exif; use Image::ExifTool::GPS; use Image::ExifTool::XMP; -$VERSION = '4.35'; +$VERSION = '4.36'; sub LensIDConv($$$); sub ProcessNikonAVI($$$); @@ -2495,6 +2495,7 @@ my %base64coord = ( { # D7100=0227 Condition => '$$valPt =~ /^0[28]/', Name => 'ShotInfo02xx', + Drop => 50000, # drop if too large (>64k for Z6iii) SubDirectory => { TagTable => 'Image::ExifTool::Nikon::ShotInfo', ProcessProc => \&ProcessNikonEncrypted, @@ -5635,6 +5636,38 @@ my %nikonFocalConversions = ( Notes => 'P6000', PrintConv => \%offOn, }, + # for Nikon Z6iii JPG and RAW images (version 0809), + # the offset table starts at 0x24 and is as follows + # JPG Offset Size NEF Offset Size + # 0) 0x0000 0 0) 0x009c 21604 + # 1) 0x0000 0 1) 0x5500 6008 + # 2) 0x009c 2528 2) 0x6c78 2528 + # 3) 0x0a7c 200 3) 0x7658 200 + # 4) 0x0b44 2488 4) 0x7720 2488 + # 5) 0x14fc 1468 5) 0x80d8 1468 + # 6) 0x1ab8 1032 6) 0x8694 1032 + # 7) 0x1ec0 256 7) 0x8a9c 256 + # 8) 0x1fc0 800 8) 0x8b9c 800 + # 9) 0x22e0 144 9) 0x8ebc 144 + # 10) 0x2370 64 10) 0x8f4c 64 + # 11) 0x0000 0 11) 0x0000 0 + # 12) 0x23b0 5009 12) 0x8f8c 5009 + # 13) 0x3741 1536 13) 0xa31d 1536 + # 14) 0x3d41 11928 14) 0xa91d 11928 + # 15) 0x6bd9 5937 15) 0xd7b5 5937 + # 16) 0x830a 500 16) 0xeee6 500 + # 17) 0x84fe 160 17) 0xf0da 160 + # 18) 0x859e 464 18) 0xf17a 464 + # 19) 0x876e 8 19) 0xf34a 8 + # 20) 0x8776 64 20) 0xf352 64 + # 21) 0x87b6 6 21) 0xf392 6 + # 22) 0x87bc 48 22) 0xf398 48 + # 23) 0x87ec 20 23) 0xf3c8 20 + # 24) 0x8800 108 24) 0xf3dc 108 + # 25) 0x886c 8 25) 0xf448 8 + # 26) 0x8874 2420 26) 0xf450 2420 + # 27) 0x0000 0 27) 0x0000 0 + # 28) 0x0000 0 28) 0x0000 0 0x66 => { Name => 'VR_0x66', Condition => '$$self{ShotInfoVersion} eq "0204"', diff --git a/bin/lib/Image/ExifTool/PNG.pm b/bin/lib/Image/ExifTool/PNG.pm index bc5f2c5..dc6e5ca 100644 --- a/bin/lib/Image/ExifTool/PNG.pm +++ b/bin/lib/Image/ExifTool/PNG.pm @@ -36,7 +36,7 @@ use strict; use vars qw($VERSION $AUTOLOAD %stdCase); use Image::ExifTool qw(:DataAccess :Utils); -$VERSION = '1.67'; +$VERSION = '1.68'; sub ProcessPNG_tEXt($$$); sub ProcessPNG_iTXt($$$); @@ -1400,7 +1400,7 @@ sub ProcessPNG($$) my $fastScan = $et->Options('FastScan'); my $hash = $$et{ImageDataHash}; my ($n, $sig, $err, $hbuf, $dbuf, $cbuf); - my ($wasHdr, $wasEnd, $wasDat, $doTxt, @txtOffset); + my ($wasHdr, $wasEnd, $wasDat, $doTxt, @txtOffset, $wasTrailer); # check to be sure this is a valid PNG/MNG/JNG image return 0 unless $raf->Read($sig,8) == 8 and $pngLookup{$sig}; @@ -1461,6 +1461,7 @@ sub ProcessPNG($$) if ($wasEnd) { last unless $n; # stop now if normal end of PNG $et->WarnOnce("Trailer data after $fileType $endChunk chunk", 1); + $wasTrailer = 1; last if $n < 8; $$et{SET_GROUP1} = 'Trailer'; } elsif ($n != 8) { @@ -1654,6 +1655,13 @@ sub ProcessPNG($$) } } delete $$et{SET_GROUP1}; + # read Samsung trailer if it exists + if ($wasTrailer and not $outfile and $raf->Seek(-8, 2) and + $raf->Read($dbuf,8) and $dbuf =~ /\0\0(QDIOBS|SEFT)$/) # (have only seen SEFT type) + { + require Image::ExifTool::Samsung; + Image::ExifTool::Samsung::ProcessSamsung($et, { DirName => 'Samsung', RAF => $raf }); + } return -1 if $outfile and ($err or not $wasEnd); return 1; # this was a valid PNG/MNG/JNG image } diff --git a/bin/lib/Image/ExifTool/QuickTime.pm b/bin/lib/Image/ExifTool/QuickTime.pm index 7f453e8..40845a6 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 = '2.98'; +$VERSION = '2.99'; sub ProcessMOV($$;$); sub ProcessKeys($$$); @@ -9737,7 +9737,7 @@ sub ProcessMOV($$;$) if ($size > 0x2000000) { # start to get worried above 32 MiB # check for RIFF trailer (written by Auto-Vox dashcam) if ($buff =~ /^(gpsa|gps0|gsen|gsea)...\0/s) { # (yet seen only gpsa as first record) - $et->VPrint(0, "Found RIFF trailer"); + $et->VPrint(0, sprintf("Found RIFF trailer at offset 0x%x",$lastPos)); if ($et->Options('ExtractEmbedded')) { $raf->Seek(-8, 1) or last; # seek back to start of trailer my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream'); @@ -9746,6 +9746,11 @@ sub ProcessMOV($$;$) EEWarn($et); } last; + } elsif ($buff eq 'CCCCCCCC') { + $et->VPrint(0, sprintf("Found Kenwood trailer at offset 0x%x",$lastPos)); + my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream'); + ProcessKenwoodTrailer($et, { RAF => $raf }, $tbl); + last; } $ignore = 1; if ($tagInfo and not $$tagInfo{Unknown} and not $eeTag) { diff --git a/bin/lib/Image/ExifTool/QuickTimeStream.pl b/bin/lib/Image/ExifTool/QuickTimeStream.pl index 2076956..843d19e 100644 --- a/bin/lib/Image/ExifTool/QuickTimeStream.pl +++ b/bin/lib/Image/ExifTool/QuickTimeStream.pl @@ -109,7 +109,7 @@ package Image::ExifTool::QuickTime; The tags below are extracted from timed metadata in QuickTime and other formats of video files when the ExtractEmbedded option is used. Although most of these tags are combined into the single table below, ExifTool - currently reads 74 different formats of timed GPS metadata from video files. + currently reads 76 different formats of timed GPS metadata from video files. }, VARS => { NO_ID => 1 }, GPSLatitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', RawConv => '$$self{FoundGPSLatitude} = 1; $val' }, @@ -1420,9 +1420,10 @@ ($) } elsif ($type eq 'gps ') { # (ie. GPSDataList tag) if ($buff =~ /^....freeGPS /s) { - # process by brute scan instead if ExtractEmbedded >= 3 - # (some videos don't reference all freeGPS info from 'gps ' table, eg. INNOV) - last if $eeOpt >= 3; + # parse freeGPS data unless done already in brute-force scan + # (some videos don't reference all freeGPS info from 'gps ' table, eg. INNOV, + # and some videos don't put 'gps ' data in mdat, eg XGODY 12" 4K Dashcam) + last if $$et{FoundGPSByScan}; # decode "freeGPS " data (Novatek and others) ProcessFreeGPS($et, { DataPt => \$buff, @@ -2049,9 +2050,41 @@ ($$$) } } - } else { + } elsif ($$dataPt =~ m<^.{23}(\d{4})/(\d{2})/(\d{2}) (\d{2}):(\d{2}):(\d{2}) [N|S]>s) { $debug and $et->FoundTag(GPSType => 16); + # XGODY 12" 4K Dashcam + # 0000: 00 00 00 a8 66 72 65 65 47 50 53 20 98 00 00 00 [....freeGPS ....] + # 0010: 6e 6f 72 6d 61 6c 3a 32 30 32 34 2f 30 35 2f 32 [normal:2024/05/2] + # 0020: 32 20 30 32 3a 35 34 3a 32 39 20 4e 3a 34 32 2e [2 02:54:29 N:42.] + # 0030: 33 38 32 34 37 30 20 57 3a 38 33 2e 33 38 39 35 [382470 W:83.3895] + # 0040: 37 30 20 35 33 2e 36 20 6b 6d 2f 68 20 78 3a 2d [70 53.6 km/h x:-] + # 0050: 30 2e 30 32 20 79 3a 30 2e 39 39 20 7a 3a 30 2e [0.02 y:0.99 z:0.] + # 0060: 31 30 20 41 3a 32 36 39 2e 32 20 48 3a 32 34 35 [10 A:269.2 H:245] + # 0070: 2e 35 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [.5..............] + ($yr,$mon,$day,$hr,$min,$sec) = ($1,$2,$3,$4,$5,$6); + $$dataPt =~ s/\0+$//; # remove trailing nulls + my @a = split ' ', substr($$dataPt,43); + $ddd = 1; + foreach (@a) { + unless (/^([A-Z]):([-+]?\d+(\.\d+)?)$/i) { + # (the "km/h" after spd is display units? because the value is stored in knots) + defined $lon and not defined $spd and /^\d+\.\d+$/ and $spd = $_ * $knotsToKph; + next; + } + ($1 eq 'N' or $1 eq 'S') and $lat = $2, $latRef = $1, next; + ($1 eq 'E' or $1 eq 'W') and $lon = $2, $lonRef = $1, next; + ($1 eq 'x' or $1 eq 'y' or $1 eq 'z') and push(@acc,$2), next; + $1 eq 'A' and $trk = $2, next; # (verified, but why 'A'?) + # seen 'H' - one might expect altitude ('H'eight), but it doesn't fit + # the sample data, so save all other information as an "Unknown_X" tag + $$tagTbl{$1} or AddTagToTable($tagTbl, $1, { Name => "Unknown_$1", Unknown => 1 }); + push(@xtra, $1 => $2), next; + } + + } else { + + $debug and $et->FoundTag(GPSType => 17); # (look for binary GPS as stored by Nextbase 512G, ref PH) # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 78 01 00 00 [....freeGPS x...] # 0010: 78 2e 78 78 00 00 00 00 00 00 00 00 00 00 00 00 [x.xx............] @@ -2115,7 +2148,7 @@ ($$$) my $time = sprintf('%.2d:%.2d:%sZ',$hr,$min,$sec); $et->HandleTag($tagTbl, GPSTimeStamp => $time); } - if (defined $lat) { + if (defined $lat and defined $lon) { # lat/long are in DDDMM.MMMM format unless $ddd is set ConvertLatLon($lat, $lon) unless $ddd; $et->HandleTag($tagTbl, GPSLatitude => $lat * ($latRef eq 'S' ? -1 : 1)); @@ -2680,6 +2713,53 @@ ($$$) return 1; } +#------------------------------------------------------------------------------ +# Process Kenwood Dashcam trailer (forum16229) +# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref +# Returns: 1 on success +# Sample data (chained 512-byte records starting like this): +# 0000: 43 43 43 43 43 43 43 43 43 43 43 43 43 43 47 50 [CCCCCCCCCCCCCCGP] +# 0010: 53 44 41 54 41 2d 2d 32 30 32 34 30 37 31 31 31 [SDATA--202407111] +# 0020: 32 30 34 31 32 4e 35 30 2e 36 31 32 33 38 36 30 [20412N50.6123860] +# 0030: 36 37 37 45 38 2e 37 30 32 37 31 38 30 39 38 39 [677E8.7027180989] +# 0040: 35 33 33 2e 30 30 30 30 30 30 30 30 30 30 30 30 [533.000000000000] +# 0050: 2e 30 30 30 30 30 30 30 30 30 30 30 30 30 2e 30 [.0000000000000.0] +# 0060: 31 39 39 39 39 39 39 39 35 35 33 2d 30 2e 30 39 [19999999553-0.09] +# 0070: 30 30 30 30 30 30 33 35 37 2d 30 2e 31 34 30 30 [000000357-0.1400] +# 0080: 30 30 30 30 30 35 39 47 50 53 44 41 54 41 2d 2d [0000059GPSDATA--] +sub ProcessKenwoodTrailer($$$) +{ + my ($et, $dirInfo, $tagTbl) = @_; + my $raf = $$dirInfo{RAF}; + my $buff; + # current file position is 8 bytes into the 14 C's, so test the next 6: + $raf->Read($buff, 14) and $buff eq 'CCCCCCCCCCCCCC' or return 0; + $et->VerboseDir('Kenwood trailer', undef, undef); + unless ($$et{OPTIONS}{ExtractEmbedded}) { + $et->WarnOnce('Use the ExtractEmbedded option to extract timed GPSData from Kenwood trailer',3); + return 1; + } + while ($raf->Read($buff, 121) and $buff =~ /^GPSDATA--(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/) { + FoundSomething($et, $tagTbl); + $et->HandleTag($tagTbl, GPSDateTime => "$1:$2:$3 $4:$5:$6"); + my $i = 9 + 14; + my ($val, @acc, $tag); + foreach $tag (qw(GPSLatitude GPSLongitude GPSSpeed unk acc acc acc)) { + $val = substr($buff, $i, 14); $i += 14; + next if $tag eq 'unk'; + my $hemi; + $hemi = $1 if $val =~ s/^([NSEW])//; + $val =~ /^[-+]?\d+\.\d+$/ or next; + $tag eq 'acc' and push(@acc,$val), next; + $val = -$val if $hemi and ($hemi eq 'S' or $hemi eq 'W'); + $et->HandleTag($tagTbl, $tag => $val); + } + $et->HandleTag($tagTbl, Accelerometer => "@acc") if @acc == 3; + } + delete $$et{DOC_NUM}; + return 1; +} + #------------------------------------------------------------------------------ # Process 'gps ' atom containing NMEA from Pittasoft Blackvue dashcam (ref PH) # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref @@ -3353,6 +3433,7 @@ ($) } my $dirInfo = { DataPt => \$buff, DataPos => $pos + $dataPos, DirLen => $len }; ProcessFreeGPS($et, $dirInfo, $tagTbl); + $$et{FoundGPSByScan} = 1; } $pos += $len; $buf2 = substr($buff, $len); diff --git a/bin/lib/Image/ExifTool/Samsung.pm b/bin/lib/Image/ExifTool/Samsung.pm index 413adf2..14250d5 100644 --- a/bin/lib/Image/ExifTool/Samsung.pm +++ b/bin/lib/Image/ExifTool/Samsung.pm @@ -22,13 +22,13 @@ use vars qw($VERSION %samsungLensTypes); use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::Exif; -$VERSION = '1.56'; +$VERSION = '1.57'; sub WriteSTMN($$$); sub ProcessINFO($$$); sub ProcessSamsungMeta($$$); sub ProcessSamsungIFD($$$); -sub ProcessSamsung($$$); +sub ProcessSamsung($$;$); # Samsung LensType lookup %samsungLensTypes = ( @@ -943,25 +943,25 @@ my %formatMinMax = ( ); # information extracted from Samsung trailer (ie. Samsung SM-T805 "Sound & Shot" JPEG) (ref PH) +# NOTE: These tags may use $$self{SamsungTagName} in a Condition statement +# if necessary to differentiate tags with the same ID but different names %Image::ExifTool::Samsung::Trailer = ( GROUPS => { 0 => 'MakerNotes', 2 => 'Other' }, VARS => { NO_ID => 1, HEX_ID => 0 }, PROCESS_PROC => \&ProcessSamsung, + TAG_PREFIX => 'SamsungTrailer', PRIORITY => 0, # (first one takes priority so DepthMapWidth/Height match first DepthMapData) NOTES => q{ - Tags extracted from the trailer of JPEG images written when using certain - features (such as "Sound & Shot" or "Shot & More") from Samsung models such - as the Galaxy S4 and Tab S, and from the 'sefd' atom in HEIC images from the - Samsung S10+. - }, - '0x0001-name' => { - Name => 'EmbeddedImageName', # ("DualShot_1","DualShot_2") - RawConv => '$$self{EmbeddedImageName} = $val', + Tags extracted from the SEFT trailer of JPEG and PNG images written when + using certain features (such as "Sound & Shot" or "Shot & More") from + Samsung models such as the Galaxy S4 and Tab S, and from the 'sefd' atom in + HEIC images from models such as the S10+. }, + '0x0001-name' => 'EmbeddedImageName', # ("DualShot_1","DualShot_2") '0x0001' => [ { Name => 'EmbeddedImage', - Condition => '$$self{EmbeddedImageName} eq "DualShot_1"', + Condition => '$$self{SamsungTagName} ne "DualShot_2"', Groups => { 2 => 'Preview' }, Binary => 1, }, @@ -1277,8 +1277,10 @@ my %formatMinMax = ( # 0x0bd0-name - seen 'Dual_Relighting_Bokeh_Info' #forum16086 # 0x0be0-name - seen 'Livefocus_JDM_Info' #forum16086 # 0x0bf0-name - seen 'Remaster_Info' #forum16086 + '0x0bf0' => 'RemasterInfo', #forum16086/16242 # 0x0c21-name - seen 'Portrait_Effect_Info' #forum16086 # 0x0c51-name - seen 'Samsung_Capture_Info' #forum16086 + '0x0c51' => 'SamsungCaptureInfo', #forum16086/16242 # 0x0c61-name - seen 'Camera_Capture_Mode_Info' #forum16086 # 0x0c71-name - seen 'Pro_White_Balance_Info' #forum16086 # 0x0c81-name - seen 'Watermark_Info' #forum16086 @@ -1289,7 +1291,11 @@ my %formatMinMax = ( # 0x0d11-name - seen 'Video_Snapshot_Info' #forum16086 # 0x0d21-name - seen 'Camera_Scene_Info' #forum16086 # 0x0d31-name - seen 'Food_Blur_Effect_Info' #forum16086 - # 0x0d91-name - seen 'PEg_Info' #forum16086 + '0x0d91' => { #forum16086/16242 + Name => 'PEg_Info', + Description => 'PEg Info', + SubDirectory => { TagTable => 'Image::ExifTool::JSON::Main' }, + }, # 0x0da1-name - seen 'Captured_App_Info' #forum16086 # 0xa050-name - seen 'Jpeg360_2D_Info' (Samsung Gear 360) # 0xa050 - seen 'Jpeg3602D' (Samsung Gear 360) @@ -1563,7 +1569,7 @@ sub ProcessSamsungIFD($$$) # Returns: 1 on success, 0 not valid Samsung trailer, or -1 error writing # - updates DataPos to point to start of Samsung trailer # - updates DirLen to existing trailer length -sub ProcessSamsung($$$) +sub ProcessSamsung($$;$) { my ($et, $dirInfo) = @_; my $raf = $$dirInfo{RAF}; @@ -1653,8 +1659,13 @@ SamBlock: $audioSize = $size - 8 - $len; next; } - # add unknown tags if necessary + last unless $raf->Seek($dirPos-$noff, 0) and $raf->Read($buf2, $size) == $size; + # (could validate the first 4 bytes of the block because they + # are the same as the first 4 bytes of the directory entry) + $len = Get32u(\$buf2, 4); + last if $len + 8 > $size; my $tag = sprintf("0x%.4x", $type); + # add unknown tags if necessary unless ($$tagTablePtr{$tag}) { next unless $unknown or $verbose; my %tagInfo = ( @@ -1673,11 +1684,8 @@ SamBlock: ); AddTagToTable($tagTablePtr, "$tag-name", \%tagInfo2); } - last unless $raf->Seek($dirPos-$noff, 0) and $raf->Read($buf2, $size) == $size; - # (could validate the first 4 bytes of the block because they - # are the same as the first 4 bytes of the directory entry) - $len = Get32u(\$buf2, 4); - last if $len + 8 > $size; + # set SamsungTagName ExifTool member for use in tag Condition + $$et{SamsungTagName} = substr($buf2, 8, $len); # extract tag name and value $et->HandleTag($tagTablePtr, "$tag-name", undef, DataPt => \$buf2, @@ -1691,6 +1699,7 @@ SamBlock: Start => 8 + $len, Size => $size - (8 + $len), ); + delete $$et{SamsungTagName}; } if ($outfile) { last unless $raf->Seek($dataPos, 0) and $raf->Read($buff, $dirLen) == $dirLen; diff --git a/bin/lib/Image/ExifTool/TagLookup.pm b/bin/lib/Image/ExifTool/TagLookup.pm index 24d7fab..aefa622 100644 --- a/bin/lib/Image/ExifTool/TagLookup.pm +++ b/bin/lib/Image/ExifTool/TagLookup.pm @@ -997,6 +997,7 @@ my %tagLookup = ( 'angleinfoyaw' => { 510 => 'AngleInfoYaw' }, 'anti-blur' => { 451 => 0xb04b }, 'antialiasstrength' => { 123 => 0xc632 }, + 'antiflicker' => { 59 => 0x20 }, 'aperturelock' => { 306 => '38.2', 308 => '38.2', 309 => '38.2', 318 => '38.2', 319 => '38.2', 321 => 0xb8, 322 => 0xb8, 323 => 0xb8 }, 'aperturemode' => { 410 => 'apmd' }, 'aperturerange' => { 88 => 0x10d }, @@ -11290,6 +11291,7 @@ my %tagExists = ( 'peakspectralsensitivity' => 1, 'peakvalue' => 1, 'pefversion' => 1, + 'peg_info' => 1, 'pentax' => 1, 'pentaxdata' => 1, 'pentaxdata2' => 1, @@ -11750,6 +11752,7 @@ my %tagExists = ( 'releasedateyearmonth' => 1, 'releasedateyearmonthday' => 1, 'releasinginstructions' => 1, + 'remasterinfo' => 1, 'rembrandtconsumertonescale' => 1, 'rembrandtportraittonescale' => 1, 'rembrandttonescale' => 1, @@ -11915,6 +11918,7 @@ my %tagExists = ( 'sampletochunk' => 1, 'sampletogroup' => 1, 'samsung' => 1, + 'samsungcaptureinfo' => 1, 'samsungifd' => 1, 'samsunginfo' => 1, 'samsungmodel' => 1, diff --git a/bin/lib/Image/ExifTool/TagNames.pod b/bin/lib/Image/ExifTool/TagNames.pod index 2a916c7..9fad2e0 100644 --- a/bin/lib/Image/ExifTool/TagNames.pod +++ b/bin/lib/Image/ExifTool/TagNames.pod @@ -12,7 +12,7 @@ meta information extracted from or written to a file. =head1 TAG TABLES The tables listed below give the names of all tags recognized by ExifTool. -They contain a total of 27892 tags, with 17459 unique tag names. +They contain a total of 27895 tags, with 17462 unique tag names. B, B or B is given in the first column of each table. A B is the computer-readable equivalent of a tag name, and @@ -10476,6 +10476,7 @@ WB tags for the Canon G9. 21 FocusDistanceLower int16u 23 ShutterMode int16s 25 FlashExposureLock int16s + 32 AntiFlicker int16s 61 RFLensType int16u =head3 Canon SerialInfo Tags @@ -20869,10 +20870,10 @@ Camera orientation information written by the Gear 360 (SM-C200). =head3 Samsung Trailer Tags -Tags extracted from the trailer of JPEG images written when using certain -features (such as "Sound & Shot" or "Shot & More") from Samsung models such -as the Galaxy S4 and Tab S, and from the 'sefd' atom in HEIC images from the -Samsung S10+. +Tags extracted from the SEFT trailer of JPEG and PNG images written when +using certain features (such as "Sound & Shot" or "Shot & More") from +Samsung models such as the Galaxy S4 and Tab S, and from the 'sefd' atom in +HEIC images from models such as the S10+. Tag Name Writable -------- -------- @@ -20890,6 +20891,9 @@ Samsung S10+. EmbeddedVideoFile no EmbeddedVideoType no MCCData no + PEg_Info JSON + RemasterInfo no + SamsungCaptureInfo no SingleShotDepthMap no SingleShotMeta Samsung SingleShotMeta SurroundShotVideo no @@ -29614,7 +29618,7 @@ for the official QuickTime specification. The tags below are extracted from timed metadata in QuickTime and other formats of video files when the ExtractEmbedded option is used. Although most of these tags are combined into the single table below, ExifTool -currently reads 74 different formats of timed GPS metadata from video files. +currently reads 76 different formats of timed GPS metadata from video files. Tag Name Writable -------- -------- diff --git a/bin/lib/Image/ExifTool/WriteQuickTime.pl b/bin/lib/Image/ExifTool/WriteQuickTime.pl index 3016c15..7768d5b 100644 --- a/bin/lib/Image/ExifTool/WriteQuickTime.pl +++ b/bin/lib/Image/ExifTool/WriteQuickTime.pl @@ -536,7 +536,7 @@ ($$$) my $comp = $et->Options('Compress'); if (defined $comp and ($comp xor $$item{ContentEncoding})) { #TODO: add ability to edit infe entry in iinf to change encoding according to Compress option if set - $et->Warn("Can't currently change compression when rewriting $name in HEIC"); + $et->Warn("Can't currently change compression when rewriting $name in HEIC",1); } my $wasDeflated; if ($$item{ContentEncoding}) { diff --git a/bin/perl-Image-ExifTool.spec b/bin/perl-Image-ExifTool.spec index 9cfc5c5..f181624 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.89 +Version: 12.92 Release: 1 License: Artistic/GPL Group: Development/Libraries/Perl diff --git a/lib/exiftool_vendored/version.rb b/lib/exiftool_vendored/version.rb index a8edda1..69937af 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.89.0') + VERSION = Gem::Version.new('12.92.0') end