MediaWiki  master
ExifBitmapHandler.php
Go to the documentation of this file.
1 <?php
33  public const BROKEN_FILE = '-1';
34 
36  public const OLD_BROKEN_FILE = '0';
37 
38  public function convertMetadataVersion( $metadata, $version = 1 ) {
39  // basically flattens arrays.
40  $version = intval( explode( ';', $version, 2 )[0] );
41  if ( $version < 1 || $version >= 2 ) {
42  return $metadata;
43  }
44 
45  $avoidHtml = true;
46 
47  if ( !is_array( $metadata ) ) {
48  $metadata = unserialize( $metadata );
49  }
50  if ( !isset( $metadata['MEDIAWIKI_EXIF_VERSION'] ) || $metadata['MEDIAWIKI_EXIF_VERSION'] != 2 ) {
51  return $metadata;
52  }
53 
54  // Treat Software as a special case because in can contain
55  // an array of (SoftwareName, Version).
56  if ( isset( $metadata['Software'] )
57  && is_array( $metadata['Software'] )
58  && is_array( $metadata['Software'][0] )
59  && isset( $metadata['Software'][0][0] )
60  && isset( $metadata['Software'][0][1] )
61  ) {
62  $metadata['Software'] = $metadata['Software'][0][0] . ' (Version '
63  . $metadata['Software'][0][1] . ')';
64  }
65 
66  $formatter = new FormatMetadata;
67 
68  // ContactInfo also has to be dealt with specially
69  if ( isset( $metadata['Contact'] ) ) {
70  $metadata['Contact'] =
71  $formatter->collapseContactInfo(
72  $metadata['Contact'] );
73  }
74 
75  foreach ( $metadata as &$val ) {
76  if ( is_array( $val ) ) {
77  $val = $formatter->flattenArrayReal( $val, 'ul', $avoidHtml );
78  }
79  }
80  $metadata['MEDIAWIKI_EXIF_VERSION'] = 1;
81 
82  return $metadata;
83  }
84 
90  public function isMetadataValid( $image, $metadata ) {
91  global $wgShowEXIF;
92  if ( !$wgShowEXIF ) {
93  # Metadata disabled and so an empty field is expected
94  return self::METADATA_GOOD;
95  }
96  if ( $metadata === self::OLD_BROKEN_FILE ) {
97  # Old special value indicating that there is no Exif data in the file.
98  # or that there was an error well extracting the metadata.
99  wfDebug( __METHOD__ . ": back-compat version" );
100 
102  }
103  if ( $metadata === self::BROKEN_FILE ) {
104  return self::METADATA_GOOD;
105  }
106  Wikimedia\suppressWarnings();
107  $exif = unserialize( $metadata );
108  Wikimedia\restoreWarnings();
109  if ( !isset( $exif['MEDIAWIKI_EXIF_VERSION'] )
110  || $exif['MEDIAWIKI_EXIF_VERSION'] != Exif::version()
111  ) {
112  if ( isset( $exif['MEDIAWIKI_EXIF_VERSION'] )
113  && $exif['MEDIAWIKI_EXIF_VERSION'] == 1
114  ) {
115  // back-compatible but old
116  wfDebug( __METHOD__ . ": back-compat version" );
117 
119  }
120  # Wrong (non-compatible) version
121  wfDebug( __METHOD__ . ": wrong version" );
122 
123  return self::METADATA_BAD;
124  }
125 
126  return self::METADATA_GOOD;
127  }
128 
134  public function formatMetadata( $image, $context = false ) {
135  $meta = $this->getCommonMetaArray( $image );
136  if ( count( $meta ) === 0 ) {
137  return false;
138  }
139 
140  return $this->formatMetadataHelper( $meta, $context );
141  }
142 
143  public function getCommonMetaArray( File $file ) {
144  $metadata = $file->getMetadata();
145  if ( $metadata === self::OLD_BROKEN_FILE
146  || $metadata === self::BROKEN_FILE
147  || $this->isMetadataValid( $file, $metadata ) === self::METADATA_BAD
148  ) {
149  // So we don't try and display metadata from PagedTiffHandler
150  // for example when using InstantCommons.
151  return [];
152  }
153 
154  $exif = unserialize( $metadata );
155  if ( !$exif ) {
156  return [];
157  }
158  unset( $exif['MEDIAWIKI_EXIF_VERSION'] );
159 
160  return $exif;
161  }
162 
163  public function getMetadataType( $image ) {
164  return 'exif';
165  }
166 
175  public function getImageSize( $image, $path ) {
176  $gis = parent::getImageSize( $image, $path );
177 
178  // Don't just call $image->getMetadata(); FSFile::getPropsFromPath() calls us with a bogus object.
179  // This may mean we read EXIF data twice on initial upload.
180  if ( $this->autoRotateEnabled() ) {
181  $meta = $this->getMetadata( $image, $path );
182  $rotation = $this->getRotationForExif( $meta );
183  } else {
184  $rotation = 0;
185  }
186 
187  if ( $rotation == 90 || $rotation == 270 ) {
188  $width = $gis[0];
189  $gis[0] = $gis[1];
190  $gis[1] = $width;
191  }
192 
193  return $gis;
194  }
195 
208  public function getRotation( $file ) {
209  if ( !$this->autoRotateEnabled() ) {
210  return 0;
211  }
212 
213  $data = $file->getMetadata();
214 
215  return $this->getRotationForExif( $data );
216  }
217 
226  protected function getRotationForExif( $data ) {
227  if ( !$data ) {
228  return 0;
229  }
230  Wikimedia\suppressWarnings();
231  $data = unserialize( $data );
232  Wikimedia\restoreWarnings();
233  if ( isset( $data['Orientation'] ) ) {
234  # See http://sylvana.net/jpegcrop/exif_orientation.html
235  switch ( $data['Orientation'] ) {
236  case 8:
237  return 90;
238  case 3:
239  return 180;
240  case 6:
241  return 270;
242  default:
243  return 0;
244  }
245  }
246 
247  return 0;
248  }
249 }
ExifBitmapHandler
Stuff specific to JPEG and (built-in) TIFF handler.
Definition: ExifBitmapHandler.php:31
ExifBitmapHandler\getImageSize
getImageSize( $image, $path)
Wrapper for base classes ImageHandler::getImageSize() that checks for rotation reported from metadata...
Definition: ExifBitmapHandler.php:175
$file
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition: router.php:42
ExifBitmapHandler\formatMetadata
formatMetadata( $image, $context=false)
Definition: ExifBitmapHandler.php:134
ExifBitmapHandler\getCommonMetaArray
getCommonMetaArray(File $file)
Get an array of standard (FormatMetadata type) metadata values.
Definition: ExifBitmapHandler.php:143
MediaHandler\METADATA_COMPATIBLE
const METADATA_COMPATIBLE
Definition: MediaHandler.php:41
File
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition: File.php:63
BitmapHandler
Generic handler for bitmap images.
Definition: BitmapHandler.php:32
Exif\version
static version()
#-
Definition: Exif.php:582
wfDebug
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
Definition: GlobalFunctions.php:909
FormatMetadata\collapseContactInfo
collapseContactInfo( $vals)
Format the contact info field into a single value.
Definition: FormatMetadata.php:1466
ExifBitmapHandler\getMetadataType
getMetadataType( $image)
Get a string describing the type of metadata, for display purposes.
Definition: ExifBitmapHandler.php:163
MediaHandler\getMetadata
getMetadata( $image, $path)
Get handler-specific metadata which will be saved in the img_metadata field.
Definition: MediaHandler.php:130
BitmapHandler\autoRotateEnabled
autoRotateEnabled()
Definition: BitmapHandler.php:565
ExifBitmapHandler\convertMetadataVersion
convertMetadataVersion( $metadata, $version=1)
Convert metadata version.
Definition: ExifBitmapHandler.php:38
FormatMetadata
Format Image metadata values into a human readable form.
Definition: FormatMetadata.php:53
ExifBitmapHandler\getRotation
getRotation( $file)
On supporting image formats, try to read out the low-level orientation of the file and return the ang...
Definition: ExifBitmapHandler.php:208
ExifBitmapHandler\OLD_BROKEN_FILE
const OLD_BROKEN_FILE
Outdated error extracting metadata.
Definition: ExifBitmapHandler.php:36
unserialize
unserialize( $serialized)
Definition: ApiMessageTrait.php:146
MediaHandler\formatMetadataHelper
formatMetadataHelper( $metadataArray, $context=false)
sorts the visible/invisible field.
Definition: MediaHandler.php:543
$path
$path
Definition: NoLocalSettings.php:25
MediaHandler\METADATA_BAD
const METADATA_BAD
Definition: MediaHandler.php:40
ExifBitmapHandler\isMetadataValid
isMetadataValid( $image, $metadata)
Definition: ExifBitmapHandler.php:90
ExifBitmapHandler\BROKEN_FILE
const BROKEN_FILE
Error extracting metadata.
Definition: ExifBitmapHandler.php:33
ExifBitmapHandler\getRotationForExif
getRotationForExif( $data)
Given a chunk of serialized Exif metadata, return the orientation as degrees of rotation.
Definition: ExifBitmapHandler.php:226
$wgShowEXIF
$wgShowEXIF
Show Exif data, on by default if available.
Definition: DefaultSettings.php:884
MediaHandler\METADATA_GOOD
const METADATA_GOOD
Definition: MediaHandler.php:39