GIF

GIF

Graphics Interchange Format β€” Palette, LZW-Kompression & Animation

GIF (Graphics Interchange Format) wurde 1987 von CompuServe entwickelt. Eine GIF-Datei beginnt mit einem 6 Byte langen Header (β€žGIF87aβ€œ oder β€žGIF89aβ€œ), gefolgt vom Logical Screen Descriptor und einer optionalen globalen Farbtabelle.

GIF ist palettenbasiert: hΓΆchstens 256 Farben pro Tabelle. Jedes Bild verweist ΓΌber einen Index auf diese Palette. Das macht GIF ideal fΓΌr Grafiken mit wenigen Farben, aber ungeeignet fΓΌr Fotos.

Die Bilddaten werden mit LZW verlustfrei komprimiert. Mit GIF89a kamen ErweiterungsblΓΆcke hinzu β€” vor allem die Graphic Control Extension, die Transparenz und Animationen (mehrere Bilder + VerzΓΆgerungen) ermΓΆglicht.

Magic Number: 47 49 46 38 39 61 Β β†’Β  G I F 8 9 a

🧩 Aufbau der Datei

So liegen die Bestandteile einer GIF-Datei nacheinander im Speicher.

SignaturKopf/StrukturMetadatenBilddatenEnde
Header
6 Byte
47 49 46 38 39 61
Signatur 'GIF' + Version '87a' oder '89a'.
Logical Screen Descriptor
7 Byte
<W><H><packed><bg><ar>
Leinwandbreite/-hΓΆhe, Packed-Feld (globale Tabelle?, Farbtiefe), Hintergrundfarbe.
Global Color Table
0–768 Byte
R G B R G B …
Optionale Palette: bis zu 256 EintrΓ€ge Γ  3 Byte (RGB).
Graphic Control Extension
8 Byte
21 F9 04 …
Nur GIF89a: Transparenzfarbe, VerzΓΆgerung (1/100 s), Entsorgungsmethode.
Image Descriptor + Daten
variabel
2C … <LZW-Sub-Blocks>
Bildposition/-grâße, optionale lokale Tabelle, dann LZW-komprimierte Indizes.
Trailer
1 Byte
3B
Einzelnes Byte 0x3B markiert das Dateiende.

πŸ“ Ablaufdiagramm (ASCII)

Schematischer Gesamtaufbau auf einen Blick.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 'G''I''F''8''9''a'                     ← Header (6 Byte)       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Logical Screen Descriptor (7 Byte)                            β”‚
β”‚   width(2) height(2) packed(1) bgColor(1) aspect(1)           β”‚
β”‚   packed-Bit 7 = globale Tabelle vorhanden                    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ [ Global Color Table ]  2^(N+1) EintrΓ€ge Γ— RGB                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Block-Schleife (bis Trailer):                                 β”‚
β”‚   21 F9 …  Graphic Control Extension (optional, GIF89a)       β”‚
β”‚   2C …     Image Descriptor                                   β”‚
β”‚            └─ LZW-Min-Code + [len][daten]…[len][daten] 00     β”‚
β”‚   21 FF …  Application Extension (z. B. NETSCAPE2.0 = Loop)   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 3B                                     ← Trailer (Ende)        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“Š Tabellen & Referenz

Blocktypen (Introducer-Byte)

ByteBlockBedeutung
2CImage DescriptorLeitet ein Einzelbild ein
21 F9Graphic Control Ext.Transparenz, VerzΓΆgerung, Disposal
21 FEComment ExtensionTextkommentar
21 01Plain Text Ext.Text als Grafik (selten)
21 FFApplication Ext.z. B. NETSCAPE2.0 (Loop-Anzahl)
3BTrailerDateiende

Packed-Feld im Screen Descriptor

Bit(s)FeldBedeutung
7Global Color Table Flag1 = globale Palette folgt
4–6Color ResolutionBittiefe der Quellfarben βˆ’ 1
3Sort FlagPalette nach HΓ€ufigkeit sortiert
0–2Size of GCTTabellengrâße = 2^(Wert+1)

⌨️ C-Strukturen & Auslese-Code

Einfache C-Strukturen, die exakt dem Byte-Layout entsprechen, plus Beispielcode zum Einlesen.

