exiftool_vendored 10.65.0 → 11.41.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of exiftool_vendored might be problematic. Click here for more details.

Files changed (205) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +818 -19
  3. data/bin/MANIFEST +38 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +48 -44
  7. data/bin/arg_files/exif2xmp.args +4 -1
  8. data/bin/arg_files/gps2xmp.args +4 -1
  9. data/bin/arg_files/iptcCore.args +8 -0
  10. data/bin/arg_files/xmp2exif.args +4 -1
  11. data/bin/arg_files/xmp2gps.args +4 -1
  12. data/bin/config_files/dji.config +131 -0
  13. data/bin/config_files/example.config +6 -2
  14. data/bin/config_files/gps2utm.config +256 -256
  15. data/bin/config_files/nksc.config +146 -0
  16. data/bin/config_files/picasa_faces.config +382 -382
  17. data/bin/exiftool +688 -408
  18. data/bin/fmt_files/gpx.fmt +10 -6
  19. data/bin/fmt_files/gpx_wpt.fmt +10 -6
  20. data/bin/fmt_files/kml.fmt +8 -5
  21. data/bin/lib/File/RandomAccess.pm +48 -8
  22. data/bin/lib/File/RandomAccess.pod +21 -2
  23. data/bin/lib/Image/ExifTool.pm +645 -256
  24. data/bin/lib/Image/ExifTool.pod +219 -164
  25. data/bin/lib/Image/ExifTool/AES.pm +1 -1
  26. data/bin/lib/Image/ExifTool/AFCP.pm +3 -8
  27. data/bin/lib/Image/ExifTool/AIFF.pm +12 -4
  28. data/bin/lib/Image/ExifTool/APE.pm +1 -1
  29. data/bin/lib/Image/ExifTool/APP12.pm +1 -1
  30. data/bin/lib/Image/ExifTool/ASF.pm +19 -6
  31. data/bin/lib/Image/ExifTool/Apple.pm +13 -5
  32. data/bin/lib/Image/ExifTool/Audible.pm +1 -1
  33. data/bin/lib/Image/ExifTool/BMP.pm +1 -1
  34. data/bin/lib/Image/ExifTool/BPG.pm +17 -15
  35. data/bin/lib/Image/ExifTool/BZZ.pm +1 -1
  36. data/bin/lib/Image/ExifTool/BigTIFF.pm +30 -15
  37. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +103 -52
  38. data/bin/lib/Image/ExifTool/Canon.pm +684 -112
  39. data/bin/lib/Image/ExifTool/CanonCustom.pm +119 -9
  40. data/bin/lib/Image/ExifTool/CanonRaw.pm +1 -1
  41. data/bin/lib/Image/ExifTool/CanonVRD.pm +13 -26
  42. data/bin/lib/Image/ExifTool/CaptureOne.pm +1 -1
  43. data/bin/lib/Image/ExifTool/Casio.pm +1 -1
  44. data/bin/lib/Image/ExifTool/Charset.pm +1 -1
  45. data/bin/lib/Image/ExifTool/DICOM.pm +12 -5
  46. data/bin/lib/Image/ExifTool/DJI.pm +51 -3
  47. data/bin/lib/Image/ExifTool/DNG.pm +15 -8
  48. data/bin/lib/Image/ExifTool/DPX.pm +1 -1
  49. data/bin/lib/Image/ExifTool/DV.pm +1 -1
  50. data/bin/lib/Image/ExifTool/DarwinCore.pm +63 -23
  51. data/bin/lib/Image/ExifTool/DjVu.pm +4 -2
  52. data/bin/lib/Image/ExifTool/EXE.pm +30 -6
  53. data/bin/lib/Image/ExifTool/Exif.pm +351 -109
  54. data/bin/lib/Image/ExifTool/FITS.pm +148 -0
  55. data/bin/lib/Image/ExifTool/FLAC.pm +2 -2
  56. data/bin/lib/Image/ExifTool/FLIF.pm +1 -1
  57. data/bin/lib/Image/ExifTool/FLIR.pm +109 -13
  58. data/bin/lib/Image/ExifTool/Fixup.pm +1 -1
  59. data/bin/lib/Image/ExifTool/Flash.pm +3 -3
  60. data/bin/lib/Image/ExifTool/FlashPix.pm +433 -9
  61. data/bin/lib/Image/ExifTool/Font.pm +2 -2
  62. data/bin/lib/Image/ExifTool/FotoStation.pm +1 -1
  63. data/bin/lib/Image/ExifTool/FujiFilm.pm +336 -16
  64. data/bin/lib/Image/ExifTool/GE.pm +1 -1
  65. data/bin/lib/Image/ExifTool/GIF.pm +5 -7
  66. data/bin/lib/Image/ExifTool/GIMP.pm +39 -3
  67. data/bin/lib/Image/ExifTool/GPS.pm +48 -22
  68. data/bin/lib/Image/ExifTool/GeoTiff.pm +23 -23
  69. data/bin/lib/Image/ExifTool/Geotag.pm +80 -45
  70. data/bin/lib/Image/ExifTool/GoPro.pm +709 -0
  71. data/bin/lib/Image/ExifTool/H264.pm +40 -18
  72. data/bin/lib/Image/ExifTool/HP.pm +1 -1
  73. data/bin/lib/Image/ExifTool/HTML.pm +19 -12
  74. data/bin/lib/Image/ExifTool/HtmlDump.pm +37 -26
  75. data/bin/lib/Image/ExifTool/ICC_Profile.pm +297 -23
  76. data/bin/lib/Image/ExifTool/ID3.pm +12 -7
  77. data/bin/lib/Image/ExifTool/IPTC.pm +48 -19
  78. data/bin/lib/Image/ExifTool/ISO.pm +1 -1
  79. data/bin/lib/Image/ExifTool/ITC.pm +1 -1
  80. data/bin/lib/Image/ExifTool/Import.pm +13 -9
  81. data/bin/lib/Image/ExifTool/InDesign.pm +3 -5
  82. data/bin/lib/Image/ExifTool/JPEG.pm +22 -11
  83. data/bin/lib/Image/ExifTool/JPEGDigest.pm +1 -1
  84. data/bin/lib/Image/ExifTool/JSON.pm +3 -3
  85. data/bin/lib/Image/ExifTool/JVC.pm +1 -1
  86. data/bin/lib/Image/ExifTool/Jpeg2000.pm +2 -2
  87. data/bin/lib/Image/ExifTool/Kodak.pm +1233 -58
  88. data/bin/lib/Image/ExifTool/KyoceraRaw.pm +1 -1
  89. data/bin/lib/Image/ExifTool/LNK.pm +1 -1
  90. data/bin/lib/Image/ExifTool/Lang/cs.pm +1 -1
  91. data/bin/lib/Image/ExifTool/Lang/de.pm +33 -24
  92. data/bin/lib/Image/ExifTool/Lang/en_ca.pm +64 -2
  93. data/bin/lib/Image/ExifTool/Lang/en_gb.pm +64 -2
  94. data/bin/lib/Image/ExifTool/Lang/es.pm +8 -4
  95. data/bin/lib/Image/ExifTool/Lang/fi.pm +46 -4
  96. data/bin/lib/Image/ExifTool/Lang/fr.pm +5 -3
  97. data/bin/lib/Image/ExifTool/Lang/it.pm +6 -3
  98. data/bin/lib/Image/ExifTool/Lang/ja.pm +15 -3
  99. data/bin/lib/Image/ExifTool/Lang/ko.pm +5 -2
  100. data/bin/lib/Image/ExifTool/Lang/nl.pm +6 -3
  101. data/bin/lib/Image/ExifTool/Lang/pl.pm +2 -2
  102. data/bin/lib/Image/ExifTool/Lang/ru.pm +1 -1
  103. data/bin/lib/Image/ExifTool/Lang/sv.pm +1 -1
  104. data/bin/lib/Image/ExifTool/Lang/tr.pm +4 -2
  105. data/bin/lib/Image/ExifTool/Lang/zh_cn.pm +1 -1
  106. data/bin/lib/Image/ExifTool/Lang/zh_tw.pm +1 -1
  107. data/bin/lib/Image/ExifTool/Leaf.pm +1 -1
  108. data/bin/lib/Image/ExifTool/Lytro.pm +4 -8
  109. data/bin/lib/Image/ExifTool/M2TS.pm +10 -9
  110. data/bin/lib/Image/ExifTool/MIE.pm +12 -8
  111. data/bin/lib/Image/ExifTool/MIEUnits.pod +1 -1
  112. data/bin/lib/Image/ExifTool/MIFF.pm +1 -1
  113. data/bin/lib/Image/ExifTool/MNG.pm +1 -1
  114. data/bin/lib/Image/ExifTool/MOI.pm +1 -1
  115. data/bin/lib/Image/ExifTool/MPC.pm +1 -1
  116. data/bin/lib/Image/ExifTool/MPEG.pm +2 -3
  117. data/bin/lib/Image/ExifTool/MPF.pm +6 -6
  118. data/bin/lib/Image/ExifTool/MWG.pm +4 -4
  119. data/bin/lib/Image/ExifTool/MXF.pm +2 -2
  120. data/bin/lib/Image/ExifTool/MacOS.pm +184 -34
  121. data/bin/lib/Image/ExifTool/MakerNotes.pm +101 -18
  122. data/bin/lib/Image/ExifTool/Matroska.pm +1 -1
  123. data/bin/lib/Image/ExifTool/Microsoft.pm +5 -3
  124. data/bin/lib/Image/ExifTool/Minolta.pm +89 -62
  125. data/bin/lib/Image/ExifTool/MinoltaRaw.pm +1 -1
  126. data/bin/lib/Image/ExifTool/Motorola.pm +1 -1
  127. data/bin/lib/Image/ExifTool/Nikon.pm +1511 -380
  128. data/bin/lib/Image/ExifTool/NikonCapture.pm +1 -1
  129. data/bin/lib/Image/ExifTool/NikonCustom.pm +2758 -2935
  130. data/bin/lib/Image/ExifTool/Nintendo.pm +1 -1
  131. data/bin/lib/Image/ExifTool/OOXML.pm +1 -1
  132. data/bin/lib/Image/ExifTool/Ogg.pm +1 -1
  133. data/bin/lib/Image/ExifTool/Olympus.pm +47 -8
  134. data/bin/lib/Image/ExifTool/OpenEXR.pm +1 -1
  135. data/bin/lib/Image/ExifTool/Opus.pm +1 -1
  136. data/bin/lib/Image/ExifTool/PCX.pm +138 -0
  137. data/bin/lib/Image/ExifTool/PDF.pm +58 -42
  138. data/bin/lib/Image/ExifTool/PGF.pm +1 -1
  139. data/bin/lib/Image/ExifTool/PICT.pm +1 -1
  140. data/bin/lib/Image/ExifTool/PLIST.pm +12 -5
  141. data/bin/lib/Image/ExifTool/PLUS.pm +1 -1
  142. data/bin/lib/Image/ExifTool/PNG.pm +108 -10
  143. data/bin/lib/Image/ExifTool/PPM.pm +3 -3
  144. data/bin/lib/Image/ExifTool/PSP.pm +1 -1
  145. data/bin/lib/Image/ExifTool/Palm.pm +1 -1
  146. data/bin/lib/Image/ExifTool/Panasonic.pm +299 -31
  147. data/bin/lib/Image/ExifTool/PanasonicRaw.pm +201 -19
  148. data/bin/lib/Image/ExifTool/Pentax.pm +164 -143
  149. data/bin/lib/Image/ExifTool/PhaseOne.pm +12 -5
  150. data/bin/lib/Image/ExifTool/PhotoCD.pm +9 -10
  151. data/bin/lib/Image/ExifTool/PhotoMechanic.pm +1 -1
  152. data/bin/lib/Image/ExifTool/Photoshop.pm +230 -60
  153. data/bin/lib/Image/ExifTool/PostScript.pm +29 -4
  154. data/bin/lib/Image/ExifTool/PrintIM.pm +1 -1
  155. data/bin/lib/Image/ExifTool/Qualcomm.pm +2 -2
  156. data/bin/lib/Image/ExifTool/QuickTime.pm +1539 -279
  157. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +1857 -0
  158. data/bin/lib/Image/ExifTool/README +84 -46
  159. data/bin/lib/Image/ExifTool/RIFF.pm +116 -23
  160. data/bin/lib/Image/ExifTool/RSRC.pm +1 -1
  161. data/bin/lib/Image/ExifTool/RTF.pm +6 -4
  162. data/bin/lib/Image/ExifTool/Radiance.pm +1 -1
  163. data/bin/lib/Image/ExifTool/Rawzor.pm +3 -2
  164. data/bin/lib/Image/ExifTool/Real.pm +1 -1
  165. data/bin/lib/Image/ExifTool/Reconyx.pm +261 -7
  166. data/bin/lib/Image/ExifTool/Red.pm +325 -0
  167. data/bin/lib/Image/ExifTool/Ricoh.pm +3 -7
  168. data/bin/lib/Image/ExifTool/Samsung.pm +95 -25
  169. data/bin/lib/Image/ExifTool/Sanyo.pm +1 -1
  170. data/bin/lib/Image/ExifTool/Scalado.pm +1 -1
  171. data/bin/lib/Image/ExifTool/Shift.pl +26 -12
  172. data/bin/lib/Image/ExifTool/Shortcuts.pm +9 -2
  173. data/bin/lib/Image/ExifTool/Sigma.pm +36 -30
  174. data/bin/lib/Image/ExifTool/SigmaRaw.pm +3 -8
  175. data/bin/lib/Image/ExifTool/Sony.pm +531 -177
  176. data/bin/lib/Image/ExifTool/SonyIDC.pm +63 -3
  177. data/bin/lib/Image/ExifTool/Stim.pm +2 -2
  178. data/bin/lib/Image/ExifTool/TagInfoXML.pm +23 -23
  179. data/bin/lib/Image/ExifTool/TagLookup.pm +6352 -5062
  180. data/bin/lib/Image/ExifTool/TagNames.pod +3024 -565
  181. data/bin/lib/Image/ExifTool/Theora.pm +1 -1
  182. data/bin/lib/Image/ExifTool/Torrent.pm +2 -2
  183. data/bin/lib/Image/ExifTool/Unknown.pm +1 -1
  184. data/bin/lib/Image/ExifTool/VCard.pm +47 -9
  185. data/bin/lib/Image/ExifTool/Validate.pm +391 -99
  186. data/bin/lib/Image/ExifTool/Vorbis.pm +1 -1
  187. data/bin/lib/Image/ExifTool/WTV.pm +319 -0
  188. data/bin/lib/Image/ExifTool/WriteCanonRaw.pl +1 -1
  189. data/bin/lib/Image/ExifTool/WriteExif.pl +91 -18
  190. data/bin/lib/Image/ExifTool/WriteIPTC.pl +6 -6
  191. data/bin/lib/Image/ExifTool/WritePDF.pl +13 -12
  192. data/bin/lib/Image/ExifTool/WritePNG.pl +1 -1
  193. data/bin/lib/Image/ExifTool/WritePhotoshop.pl +1 -1
  194. data/bin/lib/Image/ExifTool/WritePostScript.pl +2 -2
  195. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +764 -121
  196. data/bin/lib/Image/ExifTool/WriteXMP.pl +176 -67
  197. data/bin/lib/Image/ExifTool/Writer.pl +490 -246
  198. data/bin/lib/Image/ExifTool/XMP.pm +216 -76
  199. data/bin/lib/Image/ExifTool/XMP2.pl +54 -10
  200. data/bin/lib/Image/ExifTool/XMPStruct.pl +14 -11
  201. data/bin/lib/Image/ExifTool/ZIP.pm +60 -15
  202. data/bin/lib/Image/ExifTool/iWork.pm +12 -5
  203. data/bin/perl-Image-ExifTool.spec +46 -44
  204. data/lib/exiftool_vendored/version.rb +1 -1
  205. metadata +14 -4
