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 *
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 PhotometricInterpreter 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 PhotometricInterpreter 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 PhotometricInterpreter 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 this
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 this
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}