forked from leftypol/leftypol
GdMediaHandler.php: properly handle AVIF, rotated image sizes
This commit is contained in:
parent
020ab7d4fc
commit
c4b766f133
1 changed files with 33 additions and 11 deletions
|
@ -11,7 +11,8 @@ use Vichan\Functions\{Fs, Metadata};
|
|||
class GdMediaHandler implements MediaHandler {
|
||||
use MediaHandlerTrait;
|
||||
|
||||
private const PHP81 = \PHP_MAJOR_VERSION >= 8 && \PHP_MINOR_VERSION >= 1;
|
||||
// GD requires PHP 8.1 to support avif, getimagesize in sniff_image requires PHP 8.2
|
||||
private const PHP_AVIF_SUPPORT = \PHP_MAJOR_VERSION >= 8 && \PHP_MINOR_VERSION >= 2;
|
||||
|
||||
|
||||
private bool $strip_redraw;
|
||||
|
@ -33,7 +34,7 @@ class GdMediaHandler implements MediaHandler {
|
|||
case 'image/bmp':
|
||||
return \imagecreatefrombmp($file);
|
||||
case 'image/avif':
|
||||
return self::PHP81 ? \imagecreatefromavif($file) : false;
|
||||
return self::PHP_AVIF_SUPPORT ? \imagecreatefromavif($file) : false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -53,7 +54,7 @@ class GdMediaHandler implements MediaHandler {
|
|||
case 'image/bmp':
|
||||
return \imagebmp($gd, $file, true);
|
||||
case 'image/avif':
|
||||
return self::PHP81 ? \imageavif($gd, $file, 30, 6) : false;
|
||||
return self::PHP_AVIF_SUPPORT ? \imageavif($gd, $file, 30, 6) : false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -151,29 +152,50 @@ class GdMediaHandler implements MediaHandler {
|
|||
|| ($mime === 'image/gif' && $info['GIF Read Support'] && $info['GIF Create Support'])
|
||||
|| ($mime === 'image/webp' && $info['WebP Support'])
|
||||
|| $mime === 'image/bmp'
|
||||
|| ($mime === 'image/avif' && self::PHP81 && $info['AVIF Support']);
|
||||
|| ($mime === 'image/avif' && self::PHP_AVIF_SUPPORT && $info['AVIF Support']);
|
||||
}
|
||||
|
||||
public function openHandle(string $file_path, string $file_mime, int $file_kind): mixed {
|
||||
$exif_orientation = null;
|
||||
$exif_orientation_read = false;
|
||||
|
||||
try {
|
||||
list($width, $height, $mime) = Metadata\sniff_image($file_path);
|
||||
if ($width > $this->image_max_width || $height > $this->image_max_height) {
|
||||
throw new MediaException("Image too big", MediaException::ERR_IMAGE_TOO_LARGE);
|
||||
}
|
||||
if ($mime !== $file_mime) {
|
||||
throw new MediaException("Mime type mismatch, expected $file_mime, got $mime", MediaException::ERR_COMPUTE_ERR);
|
||||
}
|
||||
} catch (\RuntimeException $e) {
|
||||
throw new MediaException("Could not sniff '$file_path'", MediaException::ERR_NO_OPEN, $e);
|
||||
}
|
||||
|
||||
if ($mime !== $file_mime) {
|
||||
throw new MediaException("Mime type mismatch, expected $file_mime, got $mime", MediaException::ERR_COMPUTE_ERR);
|
||||
}
|
||||
if ($width > $this->image_max_width && $height > $this->image_max_height) {
|
||||
// Too big in all directions.
|
||||
throw new MediaException("Image too big", MediaException::ERR_IMAGE_TOO_LARGE);
|
||||
} elseif ($width > $this->image_max_width || $height > $this->image_max_height) {
|
||||
// Too big in just one direction.
|
||||
// Suppose the image is rotated by the exif orientation, would it fit?
|
||||
if ($width <= $this->image_max_height && $height <= $this->image_max_width) {
|
||||
$exif_orientation_read = true;
|
||||
$exif_orientation = $this->getOrientation($file_path, $file_mime);
|
||||
|
||||
// If width and height aren't inverted, then it wouldn't fit.
|
||||
if ($exif_orientation === null || !Exif::exifOrientationOnSide($exif_orientation)) {
|
||||
throw new MediaException("Image too big", MediaException::ERR_IMAGE_TOO_LARGE);
|
||||
}
|
||||
} else {
|
||||
throw new MediaException("Image too big", MediaException::ERR_IMAGE_TOO_LARGE);
|
||||
}
|
||||
}
|
||||
|
||||
$gd = self::imageCreateFrom($file_path, $file_mime);
|
||||
if ($gd === false) {
|
||||
throw new MediaException("Could not open '$file_path'", MediaException::ERR_NO_OPEN);
|
||||
}
|
||||
|
||||
// Fix the orientation once and for all.
|
||||
$exif_orientation = $this->getOrientation($file_path, $file_mime);
|
||||
if (!$exif_orientation_read) {
|
||||
$exif_orientation = $this->getOrientation($file_path, $file_mime);
|
||||
}
|
||||
if ($exif_orientation !== null) {
|
||||
$degrees = Exif::exifOrientationDegrees($exif_orientation);
|
||||
$flipped = Exif::exifOrientationIsFlipped($exif_orientation);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue