tags:

views:

208

answers:

1

How do I do this in C#? I looked all over the web but couldn't find an answer.

+3  A: 

According to the GIF spec, the byte stream of a gif image starts with 6 bytes for the header, and 7 bytes for the "logical screen descriptor".

The 5th byte of the logical screen descriptor is a "packed fields" byte. The first bit of the "packed fields" is set if the image contains a global color table. The last three bits are a number X that you can use to calculate the size of the global color table as 3 x 2^(X+1).

Then follows the global color table (if it is present). To skip over this you need to know its size, calculated as shown above.

Then follows a 10 byte "image descriptor". The last byte of those is another "packed fields". The second bit of that byte is set if the image is interlaced.

   public bool IsInterlacedGif(Stream stream)
   {
     byte[] buffer = new byte[10];
     int read;

     // read header
     // TODO: check that it starts with GIF, known version, 6 bytes read 
     read = stream.Read(buffer, 0, 6); 

     // read logical screen descriptor
     // TODO: check that 7 bytes were read
     read = stream.Read(buffer, 0, 7);
     byte packed1 = buffer[4];
     bool hasGlobalColorTable = ((packed1 & 0x80) != 0); // extract 1st bit

     // skip over global color table
     if (hasGlobalColorTable)
     {
        byte x = (byte)(packed1 & 0x07); // extract 3 last bits
        int globalColorTableSize = 3 * 1 << (x + 1);
        stream.Seek(globalColorTableSize, SeekOrigin.Current);
     }

     // read image descriptor
     // TODO: check that 10 bytes were read
     read = stream.Read(buffer, 0, 10);
     byte packed2 = buffer[9];
     return ((packed2 & 0x40) != 0); // extract second bit
  }

No doubt a similar inspection of the byte stream can be done for JPG and PNG, if you read those specifications.

Wim Coenen