Skip to content

Instantly share code, notes, and snippets.

@tototoshi
Last active August 29, 2015 14:02
Show Gist options
  • Save tototoshi/055d44aef05b0951d548 to your computer and use it in GitHub Desktop.
Save tototoshi/055d44aef05b0951d548 to your computer and use it in GitHub Desktop.
PHP で GIF を読む
<?php
class GIFReader
{
const TRAILER = 0x3b;
const IMAGE_INTRODUCER = 0x2c;
const EXTENSION_INTRODUCER = 0x21;
const GRAPHIC_CONTROL_LABEL = 0xf9;
const COMMENT_CONTROL_LABEL = 0xfe;
const PLAIN_TEXT_LABEL= 0x01;
const APPLICATION_EXTNSION_LABEL = 0xff;
const BLOCK_TERMINATOR = 0x00;
public static function isAnimatedGif($filename)
{
$f = fopen($filename, 'r');
$signature = fread($f, 3);
$version = fread($f, 3);
if (!in_array($signature . $version, array('GIF89a', 'GIF87a'), true)) {
return false;
}
$screen_width = ord(fread($f, 2));
$screen_height = ord(fread($f, 2));
$gctf_info = ord(fread($f, 1));
$background_color_index = ord(fread($f, 1));
$pixel_aspect_ratio = ord(fread($f, 1));
if ($gctf_info >> 7) {
fread($f, 3 * (2 << ($gctf_info & 0b111)));
}
$frame_num = 0;
while (1) {
$introducer = ord(fread($f, 1));
if ($introducer == self::TRAILER) {
break;
}
if ($introducer == self::IMAGE_INTRODUCER) {
if (++$frame_num == 2) {
return true;
}
$image_left_position = fread($f, 2);
$image_top_position = fread($f, 2);
$image_width = fread($f, 2);
$image_height = fread($f, 2);
$lctf_info = ord(fread($f, 1));
if ($lctf_info >> 7) {
fread($f, 3 * (2 << ($lctf_info & 0b1111)));
}
fread($f, 1);
while (($size = ord(fread($f, 1))) != self::BLOCK_TERMINATOR) {
fread($f, $size);
}
}
if ($introducer == self::EXTENSION_INTRODUCER) {
$label = ord(fread($f, 1));
switch ($label) {
case self::APPLICATION_EXTNSION_LABEL:
while (($size = ord(fread($f, 1))) != self::BLOCK_TERMINATOR) {
fread($f, $size);
}
break;
case self::GRAPHIC_CONTROL_LABEL;
while (($size = ord(fread($f, 1))) != self::BLOCK_TERMINATOR) {
fread($f, $size);
}
break;
case self::COMMENT_CONTROL_LABEL:
case self::PLAIN_TEXT_LABEL:
while (($size = ord(fread($f, 1))) != self::BLOCK_TERMINATOR) {
fread($f, $size);
}
break;
default:
throw new Exception("Broken GIF");
break;
}
}
}
fclose($f);
return false;
}
}
$file = $argv[1];
if (GIFReader::isAnimatedGif($file)) {
echo "animated gif" . PHP_EOL;
} else {
echo "not animated gif" . PHP_EOL;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment