feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -0,0 +1,256 @@
/*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.imageio.plugins.jpeg;
import java.util.Arrays;
/**
* A class encapsulating a single JPEG Huffman table.
* Fields are provided for the "standard" tables taken
* from Annex K of the JPEG specification.
* These are the tables used as defaults.
* <p>
* For more information about the operation of the standard JPEG plug-in,
* see the <A HREF="../../metadata/doc-files/jpeg_metadata.html">JPEG
* metadata format specification and usage notes</A>
*/
public class JPEGHuffmanTable {
/* The data for the publically defined tables, as specified in ITU T.81
* JPEG specification section K3.3 and used in the IJG library.
*/
private static final short[] StdDCLuminanceLengths = {
0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
private static final short[] StdDCLuminanceValues = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b,
};
private static final short[] StdDCChrominanceLengths = {
0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
};
private static final short[] StdDCChrominanceValues = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b,
};
private static final short[] StdACLuminanceLengths = {
0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
};
private static final short[] StdACLuminanceValues = {
0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa,
};
private static final short[] StdACChrominanceLengths = {
0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
};
private static final short[] StdACChrominanceValues = {
0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa,
};
/**
* The standard DC luminance Huffman table.
*/
public static final JPEGHuffmanTable
StdDCLuminance = new JPEGHuffmanTable(StdDCLuminanceLengths,
StdDCLuminanceValues, false);
/**
* The standard DC chrominance Huffman table.
*/
public static final JPEGHuffmanTable
StdDCChrominance = new JPEGHuffmanTable(StdDCChrominanceLengths,
StdDCChrominanceValues, false);
/**
* The standard AC luminance Huffman table.
*/
public static final JPEGHuffmanTable
StdACLuminance = new JPEGHuffmanTable(StdACLuminanceLengths,
StdACLuminanceValues, false);
/**
* The standard AC chrominance Huffman table.
*/
public static final JPEGHuffmanTable
StdACChrominance = new JPEGHuffmanTable(StdACChrominanceLengths,
StdACChrominanceValues, false);
private short[] lengths;
private short[] values;
/**
* Creates a Huffman table and initializes it. The input arrays are copied.
* The arrays must describe a possible Huffman table.
* For example, 3 codes cannot be expressed with a single bit.
*
* @param lengths an array of {@code short}s where <code>lengths[k]</code>
* is equal to the number of values with corresponding codes of
* length <code>k + 1</code> bits.
* @param values an array of shorts containing the values in
* order of increasing code length.
* @throws IllegalArgumentException if <code>lengths</code> or
* <code>values</code> are null, the length of <code>lengths</code> is
* greater than 16, the length of <code>values</code> is greater than 256,
* if any value in <code>lengths</code> or <code>values</code> is less
* than zero, or if the arrays do not describe a valid Huffman table.
*/
public JPEGHuffmanTable(short[] lengths, short[] values) {
if (lengths == null || values == null ||
lengths.length == 0 || values.length == 0 ||
lengths.length > 16 || values.length > 256) {
throw new IllegalArgumentException("Illegal lengths or values");
}
for (int i = 0; i<lengths.length; i++) {
if (lengths[i] < 0) {
throw new IllegalArgumentException("lengths["+i+"] < 0");
}
}
for (int i = 0; i<values.length; i++) {
if (values[i] < 0) {
throw new IllegalArgumentException("values["+i+"] < 0");
}
}
this.lengths = Arrays.copyOf(lengths, lengths.length);
this.values = Arrays.copyOf(values, values.length);
validate();
}
private void validate() {
int sumOfLengths = 0;
for (int i=0; i<lengths.length; i++) {
sumOfLengths += lengths[i];
}
if (sumOfLengths != values.length) {
throw new IllegalArgumentException("lengths do not correspond " +
"to length of value table");
}
}
/* Internal version which avoids the overhead of copying and checking */
private JPEGHuffmanTable(short[] lengths, short[] values, boolean copy) {
if (copy) {
this.lengths = Arrays.copyOf(lengths, lengths.length);
this.values = Arrays.copyOf(values, values.length);
} else {
this.lengths = lengths;
this.values = values;
}
}
/**
* Returns an array of <code>short</code>s containing the number of values
* for each length in the Huffman table. The returned array is a copy.
*
* @return a <code>short</code> array where <code>array[k-1]</code>
* is equal to the number of values in the table of length <code>k</code>.
* @see #getValues
*/
public short[] getLengths() {
return Arrays.copyOf(lengths, lengths.length);
}
/**
* Returns an array of <code>short</code>s containing the values arranged
* by increasing length of their corresponding codes.
* The interpretation of the array is dependent on the values returned
* from <code>getLengths</code>. The returned array is a copy.
*
* @return a <code>short</code> array of values.
* @see #getLengths
*/
public short[] getValues() {
return Arrays.copyOf(values, values.length);
}
/**
* Returns a {@code String} representing this Huffman table.
* @return a {@code String} representing this Huffman table.
*/
public String toString() {
String ls = System.getProperty("line.separator", "\n");
StringBuilder sb = new StringBuilder("JPEGHuffmanTable");
sb.append(ls).append("lengths:");
for (int i=0; i<lengths.length; i++) {
sb.append(" ").append(lengths[i]);
}
sb.append(ls).append("values:");
for (int i=0; i<values.length; i++) {
sb.append(" ").append(values[i]);
}
return sb.toString();
}
}

