MediaWiki
REL1_22
|
00001 <?php 00030 class ExifBitmapHandler extends BitmapHandler { 00031 00032 const BROKEN_FILE = '-1'; // error extracting metadata 00033 const OLD_BROKEN_FILE = '0'; // outdated error extracting metadata. 00034 00035 function convertMetadataVersion( $metadata, $version = 1 ) { 00036 // basically flattens arrays. 00037 $version = explode( ';', $version, 2 ); 00038 $version = intval( $version[0] ); 00039 if ( $version < 1 || $version >= 2 ) { 00040 return $metadata; 00041 } 00042 00043 $avoidHtml = true; 00044 00045 if ( !is_array( $metadata ) ) { 00046 $metadata = unserialize( $metadata ); 00047 } 00048 if ( !isset( $metadata['MEDIAWIKI_EXIF_VERSION'] ) || $metadata['MEDIAWIKI_EXIF_VERSION'] != 2 ) { 00049 return $metadata; 00050 } 00051 00052 // Treat Software as a special case because in can contain 00053 // an array of (SoftwareName, Version). 00054 if ( isset( $metadata['Software'] ) 00055 && is_array( $metadata['Software'] ) 00056 && is_array( $metadata['Software'][0] ) 00057 && isset( $metadata['Software'][0][0] ) 00058 && isset( $metadata['Software'][0][1] ) 00059 ) { 00060 $metadata['Software'] = $metadata['Software'][0][0] . ' (Version ' 00061 . $metadata['Software'][0][1] . ')'; 00062 } 00063 00064 // ContactInfo also has to be dealt with specially 00065 if ( isset( $metadata['Contact'] ) ) { 00066 $metadata['Contact'] = 00067 FormatMetadata::collapseContactInfo( 00068 $metadata['Contact'] ); 00069 } 00070 00071 foreach ( $metadata as &$val ) { 00072 if ( is_array( $val ) ) { 00073 $val = FormatMetadata::flattenArray( $val, 'ul', $avoidHtml ); 00074 } 00075 } 00076 $metadata['MEDIAWIKI_EXIF_VERSION'] = 1; 00077 return $metadata; 00078 } 00079 00080 function isMetadataValid( $image, $metadata ) { 00081 global $wgShowEXIF; 00082 if ( !$wgShowEXIF ) { 00083 # Metadata disabled and so an empty field is expected 00084 return self::METADATA_GOOD; 00085 } 00086 if ( $metadata === self::OLD_BROKEN_FILE ) { 00087 # Old special value indicating that there is no Exif data in the file. 00088 # or that there was an error well extracting the metadata. 00089 wfDebug( __METHOD__ . ": back-compat version\n" ); 00090 return self::METADATA_COMPATIBLE; 00091 } 00092 if ( $metadata === self::BROKEN_FILE ) { 00093 return self::METADATA_GOOD; 00094 } 00095 wfSuppressWarnings(); 00096 $exif = unserialize( $metadata ); 00097 wfRestoreWarnings(); 00098 if ( !isset( $exif['MEDIAWIKI_EXIF_VERSION'] ) || 00099 $exif['MEDIAWIKI_EXIF_VERSION'] != Exif::version() ) 00100 { 00101 if ( isset( $exif['MEDIAWIKI_EXIF_VERSION'] ) && 00102 $exif['MEDIAWIKI_EXIF_VERSION'] == 1 ) 00103 { 00104 //back-compatible but old 00105 wfDebug( __METHOD__ . ": back-compat version\n" ); 00106 return self::METADATA_COMPATIBLE; 00107 } 00108 # Wrong (non-compatible) version 00109 wfDebug( __METHOD__ . ": wrong version\n" ); 00110 return self::METADATA_BAD; 00111 } 00112 return self::METADATA_GOOD; 00113 } 00114 00119 function formatMetadata( $image ) { 00120 $metadata = $image->getMetadata(); 00121 if ( $metadata === self::OLD_BROKEN_FILE || 00122 $metadata === self::BROKEN_FILE || 00123 $this->isMetadataValid( $image, $metadata ) === self::METADATA_BAD ) 00124 { 00125 // So we don't try and display metadata from PagedTiffHandler 00126 // for example when using InstantCommons. 00127 return false; 00128 } 00129 00130 $exif = unserialize( $metadata ); 00131 if ( !$exif ) { 00132 return false; 00133 } 00134 unset( $exif['MEDIAWIKI_EXIF_VERSION'] ); 00135 if ( count( $exif ) == 0 ) { 00136 return false; 00137 } 00138 return $this->formatMetadataHelper( $exif ); 00139 } 00140 00141 function getMetadataType( $image ) { 00142 return 'exif'; 00143 } 00144 00153 function getImageSize( $image, $path ) { 00154 global $wgEnableAutoRotation; 00155 $gis = parent::getImageSize( $image, $path ); 00156 00157 // Don't just call $image->getMetadata(); FSFile::getPropsFromPath() calls us with a bogus object. 00158 // This may mean we read EXIF data twice on initial upload. 00159 if ( $wgEnableAutoRotation ) { 00160 $meta = $this->getMetadata( $image, $path ); 00161 $rotation = $this->getRotationForExif( $meta ); 00162 } else { 00163 $rotation = 0; 00164 } 00165 00166 if ( $rotation == 90 || $rotation == 270 ) { 00167 $width = $gis[0]; 00168 $gis[0] = $gis[1]; 00169 $gis[1] = $width; 00170 } 00171 return $gis; 00172 } 00173 00186 public function getRotation( $file ) { 00187 global $wgEnableAutoRotation; 00188 if ( !$wgEnableAutoRotation ) { 00189 return 0; 00190 } 00191 00192 $data = $file->getMetadata(); 00193 return $this->getRotationForExif( $data ); 00194 } 00195 00205 protected function getRotationForExif( $data ) { 00206 if ( !$data ) { 00207 return 0; 00208 } 00209 wfSuppressWarnings(); 00210 $data = unserialize( $data ); 00211 wfRestoreWarnings(); 00212 if ( isset( $data['Orientation'] ) ) { 00213 # See http://sylvana.net/jpegcrop/exif_orientation.html 00214 switch ( $data['Orientation'] ) { 00215 case 8: 00216 return 90; 00217 case 3: 00218 return 180; 00219 case 6: 00220 return 270; 00221 default: 00222 return 0; 00223 } 00224 } 00225 return 0; 00226 } 00227 }