Intervention / gif

Native PHP GIF Encoder/Decoder
MIT License
39 stars 8 forks source link

Opening an animated GIF results in DecoderException: Unable to decode Data Block #11

Closed dinamic closed 8 months ago

dinamic commented 9 months ago

Describe the bug Upon trying to open a GIF image an exception is thrown.

% php test.php

Fatal error: Uncaught Intervention\Gif\Exceptions\DecoderException: Unable to decode Data Block in /app/vendor/intervention/gif/src/Decoders/FrameBlockDecoder.php:38
Stack trace:
#0 /app/vendor/intervention/gif/src/Traits/CanDecode.php(21): Intervention\Gif\Decoders\FrameBlockDecoder->decode()
Intervention/image#1 /app/vendor/intervention/gif/src/Decoders/GifDataStreamDecoder.php(41): Intervention\Gif\AbstractEntity::decode(Resource id Intervention/image#61)
Intervention/image#2 /app/vendor/intervention/gif/src/Traits/CanDecode.php(21): Intervention\Gif\Decoders\GifDataStreamDecoder->decode()
Intervention/image#3 /app/vendor/intervention/gif/src/Decoder.php(26): Intervention\Gif\AbstractEntity::decode(Resource id Intervention/image#61)
Intervention/image#4 /app/vendor/intervention/image/src/Drivers/Gd/Decoders/Traits/CanDecodeGif.php(25): Intervention\Gif\Decoder::decode('test.gif')
Intervention/image#5 /app/vendor/intervention/image/src/Drivers/Gd/Decoders/FilePathImageDecoder.php(43): Intervention\Image\Drivers\Gd\Decoders\FilePathImageDecoder->decodeGif('test.gif')
Intervention/image#6 /app/vendor/intervention/image/src/Drivers/AbstractDecoder.php(34): Intervention\Image\Drivers\Gd\Decoders\FilePathImageDecoder->decode('test.gif')
Intervention/image#7 /app/vendor/intervention/image/src/Drivers/AbstractDecoder.php(40): Intervention\Image\Drivers\AbstractDecoder->handle('test.gif')
Intervention/image#8 /app/vendor/intervention/image/src/Drivers/AbstractDecoder.php(40): Intervention\Image\Drivers\AbstractDecoder->handle('test.gif')
Intervention/image#9 /app/vendor/intervention/image/src/Drivers/AbstractDecoder.php(40): Intervention\Image\Drivers\AbstractDecoder->handle('test.gif')
Intervention/image#10 /app/vendor/intervention/image/src/Drivers/AbstractDecoder.php(40): Intervention\Image\Drivers\AbstractDecoder->handle('test.gif')
Intervention/image#11 /app/vendor/intervention/image/src/Drivers/AbstractDecoder.php(40): Intervention\Image\Drivers\AbstractDecoder->handle('test.gif')
Intervention/image#12 /app/vendor/intervention/image/src/Drivers/AbstractDecoder.php(40): Intervention\Image\Drivers\AbstractDecoder->handle('test.gif')
Intervention/image#13 /app/vendor/intervention/image/src/Drivers/AbstractDecoder.php(40): Intervention\Image\Drivers\AbstractDecoder->handle('test.gif')
Intervention/image#14 /app/vendor/intervention/image/src/Drivers/AbstractDecoder.php(40): Intervention\Image\Drivers\AbstractDecoder->handle('test.gif')
Intervention/image#15 /app/vendor/intervention/image/src/Drivers/AbstractDecoder.php(40): Intervention\Image\Drivers\AbstractDecoder->handle('test.gif')
Intervention/image#16 /app/vendor/intervention/image/src/Drivers/AbstractDecoder.php(40): Intervention\Image\Drivers\AbstractDecoder->handle('test.gif')
Intervention/image#17 /app/vendor/intervention/image/src/Drivers/AbstractInputHandler.php(28): Intervention\Image\Drivers\AbstractDecoder->handle('test.gif')
Intervention/image#18 /app/vendor/intervention/image/src/Drivers/Gd/Driver.php(111): Intervention\Image\Drivers\AbstractInputHandler->handle('test.gif')
Intervention/image#19 /app/vendor/intervention/image/src/ImageManager.php(98): Intervention\Image\Drivers\Gd\Driver->handleInput('test.gif', Array)
Intervention/image#20 /app/test.php(10): Intervention\Image\ImageManager->read('test.gif')
Intervention/image#21 {main}
  thrown in /app/vendor/intervention/gif/src/Decoders/FrameBlockDecoder.php on line 38

Code Example

<?php
require_once __DIR__ . '/vendor/autoload.php';

use Intervention\Image\ImageManager;

$input = __DIR__ . '/test.gif';
$output = __DIR__ . '/test_resized.gif';
$url = 'https://gist.github.com/vininjr/d29bb07bdadb41e4b0923bc8fa748b1a/raw/88f20c9d749d756be63f22b09f3c4ac570bc5101/programming.gif';

file_put_contents($input, file_get_contents($url));

$image = ImageManager::gd()->read('test.gif');
$image->resize(100, 100);
$image->save($output);

Expected behavior The image to be opened, resized and saved.

Images Here's an image I found in Google at https://gist.github.com/vininjr/d29bb07bdadb41e4b0923bc8fa748b1a:

Environment (please complete the following information):

olivervogel commented 9 months ago

Thanks for reporting. I will look into this.

olivervogel commented 9 months ago

Since GIF files do not always correspond 100% to the original specification, my decoder has a "virtual" block called FrameBlock which allows different block elements in various orders and is not part of the official GIF spec. The only requirement is that the FrameBlock ends with a Table Based Image.

Apart from your file, I have not come across any GIF file that deviates from this unofficial "standard". Your file ends with a Comment Extension. However, the format is correct and I mistakenly assumed this standard. The decoder must be adapted accordingly.

olivervogel commented 8 months ago

This issue should be fixed. Update intervention/gif to >= 4.0.2, which should happen automatically if you have required intervention/image.

dinamic commented 8 months ago

Awesome! Thanks, @olivervogel 🚀