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