GIF File Documentation


Summary

A Graphics Interchange Format file is a raster image that stores one or more frames, each indexed against a palette of up to 256 colours and compressed losslessly with LZW. CompuServe introduced it in 1987, and the 1989 revision added the looping animation and transparency it is known for today. Every browser, phone, and desktop opens a .gif file (MIME image/gif) natively, so most questions are about shrinking or converting it.

Technical details

FeatureValue
Full nameGraphics Interchange Format
File extension.gif
MIME typeimage/gif
Format typeRaster image, palette-based binary
CompressionLossless (LZW — Lempel–Ziv–Welch)
DeveloperCompuServe (Steve Wilhite)
Introduced1987 (GIF87a); GIF89a in 1989
StandardCompuServe GIF89a specification (1990)
Open standardYes — the LZW patent expired worldwide by 2004
Colour depthUp to 8-bit indexed (256 colours per frame)
PaletteGlobal and per-frame local colour tables, 2–256 entries
Transparency1-bit — one palette index made fully transparent
AnimationYes — multiple frames with per-frame delay and disposal
LoopingYes — via the NETSCAPE2.0 application extension
InterlacingYes (4-pass, optional)
MetadataMinimal — plain-text comment extension blocks
Byte orderLittle-endian
Magic number (hex)47 49 46 38 39 61 (GIF89a) or 47 49 46 38 37 61 (GIF87a)
Trailer byte3B
Related extensions.png, .apng, .webp, .jpg, .mp4, .bmp, .avif
Specificationw3.org/Graphics/GIF/spec-gif89a.txt
File signature (magic bytes)
47 49 46 38 39 61

Offset 0, 6 bytes of ASCII. This reads G I F 8 9 a, the signature plus version. The older 1987 version instead ends in 37 61 (GIF87a): bytes 47 49 46 38 37 61. GIF89a is the version behind virtually every animated GIF, because animation, transparency, and the comment/application extension blocks were added in that revision. A valid file always ends with the trailer byte 3B.

What is a GIF file?

GIF stands for Graphics Interchange Format. It is a palette-based raster image format that CompuServe released in 1987, designed by Steve Wilhite so that a colour image could be sent over a dial-up link and shown identically on any member's machine. The original release, GIF87a, stored still images only. The 1989 revision, GIF89a, added the pieces the format is now known for: frame-based animation, a single transparent palette index, and a general extension-block mechanism carrying timing, comments and application data. Virtually every animated .gif in circulation is a GIF89a file.

A GIF is a byte stream with a fixed grammar: a 6-byte signature, a Logical Screen Descriptor, an optional Global Colour Table, then a sequence of blocks (image blocks and extension blocks in any order), closed by a single trailer byte. All multi-byte integers are stored little-endian (least significant byte first), and pixel data is compressed with LZW. Everything below walks the file field by field. Where GIF's design decisions are echoed or replaced in later formats, the relevant one is linked: the still-image successor PNG, the animated APNG and WebP, and video containers such as MP4. The authoritative reference is the GIF89a specification republished by the W3C.

The 6-byte header: GIF87a versus GIF89a

The file begins with a 6-byte signature made of two fixed sub-fields: a 3-byte magic identifier and a 3-byte version. The identifier is always the ASCII string GIF (47 49 46). The version is either 87a (38 37 61) or 89a (38 39 61). A decoder reads these six bytes verbatim; there is no length prefix and no byte-order mark, because the header is pure ASCII and the same in any byte order.

The version is not cosmetic. A decoder that only understands GIF87a is entitled to reject or mishandle the extension blocks that GIF89a introduces (Graphic Control, Comment, Plain Text and Application extensions), because those blocks did not exist in 1987. An encoder is expected to write 89a the moment it uses any of those features, and may write 87a for a plain still image with no extensions. In practice most writers emit GIF89a unconditionally.

The Logical Screen Descriptor, bit by bit

