stil / gif-endec

PHP GIF encoder and decoder
63 stars 16 forks source link

Decoding fails #8

Closed holgerlembke closed 7 years ago

holgerlembke commented 7 years ago

I try to decode the image downloaded from http://icons.wxug.com/i/c/k/clear.gif

it fails. Error I get is "Fatal error: Uncaught Error: Call to a member function setOffset() on null in GIFEndec/Decoder.php:242".

It seems no $this->currentFrame has been created. If I create one "on the fly" in decode() it works.


    public function decode(callable $onFrameDecoded)
    ....
                    case 0x2C:
                        if (!$this->currentFrame) {
                           $this->currentFrame = new Frame();
            }   
stil commented 7 years ago

Can you provide a short code snippet that reproduces the issue? I'm trying with following

<?php
require __DIR__ . "/vendor/autoload.php";

use GIFEndec\Events\FrameDecodedEvent;
use GIFEndec\IO\FileStream;
use GIFEndec\Decoder;

$gifStream = new FileStream(__DIR__ . '/clear.gif');
$gifDecoder = new Decoder($gifStream);
$gifDecoder->decode(function (FrameDecodedEvent $event) {

    $event->decodedFrame->getStream()->copyContentsToFile(
        __DIR__ . "/issue8/frame{$event->frameIndex}.gif"
    );

    echo $event->decodedFrame->getDuration() . "\n";
});

But it doesn't fail for me.

holgerlembke commented 7 years ago

I might show my relative cluelessness in php, but here we go:

<DOCTYPE html>
<html><head></head><body>
<?php
  require_once "GIFEndec/IO/PhpStream.php"; 
  require_once "GIFEndec/IO/FileStream.php"; 
  require_once "GIFEndec/IO/MemoryStream.php"; 
  require_once "GIFEndec/Geometry/Point.php"; 
  require_once "GIFEndec/Geometry/Rectangle.php"; 
  require_once "GIFEndec/Events/FrameDecodedEvent.php"; 
  require_once "GIFEndec/Events/FrameRenderedEvent.php"; 
  require_once "GIFEndec/Color.php"; 
  require_once "GIFEndec/Frame.php"; 
  require_once "GIFEndec/Renderer.php"; 
  require_once "GIFEndec/Decoder.php"; 
  require_once "GIFEndec/Encoder.php"; 

  use GIFEndec\Events\FrameDecodedEvent;
  use GIFEndec\IO\FileStream;
  use GIFEndec\IO\MemoryStream;
  use GIFEndec\Decoder;

  // http://servernameetcyouknowthedrill/anyfile.html?http://icons.wxug.com/i/c/k/clear.gif
  // http://pensum:8080/?http://icons.wxug.com/i/c/k/clear.gif
  $query = $_ENV['QUERY_STRING'];

  if ($stream = fopen($query, 'r')) {
    $gif = stream_get_contents($stream, -1, 10);
    echo strlen($gif);
    echo "<p>";
    fclose($stream);
  }

  $gifStream = new MemoryStream();
  $gifStream->writeString($gif);
  $gifStream->seek(0);

  $gifDecoder = new Decoder($gifStream);
  echo "ok1<br>";
  $gifDecoder->decode(function (FrameDecodedEvent $event) {
      $paddedIndex = str_pad($event->frameIndex, 3, '0', STR_PAD_LEFT);

      echo "opk";
      echo $event->decodedFrame->getDuration() . "\n";
    }
  );

?>
</body></html>

Goal was to have it run as a gif converter proxy in my local net on a nas4free system.

stil commented 7 years ago

I'm not sure why did you set offset to 10 in this line:

    $gif = stream_get_contents($stream, -1, 10);

This way it skips first 10 bytes of image and decoding becomes impossible. It's enough to have just:

    $gif = stream_get_contents($stream);

More information on stream_get_contents you can find here: https://secure.php.net/manual/en/function.stream-get-contents.php

holgerlembke commented 7 years ago

Thank you. I'm not sure what crossed my mind at that moment, too. As I said, /me not used in writing php and so.... it looks very stupid sometimes.