View File

@@ -0,0 +1,197 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.imageio.plugins.jpeg;
import javax.imageio.ImageReadParam;
/**
* This class adds the ability to set JPEG quantization and Huffman
* tables when using the built-in JPEG reader plug-in. An instance of
* this class will be returned from the
* <code>getDefaultImageReadParam</code> methods of the built-in JPEG
* <code>ImageReader</code>.
*
* <p> The sole purpose of these additions is to allow the
* specification of tables for use in decoding abbreviated streams.
* The built-in JPEG reader will also accept an ordinary
* <code>ImageReadParam</code>, which is sufficient for decoding
* non-abbreviated streams.
*
* <p> While tables for abbreviated streams are often obtained by
* first reading another abbreviated stream containing only the
* tables, in some applications the tables are fixed ahead of time.
* This class allows the tables to be specified directly from client
* code. If no tables are specified either in the stream or in a
* <code>JPEGImageReadParam</code>, then the stream is presumed to use
* the "standard" visually lossless tables. See {@link JPEGQTable JPEGQTable}
* and {@link JPEGHuffmanTable JPEGHuffmanTable} for more information
* on the default tables.
*
* <p> The default <code>JPEGImageReadParam</code> returned by the
* <code>getDefaultReadParam</code> method of the builtin JPEG reader
* contains no tables. Default tables may be obtained from the table
* classes {@link JPEGQTable JPEGQTable} and
* {@link JPEGHuffmanTable JPEGHuffmanTable}.
*
* <p> If a stream does contain tables, the tables given in a
* <code>JPEGImageReadParam</code> are ignored. Furthermore, if the
* first image in a stream does contain tables and subsequent ones do
* not, then the tables given in the first image are used for all the
* abbreviated images. Once tables have been read from a stream, they
* can be overridden only by tables subsequently read from the same
* stream. In order to specify new tables, the {@link
* javax.imageio.ImageReader#setInput setInput} method of
* the reader must be called to change the stream.
*
* <p> Note that this class does not provide a means for obtaining the
* tables found in a stream. These may be extracted from a stream by
* consulting the IIOMetadata object returned by the reader.
*
* <p>
* For more information about the operation of the built-in JPEG plug-ins,
* see the <A HREF="../../metadata/doc-files/jpeg_metadata.html">JPEG
* metadata format specification and usage notes</A>.
*
*/
public class JPEGImageReadParam extends ImageReadParam {
private JPEGQTable[] qTables = null;
private JPEGHuffmanTable[] DCHuffmanTables = null;
private JPEGHuffmanTable[] ACHuffmanTables = null;
/**
* Constructs a <code>JPEGImageReadParam</code>.
*/
public JPEGImageReadParam() {
super();
}
/**
* Returns <code>true</code> if tables are currently set.
*
* @return <code>true</code> if tables are present.
*/
public boolean areTablesSet() {
return (qTables != null);
}
/**
* Sets the quantization and Huffman tables to use in decoding
* abbreviated streams. There may be a maximum of 4 tables of
* each type. These tables are ignored once tables are
* encountered in the stream. All arguments must be
* non-<code>null</code>. The two arrays of Huffman tables must
* have the same number of elements. The table specifiers in the
* frame and scan headers in the stream are assumed to be
* equivalent to indices into these arrays. The argument arrays
* are copied by this method.
*
* @param qTables an array of quantization table objects.
* @param DCHuffmanTables an array of Huffman table objects.
* @param ACHuffmanTables an array of Huffman table objects.
*
* @exception IllegalArgumentException if any of the arguments
* is <code>null</code>, has more than 4 elements, or if the
* numbers of DC and AC tables differ.
*
* @see #unsetDecodeTables
*/
public void setDecodeTables(JPEGQTable[] qTables,
JPEGHuffmanTable[] DCHuffmanTables,
JPEGHuffmanTable[] ACHuffmanTables) {
if ((qTables == null) ||
(DCHuffmanTables == null) ||
(ACHuffmanTables == null) ||
(qTables.length > 4) ||
(DCHuffmanTables.length > 4) ||
(ACHuffmanTables.length > 4) ||
(DCHuffmanTables.length != ACHuffmanTables.length)) {
throw new IllegalArgumentException
("Invalid JPEG table arrays");
}
this.qTables = (JPEGQTable[])qTables.clone();
this.DCHuffmanTables = (JPEGHuffmanTable[])DCHuffmanTables.clone();
this.ACHuffmanTables = (JPEGHuffmanTable[])ACHuffmanTables.clone();
}
/**
* Removes any quantization and Huffman tables that are currently
* set.
*
* @see #setDecodeTables
*/
public void unsetDecodeTables() {
this.qTables = null;
this.DCHuffmanTables = null;
this.ACHuffmanTables = null;
}
/**
* Returns a copy of the array of quantization tables set on the
* most recent call to <code>setDecodeTables</code>, or
* <code>null</code> if tables are not currently set.
*
* @return an array of <code>JPEGQTable</code> objects, or
* <code>null</code>.
*
* @see #setDecodeTables
*/
public JPEGQTable[] getQTables() {
return (qTables != null) ? (JPEGQTable[])qTables.clone() : null;
}
/**
* Returns a copy of the array of DC Huffman tables set on the
* most recent call to <code>setDecodeTables</code>, or
* <code>null</code> if tables are not currently set.
*
* @return an array of <code>JPEGHuffmanTable</code> objects, or
* <code>null</code>.
*
* @see #setDecodeTables
*/
public JPEGHuffmanTable[] getDCHuffmanTables() {
return (DCHuffmanTables != null)
? (JPEGHuffmanTable[])DCHuffmanTables.clone()
: null;
}
/**
* Returns a copy of the array of AC Huffman tables set on the
* most recent call to <code>setDecodeTables</code>, or
* <code>null</code> if tables are not currently set.
*
* @return an array of <code>JPEGHuffmanTable</code> objects, or
* <code>null</code>.
*
* @see #setDecodeTables
*/
public JPEGHuffmanTable[] getACHuffmanTables() {
return (ACHuffmanTables != null)
? (JPEGHuffmanTable[])ACHuffmanTables.clone()
: null;
}
}