Immediately after the 6-byte header comes the Logical Screen Descriptor, a fixed 7-byte structure that describes the canvas onto which every image block is painted:

Offset  Size  Field
  6      2    Logical Screen Width   (uint16, little-endian)
  8      2    Logical Screen Height  (uint16, little-endian)
 10      1    Packed Fields          (see bit layout below)
 11      1    Background Color Index
 12      1    Pixel Aspect Ratio

The width and height are the canvas size in pixels, each a 16-bit little-endian integer, so the maximum canvas is 65535 × 65535. Byte 10 is a packed field whose bits, from most significant to least, carry four separate values:

bit  7   Global Color Table Flag  (1 = a GCT follows this descriptor)
bits 6-4 Color Resolution         (bits/primary in the source, minus 1)
bit  3   Sort Flag                (1 = GCT is sorted by decreasing importance)
bits 2-0 Size of Global Color Table  (N; table holds 2^(N+1) entries)

The three low bits are the field that most confuses first-time readers. They do not store the entry count directly; they store an exponent N, and the table holds 2^(N+1) entries. So N = 0 means 2 colours, N = 7 means 256 colours, and there is no way to encode a table of any size other than a power of two. The Color Resolution bits report how many bits per primary the original image had, minus one, and are informational only. The Sort Flag hints that the palette is ordered most-important-first, which lets a decoder on a colour-poor display truncate the table sensibly.

The Background Color Index selects, from the Global Colour Table, the colour used for any part of the canvas not covered by an image (it is meaningful only when a GCT exists). The Pixel Aspect Ratio is 0 when no aspect information is given; any non-zero value r encodes the ratio as (r + 15) / 64, covering aspect ratios from 4:1 to 1:4. Almost every real file stores 00 here.

Global and Local Colour Tables

A GIF stores no RGB pixels directly. Every pixel is an index into a colour table, and each table entry is three bytes: red, green, blue, in that order, one byte each. A table of 2^(N+1) entries therefore occupies 3 × 2^(N+1) bytes. Because the index is what gets written per pixel, and the table caps at 256 entries, a single image block can reference at most 256 distinct colours.

The Global Colour Table follows the Logical Screen Descriptor when bit 7 of the packed field is set, and it is the default palette for every image in the file. Each image block may instead carry its own Local Colour Table, declared in that block's own descriptor, which overrides the global one for that image only. Local tables are what let a multi-frame animation exceed 256 colours across the whole file even though each frame is individually capped at 256. When an image sets neither a local table nor a global table, the palette is decoder-defined, which is why writers almost always supply at least a global table.

The Image Descriptor and its packed field

Each rendered image is introduced by an Image Descriptor, a 10-byte structure whose first byte is the Image Separator 0x2C (the ASCII comma). This is how a decoder recognises an image block while scanning:

Offset  Size  Field
  0      1    Image Separator  (always 0x2C)
  1      2    Image Left Position   (uint16, LE)
  3      2    Image Top Position    (uint16, LE)
  5      2    Image Width           (uint16, LE)
  7      2    Image Height          (uint16, LE)
  9      1    Packed Fields

Left, top, width and height place this image as a rectangle inside the logical screen, which is what makes partial-frame updates possible: a frame that only changes a corner of the canvas need only store that corner. The packed byte at offset 9 holds:

bit  7   Local Color Table Flag  (1 = an LCT follows this descriptor)
bit  6   Interlace Flag          (1 = rows stored in interlaced order)
bit  5   Sort Flag               (1 = LCT sorted by importance)
bits 4-3 Reserved                (must be 0)
bits 2-0 Size of Local Color Table  (M; table holds 2^(M+1) entries)

The Interlace Flag marks that the image rows are not stored top-to-bottom but in four passes (rows 0, 8, 16…, then 4, 12, 20…, then 2, 6, 10…, then the odd rows), the same progressive scheme that let a partly downloaded image show a coarse preview on slow links. If the Local Colour Table Flag is set, the table (3 × 2^(M+1) bytes) sits between this descriptor and the image data that follows.

