<?php
/**
- * GIF frame counter.
- * Originally written in Perl by Steve Sanbeg.
- * Ported to PHP by Andrew Garrett
- * Deliberately not using MWExceptions to avoid external dependencies, encouraging
- * redistribution.
- */
+ * GIF frame counter.
+ *
+ * Originally written in Perl by Steve Sanbeg.
+ * Ported to PHP by Andrew Garrett
+ * Deliberately not using MWExceptions to avoid external dependencies, encouraging
+ * redistribution.
+ *
+ * @file
+ * @ingroup Media
+ */
+/**
+ * GIF frame counter.
+ *
+ * @ingroup Media
+ */
class GIFMetadataExtractor {
static $gif_frame_sep;
static $gif_extension_sep;
static $gif_term;
static function getMetadata( $filename ) {
- wfProfileIn( __METHOD__ );
-
self::$gif_frame_sep = pack( "C", ord("," ) );
self::$gif_extension_sep = pack( "C", ord("!" ) );
self::$gif_term = pack( "C", ord(";" ) );
// Found a frame
$frameCount++;
- ## Skip dimensions (Why is this 8 bytes and not 4?)
+ ## Skip bounding box
fread( $fh, 8 );
## Read BPP
if ($extension_code == 0xF9) {
// Graphics Control Extension.
fread( $fh, 1 ); // Block size
+
fread( $fh, 1 ); // Transparency, disposal method, user input
$buf = fread( $fh, 2 ); // Delay, in hundredths of seconds.
// NETSCAPE2.0 (application name)
if ($blockLength != 11 || $data != 'NETSCAPE2.0') {
- self::skipBlock();
+ fseek( $fh, -($blockLength + 1), SEEK_CUR );
+ self::skipBlock( $fh );
continue;
}
- fread( $fh, 2 ); // Block length and introduction, should be 03 01
+ $data = fread( $fh, 2 ); // Block length and introduction, should be 03 01
+
+ if ($data != "\x03\x01") {
+ throw new Exception( "Expected \x03\x01, got $data" );
+ }
// Unsigned little-endian integer, loop count or zero for "forever"
$loopData = fread( $fh, 2 );
// Read out terminator byte
fread( $fh, 1 );
+ } else {
+ self::skipBlock( $fh );
}
} elseif ( $buf == self::$gif_term ) {
break;
}
}
- wfProfileOut( __METHOD__ );
-
return array(
'frameCount' => $frameCount,
'looped' => $isLooped,
}
}
-}
\ No newline at end of file
+}