exiftool_vendored 13.03.0 → 13.06.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -17,6 +17,7 @@
17
17
  # 2022/06/21 - PH Added ability to read Google Takeout JSON files
18
18
  # 2024/04/23 - PH Added ability to read more OpenTracks GPS tags
19
19
  # 2024/08/28 - PH Added support for new Google Takeout JSON format
20
+ # 2024/11/26 - PH Also write GPSMeasureMode and GPSDOP
20
21
  #
21
22
  # References: 1) http://www.topografix.com/GPX/1/1/
22
23
  # 2) http://www.gpsinformation.org/dale/nmea.htm#GSA
@@ -31,7 +32,7 @@ use vars qw($VERSION);
31
32
  use Image::ExifTool qw(:Public);
32
33
  use Image::ExifTool::GPS;
33
34
 
34
- $VERSION = '1.80';
35
+ $VERSION = '1.81';
35
36
 
36
37
  sub JITTER() { return 2 } # maximum time jitter
37
38
 
@@ -90,12 +91,25 @@ my %fixInfoKeys = (
90
91
  orient => [ 'dir', 'pitch', 'roll' ],
91
92
  atemp => [ 'atemp' ],
92
93
  err => [ 'err' ],
94
+ dop => [ 'hdop', 'vdop', 'pdop' ],
93
95
  );
94
96
 
95
- my %isOrient = ( dir => 1, pitch => 1, roll => 1 ); # test for orientation key
97
+ # category for select keys
98
+ my %keyCategory = (
99
+ dir => 'orient',
100
+ pitch => 'orient',
101
+ roll => 'orient',
102
+ hdop => 'dop',
103
+ pdop => 'dop',
104
+ vdop => 'dop',
105
+ );
96
106
 
97
107
  # tags which may exist separately in some formats (eg. CSV)
98
- my %sepTags = ( dir => 1, pitch => 1, roll => 1, track => 1, speed => 1 );
108
+ my %sepTags = (
109
+ dir => 1, pitch => 1, roll => 1, track => 1, speed => 1,
110
+ # (plus other tags we don't want to scan outwards for)
111
+ hdop => 1, pdop => 1, vdop => 1,
112
+ );
99
113
 
100
114
  # conversion factors for GPSSpeed (standard EXIF units only)