LZW and the minimum code size

Pixel data is compressed with a variant of LZW (Lempel–Ziv–Welch). The compressed stream is preceded by a single byte, the LZW Minimum Code Size, and is then split into sub-blocks (described in the next section). The minimum code size is normally the number of bits needed to represent the palette indices, and it seeds two reserved codes and the starting code width.

Given a minimum code size of b, the code table starts with 2^b entries for the literal pixel values, plus two special codes assigned immediately after them:

  • The Clear code, value 2^b, resets the LZW dictionary back to its initial state. The encoder must emit it before the first data code, and may emit it again whenever the table fills up.
  • The End-of-Information code, value 2^b + 1, marks the end of this image's compressed data.

Codes are written with a variable width that grows as the dictionary fills. Output starts at b + 1 bits per code. Each time a new dictionary entry pushes the next code past the current width's range, the width increases by one bit, up to a hard ceiling of 12 bits (a maximum of 4096 dictionary entries). When the dictionary is exhausted, the encoder emits a Clear code, both sides reset the table to its two-special-codes-plus-literals baseline, and the width drops back to b + 1. This is a subtle point that trips up hand-written decoders: the code width depends on how many entries exist, and it must be recomputed continuously on both the encoding and decoding side. Codes are packed into bytes least-significant-bit first.

One quirk deserves a note: even a 1-bit (2-colour) image uses a minimum code size of at least 2, because the two reserved codes must not collide with the literal codes. So b is stored as max(2, bits_per_pixel).

Data sub-blocks: the 255-byte packaging

The LZW bit-stream, and the payload of most extensions, is not written as one contiguous run. It is chopped into sub-blocks, each introduced by a one-byte length count (1 to 255) followed by exactly that many data bytes. A decoder reads a length byte, consumes that many bytes, reads the next length byte, and repeats. A length byte of 0x00 is the Block Terminator: it signals that the sequence of sub-blocks is finished. This packaging is why you never see a raw length field for the whole compressed image, and why the maximum useful sub-block is 255 bytes.

The Graphic Control Extension

Timing, transparency and frame disposal live in the Graphic Control Extension (GCE), which applies to the single image block that immediately follows it. Its layout is fixed:

21 F9 04  ext introducer (0x21), GCE label (0xF9), block size (always 4)
  byte 0  Packed Fields   (reserved:3, disposal:3, user-input:1, transparency:1)
  byte 1  Delay Time      (uint16, LE, hundredths of a second)   [+byte 2]
  byte 3  Transparent Color Index
00        Block Terminator

Every extension begins with the Extension Introducer 0x21 (ASCII !); the second byte is a label identifying which extension it is (0xF9 here). The packed byte splits into three reserved high bits, a 3-bit disposal method, a 1-bit user-input flag, and a 1-bit transparency flag. The Delay Time is a 16-bit little-endian value in hundredths of a second, so a value of 0x0064 is one second; a delay of 0 asks the decoder to advance as fast as it can (most browsers clamp very small delays up to a minimum). When the transparency flag is set, the byte at offset 3 names the palette index that is treated as transparent, and pixels using that index leave whatever is already on the canvas untouched.

The disposal method decides what the decoder does with the current frame's pixels before drawing the next one:

ValueNameEffect before the next frame is drawn
0No disposal specifiedDecoder does nothing; behaviour is unspecified.
1Do not disposeLeave the current frame in place; the next frame draws on top.
2Restore to backgroundClear the frame's rectangle to the background colour.
3Restore to previousRestore the canvas to what it was before this frame drew.

Values 4 through 7 are reserved. The interplay of disposal method 1 (accumulate) with partial-frame Image Descriptors is exactly what lets a well-optimised animation store only the pixels that change between frames, rather than a full canvas each time. The 1-bit transparency here is also the reason GIF edges look hard: an index is either fully transparent or fully opaque, with no alpha channel of the kind PNG and WebP provide.

