001    /* ===========================================================
002     * JFreeChart : a free chart library for the Java(tm) platform
003     * ===========================================================
004     *
005     * (C) Copyright 2000-2008, by Object Refinery Limited and Contributors.
006     *
007     * Project Info:  http://www.jfree.org/jfreechart/index.html
008     *
009     * This library is free software; you can redistribute it and/or modify it
010     * under the terms of the GNU Lesser General Public License as published by
011     * the Free Software Foundation; either version 2.1 of the License, or
012     * (at your option) any later version.
013     *
014     * This library is distributed in the hope that it will be useful, but
015     * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
016     * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
017     * License for more details.
018     *
019     * You should have received a copy of the GNU Lesser General Public
020     * License along with this library; if not, write to the Free Software
021     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
022     * USA.
023     *
024     * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
025     * in the United States and other countries.]
026     *
027     * --------------------------
028     * SunJPEGEncoderAdapter.java
029     * --------------------------
030     * (C) Copyright 2004-2008, by Richard Atkinson and Contributors.
031     *
032     * Original Author:  Richard Atkinson;
033     * Contributor(s):   David Gilbert (for Object Refinery Limited);
034     *
035     * Changes
036     * -------
037     * 01-Aug-2004 : Initial version (RA);
038     * 01-Nov-2005 : To remove the dependency on non-supported APIs, use ImageIO
039     *               instead of com.sun.image.codec.jpeg.JPEGImageEncoder - this
040     *               adapter will only be available on JDK 1.4 or later (DG);
041     * ------------- JFREECHART 1.0.x ---------------------------------------------
042     * 20-Jul-2006 : Pass quality setting to ImageIO. Also increased default
043     *               value to 0.95 (DG);
044     *
045     */
046    
047    package org.jfree.chart.encoders;
048    
049    import java.awt.image.BufferedImage;
050    import java.io.ByteArrayOutputStream;
051    import java.io.IOException;
052    import java.io.OutputStream;
053    import java.util.Iterator;
054    
055    import javax.imageio.IIOImage;
056    import javax.imageio.ImageIO;
057    import javax.imageio.ImageWriteParam;
058    import javax.imageio.ImageWriter;
059    import javax.imageio.stream.ImageOutputStream;
060    
061    /**
062     * Adapter class for the Sun JPEG Encoder.  The {@link ImageEncoderFactory}
063     * will only return a reference to this class by default if the library has
064     * been compiled under a JDK 1.4+ and is being run using a JRE 1.4+.
065     */
066    public class SunJPEGEncoderAdapter implements ImageEncoder {
067    
068        /** The quality setting (in the range 0.0f to 1.0f). */
069        private float quality = 0.95f;
070    
071        /**
072         * Creates a new <code>SunJPEGEncoderAdapter</code> instance.
073         */
074        public SunJPEGEncoderAdapter() {
075        }
076    
077        /**
078         * Returns the quality of the image encoding, which is a number in the
079         * range 0.0f to 1.0f (higher values give better quality output, but larger
080         * file sizes).  The default value is 0.95f.
081         *
082         * @return A float representing the quality, in the range 0.0f to 1.0f.
083         *
084         * @see #setQuality(float)
085         */
086        public float getQuality() {
087            return this.quality;
088        }
089    
090        /**
091         * Set the quality of the image encoding.
092         *
093         * @param quality  A float representing the quality (in the range 0.0f to
094         *     1.0f).
095         *
096         * @see #getQuality()
097         */
098        public void setQuality(float quality) {
099            if (quality < 0.0f || quality > 1.0f) {
100                throw new IllegalArgumentException(
101                        "The 'quality' must be in the range 0.0f to 1.0f");
102            }
103            this.quality = quality;
104        }
105    
106        /**
107         * Returns <code>false</code> always, indicating that this encoder does not
108         * encode alpha transparency.
109         *
110         * @return <code>false</code>.
111         */
112        public boolean isEncodingAlpha() {
113            return false;
114        }
115    
116        /**
117         * Set whether the encoder should encode alpha transparency (this is not
118         * supported for JPEG, so this method does nothing).
119         *
120         * @param encodingAlpha  ignored.
121         */
122        public void setEncodingAlpha(boolean encodingAlpha) {
123            //  No op
124        }
125    
126        /**
127         * Encodes an image in JPEG format.
128         *
129         * @param bufferedImage  the image to be encoded (<code>null</code> not
130         *     permitted).
131         *
132         * @return The byte[] that is the encoded image.
133         *
134         * @throws IOException if there is an I/O problem.
135         * @throws NullPointerException if <code>bufferedImage</code> is
136         *     <code>null</code>.
137         */
138        public byte[] encode(BufferedImage bufferedImage) throws IOException {
139            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
140            encode(bufferedImage, outputStream);
141            return outputStream.toByteArray();
142        }
143    
144        /**
145         * Encodes an image in JPEG format and writes it to an output stream.
146         *
147         * @param bufferedImage  the image to be encoded (<code>null</code> not
148         *     permitted).
149         * @param outputStream  the OutputStream to write the encoded image to
150         *     (<code>null</code> not permitted).
151         *
152         * @throws IOException if there is an I/O problem.
153         * @throws NullPointerException if <code>bufferedImage</code> is
154         *     <code>null</code>.
155         */
156        public void encode(BufferedImage bufferedImage, OutputStream outputStream)
157                throws IOException {
158            if (bufferedImage == null) {
159                throw new IllegalArgumentException("Null 'image' argument.");
160            }
161            if (outputStream == null) {
162                throw new IllegalArgumentException("Null 'outputStream' argument.");
163            }
164            Iterator iterator = ImageIO.getImageWritersByFormatName("jpeg");
165            ImageWriter writer = (ImageWriter) iterator.next();
166            ImageWriteParam p = writer.getDefaultWriteParam();
167            p.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
168            p.setCompressionQuality(this.quality);
169            ImageOutputStream ios = ImageIO.createImageOutputStream(outputStream);
170            writer.setOutput(ios);
171            writer.write(null, new IIOImage(bufferedImage, null, null), p);
172            ios.flush();
173            writer.dispose();
174            ios.close();
175        }
176    
177    }