exiftool-vendored.pl 12.49.0 → 12.50.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.
package/bin/Changes CHANGED
@@ -4,9 +4,44 @@ ExifTool Version History
4
4
 
5
5
  RSS feed: https://exiftool.org/rss.xml
6
6
 
7
- Note: The most recent production release is Version 12.42. (Other versions are
7
+ Note: The most recent production release is Version 12.50. (Other versions are
8
8
  considered development releases, and are not uploaded to MetaCPAN.)
9
9
 
10
+ Nov. 8, 2022 - Version 12.50 (production release)
11
+
12
+ - Added a new XMP-GCreations tag
13
+ - Added a few new Sony lenses (thanks Jos Roost)
14
+ - Added new SonyModelID and Olympus CameraType values (thanks LibRaw and Herb)
15
+ - Added a couple of new XMP tags (thanks Jose Oliver-Didier)
16
+ - Added a new Nikon Z lens (thanks LibRaw)
17
+ - Added a new Canon LensType and CanonModelID (thanks Norbert Wasser and
18
+ LibRaw)
19
+ - Added some new Pentax lenses (thanks LibRaw)
20
+ - Added experimental support for timed GPS in TS videos from Jomise T860S-GM
21
+ dashcam (more samples are needed for this to be finalized)
22
+ - Decode information written in "skip" atom of 70mai Pro Plus+ MP4 videos
23
+ - Decode timed accelerometer data from Kenwood dashcam MP4 videos
24
+ - Decode a few new Nikon Z9 tags (thanks Stefan Grussen)
25
+ - Decode ColorData for some newer Canon models (thanks LibRaw)
26
+ - Decode a number of new tags for the Sony ILCE-7RM5 (thanks Jos Roost)
27
+ - Updated IPTC XMP tags to correspond with new Photo Metadata 2022.1 standard
28
+ - Extract JPEG previews from FujiFilm HIF images
29
+ - Changed -if option so multiple -if options are evaluated at the lowest
30
+ specified -fast level
31
+ - Changed MIMEType for ICO and CUR files
32
+ - Enhanced -fast2 so it stops processing QuickTime files at mdat atom
33
+ - Enhanced -listx output so -f also indicates the ID of the parent structure
34
+ for Flattened tags
35
+ - Improved conversion of IPTC date-only and time-only tags to allow formatting
36
+ with the -d option
37
+ - Improved Canon and Nikon TimeZone tags to accept a wider variety of input
38
+ formats when writing
39
+ - Disabled extraction of Nikon Z9 MenuSettings for firmware 3.0 until they can
40
+ be properly decoded (thanks Warren Hatch)
41
+ - Fixed decoding of AF points for some newer Nikon models
42
+ - Fixed inconsistent year and time zone for Kenwood dashcam timed GPS in MP4
43
+ videos
44
+
10
45
  Oct. 19, 2022 - Version 12.49
11
46
 
12
47
  - Added read support for Windows ICO and CUR files
@@ -320,7 +355,7 @@ Oct. 16, 2021 - Version 12.33
320
355
  - Added a new Canon RF lens (thanks Norbert Wasser)
321
356
  - Decode Canon ShutterMode (thanks John Moyer)
322
357
  - Extract LensModel from some Olympus MOV videos
323
- - Generate MediaDataOffset/Size for MOV videos with zero-sized MDAT chunk
358
+ - Generate MediaDataOffset/Size for MOV videos with zero-sized mdat chunk
324
359
  - Improvements to CBOR reader, including hex dump with -v3 option
325
360
  - Recognize Final Cut Pro XML files
326
361
  - Allow binary data of Protected tags to be extracted with the -X -j and -php
@@ -2119,7 +2154,7 @@ Mar. 1, 2018 - Version 10.82
2119
2154
  - Added a few new CanonModelID/SonyModelID values (thanks LibRaw)
2120
2155
  - Added support for the Sony ILCE-7M3 (thanks Jos Roost)
2121
2156
  - Decode timed GPS information from Insta360 MP4 videos with the -ee option
2122
- - Write XMP before idat in MOV/MP4/CR3 files if possible
2157
+ - Write XMP before mdat in MOV/MP4/CR3 files if possible
2123
2158
  - Fixed "'x' outside of string" runtime error when reading some Sony images
2124
2159
  - Fixed problem with some hex dumps going to the console when -v3 was combined
2125
2160
  with the -w option
package/bin/MANIFEST CHANGED
@@ -598,6 +598,8 @@ t/GoPro.t
598
598
  t/GoPro_2.out
599
599
  t/HTML.t
600
600
  t/HTML_2.out
601
+ t/ICO.t
602
+ t/ICO_2.out
601
603
  t/IPTC.t
602
604
  t/IPTC_2.out
603
605
  t/IPTC_4.out
@@ -1025,6 +1027,7 @@ t/images/Geotag_DJI_2020-12-02_[07-50-31].csv
1025
1027
  t/images/GoPro.jpg
1026
1028
  t/images/HTML.html
1027
1029
  t/images/ICC_Profile.icc
1030
+ t/images/ICO.ico
1028
1031
  t/images/IPTC.jpg
1029
1032
  t/images/ISO.iso
1030
1033
  t/images/ITC.itc
package/bin/META.json CHANGED
@@ -47,6 +47,6 @@
47
47
  }
