Path: blob/master/src/java.desktop/share/classes/javax/imageio/plugins/jpeg/JPEGImageWriteParam.java
41159 views
/*1* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.imageio.plugins.jpeg;2627import java.util.Locale;28import javax.imageio.ImageWriteParam;2930import com.sun.imageio.plugins.jpeg.JPEG;3132/**33* This class adds the ability to set JPEG quantization and Huffman34* tables when using the built-in JPEG writer plug-in, and to request that35* optimized Huffman tables be computed for an image. An instance of36* this class will be returned from the37* {@code getDefaultImageWriteParam} methods of the built-in JPEG38* {@code ImageWriter}.3940* <p> The principal purpose of these additions is to allow the41* specification of tables to use in encoding abbreviated streams.42* The built-in JPEG writer will also accept an ordinary43* {@code ImageWriteParam}, in which case the writer will44* construct the necessary tables internally.45*46* <p> In either case, the quality setting in an {@code ImageWriteParam}47* has the same meaning as for the underlying library: 1.00 means a48* quantization table of all 1's, 0.75 means the "standard", visually49* lossless quantization table, and 0.00 means aquantization table of50* all 255's.51*52* <p> While tables for abbreviated streams are often specified by53* first writing an abbreviated stream containing only the tables, in54* some applications the tables are fixed ahead of time. This class55* allows the tables to be specified directly from client code.56*57* <p> Normally, the tables are specified in the58* {@code IIOMetadata} objects passed in to the writer, and any59* tables included in these objects are written to the stream.60* If no tables are specified in the metadata, then an abbreviated61* stream is written. If no tables are included in the metadata and62* no tables are specified in a {@code JPEGImageWriteParam}, then63* an abbreviated stream is encoded using the "standard" visually64* lossless tables. This class is necessary for specifying tables65* when an abbreviated stream must be written without writing any tables66* to a stream first. In order to use this class, the metadata object67* passed into the writer must contain no tables, and no stream metadata68* must be provided. See {@link JPEGQTable JPEGQTable} and69* {@link JPEGHuffmanTable JPEGHuffmanTable} for more70* information on the default tables.71*72* <p> The default {@code JPEGImageWriteParam} returned by the73* {@code getDefaultWriteParam} method of the writer contains no74* tables. Default tables are included in the default75* {@code IIOMetadata} objects returned by the writer.76*77* <p> If the metadata does contain tables, the tables given in a78* {@code JPEGImageWriteParam} are ignored. Furthermore, once a79* set of tables has been written, only tables in the metadata can80* override them for subsequent writes, whether to the same stream or81* a different one. In order to specify new tables using this class,82* the {@link javax.imageio.ImageWriter#reset reset}83* method of the writer must be called.84*85* <p>86* For more information about the operation of the built-in JPEG plug-ins,87* see the <A HREF="../../metadata/doc-files/jpeg_metadata.html">JPEG88* metadata format specification and usage notes</A>.89*90*/91public class JPEGImageWriteParam extends ImageWriteParam {9293private JPEGQTable[] qTables = null;94private JPEGHuffmanTable[] DCHuffmanTables = null;95private JPEGHuffmanTable[] ACHuffmanTables = null;96private boolean optimizeHuffman = false;97private String[] compressionNames = {"JPEG"};98private float[] qualityVals = { 0.00F, 0.30F, 0.75F, 1.00F };99private String[] qualityDescs = {100"Low quality", // 0.00 -> 0.30101"Medium quality", // 0.30 -> 0.75102"Visually lossless" // 0.75 -> 1.00103};104105/**106* Constructs a {@code JPEGImageWriteParam}. Tiling is not107* supported. Progressive encoding is supported. The default108* progressive mode is MODE_DISABLED. A single form of compression,109* named "JPEG", is supported. The default compression quality is110* 0.75.111*112* @param locale a {@code Locale} to be used by the113* superclass to localize compression type names and quality114* descriptions, or {@code null}.115*/116public JPEGImageWriteParam(Locale locale) {117super(locale);118this.canWriteProgressive = true;119this.progressiveMode = MODE_DISABLED;120this.canWriteCompressed = true;121this.compressionTypes = compressionNames;122this.compressionType = compressionTypes[0];123this.compressionQuality = JPEG.DEFAULT_QUALITY;124}125126/**127* Removes any previous compression quality setting.128*129* <p> The default implementation resets the compression quality130* to {@code 0.75F}.131*132* @exception IllegalStateException if the compression mode is not133* {@code MODE_EXPLICIT}.134*/135public void unsetCompression() {136if (getCompressionMode() != MODE_EXPLICIT) {137throw new IllegalStateException138("Compression mode not MODE_EXPLICIT!");139}140this.compressionQuality = JPEG.DEFAULT_QUALITY;141}142143/**144* Returns {@code false} since the JPEG plug-in only supports145* lossy compression.146*147* @return {@code false}.148*149* @exception IllegalStateException if the compression mode is not150* {@code MODE_EXPLICIT}.151*/152public boolean isCompressionLossless() {153if (getCompressionMode() != MODE_EXPLICIT) {154throw new IllegalStateException155("Compression mode not MODE_EXPLICIT!");156}157return false;158}159160public String[] getCompressionQualityDescriptions() {161if (getCompressionMode() != MODE_EXPLICIT) {162throw new IllegalStateException163("Compression mode not MODE_EXPLICIT!");164}165if ((getCompressionTypes() != null) &&166(getCompressionType() == null)) {167throw new IllegalStateException("No compression type set!");168}169return qualityDescs.clone();170}171172public float[] getCompressionQualityValues() {173if (getCompressionMode() != MODE_EXPLICIT) {174throw new IllegalStateException175("Compression mode not MODE_EXPLICIT!");176}177if ((getCompressionTypes() != null) &&178(getCompressionType() == null)) {179throw new IllegalStateException("No compression type set!");180}181return qualityVals.clone();182}183/**184* Returns {@code true} if tables are currently set.185*186* @return {@code true} if tables are present.187*/188public boolean areTablesSet() {189return (qTables != null);190}191192/**193* Sets the quantization and Huffman tables to use in encoding194* abbreviated streams. There may be a maximum of 4 tables of195* each type. These tables are ignored if tables are specified in196* the metadata. All arguments must be non-{@code null}.197* The two arrays of Huffman tables must have the same number of198* elements. The table specifiers in the frame and scan headers199* in the metadata are assumed to be equivalent to indices into200* these arrays. The argument arrays are copied by this method.201*202* @param qTables An array of quantization table objects.203* @param DCHuffmanTables An array of Huffman table objects.204* @param ACHuffmanTables An array of Huffman table objects.205*206* @exception IllegalArgumentException if any of the arguments207* is {@code null} or has more than 4 elements, or if the208* numbers of DC and AC tables differ.209*210* @see #unsetEncodeTables211*/212public void setEncodeTables(JPEGQTable[] qTables,213JPEGHuffmanTable[] DCHuffmanTables,214JPEGHuffmanTable[] ACHuffmanTables) {215if ((qTables == null) ||216(DCHuffmanTables == null) ||217(ACHuffmanTables == null) ||218(qTables.length > 4) ||219(DCHuffmanTables.length > 4) ||220(ACHuffmanTables.length > 4) ||221(DCHuffmanTables.length != ACHuffmanTables.length)) {222throw new IllegalArgumentException("Invalid JPEG table arrays");223}224this.qTables = qTables.clone();225this.DCHuffmanTables = DCHuffmanTables.clone();226this.ACHuffmanTables = ACHuffmanTables.clone();227}228229/**230* Removes any quantization and Huffman tables that are currently231* set.232*233* @see #setEncodeTables234*/235public void unsetEncodeTables() {236this.qTables = null;237this.DCHuffmanTables = null;238this.ACHuffmanTables = null;239}240241/**242* Returns a copy of the array of quantization tables set on the243* most recent call to {@code setEncodeTables}, or244* {@code null} if tables are not currently set.245*246* @return an array of {@code JPEGQTable} objects, or247* {@code null}.248*249* @see #setEncodeTables250*/251public JPEGQTable[] getQTables() {252return (qTables != null) ? qTables.clone() : null;253}254255/**256* Returns a copy of the array of DC Huffman tables set on the257* most recent call to {@code setEncodeTables}, or258* {@code null} if tables are not currently set.259*260* @return an array of {@code JPEGHuffmanTable} objects, or261* {@code null}.262*263* @see #setEncodeTables264*/265public JPEGHuffmanTable[] getDCHuffmanTables() {266return (DCHuffmanTables != null)267? DCHuffmanTables.clone()268: null;269}270271/**272* Returns a copy of the array of AC Huffman tables set on the273* most recent call to {@code setEncodeTables}, or274* {@code null} if tables are not currently set.275*276* @return an array of {@code JPEGHuffmanTable} objects, or277* {@code null}.278*279* @see #setEncodeTables280*/281public JPEGHuffmanTable[] getACHuffmanTables() {282return (ACHuffmanTables != null)283? ACHuffmanTables.clone()284: null;285}286287/**288* Tells the writer to generate optimized Huffman tables289* for the image as part of the writing process. The290* default is {@code false}. If this flag is set291* to {@code true}, it overrides any tables specified292* in the metadata. Note that this means that any image293* written with this flag set to {@code true} will294* always contain Huffman tables.295*296* @param optimize A boolean indicating whether to generate297* optimized Huffman tables when writing.298*299* @see #getOptimizeHuffmanTables300*/301public void setOptimizeHuffmanTables(boolean optimize) {302optimizeHuffman = optimize;303}304305/**306* Returns the value passed into the most recent call307* to {@code setOptimizeHuffmanTables}, or308* {@code false} if {@code setOptimizeHuffmanTables}309* has never been called.310*311* @return {@code true} if the writer will generate optimized312* Huffman tables.313*314* @see #setOptimizeHuffmanTables315*/316public boolean getOptimizeHuffmanTables() {317return optimizeHuffman;318}319}320321322