MediaWiki  1.23.0
BitmapMetadataHandler.php
Go to the documentation of this file.
1 <?php
36  private $metadata = array();
37 
39  private $metaPriority = array(
40  20 => array( 'other' ),
41  40 => array( 'native' ),
42  60 => array( 'iptc-good-hash', 'iptc-no-hash' ),
43  70 => array( 'xmp-deprecated' ),
44  80 => array( 'xmp-general' ),
45  90 => array( 'xmp-exif' ),
46  100 => array( 'iptc-bad-hash' ),
47  120 => array( 'exif' ),
48  );
49 
51  private $iptcType = 'iptc-no-hash';
52 
61  private function doApp13( $app13 ) {
62  try {
63  $this->iptcType = JpegMetadataExtractor::doPSIR( $app13 );
64  } catch ( MWException $e ) {
65  // Error reading the iptc hash information.
66  // This probably means the App13 segment is something other than what we expect.
67  // However, still try to read it, and treat it as if the hash didn't exist.
68  wfDebug( "Error parsing iptc data of file: " . $e->getMessage() . "\n" );
69  $this->iptcType = 'iptc-no-hash';
70  }
71 
72  $iptc = IPTC::parse( $app13 );
73  $this->addMetadata( $iptc, $this->iptcType );
74  }
75 
86  function getExif( $filename, $byteOrder ) {
87  global $wgShowEXIF;
88  if ( file_exists( $filename ) && $wgShowEXIF ) {
89  $exif = new Exif( $filename, $byteOrder );
90  $data = $exif->getFilteredData();
91  if ( $data ) {
92  $this->addMetadata( $data, 'exif' );
93  }
94  }
95  }
96 
103  function addMetadata( $metaArray, $type = 'other' ) {
104  if ( isset( $this->metadata[$type] ) ) {
105  /* merge with old data */
106  $metaArray = $metaArray + $this->metadata[$type];
107  }
108 
109  $this->metadata[$type] = $metaArray;
110  }
111 
121  function getMetadataArray() {
122  // this seems a bit ugly... This is all so its merged in right order
123  // based on the MWG recomendation.
124  $temp = array();
125  krsort( $this->metaPriority );
126  foreach ( $this->metaPriority as $pri ) {
127  foreach ( $pri as $type ) {
128  if ( isset( $this->metadata[$type] ) ) {
129  // Do some special casing for multilingual values.
130  // Don't discard translations if also as a simple value.
131  foreach ( $this->metadata[$type] as $itemName => $item ) {
132  if ( is_array( $item ) && isset( $item['_type'] ) && $item['_type'] === 'lang' ) {
133  if ( isset( $temp[$itemName] ) && !is_array( $temp[$itemName] ) ) {
134  $default = $temp[$itemName];
135  $temp[$itemName] = $item;
136  $temp[$itemName]['x-default'] = $default;
137  unset( $this->metadata[$type][$itemName] );
138  }
139  }
140  }
141 
142  $temp = $temp + $this->metadata[$type];
143  }
144  }
145  }
146 
147  return $temp;
148  }
149 
156  static function Jpeg( $filename ) {
157  $showXMP = function_exists( 'xml_parser_create_ns' );
158  $meta = new self();
159 
160  $seg = JpegMetadataExtractor::segmentSplitter( $filename );
161  if ( isset( $seg['COM'] ) && isset( $seg['COM'][0] ) ) {
162  $meta->addMetadata( array( 'JPEGFileComment' => $seg['COM'] ), 'native' );
163  }
164  if ( isset( $seg['PSIR'] ) && count( $seg['PSIR'] ) > 0 ) {
165  foreach ( $seg['PSIR'] as $curPSIRValue ) {
166  $meta->doApp13( $curPSIRValue );
167  }
168  }
169  if ( isset( $seg['XMP'] ) && $showXMP ) {
170  $xmp = new XMPReader();
171  $xmp->parse( $seg['XMP'] );
172  foreach ( $seg['XMP_ext'] as $xmpExt ) {
173  /* Support for extended xmp in jpeg files
174  * is not well tested and a bit fragile.
175  */
176  $xmp->parseExtended( $xmpExt );
177  }
178  $res = $xmp->getResults();
179  foreach ( $res as $type => $array ) {
180  $meta->addMetadata( $array, $type );
181  }
182  }
183  if ( isset( $seg['byteOrder'] ) ) {
184  $meta->getExif( $filename, $seg['byteOrder'] );
185  }
186 
187  return $meta->getMetadataArray();
188  }
189 
198  public static function PNG( $filename ) {
199  $showXMP = function_exists( 'xml_parser_create_ns' );
200 
201  $meta = new self();
202  $array = PNGMetadataExtractor::getMetadata( $filename );
203  if ( isset( $array['text']['xmp']['x-default'] )
204  && $array['text']['xmp']['x-default'] !== '' && $showXMP
205  ) {
206  $xmp = new XMPReader();
207  $xmp->parse( $array['text']['xmp']['x-default'] );
208  $xmpRes = $xmp->getResults();
209  foreach ( $xmpRes as $type => $xmpSection ) {
210  $meta->addMetadata( $xmpSection, $type );
211  }
212  }
213  unset( $array['text']['xmp'] );
214  $meta->addMetadata( $array['text'], 'native' );
215  unset( $array['text'] );
216  $array['metadata'] = $meta->getMetadataArray();
217  $array['metadata']['_MW_PNG_VERSION'] = PNGMetadataExtractor::VERSION;
218 
219  return $array;
220  }
221 
230  public static function GIF( $filename ) {
231 
232  $meta = new self();
233  $baseArray = GIFMetadataExtractor::getMetadata( $filename );
234 
235  if ( count( $baseArray['comment'] ) > 0 ) {
236  $meta->addMetadata( array( 'GIFFileComment' => $baseArray['comment'] ), 'native' );
237  }
238 
239  if ( $baseArray['xmp'] !== '' && function_exists( 'xml_parser_create_ns' ) ) {
240  $xmp = new XMPReader();
241  $xmp->parse( $baseArray['xmp'] );
242  $xmpRes = $xmp->getResults();
243  foreach ( $xmpRes as $type => $xmpSection ) {
244  $meta->addMetadata( $xmpSection, $type );
245  }
246  }
247 
248  unset( $baseArray['comment'] );
249  unset( $baseArray['xmp'] );
250 
251  $baseArray['metadata'] = $meta->getMetadataArray();
252  $baseArray['metadata']['_MW_GIF_VERSION'] = GIFMetadataExtractor::VERSION;
253 
254  return $baseArray;
255  }
256 
270  public static function Tiff( $filename ) {
271  if ( file_exists( $filename ) ) {
272  $byteOrder = self::getTiffByteOrder( $filename );
273  if ( !$byteOrder ) {
274  throw new MWException( "Error determining byte order of $filename" );
275  }
276  $exif = new Exif( $filename, $byteOrder );
277  $data = $exif->getFilteredData();
278  if ( $data ) {
279  $data['MEDIAWIKI_EXIF_VERSION'] = Exif::version();
280 
281  return $data;
282  } else {
283  throw new MWException( "Could not extract data from tiff file $filename" );
284  }
285  } else {
286  throw new MWException( "File doesn't exist - $filename" );
287  }
288  }
289 
297  static function getTiffByteOrder( $filename ) {
298  $fh = fopen( $filename, 'rb' );
299  if ( !$fh ) {
300  return false;
301  }
302  $head = fread( $fh, 2 );
303  fclose( $fh );
304 
305  switch ( $head ) {
306  case 'II':
307  return 'LE'; // II for intel.
308  case 'MM':
309  return 'BE'; // MM for motorla.
310  default:
311  return false; // Something went wrong.
312 
313  }
314  }
315 }
BitmapMetadataHandler\Tiff
static Tiff( $filename)
This doesn't do much yet, but eventually I plan to add XMP support for Tiff.
Definition: BitmapMetadataHandler.php:267
php
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
Definition: skin.txt:62
PNGMetadataExtractor\VERSION
const VERSION
Definition: PNGMetadataExtractor.php:43
BitmapMetadataHandler\$iptcType
string $iptcType
Definition: BitmapMetadataHandler.php:48
BitmapMetadataHandler\GIF
static GIF( $filename)
function for gif images.
Definition: BitmapMetadataHandler.php:227
Exif
Class to extract and validate Exif data from jpeg (and possibly tiff) files.
Definition: Exif.php:32
BitmapMetadataHandler
Class to deal with reconciling and extracting metadata from bitmap images.
Definition: BitmapMetadataHandler.php:34
MWException
MediaWiki exception.
Definition: MWException.php:26
BitmapMetadataHandler\$metaPriority
array $metaPriority
Metadata priority *.
Definition: BitmapMetadataHandler.php:37
JpegMetadataExtractor\doPSIR
static doPSIR( $app13)
This reads the photoshop image resource.
Definition: JpegMetadataExtractor.php:201
array
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
Exif\version
static version()
#-
Definition: Exif.php:580
IPTC\parse
static parse( $rawData)
This takes the results of iptcparse() and puts it into a form that can be handled by mediawiki.
Definition: IPTC.php:40
BitmapMetadataHandler\getMetadataArray
getMetadataArray()
Merge together the various types of metadata the different types have different priorites,...
Definition: BitmapMetadataHandler.php:118
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
PNGMetadataExtractor\getMetadata
static getMetadata( $filename)
Definition: PNGMetadataExtractor.php:46
GIFMetadataExtractor\getMetadata
static getMetadata( $filename)
Definition: GIFMetadataExtractor.php:56
BitmapMetadataHandler\PNG
static PNG( $filename)
Entry point for png At some point in the future this might merge the png various tEXt chunks to that ...
Definition: BitmapMetadataHandler.php:195
XMPReader
Class for reading xmp data containing properties relevant to images, and spitting out an array that F...
Definition: XMP.php:49
wfDebug
wfDebug( $text, $dest='all')
Sends a line to the debug log if enabled or, optionally, to a comment in output.
Definition: GlobalFunctions.php:933
BitmapMetadataHandler\getExif
getExif( $filename, $byteOrder)
Get exif info using exif class.
Definition: BitmapMetadataHandler.php:83
JpegMetadataExtractor\segmentSplitter
static segmentSplitter( $filename)
Function to extract metadata segments of interest from jpeg files based on GIFMetadataExtractor.
Definition: JpegMetadataExtractor.php:50
BitmapMetadataHandler\doApp13
doApp13( $app13)
This does the photoshop image resource app13 block of interest, IPTC-IIM metadata is stored here.
Definition: BitmapMetadataHandler.php:58
BitmapMetadataHandler\$metadata
array $metadata
Definition: BitmapMetadataHandler.php:35
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
GIFMetadataExtractor\VERSION
const VERSION
Definition: GIFMetadataExtractor.php:44
BitmapMetadataHandler\Jpeg
static Jpeg( $filename)
Main entry point for jpeg's.
Definition: BitmapMetadataHandler.php:153
$e
if( $useReadline) $e
Definition: eval.php:66
$res
$res
Definition: database.txt:21
BitmapMetadataHandler\addMetadata
addMetadata( $metaArray, $type='other')
Add misc metadata.
Definition: BitmapMetadataHandler.php:100
$type
$type
Definition: testCompression.php:46
BitmapMetadataHandler\getTiffByteOrder
static getTiffByteOrder( $filename)
Read the first 2 bytes of a tiff file to figure out Little Endian or Big Endian.
Definition: BitmapMetadataHandler.php:294