1/*
2 * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package javax.imageio.plugins.jpeg;
27
28import javax.imageio.ImageReadParam;
29
30/**
31 * This class adds the ability to set JPEG quantization and Huffman
32 * tables when using the built-in JPEG reader plug-in.  An instance of
33 * this class will be returned from the
34 * {@code getDefaultImageReadParam} methods of the built-in JPEG
35 * {@code ImageReader}.
36 *
37 * <p> The sole purpose of these additions is to allow the
38 * specification of tables for use in decoding abbreviated streams.
39 * The built-in JPEG reader will also accept an ordinary
40 * {@code ImageReadParam}, which is sufficient for decoding
41 * non-abbreviated streams.
42 *
43 * <p> While tables for abbreviated streams are often obtained by
44 * first reading another abbreviated stream containing only the
45 * tables, in some applications the tables are fixed ahead of time.
46 * This class allows the tables to be specified directly from client
47 * code.  If no tables are specified either in the stream or in a
48 * {@code JPEGImageReadParam}, then the stream is presumed to use
49 * the "standard" visually lossless tables.  See {@link JPEGQTable JPEGQTable}
50 * and {@link JPEGHuffmanTable JPEGHuffmanTable} for more information
51 *  on the default tables.
52 *
53 * <p> The default {@code JPEGImageReadParam} returned by the
54 * {@code getDefaultReadParam} method of the builtin JPEG reader
55 * contains no tables.  Default tables may be obtained from the table
56 * classes {@link JPEGQTable JPEGQTable} and
57 * {@link JPEGHuffmanTable JPEGHuffmanTable}.
58 *
59 * <p> If a stream does contain tables, the tables given in a
60 * {@code JPEGImageReadParam} are ignored.  Furthermore, if the
61 * first image in a stream does contain tables and subsequent ones do
62 * not, then the tables given in the first image are used for all the
63 * abbreviated images.  Once tables have been read from a stream, they
64 * can be overridden only by tables subsequently read from the same
65 * stream.  In order to specify new tables, the {@link
66 * javax.imageio.ImageReader#setInput setInput} method of
67 * the reader must be called to change the stream.
68 *
69 * <p> Note that this class does not provide a means for obtaining the
70 * tables found in a stream.  These may be extracted from a stream by
71 * consulting the IIOMetadata object returned by the reader.
72 *
73 * <p>
74 * For more information about the operation of the built-in JPEG plug-ins,
75 * see the <A HREF="../../metadata/doc-files/jpeg_metadata.html">JPEG
76 * metadata format specification and usage notes</A>.
77 *
78 */
79public class JPEGImageReadParam extends ImageReadParam {
80
81    private JPEGQTable[] qTables = null;
82    private JPEGHuffmanTable[] DCHuffmanTables = null;
83    private JPEGHuffmanTable[] ACHuffmanTables = null;
84
85    /**
86     * Constructs a {@code JPEGImageReadParam}.
87     */
88    public JPEGImageReadParam() {
89        super();
90    }
91
92    /**
93     * Returns {@code true} if tables are currently set.
94     *
95     * @return {@code true} if tables are present.
96     */
97    public boolean areTablesSet() {
98        return (qTables != null);
99    }
100
101    /**
102     * Sets the quantization and Huffman tables to use in decoding
103     * abbreviated streams.  There may be a maximum of 4 tables of
104     * each type.  These tables are ignored once tables are
105     * encountered in the stream.  All arguments must be
106     * non-{@code null}.  The two arrays of Huffman tables must
107     * have the same number of elements.  The table specifiers in the
108     * frame and scan headers in the stream are assumed to be
109     * equivalent to indices into these arrays.  The argument arrays
110     * are copied by this method.
111     *
112     * @param qTables an array of quantization table objects.
113     * @param DCHuffmanTables an array of Huffman table objects.
114     * @param ACHuffmanTables an array of Huffman table objects.
115     *
116     * @exception IllegalArgumentException if any of the arguments
117     * is {@code null}, has more than 4 elements, or if the
118     * numbers of DC and AC tables differ.
119     *
120     * @see #unsetDecodeTables
121     */
122    public void setDecodeTables(JPEGQTable[] qTables,
123                                JPEGHuffmanTable[] DCHuffmanTables,
124                                JPEGHuffmanTable[] ACHuffmanTables) {
125        if ((qTables == null) ||
126            (DCHuffmanTables == null) ||
127            (ACHuffmanTables == null) ||
128            (qTables.length > 4) ||
129            (DCHuffmanTables.length > 4) ||
130            (ACHuffmanTables.length > 4) ||
131            (DCHuffmanTables.length != ACHuffmanTables.length)) {
132                throw new IllegalArgumentException
133                    ("Invalid JPEG table arrays");
134        }
135        this.qTables = qTables.clone();
136        this.DCHuffmanTables = DCHuffmanTables.clone();
137        this.ACHuffmanTables = ACHuffmanTables.clone();
138    }
139
140    /**
141     * Removes any quantization and Huffman tables that are currently
142     * set.
143     *
144     * @see #setDecodeTables
145     */
146    public void unsetDecodeTables() {
147        this.qTables = null;
148        this.DCHuffmanTables = null;
149        this.ACHuffmanTables = null;
150    }
151
152    /**
153     * Returns a copy of the array of quantization tables set on the
154     * most recent call to {@code setDecodeTables}, or
155     * {@code null} if tables are not currently set.
156     *
157     * @return an array of {@code JPEGQTable} objects, or
158     * {@code null}.
159     *
160     * @see #setDecodeTables
161     */
162    public JPEGQTable[] getQTables() {
163        return (qTables != null) ? qTables.clone() : null;
164    }
165
166    /**
167     * Returns a copy of the array of DC Huffman tables set on the
168     * most recent call to {@code setDecodeTables}, or
169     * {@code null} if tables are not currently set.
170     *
171     * @return an array of {@code JPEGHuffmanTable} objects, or
172     * {@code null}.
173     *
174     * @see #setDecodeTables
175     */
176    public JPEGHuffmanTable[] getDCHuffmanTables() {
177        return (DCHuffmanTables != null)
178            ? DCHuffmanTables.clone()
179            : null;
180    }
181
182    /**
183     * Returns a copy of the array of AC Huffman tables set on the
184     * most recent call to {@code setDecodeTables}, or
185     * {@code null} if tables are not currently set.
186     *
187     * @return an array of {@code JPEGHuffmanTable} objects, or
188     * {@code null}.
189     *
190     * @see #setDecodeTables
191     */
192    public JPEGHuffmanTable[] getACHuffmanTables() {
193        return (ACHuffmanTables != null)
194            ? ACHuffmanTables.clone()
195            : null;
196    }
197}
198