IPTC.pm 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264
  1. #------------------------------------------------------------------------------
  2. # File: IPTC.pm
  3. #
  4. # Description: Read IPTC meta information
  5. #
  6. # Revisions: Jan. 08/2003 - P. Harvey Created
  7. # Feb. 05/2004 - P. Harvey Added support for records other than 2
  8. #
  9. # References: 1) http://www.iptc.org/IIM/
  10. #------------------------------------------------------------------------------
  11. package Image::ExifTool::IPTC;
  12. use strict;
  13. use vars qw($VERSION $AUTOLOAD %iptcCharset);
  14. use Image::ExifTool qw(:DataAccess :Utils);
  15. $VERSION = '1.53';
  16. %iptcCharset = (
  17. "\x1b%G" => 'UTF8',
  18. # don't translate these (at least until we handle ISO 2022 shift codes)
  19. # because the sets are only designated and not invoked
  20. # "\x1b,A" => 'Latin', # G0 = ISO 8859-1 (similar to Latin1, but codes 0x80-0x9f are missing)
  21. # "\x1b-A" => 'Latin', # G1 "
  22. # "\x1b.A" => 'Latin', # G2
  23. # "\x1b/A" => 'Latin', # G3
  24. );
  25. sub ProcessIPTC($$$);
  26. sub WriteIPTC($$$);
  27. sub CheckIPTC($$$);
  28. sub PrintCodedCharset($);
  29. sub PrintInvCodedCharset($);
  30. # standard IPTC locations
  31. # (MWG specifies locations only for JPEG, TIFF and PSD -- the rest are ExifTool-defined)
  32. my %isStandardIPTC = (
  33. 'JPEG-APP13-Photoshop-IPTC' => 1,
  34. 'TIFF-IFD0-IPTC' => 1,
  35. 'PSD-IPTC' => 1,
  36. 'MIE-IPTC' => 1,
  37. 'EPS-Photoshop-IPTC' => 1,
  38. 'PS-Photoshop-IPTC' => 1,
  39. 'EXV-APP13-Photoshop-IPTC' => 1,
  40. # set file types to 0 if they have a standard location
  41. JPEG => 0,
  42. TIFF => 0,
  43. PSD => 0,
  44. MIE => 0,
  45. EPS => 0,
  46. PS => 0,
  47. EXV => 0,
  48. );
  49. my %fileFormat = (
  50. 0 => 'No ObjectData',
  51. 1 => 'IPTC-NAA Digital Newsphoto Parameter Record',
  52. 2 => 'IPTC7901 Recommended Message Format',
  53. 3 => 'Tagged Image File Format (Adobe/Aldus Image data)',
  54. 4 => 'Illustrator (Adobe Graphics data)',
  55. 5 => 'AppleSingle (Apple Computer Inc)',
  56. 6 => 'NAA 89-3 (ANPA 1312)',
  57. 7 => 'MacBinary II',
  58. 8 => 'IPTC Unstructured Character Oriented File Format (UCOFF)',
  59. 9 => 'United Press International ANPA 1312 variant',
  60. 10 => 'United Press International Down-Load Message',
  61. 11 => 'JPEG File Interchange (JFIF)',
  62. 12 => 'Photo-CD Image-Pac (Eastman Kodak)',
  63. 13 => 'Bit Mapped Graphics File [.BMP] (Microsoft)',
  64. 14 => 'Digital Audio File [.WAV] (Microsoft & Creative Labs)',
  65. 15 => 'Audio plus Moving Video [.AVI] (Microsoft)',
  66. 16 => 'PC DOS/Windows Executable Files [.COM][.EXE]',
  67. 17 => 'Compressed Binary File [.ZIP] (PKWare Inc)',
  68. 18 => 'Audio Interchange File Format AIFF (Apple Computer Inc)',
  69. 19 => 'RIFF Wave (Microsoft Corporation)',
  70. 20 => 'Freehand (Macromedia/Aldus)',
  71. 21 => 'Hypertext Markup Language [.HTML] (The Internet Society)',
  72. 22 => 'MPEG 2 Audio Layer 2 (Musicom), ISO/IEC',
  73. 23 => 'MPEG 2 Audio Layer 3, ISO/IEC',
  74. 24 => 'Portable Document File [.PDF] Adobe',
  75. 25 => 'News Industry Text Format (NITF)',
  76. 26 => 'Tape Archive [.TAR]',
  77. 27 => 'Tidningarnas Telegrambyra NITF version (TTNITF DTD)',
  78. 28 => 'Ritzaus Bureau NITF version (RBNITF DTD)',
  79. 29 => 'Corel Draw [.CDR]',
  80. );
  81. # main IPTC tag table
  82. # Note: ALL entries in main IPTC table (except PROCESS_PROC) must be SubDirectory
  83. # entries, each specifying a TagTable.
  84. %Image::ExifTool::IPTC::Main = (
  85. GROUPS => { 2 => 'Image' },
  86. PROCESS_PROC => \&ProcessIPTC,
  87. WRITE_PROC => \&WriteIPTC,
  88. 1 => {
  89. Name => 'IPTCEnvelope',
  90. SubDirectory => {
  91. TagTable => 'Image::ExifTool::IPTC::EnvelopeRecord',
  92. },
  93. },
  94. 2 => {
  95. Name => 'IPTCApplication',
  96. SubDirectory => {
  97. TagTable => 'Image::ExifTool::IPTC::ApplicationRecord',
  98. },
  99. },
  100. 3 => {
  101. Name => 'IPTCNewsPhoto',
  102. SubDirectory => {
  103. TagTable => 'Image::ExifTool::IPTC::NewsPhoto',
  104. },
  105. },
  106. 7 => {
  107. Name => 'IPTCPreObjectData',
  108. SubDirectory => {
  109. TagTable => 'Image::ExifTool::IPTC::PreObjectData',
  110. },
  111. },
  112. 8 => {
  113. Name => 'IPTCObjectData',
  114. SubDirectory => {
  115. TagTable => 'Image::ExifTool::IPTC::ObjectData',
  116. },
  117. },
  118. 9 => {
  119. Name => 'IPTCPostObjectData',
  120. Groups => { 1 => 'IPTC#' }, #(just so this shows up in group list)
  121. SubDirectory => {
  122. TagTable => 'Image::ExifTool::IPTC::PostObjectData',
  123. },
  124. },
  125. 240 => {
  126. Name => 'IPTCFotoStation',
  127. SubDirectory => {
  128. TagTable => 'Image::ExifTool::IPTC::FotoStation',
  129. },
  130. },
  131. );
  132. # Record 1 -- EnvelopeRecord
  133. %Image::ExifTool::IPTC::EnvelopeRecord = (
  134. GROUPS => { 2 => 'Other' },
  135. WRITE_PROC => \&WriteIPTC,
  136. CHECK_PROC => \&CheckIPTC,
  137. WRITABLE => 1,
  138. 0 => {
  139. Name => 'EnvelopeRecordVersion',
  140. Format => 'int16u',
  141. Mandatory => 1,
  142. },
  143. 5 => {
  144. Name => 'Destination',
  145. Flags => 'List',
  146. Groups => { 2 => 'Location' },
  147. Format => 'string[0,1024]',
  148. },
  149. 20 => {
  150. Name => 'FileFormat',
  151. Groups => { 2 => 'Image' },
  152. Format => 'int16u',
  153. PrintConv => \%fileFormat,
  154. },
  155. 22 => {
  156. Name => 'FileVersion',
  157. Groups => { 2 => 'Image' },
  158. Format => 'int16u',
  159. },
  160. 30 => {
  161. Name => 'ServiceIdentifier',
  162. Format => 'string[0,10]',
  163. },
  164. 40 => {
  165. Name => 'EnvelopeNumber',
  166. Format => 'digits[8]',
  167. },
  168. 50 => {
  169. Name => 'ProductID',
  170. Flags => 'List',
  171. Format => 'string[0,32]',
  172. },
  173. 60 => {
  174. Name => 'EnvelopePriority',
  175. Format => 'digits[1]',
  176. PrintConv => {
  177. 0 => '0 (reserved)',
  178. 1 => '1 (most urgent)',
  179. 2 => 2,
  180. 3 => 3,
  181. 4 => 4,
  182. 5 => '5 (normal urgency)',
  183. 6 => 6,
  184. 7 => 7,
  185. 8 => '8 (least urgent)',
  186. 9 => '9 (user-defined priority)',
  187. },
  188. },
  189. 70 => {
  190. Name => 'DateSent',
  191. Groups => { 2 => 'Time' },
  192. Format => 'digits[8]',
  193. Shift => 'Time',
  194. ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
  195. ValueConvInv => 'Image::ExifTool::IPTC::IptcDate($val)',
  196. PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($val)',
  197. },
  198. 80 => {
  199. Name => 'TimeSent',
  200. Groups => { 2 => 'Time' },
  201. Format => 'string[11]',
  202. Shift => 'Time',
  203. ValueConv => 'Image::ExifTool::Exif::ExifTime($val)',
  204. ValueConvInv => 'Image::ExifTool::IPTC::IptcTime($val)',
  205. PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($val)',
  206. },
  207. 90 => {
  208. Name => 'CodedCharacterSet',
  209. Notes => q{
  210. values are entered in the form "ESC X Y[, ...]". The escape sequence for
  211. UTF-8 character coding is "ESC % G", but this is displayed as "UTF8" for
  212. convenience. Either string may be used when writing. The value of this tag
  213. affects the decoding of string values in the Application and NewsPhoto
  214. records. This tag is marked as "unsafe" to prevent it from being copied by
  215. default in a group operation because existing tags in the destination image
  216. may use a different encoding. When creating a new IPTC record from scratch,
  217. it is suggested that this be set to "UTF8" if special characters are a
  218. possibility
  219. },
  220. Protected => 1,
  221. Format => 'string[0,32]',
  222. # convert ISO 2022 escape sequences to a more readable format
  223. PrintConv => \&PrintCodedCharset,
  224. PrintConvInv => \&PrintInvCodedCharset,
  225. },
  226. 100 => {
  227. Name => 'UniqueObjectName',
  228. Format => 'string[14,80]',
  229. },
  230. 120 => {
  231. Name => 'ARMIdentifier',
  232. Format => 'int16u',
  233. },
  234. 122 => {
  235. Name => 'ARMVersion',
  236. Format => 'int16u',
  237. },
  238. );
  239. # Record 2 -- ApplicationRecord
  240. %Image::ExifTool::IPTC::ApplicationRecord = (
  241. GROUPS => { 2 => 'Other' },
  242. WRITE_PROC => \&WriteIPTC,
  243. CHECK_PROC => \&CheckIPTC,
  244. WRITABLE => 1,
  245. 0 => {
  246. Name => 'ApplicationRecordVersion',
  247. Format => 'int16u',
  248. Mandatory => 1,
  249. },
  250. 3 => {
  251. Name => 'ObjectTypeReference',
  252. Format => 'string[3,67]',
  253. },
  254. 4 => {
  255. Name => 'ObjectAttributeReference',
  256. Flags => 'List',
  257. Format => 'string[4,68]',
  258. },
  259. 5 => {
  260. Name => 'ObjectName',
  261. Format => 'string[0,64]',
  262. },
  263. 7 => {
  264. Name => 'EditStatus',
  265. Format => 'string[0,64]',
  266. },
  267. 8 => {
  268. Name => 'EditorialUpdate',
  269. Format => 'digits[2]',
  270. PrintConv => {
  271. '01' => 'Additional language',
  272. },
  273. },
  274. 10 => {
  275. Name => 'Urgency',
  276. Format => 'digits[1]',
  277. PrintConv => {
  278. 0 => '0 (reserved)',
  279. 1 => '1 (most urgent)',
  280. 2 => 2,
  281. 3 => 3,
  282. 4 => 4,
  283. 5 => '5 (normal urgency)',
  284. 6 => 6,
  285. 7 => 7,
  286. 8 => '8 (least urgent)',
  287. 9 => '9 (user-defined priority)',
  288. },
  289. },
  290. 12 => {
  291. Name => 'SubjectReference',
  292. Flags => 'List',
  293. Format => 'string[13,236]',
  294. },
  295. 15 => {
  296. Name => 'Category',
  297. Format => 'string[0,3]',
  298. },
  299. 20 => {
  300. Name => 'SupplementalCategories',
  301. Flags => 'List',
  302. Format => 'string[0,32]',
  303. },
  304. 22 => {
  305. Name => 'FixtureIdentifier',
  306. Format => 'string[0,32]',
  307. },
  308. 25 => {
  309. Name => 'Keywords',
  310. Flags => 'List',
  311. Format => 'string[0,64]',
  312. },
  313. 26 => {
  314. Name => 'ContentLocationCode',
  315. Flags => 'List',
  316. Groups => { 2 => 'Location' },
  317. Format => 'string[3]',
  318. },
  319. 27 => {
  320. Name => 'ContentLocationName',
  321. Flags => 'List',
  322. Groups => { 2 => 'Location' },
  323. Format => 'string[0,64]',
  324. },
  325. 30 => {
  326. Name => 'ReleaseDate',
  327. Groups => { 2 => 'Time' },
  328. Format => 'digits[8]',
  329. Shift => 'Time',
  330. ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
  331. ValueConvInv => 'Image::ExifTool::IPTC::IptcDate($val)',
  332. PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($val)',
  333. },
  334. 35 => {
  335. Name => 'ReleaseTime',
  336. Groups => { 2 => 'Time' },
  337. Format => 'string[11]',
  338. Shift => 'Time',
  339. ValueConv => 'Image::ExifTool::Exif::ExifTime($val)',
  340. ValueConvInv => 'Image::ExifTool::IPTC::IptcTime($val)',
  341. PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($val)',
  342. },
  343. 37 => {
  344. Name => 'ExpirationDate',
  345. Groups => { 2 => 'Time' },
  346. Format => 'digits[8]',
  347. Shift => 'Time',
  348. ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
  349. ValueConvInv => 'Image::ExifTool::IPTC::IptcDate($val)',
  350. PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($val)',
  351. },
  352. 38 => {
  353. Name => 'ExpirationTime',
  354. Groups => { 2 => 'Time' },
  355. Format => 'string[11]',
  356. Shift => 'Time',
  357. ValueConv => 'Image::ExifTool::Exif::ExifTime($val)',
  358. ValueConvInv => 'Image::ExifTool::IPTC::IptcTime($val)',
  359. PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($val)',
  360. },
  361. 40 => {
  362. Name => 'SpecialInstructions',
  363. Format => 'string[0,256]',
  364. },
  365. 42 => {
  366. Name => 'ActionAdvised',
  367. Format => 'digits[2]',
  368. PrintConv => {
  369. '' => '',
  370. '01' => 'Object Kill',
  371. '02' => 'Object Replace',
  372. '03' => 'Object Append',
  373. '04' => 'Object Reference',
  374. },
  375. },
  376. 45 => {
  377. Name => 'ReferenceService',
  378. Flags => 'List',
  379. Format => 'string[0,10]',
  380. },
  381. 47 => {
  382. Name => 'ReferenceDate',
  383. Groups => { 2 => 'Time' },
  384. Flags => 'List',
  385. Format => 'digits[8]',
  386. Shift => 'Time',
  387. ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
  388. ValueConvInv => 'Image::ExifTool::IPTC::IptcDate($val)',
  389. PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($val)',
  390. },
  391. 50 => {
  392. Name => 'ReferenceNumber',
  393. Flags => 'List',
  394. Format => 'digits[8]',
  395. },
  396. 55 => {
  397. Name => 'DateCreated',
  398. Groups => { 2 => 'Time' },
  399. Format => 'digits[8]',
  400. Shift => 'Time',
  401. ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
  402. ValueConvInv => 'Image::ExifTool::IPTC::IptcDate($val)',
  403. PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($val)',
  404. },
  405. 60 => {
  406. Name => 'TimeCreated',
  407. Groups => { 2 => 'Time' },
  408. Format => 'string[11]',
  409. Shift => 'Time',
  410. ValueConv => 'Image::ExifTool::Exif::ExifTime($val)',
  411. ValueConvInv => 'Image::ExifTool::IPTC::IptcTime($val)',
  412. PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($val)',
  413. },
  414. 62 => {
  415. Name => 'DigitalCreationDate',
  416. Groups => { 2 => 'Time' },
  417. Format => 'digits[8]',
  418. Shift => 'Time',
  419. ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
  420. ValueConvInv => 'Image::ExifTool::IPTC::IptcDate($val)',
  421. PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($val)',
  422. },
  423. 63 => {
  424. Name => 'DigitalCreationTime',
  425. Groups => { 2 => 'Time' },
  426. Format => 'string[11]',
  427. Shift => 'Time',
  428. ValueConv => 'Image::ExifTool::Exif::ExifTime($val)',
  429. ValueConvInv => 'Image::ExifTool::IPTC::IptcTime($val)',
  430. PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($val)',
  431. },
  432. 65 => {
  433. Name => 'OriginatingProgram',
  434. Format => 'string[0,32]',
  435. },
  436. 70 => {
  437. Name => 'ProgramVersion',
  438. Format => 'string[0,10]',
  439. },
  440. 75 => {
  441. Name => 'ObjectCycle',
  442. Format => 'string[1]',
  443. PrintConv => {
  444. 'a' => 'Morning',
  445. 'p' => 'Evening',
  446. 'b' => 'Both Morning and Evening',
  447. },
  448. },
  449. 80 => {
  450. Name => 'By-line',
  451. Flags => 'List',
  452. Format => 'string[0,32]',
  453. Groups => { 2 => 'Author' },
  454. },
  455. 85 => {
  456. Name => 'By-lineTitle',
  457. Flags => 'List',
  458. Format => 'string[0,32]',
  459. Groups => { 2 => 'Author' },
  460. },
  461. 90 => {
  462. Name => 'City',
  463. Format => 'string[0,32]',
  464. Groups => { 2 => 'Location' },
  465. },
  466. 92 => {
  467. Name => 'Sub-location',
  468. Format => 'string[0,32]',
  469. Groups => { 2 => 'Location' },
  470. },
  471. 95 => {
  472. Name => 'Province-State',
  473. Format => 'string[0,32]',
  474. Groups => { 2 => 'Location' },
  475. },
  476. 100 => {
  477. Name => 'Country-PrimaryLocationCode',
  478. Format => 'string[3]',
  479. Groups => { 2 => 'Location' },
  480. },
  481. 101 => {
  482. Name => 'Country-PrimaryLocationName',
  483. Format => 'string[0,64]',
  484. Groups => { 2 => 'Location' },
  485. },
  486. 103 => {
  487. Name => 'OriginalTransmissionReference',
  488. Format => 'string[0,32]',
  489. },
  490. 105 => {
  491. Name => 'Headline',
  492. Format => 'string[0,256]',
  493. },
  494. 110 => {
  495. Name => 'Credit',
  496. Groups => { 2 => 'Author' },
  497. Format => 'string[0,32]',
  498. },
  499. 115 => {
  500. Name => 'Source',
  501. Groups => { 2 => 'Author' },
  502. Format => 'string[0,32]',
  503. },
  504. 116 => {
  505. Name => 'CopyrightNotice',
  506. Groups => { 2 => 'Author' },
  507. Format => 'string[0,128]',
  508. },
  509. 118 => {
  510. Name => 'Contact',
  511. Flags => 'List',
  512. Groups => { 2 => 'Author' },
  513. Format => 'string[0,128]',
  514. },
  515. 120 => {
  516. Name => 'Caption-Abstract',
  517. Format => 'string[0,2000]',
  518. },
  519. 121 => {
  520. Name => 'LocalCaption',
  521. Format => 'string[0,256]', # (guess)
  522. Notes => q{
  523. I haven't found a reference for the format of tags 121, 184-188 and
  524. 225-232, so I have just make them writable as strings with
  525. reasonable length. Beware that if this is wrong, other utilities
  526. won't be able to read these tags as written by ExifTool
  527. },
  528. },
  529. 122 => {
  530. Name => 'Writer-Editor',
  531. Flags => 'List',
  532. Groups => { 2 => 'Author' },
  533. Format => 'string[0,32]',
  534. },
  535. 125 => {
  536. Name => 'RasterizedCaption',
  537. Format => 'undef[7360]',
  538. Binary => 1,
  539. },
  540. 130 => {
  541. Name => 'ImageType',
  542. Groups => { 2 => 'Image' },
  543. Format => 'string[2]',
  544. },
  545. 131 => {
  546. Name => 'ImageOrientation',
  547. Groups => { 2 => 'Image' },
  548. Format => 'string[1]',
  549. PrintConv => {
  550. P => 'Portrait',
  551. L => 'Landscape',
  552. S => 'Square',
  553. },
  554. },
  555. 135 => {
  556. Name => 'LanguageIdentifier',
  557. Format => 'string[2,3]',
  558. },
  559. 150 => {
  560. Name => 'AudioType',
  561. Format => 'string[2]',
  562. PrintConv => {
  563. '1A' => 'Mono Actuality',
  564. '2A' => 'Stereo Actuality',
  565. '1C' => 'Mono Question and Answer Session',
  566. '2C' => 'Stereo Question and Answer Session',
  567. '1M' => 'Mono Music',
  568. '2M' => 'Stereo Music',
  569. '1Q' => 'Mono Response to a Question',
  570. '2Q' => 'Stereo Response to a Question',
  571. '1R' => 'Mono Raw Sound',
  572. '2R' => 'Stereo Raw Sound',
  573. '1S' => 'Mono Scener',
  574. '2S' => 'Stereo Scener',
  575. '0T' => 'Text Only',
  576. '1V' => 'Mono Voicer',
  577. '2V' => 'Stereo Voicer',
  578. '1W' => 'Mono Wrap',
  579. '2W' => 'Stereo Wrap',
  580. },
  581. },
  582. 151 => {
  583. Name => 'AudioSamplingRate',
  584. Format => 'digits[6]',
  585. },
  586. 152 => {
  587. Name => 'AudioSamplingResolution',
  588. Format => 'digits[2]',
  589. },
  590. 153 => {
  591. Name => 'AudioDuration',
  592. Format => 'digits[6]',
  593. },
  594. 154 => {
  595. Name => 'AudioOutcue',
  596. Format => 'string[0,64]',
  597. },
  598. 184 => {
  599. Name => 'JobID',
  600. Format => 'string[0,64]', # (guess)
  601. },
  602. 185 => {
  603. Name => 'MasterDocumentID',
  604. Format => 'string[0,256]', # (guess)
  605. },
  606. 186 => {
  607. Name => 'ShortDocumentID',
  608. Format => 'string[0,64]', # (guess)
  609. },
  610. 187 => {
  611. Name => 'UniqueDocumentID',
  612. Format => 'string[0,128]', # (guess)
  613. },
  614. 188 => {
  615. Name => 'OwnerID',
  616. Format => 'string[0,128]', # (guess)
  617. },
  618. 200 => {
  619. Name => 'ObjectPreviewFileFormat',
  620. Groups => { 2 => 'Image' },
  621. Format => 'int16u',
  622. PrintConv => \%fileFormat,
  623. },
  624. 201 => {
  625. Name => 'ObjectPreviewFileVersion',
  626. Groups => { 2 => 'Image' },
  627. Format => 'int16u',
  628. },
  629. 202 => {
  630. Name => 'ObjectPreviewData',
  631. Groups => { 2 => 'Preview' },
  632. Format => 'undef[0,256000]',
  633. Binary => 1,
  634. },
  635. 221 => {
  636. Name => 'Prefs',
  637. Groups => { 2 => 'Image' },
  638. Format => 'string[0,64]',
  639. Notes => 'PhotoMechanic preferences',
  640. PrintConv => q{
  641. $val =~ s[\s*(\d+):\s*(\d+):\s*(\d+):\s*(\S*)]
  642. [Tagged:$1, ColorClass:$2, Rating:$3, FrameNum:$4];
  643. return $val;
  644. },
  645. PrintConvInv => q{
  646. $val =~ s[Tagged:\s*(\d+).*ColorClass:\s*(\d+).*Rating:\s*(\d+).*FrameNum:\s*(\S*)]
  647. [$1:$2:$3:$4]is;
  648. return $val;
  649. },
  650. },
  651. 225 => {
  652. Name => 'ClassifyState',
  653. Format => 'string[0,64]', # (guess)
  654. },
  655. 228 => {
  656. Name => 'SimilarityIndex',
  657. Format => 'string[0,32]', # (guess)
  658. },
  659. 230 => {
  660. Name => 'DocumentNotes',
  661. Format => 'string[0,1024]', # (guess)
  662. },
  663. 231 => {
  664. Name => 'DocumentHistory',
  665. Format => 'string[0,256]', # (guess)
  666. },
  667. 232 => {
  668. Name => 'ExifCameraInfo',
  669. Format => 'string[0,4096]', # (guess)
  670. },
  671. 255 => { #PH
  672. Name => 'CatalogSets',
  673. List => 1,
  674. Format => 'string[0,256]', # (guess)
  675. Notes => 'written by iView MediaPro',
  676. },
  677. );
  678. # Record 3 -- News photo
  679. %Image::ExifTool::IPTC::NewsPhoto = (
  680. GROUPS => { 2 => 'Image' },
  681. WRITE_PROC => \&WriteIPTC,
  682. CHECK_PROC => \&CheckIPTC,
  683. WRITABLE => 1,
  684. 0 => {
  685. Name => 'NewsPhotoVersion',
  686. Format => 'int16u',
  687. Mandatory => 1,
  688. },
  689. 10 => {
  690. Name => 'IPTCPictureNumber',
  691. Format => 'string[16]',
  692. Notes => '4 numbers: 1-Manufacturer ID, 2-Equipment ID, 3-Date, 4-Sequence',
  693. PrintConv => 'Image::ExifTool::IPTC::ConvertPictureNumber($val)',
  694. PrintConvInv => 'Image::ExifTool::IPTC::InvConvertPictureNumber($val)',
  695. },
  696. 20 => {
  697. Name => 'IPTCImageWidth',
  698. Format => 'int16u',
  699. },
  700. 30 => {
  701. Name => 'IPTCImageHeight',
  702. Format => 'int16u',
  703. },
  704. 40 => {
  705. Name => 'IPTCPixelWidth',
  706. Format => 'int16u',
  707. },
  708. 50 => {
  709. Name => 'IPTCPixelHeight',
  710. Format => 'int16u',
  711. },
  712. 55 => {
  713. Name => 'SupplementalType',
  714. Format => 'int8u',
  715. PrintConv => {
  716. 0 => 'Main Image',
  717. 1 => 'Reduced Resolution Image',
  718. 2 => 'Logo',
  719. 3 => 'Rasterized Caption',
  720. },
  721. },
  722. 60 => {
  723. Name => 'ColorRepresentation',
  724. Format => 'int16u',
  725. PrintHex => 1,
  726. PrintConv => {
  727. 0x000 => 'No Image, Single Frame',
  728. 0x100 => 'Monochrome, Single Frame',
  729. 0x300 => '3 Components, Single Frame',
  730. 0x301 => '3 Components, Frame Sequential in Multiple Objects',
  731. 0x302 => '3 Components, Frame Sequential in One Object',
  732. 0x303 => '3 Components, Line Sequential',
  733. 0x304 => '3 Components, Pixel Sequential',
  734. 0x305 => '3 Components, Special Interleaving',
  735. 0x400 => '4 Components, Single Frame',
  736. 0x401 => '4 Components, Frame Sequential in Multiple Objects',
  737. 0x402 => '4 Components, Frame Sequential in One Object',
  738. 0x403 => '4 Components, Line Sequential',
  739. 0x404 => '4 Components, Pixel Sequential',
  740. 0x405 => '4 Components, Special Interleaving',
  741. },
  742. },
  743. 64 => {
  744. Name => 'InterchangeColorSpace',
  745. Format => 'int8u',
  746. PrintConv => {
  747. 1 => 'X,Y,Z CIE',
  748. 2 => 'RGB SMPTE',
  749. 3 => 'Y,U,V (K) (D65)',
  750. 4 => 'RGB Device Dependent',
  751. 5 => 'CMY (K) Device Dependent',
  752. 6 => 'Lab (K) CIE',
  753. 7 => 'YCbCr',
  754. 8 => 'sRGB',
  755. },
  756. },
  757. 65 => {
  758. Name => 'ColorSequence',
  759. Format => 'int8u',
  760. },
  761. 66 => {
  762. Name => 'ICC_Profile',
  763. # ...could add SubDirectory support to read into this (if anybody cares)
  764. Writable => 0,
  765. Binary => 1,
  766. },
  767. 70 => {
  768. Name => 'ColorCalibrationMatrix',
  769. Writable => 0,
  770. Binary => 1,
  771. },
  772. 80 => {
  773. Name => 'LookupTable',
  774. Writable => 0,
  775. Binary => 1,
  776. },
  777. 84 => {
  778. Name => 'NumIndexEntries',
  779. Format => 'int16u',
  780. },
  781. 85 => {
  782. Name => 'ColorPalette',
  783. Writable => 0,
  784. Binary => 1,
  785. },
  786. 86 => {
  787. Name => 'IPTCBitsPerSample',
  788. Format => 'int8u',
  789. },
  790. 90 => {
  791. Name => 'SampleStructure',
  792. Format => 'int8u',
  793. PrintConv => {
  794. 0 => 'OrthogonalConstangSampling',
  795. 1 => 'Orthogonal4-2-2Sampling',
  796. 2 => 'CompressionDependent',
  797. },
  798. },
  799. 100 => {
  800. Name => 'ScanningDirection',
  801. Format => 'int8u',
  802. PrintConv => {
  803. 0 => 'L-R, Top-Bottom',
  804. 1 => 'R-L, Top-Bottom',
  805. 2 => 'L-R, Bottom-Top',
  806. 3 => 'R-L, Bottom-Top',
  807. 4 => 'Top-Bottom, L-R',
  808. 5 => 'Bottom-Top, L-R',
  809. 6 => 'Top-Bottom, R-L',
  810. 7 => 'Bottom-Top, R-L',
  811. },
  812. },
  813. 102 => {
  814. Name => 'IPTCImageRotation',
  815. Format => 'int8u',
  816. PrintConv => {
  817. 0 => 0,
  818. 1 => 90,
  819. 2 => 180,
  820. 3 => 270,
  821. },
  822. },
  823. 110 => {
  824. Name => 'DataCompressionMethod',
  825. Format => 'int32u',
  826. },
  827. 120 => {
  828. Name => 'QuantizationMethod',
  829. Format => 'int8u',
  830. PrintConv => {
  831. 0 => 'Linear Reflectance/Transmittance',
  832. 1 => 'Linear Density',
  833. 2 => 'IPTC Ref B',
  834. 3 => 'Linear Dot Percent',
  835. 4 => 'AP Domestic Analogue',
  836. 5 => 'Compression Method Specific',
  837. 6 => 'Color Space Specific',
  838. 7 => 'Gamma Compensated',
  839. },
  840. },
  841. 125 => {
  842. Name => 'EndPoints',
  843. Writable => 0,
  844. Binary => 1,
  845. },
  846. 130 => {
  847. Name => 'ExcursionTolerance',
  848. Format => 'int8u',
  849. PrintConv => {
  850. 0 => 'Not Allowed',
  851. 1 => 'Allowed',
  852. },
  853. },
  854. 135 => {
  855. Name => 'BitsPerComponent',
  856. Format => 'int8u',
  857. },
  858. 140 => {
  859. Name => 'MaximumDensityRange',
  860. Format => 'int16u',
  861. },
  862. 145 => {
  863. Name => 'GammaCompensatedValue',
  864. Format => 'int16u',
  865. },
  866. );
  867. # Record 7 -- Pre-object Data
  868. %Image::ExifTool::IPTC::PreObjectData = (
  869. # (not actually writable, but used in BuildTagLookup to recognize IPTC tables)
  870. WRITE_PROC => \&WriteIPTC,
  871. 10 => {
  872. Name => 'SizeMode',
  873. Format => 'int8u',
  874. PrintConv => {
  875. 0 => 'Size Not Known',
  876. 1 => 'Size Known',
  877. },
  878. },
  879. 20 => {
  880. Name => 'MaxSubfileSize',
  881. Format => 'int32u',
  882. },
  883. 90 => {
  884. Name => 'ObjectSizeAnnounced',
  885. Format => 'int32u',
  886. },
  887. 95 => {
  888. Name => 'MaximumObjectSize',
  889. Format => 'int32u',
  890. },
  891. );
  892. # Record 8 -- ObjectData
  893. %Image::ExifTool::IPTC::ObjectData = (
  894. WRITE_PROC => \&WriteIPTC,
  895. 10 => {
  896. Name => 'SubFile',
  897. Flags => 'List',
  898. Binary => 1,
  899. },
  900. );
  901. # Record 9 -- PostObjectData
  902. %Image::ExifTool::IPTC::PostObjectData = (
  903. WRITE_PROC => \&WriteIPTC,
  904. 10 => {
  905. Name => 'ConfirmedObjectSize',
  906. Format => 'int32u',
  907. },
  908. );
  909. # Record 240 -- FotoStation proprietary data (ref PH)
  910. %Image::ExifTool::IPTC::FotoStation = (
  911. GROUPS => { 2 => 'Other' },
  912. WRITE_PROC => \&WriteIPTC,
  913. CHECK_PROC => \&CheckIPTC,
  914. WRITABLE => 1,
  915. );
  916. # IPTC Composite tags
  917. %Image::ExifTool::IPTC::Composite = (
  918. GROUPS => { 2 => 'Image' },
  919. DateTimeCreated => {
  920. Description => 'Date/Time Created',
  921. Groups => { 2 => 'Time' },
  922. Require => {
  923. 0 => 'IPTC:DateCreated',
  924. 1 => 'IPTC:TimeCreated',
  925. },
  926. ValueConv => '"$val[0] $val[1]"',
  927. PrintConv => '$self->ConvertDateTime($val)',
  928. },
  929. DigitalCreationDateTime => {
  930. Description => 'Digital Creation Date/Time',
  931. Groups => { 2 => 'Time' },
  932. Require => {
  933. 0 => 'IPTC:DigitalCreationDate',
  934. 1 => 'IPTC:DigitalCreationTime',
  935. },
  936. ValueConv => '"$val[0] $val[1]"',
  937. PrintConv => '$self->ConvertDateTime($val)',
  938. },
  939. );
  940. # add our composite tags
  941. Image::ExifTool::AddCompositeTags('Image::ExifTool::IPTC');
  942. #------------------------------------------------------------------------------
  943. # AutoLoad our writer routines when necessary
  944. #
  945. sub AUTOLOAD
  946. {
  947. return Image::ExifTool::DoAutoLoad($AUTOLOAD, @_);
  948. }
  949. #------------------------------------------------------------------------------
  950. # Print conversion for CodedCharacterSet
  951. # Inputs: 0) value
  952. sub PrintCodedCharset($)
  953. {
  954. my $val = shift;
  955. return $iptcCharset{$val} if $iptcCharset{$val};
  956. $val =~ s/(.)/ $1/g;
  957. $val =~ s/ \x1b/, ESC/g;
  958. $val =~ s/^,? //;
  959. return $val;
  960. }
  961. #------------------------------------------------------------------------------
  962. # Handle CodedCharacterSet
  963. # Inputs: 0) ExifTool ref, 1) CodedCharacterSet value
  964. # Returns: IPTC character set if translation required (or 'bad' if unknown)
  965. sub HandleCodedCharset($$)
  966. {
  967. my ($et, $val) = @_;
  968. my $xlat = $iptcCharset{$val};
  969. unless ($xlat) {
  970. if ($val =~ /^\x1b\x25/) {
  971. # some unknown character set invoked
  972. $xlat = 'bad'; # flag unsupported coding
  973. } else {
  974. $xlat = $et->Options('CharsetIPTC');
  975. }
  976. }
  977. # no need to translate if Charset is the same
  978. undef $xlat if $xlat eq $et->Options('Charset');
  979. return $xlat;
  980. }
  981. #------------------------------------------------------------------------------
  982. # Encode or decode coded string
  983. # Inputs: 0) ExifTool ref, 1) value ptr, 2) IPTC charset (or 'bad') ref
  984. # 3) flag set to decode (read) value from IPTC
  985. # Updates value on return
  986. sub TranslateCodedString($$$$)
  987. {
  988. my ($et, $valPtr, $xlatPtr, $read) = @_;
  989. if ($$xlatPtr eq 'bad') {
  990. $et->Warn('Some IPTC characters not converted (unsupported CodedCharacterSet)');
  991. undef $$xlatPtr;
  992. } elsif (not $read) {
  993. $$valPtr = $et->Decode($$valPtr, undef, undef, $$xlatPtr);
  994. } elsif ($$valPtr !~ /[\x14\x15\x1b]/) {
  995. $$valPtr = $et->Decode($$valPtr, $$xlatPtr);
  996. } else {
  997. # don't yet support reading ISO 2022 shifted character sets
  998. $et->WarnOnce('Some IPTC characters not converted (ISO 2022 shifting not supported)');
  999. }
  1000. }
  1001. #------------------------------------------------------------------------------
  1002. # Is this IPTC in a standard location?
  1003. # Inputs: 0) Current metadata path string
  1004. # Returns: true if path is standard, 0 if file type doesn't have standard IPTC,
  1005. # or undef if IPTC is non-standard
  1006. sub IsStandardIPTC($)
  1007. {
  1008. my $path = shift;
  1009. return 1 if $isStandardIPTC{$path};
  1010. return 0 unless $path =~ /^(\w+)/ and defined $isStandardIPTC{$1};
  1011. return undef; # non-standard
  1012. }
  1013. #------------------------------------------------------------------------------
  1014. # get IPTC info
  1015. # Inputs: 0) ExifTool object reference, 1) dirInfo reference
  1016. # 2) reference to tag table
  1017. # Returns: 1 on success, 0 otherwise
  1018. sub ProcessIPTC($$$)
  1019. {
  1020. my ($et, $dirInfo, $tagTablePtr) = @_;
  1021. my $dataPt = $$dirInfo{DataPt};
  1022. my $pos = $$dirInfo{DirStart} || 0;
  1023. my $dirLen = $$dirInfo{DirLen} || 0;
  1024. my $dirEnd = $pos + $dirLen;
  1025. my $verbose = $et->Options('Verbose');
  1026. my $success = 0;
  1027. my ($lastRec, $recordPtr, $recordName);
  1028. $verbose and $dirInfo and $et->VerboseDir('IPTC', 0, $$dirInfo{DirLen});
  1029. if ($tagTablePtr eq \%Image::ExifTool::IPTC::Main) {
  1030. my $path = $et->MetadataPath();
  1031. my $isStd = IsStandardIPTC($path);
  1032. if (defined $isStd and not $$et{DIR_COUNT}{STD_IPTC}) {
  1033. # set flag to ensure we only have one family 1 "IPTC" group
  1034. $$et{DIR_COUNT}{STD_IPTC} = 1;
  1035. # calculate MD5 if Digest::MD5 is available (truly standard IPTC only)
  1036. if ($isStd) {
  1037. my $md5;
  1038. if (eval { require Digest::MD5 }) {
  1039. if ($pos or $dirLen != length($$dataPt)) {
  1040. $md5 = Digest::MD5::md5(substr $$dataPt, $pos, $dirLen);
  1041. } else {
  1042. $md5 = Digest::MD5::md5($$dataPt);
  1043. }
  1044. } else {
  1045. # a zero digest indicates IPTC exists but we don't have Digest::MD5
  1046. $md5 = "\0" x 16;
  1047. }
  1048. $et->FoundTag('CurrentIPTCDigest', $md5);
  1049. }
  1050. } elsif ($Image::ExifTool::MWG::strict and $$et{FILE_TYPE} =~ /^(JPEG|TIFF|PSD)$/) {
  1051. # ignore non-standard IPTC while in strict MWG compatibility mode
  1052. $et->Warn("Ignored non-standard IPTC at $path");
  1053. return 1;
  1054. } else {
  1055. # extract non-standard IPTC
  1056. my $count = ($$et{DIR_COUNT}{IPTC} || 0) + 1; # count non-standard IPTC
  1057. $$et{DIR_COUNT}{IPTC} = $count;
  1058. $$et{LOW_PRIORITY_DIR}{IPTC} = 1; # lower priority of non-standard IPTC
  1059. $$et{SET_GROUP1} = '+' . ($count + 1); # add number to family 1 group name
  1060. }
  1061. }
  1062. # begin by assuming default IPTC encoding
  1063. my $xlat = $et->Options('CharsetIPTC');
  1064. undef $xlat if $xlat eq $et->Options('Charset');
  1065. # quick check for improperly byte-swapped IPTC
  1066. if ($dirLen >= 4 and substr($$dataPt, $pos, 1) ne "\x1c" and
  1067. substr($$dataPt, $pos + 3, 1) eq "\x1c")
  1068. {
  1069. $et->Warn('IPTC data was improperly byte-swapped');
  1070. my $newData = pack('N*', unpack('V*', substr($$dataPt, $pos, $dirLen) . "\0\0\0"));
  1071. $dataPt = \$newData;
  1072. $pos = 0;
  1073. $dirEnd = $pos + $dirLen;
  1074. # NOTE: MUST NOT access $dirInfo DataPt, DirStart or DataLen after this!
  1075. }
  1076. # extract IPTC as a block if specified
  1077. if ($$et{REQ_TAG_LOOKUP}{iptc} or ($$et{TAGS_FROM_FILE} and
  1078. not $$et{EXCL_TAG_LOOKUP}{iptc}))
  1079. {
  1080. if ($pos or $dirLen != length($$dataPt)) {
  1081. $et->FoundTag('IPTC', substr($$dataPt, $pos, $dirLen));
  1082. } else {
  1083. $et->FoundTag('IPTC', $$dataPt);
  1084. }
  1085. }
  1086. while ($pos + 5 <= $dirEnd) {
  1087. my $buff = substr($$dataPt, $pos, 5);
  1088. my ($id, $rec, $tag, $len) = unpack("CCCn", $buff);
  1089. unless ($id == 0x1c) {
  1090. unless ($id) {
  1091. # scan the rest of the data an give warning unless all zeros
  1092. # (iMatch pads the IPTC block with nulls for some reason)
  1093. my $remaining = substr($$dataPt, $pos, $dirEnd - $pos);
  1094. last unless $remaining =~ /[^\0]/;
  1095. }
  1096. $et->Warn(sprintf('Bad IPTC data tag (marker 0x%x)',$id));
  1097. last;
  1098. }
  1099. $pos += 5; # step to after field header
  1100. # handle extended IPTC entry if necessary
  1101. if ($len & 0x8000) {
  1102. my $n = $len & 0x7fff; # get num bytes in length field
  1103. if ($pos + $n > $dirEnd or $n > 8) {
  1104. $et->VPrint(0, "Invalid extended IPTC entry (dataset $rec:$tag, len $len)\n");
  1105. $success = 0;
  1106. last;
  1107. }
  1108. # determine length (a big-endian, variable sized int)
  1109. for ($len = 0; $n; ++$pos, --$n) {
  1110. $len = $len * 256 + ord(substr($$dataPt, $pos, 1));
  1111. }
  1112. }
  1113. if ($pos + $len > $dirEnd) {
  1114. $et->VPrint(0, "Invalid IPTC entry (dataset $rec:$tag, len $len)\n");
  1115. $success = 0;
  1116. last;
  1117. }
  1118. if (not defined $lastRec or $lastRec != $rec) {
  1119. my $tableInfo = $tagTablePtr->{$rec};
  1120. unless ($tableInfo) {
  1121. $et->WarnOnce("Unrecognized IPTC record $rec (ignored)");
  1122. $pos += $len;
  1123. next; # ignore this entry
  1124. }
  1125. my $tableName = $tableInfo->{SubDirectory}->{TagTable};
  1126. unless ($tableName) {
  1127. $et->Warn("No table for IPTC record $rec!");
  1128. last; # this shouldn't happen
  1129. }
  1130. $recordName = $$tableInfo{Name};
  1131. $recordPtr = Image::ExifTool::GetTagTable($tableName);
  1132. $et->VPrint(0,$$et{INDENT},"-- $recordName record --\n");
  1133. $lastRec = $rec;
  1134. }
  1135. my $val = substr($$dataPt, $pos, $len);
  1136. # add tagInfo for all unknown tags:
  1137. unless ($$recordPtr{$tag}) {
  1138. # - no Format so format is auto-detected
  1139. # - no Name so name is generated automatically with decimal tag number
  1140. AddTagToTable($recordPtr, $tag, { Unknown => 1 });
  1141. }
  1142. my $tagInfo = $et->GetTagInfo($recordPtr, $tag);
  1143. my $format;
  1144. # (could use $$recordPtr{FORMAT} if no Format below, but don't do this to
  1145. # be backward compatible with improperly written PhotoMechanic tags)
  1146. $format = $$tagInfo{Format} if $tagInfo;
  1147. # use logic to determine format if not specified
  1148. unless ($format) {
  1149. $format = 'int' if $len <= 4 and $len != 3 and $val =~ /[\0-\x08]/;
  1150. }
  1151. if ($format) {
  1152. if ($format =~ /^int/) {
  1153. if ($len <= 8) { # limit integer conversion to 8 bytes long
  1154. $val = 0;
  1155. my $i;
  1156. for ($i=0; $i<$len; ++$i) {
  1157. $val = $val * 256 + ord(substr($$dataPt, $pos+$i, 1));
  1158. }
  1159. }
  1160. } elsif ($format =~ /^string/) {
  1161. $val =~ s/\0+$//; # some braindead softwares add null terminators
  1162. if ($rec == 1) {
  1163. # handle CodedCharacterSet tag
  1164. $xlat = HandleCodedCharset($et, $val) if $tag == 90;
  1165. # translate characters if necessary and special characters exist
  1166. } elsif ($xlat and $rec < 7 and $val =~ /[\x80-\xff]/) {
  1167. # translate to specified character set
  1168. TranslateCodedString($et, \$val, \$xlat, 1);
  1169. }
  1170. } elsif ($format =~ /^digits/) {
  1171. $val =~ s/\0+$//;
  1172. } elsif ($format !~ /^undef/) {
  1173. warn("Invalid IPTC format: $format");
  1174. }
  1175. }
  1176. $verbose and $et->VerboseInfo($tag, $tagInfo,
  1177. Table => $tagTablePtr,
  1178. Value => $val,
  1179. DataPt => $dataPt,
  1180. DataPos => $$dirInfo{DataPos},
  1181. Size => $len,
  1182. Start => $pos,
  1183. Extra => ", $recordName record",
  1184. Format => $format,
  1185. );
  1186. $et->FoundTag($tagInfo, $val) if $tagInfo;
  1187. $success = 1;
  1188. $pos += $len; # increment to next field
  1189. }
  1190. delete $$et{SET_GROUP1};
  1191. delete $$et{LOW_PRIORITY_DIR}{IPTC};
  1192. return $success;
  1193. }
  1194. 1; # end
  1195. __END__
  1196. =head1 NAME
  1197. Image::ExifTool::IPTC - Read IPTC meta information
  1198. =head1 SYNOPSIS
  1199. This module is loaded automatically by Image::ExifTool when required.
  1200. =head1 DESCRIPTION
  1201. This module contains definitions required by Image::ExifTool to interpret
  1202. IPTC (International Press Telecommunications Council) meta information in
  1203. image files.
  1204. =head1 AUTHOR
  1205. Copyright 2003-2016, Phil Harvey (phil at owl.phy.queensu.ca)
  1206. This library is free software; you can redistribute it and/or modify it
  1207. under the same terms as Perl itself.
  1208. =head1 REFERENCES
  1209. =over 4
  1210. =item L<http://www.iptc.org/IIM/>
  1211. =back
  1212. =head1 SEE ALSO
  1213. L<Image::ExifTool::TagNames/IPTC Tags>,
  1214. L<Image::ExifTool(3pm)|Image::ExifTool>
  1215. =cut