1 /* 2 * Copyright (c) 2000, 2001, 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 }