Blockartefakte nach JPEG-Dekodierung (bei Bildern mit Subsampling)

JanH
Mitglied
Posts: 81
Joined: Sun 01 Dec 2019 20:19

Blockartefakte nach JPEG-Dekodierung (bei Bildern mit Subsampling)

Post by JanH »

Hallo,

bei manchen Bildern auf JPEG-Ausgangsbasis machen sich beim Rumspielen mit Hin- und Herschieben von Farbkanälen, stärkerer Anwendung von Histogrammkorrektur, Gradiationskurven o.ä. gewisse Blockartefakte im 16x16-Raster bemerkbar. Gut dachte ich mir, das betreffende Quellbild ist halt ein JPEG-Bild mit nicht der allerhöchsten Qualität, da muss man halt damit leben, bzw. irgendwie drumherumarbeiten.

Jetzt habe ich aber gerade heute mal eine ältere PLD-Datei aufgemacht, da ich nach Ewigkeiten doch noch mal was an dem betreffenden Bild ändern wollte. Die Datei war noch mit PhotoLine 8.60 erstellt worden (die Version lag mal vor Ewigkeiten einer c't als Vollversion bei, und mit der war ich dann ziemlich lange unterwegs). Damals war es mit nicht-destruktivem Bearbeiten natürlich noch nicht weit her (aber ich war auch schon damals beeindruckt im Vergleich zu beispielsweise GIMP, als ich gemerkt habe, dass man immerhin Ebenen nicht-destruktiv vergrößern/verkleinern/drehen/perspektivisch verzerren/etc. konnte), aber ich habe mir mit Duplizieren von Layern und Notieren der angewandten Filter im Layernamen so gut es eben ging irgendwie beholfen.

Damals konnte PhotoLine auch keine JPEG-Daten im .pld-Format ablegen, sodass das dekodierte Original-JPEG dann als PNG-Daten in der .pld gelandet ist. Also dachte ich mir, schiebe ich mal die wirkliche Originaldatei rein, prüfe, ob ich damals irgendwas direkt auf dem Originalbild rumgepinselt hatte (nein, hatte ich bei dem Bild nicht, lag alles auf Extra-Layern), und spare so etwas Speicherplatz in der .pld.

Dann schaue ich aber nochmal genauer und merke, dass da jetzt auf einmal ebenfalls diese Blockartefakte auftauchen, die vorher im Bild gar nicht so arg bemerkbar waren. Irgendwas scheint sich also an der JPEG-Dekodierung durch PhotoLine geändert zu haben, und offenbar nicht zum Besseren.

Ich habe daraufhin diverse andere Bildbearbeitungsprogramme und -betrachter auf meinem Computer durchprobiert (siehe Anhang), und PhotoLine scheint fast die einzige Software mit diesem Problem zu sein.

Nach noch etwas mehr rumprobieren scheint das mögliche Problem wohl libjpeg zu sein: libjpeg 6b liefert noch das gewünschte Ergebnis (falls PhotoLine tatsächlich libjpeg nutzt (Edit: Tut es, hab die liesmich.txt im Programmordner entdeckt), war es wohl deswegen im alten 8.60er-PhotoLine kein Problem?), libjpeg 7 und neuer (etwa 9e) zeigen hingegen alle diese unerwünschten Blockartefakte. Der ja ebenfalls recht weit verbreitete libjpeg-Fork libjpeg-turbo (z.B. in Firefox oder IrfanView genutzt) weist das Problem hingegen ebenfalls nicht auf, und mutmaßlich auch nicht der in Windows eingebaute JPEG-Decoder, welcher auch immer der sein mag (wenn ich mich nach den Ergebnissen von Paint und der Fotos-App richten kann).

Das Problem trifft außerdem anscheinend nur Bilder mit Subsampling, aber das sind ja vermutlich fast schon die meisten JPEG-Bilder. In allen Fällen, in denen mir dieses Phänomen aufgefallen ist, werden dadurch in eigentlich relativ glatten Bildbereichen zusätzliche harte Übergänge entlang der 16x16-Blockgrenzen des Chroma-Subsamplings erzeugt – bei manchen Bildern fallen die schon so auf, insbesondere wenn man etwas reinzoomt, bei anderen Bildern werden die dann spätestens durch meine Nachbearbeitung/Verfremdung unschön betont. Ganz vermeiden lassen sie sich bei einem Ausgangsbild gegebener JPEG-Qualität natürlich nicht, aber bei den paar Bildern, bei denen ich es mal den Vergleich ausprobiert habe, waren die neuen libjpeg-Versionen im Detail leider tatsächlich immer eine Verschlechterung, libjpeg-turbo oder die alte libjpeg-Version sahen immer etwas gefälliger aus.

Angehängt ist mal ein Beispiel-Ausschnitt aus einem Bild, der das Problem hoffentlich hinreichend demonstriert. Die .pld enthält zum Vergleich die Dekodierungsergebnisse diverser Programme zum Vergleich (und auch eine Ebene mit der Original-JPEG), und zusätzlich auch noch direkt das JPEG-Bild zum ausprobieren.
You do not have the required permissions to view the files attached to this post.
JanH
Mitglied
Posts: 81
Joined: Sun 01 Dec 2019 20:19

Re: Blockartefakte nach JPEG-Dekodierung (bei Bildern mit Subsampling)

Post by JanH »

Ich habe inzwischen noch rausgefunden, dass das daran liegt, dass libjpeg 7 und neuer das Chroma-Down- und Upsampling (wenn der Subsamplingfaktor eine Zweierpotenz ist, was ja in der Regel der Fall ist) per DCT-Skalierung durchführen, anstatt die Chromadaten einfach bilinear o.ä. zu interpolieren.

DCT-Skalierung soll angeblich den Vorteil haben, dass Up- und Downsampling so verlustfrei seien (natürlich bis auf den Datenverlust beim erstmaligen Downsampling) [1], aber es führt beim Upsampling eben auch dazu, dass jeder 8x8 Block beim hochskalieren auf 16x16 für sich alleine betrachtet wird, ohne Rücksicht darauf, was in den Nachbarblöcken passiert.

Das führt dann zu ganz ähnlichen Artefakten, wie man sie auch beim Hochskalieren von gekachelten Bildern erhält, wenn man zuerst jede Kachel individuell hochskaliert und dann erst zu einem Gesamtbild zusammenfügt, anstatt umgekehrt vorzugehen. Ist (oder war zumindest mit langsamerer Internetverbindung) z.B. bei Google Earth ganz gut zu sehen, wenn man reinzoomt – bis die neuen Kacheln für die höhere Zoomstufe geladen haben, werden die alten Kacheln einfach skaliert angezeigt, und das führt dann an den Kachelgrenzen zu Diskontinuitäten.

Der Maintainer von libjpeg-turbo schreibt dazu auch (Hervorhebung meinerseits)
Additionally, when used on a JPEG image that was compressed with even a moderate amount of quantization, IDCT upscaling can generate sharp artifacts at the boundaries of blocks containing high-frequency features, and a large amount of noise can be generated within those blocks.
und das passt auch ziemlich gut zu meinen Beobachtungen.

[1] Wobei es auch mit libjpeg 9e schlussendlich im Vergleich zu libjpeg 6b nicht wesentlich weniger Iterationen braucht, bis sich beim wiederholten Abspeichern eines Bildes ein stabiler Zustand ohne weitere Kompressionsverluste einstellt, "reversible" DCT-Skalierung beim Chroma-Subsampling hin oder her.
JanH
Mitglied
Posts: 81
Joined: Sun 01 Dec 2019 20:19

Re: Blockartefakte nach JPEG-Dekodierung (bei Bildern mit Subsampling)

Post by JanH »

Nachtrag: Und in der generellen Readme von libjpeg-turbo steht (Hervorhebung meins)
While libjpeg-turbo does emulate the libjpeg v8 API/ABI, under the hood it is still using the same algorithms as libjpeg v6b, so there are several specific cases in which libjpeg-turbo cannot be expected to produce the same output as libjpeg v8:
[…]
  • When using chrominance subsampling, because libjpeg v8 implements this with its DCT/IDCT scaling algorithms rather than with a separate downsampling/upsampling algorithm. In our testing, the subsampled/upsampled output of libjpeg v8 is less accurate than that of libjpeg v6b for this reason.
JanH
Mitglied
Posts: 81
Joined: Sun 01 Dec 2019 20:19

Re: Blockartefakte nach JPEG-Dekodierung (bei Bildern mit Subsampling)

Post by JanH »

libjpeg-turbo wäre nebenbei auch noch etwas performanter als libjpeg. Auch wenn die Geschwindigkeit beim Lesen und Schreiben von JPEGs meistens nicht der ganz riesige Flaschenhals ist, wäre es z.B. gerade für die Qualitätsvorschau beim Speichern von großen Bildern doch ganz nett, wenn die Dateivorschau da noch schneller reagieren würde. So ganz grob mitgestoppt ist Photoline zwar schon schneller als das nackte cjpeg von libjpeg, aber libjpeg-turbo scheint immer noch spürbar noch schneller.