View File

@@ -0,0 +1,320 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.imageio.plugins.jpeg;
import java.util.Locale;
import javax.imageio.ImageWriteParam;
import com.sun.imageio.plugins.jpeg.JPEG;
/**
* This class adds the ability to set JPEG quantization and Huffman
* tables when using the built-in JPEG writer plug-in, and to request that
* optimized Huffman tables be computed for an image. An instance of
* this class will be returned from the
* <code>getDefaultImageWriteParam</code> methods of the built-in JPEG
* <code>ImageWriter</code>.
* <p> The principal purpose of these additions is to allow the
* specification of tables to use in encoding abbreviated streams.
* The built-in JPEG writer will also accept an ordinary
* <code>ImageWriteParam</code>, in which case the writer will
* construct the necessary tables internally.
*
* <p> In either case, the quality setting in an <code>ImageWriteParam</code>
* has the same meaning as for the underlying library: 1.00 means a
* quantization table of all 1's, 0.75 means the "standard", visually
* lossless quantization table, and 0.00 means aquantization table of
* all 255's.
*
* <p> While tables for abbreviated streams are often specified by
* first writing an abbreviated stream containing only the tables, in
* some applications the tables are fixed ahead of time. This class
* allows the tables to be specified directly from client code.
*
* <p> Normally, the tables are specified in the
* <code>IIOMetadata</code> objects passed in to the writer, and any
* tables included in these objects are written to the stream.
* If no tables are specified in the metadata, then an abbreviated
* stream is written. If no tables are included in the metadata and
* no tables are specified in a <code>JPEGImageWriteParam</code>, then
* an abbreviated stream is encoded using the "standard" visually
* lossless tables. This class is necessary for specifying tables
* when an abbreviated stream must be written without writing any tables
* to a stream first. In order to use this class, the metadata object
* passed into the writer must contain no tables, and no stream metadata
* must be provided. See {@link JPEGQTable JPEGQTable} and
* {@link JPEGHuffmanTable JPEGHuffmanTable} for more
* information on the default tables.
*
* <p> The default <code>JPEGImageWriteParam</code> returned by the
* <code>getDefaultWriteParam</code> method of the writer contains no
* tables. Default tables are included in the default
* <code>IIOMetadata</code> objects returned by the writer.
*
* <p> If the metadata does contain tables, the tables given in a
* <code>JPEGImageWriteParam</code> are ignored. Furthermore, once a
* set of tables has been written, only tables in the metadata can
* override them for subsequent writes, whether to the same stream or
* a different one. In order to specify new tables using this class,
* the {@link javax.imageio.ImageWriter#reset reset}
* method of the writer must be called.
*
* <p>
* For more information about the operation of the built-in JPEG plug-ins,
* see the <A HREF="../../metadata/doc-files/jpeg_metadata.html">JPEG
* metadata format specification and usage notes</A>.
*
*/
public class JPEGImageWriteParam extends ImageWriteParam {
private JPEGQTable[] qTables = null;
private JPEGHuffmanTable[] DCHuffmanTables = null;
private JPEGHuffmanTable[] ACHuffmanTables = null;
private boolean optimizeHuffman = false;
private String[] compressionNames = {"JPEG"};
private float[] qualityVals = { 0.00F, 0.30F, 0.75F, 1.00F };
private String[] qualityDescs = {
"Low quality", // 0.00 -> 0.30
"Medium quality", // 0.30 -> 0.75
"Visually lossless" // 0.75 -> 1.00
};
/**
* Constructs a <code>JPEGImageWriteParam</code>. Tiling is not
* supported. Progressive encoding is supported. The default
* progressive mode is MODE_DISABLED. A single form of compression,
* named "JPEG", is supported. The default compression quality is
* 0.75.
*
* @param locale a <code>Locale</code> to be used by the
* superclass to localize compression type names and quality
* descriptions, or <code>null</code>.
*/
public JPEGImageWriteParam(Locale locale) {
super(locale);
this.canWriteProgressive = true;
this.progressiveMode = MODE_DISABLED;
this.canWriteCompressed = true;
this.compressionTypes = compressionNames;
this.compressionType = compressionTypes[0];
this.compressionQuality = JPEG.DEFAULT_QUALITY;
}
/**
* Removes any previous compression quality setting.
*
* <p> The default implementation resets the compression quality
* to <code>0.75F</code>.
*
* @exception IllegalStateException if the compression mode is not
* <code>MODE_EXPLICIT</code>.
*/
public void unsetCompression() {
if (getCompressionMode() != MODE_EXPLICIT) {
throw new IllegalStateException
("Compression mode not MODE_EXPLICIT!");
}
this.compressionQuality = JPEG.DEFAULT_QUALITY;
}
/**
* Returns <code>false</code> since the JPEG plug-in only supports
* lossy compression.
*
* @return <code>false</code>.
*
* @exception IllegalStateException if the compression mode is not
* <code>MODE_EXPLICIT</code>.
*/
public boolean isCompressionLossless() {
if (getCompressionMode() != MODE_EXPLICIT) {
throw new IllegalStateException
("Compression mode not MODE_EXPLICIT!");
}
return false;
}
public String[] getCompressionQualityDescriptions() {
if (getCompressionMode() != MODE_EXPLICIT) {
throw new IllegalStateException
("Compression mode not MODE_EXPLICIT!");
}
if ((getCompressionTypes() != null) &&
(getCompressionType() == null)) {
throw new IllegalStateException("No compression type set!");
}
return (String[])qualityDescs.clone();
}
public float[] getCompressionQualityValues() {
if (getCompressionMode() != MODE_EXPLICIT) {
throw new IllegalStateException
("Compression mode not MODE_EXPLICIT!");
}
if ((getCompressionTypes() != null) &&
(getCompressionType() == null)) {
throw new IllegalStateException("No compression type set!");
}
return (float[])qualityVals.clone();
}
/**
* Returns <code>true</code> if tables are currently set.
*
* @return <code>true</code> if tables are present.
*/
public boolean areTablesSet() {
return (qTables != null);
}
/**
* Sets the quantization and Huffman tables to use in encoding
* abbreviated streams. There may be a maximum of 4 tables of
* each type. These tables are ignored if tables are specified in
* the metadata. All arguments must be non-<code>null</code>.
* The two arrays of Huffman tables must have the same number of
* elements. The table specifiers in the frame and scan headers
* in the metadata are assumed to be equivalent to indices into
* these arrays. The argument arrays are copied by this method.
*
* @param qTables An array of quantization table objects.
* @param DCHuffmanTables An array of Huffman table objects.
* @param ACHuffmanTables An array of Huffman table objects.
*
* @exception IllegalArgumentException if any of the arguments
* is <code>null</code> or has more than 4 elements, or if the
* numbers of DC and AC tables differ.
*
* @see #unsetEncodeTables
*/
public void setEncodeTables(JPEGQTable[] qTables,
JPEGHuffmanTable[] DCHuffmanTables,
JPEGHuffmanTable[] ACHuffmanTables) {
if ((qTables == null) ||
(DCHuffmanTables == null) ||
(ACHuffmanTables == null) ||
(qTables.length > 4) ||
(DCHuffmanTables.length > 4) ||
(ACHuffmanTables.length > 4) ||
(DCHuffmanTables.length != ACHuffmanTables.length)) {
throw new IllegalArgumentException("Invalid JPEG table arrays");
}
this.qTables = (JPEGQTable[])qTables.clone();
this.DCHuffmanTables = (JPEGHuffmanTable[])DCHuffmanTables.clone();
this.ACHuffmanTables = (JPEGHuffmanTable[])ACHuffmanTables.clone();
}
/**
* Removes any quantization and Huffman tables that are currently
* set.
*
* @see #setEncodeTables
*/
public void unsetEncodeTables() {
this.qTables = null;
this.DCHuffmanTables = null;
this.ACHuffmanTables = null;
}
/**
* Returns a copy of the array of quantization tables set on the
* most recent call to <code>setEncodeTables</code>, or
* <code>null</code> if tables are not currently set.
*
* @return an array of <code>JPEGQTable</code> objects, or
* <code>null</code>.
*
* @see #setEncodeTables
*/
public JPEGQTable[] getQTables() {
return (qTables != null) ? (JPEGQTable[])qTables.clone() : null;
}
/**
* Returns a copy of the array of DC Huffman tables set on the
* most recent call to <code>setEncodeTables</code>, or
* <code>null</code> if tables are not currently set.
*
* @return an array of <code>JPEGHuffmanTable</code> objects, or
* <code>null</code>.
*
* @see #setEncodeTables
*/
public JPEGHuffmanTable[] getDCHuffmanTables() {
return (DCHuffmanTables != null)
? (JPEGHuffmanTable[])DCHuffmanTables.clone()
: null;
}
/**
* Returns a copy of the array of AC Huffman tables set on the
* most recent call to <code>setEncodeTables</code>, or
* <code>null</code> if tables are not currently set.
*
* @return an array of <code>JPEGHuffmanTable</code> objects, or
* <code>null</code>.
*
* @see #setEncodeTables
*/
public JPEGHuffmanTable[] getACHuffmanTables() {
return (ACHuffmanTables != null)
? (JPEGHuffmanTable[])ACHuffmanTables.clone()
: null;
}
/**
* Tells the writer to generate optimized Huffman tables
* for the image as part of the writing process. The
* default is <code>false</code>. If this flag is set
* to <code>true</code>, it overrides any tables specified
* in the metadata. Note that this means that any image
* written with this flag set to <code>true</code> will
* always contain Huffman tables.
*
* @param optimize A boolean indicating whether to generate
* optimized Huffman tables when writing.
*
* @see #getOptimizeHuffmanTables
*/
public void setOptimizeHuffmanTables(boolean optimize) {
optimizeHuffman = optimize;
}
/**
* Returns the value passed into the most recent call
* to <code>setOptimizeHuffmanTables</code>, or
* <code>false</code> if <code>setOptimizeHuffmanTables</code>
* has never been called.
*
* @return <code>true</code> if the writer will generate optimized
* Huffman tables.
*
* @see #setOptimizeHuffmanTables
*/
public boolean getOptimizeHuffmanTables() {
return optimizeHuffman;
}
}

