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  return isset( $metadata['frameCount'] ) && $metadata['frameCount'] > 1;
100  }
101 
107  public function canAnimateThumbnail( $image ) {
108  return false;
109  }
110 
111  public function getMetadataType( $image ) {
112  return 'parsed-png';
113  }
114 
115  public function isFileMetadataValid( $image ) {
116  $data = $image->getMetadataArray();
117  if ( $data === [ '_error' => self::BROKEN_FILE ] ) {
118  // Do not repetitively regenerate metadata on broken file.
119  return self::METADATA_GOOD;
120  }
121 
122  if ( !$data || isset( $data['_error'] ) ) {
123  wfDebug( __METHOD__ . " invalid png metadata" );
124 
125  return self::METADATA_BAD;
126  }
127 
128  if ( !isset( $data['metadata']['_MW_PNG_VERSION'] )
129  || $data['metadata']['_MW_PNG_VERSION'] !== PNGMetadataExtractor::VERSION
130  ) {
131  wfDebug( __METHOD__ . " old but compatible png metadata" );
132 
134  }
135 
136  return self::METADATA_GOOD;
137  }
138 
143  public function getLongDesc( $image ) {
144  global $wgLang;
145  $original = parent::getLongDesc( $image );
146 
147  $metadata = $image->getMetadataArray();
148 
149  if ( !$metadata || isset( $metadata['_error'] ) || $metadata['frameCount'] <= 0 ) {
150  return $original;
151  }
152 
153  $info = [];
154  $info[] = $original;
155 
156  if ( $metadata['loopCount'] == 0 ) {
157  $info[] = wfMessage( 'file-info-png-looped' )->parse();
158  } elseif ( $metadata['loopCount'] > 1 ) {
159  $info[] = wfMessage( 'file-info-png-repeat' )->numParams( $metadata['loopCount'] )->parse();
160  }
161 
162  if ( $metadata['frameCount'] > 0 ) {
163  $info[] = wfMessage( 'file-info-png-frames' )->numParams( $metadata['frameCount'] )->parse();
164  }
165 
166  if ( $metadata['duration'] ) {
167  $info[] = $wgLang->formatTimePeriod( $metadata['duration'] );
168  }
169 
170  return $wgLang->commaList( $info );
171  }
172 
181  public function getLength( $file ) {
182  $metadata = $file->getMetadataArray();
183 
184  if ( !$metadata || !isset( $metadata['duration'] ) || !$metadata['duration'] ) {
185  return 0.0;
186  }
187 
188  return (float)$metadata['duration'];
189  }
190 
191  // PNGs should be easy to support, but it will need some sharpening applied
192  // and another user test to check if the perceived quality change is noticeable
193  public function supportsBucketing() {
194  return false;
195  }
196 }
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:535
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:70
getMetadataArray()
Get the unserialized handler-specific metadata STUB.
Definition: File.php:752
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:115
isAnimatedImage( $image)
Definition: PNGHandler.php:97
formatMetadata( $image, $context=false)
Definition: PNGHandler.php:67
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:193
getLength( $file)
Return the duration of an APNG file.
Definition: PNGHandler.php:181
getLongDesc( $image)
Definition: PNGHandler.php:143
getMetadataType( $image)
Get a string describing the type of metadata, for display purposes.
Definition: PNGHandler.php:111
getSizeAndMetadata( $state, $filename)
Definition: PNGHandler.php:39
canAnimateThumbnail( $image)
We do not support making APNG thumbnails, so always false.
Definition: PNGHandler.php:107
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition: router.php:42