33 private const BROKEN_FILE =
'0';
37 private const MINIMUM_CHUNK_HEADER_LENGTH = 18;
41 private const _MW_WEBP_VERSION = 1;
43 private const VP8X_ICC = 32;
44 private const VP8X_ALPHA = 16;
45 private const VP8X_EXIF = 8;
46 private const VP8X_XMP = 4;
47 private const VP8X_ANIM = 2;
51 if ( !$parsedWebPData ) {
52 return [
'metadata' => [
'_error' => self::BROKEN_FILE ] ];
55 $parsedWebPData[
'metadata'][
'_MW_WEBP_VERSION'] = self::_MW_WEBP_VERSION;
57 'width' => $parsedWebPData[
'width'],
58 'height' => $parsedWebPData[
'height'],
59 'metadata' => $parsedWebPData
69 $data = $image->getMetadataArray();
70 if ( $data === [
'_error' => self::BROKEN_FILE ] ) {
75 if ( !$data || !isset( $data[
'_error'] ) ) {
76 wfDebug( __METHOD__ .
" invalid WebP metadata" );
81 if ( !isset( $data[
'metadata'][
'_MW_WEBP_VERSION'] )
82 || $data[
'metadata'][
'_MW_WEBP_VERSION'] != self::_MW_WEBP_VERSION
84 wfDebug( __METHOD__ .
" old but compatible WebP metadata" );
100 wfDebugLog(
'WebP', __METHOD__ .
": Extracting metadata from $filename" );
103 if ( $info ===
false ) {
104 wfDebugLog(
'WebP', __METHOD__ .
": Not a valid RIFF file" );
108 if ( $info[
'fourCC'] !=
'WEBP' ) {
109 wfDebugLog(
'WebP', __METHOD__ .
': FourCC was not WEBP: ' .
110 bin2hex( $info[
'fourCC'] ) );
116 wfDebugLog(
'WebP', __METHOD__ .
": No VP8 chunks found" );
133 foreach ( $chunks as $chunk ) {
134 if ( !in_array( $chunk[
'fourCC'], [
'VP8 ',
'VP8L',
'VP8X' ] ) ) {
139 $chunkHeader = file_get_contents( $filename,
false,
null,
140 $chunk[
'start'], self::MINIMUM_CHUNK_HEADER_LENGTH );
141 wfDebugLog(
'WebP', __METHOD__ .
": {$chunk['fourCC']}" );
143 switch ( $chunk[
'fourCC'] ) {
145 return array_merge( $vp8Info,
146 self::decodeLossyChunkHeader( $chunkHeader ) );
148 return array_merge( $vp8Info,
149 self::decodeLosslessChunkHeader( $chunkHeader ) );
151 $vp8Info = array_merge( $vp8Info,
152 self::decodeExtendedChunkHeader( $chunkHeader ) );
170 $syncCode = substr(
$header, 11, 3 );
171 if ( $syncCode !=
"\x9D\x01\x2A" ) {
172 wfDebugLog(
'WebP', __METHOD__ .
': Invalid sync code: ' .
173 bin2hex( $syncCode ) );
177 $imageSize = unpack(
'v2', substr(
$header, 14, 4 ) );
180 'compression' =>
'lossy',
181 'width' => $imageSize[1] & 0x3FFF,
182 'height' => $imageSize[2] & 0x3FFF
196 wfDebugLog(
'WebP', __METHOD__ .
': Invalid signature: ' .
202 $imageSize = unpack(
'C4', substr(
$header, 9, 4 ) );
204 'compression' =>
'lossless',
205 'width' => ( $imageSize[1] | ( ( $imageSize[2] & 0x3F ) << 8 ) ) + 1,
206 'height' => ( ( ( $imageSize[2] & 0xC0 ) >> 6 ) |
207 ( $imageSize[3] << 2 ) | ( ( $imageSize[4] & 0x03 ) << 10 ) ) + 1
220 $flags = unpack(
'c', substr(
$header, 8, 1 ) );
223 $width = unpack(
'V', substr(
$header, 12, 3 ) .
"\x00" );
224 $height = unpack(
'V', substr(
$header, 15, 3 ) .
"\x00" );
227 'compression' =>
'unknown',
228 'animated' => ( $flags[1] & self::VP8X_ANIM ) == self::VP8X_ANIM,
229 'transparency' => ( $flags[1] & self::VP8X_ALPHA ) == self::VP8X_ALPHA,
230 'width' => ( $width[1] & 0xFFFFFF ) + 1,
231 'height' => ( $height[1] & 0xFFFFFF ) + 1
248 if ( self::isAnimatedImage(
$file ) ) {
259 $metadata = $image->getMetadataArray();
260 if ( isset( $metadata[
'animated'] ) && $metadata[
'animated'] ===
true ) {
280 return [
'png',
'image/png' ];
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfDebugLog( $logGroup, $text, $dest='all', array $context=[])
Send a line to a supplementary debug log file, if configured, or main debug log if not.
Generic handler for bitmap images.
Handler for Google's WebP format https://developers.google.com/speed/webp/
canAnimateThumbnail( $file)
If the material is animated, we can animate the thumbnail.
isFileMetadataValid( $image)
Check if the metadata is valid for this handler.
static extractMetadataFromChunks( $chunks, $filename)
Extracts the image size and WebP type from a file based on the chunk list.
getScalerType( $dstPath, $checkDstPath=true)
Must use "im" for XCF.
static decodeLossyChunkHeader( $header)
Decodes a lossy chunk header.
getSizeAndMetadata( $state, $filename)
Get image size information and metadata array.
getThumbType( $ext, $mime, $params=null)
Render files as PNG.
static decodeLosslessChunkHeader( $header)
Decodes a lossless chunk header.
getMetadataType( $image)
Get a string describing the type of metadata, for display purposes.
static extractMetadata( $filename)
Extracts the image size and WebP type from a file.
static decodeExtendedChunkHeader( $header)
Decodes an extended chunk header.
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
if(!is_readable( $file)) $ext