Eine beiläufige Frage deckt eine 30 Jahre alte Fähigkeit auf
Am 17. Juli postete der bekannte Sicherheitsforscher lcamtuf (Michał Zalewski) eine lose Idee auf Mastodon:
Progressive JPEGs senden beim Laden zuerst Niederfrequenzdaten und füllen dann allmählich die Details auf. Ich wette, man kann das umkehren — ein „regressives JPEG“ machen, das erst gut aussieht und dann allmählich schlechter wird.
Der Post löste keine große Diskussion in der Tech-Szene aus — aber jemand sah ihn and legte los.
Zwei Tage später veröffentlichte der Entwickler Maurycy in der Tech-Community Lobsters sein Ergebnis: Nicht nur „regressive Bilder“ waren möglich, ein JPEG ließ sich wie ein GIF animieren. Der Beitrag erreichte △95 Punkte and wurde zum meistbewerteten Inhalt des Tages.

- ▲ Quelle: maurycyz.com. Dieselbe JPEG-Datei zeigt in verschiedenen Ladephasen unterschiedliche Katzen — der Browser glaubt, er werde „allmählich schärfer“, dabei wurde der Inhalt ausgetauscht. *
Der JPEG-Standard wurde 1992 geboren and ist nun 34 Jahre alt. Von Digitalkameras über Handy-Galerien bis zu Web-Bildern werden weltweit täglich Milliarden JPEGs betrachtet, übertragen and gespeichert. Und erst letzten Monat entdeckte jemand eine Fähigkeit in diesem Standard, die nie jemand genutzt hat — Animationen.
Zuerst unscharf, dann scharf — ein geniales Design
Um diese Entdeckung zu verstehen, muss der Autor zunächst ein Design aus den 1990er Jahren erklären.
Wer früher im Netz war, erinnert sich: Bei langsamer Verbindung baute sich ein großes Bild von oben nach unten zeilenweise auf. Das nennt man „Baseline-JPEG“ — die Daten sind der Reihe nach angeordnet, der Browser zeigt, was er empfängt.
Später fügte der JPEG-Standard eine Option namens „progressive JPEG“ hinzu. Sie funktioniert völlig anders: Zuerst wird die „Kontur“ des Bildes gesendet, dann werden nach und nach Details ergänzt.
Ein verständlicher Vergleich:
Ihr Freund ist in den Bergen mit schlechtem Empfang and will Ihnen ein Gruppenfoto schicken. Auf die alte Art sehen Sie das Foto nur von oben nach unten zeilenweise erscheinen. Mit „progressive“ schickt Ihr Freund zuerst eine verschwommene Miniatur im 1/16-Format — Sie erkennen sofort, dass es ein Gruppenfoto ist. Dann kommen Detaildaten: Gesichtsausdrücke, Stoffstrukturen, Blätter im Hintergrund, alles wird allmählich schärfer.
Die technische Umsetzung zerlegt die Bilddaten in mehrere „Batches“ (im Standard „scan“ genannt). Jeder Batch trägt ein Label, das angibt, für welchen Präzisionsbereich er zuständig ist. Der erste Batch enthält nur die grobsten Informationen, spätere Batches ergänzen höherfrequente Details.
Der entscheidende Punkt: Der Standard schreibt vor, dass jeder Batch seinen abgedeckten Bereich deklariert — aber er schreibt nie vor, dass die Inhalte späterer Batches zum selben Bild gehören müssen wie die früheren.
Wie ein Paketschein, auf dem nicht steht „muss dieselbe Person empfangen“
lcamtufs ursprüngliche Idee war das „regressive JPEG“: Der erste Batch legt ein hübsches Bild, spätere Batches decken es allmählich mit Hässlichem zu. Zum Beispiel ein Foto von Essen, das nach halber Ladezeit zu verschimmelter Nahrung wird.
Aber Maurycy entdeckte, dass man weiter gehen kann.
Da spätere Batches das bereits gerenderte Bild überdecken können, warum nicht einfach mehrere verschiedene Bilder in dieselbe Datei packen? Die Vorgehensweise ist erstaunlich einfach:
Man hängt die „Datensegmente“ mehrerer gleich großer JPEG-Bilder aneinander, entfernt die überflüssigen Markierungsköpfe dazwischen, and der Browser rendert sie als mehrere „Präzisionsebenen“ desselben Bildes nacheinander.
Zum Vergleich:
Sie schicken eine Reihe Pakete an ein Versandunternehmen, auf jedem Lieferschein steht „Empfangsadresse: Familie Li, Inhalt: Foto“. Der Bote liefert sie nacheinander and aktualisiert jedes Mal das „Foto“ bei Familie Li. Aber das zweite Foto, das Familie Li erhält, ist völlig anders als das erste — das Versandsystem prüft nur, ob die Kategorie „Foto“ stimmt, nicht, ob es dasselbe Foto ist.
Der Browser macht es genauso. Er prüft, ob das Label jedes Batches (Präzisionsbereich, Farbkanal) dem JPEG-Standard entspricht, prüft aber nie, ob „dieses Bild dasselbe ist wie das vorherige“. Er überdeckt treu das alte Bild mit den neuen Daten — and so
ändert sich das, was Sie sehen.
Vom „Bild austauschen“ zum „Video abspielen“
Die erste Version hatte eine Einschränkung: Ein normales progressives JPEG enthält etwa 10 Batches (scans). Die meisten Browser-Decoder glauben nach etwa 10 Batches, das Bild sei fertig geladen, and weigern sich, weiter zu empfangen. Das bedeutete, man konnte nur acht oder neun Frames einbauen — bei weitem nicht genug für eine Animation.
Maurycy optimierte weiter. Er entdeckte, dass man einen „minimalen Batch“ bauen kann: Jeder Frame nutzt nur einen einzigen DC-Scan (enthält nur die grundlegendsten Farbinformationen, keine Details). So ist ein Bild nur 1/16 der Schärfe der Vollversion — als Animationsframe aber ausreichend.
Mit dieser Methode kann Chrome vor dem Aufgeben etwa 90 Frames rendern, Firefox hat noch mehr Geduld. 90 Frames reichen für ein kurzes Video.

