This is an automated email from the ASF dual-hosted git repository. kinow pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-imaging.git
commit 9ab24f90ad987de5b9cd2c70b94c17c6a01a63db Author: Bruno P. Kinoshita <ki...@users.noreply.github.com> AuthorDate: Thu Apr 22 08:19:12 2021 +1200 [IMAGING-159] Use ImagingParameters and define new classes as needed for other formats --- .../java/org/apache/commons/imaging/Imaging.java | 27 +-- .../apache/commons/imaging/ImagingConstants.java | 22 --- .../imaging/formats/icns/IcnsImageParser.java | 46 +---- .../formats/icns/IcnsImagingParameters.java | 26 +++ .../imaging/formats/ico/IcoImageParser.java | 33 +--- .../imaging/formats/ico/IcoImagingParameters.java | 26 +++ .../imaging/formats/jpeg/JpegImageParser.java | 28 ++- .../formats/jpeg/JpegImagingParameters.java | 26 +++ .../commons/imaging/formats/png/PngConstants.java | 25 --- .../imaging/formats/png/PngImageParser.java | 24 +-- .../imaging/formats/png/PngImagingParameters.java | 95 +++++++++++ .../commons/imaging/formats/png/PngWriter.java | 85 +++------ .../imaging/formats/psd/PsdImageParser.java | 15 +- .../imaging/formats/psd/PsdImagingParameters.java | 28 +++ .../imaging/formats/rgbe/RgbeImageParser.java | 13 +- .../formats/rgbe/RgbeImagingParameters.java | 26 +++ .../imaging/formats/tiff/TiffCompression.java | 22 +++ .../imaging/formats/tiff/TiffDirectory.java | 15 +- .../imaging/formats/tiff/TiffImageParser.java | 102 +++++------ .../formats/tiff/TiffImagingParameters.java | 189 +++++++++++++++++++++ .../commons/imaging/formats/tiff/TiffReader.java | 21 +-- .../formats/tiff/constants/TiffConstants.java | 45 ----- .../formats/tiff/write/TiffImageWriterBase.java | 67 ++------ .../tiff/write/TiffImageWriterLossless.java | 3 +- .../imaging/formats/wbmp/WbmpImageParser.java | 30 +--- .../formats/wbmp/WbmpImagingParameters.java | 26 +++ .../imaging/formats/xbm/XbmImageParser.java | 29 +--- .../imaging/formats/xbm/XbmImagingParameters.java | 26 +++ 28 files changed, 659 insertions(+), 461 deletions(-) diff --git a/src/main/java/org/apache/commons/imaging/Imaging.java b/src/main/java/org/apache/commons/imaging/Imaging.java index 8944a44..4fbea0d 100644 --- a/src/main/java/org/apache/commons/imaging/Imaging.java +++ b/src/main/java/org/apache/commons/imaging/Imaging.java @@ -718,13 +718,16 @@ public final class Imaging { return getImageInfo(file, null); } - private static ImageInfo getImageInfo(final ByteSource byteSource, final ImagingParameters params) - throws ImageReadException, IOException { - return getImageParser(byteSource).getImageInfo(byteSource, params); + // See getImageParser + @SuppressWarnings("unchecked") + private static ImageInfo getImageInfo(final ByteSource byteSource, final ImagingParameters params) throws ImageReadException, IOException { + return Imaging.getImageParser(byteSource).getImageInfo(byteSource, params); } - private static ImageParser<?> getImageParser(final ByteSource byteSource) - throws ImageReadException, IOException { + // TODO: We have no way of knowing whether the returned ImageParser will accept the ImagingParameters, + // even if we specified generic types for the static methods. + @SuppressWarnings("rawtypes") + private static ImageParser getImageParser(final ByteSource byteSource) throws ImageReadException, IOException { final ImageFormat format = guessFormat(byteSource); if (!format.equals(ImageFormats.UNKNOWN)) { @@ -732,7 +735,7 @@ public final class Imaging { for (final ImageParser<?> imageParser : imageParsers) { if (imageParser.canAcceptType(format)) { - return (ImageParser<?>) imageParser; + return (ImageParser) imageParser; } } } @@ -743,7 +746,7 @@ public final class Imaging { for (final ImageParser<?> imageParser : imageParsers) { if (imageParser.canAcceptExtension(fileName)) { - return (ImageParser<?>) imageParser; + return (ImageParser) imageParser; } } } @@ -965,7 +968,9 @@ public final class Imaging { * @throws ImageReadException if it fails to parse the image * @throws IOException if it fails to read the image data */ - public static String getXmpXml(final ByteSource byteSource, final ImagingParameters params) + // TODO: we have no way of knowing whether getImageParser will return a parser that is compatible with the ImagingParameters instance given + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static String getXmpXml(final ByteSource byteSource, final ImagingParameters params) throws ImageReadException, IOException { final ImageParser<?> imageParser = getImageParser(byteSource); if (imageParser instanceof XmpEmbeddable) { @@ -1510,13 +1515,15 @@ public final class Imaging { * @throws IOException in the event of an unrecoverable I/O exception. * @see ImagingConstants */ - public static <T extends ImagingParameters> void writeImage(final BufferedImage src, final OutputStream os, + // TODO: fix generics due to ImageParser retrieved via getAllImageParsers, and the given ImagingParameters type + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static void writeImage(final BufferedImage src, final OutputStream os, ImagingParameters params) throws ImageWriteException, IOException { Objects.requireNonNull(params, "You must provide a valid imaging parameters object."); final ImageParser<?>[] imageParsers = ImageParser.getAllImageParsers(); - ImageParser<?> imageParser = null; + ImageParser imageParser = null; for (final ImageParser<?> imageParser2 : imageParsers) { if (imageParser2.canAcceptType(params.getImageFormat())) { imageParser = imageParser2; diff --git a/src/main/java/org/apache/commons/imaging/ImagingConstants.java b/src/main/java/org/apache/commons/imaging/ImagingConstants.java index 80de12d..d2b48e7 100644 --- a/src/main/java/org/apache/commons/imaging/ImagingConstants.java +++ b/src/main/java/org/apache/commons/imaging/ImagingConstants.java @@ -41,17 +41,6 @@ public final class ImagingConstants { public static final String PARAM_KEY_COMPRESSION = "COMPRESSION"; /** - * <p>Parameter key. Indicates whether to read embedded thumbnails.</p> - * - * <p>Only applies to read EXIF metadata from JPEG/JFIF files.</p> - * - * <p>Valid values: {@code Boolean.TRUE} and {@code Boolean.FALSE}.</p> - * - * @see org.apache.commons.imaging.formats.tiff.constants.TiffConstants - */ - public static final String PARAM_KEY_READ_THUMBNAILS = "READ_THUMBNAILS"; - - /** * <p>Parameter key. Indicates whether to throw exceptions when parsing invalid * files, or whether to tolerate small problems.</p> * @@ -63,17 +52,6 @@ public final class ImagingConstants { public static final String PARAM_KEY_STRICT = "STRICT"; /** - * <p>Parameter key.</p> - * - * <p>Only used when writing images.</p> - * - * <p>Valid values: TiffOutputSet to write into the image's EXIF metadata.</p> - * - * @see org.apache.commons.imaging.formats.tiff.write.TiffOutputSet - */ - public static final String PARAM_KEY_EXIF = "EXIF"; - - /** * Empty byte array. */ public static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; diff --git a/src/main/java/org/apache/commons/imaging/formats/icns/IcnsImageParser.java b/src/main/java/org/apache/commons/imaging/formats/icns/IcnsImageParser.java index 18965f4..9cb7d63 100644 --- a/src/main/java/org/apache/commons/imaging/formats/icns/IcnsImageParser.java +++ b/src/main/java/org/apache/commons/imaging/formats/icns/IcnsImageParser.java @@ -16,7 +16,6 @@ */ package org.apache.commons.imaging.formats.icns; -import static org.apache.commons.imaging.ImagingConstants.PARAM_KEY_FORMAT; import static org.apache.commons.imaging.common.BinaryFunctions.read4Bytes; import static org.apache.commons.imaging.common.BinaryFunctions.readBytes; @@ -28,9 +27,7 @@ import java.io.OutputStream; import java.io.PrintWriter; import java.nio.ByteOrder; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import org.apache.commons.imaging.ImageFormat; import org.apache.commons.imaging.ImageFormats; @@ -42,7 +39,7 @@ import org.apache.commons.imaging.common.BinaryOutputStream; import org.apache.commons.imaging.common.ImageMetadata; import org.apache.commons.imaging.common.bytesource.ByteSource; -public class IcnsImageParser extends ImageParser { +public class IcnsImageParser extends ImageParser<IcnsImagingParameters> { static final int ICNS_MAGIC = IcnsType.typeAsInt("icns"); private static final String DEFAULT_EXTENSION = ".icns"; private static final String[] ACCEPTED_EXTENSIONS = { ".icns", }; @@ -73,22 +70,14 @@ public class IcnsImageParser extends ImageParser { // FIXME should throw UOE @Override - public ImageMetadata getMetadata(final ByteSource byteSource, final Map<String, Object> params) + public ImageMetadata getMetadata(final ByteSource byteSource, final IcnsImagingParameters params) throws ImageReadException, IOException { return null; } @Override - public ImageInfo getImageInfo(final ByteSource byteSource, Map<String, Object> params) + public ImageInfo getImageInfo(final ByteSource byteSource, IcnsImagingParameters params) throws ImageReadException, IOException { - // make copy of params; we'll clear keys as we consume them. - params = params == null ? new HashMap<>() : new HashMap<>(params); - - if (!params.isEmpty()) { - final Object firstKey = params.keySet().iterator().next(); - throw new ImageReadException("Unknown parameter: " + firstKey); - } - final IcnsContents contents = readImage(byteSource); final List<BufferedImage> images = IcnsDecoder.decodeAllImages(contents.icnsElements); if (images.isEmpty()) { @@ -104,16 +93,8 @@ public class IcnsImageParser extends ImageParser { } @Override - public Dimension getImageSize(final ByteSource byteSource, Map<String, Object> params) + public Dimension getImageSize(final ByteSource byteSource, IcnsImagingParameters params) throws ImageReadException, IOException { - // make copy of params; we'll clear keys as we consume them. - params = (params == null) ? new HashMap<>() : new HashMap<>(params); - - if (!params.isEmpty()) { - final Object firstKey = params.keySet().iterator().next(); - throw new ImageReadException("Unknown parameter: " + firstKey); - } - final IcnsContents contents = readImage(byteSource); final List<BufferedImage> images = IcnsDecoder.decodeAllImages(contents.icnsElements); if (images.isEmpty()) { @@ -124,7 +105,7 @@ public class IcnsImageParser extends ImageParser { } @Override - public byte[] getICCProfileBytes(final ByteSource byteSource, final Map<String, Object> params) + public byte[] getICCProfileBytes(final ByteSource byteSource, final IcnsImagingParameters params) throws ImageReadException, IOException { return null; } @@ -244,7 +225,7 @@ public class IcnsImageParser extends ImageParser { @Override public final BufferedImage getBufferedImage(final ByteSource byteSource, - final Map<String, Object> params) throws ImageReadException, IOException { + final IcnsImagingParameters params) throws ImageReadException, IOException { final IcnsContents icnsContents = readImage(byteSource); final List<BufferedImage> result = IcnsDecoder.decodeAllImages(icnsContents.icnsElements); if (!result.isEmpty()) { @@ -261,21 +242,8 @@ public class IcnsImageParser extends ImageParser { } @Override - public void writeImage(final BufferedImage src, final OutputStream os, Map<String, Object> params) + public void writeImage(final BufferedImage src, final OutputStream os, IcnsImagingParameters params) throws ImageWriteException, IOException { - // make copy of params; we'll clear keys as we consume them. - params = (params == null) ? new HashMap<>() : new HashMap<>(params); - - // clear format key. - if (params.containsKey(PARAM_KEY_FORMAT)) { - params.remove(PARAM_KEY_FORMAT); - } - - if (!params.isEmpty()) { - final Object firstKey = params.keySet().iterator().next(); - throw new ImageWriteException("Unknown parameter: " + firstKey); - } - IcnsType imageType; if (src.getWidth() == 16 && src.getHeight() == 16) { imageType = IcnsType.ICNS_16x16_32BIT_IMAGE; diff --git a/src/main/java/org/apache/commons/imaging/formats/icns/IcnsImagingParameters.java b/src/main/java/org/apache/commons/imaging/formats/icns/IcnsImagingParameters.java new file mode 100644 index 0000000..bbfd8c8 --- /dev/null +++ b/src/main/java/org/apache/commons/imaging/formats/icns/IcnsImagingParameters.java @@ -0,0 +1,26 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * under the License. + */ + +package org.apache.commons.imaging.formats.icns; + +import org.apache.commons.imaging.ImagingParameters; + +/** + * Icns format parameters. + * @since 1.0-alpha3 + */ +public class IcnsImagingParameters extends ImagingParameters { + +} diff --git a/src/main/java/org/apache/commons/imaging/formats/ico/IcoImageParser.java b/src/main/java/org/apache/commons/imaging/formats/ico/IcoImageParser.java index 546e497..d6a4bd7 100644 --- a/src/main/java/org/apache/commons/imaging/formats/ico/IcoImageParser.java +++ b/src/main/java/org/apache/commons/imaging/formats/ico/IcoImageParser.java @@ -16,8 +16,6 @@ */ package org.apache.commons.imaging.formats.ico; -import static org.apache.commons.imaging.ImagingConstants.PARAM_KEY_FORMAT; -import static org.apache.commons.imaging.ImagingConstants.PARAM_KEY_PIXEL_DENSITY; import static org.apache.commons.imaging.common.BinaryFunctions.read2Bytes; import static org.apache.commons.imaging.common.BinaryFunctions.read4Bytes; import static org.apache.commons.imaging.common.BinaryFunctions.readByte; @@ -33,9 +31,7 @@ import java.io.OutputStream; import java.io.PrintWriter; import java.nio.ByteOrder; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import org.apache.commons.imaging.ImageFormat; import org.apache.commons.imaging.ImageFormats; @@ -52,7 +48,7 @@ import org.apache.commons.imaging.formats.bmp.BmpImageParser; import org.apache.commons.imaging.palette.PaletteFactory; import org.apache.commons.imaging.palette.SimplePalette; -public class IcoImageParser extends ImageParser { +public class IcoImageParser extends ImageParser<IcoImagingParameters> { private static final String DEFAULT_EXTENSION = ".ico"; private static final String[] ACCEPTED_EXTENSIONS = { ".ico", ".cur", }; @@ -83,28 +79,28 @@ public class IcoImageParser extends ImageParser { // TODO should throw UOE @Override - public ImageMetadata getMetadata(final ByteSource byteSource, final Map<String, Object> params) + public ImageMetadata getMetadata(final ByteSource byteSource, final IcoImagingParameters params) throws ImageReadException, IOException { return null; } // TODO should throw UOE @Override - public ImageInfo getImageInfo(final ByteSource byteSource, final Map<String, Object> params) + public ImageInfo getImageInfo(final ByteSource byteSource, final IcoImagingParameters params) throws ImageReadException, IOException { return null; } // TODO should throw UOE @Override - public Dimension getImageSize(final ByteSource byteSource, final Map<String, Object> params) + public Dimension getImageSize(final ByteSource byteSource, final IcoImagingParameters params) throws ImageReadException, IOException { return null; } // TODO should throw UOE @Override - public byte[] getICCProfileBytes(final ByteSource byteSource, final Map<String, Object> params) + public byte[] getICCProfileBytes(final ByteSource byteSource, final IcoImagingParameters params) throws ImageReadException, IOException { return null; } @@ -572,7 +568,7 @@ public class IcoImageParser extends ImageParser { @Override public final BufferedImage getBufferedImage(final ByteSource byteSource, - final Map<String, Object> params) throws ImageReadException, IOException { + final IcoImagingParameters params) throws ImageReadException, IOException { final ImageContents contents = readImage(byteSource); final FileHeader fileHeader = contents.fileHeader; if (fileHeader.iconCount > 0) { @@ -624,22 +620,9 @@ public class IcoImageParser extends ImageParser { // } @Override - public void writeImage(final BufferedImage src, final OutputStream os, Map<String, Object> params) + public void writeImage(final BufferedImage src, final OutputStream os, IcoImagingParameters params) throws ImageWriteException, IOException { - // make copy of params; we'll clear keys as we consume them. - params = (params == null) ? new HashMap<>() : new HashMap<>(params); - - // clear format key. - if (params.containsKey(PARAM_KEY_FORMAT)) { - params.remove(PARAM_KEY_FORMAT); - } - - final PixelDensity pixelDensity = (PixelDensity) params.remove(PARAM_KEY_PIXEL_DENSITY); - - if (!params.isEmpty()) { - final Object firstKey = params.keySet().iterator().next(); - throw new ImageWriteException("Unknown parameter: " + firstKey); - } + final PixelDensity pixelDensity = params.getPixelDensity(); final PaletteFactory paletteFactory = new PaletteFactory(); final SimplePalette palette = paletteFactory.makeExactRgbPaletteSimple(src, 256); diff --git a/src/main/java/org/apache/commons/imaging/formats/ico/IcoImagingParameters.java b/src/main/java/org/apache/commons/imaging/formats/ico/IcoImagingParameters.java new file mode 100644 index 0000000..d686bce --- /dev/null +++ b/src/main/java/org/apache/commons/imaging/formats/ico/IcoImagingParameters.java @@ -0,0 +1,26 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * under the License. + */ + +package org.apache.commons.imaging.formats.ico; + +import org.apache.commons.imaging.ImagingParameters; + +/** + * Ico format parameters. + * @since 1.0-alpha3 + */ +public class IcoImagingParameters extends ImagingParameters { + +} diff --git a/src/main/java/org/apache/commons/imaging/formats/jpeg/JpegImageParser.java b/src/main/java/org/apache/commons/imaging/formats/jpeg/JpegImageParser.java index 288c239..216e0eb 100644 --- a/src/main/java/org/apache/commons/imaging/formats/jpeg/JpegImageParser.java +++ b/src/main/java/org/apache/commons/imaging/formats/jpeg/JpegImageParser.java @@ -16,7 +16,6 @@ */ package org.apache.commons.imaging.formats.jpeg; -import static org.apache.commons.imaging.ImagingConstants.PARAM_KEY_READ_THUMBNAILS; import static org.apache.commons.imaging.common.BinaryFunctions.remainingBytes; import static org.apache.commons.imaging.common.BinaryFunctions.startsWith; @@ -30,9 +29,7 @@ import java.text.NumberFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; @@ -64,7 +61,7 @@ import org.apache.commons.imaging.formats.tiff.TiffImageParser; import org.apache.commons.imaging.formats.tiff.constants.TiffTagConstants; import org.apache.commons.imaging.internal.Debug; -public class JpegImageParser extends ImageParser implements XmpEmbeddable { +public class JpegImageParser extends ImageParser<JpegImagingParameters> implements XmpEmbeddable<JpegImagingParameters> { private static final Logger LOGGER = Logger.getLogger(JpegImageParser.class.getName()); @@ -99,7 +96,7 @@ public class JpegImageParser extends ImageParser implements XmpEmbeddable { @Override public final BufferedImage getBufferedImage(final ByteSource byteSource, - final Map<String, Object> params) throws ImageReadException, IOException { + final JpegImagingParameters params) throws ImageReadException, IOException { final JpegDecoder jpegDecoder = new JpegDecoder(); return jpegDecoder.decode(byteSource); } @@ -290,7 +287,7 @@ public class JpegImageParser extends ImageParser implements XmpEmbeddable { } @Override - public byte[] getICCProfileBytes(final ByteSource byteSource, final Map<String, Object> params) + public byte[] getICCProfileBytes(final ByteSource byteSource, final JpegImagingParameters params) throws ImageReadException, IOException { final List<Segment> segments = readSegments(byteSource, new int[] { JpegConstants.JPEG_APP2_MARKER, }, false); @@ -320,7 +317,7 @@ public class JpegImageParser extends ImageParser implements XmpEmbeddable { } @Override - public ImageMetadata getMetadata(final ByteSource byteSource, final Map<String, Object> params) + public ImageMetadata getMetadata(final ByteSource byteSource, final JpegImagingParameters params) throws ImageReadException, IOException { final TiffImageMetadata exif = getExifMetadata(byteSource, params); @@ -351,19 +348,14 @@ public class JpegImageParser extends ImageParser implements XmpEmbeddable { return result; } - public TiffImageMetadata getExifMetadata(final ByteSource byteSource, Map<String, Object> params) + public TiffImageMetadata getExifMetadata(final ByteSource byteSource, JpegImagingParameters params) throws ImageReadException, IOException { final byte[] bytes = getExifRawData(byteSource); if (null == bytes) { return null; } - if (params == null) { - params = new HashMap<>(); - } - if (!params.containsKey(PARAM_KEY_READ_THUMBNAILS)) { - params.put(PARAM_KEY_READ_THUMBNAILS, Boolean.TRUE); - } + params.setReadThumbnails(Boolean.TRUE); return (TiffImageMetadata) new TiffImageParser().getMetadata(bytes, params); @@ -542,7 +534,7 @@ public class JpegImageParser extends ImageParser implements XmpEmbeddable { * @return Xmp Xml as String, if present. Otherwise, returns null. */ @Override - public String getXmpXml(final ByteSource byteSource, final Map<String, Object> params) + public String getXmpXml(final ByteSource byteSource, final JpegImagingParameters params) throws ImageReadException, IOException { final List<String> result = new ArrayList<>(); @@ -592,7 +584,7 @@ public class JpegImageParser extends ImageParser implements XmpEmbeddable { } public JpegPhotoshopMetadata getPhotoshopMetadata(final ByteSource byteSource, - final Map<String, Object> params) throws ImageReadException, IOException { + final JpegImagingParameters params) throws ImageReadException, IOException { final List<Segment> segments = readSegments(byteSource, new int[] { JpegConstants.JPEG_APP13_MARKER, }, false); @@ -621,7 +613,7 @@ public class JpegImageParser extends ImageParser implements XmpEmbeddable { } @Override - public Dimension getImageSize(final ByteSource byteSource, final Map<String, Object> params) + public Dimension getImageSize(final ByteSource byteSource, final JpegImagingParameters params) throws ImageReadException, IOException { final List<Segment> segments = readSegments(byteSource, new int[] { // kJFIFMarker, @@ -655,7 +647,7 @@ public class JpegImageParser extends ImageParser implements XmpEmbeddable { } @Override - public ImageInfo getImageInfo(final ByteSource byteSource, final Map<String, Object> params) + public ImageInfo getImageInfo(final ByteSource byteSource, final JpegImagingParameters params) throws ImageReadException, IOException { // List allSegments = readSegments(byteSource, null, false); diff --git a/src/main/java/org/apache/commons/imaging/formats/jpeg/JpegImagingParameters.java b/src/main/java/org/apache/commons/imaging/formats/jpeg/JpegImagingParameters.java new file mode 100644 index 0000000..d2083f3 --- /dev/null +++ b/src/main/java/org/apache/commons/imaging/formats/jpeg/JpegImagingParameters.java @@ -0,0 +1,26 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * under the License. + */ + +package org.apache.commons.imaging.formats.jpeg; + +import org.apache.commons.imaging.formats.tiff.TiffImagingParameters; + +/** + * Jpeg format parameters. + * @since 1.0-alpha3 + */ +public class JpegImagingParameters extends TiffImagingParameters { + +} diff --git a/src/main/java/org/apache/commons/imaging/formats/png/PngConstants.java b/src/main/java/org/apache/commons/imaging/formats/png/PngConstants.java index b1f1828..bbc460c 100644 --- a/src/main/java/org/apache/commons/imaging/formats/png/PngConstants.java +++ b/src/main/java/org/apache/commons/imaging/formats/png/PngConstants.java @@ -25,13 +25,6 @@ public final class PngConstants { public static final BinaryConstant PNG_SIGNATURE = new BinaryConstant( new byte[] { (byte) 0x89, 'P', 'N', 'G', '\r', '\n', 0x1A, '\n', }); - public static final String PARAM_KEY_PNG_BIT_DEPTH = "PNG_BIT_DEPTH"; - public static final String PARAM_KEY_PNG_FORCE_INDEXED_COLOR = "PNG_FORCE_INDEXED_COLOR"; - public static final String PARAM_KEY_PNG_FORCE_TRUE_COLOR = "PNG_FORCE_TRUE_COLOR"; - - // public static final Object PARAM_KEY_PNG_BIT_DEPTH_YES = "YES"; - // public static final Object PARAM_KEY_PNG_BIT_DEPTH_NO = "NO"; - public static final byte COMPRESSION_TYPE_INFLATE_DEFLATE = 0; public static final byte FILTER_METHOD_ADAPTIVE = 0; @@ -60,24 +53,6 @@ public final class PngConstants { public static final String XMP_KEYWORD = "XML:com.adobe.xmp"; /** - * Parameter key. - * - * <p>Only used when writing Png images.</p> - * - * <p>Valid values: a list of WriteTexts.</p> - */ - public static final String PARAM_KEY_PNG_TEXT_CHUNKS = "PNG_TEXT_CHUNKS"; - - /** - * Parameter key. Used in write operations to indicate the Physical Scale - sCAL. - * - * <p>Valid values: PhysicalScale</p> - * - * @see org.apache.commons.imaging.formats.png.PhysicalScale - */ - public static final String PARAM_KEY_PHYSICAL_SCALE = "PHYSICAL_SCALE_CHUNK"; - - /** * Parameter key. Used to indicate the PNG compression level to be used. * * <p>For valid values, see {@link java.util.zip.Deflater}. If no value is specified, it will use diff --git a/src/main/java/org/apache/commons/imaging/formats/png/PngImageParser.java b/src/main/java/org/apache/commons/imaging/formats/png/PngImageParser.java index 62709a8..67bd8a5 100644 --- a/src/main/java/org/apache/commons/imaging/formats/png/PngImageParser.java +++ b/src/main/java/org/apache/commons/imaging/formats/png/PngImageParser.java @@ -35,9 +35,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import java.util.zip.InflaterInputStream; @@ -71,7 +69,7 @@ import org.apache.commons.imaging.formats.png.transparencyfilters.TransparencyFi import org.apache.commons.imaging.formats.png.transparencyfilters.TransparencyFilterTrueColor; import org.apache.commons.imaging.icc.IccProfileParser; -public class PngImageParser extends ImageParser implements XmpEmbeddable { +public class PngImageParser extends ImageParser<PngImagingParameters> implements XmpEmbeddable<PngImagingParameters> { private static final Logger LOGGER = Logger.getLogger(PngImageParser.class.getName()); @@ -238,7 +236,7 @@ public class PngImageParser extends ImageParser implements XmpEmbeddable { } @Override - public byte[] getICCProfileBytes(final ByteSource byteSource, final Map<String, Object> params) + public byte[] getICCProfileBytes(final ByteSource byteSource, final PngImagingParameters params) throws ImageReadException, IOException { final List<PngChunk> chunks = readChunks(byteSource, new ChunkType[] { ChunkType.iCCP }, true); @@ -258,7 +256,7 @@ public class PngImageParser extends ImageParser implements XmpEmbeddable { } @Override - public Dimension getImageSize(final ByteSource byteSource, final Map<String, Object> params) + public Dimension getImageSize(final ByteSource byteSource, final PngImagingParameters params) throws ImageReadException, IOException { final List<PngChunk> chunks = readChunks(byteSource, new ChunkType[] { ChunkType.IHDR, }, true); @@ -276,7 +274,7 @@ public class PngImageParser extends ImageParser implements XmpEmbeddable { } @Override - public ImageMetadata getMetadata(final ByteSource byteSource, final Map<String, Object> params) + public ImageMetadata getMetadata(final ByteSource byteSource, final PngImagingParameters params) throws ImageReadException, IOException { final List<PngChunk> chunks = readChunks(byteSource, new ChunkType[] { ChunkType.tEXt, ChunkType.zTXt, }, false); @@ -328,7 +326,7 @@ public class PngImageParser extends ImageParser implements XmpEmbeddable { } @Override - public ImageInfo getImageInfo(final ByteSource byteSource, final Map<String, Object> params) + public ImageInfo getImageInfo(final ByteSource byteSource, final PngImagingParameters params) throws ImageReadException, IOException { final List<PngChunk> chunks = readChunks(byteSource, new ChunkType[] { ChunkType.IHDR, @@ -482,14 +480,8 @@ public class PngImageParser extends ImageParser implements XmpEmbeddable { } @Override - public BufferedImage getBufferedImage(final ByteSource byteSource, Map<String, Object> params) + public BufferedImage getBufferedImage(final ByteSource byteSource, PngImagingParameters params) throws ImageReadException, IOException { - params = (params == null) ? new HashMap<>() : new HashMap<>(params); - - // if (params.size() > 0) { - // Object firstKey = params.keySet().iterator().next(); - // throw new ImageWriteException("Unknown parameter: " + firstKey); - // } final List<PngChunk> chunks = readChunks(byteSource, new ChunkType[] { ChunkType.IHDR, @@ -705,13 +697,13 @@ public class PngImageParser extends ImageParser implements XmpEmbeddable { } @Override - public void writeImage(final BufferedImage src, final OutputStream os, final Map<String, Object> params) + public void writeImage(final BufferedImage src, final OutputStream os, final PngImagingParameters params) throws ImageWriteException, IOException { new PngWriter().writeImage(src, os, params); } @Override - public String getXmpXml(final ByteSource byteSource, final Map<String, Object> params) + public String getXmpXml(final ByteSource byteSource, final PngImagingParameters params) throws ImageReadException, IOException { final List<PngChunk> chunks = readChunks(byteSource, new ChunkType[] { ChunkType.iTXt }, false); diff --git a/src/main/java/org/apache/commons/imaging/formats/png/PngImagingParameters.java b/src/main/java/org/apache/commons/imaging/formats/png/PngImagingParameters.java new file mode 100644 index 0000000..3fdcc07 --- /dev/null +++ b/src/main/java/org/apache/commons/imaging/formats/png/PngImagingParameters.java @@ -0,0 +1,95 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * under the License. + */ + +package org.apache.commons.imaging.formats.png; + +import java.util.Collections; +import java.util.List; + +import org.apache.commons.imaging.common.XmpImagingParameters; + +/** + * Png format parameters. + * @since 1.0-alpha3 + */ +public class PngImagingParameters extends XmpImagingParameters { + + public static final byte DEFAULT_BIT_DEPTH = 8; + + /** + * Bit depth. Default value is {@literal 8}. + */ + private byte bitDepth = DEFAULT_BIT_DEPTH; + + private boolean forceIndexedColor = false; + + private boolean forceTrueColor = false; + + /** + * Used in write operations to indicate the Physical Scale - sCAL. + * + * <p>Valid values: PhysicalScale</p> + * + * @see org.apache.commons.imaging.formats.png.PhysicalScale + */ + private PhysicalScale physicalScale = null; + + /** + * <p>Only used when writing Png images.</p> + * + * <p>Valid values: a list of WriteTexts.</p> + */ + private List<PngText> textChunks = null; + + public byte getBitDepth() { + return bitDepth; + } + + public void setBitDepth(byte bitDepth) { + this.bitDepth = bitDepth; + } + + public boolean isForceIndexedColor() { + return forceIndexedColor; + } + + public void setForceIndexedColor(boolean forceIndexedColor) { + this.forceIndexedColor = forceIndexedColor; + } + + public boolean isForceTrueColor() { + return forceTrueColor; + } + + public void setForceTrueColor(boolean forceTrueColor) { + this.forceTrueColor = forceTrueColor; + } + + public PhysicalScale getPhysicalScale() { + return physicalScale; + } + + public void setPhysicalScale(PhysicalScale physicalScale) { + this.physicalScale = physicalScale; + } + + public List<PngText> getTextChunks() { + return Collections.unmodifiableList(textChunks); + } + + public void setTextChunks(List<PngText> textChunks) { + this.textChunks = textChunks; + } +} diff --git a/src/main/java/org/apache/commons/imaging/formats/png/PngWriter.java b/src/main/java/org/apache/commons/imaging/formats/png/PngWriter.java index 627501e..ca32993 100644 --- a/src/main/java/org/apache/commons/imaging/formats/png/PngWriter.java +++ b/src/main/java/org/apache/commons/imaging/formats/png/PngWriter.java @@ -21,14 +21,11 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.nio.charset.StandardCharsets; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; import org.apache.commons.imaging.ImageWriteException; -import org.apache.commons.imaging.ImagingConstants; import org.apache.commons.imaging.PixelDensity; import org.apache.commons.imaging.internal.Debug; import org.apache.commons.imaging.palette.Palette; @@ -45,7 +42,7 @@ class PngWriter { The remaining 14 chunk types are termed ancillary chunk types, which encoders may generate and decoders may interpret. 1. Transparency information: tRNS (see 11.3.2: Transparency information). - 2. Colour space information: cHRM, gAMA, iCCP, sBIT, sRGB (see 11.3.3: Colour space information). + 2. Color space information: cHRM, gAMA, iCCP, sBIT, sRGB (see 11.3.3: Color space information). 3. Textual information: iTXt, tEXt, zTXt (see 11.3.4: Textual information). 4. Miscellaneous information: bKGD, hIST, pHYs, sPLT (see 11.3.5: Miscellaneous information). 5. Time information: tIME (see 11.3.6: Time stamp information). @@ -295,15 +292,10 @@ class PngWriter { writeChunk(os, ChunkType.sCAL, baos.toByteArray()); } - private byte getBitDepth(final PngColorType pngColorType, final Map<String, Object> params) { - byte depth = 8; + private byte getBitDepth(final PngColorType pngColorType, final PngImagingParameters params) { + byte depth = params.getBitDepth(); - final Object o = params.get(PngConstants.PARAM_KEY_PNG_BIT_DEPTH); - if (o instanceof Number) { - depth = ((Number) o).byteValue(); - } - - return pngColorType.isBitDepthAllowed(depth) ? depth : 8; + return pngColorType.isBitDepthAllowed(depth) ? depth : PngImagingParameters.DEFAULT_BIT_DEPTH; } /* @@ -335,44 +327,9 @@ class PngWriter { tEXt Yes None zTXt Yes None */ - public void writeImage(final BufferedImage src, final OutputStream os, Map<String, Object> params) + public void writeImage(final BufferedImage src, final OutputStream os, PngImagingParameters params) throws ImageWriteException, IOException { - // make copy of params; we'll clear keys as we consume them. - params = new HashMap<>(params); - - // clear format key. - if (params.containsKey(ImagingConstants.PARAM_KEY_FORMAT)) { - params.remove(ImagingConstants.PARAM_KEY_FORMAT); - } - int compressionLevel = Deflater.DEFAULT_COMPRESSION; - final Map<String, Object> rawParams = new HashMap<>(params); - if (params.containsKey(PngConstants.PARAM_KEY_PNG_FORCE_TRUE_COLOR)) { - params.remove(PngConstants.PARAM_KEY_PNG_FORCE_TRUE_COLOR); - } - if (params.containsKey(PngConstants.PARAM_KEY_PNG_FORCE_INDEXED_COLOR)) { - params.remove(PngConstants.PARAM_KEY_PNG_FORCE_INDEXED_COLOR); - } - if (params.containsKey(PngConstants.PARAM_KEY_PNG_BIT_DEPTH)) { - params.remove(PngConstants.PARAM_KEY_PNG_BIT_DEPTH); - } - if (params.containsKey(ImagingConstants.PARAM_KEY_XMP_XML)) { - params.remove(ImagingConstants.PARAM_KEY_XMP_XML); - } - if (params.containsKey(PngConstants.PARAM_KEY_PNG_TEXT_CHUNKS)) { - params.remove(PngConstants.PARAM_KEY_PNG_TEXT_CHUNKS); - } - if (params.containsKey(PngConstants.PARAM_KEY_PNG_COMPRESSION_LEVEL)) { - compressionLevel = (int) params.remove(PngConstants.PARAM_KEY_PNG_COMPRESSION_LEVEL); - } - params.remove(ImagingConstants.PARAM_KEY_PIXEL_DENSITY); - params.remove(PngConstants.PARAM_KEY_PHYSICAL_SCALE); - params.remove(PngConstants.PARAM_KEY_PNG_COMPRESSION_LEVEL); - if (!params.isEmpty()) { - final Object firstKey = params.keySet().iterator().next(); - throw new ImageWriteException("Unknown parameter: " + firstKey); - } - params = rawParams; final int width = src.getWidth(); final int height = src.getHeight(); @@ -386,8 +343,8 @@ class PngWriter { PngColorType pngColorType; { - final boolean forceIndexedColor = Boolean.TRUE.equals(params.get(PngConstants.PARAM_KEY_PNG_FORCE_INDEXED_COLOR)); - final boolean forceTrueColor = Boolean.TRUE.equals(params.get(PngConstants.PARAM_KEY_PNG_FORCE_TRUE_COLOR)); + final boolean forceIndexedColor = params.isForceIndexedColor(); + final boolean forceTrueColor = params.isForceTrueColor(); if (forceIndexedColor && forceTrueColor) { throw new ImageWriteException( @@ -456,7 +413,7 @@ class PngWriter { } } - final Object pixelDensityObj = params.get(ImagingConstants.PARAM_KEY_PIXEL_DENSITY); + final Object pixelDensityObj = params.getPixelDensity(); if (pixelDensityObj instanceof PixelDensity) { final PixelDensity pixelDensity = (PixelDensity) pixelDensityObj; if (pixelDensity.isUnitless()) { @@ -470,22 +427,23 @@ class PngWriter { } } - final Object physcialScaleObj = params.get(PngConstants.PARAM_KEY_PHYSICAL_SCALE); - if (physcialScaleObj instanceof PhysicalScale) { - final PhysicalScale physicalScale = (PhysicalScale)physcialScaleObj; - writeChunkSCAL(os, physicalScale.getHorizontalUnitsPerPixel(), physicalScale.getVerticalUnitsPerPixel(), - physicalScale.isInMeters() ? (byte) 1 : (byte) 2); + final PhysicalScale physicalScale = params.getPhysicalScale(); + if (physicalScale != null) { + writeChunkSCAL( + os, + physicalScale.getHorizontalUnitsPerPixel(), + physicalScale.getVerticalUnitsPerPixel(), + physicalScale.isInMeters() ? (byte) 1 : (byte) 2); } - if (params.containsKey(ImagingConstants.PARAM_KEY_XMP_XML)) { - final String xmpXml = (String) params.get(ImagingConstants.PARAM_KEY_XMP_XML); + final String xmpXml = params.getXmpXml(); + if (xmpXml != null) { writeChunkXmpiTXt(os, xmpXml); } - if (params.containsKey(PngConstants.PARAM_KEY_PNG_TEXT_CHUNKS)) { - final List<?> outputTexts = (List<?>) params.get(PngConstants.PARAM_KEY_PNG_TEXT_CHUNKS); - for (final Object outputText : outputTexts) { - final PngText text = (PngText) outputText; + final List<PngText> outputTexts = params.getTextChunks(); + if (outputTexts != null) { + for (final PngText text : outputTexts) { if (text instanceof PngText.Text) { writeChunktEXt(os, (PngText.Text) text); } else if (text instanceof PngText.Ztxt) { @@ -493,8 +451,7 @@ class PngWriter { } else if (text instanceof PngText.Itxt) { writeChunkiTXt(os, (PngText.Itxt) text); } else { - throw new ImageWriteException( - "Unknown text to embed in PNG: " + text); + throw new ImageWriteException("Unknown text to embed in PNG: " + text); } } } diff --git a/src/main/java/org/apache/commons/imaging/formats/psd/PsdImageParser.java b/src/main/java/org/apache/commons/imaging/formats/psd/PsdImageParser.java index 997fb42..56c439d 100644 --- a/src/main/java/org/apache/commons/imaging/formats/psd/PsdImageParser.java +++ b/src/main/java/org/apache/commons/imaging/formats/psd/PsdImageParser.java @@ -33,7 +33,6 @@ import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; -import java.util.Map; import org.apache.commons.imaging.ImageFormat; import org.apache.commons.imaging.ImageFormats; @@ -54,7 +53,7 @@ import org.apache.commons.imaging.formats.psd.datareaders.CompressedDataReader; import org.apache.commons.imaging.formats.psd.datareaders.DataReader; import org.apache.commons.imaging.formats.psd.datareaders.UncompressedDataReader; -public class PsdImageParser extends ImageParser implements XmpEmbeddable { +public class PsdImageParser extends ImageParser<PsdImagingParameters> implements XmpEmbeddable<PsdImagingParameters> { private static final String DEFAULT_EXTENSION = ".psd"; private static final String[] ACCEPTED_EXTENSIONS = { DEFAULT_EXTENSION, }; private static final int PSD_SECTION_HEADER = 0; @@ -381,7 +380,7 @@ public class PsdImageParser extends ImageParser implements XmpEmbeddable { } @Override - public byte[] getICCProfileBytes(final ByteSource byteSource, final Map<String, Object> params) + public byte[] getICCProfileBytes(final ByteSource byteSource, final PsdImagingParameters params) throws ImageReadException, IOException { final List<ImageResourceBlock> blocks = readImageResourceBlocks(byteSource, new int[] { IMAGE_RESOURCE_ID_ICC_PROFILE, }, 1); @@ -399,7 +398,7 @@ public class PsdImageParser extends ImageParser implements XmpEmbeddable { } @Override - public Dimension getImageSize(final ByteSource byteSource, final Map<String, Object> params) + public Dimension getImageSize(final ByteSource byteSource, final PsdImagingParameters params) throws ImageReadException, IOException { final PsdHeaderInfo bhi = readHeader(byteSource); @@ -408,7 +407,7 @@ public class PsdImageParser extends ImageParser implements XmpEmbeddable { } @Override - public ImageMetadata getMetadata(final ByteSource byteSource, final Map<String, Object> params) + public ImageMetadata getMetadata(final ByteSource byteSource, final PsdImagingParameters params) throws ImageReadException, IOException { return null; } @@ -438,7 +437,7 @@ public class PsdImageParser extends ImageParser implements XmpEmbeddable { } @Override - public ImageInfo getImageInfo(final ByteSource byteSource, final Map<String, Object> params) + public ImageInfo getImageInfo(final ByteSource byteSource, final PsdImagingParameters params) throws ImageReadException, IOException { final PsdImageContents imageContents = readImageContents(byteSource); // ImageContents imageContents = readImage(byteSource, false); @@ -545,7 +544,7 @@ public class PsdImageParser extends ImageParser implements XmpEmbeddable { } @Override - public BufferedImage getBufferedImage(final ByteSource byteSource, final Map<String, Object> params) + public BufferedImage getBufferedImage(final ByteSource byteSource, final PsdImagingParameters params) throws ImageReadException, IOException { final PsdImageContents imageContents = readImageContents(byteSource); // ImageContents imageContents = readImage(byteSource, false); @@ -657,7 +656,7 @@ public class PsdImageParser extends ImageParser implements XmpEmbeddable { * @return Xmp Xml as String, if present. Otherwise, returns null. */ @Override - public String getXmpXml(final ByteSource byteSource, final Map<String, Object> params) + public String getXmpXml(final ByteSource byteSource, final PsdImagingParameters params) throws ImageReadException, IOException { final PsdImageContents imageContents = readImageContents(byteSource); diff --git a/src/main/java/org/apache/commons/imaging/formats/psd/PsdImagingParameters.java b/src/main/java/org/apache/commons/imaging/formats/psd/PsdImagingParameters.java new file mode 100644 index 0000000..306069f --- /dev/null +++ b/src/main/java/org/apache/commons/imaging/formats/psd/PsdImagingParameters.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.imaging.formats.psd; + +import org.apache.commons.imaging.ImagingParameters; + +/** + * Psd format parameters. + * @since 1.0-alpha3 + */ +public class PsdImagingParameters extends ImagingParameters { + +} diff --git a/src/main/java/org/apache/commons/imaging/formats/rgbe/RgbeImageParser.java b/src/main/java/org/apache/commons/imaging/formats/rgbe/RgbeImageParser.java index b7a6a77..a3219e7 100644 --- a/src/main/java/org/apache/commons/imaging/formats/rgbe/RgbeImageParser.java +++ b/src/main/java/org/apache/commons/imaging/formats/rgbe/RgbeImageParser.java @@ -29,7 +29,6 @@ import java.awt.image.Raster; import java.io.IOException; import java.nio.ByteOrder; import java.util.ArrayList; -import java.util.Map; import org.apache.commons.imaging.ImageFormat; import org.apache.commons.imaging.ImageFormats; @@ -44,7 +43,7 @@ import org.apache.commons.imaging.common.bytesource.ByteSource; * * @author <a href="mailto:pe...@electrotank.com">peter royal</a> */ -public class RgbeImageParser extends ImageParser { +public class RgbeImageParser extends ImageParser<RgbeImagingParameters> { public RgbeImageParser() { setByteOrder(ByteOrder.BIG_ENDIAN); @@ -71,7 +70,7 @@ public class RgbeImageParser extends ImageParser { } @Override - public ImageMetadata getMetadata(final ByteSource byteSource, final Map<String, Object> params) + public ImageMetadata getMetadata(final ByteSource byteSource, final RgbeImagingParameters params) throws ImageReadException, IOException { try (RgbeInfo info = new RgbeInfo(byteSource)) { return info.getMetadata(); @@ -79,7 +78,7 @@ public class RgbeImageParser extends ImageParser { } @Override - public ImageInfo getImageInfo(final ByteSource byteSource, final Map<String, Object> params) + public ImageInfo getImageInfo(final ByteSource byteSource, final RgbeImagingParameters params) throws ImageReadException, IOException { try (RgbeInfo info = new RgbeInfo(byteSource)) { return new ImageInfo( @@ -93,7 +92,7 @@ public class RgbeImageParser extends ImageParser { } @Override - public BufferedImage getBufferedImage(final ByteSource byteSource, final Map<String, Object> params) + public BufferedImage getBufferedImage(final ByteSource byteSource, final RgbeImagingParameters params) throws ImageReadException, IOException { try (RgbeInfo info = new RgbeInfo(byteSource)) { // It is necessary to create our own BufferedImage here as the @@ -114,7 +113,7 @@ public class RgbeImageParser extends ImageParser { } @Override - public Dimension getImageSize(final ByteSource byteSource, final Map<String, Object> params) + public Dimension getImageSize(final ByteSource byteSource, final RgbeImagingParameters params) throws ImageReadException, IOException { try (RgbeInfo info = new RgbeInfo(byteSource)) { return new Dimension(info.getWidth(), info.getHeight()); @@ -122,7 +121,7 @@ public class RgbeImageParser extends ImageParser { } @Override - public byte[] getICCProfileBytes(final ByteSource byteSource, final Map<String, Object> params) + public byte[] getICCProfileBytes(final ByteSource byteSource, final RgbeImagingParameters params) throws ImageReadException, IOException { return null; } diff --git a/src/main/java/org/apache/commons/imaging/formats/rgbe/RgbeImagingParameters.java b/src/main/java/org/apache/commons/imaging/formats/rgbe/RgbeImagingParameters.java new file mode 100644 index 0000000..9d1f6eb --- /dev/null +++ b/src/main/java/org/apache/commons/imaging/formats/rgbe/RgbeImagingParameters.java @@ -0,0 +1,26 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * under the License. + */ + +package org.apache.commons.imaging.formats.rgbe; + +import org.apache.commons.imaging.ImagingParameters; + +/** + * Rgbe format parameters. + * @since 1.0-alpha3 + */ +public class RgbeImagingParameters extends ImagingParameters { + +} diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/TiffCompression.java b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffCompression.java new file mode 100644 index 0000000..3db2290 --- /dev/null +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffCompression.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.imaging.formats.tiff; + +public enum TiffCompression { + +} diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/TiffDirectory.java b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffDirectory.java index d548365..b22b040 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/TiffDirectory.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffDirectory.java @@ -22,7 +22,6 @@ import java.nio.ByteOrder; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Map; import org.apache.commons.imaging.ImageReadException; import org.apache.commons.imaging.common.ByteConversions; @@ -189,18 +188,18 @@ public class TiffDirectory extends TiffElement { * Gets the image associated with the directory, if any. Note that not all * directories contain images. * <p> - * The optional parameters map can be used to specify image access or + * The optional parameters object can be used to specify image access or * rendering options such as reading only a part of the overall image (i.e. * reading a sub-image) or applying a custom photometric interpreter. * - * @param params a map containing optional parameters to be applied to the + * @param params an object containing optional parameters to be applied to the * read operation. * @return if successful, a valid BufferedImage instance. * @throws ImageReadException in the event of an invalid or incompatible * data format. * @throws IOException in the event of an I/O error. */ - public BufferedImage getTiffImage(final Map<String, Object> params) + public BufferedImage getTiffImage(final TiffImagingParameters params) throws ImageReadException, IOException { if (null == tiffImageData) { return null; @@ -226,7 +225,7 @@ public class TiffDirectory extends TiffElement { */ public BufferedImage getTiffImage(final ByteOrder byteOrder) throws ImageReadException, IOException { - return getTiffImage(byteOrder, null); + return getTiffImage(byteOrder, new TiffImagingParameters()); } /** @@ -239,14 +238,14 @@ public class TiffDirectory extends TiffElement { * argument. * * @param byteOrder byte-order obtained from the containing TIFF file - * @param params a map containing optional parameters to be applied to the + * @param params an object containing optional parameters to be applied to the * read operation. * @return if successful, a valid BufferedImage instance. * @throws ImageReadException in the event of an invalid or incompatible * data format. * @throws IOException in the event of an I/O error. */ - public BufferedImage getTiffImage(final ByteOrder byteOrder, final Map<String, Object> params) + public BufferedImage getTiffImage(final ByteOrder byteOrder, final TiffImagingParameters params) throws ImageReadException, IOException { if (null == tiffImageData) { return null; @@ -889,7 +888,7 @@ public class TiffDirectory extends TiffElement { * @throws IOException in the event of an I/O error */ public TiffRasterData getRasterData( - final Map<String, Object> params) + final TiffImagingParameters params) throws ImageReadException, IOException { final TiffImageParser parser = new TiffImageParser(); diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/TiffImageParser.java b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffImageParser.java index 04eb259..308362a 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/TiffImageParser.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffImageParser.java @@ -36,7 +36,6 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import java.util.Map; import org.apache.commons.imaging.FormatCompliance; import org.apache.commons.imaging.ImageFormat; @@ -50,7 +49,6 @@ import org.apache.commons.imaging.common.ImageMetadata; import org.apache.commons.imaging.common.XmpEmbeddable; import org.apache.commons.imaging.common.bytesource.ByteSource; import org.apache.commons.imaging.formats.tiff.TiffDirectory.ImageDataElement; -import org.apache.commons.imaging.formats.tiff.constants.TiffConstants; import org.apache.commons.imaging.formats.tiff.constants.TiffEpTagConstants; import org.apache.commons.imaging.formats.tiff.constants.TiffPlanarConfiguration; import org.apache.commons.imaging.formats.tiff.constants.TiffTagConstants; @@ -65,7 +63,7 @@ import org.apache.commons.imaging.formats.tiff.photometricinterpreters.Photometr import org.apache.commons.imaging.formats.tiff.photometricinterpreters.PhotometricInterpreterYCbCr; import org.apache.commons.imaging.formats.tiff.write.TiffImageWriterLossy; -public class TiffImageParser extends ImageParser implements XmpEmbeddable { +public class TiffImageParser extends ImageParser<TiffImagingParameters> implements XmpEmbeddable<TiffImagingParameters> { private static final String DEFAULT_EXTENSION = ".tif"; private static final String[] ACCEPTED_EXTENSIONS = { ".tif", ".tiff", }; @@ -91,7 +89,7 @@ public class TiffImageParser extends ImageParser implements XmpEmbeddable { } @Override - public byte[] getICCProfileBytes(final ByteSource byteSource, final Map<String, Object> params) + public byte[] getICCProfileBytes(final ByteSource byteSource, final TiffImagingParameters params) throws ImageReadException, IOException { final FormatCompliance formatCompliance = FormatCompliance.getDefault(); final TiffContents contents = new TiffReader(isStrict(params)).readFirstDirectory( @@ -103,7 +101,7 @@ public class TiffImageParser extends ImageParser implements XmpEmbeddable { } @Override - public Dimension getImageSize(final ByteSource byteSource, final Map<String, Object> params) + public Dimension getImageSize(final ByteSource byteSource, final TiffImagingParameters params) throws ImageReadException, IOException { final FormatCompliance formatCompliance = FormatCompliance.getDefault(); final TiffContents contents = new TiffReader(isStrict(params)).readFirstDirectory( @@ -126,10 +124,10 @@ public class TiffImageParser extends ImageParser implements XmpEmbeddable { } @Override - public ImageMetadata getMetadata(final ByteSource byteSource, final Map<String, Object> params) + public ImageMetadata getMetadata(final ByteSource byteSource, final TiffImagingParameters params) throws ImageReadException, IOException { final FormatCompliance formatCompliance = FormatCompliance.getDefault(); - final TiffReader tiffReader = new TiffReader(isStrict(params)); + final TiffReader tiffReader = new TiffReader(params.isStrict()); final TiffContents contents = tiffReader.readContents(byteSource, params, formatCompliance); @@ -154,7 +152,7 @@ public class TiffImageParser extends ImageParser implements XmpEmbeddable { } @Override - public ImageInfo getImageInfo(final ByteSource byteSource, final Map<String, Object> params) + public ImageInfo getImageInfo(final ByteSource byteSource, final TiffImagingParameters params) throws ImageReadException, IOException { final FormatCompliance formatCompliance = FormatCompliance.getDefault(); final TiffContents contents = new TiffReader(isStrict(params)).readDirectories( @@ -311,7 +309,7 @@ public class TiffImageParser extends ImageParser implements XmpEmbeddable { } @Override - public String getXmpXml(final ByteSource byteSource, final Map<String, Object> params) + public String getXmpXml(final ByteSource byteSource, final TiffImagingParameters params) throws ImageReadException, IOException { final FormatCompliance formatCompliance = FormatCompliance.getDefault(); final TiffContents contents = new TiffReader(isStrict(params)).readDirectories( @@ -348,8 +346,9 @@ public class TiffImageParser extends ImageParser implements XmpEmbeddable { // try { final FormatCompliance formatCompliance = FormatCompliance.getDefault(); + final TiffImagingParameters params = null; final TiffContents contents = new TiffReader(true).readContents( - byteSource, null, formatCompliance); + byteSource, params, formatCompliance); final List<TiffDirectory> directories = contents.directories; @@ -388,15 +387,16 @@ public class TiffImageParser extends ImageParser implements XmpEmbeddable { public FormatCompliance getFormatCompliance(final ByteSource byteSource) throws ImageReadException, IOException { final FormatCompliance formatCompliance = FormatCompliance.getDefault(); - new TiffReader(isStrict(null)).readContents(byteSource, null, + final TiffImagingParameters params = null; + new TiffReader(isStrict(params)).readContents(byteSource, params, formatCompliance); return formatCompliance; } - public List<byte[]> collectRawImageData(final ByteSource byteSource, final Map<String, Object> params) + public List<byte[]> collectRawImageData(final ByteSource byteSource, final TiffImagingParameters params) throws ImageReadException, IOException { final FormatCompliance formatCompliance = FormatCompliance.getDefault(); - final TiffContents contents = new TiffReader(isStrict(params)).readDirectories( + final TiffContents contents = new TiffReader(params.isStrict()).readDirectories( byteSource, true, formatCompliance); final List<byte[]> result = new ArrayList<>(); @@ -429,11 +429,11 @@ public class TiffImageParser extends ImageParser implements XmpEmbeddable { * as follows:</p> * * <pre> - * HashMap<String, Object> params = new HashMap<String, Object>(); - * params.put(TiffConstants.PARAM_KEY_SUBIMAGE_X, new Integer(x)); - * params.put(TiffConstants.PARAM_KEY_SUBIMAGE_Y, new Integer(y)); - * params.put(TiffConstants.PARAM_KEY_SUBIMAGE_WIDTH, new Integer(width)); - * params.put(TiffConstants.PARAM_KEY_SUBIMAGE_HEIGHT, new Integer(height)); + * TiffImagingParameters params = new TiffImagingParameters(); + * params.setSubImageX(x); + * params.setSubImageY(y); + * params.setSubImageWidth(width); + * params.setSubImageHeight(height); * </pre> * * <p>Note that the arguments x, y, width, and height must specify a @@ -452,7 +452,7 @@ public class TiffImageParser extends ImageParser implements XmpEmbeddable { * access operation. */ @Override - public BufferedImage getBufferedImage(final ByteSource byteSource, final Map<String, Object> params) + public BufferedImage getBufferedImage(final ByteSource byteSource, final TiffImagingParameters params) throws ImageReadException, IOException { final FormatCompliance formatCompliance = FormatCompliance.getDefault(); final TiffReader reader = new TiffReader(isStrict(params)); @@ -486,32 +486,13 @@ public class TiffImageParser extends ImageParser implements XmpEmbeddable { return results; } - private Integer getIntegerParameter( - final String key, final Map<String, Object>params) - throws ImageReadException { - if (params == null) { - return null; - } - - if (!params.containsKey(key)) { - return null; - } - - final Object obj = params.get(key); - - if (obj instanceof Integer) { - return (Integer) obj; - } - throw new ImageReadException("Non-Integer parameter " + key); - } - private Rectangle checkForSubImage( - final Map<String, Object> params) + final TiffImagingParameters params) throws ImageReadException { - final Integer ix0 = getIntegerParameter(TiffConstants.PARAM_KEY_SUBIMAGE_X, params); - final Integer iy0 = getIntegerParameter(TiffConstants.PARAM_KEY_SUBIMAGE_Y, params); - final Integer iwidth = getIntegerParameter(TiffConstants.PARAM_KEY_SUBIMAGE_WIDTH, params); - final Integer iheight = getIntegerParameter(TiffConstants.PARAM_KEY_SUBIMAGE_HEIGHT, params); + final Integer ix0 = params.getSubImageX(); + final Integer iy0 = params.getSubImageY(); + final Integer iwidth = params.getSubImageWidth(); + final Integer iheight = params.getSubImageHeight(); if (ix0 == null && iy0 == null && iwidth == null && iheight == null) { return null; @@ -539,7 +520,7 @@ public class TiffImageParser extends ImageParser implements XmpEmbeddable { } protected BufferedImage getBufferedImage(final TiffDirectory directory, - final ByteOrder byteOrder, final Map<String, Object> params) + final ByteOrder byteOrder, final TiffImagingParameters params) throws ImageReadException, IOException { final List<TiffField> entries = directory.entries; @@ -655,13 +636,8 @@ public class TiffImageParser extends ImageParser implements XmpEmbeddable { } } - PhotometricInterpreter photometricInterpreter; - final Object test = params == null - ? null - : params.get(TiffConstants.PARAM_KEY_CUSTOM_PHOTOMETRIC_INTERPRETER); - if (test instanceof PhotometricInterpreter) { - photometricInterpreter = (PhotometricInterpreter) test; - } else { + PhotometricInterpreter photometricInterpreter = params.getCustomPhotometricInterpreter(); + if (photometricInterpreter == null) { photometricInterpreter = getPhotometricInterpreter( directory, photometricInterpretation, bitsPerPixel, bitsPerSample, predictor, samplesPerPixel, width, height); @@ -775,7 +751,7 @@ public class TiffImageParser extends ImageParser implements XmpEmbeddable { } @Override - public void writeImage(final BufferedImage src, final OutputStream os, final Map<String, Object> params) + public void writeImage(final BufferedImage src, final OutputStream os, final TiffImagingParameters params) throws ImageWriteException, IOException { new TiffImageWriterLossy().writeImage(src, os, params); } @@ -784,20 +760,26 @@ public class TiffImageParser extends ImageParser implements XmpEmbeddable { * Reads the content of a TIFF file that contains numerical data samples * rather than image-related pixels. * <p> +<<<<<<< HEAD * If desired, sub-image data can be read from the file by using a Java * {@code Map} instance to specify the subsection of the image that * is required. The following code illustrates the approach: +======= + * If desired, sub-image data can be read from the file by using an {@code TiffImagingParameters} + * instance to specify the subsection of the image that is required. The + * following code illustrates the approach: +>>>>>>> [IMAGING-159] Use ImagingParameters and define new classes as needed for other formats * <pre> * int x; // coordinate (column) of corner of sub-image * int y; // coordinate (row) of corner of sub-image * int width; // width of sub-image * int height; // height of sub-image * - * Map<String, Object>params = new HashMap<>(); - * params.put(TiffConstants.PARAM_KEY_SUBIMAGE_X, x); - * params.put(TiffConstants.PARAM_KEY_SUBIMAGE_Y, y); - * params.put(TiffConstants.PARAM_KEY_SUBIMAGE_WIDTH, width); - * params.put(TiffConstants.PARAM_KEY_SUBIMAGE_HEIGHT, height); + * TiffImagingParameters params = new TiffImagingParameters(); + * params.setSubImageX(x); + * params.setSubImageY(y); + * params.setSubImageWidth(width); + * params.setSubImageHeight(height); * TiffRasterData raster = * readFloatingPointRasterData(directory, byteOrder, params); * </pre> @@ -805,7 +787,7 @@ public class TiffImageParser extends ImageParser implements XmpEmbeddable { * @param directory the TIFF directory pointing to the data to be extracted * (TIFF files may contain multiple directories) * @param byteOrder the byte order of the data to be extracted - * @param params an optional parameter map instance + * @param params an optional parameter object instance * @return a valid instance * @throws ImageReadException in the event of incompatible or malformed data * @throws IOException in the event of an I/O error @@ -813,7 +795,7 @@ public class TiffImageParser extends ImageParser implements XmpEmbeddable { TiffRasterData getRasterData( final TiffDirectory directory, final ByteOrder byteOrder, - Map<String, Object> params) + TiffImagingParameters params) throws ImageReadException, IOException { final List<TiffField> entries = directory.entries; @@ -822,7 +804,7 @@ public class TiffImageParser extends ImageParser implements XmpEmbeddable { } if (params == null) { - params = new HashMap<>(); + params = this.getDefaultParameters(); } final short[] sSampleFmt = directory.getFieldValue( diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/TiffImagingParameters.java b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffImagingParameters.java new file mode 100644 index 0000000..b61bfde --- /dev/null +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffImagingParameters.java @@ -0,0 +1,189 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * under the License. + */ + +package org.apache.commons.imaging.formats.tiff; + +import org.apache.commons.imaging.common.XmpImagingParameters; +import org.apache.commons.imaging.formats.tiff.photometricinterpreters.PhotometricInterpreter; +import org.apache.commons.imaging.formats.tiff.write.TiffOutputSet; + +/** + * Tiff format parameters. + * @since 1.0-alpha3 + */ +public class TiffImagingParameters extends XmpImagingParameters { + + /** + * Indicates whether to read embedded thumbnails or not. Only applies to read EXIF metadata from JPEG/JFIF files. + * + * <p>Default value is {@code true}.</p> + */ + private boolean readThumbnails = true; + + /** + * User provided {@code TiffOutputSet} used to write into the image's EXIF metadata. + */ + private TiffOutputSet exif = null; + + /** + * X-coordinate of a sub-image. + */ + private Integer subImageX = null; + + /** + * Y-coordinate of a sub-image. + */ + private Integer subImageY = null; + + /** + * Width of a sub-image. + */ + private Integer subImageWidth = null; + + /** + * Height of a sub-image. + */ + private Integer subImageHeight = null; + + /** + * Specifies that an application-specified photometric interpreter + * is to be used when reading TIFF files to convert raster data samples + * to RGB values for the output image. + * + * <p>The value supplied with this key should be a valid instance of + * a class that implements PhotometricInterpreter.</p> + */ + private PhotometricInterpreter customPhotometricInterpreter = null; + + /** + * TIFF compression algorithm, if any. + */ + private Integer compression = null; + + /** + * Specifies the amount of memory in bytes to be used for a strip + * or tile size when employing LZW compression. The default is + * 8000 (roughly 8K). Minimum value is 8000. + */ + private Integer lzwCompressionBlockSize = null; + + /** + * Used in write operations to indicate the desired T.4 options to + * use when using TIFF_COMPRESSION_CCITT_GROUP_3. + * + * <p>Valid values: any Integer containing a mixture of the + * TIFF_FLAG_T4_OPTIONS_2D, TIFF_FLAG_T4_OPTIONS_UNCOMPRESSED_MODE, + * and TIFF_FLAG_T4_OPTIONS_FILL flags.</p> + */ + private Integer t4Options = null; + + /** + * Used in write operations to indicate the desired T.6 options to + * use when using TIFF_COMPRESSION_CCITT_GROUP_4. + * + * <p>Valid values: any Integer containing either zero or + * TIFF_FLAG_T6_OPTIONS_UNCOMPRESSED_MODE.</p> + */ + private Integer t6Options = null; + + public boolean isReadThumbnails() { + return readThumbnails; + } + + public void setReadThumbnails(boolean readThumbnails) { + this.readThumbnails = readThumbnails; + } + + public TiffOutputSet getExif() { + return exif; + } + + public void setExif(TiffOutputSet exif) { + this.exif = exif; + } + + public Integer getSubImageX() { + return subImageX; + } + + public void setSubImageX(Integer subImageX) { + this.subImageX = subImageX; + } + + public Integer getSubImageY() { + return subImageY; + } + + public void setSubImageY(Integer subImageY) { + this.subImageY = subImageY; + } + + public Integer getSubImageWidth() { + return subImageWidth; + } + + public void setSubImageWidth(Integer subImageWidth) { + this.subImageWidth = subImageWidth; + } + + public Integer getSubImageHeight() { + return subImageHeight; + } + + public void setSubImageHeight(Integer subImageHeight) { + this.subImageHeight = subImageHeight; + } + + public PhotometricInterpreter getCustomPhotometricInterpreter() { + return customPhotometricInterpreter; + } + + public void setCustomPhotometricInterpreter(PhotometricInterpreter customPhotometricInterpreter) { + this.customPhotometricInterpreter = customPhotometricInterpreter; + } + + public Integer getCompression() { + return compression; + } + + public void setCompression(Integer compression) { + this.compression = compression; + } + + public Integer getLzwCompressionBlockSize() { + return lzwCompressionBlockSize; + } + + public void setLzwCompressionBlockSize(Integer lzwCompressionBlockSize) { + this.lzwCompressionBlockSize = lzwCompressionBlockSize; + } + + public Integer getT4Options() { + return t4Options; + } + + public void setT4Options(Integer t4Options) { + this.t4Options = t4Options; + } + + public Integer getT6Options() { + return t6Options; + } + + public void setT6Options(Integer t6Options) { + this.t6Options = t6Options; + } + +} diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/TiffReader.java b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffReader.java index 68029fc..b312032 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/TiffReader.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffReader.java @@ -27,13 +27,10 @@ import java.io.IOException; import java.io.InputStream; import java.nio.ByteOrder; import java.util.ArrayList; -import java.util.Collections; import java.util.List; -import java.util.Map; import org.apache.commons.imaging.FormatCompliance; import org.apache.commons.imaging.ImageReadException; -import org.apache.commons.imaging.ImagingConstants; import org.apache.commons.imaging.common.BinaryFileParser; import org.apache.commons.imaging.common.ByteConversions; import org.apache.commons.imaging.common.bytesource.ByteSource; @@ -294,12 +291,8 @@ public class TiffReader extends BinaryFileParser { this(null); } - Collector(final Map<String, Object> params) { - boolean tmpReadThumbnails = true; - if (params != null && params.containsKey(ImagingConstants.PARAM_KEY_READ_THUMBNAILS)) { - tmpReadThumbnails = Boolean.TRUE.equals(params.get(ImagingConstants.PARAM_KEY_READ_THUMBNAILS)); - } - this.readThumbnails = tmpReadThumbnails; + Collector(final TiffImagingParameters params) { + this.readThumbnails = params.isReadThumbnails(); } @Override @@ -374,7 +367,7 @@ public class TiffReader extends BinaryFileParser { // } // } - public TiffContents readFirstDirectory(final ByteSource byteSource, final Map<String, Object> params, + public TiffContents readFirstDirectory(final ByteSource byteSource, final TiffImagingParameters params, final boolean readImageData, final FormatCompliance formatCompliance) throws ImageReadException, IOException { final Collector collector = new FirstDirectoryCollector(readImageData); @@ -390,8 +383,8 @@ public class TiffReader extends BinaryFileParser { public TiffContents readDirectories(final ByteSource byteSource, final boolean readImageData, final FormatCompliance formatCompliance) throws ImageReadException, IOException { - final Map<String, Object> params = Collections.singletonMap( - ImagingConstants.PARAM_KEY_READ_THUMBNAILS, readImageData); + final TiffImagingParameters params = new TiffImagingParameters(); + params.setReadThumbnails(readImageData); final Collector collector = new Collector(params); readDirectories(byteSource, formatCompliance, collector); final TiffContents contents = collector.getContents(); @@ -402,7 +395,7 @@ public class TiffReader extends BinaryFileParser { return contents; } - public TiffContents readContents(final ByteSource byteSource, final Map<String, Object> params, + public TiffContents readContents(final ByteSource byteSource, final TiffImagingParameters params, final FormatCompliance formatCompliance) throws ImageReadException, IOException { @@ -411,7 +404,7 @@ public class TiffReader extends BinaryFileParser { return collector.getContents(); } - public void read(final ByteSource byteSource, final Map<String, Object> params, + public void read(final ByteSource byteSource, final TiffImagingParameters params, final FormatCompliance formatCompliance, final Listener listener) throws ImageReadException, IOException { // TiffContents contents = diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/constants/TiffConstants.java b/src/main/java/org/apache/commons/imaging/formats/tiff/constants/TiffConstants.java index 42505bf..16ca42f 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/constants/TiffConstants.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/constants/TiffConstants.java @@ -44,56 +44,11 @@ public final class TiffConstants { public static final int TIFF_COMPRESSION_DEFLATE_PKZIP = 32946; public static final int TIFF_COMPRESSION_DEFLATE_ADOBE = 8; - /** - * Parameter key. Used in write operations to indicate the desired - * T.4 options to use when using TIFF_COMPRESSION_CCITT_GROUP_3. - * <p> - * Valid values: any Integer containing a mixture of the - * TIFF_FLAG_T4_OPTIONS_2D, TIFF_FLAG_T4_OPTIONS_UNCOMPRESSED_MODE, - * and TIFF_FLAG_T4_OPTIONS_FILL flags. - */ - public static final String PARAM_KEY_T4_OPTIONS = "T4_OPTIONS"; - - /** - * Parameter key. Used in write operations to indicate the desired - * T.6 options to use when using TIFF_COMPRESSION_CCITT_GROUP_4. - * <p> - * Valid values: any Integer containing either zero or - * TIFF_FLAG_T6_OPTIONS_UNCOMPRESSED_MODE. - */ - public static final String PARAM_KEY_T6_OPTIONS = "T6_OPTIONS"; - public static final int TIFF_FLAG_T4_OPTIONS_2D = 1; public static final int TIFF_FLAG_T4_OPTIONS_UNCOMPRESSED_MODE = 2; public static final int TIFF_FLAG_T4_OPTIONS_FILL = 4; public static final int TIFF_FLAG_T6_OPTIONS_UNCOMPRESSED_MODE = 2; - - public static final String PARAM_KEY_SUBIMAGE_X = "SUBIMAGE_X"; - public static final String PARAM_KEY_SUBIMAGE_Y = "SUBIMAGE_Y"; - public static final String PARAM_KEY_SUBIMAGE_WIDTH = "SUBIMAGE_WIDTH"; - public static final String PARAM_KEY_SUBIMAGE_HEIGHT = "SUBIMAGE_HEIGHT"; - - - /** - * Specifies that an application-specified photometric interpreter - * is to be used when reading TIFF files to convert raster data samples - * to RGB values for the output image. - * <p> - * The value supplied with this key should be a valid instance of - * a class that implements PhotometricInterpreter. - */ - public static final String PARAM_KEY_CUSTOM_PHOTOMETRIC_INTERPRETER - = "CUSTOM_PHOTOMETRIC_INTERPRETER"; - - /** - * Specifies the amount of memory in bytes to be used for a strip - * or tile size when employing LZW compression. The default is - * 8000 (roughly 8K). Minimum value is 8000. - */ - public static final String PARAM_KEY_LZW_COMPRESSION_BLOCK_SIZE = - "PARAM_KEY_LZW_COMPRESSION_BLOCK_SIZE"; - /** * Specifies a larger strip-size to be used for compression. This setting * generally produces smaller output files, but requires a slightly longer diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/write/TiffImageWriterBase.java b/src/main/java/org/apache/commons/imaging/formats/tiff/write/TiffImageWriterBase.java index 775ecd2..696cede 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/write/TiffImageWriterBase.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/write/TiffImageWriterBase.java @@ -17,9 +17,6 @@ package org.apache.commons.imaging.formats.tiff.write; import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.DEFAULT_TIFF_BYTE_ORDER; -import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.PARAM_KEY_LZW_COMPRESSION_BLOCK_SIZE; -import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.PARAM_KEY_T4_OPTIONS; -import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.PARAM_KEY_T6_OPTIONS; import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_COMPRESSION_CCITT_1D; import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_COMPRESSION_CCITT_GROUP_3; import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_COMPRESSION_CCITT_GROUP_4; @@ -44,7 +41,6 @@ import java.util.List; import java.util.Map; import org.apache.commons.imaging.ImageWriteException; -import org.apache.commons.imaging.ImagingConstants; import org.apache.commons.imaging.PixelDensity; import org.apache.commons.imaging.common.BinaryOutputStream; import org.apache.commons.imaging.common.PackBits; @@ -54,6 +50,7 @@ import org.apache.commons.imaging.common.mylzw.MyLzwCompressor; import org.apache.commons.imaging.common.ZlibDeflate; import org.apache.commons.imaging.formats.tiff.TiffElement; import org.apache.commons.imaging.formats.tiff.TiffImageData; +import org.apache.commons.imaging.formats.tiff.TiffImagingParameters; import org.apache.commons.imaging.formats.tiff.constants.ExifTagConstants; import org.apache.commons.imaging.formats.tiff.constants.TiffDirectoryConstants; import org.apache.commons.imaging.formats.tiff.constants.TiffTagConstants; @@ -303,29 +300,13 @@ public abstract class TiffImageWriterBase { } } - public void writeImage(final BufferedImage src, final OutputStream os, Map<String, Object> params) + public void writeImage(final BufferedImage src, final OutputStream os, TiffImagingParameters params) throws ImageWriteException, IOException { - // make copy of params; we'll clear keys as we consume them. - params = new HashMap<>(params); + TiffOutputSet userExif = params.getExif(); - // clear format key. - if (params.containsKey(ImagingConstants.PARAM_KEY_FORMAT)) { - params.remove(ImagingConstants.PARAM_KEY_FORMAT); - } - - TiffOutputSet userExif = null; - if (params.containsKey(ImagingConstants.PARAM_KEY_EXIF)) { - userExif = (TiffOutputSet) params.remove(ImagingConstants.PARAM_KEY_EXIF); - } + String xmpXml = params.getXmpXml(); - String xmpXml = null; - if (params.containsKey(ImagingConstants.PARAM_KEY_XMP_XML)) { - xmpXml = (String) params.get(ImagingConstants.PARAM_KEY_XMP_XML); - params.remove(ImagingConstants.PARAM_KEY_XMP_XML); - } - - PixelDensity pixelDensity = (PixelDensity) params.remove( - ImagingConstants.PARAM_KEY_PIXEL_DENSITY); + PixelDensity pixelDensity = params.getPixelDensity(); if (pixelDensity == null) { pixelDensity = PixelDensity.createFromPixelsPerInch(72, 72); } @@ -358,41 +339,19 @@ public abstract class TiffImageWriterBase { short predictor = TiffTagConstants.PREDICTOR_VALUE_NONE; int stripSizeInBits = 64000; // the default from legacy implementation - if (params.containsKey(ImagingConstants.PARAM_KEY_COMPRESSION)) { - final Object value = params.get(ImagingConstants.PARAM_KEY_COMPRESSION); - if (value != null) { - if (!(value instanceof Number)) { - throw new ImageWriteException( - "Invalid compression parameter, must be numeric: " - + value); - } - compression = ((Number) value).intValue(); - } - params.remove(ImagingConstants.PARAM_KEY_COMPRESSION); - if (params.containsKey(PARAM_KEY_LZW_COMPRESSION_BLOCK_SIZE)) { - final Object bValue = - params.get(PARAM_KEY_LZW_COMPRESSION_BLOCK_SIZE); - if (!(bValue instanceof Number)) { - throw new ImageWriteException( - "Invalid compression block-size parameter: " + value); - } - final int stripSizeInBytes = ((Number) bValue).intValue(); + Integer compressionParameter = params.getCompression(); + if (compressionParameter != null) { + compression = compressionParameter.intValue(); + final Integer stripSizeInBytes = params.getLzwCompressionBlockSize(); + if (stripSizeInBytes != null) { if (stripSizeInBytes < 8000) { throw new ImageWriteException( "Block size parameter " + stripSizeInBytes + " is less than 8000 minimum"); } - stripSizeInBits = stripSizeInBytes*8; - params.remove(PARAM_KEY_LZW_COMPRESSION_BLOCK_SIZE); + stripSizeInBits = stripSizeInBytes * 8; } } - final HashMap<String, Object> rawParams = new HashMap<>(params); - params.remove(PARAM_KEY_T4_OPTIONS); - params.remove(PARAM_KEY_T6_OPTIONS); - if (!params.isEmpty()) { - final Object firstKey = params.keySet().iterator().next(); - throw new ImageWriteException("Unknown parameter: " + firstKey); - } int samplesPerPixel; int bitsPerSample; @@ -428,7 +387,7 @@ public abstract class TiffImageWriterBase { strips[i], width, strips[i].length / ((width + 7) / 8)); } } else if (compression == TIFF_COMPRESSION_CCITT_GROUP_3) { - final Integer t4Parameter = (Integer) rawParams.get(PARAM_KEY_T4_OPTIONS); + final Integer t4Parameter = params.getT4Options(); if (t4Parameter != null) { t4Options = t4Parameter.intValue(); } @@ -452,7 +411,7 @@ public abstract class TiffImageWriterBase { } } } else if (compression == TIFF_COMPRESSION_CCITT_GROUP_4) { - final Integer t6Parameter = (Integer) rawParams.get(PARAM_KEY_T6_OPTIONS); + final Integer t6Parameter = params.getT6Options(); if (t6Parameter != null) { t6Options = t6Parameter.intValue(); } diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/write/TiffImageWriterLossless.java b/src/main/java/org/apache/commons/imaging/formats/tiff/write/TiffImageWriterLossless.java index b98fb53..7f1b921 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/write/TiffImageWriterLossless.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/write/TiffImageWriterLossless.java @@ -42,6 +42,7 @@ import org.apache.commons.imaging.formats.tiff.TiffElement; import org.apache.commons.imaging.formats.tiff.TiffElement.DataElement; import org.apache.commons.imaging.formats.tiff.TiffField; import org.apache.commons.imaging.formats.tiff.TiffImageData; +import org.apache.commons.imaging.formats.tiff.TiffImagingParameters; import org.apache.commons.imaging.formats.tiff.TiffReader; import org.apache.commons.imaging.formats.tiff.constants.ExifTagConstants; @@ -65,7 +66,7 @@ public class TiffImageWriterLossless extends TiffImageWriterBase { final ByteSource byteSource = new ByteSourceArray(exifBytes); final FormatCompliance formatCompliance = FormatCompliance.getDefault(); final TiffContents contents = new TiffReader(false).readContents( - byteSource, null, formatCompliance); + byteSource, new TiffImagingParameters(), formatCompliance); final List<TiffElement> elements = new ArrayList<>(); diff --git a/src/main/java/org/apache/commons/imaging/formats/wbmp/WbmpImageParser.java b/src/main/java/org/apache/commons/imaging/formats/wbmp/WbmpImageParser.java index 343d806..d71ab43 100644 --- a/src/main/java/org/apache/commons/imaging/formats/wbmp/WbmpImageParser.java +++ b/src/main/java/org/apache/commons/imaging/formats/wbmp/WbmpImageParser.java @@ -14,7 +14,6 @@ */ package org.apache.commons.imaging.formats.wbmp; -import static org.apache.commons.imaging.ImagingConstants.PARAM_KEY_FORMAT; import static org.apache.commons.imaging.common.BinaryFunctions.readByte; import static org.apache.commons.imaging.common.BinaryFunctions.readBytes; @@ -30,8 +29,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; import java.util.Properties; import org.apache.commons.imaging.ImageFormat; @@ -43,7 +40,7 @@ import org.apache.commons.imaging.ImageWriteException; import org.apache.commons.imaging.common.ImageMetadata; import org.apache.commons.imaging.common.bytesource.ByteSource; -public class WbmpImageParser extends ImageParser { +public class WbmpImageParser extends ImageParser<WbmpImagingParameters> { private static final String DEFAULT_EXTENSION = ".wbmp"; private static final String[] ACCEPTED_EXTENSIONS = { ".wbmp", }; @@ -69,13 +66,13 @@ public class WbmpImageParser extends ImageParser { } @Override - public ImageMetadata getMetadata(final ByteSource byteSource, final Map<String, Object> params) + public ImageMetadata getMetadata(final ByteSource byteSource, final WbmpImagingParameters params) throws ImageReadException, IOException { return null; } @Override - public ImageInfo getImageInfo(final ByteSource byteSource, final Map<String, Object> params) + public ImageInfo getImageInfo(final ByteSource byteSource, final WbmpImagingParameters params) throws ImageReadException, IOException { final WbmpHeader wbmpHeader = readWbmpHeader(byteSource); return new ImageInfo("WBMP", 1, new ArrayList<String>(), @@ -87,14 +84,14 @@ public class WbmpImageParser extends ImageParser { } @Override - public Dimension getImageSize(final ByteSource byteSource, final Map<String, Object> params) + public Dimension getImageSize(final ByteSource byteSource, final WbmpImagingParameters params) throws ImageReadException, IOException { final WbmpHeader wbmpHeader = readWbmpHeader(byteSource); return new Dimension(wbmpHeader.width, wbmpHeader.height); } @Override - public byte[] getICCProfileBytes(final ByteSource byteSource, final Map<String, Object> params) + public byte[] getICCProfileBytes(final ByteSource byteSource, final WbmpImagingParameters params) throws ImageReadException, IOException { return null; } @@ -208,7 +205,7 @@ public class WbmpImageParser extends ImageParser { @Override public final BufferedImage getBufferedImage(final ByteSource byteSource, - final Map<String, Object> params) throws ImageReadException, IOException { + final WbmpImagingParameters params) throws ImageReadException, IOException { try (InputStream is = byteSource.getInputStream()) { final WbmpHeader wbmpHeader = readWbmpHeader(is); return readImage(wbmpHeader, is); @@ -216,21 +213,8 @@ public class WbmpImageParser extends ImageParser { } @Override - public void writeImage(final BufferedImage src, final OutputStream os, Map<String, Object> params) + public void writeImage(final BufferedImage src, final OutputStream os, WbmpImagingParameters params) throws ImageWriteException, IOException { - // make copy of params; we'll clear keys as we consume them. - params = (params == null) ? new HashMap<>() : new HashMap<>(params); - - // clear format key. - if (params.containsKey(PARAM_KEY_FORMAT)) { - params.remove(PARAM_KEY_FORMAT); - } - - if (!params.isEmpty()) { - final Object firstKey = params.keySet().iterator().next(); - throw new ImageWriteException("Unknown parameter: " + firstKey); - } - writeMultiByteInteger(os, 0); // typeField os.write(0); // fixHeaderField writeMultiByteInteger(os, src.getWidth()); diff --git a/src/main/java/org/apache/commons/imaging/formats/wbmp/WbmpImagingParameters.java b/src/main/java/org/apache/commons/imaging/formats/wbmp/WbmpImagingParameters.java new file mode 100644 index 0000000..00af50d --- /dev/null +++ b/src/main/java/org/apache/commons/imaging/formats/wbmp/WbmpImagingParameters.java @@ -0,0 +1,26 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * under the License. + */ + +package org.apache.commons.imaging.formats.wbmp; + +import org.apache.commons.imaging.ImagingParameters; + +/** + * Wbmp format parameters. + * @since 1.0-alpha3 + */ +public class WbmpImagingParameters extends ImagingParameters { + +} diff --git a/src/main/java/org/apache/commons/imaging/formats/xbm/XbmImageParser.java b/src/main/java/org/apache/commons/imaging/formats/xbm/XbmImageParser.java index 0e17654..51113de 100644 --- a/src/main/java/org/apache/commons/imaging/formats/xbm/XbmImageParser.java +++ b/src/main/java/org/apache/commons/imaging/formats/xbm/XbmImageParser.java @@ -14,8 +14,6 @@ */ package org.apache.commons.imaging.formats.xbm; -import static org.apache.commons.imaging.ImagingConstants.PARAM_KEY_FORMAT; - import java.awt.Dimension; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; @@ -48,7 +46,7 @@ import org.apache.commons.imaging.common.BasicCParser; import org.apache.commons.imaging.common.ImageMetadata; import org.apache.commons.imaging.common.bytesource.ByteSource; -public class XbmImageParser extends ImageParser { +public class XbmImageParser extends ImageParser<XbmImagingParameters> { private static final String DEFAULT_EXTENSION = ".xbm"; private static final String[] ACCEPTED_EXTENSIONS = { ".xbm", }; @@ -74,13 +72,13 @@ public class XbmImageParser extends ImageParser { } @Override - public ImageMetadata getMetadata(final ByteSource byteSource, final Map<String, Object> params) + public ImageMetadata getMetadata(final ByteSource byteSource, final XbmImagingParameters params) throws ImageReadException, IOException { return null; } @Override - public ImageInfo getImageInfo(final ByteSource byteSource, final Map<String, Object> params) + public ImageInfo getImageInfo(final ByteSource byteSource, final XbmImagingParameters params) throws ImageReadException, IOException { final XbmHeader xbmHeader = readXbmHeader(byteSource); return new ImageInfo("XBM", 1, new ArrayList<String>(), @@ -91,14 +89,14 @@ public class XbmImageParser extends ImageParser { } @Override - public Dimension getImageSize(final ByteSource byteSource, final Map<String, Object> params) + public Dimension getImageSize(final ByteSource byteSource, final XbmImagingParameters params) throws ImageReadException, IOException { final XbmHeader xbmHeader = readXbmHeader(byteSource); return new Dimension(xbmHeader.width, xbmHeader.height); } @Override - public byte[] getICCProfileBytes(final ByteSource byteSource, final Map<String, Object> params) + public byte[] getICCProfileBytes(final ByteSource byteSource, final XbmImagingParameters params) throws ImageReadException, IOException { return null; } @@ -310,7 +308,7 @@ public class XbmImageParser extends ImageParser { @Override public final BufferedImage getBufferedImage(final ByteSource byteSource, - final Map<String, Object> params) throws ImageReadException, IOException { + final XbmImagingParameters params) throws ImageReadException, IOException { final XbmParseResult result = parseXbmHeader(byteSource); return readXbmImage(result.xbmHeader, result.cParser); } @@ -339,21 +337,8 @@ public class XbmImageParser extends ImageParser { } @Override - public void writeImage(final BufferedImage src, final OutputStream os, Map<String, Object> params) + public void writeImage(final BufferedImage src, final OutputStream os, XbmImagingParameters params) throws ImageWriteException, IOException { - // make copy of params; we'll clear keys as we consume them. - params = (params == null) ? new HashMap<>() : new HashMap<>(params); - - // clear format key. - if (params.containsKey(PARAM_KEY_FORMAT)) { - params.remove(PARAM_KEY_FORMAT); - } - - if (!params.isEmpty()) { - final Object firstKey = params.keySet().iterator().next(); - throw new ImageWriteException("Unknown parameter: " + firstKey); - } - final String name = randomName(); os.write(("#define " + name + "_width " + src.getWidth() + "\n").getBytes(StandardCharsets.US_ASCII)); diff --git a/src/main/java/org/apache/commons/imaging/formats/xbm/XbmImagingParameters.java b/src/main/java/org/apache/commons/imaging/formats/xbm/XbmImagingParameters.java new file mode 100644 index 0000000..a86d539 --- /dev/null +++ b/src/main/java/org/apache/commons/imaging/formats/xbm/XbmImagingParameters.java @@ -0,0 +1,26 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * under the License. + */ + +package org.apache.commons.imaging.formats.xbm; + +import org.apache.commons.imaging.ImagingParameters; + +/** + * Xbm format parameters. + * @since 1.0-alpha3 + */ +public class XbmImagingParameters extends ImagingParameters { + +}