Bug in Javas ImageIO

vorhergehende Artikel in: Java Software-Test Git(lab|hub)
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 Github Repositories Gitlab Repositories Mastodon Über mich home xmpp


Vor 5 Jahren hier im Blog

  • Android als Smartcard (NFC) II

    05.05.2019

    Das letzte Mal war das ganze eher grobe Bastelei. Nachdem ich nun ein neues Smartphone angeschafft habe, wollte ich probieren, ob es inzwischen einfacher funktioniert - und ich wurde über alle Erwartungen hinaus überrascht...

    Weiterlesen...

Neueste Artikel

  • SQLite als Geodatenbank

    Wie bereits in einem früheren Artikel beschrieben treibe ich derzeit Anstrengungen voran, die sQLshell attraktiver für Nutzer zu machen, die mit Geodatenbanken arbeiten.

    Weiterlesen...
  • Contributor bei Rosetta Code

    Ich habe mich neulich einmal ein wenig auf Rosetta Code umgesehen und bin über die Rubrik Draft Programming Tasks gestolpert, wo ich sofort eine Aufgabe fand, die mich ansprach.

    Weiterlesen...
  • Graphics2D Implementierung für Java mit verlegtem Koordinatenursprung

    Es gibt seit vielen Jahren immer mal wieder Leute, die im Internet fragen, ob man in Javas diversen Methoden zum Zeichnen von Graphiken das Koordinatensystem so ändern könnte, dass sich der Koordinatenursprung links unten befindet und die positive y-Achse nach oben weist. Meist sind die Antworten dann, dass eine Affine Transformation eingeschaltet werden solle, die das Bild spiegelt.

    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, muß 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 GitHub-Repositories findet man hier - meine öffentlichen GitLab-Repositories finden sich dagegen hier.