exiftool_vendored 13.12.0 → 13.14.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 +52 -22
- data/bin/MANIFEST +5 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +2 -2
- data/bin/arg_files/exif2xmp.args +4 -0
- data/bin/arg_files/xmp2exif.args +2 -1
- data/bin/build_geolocation +1 -1
- data/bin/exiftool +5 -5
- data/bin/lib/Image/ExifTool/AFCP.pm +5 -5
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +24 -13
- data/bin/lib/Image/ExifTool/DJI.pm +64 -11
- data/bin/lib/Image/ExifTool/EXE.pm +2 -2
- data/bin/lib/Image/ExifTool/Geolocation.pm +16 -7
- data/bin/lib/Image/ExifTool/JPEG.pm +5 -1
- data/bin/lib/Image/ExifTool/LigoGPS.pm +1 -0
- data/bin/lib/Image/ExifTool/Nikon.pm +2 -0
- data/bin/lib/Image/ExifTool/Protobuf.pm +25 -7
- data/bin/lib/Image/ExifTool/QuickTime.pm +161 -50
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +2 -2
- data/bin/lib/Image/ExifTool/Samsung.pm +1 -1
- data/bin/lib/Image/ExifTool/TagLookup.pm +3438 -3430
- data/bin/lib/Image/ExifTool/TagNames.pod +89 -22
- data/bin/lib/Image/ExifTool/Torrent.pm +2 -2
- data/bin/lib/Image/ExifTool/Vivo.pm +124 -0
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +69 -40
- data/bin/lib/Image/ExifTool/Writer.pl +12 -8
- data/bin/lib/Image/ExifTool.pm +22 -6
- data/bin/lib/Image/ExifTool.pod +43 -41
- data/bin/perl-Image-ExifTool.spec +1 -1
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +3 -2
| @@ -71,7 +71,7 @@ package Image::ExifTool::Geolocation; | |
| 71 71 | 
             
            use strict;
         | 
| 72 72 | 
             
            use vars qw($VERSION $geoDir $altDir $dbInfo);
         | 
| 73 73 |  | 
| 74 | 
            -
            $VERSION = '1. | 
| 74 | 
            +
            $VERSION = '1.09';  # (this is the module version number, not the database version)
         | 
| 75 75 |  | 
| 76 76 | 
             
            my $debug; # set to output processing time for testing
         | 
| 77 77 |  | 
| @@ -463,7 +463,7 @@ sub GetAltNames($;$) | |
| 463 463 | 
             
            sub Geolocate($;$)
         | 
