Stranger Than Usual

Tim: „Wer jetzt die letzten Tage unter einem Stein gelebt hat, das tun ja…“
Linus: „Bleibt drunter! […] Bleibt unter eurem Stein, Leute. Er ist ein super Stein.“

— LNP541 Bleibt unter Eurem Stein! (vom 6. Januar 2026)

JPEG XL steht vor der Tür

JPEG XL

Wer dieses Blog hier regelmäßig liest, weiß, dass ich besessen bin von Datenkompression, insbesondere von verlustfreier Kompression. Und ich weiß nicht einmal besonders viel über die inneren Wirkmechanismen den Kompression. Ich bin einfach besessen davon, die Daten, die hier auf dem Server liegen, für die Übertragung möglichst klein zu kriegen.

Und jetzt, nach Jahren des Dramas, steht endlich die Unterstützung von JPEG XL in Firefox und Chromium bevor. JPEG XL ist ein relativ neuer, offener Standard für Bildkompression. Es unterstützt sowohl verlustfreie als auch verlustbehaftete Kompression (wem das nichts sagt: Ich habe mal versucht, Bilddateiformate und Bildkompression verständlich zu machen). Es soll verlustfrei besser komprimieren als WebP, bei vergleichbarer Qualität kleinere Dateien erzeugen als WebP oder AVIF (und erst recht kleiner als JPEG) und, ein Alleinstellungsmerkmal: Man kann JPEG-Dateien verlustfrei re-codieren und kriegt kleinere Ergebnisdateien mit identischem Bildinhalt. Wenn man also alte JPEG-Dateien herumliegen hat, die man nich in WebP oder AVIF umcodieren wollte, weil das ein Qualitätsverlust wäre: Hier ist die Lösung.

Bis wir aber an dem heutigen Punkt angekommen sind, gab es eine Menge Drama.

Drama

Ich habe das damals nur im Hintergrund verfolgt (viele wütende Posts auf Mastodon und anderen Kanälen), aber nachdem Google experimentelle JPEG XL-Unterstützung 2021 in Chromium eingebaut hatte, haben sie diese Ende 2022 wieder entfernt (Wikipedia-Artikel dazu). Ich habe verschiedene Begründungen dafür gelesen, aber am Ende lief es darauf hinaus, dass Google sich auf die anderen Bildformate konzentrieren wollte und ein weiteres Bildformat mehr Wartungskosten und weitere Sicherheitsrisiken erzeugt hätte.

Mozilla hat daraufhin auch den experimentellen JPEG XL-Support in Firefox gestrichen. Die Idee dahinter ist hier verständlich: Kaum eine Website wird ein Bildformat verwenden, dass vom marktbeherrschenden Browser nicht auch unterstützt wird.

Es wurden dann natürlich Stimmen laut, dass Google JPEG XL unterdrücke, um ihr eigenes Bildformat (WebP) zu pushen, und dass Mozilla JPEG XL zumindest weiter hätte unterstützen können, um Druck auf Google aufzubauen. Ich persönlich kann aber verstehen, dass Google sich den Wartungsaufwand und die potentiellen Sicherheitsprobleme mit JPEG XL ersparen wollte.

In 2024 hat Mozilla dann eingelenkt und gesagt, sie würden JPEG XL unerstützen, wenn es eine Rust-Implementierung des Decoders gibt. Und diese Implementierung gibt es. Also hat Mozilla die experimentelle Unterstützung für JPEG XL wieder in Firefox eingebaut, und Google hat das bei Chromium auch gemacht.

Dieses Drama steht kurz vor dem guten Ausgang. Firefox hat JPEG XL ab Version 158 per default aktiviert (ursprünglich war Version 157 geplant, das hat aber nicht geklappt), Chromium ab Version 155 (beide liegen aktuell noch in der Zukunft), Safari unterstützt JPEG XL (allerdings ohne Animationen) schon länger. Anderen Browser ohne Unterstützung bauen auf einem der anderen engines auf und werden vermutlich nachziehen. Und wenn nicht? Das wäre eh hauptsächlich Edge, und fuck Edge.

Erwähnenswert ist, wie ich finde, jedoch der kürzlich veröffentlichte Blogpost The case against JPEG XL. Der Autor sagt, er sei selber ein Fan von JPEG XL, hält JPEG XL im Webbrowser aber für überflüssig. Insbesondere schreibt er:

