Was ist ein GIF mit Interlacing?
Ein GIF mit Interlacing speichert Bildzeilen in vier Durchläufen statt der Reihe nach. Ein Decoder kann daher eine grobe Version des vollständigen Bildes anzeigen, bevor genügend Daten zum Darstellen jeder Zeile eintreffen.
So funktionieren GIFs mit Interlacing
GIF-Interlacing ändert nur die Reihenfolge, in der die Zeilen eines Frames in die LZW-komprimierten Bilddaten eingehen. Der erste Durchlauf deckt die gesamte Höhe mit wenigen Zeilen ab, spätere Durchläufe füllen die Lücken. Die daraus entstehende Vorschau ist ein Verhalten des Decoders, keine Vorgabe des Formats: GIF89a definiert die Zeilenreihenfolge, und ein Decoder kann Zeilen beim Eintreffen zeichnen. Der Deinterlacing-Filter von Firefox kopiert beispielsweise bei aktivierter progressiver Anzeige jede empfangene Zeile in die benachbarten Zeilen, die noch nicht eingetroffen sind. Farbtabelle, Abmessungen, Transparenzregeln und endgültige Pixel entsprechen denen bei sequenzieller Speicherung. Bibliotheken unterscheiden sich darin, welche Komponente die Umordnung rückgängig macht: Die Funktion DGifSlurp von giflib platziert die Zeilen eines Frames mit Interlacing anhand der vier Durchlauf-Offsets an ihren endgültigen Positionen. Dabei ruft sie die zeilenweise Leseroutine für jede Zeile einmal in der gespeicherten Reihenfolge auf.
Wichtige Fakten
- In welcher Reihenfolge werden die Zeilen gespeichert? Durchlauf 1 enthält Zeilen im Abstand von 8 Zeilen, beginnend mit Zeile 0, Durchlauf 2 im Abstand von 8 Zeilen, beginnend mit Zeile 4, Durchlauf 3 im Abstand von 4 Zeilen, beginnend mit Zeile 2, und Durchlauf 4 im Abstand von 2 Zeilen, beginnend mit Zeile 1. GIF89a legt dieses Muster fest. Ein Decoder verfügt daher nach Durchlauf 1 über etwa ein Achtel der Zeilen, nach Durchlauf 2 über ein Viertel und nach Durchlauf 3 über die Hälfte (exakt dann, wenn die Höhe ein Vielfaches von 8 ist). Bei niedrigen Frames bleiben Durchläufe leer: Bei vier oder weniger Zeilen enthält Durchlauf 2 keine Zeile, und ein Frame mit einer Zeile hat nur Durchlauf 1. Ein Deinterlacer muss vor dem Kopieren einer Zeile prüfen, ob die Startzeile des jeweiligen Durchlaufs innerhalb der Framehöhe liegt: Ein öffentlicher Fehlerbericht zum GIF-Decoder von APNG4Android beschreibt, wie dieser bei einem Frame mit zwei Zeilen und Interlacing über seinen Ausgabepuffer hinausschrieb, weil er zuerst eine Zeile aus Durchlauf 2 kopierte.
- Wie erkenne ich, ob ein GIF Interlacing verwendet? Pro Frame, nicht pro Datei. Das Interlace Flag ist ein Bit im gepackten Byte jedes Image Descriptor (giflib prüft es mit der Maske
0x40). Jedes Bild im Datenstrom hat seinen eigenen Deskriptor, daher können sich die Frames einer Animation unterscheiden. Werkzeuge zeigen das Flag nicht immer an: Eine Person, die libvips verwendet, bat um ein Interlacing-Feld in der GIF-Header-Ausgabe, nachdemgifsavedie Optioninterlaceerhalten hatte. - Bietet Interlacing außer der Vorschau weitere Vorteile? Nein. Die umgeordneten Zeilen bestehen weiterhin aus Indizes in die aktive Farbtabelle und werden mit LZW komprimiert. Transparenz wird weiterhin durch den einzelnen Index bestimmt, der in der Graphic Control Extension angegeben ist. Interlacing ergänzt weder Farben noch Teiltransparenz.
- Schreiben meine Werkzeuge GIFs mit Interlacing, ohne dass ich es anfordere? Manche tun das, aber nicht in jedem Codepfad. Laut Pillow-Handbuch ist die Speicheroption
interlacestandardmäßig aktiviert, sofern das Bild nicht weniger als 16 Pixel breit oder hoch ist. Im Pillow-Quellcode (Release 12.0.0 und Hauptbranch, eingesehen im Oktober 2026) wendet nur die Schreibroutine für einzelne Frames diese Option an: Die Übergabe voninterlace=Falseschaltet sie dort aus. Frames aus einem Speichervorgang für mehrere Frames (save_allmit mehr als einem resultierenden Frame) erhalten dagegen immer ein nicht gesetztes Interlace Flag und sequenzielle Zeilen. Gifsicle überlässt die Wahl dem Aufrufer:--interlaceschaltet Interlacing ein, und--same-interlacebehält die vorhandene Einstellung jeder Eingabe bei. Setzen Sie die Option explizit, wenn eine nachgelagerte Komponente eine bestimmte Anordnung erwartet. Lesen Sie außerdem das Flag der geschriebenen Frames aus, statt es aus der Standardeinstellung abzuleiten.
Wann GIFs mit Interlacing relevant sind
Interlacing ist an zwei Stellen relevant. Bei der Auslieferung ändert es die Reihenfolge, in der Zeilen eintreffen. So kann ein Decoder früh eine grobe Version des gesamten Frames anzeigen. Es handelt sich um eine Zeilenreihenfolge, keine Kompressionseinstellung. Da LZW jedoch die umgeordneten Zeilen komprimiert, ist nicht garantiert, dass die codierte Größe der Größe beim sequenziellen Encoding entspricht. GIF89a macht keine Angaben zum Einfluss von Interlacing auf die Größe. Vergleichen Sie daher beide Ausgaben, statt anzunehmen, dass sie gleich groß sind oder eine kleiner ist. Für die Verarbeitung ist relevant, dass weiterhin Dateien mit Interlacing entstehen, da Pillow GIFs mit einem einzelnen Frame standardmäßig mit Interlacing speichert. Jeder Code, der GIF-Bilddaten zeilenweise liest, muss die Zeilen daher wieder in die richtige Reihenfolge bringen, bevor er einen Frame zuschneidet, seine Größe ändert oder ihn konvertiert.
Quellen
- GIF89a-Spezifikation: Image Descriptor (Interlace Flag) und Anhang E, Bilder mit Interlacing
- giflib-Quellcode: dgif_lib.c (Interlace Flag und Deinterlacing in DGifSlurp)
- Firefox-Quellcode: image/SurfaceFilters.h (DeinterlacingFilter und progressive Anzeige)
- Pillow-Handbuch: GIF-Speicheroptionen, einschließlich interlace
- Quellcode von Pillow 12.0.0: GifImagePlugin.py (GIF-Schreibroutinen für einzelne und mehrere Frames)
- Gifsicle-Handbuch: --interlace und --same-interlace
- libvips-Issue 3267: Interlacing-Informationen im Header für das GIF-Format ergänzen
- APNG4Android-Issue 258: GIF-Decoder kann bei kleinen Frames mit Interlacing über den Ausgabepuffer hinausschreiben