1 /* JPEGImageEncoder.java -- JPEG encoder implementation
2 Copyright (C) 2011 Red Hat
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */
18 package sun.awt.image.codec;
19 
20 import java.awt.color.ColorSpace;
21 import java.awt.image.BufferedImage;
22 import java.awt.image.ColorModel;
23 import java.awt.image.Raster;
24 import java.io.IOException;
25 import java.io.OutputStream;
26 import java.util.ArrayList;
27 import java.util.Iterator;
28 
29 import javax.imageio.IIOImage;
30 import javax.imageio.ImageIO;
31 import javax.imageio.ImageWriteParam;
32 import javax.imageio.ImageWriter;
33 import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
34 import javax.imageio.stream.MemoryCacheImageOutputStream;
35 
36 import com.sun.image.codec.jpeg.ImageFormatException;
37 import com.sun.image.codec.jpeg.JPEGCodec;
38 import com.sun.image.codec.jpeg.JPEGDecodeParam;
39 import com.sun.image.codec.jpeg.JPEGEncodeParam;
40 import com.sun.image.codec.jpeg.JPEGImageEncoder;
41 import com.sun.imageio.plugins.jpeg.JPEG;
42 
43 /**
44  * This class provides the implementation for encoding JPEG images.
45  *
46  */
47 public class JPEGImageEncoderImpl implements JPEGImageEncoder {
48     private static final String JPGMime = "image/jpeg";
49 
50     private ImageWriter JPGWriter;
51     private JPEGEncodeParam param;
52     private OutputStream out;
53 
JPEGImageEncoderImpl(OutputStream os)54     public JPEGImageEncoderImpl(OutputStream os) {
55         this(os, null);
56     }
57 
JPEGImageEncoderImpl(OutputStream out, JPEGEncodeParam newParam)58     public JPEGImageEncoderImpl(OutputStream out, JPEGEncodeParam newParam) {
59         this.out = out;
60         setJPEGEncodeParam(newParam);
61 
62         Iterator<ImageWriter> JPGWriterIter = ImageIO
63                 .getImageWritersByMIMEType(JPGMime);
64         if (JPGWriterIter.hasNext()) {
65             JPGWriter = JPGWriterIter.next();
66         }
67 
68         JPGWriter.setOutput(new MemoryCacheImageOutputStream(out));
69     }
70 
getDefaultJPEGEncodeParam(BufferedImage bi)71     public JPEGEncodeParam getDefaultJPEGEncodeParam(BufferedImage bi)
72             throws ImageFormatException {
73         return JPEGCodec.getDefaultJPEGEncodeParam(bi);
74     }
75 
getDefaultJPEGEncodeParam(int numBands, int colorID)76     public JPEGEncodeParam getDefaultJPEGEncodeParam(int numBands, int colorID)
77             throws ImageFormatException {
78         return JPEGCodec.getDefaultJPEGEncodeParam(numBands, colorID);
79     }
80 
getDefaultJPEGEncodeParam(JPEGDecodeParam d)81     public JPEGEncodeParam getDefaultJPEGEncodeParam(JPEGDecodeParam d)
82             throws ImageFormatException {
83         return JPEGCodec.getDefaultJPEGEncodeParam(d);
84     }
85 
getDefaultJPEGEncodeParam(Raster ras, int colorID)86     public JPEGEncodeParam getDefaultJPEGEncodeParam(Raster ras, int colorID)
87             throws ImageFormatException {
88         return JPEGCodec.getDefaultJPEGEncodeParam(ras, colorID);
89     }
90 
getJPEGEncodeParam()91     public JPEGEncodeParam getJPEGEncodeParam() throws ImageFormatException {
92         if (param == null)
93             return null;
94         return (JPEGEncodeParam) param.clone();
95     }
96 
setJPEGEncodeParam(JPEGEncodeParam p)97     public void setJPEGEncodeParam(JPEGEncodeParam p) {
98         param = p;
99     }
100 
getOutputStream()101     public OutputStream getOutputStream() {
102         return out;
103     }
104 
encode(IIOImage img)105     private void encode(IIOImage img) throws IOException, ImageFormatException {
106         if (JPGWriter == null)
107             throw new ImageFormatException(
108                     "JPEG writer code not implemented in ImageIO");
109 
110         JPEGImageWriteParam jiwp = new JPEGImageWriteParam(null);
111         ;
112         jiwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
113         if (param != null && param instanceof JPEGParam) {
114             JPEGParam jp = (JPEGParam) param;
115             jiwp.setCompressionQuality(jp.getQuality());
116         } else {
117             jiwp.setCompressionQuality(JPEG.DEFAULT_QUALITY);
118         }
119 
120         JPGWriter.write(null, img, jiwp);
121     }
122 
encode(BufferedImage bi, JPEGEncodeParam writeParam)123     public void encode(BufferedImage bi, JPEGEncodeParam writeParam)
124             throws IOException, ImageFormatException {
125         setJPEGEncodeParam(writeParam);
126         encode(new IIOImage(bi, new ArrayList<BufferedImage>(), null));
127     }
128 
encode(Raster rs, JPEGEncodeParam writeParam)129     public void encode(Raster rs, JPEGEncodeParam writeParam)
130             throws IOException, ImageFormatException {
131         setJPEGEncodeParam(writeParam);
132         encode(new IIOImage(rs, new ArrayList<BufferedImage>(), null));
133     }
134 
encode(BufferedImage bi)135     public void encode(BufferedImage bi) throws IOException,
136             ImageFormatException {
137         encode(bi, null);
138     }
139 
encode(Raster rs)140     public void encode(Raster rs) throws IOException, ImageFormatException {
141         encode(rs, null);
142     }
143 
144     @Override
getDefaultColorId(ColorModel cm)145     public int getDefaultColorId(ColorModel cm) {
146         ColorSpace cs = cm.getColorSpace();
147         int type = cs.getType();
148         int id = -1;
149         switch (type) {
150             case ColorSpace.TYPE_GRAY:
151                 id = JPEGEncodeParam.COLOR_ID_GRAY;
152                 break;
153 
154             case ColorSpace.TYPE_RGB:
155                 id = cm.hasAlpha() ? JPEGEncodeParam.COLOR_ID_RGBA
156                         : JPEGEncodeParam.COLOR_ID_RGB;
157 
158             case ColorSpace.TYPE_YCbCr:
159                 try {
160                     if (cs == ColorSpace.getInstance(ColorSpace.CS_PYCC)) {
161                         id = cm.hasAlpha() ? JPEGEncodeParam.COLOR_ID_PYCCA
162                                 : JPEGEncodeParam.COLOR_ID_PYCC;
163                     }
164                 } catch (IllegalArgumentException e) {
165                     /* We know it isn't PYCC type, nothing to handle */
166                 }
167                 if (id == -1) {
168                     id = cm.hasAlpha() ? JPEGEncodeParam.COLOR_ID_YCbCrA
169                             : JPEGEncodeParam.COLOR_ID_YCbCr;
170                 }
171                 break;
172 
173             case ColorSpace.TYPE_CMYK:
174                 id = JPEGEncodeParam.COLOR_ID_CMYK;
175                 break;
176 
177             default:
178                 id = JPEGEncodeParam.COLOR_ID_UNKNOWN;
179         }
180 
181         return id;
182     }
183 }
184