View File

@@ -0,0 +1,210 @@
/*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.imageio.plugins.jpeg;
import java.util.Arrays;
/**
* A class encapsulating a single JPEG quantization table.
* The elements appear in natural order (as opposed to zig-zag order).
* Static variables are provided for the "standard" tables taken from
* Annex K of the JPEG specification, as well as the default tables
* conventionally used for visually lossless encoding.
* <p>
* For more information about the operation of the standard JPEG plug-in,
* see the <A HREF="../../metadata/doc-files/jpeg_metadata.html">JPEG
* metadata format specification and usage notes</A>
*/
public class JPEGQTable {
private static final int[] k1 = {
16, 11, 10, 16, 24, 40, 51, 61,
12, 12, 14, 19, 26, 58, 60, 55,
14, 13, 16, 24, 40, 57, 69, 56,
14, 17, 22, 29, 51, 87, 80, 62,
18, 22, 37, 56, 68, 109, 103, 77,
24, 35, 55, 64, 81, 104, 113, 92,
49, 64, 78, 87, 103, 121, 120, 101,
72, 92, 95, 98, 112, 100, 103, 99,
};
private static final int[] k1div2 = {
8, 6, 5, 8, 12, 20, 26, 31,
6, 6, 7, 10, 13, 29, 30, 28,
7, 7, 8, 12, 20, 29, 35, 28,
7, 9, 11, 15, 26, 44, 40, 31,
9, 11, 19, 28, 34, 55, 52, 39,
12, 18, 28, 32, 41, 52, 57, 46,
25, 32, 39, 44, 52, 61, 60, 51,
36, 46, 48, 49, 56, 50, 52, 50,
};
private static final int[] k2 = {
17, 18, 24, 47, 99, 99, 99, 99,
18, 21, 26, 66, 99, 99, 99, 99,
24, 26, 56, 99, 99, 99, 99, 99,
47, 66, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
};
private static final int[] k2div2 = {
9, 9, 12, 24, 50, 50, 50, 50,
9, 11, 13, 33, 50, 50, 50, 50,
12, 13, 28, 50, 50, 50, 50, 50,
24, 33, 50, 50, 50, 50, 50, 50,
50, 50, 50, 50, 50, 50, 50, 50,
50, 50, 50, 50, 50, 50, 50, 50,
50, 50, 50, 50, 50, 50, 50, 50,
50, 50, 50, 50, 50, 50, 50, 50,
};
/**
* The sample luminance quantization table given in the JPEG
* specification, table K.1. According to the specification,
* these values produce "good" quality output.
* @see #K1Div2Luminance
*/
public static final JPEGQTable
K1Luminance = new JPEGQTable(k1, false);
/**
* The sample luminance quantization table given in the JPEG
* specification, table K.1, with all elements divided by 2.
* According to the specification, these values produce "very good"
* quality output. This is the table usually used for "visually lossless"
* encoding, and is the default luminance table used if the default
* tables and quality settings are used.
* @see #K1Luminance
*/
public static final JPEGQTable
K1Div2Luminance = new JPEGQTable(k1div2, false);
/**
* The sample chrominance quantization table given in the JPEG
* specification, table K.2. According to the specification,
* these values produce "good" quality output.
* @see #K2Div2Chrominance
*/
public static final JPEGQTable K2Chrominance =
new JPEGQTable(k2, false);
/**
* The sample chrominance quantization table given in the JPEG
* specification, table K.1, with all elements divided by 2.
* According to the specification, these values produce "very good"
* quality output. This is the table usually used for "visually lossless"
* encoding, and is the default chrominance table used if the default
* tables and quality settings are used.
* @see #K2Chrominance
*/
public static final JPEGQTable K2Div2Chrominance =
new JPEGQTable(k2div2, false);
private int[] qTable;
private JPEGQTable(int[] table, boolean copy) {
qTable = (copy) ? Arrays.copyOf(table, table.length) : table;
}
/**
* Constructs a quantization table from the argument, which must
* contain 64 elements in natural order (not zig-zag order).
* A copy is made of the the input array.
* @param table the quantization table, as an <code>int</code> array.
* @throws IllegalArgumentException if <code>table</code> is
* <code>null</code> or <code>table.length</code> is not equal to 64.
*/
public JPEGQTable(int[] table) {
if (table == null) {
throw new IllegalArgumentException("table must not be null.");
}
if (table.length != 64) {
throw new IllegalArgumentException("table.length != 64");
}
qTable = Arrays.copyOf(table, table.length);
}
/**
* Returns a copy of the current quantization table as an array
* of {@code int}s in natural (not zig-zag) order.
* @return A copy of the current quantization table.
*/
public int[] getTable() {
return Arrays.copyOf(qTable, qTable.length);
}
/**
* Returns a new quantization table where the values are multiplied
* by <code>scaleFactor</code> and then clamped to the range 1..32767
* (or to 1..255 if <code>forceBaseline</code> is true).
* <p>
* Values of <code>scaleFactor</code> less than 1 tend to improve
* the quality level of the table, and values greater than 1.0
* degrade the quality level of the table.
* @param scaleFactor multiplication factor for the table.
* @param forceBaseline if <code>true</code>,
* the values will be clamped to the range 1..255
* @return a new quantization table that is a linear multiple
* of the current table.
*/
public JPEGQTable getScaledInstance(float scaleFactor,
boolean forceBaseline) {
int max = (forceBaseline) ? 255 : 32767;
int[] scaledTable = new int[qTable.length];
for (int i=0; i<qTable.length; i++) {
int sv = (int)((qTable[i] * scaleFactor)+0.5f);
if (sv < 1) {
sv = 1;
}
if (sv > max) {
sv = max;
}
scaledTable[i] = sv;
}
return new JPEGQTable(scaledTable);
}
/**
* Returns a {@code String} representing this quantization table.
* @return a {@code String} representing this quantization table.
*/
public String toString() {
String ls = System.getProperty("line.separator", "\n");
StringBuilder sb = new StringBuilder("JPEGQTable:"+ls);
for (int i=0; i < qTable.length; i++) {
if (i % 8 == 0) {
sb.append('\t');
}
sb.append(qTable[i]);
sb.append(((i % 8) == 7) ? ls : ' ');
}
return sb.toString();
}
}