exiftool_vendored 13.37.0 → 13.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/bin/Changes +41 -3
 - data/bin/MANIFEST +7 -0
 - data/bin/META.json +1 -1
 - data/bin/META.yml +1 -1
 - data/bin/README +49 -47
 - data/bin/config_files/local_time.config +55 -0
 - data/bin/exiftool +83 -70
 - data/bin/lib/Image/ExifTool/BMP.pm +1 -1
 - data/bin/lib/Image/ExifTool/BuildTagLookup.pm +2 -2
 - data/bin/lib/Image/ExifTool/DJI.pm +256 -20
 - data/bin/lib/Image/ExifTool/DSF.pm +138 -0
 - data/bin/lib/Image/ExifTool/EXE.pm +3 -1
 - data/bin/lib/Image/ExifTool/Font.pm +386 -118
 - data/bin/lib/Image/ExifTool/Geolocation.pm +10 -7
 - data/bin/lib/Image/ExifTool/Geotag.pm +21 -2
 - data/bin/lib/Image/ExifTool/GoPro.pm +6 -3
 - data/bin/lib/Image/ExifTool/Google.pm +16 -6
 - data/bin/lib/Image/ExifTool/ID3.pm +11 -10
 - data/bin/lib/Image/ExifTool/LNK.pm +63 -2
 - data/bin/lib/Image/ExifTool/M2TS.pm +32 -23
 - data/bin/lib/Image/ExifTool/MIEUnits.pod +1 -1
 - data/bin/lib/Image/ExifTool/OOXML.pm +3 -2
 - data/bin/lib/Image/ExifTool/Olympus.pm +3 -1
 - data/bin/lib/Image/ExifTool/Pentax.pm +7 -2
 - data/bin/lib/Image/ExifTool/QuickTime.pm +3 -3
 - data/bin/lib/Image/ExifTool/QuickTimeStream.pl +44 -35
 - data/bin/lib/Image/ExifTool/Sony.pm +19 -14
 - data/bin/lib/Image/ExifTool/TagLookup.pm +35 -1
 - data/bin/lib/Image/ExifTool/TagNames.pod +1383 -1217
 - data/bin/lib/Image/ExifTool/WavPack.pm +144 -0
 - data/bin/lib/Image/ExifTool/XMP.pm +12 -7
 - data/bin/lib/Image/ExifTool/XMP2.pl +11 -5
 - data/bin/lib/Image/ExifTool.pm +46 -26
 - data/bin/lib/Image/ExifTool.pod +64 -56
 - data/bin/perl-Image-ExifTool.spec +47 -46
 - data/lib/exiftool_vendored/version.rb +1 -1
 - metadata +4 -1
 
| 
         @@ -20,6 +20,7 @@ 
     | 
|
| 
       20 
20 
     | 
    
         
             
            #               2024/11/26 - PH Also write GPSMeasureMode and GPSDOP
         
     | 
| 
       21 
21 
     | 
    
         
             
            #               2024/11/05 - PH Added support for Google Maps "Export timeline data"
         
     | 
| 
       22 
22 
     | 
    
         
             
            #                               JSON format
         
     | 
| 
      
 23 
     | 
    
         
            +
            #               2025/09/22 - PH Added ability to read Columbus CSV  log files
         
     | 
| 
       23 
24 
     | 
    
         
             
            #
         
     | 
| 
       24 
25 
     | 
    
         
             
            # References:   1) http://www.topografix.com/GPX/1/1/
         
     | 
| 
       25 
26 
     | 
    
         
             
            #               2) http://www.gpsinformation.org/dale/nmea.htm#GSA
         
     | 
| 
         @@ -34,7 +35,7 @@ use vars qw($VERSION); 
     | 
|
| 
       34 
35 
     | 
    
         
             
            use Image::ExifTool qw(:Public);
         
     | 
| 
       35 
36 
     | 
    
         
             
            use Image::ExifTool::GPS;
         
     | 
| 
       36 
37 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
            $VERSION = '1. 
     | 
| 
      
 38 
     | 
    
         
            +
            $VERSION = '1.83';
         
     | 
| 
       38 
39 
     | 
    
         | 
| 
       39 
40 
     | 
    
         
             
            sub JITTER() { return 2 }       # maximum time jitter
         
     | 
| 
       40 
41 
     | 
    
         | 
| 
         @@ -1344,6 +1345,23 @@ Category:       foreach $category (qw{pos track alt orient atemp err dop}) { 
     | 
|
| 
       1344 
1345 
     | 
    
         
             
                        if (defined $dop) {
         
     | 
| 
       1345 
1346 
     | 
    
         
             
                            $et->SetNewValue(GPSMeasureMode => $mm, %opts);
         
     | 
| 
       1346 
1347 
     | 
    
         
             
                            $et->SetNewValue(GPSDOP => $dop, %opts);
         
     | 
| 
      
 1348 
     | 
    
         
            +
                            # also set GPSHPositioningError if specified
         
     | 
| 
      
 1349 
     | 
    
         
            +
                            my $hposErr = $$et{OPTIONS}{GeoHPosErr};
         
     | 
| 
      
 1350 
     | 
    
         
            +
                            if ($hposErr) {
         
     | 
| 
      
 1351 
     | 
    
         
            +
                                $hposErr =~ s/gpsdop/GPSDOP/i;
         
     | 
| 
      
 1352 
     | 
    
         
            +
                                my $GPSDOP = $dop;
         
     | 
| 
      
 1353 
     | 
    
         
            +
                                local $SIG{'__WARN__'} = \&Image::ExifTool::SetWarning;
         
     | 
| 
      
 1354 
     | 
    
         
            +
                                undef $Image::ExifTool::evalWarning;
         
     | 
| 
      
 1355 
     | 
    
         
            +
                                #### eval GeoHPosErr ($GPSDOP)
         
     | 
| 
      
 1356 
     | 
    
         
            +
                                $hposErr = eval $hposErr;
         
     | 
| 
      
 1357 
     | 
    
         
            +
                                my $err = Image::ExifTool::GetWarning() || $@;
         
     | 
| 
      
 1358 
     | 
    
         
            +
                                if ($err) {
         
     | 
| 
      
 1359 
     | 
    
         
            +
                                    $err = Image::ExifTool::CleanWarning($err);
         
     | 
| 
      
 1360 
     | 
    
         
            +
                                    $et->Warn("Error calculating GPSHPositioningError: $err", 1);
         
     | 
| 
      
 1361 
     | 
    
         
            +
                                } else {
         
     | 
| 
      
 1362 
     | 
    
         
            +
                                    $et->SetNewValue(GPSHPositioningError => $hposErr, %opts);
         
     | 
| 
      
 1363 
     | 
    
         
            +
                                }
         
     | 
| 
      
 1364 
     | 
    
         
            +
                            }
         
     | 
| 
       1347 
1365 
     | 
    
         
             
                        }
         
     | 
| 
       1348 
1366 
     | 
    
         
             
                    }
         
     | 
| 
       1349 
1367 
     | 
    
         
             
                    unless ($xmp) {
         
     | 
| 
         @@ -1557,7 +1575,8 @@ This module loads GPS track logs, interpolates to determine position based 
     | 
|
| 
       1557 
1575 
     | 
    
         
             
            on time, and sets new GPS values for geotagging images.  Currently supported
         
     | 
| 
       1558 
1576 
     | 
    
         
             
            formats are GPX, NMEA RMC/GGA/GLL/GSA/ZDA, KML, IGC, Garmin XML and TCX,
         
     | 
| 
       1559 
1577 
     | 
    
         
             
            Magellan PMGNTRK, Honeywell PTNTHPR, Bramor gEO, Winplus Beacon text,
         
     | 
| 
       1560 
     | 
    
         
            -
            GPS/IMU CSV, DJI CSV 
     | 
| 
      
 1578 
     | 
    
         
            +
            GPS/IMU CSV, DJI/Columbus/ExifTool CSV format and 3 different Google JSON
         
     | 
| 
      
 1579 
     | 
    
         
            +
            formats.
         
     | 
| 
       1561 
1580 
     | 
    
         | 
| 
       1562 
1581 
     | 
    
         
             
            Methods in this module should not be called directly.  Instead, the Geotag
         
     | 
| 
       1563 
1582 
     | 
    
         
             
            feature is accessed by writing the values of the ExifTool Geotag, Geosync
         
     | 
| 
         @@ -17,7 +17,7 @@ use vars qw($VERSION); 
     | 
|
| 
       17 
17 
     | 
    
         
             
            use Image::ExifTool qw(:DataAccess :Utils);
         
     | 
| 
       18 
18 
     | 
    
         
             
            use Image::ExifTool::QuickTime;
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
     | 
    
         
            -
            $VERSION = '1. 
     | 
| 
      
 20 
     | 
    
         
            +
            $VERSION = '1.15';
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
22 
     | 
    
         
             
            sub ProcessGoPro($$$);
         
     | 
| 
       23 
23 
     | 
    
         
             
            sub ProcessString($$$);
         
     | 
| 
         @@ -251,7 +251,8 @@ my %noYes = ( N => 'No', Y => 'Yes' ); 
     | 
|
| 
       251 
251 
     | 
    
         
             
                    Notes => 'gyroscope readings in rad/s',
         
     | 
| 
       252 
252 
     | 
    
         
             
                    Binary => 1,
         
     | 
| 
       253 
253 
     | 
    
         
             
                },
         
     | 
