exiftool-vendored.pl 12.97.0 → 13.0.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 +48 -2
- package/bin/META.json +1 -1
- package/bin/META.yml +1 -1
- package/bin/README +2 -2
- package/bin/arg_files/exif2xmp.args +4 -0
- package/bin/arg_files/xmp2exif.args +4 -0
- package/bin/config_files/example.config +2 -1
- package/bin/exiftool +255 -54
- package/bin/lib/File/RandomAccess.pm +5 -2
- package/bin/lib/Image/ExifTool/APP12.pm +3 -2
- package/bin/lib/Image/ExifTool/Canon.pm +2 -1
- package/bin/lib/Image/ExifTool/Exif.pm +1 -1
- package/bin/lib/Image/ExifTool/Geolocation.dat +0 -0
- package/bin/lib/Image/ExifTool/Geotag.pm +4 -3
- package/bin/lib/Image/ExifTool/Import.pm +7 -3
- package/bin/lib/Image/ExifTool/InDesign.pm +4 -3
- package/bin/lib/Image/ExifTool/JSON.pm +3 -4
- package/bin/lib/Image/ExifTool/Jpeg2000.pm +2 -1
- package/bin/lib/Image/ExifTool/Lytro.pm +2 -2
- package/bin/lib/Image/ExifTool/M2TS.pm +10 -2
- package/bin/lib/Image/ExifTool/PhaseOne.pm +2 -1
- package/bin/lib/Image/ExifTool/QuickTime.pm +17 -6
- package/bin/lib/Image/ExifTool/QuickTimeStream.pl +88 -9
- package/bin/lib/Image/ExifTool/Sony.pm +6 -1
- package/bin/lib/Image/ExifTool/TagLookup.pm +14 -9
- package/bin/lib/Image/ExifTool/TagNames.pod +40 -23
- package/bin/lib/Image/ExifTool/WritePDF.pl +47 -21
- package/bin/lib/Image/ExifTool/WriteXMP.pl +16 -4
- package/bin/lib/Image/ExifTool/Writer.pl +16 -6
- package/bin/lib/Image/ExifTool/XMP.pm +19 -4
- package/bin/lib/Image/ExifTool/XMPStruct.pl +15 -7
- package/bin/lib/Image/ExifTool.pm +37 -12
- package/bin/lib/Image/ExifTool.pod +31 -8
- package/bin/perl-Image-ExifTool.spec +1 -1
- package/bin/pp_build_exe.args +4 -4
- package/bin/windows_exiftool.txt +32 -10
- package/package.json +3 -3
|
@@ -1349,7 +1349,7 @@ my %tagLookup = (
|
|
|
1349
1349
|
'camerae-mountversion' => { 490 => 0xb },
|
|
1350
1350
|
'cameraelevationangle' => { 124 => 0x9405, 524 => 'CameraElevationAngle' },
|
|
1351
1351
|
'camerafilename' => { 507 => 'CameraFilename' },
|
|
1352
|
-
'camerafirmware' => { 124 => 0xa439 },
|
|
1352
|
+
'camerafirmware' => { 124 => 0xa439, 524 => 'CameraFirmware' },
|
|
1353
1353
|
'cameraid' => { 333 => 0x209, 413 => 'cmid', 429 => 0x209 },
|
|
1354
1354
|
'cameraidentifier' => { 407 => 'camera.identifier' },
|
|
1355
1355
|
'cameraimage' => { 495 => [\'Cameras','CamerasCameraImage'] },
|
|
@@ -3728,8 +3728,8 @@ my %tagLookup = (
|
|
|
3728
3728
|
'imagedustoff' => { 300 => 0xfe443a45 },
|
|
3729
3729
|
'imageeditcount' => { 388 => 0x41 },
|
|
3730
3730
|
'imageediting' => { 388 => 0x32 },
|
|
3731
|
-
'imageeditingsoftware' => { 124 => 0xa43b },
|
|
3732
|
-
'imageeditor' => { 124 => 0xa438 },
|
|
3731
|
+
'imageeditingsoftware' => { 124 => 0xa43b, 524 => 'ImageEditingSoftware' },
|
|
3732
|
+
'imageeditor' => { 124 => 0xa438, 524 => 'ImageEditor' },
|
|
3733
3733
|
'imageeffects' => { 420 => 0x1010 },
|
|
3734
3734
|
'imagefileconstraints' => { 338 => 'ImageFileConstraints' },
|
|
3735
3735
|
'imagefileformatasdelivered' => { 338 => 'ImageFileFormatAsDelivered' },
|
|
@@ -3805,9 +3805,10 @@ my %tagLookup = (
|
|
|
3805
3805
|
'imagesuppliername' => { 338 => [\'ImageSupplier','ImageSupplierImageSupplierName'] },
|
|
3806
3806
|
'imagetemperaturemax' => { 126 => 0x1 },
|
|
3807
3807
|
'imagetemperaturemin' => { 126 => 0x2 },
|
|
3808
|
+
'imagetitle' => { 124 => 0xa436, 524 => 'ImageTitle' },
|
|
3808
3809
|
'imagetone' => { 388 => 0x4f },
|
|
3809
3810
|
'imagetype' => { 136 => 0x82, 338 => 'ImageType' },
|
|
3810
|
-
'imageuniqueid' => { 1 => 0x15, 68 => 0x28, 124 => 0xa420, 522 => 'ImageUniqueID', 523 => 'ImageUniqueID' },
|
|
3811
|
+
'imageuniqueid' => { 1 => 0x15, 68 => 0x28, 124 => 0xa420, 522 => 'ImageUniqueID', 523 => 'ImageUniqueID', 524 => 'ImageUniqueID' },
|
|
3811
3812
|
'imagewidth' => { 124 => 0x100, 193 => 0xe, 397 => 0x10c, 502 => 'ImageWidth', 542 => 'ImageWidth' },
|
|
3812
3813
|
'inclinationangle' => { 491 => 0x900f },
|
|
3813
3814
|
'inclinationcorrection' => { 491 => 0x900e },
|
|
@@ -4796,7 +4797,7 @@ my %tagLookup = (
|
|
|
4796
4797
|
'metadataauthorityidentifier' => { 531 => [\'metadataAuthority','metadataAuthorityIdentifier'] },
|
|
4797
4798
|
'metadataauthorityname' => { 531 => [\'metadataAuthority','metadataAuthorityName'] },
|
|
4798
4799
|
'metadatadate' => { 544 => 'MetadataDate' },
|
|
4799
|
-
'metadataeditingsoftware' => { 124 => 0xa43c },
|
|
4800
|
+
'metadataeditingsoftware' => { 124 => 0xa43c, 524 => 'MetadataEditingSoftware' },
|
|
4800
4801
|
'metadatalastedited' => { 531 => 'metadataLastEdited' },
|
|
4801
4802
|
'metadatalasteditor' => { 531 => 'metadataLastEditor' },
|
|
4802
4803
|
'metadatalasteditoridentifier' => { 531 => [\'metadataLastEditor','metadataLastEditorIdentifier'] },
|
|
@@ -5599,7 +5600,7 @@ my %tagLookup = (
|
|
|
5599
5600
|
'photoeffectsgreen' => { 302 => 0x6 },
|
|
5600
5601
|
'photoeffectsred' => { 302 => 0x4 },
|
|
5601
5602
|
'photoeffectstype' => { 302 => 0x0 },
|
|
5602
|
-
'photographer' => { 124 => 0xa437 },
|
|
5603
|
+
'photographer' => { 124 => 0xa437, 524 => 'Photographer' },
|
|
5603
5604
|
'photographicsensitivity' => { 524 => 'PhotographicSensitivity' },
|
|
5604
5605
|
'photoidentifier' => { 1 => 0x2b },
|
|
5605
5606
|
'photoinfoplayback' => { 307 => '17.6', 316 => '33.6' },
|
|
@@ -5946,7 +5947,7 @@ my %tagLookup = (
|
|
|
5946
5947
|
'rawdevcolorspace' => { 334 => 0x108, 335 => 0x109 },
|
|
5947
5948
|
'rawdevcontrastvalue' => { 334 => 0x106, 335 => 0x105 },
|
|
5948
5949
|
'rawdeveditstatus' => { 334 => 0x10b },
|
|
5949
|
-
'rawdevelopingsoftware' => { 124 => 0xa43a },
|
|
5950
|
+
'rawdevelopingsoftware' => { 124 => 0xa43a, 524 => 'RAWDevelopingSoftware' },
|
|
5950
5951
|
'rawdevelopmentprocess' => { 388 => 0x62 },
|
|
5951
5952
|
'rawdevengine' => { 334 => 0x109, 335 => 0x10b },
|
|
5952
5953
|
'rawdevexposurebiasvalue' => { 334 => 0x100, 335 => 0x100 },
|
|
@@ -6940,7 +6941,7 @@ my %tagLookup = (
|
|
|
6940
6941
|
'timezoneinfo' => { 105 => 0x2 },
|
|
6941
6942
|
'timezoneoffset' => { 124 => 0x882a },
|
|
6942
6943
|
'tint' => { 407 => 'player.movie.visual.tint', 517 => 'Tint', 519 => 'Tint' },
|
|
6943
|
-
'title' => {
|
|
6944
|
+
'title' => { 162 => 'Title', 337 => 'Title', 341 => 'Title', 352 => 0x65, 404 => 'Title', 405 => ['titl',"\xa9nam"], 407 => 'title', 413 => ['titl',"\xa9nam"], 520 => 'title', 533 => 'Title', 544 => 'Title' },
|
|
6944
6945
|
'togglestyleamount' => { 517 => 'ToggleStyleAmount', 519 => 'ToggleStyleAmount' },
|
|
6945
6946
|
'togglestyledigest' => { 517 => 'ToggleStyleDigest', 519 => 'ToggleStyleDigest' },
|
|
6946
6947
|
'tonecomp' => { 241 => 0x81 },
|
|
@@ -8686,7 +8687,6 @@ my %tagExists = (
|
|
|
8686
8687
|
'cont' => 1,
|
|
8687
8688
|
'contactnames' => 1,
|
|
8688
8689
|
'containerversion' => 1,
|
|
8689
|
-
'contake' => 1,
|
|
8690
8690
|
'contentbranding' => 1,
|
|
8691
8691
|
'contentdescribes' => 1,
|
|
8692
8692
|
'contentdescription' => 1,
|
|
@@ -8709,6 +8709,7 @@ my %tagExists = (
|
|
|
8709
8709
|
'contrastadjustment' => 1,
|
|
8710
8710
|
'contrastinfo' => 1,
|
|
8711
8711
|
'controller' => 1,
|
|
8712
|
+
'conttake' => 1,
|
|
8712
8713
|
'convergenceangle' => 1,
|
|
8713
8714
|
'convergencebaseimage' => 1,
|
|
8714
8715
|
'convergencedistance' => 1,
|
|
@@ -8820,6 +8821,7 @@ my %tagExists = (
|
|
|
8820
8821
|
'customfunctionsd30' => 1,
|
|
8821
8822
|
'customfunctionsd60' => 1,
|
|
8822
8823
|
'customfunctionsunknown' => 1,
|
|
8824
|
+
'custominfo' => 1,
|
|
8823
8825
|
'customsettingsd3' => 1,
|
|
8824
8826
|
'customsettingsd300' => 1,
|
|
8825
8827
|
'customsettingsd300s' => 1,
|
|
@@ -9741,6 +9743,8 @@ my %tagExists = (
|
|
|
9741
9743
|
'gpsframingaltitude' => 1,
|
|
9742
9744
|
'gpsframinglatitude' => 1,
|
|
9743
9745
|
'gpsframinglongitude' => 1,
|
|
9746
|
+
'gpshomelatitude' => 1,
|
|
9747
|
+
'gpshomelongitude' => 1,
|
|
9744
9748
|
'gpshorizontalaccuracy' => 1,
|
|
9745
9749
|
'gpsinfo' => 1,
|
|
9746
9750
|
'gpslatitude2' => 1,
|
|
@@ -12014,6 +12018,7 @@ my %tagExists = (
|
|
|
12014
12018
|
'scenebalancealgorithmrevision' => 1,
|
|
12015
12019
|
'sceneclassification' => 1,
|
|
12016
12020
|
'scenecolorimetryestimates' => 1,
|
|
12021
|
+
'sceneilluminance' => 1,
|
|
12017
12022
|
'scheduleitemid' => 1,
|
|
12018
12023
|
'schemeinfo' => 1,
|
|
12019
12024
|
'schemetype' => 1,
|
|
@@ -12,7 +12,7 @@ meta information extracted from or written to a file.
|
|
|
12
12
|
=head1 TAG TABLES
|
|
13
13
|
|
|
14
14
|
The tables listed below give the names of all tags recognized by ExifTool.
|
|
15
|
-
They contain a total of
|
|
15
|
+
They contain a total of 28165 tags, with 17491 unique tag names.
|
|
16
16
|
|
|
17
17
|
B<Tag ID>, B<Index#> or B<Sequence> is given in the first column of each
|
|
18
18
|
table. A B<Tag ID> is the computer-readable equivalent of a tag name, and
|
|
@@ -871,7 +871,7 @@ for the official EXIF 2.32 specification.
|
|
|
871
871
|
0xa433 LensMake ExifIFD string
|
|
872
872
|
0xa434 LensModel ExifIFD string
|
|
873
873
|
0xa435 LensSerialNumber ExifIFD string
|
|
874
|
-
0xa436
|
|
874
|
+
0xa436 ImageTitle ExifIFD string
|
|
875
875
|
0xa437 Photographer ExifIFD string
|
|
876
876
|
0xa438 ImageEditor ExifIFD string
|
|
877
877
|
0xa439 CameraFirmware ExifIFD string
|
|
@@ -4605,7 +4605,7 @@ These tags belong to the ExifTool XMP-exif family 1 group.
|
|
|
4605
4605
|
GPSTrack rational
|
|
4606
4606
|
GPSTrackRef string
|
|
4607
4607
|
GPSVersionID string
|
|
4608
|
-
ImageUniqueID string
|
|
4608
|
+
ImageUniqueID string/
|
|
4609
4609
|
ISO integer+
|
|
4610
4610
|
LightSource string
|
|
4611
4611
|
MakerNote string
|
|
@@ -4686,6 +4686,7 @@ These tags belong to the ExifTool XMP-exifEX family 1 group.
|
|
|
4686
4686
|
Acceleration rational
|
|
4687
4687
|
SerialNumber string
|
|
4688
4688
|
CameraElevationAngle rational
|
|
4689
|
+
CameraFirmware string
|
|
4689
4690
|
OwnerName string
|
|
4690
4691
|
CompositeImage integer
|
|
4691
4692
|
CompositeImageCount integer+
|
|
@@ -4702,6 +4703,10 @@ These tags belong to the ExifTool XMP-exifEX family 1 group.
|
|
|
4702
4703
|
CompImageValues rational_+
|
|
4703
4704
|
Gamma rational
|
|
4704
4705
|
Humidity rational
|
|
4706
|
+
ImageEditingSoftware string
|
|
4707
|
+
ImageEditor string
|
|
4708
|
+
ImageTitle string
|
|
4709
|
+
ImageUniqueID string
|
|
4705
4710
|
InteropIndex string
|
|
4706
4711
|
ISOSpeed integer
|
|
4707
4712
|
ISOSpeedLatitudeyyy integer
|
|
@@ -4710,8 +4715,11 @@ These tags belong to the ExifTool XMP-exifEX family 1 group.
|
|
|
4710
4715
|
LensModel string
|
|
4711
4716
|
LensSerialNumber string
|
|
4712
4717
|
LensInfo rational+
|
|
4718
|
+
MetadataEditingSoftware string
|
|
4719
|
+
Photographer string
|
|
4713
4720
|
PhotographicSensitivity integer
|
|
4714
4721
|
Pressure rational
|
|
4722
|
+
RAWDevelopingSoftware string
|
|
4715
4723
|
RecommendedExposureIndex integer
|
|
4716
4724
|
SensitivityType integer
|
|
4717
4725
|
StandardOutputSensitivity integer
|
|
@@ -26108,7 +26116,7 @@ the image undisplayable.
|
|
|
26108
26116
|
------ -------- --------
|
|
26109
26117
|
0 MajorBrand no
|
|
26110
26118
|
1 MinorVersion no
|
|
26111
|
-
2 CompatibleBrands no
|
|
26119
|
+
2 CompatibleBrands no+
|
|
26112
26120
|
|
|
26113
26121
|
=head3 Jpeg2000 ImageHeader Tags
|
|
26114
26122
|
|
|
@@ -26163,7 +26171,7 @@ from any tags found in this segment.
|
|
|
26163
26171
|
------ -------- --------
|
|
26164
26172
|
'Aperture' Aperture no
|
|
26165
26173
|
'ColorMode' ColorMode no
|
|
26166
|
-
'
|
|
26174
|
+
'ContTake' ContTake no
|
|
26167
26175
|
'ExpBias' ExposureCompensation no
|
|
26168
26176
|
'FNumber' FNumber no
|
|
26169
26177
|
'FWare' FirmwareVersion no
|
|
@@ -29846,6 +29854,7 @@ for the official QuickTime specification.
|
|
|
29846
29854
|
'PICT' PreviewPICT no
|
|
29847
29855
|
'_htc' HTCInfo QuickTime HTCInfo
|
|
29848
29856
|
'ardt' ARDroneFile no
|
|
29857
|
+
'cust' CustomInfo no
|
|
29849
29858
|
'frea' Kodak_frea Kodak frea
|
|
29850
29859
|
'free' KodakFree Kodak Free
|
|
29851
29860
|
Pittasoft QuickTime Pittasoft
|
|
@@ -29897,7 +29906,7 @@ for the official QuickTime specification.
|
|
|
29897
29906
|
The tags below are extracted from timed metadata in QuickTime and other
|
|
29898
29907
|
formats of video files when the ExtractEmbedded option is used. Although
|
|
29899
29908
|
most of these tags are combined into the single table below, ExifTool
|
|
29900
|
-
currently reads
|
|
29909
|
+
currently reads 78 different formats of timed GPS metadata from video files.
|
|
29901
29910
|
|
|
29902
29911
|
Tag Name Writable
|
|
29903
29912
|
-------- --------
|
|
@@ -30163,6 +30172,7 @@ changed via the config file.
|
|
|
30163
30172
|
'producer' Producer yes
|
|
30164
30173
|
'publisher' Publisher yes
|
|
30165
30174
|
'rating.user' UserRating yes
|
|
30175
|
+
'scene-illuminance' SceneIlluminance no
|
|
30166
30176
|
'software' Software yes
|
|
30167
30177
|
'still-image-time' StillImageTime no
|
|
30168
30178
|
'title' Title yes
|
|
@@ -30185,22 +30195,29 @@ changed via the config file.
|
|
|
30185
30195
|
|
|
30186
30196
|
=head3 QuickTime tx3g Tags
|
|
30187
30197
|
|
|
30188
|
-
Tags extracted from the tx3g sbtl timed metadata of Yuneec drones,
|
|
30189
|
-
subtitle text in some other videos.
|
|
30198
|
+
Tags extracted from the tx3g sbtl timed metadata of Yuneec and Autel drones,
|
|
30199
|
+
and subtitle text in some other videos.
|
|
30190
30200
|
|
|
30191
|
-
Tag ID
|
|
30192
|
-
------
|
|
30193
|
-
'Alt'
|
|
30194
|
-
'DateTime'
|
|
30195
|
-
'
|
|
30196
|
-
'
|
|
30197
|
-
'
|
|
30198
|
-
'
|
|
30199
|
-
'
|
|
30200
|
-
'
|
|
30201
|
-
'
|
|
30202
|
-
'
|
|
30203
|
-
'
|
|
30201
|
+
Tag ID Tag Name Writable
|
|
30202
|
+
------ -------- --------
|
|
30203
|
+
'Alt' GPSAltitude no
|
|
30204
|
+
'DateTime' DateTime no
|
|
30205
|
+
'EV' ExposureCompensation no
|
|
30206
|
+
'F-NUM' FNumber no
|
|
30207
|
+
'GPSDateTime' GPSDateTime no
|
|
30208
|
+
'GimPitch' GimbalPitch no
|
|
30209
|
+
'GimRoll' GimbalRoll no
|
|
30210
|
+
'GimYaw' GimbalYaw no
|
|
30211
|
+
'HomeLat' GPSHomeLatitude no
|
|
30212
|
+
'HomeLon' GPSHomeLongitude no
|
|
30213
|
+
'ISO' ISO no
|
|
30214
|
+
'Lat' GPSLatitude no
|
|
30215
|
+
'Lon' GPSLongitude no
|
|
30216
|
+
'Pitch' Pitch no
|
|
30217
|
+
'Roll' Roll no
|
|
30218
|
+
'SHUTTER' ExposureTime no
|
|
30219
|
+
'Text' Text no
|
|
30220
|
+
'Yaw' Yaw no
|
|
30204
30221
|
|
|
30205
30222
|
=head3 QuickTime HTCInfo Tags
|
|
30206
30223
|
|
|
@@ -30230,7 +30247,7 @@ Tags found in Pittasoft Blackvue dashcam "free" data.
|
|
|
30230
30247
|
------ -------- --------
|
|
30231
30248
|
0 MajorBrand no
|
|
30232
30249
|
1 MinorVersion no
|
|
30233
|
-
2 CompatibleBrands no
|
|
30250
|
+
2 CompatibleBrands no+
|
|
30234
30251
|
|
|
30235
30252
|
=head3 QuickTime OtherMeta Tags
|
|
30236
30253
|
|
|
@@ -31280,7 +31297,7 @@ Tags found in TomTom Bandit Action Cam MP4 videos.
|
|
|
31280
31297
|
'TTAD' TomTomAD QuickTime Stream
|
|
31281
31298
|
'TTHL' TomTomHL? no
|
|
31282
31299
|
'TTID' TomTomID no
|
|
31283
|
-
'TTVD' TomTomVD no
|
|
31300
|
+
'TTVD' TomTomVD no+
|
|
31284
31301
|
'TTVI' TomTomVI? no
|
|
31285
31302
|
|
|
31286
31303
|
=head3 QuickTime HintTrackInfo Tags
|
|
@@ -184,11 +184,19 @@ sub GetFreeEntries($)
|
|
|
184
184
|
{
|
|
185
185
|
my $dict = shift;
|
|
186
186
|
my %xrefFree;
|
|
187
|
-
#
|
|
188
|
-
# so we can simplify things for now and only support this type of entry
|
|
187
|
+
# we write xref stream entries in 'CNn' or 'CNNn' format (with 8-byte 'NN' offset),
|
|
189
188
|
my $w = $$dict{W};
|
|
190
|
-
if (ref $w eq 'ARRAY'
|
|
191
|
-
my $
|
|
189
|
+
if (ref $w eq 'ARRAY') {
|
|
190
|
+
my $bytes = "@$w";
|
|
191
|
+
my $fmt;
|
|
192
|
+
if ($bytes eq '1 4 2') {
|
|
193
|
+
$fmt = 'CNn';
|
|
194
|
+
} elsif ($bytes eq '1 8 2') {
|
|
195
|
+
$fmt = 'CNNn';
|
|
196
|
+
} else {
|
|
197
|
+
return \%xrefFree;
|
|
198
|
+
}
|
|
199
|
+
my $size = $$dict{_entry_size}; # this will be 7 for 'CNn' or 11 for 'CNNn'
|
|
192
200
|
my $index = $$dict{Index};
|
|
193
201
|
my $len = length $$dict{_stream};
|
|
194
202
|
# scan the table for free objects
|
|
@@ -200,7 +208,12 @@ sub GetFreeEntries($)
|
|
|
200
208
|
my $count = $$index[$i*2+1];
|
|
201
209
|
for ($j=0; $j<$count; ++$j) {
|
|
202
210
|
last if $pos + $size > $len;
|
|
203
|
-
my @t = unpack("x$pos
|
|
211
|
+
my @t = unpack("x$pos $fmt", $$dict{_stream});
|
|
212
|
+
if (@t == 4) {
|
|
213
|
+
$t[1] = $t[1] * 4294967296 + $t[2];
|
|
214
|
+
$t[2] = $t[3];
|
|
215
|
+
@t = 3;
|
|
216
|
+
}
|
|
204
217
|
# add entry if object was free
|
|
205
218
|
$xrefFree{$start+$j} = [ $t[1], $t[2], 'f' ] if $t[0] == 0;
|
|
206
219
|
$pos += $size; # step to next entry
|
|
@@ -657,24 +670,37 @@ sub WritePDF($$)
|
|
|
657
670
|
$newXRef{$nextObject++} = [ Tell($outfile) - $$et{PDFBase} + length($/), 0, 'n' ];
|
|
658
671
|
$$mainDict{Size} = $nextObject;
|
|
659
672
|
# create xref stream and Index entry
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
my
|
|
666
|
-
|
|
667
|
-
$
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
$
|
|
671
|
-
|
|
673
|
+
my $bits = 4;
|
|
674
|
+
Restart: for (;;) {
|
|
675
|
+
$$mainDict{W} = [ 1, $bits, 2 ]; # int8u, int32u/int64u, int16u ('CNn' or 'CNNn')
|
|
676
|
+
$$mainDict{Index} = [ ];
|
|
677
|
+
$$mainDict{_stream} = '';
|
|
678
|
+
my @ids = sort { $a <=> $b } keys %newXRef;
|
|
679
|
+
while (@ids) {
|
|
680
|
+
my $startID = $ids[0];
|
|
681
|
+
for (;;) {
|
|
682
|
+
$id = shift @ids;
|
|
683
|
+
my ($pos, $gen, $type) = @{$newXRef{$id}};
|
|
684
|
+
if ($pos > 0xffffffff) {
|
|
685
|
+
if ($bits == 4) {
|
|
686
|
+
# switch to 64-bit integer offsets
|
|
687
|
+
$bits = 8;
|
|
688
|
+
next Restart;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
if ($bits == 4) {
|
|
692
|
+
$$mainDict{_stream} .= pack('CNn', $type eq 'f' ? 0 : 1, $pos, $gen);
|
|
693
|
+
} else {
|
|
694
|
+
my $hi = int($pos / 4294967296);
|
|
695
|
+
my $lo = $pos - $hi * 4294967296;
|
|
696
|
+
$$mainDict{_stream} .= pack('CNNn', $type eq 'f' ? 0 : 1, $hi, $lo, $gen);
|
|
697
|
+
}
|
|
698
|
+
last if not @ids or $ids[0] != $id + 1;
|
|
672
699
|
}
|
|
673
|
-
|
|
674
|
-
|
|
700
|
+
# add Index entries for this section of the xref stream
|
|
701
|
+
push @{$$mainDict{Index}}, $startID, $id - $startID + 1;
|
|
675
702
|
}
|
|
676
|
-
|
|
677
|
-
push @{$$mainDict{Index}}, $startID, $id - $startID + 1;
|
|
703
|
+
last;
|
|
678
704
|
}
|
|
679
705
|
# write the xref stream object
|
|
680
706
|
$keyExt = "$id 0 obj"; # (set anyway, but xref stream should NOT be encrypted)
|
|
@@ -925,19 +925,31 @@ sub WriteXMP($$;$)
|
|
|
925
925
|
# get hash of all information we want to change
|
|
926
926
|
# (sorted by tag name so alternate languages come last, but with structures
|
|
927
927
|
# first so flattened tags may be used to override individual structure elements)
|
|
928
|
-
my (@tagInfoList, $delLangPath, %delLangPaths, %delAllLang, $firstNewPath);
|
|
928
|
+
my (@tagInfoList, @structList, $delLangPath, %delLangPaths, %delAllLang, $firstNewPath, @langTags);
|
|
929
929
|
my $writeGroup = $$dirInfo{WriteGroup};
|
|
930
930
|
foreach $tagInfo (sort ByTagName $et->GetNewTagInfoList()) {
|
|
931
931
|
next unless $et->GetGroup($tagInfo, 0) eq 'XMP';
|
|
932
932
|
next if $$tagInfo{Name} eq 'XMP'; # (ignore full XMP block if we didn't write it already)
|
|
933
933
|
next if $writeGroup and $writeGroup ne $$et{NEW_VALUE}{$tagInfo}{WriteGroup};
|
|
934
|
-
if ($$tagInfo{
|
|
935
|
-
|
|
934
|
+
if ($$tagInfo{LangCode}) {
|
|
935
|
+
push @langTags, $tagInfo
|
|
936
|
+
} elsif ($$tagInfo{Struct}) {
|
|
937
|
+
push @structList, $tagInfo;
|
|
936
938
|
} else {
|
|
937
939
|
push @tagInfoList, $tagInfo;
|
|
938
940
|
}
|
|
939
941
|
}
|
|
940
|
-
|
|
942
|
+
if (@langTags) {
|
|
943
|
+
# keep original order in which lang-alt entries were added
|
|
944
|
+
foreach $tagInfo (sort { $$et{NEW_VALUE}{$a}{Order} <=> $$et{NEW_VALUE}{$b}{Order} } @langTags) {
|
|
945
|
+
if ($$tagInfo{Struct}) {
|
|
946
|
+
push @structList, $tagInfo;
|
|
947
|
+
} else {
|
|
948
|
+
push @tagInfoList, $tagInfo;
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
foreach $tagInfo (@structList, @tagInfoList) {
|
|
941
953
|
my @delPaths; # list of deleted paths
|
|
942
954
|
my $tag = $$tagInfo{TagID};
|
|
943
955
|
my $path = GetPropertyPath($tagInfo);
|
|
@@ -295,10 +295,11 @@ my %ignorePrintConv = map { $_ => 1 } qw(OTHER BITMASK Notes);
|
|
|
295
295
|
# CreateGroups - hash of all family 0 group names where tag may be created
|
|
296
296
|
# WriteGroup - group name where information is being written (correct case)
|
|
297
297
|
# WantGroup - group name as specified in call to function (case insensitive)
|
|
298
|
-
# Next - pointer to next new value hash (if more than one)
|
|
298
|
+
# Next - pointer to next new value hash (if more than one for this tag)
|
|
299
299
|
# NoReplace - set if value was created with Replace=0
|
|
300
300
|
# AddBefore - number of list items added by a subsequent Replace=0 call
|
|
301
|
-
# IsNVH -
|
|
301
|
+
# IsNVH - flag indicating this is a new value hash
|
|
302
|
+
# Order - counter to indicate the order that new value hashes were created
|
|
302
303
|
# Shift - shift value
|
|
303
304
|
# Save - counter used by SaveNewValues()/RestoreNewValues()
|
|
304
305
|
# MAKER_NOTE_FIXUP - pointer to fixup if necessary for a maker note value
|
|
@@ -317,7 +318,7 @@ sub SetNewValue($;$$%)
|
|
|
317
318
|
|
|
318
319
|
unless (defined $tag) {
|
|
319
320
|
delete $$self{NEW_VALUE};
|
|
320
|
-
$$self{SAVE_COUNT} = 0;
|
|
321
|
+
$$self{SAVE_COUNT} = $$self{NV_COUNT} = 0;
|
|
321
322
|
$$self{DEL_GROUP} = { };
|
|
322
323
|
return 1;
|
|
323
324
|
}
|
|
@@ -1389,8 +1390,16 @@ sub SetNewValuesFromFile($$;@)
|
|
|
1389
1390
|
return $info if $$info{Error} and $$info{Error} eq 'Error opening file';
|
|
1390
1391
|
delete $$srcExifTool{VALUE}{Error}; # delete so we can check this later
|
|
1391
1392
|
|
|
1392
|
-
# sort tags in
|
|
1393
|
-
my @tags
|
|
1393
|
+
# sort tags in file order with priority tags last
|
|
1394
|
+
my (@tags, @prio);
|
|
1395
|
+
foreach (sort { $$srcExifTool{FILE_ORDER}{$a} <=> $$srcExifTool{FILE_ORDER}{$b} } keys %$info) {
|
|
1396
|
+
if (/ /) {
|
|
1397
|
+
push @tags, $_;
|
|
1398
|
+
} else {
|
|
1399
|
+
push @prio, $_;
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
push @tags, @prio;
|
|
1394
1403
|
#
|
|
1395
1404
|
# simply transfer all tags from source image if no tags specified
|
|
1396
1405
|
#
|
|
@@ -3896,6 +3905,7 @@ sub GetNewValueHash($$;$$$$)
|
|
|
3896
3905
|
TagInfo => $tagInfo,
|
|
3897
3906
|
WriteGroup => $writeGroup,
|
|
3898
3907
|
IsNVH => 1, # set flag so we can recognize a new value hash
|
|
3908
|
+
Order => $$self{NV_COUNT}++,
|
|
3899
3909
|
};
|
|
3900
3910
|
# add entry to our NEW_VALUE hash
|
|
3901
3911
|
if ($$self{NEW_VALUE}{$tagInfo}) {
|
|
@@ -4023,7 +4033,7 @@ sub RemoveNewValuesForGroup($$)
|
|
|
4023
4033
|
#------------------------------------------------------------------------------
|
|
4024
4034
|
# Get list of tagInfo hashes for all new data
|
|
4025
4035
|
# Inputs: 0) ExifTool object reference, 1) optional tag table pointer
|
|
4026
|
-
# Returns: list of tagInfo hashes
|
|
4036
|
+
# Returns: list of tagInfo hashes in no particular order
|
|
4027
4037
|
sub GetNewTagInfoList($;$)
|
|
4028
4038
|
{
|
|
4029
4039
|
my ($self, $tagTablePtr) = @_;
|
|
@@ -50,7 +50,7 @@ use Image::ExifTool::Exif;
|
|
|
50
50
|
use Image::ExifTool::GPS;
|
|
51
51
|
require Exporter;
|
|
52
52
|
|
|
53
|
-
$VERSION = '3.
|
|
53
|
+
$VERSION = '3.67';
|
|
54
54
|
@ISA = qw(Exporter);
|
|
55
55
|
@EXPORT_OK = qw(EscapeXML UnescapeXML);
|
|
56
56
|
|
|
@@ -2016,6 +2016,7 @@ my %sPantryItem = (
|
|
|
2016
2016
|
Writable => 'integer',
|
|
2017
2017
|
List => 'Seq',
|
|
2018
2018
|
AutoSplit => 1,
|
|
2019
|
+
Notes => 'deprecated',
|
|
2019
2020
|
},
|
|
2020
2021
|
OECF => {
|
|
2021
2022
|
Name => 'Opto-ElectricConvFactor',
|
|
@@ -2267,7 +2268,7 @@ my %sPantryItem = (
|
|
|
2267
2268
|
3 => 'Distant',
|
|
2268
2269
|
},
|
|
2269
2270
|
},
|
|
2270
|
-
ImageUniqueID => { },
|
|
2271
|
+
ImageUniqueID => { Avoid => 1, Notes => 'moved to exifEX namespace in 2024 spec' },
|
|
2271
2272
|
GPSVersionID => { Groups => { 2 => 'Location' } },
|
|
2272
2273
|
GPSLatitude => { Groups => { 2 => 'Location' }, %latConv },
|
|
2273
2274
|
GPSLongitude => { Groups => { 2 => 'Location' }, %longConv },
|
|
@@ -2509,6 +2510,15 @@ my %sPantryItem = (
|
|
|
2509
2510
|
Values => { List => 'Seq', Writable => 'rational' },
|
|
2510
2511
|
},
|
|
2511
2512
|
},
|
|
2513
|
+
# new in Exif 3.0
|
|
2514
|
+
ImageUniqueID => { },
|
|
2515
|
+
ImageTitle => { },
|
|
2516
|
+
ImageEditor => { },
|
|
2517
|
+
Photographer => { Groups => { 2 => 'Author' } },
|
|
2518
|
+
CameraFirmware => { Groups => { 2 => 'Camera' } },
|
|
2519
|
+
RAWDevelopingSoftware => { },
|
|
2520
|
+
ImageEditingSoftware => { },
|
|
2521
|
+
MetadataEditingSoftware => { },
|
|
2512
2522
|
);
|
|
2513
2523
|
|
|
2514
2524
|
# Auxiliary namespace properties (aux) - not fully documented (ref PH)
|
|
@@ -3777,8 +3787,13 @@ sub ParseXMPElement($$$;$$$$)
|
|
|
3777
3787
|
|
|
3778
3788
|
# extract property attributes
|
|
3779
3789
|
my ($parseResource, %attrs, @attrs);
|
|
3780
|
-
|
|
3781
|
-
|
|
3790
|
+
# this hangs Perl (v5.18.4) for a specific capture string [patched in ExifTool 12.98]
|
|
3791
|
+
# while ($attrs =~ m/(\S+?)\s*=\s*(['"])(.*?)\2/sg) {
|
|
3792
|
+
while ($attrs =~ /(\S+?)\s*=\s*(['"])/g) {
|
|
3793
|
+
my ($attr, $quote) = ($1, $2);
|
|
3794
|
+
my $p0 = pos($attrs);
|
|
3795
|
+
last unless $attrs =~ /$quote/g;
|
|
3796
|
+
my $val = substr($attrs, $p0, pos($attrs)-$p0-1);
|
|
3782
3797
|
# handle namespace prefixes (defined by xmlns:PREFIX, or used with PREFIX:tag)
|
|
3783
3798
|
if ($attr =~ /(.*?):/) {
|
|
3784
3799
|
if ($1 eq 'xmlns') {
|
|
@@ -39,8 +39,7 @@ sub SerializeStruct($$;$)
|
|
|
39
39
|
|
|
40
40
|
if (ref $obj eq 'HASH') {
|
|
41
41
|
# support hashes with ordered keys
|
|
42
|
-
|
|
43
|
-
foreach $key (@keys) {
|
|
42
|
+
foreach $key (Image::ExifTool::OrderedKeys($obj)) {
|
|
44
43
|
my $hdr = $sfmt ? EscapeJSON($key) . ':' : $key . '=';
|
|
45
44
|
push @vals, $hdr . SerializeStruct($et, $$obj{$key}, '}');
|
|
46
45
|
}
|
|
@@ -218,7 +217,7 @@ sub DumpStruct($;$)
|
|
|
218
217
|
$indent or $indent = '';
|
|
219
218
|
if (ref $obj eq 'HASH') {
|
|
220
219
|
print "{\n";
|
|
221
|
-
foreach (
|
|
220
|
+
foreach (Image::ExifTool::OrderedKeys($obj)) {
|
|
222
221
|
print "$indent $_ = ";
|
|
223
222
|
DumpStruct($$obj{$_}, "$indent ");
|
|
224
223
|
}
|
|
@@ -253,8 +252,10 @@ sub CheckStruct($$$)
|
|
|
253
252
|
ref $struct eq 'HASH' or return wantarray ? (undef, "Expecting $strName structure") : undef;
|
|
254
253
|
|
|
255
254
|
my ($key, $err, $warn, %copy, $rtnVal, $val);
|
|
255
|
+
# copy the ordered keys if they exist
|
|
256
|
+
$copy{_ordered_keys_} = [ ] if $$struct{_ordered_keys_};
|
|
256
257
|
Key:
|
|
257
|
-
foreach $key (
|
|
258
|
+
foreach $key (Image::ExifTool::OrderedKeys($struct)) {
|
|
258
259
|
my $tag = $key;
|
|
259
260
|
# allow trailing '#' to disable print conversion on a per-field basis
|
|
260
261
|
my ($type, $fieldInfo);
|
|
@@ -377,6 +378,7 @@ Key:
|
|
|
377
378
|
$copy{$tag} = \@copy;
|
|
378
379
|
} elsif ($$fieldInfo{Struct}) {
|
|
379
380
|
$warn = "Improperly formed structure in $strName $tag";
|
|
381
|
+
next;
|
|
380
382
|
} else {
|
|
381
383
|
$et->Sanitize(\$$struct{$key});
|
|
382
384
|
($val,$err) = $et->ConvInv($$struct{$key},$fieldInfo,$tag,$strName,$type,'');
|
|
@@ -387,6 +389,7 @@ Key:
|
|
|
387
389
|
# turn this into a list if necessary
|
|
388
390
|
$copy{$tag} = $$fieldInfo{List} ? [ $val ] : $val;
|
|
389
391
|
}
|
|
392
|
+
push @{$copy{_ordered_keys_}}, $tag if $copy{_ordered_keys_}; # save ordered keys
|
|
390
393
|
}
|
|
391
394
|
if (%copy or not $warn) {
|
|
392
395
|
$rtnVal = \%copy;
|
|
@@ -562,7 +565,7 @@ sub AddNewStruct($$$$$$)
|
|
|
562
565
|
# after all valid structure fields, which is necessary when serializing the XMP later)
|
|
563
566
|
%$struct or $$struct{'~dummy~'} = '';
|
|
564
567
|
|
|
565
|
-
foreach $tag (
|
|
568
|
+
foreach $tag (Image::ExifTool::OrderedKeys($struct)) {
|
|
566
569
|
my $fieldInfo = $$strTable{$tag};
|
|
567
570
|
unless ($fieldInfo) {
|
|
568
571
|
next unless $tag eq '~dummy~'; # check for dummy field
|
|
@@ -652,7 +655,8 @@ sub ConvertStruct($$$$;$)
|
|
|
652
655
|
my (%struct, $key);
|
|
653
656
|
my $table = $$tagInfo{Table};
|
|
654
657
|
$parentID = $$tagInfo{TagID} unless $parentID;
|
|
655
|
-
|
|
658
|
+
$struct{_ordered_keys_} = [ ] if $$value{_ordered_keys_};
|
|
659
|
+
foreach $key (Image::ExifTool::OrderedKeys($value)) {
|
|
656
660
|
my $tagID = $parentID . ucfirst($key);
|
|
657
661
|
my $flatInfo = $$table{$tagID};
|
|
658
662
|
unless ($flatInfo) {
|
|
@@ -669,7 +673,11 @@ sub ConvertStruct($$$$;$)
|
|
|
669
673
|
} else {
|
|
670
674
|
$v = $et->GetValue($flatInfo, $type, $v);
|
|
671
675
|
}
|
|
672
|
-
|
|
676
|
+
if (defined $v) {
|
|
677
|
+
$struct{$key} = $v; # save the converted value
|
|
678
|
+
# maintain ordered keys if necessary
|
|
679
|
+
push @{$struct{_ordered_keys_}}, $key if $struct{_ordered_keys_};
|
|
680
|
+
}
|
|
673
681
|
}
|
|
674
682
|
return \%struct;
|
|
675
683
|
} elsif (ref $value eq 'ARRAY') {
|