According to the GIF specification , the byte stream of the gif image starts with 6 bytes for the header and 7 bytes for the "logical screen descriptor".
The fifth byte of the logical screen descriptor is the packed field byte. The first bit of "packed fields" is set if the image contains a global color table. The last three bits are the number X, which can be used to calculate the size of the global color table as 3 x 2^(X+1) .
Then follows the global color table (if present). To skip this, you need to know its size, calculated as shown above.
Then comes the decimal “image descriptor”. The last byte is another "packed field". The second bit of this 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 }
Undoubtedly, a similar byte stream check can be performed for JPG and PNG if you read these specifications.
source share