- ▲ Quelle: maurycyz.com. Eine statische JPEG-Datei nutzt die Überdeckungseigenschaft progressiver Batches, um beim Laden Frames einer laufenden schwarzen Katze abzuspielen. Das ist eine völlig JPEG-konforme Datei, die jeder Browser öffnen kann. *
Wozu ist das gut?
Ehrlich gesagt — gar nichts.
Dieser Hack hat einen fatalen Fehler: Man kann die Abspielgeschwindigkeit nicht steuern. Denn die „Framerate“ hängt völlig von der Netzgeschwindigkeit ab — schneller Download, schnellere Wiedergabe, langsamer Download, langsamere Wiedergabe. Er hat keinen Zeitsteuerungsmechanismus wie GIF- oder Videoformate.
Und die meiste Bildbetrachtungssoftware hört auf zu zeigen, sobald das Bild „geladen“ ist, and spielt nicht in Schleife. Um den Animationseffekt zu sehen, muss man bei langsamer Verbindung schrittweise laden oder eine spezielle Darstellungsweise nutzen.
Aber das ist unwichtig.
Wirklich interessant ist die Entdeckung an sich: Ein vor 30 Jahren geschriebener internationaler Standard, 30 Jahre lang von unzähligen Ingenieuren gelesen, implementiert and genutzt — and keinem ist aufgefallen, dass er animieren kann — bis jemand beiläufig fragte.
Ein ignorierter Standard and der Triumph der technischen Neugier
Diese Geschichte hat für den Autor einen besonderen Reiz.
Der JPEG-Standard — veröffentlicht von der International Organization for Standardization (ISO), tausende Seiten Technikdokumentation, von aller Bildsoftware der Welt implementiert — er steht da, unverrückbar, seit 34 Jahren. Jede Zeile seiner Spezifikation ist öffentlich, jeder kann sie lesen.
Der „Scan-Überdeckungs“-Mechanismus progressiver JPEGs stand von Anfang an im Standard. lcamtuf entdeckte keine neue Lücke, er stellte einfach eine Frage, die der Standard nie mit „das geht nicht“ beantwortet hat: Was passiert, wenn die Daten des späteren Scans anders sind als die des früheren?
Der Standard kann diese Frage nicht beantworten — weil er nie dachte, dass jemand das tun würde.
Und Maurycy schrieb nicht einmal ein kompliziertes Programm. Sein Code ist eine kurze C-Datei, deren Wesen darin besteht, „die mittleren Teile einiger Bilder zusammenzufügen and die Kopf- and Fußmarkierungen zu entfernen“. Die eigentliche Schwierigkeit lag darin, auf die Idee zu kommen.
Die Tech-Szene diskutiert zu viel über „Best Practices“, „Performance-Optimierung“, „Architekturdesign“. Ab and zu taucht so eine Geschichte auf — jemand kramt ein 30 Jahre altes Dokument hervor, zeigt auf eine Zeile and sagt „hier steht nicht, dass es verboten ist“ — and erinnert an den Ursprung des Hacker-Geistes.
Zum Schluss
Wenn Sie es selbst ausprobieren möchten, hat Maurycy auf seinem Blog den gesamten Code and Beispielbilder veröffentlicht. Eine JPEG-Datei von einigen hundert KB, in einem Browser geöffnet, „erwacht“ beim Laden allmählich zum Leben.
Natürlich ist das kein revolutionärer Durchbruch. Es wird GIF nicht ersetzen, die Formatlandschaft nicht verändern. Aber es ist die Art Entdeckung, die einen schmunzeln lässt — wie eine nie geöffnete Geheimtür unter den Dielen eines alten Hauses zu finden; hinter der Tür kein Schatz, aber der Moment des Öffnens ist an sich eine Freude.
Referenzen:
- Lobsters Diskussion: Regressive JPEGs
- lcamtufs ursprüngliche Mastodon-Frage
- Maurycys Tech-Blog: Regressive JPEGs