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