| 464 464 | 
             
            {
         | 
| 465 465 | 
             
                my ($arg, $opts) = @_;
         | 
| 466 | 
            -
                my ($city, @exact, %regex, @multiCity, $other, $idx, @cargs | 
| 466 | 
            +
                my ($city, @exact, %regex, @multiCity, $other, $idx, @cargs);
         | 
| 467 467 | 
             
                my ($minPop, $minDistU, $minDistC, @matchParms, @coords, %fcOK, $both);
         | 
| 468 468 | 
             
                my ($pop, $maxDist, $multi, $fcodes, $altNames, @startTime);
         | 
| 469 469 |  | 
| @@ -594,8 +594,16 @@ Entry:  for (; $i<@cityList; ++$i) { | |
| 594 594 | 
             
                    }
         | 
| 595 595 | 
             
                    @startTime and printf("= Processing time: %.3f sec\n", Time::HiRes::tv_interval(\@startTime));
         | 
| 596 596 | 
             
                    if (%lastFound) {
         | 
| 597 | 
            -
                        @coords == 2 | 
| 597 | 
            +
                        last if @coords == 2;   # continue to use coords with last city matches
         | 
| 598 598 | 
             
                        scalar(keys %lastFound) > 200 and warn("Too many matching cities\n"), return();
         | 
| 599 | 
            +
                        # return nearby cities if "num=" is used and only one match found
         | 
| 600 | 
            +
                        if ($num > 1 and scalar(keys %lastFound) == 1) {
         | 
| 601 | 
            +
                            my ($i) = keys %lastFound;
         | 
| 602 | 
            +
                            my @entry = GetEntry($i);
         | 
| 603 | 
            +
                            @coords = @entry[8,9];
         | 
| 604 | 
            +
                            SortDatabase('Latitude');   # (make sure we are sorted by latitude)
         | 
| 605 | 
            +
                            last;
         | 
| 606 | 
            +
                        }
         | 
| 599 607 | 
             
                        unless (@lastByPop) {
         | 
| 600 608 | 
             
                            @lastByPop = sort { $lastFound{$b} cmp $lastFound{$a} or $cityList[$a] cmp $cityList[$b] } keys %lastFound;
         | 
| 601 609 | 
             
                        }
         | 
| @@ -777,7 +785,7 @@ on the first call. | |
| 777 785 |  | 
| 778 786 | 
             
            Sort database in specified order.
         | 
| 779 787 |  | 
| 780 | 
            -
                Image::ExifTool::Geolocation:: | 
| 788 | 
            +
                Image::ExifTool::Geolocation::SortDatabase('City');
         | 
| 781 789 |  | 
| 782 790 | 
             
            =over 4
         | 
| 783 791 |  | 
| @@ -924,9 +932,10 @@ to the argument list: | |
| 924 932 | 
             
                          both to determine the closest city matching the specified
         | 
| 925 933 | 
             
                          name(s) instead of using GPS only.
         | 
| 926 934 |  | 
| 927 | 
            -
               'num=##' - When the search includes GPS coordinates,  | 
| 928 | 
            -
                           | 
| 929 | 
            -
                           | 
| 935 | 
            +
               'num=##' - When the search includes GPS coordinates, or when a single
         | 
| 936 | 
            +
                          city is matched by name, return the nearest ## cities instead
         | 
| 937 | 
            +
                          of just the closest or named one.  Returned cities are in the
         | 
| 938 | 
            +
                          order from nearest to farthest.
         | 
| 930 939 |  | 
| 931 940 | 
             
            See L<https://exiftool.org/geolocation.html#Read> for more details.
         | 
| 932 941 |  | 
| @@ -11,7 +11,7 @@ use strict; | |
| 11 11 | 
             
            use vars qw($VERSION);
         | 
| 12 12 | 
             
            use Image::ExifTool qw(:DataAccess :Utils);
         | 
| 13 13 |  | 
| 14 | 
            -
            $VERSION = '1. | 
| 14 | 
            +
            $VERSION = '1.39';
         | 
| 15 15 |  | 
| 16 16 | 
             
            sub ProcessOcad($$$);
         | 
| 17 17 | 
             
            sub ProcessJPEG_HDR($$$);
         | 
| @@ -347,6 +347,10 @@ sub ProcessJPEG_HDR($$$); | |
| 347 347 | 
             
                    Name => 'Samsung',
         | 
| 348 348 | 
             
                    Condition => '$$valPt =~ /QDIOBS$/',
         | 
| 349 349 | 
             
                    SubDirectory => { TagTable => 'Image::ExifTool::Samsung::Trailer' },
         | 
| 350 | 
            +
                  }, {
         | 
| 351 | 
            +
                    Name => 'Vivo',
         | 
| 352 | 
            +
                    Condition => '$$valPt =~ /^(streamdata|vivo\{")/',
         | 
| 353 | 
            +
                    SubDirectory => { TagTable => 'Image::ExifTool::Vivo::Main' },
         | 
| 350 354 | 
             
                  }, {
         | 
| 351 355 | 
             
                    Name => 'EmbeddedVideo',
         | 
| 352 356 | 
             
                    Notes => 'extracted only when ExtractEmbedded option is used',
         | 
| @@ -269,6 +269,7 @@ sub ParseLigoGPS($$$;$) | |
| 269 269 | 
             
            # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
         | 
| 270 270 | 
             
            #         3) 1=LIGOGPS lat/lon/spd weren't fuzzed
         | 
| 271 271 | 
             
            # Returns: 1 on success
         | 
| 272 | 
            +
            # Notes:  The directory data should start with the string "LIGOGPSINFO\0"
         | 
| 272 273 | 
             
            sub ProcessLigoGPS($$$;$)
         | 
| 273 274 | 
             
            {
         | 
| 274 275 | 
             
                my ($et, $dirInfo, $tagTbl, $noFuzz) = @_;
         | 
| @@ -3118,6 +3118,7 @@ my %base64coord = ( | |
| 3118 3118 | 
             
                    Condition => '$$valPt =~ /^040[012]/',
         | 
| 3119 3119 | 
             
                    SubDirectory => { TagTable => 'Image::ExifTool::Nikon::AFInfo2V0400' },
         | 
| 3120 3120 | 
             
                },{ #JD
         | 
| 3121 | 
            +
                    # (expeed 5 processor cameras are version 0101, expeed 6 are version 03xx)
         | 
| 3121 3122 | 
             
                    Name => 'AFInfo2',
         | 
| 3122 3123 | 
             
                    # (this structure may be byte swapped when rewritten by CaptureNX)
         | 
| 3123 3124 | 
             
                    SubDirectory => { TagTable => 'Image::ExifTool::Nikon::AFInfo2' },
         | 
| @@ -4160,6 +4161,7 @@ my %base64coord = ( | |
| 4160 4161 | 
             
                DATAMEMBER => [ 0, 4, 6 ],
         | 
| 4161 4162 | 
             
                NOTES => "These tags are written by Nikon DSLR's which have the live view feature.",
         | 
| 4162 4163 | 
             
                0 => {
         | 
| 4164 | 
            +
                    # (expeed 5 processor cameras are version 0101, expeed 6 are version 03xx)
         | 
| 4163 4165 | 
             
                    Name => 'AFInfo2Version',
         | 
| 4164 4166 | 
             
                    Format => 'undef[4]',
         | 
| 4165 4167 | 
             
                    Writable => 0,
         | 
| @@ -5,8 +5,9 @@ | |
| 5 5 | 
             
            #
         | 
| 6 6 | 
             
            # Revisions:    2024-12-04 - P. Harvey Created
         | 
| 7 7 | 
             
            #
         | 
| 8 | 
            -
            # Notes:        Tag definitions for Protobuf tags support additional 'signed'
         | 
| 9 | 
            -
            #               and ' | 
| 8 | 
            +
            # Notes:        Tag definitions for Protobuf tags support additional 'signed',
         | 
| 9 | 
            +
            #               'unsigned' and 'int64s' formats for varInt (type 0) values,
         | 
| 10 | 
            +
            #               and 'rational' for byte (type 2) values
         | 
| 10 11 | 
             
            #
         | 
| 11 12 | 
             
            # References:   1) https://protobuf.dev/programming-guides/encoding/
         | 
| 12 13 | 
             
            #------------------------------------------------------------------------------
         | 
| @@ -17,13 +18,13 @@ use strict; | |
| 17 18 | 
             
            use vars qw($VERSION);
         | 
| 18 19 | 
             
            use Image::ExifTool qw(:DataAccess :Utils);
         | 
| 19 20 |  | 
| 20 | 
            -
            $VERSION = '1. | 
| 21 | 
            +
            $VERSION = '1.02';
         | 
| 21 22 |  | 
| 22 23 | 
             
            sub ProcessProtobuf($$$;$);
         | 
| 23 24 |  | 
| 24 25 | 
             
            #------------------------------------------------------------------------------
         | 
| 25 26 | 
             
            # Read bytes from dirInfo object
         | 
| 26 | 
            -
            # Inputs: 0) dirInfo ref, 1) number of bytes
         | 
| 27 | 
            +
            # Inputs: 0) dirInfo ref (with DataPt and Pos set), 1) number of bytes
         | 
| 27 28 | 
             
            # Returns: binary data or undef on error
         | 
| 28 29 | 
             
            sub GetBytes($$)
         | 
| 29 30 | 
             
            {
         | 
| @@ -162,14 +163,31 @@ sub ProcessProtobuf($$$;$) | |
| 162 163 | 
             
                    if ($$tagInfo{Format}) {
         | 
| 163 164 | 
             
                        if ($type == 0) {
         | 
| 164 165 | 
             
                            $val = $buff;
         | 
| 165 | 
            -
                             | 
| 166 | 
            +
                            if ($$tagInfo{Format} eq 'signed') {
         | 
| 167 | 
            +
                                $val = ($val & 1) ? -($val >> 1)-1 : ($val >> 1);
         | 
| 168 | 
            +
                            } elsif ($$tagInfo{Format} eq 'int64s' and $val > 0xffffffff) {
         | 
| 169 | 
            +
                                # hack for DJI drones which store 64-bit signed integers improperly
         | 
| 170 | 
            +
                                # (just toss upper 32 bits which should be all 1's anyway)
         | 
| 171 | 
            +
                                $val = ($val & 0xffffffff) - 4294967296;
         | 
| 172 | 
            +
                            }
         | 
| 173 | 
            +
                        } elsif ($type == 2 and $$tagInfo{Format} eq 'rational') {
         | 
| 174 | 
            +
                            my $dir = { DataPt => \$buff, Pos => 0 };
         | 
| 175 | 
            +
                            my $num = VarInt($dir);
         | 
| 176 | 
            +
                            my $den = VarInt($dir);
         | 
| 177 | 
            +
                            $val = (defined $num and $den) ? "$num/$den" : 'err';
         | 
| 166 178 | 
             
                        } else {
         | 
| 167 179 | 
             
                            $val = ReadValue(\$buff, 0, $$tagInfo{Format}, undef, length($buff));
         | 
| 168 180 | 
             
                        }
         | 
| 169 181 | 
             
                    } elsif ($type == 0) {
         | 
| 170 182 | 
             
                        $val = $buff;
         | 
| 171 | 
            -
                        my $ | 
| 172 | 
            -
                        $ | 
| 183 | 
            +
                        my $hex = sprintf('%x', $val);
         | 
| 184 | 
            +
                        if (length($hex) == 16 and $hex =~ /^ffffffff/) {
         | 
| 185 | 
            +
                            my $s64 = hex(substr($hex, 8)) - 4294967296;
         | 
| 186 | 
            +
                            $val .= " (0x$hex, int64s $s64)";
         | 
| 187 | 
            +
                        } else {
         | 
| 188 | 
            +
                            my $signed = ($val & 1) ? -($val >> 1)-1 : ($val >> 1);
         | 
| 189 | 
            +
                            $val .= " (0x$hex, signed $signed)";
         | 
| 190 | 
            +
                        }
         | 
| 173 191 | 
             
                    } elsif ($type == 1) {
         | 
| 174 192 | 
             
                        $val = '0x' . unpack('H*', $buff) . ' (double ' . GetDouble(\$buff,0) . ')';
         | 
| 175 193 | 
             
                    } elsif ($type == 2) {
         | 
| @@ -43,12 +43,12 @@ | |
| 43 43 | 
             
            package Image::ExifTool::QuickTime;
         | 
| 44 44 |  | 
| 45 45 | 
             
            use strict;
         | 
| 46 | 
            -
            use vars qw($VERSION $AUTOLOAD %stringEncoding);
         | 
| 46 | 
            +
            use vars qw($VERSION $AUTOLOAD %stringEncoding %avType);
         | 
| 47 47 | 
             
            use Image::ExifTool qw(:DataAccess :Utils);
         | 
| 48 48 | 
             
            use Image::ExifTool::Exif;
         | 
| 49 49 | 
             
            use Image::ExifTool::GPS;
         | 
| 50 50 |  | 
| 51 | 
            -
            $VERSION = '3. | 
| 51 | 
            +
            $VERSION = '3.09';
         | 
| 52 52 |  | 
| 53 53 | 
             
            sub ProcessMOV($$;$);
         | 
| 54 54 | 
             
            sub ProcessKeys($$$);
         | 
| @@ -358,6 +358,19 @@ my %vendorID = ( | |
| 358 358 | 
             
                5 => 'UTF16',
         | 
| 359 359 | 
             
            );
         | 
| 360 360 |  | 
| 361 | 
            +
            # media types for which we have separate Keys tables (AudioKeys, VideoKeys)
         | 
| 362 | 
            +
            %avType = (
         | 
| 363 | 
            +
                soun => 'Audio',
         | 
| 364 | 
            +
                vide => 'Video',
         | 
| 365 | 
            +
            );
         | 
| 366 | 
            +
             | 
| 367 | 
            +
            # path to Keys/ItemList/UserData tags stored in tracks
         | 
| 368 | 
            +
            my %trackPath = (
         | 
| 369 | 
            +
                'MOV-Movie-Track-Meta-ItemList' => 'Keys',
         | 
| 370 | 
            +
                'MOV-Movie-Track-UserData-Meta-ItemList' => 'ItemList',
         | 
| 371 | 
            +
                'MOV-Movie-Track-UserData' => 'UserData',
         | 
| 372 | 
            +
            );
         | 
| 373 | 
            +
             | 
| 361 374 | 
             
            my %graphicsMode = (
         | 
| 362 375 | 
             
                # (ref http://homepage.mac.com/vanhoek/MovieGuts%20docs/64.html)
         | 
| 363 376 | 
             
                0x00 => 'srcCopy',
         | 
| @@ -594,13 +607,24 @@ my %userDefined = ( | |
| 594 607 | 
             
                    },
         | 
| 595 608 | 
             
                    {
         | 
| 596 609 | 
             
                        Name => 'LigoGPSInfo',
         | 
| 597 | 
            -
                        Condition => '$$valPt =~ /^LIGOGPSINFO\0/',
         | 
| 598 | 
            -
                        SubDirectory => { | 
| 610 | 
            +
                        Condition => '$$valPt =~ /^LIGOGPSINFO\0/ and $$self{OPTIONS}{ExtractEmbedded}',
         | 
| 611 | 
            +
                        SubDirectory => {
         | 
| 599 612 | 
             
                            TagTable => 'Image::ExifTool::QuickTime::Stream',
         | 
| 600 613 | 
             
                            ProcessProc => 'Image::ExifTool::LigoGPS::ProcessLigoGPS',
         | 
| 601 614 | 
             
                        },
         | 
| 602 615 | 
             
                    },
         | 
| 603 | 
            -
                    { | 
| 616 | 
            +
                    {
         | 
| 617 | 
            +
                        Name => 'Skip',
         | 
| 618 | 
            +
                        RawConv => q{
         | 
| 619 | 
            +
                            if ($val =~ /^LIGOGPSINFO\0/) {
         | 
| 620 | 
            +
                                $self->Warn('Use the ExtractEmbedded option to decode timed GPS',3);
         | 
| 621 | 
            +
                                return undef;
         | 
| 622 | 
            +
                            }
         | 
| 623 | 
            +
                            return $val;
         | 
| 624 | 
            +
                        },
         | 
| 625 | 
            +
                        Unknown => 1,
         | 
| 626 | 
            +
                        Binary => 1,
         | 
| 627 | 
            +
                    },
         | 
| 604 628 | 
             
                ],
         | 
| 605 629 | 
             
                wide => { Unknown => 1, Binary => 1 },
         | 
| 606 630 | 
             
                ftyp => { #MP4
         | 
| @@ -1525,7 +1549,7 @@ my %userDefined = ( | |
| 1525 1549 | 
             
                        # (this tag is readable/writable as a block through the Extra SphericalVideoXML tags)
         | 
| 1526 1550 | 
             
                        Condition => '$$valPt=~/^\xff\xcc\x82\x63\xf8\x55\x4a\x93\x88\x14\x58\x7a\x02\x52\x1f\xdd/',
         | 
| 1527 1551 | 
             
                        WriteGroup => 'GSpherical', # write only GSpherical XMP tags here
         | 
| 1528 | 
            -
                         | 
| 1552 | 
            +
                        MediaType => 'vide',        # only write in video tracks
         | 
| 1529 1553 | 
             
                        SubDirectory => {
         | 
| 1530 1554 | 
             
                            TagTable => 'Image::ExifTool::XMP::Main',
         | 
| 1531 1555 | 
             
                            Start => 16,
         | 
| @@ -2853,10 +2877,18 @@ my %userDefined = ( | |
| 2853 2877 | 
             
                        IgnoreProp => { NonRealTimeMeta => 1 }, # ignore container for Sony 'nrtm'
         | 
| 2854 2878 | 
             
                    },
         | 
| 2855 2879 | 
             
                },
         | 
| 2856 | 
            -
               'keys' => {
         | 
| 2880 | 
            +
               'keys' => [{
         | 
| 2881 | 
            +
                    Name => 'AudioKeys',
         | 
| 2882 | 
            +
                    Condition => '$$self{MediaType} eq "soun"',
         | 
| 2883 | 
            +
                    SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::AudioKeys' },
         | 
| 2884 | 
            +
                },{
         | 
| 2885 | 
            +
                    Name => 'VideoKeys',
         | 
| 2886 | 
            +
                    Condition => '$$self{MediaType} eq "vide"',
         | 
| 2887 | 
            +
                    SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::VideoKeys' },
         | 
| 2888 | 
            +
                },{
         | 
| 2857 2889 | 
             
                    Name => 'Keys',
         | 
| 2858 2890 | 
             
                    SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Keys' },
         | 
| 2859 | 
            -
                },
         | 
| 2891 | 
            +
                }],
         | 
| 2860 2892 | 
             
                bxml => {
         | 
| 2861 2893 | 
             
                    Name => 'BinaryXML',
         | 
| 2862 2894 | 
             
                    Flags => ['Binary','Unknown'],
         | 
| @@ -3597,7 +3629,7 @@ my %userDefined = ( | |
| 3597 3629 | 
             
                        my $id = Image::ExifTool::ID3::GetGenreID($val);
         | 
| 3598 3630 | 
             
                        return unless defined $id and $id =~ /^\d+$/;
         | 
| 3599 3631 | 
             
                        return $id + 1;
         | 
| 3600 | 
            -
                    }, | 
| 3632 | 
            +
                    },
         | 
| 3601 3633 | 
             
                },
         | 
| 3602 3634 | 
             
                egid => 'EpisodeGlobalUniqueID', #7
         | 
| 3603 3635 | 
             
                geID => { #10
         | 
| @@ -6599,7 +6631,7 @@ my %userDefined = ( | |
| 6599 6631 | 
             
                PROCESS_PROC => \&ProcessKeys,
         | 
| 6600 6632 | 
             
                WRITE_PROC => \&WriteKeys,
         | 
| 6601 6633 | 
             
                CHECK_PROC => \&CheckQTValue,
         | 
| 6602 | 
            -
                VARS => { LONG_TAGS =>  | 
| 6634 | 
            +
                VARS => { LONG_TAGS => 8 },
         | 
| 6603 6635 | 
             
                WRITABLE => 1,
         | 
| 6604 6636 | 
             
                # (not PREFERRED when writing)
         | 
| 6605 6637 | 
             
                GROUPS => { 1 => 'Keys' },
         | 
| @@ -6645,21 +6677,11 @@ my %userDefined = ( | |
| 6645 6677 | 
             
                publisher   => { },
         | 
| 6646 6678 | 
             
                software    => { },
         | 
| 6647 6679 | 
             
                year        => { Groups => { 2 => 'Time' } },
         | 
| 6648 | 
            -
                'camera.identifier' => 'CameraIdentifier', # (iPhone 4)
         | 
| 6649 | 
            -
                'camera.framereadouttimeinmicroseconds' => { # (iPhone 4)
         | 
| 6650 | 
            -
                    Name => 'FrameReadoutTime',
         | 
| 6651 | 
            -
                    ValueConv => '$val * 1e-6',
         | 
| 6652 | 
            -
                    ValueConvInv => 'int($val * 1e6 + 0.5)',
         | 
| 6653 | 
            -
                    PrintConv => '$val * 1e6 . " microseconds"',
         | 
| 6654 | 
            -
                    PrintConvInv => '$val =~ s/ .*//; $val * 1e-6',
         | 
| 6655 | 
            -
                },
         | 
| 6656 | 
            -
              # 'camera.focal_length.35mm_equivalent' - not top level (written to Keys in video track)
         | 
| 6657 | 
            -
              # 'camera.lens_model'                   - not top level (written to Keys in video track)
         | 
| 6658 6680 | 
             
                'location.ISO6709' => {
         | 
| 6659 6681 | 
             
                    Name => 'GPSCoordinates',
         | 
| 6660 6682 | 
             
                    Groups => { 2 => 'Location' },
         | 
| 6661 6683 | 
             
                    Notes => q{
         | 
| 6662 | 
            -
                        Google Photos may ignore this if the  | 
| 6684 | 
            +
                        Google Photos may ignore this if the coordinates have more than 5 digits
         | 
| 6663 6685 | 
             
                        after the decimal
         | 
| 6664 6686 | 
             
                    },
         | 
| 6665 6687 | 
             
                    ValueConv => \&ConvertISO6709,
         | 
| @@ -6715,7 +6737,6 @@ my %userDefined = ( | |
| 6715 6737 | 
             
            #
         | 
| 6716 6738 | 
             
            # the following tags aren't in the com.apple.quicktime namespace:
         | 
| 6717 6739 | 
             
            #
         | 
| 6718 | 
            -
                'com.apple.photos.captureMode' => 'CaptureMode',
         | 
| 6719 6740 | 
             
                'com.android.version' => 'AndroidVersion',
         | 
| 6720 6741 | 
             
                'com.android.capture.fps' => { Name  => 'AndroidCaptureFPS', Writable => 'float' },
         | 
| 6721 6742 | 
             
                'com.android.manufacturer' => 'AndroidMake',
         | 
| @@ -6815,6 +6836,58 @@ my %userDefined = ( | |
| 6815 6836 | 
             
                # (mdta)com.apple.proapps.image.{TIFF}.Software (eg. "9.0")
         | 
| 6816 6837 | 
             
            );
         | 
| 6817 6838 |  | 
| 6839 | 
            +
            # Keys tags in the audio track (ref PH)
         | 
| 6840 | 
            +
            %Image::ExifTool::QuickTime::AudioKeys = (
         | 
| 6841 | 
            +
                PROCESS_PROC => \&ProcessKeys,
         | 
| 6842 | 
            +
                WRITE_PROC => \&WriteKeys,
         | 
| 6843 | 
            +
                CHECK_PROC => \&CheckQTValue,
         | 
| 6844 | 
            +
                WRITABLE => 1,
         | 
| 6845 | 
            +
                GROUPS => { 1 => 'AudioKeys', 2 => 'Audio' },
         | 
| 6846 | 
            +
                WRITE_GROUP => 'AudioKeys',
         | 
| 6847 | 
            +
                LANG_INFO => \&GetLangInfo,
         | 
| 6848 | 
            +
                NOTES => q{
         | 
| 6849 | 
            +
                    Keys tags written in the audio track by some Apple devices.  These tags
         | 
| 6850 | 
            +
                    belong to the ExifTool AudioKeys family 1 gorup.
         | 
| 6851 | 
            +
                },
         | 
| 6852 | 
            +
                'player.movie.audio.gain'       => 'AudioGain',
         | 
| 6853 | 
            +
                'player.movie.audio.treble'     => 'Treble',
         | 
| 6854 | 
            +
                'player.movie.audio.bass'       => 'Bass',
         | 
| 6855 | 
            +
                'player.movie.audio.balance'    => 'Balance',
         | 
| 6856 | 
            +
                'player.movie.audio.pitchshift' => 'PitchShift',
         | 
| 6857 | 
            +
                'player.movie.audio.mute' => {
         | 
| 6858 | 
            +
                    Name => 'Mute',
         | 
| 6859 | 
            +
                    Format => 'int8u',
         | 
| 6860 | 
            +
                    PrintConv => { 0 => 'Off', 1 => 'On' },
         | 
| 6861 | 
            +
                },
         | 
| 6862 | 
            +
            );
         | 
| 6863 | 
            +
             | 
| 6864 | 
            +
            # Keys tags in the video track (ref PH)
         | 
| 6865 | 
            +
            %Image::ExifTool::QuickTime::VideoKeys = (
         | 
| 6866 | 
            +
                PROCESS_PROC => \&ProcessKeys,
         | 
| 6867 | 
            +
                WRITE_PROC => \&WriteKeys,
         | 
| 6868 | 
            +
                CHECK_PROC => \&CheckQTValue,
         | 
| 6869 | 
            +
                VARS => { LONG_TAGS => 2 },
         | 
| 6870 | 
            +
                WRITABLE => 1,
         | 
| 6871 | 
            +
                GROUPS => { 1 => 'VideoKeys', 2 => 'Camera' },
         | 
| 6872 | 
            +
                WRITE_GROUP => 'VideoKeys',
         | 
| 6873 | 
            +
                LANG_INFO => \&GetLangInfo,
         | 
| 6874 | 
            +
                NOTES => q{
         | 
| 6875 | 
            +
                    Keys tags written in the video track.  These tags belong to the ExifTool
         | 
| 6876 | 
            +
                    VideoKeys family 1 gorup.
         | 
| 6877 | 
            +
                },
         | 
| 6878 | 
            +
                'camera.identifier' => 'CameraIdentifier',
         | 
| 6879 | 
            +
                'camera.lens_model' => 'LensModel',
         | 
| 6880 | 
            +
                'camera.focal_length.35mm_equivalent' => 'FocalLengthIn35mmFormat',
         | 
| 6881 | 
            +
                'camera.framereadouttimeinmicroseconds' => {
         | 
| 6882 | 
            +
                    Name => 'FrameReadoutTime',
         | 
| 6883 | 
            +
                    ValueConv => '$val * 1e-6',
         | 
| 6884 | 
            +
                    ValueConvInv => 'int($val * 1e6 + 0.5)',
         | 
| 6885 | 
            +
                    PrintConv => '$val * 1e6 . " microseconds"',
         | 
| 6886 | 
            +
                    PrintConvInv => '$val =~ s/ .*//; $val * 1e-6',
         | 
| 6887 | 
            +
                },
         | 
| 6888 | 
            +
                'com.apple.photos.captureMode' => 'CaptureMode',
         | 
| 6889 | 
            +
            );
         | 
| 6890 | 
            +
             | 
| 6818 6891 | 
             
            # iTunes info ('----') atoms
         | 
| 6819 6892 | 
             
            %Image::ExifTool::QuickTime::iTunesInfo = (
         | 
| 6820 6893 | 
             
                PROCESS_PROC => \&ProcessMOV,
         | 
| @@ -7280,7 +7353,7 @@ my %userDefined = ( | |
| 7280 7353 | 
             
                    {
         | 
| 7281 7354 | 
             
                        Name => 'VideoFrameRate',
         | 
| 7282 7355 | 
             
                        Notes => 'average rate calculated from time-to-sample table for video media',
         | 
| 7283 | 
            -
                        Condition => '$$self{ | 
| 7356 | 
            +
                        Condition => '$$self{MediaType} eq "vide"',
         | 
| 7284 7357 | 
             
                        Format => 'undef',  # (necessary to prevent decoding as string!)
         | 
| 7285 7358 | 
             
                        # (must be RawConv so appropriate MediaTS is used in calculation)
         | 
| 7286 7359 | 
             
                        RawConv => 'Image::ExifTool::QuickTime::CalcSampleRate($self, \$val)',
         | 
| @@ -7871,7 +7944,6 @@ my %userDefined = ( | |
| 7871 7944 | 
             
                mode => 'ModeFlags', #PH (?) 0x04 is HD flag (https://compilr.com/heksesang/requiem-mac/UnDrm.java)
         | 
| 7872 7945 | 
             
                # sing - seen 4 zeros
         | 
| 7873 7946 | 
             
                # hi32 - seen "00 00 00 04"
         | 
| 7874 | 
            -
                
         | 
| 7875 7947 | 
             
            );
         | 
| 7876 7948 |  | 
| 7877 7949 | 
             
            # MP4 hint sample description box (ref 5)
         | 
| @@ -8119,6 +8191,7 @@ my %userDefined = ( | |
| 8119 8191 | 
             
                    Format => 'undef[4]',
         | 
| 8120 8192 | 
             
                    RawConv => q{
         | 
| 8121 8193 | 
             
                        $$self{HandlerType} = $val unless $val eq 'alis' or $val eq 'url ';
         | 
| 8194 | 
            +
                        $$self{MediaType} = $val if @{$$self{PATH}} > 1 and $$self{PATH}[-2] eq 'Media';
         | 
| 8122 8195 | 
             
                        $$self{HasHandler}{$val} = 1; # remember all our handlers
         | 
| 8123 8196 | 
             
                        return $val;
         | 
| 8124 8197 | 
             
                    },
         | 
| @@ -9538,6 +9611,8 @@ sub ProcessKeys($$$) | |
| 9538 9611 | 
             
                        my $groups = $$tagInfo{Groups};
         | 
| 9539 9612 | 
             
                        $$newInfo{Groups} = $groups ? { %$groups } : { };
         | 
| 9540 9613 | 
             
                        $$newInfo{Groups}{$_} or $$newInfo{Groups}{$_} = $$tagTablePtr{GROUPS}{$_} foreach 0..2;
         | 
| 9614 | 
            +
                        # set Keys group.  This is necessary for logic when reading the associated ItemList entry,
         | 
| 9615 | 
            +
                        # but note that the group name will be overridden by TAG_EXTRA G1 for tags in a track
         | 
| 9541 9616 | 
             
                        $$newInfo{Groups}{1} = 'Keys';
         | 
| 9542 9617 | 
             
                    } elsif ($tag =~ /^[-\w. ]+$/ or $tag =~ /\w{4}/) {
         | 
| 9543 9618 | 
             
                        # create info for tags with reasonable id's
         | 
| @@ -9605,7 +9680,7 @@ sub ProcessMOV($$;$) | |
| 9605 9680 |  | 
| 9606 9681 | 
             
                my $topLevel = not $$et{InQuickTime};
         | 
| 9607 9682 | 
             
                $$et{InQuickTime} = 1;
         | 
| 9608 | 
            -
                $$et{HandlerType} = $$et{MetaFormat} = ''  | 
| 9683 | 
            +
                $$et{HandlerType} = $$et{MetaFormat} = $$et{MediaType} = '' if $topLevel;
         | 
| 9609 9684 |  | 
| 9610 9685 | 
             
                unless (defined $$et{KeysCount}) {
         | 
| 9611 9686 | 
             
                    $$et{KeysCount} = 0;    # initialize ItemList key directory count
         | 
| @@ -9631,13 +9706,15 @@ sub ProcessMOV($$;$) | |
| 9631 9706 | 
             
                }
         | 
| 9632 9707 | 
             
                ($size, $tag) = unpack('Na4', $buff);
         | 
| 9633 9708 | 
             
                my $fast = $$et{OPTIONS}{FastScan} || 0;
         | 
| 9634 | 
            -
                # check for Insta360 trailer
         | 
| 9709 | 
            +
                # check for Insta360 or LIGOGPSINFO trailer
         | 
| 9635 9710 | 
             
                if ($topLevel and not $fast) {
         | 
| 9636 9711 | 
             
                    my $pos = $raf->Tell();
         | 
| 9637 | 
            -
                    if ($raf->Seek(-40, 2) and $raf->Read($buff, 40) == 40  | 
| 9638 | 
            -
                        substr($buff, 8) eq '8db42d694ccc418790edff439fe026bf')
         | 
| 9639 | 
            -
             | 
| 9640 | 
            -
                         | 
| 9712 | 
            +
                    if ($raf->Seek(-40, 2) and $raf->Read($buff, 40) == 40) {
         | 
| 9713 | 
            +
                        if (substr($buff, 8) eq '8db42d694ccc418790edff439fe026bf') {
         | 
| 9714 | 
            +
                            $trailer = [ 'Insta360', $raf->Tell() - unpack('V',$buff) ];
         | 
| 9715 | 
            +
                        } elsif ($buff =~ /\&\&\&\&(.{4})$/) {
         | 
| 9716 | 
            +
                            $trailer = [ 'LigoGPS', $raf->Tell() - Get32u(\$buff, 36) ];
         | 
| 9717 | 
            +
                        }
         | 
| 9641 9718 | 
             
                    }
         | 
| 9642 9719 | 
             
                    $raf->Seek($pos,0) or return 0;
         | 
| 9643 9720 | 
             
                }
         | 
| @@ -9754,16 +9831,18 @@ sub ProcessMOV($$;$) | |
| 9754 9831 | 
             
                    }
         | 
| 9755 9832 | 
             
                    if ($isUserData and $$et{SET_GROUP1}) {
         | 
| 9756 9833 | 
             
                        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
         | 
| 9757 | 
            -
                         | 
| 9758 | 
            -
             | 
| 9759 | 
            -
             | 
| 9760 | 
            -
                             | 
| 9761 | 
            -
             | 
| 9762 | 
            -
                                 | 
| 9763 | 
            -
             | 
| 9764 | 
            -
             | 
| 9834 | 
            +
                        unless ($$tagInfo{SubDirectory}) {
         | 
| 9835 | 
            +
                            # add track name to UserData tags inside tracks
         | 
| 9836 | 
            +
                            $tag = $$et{SET_GROUP1} . $tag;
         | 
| 9837 | 
            +
                            if (not $$tagTablePtr{$tag} and $tagInfo) {
         | 
| 9838 | 
            +
                                my %newInfo = %$tagInfo;
         | 
| 9839 | 
            +
                                foreach ('Name', 'Description') {
         | 
| 9840 | 
            +
                                    next unless $$tagInfo{$_};
         | 
| 9841 | 
            +
                                    $newInfo{$_} = $$et{SET_GROUP1} . $$tagInfo{$_};
         | 
| 9842 | 
            +
                                    $newInfo{$_} =~ s/^(Track\d+)Track/$1/; # remove duplicate "Track" in name
         | 
| 9843 | 
            +
                                }
         | 
| 9844 | 
            +
                                AddTagToTable($tagTablePtr, $tag, \%newInfo);
         | 
| 9765 9845 | 
             
                            }
         | 
| 9766 | 
            -
                            AddTagToTable($tagTablePtr, $tag, \%newInfo);
         | 
| 9767 9846 | 
             
                        }
         | 
| 9768 9847 | 
             
                    }
         | 
| 9769 9848 | 
             
                    # set flag to store additional information for ExtractEmbedded option
         | 
| @@ -9830,7 +9909,7 @@ sub ProcessMOV($$;$) | |
| 9830 9909 | 
             
                        # check for RIFF trailer (written by Auto-Vox dashcam)
         | 
| 9831 9910 | 
             
                        if ($buff =~ /^(gpsa|gps0|gsen|gsea)...\0/s) { # (yet seen only gpsa as first record)
         | 
| 9832 9911 | 
             
                            $et->VPrint(0, sprintf("Found RIFF trailer at offset 0x%x",$lastPos));
         | 
| 9833 | 
            -
                            if ($ | 
| 9912 | 
            +
                            if ($ee) {
         | 
| 9834 9913 | 
             
                                $raf->Seek(-8, 1) or last;  # seek back to start of trailer
         | 
| 9835 9914 | 
             
                                my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
         | 
| 9836 9915 | 
             
                                ProcessRIFFTrailer($et, { RAF => $raf }, $tbl);
         | 
| @@ -9980,6 +10059,7 @@ ItemID:         foreach $id (reverse sort { $a <=> $b } keys %$items) { | |
| 9980 10059 | 
             
                            }
         | 
| 9981 10060 | 
             
                        }
         | 
| 9982 10061 | 
             
                        if ($tagInfo) {
         | 
| 10062 | 
            +
                            my @found;
         | 
| 9983 10063 | 
             
                            my $subdir = $$tagInfo{SubDirectory};
         | 
| 9984 10064 | 
             
                            if ($subdir) {
         | 
| 9985 10065 | 
             
                                my $start = $$subdir{Start} || 0;
         | 
| @@ -10098,21 +10178,23 @@ ItemID:         foreach $id (reverse sort { $a <=> $b } keys %$items) { | |
| 10098 10178 | 
             
                                        Index   => $index,
         | 
| 10099 10179 | 
             
                                        Extra   => sprintf(", Type='${type}', Flags=0x%x%s, Lang=0x%.4x",$flags,$str,$lang),
         | 
| 10100 10180 | 
             
                                    ) if $verbose;
         | 
| 10101 | 
            -
                                     | 
| 10102 | 
            -
             | 
| 10103 | 
            -
             | 
| 10104 | 
            -
                                         | 
| 10105 | 
            -
                                         | 
| 10181 | 
            +
                                    if (defined $value) {
         | 
| 10182 | 
            +
                                        # use "Keys" in path instead of ItemList if this was defined by a Keys tag
         | 
| 10183 | 
            +
                                        # (the only reason for this is to have "Keys" in the family 5 group name)
         | 
| 10184 | 
            +
                                        # Note that the Keys group is specifically set by the ProcessKeys routine,
         | 
| 10185 | 
            +
                                        # even though this tag would be in the ItemList table
         | 
| 10186 | 
            +
                                        my $isKeys = $$tagInfo{Groups} && $$tagInfo{Groups}{1} && $$tagInfo{Groups}{1} eq 'Keys';
         | 
| 10187 | 
            +
                                        $isKeys and $oldDir = $$et{PATH}[-1], $$et{PATH}[-1] = 'Keys';
         | 
| 10188 | 
            +
                                        push @found, $et->FoundTag($langInfo, $value);
         | 
| 10189 | 
            +
                                        $$et{PATH}[-1] = $oldDir if $isKeys;
         | 
| 10106 10190 | 
             
                                    }
         | 
| 10107 | 
            -
                                    $et->FoundTag($langInfo, $value) if defined $value;
         | 
| 10108 | 
            -
                                    $$et{PATH}[-1] = $oldDir if $isKey;
         | 
| 10109 10191 | 
             
                                    $pos += $len;
         | 
| 10110 10192 | 
             
                                }
         | 
| 10111 10193 | 
             
                            } elsif ($tag =~ /^\xa9/ or $$tagInfo{IText}) {
         | 
| 10112 10194 | 
             
                                # parse international text to extract all languages
         | 
| 10113 10195 | 
             
                                my $pos = 0;
         | 
| 10114 10196 | 
             
                                if ($$tagInfo{Format}) {
         | 
| 10115 | 
            -
                                    $et->FoundTag($tagInfo, ReadValue(\$val, 0, $$tagInfo{Format}, undef, length($val)));
         | 
| 10197 | 
            +
                                    push @found, $et->FoundTag($tagInfo, ReadValue(\$val, 0, $$tagInfo{Format}, undef, length($val)));
         | 
| 10116 10198 | 
             
                                    $pos = $size;
         | 
| 10117 10199 | 
             
                                }
         | 
| 10118 10200 | 
             
                                for (;;) {
         | 
| @@ -10177,7 +10259,7 @@ ItemID:         foreach $id (reverse sort { $a <=> $b } keys %$items) { | |
| 10177 10259 | 
             
                                        $str = substr($val, $pos-$n-2, $n) . $str;
         | 
| 10178 10260 | 
             
                                    }
         | 
| 10179 10261 | 
             
                                    $langInfo = GetLangInfoQT($et, $tagInfo, $lang) if $lang;
         | 
| 10180 | 
            -
                                    $et->FoundTag($langInfo || $tagInfo, $str);
         | 
| 10262 | 
            +
                                    push @found, $et->FoundTag($langInfo || $tagInfo, $str);
         | 
| 10181 10263 | 
             
                                    $pos += $len;
         | 
| 10182 10264 | 
             
                                }
         | 
| 10183 10265 | 
             
                            } else {
         | 
| @@ -10191,6 +10273,7 @@ ItemID:         foreach $id (reverse sort { $a <=> $b } keys %$items) { | |
| 10191 10273 | 
             
                                    $$et{BASE} = $dataPos;
         | 
| 10192 10274 | 
             
                                }
         | 
| 10193 10275 | 
             
                                my $key = $et->FoundTag($tagInfo, $val);
         | 
| 10276 | 
            +
                                push @found, $key;
         | 
| 10194 10277 | 
             
                                $$et{BASE} = $oldBase if defined $oldBase;
         | 
| 10195 10278 | 
             
                                # decode if necessary (NOTE: must be done after RawConv)
         | 
| 10196 10279 | 
             
                                if (defined $key and (not $format or $format =~ /^string/) and
         | 
| @@ -10206,6 +10289,14 @@ ItemID:         foreach $id (reverse sort { $a <=> $b } keys %$items) { | |
| 10206 10289 | 
             
                                    }
         | 
| 10207 10290 | 
             
                                }
         | 
| 10208 10291 | 
             
                            }
         | 
| 10292 | 
            +
                            # tweak family 1 group names for Keys/ItemList/UserData tags in a track
         | 
| 10293 | 
            +
                            if ($$et{SET_GROUP1} and ($dirID eq 'ilst' or $dirID eq 'udta') and @found) {
         | 
| 10294 | 
            +
                                my $type = $trackPath{join '-', @{$$et{PATH}}};
         | 
| 10295 | 
            +
                                if ($type) {
         | 
| 10296 | 
            +
                                    my $grp = ($avType{$$et{MediaType}} || $$et{SET_GROUP1}) . $type;
         | 
| 10297 | 
            +
                                    defined and $et->SetGroup($_, $grp) foreach @found;
         | 
| 10298 | 
            +
                                }
         | 
| 10299 | 
            +
                            }
         | 
| 10209 10300 | 
             
                        }
         | 
| 10210 10301 | 
             
                    } else {
         | 
| 10211 10302 | 
             
                        $et->VerboseInfo($tag, $tagInfo,
         | 
| @@ -10218,6 +10309,7 @@ ItemID:         foreach $id (reverse sort { $a <=> $b } keys %$items) { | |
| 10218 10309 | 
             
                            last;
         | 
| 10219 10310 | 
             
                        }
         | 
| 10220 10311 | 
             
                    }
         | 
| 10312 | 
            +
                    $$et{MediaType} = '' if $tag eq 'trak';  # reset track type at end of track
         | 
| 10221 10313 | 
             
                    $dataPos += $size + 8;  # point to start of next atom data
         | 
| 10222 10314 | 
             
                    last if $dirEnd and $dataPos >= $dirEnd; # (note: ignores last value if 0 bytes)
         | 
| 10223 10315 | 
             
                    $lastPos = $raf->Tell() + $dirBase;
         | 
| @@ -10273,7 +10365,26 @@ QTLang: foreach $tag (@{$$et{QTLang}}) { | |
| 10273 10365 | 
             
                # process item information now that we are done processing its 'meta' container
         | 
| 10274 10366 | 
             
                HandleItemInfo($et) if $topLevel or $dirID eq 'meta';
         | 
| 10275 10367 |  | 
| 10276 | 
            -
                 | 
| 10368 | 
            +
                # process LigoGPS trailer now if it exists and we haven't already processed it
         | 
| 10369 | 
            +
                if ($trailer and $$trailer[0] eq 'LigoGPS' and $lastPos <= $$trailer[1] and
         | 
| 10370 | 
            +
                    $raf->Seek($$trailer[1]) and $raf->Read($buff, 8) == 8 and $buff =~ /skip$/)
         | 
| 10371 | 
            +
                {
         | 
| 10372 | 
            +
                    if ($ee) {
         | 
| 10373 | 
            +
                        my $len = Get32u(\$buff, 0) - 16;
         | 
| 10374 | 
            +
                        if ($len > 0 and $raf->Read($buff, $len) == $len and $buff =~ /^LIGOGPSINFO\0/) {
         | 
| 10375 | 
            +
                            my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
         | 
| 10376 | 
            +
                            my %dirInfo = ( DataPt => \$buff, DataPos => $$trailer[1] + 8, DirName => 'LigoGPSTrailer' );
         | 
| 10377 | 
            +
                            Image::ExifTool::LigoGPS::ProcessLigoGPS($et, \%dirInfo, $tbl);
         | 
| 10378 | 
            +
                        } else {
         | 
| 10379 | 
            +
                            $et->Warn('Unrecognized data in LigoGPS trailer');
         | 
| 10380 | 
            +
                        }
         | 
| 10381 | 
            +
                    } else {
         | 
| 10382 | 
            +
                        $et->Warn('Use the ExtractEmbedded option to decode timed GPS',3);
         | 
| 10383 | 
            +
                    }
         | 
| 10384 | 
            +
                }
         | 
| 10385 | 
            +
                # brute force scan for metadata embedded in media data
         | 
| 10386 | 
            +
                # (and process Insta360 trailer if it exists)
         | 
| 10387 | 
            +
                ScanMediaData($et) if $ee and $topLevel;
         | 
| 10277 10388 |  | 
| 10278 10389 | 
             
                # restore any changed options
         | 
| 10279 10390 | 
             
                $et->Options($_ => $saveOptions{$_}) foreach keys %saveOptions;
         | 
| @@ -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 100 different types of timed GPS metadata from video files.
         | 
| 115 115 | 
             
                },
         | 
| 116 116 | 
             
                VARS => { NO_ID => 1 },
         | 
| 117 117 | 
             
                GPSLatitude  => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', RawConv => '$$self{FoundGPSLatitude} = 1; $val' },
         | 
| @@ -1512,7 +1512,7 @@ Sample:     for ($i=0; ; ) { | |
| 1512 1512 | 
             
                # clean up
         | 
| 1513 1513 | 
             
                $raf->Seek($tell, 0); # restore original file position
         | 
| 1514 1514 | 
             
                delete $$et{DOC_NUM};
         | 
| 1515 | 
            -
                $$et{HandlerType} =  | 
| 1515 | 
            +
                $$et{HandlerType} = '';
         | 
| 1516 1516 | 
             
            }
         | 
| 1517 1517 |  | 
| 1518 1518 | 
             
            #------------------------------------------------------------------------------
         | 
| @@ -1718,7 +1718,7 @@ SamBlock: | |
| 1718 1718 | 
             
                            $fixup->AddFixup(length($buff) - $offsetPos);
         | 
| 1719 1719 | 
             
                            $fixup->AddFixup(length($buff) - $offsetPos + 4);
         | 
| 1720 1720 | 
             
                        }
         | 
| 1721 | 
            -
                        $et->VPrint(0, "Writing Samsung trailer ($dirLen bytes)\n") if $verbose;
         | 
| 1721 | 
            +
                        $et->VPrint(0, "  Writing Samsung trailer ($dirLen bytes)\n") if $verbose;
         | 
| 1722 1722 | 
             
                        Write($$dirInfo{OutFile}, $buff) or return -1;
         | 
| 1723 1723 | 
             
                        return 1;
         | 
| 1724 1724 | 
             
                    }
         |