MediaWiki
REL1_19
|
00001 <?php 00013 class ExifBitmapHandler extends BitmapHandler { 00014 00015 const BROKEN_FILE = '-1'; // error extracting metadata 00016 const OLD_BROKEN_FILE = '0'; // outdated error extracting metadata. 00017 00018 function convertMetadataVersion( $metadata, $version = 1 ) { 00019 // basically flattens arrays. 00020 $version = explode(';', $version, 2); 00021 $version = intval($version[0]); 00022 if ( $version < 1 || $version >= 2 ) { 00023 return $metadata; 00024 } 00025 00026 $avoidHtml = true; 00027 00028 if ( !is_array( $metadata ) ) { 00029 $metadata = unserialize( $metadata ); 00030 } 00031 if ( !isset( $metadata['MEDIAWIKI_EXIF_VERSION'] ) || $metadata['MEDIAWIKI_EXIF_VERSION'] != 2 ) { 00032 return $metadata; 00033 } 00034 00035 // Treat Software as a special case because in can contain 00036 // an array of (SoftwareName, Version). 00037 if (isset( $metadata['Software'] ) 00038 && is_array( $metadata['Software'] ) 00039 && is_array( $metadata['Software'][0]) 00040 && isset( $metadata['Software'][0][0] ) 00041 && isset( $metadata['Software'][0][1]) 00042 ) { 00043 $metadata['Software'] = $metadata['Software'][0][0] . ' (Version ' 00044 . $metadata['Software'][0][1] . ')'; 00045 } 00046 00047 // ContactInfo also has to be dealt with specially 00048 if ( isset( $metadata['Contact'] ) ) { 00049 $metadata['Contact'] = 00050 FormatMetadata::collapseContactInfo( 00051 $metadata['Contact'] ); 00052 } 00053 00054 foreach ( $metadata as &$val ) { 00055 if ( is_array( $val ) ) { 00056 $val = FormatMetadata::flattenArray( $val, 'ul', $avoidHtml ); 00057 } 00058 } 00059 $metadata['MEDIAWIKI_EXIF_VERSION'] = 1; 00060 return $metadata; 00061 } 00062 00063 function isMetadataValid( $image, $metadata ) { 00064 global $wgShowEXIF; 00065 if ( !$wgShowEXIF ) { 00066 # Metadata disabled and so an empty field is expected 00067 return self::METADATA_GOOD; 00068 } 00069 if ( $metadata === self::OLD_BROKEN_FILE ) { 00070 # Old special value indicating that there is no EXIF data in the file. 00071 # or that there was an error well extracting the metadata. 00072 wfDebug( __METHOD__ . ": back-compat version\n"); 00073 return self::METADATA_COMPATIBLE; 00074 } 00075 if ( $metadata === self::BROKEN_FILE ) { 00076 return self::METADATA_GOOD; 00077 } 00078 wfSuppressWarnings(); 00079 $exif = unserialize( $metadata ); 00080 wfRestoreWarnings(); 00081 if ( !isset( $exif['MEDIAWIKI_EXIF_VERSION'] ) || 00082 $exif['MEDIAWIKI_EXIF_VERSION'] != Exif::version() ) 00083 { 00084 if ( isset( $exif['MEDIAWIKI_EXIF_VERSION'] ) && 00085 $exif['MEDIAWIKI_EXIF_VERSION'] == 1 ) 00086 { 00087 //back-compatible but old 00088 wfDebug( __METHOD__.": back-compat version\n" ); 00089 return self::METADATA_COMPATIBLE; 00090 } 00091 # Wrong (non-compatible) version 00092 wfDebug( __METHOD__.": wrong version\n" ); 00093 return self::METADATA_BAD; 00094 } 00095 return self::METADATA_GOOD; 00096 } 00097 00102 function formatMetadata( $image ) { 00103 $metadata = $image->getMetadata(); 00104 if ( $metadata === self::OLD_BROKEN_FILE || 00105 $metadata === self::BROKEN_FILE || 00106 $this->isMetadataValid( $image, $metadata ) === self::METADATA_BAD ) 00107 { 00108 // So we don't try and display metadata from PagedTiffHandler 00109 // for example when using InstantCommons. 00110 return false; 00111 } 00112 00113 $exif = unserialize( $metadata ); 00114 if ( !$exif ) { 00115 return false; 00116 } 00117 unset( $exif['MEDIAWIKI_EXIF_VERSION'] ); 00118 if ( count( $exif ) == 0 ) { 00119 return false; 00120 } 00121 return $this->formatMetadataHelper( $exif ); 00122 } 00123 00124 function getMetadataType( $image ) { 00125 return 'exif'; 00126 } 00127 00136 function getImageSize( $image, $path ) { 00137 global $wgEnableAutoRotation; 00138 $gis = parent::getImageSize( $image, $path ); 00139 00140 // Don't just call $image->getMetadata(); FSFile::getPropsFromPath() calls us with a bogus object. 00141 // This may mean we read EXIF data twice on initial upload. 00142 if ( $wgEnableAutoRotation ) { 00143 $meta = $this->getMetadata( $image, $path ); 00144 $rotation = $this->getRotationForExif( $meta ); 00145 } else { 00146 $rotation = 0; 00147 } 00148 00149 if ($rotation == 90 || $rotation == 270) { 00150 $width = $gis[0]; 00151 $gis[0] = $gis[1]; 00152 $gis[1] = $width; 00153 } 00154 return $gis; 00155 } 00156 00169 public function getRotation( $file ) { 00170 global $wgEnableAutoRotation; 00171 if ( !$wgEnableAutoRotation ) { 00172 return 0; 00173 } 00174 00175 $data = $file->getMetadata(); 00176 return $this->getRotationForExif( $data ); 00177 } 00178 00187 protected function getRotationForExif( $data ) { 00188 if ( !$data ) { 00189 return 0; 00190 } 00191 wfSuppressWarnings(); 00192 $data = unserialize( $data ); 00193 wfRestoreWarnings(); 00194 if ( isset( $data['Orientation'] ) ) { 00195 # See http://sylvana.net/jpegcrop/exif_orientation.html 00196 switch ( $data['Orientation'] ) { 00197 case 8: 00198 return 90; 00199 case 3: 00200 return 180; 00201 case 6: 00202 return 270; 00203 default: 00204 return 0; 00205 } 00206 } 00207 return 0; 00208 } 00209 } 00210