* @return array Data about image
*
*/
-function serendipity_getImageData($sRelativePath) {
+function &serendipity_getImageData($sRelativePath) {
global $serendipity;
// First, peel off the file name from the path
$show[$idx] =& $media['internal'];
$show[$idx]['image_id'] = $media['image_id'];
+
serendipity_prepareMedia($show[$idx]);
+ if (!is_array($props['base_metadata'])) {
+ $show[$idx]['metadata'] =& serendipity_getMetaData($show[$idx]['realfile'], $show[$idx]['header']);
+ } else {
+ $show[$idx]['metadata'] = $props['base_metadata'];
+ }
foreach($dprops AS $prop) {
$type = 'input';
serendipity_db_escape_string($val));
serendipity_db_query($q);
}
+
+ $s9y_img = $media['internal'];
+ $s9y_img['image_id'] = $media['image_id'];
+ serendipity_prepareMedia($s9y_img);
+ $s9y_img['metadata'] =& serendipity_getMetaData($s9y_img['realfile'], $s9y_img['header']);
+ serendipity_db_query("DELETE FROM {$serendipity['dbPrefix']}mediaproperties
+ WHERE mediaid = " . (int)$media['image_id'] . "
+ property_group = 'base_metadata'");
+ foreach($s9y_img['metadata'] AS $maingroup => $items) {
+ foreach($items AS $key => $val) {
+ $q = sprintf("INSERT INTO {$serendipity['dbPrefix']}mediaproperties
+ (mediaid, property_group, property_subgroup, property, value)
+ VALUES (%d, 'base_metadata', '%s', '%s', '%s')",
+ $media['image_id'],
+ $maingroup,
+ serendipity_db_escape_string($key),
+ serendipity_db_escape_string($val));
+ serendipity_db_query($q);
+ }
+ }
}
foreach($serendipity['POST']['mediaKeywords'] AS $id => $keywords) {
'image_id' => $serendipity['POST']['mediaProperties'][0]['image_id'],
);
-
return $array;
}
foreach($rows AS $row) {
if (empty($row['property_subgroup'])) {
$props[$row['property_group']][$row['property']] = $row['value'];
+ } else {
+ $props[$row['property_group']][$row['property_subgroup']][$row['property']] = $row['value'];
}
}
}
if (!isset($file['imgsrc'])) {
$file['imgsrc'] = $serendipity['uploadHTTPPath'] . $file['path'] . $file['name'] . (!empty($file['thumbnail_name']) ? '.' . $file['thumbnail_name'] : '') . '.' . $file['extension'];
}
- $file['dim'] = @getimagesize($img);
+ $file['dim'] = @getimagesize($img, $file['header']);
$file['is_image'] = serendipity_isImage($file);
$file['full_file'] = $serendipity['serendipityHTTPPath'] . $serendipity['uploadHTTPPath'] . $file['path'] . $file['name'] . '.'. $file['extension'];
+ $file['realfile'] = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $file['path'] . $file['name'] . '.'. $file['extension'];
if ($full_perm || $serendipity['authorid'] == $file['authorid'] || $file['authorid'] == '0') {
$file['is_editable'] = true;
* @param boolean Whether to show maintenance task items
* @param int how many media items to display per row
* @param boolean Enclose within a table cell?
+ * @param array Additional Smarty variables
* @return boolean
*
*/
}
return true;
-}
\ No newline at end of file
+}
+
+/**
+ * Convert a IPTC/EXIF/XMP item
+ *
+ * @param string The content
+ * @param string The type of the content
+ * @return string The converted content
+ *
+ */
+function serendipity_metaFieldConvert(&$item, $type) {
+ switch($type) {
+ case 'math':
+ $parts = explode('/', $item);
+ return ($parts[0] / $parts[1]);
+ break;
+
+ case 'or':
+ if ($item == '1') {
+ return 'Landscape';
+ } else {
+ return 'Portrait';
+ }
+
+ case 'date':
+ return strtotime($item);
+ break;
+
+ case 'date2':
+ $parts = explode(':', $item);
+ return mktime($parts[3], $parts[4], $parts[5], $parts[1], $parts[2], $parts[0]);
+ break;
+
+ case 'rdf':
+ if (preg_match('@<rdf:li[^>]*>(.*)</rdf:li>@i', $item, $ret)) {
+ return $ret[1];
+ }
+ break;
+
+ case 'text':
+ default:
+ return trim($item);
+ break;
+ }
+
+ return '';
+}
+
+/**
+ * Get the RAW media header data (XMP)
+ *
+ * @param string Filename
+ * @return array The raw media header data
+ *
+ * Inspired, but rewritten, by "PHP JPEG Metadata Toolkit" from http://electronics.ozhiker.com.
+ * Code is GPL so sadly we couldn't bundle that GREAT library.
+ */
+function serendipity_getMediaRaw($filename) {
+ $abort = false;
+
+ $f = @fopen($filename, 'rb');
+ $ret = array();
+ if (!$f) {
+ return $ret;
+ }
+
+ $filedata = fread($f, 2);
+
+ if ($filedata != "\xFF\xD8") {
+ fclose($f);
+ return $ret;
+ }
+
+ $filedata = fread($f, 2);
+
+ if ($filedata{0} != "\xFF") {
+ fclose($f);
+ return $ret;
+ }
+
+ while (!$abort && !feof($f) && $filedata{1} != "\xD9") {
+ if ((ord($filedata{1}) < 0xD0) || (ord($filedata{1}) > 0xD7)) {
+ $ordret = fread($f, 2);
+ $ordstart = ftell($f);
+ $int = unpack('nsize', $ordret);
+
+ if (ord($filedata{1}) == 225) {
+ $content = fread($f, $int['size'] - 2);
+
+ if (substr($content, 0, 24) == 'http://ns.adobe.com/xap/') {
+ $ret[] = array(
+ 'ord' => ord($filedata{1}),
+ 'ordstart' => $ordstart,
+ 'int' => $int,
+ 'content' => $content
+ );
+ }
+ } else {
+ fseek($f, $int['size'] - 2, SEEK_CUR);
+ }
+ }
+
+ if ($filedata{1} == "\xDA") {
+ $abort = true;
+ } else {
+ $filedata = fread($f, 2);
+ if ($filedata{0} != "\xFF") {
+ fclose($f);
+ return $ret;
+ }
+ }
+ }
+
+ fclose($f);
+
+ return $ret;
+}
+
+/**
+ * Get the IPTC/EXIF/XMP media metadata
+ *
+ * @param string Filename
+ * @return array The raw media header data
+ *
+ */
+function &serendipity_getMetaData($file, &$info) {
+ # Fields taken from: http://demo.imagefolio.com/demo/ImageFolio31_files/skins/cool_blue/images/iptc.html
+ static $IPTC_Fields = array(
+ '2#005' => 'ObjectName',
+ '2#025' => 'Keywords',
+ '2#026' => 'LocationCode',
+ '2#027' => 'LocationName',
+ '2#030' => 'ReleaseDate',
+ '2#035' => 'ReleaseTime',
+ '2#037' => 'ExpirationDate',
+ '2#038' => 'ExpirationTime',
+ '2#055' => 'DateCreated',
+ '2#060' => 'TimeCreated',
+ '2#062' => 'DigitalDateCreated',
+ '2#063' => 'DigitalTimeCreated',
+ '2#065' => 'Software',
+ '2#070' => 'SoftwareVersion',
+ '2#080' => 'Photographer',
+ '2#085' => 'Photographer Name',
+ '2#090' => 'PhotoLocation',
+ '2#092' => 'PhotoLocation2',
+ '2#095' => 'PhotoState',
+ '2#100' => 'PhotoCountryCode',
+ '2#101' => 'PhotoCountry',
+ '2#105' => 'Title',
+ '2#110' => 'Credits',
+ '2#115' => 'Source',
+ '2#116' => 'Copyright',
+ '2#118' => 'Contact',
+ '2#120' => 'Description',
+ '2#131' => 'Orientation',
+ '2#150' => 'AudioType',
+ '2#151' => 'AudioSamplingRate',
+ '2#152' => 'AudioSamplingResolution',
+ '2#153' => 'AudioDuration'
+ );
+
+ static $ExifFields = array(
+ 'IFD0' => array(
+ 'Make' => array('type' => 'text', 'name' => 'CameraMaker'),
+ 'Model' => array('type' => 'text', 'name' => 'CameraModel'),
+ 'Orientation' => array('type' => 'or', 'name' => 'Orientation'),
+ 'XResolution' => array('type' => 'math', 'name' => 'XResolution'),
+ 'YResolution' => array('type' => 'math', 'name' => 'YResolution'),
+ 'Software' => array('type' => 'text', 'name' => 'Software'),
+ 'DateTime' => array('type' => 'date2', 'name' => 'DateCreated'),
+ 'Artist' => array('type' => 'text', 'name' => 'Creator'),
+ ),
+
+ 'EXIF' => array(
+ 'ExposureTime' => array('type' => 'math', 'name' => 'ExposureTime'),
+ 'ApertureValue' => array('type' => 'math', 'name' => 'ApertureValue'),
+ 'MaxApertureValue' => array('type' => 'math', 'name' => 'MaxApertureValue'),
+ 'ISOSpeedRatings' => array('type' => 'text', 'name' => 'ISOSpeedRatings'),
+ 'DateTimeOriginal' => array('type' => 'date2', 'name' => 'DateCreated'),
+ 'MeteringMode' => array('type' => 'text', 'name' => 'MeteringMode'),
+ 'FNumber' => array('type' => 'math', 'name' => 'FNumber'),
+ 'ExposureProgram' => array('type' => 'text', 'name' => 'ExposureProgram'),
+ 'FocalLength' => array('type' => 'math', 'name' => 'FocalLength'),
+ 'WhiteBalance' => array('type' => 'text', 'name' => 'WhiteBalance'),
+ 'DigitalZoomRatio' => array('type' => 'math', 'name' => 'DigitalZoomRatio'),
+ 'FocalLengthIn35mmFilm' => array('type' => 'text', 'name' => 'FocalLengthIn35mmFilm'),
+ 'Flash' => array('type' => 'text', 'name' => 'Flash'),
+ 'Fired' => array('type' => 'text', 'name' => 'FlashFired'),
+ 'RedEyeMode' => array('type' => 'text', 'name' => 'RedEyeMode'),
+ )
+ );
+
+ static $xmpPatterns = array(
+ 'tiff:Orientation' => array('type' => 'or', 'name' => 'Orientation'),
+ 'tiff:XResolution' => array('type' => 'math', 'name' => 'XResolution'),
+ 'tiff:YResolution' => array('type' => 'math', 'name' => 'YResolution'),
+ 'tiff:Make' => array('type' => 'text', 'name' => 'CameraMaker'),
+ 'tiff:Model' => array('type' => 'text', 'name' => 'CameraModel'),
+ 'xap:ModifyDate' => array('type' => 'date', 'name' => 'DateModified'),
+ 'xap:CreatorTool' => array('type' => 'text', 'name' => 'Software'),
+ 'xap:CreateDate' => array('type' => 'date', 'name' => 'DateCreated'),
+ 'xap:MetadataDate' => array('type' => 'date', 'name' => 'DateMetadata'),
+
+ 'exif:ExposureTime' => array('type' => 'math', 'name' => 'ExposureTime'),
+ 'exif:ApertureValue' => array('type' => 'math', 'name' => 'ApertureValue'),
+ 'exif:MaxApertureValue' => array('type' => 'math', 'name' => 'MaxApertureValue'),
+ 'exif:ISOSpeedRatings' => array('type' => 'text', 'name' => 'ISOSpeedRatings'),
+ 'exif:DateTimeOriginal' => array('type' => 'date', 'name' => 'DateCreated'),
+ 'exif:MeteringMode' => array('type' => 'text', 'name' => 'MeteringMode'),
+ 'exif:FNumber' => array('type' => 'math', 'name' => 'FNumber'),
+ 'exif:ExposureProgram' => array('type' => 'text', 'name' => 'ExposureProgram'),
+ 'exif:FocalLength' => array('type' => 'math', 'name' => 'FocalLength'),
+ 'exif:WhiteBalance' => array('type' => 'text', 'name' => 'WhiteBalance'),
+ 'exif:DigitalZoomRatio' => array('type' => 'math', 'name' => 'DigitalZoomRatio'),
+ 'exif:FocalLengthIn35mmFilm' => array('type' => 'text', 'name' => 'FocalLengthIn35mmFilm'),
+ 'exif:Fired' => array('type' => 'text', 'name' => 'FlashFired'),
+ 'exif:RedEyeMode' => array('type' => 'text', 'name' => 'RedEyeMode'),
+
+ 'dc:title' => array('type' => 'rdf', 'name' => 'Title'),
+ 'dc:creator' => array('type' => 'rdf', 'name' => 'Creator'),
+ );
+
+ $ret = array();
+
+ if (!file_exists($file)) {
+ return $ret;
+ }
+
+ if (function_exists('iptcparse') && is_array($info) && isset($info['APP13'])) {
+ $iptc = iptcparse($info['APP13']);
+ foreach($IPTC_Fields AS $field => $desc) {
+ if ($iptc[$field]) {
+ if (is_array($iptc[$field])) {
+ $ret['IPTC'][$desc] = trim(implode(';', $iptc[$field]));
+ } else {
+ $ret['IPTC'][$desc] = trim($iptc[$field]);
+ }
+ }
+ }
+ }
+
+ if (function_exists('exif_read_data') && is_array($info)) {
+ $exif = @exif_read_data($file, 'FILE,COMPUTED,ANY_TAG,IFD0,COMMENT,EXIF', true, false);
+ if (is_array($exif)) {
+ foreach($ExifFields AS $Exifgroup => $ExifField) {
+ foreach($ExifField AS $ExifName => $ExifItem) {
+ if (!isset($exif[$Exifgroup][$ExifName])) {
+ continue;
+ }
+ $ret['EXIF'][$ExifItem['name']] = serendipity_metaFieldConvert($exif[$Exifgroup][$ExifName], $ExifItem['type']);
+ if ($ret['EXIF'][$item['name']] == $ret['IPTC'][$item['name']]) {
+ unset($ret['IPTC'][$item['name']]);
+ }
+ }
+ }
+ }
+ }
+
+ $xmp = serendipity_getMediaRaw($file);
+ foreach($xmp AS $xmp_data) {
+ if (empty($xmp_data['content'])) {
+ continue;
+ }
+ foreach($xmpPatterns AS $lookup => $item) {
+ if (preg_match('@<' . $lookup . '>(.*)</' . $lookup . '>@', $xmp_data['content'], $match)) {
+ $ret['XMP'][$item['name']] = serendipity_metaFieldConvert($match[1], $item['type']);
+ if ($ret['EXIF'][$item['name']] == $ret['XMP'][$item['name']]) {
+ unset($ret['EXIF'][$item['name']]);
+ }
+ }
+ }
+ }
+
+ return $ret;
+}