The Application Extension and the NETSCAPE2.0 loop count

The loop count of an animation is not part of the core GIF grammar. It rides in an Application Extension, a general block for vendor-specific data:

21 FF 0B  ext introducer, Application label (0xFF), block size (always 11)
  "NETSCAPE2.0"      8-byte identifier + 3-byte auth code
03 01 <count LE> 00  sub-block: id 0x01, loop count (uint16, LE), terminator

The 11 bytes after the block size are an 8-byte application identifier (NETSCAPE) and a 3-byte authentication code (2.0). A data sub-block then carries a sub-block id of 0x01 followed by a 16-bit little-endian loop count. A count of 0 means loop forever; any other value n means play the animation n additional times. This convention was introduced by the Netscape browser and became universal despite never being in the specification. A GIF with no such block plays its frames once and stops.

Comment and Plain Text extensions

Two more GIF89a extensions round out the block set. The Comment Extension (0x21 0xFE) holds human-readable 7-bit ASCII text in a chain of data sub-blocks, terminated by a 0x00 byte; decoders ignore it during rendering. The Plain Text Extension (0x21 0x01) was meant to overlay text rendered from the colour table in a grid of character cells, defined by a 12-byte header giving the text grid position, cell width and height, and foreground and background colour indices. It is effectively obsolete: almost no decoder renders it, so text in real GIFs is baked into the pixels instead.

The trailer byte

The file ends with a single Trailer byte, 0x3B (ASCII ;). It is the last byte a conforming decoder needs to read; anything after it is not part of the GIF and is ignored. A minimal still GIF is therefore: header, Logical Screen Descriptor, optional Global Colour Table, one Image Descriptor with its LZW data, then 0x3B.

An annotated header hex dump

Reading the first bytes of a real file makes the field layout concrete. Here are the opening 20 bytes of a small GIF89a with a 16-entry global colour table, annotated:

Offset  Bytes            Meaning
0000    47 49 46 38 39 61   "GIF89a"  — signature + version
0006    0A 00               width  = 0x000A = 10 px   (little-endian)
0008    0A 00               height = 0x000A = 10 px
000A    83                  packed: GCT=1, colorRes=000, sort=0, size=011
                            → 2^(3+1) = 16-entry global colour table
000B    00                  background colour index = 0
000C    00                  pixel aspect ratio = 0 (none)
000D    FF FF FF            GCT entry 0 = RGB(255,255,255)  white
0010    00 00 00            GCT entry 1 = RGB(0,0,0)        black
0013    ...                 (14 more RGB triples follow)

The packed byte 0x83 is 1000 0011 in binary: the top bit sets the Global Colour Table Flag, the low three bits are 011 = 3, giving 2^(3+1) = 16 table entries, and each entry that follows is a 3-byte RGB triple. After the 48 bytes of colour table comes the first Image Descriptor beginning with 0x2C.

Frequently asked questions

What sets the minimum LZW code size in a GIF?

It is stored as a single byte at the start of each image's compressed data, and it is normally the number of bits needed to index the active colour table, but never less than 2. That value b fixes the two reserved codes (Clear = 2^b, End-of-Information = 2^b + 1) and the starting output width of b + 1 bits.

Why does a decoder key on the byte 0x2C?

GIF blocks are self-identifying by their first byte. 0x2C introduces an Image Descriptor, 0x21 introduces an extension (with a label byte deciding which), and 0x3B is the trailer. A decoder loops reading one lead byte and dispatching on it, which is why images and extensions can appear in any order.

Why is the delay time stored as two bytes in reverse order?

All multi-byte integers in GIF are little-endian, a legacy of the format's origins on little-endian hardware. A one-second delay is written 64 00, not 00 64: the low byte 0x64 (100) comes first, then the high byte.

References