Header & Logical Screen Descriptor Β· c
#include <stdint.h>

#pragma pack(push, 1)
typedef struct {
    char    signature[3];   /* 'G','I','F'                    */
    char    version[3];     /* '8','7','a' oder '8','9','a'    */
} gif_header_t;

typedef struct {
    uint16_t width;         /* Leinwandbreite  (Little-Endian)*/
    uint16_t height;        /* LeinwandhΓΆhe    (Little-Endian)*/
    uint8_t  packed;        /* siehe Bitfeld unten            */
    uint8_t  bg_color_index;/* Index in globale Palette       */
    uint8_t  pixel_aspect;  /* SeitenverhΓ€ltnis (meist 0)     */
} gif_lsd_t;
#pragma pack(pop)

/* Bitmasken fΓΌr das packed-Feld */
#define GIF_HAS_GCT(p)   (((p) & 0x80) != 0)
#define GIF_GCT_SIZE(p)  (1 << (((p) & 0x07) + 1))  /* Farbanzahl */

ℹ️ Wichtig: GIF speichert Mehrbyte-Zahlen Little-Endian (anders als PNG/JPEG!).

Image Descriptor & Graphic Control Extension Β· c
#pragma pack(push, 1)
typedef struct {
    uint8_t  separator;     /* immer 0x2C                     */
    uint16_t left, top;     /* Position auf der Leinwand      */
    uint16_t width, height; /* Bildgrâße                      */
    uint8_t  packed;        /* lokale Palette?, Interlace     */
} gif_image_descriptor_t;

typedef struct {
    uint8_t  introducer;    /* 0x21 Extension                 */
    uint8_t  label;         /* 0xF9 Graphic Control           */
    uint8_t  block_size;    /* immer 4                        */
    uint8_t  packed;        /* Disposal + Transparenz-Flag    */
    uint16_t delay_cs;      /* VerzΓΆgerung in 1/100 Sekunden  */
    uint8_t  transp_index;  /* transparenter Paletten-Index   */
    uint8_t  terminator;    /* 0x00                           */
} gif_gce_t;
#pragma pack(pop)
GIF-Header einlesen & validieren Β· c
#include <stdio.h>
#include <string.h>

int read_gif_header(FILE *f, gif_lsd_t *lsd) {
    gif_header_t h;
    if (fread(&h, 1, sizeof h, f) != sizeof h) return -1;
    if (memcmp(h.signature, "GIF", 3) != 0) return -1;     /* kein GIF */

    int v89 = (memcmp(h.version, "89a", 3) == 0);
    int v87 = (memcmp(h.version, "87a", 3) == 0);
    if (!v89 && !v87) return -1;                            /* unbekannt */

    fread(lsd, 1, sizeof *lsd, f);
    printf("GIF%.3s  %ux%u  Palette: %s (%d Farben)\n",
           h.version, lsd->width, lsd->height,
           GIF_HAS_GCT(lsd->packed) ? "global" : "keine",
           GIF_GCT_SIZE(lsd->packed));
    return 0;
}

ℹ️ Little-Endian-Felder kΓΆnnen auf x86 direkt gelesen werden, auf Big-Endian-CPUs nicht.

πŸ—œοΈ Kompression

GIF komprimiert die Paletten-Indizes mit LZW (Lempel-Ziv-Welch) β€” verlustfrei. LZW baut wΓ€hrend des Lesens ein wachsendes WΓΆrterbuch aus bereits gesehenen Index-Folgen auf und ersetzt Wiederholungen durch kurze Codes. Die komprimierten Daten liegen in β€žSub-Blocksβ€œ (je max. 255 Byte, LΓ€nge vorangestellt), abgeschlossen durch ein Null-Byte.

πŸ’‘ Wissenswert

✨Die Aussprache ist bis heute umstritten β€” der Erfinder Steve Wilhite sagte β€žJifβ€œ (wie das Erdnussbutter-Logo).
✨Animationen sind technisch nur eine Folge von Image-Blâcken mit Graphic Control Extensions dazwischen.
✨Endlosschleifen entstehen durch die NETSCAPE2.0-Application-Extension β€” sie steht nicht im Original-Standard.
← ZurΓΌck zur Übersicht