author | bae |
Sat, 23 May 2009 08:35:37 +0400 | |
changeset 3009 | de653b2cab31 |
parent 2381 | 0afc5d868c46 |
child 5506 | 202f599c92aa |
permissions | -rw-r--r-- |
2 | 1 |
/* |
2 |
* Copyright 2000-2002 Sun Microsystems, Inc. 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. Sun designates this |
|
8 |
* particular file as subject to the "Classpath" exception as provided |
|
9 |
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
|
22 |
* CA 95054 USA or visit www.sun.com if you need additional information or |
|
23 |
* have any questions. |
|
24 |
*/ |
|
25 |
||
26 |
package com.sun.imageio.plugins.jpeg; |
|
27 |
||
28 |
import javax.imageio.metadata.IIOMetadataFormatImpl; |
|
29 |
import javax.imageio.ImageTypeSpecifier; |
|
30 |
import javax.imageio.plugins.jpeg.JPEGQTable; |
|
31 |
import javax.imageio.plugins.jpeg.JPEGHuffmanTable; |
|
32 |
||
33 |
import java.awt.image.ColorModel; |
|
34 |
import java.awt.image.BufferedImage; |
|
35 |
import java.awt.image.DataBuffer; |
|
36 |
import java.awt.color.ColorSpace; |
|
37 |
import java.awt.color.ICC_ColorSpace; |
|
38 |
||
39 |
/** |
|
40 |
* A class containing JPEG-related constants, definitions, and |
|
41 |
* static methods. This class and its constants must be public so that |
|
42 |
* <code>JPEGImageWriteParam</code> can see it. |
|
43 |
*/ |
|
44 |
public class JPEG { |
|
45 |
||
46 |
// List of all the JPEG markers (pre-JPEG2000) |
|
47 |
||
48 |
/** For temporary use in arithmetic coding */ |
|
49 |
public static final int TEM = 0x01; |
|
50 |
||
51 |
// Codes 0x02 - 0xBF are reserved |
|
52 |
||
53 |
// SOF markers for Nondifferential Huffman coding |
|
54 |
/** Baseline DCT */ |
|
55 |
public static final int SOF0 = 0xC0; |
|
56 |
/** Extended Sequential DCT */ |
|
57 |
public static final int SOF1 = 0xC1; |
|
58 |
/** Progressive DCT */ |
|
59 |
public static final int SOF2 = 0xC2; |
|
60 |
/** Lossless Sequential */ |
|
61 |
public static final int SOF3 = 0xC3; |
|
62 |
||
63 |
/** Define Huffman Tables */ |
|
64 |
public static final int DHT = 0xC4; |
|
65 |
||
66 |
// SOF markers for Differential Huffman coding |
|
67 |
/** Differential Sequential DCT */ |
|
68 |
public static final int SOF5 = 0xC5; |
|
69 |
/** Differential Progressive DCT */ |
|
70 |
public static final int SOF6 = 0xC6; |
|
71 |
/** Differential Lossless */ |
|
72 |
public static final int SOF7 = 0xC7; |
|
73 |
||
74 |
/** Reserved for JPEG extensions */ |
|
75 |
public static final int JPG = 0xC8; |
|
76 |
||
77 |
// SOF markers for Nondifferential arithmetic coding |
|
78 |
/** Extended Sequential DCT, Arithmetic coding */ |
|
79 |
public static final int SOF9 = 0xC9; |
|
80 |
/** Progressive DCT, Arithmetic coding */ |
|
81 |
public static final int SOF10 = 0xCA; |
|
82 |
/** Lossless Sequential, Arithmetic coding */ |
|
83 |
public static final int SOF11 = 0xCB; |
|
84 |
||
85 |
/** Define Arithmetic conditioning tables */ |
|
86 |
public static final int DAC = 0xCC; |
|
87 |
||
88 |
// SOF markers for Differential arithmetic coding |
|
89 |
/** Differential Sequential DCT, Arithmetic coding */ |
|
90 |
public static final int SOF13 = 0xCD; |
|
91 |
/** Differential Progressive DCT, Arithmetic coding */ |
|
92 |
public static final int SOF14 = 0xCE; |
|
93 |
/** Differential Lossless, Arithmetic coding */ |
|
94 |
public static final int SOF15 = 0xCF; |
|
95 |
||
96 |
// Restart Markers |
|
97 |
public static final int RST0 = 0xD0; |
|
98 |
public static final int RST1 = 0xD1; |
|
99 |
public static final int RST2 = 0xD2; |
|
100 |
public static final int RST3 = 0xD3; |
|
101 |
public static final int RST4 = 0xD4; |
|
102 |
public static final int RST5 = 0xD5; |
|
103 |
public static final int RST6 = 0xD6; |
|
104 |
public static final int RST7 = 0xD7; |
|
105 |
/** Number of restart markers */ |
|
106 |
public static final int RESTART_RANGE = 8; |
|
107 |
||
108 |
/** Start of Image */ |
|
109 |
public static final int SOI = 0xD8; |
|
110 |
/** End of Image */ |
|
111 |
public static final int EOI = 0xD9; |
|
112 |
/** Start of Scan */ |
|
113 |
public static final int SOS = 0xDA; |
|
114 |
||
115 |
/** Define Quantisation Tables */ |
|
116 |
public static final int DQT = 0xDB; |
|
117 |
||
118 |
/** Define Number of lines */ |
|
119 |
public static final int DNL = 0xDC; |
|
120 |
||
121 |
/** Define Restart Interval */ |
|
122 |
public static final int DRI = 0xDD; |
|
123 |
||
124 |
/** Define Heirarchical progression */ |
|
125 |
public static final int DHP = 0xDE; |
|
126 |
||
127 |
/** Expand reference image(s) */ |
|
128 |
public static final int EXP = 0xDF; |
|
129 |
||
130 |
// Application markers |
|
131 |
/** APP0 used by JFIF */ |
|
132 |
public static final int APP0 = 0xE0; |
|
133 |
public static final int APP1 = 0xE1; |
|
134 |
public static final int APP2 = 0xE2; |
|
135 |
public static final int APP3 = 0xE3; |
|
136 |
public static final int APP4 = 0xE4; |
|
137 |
public static final int APP5 = 0xE5; |
|
138 |
public static final int APP6 = 0xE6; |
|
139 |
public static final int APP7 = 0xE7; |
|
140 |
public static final int APP8 = 0xE8; |
|
141 |
public static final int APP9 = 0xE9; |
|
142 |
public static final int APP10 = 0xEA; |
|
143 |
public static final int APP11 = 0xEB; |
|
144 |
public static final int APP12 = 0xEC; |
|
145 |
public static final int APP13 = 0xED; |
|
146 |
/** APP14 used by Adobe */ |
|
147 |
public static final int APP14 = 0xEE; |
|
148 |
public static final int APP15 = 0xEF; |
|
149 |
||
150 |
// codes 0xF0 to 0xFD are reserved |
|
151 |
||
152 |
/** Comment marker */ |
|
153 |
public static final int COM = 0xFE; |
|
154 |
||
155 |
// JFIF Resolution units |
|
156 |
/** The X and Y units simply indicate the aspect ratio of the pixels. */ |
|
157 |
public static final int DENSITY_UNIT_ASPECT_RATIO = 0; |
|
158 |
/** Pixel density is in pixels per inch. */ |
|
159 |
public static final int DENSITY_UNIT_DOTS_INCH = 1; |
|
160 |
/** Pixel density is in pixels per centemeter. */ |
|
161 |
public static final int DENSITY_UNIT_DOTS_CM = 2; |
|
162 |
/** The max known value for DENSITY_UNIT */ |
|
163 |
public static final int NUM_DENSITY_UNIT = 3; |
|
164 |
||
165 |
// Adobe transform values |
|
166 |
public static final int ADOBE_IMPOSSIBLE = -1; |
|
167 |
public static final int ADOBE_UNKNOWN = 0; |
|
168 |
public static final int ADOBE_YCC = 1; |
|
169 |
public static final int ADOBE_YCCK = 2; |
|
170 |
||
171 |
// Spi initialization stuff |
|
172 |
public static final String vendor = "Sun Microsystems, Inc."; |
|
173 |
public static final String version = "0.5"; |
|
174 |
// Names of the formats we can read or write |
|
175 |
public static final String [] names = {"JPEG", "jpeg", "JPG", "jpg"}; |
|
176 |
public static final String [] suffixes = {"jpg", "jpeg"}; |
|
177 |
public static final String [] MIMETypes = {"image/jpeg"}; |
|
178 |
public static final String nativeImageMetadataFormatName = |
|
179 |
"javax_imageio_jpeg_image_1.0"; |
|
180 |
public static final String nativeImageMetadataFormatClassName = |
|
181 |
"com.sun.imageio.plugins.jpeg.JPEGImageMetadataFormat"; |
|
182 |
public static final String nativeStreamMetadataFormatName = |
|
183 |
"javax_imageio_jpeg_stream_1.0"; |
|
184 |
public static final String nativeStreamMetadataFormatClassName = |
|
185 |
"com.sun.imageio.plugins.jpeg.JPEGStreamMetadataFormat"; |
|
186 |
||
187 |
// IJG Color codes. |
|
188 |
public static final int JCS_UNKNOWN = 0; // error/unspecified |
|
189 |
public static final int JCS_GRAYSCALE = 1; // monochrome |
|
190 |
public static final int JCS_RGB = 2; // red/green/blue |
|
191 |
public static final int JCS_YCbCr = 3; // Y/Cb/Cr (also known as YUV) |
|
192 |
public static final int JCS_CMYK = 4; // C/M/Y/K |
|
193 |
public static final int JCS_YCC = 5; // PhotoYCC |
|
194 |
public static final int JCS_RGBA = 6; // RGB-Alpha |
|
195 |
public static final int JCS_YCbCrA = 7; // Y/Cb/Cr/Alpha |
|
196 |
// 8 and 9 were old "Legacy" codes which the old code never identified |
|
197 |
// on reading anyway. Support for writing them is being dropped, too. |
|
198 |
public static final int JCS_YCCA = 10; // PhotoYCC-Alpha |
|
199 |
public static final int JCS_YCCK = 11; // Y/Cb/Cr/K |
|
200 |
||
201 |
public static final int NUM_JCS_CODES = JCS_YCCK+1; |
|
202 |
||
203 |
/** IJG can handle up to 4-channel JPEGs */ |
|
204 |
public static final int [] [] bandOffsets = {{0}, |
|
205 |
{0, 1}, |
|
206 |
{0, 1, 2}, |
|
207 |
{0, 1, 2, 3}}; |
|
208 |
||
209 |
public static final int [] bOffsRGB = { 2, 1, 0 }; |
|
210 |
||
2381
0afc5d868c46
6631559: Registration of ImageIO plugins should not cause loading of jpeg.dlli and cmm.dll
bae
parents:
2
diff
changeset
|
211 |
/* These are kept in the inner class to avoid static initialization |
0afc5d868c46
6631559: Registration of ImageIO plugins should not cause loading of jpeg.dlli and cmm.dll
bae
parents:
2
diff
changeset
|
212 |
* of the CMM class until someone actually needs it. |
0afc5d868c46
6631559: Registration of ImageIO plugins should not cause loading of jpeg.dlli and cmm.dll
bae
parents:
2
diff
changeset
|
213 |
* (e.g. do not init CMM on the request for jpeg mime types) |
0afc5d868c46
6631559: Registration of ImageIO plugins should not cause loading of jpeg.dlli and cmm.dll
bae
parents:
2
diff
changeset
|
214 |
*/ |
0afc5d868c46
6631559: Registration of ImageIO plugins should not cause loading of jpeg.dlli and cmm.dll
bae
parents:
2
diff
changeset
|
215 |
public static class JCS { |
0afc5d868c46
6631559: Registration of ImageIO plugins should not cause loading of jpeg.dlli and cmm.dll
bae
parents:
2
diff
changeset
|
216 |
public static final ColorSpace sRGB = |
0afc5d868c46
6631559: Registration of ImageIO plugins should not cause loading of jpeg.dlli and cmm.dll
bae
parents:
2
diff
changeset
|
217 |
ColorSpace.getInstance(ColorSpace.CS_sRGB); |
3009
de653b2cab31
4893408: JPEGReader throws IllegalArgException when setting the destination to BYTE_GRAY
bae
parents:
2381
diff
changeset
|
218 |
|
de653b2cab31
4893408: JPEGReader throws IllegalArgException when setting the destination to BYTE_GRAY
bae
parents:
2381
diff
changeset
|
219 |
private static ColorSpace YCC = null; |
de653b2cab31
4893408: JPEGReader throws IllegalArgException when setting the destination to BYTE_GRAY
bae
parents:
2381
diff
changeset
|
220 |
private static boolean yccInited = false; |
2 | 221 |
|
3009
de653b2cab31
4893408: JPEGReader throws IllegalArgException when setting the destination to BYTE_GRAY
bae
parents:
2381
diff
changeset
|
222 |
public static ColorSpace getYCC() { |
de653b2cab31
4893408: JPEGReader throws IllegalArgException when setting the destination to BYTE_GRAY
bae
parents:
2381
diff
changeset
|
223 |
if (!yccInited) { |
de653b2cab31
4893408: JPEGReader throws IllegalArgException when setting the destination to BYTE_GRAY
bae
parents:
2381
diff
changeset
|
224 |
try { |
de653b2cab31
4893408: JPEGReader throws IllegalArgException when setting the destination to BYTE_GRAY
bae
parents:
2381
diff
changeset
|
225 |
YCC = ColorSpace.getInstance(ColorSpace.CS_PYCC); |
de653b2cab31
4893408: JPEGReader throws IllegalArgException when setting the destination to BYTE_GRAY
bae
parents:
2381
diff
changeset
|
226 |
} catch (IllegalArgumentException e) { |
de653b2cab31
4893408: JPEGReader throws IllegalArgException when setting the destination to BYTE_GRAY
bae
parents:
2381
diff
changeset
|
227 |
// PYCC.pf may not always be installed |
de653b2cab31
4893408: JPEGReader throws IllegalArgException when setting the destination to BYTE_GRAY
bae
parents:
2381
diff
changeset
|
228 |
} finally { |
de653b2cab31
4893408: JPEGReader throws IllegalArgException when setting the destination to BYTE_GRAY
bae
parents:
2381
diff
changeset
|
229 |
yccInited = true; |
de653b2cab31
4893408: JPEGReader throws IllegalArgException when setting the destination to BYTE_GRAY
bae
parents:
2381
diff
changeset
|
230 |
} |
2381
0afc5d868c46
6631559: Registration of ImageIO plugins should not cause loading of jpeg.dlli and cmm.dll
bae
parents:
2
diff
changeset
|
231 |
} |
3009
de653b2cab31
4893408: JPEGReader throws IllegalArgException when setting the destination to BYTE_GRAY
bae
parents:
2381
diff
changeset
|
232 |
return YCC; |
2 | 233 |
} |
234 |
} |
|
235 |
||
236 |
// Default value for ImageWriteParam |
|
237 |
public static final float DEFAULT_QUALITY = 0.75F; |
|
238 |
||
239 |
/** |
|
240 |
* Returns <code>true</code> if the given <code>ColorSpace</code> |
|
241 |
* object is an instance of ICC_ColorSpace but is not one of the |
|
242 |
* standard <code>ColorSpaces</code> returned by |
|
243 |
* <code>ColorSpace.getInstance()</code>. |
|
244 |
*/ |
|
245 |
static boolean isNonStandardICC(ColorSpace cs) { |
|
246 |
boolean retval = false; |
|
247 |
if ((cs instanceof ICC_ColorSpace) |
|
248 |
&& (!cs.isCS_sRGB()) |
|
249 |
&& (!cs.equals(ColorSpace.getInstance(ColorSpace.CS_CIEXYZ))) |
|
250 |
&& (!cs.equals(ColorSpace.getInstance(ColorSpace.CS_GRAY))) |
|
251 |
&& (!cs.equals(ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB))) |
|
252 |
&& (!cs.equals(ColorSpace.getInstance(ColorSpace.CS_PYCC))) |
|
253 |
) { |
|
254 |
retval = true; |
|
255 |
} |
|
256 |
return retval; |
|
257 |
} |
|
258 |
||
259 |
||
260 |
/** |
|
261 |
* Returns <code>true</code> if the given imageType can be used |
|
262 |
* in a JFIF file. If <code>input</code> is true, then the |
|
263 |
* image type is considered before colorspace conversion. |
|
264 |
*/ |
|
265 |
static boolean isJFIFcompliant(ImageTypeSpecifier imageType, |
|
266 |
boolean input) { |
|
267 |
ColorModel cm = imageType.getColorModel(); |
|
268 |
// Can't have alpha |
|
269 |
if (cm.hasAlpha()) { |
|
270 |
return false; |
|
271 |
} |
|
272 |
// Gray is OK, always |
|
273 |
int numComponents = imageType.getNumComponents(); |
|
274 |
if (numComponents == 1) { |
|
275 |
return true; |
|
276 |
} |
|
277 |
||
278 |
// If it isn't gray, it must have 3 channels |
|
279 |
if (numComponents != 3) { |
|
280 |
return false; |
|
281 |
} |
|
282 |
||
283 |
if (input) { |
|
284 |
// Must be RGB |
|
285 |
if (cm.getColorSpace().getType() == ColorSpace.TYPE_RGB) { |
|
286 |
return true; |
|
287 |
} |
|
288 |
} else { |
|
289 |
// Must be YCbCr |
|
290 |
if (cm.getColorSpace().getType() == ColorSpace.TYPE_YCbCr) { |
|
291 |
return true; |
|
292 |
} |
|
293 |
} |
|
294 |
||
295 |
return false; |
|
296 |
} |
|
297 |
||
298 |
/** |
|
299 |
* Given an image type, return the Adobe transform corresponding to |
|
300 |
* that type, or ADOBE_IMPOSSIBLE if the image type is incompatible |
|
301 |
* with an Adobe marker segment. If <code>input</code> is true, then |
|
302 |
* the image type is considered before colorspace conversion. |
|
303 |
*/ |
|
304 |
static int transformForType(ImageTypeSpecifier imageType, boolean input) { |
|
305 |
int retval = ADOBE_IMPOSSIBLE; |
|
306 |
ColorModel cm = imageType.getColorModel(); |
|
307 |
switch (cm.getColorSpace().getType()) { |
|
308 |
case ColorSpace.TYPE_GRAY: |
|
309 |
retval = ADOBE_UNKNOWN; |
|
310 |
break; |
|
311 |
case ColorSpace.TYPE_RGB: |
|
312 |
retval = input ? ADOBE_YCC : ADOBE_UNKNOWN; |
|
313 |
break; |
|
314 |
case ColorSpace.TYPE_YCbCr: |
|
315 |
retval = ADOBE_YCC; |
|
316 |
break; |
|
317 |
case ColorSpace.TYPE_CMYK: |
|
318 |
retval = input ? ADOBE_YCCK : ADOBE_IMPOSSIBLE; |
|
319 |
} |
|
320 |
return retval; |
|
321 |
} |
|
322 |
||
323 |
/** |
|
324 |
* Converts an ImageWriteParam (i.e. IJG) non-linear quality value |
|
325 |
* to a float suitable for passing to JPEGQTable.getScaledInstance(). |
|
326 |
*/ |
|
327 |
static float convertToLinearQuality(float quality) { |
|
328 |
// The following is converted from the IJG code. |
|
329 |
if (quality <= 0.0F) { |
|
330 |
quality = 0.01F; |
|
331 |
} |
|
332 |
||
333 |
if (quality > 1.00F) { |
|
334 |
quality = 1.00F; |
|
335 |
} |
|
336 |
||
337 |
if (quality < 0.5F) { |
|
338 |
quality = 0.5F / quality; |
|
339 |
} else { |
|
340 |
quality = 2.0F - (quality * 2.0F); |
|
341 |
} |
|
342 |
||
343 |
return quality; |
|
344 |
} |
|
345 |
||
346 |
/** |
|
347 |
* Return an array of default, visually lossless quantization tables. |
|
348 |
*/ |
|
349 |
static JPEGQTable [] getDefaultQTables() { |
|
350 |
JPEGQTable [] qTables = new JPEGQTable[2]; |
|
351 |
qTables[0] = JPEGQTable.K1Div2Luminance; |
|
352 |
qTables[1] = JPEGQTable.K2Div2Chrominance; |
|
353 |
return qTables; |
|
354 |
} |
|
355 |
||
356 |
/** |
|
357 |
* Return an array of default Huffman tables. |
|
358 |
*/ |
|
359 |
static JPEGHuffmanTable [] getDefaultHuffmanTables(boolean wantDC) { |
|
360 |
JPEGHuffmanTable [] tables = new JPEGHuffmanTable[2]; |
|
361 |
if (wantDC) { |
|
362 |
tables[0] = JPEGHuffmanTable.StdDCLuminance; |
|
363 |
tables[1] = JPEGHuffmanTable.StdDCChrominance; |
|
364 |
} else { |
|
365 |
tables[0] = JPEGHuffmanTable.StdACLuminance; |
|
366 |
tables[1] = JPEGHuffmanTable.StdACChrominance; |
|
367 |
} |
|
368 |
return tables; |
|
369 |
} |
|
370 |
||
371 |
} |