/** * @param PhpGdEvent $event * @throws RuntimeException */ public function verifyMemoryLimit(PhpGdEvent $event) { $options = $event->getOptions(); $layers = $event->getLayers(); $limit = $this->context->getMemoryLimit($options['memory_limit']); $fixed = memory_get_usage(true); $peak = 0; foreach ($layers as $key => $layer) { if (!$layer instanceof ImageAwareLayerInterface) { continue; } $width = $layer->get('image.width'); $height = $layer->get('image.height'); $finalWidth = $layer->get('final.width'); $finalHeight = $layer->get('final.height'); $constant = $this->getMemoryConstant($layer->get('image.format')); $dynamic = $width * $height * $constant; if (0 === $key) { $fixed += $finalWidth * $finalHeight * $constant; if ($limit < $fixed + $dynamic) { if ($finalWidth * $finalHeight > $width * $height) { throw new RuntimeException('output.image.dimensions.exceed.limit.%cp_dimensions%', ['%cp_dimensions%' => $finalWidth . 'x' . $finalHeight]); } else { throw new RuntimeException('image.dimensions.exceed.limit.%cp_dimensions%', ['%cp_dimensions%' => $width . 'x' . $height]); } } } elseif ($limit < $fixed + $dynamic) { throw new RuntimeException('not.enough.memory.to.process.image'); } $peak = $dynamic > $peak ? $dynamic : $peak; } $this->extras['memory_approx'] = number_format(($fixed + $peak) / (1024 * 1024), 2) . ' MB'; }
/** * @param PhpGdEvent $event */ public function verifyMemoryLimit(PhpGdEvent $event) { $layers = $event->getLayers(); $options = $event->getOptions(); if (!$layers[0]->has('gif.extracted')) { return; } $totalFrames = count($layers[0]->get('gif.extracted')); $width = $layers[0]->get('image.width'); $height = $layers[0]->get('image.height'); $pixels = $width * $height; $finalWidth = $layers[0]->get('final.width'); $finalHeight = $layers[0]->get('final.height'); $finalPixels = $finalWidth * $finalHeight; $totalPixels = $totalFrames * $finalPixels; $limit = $this->context->getMemoryLimit($options['memory_limit']); $peak = memory_get_peak_usage(true) + 15 * 1024 * 1024 + 3 * ($pixels + $finalPixels); if (1000000 < $finalPixels || 57000000 < $totalPixels || $peak > $limit) { $e = new TranslatedException('gif.animation.may.lost.as.too.many.frames.or.dimensions.too.large.%total_frames%.%dimensions%', ['%total_frames%' => $totalFrames, '%dimensions%' => $width . 'x' . $height]); $this->extras['gif_error'] = $e->getMessage(); $layers[0]->remove('gif.extracted'); } else { $this->extras['memory_approx'] = number_format($peak / (1024 * 1024), 2) . ' MB'; } }
/** * @param PhpGdEvent $event */ public function createImage(PhpGdEvent $event) { $layers = $event->getLayers(); if (1 === count($layers) && $layers[0]->get('image.width') === $layers[0]->get('final.width') && $layers[0]->get('image.height') === $layers[0]->get('final.height') && $layers[0]->get('image.format') === $layers[0]->get('final.format')) { $options = $event->getOptions(); $image = $this->factory->createImage($layers, $options); $event->setImage($image); $event->stopPropagation(); } }
/** * @param PhpGdEvent */ public function initFinalFormat(PhpGdEvent $event) { $layer = $event->getLayers()[0]; $options = $event->getOptions(); if ('default' === $options['output_format']) { $format = $layer->get('image.format'); } else { $format = $options['output_format']; } $layer->set('final.format', $format); }
/** * @param PhpGdEvent $event */ public function addImageMetadatas(PhpGdEvent $event) { $image = $event->getImage(); $layers = $event->getLayers(); $format = $layers[0]->get('final.format'); $image->setMime($this->context->getImageMime($format)); $image->setExtension($this->context->getImageExtension($format)); $image->setWidth($layers[0]->get('final.width')); $image->setHeight($layers[0]->get('final.height')); $image->addExtras(['original_width' => $layers[0]->get('image.width'), 'original_height' => $layers[0]->get('image.height')]); }
/** * @param PhpGdEvent * @throws RuntimeException */ public function verifyFreeType(PhpGdEvent $event) { $layers = $event->getLayers(); foreach ($layers as $key => $layer) { if (!$layer instanceof TextLayerInterface) { continue; } if (!$this->context->isFreeTypeSupported()) { throw new RuntimeException('adding.text.not.supported'); } break; } }
/** * @param PhpGdEvent $event */ public function createImage(PhpGdEvent $event) { $layers = $event->getLayers(); if (!$layers[0]->has('gif.extracted')) { return; } try { $options = $event->getOptions(); $image = $this->factory->createImage($layers, $options); $event->setImage($image); $event->stopPropagation(); } catch (\Exception $e) { $e = new TranslatedException('gif.animation.may.lost.due.to.corrupted.frame.data'); $this->extras['gif_error'] = $e->getMessage(); } }
/** * @param PhpGdEvent $event */ public function initExtracted(PhpGdEvent $event) { $options = $event->getOptions(); $layers = $event->getLayers(); if (!$options['gif_animation'] || PhpGdContext::FORMAT_GIF !== $layers[0]->get('final.format') || PhpGdContext::FORMAT_GIF !== $layers[0]->get('image.format')) { return; } $fp = $layers[0]->get('image.fp'); rewind($fp); if ('GIF89a' !== fread($fp, 6)) { return; } rewind($fp); $extracted = $this->extractor->extractFromFilePointer($fp); if (!$extracted->isAnimated()) { return; } if (!$extracted->isValid()) { $e = new TranslatedException('gif.animation.may.lost.due.to.corrupted.frame.data'); $this->extras['gif_error'] = $e->getMessage(); return; } $layers[0]->set('gif.extracted', $extracted); }
/** * @param PhpGdEvent $event */ public function createImage(PhpGdEvent $event) { $image = $this->factory->createImage($event->getLayers(), $event->getOptions()); $event->setImage($image); $event->stopPropagation(); }
/** * @param PhpGdEvent */ public function termImcUri(PhpGdEvent $event) { $layers = $event->getLayers(); foreach ($layers as $key => $layer) { if (!$layer instanceof ImageAwareLayerInterface) { continue; } if ($layer->has('image.imc_uri')) { ImcStream::fclose($layer->get('image.imc_uri')); $layer->remove('image.imc_uri'); } } }