Endianness of 16-Bit Integers in GIF Headers
This article explains the byte order used for 16-bit integer values in Graphics Interchange Format (GIF) file headers and descriptors. It covers the specific endianness mandated by the GIF specification, highlights the exact header fields affected, provides a byte-level example of how dimensions are stored, and details the implications for software developers parsing GIF files on different CPU architectures.
The GIF specification—encompassing both the original GIF87a and the updated GIF89a standards—explicitly dictates that all multi-byte numerical values are stored in little-endian byte order. In a little-endian format, the least significant byte (LSB) is stored at the lowest memory address (first in the byte stream), followed by the most significant byte (MSB).
In a GIF file, 16-bit unsigned integers appear immediately following
the 6-byte signature and version header (GIF87a or
GIF89a) within the Logical Screen Descriptor:
- Logical Screen Width (2 bytes): Bytes 6 and 7 of the file.
- Logical Screen Height (2 bytes): Bytes 8 and 9 of the file.
Similar 16-bit integers are also used later in the file within each local Image Descriptor:
- Image Left Position (2 bytes)
- Image Top Position (2 bytes)
- Image Width (2 bytes)
- Image Height (2 bytes)
Byte-Level Example
Consider an image with a width of 800 pixels and a height of 600 pixels:
- Width (800): In hexadecimal, 800 is
0x0320. In little-endian order, the least significant byte (0x20) is written first, followed by the most significant byte (0x03). The resulting byte sequence in the file is20 03. - Height (600): In hexadecimal, 600 is
0x0258. Stored in little-endian order, the least significant byte (0x58) comes first, followed by the most significant byte (0x02). The resulting byte sequence is58 02.
In the raw binary stream of the Logical Screen Descriptor, these dimensions appear sequentially as:
20 03 58 02
Implementation Considerations
Because GIF was developed by CompuServe primarily for x86-based personal computers, its native little-endian layout matches the native memory layout of x86 and modern ARM architectures.
When writing a GIF parser or decoder:
- On little-endian systems (such as x86, x64, and most ARM configurations), reading these 16-bit fields directly into standard 16-bit integer types requires no byte-swapping.
- On big-endian systems (such as legacy PowerPC,
SPARC, or specific network processors), developers must swap the byte
order (e.g., using functions like
ntohsor bitwise shift operations(byte1 | (byte2 << 8))) to reconstruct the correct numerical values.