From eb896323fdbb3a4b36d0420695980a386ea1e5b6 Mon Sep 17 00:00:00 2001 From: lenamonj <85593689+lenamonj@users.noreply.github.com> Date: Wed, 9 Sep 2026 08:06:21 -0400 Subject: [PATCH] Honor the requested format in Imaging.writeImage PnmImageParser accepts PBM, PGM, PPM, PNM and PAM, but Imaging.writeImage passed null parameters, so every request took the default writer (PPM, or PAM for a transparent image). The format now reaches the parser through a writeImageForFormat hook that the base class ignores and PnmImageParser overrides. --- .../commons/imaging/AbstractImageParser.java | 20 +++++++++++++++++++ .../org/apache/commons/imaging/Imaging.java | 2 +- .../imaging/formats/pnm/PnmImageParser.java | 9 +++++++++ .../formats/pnm/PnmImageParserTest.java | 13 ++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/apache/commons/imaging/AbstractImageParser.java b/src/main/java/org/apache/commons/imaging/AbstractImageParser.java index 4ad1b84385..de3a9ed6de 100644 --- a/src/main/java/org/apache/commons/imaging/AbstractImageParser.java +++ b/src/main/java/org/apache/commons/imaging/AbstractImageParser.java @@ -746,4 +746,24 @@ public final ImageMetadata getMetadata(final File file, final T params) throws I public void writeImage(final BufferedImage src, final OutputStream os, final T params) throws ImagingException, IOException { throw new ImagingException("This image format (" + getName() + ") cannot be written."); } + + /** + * Writes the content of a BufferedImage to the specified output stream in the given format. + * + *
+ * A parser whose {@link #getAcceptedTypes()} lists more than one format overrides this method so that the format selects the output; the rest write their + * only format and ignore the argument. + *
+ * + * @param src An image giving the source content for output. + * @param os A valid output stream for storing the formatted image. + * @param format The format the caller asked for; one of {@link #getAcceptedTypes()}. + * @throws ImagingException In the event that the output format cannot handle the input image. + * @throws IOException In the event of a write error from the output stream. + * + * @since 1.0.0-alpha7 + */ + protected void writeImageForFormat(final BufferedImage src, final OutputStream os, final ImageFormat format) throws ImagingException, IOException { + writeImage(src, os, null); + } } diff --git a/src/main/java/org/apache/commons/imaging/Imaging.java b/src/main/java/org/apache/commons/imaging/Imaging.java index 8af199d607..4b41e42c7f 100644 --- a/src/main/java/org/apache/commons/imaging/Imaging.java +++ b/src/main/java/org/apache/commons/imaging/Imaging.java @@ -917,7 +917,7 @@ public static void writeImage(final BufferedImage src, final OutputStream output Objects.requireNonNull(format, "format"); final AbstractImageParser> imageParser = ImageParserFactory.getImageParser(format); - imageParser.writeImage(src, outputStream, null); + imageParser.writeImageForFormat(src, outputStream, format); } /** diff --git a/src/main/java/org/apache/commons/imaging/formats/pnm/PnmImageParser.java b/src/main/java/org/apache/commons/imaging/formats/pnm/PnmImageParser.java index 0eb402109a..49d321a42c 100644 --- a/src/main/java/org/apache/commons/imaging/formats/pnm/PnmImageParser.java +++ b/src/main/java/org/apache/commons/imaging/formats/pnm/PnmImageParser.java @@ -343,4 +343,13 @@ public void writeImage(final BufferedImage src, final OutputStream os, final Pnm writer.writeImage(src, os, params); } + + @Override + protected void writeImageForFormat(final BufferedImage src, final OutputStream os, final ImageFormat format) throws ImagingException, IOException { + final PnmImagingParameters params = new PnmImagingParameters(); + if (format instanceof ImageFormats) { + params.setSubtype((ImageFormats) format); + } + writeImage(src, os, params); + } } diff --git a/src/test/java/org/apache/commons/imaging/formats/pnm/PnmImageParserTest.java b/src/test/java/org/apache/commons/imaging/formats/pnm/PnmImageParserTest.java index 5ed7e99716..17c675f09f 100644 --- a/src/test/java/org/apache/commons/imaging/formats/pnm/PnmImageParserTest.java +++ b/src/test/java/org/apache/commons/imaging/formats/pnm/PnmImageParserTest.java @@ -22,6 +22,7 @@ import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; @@ -36,6 +37,18 @@ class PnmImageParserTest { private static final Charset US_ASCII = StandardCharsets.US_ASCII; + @Test + void testWriteImageHonorsRequestedFormat() throws ImagingException, IOException { + final BufferedImage image = new BufferedImage(2, 2, BufferedImage.TYPE_INT_RGB); + final ImageFormats[] formats = { ImageFormats.PBM, ImageFormats.PGM, ImageFormats.PPM, ImageFormats.PAM }; + final String[] magic = { "P4", "P5", "P6", "P7" }; + for (int i = 0; i < formats.length; i++) { + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + Imaging.writeImage(image, out, formats[i]); + assertEquals(magic[i], new String(out.toByteArray(), 0, 2, US_ASCII), formats[i].name()); + } + } + @Test void testGetImageInfo_happyCase() throws ImagingException, IOException { final byte[] bytes = "P1\n3 2\n0 1 0\n1 0 1\n".getBytes(US_ASCII);