PageRenderTime 67ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 1ms

/add-ons/pjmt/Photoshop_File_Info.php

https://github.com/jcplat/console-seolan
PHP | 2498 lines | 1215 code | 514 blank | 769 comment | 221 complexity | 97e084ed80b56ce2e576afed3824bafe MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-2.1, GPL-3.0, Apache-2.0, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /******************************************************************************
  3. *
  4. * Filename: Photoshop_File_Info.php
  5. *
  6. * Description: Provides functions that mimic the way Photoshop reads and writes
  7. * metadata in it's 'File Info' dialog
  8. *
  9. * Author: Evan Hunter
  10. *
  11. * Date: 11/11/2004
  12. *
  13. * Project: JPEG Metadata
  14. *
  15. * Revision: 1.11
  16. * Changes: 1.10 -> 1.11 : Changed displayed toolkit version numbers to reference Toolkit_Version.php
  17. *
  18. * URL: http://electronics.ozhiker.com
  19. *
  20. * License: This file is part of the PHP JPEG Metadata Toolkit.
  21. *
  22. * The PHP JPEG Metadata Toolkit is free software; you can
  23. * redistribute it and/or modify it under the terms of the
  24. * GNU General Public License as published by the Free Software
  25. * Foundation; either version 2 of the License, or (at your
  26. * option) any later version.
  27. *
  28. * The PHP JPEG Metadata Toolkit is distributed in the hope
  29. * that it will be useful, but WITHOUT ANY WARRANTY; without
  30. * even the implied warranty of MERCHANTABILITY or FITNESS
  31. * FOR A PARTICULAR PURPOSE. See the GNU General Public License
  32. * for more details.
  33. *
  34. * You should have received a copy of the GNU General Public
  35. * License along with the PHP JPEG Metadata Toolkit; if not,
  36. * write to the Free Software Foundation, Inc., 59 Temple
  37. * Place, Suite 330, Boston, MA 02111-1307 USA
  38. *
  39. * If you require a different license for commercial or other
  40. * purposes, please contact the author: evan@ozhiker.com
  41. *
  42. ******************************************************************************/
  43. // TODO: XMP sections: XAPMM, TIFF, EXIF
  44. include 'Toolkit_Version.php'; // Change: added as of version 1.11
  45. /******************************************************************************
  46. * Global Variable: Software Name
  47. *
  48. * Contents: The string that is appended to fields which store the name of
  49. * the software editor.
  50. *
  51. ******************************************************************************/
  52. $GLOBALS[ "Software Name" ] = "(PHP JPEG Metadata Toolkit v" . $GLOBALS['Toolkit_Version'] . ")"; // Change: Changed version numbers to reference Toolkit_Version.php - as of version 1.11
  53. /******************************************************************************
  54. * End of Global Variable: Software Name
  55. ******************************************************************************/
  56. /******************************************************************************
  57. *
  58. * Function: get_photoshop_file_info
  59. *
  60. * Description: Retrieves Photoshop 'File Info' metadata in the same way that Photoshop
  61. * does. The results are returned in an array as below:
  62. *
  63. * $file_info_array = array(
  64. * "title" => "",
  65. * "author" => "",
  66. * "authorsposition" => "", // Note: Not used in Photoshop 7 or higher
  67. * "caption" => "",
  68. * "captionwriter" => "",
  69. * "jobname" => "", // Note: Not used in Photoshop CS
  70. * "copyrightstatus" => "",
  71. * "copyrightnotice" => "",
  72. * "ownerurl" => "",
  73. * "keywords" => array( 0 => "", 1 => "", ... ),
  74. * "category" => "", // Note: Max 3 characters
  75. * "supplementalcategories" => array( 0 => "", 1 => "", ... ),
  76. * "date" => "", // Note: DATE MUST BE IN YYYY-MM-DD format
  77. * "city" => "",
  78. * "state" => "",
  79. * "country" => "",
  80. * "credit" => "",
  81. * "source" => "",
  82. * "headline" => "",
  83. * "instructions" => "",
  84. * "transmissionreference" => "",
  85. * "urgency" => "" );
  86. *
  87. * Parameters: Exif_array - an array containing the EXIF information to be
  88. * searched, as retrieved by get_EXIF_JPEG. (saves having to parse the EXIF again)
  89. * XMP_array - an array containing the XMP information to be
  90. * searched, as retrieved by read_XMP_array_from_text. (saves having to parse the XMP again)
  91. * IRB_array - an array containing the Photoshop IRB information
  92. * to be searched, as retrieved by get_Photoshop_IRB. (saves having to parse the IRB again)
  93. *
  94. * Returns: outputarray - an array as above, containing the Photoshop File Info data
  95. *
  96. ******************************************************************************/
  97. function get_photoshop_file_info( $Exif_array, $XMP_array, $IRB_array )
  98. {
  99. // Create a blank array to receive the output
  100. $outputarray = array(
  101. "title" => "",
  102. "author" => "",
  103. "authorsposition" => "",
  104. "caption" => "",
  105. "captionwriter" => "",
  106. "jobname" => "",
  107. "copyrightstatus" => "",
  108. "copyrightnotice" => "",
  109. "ownerurl" => "",
  110. "keywords" => array(),
  111. "category" => "",
  112. "supplementalcategories" => array(),
  113. "date" => "",
  114. "city" => "",
  115. "state" => "",
  116. "country" => "",
  117. "credit" => "",
  118. "source" => "",
  119. "headline" => "",
  120. "instructions" => "",
  121. "transmissionreference" => "",
  122. "urgency" => "" );
  123. /***************************************/
  124. // XMP Processing
  125. // Retrieve the dublin core section from the XMP header
  126. // Extract the Dublin Core section from the XMP
  127. $dublincore_block = find_XMP_block( $XMP_array, "dc" );
  128. // Check that the Dublin Core section exists
  129. if ( $dublincore_block != FALSE )
  130. {
  131. // Dublin Core Description Field contains caption
  132. // Extract Description
  133. $Item = find_XMP_item( $dublincore_block, "dc:description" );
  134. // Check if Description Tag existed
  135. if ( $Item != FALSE )
  136. {
  137. // Ensure that the Description value exists and save it.
  138. if ( ( array_key_exists( 'children', $Item ) ) &&
  139. ( $Item['children'][0]['tag'] == "rdf:Alt" ) &&
  140. ( array_key_exists( 'value', $Item['children'][0]['children'][0] ) ) )
  141. {
  142. $outputarray = add_to_field( $outputarray, 'caption' , HTML_UTF8_Escape( $Item['children'][0]['children'][0]['value'] ), "\n" );
  143. }
  144. }
  145. /***************************************/
  146. // Dublin Core Creator Field contains author
  147. // Extract Description
  148. $Item = find_XMP_item( $dublincore_block, "dc:creator" );
  149. // Check if Creator Tag existed
  150. if ( $Item != FALSE )
  151. {
  152. // Ensure that the Creator value exists and save it.
  153. if ( ( array_key_exists( 'children', $Item ) ) &&
  154. ( $Item['children'][0]['tag'] =="rdf:Seq" ) &&
  155. ( array_key_exists( 'value', $Item['children'][0]['children'][0] ) ) )
  156. {
  157. $outputarray = add_to_field( $outputarray, 'author' , HTML_UTF8_Escape( $Item['children'][0]['children'][0]['value'] ), "\n" );
  158. }
  159. }
  160. /***************************************/
  161. // Dublin Core Title Field contains title
  162. // Extract Title
  163. $Item = find_XMP_item( $dublincore_block, "dc:title" );
  164. // Check if Title Tag existed
  165. if ( $Item != FALSE )
  166. {
  167. // Ensure that the Title value exists and save it.
  168. if ( ( array_key_exists( 'children', $Item ) ) &&
  169. ( $Item['children'][0]['tag'] =="rdf:Alt" ) &&
  170. ( array_key_exists( 'value', $Item['children'][0]['children'][0] ) ) )
  171. {
  172. $outputarray = add_to_field( $outputarray, 'title' , HTML_UTF8_Escape( $Item['children'][0]['children'][0]['value'] ), "," );
  173. }
  174. }
  175. /***************************************/
  176. // Dublin Core Rights Field contains copyrightnotice
  177. // Extract Rights
  178. $Item = find_XMP_item( $dublincore_block, "dc:rights" );
  179. // Check if Rights Tag existed
  180. if ( $Item != FALSE )
  181. {
  182. // Ensure that the Rights value exists and save it.
  183. if ( ( array_key_exists( 'children', $Item ) ) &&
  184. ( $Item['children'][0]['tag'] =="rdf:Alt" ) &&
  185. ( array_key_exists( 'value', $Item['children'][0]['children'][0] ) ) )
  186. {
  187. $outputarray = add_to_field( $outputarray, 'copyrightnotice' , HTML_UTF8_Escape( $Item['children'][0]['children'][0]['value'] ), "," );
  188. }
  189. }
  190. /***************************************/
  191. // Dublin Core Subject Field contains keywords
  192. // Extract Subject
  193. $Item = find_XMP_item( $dublincore_block, "dc:subject" );
  194. // Check if Subject Tag existed
  195. if ( $Item != FALSE )
  196. {
  197. // Ensure that the Subject values exist
  198. if ( ( array_key_exists( 'children', $Item ) ) && ( $Item['children'][0]['tag'] =="rdf:Bag" ) )
  199. {
  200. // Cycle through each Subject value and save them
  201. foreach ( $Item['children'][0]['children'] as $keywords )
  202. {
  203. if ( ! in_array ( HTML_UTF8_Escape( $keywords['value'] ), $outputarray['keywords']))
  204. {
  205. if ( array_key_exists( 'value', $keywords ) )
  206. {
  207. $outputarray['keywords'][] = HTML_UTF8_Escape( $keywords['value'] );
  208. }
  209. }
  210. }
  211. }
  212. }
  213. }
  214. /***************************************/
  215. // Find the Photoshop Information within the XMP block
  216. $photoshop_block = find_XMP_block( $XMP_array, "photoshop" );
  217. // Check that the Photoshop Information exists
  218. if ( $photoshop_block != FALSE )
  219. {
  220. // The Photoshop CaptionWriter tag contains captionwriter - Find it
  221. $Item = find_XMP_item( $photoshop_block, "photoshop:CaptionWriter" );
  222. // Check that the CaptionWriter Field exists and save the value
  223. if ( ( $Item != FALSE ) && ( array_key_exists( 'value', $Item ) ) )
  224. {
  225. $outputarray = add_to_field( $outputarray, 'captionwriter' , HTML_UTF8_Escape( $Item['value'] ), "," );
  226. }
  227. /***************************************/
  228. // The Photoshop Headline tag contains headline - Find it
  229. $Item = find_XMP_item( $photoshop_block, "photoshop:Headline" );
  230. // Check that the Headline Field exists and save the value
  231. if ( ( $Item != FALSE ) && ( array_key_exists( 'value', $Item ) ) )
  232. {
  233. $outputarray = add_to_field( $outputarray, 'headline' , HTML_UTF8_Escape( $Item['value'] ), "," );
  234. }
  235. /***************************************/
  236. // The Photoshop Instructions tag contains instructions - Find it
  237. $Item = find_XMP_item( $photoshop_block, "photoshop:Instructions" );
  238. // Check that the Instructions Field exists and save the value
  239. if ( ( $Item != FALSE ) && ( array_key_exists( 'value', $Item ) ) )
  240. {
  241. $outputarray = add_to_field( $outputarray, 'instructions' , HTML_UTF8_Escape( $Item['value'] ), "\n" );
  242. }
  243. /***************************************/
  244. // The Photoshop AuthorsPosition tag contains authorsposition - Find it
  245. $Item = find_XMP_item( $photoshop_block, "photoshop:AuthorsPosition" );
  246. // Check that the AuthorsPosition Field exists and save the value
  247. if ( ( $Item != FALSE ) && ( array_key_exists( 'value', $Item ) ) )
  248. {
  249. $outputarray = add_to_field( $outputarray, 'authorsposition' , HTML_UTF8_Escape( $Item['value'] ), "," );
  250. }
  251. /***************************************/
  252. // The Photoshop Credit tag contains credit - Find it
  253. $Item = find_XMP_item( $photoshop_block, "photoshop:Credit" );
  254. // Check that the Credit Field exists and save the value
  255. if ( ( $Item != FALSE ) && ( array_key_exists( 'value', $Item ) ) )
  256. {
  257. $outputarray = add_to_field( $outputarray, 'credit' , HTML_UTF8_Escape( $Item['value'] ), "," );
  258. }
  259. /***************************************/
  260. // The Photoshop Source tag contains source - Find it
  261. $Item = find_XMP_item( $photoshop_block, "photoshop:Source" );
  262. // Check that the Credit Field exists and save the value
  263. if ( ( $Item != FALSE ) && ( array_key_exists( 'value', $Item ) ) )
  264. {
  265. $outputarray = add_to_field( $outputarray, 'source' , HTML_UTF8_Escape( $Item['value'] ), "," );
  266. }
  267. /***************************************/
  268. // The Photoshop City tag contains city - Find it
  269. $Item = find_XMP_item( $photoshop_block, "photoshop:City" );
  270. // Check that the City Field exists and save the value
  271. if ( ( $Item != FALSE ) && ( array_key_exists( 'value', $Item ) ) )
  272. {
  273. $outputarray = add_to_field( $outputarray, 'city' , HTML_UTF8_Escape( $Item['value'] ), "," );
  274. }
  275. /***************************************/
  276. // The Photoshop State tag contains state - Find it
  277. $Item = find_XMP_item( $photoshop_block, "photoshop:State" );
  278. // Check that the State Field exists and save the value
  279. if ( ( $Item != FALSE ) && ( array_key_exists( 'value', $Item ) ) )
  280. {
  281. $outputarray = add_to_field( $outputarray, 'state' , HTML_UTF8_Escape( $Item['value'] ), "," );
  282. }
  283. /***************************************/
  284. // The Photoshop Country tag contains country - Find it
  285. $Item = find_XMP_item( $photoshop_block, "photoshop:Country" );
  286. // Check that the Country Field exists and save the value
  287. if ( ( $Item != FALSE ) && ( array_key_exists( 'value', $Item ) ) )
  288. {
  289. $outputarray = add_to_field( $outputarray, 'country' , HTML_UTF8_Escape( $Item['value'] ), "," );
  290. }
  291. /***************************************/
  292. // The Photoshop TransmissionReference tag contains transmissionreference - Find it
  293. $Item = find_XMP_item( $photoshop_block, "photoshop:TransmissionReference" );
  294. // Check that the TransmissionReference Field exists and save the value
  295. if ( ( $Item != FALSE ) && ( array_key_exists( 'value', $Item ) ) )
  296. {
  297. $outputarray = add_to_field( $outputarray, 'transmissionreference' , HTML_UTF8_Escape( $Item['value'] ), "," );
  298. }
  299. /***************************************/
  300. // The Photoshop Category tag contains category - Find it
  301. $Item = find_XMP_item( $photoshop_block, "photoshop:Category" );
  302. // Check that the TransmissionReference Field exists and save the value
  303. if ( ( $Item != FALSE ) && ( array_key_exists( 'value', $Item ) ) )
  304. {
  305. $outputarray = add_to_field( $outputarray, 'category' , HTML_UTF8_Escape( $Item['value'] ), "," );
  306. }
  307. /***************************************/
  308. // The Photoshop DateCreated tag contains date - Find it
  309. $Item = find_XMP_item( $photoshop_block, "photoshop:DateCreated" );
  310. // Check that the DateCreated Field exists and save the value
  311. if ( ( $Item != FALSE ) && ( array_key_exists( 'value', $Item ) ) )
  312. {
  313. $outputarray = add_to_field( $outputarray, 'date' , HTML_UTF8_Escape( $Item['value'] ), "," );
  314. }
  315. /***************************************/
  316. // The Photoshop Urgency tag contains urgency - Find it
  317. $Item = find_XMP_item( $photoshop_block, "photoshop:Urgency" );
  318. // Check that the Urgency Field exists and save the value
  319. if ( ( $Item != FALSE ) && ( array_key_exists( 'value', $Item ) ) )
  320. {
  321. $outputarray = add_to_field( $outputarray, 'urgency' , HTML_UTF8_Escape( $Item['value'] ), "," );
  322. }
  323. /***************************************/
  324. // The Photoshop SupplementalCategories tag contains supplementalcategories - Find it
  325. $Item = find_XMP_item( $photoshop_block, "photoshop:SupplementalCategories" );
  326. // Check that the SupplementalCategories Field exists
  327. if ( $Item != FALSE )
  328. {
  329. // Check that the values exist
  330. if ( ( array_key_exists( 'children', $Item ) ) && ( $Item['children'][0]['tag'] =="rdf:Bag" ) )
  331. {
  332. // Cycle through the values and save them
  333. foreach ( $Item['children'][0]['children'] as $sup_category )
  334. {
  335. if ( ( array_key_exists( 'value', $sup_category ) ) &&
  336. ( ! in_array ( HTML_UTF8_Escape( $sup_category['value'] ), $outputarray['supplementalcategories'])) )
  337. {
  338. if ( array_key_exists( 'value', $sup_category ) )
  339. {
  340. $outputarray['supplementalcategories'][] = HTML_UTF8_Escape( $sup_category['value'] );
  341. }
  342. }
  343. }
  344. }
  345. }
  346. }
  347. /***************************************/
  348. // Find the Job Reference Information within the XMP block
  349. $job_block = find_XMP_block( $XMP_array, "xapBJ" );
  350. // Check that the Job Reference Information exists
  351. if ( $job_block != FALSE )
  352. {
  353. // The JobRef Field contains jobname - Find it
  354. $Item = find_XMP_item( $job_block, "xapBJ:JobRef" );
  355. // Check that the JobRef Field exists
  356. if ( $Item != FALSE )
  357. {
  358. // Check that the value exists and save it
  359. if ( ( array_key_exists( 'children', $Item ) ) &&
  360. ( $Item['children'][0]['tag'] =="rdf:Bag" ) &&
  361. ( array_key_exists( 'children', $Item['children'][0] ) ) &&
  362. ( $Item['children'][0]['children'][0]['tag'] =="rdf:li" ) &&
  363. ( array_key_exists( 'children', $Item['children'][0]['children'][0] ) ) &&
  364. ( $Item['children'][0]['children'][0]['children'][0]['tag'] =="stJob:name" ) &&
  365. ( array_key_exists( 'value', $Item['children'][0]['children'][0]['children'][0] ) ) )
  366. {
  367. $outputarray = add_to_field( $outputarray, 'jobname' , HTML_UTF8_Escape( $Item['children'][0]['children'][0]['children'][0]['value'] ), "," );
  368. }
  369. }
  370. }
  371. /***************************************/
  372. // Find the Rights Information within the XMP block
  373. $rights_block = find_XMP_block( $XMP_array, "xapRights" );
  374. // Check that the Rights Information exists
  375. if ( $rights_block != FALSE )
  376. {
  377. // The WebStatement Field contains ownerurl - Find it
  378. $Item = find_XMP_item( $rights_block, "xapRights:WebStatement" );
  379. // Check that the WebStatement Field exists and save the value
  380. if ( ( $Item != FALSE ) && ( array_key_exists( 'value', $Item ) ) )
  381. {
  382. $outputarray = add_to_field( $outputarray, 'ownerurl' , HTML_UTF8_Escape( $Item['value'] ), "\n" );
  383. }
  384. /***************************************/
  385. // The Marked Field contains copyrightstatus - Find it
  386. $Item = find_XMP_item( $rights_block, "xapRights:Marked" );
  387. // Check that the Marked Field exists and save the value
  388. if ( ( $Item != FALSE ) && ( array_key_exists( 'value', $Item ) ) )
  389. {
  390. if ( $Item['value'] == "True" )
  391. {
  392. $outputarray = add_to_field( $outputarray, 'copyrightstatus' , "Copyrighted Work", "," );
  393. }
  394. else
  395. {
  396. $outputarray = add_to_field( $outputarray, 'copyrightstatus' , "Public Domain", "," );
  397. }
  398. }
  399. }
  400. /***************************************/
  401. // Photoshop IRB Processing
  402. // Check that the Photoshop IRB exists
  403. if ( $IRB_array != FALSE )
  404. {
  405. // Create a translation table to convert carriage returns to linefeeds
  406. $irbtrans = array("\x0d" => "\x0a");
  407. // The Photoshop IRB Copyright flag (0x040A) contains copyrightstatus - find it
  408. $IRB_copyright_flag = find_Photoshop_IRB_Resource( $IRB_array, 0x040A );
  409. // Check if the Copyright flag Field exists, and save the value
  410. if( $IRB_copyright_flag != FALSE )
  411. {
  412. // Check the value of the copyright flag
  413. if ( hexdec( bin2hex( $IRB_copyright_flag['ResData'] ) ) == 1 )
  414. {
  415. // Save the value
  416. $outputarray = add_to_field( $outputarray, 'copyrightstatus' , "Copyrighted Work", "," );
  417. }
  418. else
  419. {
  420. // Do nothing - copyrightstatus will be set to unmarked if still blank at end
  421. }
  422. }
  423. /***************************************/
  424. // The Photoshop IRB URL (0x040B) contains ownerurl - find it
  425. $IRB_url = find_Photoshop_IRB_Resource( $IRB_array, 0x040B );
  426. // Check if the URL Field exists and save the value
  427. if( $IRB_url != FALSE )
  428. {
  429. $outputarray = add_to_field( $outputarray, 'ownerurl' , strtr( $IRB_url['ResData'], $irbtrans ), "\n" );
  430. }
  431. /***************************************/
  432. // Extract any IPTC block from the Photoshop IRB information
  433. $IPTC_array = get_Photoshop_IPTC( $IRB_array );
  434. // Check if the IPTC block exits
  435. if ( ( $IPTC_array != FALSE ) && ( count( $IPTC_array ) != 0 ) )
  436. {
  437. // The IPTC Caption/Abstract Field contains caption - find it
  438. $record = find_IPTC_Resource( $IPTC_array, "2:120" );
  439. // Check if the Caption/Abstract Field exists and save the value
  440. if ( $record != FALSE )
  441. {
  442. $outputarray = add_to_field( $outputarray, 'caption' , strtr( $record['RecData'], $irbtrans ), "\n" );
  443. }
  444. /***************************************/
  445. // The IPTC Caption Writer/Editor Field contains captionwriter - find it
  446. $record = find_IPTC_Resource( $IPTC_array, "2:122" );
  447. // Check if the Caption Writer/Editor Field exists and save the value
  448. if ( $record != FALSE )
  449. {
  450. $outputarray = add_to_field( $outputarray, 'captionwriter' , strtr( $record['RecData'], $irbtrans ), "\n" );
  451. }
  452. /***************************************/
  453. // The IPTC Headline Field contains headline - find it
  454. $record = find_IPTC_Resource( $IPTC_array, "2:105" );
  455. // Check if the Headline Field exists and save the value
  456. if ( $record != FALSE )
  457. {
  458. $outputarray = add_to_field( $outputarray, 'headline' , strtr( $record['RecData'], $irbtrans ), "\n" );
  459. }
  460. /***************************************/
  461. // The IPTC Special Instructions Field contains instructions - find it
  462. $record = find_IPTC_Resource( $IPTC_array, "2:40" );
  463. // Check if the Special Instructions Field exists and save the value
  464. if ( $record != FALSE )
  465. {
  466. $outputarray = add_to_field( $outputarray, 'instructions' , strtr( $record['RecData'], $irbtrans ), "\n" );
  467. }
  468. /***************************************/
  469. // The IPTC By-Line Field contains author - find it
  470. $record = find_IPTC_Resource( $IPTC_array, "2:80" );
  471. // Check if the By-Line Field exists and save the value
  472. if ( $record != FALSE )
  473. {
  474. $outputarray = add_to_field( $outputarray, 'author' , strtr( $record['RecData'], $irbtrans ), "\n" );
  475. }
  476. /***************************************/
  477. // The IPTC By-Line Title Field contains authorsposition - find it
  478. $record = find_IPTC_Resource( $IPTC_array, "2:85" );
  479. // Check if the By-Line Title Field exists and save the value
  480. if ( $record != FALSE )
  481. {
  482. $outputarray = add_to_field( $outputarray, 'authorsposition' , strtr( $record['RecData'], $irbtrans ), "\n" );
  483. }
  484. /***************************************/
  485. // The IPTC Credit Field contains credit - find it
  486. $record = find_IPTC_Resource( $IPTC_array, "2:110" );
  487. // Check if the Credit Field exists and save the value
  488. if ( $record != FALSE )
  489. {
  490. $outputarray = add_to_field( $outputarray, 'credit' , strtr( $record['RecData'], $irbtrans ), "\n" );
  491. }
  492. /***************************************/
  493. // The IPTC Source Field contains source - find it
  494. $record = find_IPTC_Resource( $IPTC_array, "2:115" );
  495. // Check if the Source Field exists and save the value
  496. if ( $record != FALSE )
  497. {
  498. $outputarray = add_to_field( $outputarray, 'source' , strtr( $record['RecData'], $irbtrans ), "\n" );
  499. }
  500. /***************************************/
  501. // The IPTC Object Name Field contains title - find it
  502. $record = find_IPTC_Resource( $IPTC_array, "2:05" );
  503. // Check if the Object Name Field exists and save the value
  504. if ( $record != FALSE )
  505. {
  506. $outputarray = add_to_field( $outputarray, 'title' , strtr( $record['RecData'], $irbtrans ), "\n" );
  507. }
  508. /***************************************/
  509. // The IPTC Date Created Field contains date - find it
  510. $record = find_IPTC_Resource( $IPTC_array, "2:55" );
  511. // Check if the Date Created Field exists and save the value
  512. if ( $record != FALSE )
  513. {
  514. $date_array = unpack( "a4Year/a2Month/A2Day", $record['RecData'] );
  515. $tmpdate = $date_array['Year'] . "-" . $date_array['Month'] . "-" . $date_array['Day'];
  516. $outputarray = add_to_field( $outputarray, 'date' , strtr( $tmpdate, $irbtrans ), "," );
  517. }
  518. /***************************************/
  519. // The IPTC City Field contains city - find it
  520. $record = find_IPTC_Resource( $IPTC_array, "2:90" );
  521. // Check if the City Field exists and save the value
  522. if ( $record != FALSE )
  523. {
  524. $outputarray = add_to_field( $outputarray, 'city' , strtr( $record['RecData'], $irbtrans ), "\n" );
  525. }
  526. /***************************************/
  527. // The IPTC Province/State Field contains state - find it
  528. $record = find_IPTC_Resource( $IPTC_array, "2:95" );
  529. // Check if the Province/State Field exists and save the value
  530. if ( $record != FALSE )
  531. {
  532. $outputarray = add_to_field( $outputarray, 'state' , strtr( $record['RecData'], $irbtrans ), "\n" );
  533. }
  534. /***************************************/
  535. // The IPTC Country/Primary Location Name Field contains country - find it
  536. $record = find_IPTC_Resource( $IPTC_array, "2:101" );
  537. // Check if the Country/Primary Location Name Field exists and save the value
  538. if ( $record != FALSE )
  539. {
  540. $outputarray = add_to_field( $outputarray, 'country' , strtr( $record['RecData'], $irbtrans ), "\n" );
  541. }
  542. /***************************************/
  543. // The IPTC Original Transmission Reference Field contains transmissionreference - find it
  544. $record = find_IPTC_Resource( $IPTC_array, "2:103" );
  545. // Check if the Original Transmission Reference Field exists and save the value
  546. if ( $record != FALSE )
  547. {
  548. $outputarray = add_to_field( $outputarray, 'transmissionreference' , strtr( $record['RecData'], $irbtrans ), "\n" );
  549. }
  550. /***************************************/
  551. // The IPTC Category Field contains category - find it
  552. $record = find_IPTC_Resource( $IPTC_array, "2:15" );
  553. // Check if the Category Field exists and save the value
  554. if ( $record != FALSE )
  555. {
  556. $outputarray = add_to_field( $outputarray, 'category' , strtr( $record['RecData'], $irbtrans ), "\n" );
  557. }
  558. /***************************************/
  559. // Cycle through the IPTC records looking for Supplemental Category records
  560. foreach ($IPTC_array as $record)
  561. {
  562. // Check if a Supplemental Category record has been found
  563. if ( $record['IPTC_Type'] == "2:20" )
  564. {
  565. // A Supplemental Category record has been found, save it's value if the value doesn't already exist
  566. if ( ! in_array ( $record['RecData'], $outputarray['supplementalcategories']))
  567. {
  568. $outputarray['supplementalcategories'][] = strtr( $record['RecData'], array("\x0a" => "", "\x0d" => "&#xA;") ) ;
  569. }
  570. }
  571. }
  572. /***************************************/
  573. // The IPTC Urgency Field contains urgency - find it
  574. $record = find_IPTC_Resource( $IPTC_array, "2:10" );
  575. // Check if the Urgency Field exists and save the value
  576. if ( $record != FALSE )
  577. {
  578. $outputarray = add_to_field( $outputarray, 'urgency' , strtr( $record['RecData'], $irbtrans ), "\n" );
  579. }
  580. /***************************************/
  581. // Cycle through the IPTC records looking for Keywords records
  582. foreach ($IPTC_array as $record)
  583. {
  584. // Check if a Keywords record has been found
  585. if ( $record['IPTC_Type'] == "2:25" )
  586. {
  587. // A Keywords record has been found, save it's value if the value doesn't already exist
  588. if ( ! in_array ( $record['RecData'], $outputarray['keywords']))
  589. {
  590. $outputarray['keywords'][] = strtr( $record['RecData'], array("\x0a" => "", "\x0d" => "&#xA;") ) ;
  591. }
  592. }
  593. }
  594. /***************************************/
  595. // The IPTC Copyright Notice Field contains copyrightnotice - find it
  596. $record = find_IPTC_Resource( $IPTC_array, "2:116" );
  597. // Check if the Copyright Field exists and save the value
  598. if ( $record != FALSE )
  599. {
  600. $outputarray = add_to_field( $outputarray, 'copyrightnotice' , strtr( $record['RecData'], $irbtrans ), "\n" );
  601. }
  602. }
  603. }
  604. /***************************************/
  605. // EXIF Processing
  606. // Retreive Information from the EXIF data if it exists
  607. if ( ( $Exif_array != FALSE ) || ( count( $Exif_array ) == 0 ) )
  608. {
  609. // Check the Image Description Tag - it can contain the caption
  610. if ( array_key_exists( 270, $Exif_array[0] ) )
  611. {
  612. $outputarray = add_to_field( $outputarray, 'caption' , $Exif_array[0][270]['Data'][0], "\n" );
  613. }
  614. /***************************************/
  615. // Check the Copyright Information Tag - it contains the copyrightnotice
  616. if ( array_key_exists( 33432, $Exif_array[0] ) )
  617. {
  618. $outputarray = add_to_field( $outputarray, 'copyrightnotice' , HTML_UTF8_UnEscape( $Exif_array[0][33432]['Data'][0] ), "\n" );
  619. }
  620. /***************************************/
  621. // Check the Artist Name Tag - it contains the author
  622. if ( array_key_exists( 315, $Exif_array[0] ) )
  623. {
  624. $outputarray = add_to_field( $outputarray, 'author' , HTML_UTF8_UnEscape( $Exif_array[0][315]['Data'][0] ), "\n" );
  625. }
  626. }
  627. /***************************/
  628. // FINISHED RETRIEVING INFORMATION
  629. // Perform final processing
  630. // Check if any urgency information was found
  631. if ( $outputarray["urgency"] == "" )
  632. {
  633. // No urgency information was found - set it to default (None)
  634. $outputarray["urgency"] = "none";
  635. }
  636. // Check if any copyrightstatus information was found
  637. if ( $outputarray["copyrightstatus"] == "" )
  638. {
  639. // No copyrightstatus information was found - set it to default (Unmarked)
  640. $outputarray["copyrightstatus"] = "unmarked";
  641. }
  642. // Return the resulting Photoshop File Info Array
  643. return $outputarray;
  644. }
  645. /******************************************************************************
  646. * End of Function: get_photoshop_file_info
  647. ******************************************************************************/
  648. /******************************************************************************
  649. *
  650. * Function: put_photoshop_file_info
  651. *
  652. * Description: Stores Photoshop 'File Info' metadata in the same way that Photoshop
  653. * does. The 'File Info' metadata must be in an array similar to that
  654. * returned by get_photoshop_file_info, as follows:
  655. *
  656. * $file_info_array = array(
  657. * "title" => "",
  658. * "author" => "",
  659. * "authorsposition" => "", // Note: Not used in Photoshop 7 or higher
  660. * "caption" => "",
  661. * "captionwriter" => "",
  662. * "jobname" => "", // Note: Not used in Photoshop CS
  663. * "copyrightstatus" => "",
  664. * "copyrightnotice" => "",
  665. * "ownerurl" => "",
  666. * "keywords" => array( 0 => "", 1 => "", ... ),
  667. * "category" => "", // Note: Max 3 characters
  668. * "supplementalcategories" => array( 0 => "", 1 => "", ... ),
  669. * "date" => "", // Note: DATE MUST BE IN YYYY-MM-DD format
  670. * "city" => "",
  671. * "state" => "",
  672. * "country" => "",
  673. * "credit" => "",
  674. * "source" => "",
  675. * "headline" => "",
  676. * "instructions" => "",
  677. * "transmissionreference" => "",
  678. * "urgency" => "" );
  679. *
  680. * Parameters: jpeg_header_data - a JPEG header data array in the same format
  681. * as from get_jpeg_header_data. This contains the
  682. * header information which is to be updated.
  683. * new_ps_file_info_array - An array as above, which contains the
  684. * 'File Info' metadata information to be
  685. * written.
  686. * Old_Exif_array - an array containing the EXIF information to be
  687. * updated, as retrieved by get_EXIF_JPEG. (saves having to parse the EXIF again)
  688. * Old_XMP_array - an array containing the XMP information to be
  689. * updated, as retrieved by read_XMP_array_from_text. (saves having to parse the XMP again)
  690. * Old_IRB_array - an array containing the Photoshop IRB information
  691. * to be updated, as retrieved by get_Photoshop_IRB. (saves having to parse the IRB again)
  692. *
  693. * Returns: jpeg_header_data - a JPEG header data array in the same format
  694. * as from get_jpeg_header_data, containing the
  695. * Photshop 'File Info' metadata. This can then
  696. * be written to a file using put_jpeg_header_data.
  697. *
  698. ******************************************************************************/
  699. function put_photoshop_file_info( $jpeg_header_data, $new_ps_file_info_array, $Old_Exif_array, $Old_XMP_array, $Old_IRB_array )
  700. {
  701. /*******************************************/
  702. // PREPROCESSING
  703. // Check that the date is in the correct format (YYYY-MM-DD)
  704. // Explode the date into pieces using the - symbol
  705. $date_pieces = explode( "-", $new_ps_file_info_array[ 'date' ] );
  706. // If there are not 3 pieces to the date, it is invalid
  707. if ( count( $date_pieces ) != 3 )
  708. {
  709. // INVALID DATE
  710. echo "Invalid Date - must be YYYY-MM-DD format<br>";
  711. return FALSE;
  712. }
  713. // Cycle through each piece of the date
  714. foreach( $date_pieces as $piece )
  715. {
  716. // If the piece is not numeric, then the date is invalid.
  717. if ( ! is_numeric( $piece ) )
  718. {
  719. // INVALID DATE
  720. echo "Invalid Date - must be YYYY-MM-DD format<br>";
  721. return FALSE;
  722. }
  723. }
  724. // Make a unix timestamp at midnight on the date specified
  725. $date_stamp = mktime( 0,0,0, $date_pieces[1], $date_pieces[2], $date_pieces[0] );
  726. // Create a translation table to remove carriage return characters
  727. $trans = array( "\x0d" => "" );
  728. // Cycle through each of the File Info elements
  729. foreach( $new_ps_file_info_array as $valkey => $val )
  730. {
  731. // If the element is 'Keywords' or 'Supplemental Categories', then
  732. // it is an array, and needs to be treated as one
  733. if ( ( $valkey != 'supplementalcategories' ) && ( $valkey != 'keywords' ) )
  734. {
  735. // Not Keywords or Supplemental Categories
  736. // Convert escaped HTML characters to UTF8 and remove carriage returns
  737. $new_ps_file_info_array[ $valkey ] = strtr( HTML_UTF8_UnEscape( $val ), $trans );
  738. }
  739. else
  740. {
  741. // Either Keywords or Supplemental Categories
  742. // Cycle through the array,
  743. foreach( $val as $subvalkey => $subval )
  744. {
  745. // Convert escaped HTML characters to UTF8 and remove carriage returns
  746. $new_ps_file_info_array[ $valkey ][ $subvalkey ] = strtr( HTML_UTF8_UnEscape( $subval ), $trans );
  747. }
  748. }
  749. }
  750. /*******************************************/
  751. // EXIF Processing
  752. // Check if the EXIF array exists
  753. if( $Old_Exif_array == FALSE )
  754. {
  755. // EXIF Array doesn't exist - create a new one
  756. $new_Exif_array = array ( 'Byte_Align' => "MM",
  757. 'Makernote_Tag' => false,
  758. 'Tags Name' => "TIFF",
  759. 0 => array( "Tags Name" => "TIFF" ) );
  760. }
  761. else
  762. {
  763. // EXIF Array Does Exist - use it
  764. $new_Exif_array = $Old_Exif_array;
  765. }
  766. // Update the EXIF Image Description Tag with the new value
  767. $new_Exif_array[0][270] = array ( "Tag Name" => $GLOBALS[ "IFD_Tag_Definitions" ]['TIFF'][ 270 ]['Name'],
  768. "Tag Number" => 270,
  769. "Data Type" => 2,
  770. "Type" => $GLOBALS[ "IFD_Tag_Definitions" ]['TIFF'][ 270 ]['Type'],
  771. "Data" => array( HTML_UTF8_Escape( $new_ps_file_info_array[ 'caption' ]) ));
  772. // Update the EXIF Artist Name Tag with the new value
  773. $new_Exif_array[0][315] = array ( "Tag Name" => $GLOBALS[ "IFD_Tag_Definitions" ]['TIFF'][ 315 ]['Name'],
  774. "Tag Number" => 315,
  775. "Data Type" => 2,
  776. "Type" => $GLOBALS[ "IFD_Tag_Definitions" ]['TIFF'][ 315 ]['Type'],
  777. "Data" => array( HTML_UTF8_Escape( $new_ps_file_info_array[ 'author' ] ) ) );
  778. // Update the EXIF Copyright Information Tag with the new value
  779. $new_Exif_array[0][33432] = array ( "Tag Name" => $GLOBALS[ "IFD_Tag_Definitions" ]['TIFF'][ 33432 ]['Name'],
  780. "Tag Number" => 33432,
  781. "Data Type" => 2,
  782. "Type" => $GLOBALS[ "IFD_Tag_Definitions" ]['TIFF'][ 33432 ]['Type'],
  783. "Data" => array( HTML_UTF8_Escape( $new_ps_file_info_array[ 'copyrightnotice' ]) ) );
  784. // Photoshop checks if the "Date and Time of Original" and "Date and Time when Digitized" tags exist
  785. // If they don't exist, it means that the EXIF date may be wiped out if it is changed, so Photoshop
  786. // copies the EXIF date to these two tags
  787. if ( ( array_key_exists( 306, $new_Exif_array[0] ) )&&
  788. ( array_key_exists( 34665, $new_Exif_array[0] ) ) &&
  789. ( array_key_exists( 0, $new_Exif_array[0][34665] ) ) )
  790. {
  791. // Replace "Date and Time of Original" if it doesn't exist
  792. if ( ! array_key_exists( 36867, $new_Exif_array[0][34665][0] ) )
  793. {
  794. $new_Exif_array[0][34665][0][36867] = array ( "Tag Name" => $GLOBALS[ "IFD_Tag_Definitions" ]['EXIF'][ 36867 ]['Name'],
  795. "Tag Number" => 36867,
  796. "Data Type" => 2,
  797. "Type" => $GLOBALS[ "IFD_Tag_Definitions" ]['EXIF'][ 36867 ]['Type'],
  798. "Data" => $new_Exif_array[0][306]['Data'] );
  799. }
  800. // Replace "Date and Time when Digitized" if it doesn't exist
  801. if ( ! array_key_exists( 36868, $new_Exif_array[0][34665][0] ) )
  802. {

Large files files are truncated, but you can click here to view the full file