| 
       254 
     | 
    
         
            -
                 
     | 
| 
      
 254 
     | 
    
         
            +
                LOGS => 'HealthLogs',
         
     | 
| 
      
 255 
     | 
    
         
            +
                HCTL => 'HorizonControl', #3
         
     | 
| 
       255 
256 
     | 
    
         
             
                HDRV => { Name => 'HDRVideo', PrintConv => \%noYes }, #3/PH (NC)
         
     | 
| 
       256 
257 
     | 
    
         
             
              # HFLG (APP6) - seen: 0
         
     | 
| 
       257 
258 
     | 
    
         
             
                HSGT => 'HindsightSettings', #3
         
     | 
| 
         @@ -409,6 +410,7 @@ my %noYes = ( N => 'No', Y => 'Yes' ); 
     | 
|
| 
       409 
410 
     | 
    
         
             
                },
         
     | 
| 
       410 
411 
     | 
    
         
             
              # TOCK => { Name => 'OutTime', Unknown => 1, ValueConv => '$val/1000' }, #1 (gpmd)
         
     | 
| 
       411 
412 
     | 
    
         
             
                TSMP => { Name => 'TotalSamples', Unknown => 1 }, #2 (gpmd)
         
     | 
| 
      
 413 
     | 
    
         
            +
                TIMO => 'TimeOffset',
         
     | 
| 
       412 
414 
     | 
    
         
             
                TYPE => { Name => 'StructureType', Unknown => 1 }, #2 (gpmd,GPMF - eg 'LLLllfFff', fmt c)
         
     | 
| 
       413 
