View Javadoc
1   /*
2    * Copyright (c) 2000, 2013, 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  
26  package javax.imageio.plugins.jpeg;
27  
28  import 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</code> methods of the built-in JPEG
35   * <code>ImageReader</code>.
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</code>, 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</code>, 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</code> returned by the
54   * <code>getDefaultReadParam</code> 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</code> 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   */
79  public 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</code>.
87       */
88      public JPEGImageReadParam() {
89          super();
90      }
91  
92      /**
93       * Returns <code>true</code> if tables are currently set.
94       *
95       * @return <code>true</code> 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</code>.  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</code>, 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 = (JPEGQTable[])qTables.clone();
136         this.DCHuffmanTables = (JPEGHuffmanTable[])DCHuffmanTables.clone();
137         this.ACHuffmanTables = (JPEGHuffmanTable[])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</code>, or
155      * <code>null</code> if tables are not currently set.
156      *
157      * @return an array of <code>JPEGQTable</code> objects, or
158      * <code>null</code>.
159      *
160      * @see #setDecodeTables
161      */
162     public JPEGQTable[] getQTables() {
163         return (qTables != null) ? (JPEGQTable[])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</code>, or
169      * <code>null</code> if tables are not currently set.
170      *
171      * @return an array of <code>JPEGHuffmanTable</code> objects, or
172      * <code>null</code>.
173      *
174      * @see #setDecodeTables
175      */
176     public JPEGHuffmanTable[] getDCHuffmanTables() {
177         return (DCHuffmanTables != null)
178             ? (JPEGHuffmanTable[])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</code>, or
185      * <code>null</code> if tables are not currently set.
186      *
187      * @return an array of <code>JPEGHuffmanTable</code> objects, or
188      * <code>null</code>.
189      *
190      * @see #setDecodeTables
191      */
192     public JPEGHuffmanTable[] getACHuffmanTables() {
193         return (ACHuffmanTables != null)
194             ? (JPEGHuffmanTable[])ACHuffmanTables.clone()
195             : null;
196     }
197 }