Extension blocks ($21)
GIF89a added extensions to the format: blocks that hold no pixels but say how to show them, or carry extra data. They all share one structure, so a decoder can skip any it does not know.
Common structure
Formally the fixed block is just the first sub-block. The specification singles it out because its length and byte meanings are set in advance.
The four standard extensions
| Label | Name | Purpose | Used? |
|---|---|---|---|
F9 | graphic control | transparency, frame delay, disposal | very often, in every animation |
FF | application extension | program data, e.g. the animation loop count | often (NETSCAPE2.0) |
FE | comment | text not shown in the image | sometimes |
01 | plain text | text drawn on the image | almost never |
Labels 00-7F are meant for extensions that draw something, 80-F9 for control extensions, FA-FF for special ones. In practice no new official labels were ever added. New uses (XMP, ICC profiles) rely on the $FF application extension with their own identifier.
Skipping an unknown extension
// pos points at byte 21; returns the position after the terminator
function skipExtension(b, pos) {
pos += 2; // 21 and the label
for (let n = b[pos++]; n !== 0; n = b[pos++]) pos += n;
return pos;
}
This one function is enough to keep a decoder from stopping at an extension it does not understand. That is why 1990s browsers displayed GIFs with blocks added long after they were released.
In the example file
The whole file is broken down in the introduction.