415 
     | 
    
         
             
                TZON => { # (GPMF) - seen: 60 (fmt s)
         
     | 
| 
       414 
416 
     | 
    
         
             
                    Name => 'TimeZone',
         
     | 
| 
         @@ -469,7 +471,8 @@ my %noYes = ( N => 'No', Y => 'Yes' ); 
     | 
|
| 
       469 
471 
     | 
    
         
             
                AALP => { Name => 'AudioLevel', Notes => 'dBFS' },
         
     | 
| 
       470 
472 
     | 
    
         
             
                GPSA => 'GPSAltitudeSystem', # (eg. 'MSLV')
         
     | 
| 
       471 
473 
     | 
    
         
             
                GRAV => { Name => 'GravityVector', Binary => 1 },
         
     | 
| 
       472 
     | 
    
         
            -
                 
     | 
| 
      
 474 
     | 
    
         
            +
                # DISP - Disparity track
         
     | 
| 
      
 475 
     | 
    
         
            +
                HUES => 'PredominantHue',
         
     | 
| 
       473 
476 
     | 
    
         
             
                IORI => { Name => 'ImageOrientation', Binary => 1, Notes => 'quaternions 0-1' },
         
     | 
| 
       474 
477 
     | 
    
         
             
                # LRVO - ? Part of LRV Frame Skip
         
     | 
| 
       475 
478 
     | 
    
         
             
                # LRVS - ? Part of LRV Frame Skip
         
     | 
| 
         @@ -512,11 +512,20 @@ my %sAppInfo = ( 
     | 
|
| 
       512 
512 
     | 
    
         
             
                GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
         
     | 
| 
       513 
513 
     | 
    
         
             
                TAG_PREFIX => 'HDRPlusMakerNote',
         
     | 
| 
       514 
514 
     | 
    
         
             
                PROCESS_PROC => \&ProcessHDRP,
         
     | 
| 
       515 
     | 
    
         
            -
                VARS => { 
     | 
| 
      
 515 
     | 
    
         
            +
                VARS => {   
         
     | 
| 
      
 516 
     | 
    
         
            +
                    ID_FMT => 'str',
         
     | 
| 
      
 517 
     | 
    
         
            +
                    SORT_PROC => sub {
         
     | 
| 
      
 518 
     | 
    
         
            +
                        my ($a,$b) = @_;
         
     | 
| 
      
 519 
     | 
    
         
            +
                        $a =~ s/(\d+)/sprintf("%.3d",$1)/eg;
         
     | 
| 
      
 520 
     | 
    
         
            +
                        $b =~ s/(\d+)/sprintf("%.3d",$1)/eg;
         
     | 
| 
      
 521 
     | 
    
         
            +
                        return $a cmp $b;
         
     | 
| 
      
 522 
     | 
    
         
            +
                    },
         
     | 
| 
      
 523 
     | 
    
         
            +
                },
         
     | 
| 
       516 
524 
     | 
    
         
             
                NOTES => q{
         
     | 
| 
       517 
525 
     | 
    
         
             
                    Google protobuf-format HDR-Plus maker notes.  Tag ID's are hierarchical
         
     | 
| 
       518 
526 
     | 
    
         
             
                    protobuf field numbers.  Stored as base64-encoded, encrypted and gzipped
         
     | 
| 
       519 
     | 
    
         
            -
                    Protobuf data.
         
     | 
| 
      
 527 
     | 
    
         
            +
                    Protobuf data.  Much of this metadata is still unknown, but is extracted
         
     | 
| 
      
 528 
     | 
    
         
            +
                    using the Unknown option.
         
     | 
| 
       520 
529 
     | 
    
         
             
                },
         
     | 
| 
       521 
530 
     | 
    
         
             
                '1-1' => 'ImageName',
         
     | 
| 
       522 
531 
     | 
    
         
             
                '1-2' => { Name => 'ImageData',   Format => 'undef', Binary => 1 },
         
     | 
| 
         @@ -693,8 +702,8 @@ sub ProcessHDRP($$$) 
     | 
|
| 
       693 
702 
     | 
    
         
             
                my $i = 0;
         
     | 
| 
       694 
703 
     | 
    
         
             
                while ($i < @words) {
         
     | 
| 
       695 
704 
     | 
    
         
             
                    # (messy, but handle all 64-bit arithmetic with 32-bit backward
         
     | 
| 
       696 
     | 
    
         
            -
                    #  compatibility  
     | 
| 
       697 
     | 
    
         
            -
                    # rotate the key
         
     | 
| 
      
 705 
     | 
    
         
            +
                    #  compatibility, so no bit operations on any number > 0xffffffff)
         
     | 
| 
      
 706 
     | 
    
         
            +
                    # rotate the key for each new 64-bit word
         
     | 
| 
       698 
707 
     | 
    
         
             
                    # $key ^= $key >> 12;
         
     | 
| 
       699 
708 
     | 
    
         
             
                    $lo ^= $lo >> 12 | ($hi & 0xfff) << 20;
         
     | 
| 
       700 
709 
     | 
    
         
             
                    $hi ^= $hi >> 12;
         
     | 
| 
         @@ -715,7 +724,8 @@ sub ProcessHDRP($$$) 
     | 
|
| 
       715 
724 
     | 
    
         
             
                            $c[$j+$k] += $a[$j] * $b[$k];
         
     | 
| 
       716 
725 
     | 
    
         
             
                        }
         
     | 
| 
       717 
726 
     | 
    
         
             
                    }
         
     | 
| 
       718 
     | 
    
         
            -
                    # (we only  
     | 
| 
      
 727 
     | 
    
         
            +
                    # (we will only retain the low 64-bits of the key, so
         
     | 
| 
      
 728 
     | 
    
         
            +
                    #  don't bother finishing the calculation of the upper bits)
         
     | 
| 
       719 
729 
     | 
    
         
             
                    for ($j=6; $j>=3; --$j) {
         
     | 
| 
       720 
730 
     | 
    
         
             
                        while ($c[$j] > 0xffffffff) {
         
     | 
| 
       721 
731 
     | 
    
         
             
                            ++$c[$j-2];
         
     | 
| 
         @@ -726,7 +736,7 @@ sub ProcessHDRP($$$) 
     | 
|
| 
       726 
736 
     | 
    
         
             
                    }
         
     | 
| 
       727 
737 
     | 
    
         
             
                    $hi = ($c[3] << 16) + $c[4];
         
     | 
| 
       728 
738 
     | 
    
         
             
                    $lo = ($c[5] << 16) + $c[6];
         
     | 
| 
       729 
     | 
    
         
            -
                    # apply the  
     | 
| 
      
 739 
     | 
    
         
            +
                    # apply the key to this 64-bit word
         
     | 
| 
       730 
740 
     | 
    
         
             
                    $words[$i++] ^= $lo;
         
     | 
| 
       731 
741 
     | 
    
         
             
                    $words[$i++] ^= $hi;
         
     | 
| 
       732 
742 
     | 
    
         
             
                }
         
     | 
| 
         @@ -18,7 +18,7 @@ use strict; 
     | 
|
| 
       18 
18 
     | 
    
         
             
            use vars qw($VERSION);
         
     | 
| 
       19 
19 
     | 
    
         
             
            use Image::ExifTool qw(:DataAccess :Utils);
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
            $VERSION = '1. 
     | 
| 
      
 21 
     | 
    
         
            +
            $VERSION = '1.64';
         
     | 
| 
       22 
22 
     | 
    
         | 
| 
       23 
23 
     | 
    
         
             
            sub ProcessID3v2($$$);
         
     | 
| 
       24 
24 
     | 
    
         
             
            sub ProcessPrivate($$$);
         
     | 
| 
         @@ -79,13 +79,13 @@ my %userTagName = ( 
     | 
|
| 
       79 
79 
     | 
    
         
             
                VARS => { ID_FMT => 'none' },
         
     | 
| 
       80 
80 
     | 
    
         
             
                PROCESS_PROC => \&ProcessID3Dir, # (used to process 'id3 ' chunk in WAV files)
         
     | 
| 
       81 
81 
     | 
    
         
             
                NOTES => q{
         
     | 
| 
       82 
     | 
    
         
            -
                    ExifTool extracts ID3 and Lyrics3 information from MP3, MPEG, WAV, AIFF,
         
     | 
| 
       83 
     | 
    
         
            -
                    OGG, FLAC, APE, MPC and RealAudio files.  ID3v2 tags which support 
     | 
| 
       84 
     | 
    
         
            -
                    languages (eg. Comment and Lyrics) are extracted by specifying the 
     | 
| 
       85 
     | 
    
         
            -
                    followed by a dash ('-'), then a 3-character ISO 639-2 language 
     | 
| 
       86 
     | 
    
         
            -
                    "Comment-spa"). See L<https://id3.org/> for the official ID3 
     | 
| 
       87 
     | 
    
         
            -
                    and L<http://www.loc.gov/standards/iso639-2/php/code_list.php> 
     | 
| 
       88 
     | 
    
         
            -
                    ISO 639-2 language codes.
         
     | 
| 
      
 82 
     | 
    
         
            +
                    ExifTool extracts ID3 and Lyrics3 information from MP3, MPEG, WAV, WV, AIFF,
         
     | 
| 
      
 83 
     | 
    
         
            +
                    OGG, FLAC, APE, DSF, MPC and RealAudio files.  ID3v2 tags which support
         
     | 
| 
      
 84 
     | 
    
         
            +
                    multiple languages (eg. Comment and Lyrics) are extracted by specifying the
         
     | 
| 
      
 85 
     | 
    
         
            +
                    tag name, followed by a dash ('-'), then a 3-character ISO 639-2 language
         
     | 
| 
      
 86 
     | 
    
         
            +
                    code (eg. "Comment-spa"). See L<https://id3.org/> for the official ID3
         
     | 
| 
      
 87 
     | 
    
         
            +
                    specification and L<http://www.loc.gov/standards/iso639-2/php/code_list.php>
         
     | 
| 
      
 88 
     | 
    
         
            +
                    for a list of ISO 639-2 language codes.
         
     | 
| 
       89 
89 
     | 
    
         
             
                },
         
     | 
| 
       90 
90 
     | 
    
         
             
                ID3v1 => {
         
     | 
| 
       91 
91 
     | 
    
         
             
                    Name => 'ID3v1',
         
     | 
| 
         @@ -1437,6 +1437,7 @@ sub ProcessID3($$) 
     | 
|
| 
       1437 
1437 
     | 
    
         | 
| 
       1438 
1438 
     | 
    
         
             
                # allow this to be called with either RAF or DataPt
         
     | 
| 
       1439 
1439 
     | 
    
         
             
                my $raf = $$dirInfo{RAF} || File::RandomAccess->new($$dirInfo{DataPt});
         
     | 
| 
      
 1440 
     | 
    
         
            +
                my $dataPos = $$dirInfo{DataPos} || 0;
         
     | 
| 
       1440 
1441 
     | 
    
         
             
                my ($buff, %id3Header, %id3Trailer, $hBuff, $tBuff, $eBuff, $tagTablePtr);
         
     | 
| 
       1441 
1442 
     | 
    
         
             
                my $rtnVal = 0;
         
     | 
| 
       1442 
1443 
     | 
    
         
             
                my $hdrEnd = 0;
         
     | 
| 
         @@ -1486,7 +1487,7 @@ sub ProcessID3($$) 
     | 
|
| 
       1486 
1487 
     | 
    
         
             
                    }
         
     | 
| 
       1487 
1488 
     | 
    
         
             
                    %id3Header = (
         
     | 
| 
       1488 
1489 
     | 
    
         
             
                        DataPt   => \$hBuff,
         
     | 
| 
       1489 
     | 
    
         
            -
                        DataPos  => $pos,
         
     | 
| 
      
 1490 
     | 
    
         
            +
                        DataPos  => $dataPos + $pos,
         
     | 
| 
       1490 
1491 
     | 
    
         
             
                        DirStart => 0,
         
     | 
| 
       1491 
1492 
     | 
    
         
             
                        DirLen   => length($hBuff),
         
     | 
| 
       1492 
1493 
     | 
    
         
             
                        Version  => $vers,
         
     | 
| 
         @@ -1511,7 +1512,7 @@ sub ProcessID3($$) 
     | 
|
| 
       1511 
1512 
     | 
    
         
             
                    $trailSize = 128;
         
     | 
| 
       1512 
1513 
     | 
    
         
             
                    %id3Trailer = (
         
     | 
| 
       1513 
1514 
     | 
    
         
             
                        DataPt   => \$tBuff,
         
     | 
| 
       1514 
     | 
    
         
            -
                        DataPos  => $raf->Tell() - 128,
         
     | 
| 
      
 1515 
     | 
    
         
            +
                        DataPos  => $dataPos + $raf->Tell() - 128,
         
     | 
| 
       1515 
1516 
     | 
    
         
             
                        DirStart => 0,
         
     | 
| 
       1516 
1517 
     | 
    
         
             
                        DirLen   => length($tBuff),
         
     | 
| 
       1517 
1518 
     | 
    
         
             
                    );
         
     | 
| 
         @@ -4,6 +4,7 @@ 
     | 
|
| 
       4 
4 
     | 
    
         
             
            # Description:  Read meta information from MS Shell Link files
         
     | 
| 
       5 
5 
     | 
    
         
             
            #
         
     | 
| 
       6 
6 
     | 
    
         
             
            # Revisions:    2009/09/19 - P. Harvey Created
         
     | 
| 
      
 7 
     | 
    
         
            +
            #               2025/10/20 - PH Added .URL file support
         
     | 
| 
       7 
8 
     | 
    
         
             
            #
         
     | 
| 
       8 
9 
     | 
    
         
             
            # References:   1) http://msdn.microsoft.com/en-us/library/dd871305(PROT.10).aspx
         
     | 
| 
       9 
10 
     | 
    
         
             
            #               2) http://www.i2s-lab.com/Papers/The_Windows_Shortcut_File_Format.pdf
         
     | 
| 
         @@ -17,7 +18,7 @@ use vars qw($VERSION); 
     | 
|
| 
       17 
18 
     | 
    
         
             
            use Image::ExifTool qw(:DataAccess :Utils);
         
     | 
| 
       18 
19 
     | 
    
         
             
            use Image::ExifTool::Microsoft;
         
     | 
| 
       19 
20 
     | 
    
         | 
| 
       20 
     | 
    
         
            -
            $VERSION = '1. 
     | 
| 
      
 21 
     | 
    
         
            +
            $VERSION = '1.12';
         
     | 
| 
       21 
22 
     | 
    
         | 
| 
       22 
23 
     | 
    
         
             
            sub ProcessItemID($$$);
         
     | 
| 
       23 
24 
     | 
    
         
             
            sub ProcessLinkInfo($$$);
         
     | 
| 
         @@ -447,6 +448,39 @@ sub ProcessLinkInfo($$$); 
     | 
|
| 
       447 
448 
     | 
    
         
             
                },
         
     | 
| 
       448 
449 
     | 
    
         
             
            );
         
     | 
| 
       449 
450 
     | 
    
         | 
| 
      
 451 
     | 
    
         
            +
            %Image::ExifTool::LNK::INI = (
         
     | 
| 
      
 452 
     | 
    
         
            +
                GROUPS => { 2 => 'Document' },
         
     | 
| 
      
 453 
     | 
    
         
            +
                VARS => { ID_FMT => 'none' },
         
     | 
| 
      
 454 
     | 
    
         
            +
                NOTES => 'Tags found in INI-format Windows .URL files.',
         
     | 
| 
      
 455 
     | 
    
         
            +
                URL         => { },
         
     | 
| 
      
 456 
     | 
    
         
            +
                IconFile    => { },
         
     | 
| 
      
 457 
     | 
    
         
            +
                IconIndex   => { },
         
     | 
| 
      
 458 
     | 
    
         
            +
                WorkingDirectory => { },
         
     | 
| 
      
 459 
     | 
    
         
            +
                HotKey      => { },
         
     | 
| 
      
 460 
     | 
    
         
            +
                ShowCommand => { PrintConv => { 1 => 'Normal', 2 => 'Minimized', 3 => 'Maximized' } },
         
     | 
| 
      
 461 
     | 
    
         
            +
                Modified    => {
         
     | 
| 
      
 462 
     | 
    
         
            +
                    Groups => { 2 => 'Time' },
         
     | 
| 
      
 463 
     | 
    
         
            +
                    Format => 'int64u',
         
     | 
| 
      
 464 
     | 
    
         
            +
                    Groups => { 2 => 'Time' },
         
     | 
| 
      
 465 
     | 
    
         
            +
                    # convert time from 100-ns intervals since Jan 1, 1601 (NC)
         
     | 
| 
      
 466 
     | 
    
         
            +
                    RawConv => q{
         
     | 
| 
      
 467 
     | 
    
         
            +
                        my $dat = pack('H*', $val);
         
     | 
| 
      
 468 
     | 
    
         
            +
                        return undef if length $dat < 8;
         
     | 
| 
      
 469 
     | 
    
         
            +
                        my ($lo, $hi) = unpack('V2', $dat);
         
     | 
| 
      
 470 
     | 
    
         
            +
                        return undef unless $lo or $hi;
         
     | 
| 
      
 471 
     | 
    
         
            +
                        return $hi * 4294967296 + $lo;
         
     | 
| 
      
 472 
     | 
    
         
            +
                    },
         
     | 
| 
      
 473 
     | 
    
         
            +
                    ValueConv => '$val=$val/1e7-11644473600; ConvertUnixTime($val,1)',
         
     | 
| 
      
 474 
     | 
    
         
            +
                    PrintConv => '$self->ConvertDateTime($val)',
         
     | 
| 
      
 475 
     | 
    
         
            +
                },
         
     | 
| 
      
 476 
     | 
    
         
            +
                Author      => { Groups => { 2 => 'Author' } },
         
     | 
| 
      
 477 
     | 
    
         
            +
                WhatsNew    => { },
         
     | 
| 
      
 478 
     | 
    
         
            +
                Comment     => { },
         
     | 
| 
      
 479 
     | 
    
         
            +
                Desc        => { },
         
     | 
| 
      
 480 
     | 
    
         
            +
                Roamed      => { Notes => '1 if synced across multiple devices' },
         
     | 
| 
      
 481 
     | 
    
         
            +
                IDList      => { },
         
     | 
| 
      
 482 
     | 
    
         
            +
            );
         
     | 
| 
      
 483 
     | 
    
         
            +
             
     | 
| 
       450 
484 
     | 
    
         
             
            #------------------------------------------------------------------------------
         
     | 
| 
       451 
485 
     | 
    
         
             
            # Extract null-terminated ASCII or Unicode string from buffer
         
     | 
| 
       452 
486 
     | 
    
         
             
            # Inputs: 0) buffer ref, 1) start position, 2) flag for unicode string
         
     | 
| 
         @@ -588,6 +622,27 @@ sub ProcessLinkInfo($$$) 
     | 
|
| 
       588 
622 
     | 
    
         
             
                return 1;
         
     | 
| 
       589 
623 
     | 
    
         
             
            }
         
     | 
