[ Index ] |
PHP Cross Reference of MediaWiki-1.24.0 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Handler for bitmap images with exif metadata. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 * http://www.gnu.org/copyleft/gpl.html 19 * 20 * @file 21 * @ingroup Media 22 */ 23 24 /** 25 * Stuff specific to JPEG and (built-in) TIFF handler. 26 * All metadata related, since both JPEG and TIFF support Exif. 27 * 28 * @ingroup Media 29 */ 30 class ExifBitmapHandler extends BitmapHandler { 31 const BROKEN_FILE = '-1'; // error extracting metadata 32 const OLD_BROKEN_FILE = '0'; // outdated error extracting metadata. 33 34 function convertMetadataVersion( $metadata, $version = 1 ) { 35 // basically flattens arrays. 36 $version = explode( ';', $version, 2 ); 37 $version = intval( $version[0] ); 38 if ( $version < 1 || $version >= 2 ) { 39 return $metadata; 40 } 41 42 $avoidHtml = true; 43 44 if ( !is_array( $metadata ) ) { 45 $metadata = unserialize( $metadata ); 46 } 47 if ( !isset( $metadata['MEDIAWIKI_EXIF_VERSION'] ) || $metadata['MEDIAWIKI_EXIF_VERSION'] != 2 ) { 48 return $metadata; 49 } 50 51 // Treat Software as a special case because in can contain 52 // an array of (SoftwareName, Version). 53 if ( isset( $metadata['Software'] ) 54 && is_array( $metadata['Software'] ) 55 && is_array( $metadata['Software'][0] ) 56 && isset( $metadata['Software'][0][0] ) 57 && isset( $metadata['Software'][0][1] ) 58 ) { 59 $metadata['Software'] = $metadata['Software'][0][0] . ' (Version ' 60 . $metadata['Software'][0][1] . ')'; 61 } 62 63 $formatter = new FormatMetadata; 64 65 // ContactInfo also has to be dealt with specially 66 if ( isset( $metadata['Contact'] ) ) { 67 $metadata['Contact'] = 68 $formatter->collapseContactInfo( 69 $metadata['Contact'] ); 70 } 71 72 foreach ( $metadata as &$val ) { 73 if ( is_array( $val ) ) { 74 $val = $formatter->flattenArrayReal( $val, 'ul', $avoidHtml ); 75 } 76 } 77 $metadata['MEDIAWIKI_EXIF_VERSION'] = 1; 78 79 return $metadata; 80 } 81 82 /** 83 * @param File $image 84 * @param array $metadata 85 * @return bool|int 86 */ 87 function isMetadataValid( $image, $metadata ) { 88 global $wgShowEXIF; 89 if ( !$wgShowEXIF ) { 90 # Metadata disabled and so an empty field is expected 91 return self::METADATA_GOOD; 92 } 93 if ( $metadata === self::OLD_BROKEN_FILE ) { 94 # Old special value indicating that there is no Exif data in the file. 95 # or that there was an error well extracting the metadata. 96 wfDebug( __METHOD__ . ": back-compat version\n" ); 97 98 return self::METADATA_COMPATIBLE; 99 } 100 if ( $metadata === self::BROKEN_FILE ) { 101 return self::METADATA_GOOD; 102 } 103 wfSuppressWarnings(); 104 $exif = unserialize( $metadata ); 105 wfRestoreWarnings(); 106 if ( !isset( $exif['MEDIAWIKI_EXIF_VERSION'] ) 107 || $exif['MEDIAWIKI_EXIF_VERSION'] != Exif::version() 108 ) { 109 if ( isset( $exif['MEDIAWIKI_EXIF_VERSION'] ) 110 && $exif['MEDIAWIKI_EXIF_VERSION'] == 1 111 ) { 112 //back-compatible but old 113 wfDebug( __METHOD__ . ": back-compat version\n" ); 114 115 return self::METADATA_COMPATIBLE; 116 } 117 # Wrong (non-compatible) version 118 wfDebug( __METHOD__ . ": wrong version\n" ); 119 120 return self::METADATA_BAD; 121 } 122 123 return self::METADATA_GOOD; 124 } 125 126 /** 127 * @param File $image 128 * @return array|bool 129 */ 130 function formatMetadata( $image ) { 131 $meta = $this->getCommonMetaArray( $image ); 132 if ( count( $meta ) === 0 ) { 133 return false; 134 } 135 136 return $this->formatMetadataHelper( $meta ); 137 } 138 139 public function getCommonMetaArray( File $file ) { 140 $metadata = $file->getMetadata(); 141 if ( $metadata === self::OLD_BROKEN_FILE 142 || $metadata === self::BROKEN_FILE 143 || $this->isMetadataValid( $file, $metadata ) === self::METADATA_BAD 144 ) { 145 // So we don't try and display metadata from PagedTiffHandler 146 // for example when using InstantCommons. 147 return array(); 148 } 149 150 $exif = unserialize( $metadata ); 151 if ( !$exif ) { 152 return array(); 153 } 154 unset( $exif['MEDIAWIKI_EXIF_VERSION'] ); 155 156 return $exif; 157 } 158 159 function getMetadataType( $image ) { 160 return 'exif'; 161 } 162 163 /** 164 * Wrapper for base classes ImageHandler::getImageSize() that checks for 165 * rotation reported from metadata and swaps the sizes to match. 166 * 167 * @param File $image 168 * @param string $path 169 * @return array 170 */ 171 function getImageSize( $image, $path ) { 172 $gis = parent::getImageSize( $image, $path ); 173 174 // Don't just call $image->getMetadata(); FSFile::getPropsFromPath() calls us with a bogus object. 175 // This may mean we read EXIF data twice on initial upload. 176 if ( $this->autoRotateEnabled() ) { 177 $meta = $this->getMetadata( $image, $path ); 178 $rotation = $this->getRotationForExif( $meta ); 179 } else { 180 $rotation = 0; 181 } 182 183 if ( $rotation == 90 || $rotation == 270 ) { 184 $width = $gis[0]; 185 $gis[0] = $gis[1]; 186 $gis[1] = $width; 187 } 188 189 return $gis; 190 } 191 192 /** 193 * On supporting image formats, try to read out the low-level orientation 194 * of the file and return the angle that the file needs to be rotated to 195 * be viewed. 196 * 197 * This information is only useful when manipulating the original file; 198 * the width and height we normally work with is logical, and will match 199 * any produced output views. 200 * 201 * @param File $file 202 * @return int 0, 90, 180 or 270 203 */ 204 public function getRotation( $file ) { 205 if ( !$this->autoRotateEnabled() ) { 206 return 0; 207 } 208 209 $data = $file->getMetadata(); 210 211 return $this->getRotationForExif( $data ); 212 } 213 214 /** 215 * Given a chunk of serialized Exif metadata, return the orientation as 216 * degrees of rotation. 217 * 218 * @param string $data 219 * @return int 0, 90, 180 or 270 220 * @todo FIXME: Orientation can include flipping as well; see if this is an issue! 221 */ 222 protected function getRotationForExif( $data ) { 223 if ( !$data ) { 224 return 0; 225 } 226 wfSuppressWarnings(); 227 $data = unserialize( $data ); 228 wfRestoreWarnings(); 229 if ( isset( $data['Orientation'] ) ) { 230 # See http://sylvana.net/jpegcrop/exif_orientation.html 231 switch ( $data['Orientation'] ) { 232 case 8: 233 return 90; 234 case 3: 235 return 180; 236 case 6: 237 return 270; 238 default: 239 return 0; 240 } 241 } 242 243 return 0; 244 } 245 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 14:03:12 2014 | Cross-referenced by PHPXref 0.7.1 |