[Linpha-cvs] SF.net SVN: linpha: [4688] trunk/linpha2
Status: Inactive
Brought to you by:
bzrudi
From: <bz...@us...> - 2007-02-28 17:43:21
|
Revision: 4688 http://svn.sourceforge.net/linpha/?rev=4688&view=rev Author: bzrudi Date: 2007-02-28 09:41:13 -0800 (Wed, 28 Feb 2007) Log Message: ----------- Improved Metadata Support (still not complete) Modified Paths: -------------- trunk/linpha2/ChangeLog trunk/linpha2/admin/metadata_define_post.php trunk/linpha2/lib/classes/linpha.metadata.class.php trunk/linpha2/lib/include/metadata_iptc_edit.php trunk/linpha2/lib/include/metadata_xmp_edit.php Modified: trunk/linpha2/ChangeLog =================================================================== --- trunk/linpha2/ChangeLog 2007-02-21 10:42:02 UTC (rev 4687) +++ trunk/linpha2/ChangeLog 2007-02-28 17:41:13 UTC (rev 4688) @@ -1,4 +1,7 @@ - +2007-02-28 bzrudi + * Improved MetaData support + TODO: XMP write, code cleanups, encoding + 2007-02-20 flo * i18n - added check for outdated strings Modified: trunk/linpha2/admin/metadata_define_post.php =================================================================== --- trunk/linpha2/admin/metadata_define_post.php 2007-02-21 10:42:02 UTC (rev 4687) +++ trunk/linpha2/admin/metadata_define_post.php 2007-02-28 17:41:13 UTC (rev 4688) @@ -46,6 +46,7 @@ } break; + case 'add_new': /** * check for duplicates with the same name @@ -53,6 +54,7 @@ $linpha->db->Execute("INSERT into ".LIN_PREFIX."meta_fields (name, field_type, flags) " . "VALUES ('".LinSql::linAddslashes($_POST['new_name'])."', '".LinSql::linAddslashes($_POST['new_type'])."', '7') "); break; + case 'change_field': if(LinSql::linAddslashes($_POST['builtin'][$_POST['id']])) { @@ -66,6 +68,7 @@ "flags = '".$flag."' ". "WHERE id = '".LinSql::linAddslashes($_POST['id'])."'"); break; + case 'delete': ?> <h3>Delete selected field</h3> @@ -79,9 +82,11 @@ <br /><br /> <?php break; + case 'do_delete': $linpha->db->Execute("DELETE FROM ".LIN_PREFIX."meta_fields WHERE id = '".LinSql::linAddslashes($_POST['id'])."'"); break; + case 'add_new_category': if(isset($_POST['isprivate'])) { $isprivate = 1; @@ -94,6 +99,7 @@ "'".$isprivate."')"); break; + case 'mod_category': if(isset($_POST['isprivate'])) { $isprivate = 1; @@ -107,30 +113,33 @@ "WHERE id = '".LinSql::linAddslashes($_POST['id'])."'"); break; + case 'delete_category': $linpha->db->Execute("DELETE FROM ".LIN_PREFIX."meta_category WHERE id = '".LinSql::linAddslashes($_POST['id'])."'"); break; + case 'update_config_metadata': $linpha->sql->config->updateConfig('sys_image_'.$cat3,$_POST['metadata_config_enable']); $linpha->sql->config->reloadConfig(); break; + case 'create_metadata_table': - if( ! isset($_POST['selected_fields'])) - { + if( ! isset($_POST['selected_fields'])) { $_POST['selected_fields'] = Array(); } - if($cat3 == 'exif') { - $linpha->db->Execute("DROP TABLE ".LIN_PREFIX."meta_exif"); - $linpha->db->Execute( LinMetaDataAdmin::createMetaDataTable( $_POST['selected_fields'], 'exif')); - } elseif($cat3 == 'iptc') { - $linpha->db->Execute("DROP TABLE ".LIN_PREFIX."meta_iptc"); - $linpha->db->Execute( LinMetaDataAdmin::createMetaDataTable( $_POST['selected_fields'], 'iptc')); - } elseif($cat3 == 'xmp') { - $linpha->db->Execute("DROP TABLE ".LIN_PREFIX."meta_xmp"); - $linpha->db->Execute( LinMetaDataAdmin::createMetaDataTable( $_POST['selected_fields'], 'xmp' )); + if(isset($cat3)) { + if(LIN_DB_TYPE == "mysql") { + $linpha->db->Execute("DROP TABLE IF EXISTS ".LIN_PREFIX."meta_$cat3"); + } else { + @$linpha->db->Execute("DROP TABLE ".LIN_PREFIX."meta_$cat3"); + } + $linpha->db->Execute( LinMetaDataAdmin::createMetaDataTable( $_POST['selected_fields'], $cat3)); } break; + +default: + echo i18n("FATAL: Unknown POST Request"); + exit(); + break; } - - -?> \ No newline at end of file +?> Modified: trunk/linpha2/lib/classes/linpha.metadata.class.php =================================================================== --- trunk/linpha2/lib/classes/linpha.metadata.class.php 2007-02-21 10:42:02 UTC (rev 4687) +++ trunk/linpha2/lib/classes/linpha.metadata.class.php 2007-02-28 17:41:13 UTC (rev 4688) @@ -1708,90 +1708,9 @@ ), 'xmp' => array ( - - // Iptc4xmpCore Segment - - 'i4xcore_country_code' => array ( - 'name' => 'Country Code', - 'pathkey' => 'i4xcore_country_code', - 'path' => 'Iptc4xmpCore:CountryCode' - ), - - 'i4xcore_addr_city' => array ( - 'name' => 'Creator Info City', - 'pathkey' => 'i4xcore_addr_city', - 'path' => 'Iptc4xmpCore:CreatorContactInfoCiAdrCity' - ), - - 'i4xcore_addr_ctry' => array ( - 'name' => 'Creator Info Country', - 'pathkey' => 'i4xcore_addr_ctry', - 'path' => 'Iptc4xmpCore:CreatorContactInfoCiAdrCtry' - ), - - 'i4xcore_addr_etra' => array ( - 'name' => 'Creator Extra Information', - 'pathkey' => 'i4xcore_addr_etra', - 'path' => 'Iptc4xmpCore:CreatorContactInfoCiAdrExtadr' - ), - - 'i4xcore_zip_code' => array ( - 'name' => 'Creator Info Zip Code', - 'pathkey' => 'i4xcore_zip_code', - 'path' => 'Iptc4xmpCore:CreatorContactInfoCiAdrPcode' - ), - - 'i4xcore_region_code' => array ( - 'name' => 'Creator Info Region', - 'pathkey' => 'i4xcore_region_code', - 'path' => 'Iptc4xmpCore:CreatorContactInfoCiAdrRegion' - ), - - 'i4xcore_email_work' => array ( - 'name' => 'Creator Email Work', - 'pathkey' => 'i4xcore_email_work', - 'path' => 'Iptc4xmpCore:CreatorContactInfoCiEmailWork' - ), - - 'i4xcore_tel_work' => array ( - 'name' => 'Creator Telephone Work', - 'pathkey' => 'i4xcore_tel_work', - 'path' => 'Iptc4xmpCore:CreatorContactInfoCiTelWork' - ), - - 'i4xcore_url_work' => array ( - 'name' => 'Creator Website Work', - 'pathkey' => 'i4xcore_url_work', - 'path' => 'Iptc4xmpCore:CreatorContactInfoCiUrlWork' - ), - - 'i4xcore_intel_genre' => array ( - 'name' => 'Creator Intellectual Genre', - 'pathkey' => 'i4xcore_intel_genre', - 'path' => 'Iptc4xmpCore:IntellectualGenre' - ), - - 'i4xcore_location' => array ( - 'name' => 'Creator Location', - 'pathkey' => 'i4xcore_location', - 'path' => 'Iptc4xmpCore:Location' - ), - - 'i4xcore_scene' => array ( - 'name' => 'Creator Scene', - 'pathkey' => 'i4xcore_scene', - 'path' => 'Iptc4xmpCore:Scene' - ), - - 'i4xcore_subject_code' => array ( - 'name' => 'Subject Code', - 'pathkey' => 'i4xcore_subject_code', - 'path' => 'Iptc4xmpCore:SubjectCode' - ), - // Photoshop RDF Segment - 'ps_authors_pos' => array ( + 'ps_authors_pos' => array ( 'name' => 'Authors Position', 'pathkey' => 'ps_authors_pos', 'path' => 'photoshop:AuthorsPosition' @@ -1881,6 +1800,86 @@ 'path' => 'photoshop:Urgency' ), + // Iptc4xmpCore Segment + + 'i4xcore_country_code' => array ( + 'name' => 'Country Code', + 'pathkey' => 'i4xcore_country_code', + 'path' => 'Iptc4xmpCore:CountryCode' + ), + + 'i4xcore_addr_city' => array ( + 'name' => 'Creator Info City', + 'pathkey' => 'i4xcore_addr_city', + 'path' => 'Iptc4xmpCore:CreatorContactInfoCiAdrCity' + ), + + 'i4xcore_addr_ctry' => array ( + 'name' => 'Creator Info Country', + 'pathkey' => 'i4xcore_addr_ctry', + 'path' => 'Iptc4xmpCore:CreatorContactInfoCiAdrCtry' + ), + + 'i4xcore_addr_etra' => array ( + 'name' => 'Creator Extra Information', + 'pathkey' => 'i4xcore_addr_etra', + 'path' => 'Iptc4xmpCore:CreatorContactInfoCiAdrExtadr' + ), + + 'i4xcore_zip_code' => array ( + 'name' => 'Creator Info Zip Code', + 'pathkey' => 'i4xcore_zip_code', + 'path' => 'Iptc4xmpCore:CreatorContactInfoCiAdrPcode' + ), + + 'i4xcore_region_code' => array ( + 'name' => 'Creator Info Region', + 'pathkey' => 'i4xcore_region_code', + 'path' => 'Iptc4xmpCore:CreatorContactInfoCiAdrRegion' + ), + + 'i4xcore_email_work' => array ( + 'name' => 'Creator Email Work', + 'pathkey' => 'i4xcore_email_work', + 'path' => 'Iptc4xmpCore:CreatorContactInfoCiEmailWork' + ), + + 'i4xcore_tel_work' => array ( + 'name' => 'Creator Telephone Work', + 'pathkey' => 'i4xcore_tel_work', + 'path' => 'Iptc4xmpCore:CreatorContactInfoCiTelWork' + ), + + 'i4xcore_url_work' => array ( + 'name' => 'Creator Website Work', + 'pathkey' => 'i4xcore_url_work', + 'path' => 'Iptc4xmpCore:CreatorContactInfoCiUrlWork' + ), + + 'i4xcore_intel_genre' => array ( + 'name' => 'Creator Intellectual Genre', + 'pathkey' => 'i4xcore_intel_genre', + 'path' => 'Iptc4xmpCore:IntellectualGenre' + ), + + 'i4xcore_location' => array ( + 'name' => 'Creator Location', + 'pathkey' => 'i4xcore_location', + 'path' => 'Iptc4xmpCore:Location' + ), + + 'i4xcore_scene' => array ( + 'name' => 'Creator Scene', + 'pathkey' => 'i4xcore_scene', + 'path' => 'Iptc4xmpCore:Scene' + ), + + 'i4xcore_subject_code' => array ( + 'name' => 'Subject Code', + 'pathkey' => 'i4xcore_subject_code', + 'path' => 'Iptc4xmpCore:SubjectCode' + ), + // Dublin Core Metadata Initiative RDF Segment 'dc_contributor' => array ( @@ -2060,4 +2059,4 @@ } } // end class LinMetaData -?> \ No newline at end of file +?> Modified: trunk/linpha2/lib/include/metadata_iptc_edit.php =================================================================== --- trunk/linpha2/lib/include/metadata_iptc_edit.php 2007-02-21 10:42:02 UTC (rev 4687) +++ trunk/linpha2/lib/include/metadata_iptc_edit.php 2007-02-28 17:41:13 UTC (rev 4688) @@ -1,228 +1,229 @@ <?php -if(!defined('LINPHA_DIR')) { exit(1); } - -/**************************************************************************** +/* +* Copyright (c) 2005 Heiko Rutenbeck <bz...@tu...> +* Florian Angehrn +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. * -* Filename: Edit_File_Info.php +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. * -* Description: Allows the user to edit the metadata of an image over the internet -* in the same way that Photoshop edits 'File Info' data -* This file provides only the html for a form containing the file info -* input fields. The rest of the html file must be provided by the calling script. -* $outputfilename must always be defined - it is ne name of the file which -* have the metadata changed after the form has been submitted -* -* This file has several modes of operation: -* -* 1) If $new_ps_file_info_array is defined then it's data will be used -* to fill the fields. -* 2) If $new_ps_file_info_array is not defined but $filename is defined, -* then the file info fields will be filled from the metadata in the file specified -* 3) If $new_ps_file_info_array is not defined but $filename and $default_ps_file_info_array -* are defined, then the file info fields will be filled from the metadata -* in the file specified, but where fields are blank, they will be filled from $default_ps_file_info_array -* 4) Otherwise the fields will be blank -* -* See Edit_File_Info_Example.php for an example of usage -* -* Author: Evan Hunter -* -* Date: 17/11/2004 -* -* Project: PHP JPEG Metadata Toolkit -* -* Revision: 1.11 -* -* Changes: 1.10 -> 1.11 : Changed displayed toolkit version numbers to reference Toolkit_Version.php -* -* URL: http://electronics.ozhiker.com -* -* Copyright: Copyright Evan Hunter 2004 -* -* License: This file is part of the PHP JPEG Metadata Toolkit. -* -* The PHP JPEG Metadata Toolkit is free software; you can -* redistribute it and/or modify it under the terms of the -* GNU General Public License as published by the Free Software -* Foundation; either version 2 of the License, or (at your -* option) any later version. -* -* The PHP JPEG Metadata Toolkit is distributed in the hope -* that it will be useful, but WITHOUT ANY WARRANTY; without -* even the implied warranty of MERCHANTABILITY or FITNESS -* FOR A PARTICULAR PURPOSE. See the GNU General Public License -* for more details. -* -* You should have received a copy of the GNU General Public -* License along with the PHP JPEG Metadata Toolkit; if not, -* write to the Free Software Foundation, Inc., 59 Temple -* Place, Suite 330, Boston, MA 02111-1307 USA -* -* If you require a different license for commercial or other -* purposes, please contact the author: ev...@oz... -* -***************************************************************************/ +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +/** + * This File handles IPTC editing + * @package MetaData + * @author bzrudi,flo + */ +if(!defined('LINPHA_DIR')) { exit(1); } - - /** * if $default_ps_file_info_array is set and the key 'date' is empty * it will be auto filled with the exif date and we prevent errors like * "Invalid Date - must be YYYY-MM-DD format" */ -$default_ps_file_info_array = array ( - 'title' => "", - 'author' => "", - 'authorsposition' => "", - 'caption' => "", - 'captionwriter' => "", - 'jobname' => "", - 'copyrightstatus' => "", - 'copyrightnotice' => "", - 'ownerurl' => "", - 'keywords' => array(), - 'category' => "", - 'supplementalcategories'=> array(), - 'date' => "", - 'city' => "", - 'state' => "", - 'country' => "", - 'credit' => "", - 'source' => "", - 'headline' => "", - 'instructions' => "", - 'transmissionreference' => "", - 'urgency' => "" - ); +$default_ps_file_info_array = array( + 'title' => "", + 'author' => "", + 'authorsposition' => "", + 'caption' => "", + 'captionwriter' => "", + 'jobname' => "", + 'copyrightstatus' => "", + 'copyrightnotice' => "", + 'ownerurl' => "", + 'keywords' => array(), + 'category' => "", + 'supplementalcategories'=> array(), + 'date' => "", + 'city' => "", + 'state' => "", + 'country' => "", + 'credit' => "", + 'source' => "", + 'headline' => "", + 'instructions' => "", + 'transmissionreference' => "", + 'urgency' => "" + ); - include LINPHA_DIR.'/lib/classes/pjmt/Toolkit_Version.php'; // Change: added as of version 1.11 - global $new_ps_file_info_array; +include LINPHA_DIR.'/lib/classes/pjmt/Toolkit_Version.php'; - // Check for operation modes 2 or 3 - // i.e. $filename is defined, and $new_ps_file_info_array is not - if ( ( ! isset( $new_ps_file_info_array ) ) && - ( isset( $filename ) ) && - ( is_string( $filename ) ) ) - { - // Hide any unknown EXIF tags - $GLOBALS['HIDE_UNKNOWN_TAGS'] = TRUE; +global $new_ps_file_info_array; - // Accessing the existing file info for the specified file requires these includes - include_once( LINPHA_DIR.'/lib/classes/pjmt/JPEG.php' ); - include_once( LINPHA_DIR.'/lib/classes/pjmt/XMP.php' ); - include_once( LINPHA_DIR.'/lib/classes/pjmt/Photoshop_IRB.php' ); - include_once( LINPHA_DIR.'/lib/classes/pjmt/EXIF.php' ); - include_once( LINPHA_DIR.'/lib/classes/pjmt/Photoshop_File_Info.php' ); +// Check for operation modes 2 or 3 +// i.e. $filename is defined, and $new_ps_file_info_array is not +if ((!isset($new_ps_file_info_array)) && (isset($filename)) + && (is_string($filename))) +{ + // Hide any unknown EXIF tags + $GLOBALS['HIDE_UNKNOWN_TAGS'] = TRUE; - // Retrieve the header information from the JPEG file - $jpeg_header_data = get_jpeg_header_data( $filename ); +/** + * @TODO check what really needs to be included! + */ + include_once( LINPHA_DIR.'/lib/classes/pjmt/JPEG.php' ); + include_once( LINPHA_DIR.'/lib/classes/pjmt/XMP.php' ); + include_once( LINPHA_DIR.'/lib/classes/pjmt/Photoshop_IRB.php' ); + include_once( LINPHA_DIR.'/lib/classes/pjmt/EXIF.php' ); + include_once( LINPHA_DIR.'/lib/classes/pjmt/Photoshop_File_Info.php' ); - // Retrieve EXIF information from the JPEG file - $Exif_array = get_EXIF_JPEG( $filename ); + // Retrieve the header information from the JPEG file + $jpeg_header_data = get_jpeg_header_data( $filename ); + + // Retrieve EXIF information from the JPEG file + $Exif_array = get_EXIF_JPEG( $filename ); - // Retrieve XMP information from the JPEG file - $XMP_array = read_XMP_array_from_text( get_XMP_text( $jpeg_header_data ) ); - //$XMP_array = array(); - // Retrieve Photoshop IRB information from the JPEG file - $IRB_array = get_Photoshop_IRB( $jpeg_header_data ); + // Retrieve XMP information from the JPEG file + $XMP_array = read_XMP_array_from_text( get_XMP_text( $jpeg_header_data ) ); - // Retrieve Photoshop File Info from the three previous arrays - $new_ps_file_info_array = get_photoshop_file_info( $Exif_array, $XMP_array, $IRB_array ); + // Retrieve Photoshop IRB information from the JPEG file + $IRB_array = get_Photoshop_IRB( $jpeg_header_data ); + // Retrieve Photoshop File Info from the three previous arrays + $new_ps_file_info_array = get_photoshop_file_info( $Exif_array, $XMP_array, $IRB_array ); +//echo '<pre>', print_r($new_ps_file_info_array), '</pre>'; - // Check if there is an array of defaults available - if ( ( isset( $default_ps_file_info_array) ) && - ( is_array( $default_ps_file_info_array) ) ) + // Check if there is an array of defaults available + if((isset($default_ps_file_info_array)) && + (is_array($default_ps_file_info_array))) + { + // There are defaults defined + // Check if there is a default for the date defined + if((!array_key_exists('date', $default_ps_file_info_array)) || + ((array_key_exists('date', $default_ps_file_info_array)) && + ($default_ps_file_info_array['date'] == '' ))) + { + /** + * No default for the date defined figure out a default from + * the file check if there is a EXIF Tag 36867 "Date and Time + * of Original" + */ + if(($Exif_array != FALSE) && + (array_key_exists(0, $Exif_array)) && + (array_key_exists(34665, $Exif_array[0])) && + (array_key_exists(0, $Exif_array[0][34665])) && + (array_key_exists(36867, $Exif_array[0][34665][0]))) + { + /** + * Tag "Date and Time of Original" found - use it for + * the default date + */ + $default_ps_file_info_array['date'] = + $Exif_array[0][34665][0][36867]['Data'][0]; + $default_ps_file_info_array['date'] = + preg_replace( "/(\d\d\d\d):(\d\d):(\d\d)( \d\d:\d\d:\d\d)/", "$1-$2-$3", $default_ps_file_info_array['date'] ); + } + /** + * Check if there is a EXIF Tag 36868 "Date and Time when + * Digitized" + */ + elseif(($Exif_array != FALSE) && + (array_key_exists(0, $Exif_array)) && + (array_key_exists(34665, $Exif_array[0])) && + (array_key_exists(0, $Exif_array[0][34665])) && + (array_key_exists(36868, $Exif_array[0][34665][0]))) + { + /** + * Tag "Date and Time when Digitized" found - use it for + * the default date + */ + $default_ps_file_info_array['date'] = + $Exif_array[0][34665][0][36868]['Data'][0]; + $default_ps_file_info_array['date'] = + preg_replace( "/(\d\d\d\d):(\d\d):(\d\d)( \d\d:\d\d:\d\d)/", "$1-$2-$3", $default_ps_file_info_array['date'] ); + } + /** + * Check if there is a EXIF Tag 306 "Date and Time" + */ + elseif(($Exif_array != FALSE) && + (array_key_exists(0, $Exif_array)) && + (array_key_exists(306, $Exif_array[0]))) + { + /** + * Tag "Date and Time" found - use it for the default date + */ + $default_ps_file_info_array['date'] = + $Exif_array[0][306]['Data'][0]; + $default_ps_file_info_array['date'] = + preg_replace( "/(\d\d\d\d):(\d\d):(\d\d)( \d\d:\d\d:\d\d)/", "$1-$2-$3", $default_ps_file_info_array['date'] ); + } + else + { + /** + * Couldn't find an EXIF date in the image set default date + * as creation date of file + */ + $default_ps_file_info_array['date'] = + date ("Y-m-d", filectime( $filename )); + } + } + /* + * Cycle through all the elements of the default values array + */ + foreach( $default_ps_file_info_array as $def_key =>$default_item ) + { + /** + * Check if the current element is Keywords or Supplemental + * Categories as these are arrays and need to be treated + * differently + */ + if((strcasecmp($def_key, "keywords") == 0) || + (strcasecmp($def_key, "supplementalcategories" ) == 0)) + { + /** + * Keywords or Supplemental Categories found check if the + * File Info from the file is empty for this element and if + * there are default values in this array element + */ + if((count($new_ps_file_info_array[ $def_key ]) == 0) && + (is_array($default_item)) && + (count($default_item) >= 0)) { - // There are defaults defined - - // Check if there is a default for the date defined - if ( ( ! array_key_exists( 'date', $default_ps_file_info_array ) ) || - ( ( array_key_exists( 'date', $default_ps_file_info_array ) ) && - ( $default_ps_file_info_array['date'] == '' ) ) ) - { - // No default for the date defined - // figure out a default from the file - - // Check if there is a EXIF Tag 36867 "Date and Time of Original" - if ( ( $Exif_array != FALSE ) && - ( array_key_exists( 0, $Exif_array ) ) && - ( array_key_exists( 34665, $Exif_array[0] ) ) && - ( array_key_exists( 0, $Exif_array[0][34665] ) ) && - ( array_key_exists( 36867, $Exif_array[0][34665][0] ) ) ) - { - // Tag "Date and Time of Original" found - use it for the default date - $default_ps_file_info_array['date'] = $Exif_array[0][34665][0][36867]['Data'][0]; - $default_ps_file_info_array['date'] = preg_replace( "/(\d\d\d\d):(\d\d):(\d\d)( \d\d:\d\d:\d\d)/", "$1-$2-$3", $default_ps_file_info_array['date'] ); - } - // Check if there is a EXIF Tag 36868 "Date and Time when Digitized" - else if ( ( $Exif_array != FALSE ) && - ( array_key_exists( 0, $Exif_array ) ) && - ( array_key_exists( 34665, $Exif_array[0] ) ) && - ( array_key_exists( 0, $Exif_array[0][34665] ) ) && - ( array_key_exists( 36868, $Exif_array[0][34665][0] ) ) ) - { - // Tag "Date and Time when Digitized" found - use it for the default date - $default_ps_file_info_array['date'] = $Exif_array[0][34665][0][36868]['Data'][0]; - $default_ps_file_info_array['date'] = preg_replace( "/(\d\d\d\d):(\d\d):(\d\d)( \d\d:\d\d:\d\d)/", "$1-$2-$3", $default_ps_file_info_array['date'] ); - } - // Check if there is a EXIF Tag 306 "Date and Time" - else if ( ( $Exif_array != FALSE ) && - ( array_key_exists( 0, $Exif_array ) ) && - ( array_key_exists( 306, $Exif_array[0] ) ) ) - { - // Tag "Date and Time" found - use it for the default date - $default_ps_file_info_array['date'] = $Exif_array[0][306]['Data'][0]; - $default_ps_file_info_array['date'] = preg_replace( "/(\d\d\d\d):(\d\d):(\d\d)( \d\d:\d\d:\d\d)/", "$1-$2-$3", $default_ps_file_info_array['date'] ); - } - else - { - // Couldn't find an EXIF date in the image - // Set default date as creation date of file - $default_ps_file_info_array['date'] = date ("Y-m-d", filectime( $filename )); - } - } - - // Cycle through all the elements of the default values array - foreach( $default_ps_file_info_array as $def_key =>$default_item ) - { - // Check if the current element is Keywords or - // Supplemental Categories as these are arrays - // and need to be treated differently - if ( ( strcasecmp( $def_key, "keywords" ) == 0 ) || - ( strcasecmp( $def_key, "supplementalcategories" ) == 0 ) ) - { - // Keywords or Supplemental Categories found - // Check if the File Info from the file is empty for this element - // and if there are default values in this array element - if ( ( count( $new_ps_file_info_array[ $def_key ] ) == 0 ) && - ( is_array( $default_item ) ) && - ( count( $default_item ) >= 0 ) ) - { - // The existing file info is empty, and there are - // defaults - add them - $new_ps_file_info_array[ $def_key ] = $default_item; - } - } - // Otherwise, this is not an array element, just check if it is blank in the existing file info - else if ( trim( $new_ps_file_info_array[ $def_key ] ) == "" ) - { - // The existing file info is blank, add the default value - $new_ps_file_info_array[ $def_key ] = $default_item; - } - - } + /** + * The existing file info is empty, and there are + * defaults - add them + */ + $new_ps_file_info_array[ $def_key ] = $default_item; } + } + /** + * Otherwise, this is not an array element, just check if it is + * blank in the existing file info + */ + elseif(trim($new_ps_file_info_array[$def_key] ) == "" ) + { + /** + * The existing file info is blank, add the default value + */ + $new_ps_file_info_array[ $def_key ] = $default_item; + } } - // Check for operation mode 4 - $new_ps_file_info_array and $filename are not defined, - else if ( ( ( !isset($new_ps_file_info_array) ) || ( ! is_array($new_ps_file_info_array) ) ) && - ( ( !isset($filename) ) || ( ! is_string( $filename ) ) ) ) - { - // No filename or new_ps_file_info_array defined, create a blank file info array to display - $new_ps_file_info_array = array( + } +} +/** + * Check for operation mode 4 - $new_ps_file_info_array and $filename are + * not defined, + */ +elseif(((!isset($new_ps_file_info_array)) || + (!is_array($new_ps_file_info_array))) && + ((!isset($filename)) || (!is_string($filename)))) +{ +/** + * No filename or new_ps_file_info_array defined, create a blank file + * info array to display + */ + $new_ps_file_info_array = array( "title" => "", "author" => "", "authorsposition" => "", @@ -245,41 +246,26 @@ "instructions" => "", "transmissionreference" => "", "urgency" => "" ); - } - +} /*************************************************************************** * * Now output the actual HTML form * ***************************************************************************/ -/** -?> - - - - <form name="EditJPEG" action="Write_File_Info.php" method="post"> - - - echo "<input name=\"filename\" type=\"hidden\" value=\"$outputfilename\">"; - - <table> -*/ +echo + "<tr>" . + "<td>Title</td>" . + "<td> ". + "<input size=49 class='linForms' name='title' type='text' + value=". htmlspecialchars($new_ps_file_info_array[ 'title' ], + ENT_QUOTES).">" . + "</td>" . + "</tr>"; ?> <tr> <td> - Title - </td> - <td> - <?php - echo "<input size=49 class=\"linForms\" name=\"title\" type=\"text\" value=\"". htmlspecialchars($new_ps_file_info_array[ 'title' ], ENT_QUOTES) ."\">"; - ?> - </td> - </tr> - - <tr> - <td> Author </td> <td> Modified: trunk/linpha2/lib/include/metadata_xmp_edit.php =================================================================== --- trunk/linpha2/lib/include/metadata_xmp_edit.php 2007-02-21 10:42:02 UTC (rev 4687) +++ trunk/linpha2/lib/include/metadata_xmp_edit.php 2007-02-28 17:41:13 UTC (rev 4688) @@ -19,42 +19,425 @@ */ /** - * This File handles XMP editing + * This file handles XMP MetaData editing + * * @package MetaData * @author bzrudi */ +if(!defined('LINPHA_DIR')) { exit(1); } + include LINPHA_DIR.'/lib/classes/pjmt/Toolkit_Version.php'; if ( isset( $filename ) && is_string( $filename )) { - // Hide any unknown EXIF tags - $GLOBALS['HIDE_UNKNOWN_TAGS'] = TRUE; - // Accessing the existing file info for the specified file requires these includes - include_once( LINPHA_DIR.'/lib/classes/pjmt/JPEG.php' ); - include_once( LINPHA_DIR.'/lib/classes/pjmt/XMP.php' ); - include_once( LINPHA_DIR.'/lib/classes/pjmt/Photoshop_IRB.php' ); - include_once( LINPHA_DIR.'/lib/classes/pjmt/EXIF.php' ); - include_once( LINPHA_DIR.'/lib/classes/pjmt/Photoshop_File_Info.php' ); +/** + * @TODO check what really needs to be included! + */ + include_once( LINPHA_DIR.'/lib/classes/pjmt/JPEG.php' ); + include_once( LINPHA_DIR.'/lib/classes/pjmt/XMP.php' ); + include_once( LINPHA_DIR.'/lib/classes/pjmt/Photoshop_IRB.php' ); + include_once( LINPHA_DIR.'/lib/classes/pjmt/EXIF.php' ); + include_once( LINPHA_DIR.'/lib/classes/pjmt/Photoshop_File_Info.php' ); - // Retrieve the header information from the JPEG file - $jpeg_header_data = get_jpeg_header_data( $filename ); + /** + * Retrieve the header information from the JPEG file + */ + $jpeg_header_data = get_jpeg_header_data( $filename ); + $XMP_from_image = read_XMP_array_from_text(get_XMP_text($jpeg_header_data)); - // Retrieve EXIF information from the JPEG file - $Exif_array = get_EXIF_JPEG( $filename ); + /** + * Check if the XMP tree structure array is valid + */ + if($XMP_from_image !== FALSE) + { + /** + * Check if there is a rdf:RDF tag at either the first or second level + */ + if(($XMP_array[0]['tag'] == "x:xapmeta") + && ($XMP_array[0]['children'][0]['tag'] == "rdf:RDF")) + { + /** + * RDF found at second level - Save it's position + */ + $RDF_Contents = &$XMP_array[0]['children'][0]['children']; + } + else if ( ( $XMP_array[0]['tag'] == "x:xmpmeta" ) + && ( $XMP_array[0]['children'][0]['tag'] == "rdf:RDF" ) ) + { + /** + * RDF found at second level - Save it's position + */ + $RDF_Contents = &$XMP_array[0]['children'][0]['children']; + } + else if ( $XMP_array[0]['tag'] == "rdf:RDF" ) + { + /** + * RDF found at first level - Save it's position + */ + $RDF_Contents = &$XMP_array[0]['children']; + } + } - // Retrieve XMP information from the JPEG file - $XMP_array = read_XMP_array_from_text( get_XMP_text( $jpeg_header_data ) ); +/** + * This function creates an array with all available fields from the XMP + * MetaData relation, as defined in linpha.metadata.class.php + * + * @param none + * @return array or in case of failure FALSE + * @author bzrudi + */ +function createNewEmptyXmpArray() +{ + /** + * create new empty array with no defaults + */ + foreach(array_values(LinMetaData::$Tags['xmp']) AS $value) + { + $new_xmp_array[$value['path']] = ""; + } + + if(is_array($new_xmp_array)) + { + return $new_xmp_array; + } + else + { + return FALSE; + } +} - // Retrieve Photoshop IRB information from the JPEG file - $IRB_array = get_Photoshop_IRB( $jpeg_header_data ); +/** + * This function just prevents Notices when calling unset array data + * + * @param string + * @return string + * @author bzrudi + */ +function preventNotice($item) +{ + if(!isset($item)) + { + $item = ''; + } +return $item; +} - // Retrieve Photoshop File Info from the three previous arrays - $new_xmp_file_info_array = get_photoshop_file_info( $Exif_array, $XMP_array, $IRB_array ); +/** + * This function is mainly a copy from the pjmt, but as we need to have it mod + * slightly it's required. + * + * @param array XMP item + * @return array with key and value + * @author pjmt, bzrudi + */ +function linInterpretRdfItem( $Item ) +{ + $value_str = ""; -$test = read_XMP_array_from_text(get_XMP_text($jpeg_header_data)); -print_r($test); + /** + * Check if the item has is in the lookup table of tag captions + */ + if ( array_key_exists( $Item['tag'], $GLOBALS[ 'XMP_tag_captions' ] ) ) + { + /** + * Item is in list of captions, get the caption + */ + $tag_caption = $GLOBALS[ 'XMP_tag_captions' ][ $Item['tag'] ]; + } + else + { + /** + * Item has no caption - make one + */ + $tag_caption = "Unknown field " . $Item['tag']; + } + + /** + * Process specially the item according to it's tag + */ + switch($Item['tag']) + { + case "photoshopDateCreated": + list( $year, $month, $day ) = sscanf( $Item['value'], "%d-%d-%d" ); + /** + * Make a new date string with Day, Month, Year + */ + $value_str = "$day/$month/$year"; + break; + + default : + $value_str = linGetRdfField( $Item ); + break; + } + /** + * Return the caption and the value + */ + return array($tag_caption, $value_str); } + +/** + * This function is mainly a copy from the pjmt, but as we need to have it mod + * it slightly it's required + * + * @param array XMP item + * @return string interpreted item value + * @author pjmt, bzrudi + */ +function linGetRdfField($rdf_item) +{ + $output_str = ""; + + /** + * Check if the item has a value + */ + if(array_key_exists('value', $rdf_item)) + { + /** + * The item does have a value - add it to the text + */ + $output_str .= $rdf_item['value']; + } + + /** + * Check if the item has any attributes + */ + if (array_key_exists( 'attributes', $rdf_item)) + { + /** + * Cycle through each of the attributes + */ + foreach($rdf_item['attributes'] as $key => $val) + { + /** + * Check if this attribute is rdf:parseType = 'Resource' + * i.e. a sub-resource indicator + */ + if(($key == "rdf:parseType") && ($val == "Resource")) + { + /** + * This item has a attribute indicating sub-resources + */ + if (array_key_exists('children', $rdf_item)) + { + /** + * The item does have sub-items, Cycle through each, + * Interpreting them and adding the result to the + * output text + */ + foreach($rdf_item['children'] as $child) + { + list($tag_caption, $value_str) = linInterpretRdfItem($child); + $output_str .= "$tag_caption = $value_str\n"; + } + /** + * The output text will have an extra \n on it - remove it + */ + $output_str = rtrim($output_str); + } + } + } + } + /** + * If the item did not have sub-resources, it may still have + * sub-items - check for this + */ + else if (array_key_exists('children', $rdf_item)) + { + /** + * Non-resource Sub-items found, Cycle through each + */ + foreach($rdf_item['children'] as $child_item) + { + /** + * Check if this sub-item has a tag + */ + if (array_key_exists('tag', $child_item)) + { + /** + * Sub item has a tag, Process it according to the tag + */ + switch ($child_item['tag']) + { + // Collections + case "rdf:Alt": + $output_str .= interpret_RDF_collection( $child_item ); + break; + + case "rdf:Bag": + $output_str .= interpret_RDF_collection( $child_item ); + break; + + case "rdf:Seq": + $output_str .= interpret_RDF_collection( $child_item ); + break; + // Sub-Resource + case "rdf:Description": + // Check that the item has sub items + if (array_key_exists('children', $child_item)) + { + /** + * The item does have sub-items, Cycle through + * each, Interpreting them and adding the + * result to the output text + */ + foreach($child_item['children'] as $child) + { + list($tag_caption, $value_str) = + linInterpretRdfItem( $child ); + $output_str .= "$tag_caption = $value_str\n"; + } + /** + * The output text will have an extra \n on it + * - remove it + */ + $output_str = rtrim( $output_str ); + } + break; + + default: + $output_str .= "Unknown Item:".$child_item['tag']."\n"; + break; + } + } // sub-item Has no tags, look for a value + elseif(array_key_exists('value', $child_item)) + { + $output_str .= $rdf_item['value'] . "\n"; + } + } + } + // return the resulting value string + return $output_str; +} + +$XMP_default = createNewEmptyXmpArray(); + +foreach($RDF_Contents AS $RDF_Item) +{ + if(($RDF_Item['tag'] == "rdf:Description") + && (array_key_exists('children', $RDF_Item))) + { + /** + * Bingo item is a rdf:Description tag. + * Cycle through each of the attributes for this tag, looking + * for a xmlns: attribute, which tells us what Namespace the + * sub-items will be in. + */ + foreach( $RDF_Item['attributes'] as $key => $val ) + { + if(substr($key,0,6) == "xmlns:") +{ + /** + * Now lets take good care of the subchildren items and the + * data itself + */ + if(array_key_exists('children', $RDF_Item)) + { + /** + * Let's get each of the sub items + */ + foreach( $RDF_Item['children'] as $child_item ) + { + $XMP_default[$child_item['tag']] = + linInterpretRdfItem($child_item); + } + } + } + } + } +} +//echo '<pre>', print_r($XMP_default), '</pre>'; +//echo '<pre>', print_r($XMP_from_image), '</pre>'; +} + +/** + * Generate form data. + */ +echo "<tr>" . + "<td colspan='2'><b>".i18n("Photoshop XMP Segment")."</b><hr>" . + "</td></tr>"; + +foreach($XMP_default AS $key => $value) +{ + if(strpos($key, "photoshop") !== false) + { + echo + "<tr>" . + "<td>".$GLOBALS['XMP_tag_captions'][$key]."</td>" . + "<td>" . + "<input size='50' class='linForms' " . + "name=".$XMP_default[$key]." type='text' " . + "value=".@preventNotice($XMP_default[$key][1]).">" . + "</td>" . + "</tr>"; + } +} + +/** + * IPTC4XMP Core Segment Data + */ +echo "<tr><td colspan='2'> </td></tr>" . + "<tr>" . + "<td colspan='2'><b>".i18n("Iptc4xmp Core XMP Segment")."</b><hr>" . + "</td></tr>"; + +foreach($XMP_default AS $key => $value) +{ + if(strpos($key, "Iptc4xmpCore") !== false) + { + /** + * Iptc4xmpCore:SubjectCode needs special attention (unordered list) + */ + if($key == "Iptc4xmpCore:SubjectCode") + { + echo + "<tr>" . + "<td>".$GLOBALS['XMP_tag_captions'][$key]."</td>" . + "<td>" . + "<textarea class='linForms' " . + "name=".$XMP_default[$key]." rows='3' cols='50' wrap='off'>" . + "".@preventNotice($XMP_default[$key][1])."</textarea>" . + "</td>" . + "</tr>"; + } + else + { + echo + "<tr>" . + "<td>".$GLOBALS['XMP_tag_captions'][$key]."</td>" . + "<td>" . + "<input size='50' class='linForms' " . + "name=".$XMP_default[$key]." type='text' " . + "value=".@preventNotice($XMP_default[$key][1]).">" . + "</td>" . + "</tr>"; + } + + } +} + +/** + * DC Dublin Core Segment Data + */ +echo "<tr><td colspan='2'> </td></tr>" . + "<tr><td colspan='2'><b>".i18n("Dublin Core XMP Segment")."</b><hr>" . + "</td></tr>"; + +foreach($XMP_default AS $key => $value) +{ + if(strpos($key, "dc") !== false) + { + echo + "<tr>" . + "<td>".$GLOBALS['XMP_tag_captions'][$key]."</td>" . + "<td>" . + "<textarea class='linForms' " . + "name=".$XMP_default[$key]." rows='3' cols='50' wrap='off'>" . + "".@preventNotice($XMP_default[$key][1])."</textarea>" . + "</td>" . + "</tr>"; + } +} +/* vi: set ts=4 sw=4 sts=4 */ ?> - This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |