WordPress Version: 6.3
/**
* Extracts meta information about a WebP file: width, height, and type.
*
* @since 5.8.0
*
* @param string $filename Path to a WebP file.
* @return array {
* An array of WebP image information.
*
* @type int|false $width Image width on success, false on failure.
* @type int|false $height Image height on success, false on failure.
* @type string|false $type The WebP type: one of 'lossy', 'lossless' or 'animated-alpha'.
* False on failure.
* }
*/
function wp_get_webp_info($filename)
{
$width = false;
$height = false;
$type = false;
if ('image/webp' !== wp_get_image_mime($filename)) {
return compact('width', 'height', 'type');
}
$magic = file_get_contents($filename, false, null, 0, 40);
if (false === $magic) {
return compact('width', 'height', 'type');
}
// Make sure we got enough bytes.
if (strlen($magic) < 40) {
return compact('width', 'height', 'type');
}
/*
* The headers are a little different for each of the three formats.
* Header values based on WebP docs, see https://developers.google.com/speed/webp/docs/riff_container.
*/
switch (substr($magic, 12, 4)) {
// Lossy WebP.
case 'VP8 ':
$parts = unpack('v2', substr($magic, 26, 4));
$width = (int) ($parts[1] & 0x3fff);
$height = (int) ($parts[2] & 0x3fff);
$type = 'lossy';
break;
// Lossless WebP.
case 'VP8L':
$parts = unpack('C4', substr($magic, 21, 4));
$width = (int) ($parts[1] | ($parts[2] & 0x3f) << 8) + 1;
$height = (int) (($parts[2] & 0xc0) >> 6 | $parts[3] << 2 | ($parts[4] & 0x3) << 10) + 1;
$type = 'lossless';
break;
// Animated/alpha WebP.
case 'VP8X':
// Pad 24-bit int.
$width = unpack('V', substr($magic, 24, 3) . "\x00");
$width = (int) ($width[1] & 0xffffff) + 1;
// Pad 24-bit int.
$height = unpack('V', substr($magic, 27, 3) . "\x00");
$height = (int) ($height[1] & 0xffffff) + 1;
$type = 'animated-alpha';
break;
}
return compact('width', 'height', 'type');
}