-
- $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 );
- $loopData = unpack( 'v', $loopData );
- $loopCount = $loopData[1];
-
- if ($loopCount != 1) {
- $isLooped = true;
+
+ // NETSCAPE2.0 (application name for animated gif)
+ if ( $data == 'NETSCAPE2.0' ) {
+ $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 );
+ if ( strlen( $loopData ) < 2 ) {
+ throw new Exception( "Ran out of input" );
+ }
+ $loopCount = unpack( 'v', $loopData )[1];
+
+ if ( $loopCount != 1 ) {
+ $isLooped = true;
+ }
+
+ // Read out terminator byte
+ fread( $fh, 1 );
+ } elseif ( $data == 'XMP DataXMP' ) {
+ // application name for XMP data.
+ // see pg 18 of XMP spec part 3.
+
+ $xmp = self::readBlock( $fh, true );
+
+ if ( substr( $xmp, -257, 3 ) !== "\x01\xFF\xFE"
+ || substr( $xmp, -4 ) !== "\x03\x02\x01\x00"
+ ) {
+ // this is just a sanity check.
+ throw new Exception( "XMP does not have magic trailer!" );
+ }
+
+ // strip out trailer.
+ $xmp = substr( $xmp, 0, -257 );
+ } else {
+ // unrecognized extension block
+ fseek( $fh, -( $blockLength + 1 ), SEEK_CUR );
+ self::skipBlock( $fh );
+ continue;