101
115
  my %speedConv = (
@@ -348,8 +362,8 @@ sub LoadTrackLog($$;$)
348
362
  my $tag = $xmlTag{lc $2};
349
363
  if ($tag) {
350
364
  $$fix{$tag} = $4;
351
- if ($isOrient{$tag}) {
352
- $$has{orient} = 1;
365
+ if ($keyCategory{$tag}) {
366
+ $$has{$keyCategory{$tag}} = 1;
353
367
  } elsif ($tag eq 'alt') {
354
368
  # validate altitude
355
369
  undef $$fix{alt} if defined $$fix{alt} and $$fix{alt} !~ /^[+-]?\d+\.?\d*/;
@@ -394,8 +408,8 @@ sub LoadTrackLog($$;$)
394
408
  } else {
395
409
  $$fix{$tag} = $1;
396
410
  }
397
- if ($isOrient{$tag}) {
398
- $$has{orient} = 1;
411
+ if ($keyCategory{$tag}) {
412
+ $$has{$keyCategory{$tag}} = 1;
399
413
  } elsif ($tag eq 'alt') {
400
414
  # validate altitude
401
415
  undef $$fix{alt} if defined $$fix{alt} and $$fix{alt} !~ /^[+-]?\d+\.?\d*/;
@@ -1145,7 +1159,7 @@ sub SetGeoValues($$;$)
1145
1159
  # loop through available fix information categories
1146
1160
  # (pos, track, alt, orient)
1147
1161
  my ($category, $key);
1148
- Category: foreach $category (qw{pos track alt orient atemp err}) {
1162
+ Category: foreach $category (qw{pos track alt orient atemp err dop}) {
1149
1163
  next unless $$has{$category};
1150
1164
  my ($f, $p0b, $p1b, $f0b);
1151
1165
  # loop through specific fix information keys
@@ -1303,6 +1317,25 @@ Category: foreach $category (qw{pos track alt orient atemp err}) {
1303
1317
  if ($$has{err}) {
1304
1318
  @r = $et->SetNewValue(GPSHPositioningError => $$fix{err}, %opts);
1305
1319
  }
1320
+ if ($$has{dop}) {
1321
+ my ($dop, $mm);
1322
+ if (defined $$fix{pdop}) {
1323
+ $dop = $$fix{pdop};
1324
+ $mm = 3;
1325
+ } elsif (defined $$fix{hdop}) {
1326
+ if (defined $$fix{vdop}) {
1327
+ $dop = sqrt($$fix{hdop} * $$fix{hdop} + $$fix{vdop} * $$fix{vdop});
1328
+ $mm = 3;
1329
+ } else {
1330
+ $dop = $$fix{hdop};
1331
+ $mm = 2;
1332
+ }
1333
+ }
1334
+ if (defined $dop) {
1335
+ $et->SetNewValue(GPSMeasureMode => $mm, %opts);
1336
+ $et->SetNewValue(GPSDOP => $dop, %opts);
1337
+ }
1338
+ }
1306
1339
  unless ($xmp) {
1307
1340
  my ($latRef, $lonRef);
1308
1341
  $latRef = ($$fix{lat} > 0 ? 'N' : 'S') if defined $$fix{lat};
@@ -1328,7 +1361,8 @@ Category: foreach $category (qw{pos track alt orient atemp err}) {
1328
1361
  GPSAltitude GPSAltitudeRef GPSDateStamp GPSTimeStamp GPSDateTime
1329
1362
  GPSTrack GPSTrackRef GPSSpeed GPSSpeedRef GPSImgDirection
1330
1363
  GPSImgDirectionRef GPSPitch GPSRoll CameraElevationAngle
1331
- AmbientTemperature GPSHPositioningError GPSCoordinates))
1364
+ AmbientTemperature GPSHPositioningError GPSCoordinates
1365
+ GPSMeasureMode GPSDOP))
1332
1366
  {
1333
1367
  my @r = $et->SetNewValue($_, undef, %opts);
1334
1368
  }
@@ -16,7 +16,7 @@ use vars qw($VERSION);
16
16
  use Image::ExifTool qw(:DataAccess :Utils);
17
17
  use Image::ExifTool::QuickTime;
18
18
 
19
- $VERSION = '1.09';
19
+ $VERSION = '1.11';
20
20
 
21
21
  sub ProcessGoPro($$$);
22
22
  sub ProcessString($$$);
@@ -72,6 +72,7 @@ my %addUnits = (
72
72
  let me know if you discover the meaning of any of these unknown tags. See
73
73
  L<https://github.com/gopro/gpmf-parser> for details about this format.
74
74
  },
75
+ # ABSC (GPMF) - seen: 0 (fmt f)
75
76
  ACCL => { #2 (gpmd)
76
77
  Name => 'Accelerometer',
77
78
  Notes => 'accelerator readings in m/s2',
@@ -81,7 +82,9 @@ my %addUnits = (
81
82
  # ANGY (GPMF-GEOC) - seen 179.9 (fmt d, Max)
82
83
  # ANGZ (GPMF-GEOC) - seen 0.152 (fmt d, Max)
83
84
  ALLD => 'AutoLowLightDuration', #1 (gpmd) (untested)
84
- # APTO (GPMF) - seen: 'RAW', 'DYNM' (fmt c)
85
+ # APTO (GPMF) - seen: 'OFF', 'RAW', 'DYNM' (fmt c)
86
+ # ARUW (GPMF) - seen: 1.14285719394684 (fmt f)
87
+ # ARWA (GPMF) - seen: 1.14285719394684 (fmt f)
85
88
  ATTD => { #PH (Karma)
86
89
  Name => 'Attitude',
87
90
  # UNIT=s,rad,rad,rad,rad/s,rad/s,rad/s,
@@ -96,8 +99,10 @@ my %addUnits = (
96
99
  # SCAL=1000 1 1 1 1
97
100
  Binary => 1,
98
101
  },
102
+ # AUBT (GPMF) - seen: ''N' (type c)
99
103
  AUDO => 'AudioSetting', #PH (GPMF - seen: 'WIND', fmt c)
100
104
  # AUPT (GPMF) - seen: 'N','Y' (fmt c)
105
+ # BITR (GPMF) - seen: 'STANDARD' (fmt c)
101
106
  BPOS => { #PH (Karma)
102
107
  Name => 'Controller',
103
108
  Unknown => 1,
@@ -111,9 +116,16 @@ my %addUnits = (
111
116
  # CALH (GPMF-GEOC) - seen 3040 (fmt L, Max)
112
117
  # CALW (GPMF-GEOC) - seen 4056 (fmt L, Max)
113
118
  CASN => 'CameraSerialNumber', #PH (GPMF - seen: 'C3221324545448', fmt c)
119
+ # CDAT (GPMF) - seen: 1732152823 (fmt J)
120
+ # CDTM (GPMF) - seen: 0 (fmt L)
114
121
  # CINF (GPMF) - seen: 0x67376be7709bc8876a8baf3940908618, 0xe230988539b30cf5f016627ae8fc5395,
115
122
  # 0x8bcbe424acc5b37d7d77001635198b3b (fmt B) (Camera INFormation?)
123
+ # CLDP (GPMF) - seen: 'Y' (fmt c)
124
+ # CLKC (GPMF) - seen: 0 (fmt L)
125
+ # CLKS (GPMF) - seen: 2 (fmt B)
116
126
  # CMOD (GPMF) - seen: 12,13,17 [12 360 video, 13 time-laps video, 17 JPEG] (fmt B)
127
+ # CPID (GPMF) - seen: '1194885996 3387225026 733916448 2433577768' (fmt L)
128
+ # CPIN (GPMF) - seen: 1
117
129
  # CRTX (GPMF-BACK/FRNT) - double[1]
118
130
  # CRTY (GPMF-BACK/FRNT) - double[1]
119
131
  CSEN => { #PH (Karma)
@@ -123,6 +135,7 @@ my %addUnits = (
123
135
  # SCAL=1000 1 1 1 1 1 1 1 1 1 1
124
136
  Binary => 1,
125
137
  },
138
+ # CTRL (GPMF) - seen: 'Pro' (fmt c)
126
139
  CYTS => { #PH (Karma)
127
140
  Name => 'CoyoteStatus',
128
141
  # UNIT=s,,,,,rad,rad,rad,,
@@ -141,6 +154,8 @@ my %addUnits = (
141
154
  # (Max) DVID='FRNT',DVNM='Front Lens',KLNS,CTRX,CTRY,MFOV,SFTR
142
155
  # (Max) DVID='HLMT',DVNM='Highlights'
143
156
  },
157
+ # DNSC (GPMF) - seen: 'HIGH' (fmt c)
158
+ # DUST (GPMF) - seen: 'NO_LIMIT' (fmt c)
144
159
  # DVID (GPMF) - DeviceID; seen: 1 (fmt L), HLMT (fmt F), GEOC (fmt F), 'BACK' (fmt F, Max)
145
160
  DVID => { Name => 'DeviceID', Unknown => 1 }, #2 (gpmd)
146
161
  # DVNM (GPMF) seen: 'Video Global Settings' (fmt c), 'Highlights' (fmt c), 'Geometry Calibrations' (Max)
@@ -150,6 +165,7 @@ my %addUnits = (
150
165
  Name => 'DigitalZoom',
151
166
  PrintConv => { N => 'No', Y => 'Yes' },
152
167
  },
168
+ # DZMX (GPMF) - seen: 1.39999997615814 (fmt f)
153
169
  # DZST (GPMF) - seen: 0 (fmt L) (something to do with digital zoom maybe?)
154
170
  EISA => { #PH (GPMF) - seen: 'Y','N','HS EIS','N/A' (fmt c) [N was for a time-lapse video]
155
171
  Name => 'ElectronicImageStabilization',
@@ -188,10 +204,20 @@ my %addUnits = (
188
204
  },
189
205
  GPS5 => { #2 (gpmd)
190
206
  Name => 'GPSInfo',
207
+ # UNIT=deg,deg,m,m/s,m/s
208
+ # TYPE=l
191
209
  # SCAL=10000000,10000000,1000,1000,100
192
210
  RawConv => '$val', # necessary to use scaled value instead of raw data as subdir data
193
211
  SubDirectory => { TagTable => 'Image::ExifTool::GoPro::GPS5' },
194
212
  },
213
+ GPS9 => { #PH (gpmd, Hero 13)
214
+ Name => 'GPSInfo9',
215
+ # UNIT=deg,deg,m,m/s,m/s,,s,,
216
+ # TYPE=lllllllSS
217
+ # SCAL=10000000 10000000 1000 1000 100 1 1000 100 1
218
+ RawConv => '$val', # necessary to use scaled value instead of raw data as subdir data
219
+ SubDirectory => { TagTable => 'Image::ExifTool::GoPro::GPS9' },
220
+ },
195
221
  GPSF => { #2 (gpmd)
196
222
  Name => 'GPSMeasureMode',
197
223
  PrintConv => {
@@ -216,7 +242,10 @@ my %addUnits = (
216
242
  Notes => 'gyroscope readings in rad/s',
217
243
  Binary => 1,
218
244
  },
245
+ # HCTL (GPMF) - seen: "Off" (fmt c)
246
+ # HDRV (GPMF) - seen: "N" (fmt c)
219
247
  # HFLG (APP6) - seen: 0
248
+ # HSGT (GPMF) - seen: 'OFF' (fmt c)
220
249
  ISOE => 'ISOSpeeds', #PH (gpmd)
221
250
  ISOG => { #2 (gpmd)
222
251
  Name => 'ImageSensorGain',
@@ -232,6 +261,7 @@ my %addUnits = (
232
261
  },
233
262
  # KLNS (GPMF-BACK/FRNT) - double[5] (fmt d, Max)
234
263
  # LINF (GPMF) - seen: LAJ7061916601668,C3341326002180,C33632245450981 (fmt c) (Lens INFormation?)
264
+ # LMOD (GPMF) - seen: 'NONE' (fmt F)
235
265
  LNED => { #PH (Karma)
236
266
  Name => 'LocalPositionNED',
237
267
  # UNIT=s,m,m,m,m/s,m/s,m/s
@@ -240,14 +270,20 @@ my %addUnits = (
240
270
  Binary => 1,
241
271
  },
242
272
  MAGN => 'Magnetometer', #1 (gpmd) (units of uT)
273
+ # MAPX (GPMF) - seen: 1 (fmt f)
274
+ # MAPY (GPMF) - seen: 1 (fmt f)
243
275
  # MFOV (GPMF-BACK/FRNT) - seen: 100 (fmt d, Max)
244
276
  MINF => { #PH (GPMF - seen: HERO6 Black, fmt c)
245
277
  Name => 'Model',
246
278
  Groups => { 2 => 'Camera' },
247
279
  Description => 'Camera Model Name',
248
280
  },
281
+ # MMOD (GPMF) - seen: 'STEREO' (fmt c)
249
282
  # MTYP (GPMF) - seen: 0,1,5,11 [1 for time-lapse video, 5 for 360 video, 11 for JPEG] (fmt B)
250
283
  # MUID (GPMF) - seen: 3882563431 2278071152 967805802 411471936 0 0 0 0 (fmt L)
284
+ # MXCF (GPMF) - seen: 'x1' (fmt c)
285
+ # MYCF (GPMF) - seen: 'y1' (fmt c)
286
+ # ORDP (GPMF) - seen: 'Y' (fmt c)
251
287
  OREN => { #PH (GPMF - seen: 'U', fmt c)
252
288
  Name => 'AutoRotation',
253
289
  PrintConv => {
@@ -258,11 +294,16 @@ my %addUnits = (
258
294
  },
259
295
  # (most of the "P" tags are ProTune settings - PH)
260
296
  PHDR => 'HDRSetting', #PH (APP6 - seen: 0)
297
+ # PIMD (GPMF) - seen: 'AUTO' (fmt c)
261
298
  PIMN => 'AutoISOMin', #PH (GPMF - seen: 100, fmt L)
262
299
  PIMX => 'AutoISOMax', #PH (GPMF - seen: 1600, fmt L)
300
+ # POLY (GPMF) - seen: '0 2.11120247840881 0.14325800538063 -1.030...' (fmt f)
263
301
  # PRAW (APP6) - seen: 0, 'N', 'Y' (fmt c)
302
+ # PRCN (GPMF) - seen: 65 zeros (fmt B)
264
303
  PRES => 'PhotoResolution', #PH (APP6 - seen: '12MP_W')
265
304
  # PRJT (APP6) - seen: 'GPRO','EACO' (fmt F, Hero8, Max)
305
+ # PRNA (GPMF) - seen 10 (fmt B)
306
+ # PRNU (GPMF) - seen 0 (fmt B)
266
307
  PRTN => { #PH (GPMF - seen: 'N', fmt c)
267
308
  Name => 'ProTune',
268
309
  PrintConv => {
@@ -275,6 +316,9 @@ my %addUnits = (
275
316
  PTSH => 'Sharpness', #PH (GPMF - seen: 'HIGH', fmt c)
276
317
  PTWB => 'WhiteBalance', #PH (GPMF - seen: 'AUTO', fmt c)
277
318
  # PVUL (APP6) - seen: 'F' (fmt c, Hero8, Max)
319
+ # PWPR (GPMF) - seen: 'PERFORMANCE' (fmt c)
320
+ # PYCF (GPMF) - seen: '[r0,r1,r2,r3,r4,r5,r6]' (fmt c)
321
+ # RAMP (GPMF) - seen: empty string (fmt c)
278
322
  RATE => 'Rate', #PH (GPMF - seen: '0_5SEC', fmt c; APP6 - seen: '4_1SEC')
279
323
  RMRK => { #2 (gpmd)
280
324
  Name => 'Comments',
@@ -284,6 +328,7 @@ my %addUnits = (
284
328
  Name => 'ScaleFactor',
285
329
  Unknown => 1,
286
330
  },
331
+ # SCAP (GPMF) - seen: 'N' (fmt c)
287
332
  SCPR => { #PH (Karma) [stream was empty]
288
333
  Name => 'ScaledPressure',
289
334
  # UNIT=s,Pa,Pa,degC
@@ -291,6 +336,7 @@ my %addUnits = (
291
336
  # SCAL=1000 0.00999999977648258 0.00999999977648258 100
292
337
  %addUnits,
293
338
  },
339
+ # SCTM (GPMF) - seen 0 (fmt L)
294
340
  # SFTR (GPMF-BACK/FRNT) - seen 0.999,1.00004 (fmt d, Max)
295
341
  # SHFX (GPMF-GEOC) - seen 22.92 (fmt d, Max)
296
342
  # SHFY (GPMF-GEOC) - seen 0.123 (fmt d, Max)
@@ -355,6 +401,10 @@ my %addUnits = (
355
401
  # TOCK => { Name => 'OutTime', Unknown => 1, ValueConv => '$val/1000' }, #1 (gpmd)
356
402
  TSMP => { Name => 'TotalSamples', Unknown => 1 }, #2 (gpmd)
357
403
  TYPE => { Name => 'StructureType', Unknown => 1 }, #2 (gpmd,GPMF - eg 'LLLllfFff', fmt c)
404
+ TZON => { # (GPMF) - seen: 60 (fmt s)
405
+ Name => 'TimeZone',
406
+ PrintConv => 'Image::ExifTool::TimeZoneString($val)',
407
+ },
358
408
  UNIT => { #2 (gpmd) alternative units
359
409
  Name => 'Units',
360
410
  Unknown => 1,
@@ -373,6 +423,7 @@ my %addUnits = (
373
423
  },
374
424
  },
375
425
  # VLTA (GPMF) - seen: 78 ('N') (fmt B -- wrong format?)
426
+ VFPS => { Name => 'VideoFrameRate', PrintConv => '$val=~s( )(/);$val' }, #PH (GPMF, fmt L)
376
427
  VFRH => { #PH (Karma)
377
428
  Name => 'VisualFlightRulesHUD',
378
429
  BinaryData => 1,
@@ -380,13 +431,17 @@ my %addUnits = (
380
431
  # TYPE=ffffsS
381
432
  },
382
433
  # VLTE (GPMF) - seen: 'Y','N' (fmt c)
434
+ VRES => { Name => 'VideoFrameSize', PrintConv => '$val=~s/ /x/;$val' }, #PH (GPMF, fmt L)
383
435
  WBAL => 'ColorTemperatures', #PH (gpmd)
384
436
  WRGB => { #PH (gpmd)
385
437
  Name => 'WhiteBalanceRGB',
386
438
  Binary => 1,
387
439
  },
388
440
  # ZFOV (APP6,GPMF) - seen: 148.34, 0 (fmt f, Hero8, Max)
389
- # the following ref forum12825
441
+ # ZMPL (GPMF) - seen: 0.652929663658142 (fmt f)
442
+ #
443
+ # the following ref forum12825
444
+ #
390
445
  MUID => {
391
446
  Name => 'MediaUniqueID',
392
447
  PrintConv => q{
@@ -418,7 +473,7 @@ my %addUnits = (
418
473
  YAVG => 'LumaAverage',
419
474
  );
420
475
 
421
- # GoPro GPS5 tags (ref 2) (Hero5,Hero6)
476
+ # GoPro GPS5 tags (ref 2) (Hero5,Hero6,Hero9)
422
477
  %Image::ExifTool::GoPro::GPS5 = (
423
478
  PROCESS_PROC => \&ProcessString,
424
479
  GROUPS => { 1 => 'GoPro', 2 => 'Location' },
@@ -435,8 +490,65 @@ my %addUnits = (
435
490
  Name => 'GPSAltitude',
436
491
  PrintConv => '"$val m"',
437
492
  },
438
- 3 => 'GPSSpeed', # (unit='m/s')
439
- 4 => 'GPSSpeed3D', # (unit='m/s')
493
+ 3 => {
494
+ Name => 'GPSSpeed',
495
+ Notes => 'stored as m/s but converted to km/h when extracted',
496
+ ValueConv => '$val * 3.6',
497
+ },
498
+ 4 => {
499
+ Name => 'GPSSpeed3D',
500
+ Notes => 'stored as m/s but converted to km/h when extracted',
501
+ ValueConv => '$val * 3.6',
502
+ },
503
+ );
504
+
505
+ # GoPro GPS9 tags (Hero13)
506
+ %Image::ExifTool::GoPro::GPS9 = (
507
+ PROCESS_PROC => \&ProcessString,
508
+ GROUPS => { 1 => 'GoPro', 2 => 'Location' },
509
+ VARS => { HEX_ID => 0, ID_LABEL => 'Index' },
510
+ 0 => { # (unit='deg')
511
+ Name => 'GPSLatitude',
512
+ PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
513
+ },
514
+ 1 => { # (unit='deg')
515
+ Name => 'GPSLongitude',
516
+ PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
517
+ },
518
+ 2 => { # (unit='m')
519
+ Name => 'GPSAltitude',
520
+ PrintConv => '"$val m"',
521
+ },
522
+ 3 => {
523
+ Name => 'GPSSpeed',
524
+ Notes => 'stored as m/s but converted to km/h when extracted',
525
+ ValueConv => '$val * 3.6',
526
+ },
527
+ 4 => {
528
+ Name => 'GPSSpeed3D',
529
+ Notes => 'stored as m/s but converted to km/h when extracted',
530
+ ValueConv => '$val * 3.6',
531
+ },
532
+ 5 => { # days since 2000
533
+ Name => 'GPSDays',
534
+ RawConv => '$$self{GPSDays} = $val; undef',
535
+ Hidden => 1,
536
+ },
537
+ 6 => { # seconds of date/time
538
+ Name => 'GPSDateTime',
539
+ Groups => { 2 => 'Time' },
540
+ # (10957 days from Jan 1 1970 to Jan 1 2000)
541
+ RawConv => 'ConvertUnixTime(($$self{GPSDays} + 10957) * 24 * 3600 + $val, undef, 3)',
542
+ PrintConv => '$self->ConvertDateTime($val)',
543
+ },
544
+ 7 => 'GPSDOP',
545
+ 8 => {
546
+ Name => 'GPSMeasureMode', #PH (NC)
547
+ PrintConv => {
548
+ 2 => '2-Dimensional Measurement',
549
+ 3 => '3-Dimensional Measurement',
550
+ },
551
+ },
440
552
  );
441
553
 
442
554
  # GoPro GPRI tags (ref PH) (Karma)
@@ -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.37';
14
+ $VERSION = '1.38';
15
15
 
16
16
  sub ProcessOcad($$$);
17
17
  sub ProcessJPEG_HDR($$$);
@@ -87,6 +87,11 @@ sub ProcessJPEG_HDR($$$);
87
87
  Name => 'InfiRayVersion',
88
88
  Condition => '$$valPt =~ /^....IJPEG\0/s',
89
89
  SubDirectory => { TagTable => 'Image::ExifTool::InfiRay::Version' },
90
+ }, {
91
+ Name => 'UniformResourceName',
92
+ Groups => { 1 => 'APP2' },
93
+ Condition => '$$valPt =~ /^urn:/',
94
+ Notes => 'used in Apple HDR images',
90
95
  }, {
91
96
  Name => 'PreviewImage',
92
97
  Condition => '$$valPt =~ /^(|QVGA\0|BGTH)\xff\xd8\xff\xdb/',
@@ -246,16 +251,26 @@ sub ProcessJPEG_HDR($$$);
246
251
  Condition => '$$valPt =~ /^SEAL\0/',
247
252
  SubDirectory => { TagTable => 'Image::ExifTool::XMP::SEAL' },
248
253
  }],
249
- APP10 => {
254
+ APP10 => [{
250
255
  Name => 'Comment',
251
256
  Condition => '$$valPt =~ /^UNICODE\0/',
252
257
  Notes => 'PhotoStudio Unicode comment',
253
- },
258
+ }, {
259
+ Name => 'HDRGainCurve', #PH (NC)
260
+ Condition => '$$valPt =~ /^AROT\0\0.{4}/s',
261
+ Groups => { 1 => 'APP10', 2 => 'Image' },
262
+ ValueConv => q{
263
+ my $n = unpack('x6N', $val);
264
+ return '<truncated AROT data>' if length($val)-6 < $n * 4;
265
+ my $str = join ' ', unpack("x10V$n", $val);
266
+ return \$str;
267
+ },
268
+ }],
254
269
  APP11 => [{
255
270
  Name => 'JPEG-HDR',
256
271
  Condition => '$$valPt =~ /^HDR_RI /',
257
272
  SubDirectory => { TagTable => 'Image::ExifTool::JPEG::HDR' },
258
- },{
273
+ }, {
259
274
  Name => 'JUMBF',
260
275
  Condition => '$$valPt =~ /^JP/',
261
276
  SubDirectory => { TagTable => 'Image::ExifTool::Jpeg2000::Main' },
@@ -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.08';
17
+ $VERSION = '1.09';
18
18
 
19
19
  # test for recognized OOXML document extensions
20
20
  my %isOOXML = (
@@ -360,12 +360,12 @@ sub ProcessDOCX($$)
360
360
  }
361
361
  # process XML files (docProps/app.xml, docProps/core.xml, docProps/custom.xml)
362
362
  my %dirInfo = (
363
- DataPt => \$buff,
364
- DirLen => length $buff,
365
- DataLen => length $buff,
366
- XMPParseOpts => {
367
- FoundProc => \&FoundTag,
368
- },
363
+ DataPt => \$buff,
364
+ DirLen => length $buff,
365
+ # (skip over XML header if it exists)
366
+ DirStart => ($buff =~ /<\?xml\s+.*?\?>/g ? pos($buff) : 0),
367
+ DataLen => length $buff,
368
+ XMPParseOpts => { FoundProc => \&FoundTag },
369
369
  );
370
370
  $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
371
371
  undef $buff; # (free memory now)
@@ -28,7 +28,7 @@ use strict;
28
28
  use vars qw($VERSION $AUTOLOAD $iptcDigestInfo %printFlags);
29
29
  use Image::ExifTool qw(:DataAccess :Utils);
30
30
 
31
- $VERSION = '1.70';
31
+ $VERSION = '1.71';
32
32
 
33
33
  sub ProcessPhotoshop($$$);
34
34
  sub WritePhotoshop($$$);
@@ -322,7 +322,7 @@ my %unicodeString = (
322
322
  0x0432 => { Unknown => 1, Name => 'MeasurementScale' }, #7
323
323
  0x0433 => { Unknown => 1, Name => 'TimelineInfo' }, #7
324
324
  0x0434 => { Unknown => 1, Name => 'SheetDisclosure' }, #7
325
- 0x0435 => { Unknown => 1, Name => 'DisplayInfo' }, #7
325
+ 0x0435 => { Unknown => 1, Name => 'ChannelOptions' }, #7/forum16762
326
326
  0x0436 => { Unknown => 1, Name => 'OnionSkins' }, #7
327
327
  0x0438 => { Unknown => 1, Name => 'CountInfo' }, #7
328
328
  0x043a => { Unknown => 1, Name => 'PrintInfo2' }, #7