    001/*
    002 *  Licensed under the Apache License, Version 2.0 (the "License");
    003 *  you may not use this file except in compliance with the License.
    004 *  You may obtain a copy of the License at
    005 *
    006 *       http://www.apache.org/licenses/LICENSE-2.0
    007 *
    008 *  Unless required by applicable law or agreed to in writing, software
    009 *  distributed under the License is distributed on an "AS IS" BASIS,
    010 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    011 *  See the License for the specific language governing permissions and
    012 *  limitations under the License.
    013 *  under the License.
    014 */
    015
    016package org.apache.commons.imaging.formats.tiff;
    017
    018import org.apache.commons.imaging.common.XmpImagingParameters;
    019import org.apache.commons.imaging.formats.tiff.photometricinterpreters.AbstractPhotometricInterpreter;
    020import org.apache.commons.imaging.formats.tiff.write.TiffOutputSet;
    021
    022/**
    023 * TIFF format parameters.
    024 *
    025 * @since 1.0-alpha3
    026 */
    027public class TiffImagingParameters extends XmpImagingParameters<TiffImagingParameters> {
    028
    029    /**
    030     * Indicates whether to read embedded thumbnails or not. Only applies to read EXIF metadata from JPEG/JFIF files.
    031     *
    032     * <p>
    033     * Default value is {@code true}.
    034     * </p>
    035     */
    036    private boolean readThumbnails = true;
    037
    038    /**
    039     * User provided {@code TiffOutputSet} used to write into the image's metadata including standard directory and EXIF tags.
    040     */
    041    private TiffOutputSet tiffOutputSet;
    042
    043    /**
    044     * X-coordinate of a sub-image.
    045     */
    046    private int subImageX;
    047
    048    /**
    049     * Y-coordinate of a sub-image.
    050     */
    051    private int subImageY;
    052
    053    /**
    054     * Width of a sub-image.
    055     */
    056    private int subImageWidth;
    057
    058    /**
    059     * Height of a sub-image.
    060     */
    061    private int subImageHeight;
    062
    063    /**
    064     * Specifies that an application-specified photometric interpreter is to be used when reading TIFF files to convert raster data samples to RGB values for
    065     * the output image.
    066     *
    067     * <p>
    068     * The value supplied with this key should be a valid instance of a class that implements PhotometricInterpreter.
    069     * </p>
    070     */
    071    private AbstractPhotometricInterpreter customPhotometricInterpreter;
    072
    073    /**
    074     * TIFF compression algorithm, if any.
    075     */
    076    private Integer compression;
    077
    078    /**
    079     * 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
    080     * value is 8000.
    081     */
    082    private Integer lzwCompressionBlockSize;
    083
    084    /**
    085     * Used in write operations to indicate the desired T.4 options to use when using TIFF_COMPRESSION_CCITT_GROUP_3.
    086     *
    087     * <p>
    088     * 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
    089     * flags.
    090     * </p>
    091     */
    092    private Integer t4Options;
    093
    094    /**
    095     * Used in write operations to indicate the desired T.6 options to use when using TIFF_COMPRESSION_CCITT_GROUP_4.
    096     *
    097     * <p>
    098     * Valid values: any Integer containing either zero or TIFF_FLAG_T6_OPTIONS_UNCOMPRESSED_MODE.
    099     * </p>
    100     */
    101    private Integer t6Options;
    102
    103    /**
    104     * Clears settings for sub-image. Subsequent read operations will retrieve the entire image.
    105     */
    106    public void clearSubImage() {
    107        subImageWidth = 0;
    108        subImageHeight = 0;
    109    }
    110
    111    public Integer getCompression() {
    112        return compression;
    113    }
    114
    115    public AbstractPhotometricInterpreter getCustomPhotometricInterpreter() {
    116        return customPhotometricInterpreter;
    117    }
    118
    119    public Integer getLzwCompressionBlockSize() {
    120        return lzwCompressionBlockSize;
    121    }
    122
    123    /**
    124     * Gets the TIFF output set for writing TIFF files.
    125     *
    126     * @return if set, a valid instance; otherwise, a null reference.
    127     */
    128    public TiffOutputSet getOutputSet() {
    129        return tiffOutputSet;
    130    }
    131
    132    /**
    133     * Gets the height for a sub-image setting. For a sub-image setting to be meaningful, both the width and height must be set.
    134     *
    135     * @return if the sub-image feature is enabled, a value greater than zero; otherwise, zero.
    136     */
    137    public int getSubImageHeight() {
    138        return subImageHeight;
    139    }
    140
    141    /**
    142     * Gets the width for a sub-image setting. For a sub-image setting to be meaningful, both the width and height must be set.
    143     *
    144     * @return if the sub-image feature is enabled, a value greater than zero; otherwise, zero.
    145     */
    146    public int getSubImageWidth() {
    147        return subImageWidth;
    148    }
    149
    150    /**
    151     * Gets the X coordinate of a sub-image. This setting is meaningful only if a sub-image is set.
    152     *
    153     * @return a positive integer
    154     */
    155    public int getSubImageX() {
    156        return subImageX;
    157    }
    158
    159    /**
    160     * Gets the Y coordinate of a sub-image. This setting is meaningful only if a sub-image is set.
    161     *
    162     * @return a positive integer
    163     */
    164    public int getSubImageY() {
    165        return subImageY;
    166    }
    167
    168    public Integer getT4Options() {
    169        return t4Options;
    170    }
    171
    172    public Integer getT6Options() {
    173        return t6Options;
    174    }
    175
    176    public boolean isReadThumbnails() {
    177        return readThumbnails;
    178    }
    179
    180    /**
    181     * Indicates whether the application has set sub-image parameters.
    182     *
    183     * @return true if the sub-image parameters are set; otherwise, false.
    184     */
    185    public boolean isSubImageSet() {
    186        return subImageWidth > 0 && subImageHeight > 0;
    187    }
    188
    189    public TiffImagingParameters setCompression(final Integer compression) {
    190        this.compression = compression;
    191        return asThis();
    192    }
    193
    194    public TiffImagingParameters setCustomPhotometricInterpreter(final AbstractPhotometricInterpreter customPhotometricInterpreter) {
    195        this.customPhotometricInterpreter = customPhotometricInterpreter;
    196        return asThis();
    197    }
    198
    199    public TiffImagingParameters setLzwCompressionBlockSize(final Integer lzwCompressionBlockSize) {
    200        this.lzwCompressionBlockSize = lzwCompressionBlockSize;
    201        return asThis();
    202    }
    203
    204    /**
    205     * Sets the TIFF output set for writing TIFF files. An output set may contain various types of TiffDirectories including image directories, EXIF
    206     * directories, GPS-related directories, etc.
    207     *
    208     * @param tiffOutputSet A valid instance.
    209     * @return {@code this} instance.
    210     */
    211    public TiffImagingParameters setOutputSet(final TiffOutputSet tiffOutputSet) {
    212        this.tiffOutputSet = tiffOutputSet;
    213        return asThis();
    214    }
    215
    216    public TiffImagingParameters setReadThumbnails(final boolean readThumbnails) {
    217        this.readThumbnails = readThumbnails;
    218        return asThis();
    219    }
    220
    221    /**
    222     * Sets parameters for performing a partial read operation on an image. This method is useful for reducing memory and run-time overhead when accessing large
    223     * source images.
    224     * <p>
    225     * Note that the corner x and y coordinates must be positive integers (zero or greater). The width and height must be greater than zero.
    226     *
    227     * @param x      pixel coordinate of the upper-left corner of the source image, must be zero or greater.
    228     * @param y      pixel coordinate of the upper-left corner of the source image, must be zero or greater.
    229     * @param width  width of the image subset to be read, must be greater than zero.
    230     * @param height height of the image subset to be read, must be greater than zero.
    231     * @return {@code this} instance.
    232     */
    233    public TiffImagingParameters setSubImage(final int x, final int y, final int width, final int height) {
    234        if (x < 0 || y < 0) {
    235            throw new IllegalArgumentException("Invalid sub-image specification: negative x and y values not allowed");
    236        }
    237        if (width <= 0 || height <= 0) {
    238            throw new IllegalArgumentException("Invalid sub-image specification width and height must be greater than zero");
    239        }
    240        subImageX = x;
    241        subImageY = y;
    242        subImageWidth = width;
    243        subImageHeight = height;
    244        return asThis();
    245    }
    246
    247    public TiffImagingParameters setT4Options(final Integer t4Options) {
    248        this.t4Options = t4Options;
    249        return asThis();
    250    }
    251
    252    public TiffImagingParameters setT6Options(final Integer t6Options) {
    253        this.t6Options = t6Options;
    254        return asThis();
    255    }
    256
    257}