48
48
  },
49
49
  "release_status" : "stable",
50
- "version" : "12.49",
50
+ "version" : "12.50",
51
51
  "x_serialization_backend" : "JSON::PP version 4.02"
52
52
  }
package/bin/META.yml CHANGED
@@ -28,5 +28,5 @@ recommends:
28
28
  Time::HiRes: 0
29
29
  requires:
30
30
  perl: 5.004
31
- version: 12.49
31
+ version: 12.50
32
32
  x_serialization_backend: 'JSON::PP version 4.02'
package/bin/README CHANGED
@@ -107,8 +107,8 @@ your home directory, then you would type the following commands in a
107
107
  terminal window to extract and run ExifTool:
108
108
 
109
109
  cd ~/Desktop
110
- gzip -dc Image-ExifTool-12.49.tar.gz | tar -xf -
111
- cd Image-ExifTool-12.49
110
+ gzip -dc Image-ExifTool-12.50.tar.gz | tar -xf -
111
+ cd Image-ExifTool-12.50
112
112
  ./exiftool t/images/ExifTool.jpg
113
113
 
114
114
  Note: These commands extract meta information from one of the test images.
package/bin/exiftool CHANGED
@@ -11,7 +11,7 @@ use strict;
11
11
  use warnings;
12
12
  require 5.004;
13
13
 
14
- my $version = '12.49';
14
+ my $version = '12.50';
15
15
 
16
16
  # add our 'lib' directory to the include list BEFORE 'use Image::ExifTool'
