checkHealth(); } /** * {@inheritdoc} * * @see DriverInterface::config() */ public function config(): Config { return $this->config; } /** * {@inheritdoc} * * @see DriverInterface::decodeImage() * * @throws InvalidArgumentException * @throws ImageDecoderException * @throws DriverException */ public function decodeImage(mixed $input, ?array $decoders = null): ImageInterface { $decoders = $decoders === null ? InputHandler::IMAGE_DECODERS : $decoders; if (count($decoders) === 0) { throw new InvalidArgumentException('No decoders in array'); } try { $result = InputHandler::usingDecoders($decoders, $this)->handle($input); } catch (NotSupportedException) { $type = is_object($input) ? $input::class : gettype($input); throw new InvalidArgumentException('Unsupported image source type "' . $type . '"'); } if (!$result instanceof ImageInterface) { throw new ImageDecoderException('Result must be instance of ' . ImageInterface::class); } return $result; } /** * {@inheritdoc} * * @see DriverInterface::decodeColor() * * @throws InvalidArgumentException * @throws ColorDecoderException * @throws DriverException */ public function decodeColor(mixed $input, ?array $decoders = null): ColorInterface { $decoders = $decoders === null ? InputHandler::COLOR_DECODERS : $decoders; if (count($decoders) === 0) { throw new InvalidArgumentException('No decoders in array'); } try { $result = InputHandler::usingDecoders($decoders, $this)->handle($input); } catch (NotSupportedException) { throw new ColorDecoderException('Unknown color format'); } if (!$result instanceof ColorInterface) { throw new ColorDecoderException('Result must be instance of ' . ColorInterface::class); } return $result; } /** * {@inheritdoc} * * @see DriverInterface::specializeModifier() * * @throws NotSupportedException */ public function specializeModifier(ModifierInterface $modifier): ModifierInterface { return $this->specialize($modifier); } /** * {@inheritdoc} * * @see DriverInterface::specializeAnalyzer() * * @throws NotSupportedException */ public function specializeAnalyzer(AnalyzerInterface $analyzer): AnalyzerInterface { return $this->specialize($analyzer); } /** * {@inheritdoc} * * @see DriverInterface::specializeEncoder() * * @throws NotSupportedException */ public function specializeEncoder(EncoderInterface $encoder): EncoderInterface { return $this->specialize($encoder); } /** * {@inheritdoc} * * @see DriverInterface::specializeDecoder() * * @throws NotSupportedException */ public function specializeDecoder(DecoderInterface $decoder): DecoderInterface { return $this->specialize($decoder); } /** * @throws NotSupportedException */ private function specialize( ModifierInterface|AnalyzerInterface|EncoderInterface|DecoderInterface $object ): ModifierInterface|AnalyzerInterface|EncoderInterface|DecoderInterface { // return object directly if no specializing is possible if (!$object instanceof SpecializableInterface) { return $object; } // return directly and only attach driver if object is already specialized if ($object instanceof SpecializedInterface) { $object->setDriver($this); return $object; } // resolve classname for specializable object $objectShortname = substr($object::class, (int) strrpos($object::class, '\\') + 1); $specializedClassname = implode("\\", [ substr($this::class, 0, (int) strrpos($this::class, '\\')), // driver's namespace match (true) { $object instanceof ModifierInterface => 'Modifiers', $object instanceof AnalyzerInterface => 'Analyzers', $object instanceof EncoderInterface => 'Encoders', $object instanceof DecoderInterface => 'Decoders', }, $objectShortname, ]); // fail if driver specialized classname does not exists if (!class_exists($specializedClassname)) { throw new NotSupportedException( "Class '" . $objectShortname . "' is not supported by " . $this->id() . " driver" ); } // create a driver specialized object with the specializable properties of generic object $specialized = new $specializedClassname(...$object->specializationArguments()); // attach driver return $specialized->setDriver($this); } }