By volume, there are very few use cases on the Web that aren't served by versatile lossy compression. The average Web consumer doesn't need lossless; they just need a lossy codec versatile enough to prevent terrible artifacts. […] This rules out JPEG XL's lossless advantage, which in practice is only roughly 11.9% smaller than lossless WebP anyway […].

Ok. Ich selber bin aber besessen von der verlustfreien Kompression. Und knap 12 % bessere Kompressionsrate als WebP (was noch einmal eine Verbesserung zu PNG ist) ist schon ordentlich. Das will ich.

Test: Verlustfreie Kompression mit JPEG XL

Ich habe mal ein paar Tests durchgeführt. Verlustfreie Kompression ist da relativ gut zu testen, wenn man die Encoding-/Decoding-Geschwindigkeit ignoriert: Je kleiner, desto besser (und decoding ist hier i.d.R. deutlich schneller als encoding, was gut ist, denn die Datei muss nur einmal encodiert werden, aber oft decodiert).

Verlustbehaftete Kompression ist schwieriger zu bewerten, dazu kommt vielleicht später noch ein Post.

Ich habe drei verschiedene Testbilder in insgesamt drei Bilddateiformaten ausprobiert. Die Formate waren PNG (mit Zopflipng optimiert), WebP (mit höchster verlustfreier Kompressionsstufe) und JPEG XL (ebenfalls mit höchster verlustfreie Kompressionsstufe).

Die drei Bilder sind unterschiedlich schwierig zu komprimieren. Das erste Beispiel ist trivial: ein komplett schwarzes Bild, 1000×1000 Pixel. Das zweite Beispiel ist eines meiner Fordite-Bilder: „Tanz eines Feuergottes“:

Geschwungene rote, gelbe und braune Flächen, Die Flächen haben komplizierte Formen, aber scharfe Kanten zwischen ihnen

Das ist auch sehr einfach, es sind große, einfarbige Flächen mit klaren Kanten (ohne Kantenglättung). Das dritte Bild ist Artwork aus dem Trainpunks-Rollenspiel:

Aus einem Schild an einer Wand, von dem nur „TRAIN███ON“ zu sehen ist, wächst ein lidloses Auge umgeben von pinkem Gewebe hervor. Das Auge ist umringt von ebenfalls pinken Armen, die Wand um das Auge herum ist merkwürdig verzerrt. Vor der Wand sind zwei Personen zu sehen. Eine Person halt eine Spraydose in der Hand und hetzt eine hundeartige Gestalt die sich aus Farben auf dem Boden erhebt, auf das Auge. Die zweite Person hat eine Kleine Gießkanne in der Hand, unter ihr wachsen Pflanzenranken.

Von diesem Artwork habe ich aber die Originalversion mit einer Auflösung von 1917×1719 genommen, die nie verlustbehaftet komprimiert war.

Hier sind die Befehle, die ich zum Encodieren genutzt habe:

zopflipng -m -y "input.png" "output.png"
cwebp -z 9 "input.png" -o "output.webp"
cjxl -q 100 -e 9 "input.png" "output.jxl"

Die Ergebnisse sehen so aus:

Bilddateigröße (in Byte) in verschiedenen verlustfreien Formaten
Format trivial Feuergott Trainpunks
PNG 202 33974 2051089
WebP 82 22638 1342528
JPEG XL 64 16498 1101756

Die PNG-Version habe ich nur so als Baseline hinzugefügt. Das ist mit Zopflipng komprimiert, das ist so ziemlich das Beste, was man aus PNG herausholen kann (die Optimierung dauert dafür sehr lange).

Beim trivialen Bild macht sich der relative Unterschied am stärksten Bemerkbar, der absolute Unterschied ist aber vernachlässigbar, und das Bild ist sowieso eines, das keine praktische Anwendung hat.

Bei den anderen Bildern ist die WebP-Variante etwa 65 % so groß wie die PNG-Variante, während JPEG XL auf etwa 50 % kommt. Das bedeutet eine Verbesserung von 7 % bis 8 % von WebP auf JPEG XL. Das ist schon noch einmal ein ordentlicher Unterschied. Was mache ich jetzt damit?

Zukunft: JPEG XL in diesem Blog

