Bug in Javas ImageIO

vorhergehende Artikel in: Java Software-Test OpenSource
20.07.2023

Nachdem in letzter Zeit die Diskussion - bedingt durch die Unterstützung von Apple - um JPEG XL wieder aufgeflammt ist, begann ich mich dafür zu interessieren.

Da ich oft und gerne auf ImageIO zurückgreife, wann immer ich in einer Java-Anwendung Bilder laden oder speichern muss hat mich nicht nur interessiert, ob dieses Format von Java unterstützt wird, sondern auch, ob es entsprechende ImageIO-Reader und -Writer dafür gibt.

Ich stieß ziemlich schnell auf eine Implementierung in purem Java, musste allerdings feststellen, dass dort keine ImageIO-Unterstützung existiert. Eine Rückfrage beim Autor ergab, dass er dies bereits als eines der nächsten Ziele auf der Liste habe.

Da ich bereits in der Vergengenheit einige Reader und Writer für ImageIO geschrieben habe überlegte ich, selbst tätig zu werden.

Da das im Projekt verwendete Buildsystem Meson mir überhaupt nichts sagte und bereits das erste in der Readme angegebene Kommando mit einer nichtssagenden Fehlermeldung seinen Dienst versagte entschloss ich mich zunächst, das Projekt in meinem Fork auf Maven umzustellen.

Anschließend entwickelte ich darin einen ersten Prototyp eines Readers für JPEG XL. Dieser Reader war noch nicht optimal und kann zum Beispiel im Aspekt Performance noch erheblich verbessert werden. Für den Anfang und zum Testen war ich damit jedoch erst einmal zufrieden.

Der Grund dafür, dass es keinen Pull-Request gibt und der Branch auch in meinem Fork noch nicht in den Master integriert ist ist, dass beim Testen ein sehr seltsamer Fehler zu Tage trat: Ich lud zu Testzwecken ein mit JPEG XL kodiertes Bild und speicherte es danach ebenfalls mittels ImageIO im Format PNG ab. Es wurde kein Fehler gemeldet, es flog keine Exception - jedoch war die Ergebnisdatei 0 Bytes groß. Dasselbe Ergebnis erreichte ich mit einem ByteArrayOutputStream statt der Date und mit JPEG als Ausgabeformat statt PNG.

Ich war zunächst überrascht und enttäuscht und suchte den Fehler lange Zeit in meinem Reader bis ich zu weiteren Tests überging: Da ich keinen Fehler finden konnte versuchte ich eine kleine Swing-Anwendunung zu bauen, die nur einen Button in einem Window anzeigen sollte und setzte das geladene Bild als Icon auf diesen Button. Nun war ich noch erstaunter, denn das Bild wurde auf dem Button korrekt angezeigt.

Weitere Tests brachten die ganze Tragweite zum Vorschein: Wenn ich von Hand ein neues BufferedImage anlegte, davon eine Graphics2D Instanz erzeugte und das geladene Bild in diesen zeichnete, konnte ich dieses neue Bild in jedem beliebigen Format mittels ImageIO abspeichern. Das ließ mic hein wenig weiter in den Quelltext abtauchen und letztlich stellte sich heraus, dass der Grund für das fehlgeschlagene Speichern die Art der Datenstruktur war, die die eigentlichen Pixeldaten enthält. Es handelt sich dabei um konkrete Implementierungen von DataBuffer. Eine diser Implementierungen ist DataBufferFloat - und immer wenn diese Klasse benutzt wird, versagt ImageIO beim Speichern.

Ich habe daher in meinem Fork einen neuen Branch angelegt und ihn im entsprechenden Bug Report referenziert: Dieser Branch enthält JUnit-Tests, mit denen sich der Fehler und der Workaround demonstrieren lassen. Der Link zum Bug funktioniert derzeit noch nicht, da er noch nicht verifiziert wurde.

Allerdings lässt mich ein Kommentar auf die Beschreibung des Fehlers im Repository des JPEG XL-Decoders darauf schließen, dass ich nicht der erste war, der darüber gestolpert ist: Der Autor der Bibliothek scheint sich darüber ebenfalls bereits im Klaren gewesen zu sein.

Ich werde abwarten, ob ich ein Feedback auf meine Meldung im offiziellen Java Bugtracker erhalte und wie dieses dann ausfallen wird...

Artikel, die hierher verlinken

TagManager auf GitHub

29.07.2023

Nachdem ich vor einiger Zeit über die Komponente zur Verwaltung von Tags für (Bild-)Dateien berichtet habe ist es nun an der Zeit, die Information über die Veröffentlichung einer entsprechenden darauf basierenden Anwendung nachzureichen.

Alle Artikel rss Wochenübersicht Monatsübersicht Codeberg Repositories Mastodon Über mich home xmpp


Vor 5 Jahren hier im Blog

  • Multi-User-WebDAV, Docker, GitHub

    17.11.2019

    Nachdem ich mich in letzter Zeit verstärkt mit Docker und dem zugehörigen Ökosystem beschäftige, habe ich begonnen, verschiedenste Dienste in Containern zu testen um zu sehen, ob in manchen Fällen LXC oder KVM nicht doch die bessere Wahl wäre...

    Weiterlesen...

Neueste Artikel

  • Migration der Webseite und aller OpenSource Projekte

    In eigener Sache...

    Weiterlesen...
  • AutoHideToolbar für Java Swing

    Ich habe eine neue Java Swing Komponente erstellt: Es handelt sich um einen Wrapper für von JToolBar abgeleitete Klassen, die die Werkzeugleiste minimieren und sie nur dann einblenden, wenn der Mauszeiger über ihnen schwebt.

    Weiterlesen...
  • Integration von EBMap4D in die sQLshell

    Ich habe bereits in einem früheren Artikel über meine ersten Erfolge berichtet, der sQLshell auf Basis des bestehenden Codes aus dem Projekt EBMap4D eine bessere Integration für Geo-Daten zu spendieren und entsprechende Abfragen, bzw. deren Ergebnisse auf einer Kartenansicht zu visualisieren.

    Weiterlesen...

Manche nennen es Blog, manche Web-Seite - ich schreibe hier hin und wieder über meine Erlebnisse, Rückschläge und Erleuchtungen bei meinen Hobbies.

Wer daran teilhaben und eventuell sogar davon profitieren möchte, muss damit leben, daß ich hin und wieder kleine Ausflüge in Bereiche mache, die nichts mit IT, Administration oder Softwareentwicklung zu tun haben.

Ich wünsche allen Lesern viel Spaß und hin und wieder einen kleinen AHA!-Effekt...

PS: Meine öffentlichen Codeberg-Repositories findet man hier.