| 
       590 
624 
     | 
    
         | 
| 
      
 625 
     | 
    
         
            +
            #------------------------------------------------------------------------------
         
     | 
| 
      
 626 
     | 
    
         
            +
            # Extract information from a INI-format file
         
     | 
| 
      
 627 
     | 
    
         
            +
            # Inputs: 0) ExifTool object reference, 1) dirInfo reference
         
     | 
| 
      
 628 
     | 
    
         
            +
            # Returns: 1 on success, 0 if this wasn't a valid INI file
         
     | 
| 
      
 629 
     | 
    
         
            +
            sub ProcessINI($$)
         
     | 
| 
      
 630 
     | 
    
         
            +
            {
         
     | 
| 
      
 631 
     | 
    
         
            +
                my ($et, $dirInfo) = @_;
         
     | 
| 
      
 632 
     | 
    
         
            +
                my $raf = $$dirInfo{RAF};
         
     | 
| 
      
 633 
     | 
    
         
            +
                my $buff;
         
     | 
| 
      
 634 
     | 
    
         
            +
                local $/ = "\x0d\x0a";
         
     | 
| 
      
 635 
     | 
    
         
            +
                my $tagTablePtr = GetTagTable('Image::ExifTool::LNK::INI');
         
     | 
| 
      
 636 
     | 
    
         
            +
                while ($raf->ReadLine($buff)) {
         
     | 
| 
      
 637 
     | 
    
         
            +
                    if ($buff =~ /^\[(.*?)\]/) {
         
     | 
| 
      
 638 
     | 
    
         
            +
                        $et->VPrint(0, "$1 section:\n");
         
     | 
| 
      
 639 
     | 
    
         
            +
                    } elsif ($buff =~ /^\s*(\w+)=(.*)\x0d\x0a$/) {
         
     | 
| 
      
 640 
     | 
    
         
            +
                        $et->HandleTag($tagTablePtr, $1, $2, MakeTagInfo => 1);
         
     | 
| 
      
 641 
     | 
    
         
            +
                    }
         
     | 
| 
      
 642 
     | 
    
         
            +
                }
         
     | 
| 
      
 643 
     | 
    
         
            +
                return 1;
         
     | 
| 
      
 644 
     | 
    
         
            +
            }
         
     | 
| 
      
 645 
     | 
    
         
            +
             
     | 
| 
       591 
646 
     | 
    
         
             
            #------------------------------------------------------------------------------
         
     | 
| 
       592 
647 
     | 
    
         
             
            # Extract information from a MS Shell Link (Windows shortcut) file
         
     | 
| 
       593 
648 
     | 
    
         
             
            # Inputs: 0) ExifTool object reference, 1) dirInfo reference
         
     | 
| 
         @@ -600,7 +655,13 @@ sub ProcessLNK($$) 
     | 
|
| 
       600 
655 
     | 
    
         | 
| 
       601 
656 
     | 
    
         
             
                # read LNK file header
         
     | 
| 
       602 
657 
     | 
    
         
             
                $raf->Read($buff, 0x4c) == 0x4c or return 0;
         
     | 
| 
       603 
     | 
    
         
            -
                $buff =~ /^.{4}\x01\x14\x02\0{5}\xc0\0{6}\x46/s  
     | 
