css4j / echosvg

SVG implementation in the Java™ Language, fork of Apache Batik, supporting level 4 selectors and colors.
Apache License 2.0
39 stars 2 forks source link

`PNGImageEncoder` closes the output stream #105

Closed carlosame closed 2 months ago

carlosame commented 2 months ago

The documentation for PNGImageEncoder.encode(RenderedImage) says the following:

The stream into which the PNG is dumped is not closed at the end of the operation, this should be done if needed by the caller of this method.

However, it is closing that stream:

https://github.com/css4j/echosvg/blob/932da68d276dc9c2a2fa371c8dcf4856cb7668d6/echosvg-transcoder/src/main/java/io/sf/carte/echosvg/ext/awt/image/codec/png/PNGImageEncoder.java#L1033

and has been doing that since commit 71d462f4ed103b002e634a1d673c521af2ca6015 from July 2009, with title "Close DeflaterOutputStream":

https://svn.apache.org/viewvc?view=revision&revision=796596

The commit says nothing about the motivation, but seems related to BATIK-895 and BATIK-937. In BATIK-895, the suggested patch just closes a couple of DeflaterOutputStream, but not the whole stream at the end of the file (which 71d462f4ed103b002e634a1d673c521af2ca6015 does).

As a consequence of that final close(), one cannot sync the output file after the encoding, which means that if one opens that file immediately after that, the full contents may have not been written yet and cause errors like:

java.io.EOFException
    at java.base/java.io.DataInputStream.readFully(DataInputStream.java:202)
    at java.base/java.io.DataInputStream.readFully(DataInputStream.java:170)
    at io.sf.carte.echosvg.ext.awt.image.codec.png.PNGRed.readChunk(PNGRed.java:489)
    at io.sf.carte.echosvg.ext.awt.image.codec.png.PNGRed.<init>(PNGRed.java:389)
    at io.sf.carte.echosvg.ext.awt.image.codec.png.PNGRegistryEntry$1.run(PNGRegistryEntry.java:91)

Calling close() is a responsibility of the caller, so my plan is to remove that final call.