diff --git a/inc/Service/Media/CmdMagickMediaHandler.php b/inc/Service/Media/CmdMagickMediaHandler.php new file mode 100644 index 00000000..182b4ac3 --- /dev/null +++ b/inc/Service/Media/CmdMagickMediaHandler.php @@ -0,0 +1,143 @@ +prefix} identify -format '%w %h %m %[orientation] %n' $arg"); + + if (!\is_string($ret_exec)) { + throw new MediaException('Error while executing identify', MediaException::ERR_COMPUTE_ERR); + } + $ret_match = \preg_match('/^(\d+) (\d+) ([\w\d]+) ([\w]+) (\d+)$/', $ret_exec, $m); + if ($ret_match !== 1) { + throw new MediaException('Could not parse identify output', MediaException::ERR_COMPUTE_ERR); + } + $width = \intval($m[1]); + $height = \intval($m[2]); + $ext = $m[3]; + $orientation_str = $m[4]; + $frame_count = \intval($m[5]); + + $mime = Metadata\ext_to_mime($ext) ?? 'application/octet-stream'; + $exif_orientation = self::parseOrientation($orientation_str); + return [ $width, $height, $mime, $exif_orientation, $frame_count ]; + } + + private function __construct(string $cmd, bool $strip_metadata, int $max_image_width, int $max_image_height) { + $this->prefix = $cmd; + $this->strip_metadata = $strip_metadata; + $this->max_image_width = $max_image_width; + $this->max_image_height = $max_image_height; + } + + public function supportsMime(string $mime): bool { + // Could not find a good way to query the commands. Also it would be really slow. + return \in_array($mime, Metadata\SUPPORTED_IMAGE_MIME_TYPES) + || \in_array($mime, Metadata\SUPPORTED_THUMB_MIME_TYPES); + } + + public function openHandle(string $file_path, string $file_mime, int $file_kind): mixed { + $is_pdf = $file_mime === 'application/pdf'; + list($width, $height, $mime, $exif_orientation) = self::getMetadata($file_path, $is_pdf); + + if ($mime !== $file_mime) { + throw new MediaException("Mime type mismatch, expected $file_mime, got $mime", MediaException::ERR_COMPUTE_ERR); + } + if ($width > $this->max_image_width || $height > $this->max_image_height) { + throw new MediaException("Image too big", MediaException::ERR_IMAGE_TOO_LARGE); + } + + return [ $file_path, $file_mime, $file_kind, $width, $height, $exif_orientation ]; + } + + public function closeHandle(mixed $handle) { + // No-op. + } + + public function installMediaAndGenerateThumb( + mixed $handle, + string $media_preferred_out_file_basepath, + string $thumb_preferred_out_file_basepath, + int $thumb_max_width, + int $thumb_max_height + ): MediaInstallResult { + list($source_file_path, $source_file_mime, $source_file_kind, $width, $height, $exif_orientation) = $handle; + + if (!$this->strip_metadata) { + $media_out_path = $media_preferred_out_file_basepath . Metadata\mime_to_ext($source_file_mime); + $this->move_or_link_or_copy($source_file_kind, $source_file_path, $media_out_path); + + if ($width <= $thumb_max_width && $height <= $thumb_max_height) { + $thumb_out_path = $thumb_preferred_out_file_basepath . Metadata\mime_to_ext($source_file_mime); + if (!Fs\link_or_copy($media_out_path, $thumb_out_path)) { + throw new MediaException("Could not link or copy '$media_out_path' to '$thumb_out_path'", MediaException::ERR_IO_ERR); + } + } + } + } + + public function installMedia(mixed $handle, string $preferred_out_file_basepath): string { + list($source_file_path, $source_file_mime, $source_file_kind, $width, $height, $exif_orientation) = $handle; + + if (!$this->strip_metadata) { + $out_path = $preferred_out_file_basepath . Metadata\mime_to_ext($source_file_mime); + $this->move_or_link_or_copy($source_file_kind, $source_file_path, $out_path); + return $out_path; + } + } + + public function generateThumb(mixed $handle, string $preferred_out_file_basepath, int $max_width, int $max_height): ThumbGenerationResult { + list($source_file_path, $source_file_mime, $source_file_kind, $width, $height, $exif_orientation) = $handle; + + if (!$this->strip_metadata && $width <= $max_width && $height <= $max_height) { + $out_path = $preferred_out_file_basepath . Metadata\mime_to_ext($source_file_mime); + $this->move_or_link_or_copy($source_file_kind, $source_file_path, $out_path); + return new ThumbGenerationResult($out_path, $source_file_mime, $width, $height); + } else { + + } + } +}