@@ -0,0 +1,146 @@
1
+ #------------------------------------------------------------------------------
2
+ # File: nksc.config
3
+ #
4
+ # Description: This config file contains tag definitions to extract metadata
5
+ # from RDF/XML-based Nikon ViewNX NKSC sidecar files
6
+ #
7
+ # Usage: exiftool -config nksc.config -ext nksc DIR
8
+ #
9
+ # Requires: ExifTool version 11.38 or later
10
+ #
11
+ # Revisions: 2019/04/24 - P. Harvey Created
12
+ #------------------------------------------------------------------------------
13
+
14
+ %Image::ExifTool::UserDefined = (
15
+ 'Image::ExifTool::XMP::Main' => {
16
+ ast => {
17
+ SubDirectory => { TagTable => 'Image::ExifTool::UserDefined::ast' },
18
+ },
19
+ sdc => {
20
+ SubDirectory => { TagTable => 'Image::ExifTool::UserDefined::sdc' },
21
+ },
22
+ nine => {
23
+ SubDirectory => { TagTable => 'Image::ExifTool::UserDefined::nine' },
24
+ },
25
+ },
26
+ 'Image::ExifTool::Composite' => {
27
+ GPSLatitude => {
28
+ Require => {
29
+ 0 => 'XMP-ast:GPSLatitude',
30
+ 1 => 'XMP-ast:GPSLatitudeRef',
31
+ },
32
+ ValueConv => '$prt[1] =~ /^S/i ? -$val[0] : $val[0]',
33
+ PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
34
+ },
35
+ GPSLongitude => {
36
+ Require => {
37
+ 0 => 'XMP-ast:GPSLongitude',
38
+ 1 => 'XMP-ast:GPSLongitudeRef',
39
+ },
40
+ ValueConv => '$prt[1] =~ /^W/i ? -$val[0] : $val[0]',
41
+ PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
42
+ },
43
+ },
44
+ );
45
+
46
+ %Image::ExifTool::UserDefined::ast = (
47
+ GROUPS => { 0 => 'XMP', 1 => 'XMP-ast', 2 => 'Location' },
48
+ NAMESPACE => { 'ast' => 'http://ns.nikon.com/asteroid/1.0/' },
49
+ about => { Groups => { 2 => 'Image' } },
50
+ version => { Groups => { 2 => 'Image' } },
51
+ GPSVersionID => {
52
+ ValueConv => q{
53
+ my $valPt = Image::ExifTool::XMP::DecodeBase64($val);
54
+ SetByteOrder('II');
55
+ ReadValue($valPt, 0, 'int8u', 4, length($$valPt));
56
+ },
57
+ PrintConv => '$val =~ tr/ /./; $val',
58
+ },
59
+ GPSLatitude => {
60
+ ValueConv => q{
61
+ my $valPt = Image::ExifTool::XMP::DecodeBase64($val);
62
+ SetByteOrder('II');
63
+ $val = ReadValue($valPt, 0, 'double', 3, length($$valPt));
64
+ Image::ExifTool::GPS::ToDegrees($val);
65
+ },
66
+ PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val)',
67
+ },
68
+ GPSLatitudeRef => {
69
+ ValueConv => q{
70
+ my $valPt = Image::ExifTool::XMP::DecodeBase64($val);
71
+ SetByteOrder('II');
72
+ ReadValue($valPt, 0, 'int32u', 3, length($$valPt));
73
+ },
74
+ PrintConv => { 0 => 'North', 1 => 'South' },
75
+ },
76
+ GPSLongitude => {
77
+ ValueConv => q{
78
+ my $valPt = Image::ExifTool::XMP::DecodeBase64($val);
79
+ SetByteOrder('II');
80
+ $val = ReadValue($valPt, 0, 'double', 3, length($$valPt));
81
+ Image::ExifTool::GPS::ToDegrees($val);
82
+ },
83
+ PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val)',
84
+ },
85
+ GPSLongitudeRef => {
86
+ ValueConv => q{
87
+ my $valPt = Image::ExifTool::XMP::DecodeBase64($val);
88
+ SetByteOrder('II');
89
+ ReadValue($valPt, 0, 'int32u', 3, length($$valPt));
90
+ },
91
+ PrintConv => { 2 => 'East', 3 => 'West' },
92
+ },
93
+ GPSAltitude => {
94
+ ValueConv => q{
95
+ my $valPt = Image::ExifTool::XMP::DecodeBase64($val);
96
+ SetByteOrder('II');
97
+ ReadValue($valPt, 0, 'double');
98
+ },
99
+ PrintConv => '$val =~ /^(inf|undef)$/ ? $val : "$val m"',
100
+ },
101
+ GPSAltitudeRef => {
102
+ ValueConv => q{
103
+ my $valPt = Image::ExifTool::XMP::DecodeBase64($val);
104
+ ReadValue($valPt, 0, 'int8u');
105
+ },
106
+ PrintConv => {
107
+ 0 => 'Above Sea Level',
108
+ 1 => 'Below Sea Level',
109
+ },
110
+ },
111
+ GPSMapDatum => { },
112
+ XMLPackets => {
113
+ Name => 'XMP',
114
+ Groups => { 2 => 'Image' },
115
+ RawConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
116
+ SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
117
+ },
118
+ IPTC => {
119
+ Name => 'IPTC',
120
+ Groups => { 2 => 'Image' },
121
+ RawConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
122
+ SubDirectory => { TagTable => 'Image::ExifTool::IPTC::Main' },
123
+ },
124
+ );
125
+
126
+ %Image::ExifTool::UserDefined::sdc = (
127
+ GROUPS => { 0 => 'XMP', 1 => 'XMP-sdc', 2 => 'Image' },
128
+ NAMESPACE => { 'sdc' => 'http://ns.nikon.com/sdc/1.0/' },
129
+ about => { },
130
+ version => { },
131
+ appversion => { },
132
+ appname => { },
133
+ );
134
+
135
+ %Image::ExifTool::UserDefined::nine = (
136
+ GROUPS => { 0 => 'XMP', 1 => 'XMP-nine', 2 => 'Image' },
137
+ NAMESPACE => { 'nine' => 'http://ns.nikon.com/nine/1.0/' },
138
+ about => { },
139
+ version => { },
140
+ NineEdits => { Binary => 1 },
141
+ Label => { },
142
+ Rating => { },
143
+ Trim => { ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)' },
144
+ );
145
+
146
+ 1; #end
@@ -1,382 +1,382 @@
1
- #------------------------------------------------------------------------------
2
- # File: picasa_faces.config
3
- #
4
- # Description: User-defined Composite tag definitions to convert face regions
5
- # in .picasa.ini files to MWG region tags (Metadata Working Group
6
- # region, used by Picasa) and MP region tags (used by Microsoft
7
- # Photo Library).
8
- #
9
- # Tag definitions and examples:
10
- #
11
- # PicasaToMWGRegion
12
- # This will create the MWG region tag but will filter out the regions
13
- # that are still unnamed in Picasa. Picasa defaults to naming these
14
- # regions 'ffffffffffffffff' but normally will not save these to file.
15
- # Example:
16
- # exiftool -config picasa_faces.config "-RegionInfo<PicasaToMWGRegion" FILE
17
- #
18
- # PicasaToMPRegion
19
- # This will create the MP region tag but will filter out the regions that
20
- # are still unnamed in Picasa. Picasa defaults to naming these regions
21
- # 'ffffffffffffffff' but normally will not save these to file.
22
- # Example:
23
- # exiftool -config picasa_faces.config "-RegionInfoMP<PicasaToMPRegion" FILE
24
- #
25
- # PicasaRegionNames
26
- # Returns a list of the region names associated with the file. This
27
- # allows copying of the region names to XMP:Subject and/or IPTC:Keywords.
28
- # It also allows checking to see if regions need to be updated.
29
- # Example:
30
- # exiftool -config picasa_faces.config "-XMP:Subject<PicasaRegionNames" FILE
31
- #
32
- # PicasaToMWGRegionUnfiltered
33
- # This will create the MWG region tag. This version does not filter out
34
- # the unnamed regions. Picasa normally will filter out unnamed regions
35
- # when it saves regions in the file.
36
- # Example:
37
- # exiftool -config picasa_faces.config "-RegionInfo<PicasaToMWGRegionUnfiltered" FILE
38
- #
39
- # PicasaToMPRegionUnfiltered
40
- # This will create the MP region tag. This version does not filter out
41
- # the unnamed regions. Picasa normally will filter out unnamed regions
42
- # when it saves regions in the file.
43
- # Example:
44
- # exiftool -config picasa_faces.config "-RegionInfoMP<PicasaToMPRegionUnfiltered" FILE
45
- #
46
- # Notes: The face names are loaded from the Picasa contacts file, which
47
- # defaults to:
48
- #
49
- # C:/Users/MainUser/AppData/Local/PicasaData/Google/Picasa2/contacts/contacts.xml
50
- #
51
- # The default contacts file may be changed by editing the value
52
- # of $contactXML below, or on the command line with ExifTool 9.90
53
- # or later via the -userParam option, eg:
54
- # -userparam PicasaContactsFile=/path/to/contacts.xml
55
- #
56
- # Requires: ExifTool version 8.82 or later (9.90 or later for -userparam)
57
- #
58
- # Revisions: 2015/03/07 - Bryan K. Williams (aka StarGeek) Created
59
- # 2015/03/12 - PH Minor changes, optimizations and reformatting
60
- # 2015/05/11 - BKW Fix bug where Picasa writes region data for
61
- # rotated NEF and CR2 images as if the orientation
62
- # is not rotated.
63
- # 2015/05/12 - PH Minor code tweaks
64
- # 2015/10/26 - BKW Round off area sizes to 7 decimal places
65
- # 2016/01/18 - BKW Improved rounding algorithm
66
- # 2016/05/14 - BKW Increased rounding to 9 decimal places (Max Picasa accepts),
67
- # moved rounding operation to subroutine
68
- #
69
- # References: http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,6354.0.html
70
- #------------------------------------------------------------------------------
71
-
72
- # Picasa contacts file name
73
- my $contactXML = 'C:/Users/MainUser/AppData/Local/PicasaData/Google/Picasa2/contacts/contacts.xml';
74
-
75
- # local variables
76
- my $lastIniFile = ''; # path of last .picasa.ini file loaded
77
- my $lastContactFile = ''; # path of last contacts.xml file loaded
78
-
79
- # raw file types that need additional processing to get regions correct
80
- my %isRawFile = map { $_ => 1 } qw(
81
- 3FR ARW CR2 CRW CS1 DCR DNG EIP ERF IIQ K25 KDC MEF MOS MRW NEF NRW
82
- ORF PEF RAF RAW RW2 RWL SR2 SRF SRW X3F), 'Canon 1D RAW';
83
-
84
- my %contactHash; # lookup for loaded contacts.xml entries
85
- my %fileHash; # lookup for loaded .picasa.ini entries
86
-
87
- #------------------------------------------------------------------------------
88
- # Load Picasa's contacts.xml and .picasa.ini files.
89
- # Inputs: 0) ExifTool object reference, 1) .picasa.ini directory
90
- # Returns: 1 if files were loaded and parsed, undef on error
91
- # Notes: If file has already been loaded, it isn't reloaded
92
- sub LoadPicasaFiles($$)
93
- {
94
- local (*CONTACTS, *INI);
95
- my ($et, $iniDir) = @_;
96
-
97
- # check ExifTool version to see if there might be
98
- # a command line setting for the contact file
99
- my $contactFile = ($Image::ExifTool::VERSION >= 9.89 and
100
- defined($et->Options(UserParam => 'PicasaContactsFile'))) ?
101
- $et->Options(UserParam => 'PicasaContactsFile') : $contactXML;
102
-
103
- # load Picasa contacts.xml file unless done already
104
- unless ($contactFile eq $lastContactFile) {
105
- $lastContactFile = $contactFile;
106
- undef %contactHash;
107
- # Picasa's default setting for unnamed faces.
108
- $contactHash{'ffffffffffffffff'} = 'unnamed';
109
- if (open(CONTACTS, $contactFile)) {
110
- require Image::ExifTool::HTML;
111
- while (<CONTACTS>) {
112
- /name="(.*?)"/ or next;
113
- my $name = $1;
114
- /id="([a-f0-9]+)"/ or next;
115
- my $id = $1;
116
- $contactHash{$id} = Image::ExifTool::HTML::UnescapeHTML($name);
117
- }
118
- close(CONTACTS);
119
- } else {
120
- local $SIG{'__WARN__'} = undef; # stop ExifTool from catching the warning
121
- warn "Error reading contacts file $contactFile\n";
122
- }
123
- }
124
-
125
- # load .picasa.ini file from the specified directory
126
- my $iniFile = "$iniDir/.picasa.ini";
127
-
128
- if ($iniFile eq $lastIniFile) {
129
- return %fileHash ? 1 : undef;
130
- }
131
- $lastIniFile = $iniFile;
132
- open(INI, $iniFile) or return undef;
133
- my $section = '';
134
- while (<INI>) {
135
- # Process New Section
136
- /^\s*\[(.+)\][\n\r]*$/ and $section = $1, next;
137
- # process entry (all we care about are the "faces" lines)
138
- /^faces=(.*)$/ or next;
139
- my @temp = split /;/, $1;
140
- foreach (@temp) {
141
- /rect64\(([\da-f]{1,16})\),([\da-f]{1,16})/ or next;
142
- # the string in parens after "rect64" is a 64 bit number in hex,
143
- # but Picasa doesn't add leading zeroes, so the length of the string
144
- # cannot be assumed to be 16 bytes. Handle this as two 32-bit numbers
145
- # for compatibility with 32-bit systems.
146
- my $hi = hex(substr($1, 0, -8));
147
- my $lo = hex(substr($1, -8));
148
- my $x0 = ($hi >> 16) /65535;
149
- my $y0 = ($hi & 0xffff)/65535;
150
- my $x1 = ($lo >> 16) /65535;
151
- my $y1 = ($lo & 0xffff)/65535;
152
- push @{ $fileHash{$section} }, {
153
- ContactID => $2,
154
- X => $x0,
155
- Y => $y0,
156
- W => $x1 - $x0,
157
- H => $y1 - $y0,
158
- };
159
- }
160
- }
161
- close(INI);
162
- return %fileHash ? 1 : undef;
163
- }
164
-
165
- #------------------------------------------------------------------------------
166
- # Rotate region to specified orientation (for RAW file types only)
167
- # Input: 0) rectangle array ref (x,y,w,h), 1) EXIF orientation value, 2) file type
168
- sub RotateRegion($$$)
169
- {
170
- my ($rect, $orientation, $fileType) = @_;
171
- if ($orientation and $fileType and $isRawFile{$fileType}) {
172
- my ($x,$y,$w,$h) = @$rect;
173
- if ($orientation == 8) { # CW 90
174
- @$rect = (1-$h-$y, $x, $h, $w);
175
- } elsif ($orientation == 3) { # CW 180
176
- @$rect = (1-$x-$w, 1-$y-$h, $w, $h);
177
- } elsif ($orientation == 6) { # CW 270
178
- @$rect = ($y, 1-$x-$w, $h, $w);
179
- }
180
- }
181
- }
182
-
183
- #------------------------------------------------------------------------------
184
- # Rounds number to 9 decimal places, which is the limit to the number of decimal places that Picasa can read.
185
- sub Rounded
186
- {
187
- my $DecAcc = 10**9;
188
- return(int($_[0]*$DecAcc+.5)/$DecAcc);
189
- }
190
-
191
- #------------------------------------------------------------------------------
192
- # User-defined tag definitions
193
- #
194
- %Image::ExifTool::UserDefined = (
195
- 'Image::ExifTool::Composite' => {
196
- #
197
- # Versions that filter out unnamed regions (ContactID=ffffffffffffffff)
198
- #
199
- PicasaToMWGRegion => {
200
- Require => {
201
- 0 => 'Directory',
202
- 1 => 'FileName',
203
- 2 => 'ImageWidth',
204
- 3 => 'ImageHeight',
205
- },
206
- Desire => {
207
- 4 => 'Orientation',
208
- 5 => 'FileType',
209
- },
210
- ValueConv => sub {
211
- my ($val, $et) = @_;
212
- LoadPicasaFiles($et, $$val[0]) or return undef; # load contacts.xml and Picasa.ini
213
- my $filename = $$val[1];
214
- my @regList;
215
- # convert to local variables for readability, and make
216
- # sure there is a region associated with the current file
217
- my $contactHashRef = \%contactHash;
218
- my $tempArrayRef = $fileHash{$filename} or return undef;
219
- foreach my $tempHash (@$tempArrayRef) {
220
- next if $$tempHash{ContactID} eq 'ffffffffffffffff';
221
- my $name = $$contactHashRef{$$tempHash{ContactID}};
222
- next unless defined $name;
223
- my @rect = @$tempHash{'X','Y','W','H'};
224
- RotateRegion(\@rect, $$val[4], $$val[5]);
225
- push @regList, {
226
- Area => {
227
- X => Rounded($rect[0] + $rect[2] / 2),
228
- Y => Rounded($rect[1] + $rect[3] / 2),
229
- W => Rounded($rect[2]),
230
- H => Rounded($rect[3]),
231
- Unit => 'normalized',
232
- },
233
- Name => $name,
234
- Type => 'Face',
235
- };
236
- }
237
- # make sure a region exists, otherwise return undef
238
- return @regList ? {
239
- AppliedToDimensions => { W => $$val[2], H => $$val[3], Unit => 'pixel' },
240
- RegionList => \@regList,
241
- } : undef;
242
- },
243
- },
244
- PicasaToMPRegion => {
245
- Require => {
246
- 0 => 'Directory',
247
- 1 => 'FileName',
248
- },
249
- Desire => {
250
- 2 => 'Orientation',
251
- 3 => 'FileType',
252
- },
253
- ValueConv => sub {
254
- my ($val, $et) = @_;
255
- LoadPicasaFiles($et, $$val[0]) or return undef; # load contacts.xml and Picasa.ini
256
- my $filename = $$val[1];
257
- my @regList;
258
- # convert to local variables for readability, and make
259
- # sure there is a region associated with the current file
260
- my $contactHashRef = \%contactHash;
261
- my $tempArrayRef = $fileHash{$filename} or return undef;
262
- foreach my $tempHash (@$tempArrayRef) {
263
- next if $$tempHash{ContactID} eq 'ffffffffffffffff';
264
- my $name = $$contactHashRef{$$tempHash{ContactID}};
265
- next unless defined $name;
266
- my @rect = @$tempHash{'X','Y','W','H'};
267
- RotateRegion(\@rect, $$val[2], $$val[3]);
268
- @rect = map {Rounded($_)} @rect;
269
- push @regList, {
270
- PersonDisplayName => $name,
271
- Rectangle => join(', ', @rect),
272
- };
273
- }
274
- # make sure a region exists, otherwise return undef
275
- return @regList ? { Regions => \@regList } : undef;
276
- },
277
- },
278
- PicasaRegionNames => {
279
- Require => {
280
- 0 => 'Directory',
281
- 1 => 'FileName',
282
- },
283
- ValueConv => sub {
284
- my ($val, $et) = @_;
285
- LoadPicasaFiles($et, $$val[0]) or return undef; # load contacts.xml and Picasa.ini
286
- my $filename = $$val[1];
287
- my @regList;
288
- # convert to local variables for readability, and make
289
- # sure there is a region associated with the current file
290
- my $contactHashRef = \%contactHash;
291
- my $tempArrayRef = $fileHash{$filename} or return undef;
292
- foreach my $tempHash (@$tempArrayRef) {
293
- next if $$tempHash{ContactID} eq 'ffffffffffffffff';
294
- my $name = $$contactHashRef{$$tempHash{ContactID}};
295
- push @regList, $name if defined $name;
296
- }
297
- # make sure a region exists, otherwise return undef
298
- return @regList ? \@regList : undef;
299
- },
300
- },
301
- #
302
- # Versions that do not filter out unnamed regions (ContactID=ffffffffffffffff)
303
- # Picasa normally does not add these regions when it saves names to the file.
304
- #
305
- PicasaToMWGRegionUnfiltered => {
306
- Require => {
307
- 0 => 'Directory',
308
- 1 => 'FileName',
309
- 2 => 'ImageWidth',
310
- 3 => 'ImageHeight',
311
- },
312
- Desire => {
313
- 4 => 'Orientation',
314
- 5 => 'FileType',
315
- },
316
- ValueConv => sub {
317
- my ($val, $et) = @_;
318
- LoadPicasaFiles($et, $$val[0]) or return undef; # load contacts.xml and Picasa.ini
319
- my $filename = $$val[1];
320
- my @regList;
321
- # convert to local variables for readability, and make
322
- # sure there is a region associated with the current file
323
- my $contactHashRef = \%contactHash;
324
- my $tempArrayRef = $fileHash{$filename} or return undef;
325
- foreach my $tempHash (@$tempArrayRef) {
326
- my @rect = @$tempHash{'X','Y','W','H'};
327
- RotateRegion(\@rect, $$val[4], $$val[5]);
328
- push @regList, {
329
- Area => {
330
- X => Rounded($rect[0] + $rect[2] / 2),
331
- Y => Rounded($rect[1] + $rect[3] / 2),
332
- W => Rounded($rect[2]),
333
- H => Rounded($rect[3]),
334
- Unit => 'normalized',
335
- },
336
- Name => $$contactHashRef{$$tempHash{ContactID}} || 'unnamed',
337
- Type => 'Face',
338
- };
339
- }
340
- # make sure a region exists, otherwise return undef
341
- return @regList ? {
342
- AppliedToDimensions => { W => $$val[2], H => $$val[3], Unit => 'pixel' },
343
- RegionList => \@regList,
344
- } : undef;
345
- },
346
- },
347
- PicasaToMPRegionUnfiltered => {
348
- Require => {
349
- 0 => 'Directory',
350
- 1 => 'FileName',
351
- },
352
- Desire => {
353
- 2 => 'Orientation',
354
- 3 => 'FileType',
355
- },
356
- ValueConv => sub {
357
- my ($val, $et) = @_;
358
- LoadPicasaFiles($et, $$val[0]) or return undef; # load contacts.xml and Picasa.ini
359
- my $filename = $$val[1];
360
- my @regList;
361
- # convert to local variables for readability, and make
362
- # sure there is a region associated with the current file
363
- my $contactHashRef = \%contactHash;
364
- my $tempArrayRef = $fileHash{$filename} or return undef;
365
- foreach my $tempHash (@$tempArrayRef) {
366
- my @rect = @$tempHash{'X','Y','W','H'};
367
- RotateRegion(\@rect, $$val[2], $$val[3]);
368
- @rect = map {Rounded($_)} @rect;
369
- push @regList, {
370
- PersonDisplayName => $$contactHashRef{$$tempHash{ContactID}} || 'unnamed',
371
- Rectangle => join(', ', @rect),
372
- }
373
- }
374
- # make sure a region exists, otherwise return undef
375
- return @regList ? { Regions => \@regList } : undef;
376
- },
377
- },
378
- },
379
- );
380
-
381
- #------------------------------------------------------------------------------
382
- 1; #end
1
+ #------------------------------------------------------------------------------
2
+ # File: picasa_faces.config
3
+ #
4
+ # Description: User-defined Composite tag definitions to convert face regions
5
+ # in .picasa.ini files to MWG region tags (Metadata Working Group
6
+ # region, used by Picasa) and MP region tags (used by Microsoft
7
+ # Photo Library).
8
+ #
9
+ # Tag definitions and examples:
10
+ #
11
+ # PicasaToMWGRegion
12
+ # This will create the MWG region tag but will filter out the regions
13
+ # that are still unnamed in Picasa. Picasa defaults to naming these
14
+ # regions 'ffffffffffffffff' but normally will not save these to file.
15
+ # Example:
16
+ # exiftool -config picasa_faces.config "-RegionInfo<PicasaToMWGRegion" FILE
17
+ #
18
+ # PicasaToMPRegion
19
+ # This will create the MP region tag but will filter out the regions that
20
+ # are still unnamed in Picasa. Picasa defaults to naming these regions
21
+ # 'ffffffffffffffff' but normally will not save these to file.
22
+ # Example:
23
+ # exiftool -config picasa_faces.config "-RegionInfoMP<PicasaToMPRegion" FILE
24
+ #
25
+ # PicasaRegionNames
26
+ # Returns a list of the region names associated with the file. This
27
+ # allows copying of the region names to XMP:Subject and/or IPTC:Keywords.
28
+ # It also allows checking to see if regions need to be updated.
29
+ # Example:
30
+ # exiftool -config picasa_faces.config "-XMP:Subject<PicasaRegionNames" FILE
31
+ #
32
+ # PicasaToMWGRegionUnfiltered
33
+ # This will create the MWG region tag. This version does not filter out
34
+ # the unnamed regions. Picasa normally will filter out unnamed regions
35
+ # when it saves regions in the file.
36
+ # Example:
37
+ # exiftool -config picasa_faces.config "-RegionInfo<PicasaToMWGRegionUnfiltered" FILE
38
+ #
39
+ # PicasaToMPRegionUnfiltered
40
+ # This will create the MP region tag. This version does not filter out
41
+ # the unnamed regions. Picasa normally will filter out unnamed regions
42
+ # when it saves regions in the file.
43
+ # Example:
44
+ # exiftool -config picasa_faces.config "-RegionInfoMP<PicasaToMPRegionUnfiltered" FILE
45
+ #
46
+ # Notes: The face names are loaded from the Picasa contacts file, which
47
+ # defaults to:
48
+ #
49
+ # C:/Users/MainUser/AppData/Local/PicasaData/Google/Picasa2/contacts/contacts.xml
50
+ #
51
+ # The default contacts file may be changed by editing the value
52
+ # of $contactXML below, or on the command line with ExifTool 9.90
53
+ # or later via the -userParam option, eg:
54
+ # -userparam PicasaContactsFile=/path/to/contacts.xml
55
+ #
56
+ # Requires: ExifTool version 8.82 or later (9.90 or later for -userparam)
57
+ #
58
+ # Revisions: 2015/03/07 - Bryan K. Williams (aka StarGeek) Created
59
+ # 2015/03/12 - PH Minor changes, optimizations and reformatting
60
+ # 2015/05/11 - BKW Fix bug where Picasa writes region data for
61
+ # rotated NEF and CR2 images as if the orientation
62
+ # is not rotated.
63
+ # 2015/05/12 - PH Minor code tweaks
64
+ # 2015/10/26 - BKW Round off area sizes to 7 decimal places
65
+ # 2016/01/18 - BKW Improved rounding algorithm
66
+ # 2016/05/14 - BKW Increased rounding to 9 decimal places (Max Picasa accepts),
67
+ # moved rounding operation to subroutine
68
+ #
69
+ # References: http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,6354.0.html
70
+ #------------------------------------------------------------------------------
71
+
72
+ # Picasa contacts file name
73
+ my $contactXML = 'C:/Users/MainUser/AppData/Local/PicasaData/Google/Picasa2/contacts/contacts.xml';
74
+
75
+ # local variables
76
+ my $lastIniFile = ''; # path of last .picasa.ini file loaded
77
+ my $lastContactFile = ''; # path of last contacts.xml file loaded
78
+
79
+ # raw file types that need additional processing to get regions correct
80
+ my %isRawFile = map { $_ => 1 } qw(
81
+ 3FR ARW CR2 CRW CS1 DCR DNG EIP ERF IIQ K25 KDC MEF MOS MRW NEF NRW
82
+ ORF PEF RAF RAW RW2 RWL SR2 SRF SRW X3F), 'Canon 1D RAW';
83
+
84
+ my %contactHash; # lookup for loaded contacts.xml entries
85
+ my %fileHash; # lookup for loaded .picasa.ini entries
86
+
87
+ #------------------------------------------------------------------------------
88
+ # Load Picasa's contacts.xml and .picasa.ini files.
89
+ # Inputs: 0) ExifTool object reference, 1) .picasa.ini directory
90
+ # Returns: 1 if files were loaded and parsed, undef on error
91
+ # Notes: If file has already been loaded, it isn't reloaded
92
+ sub LoadPicasaFiles($$)
93
+ {
94
+ local (*CONTACTS, *INI);
95
+ my ($et, $iniDir) = @_;
96
+
97
+ # check ExifTool version to see if there might be
98
+ # a command line setting for the contact file
99
+ my $contactFile = ($Image::ExifTool::VERSION >= 9.89 and
100
+ defined($et->Options(UserParam => 'PicasaContactsFile'))) ?
101
+ $et->Options(UserParam => 'PicasaContactsFile') : $contactXML;
102
+
103
+ # load Picasa contacts.xml file unless done already
104
+ unless ($contactFile eq $lastContactFile) {
105
+ $lastContactFile = $contactFile;
106
+ undef %contactHash;
107
+ # Picasa's default setting for unnamed faces.
108
+ $contactHash{'ffffffffffffffff'} = 'unnamed';
109
+ if (open(CONTACTS, $contactFile)) {
110
+ require Image::ExifTool::HTML;
111
+ while (<CONTACTS>) {
112
+ /name="(.*?)"/ or next;
113
+ my $name = $1;
114
+ /id="([a-f0-9]+)"/ or next;
115
+ my $id = $1;
116
+ $contactHash{$id} = Image::ExifTool::HTML::UnescapeHTML($name);
117
+ }
118
+ close(CONTACTS);
119
+ } else {
120
+ local $SIG{'__WARN__'} = undef; # stop ExifTool from catching the warning
121
+ warn "Error reading contacts file $contactFile\n";
122
+ }
123
+ }
124
+
125
+ # load .picasa.ini file from the specified directory
126
+ my $iniFile = "$iniDir/.picasa.ini";
127
+
128
+ if ($iniFile eq $lastIniFile) {
129
+ return %fileHash ? 1 : undef;
130
+ }
131
+ $lastIniFile = $iniFile;
132
+ open(INI, $iniFile) or return undef;
133
+ my $section = '';
134
+ while (<INI>) {
135
+ # Process New Section
136
+ /^\s*\[(.+)\][\n\r]*$/ and $section = $1, next;
137
+ # process entry (all we care about are the "faces" lines)
138
+ /^faces=(.*)$/ or next;
139
+ my @temp = split /;/, $1;
140
+ foreach (@temp) {
141
+ /rect64\(([\da-f]{1,16})\),([\da-f]{1,16})/ or next;
142
+ # the string in parens after "rect64" is a 64 bit number in hex,
143
+ # but Picasa doesn't add leading zeroes, so the length of the string
144
+ # cannot be assumed to be 16 bytes. Handle this as two 32-bit numbers
145
+ # for compatibility with 32-bit systems.
146
+ my $hi = hex(substr($1, 0, -8));
147
+ my $lo = hex(substr($1, -8));
148
+ my $x0 = ($hi >> 16) /65535;
149
+ my $y0 = ($hi & 0xffff)/65535;
150
+ my $x1 = ($lo >> 16) /65535;
151
+ my $y1 = ($lo & 0xffff)/65535;
152
+ push @{ $fileHash{$section} }, {
153
+ ContactID => $2,
154
+ X => $x0,
155
+ Y => $y0,
156
+ W => $x1 - $x0,
157
+ H => $y1 - $y0,
158
+ };
159
+ }
160
+ }
161
+ close(INI);
162
+ return %fileHash ? 1 : undef;
163
+ }
164
+
165
+ #------------------------------------------------------------------------------
166
+ # Rotate region to specified orientation (for RAW file types only)
167
+ # Input: 0) rectangle array ref (x,y,w,h), 1) EXIF orientation value, 2) file type
168
+ sub RotateRegion($$$)
169
+ {
170
+ my ($rect, $orientation, $fileType) = @_;
171
+ if ($orientation and $fileType and $isRawFile{$fileType}) {
172
+ my ($x,$y,$w,$h) = @$rect;
173
+ if ($orientation == 8) { # CW 90
174
+ @$rect = (1-$h-$y, $x, $h, $w);
175
+ } elsif ($orientation == 3) { # CW 180
176
+ @$rect = (1-$x-$w, 1-$y-$h, $w, $h);
177
+ } elsif ($orientation == 6) { # CW 270
178
+ @$rect = ($y, 1-$x-$w, $h, $w);
179
+ }
180
+ }
181
+ }
182
+
183
+ #------------------------------------------------------------------------------
184
+ # Rounds number to 9 decimal places, which is the limit to the number of decimal places that Picasa can read.
185
+ sub Rounded
186
+ {
187
+ my $DecAcc = 10**9;
188
+ return(int($_[0]*$DecAcc+.5)/$DecAcc);
189
+ }
190
+
191
+ #------------------------------------------------------------------------------
192
+ # User-defined tag definitions
193
+ #
194
+ %Image::ExifTool::UserDefined = (
195
+ 'Image::ExifTool::Composite' => {
196
+ #
197
+ # Versions that filter out unnamed regions (ContactID=ffffffffffffffff)
198
+ #
199
+ PicasaToMWGRegion => {
200
+ Require => {
201
+ 0 => 'Directory',
202
+ 1 => 'FileName',
203
+ 2 => 'ImageWidth',
204
+ 3 => 'ImageHeight',
205
+ },
206
+ Desire => {
207
+ 4 => 'Orientation',
208
+ 5 => 'FileType',
209
+ },
210
+ ValueConv => sub {
211
+ my ($val, $et) = @_;
212
+ LoadPicasaFiles($et, $$val[0]) or return undef; # load contacts.xml and Picasa.ini
213
+ my $filename = $$val[1];
214
+ my @regList;
215
+ # convert to local variables for readability, and make
216
+ # sure there is a region associated with the current file
217
+ my $contactHashRef = \%contactHash;
218
+ my $tempArrayRef = $fileHash{$filename} or return undef;
219
+ foreach my $tempHash (@$tempArrayRef) {
220
+ next if $$tempHash{ContactID} eq 'ffffffffffffffff';
221
+ my $name = $$contactHashRef{$$tempHash{ContactID}};
222
+ next unless defined $name;
223
+ my @rect = @$tempHash{'X','Y','W','H'};
224
+ RotateRegion(\@rect, $$val[4], $$val[5]);
225
+ push @regList, {
226
+ Area => {
227
+ X => Rounded($rect[0] + $rect[2] / 2),
228
+ Y => Rounded($rect[1] + $rect[3] / 2),
229
+ W => Rounded($rect[2]),
230
+ H => Rounded($rect[3]),
231
+ Unit => 'normalized',
232
+ },
233
+ Name => $name,
234
+ Type => 'Face',
235
+ };
236
+ }
237
+ # make sure a region exists, otherwise return undef
238
+ return @regList ? {
239
+ AppliedToDimensions => { W => $$val[2], H => $$val[3], Unit => 'pixel' },
240
+ RegionList => \@regList,
241
+ } : undef;
242
+ },
243
+ },
244
+ PicasaToMPRegion => {
245
+ Require => {
246
+ 0 => 'Directory',
247
+ 1 => 'FileName',
248
+ },
249
+ Desire => {
250
+ 2 => 'Orientation',
251
+ 3 => 'FileType',
252
+ },
253
+ ValueConv => sub {
254
+ my ($val, $et) = @_;
255
+ LoadPicasaFiles($et, $$val[0]) or return undef; # load contacts.xml and Picasa.ini
256
+ my $filename = $$val[1];
257
+ my @regList;
258
+ # convert to local variables for readability, and make
259
+ # sure there is a region associated with the current file
260
+ my $contactHashRef = \%contactHash;
261
+ my $tempArrayRef = $fileHash{$filename} or return undef;
262
+ foreach my $tempHash (@$tempArrayRef) {
263
+ next if $$tempHash{ContactID} eq 'ffffffffffffffff';
264
+ my $name = $$contactHashRef{$$tempHash{ContactID}};
265
+ next unless defined $name;
266
+ my @rect = @$tempHash{'X','Y','W','H'};
267
+ RotateRegion(\@rect, $$val[2], $$val[3]);
268
+ @rect = map {Rounded($_)} @rect;
269
+ push @regList, {
270
+ PersonDisplayName => $name,
271
+ Rectangle => join(', ', @rect),
272
+ };
273
+ }
274
+ # make sure a region exists, otherwise return undef
275
+ return @regList ? { Regions => \@regList } : undef;
276
+ },
277
+ },
278
+ PicasaRegionNames => {
279
+ Require => {
280
+ 0 => 'Directory',
281
+ 1 => 'FileName',
282
+ },
283
+ ValueConv => sub {
284
+ my ($val, $et) = @_;
285
+ LoadPicasaFiles($et, $$val[0]) or return undef; # load contacts.xml and Picasa.ini
286
+ my $filename = $$val[1];
287
+ my @regList;
288
+ # convert to local variables for readability, and make
289
+ # sure there is a region associated with the current file
290
+ my $contactHashRef = \%contactHash;
291
+ my $tempArrayRef = $fileHash{$filename} or return undef;
292
+ foreach my $tempHash (@$tempArrayRef) {
293
+ next if $$tempHash{ContactID} eq 'ffffffffffffffff';
294
+ my $name = $$contactHashRef{$$tempHash{ContactID}};
295
+ push @regList, $name if defined $name;
296
+ }
297
+ # make sure a region exists, otherwise return undef
298
+ return @regList ? \@regList : undef;
299
+ },
300
+ },
301
+ #
302
+ # Versions that do not filter out unnamed regions (ContactID=ffffffffffffffff)
303
+ # Picasa normally does not add these regions when it saves names to the file.
304
+ #
305
+ PicasaToMWGRegionUnfiltered => {
306
+ Require => {
307
+ 0 => 'Directory',
308
+ 1 => 'FileName',
309
+ 2 => 'ImageWidth',
310
+ 3 => 'ImageHeight',
311
+ },
312
+ Desire => {
313
+ 4 => 'Orientation',
314
+ 5 => 'FileType',
315
+ },
316
+ ValueConv => sub {
317
+ my ($val, $et) = @_;
318
+ LoadPicasaFiles($et, $$val[0]) or return undef; # load contacts.xml and Picasa.ini
319
+ my $filename = $$val[1];
320
+ my @regList;
321
+ # convert to local variables for readability, and make
322
+ # sure there is a region associated with the current file
323
+ my $contactHashRef = \%contactHash;
324
+ my $tempArrayRef = $fileHash{$filename} or return undef;
325
+ foreach my $tempHash (@$tempArrayRef) {
326
+ my @rect = @$tempHash{'X','Y','W','H'};
327
+ RotateRegion(\@rect, $$val[4], $$val[5]);
328
+ push @regList, {
329
+ Area => {
330
+ X => Rounded($rect[0] + $rect[2] / 2),
331
+ Y => Rounded($rect[1] + $rect[3] / 2),
332
+ W => Rounded($rect[2]),
333
+ H => Rounded($rect[3]),
334
+ Unit => 'normalized',
335
+ },
336
+ Name => $$contactHashRef{$$tempHash{ContactID}} || 'unnamed',
337
+ Type => 'Face',
338
+ };
339
+ }
340
+ # make sure a region exists, otherwise return undef
341
+ return @regList ? {
342
+ AppliedToDimensions => { W => $$val[2], H => $$val[3], Unit => 'pixel' },
343
+ RegionList => \@regList,
344
+ } : undef;
345
+ },
346
+ },
347
+ PicasaToMPRegionUnfiltered => {
348
+ Require => {
349
+ 0 => 'Directory',
350
+ 1 => 'FileName',
351
+ },
352
+ Desire => {
353
+ 2 => 'Orientation',
354
+ 3 => 'FileType',
355
+ },
356
+ ValueConv => sub {
357
+ my ($val, $et) = @_;
358
+ LoadPicasaFiles($et, $$val[0]) or return undef; # load contacts.xml and Picasa.ini
359
+ my $filename = $$val[1];
360
+ my @regList;
361
+ # convert to local variables for readability, and make
362
+ # sure there is a region associated with the current file
363
+ my $contactHashRef = \%contactHash;
364
+ my $tempArrayRef = $fileHash{$filename} or return undef;
365
+ foreach my $tempHash (@$tempArrayRef) {
366
+ my @rect = @$tempHash{'X','Y','W','H'};
367
+ RotateRegion(\@rect, $$val[2], $$val[3]);
368
+ @rect = map {Rounded($_)} @rect;
369
+ push @regList, {
370
+ PersonDisplayName => $$contactHashRef{$$tempHash{ContactID}} || 'unnamed',
371
+ Rectangle => join(', ', @rect),
372
+ }
373
+ }
374
+ # make sure a region exists, otherwise return undef
375
+ return @regList ? { Regions => \@regList } : undef;
376
+ },
377
+ },
378
+ },
379
+ );
380
+
381
+ #------------------------------------------------------------------------------
382
+ 1; #end