GIF Signature Format: Introduction & Recovery
Graphics Interchange Format
|Type of format||Raster/lossless|
|Colors||up to 8 bits|
|Magic number||47 49 46 38 37 61 (GIF87a)
47 49 46 38 39 61 (GIF89a)
Developed by CompuServe in 1987, a bitmap image format known as GIF (Graphics Interchange Format has since received widespread use on the internet due to its wide support and portability.
GIF format supports up to 8 bits per pixel for each image, allowing a single image to reference its palette of up to 256 different colors chosen from the 24-bit RGB color space.
It supports animations and allows a separate palette of up to 256 colors for each frame. GIF images are compressed using the LZW lossless data compression technique to reduce the file size without degrading the visual quality of the image.
GIF files start with a fixed-length header (GIF87a or GIF89a) where 7a and 9a specify the version, followed by a fixed-length Logical Screen Descriptor giving the size and other characteristics of the logical display. Screen Descriptor may also specify the presence & size of a Global Color Table, which follows next (if present).
After that, the file is divided into segments, each introduced by a 1-byte prefix:
- An image - introduced by hex value: 2C, a comma sign (,)
- An extension block - introduced by hex value: 21, an exclamation point (!)
- The trailer - a single byte of hex value: 3B, a semi-colon (;), which should be the last byte of the file
An image starts with a fixed-length Image Descriptor, which may specify the presence and size of a Local Color Table (which follows next if present).
The code is being continued with image data: one byte giving the bit width of the unencoded symbols (which must be at least 2 bits wide, even for bi-color images).
It is later followed by a linked list of sub-blocks containing the LZW-encoded data.
Extension blocks (blocks that "extend" the 87a definition via a mechanism already defined in the 87a spec) consist of the prefix, an additional byte specifying the type of an extension, and a linked list of sub-blocks with the extension data.
Extension blocks that modify an image (like the Graphic Control Extension that specifies the optional animation delay time and optional transparent background color) must immediately precede the segment with the image to which they are referring. The linked lists used by the image data and the extension blocks consist of series of sub-blocks, each sub-block beginning with a byte giving the number of subsequent data bytes in the sub-block (1 to 255). The series of sub-blocks is terminated by an empty sub-block (a 0 byte). A closer look at the GIF image
When inspecting sample.gif file's binary data using any Hex Viewer, like Active@ Disk Editor we can see it starts with a signature GIF8 (hex: 47 49 46 38). It is followed with the version 9a (hex: 39 61), and then goes logical screen width: 280 pixels (hex 18 01) and height 90 pixels (hex: 5A 00). All multi-byte values in GIF structures are in little-endian order (lowest byte goes first).
Flags byte at offset 0A (hex) is E6 (hex), high bit is set, which shows that Global Color Table is following. Its size is calculated as:
(1 <<((0xE6 & 0x07) + 1)) * 3 = 384 bytes.
Add 13 (GIF header size) to 384 (GCT size) and the result is 397. Thus at offset 397 (hex: 018D) first data block starts. The first block starts with an exclamation sign (! or 21 hex) which means it is an extension block.
Extension block size is fixed, and it is 8 bytes. Add 8 bytes to 397, and go to the next block at offset 405 (hex: 0195). The second block starts with a comma sign (, or 2C hex) which means it is an image block. It has fixed size header (11 bytes). Image header's last byte (at offset 019F hex) is a GCT flag: 07.
Calculating GCT size the same way as in GIF primary header. A high bit (hex: 80) is NOT set, so no GCT is followed and no calculations for color table required. After image header, the next in line are sub-blocks. First sub-block has its size in a first byte, which is 255 (hex value FF at offset: 01A0 hex).
Next sub-block offset is 672 (405 + 11 + 1 + 255). Keep iterating blocks and sub-blocks. This sample has 4 sub-blocks by 255 bytes each, at offsets: 01A0, 02A0, 03A0, 04A0 hex, and one sub-block 126 bytes (hex: 7E) at offset 05A0 hex. At offset 061F hex (05A0+7E hex) there is a zero byte 00 which says that no more sub-blocks in the current block. Moving to the next byte (offset 0620 hex). The next block starts with a semi-colon (; or 3B hex), which points to the end of the file. Thus, this GIF image file size is 1,569 bytes (hex: 0620+1).