%PDF- %PDF-
| Direktori : /home1/lightco1/www/plugins/content/sigplus/core/ |
| Current File : //home1/lightco1/www/plugins/content/sigplus/core/metadata.php |
<?php
/**
* @file
* @brief sigplus Image Gallery Plus metadata extraction
* @author Levente Hunyadi
* @version 1.5.0
* @remarks Copyright (C) 2009-2017 Levente Hunyadi
* @remarks Licensed under GNU/GPLv3, see http://www.gnu.org/licenses/gpl-3.0.html
* @see http://hunyadi.info.hu/sigplus
*/
/*
* sigplus Image Gallery Plus plug-in for Joomla
* Copyright 2009-2017 Levente Hunyadi
*
* sigplus 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 3 of the License, or
* (at your option) any later version.
*
* sigplus 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );
require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'filesystem.php';
class SigPlusNovoMetadataServices {
private static $enveloperecord = array(
0=>'Envelope Record Version',
5=>'Destination',
20=>'File Format',
22=>'File Version',
30=>'Service Identifier',
40=>'Envelope Number',
50=>'Product ID',
60=>'Envelope Priority',
70=>'Date Sent',
80=>'Time Sent',
90=>'Coded Character Set',
100=>'Unique Object Name',
120=>'ARM Identifier',
122=>'ARM Version');
private static $applicationrecord = array(
0=>'Application Record Version',
3=>'Object Type Reference',
4=>'Object Attribute Reference',
5=>'Object Name',
7=>'Edit Status',
8=>'Editorial Update',
10=>'Urgency',
12=>'Subject Reference',
15=>'Category',
20=>'Supplemental Categories',
22=>'Fixture Identifier',
25=>'Keywords',
26=>'Content Location Code',
27=>'Content Location Name',
30=>'Release Date',
35=>'Release Time',
37=>'Expiration Date',
38=>'Expiration Time',
40=>'Special Instructions',
42=>'Action Advised',
45=>'Reference Service',
47=>'Reference Date',
50=>'Reference Number',
55=>'Date Created',
60=>'Time Created',
62=>'Digital Creation Date',
63=>'Digital Creation Time',
65=>'Originating Program',
70=>'Program Version',
75=>'Object Cycle',
80=>'By-line',
85=>'By-line Title',
90=>'City',
92=>'Sub-location',
95=>'Province-State',
100=>'Country-Primary Location Code',
101=>'Country-Primary Location Name',
103=>'Original Transmission Reference',
105=>'Headline',
110=>'Credit',
115=>'Source',
116=>'Copyright Notice',
118=>'Contact',
120=>'Caption-Abstract',
121=>'Local Caption',
122=>'Writer-Editor',
125=>'Rasterized Caption',
130=>'Image Type',
131=>'Image Orientation',
135=>'Language Identifier',
150=>'Audio Type',
151=>'Audio Sampling Rate',
152=>'Audio Sampling Resolution',
153=>'Audio Duration',
154=>'Audio Outcue',
184=>'JobID',
185=>'Master Document ID',
186=>'Short Document ID',
187=>'Unique Document ID',
188=>'Owner ID',
200=>'Object Preview File Format',
201=>'Object Preview File Version',
202=>'Object Preview Data',
221=>'Prefs',
225=>'Classify State',
228=>'Similarity Index',
230=>'Document Notes',
231=>'Document History',
232=>'Exif Camera Info');
private static $fileformats = array(
0=>'No Object Data',
1=>'IPTC-NAA Digital Newsphoto Parameter Record',
2=>'IPTC7901 Recommended Message Format',
3=>'Tagged Image File Format (Adobe/Aldus Image data)',
4=>'Illustrator (Adobe Graphics data)',
5=>'AppleSingle (Apple Computer Inc)',
6=>'NAA 89-3 (ANPA 1312)',
7=>'MacBinary II',
8=>'IPTC Unstructured Character Oriented File Format (UCOFF)',
9=>'United Press International ANPA 1312 variant',
10=>'United Press International Down-Load Message',
11=>'JPEG File Interchange (JFIF)',
12=>'Photo-CD Image-Pac (Eastman Kodak)',
13=>'Bit Mapped Graphics File [.BMP] (Microsoft)',
14=>'Digital Audio File [.WAV] (Microsoft & Creative Labs)',
15=>'Audio plus Moving Video [.AVI] (Microsoft)',
16=>'PC DOS/Windows Executable Files [.COM][.EXE]',
17=>'Compressed Binary File [.ZIP] (PKWare Inc)',
18=>'Audio Interchange File Format AIFF (Apple Computer Inc)',
19=>'RIFF Wave (Microsoft Corporation)',
20=>'Freehand (Macromedia/Aldus)',
21=>'Hypertext Markup Language [.HTML] (The Internet Society)',
22=>'MPEG 2 Audio Layer 2 (Musicom), ISO/IEC',
23=>'MPEG 2 Audio Layer 3, ISO/IEC',
24=>'Portable Document File [.PDF] Adobe',
25=>'News Industry Text Format (NITF)',
26=>'Tape Archive [.TAR]',
27=>'Tidningarnas Telegrambyra NITF version (TTNITF DTD)',
28=>'Ritzaus Bureau NITF version (RBNITF DTD)',
29=>'Corel Draw [.CDR]');
public static function getProperties() {
static $properties;
if (!isset($properties)) {
// fetch supported EXIF tags from PHP
$exiftags = array();
if (function_exists('exif_tagname')) {
for ($k = 1; $k < 0xB000; $k++) {
$exiftag = exif_tagname($k);
if ($exiftag) {
$exiftags[] = $exiftag;
}
}
}
$properties = array_unique(array_merge(self::$enveloperecord, self::$applicationrecord, $exiftags));
// force re-indexing numeric array starting at index 1 (MySQL does not allow a value of 0 for AUTO_INCREMENT columns)
array_unshift($properties, false);
unset($properties[0]);
}
return $properties;
}
public static function getPropertyNumericKey($key) {
static $propertymap;
if (!isset($propertymap)) {
$propertymap = array_flip(self::getProperties());
}
if (isset($propertymap[$key])) {
return $propertymap[$key];
} else {
return false;
}
}
/**
* Canonicalizes the value of a metadata entry to ensure proper display.
*/
private static function canonicalizeMetadataValue($key, $value) {
if (is_array($value)) {
switch (count($value)) {
case 0: return false; // nothing to process
case 1: $value = reset($value); break; // extract the only element from single-entry array
}
}
switch ($key) {
case 'Coded Character Set':
switch ($value) { // see International Register of Coded Character Sets to be used with escape sequences
case "\x1b%G": $value = 'utf-8'; break;
case "\x1b.A": $value = 'iso-8859-1'; break;
case "\x1b.B": $value = 'iso-8859-2'; break;
case "\x1b.C": $value = 'iso-8859-3'; break;
case "\x1b.D": $value = 'iso-8859-4'; break;
case "\x1b.@": $value = 'iso-8859-5'; break;
case "\x1b.F": $value = 'iso-8859-7'; break;
case "\x1b.G": $value = 'iso-8859-6'; break;
case "\x1b.H": $value = 'iso-8859-8'; break;
default: $value = 'iso-8859-1'; // assume ISO-8859-1 (a superset of ASCII) for unrecognized escape sequences
}
break;
case 'Envelope Record Version':
case 'File Version':
case 'ARM Identifier':
case 'ARM Version':
case 'Application Record Version':
case 'ObjectPreviewFileVersion':
$value = (int) $value;
break;
case 'File Format':
case 'ObjectPreviewFileFormat':
$value = (int) $value;
if (isset(self::$fileformats[$value])) {
$value = self::$fileformats[$value];
}
break;
case 'Image Orientation':
switch ($value) {
case 'L': $value = 'landscape'; break;
case 'P': $value = 'portrait'; break;
case 'S': $value = 'square'; break;
}
break;
}
return $value;
}
private static function convertCharacterEncoding($charset_in, $charset_out, $str) {
// avoid uninformative PHP notice "iconv(): Detected an illegal character in input string"
if (extension_loaded('mbstring') && function_exists('mb_check_encoding')) {
if (!mb_check_encoding($str, $charset_in)) {
return false;
}
}
return iconv($charset_in, $charset_out, $str);
}
/**
* Map keys from PHP function @c iptcparse.
*/
private static function mapMetadataKeys($array) {
$metadata = array();
if ($array === false) {
return $metadata;
}
foreach ($array as $key => $value) {
@list($recordid, $tagid) = explode('#', $key, 2); // key = record number + # + tag ID
$recordid = (int) $recordid;
$tagid = (int) $tagid;
switch ($recordid) {
case 1: // envelope record
if (isset(self::$enveloperecord[$tagid])) {
$tagname = self::$enveloperecord[$tagid];
$metadata[$tagname] = self::canonicalizeMetadataValue($tagname, $value);
}
break;
case 2: // application record
if (isset(self::$applicationrecord[$tagid])) {
$tagname = self::$applicationrecord[$tagid];
$metadata[$tagname] = self::canonicalizeMetadataValue($tagname, $value);
}
break;
}
}
if (!isset($metadata['Coded Character Set'])) { // assume cp1252 (Latin1) if no character set is specified
$charset = 'cp1252';
} else {
$charset = $metadata['Coded Character Set'];
}
if ($charset != 'utf-8' && extension_loaded('iconv')) {
foreach ($metadata as $key => &$value) {
if (is_array($value)) {
foreach ($value as &$elementvalue) {
$elementvalue = self::convertCharacterEncoding($charset, 'utf-8', $elementvalue);
}
} else {
$value = self::convertCharacterEncoding($charset, 'utf-8', $value);
}
}
}
unset($metadata['Envelope Record Version']);
unset($metadata['Coded Character Set']);
unset($metadata['Application Record Version']);
return $metadata;
}
private static function getIptcData($imagefile) {
$info = array();
$size = fsx::getimagesize($imagefile, $info);
if ($size !== false && isset($info["APP13"])) {
return self::mapMetadataKeys(iptcparse($info["APP13"]));
} else {
return false;
}
}
private static function getExifData($imagefile) {
if (!function_exists('exif_read_data')) {
return false;
}
if (($exifdata = @exif_read_data($imagefile, 'EXIF')) === false) {
return false;
} else {
// ISOSpeed
if (isset($exifdata['ISOSpeedRatings'])) {
$iso = $exifdata['ISOSpeedRatings'];
} elseif (isset($exifdata['MakerNote']) && isset($exifdata['ModeArray'])) {
// add ISO for PowerShot cameras
switch (@$exifdata['ModeArray'][16]) {
case 15: $iso = 'auto'; break;
case 16: $iso = '50'; break;
case 17: $iso = '100'; break;
case 18: $iso = '200'; break;
case 19: $iso = '400'; break;
}
}
if (isset($iso)) {
$exifdata['ISOSpeed'] = $iso;
}
// ComponentsConfiguration
if (isset($exifdata['ComponentsConfiguration'])) {
$value = $exifdata['ComponentsConfiguration'];
$components = array();
for ($k = 0; $k < strlen($value); $k++) {
switch (ord($value{$k})) {
case 1: $components[] = 'Y'; break;
case 2: $components[] = 'Cb'; break;
case 3: $components[] = 'Cr'; break;
case 4: $components[] = 'R'; break;
case 5: $components[] = 'G'; break;
case 6: $components[] = 'B'; break;
}
}
$exifdata['ComponentsConfiguration'] = implode(', ', $components);
}
// FileSource
if (isset($exifdata['FileSource']) && ord($exifdata['FileSource']) == 3) {
$exifdata['FileSource'] = 'Digital Still Camera';
}
// SceneType
if (isset($exifdata['SceneType']) && ord($exifdata['SceneType']) == 1) {
$exifdata['SceneType'] = 'Directly photographed image';
}
// remove sections of little interest
unset($exifdata['SectionsFound']);
unset($exifdata['Exif_IFD_Pointer']);
unset($exifdata['COMPUTED']);
unset($exifdata['THUMBNAIL']);
unset($exifdata['ImageInfo']);
unset($exifdata['MakerNote']); // proprietary data by camera manufacturers, no standardized format
unset($exifdata['ModeArray']);
foreach ($exifdata as $key => $value) {
if (strpos($key, 'UndefinedTag:') === 0) { // tags unrecognized by PHP
unset($exifdata[$key]);
continue;
}
}
return $exifdata;
}
}
/**
* Returns IPTC metadata for an image.
* @param {string} $image_file The full path to a file from which to extract embedded metadata.
* @param {string} $type The type of embedded metadata to extract from the file.
*/
public static function getImageMetadata($image_file, $type) {
switch ($type) {
case 'none':
$use_iptc = false;
$use_iptc_minimal_tag_set = false;
$use_exif = false;
break;
case 'minimal':
$use_iptc = true;
$use_iptc_minimal_tag_set = true;
$use_exif = false;
break;
case 'iptc':
$use_iptc = true;
$use_iptc_minimal_tag_set = false;
$use_exif = false;
break;
case 'exif':
$use_iptc = false;
$use_iptc_minimal_tag_set = false;
$use_exif = true;
break;
case 'all':
case 'default':
default:
$use_iptc = true;
$use_iptc_minimal_tag_set = false;
$use_exif = true;
}
if ($use_iptc) { // whether to include IPTC information in metadata
$iptcdata = self::getIptcData($image_file);
if ($use_iptc_minimal_tag_set && is_array($iptcdata)) {
$iptc_minimal_tag_set = array(
'By-line'=>true,
'By-line Title'=>true,
'Caption-Abstract'=>true,
'Contact'=>true,
'Copyright Notice'=>true,
'Credit'=>true,
'Headline'=>true,
'Image Orientation'=>true,
'Image Type'=>true,
'Local Caption'=>true
);
$iptcdata = array_filter($iptcdata, function($key) use($iptc_minimal_tag_set) {
return $iptc_minimal_tag_set[$key];
}, ARRAY_FILTER_USE_KEY);
}
} else {
$iptcdata = false;
}
if ($use_exif) { // whether to include EXIF information in metadata
$exifdata = self::getExifData($image_file);
} else {
$exifdata = false;
}
if (is_array($iptcdata) && is_array($exifdata)) {
return array_merge($iptcdata, $exifdata);
} elseif (is_array($iptcdata)) {
return $iptcdata;
} elseif (is_array($exifdata)) {
return $exifdata;
} else {
return false;
}
}
}