Ich habe vor, JPEG XL auch in diesem Blog zu nutzen. Mein static site generator (in Rust geschrieben) muss allerdings die Bilddimensionen von Bilddateien aus den Headern herausfischen, um sie ins HTML einzufügen. Glücklicherweise gibt es dafür aber ja schon ein Rust-Crate, weil das ja Mozillas Bedingung war, das Format überhaupt zu unterstützen.

Wann wird das kommen? Jedenfalls nicht bevor Firefox und Chromium das Format per default aktivieren. Ansonsten würde ich mich nach der Can I Use-Seite richten. Sobald Chromium das Format kann, werden vermutlich die meisten Browser, die auf Chromium basieren, nachziehen. Wenn nicht… Das ist eh hauptsächlich Edge, und Edge-User sind nun wirklich nicht meine Zielgruppe. Außerdem schreibe ich immer Alt-Texte an meine Bilder.

Was ich auch schon länger überlege ist, dass ich ja je nach Accept-Header der HTTP-Anfrage unterschiedliche Typen ausliefern könnte. Das ist sowieso besser, wenn ich später mal meine Bilddateien im Format ändern möchte. Dann sollte ich vielleicht die Dateiendungen der Bilddateien in der URL auch weglassen, sonst könnte das zu Verwirrung führen. Meine alten JPEG-Dateien könnte ich dann auch verlustfrei in JPEG XL umwandeln und sie damit nennenswert kleiner kriegen.

Ein Problemchen, dass ich aber auch jetzt schon habe: Je nach Plattform könnte es länger dauern, bis JPEG XL-Dateien in Vorschau-Bildern (og:image meta tag) unterstützt werden. Avif zum Beispiel wird von Mastodon bis heute nicht in Vorschaubildern angezeigt.

Ich bin jedenfalls gespannt, ob und wie schnell JPEG XL Verbreitung finden wird. Und wenn ich mal Lust habe, mache ich auch noch einen kleinen nicht methodisch korrekten Vergleich zwischen verschiedenen verlustbehafteten Formaten und JPEG XL, ebenso wie oben mit den verlustfreien Formaten.

Dropbox deleted

In den letzten Monaten habe ich am Digital Independence Day nichts gemacht. Mir ist nicht eingefallen, was ich noch umstellen könnte.

Heute habe ich von Dropbox eine Mail bekommen, dass sie ihre Nutzungsbedingungen ändern. Dadurch ist mir eingefallen, dass ich immernoch einen Dropbox-Account habe. Ich habe mir damals einen angelegt, weil es praktisch war. Ich habe ihn ab und zu genutzt, um Daten zu übetragen, die letzte aktive Nutzung war jetzt aber 2015, sie liegt also schon über zehn Jahre zurück.

Also habe ich ein Backup von den wenigen Daten dort gezogen und den Account gelöscht. Zum Online-Datenablegen habe ich ja meine Nextcloud-Instanz (trotz des ganzen Ärgers, den ich im Schnitt einmal im Jahr mit ihr habe).

Insofern war das auch keine große Digital Independence Day-Aktion. Aber es fühlt sich trotzdem gut an, ein bisschen sauber gemacht zu haben.

Ich habe ein neues Lieblingsemoji

Diesen Monat wurde Unicode 18.0.0 beschlossen. Darunter auch ein paar neue Emojis. Meist sind mir Emojis ja recht egal, aber jetzt habe ich ein Lieblingsemoji (vorher hatte ich keins):

🫫

Dummerweise haben die meisten Systeme bisher noch keine Schriftarten installiert, die dieses Emoji darstellen können. Deswegen werden zum Zeitpunkt der Veröffentlichung dieses Posts die meisten (mich eingeschlossen) dieses Emoji auf meinem Blog nicht sehen können.

À propos: Die laufende Figur aus Unicode 16? Unter (Ubuntu) Linux kein Problem, auf Windows, MacOS oder Android wird immernoch ein Platzhalter angezeigt.

Noch schlimmer trifft es die Creative Commons-Symbole. Die gibt es schon seit 2020, und ich wollte die immer im Footer dieses Blogs verwenden, aber bisher werden praktisch nirgendwo Schriftarten installiert, die diese Symbole enthalten.

Es gibt einen Fallback-Font, der nur diese Symbole enthält. Vielleicht sollte ich den mal in dieses Blog einbauen. Der würde dann auch nur geladen, wenn die Symbole nicht von Systemschriftarten unterstützt würden, zumindest, wenn ich es richtig einstelle.

