/** * @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 (!$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); }