MediaWiki  master
PNGHandler.php
Go to the documentation of this file.
1 <?php
24 use Wikimedia\RequestTimeout\TimeoutException;
25 
31 class PNGHandler extends BitmapHandler {
32  private const BROKEN_FILE = '0';
33 
39  public function getSizeAndMetadata( $state, $filename ) {
40  try {
41  $metadata = BitmapMetadataHandler::PNG( $filename );
42  } catch ( TimeoutException $e ) {
43  throw $e;
44  } catch ( Exception $e ) {
45  // Broken file?
46  wfDebug( __METHOD__ . ': ' . $e->getMessage() );
47 
48  return [ 'metadata' => [ '_error' => self::BROKEN_FILE ] ];
49  }
50 
51  return [
52  'width' => $metadata['width'],
53  'height' => $metadata['height'],
54  'bits' => $metadata['bitDepth'],
55  'metadata' => array_diff_key(
56  $metadata,
57  [ 'width' => true, 'height' => true, 'bits' => true ]
58  )
59  ];
60  }
61 
67  public function formatMetadata( $image, $context = false ) {
68  $meta = $this->getCommonMetaArray( $image );
69  if ( !$meta ) {
70  return false;
71  }
72 
73  return $this->formatMetadataHelper( $meta, $context );
74  }
75 
82  public function getCommonMetaArray( File $image ) {
83  $meta = $image->getMetadataArray();
84 
85  if ( !isset( $meta['metadata'] ) ) {
86  return [];
87  }
88  unset( $meta['metadata']['_MW_PNG_VERSION'] );
89 
90  return $meta['metadata'];
91  }
92 
97  public function isAnimatedImage( $image ) {
98  $metadata = $image->getMetadataArray();
99  if ( isset( $metadata['frameCount'] ) && $metadata['frameCount'] > 1 ) {
100  return true;
101  }
102 
103  return false;
104  }
105 
111  public function canAnimateThumbnail( $image ) {
112  return false;
113  }
114 
115  public function getMetadataType( $image ) {
116  return 'parsed-png';
117  }
118 
119  public function isFileMetadataValid( $image ) {
120  $data = $image->getMetadataArray();
121  if ( $data === [ '_error' => self::BROKEN_FILE ] ) {
122  // Do not repetitively regenerate metadata on broken file.
123  return self::METADATA_GOOD;
124  }
125 
126  if ( !$data || isset( $data['_error'] ) ) {
127  wfDebug( __METHOD__ . " invalid png metadata" );
128 
129  return self::METADATA_BAD;
130  }
131 
132  if ( !isset( $data['metadata']['_MW_PNG_VERSION'] )
133  || $data['metadata']['_MW_PNG_VERSION'] != PNGMetadataExtractor::VERSION
134  ) {
135  wfDebug( __METHOD__ . " old but compatible png metadata" );
136 
138  }
139 
140  return self::METADATA_GOOD;
141  }
142 
147  public function getLongDesc( $image ) {
148  global $wgLang;
149  $original = parent::getLongDesc( $image );
150 
151  $metadata = $image->getMetadataArray();
152 
153  if ( !$metadata || isset( $metadata['_error'] ) || $metadata['frameCount'] <= 0 ) {
154  return $original;
155  }
156 
157  $info = [];
158  $info[] = $original;
159 
160  if ( $metadata['loopCount'] == 0 ) {
161  $info[] = wfMessage( 'file-info-png-looped' )->parse();
162  } elseif ( $metadata['loopCount'] > 1 ) {
163  $info[] = wfMessage( 'file-info-png-repeat' )->numParams( $metadata['loopCount'] )->parse();
164  }
165 
166  if ( $metadata['frameCount'] > 0 ) {
167  $info[] = wfMessage( 'file-info-png-frames' )->numParams( $metadata['frameCount'] )->parse();
168  }
169 
170  if ( $metadata['duration'] ) {
171  $info[] = $wgLang->formatTimePeriod( $metadata['duration'] );
172  }
173 
174  return $wgLang->commaList( $info );
175  }
176 
185  public function getLength( $file ) {
186  $metadata = $file->getMetadataArray();
187 
188  if ( !$metadata || !isset( $metadata['duration'] ) || !$metadata['duration'] ) {
189  return 0.0;
190  } else {
191  return (float)$metadata['duration'];
192  }
193  }
194 
195  // PNGs should be easy to support, but it will need some sharpening applied
196  // and another user test to check if the perceived quality change is noticeable
197  public function supportsBucketing() {
198  return false;
199  }
200 }
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
if(!defined( 'MW_NO_SESSION') &&! $wgCommandLineMode) $wgLang
Definition: Setup.php:485
Generic handler for bitmap images.
static PNG( $filename)
Entry point for png At some point in the future this might merge the png various tEXt chunks to that ...
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition: File.php:68
getMetadataArray()
Get the unserialized handler-specific metadata STUB.
Definition: File.php:747
const METADATA_COMPATIBLE
const METADATA_BAD
formatMetadataHelper( $metadataArray, $context=false)
sorts the visible/invisible field.
const METADATA_GOOD
Handler for PNG images.
Definition: PNGHandler.php:31
isFileMetadataValid( $image)
Check if the metadata is valid for this handler.
Definition: PNGHandler.php:119
isAnimatedImage( $image)
Definition: PNGHandler.php:97
formatMetadata( $image, $context=false)
Definition: PNGHandler.php:67
const BROKEN_FILE
Definition: PNGHandler.php:32
getCommonMetaArray(File $image)
Get a file type independent array of metadata.
Definition: PNGHandler.php:82
supportsBucketing()
Returns whether or not this handler supports the chained generation of thumbnails according to bucket...
Definition: PNGHandler.php:197
getLength( $file)
Return the duration of an APNG file.
Definition: PNGHandler.php:185
getLongDesc( $image)
Definition: PNGHandler.php:147
getMetadataType( $image)
Get a string describing the type of metadata, for display purposes.
Definition: PNGHandler.php:115
getSizeAndMetadata( $state, $filename)
Definition: PNGHandler.php:39
canAnimateThumbnail( $image)
We do not support making APNG thumbnails, so always false.
Definition: PNGHandler.php:111
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition: router.php:42