MediaWiki  REL1_19
ExifBitmap.php
Go to the documentation of this file.
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