Rollenspielszenen: Ich frag' für 'nen Freund

Rollenspielszene. Wir müssen in die Kanalisation, um eine gesuchte Mörderin zu finden. Die Kanalisation und ihre Bewohner sind eine sehr gute Gelegenheit, um sich gefährliche Krankheiten einzufangen. Also treffen wir ein paar Vorsichtsmaßnahmen, aber erkundigen uns auch vorher, wo in der Stadt man Krankheiten heilen lassen kann.

Nun möchte man natürlich nicht den Eindruck erwecken, dass man eine gefährliche Krankheit in die Stadt schleppt. Und wir möchten auch nicht preisgeben, dass wir eine Expedition in die Kanalisation machen (es könnte die falschen Personen vorwarnen. Also wie gehen wir vor? Fredegar der Halbling-Barde hat eine Idee:

Wo geht man hin, wenn es… untenrum juckt und brennt? Ich frag' für 'nen Freund.

Rollenspielszenen: Wie gewonnen, so zerronnen

Rollenspielszene. Jacksnipe ist immer noch blind, aber der Arzt / verrückte Wissenschaftler Fantasy Name Generator hat eine Idee, wie man das ändern kann, ohne Jacksnipes Augen aus den Sockeln zu holen. Wir müssen nur ein spezielles Kraut finden.

Das Kraut haben wir dann auch gefunden, aber es ist in der Mitte eines Sees aus türkiser Farbe, und dieser See lässt, ähnlich zu Jacksnipe selber, Lebewesen aus Farbe entstehen. Jacksnipe hat eine Idee: Komplementärfarben! Wenn sie ein rotes Blobmonster malt, kann sie es vielleicht strategisch geschickt einsetzen, so dass es die türkise Farbe auslöscht!

Das Blobmonster erweckt zum Leben. Durch einen ungeschickt formulierten Befehl von Jacksnipes greift es jedoch den See direkt an, anstatt taktisch sinnvoll eingesetzt zu werden.

Es gibt ein sploosh und das Blobmonster ist im türkisen Farbsee versunken, ohne dass dieser davon viel mitgekriegt hat.

Damit ich es nicht vergesse: Linux Capabilities

Capabilities sind ein praktischer Weg, um in Linux vereinzelt Rechte für einzelne Programme zu vergeben (z.B. um an Port 80 zu binden). Darüber findet man im Internet sehr viele Informationen. Weil ich aber immer wieder alles mögliche davon vergesse und manche Details in dem ganzen AI-Slop heutzutage schwierig zu finden sind, hier eine kleine Zusammenstellung für mich selber:

Capabilities eines Prozesses herausfinden

cat /proc/<PID>/status | grep Cap

Dann kriegt man etwas wie

CapInh:	0000000000000000
CapPrm:	000001f3f5fcffff
CapEff:	000001f3f5fcffff
CapBnd:	000001f3f5fcffff
CapAmb:	0000000000000000

Das kann man dann z.B. mit capsh entschlüsseln:

capsh --decode=000001f3f5fcffff

Was diese ganzen Capabilities bedeuten findet man auf der capabilities-Manpage (man 7 capabilities).

Was bedeuten die verschiedenen Zeilen?

Wichtig: Ich schreibe das hier für mich selbst auf, nach meinem aktuellen Verständnis. Das hier kann also falsch oder irreführend sein. Wenn ihr mich korrigieren wollt, schreibt mich gerne an.

  • CapInh sind „Inheritable Capabilities“. Child-Prozesse können die erben.
  • CapPrm sind „Permitted Capabilities“. Die sind einem Executable zugeordnet und werden dem Prozess zugeordnet, wenn er gestartet wird (?)
  • CapEff sind „Effective Capabilities“. Das ist eine Untermenge von CapPrm und sind die Capabilities, die ein Prozess zu einem Zeitpunkt tatsächlich hat.
  • CapBnd („Bounding Set“) ist, was der Prozess maximal an Capabilities haben kann. Wir z.B. gerne als Sicherheitsmechanismus verwendet, um einzuschränken, was ein Prozess darf (z.B. von SystemD).
  • CapAmb sind „Ambient Capabilities“ sind capabilities, die an Kindprozesse weitergegeben werden können, selbst wenn die executables für die Kindprozesse die Capability nicht haben.

pixel_area

Heute gefunden: pixel_area. Eine 100×100-Fläche, jeder „Pixel“ (es ist ein logischer Pixel, kein Pixel im eigentlichen Bildsinne) kann auf eine Website verlinken. Momentan sind aber nur 313 davon vergeben.

Erinnert ein bisschen an die Million Dollar Homepage, aber es gibt weniger Pixel, Pixel kosten nichts und eine Seite kriegt immer nur einen Pixel.

Ich habe dieses Blog da auch einmal eingepflegt:

pixel_area 42 41

Ist eine lustige kleine Seite, registriert eure Seiten dort!

Rollenspielszenen: Die Suppenverkäuferin

Rollenspielszene. Siobhan hat im Wald ein Lager von Matsutake-Arbeitern gefunden. Das sind weitere Leute, die wir für uns gewinnen können, wenn wir den Wald retten wollen.

Das Lager ist eine Ansammlung von Zelten, Ständen, an denen Sammler und Händler um Mastutake feilschen und verschiedene Stände, die Mahlzeiten anbieten. Shane kauft sich eine Suppe und unterhält sich mit der Verkäuferin. Die erzählt ihm:

Die lokale Regierung versteht nicht, wie die Matsutake-Pilze funktionieren! Sie denken, wenn wir die Pilze ernten, dann sind hinterher keine mehr da! Dabei helfen wir, die Pilze zu verbreiten! Die denken nur, wir machen den Wald kaputt!

Shane sieht die Gelegenheit:

Ziemlich ironisch, wenn man bedenkt, dass die Regierung selber den Wald abholzen will.

Die Verkäuferin ist entsetzt:

Die Regierung will WAS?!?

Shane erzählt ihr von den Abholzungsplänen, dass hier einen Militärbasis entstehen soll und dass es auch wirtschaftliche Interessen am Holz gibt. Er erzählt auch von den Protesten gegen die Aktion, dass am nächsten Tag eine große Demo ist und gibt der Verkäuferin Flyer. Die Matsutake-Sammler, die Händler und auch die Streetfood-Verkäufer brauchen alle diesen Wald. Ihre Unterstützung für die Demo ist gesichert.

Lilith Wittmann zerforscht illegale Online-Casinos

Lilith Wittmann hat wieder zugeschlagen. Dieses Mal hat sie die Strukturen hinter illegalen Onlinecasinos aufgedeckt. So hat sie über Sicherheitslücken Einblicke in die Glücksspiellizenzvergabe von Curaçao erhalten und den Eigentümer des größten illegalen deutschen Onlinecasinos ermittelt (der unabhängig davon seitdem festgenommen wurde). Es geht nicht nur darum, dass Menschen viel Geld verloren haben, sondern auch, dass diese Online-Casinos massiv Steuerhinterziehung betreiben.

Aus ihren Andeutungen auf Mastodon zu schließen hat wurde sie auch von Malta aus angeklagt und musste sich verteidigen (teuer), weil sieso schwere Hacking-Aktivitäten begangen hat, in einem HTML-Formular ein gesperrtes Eingabefeld zu entsperren, um auf Daten zuzugreifen. Die Klage ist, soweit ich das mitbekommen habe (habe das nur am Rande verfolgt), eher eine SLAPP-Klage.

Ich bin immer wieder beeindruckt von Liliths Aktionen. Sie ist fähig, persistent, arbeitet nach der Hackerethik und nimmt kein Blatt vor den Mund. Ich betrachte sie definitiv als Investigativjournalistin, auch wenn ich nicht weiß, ob sie sich selber so sieht. Ich hoffe mal, es gibt auf dem 40C3 wieder einen Vortrag von ihr.

Rollenspielszenen: Zauber oder Schatz

Rollenspielszene. Der Schatz, den die Gruppe erbeutet hat muss aufgeteilt werden. Die Abmachung besagt: Nini und Sprinkle kriegen je ein Fünftel des Schatzes. Und unter dem Schatz ist auch ein mächtiger Heilzauber: Heal the Itchy Poison.

Allerdings ist ein Teil des Schatzes auch funkelnder und glitzernder Schmuck. Und Nini mag glitzernde Sachen. Jetzt muss zie sich entscheiden: Vernünftig sein und den Zauber nehmen, oder dem Verlangen nachgeben, den glitzernden Schmuc zu horten?