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 }