| 
      
 658 
     | 
    
         
            +
                unless ($buff =~ /^.{4}\x01\x14\x02\0{5}\xc0\0{6}\x46/s) {
         
     | 
| 
      
 659 
     | 
    
         
            +
                    # check for INI-format LNK file (eg. .URL file)
         
     | 
| 
      
 660 
     | 
    
         
            +
                    return undef unless $buff =~ /^\[[InternetShortcut\][\x0d\x0a]/;
         
     | 
| 
      
 661 
     | 
    
         
            +
                    $raf->Seek(0,0) or return 0;
         
     | 
| 
      
 662 
     | 
    
         
            +
                    $et->SetFileType('URL', 'application/x-mswinurl');
         
     | 
| 
      
 663 
     | 
    
         
            +
                    return ProcessINI($et, $dirInfo);
         
     | 
| 
      
 664 
     | 
    
         
            +
                };
         
     | 
| 
       604 
665 
     | 
    
         
             
                $len = unpack('V', $buff);
         
     | 
| 
       605 
666 
     | 
    
         
             
                $len >= 0x4c or return 0;
         
     | 
| 
       606 
667 
     | 
    
         
             
                if ($len > 0x4c) {
         
     | 
| 
         @@ -32,7 +32,7 @@ use strict; 
     | 
|
| 
       32 
32 
     | 
    
         
             
            use vars qw($VERSION);
         
     | 
| 
       33 
33 
     | 
    
         
             
            use Image::ExifTool qw(:DataAccess :Utils);
         
     | 
| 
       34 
34 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
            $VERSION = '1. 
     | 
| 
      
 35 
     | 
    
         
            +
            $VERSION = '1.31';
         
     | 
| 
       36 
36 
     | 
    
         | 
| 
       37 
37 
     | 
    
         
             
            # program map table "stream_type" lookup (ref 6/1/9)
         
     | 
| 
       38 
38 
     | 
    
         
             
            my %streamType = (
         
     | 
| 
         @@ -322,7 +322,7 @@ sub ParsePID($$$$$) 
     | 
|
| 
       322 
322 
     | 
    
         
             
                    if ($$et{OPTIONS}{ExtractEmbedded}) {
         
     | 
| 
       323 
323 
     | 
    
         
             
                        $more = 1;
         
     | 
| 
       324 
324 
     | 
    
         
             
                    } elsif (not $$et{OPTIONS}{Validate}) {
         
     | 
| 
       325 
     | 
    
         
            -
                        $et->Warn('The ExtractEmbedded option may find more tags in the video data', 
     | 
| 
      
 325 
     | 
    
         
            +
                        $et->Warn('The ExtractEmbedded option may find more tags in the video data',7);
         
     | 
| 
       326 
326 
     | 
    
         
             
                    }
         
     | 
| 
       327 
327 
     | 
    
         
             
                } elsif ($type == 0x81 or $type == 0x87 or $type == 0x91) {
         
     | 
| 
       328 
328 
     | 
    
         
             
                    # AC-3 audio
         
     | 
| 
         @@ -557,31 +557,40 @@ sub ProcessM2TS($$) 
     | 
|
| 
       557 
557 
     | 
    
         
             
            {
         
     | 
| 
       558 
558 
     | 
    
         
             
                my ($et, $dirInfo) = @_;
         
     | 
| 
       559 
559 
     | 
    
         
             
                my $raf = $$dirInfo{RAF};
         
     | 
| 
       560 
     | 
    
         
            -
                my ($buff, $ 
     | 
| 
      
 560 
     | 
    
         
            +
                my ($buff, $j, $eof, $pLen, $readSize);
         
     | 
| 
       561 
561 
     | 
    
         
             
                my (%pmt, %pidType, %data, %sectLen, %packLen, %fromStart);
         
     | 
| 
       562 
562 
     | 
    
         
             
                my ($startTime, $endTime, $fwdTime, $backScan, $maxBack);
         
     | 
| 
       563 
563 
     | 
    
         
             
                my $verbose = $et->Options('Verbose');
         
     | 
| 
       564 
564 
     | 
    
         
             
                my $out = $et->Options('TextOut');
         
     | 
| 
       565 
565 
     | 
    
         | 
| 
       566 
     | 
    
         
            -
                # read  
     | 
| 
       567 
     | 
    
         
            -
                return 0 unless $raf->Read($buff,  
     | 
| 
      
 566 
     | 
    
         
            +
                # read enough to guarantee 2 sync bytes
         
     | 
| 
      
 567 
     | 
    
         
            +
                return 0 unless $raf->Read($buff, 383) == 383;
         
     | 
| 
       568 
568 
     | 
    
         
             
                # test for magic number (sync byte is the only thing we can safely check)
         
     | 
| 
       569 
     | 
    
         
            -
                return 0 unless $buff =~ /^( 
     | 
| 
       570 
     | 
    
         
            -
                 
     | 
| 
       571 
     | 
    
         
            -
             
     | 
| 
       572 
     | 
    
         
            -
             
     | 
| 
       573 
     | 
    
         
            -
                 
     | 
| 
       574 
     | 
    
         
            -
             
     | 
| 
       575 
     | 
    
         
            -
             
     | 
| 
       576 
     | 
    
         
            -
             
     | 
| 
       577 
     | 
    
         
            -
             
     | 
| 
       578 
     | 
    
         
            -
             
     | 
| 
       579 
     | 
    
         
            -
             
     | 
| 
       580 
     | 
    
         
            -
             
     | 
| 
       581 
     | 
    
         
            -
             
     | 
| 
       582 
     | 
    
         
            -
                     
     | 
| 
      
 569 
     | 
    
         
            +
                return 0 unless $buff =~ /^(.{0,190}?)\x47(.{187}|.{191})\x47/s;
         
     | 
| 
      
 570 
     | 
    
         
            +
                my $tcLen = length($2) - 187; # (length of timecode = 0 or 4 bytes)
         
     | 
| 
      
 571 
     | 
    
         
            +
                my $start = length($1) - $tcLen;
         
     | 
| 
      
 572 
     | 
    
         
            +
                # we may need to try the validation twice to handle the edge case
         
     | 
| 
      
 573 
     | 
    
         
            +
                # where the first byte of a timecode is 0x47 and we were fooled
         
     | 
| 
      
 574 
     | 
    
         
            +
                # into thinking there was no timecode
         
     | 
| 
      
 575 
     | 
    
         
            +
            Try: for (;;) {
         
     | 
| 
      
 576 
     | 
    
         
            +
                    $start += 192 if $start < 0; # (if all or part of first timecode was missing)
         
     | 
| 
      
 577 
     | 
    
         
            +
                    $pLen = 188 + $tcLen;
         
     | 
| 
      
 578 
     | 
    
         
            +
                    $readSize = 64 * $pLen;      # size of our read buffer
         
     | 
| 
      
 579 
     | 
    
         
            +
                    $raf->Seek($start, 0);       # rewind to start
         
     | 
| 
      
 580 
     | 
    
         
            +
                    $raf->Read($buff, $readSize) >= $pLen * 4 or return 0;  # require at least 4 packets
         
     | 
| 
      
 581 
     | 
    
         
            +
                    # validate the sync byte in the next 3 packets
         
     | 
| 
      
 582 
     | 
    
         
            +
                    for ($j=1; $j<4; ++$j) {
         
     | 
| 
      
 583 
     | 
    
         
            +
                        next if substr($buff, $tcLen + $pLen * $j, 1) eq 'G'; # (0x47)
         
     | 
| 
      
 584 
     | 
    
         
            +
                        return 0 if $tcLen;
         
     | 
| 
      
 585 
     | 
    
         
            +
                        $tcLen = 4;
         
     | 
| 
      
 586 
     | 
    
         
            +
                        $start -= 4;
         
     | 
| 
      
 587 
     | 
    
         
            +
                        next Try;
         
     | 
| 
      
 588 
     | 
    
         
            +
                    }
         
     | 
| 
      
 589 
     | 
    
         
            +
                    last;   # success!
         
     | 
| 
       583 
590 
     | 
    
         
             
                }
         
     | 
| 
       584 
     | 
    
         
            -
                 
     | 
| 
      
 591 
     | 
    
         
            +
                # (use M2T instead of M2TS just as an indicator that there is no timecode)
         
     | 
| 
      
 592 
     | 
    
         
            +
                $et->SetFileType($tcLen ? 'M2TS' : 'M2T');
         
     | 
| 
      
 593 
     | 
    
         
            +
                $et->Warn("File doesn't begin with the start of a packet") if $start;
         
     | 
| 
       585 
594 
     | 
    
         
             
                SetByteOrder('MM');
         
     | 
| 
       586 
595 
     | 
    
         
             
                my $tagTablePtr = GetTagTable('Image::ExifTool::M2TS::Main');
         
     | 
| 
       587 
596 
     | 
    
         | 
| 
         @@ -667,7 +676,7 @@ sub ProcessM2TS($$) 
     | 
|
| 
       667 
676 
     | 
    
         
             
                    }
         
     | 
| 
       668 
677 
     | 
    
         
             
                    $pEnd += $pLen;
         
     | 
| 
       669 
678 
     | 
    
         
             
                    # decode the packet prefix
         
     | 
| 
       670 
     | 
    
         
            -
                    $pos += $ 
     | 
| 
      
 679 
     | 
    
         
            +
                    $pos += $tcLen;
         
     | 
| 
       671 
680 
     | 
    
         
             
                    my $prefix = unpack("x${pos}N", $buff); # (use unpack instead of Get32u for speed)
         
     | 
| 
       672 
681 
     | 
    
         
             
                    # validate sync byte
         
     | 
| 
       673 
682 
     | 
    
         
             
                    unless (($prefix & 0xff000000) == 0x47000000) {
         
     | 
| 
         @@ -685,9 +694,9 @@ sub ProcessM2TS($$) 
     | 
|
| 
       685 
694 
     | 
    
         
             
                    if ($verbose > 1) {
         
     | 
| 
       686 
695 
     | 
    
         
             
                        my $i = ($raf->Tell() - length($buff) + $pEnd) / $pLen - 1;
         
     | 
| 
       687 
696 
     | 
    
         
             
                        print  $out "Transport packet $i:\n";
         
     | 
| 
       688 
     | 
    
         
            -
                        $et->VerboseDump(\$buff, Len => $pLen, Addr => $i * $pLen, Start => $pos - $ 
     | 
| 
      
 697 
     | 
    
         
            +
                        $et->VerboseDump(\$buff, Len => $pLen, Addr => $i * $pLen, Start => $pos - $tcLen);
         
     | 
| 
       689 
698 
     | 
    
         
             
                        my $str = $pidName{$pid} ? " ($pidName{$pid})" : ' <not in Program Map Table!>';
         
     | 
| 
       690 
     | 
    
         
            -
                        printf $out "  Timecode:   0x%.4x\n", Get32u(\$buff, $pos - $ 
     | 
| 
      
 699 
     | 
    
         
            +
                        printf $out "  Timecode:   0x%.4x\n", Get32u(\$buff, $pos - $tcLen) if $pLen == 192;
         
     | 
| 
       691 
700 
     | 
    
         
             
                        printf $out "  Packet ID:  0x%.4x$str\n", $pid;
         
     | 
| 
       692 
701 
     | 
    
         
             
                        printf $out "  Start Flag: %s\n", $payload_unit_start_indicator ? 'Yes' : 'No';
         
     | 
| 
       693 
702 
     | 
    
         
             
                    }
         
     | 
| 
         @@ -172,7 +172,7 @@ strings. 
     | 
|
| 
       172 
172 
     | 
    
         
             
              hp_C        homeopathic potency of centesimal series (homeopathic potency)
         
     | 
| 
       173 
173 
     | 
    
         
             
              hp_X        homeopathic potency of decimal series (homeopathic potency)
         
     | 
| 
       174 
174 
     | 
    
         
             
              HPF         high power field (view area in microscope)
         
     | 
| 
       175 
     | 
    
         
            -
              Hz           
     | 
| 
      
 175 
     | 
    
         
            +
              Hz          Hertz (frequency)
         
     | 
| 
       176 
176 
     | 
    
         
             
              in          inch, international (length)
         
     | 
| 
       177 
177 
     | 
    
         
             
              in_br       inch, British (length)
         
     | 
| 
       178 
178 
     | 
    
         
             
              in_us       inch, U.S. (length)
         
     | 
| 
         @@ -14,7 +14,7 @@ use Image::ExifTool qw(:DataAccess :Utils); 
     | 
|
| 
       14 
14 
     | 
    
         
             
            use Image::ExifTool::XMP;
         
     | 
| 
       15 
15 
     | 
    
         
             
            use Image::ExifTool::ZIP;
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
            $VERSION = '1. 
     | 
| 
      
 17 
     | 
    
         
            +
            $VERSION = '1.10';
         
     | 
| 
       18 
18 
     | 
    
         | 
| 
       19 
19 
     | 
    
         
             
            # test for recognized OOXML document extensions
         
     | 
| 
       20 
20 
     | 
    
         
             
            my %isOOXML = (
         
     | 
| 
         @@ -27,6 +27,7 @@ my %isOOXML = ( 
     | 
|
| 
       27 
27 
     | 
    
         
             
                XLAM => 1,
         
     | 
| 
       28 
28 
     | 
    
         
             
                XLSX => 1,  XLSM => 1,  XLSB => 1,
         
     | 
| 
       29 
29 
     | 
    
         
             
                XLTX => 1,  XLTM => 1,
         
     | 
| 
      
 30 
     | 
    
         
            +
                VSDX => 1,
         
     | 
| 
       30 
31 
     | 
    
         
             
            );
         
     | 
| 
       31 
32 
     | 
    
         | 
| 
       32 
33 
     | 
    
         
             
            # generate reverse lookup for file type based on MIME
         
     | 
| 
         @@ -57,7 +58,7 @@ my @vectorVals; 
     | 
|
| 
       57 
58 
     | 
    
         
             
                VARS => { ID_FMT => 'none' },
         
     | 
| 
       58 
59 
     | 
    
         
             
                NOTES => q{
         
     | 
| 
       59 
60 
     | 
    
         
             
                    The Office Open XML (OOXML) format was introduced with Microsoft Office 2007
         
     | 
| 
       60 
     | 
    
         
            -
                    and is used by file types such as DOCX, PPTX and  
     | 
| 
      
 61 
     | 
    
         
            +
                    and is used by file types such as DOCX, PPTX, XLSX and VSDX.  These are
         
     | 
| 
       61 
62 
     | 
    
         
             
                    essentially ZIP archives containing XML files.  The table below lists some
         
     | 
| 
       62 
63 
     | 
    
         
             
                    tags which have been observed in OOXML documents, but ExifTool will extract
         
     | 
| 
       63 
64 
     | 
    
         
             
                    any tags found from XML files of the OOXML document properties ("docProps")
         
     | 
| 
         @@ -31,6 +31,7 @@ 
     | 
|
| 
       31 
31 
     | 
    
         
             
            #              25) Karsten Gieselmann private communication (OM series)
         
     | 
| 
       32 
32 
     | 
    
         
             
            #              IB) Iliah Borg private communication (LibRaw)
         
     | 
| 
       33 
33 
     | 
    
         
             
            #              NJ) Niels Kristian Bech Jensen private communication
         
     | 
| 
      
 34 
     | 
    
         
            +
            #              KG) Karsten Gieselmann private communication
         
     | 
| 
       34 
35 
     | 
    
         
             
            #------------------------------------------------------------------------------
         
     | 
| 
       35 
36 
     | 
    
         | 
| 
       36 
37 
     | 
    
         
             
            package Image::ExifTool::Olympus;
         
     | 
| 
         @@ -41,7 +42,7 @@ use Image::ExifTool qw(:DataAccess :Utils); 
     | 
|
| 
       41 
42 
     | 
    
         
             
            use Image::ExifTool::Exif;
         
     | 
| 
       42 
43 
     | 
    
         
             
            use Image::ExifTool::APP12;
         
     | 
| 
       43 
44 
     | 
    
         | 
| 
       44 
     | 
    
         
            -
            $VERSION = '2. 
     | 
| 
      
 45 
     | 
    
         
            +
            $VERSION = '2.92';
         
     | 
| 
       45 
46 
     | 
    
         | 
| 
       46 
47 
     | 
    
         
             
            sub PrintLensInfo($$$);
         
     | 
| 
       47 
48 
     | 
    
         | 
| 
         @@ -201,6 +202,7 @@ my %olympusLensTypes = ( 
     | 
|
| 
       201 
202 
     | 
    
         
             
                # Other makes
         
     | 
| 
       202 
203 
     | 
    
         
             
                '24 01 10' => 'Venus Optics Laowa 50mm F2.8 2x Macro', #DonKomarechka
         
     | 
| 
       203 
204 
     | 
    
         
             
                'f7 03 10' => 'LAOWA C&D-Dreamer MFT 7.5mm F2.0', #forum3833
         
     | 
| 
      
 205 
     | 
    
         
            +
                'f7 10 10' => 'LAOWA C&D-Dreamer MFT 6.0mm F2.0', #KG
         
     | 
| 
       204 
206 
     | 
    
         
             
            );
         
     | 
| 
       205 
207 
     | 
    
         | 
| 
       206 
208 
     | 
    
         
             
            # lookup for Olympus camera types (ref PH)
         
     | 
| 
         @@ -59,7 +59,7 @@ use Image::ExifTool::Exif; 
     | 
|
| 
       59 
59 
     | 
    
         
             
            use Image::ExifTool::GPS;
         
     | 
| 
       60 
60 
     | 
    
         
             
            use Image::ExifTool::HP;
         
     | 
| 
       61 
61 
     | 
    
         | 
| 
       62 
     | 
    
         
            -
            $VERSION = '3. 
     | 
| 
      
 62 
     | 
    
         
            +
            $VERSION = '3.59';
         
     | 
| 
       63 
63 
     | 
    
         | 
| 
       64 
64 
     | 
    
         
             
            sub CryptShutterCount($$);
         
     | 
| 
       65 
65 
     | 
    
         
             
            sub PrintFilter($$$);
         
     | 
| 
         @@ -1947,7 +1947,8 @@ my %binaryDataAttrs = ( 
     | 
|
| 
       1947 
1947 
     | 
    
         
             
                        '0 28' => 'Quick Macro', # (Q)
         
     | 
| 
       1948 
1948 
     | 
    
         
             
                        '0 29' => 'Forest', # (Q)
         
     | 
| 
       1949 
1949 
     | 
    
         
             
                        '0 30' => 'Backlight Silhouette', # (Q)
         
     | 
| 
       1950 
     | 
    
         
            -
                        '0  
     | 
| 
      
 1950 
     | 
    
         
            +
                        '0 31' => 'Max. Aperture Priority', #KG (Ricoh GR III)
         
     | 
| 
      
 1951 
     | 
    
         
            +
                        '0 32' => 'DOF', #PH (GR III)       #KG ???? GR III 'DOF Priority (Deep)' is mapped to '0 2' ???
         
     | 
| 
       1951 
1952 
     | 
    
         
             
                        # AUTO PICT modes (auto-selected)
         
     | 
| 
       1952 
1953 
     | 
    
         
             
                        '1 4'  => 'Auto PICT (Standard)', #13
         
     | 
| 
       1953 
1954 
     | 
    
         
             
                        '1 5'  => 'Auto PICT (Portrait)', #7 (K100D)
         
     | 
| 
         @@ -1962,7 +1963,11 @@ my %binaryDataAttrs = ( 
     | 
|
| 
       1962 
1963 
     | 
    
         
             
                        '2 22' => 'Shallow DOF (HyP)', #PH (K-5)
         
     | 
| 
       1963 
1964 
     | 
    
         
             
                        '3 0'  => 'Green Mode', #16
         
     | 
| 
       1964 
1965 
     | 
    
         
             
                        '4 0'  => 'Shutter Speed Priority',
         
     | 
| 
      
 1966 
     | 
    
         
            +
                        '4 2'  => 'Shutter Speed Priority 2', #KG  Coding error? 'DOF Priority' in Tv makes no sense
         
     | 
| 
      
 1967 
     | 
    
         
            +
                        '4 31' => 'Shutter Speed Priority 31',#KG  Coding error? 'Max Aperture' in Tv makes no sense
         
     | 
| 
       1965 
1968 
     | 
    
         
             
                        '5 0'  => 'Aperture Priority',
         
     | 
| 
      
 1969 
     | 
    
         
            +
                        '5 2'  => 'Aperture Priority 2',      #KG  Coding error? 'DOF Priority' in Av makes no sense
         
     | 
| 
      
 1970 
     | 
    
         
            +
                        '5 31' => 'Aperture Priority 31',     #KG  Coding error? 'DOF Priority' in Av makes no sense
         
     | 
| 
       1966 
1971 
     | 
    
         
             
                        '6 0'  => 'Program Tv Shift',
         
     | 
| 
       1967 
1972 
     | 
    
         
             
                        '7 0'  => 'Program Av Shift', #19
         
     | 
| 
       1968 
1973 
     | 
    
         
             
                        '8 0'  => 'Manual',
         
     | 
| 
         @@ -49,7 +49,7 @@ use Image::ExifTool qw(:DataAccess :Utils); 
     | 
|
| 
       49 
49 
     | 
    
         
             
            use Image::ExifTool::Exif;
         
     | 
| 
       50 
50 
     | 
    
         
             
            use Image::ExifTool::GPS;
         
     | 
| 
       51 
51 
     | 
    
         | 
| 
       52 
     | 
    
         
            -
            $VERSION = '3. 
     | 
| 
      
 52 
     | 
    
         
            +
            $VERSION = '3.22';
         
     | 
| 
       53 
53 
     | 
    
         | 
| 
       54 
54 
     | 
    
         
             
            sub ProcessMOV($$;$);
         
     | 
| 
       55 
55 
     | 
    
         
             
            sub ProcessKeys($$$);
         
     | 
| 
         @@ -10515,9 +10515,9 @@ ItemID:         foreach $id (reverse sort { $a <=> $b } keys %$items) { 
     | 
|
| 
       10515 
10515 
     | 
    
         
             
                        $et->Warn($warnStr);
         
     | 
| 
       10516 
10516 
     | 
    
         
             
                    }
         
     | 
| 
       10517 
10517 
     | 
    
         
             
                }
         
     | 
| 
       10518 
     | 
    
         
            -
                # tweak file type based on track content ("iso*" and "dash" ftyp only)
         
     | 
| 
      
 10518 
     | 
    
         
            +
                # tweak file type based on track content ("iso*" and "dash" ftyp only ["mp42" added in 13.39])
         
     | 
| 
       10519 
10519 
     | 
    
         
             
                if ($topLevel and $$et{FileType} and $$et{FileType} eq 'MP4' and
         
     | 
| 
       10520 
     | 
    
         
            -
                    $$et{save_ftyp} and $$et{HasHandler} and $$et{save_ftyp} =~ /^(iso|dash)/ and
         
     | 
| 
      
 10520 
     | 
    
         
            +
                    $$et{save_ftyp} and $$et{HasHandler} and $$et{save_ftyp} =~ /^(iso|dash|mp42)/ and
         
     | 
| 
       10521 
10521 
     | 
    
         
             
                    $$et{HasHandler}{soun} and not $$et{HasHandler}{vide})
         
     | 
| 
       10522 
10522 
     | 
    
         
             
                {
         
     | 
| 
       10523 
10523 
     | 
    
         
             
                    $et->OverrideFileType('M4A', 'audio/mp4');
         
     | 
| 
         @@ -111,7 +111,7 @@ my %insvLimit = ( 
     | 
|
| 
       111 
111 
     | 
    
         
             
                    The tags below are extracted from timed metadata in QuickTime and other
         
     | 
| 
       112 
112 
     | 
    
         
             
                    formats of video files when the ExtractEmbedded option is used.  Although
         
     | 
| 
       113 
113 
     | 
    
         
             
                    most of these tags are combined into the single table below, ExifTool
         
     | 
| 
       114 
     | 
    
         
            -
                    currently reads  
     | 
| 
      
 114 
     | 
    
         
            +
                    currently reads 116 different types of timed GPS metadata from video files.
         
     | 
| 
       115 
115 
     | 
    
         
             
                },
         
     | 
| 
       116 
116 
     | 
    
         
             
                GPSLatitude  => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', RawConv => '$$self{FoundGPSLatitude} = 1; $val' },
         
     | 
| 
       117 
117 
     | 
    
         
             
                GPSLongitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")' },
         
     | 
| 
         @@ -984,7 +984,9 @@ sub SetGPSDateTime($$$;$) 
     | 
|
| 
       984 
984 
     | 
    
         
             
                        }
         
     | 
| 
       985 
985 
     | 
    
         
             
                        $sampleTime -= $tzOff;  # shift from local time to UTC
         
     | 
| 
       986 
986 
     | 
    
         
             
                    }
         
     | 
| 
      
 987 
     | 
    
         
            +
                    $$et{SET_GROUP0} = 'Composite';
         
     | 
| 
       987 
988 
     | 
    
         
             
                    $et->HandleTag($tagTbl, GPSDateTime => Image::ExifTool::ConvertUnixTime($sampleTime,0,3) . 'Z');
         
     | 
| 
      
 989 
     | 
    
         
            +
                    delete $$et{SET_GROUP0};
         
     | 
| 
       988 
990 
     | 
    
         
             
                }
         
     | 
| 
       989 
991 
     | 
    
         
             
            }
         
     | 
| 
       990 
992 
     | 
    
         | 
| 
         @@ -1004,6 +1006,28 @@ sub HandleTextTags($$$) 
     | 
|
| 
       1004 
1006 
     | 
    
         
             
                undef %$tags;   # clear the hash
         
     | 
| 
       1005 
1007 
     | 
    
         
             
            }
         
     | 
| 
       1006 
1008 
     | 
    
         | 
| 
      
 1009 
     | 
    
         
            +
            #------------------------------------------------------------------------------
         
     | 
| 
      
 1010 
     | 
    
         
            +
            # Handle new time in NMEA stream and store queued tags if necessary
         
     | 
| 
      
 1011 
     | 
    
         
            +
            # Inputs: 0) ExifTool ref, 1) time string, 2) tag table ref, 3) tags hash
         
     | 
| 
      
 1012 
     | 
    
         
            +
            sub HandleNewTime($$$$)
         
     | 
| 
      
 1013 
     | 
    
         
            +
            {
         
     | 
| 
      
 1014 
     | 
    
         
            +
                my ($et, $time, $tagTbl, $tags) = @_;
         
     | 
| 
      
 1015 
     | 
    
         
            +
                if ($$et{LastTime}) {
         
     | 
| 
      
 1016 
     | 
    
         
            +
                    if ($$et{LastTime} eq $time) {
         
     | 
| 
      
 1017 
     | 
    
         
            +
                        # combine with the previous NMEA sentence
         
     | 
| 
      
 1018 
     | 
    
         
            +
                        $$et{DOC_NUM} = $$et{LastDoc};
         
     | 
| 
      
 1019 
     | 
    
         
            +
                    } elsif (%$tags) {
         
     | 
| 
      
 1020 
     | 
    
         
            +
                        # handle existing tags and start a new document
         
     | 
| 
      
 1021 
     | 
    
         
            +
                        # (see https://exiftool.org/forum/index.php?msg=75422)
         
     | 
| 
      
 1022 
     | 
    
         
            +
                        HandleTextTags($et, $tagTbl, $tags);
         
     | 
| 
      
 1023 
     | 
    
         
            +
                        # increment document number and update document count if necessary
         
     | 
| 
      
 1024 
     | 
    
         
            +
                        $$et{DOC_COUNT} < ++$$et{DOC_NUM} and $$et{DOC_COUNT} = $$et{DOC_NUM};
         
     | 
| 
      
 1025 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1026 
     | 
    
         
            +
                }
         
     | 
| 
      
 1027 
     | 
    
         
            +
                $$et{LastTime} = $time;
         
     | 
| 
      
 1028 
     | 
    
         
            +
                $$et{LastDoc} = $$et{DOC_NUM};
         
     | 
| 
      
 1029 
     | 
    
         
            +
            }
         
     | 
| 
      
 1030 
     | 
    
         
            +
             
     | 
| 
       1007 
1031 
     | 
    
         
             
            #------------------------------------------------------------------------------
         
     | 
| 
       1008 
1032 
     | 
    
         
             
            # Process subtitle 'text'
         
     | 
| 
       1009 
1033 
     | 
    
         
             
            # Inputs: 0) ExifTool ref, 1) data ref or dirInfo ref, 2) tag table ref
         
     | 
| 
         @@ -1030,41 +1054,18 @@ sub Process_text($$$;$) 
     | 
|
| 
       1030 
1054 
     | 
    
         
             
                            next;
         
     | 
| 
       1031 
1055 
     | 
    
         
             
                        }
         
     | 
| 
       1032 
1056 
     | 
    
         
             
                        my $time = "$1:$2:$3";
         
     | 
| 
       1033 
     | 
    
         
            -
                         
     | 
| 
       1034 
     | 
    
         
            -
                            if ($$et{LastTime} eq $time) {
         
     | 
| 
       1035 
     | 
    
         
            -
                                # combine with the previous NMEA sentence
         
     | 
| 
       1036 
     | 
    
         
            -
                                $$et{DOC_NUM} = $$et{LastDoc};
         
     | 
| 
       1037 
     | 
    
         
            -
                            } elsif (%tags) {
         
     | 
| 
       1038 
     | 
    
         
            -
                                # handle existing tags and start a new document
         
     | 
| 
       1039 
     | 
    
         
            -
                                # (see https://exiftool.org/forum/index.php?msg=75422)
         
     | 
| 
       1040 
     | 
    
         
            -
                                HandleTextTags($et, $tagTbl, \%tags);
         
     | 
| 
       1041 
     | 
    
         
            -
                                undef %tags;
         
     | 
| 
       1042 
     | 
    
         
            -
                                # increment document number and update document count if necessary
         
     | 
| 
       1043 
     | 
    
         
            -
                                $$et{DOC_COUNT} < ++$$et{DOC_NUM} and $$et{DOC_COUNT} = $$et{DOC_NUM};
         
     | 
| 
       1044 
     | 
    
         
            -
                            }
         
     | 
| 
       1045 
     | 
    
         
            -
                        }
         
     | 
| 
       1046 
     | 
    
         
            -
                        $$et{LastTime} = $time;
         
     | 
| 
       1047 
     | 
    
         
            -
                        $$et{LastDoc} = $$et{DOC_NUM};
         
     | 
| 
      
 1057 
     | 
    
         
            +
                        HandleNewTime($et, $time, $tagTbl, \%tags);
         
     | 
| 
       1048 
1058 
     | 
    
         
             
                        my $year = $14 + ($14 >= 70 ? 1900 : 2000);
         
     | 
| 
       1049 
     | 
    
         
            -
                        my $ 
     | 
| 
       1050 
     | 
    
         
            -
                         
     | 
| 
      
 1059 
     | 
    
         
            +
                        my $date = sprintf('%.4d:%.2d:%.2d', $year, $13, $12);
         
     | 
| 
      
 1060 
     | 
    
         
            +
                        $$et{LastDate} = $date;
         
     | 
| 
      
 1061 
     | 
    
         
            +
                        $tags{GPSDateTime} = "$date ${time}Z";
         
     | 
| 
       1051 
1062 
     | 
    
         
             
                        $tags{GPSLatitude} = (($4 || 0) + $5/60) * ($6 eq 'N' ? 1 : -1);
         
     | 
| 
       1052 
1063 
     | 
    
         
             
                        $tags{GPSLongitude} = (($7 || 0) + $8/60) * ($9 eq 'E' ? 1 : -1);
         
     | 
| 
       1053 
1064 
     | 
    
         
             
                        $tags{GPSSpeed} = $10 * $knotsToKph if length $10;
         
     | 
| 
       1054 
1065 
     | 
    
         
             
                        $tags{GPSTrack} = $11 if length $11;
         
     | 
| 
       1055 
1066 
     | 
    
         
             
                    } elsif ($tag =~ /^[A-Z]{2}GGA$/ and $dat =~ /^,(\d{2})(\d{2})(\d+(?:\.\d*)?),(\d*?)(\d{1,2}\.\d+),([NS]),(\d*?)(\d{1,2}\.\d+),([EW]),[1-6]?,(\d+)?,(\.\d+|\d+\.?\d*)?,(-?\d+\.?\d*)?,M?/s) {
         
     | 
| 
       1056 
1067 
     | 
    
         
             
                        my $time = "$1:$2:$3";
         
     | 
| 
       1057 
     | 
    
         
            -
                         
     | 
| 
       1058 
     | 
    
         
            -
                            if ($$et{LastTime} eq $time) {
         
     | 
| 
       1059 
     | 
    
         
            -
                                $$et{DOC_NUM} = $$et{LastDoc};
         
     | 
| 
       1060 
     | 
    
         
            -
                            } elsif (%tags) {
         
     | 
| 
       1061 
     | 
    
         
            -
                                HandleTextTags($et, $tagTbl, \%tags);
         
     | 
| 
       1062 
     | 
    
         
            -
                                undef %tags;
         
     | 
| 
       1063 
     | 
    
         
            -
                                $$et{DOC_COUNT} < ++$$et{DOC_NUM} and $$et{DOC_COUNT} = $$et{DOC_NUM};
         
     | 
| 
       1064 
     | 
    
         
            -
                            }
         
     | 
| 
       1065 
     | 
    
         
            -
                        }
         
     | 
| 
       1066 
     | 
    
         
            -
                        $$et{LastTime} = $time;
         
     | 
| 
       1067 
     | 
    
         
            -
                        $$et{LastDoc} = $$et{DOC_NUM};
         
     | 
| 
      
 1068 
     | 
    
         
            +
                        HandleNewTime($et, $time, $tagTbl, \%tags);
         
     | 
| 
       1068 
1069 
     | 
    
         
             
                        $tags{GPSTimeStamp} = $time;
         
     | 
| 
       1069 
1070 
     | 
    
         
             
                        $tags{GPSLatitude} = (($4 || 0) + $5/60) * ($6 eq 'N' ? 1 : -1);
         
     | 
| 
       1070 
1071 
     | 
    
         
             
                        $tags{GPSLongitude} = (($7 || 0) + $8/60) * ($9 eq 'E' ? 1 : -1);
         
     | 
| 
         @@ -1112,6 +1113,11 @@ sub Process_text($$$;$) 
     | 
|
| 
       1112 
1113 
     | 
    
         
             
                            }
         
     | 
| 
       1113 
1114 
     | 
    
         
             
                        }
         
     | 
| 
       1114 
1115 
     | 
    
         
             
                    }
         
     | 
| 
      
 1116 
     | 
    
         
            +
                    if ($tags{GPSTimeStamp} and not $tags{GPSDateTime} and $$et{LastDate}) {
         
     | 
| 
      
 1117 
     | 
    
         
            +
                        # hack to fill in missing date for NextBase 662GW
         
     | 
| 
      
 1118 
     | 
    
         
            +
                        # (note: this doesn't necessarily handle day rollover properly)
         
     | 
| 
      
 1119 
     | 
    
         
            +
                        $tags{GPSDateTime} = "$$et{LastDate} $tags{GPSTimeStamp}Z";
         
     | 
| 
      
 1120 
     | 
    
         
            +
                    }
         
     | 
| 
       1115 
1121 
     | 
    
         
             
                    HandleTextTags($et, $tagTbl, \%tags);
         
     | 
| 
       1116 
1122 
     | 
    
         
             
                    return;
         
     | 
| 
       1117 
1123 
     | 
    
         
             
                }
         
     | 
| 
         @@ -3488,14 +3494,17 @@ sub ProcessGarminGPS($$$) 
     | 
|
| 
       3488 
3494 
     | 
    
         
             
                while ($pos + 20 <= $dataLen) {
         
     | 
| 
       3489 
3495 
     | 
    
         
             
                    $$et{DOC_NUM} = ++$$et{DOC_COUNT};
         
     | 
| 
       3490 
3496 
     | 
    
         
             
                    my $time = Image::ExifTool::ConvertUnixTime(Get32u($dataPt, $pos) - $epoch) . 'Z';
         
     | 
| 
       3491 
     | 
    
         
            -
                    my $lat = Get32s($dataPt, $pos + 12) 
     | 
| 
       3492 
     | 
    
         
            -
                    my $lon = Get32s($dataPt, $pos + 16) 
     | 
| 
      
 3497 
     | 
    
         
            +
                    my $lat = Get32s($dataPt, $pos + 12);
         
     | 
| 
      
 3498 
     | 
    
         
            +
                    my $lon = Get32s($dataPt, $pos + 16);
         
     | 
| 
       3493 
3499 
     | 
    
         
             
                    my $spd = Get16u($dataPt, $pos + 4); # (in mph)
         
     | 
| 
       3494 
3500 
     | 
    
         
             
                    $et->HandleTag($tagTbl, 'GPSDateTime',  $time);
         
     | 
| 
       3495 
     | 
    
         
            -
                     
     | 
| 
       3496 
     | 
    
         
            -
                     
     | 
| 
       3497 
     | 
    
         
            -
             
     | 
| 
       3498 
     | 
    
         
            -
             
     | 
| 
      
 3501 
     | 
    
         
            +
                    # skip bad GPS fixes
         
     | 
| 
      
 3502 
     | 
    
         
            +
                    if ($lat != -2147483648 or $lon != -2147483648) {
         
     | 
| 
      
 3503 
     | 
    
         
            +
                        $et->HandleTag($tagTbl, 'GPSLatitude',  $lat * $scl);
         
     | 
| 
      
 3504 
     | 
    
         
            +
                        $et->HandleTag($tagTbl, 'GPSLongitude', $lon * $scl);
         
     | 
| 
      
 3505 
     | 
    
         
            +
                        $et->HandleTag($tagTbl, 'GPSSpeed',     $spd);
         
     | 
| 
      
 3506 
     | 
    
         
            +
                        $et->HandleTag($tagTbl, 'GPSSpeedRef', 'M');
         
     | 
| 
      
 3507 
     | 
    
         
            +
                    }
         
     | 
| 
       3499 
3508 
     | 
    
         
             
                    $pos += 20;
         
     | 
| 
       3500 
3509 
     | 
    
         
             
                }
         
     | 
| 
       3501 
3510 
     | 
    
         
             
                delete $$et{DOC_NUM};
         
     |