MediaWiki  master
ExifBitmapHandler.php
Go to the documentation of this file.
1 <?php
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 = intval( explode( ';', $version, 2 )[0] );
37  if ( $version < 1 || $version >= 2 ) {
38  return $metadata;
39  }
40 
41  $avoidHtml = true;
42 
43  if ( !is_array( $metadata ) ) {
44  $metadata = unserialize( $metadata );
45  }
46  if ( !isset( $metadata['MEDIAWIKI_EXIF_VERSION'] ) || $metadata['MEDIAWIKI_EXIF_VERSION'] != 2 ) {
47  return $metadata;
48  }
49 
50  // Treat Software as a special case because in can contain
51  // an array of (SoftwareName, Version).
52  if ( isset( $metadata['Software'] )
53  && is_array( $metadata['Software'] )
54  && is_array( $metadata['Software'][0] )
55  && isset( $metadata['Software'][0][0] )
56  && isset( $metadata['Software'][0][1] )
57  ) {
58  $metadata['Software'] = $metadata['Software'][0][0] . ' (Version '
59  . $metadata['Software'][0][1] . ')';
60  }
61 
62  $formatter = new FormatMetadata;
63 
64  // ContactInfo also has to be dealt with specially
65  if ( isset( $metadata['Contact'] ) ) {
66  $metadata['Contact'] =
67  $formatter->collapseContactInfo(
68  $metadata['Contact'] );
69  }
70 
71  foreach ( $metadata as &$val ) {
72  if ( is_array( $val ) ) {
73  $val = $formatter->flattenArrayReal( $val, 'ul', $avoidHtml );
74  }
75  }
76  $metadata['MEDIAWIKI_EXIF_VERSION'] = 1;
77 
78  return $metadata;
79  }
80 
86  public function isMetadataValid( $image, $metadata ) {
87  global $wgShowEXIF;
88  if ( !$wgShowEXIF ) {
89  # Metadata disabled and so an empty field is expected
90  return self::METADATA_GOOD;
91  }
92  if ( $metadata === self::OLD_BROKEN_FILE ) {
93  # Old special value indicating that there is no Exif data in the file.
94  # or that there was an error well extracting the metadata.
95  wfDebug( __METHOD__ . ": back-compat version\n" );
96 
98  }
99  if ( $metadata === self::BROKEN_FILE ) {
100  return self::METADATA_GOOD;
101  }
102  Wikimedia\suppressWarnings();
103  $exif = unserialize( $metadata );
104  Wikimedia\restoreWarnings();
105  if ( !isset( $exif['MEDIAWIKI_EXIF_VERSION'] )
106  || $exif['MEDIAWIKI_EXIF_VERSION'] != Exif::version()
107  ) {
108  if ( isset( $exif['MEDIAWIKI_EXIF_VERSION'] )
109  && $exif['MEDIAWIKI_EXIF_VERSION'] == 1
110  ) {
111  // back-compatible but old
112  wfDebug( __METHOD__ . ": back-compat version\n" );
113 
115  }
116  # Wrong (non-compatible) version
117  wfDebug( __METHOD__ . ": wrong version\n" );
118 
119  return self::METADATA_BAD;
120  }
121 
122  return self::METADATA_GOOD;
123  }
124 
130  public function formatMetadata( $image, $context = false ) {
131  $meta = $this->getCommonMetaArray( $image );
132  if ( count( $meta ) === 0 ) {
133  return false;
134  }
135 
136  return $this->formatMetadataHelper( $meta, $context );
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 [];
148  }
149 
150  $exif = unserialize( $metadata );
151  if ( !$exif ) {
152  return [];
153  }
154  unset( $exif['MEDIAWIKI_EXIF_VERSION'] );
155 
156  return $exif;
157  }
158 
159  function getMetadataType( $image ) {
160  return 'exif';
161  }
162 
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 
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 
222  protected function getRotationForExif( $data ) {
223  if ( !$data ) {
224  return 0;
225  }
226  Wikimedia\suppressWarnings();
227  $data = unserialize( $data );
228  Wikimedia\restoreWarnings();
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 }
ExifBitmapHandler
Stuff specific to JPEG and (built-in) TIFF handler.
Definition: ExifBitmapHandler.php:30
ExifBitmapHandler\getImageSize
getImageSize( $image, $path)
Wrapper for base classes ImageHandler::getImageSize() that checks for rotation reported from metadata...
Definition: ExifBitmapHandler.php:171
$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:130
ExifBitmapHandler\getCommonMetaArray
getCommonMetaArray(File $file)
Get an array of standard (FormatMetadata type) metadata values.
Definition: ExifBitmapHandler.php:139
MediaHandler\METADATA_COMPATIBLE
const METADATA_COMPATIBLE
Definition: MediaHandler.php:34
File
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition: File.php:61
BitmapHandler
Generic handler for bitmap images.
Definition: BitmapHandler.php:31
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:913
FormatMetadata\collapseContactInfo
collapseContactInfo( $vals)
Format the contact info field into a single value.
Definition: FormatMetadata.php:1461
ExifBitmapHandler\getMetadataType
getMetadataType( $image)
Get a string describing the type of metadata, for display purposes.
Definition: ExifBitmapHandler.php:159
MediaHandler\getMetadata
getMetadata( $image, $path)
Get handler-specific metadata which will be saved in the img_metadata field.
Definition: MediaHandler.php:122
BitmapHandler\autoRotateEnabled
autoRotateEnabled()
Definition: BitmapHandler.php:547
$context
$context
Definition: load.php:40
ExifBitmapHandler\convertMetadataVersion
convertMetadataVersion( $metadata, $version=1)
Convert metadata version.
Definition: ExifBitmapHandler.php:34
FormatMetadata
Format Image metadata values into a human readable form.
Definition: FormatMetadata.php:51
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:204
ExifBitmapHandler\OLD_BROKEN_FILE
const OLD_BROKEN_FILE
Definition: ExifBitmapHandler.php:32
unserialize
unserialize( $serialized)
Definition: ApiMessageTrait.php:146
MediaHandler\formatMetadataHelper
formatMetadataHelper( $metadataArray, $context=false)
sorts the visible/invisible field.
Definition: MediaHandler.php:494
$path
$path
Definition: NoLocalSettings.php:25
MediaHandler\METADATA_BAD
const METADATA_BAD
Definition: MediaHandler.php:33
ExifBitmapHandler\isMetadataValid
isMetadataValid( $image, $metadata)
Definition: ExifBitmapHandler.php:86
ExifBitmapHandler\BROKEN_FILE
const BROKEN_FILE
Definition: ExifBitmapHandler.php:31
ExifBitmapHandler\getRotationForExif
getRotationForExif( $data)
Given a chunk of serialized Exif metadata, return the orientation as degrees of rotation.
Definition: ExifBitmapHandler.php:222
$wgShowEXIF
$wgShowEXIF
Show Exif data, on by default if available.
Definition: DefaultSettings.php:804
MediaHandler\METADATA_GOOD
const METADATA_GOOD
Definition: MediaHandler.php:32