17
17
  BEGIN {
@@ -1009,8 +1009,12 @@ for (;;) {
1009
1009
  }
1010
1010
  if (/^if(\d*)$/i) {
1011
1011
  my $cond = shift;
1012
- $fastCondition = $1 if length $1;
1012
+ my $fast = length($1) ? $1 : undef;
1013
1013
  defined $cond or Error("Expecting expression for -if option\n"), $badCmd=1, next;
1014
+ # use lowest -fast setting if multiple conditions
1015
+ if (not @condition or not defined $fast or (defined $fastCondition and $fastCondition > $fast)) {
1016
+ $fastCondition = $fast;
1017
+ }
1014
1018
  # prevent processing file unnecessarily for simple case of failed '$ok' or 'not $ok'
1015
1019
  $cond =~ /^\s*(not\s*)\$ok\s*$/i and ($1 xor $rtnValPrev) and $failCondition=1;
1016
1020
  # add to list of requested tags
@@ -5470,7 +5474,7 @@ with this command:
5470
5474
 
5471
5475
  produces output like this:
5472
5476
 
5473
- -- Generated by ExifTool 12.49 --
5477
+ -- Generated by ExifTool 12.50 --
5474
5478
  File: a.jpg - 2003:10:31 15:44:19
5475
5479
  (f/5.6, 1/60s, ISO 100)
5476
5480
  File: b.jpg - 2006:05:23 11:57:38
@@ -5889,12 +5893,14 @@ audio/video data in WAV/AVI files to search for additional metadata. These
5889
5893
  speed benefits are small when reading images directly from disk, but can be
5890
5894
  substantial if piping images through a network connection. For more
5891
5895
  substantial speed benefits, B<-fast2> also causes exiftool to avoid
5892
- extracting any EXIF MakerNote information. B<-fast3> avoids extracting
5893
- metadata from the file, and returns only pseudo System tags, but still reads
5894
- the file header to obtain an educated guess at FileType. B<-fast4> doesn't
5895
- even read the file header, and returns only System tags and a FileType based
5896
- on the file extension. B<-fast5> also disables generation of the Composite
5897
- tags (like B<-e>). Has no effect when writing.
5896
+ extracting any EXIF MakerNote information, and to stop processing at the
5897
+ IDAT chunk of PNG images and the mdat atom of QuickTime-format files (but
5898
+ note that some files may store metadata after this). B<-fast3> avoids
5899
+ extracting metadata from the file, and returns only pseudo System tags, but
5900
+ still reads the file header to obtain an educated guess at FileType.
5901
+ B<-fast4> doesn't even read the file header, and returns only System tags
5902
+ and a FileType based on the file extension. B<-fast5> also disables
5903
+ generation of the Composite tags (like B<-e>). Has no effect when writing.
5898
5904
 
5899
5905
  Note that a separate B<-fast> setting may be used for evaluation of a B<-if>
5900
5906
  condition, or when ordering files with the B<-fileOrder> option. See the
@@ -5914,14 +5920,13 @@ order may be reversed by prefixing the tag name with a C<-> (eg.
5914
5920
  C<-fileOrder -createdate>). Print conversion of the sorted values is
5915
5921
  disabled with the B<-n> option, or a C<#> appended to the tag name. Other
5916
5922
  formatting options (eg. B<-d>) have no effect on the sorted values. Note
5917
- that the B<-fileOrder> option can have a large performance impact since it
5918
- involves an additional processing pass of each file, but this impact may be
5919
- reduced by specifying a I<NUM> for the B<-fast> level used during the
5920
- metadata-extraction phase. For example, B<-fileOrder4> may be used if
5921
- I<TAG> is a pseudo System tag. If multiple B<-fileOrder> options are used,
5922
- the extraction is done at the lowest B<-fast> level. Note that files are
5923
- sorted across directory boundaries if multiple input directories are
5924
- specified.
5923
+ that the B<-fileOrder> option can incur large performance penalty since it
5924
+ involves an additional initial processing pass of all files, but this impact
5925
+ may be reduced by specifying a I<NUM> to effectively set the B<-fast> level
5926
+ for the initial pass. For example, B<-fileOrder4> may be used if I<TAG> is
5927
+ a pseudo System tag. If multiple B<-fileOrder> options are used, the
5928
+ extraction is done at the lowest B<-fast> level. Note that files are sorted
5929
+ across directory boundaries if multiple input directories are specified.
5925
5930
 
5926
5931
  =item B<-i> I<DIR> (B<-ignore>)
5927
5932
 
@@ -6256,12 +6261,13 @@ are some examples:
6256
6261
 
6257
6262
  When combined with B<-listx>, the B<-s> option shortens the output by
6258
6263
  omitting the descriptions and values (as in the last example above), and
6259
- B<-f> adds a 'flags' attribute if applicable. The flags are formatted as a
6260
- comma-separated list of the following possible values: Avoid, Binary, List,
6261
- Mandatory, Permanent, Protected, Unknown and Unsafe (see the L<Tag Name
6262
- documentation|Image::ExifTool::TagNames>). For XMP List tags, the list type
6263
- (Alt, Bag or Seq) is added to the flags, and flattened structure tags are
6264
- indicated by a Flattened flag.
6264
+ B<-f> adds 'flags' and 'struct' attributes if applicable. The flags are
6265
+ formatted as a comma-separated list of the following possible values:
6266
+ Avoid, Binary, List, Mandatory, Permanent, Protected, Unknown and Unsafe
6267
+ (see the L<Tag Name documentation|Image::ExifTool::TagNames>). For XMP List
6268
+ tags, the list type (Alt, Bag or Seq) is added to the flags, and flattened
6269
+ structure tags are indicated by a Flattened flag with 'struct' giving the ID
6270
+ of the parent structure.
6265
6271
 
6266
6272
  Note that none of the B<-list> options require an input I<FILE>.
6267
6273
 
@@ -35,7 +35,7 @@ use Image::ExifTool::Sony;
35
35
  use Image::ExifTool::Validate;
36
36
  use Image::ExifTool::MacOS;
37
37
 
38
- $VERSION = '3.49';
38
+ $VERSION = '3.50';
39
39
  @ISA = qw(Exporter);
40
40
 
41
41
  sub NumbersFirst($$);
@@ -1291,16 +1291,19 @@ TagID: foreach $tagID (@keys) {
1291
1291
  $printConv = shift @printConvList;
1292
1292
  $index = shift @indexList;
1293
1293
  }
1294
- } elsif ($printConv and $printConv =~ /DecodeBits\(\$val,\s*(\{.*\})\s*\)/s) {
1294
+ # look inside scalar PrintConv for a bit/byte conversion
1295
+ # (see Photoshop:PrintFlags for use of "$byte" decoding)
1296
+ } elsif ($printConv and $printConv =~ /DecodeBits\(\$(val|byte),\s*(\\\%[\w:]+|\{.*\})\s*\)/s) {
1297
+ my $type = $1 eq 'byte' ? 'Byte' : 'Bit';
1295
1298
  $$self{Model} = ''; # needed for Nikon ShootingMode
1296
- my $bits = eval $1;
1299
+ my $bits = eval $2;
1297
1300
  delete $$self{Model};
1298
1301
  if ($@) {
1299
1302
  warn $@;
1300
1303
  } else {
1301
1304
  my @pk = sort { NumbersFirst($a,$b) } keys %$bits;
1302
1305
  foreach (@pk) {
1303
- push @values, "Bit $_ = " . $$bits{$_};
1306
+ push @values, "$type $_ = " . $$bits{$_};
1304
1307
  }
1305
1308
  }
1306
1309
  }
@@ -88,7 +88,7 @@ sub ProcessCTMD($$$);
88
88
  sub ProcessExifInfo($$$);
89
89
  sub SwapWords($);
90
90
 
91
- $VERSION = '4.62';
91
+ $VERSION = '4.63';
92
92
 
93
93
  # Note: Removed 'USM' from 'L' lenses since it is redundant - PH
94
94
  # (or is it? Ref 32 shows 5 non-USM L-type lenses)
@@ -620,8 +620,9 @@ $VERSION = '4.62';
620
620
  '61182.40' => 'Canon RF 1200mm F8L IS USM', #42
621
621
  '61182.41' => 'Canon RF 1200mm F8L IS USM + RF1.4x', #42
622
622
  '61182.42' => 'Canon RF 1200mm F8L IS USM + RF2x', #42
623
+ '61182.43' => 'Canon RF 135mm F1.8 L IS USM', #42
623
624
  # we need the RFLensType values for the following...
624
- '61182.43' => 'Canon RF 5.2mm F2.8L Dual Fisheye 3D VR', #PH (NC)
625
+ '61182.44' => 'Canon RF 5.2mm F2.8L Dual Fisheye 3D VR', #PH (NC)
625
626
  65535 => 'n/a',
626
627
  );
627
628
 
@@ -982,6 +983,7 @@ $VERSION = '4.62';
982
983
  0x80000465 => 'EOS R10', #42
983
984
  0x80000467 => 'PowerShot ZOOM',
984
985
  0x80000468 => 'EOS M50 Mark II / Kiss M2', #IB
986
+ 0x80000481 => 'EOS R6 Mark II', #42
985
987
  0x80000520 => 'EOS D2000C', #IB
986
988
  0x80000560 => 'EOS D6000C', #PH (guess)
987
989
  );
@@ -1944,7 +1946,7 @@ my %offOn = ( 0 => 'Off', 1 => 'On' );
1944
1946
  SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData10' },
1945
1947
  },
1946
1948
  { # (int16u[3973]) - R3 ref IB
1947
- Condition => '$count == 3973',
1949
+ Condition => '$count == 3973 or $count == 3778',
1948
1950
  Name => 'ColorData11',
1949
1951
  SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData11' },
1950
1952
  },
@@ -6377,10 +6379,11 @@ my %ciMaxFocal = (
6377
6379
  1 => {
6378
6380
  Name => 'TimeZone',
6379
6381
  PrintConv => 'Image::ExifTool::TimeZoneString($val)',
6380
- PrintConvInv => sub {
6381
- my $val = shift;
6382
- $val =~ /^([-+]?)(\d{1,2}):?(\d{2})$/ or return undef;
6383
- return(($1 eq '-' ? -1 : 1) * ($2 * 60 + $3));
6382
+ PrintConvInv => q{
6383
+ $val =~ /Z$/ and return 0;
6384
+ $val =~ /([-+])(\d{1,2}):?(\d{2})$/ and return $1 . ($2 * 60 + $3);
6385
+ $val =~ /^(\d{2})(\d{2})$/ and return $1 * 60 + $2;
6386
+ return undef;
6384
6387
  },
6385
6388
  },
6386
6389
  2 => {
@@ -6836,6 +6839,7 @@ my %ciMaxFocal = (
6836
6839
  299 => 'Canon RF 1200mm F8L IS USM + RF1.4x', #42
6837
6840
  300 => 'Canon RF 1200mm F8L IS USM + RF2x', #42
6838
6841
  302 => 'Canon RF 15-30mm F4.5-6.3 IS STM', #42
6842
+ 303 => 'Canon RF 135mm F1.8 L IS USM', #42
6839
6843
  # Note: add new RF lenses to %canonLensTypes with ID 61182
6840
6844
  },
6841
6845
  },
@@ -8333,7 +8337,7 @@ my %ciMaxFocal = (
8333
8337
  # Color data (MakerNotes tag 0x4001, count=3973, ref IB)
8334
8338
  %Image::ExifTool::Canon::ColorData11 = (
8335
8339
  %binaryDataAttrs,
8336
- NOTES => 'These tags are used by the EOS R3',
8340
+ NOTES => 'These tags are used by the EOS R3, R7 and R6mkII',
8337
8341
  FORMAT => 'int16s',
8338
8342
  FIRST_ENTRY => 0,
8339
8343
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
@@ -8345,6 +8349,7 @@ my %ciMaxFocal = (
8345
8349
  RawConv => '$$self{ColorDataVersion} = $val',
8346
8350
  PrintConv => {
8347
8351
  34 => '34 (R3)', #IB
8352
+ 48 => '48 (R7, R10, R6 Mark II)', #IB
8348
8353
  },
8349
8354
  },
8350
8355
  0x69 => { Name => 'WB_RGGBLevelsAsShot', Format => 'int16s[4]' },
@@ -1084,11 +1084,11 @@ my %opcodeInfo = (
1084
1084
  {
1085
1085
  Name => 'ThumbnailOffset',
1086
1086
  Notes => q{
1087
- ThumbnailOffset in IFD1 of JPEG and some TIFF-based images, IFD0 of MRW
1088
- images and AVI and MOV videos, and the SubIFD in IFD1 of SRW images;
1089
- PreviewImageStart in MakerNotes and IFD0 of ARW and SR2 images;
1090
- JpgFromRawStart in SubIFD of NEF images and IFD2 of PEF images; and
1091
- OtherImageStart in everything else
1087
+ called JPEGInterchangeFormat in the specification, this is ThumbnailOffset
1088
+ in IFD1 of JPEG and some TIFF-based images, IFD0 of MRW images and AVI and
1089
+ MOV videos, and the SubIFD in IFD1 of SRW images; PreviewImageStart in
1090
+ MakerNotes and IFD0 of ARW and SR2 images; JpgFromRawStart in SubIFD of NEF
1091
+ images and IFD2 of PEF images; and OtherImageStart in everything else
1092
1092
  },
1093
1093
  # thumbnail is found in IFD1 of JPEG and TIFF images, and
1094
1094
  # IFD0 of EXIF information in FujiFilm AVI (RIFF) and MOV videos
@@ -1225,6 +1225,7 @@ my %opcodeInfo = (
1225
1225
  {
1226
1226
  Name => 'ThumbnailLength',
1227
1227
  Notes => q{
1228
+ called JPEGInterchangeFormatLength in the specification, this is
1228
1229
  ThumbnailLength in IFD1 of JPEG and some TIFF-based images, IFD0 of MRW
1229
1230
  images and AVI and MOV videos, and the SubIFD in IFD1 of SRW images;
1230
1231
  PreviewImageLength in MakerNotes and IFD0 of ARW and SR2 images;
@@ -558,7 +558,7 @@ DoneFix: $isDate = 1;
558
558
  } elsif ($nmea eq 'RMC') {
559
559
  # $GPRMC,092204.999,A,4250.5589,S,14718.5084,E,0.00,89.68,211200,,*25
560
560
  # $GPRMC,093657.007,,3652.835020,N,01053.104094,E,1.642,,290913,,,A*0F
561
- # $GPRMC,hhmmss.sss,A/V,ddmm.mmmm,N/S,ddmmm.mmmm,E/W,spd(knots),dir(deg),DDMMYY,,*cs
561
+ # $GPRMC,hhmmss.sss,A/V,ddmm.mmmm,N/S,dddmm.mmmm,E/W,spd(knots),dir(deg),DDMMYY,,*cs
562
562
  /^\$[A-Z]{2}RMC,(\d{2})(\d{2})(\d+(\.\d*)?),A?,(\d*?)(\d{1,2}\.\d+),([NS]),(\d*?)(\d{1,2}\.\d+),([EW]),(\d*\.?\d*),(\d*\.?\d*),(\d{2})(\d{2})(\d+)/ or next;
563
563
  next if $13 > 31 or $14 > 12 or $15 > 99; # validate day/month/year
564
564
  $fix{lat} = (($5 || 0) + $6/60) * ($7 eq 'N' ? 1 : -1);
@@ -86,6 +86,8 @@ sub ProcessICO($$$)
86
86
  # verify this is a valid ICO/CUR file
87
87
  return 0 unless $raf->Read($buff, 6) == 6;
88
88
  return 0 unless $buff =~ /^\0\0([\x01\x02])\0[^0]\0/s;
89
+ # (note: have seen cursor files in the wild with an 0x01 here,
90
+ # but SetFileType will use the .cur extension to identify these)
89
91
  $et->SetFileType($1 eq "\x01" ? 'ICO' : 'CUR');
90
92
  SetByteOrder('II');
91
93
  my $tagTbl = GetTagTable('Image::ExifTool::ICO::Main');
@@ -15,7 +15,7 @@ use strict;
15
15
  use vars qw($VERSION $AUTOLOAD %iptcCharset);
16
16
  use Image::ExifTool qw(:DataAccess :Utils);
17
17
 
18
- $VERSION = '1.57';
18
+ $VERSION = '1.58';
19
19
 
20
20
  %iptcCharset = (
21
21
  "\x1b%G" => 'UTF8',
@@ -411,6 +411,7 @@ my %fileFormat = (
411
411
  Shift => 'Time',
412
412
  ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
413
413
  ValueConvInv => 'Image::ExifTool::IPTC::IptcDate($val)',
414
+ PrintConv => '$self->Options("DateFormat") ? $self->ConvertDateTime("$val 00:00:00") : $val',
414
415
  PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($self,$val)',
415
416
  },
416
417
  60 => {
@@ -420,6 +421,7 @@ my %fileFormat = (
420
421
  Shift => 'Time',
421
422
  ValueConv => 'Image::ExifTool::Exif::ExifTime($val)',
422
423
  ValueConvInv => 'Image::ExifTool::IPTC::IptcTime($val)',
424
+ PrintConv => '$self->Options("DateFormat") ? $self->ConvertDateTime("1970:01:01 $val") : $val',
423
425
  PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($self,$val)',
424
426
  },
425
427
  62 => {
@@ -429,6 +431,7 @@ my %fileFormat = (
429
431
  Shift => 'Time',
430
432
  ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
431
433
  ValueConvInv => 'Image::ExifTool::IPTC::IptcDate($val)',
434
+ PrintConv => '$self->Options("DateFormat") ? $self->ConvertDateTime("$val 00:00:00") : $val',
432
435
  PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($self,$val)',
433
436
  },
434
437
  63 => {
@@ -438,6 +441,7 @@ my %fileFormat = (
438
441
  Shift => 'Time',
439
442
  ValueConv => 'Image::ExifTool::Exif::ExifTime($val)',
440
443
  ValueConvInv => 'Image::ExifTool::IPTC::IptcTime($val)',
444
+ PrintConv => '$self->Options("DateFormat") ? $self->ConvertDateTime("1970:01:01 $val") : $val',
441
445
  PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($self,$val)',
442
446
  },
443
447
  65 => {
@@ -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.22';
35
+ $VERSION = '1.23';
36
36
 
37
37
  # program map table "stream_type" lookup (ref 6/1/9)
38
38
  my %streamType = (
@@ -415,6 +415,48 @@ sub ParsePID($$$$$)
415
415
  }
416
416
  }
417
417
  $more = 1;
418
+ } elsif ($$dataPt =~ /\$GPRMC,/) {
419
+ # Jomise T860S-GM dashcam
420
+ # $GPRMC,hhmmss.ss,A,ddmm.mmmmm,N,dddmm.mmmmm,W,spd-kts,dir-dg,DDMMYY,,*cs
421
+ # $GPRMC,172255.00,A,:985.95194,N,17170.14674,W,029.678,170.68,240822,,,D*7B
422
+ # $GPRMC,172355.00,A,:984.76779,N,17170.00473,W,032.219,172.04,240822,,,D*7B
423
+ # ddmm.mmmm: from 4742.2568 12209.2028 (should be)
424
+ # to 4741.7696 12209.1056
425
+ # stamped on video: 47.70428N, 122.15338W, 35mph (dd.ddddd)
426
+ # to 47.69616N, 122.15176W, 37mph
427
+ my $tagTbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
428
+ while ($$dataPt =~ /\$[A-Z]{2}RMC,(\d{2})(\d{2})(\d+(\.\d*)?),A?,(.{2})(\d{2}\.\d+),([NS]),(.{3})(\d{2}\.\d+),([EW]),(\d*\.?\d*),(\d*\.?\d*),(\d{2})(\d{2})(\d+)/g and
429
+ # do some basic sanity checks on the date
430
+ $13 <= 31 and $14 <= 12 and $15 <= 99)
431
+ {
432
+ $$et{DOC_NUM} = ++$$et{DOC_COUNT};
433
+ my $year = $15 + ($15 >= 70 ? 1900 : 2000);
434
+ $et->HandleTag($tagTbl, GPSDateTime => sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2dZ', $year, $14, $13, $1, $2, $3));
435
+ #(not this simple)
436
+ #$et->HandleTag($tagTbl, GPSLatitude => (($5 || 0) + $6/60) * ($7 eq 'N' ? 1 : -1));
437
+ #$et->HandleTag($tagTbl, GPSLongitude => (($8 || 0) + $9/60) * ($10 eq 'E' ? 1 : -1));
438
+ $et->HandleTag($tagTbl, GPSSpeed => $11 * $knotsToKph) if length $11;
439
+ $et->HandleTag($tagTbl, GPSTrack => $12) if length $12;
440
+ # it looks like maybe the degrees are xor-ed with something,
441
+ # and the minutes have some scaling factor and offset?
442
+ # (the code below is approximately correct for my only sample)
443
+ my @chars = unpack('C*', $5 . $8);
444
+ my @xor = (0x0e,0x0e,0x00,0x05,0x03); # (empirical based on 1 sample; may be completely off base)
445
+ my $bad;
446
+ foreach (@chars) {
447
+ $_ ^= shift(@xor);
448
+ $bad = 1 if $_ < 0x30 or $_ > 0x39;
449
+ }
450
+ if ($bad) {
451
+ $et->WarnOnce('Error decrypting GPS degrees');
452
+ } else {
453
+ my $la = pack('C*', @chars[0,1]);
454
+ my $lo = pack('C*', @chars[2,3,4]);
455
+ $et->WarnOnce('Decryption of this GPS is highly experimental. More testing samples are required');
456
+ $et->HandleTag($tagTbl, GPSLatitude => (($la || 0) + (($6-85.95194)/2.43051724137931+42.2568)/60) * ($7 eq 'N' ? 1 : -1));
457
+ $et->HandleTag($tagTbl, GPSLongitude => (($lo || 0) + (($9-70.14674)/1.460987654320988+9.2028)/60) * ($10 eq 'E' ? 1 : -1));
458
+ }
459
+ }
418
460
  } elsif ($$dataPt =~ /^.{44}A\0{3}.{4}([NS])\0{3}.{4}([EW])\0{3}/s and length($$dataPt) >= 84) {
419
461
  #forum11320
420
462
  SetByteOrder('II');
@@ -493,6 +535,7 @@ sub ProcessM2TS($$)
493
535
  my %gpsPID = (
494
536
  0x0300 => 1, # Novatek INNOVV
495
537
  0x01e4 => 1, # vsys a6l dashcam
538
+ 0x0e1b => 1, # Jomise T860S-GM dashcam
496
539
  );
497
540
  my $pEnd = 0;
498
541
 
@@ -385,7 +385,7 @@ sub ProcessKLV($$$)
385
385
  # Parse MISB metadata
386
386
  # Inputs: 0) ExifTool ref, 1) data ref, 2) tag table ref
387
387
  # Returns: 1 if something was extracted, 0 otherwise
388
- sub ParseMISB($$)
388
+ sub ParseMISB($$$)
389
389
  {
390
390
  my ($et, $dataPt, $tagTablePtr) = @_;
391
391
  my $end = length $$dataPt;