| /* |
| * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package com.sun.imageio.plugins.jpeg; |
| |
| import javax.imageio.ImageTypeSpecifier; |
| import javax.imageio.plugins.jpeg.JPEGQTable; |
| import javax.imageio.plugins.jpeg.JPEGHuffmanTable; |
| |
| import java.awt.image.ColorModel; |
| import java.awt.color.ColorSpace; |
| import java.awt.color.ICC_ColorSpace; |
| |
| /** |
| * A class containing JPEG-related constants, definitions, and |
| * static methods. This class and its constants must be public so that |
| * <code>JPEGImageWriteParam</code> can see it. |
| */ |
| public class JPEG { |
| |
| // List of all the JPEG markers (pre-JPEG2000) |
| |
| /** For temporary use in arithmetic coding */ |
| public static final int TEM = 0x01; |
| |
| // Codes 0x02 - 0xBF are reserved |
| |
| // SOF markers for Nondifferential Huffman coding |
| /** Baseline DCT */ |
| public static final int SOF0 = 0xC0; |
| /** Extended Sequential DCT */ |
| public static final int SOF1 = 0xC1; |
| /** Progressive DCT */ |
| public static final int SOF2 = 0xC2; |
| /** Lossless Sequential */ |
| public static final int SOF3 = 0xC3; |
| |
| /** Define Huffman Tables */ |
| public static final int DHT = 0xC4; |
| |
| // SOF markers for Differential Huffman coding |
| /** Differential Sequential DCT */ |
| public static final int SOF5 = 0xC5; |
| /** Differential Progressive DCT */ |
| public static final int SOF6 = 0xC6; |
| /** Differential Lossless */ |
| public static final int SOF7 = 0xC7; |
| |
| /** Reserved for JPEG extensions */ |
| public static final int JPG = 0xC8; |
| |
| // SOF markers for Nondifferential arithmetic coding |
| /** Extended Sequential DCT, Arithmetic coding */ |
| public static final int SOF9 = 0xC9; |
| /** Progressive DCT, Arithmetic coding */ |
| public static final int SOF10 = 0xCA; |
| /** Lossless Sequential, Arithmetic coding */ |
| public static final int SOF11 = 0xCB; |
| |
| /** Define Arithmetic conditioning tables */ |
| public static final int DAC = 0xCC; |
| |
| // SOF markers for Differential arithmetic coding |
| /** Differential Sequential DCT, Arithmetic coding */ |
| public static final int SOF13 = 0xCD; |
| /** Differential Progressive DCT, Arithmetic coding */ |
| public static final int SOF14 = 0xCE; |
| /** Differential Lossless, Arithmetic coding */ |
| public static final int SOF15 = 0xCF; |
| |
| // Restart Markers |
| public static final int RST0 = 0xD0; |
| public static final int RST1 = 0xD1; |
| public static final int RST2 = 0xD2; |
| public static final int RST3 = 0xD3; |
| public static final int RST4 = 0xD4; |
| public static final int RST5 = 0xD5; |
| public static final int RST6 = 0xD6; |
| public static final int RST7 = 0xD7; |
| /** Number of restart markers */ |
| public static final int RESTART_RANGE = 8; |
| |
| /** Start of Image */ |
| public static final int SOI = 0xD8; |
| /** End of Image */ |
| public static final int EOI = 0xD9; |
| /** Start of Scan */ |
| public static final int SOS = 0xDA; |
| |
| /** Define Quantisation Tables */ |
| public static final int DQT = 0xDB; |
| |
| /** Define Number of lines */ |
| public static final int DNL = 0xDC; |
| |
| /** Define Restart Interval */ |
| public static final int DRI = 0xDD; |
| |
| /** Define Heirarchical progression */ |
| public static final int DHP = 0xDE; |
| |
| /** Expand reference image(s) */ |
| public static final int EXP = 0xDF; |
| |
| // Application markers |
| /** APP0 used by JFIF */ |
| public static final int APP0 = 0xE0; |
| public static final int APP1 = 0xE1; |
| public static final int APP2 = 0xE2; |
| public static final int APP3 = 0xE3; |
| public static final int APP4 = 0xE4; |
| public static final int APP5 = 0xE5; |
| public static final int APP6 = 0xE6; |
| public static final int APP7 = 0xE7; |
| public static final int APP8 = 0xE8; |
| public static final int APP9 = 0xE9; |
| public static final int APP10 = 0xEA; |
| public static final int APP11 = 0xEB; |
| public static final int APP12 = 0xEC; |
| public static final int APP13 = 0xED; |
| /** APP14 used by Adobe */ |
| public static final int APP14 = 0xEE; |
| public static final int APP15 = 0xEF; |
| |
| // codes 0xF0 to 0xFD are reserved |
| |
| /** Comment marker */ |
| public static final int COM = 0xFE; |
| |
| // JFIF Resolution units |
| /** The X and Y units simply indicate the aspect ratio of the pixels. */ |
| public static final int DENSITY_UNIT_ASPECT_RATIO = 0; |
| /** Pixel density is in pixels per inch. */ |
| public static final int DENSITY_UNIT_DOTS_INCH = 1; |
| /** Pixel density is in pixels per centemeter. */ |
| public static final int DENSITY_UNIT_DOTS_CM = 2; |
| /** The max known value for DENSITY_UNIT */ |
| public static final int NUM_DENSITY_UNIT = 3; |
| |
| // Adobe transform values |
| public static final int ADOBE_IMPOSSIBLE = -1; |
| public static final int ADOBE_UNKNOWN = 0; |
| public static final int ADOBE_YCC = 1; |
| public static final int ADOBE_YCCK = 2; |
| |
| // Spi initialization stuff |
| public static final String vendor = "Oracle Corporation"; |
| public static final String version = "0.5"; |
| // Names of the formats we can read or write |
| static final String [] names = {"JPEG", "jpeg", "JPG", "jpg"}; |
| static final String [] suffixes = {"jpg", "jpeg"}; |
| static final String [] MIMETypes = {"image/jpeg"}; |
| public static final String nativeImageMetadataFormatName = |
| "javax_imageio_jpeg_image_1.0"; |
| public static final String nativeImageMetadataFormatClassName = |
| "com.sun.imageio.plugins.jpeg.JPEGImageMetadataFormat"; |
| public static final String nativeStreamMetadataFormatName = |
| "javax_imageio_jpeg_stream_1.0"; |
| public static final String nativeStreamMetadataFormatClassName = |
| "com.sun.imageio.plugins.jpeg.JPEGStreamMetadataFormat"; |
| |
| // IJG Color codes. |
| public static final int JCS_UNKNOWN = 0; // error/unspecified |
| public static final int JCS_GRAYSCALE = 1; // monochrome |
| public static final int JCS_RGB = 2; // red/green/blue |
| public static final int JCS_YCbCr = 3; // Y/Cb/Cr (also known as YUV) |
| public static final int JCS_CMYK = 4; // C/M/Y/K |
| public static final int JCS_YCC = 5; // PhotoYCC |
| public static final int JCS_RGBA = 6; // RGB-Alpha |
| public static final int JCS_YCbCrA = 7; // Y/Cb/Cr/Alpha |
| // 8 and 9 were old "Legacy" codes which the old code never identified |
| // on reading anyway. Support for writing them is being dropped, too. |
| public static final int JCS_YCCA = 10; // PhotoYCC-Alpha |
| public static final int JCS_YCCK = 11; // Y/Cb/Cr/K |
| |
| public static final int NUM_JCS_CODES = JCS_YCCK+1; |
| |
| /** IJG can handle up to 4-channel JPEGs */ |
| static final int [] [] bandOffsets = {{0}, |
| {0, 1}, |
| {0, 1, 2}, |
| {0, 1, 2, 3}}; |
| |
| static final int [] bOffsRGB = { 2, 1, 0 }; |
| |
| /* These are kept in the inner class to avoid static initialization |
| * of the CMM class until someone actually needs it. |
| * (e.g. do not init CMM on the request for jpeg mime types) |
| */ |
| public static class JCS { |
| public static final ColorSpace sRGB = |
| ColorSpace.getInstance(ColorSpace.CS_sRGB); |
| |
| private static ColorSpace YCC = null; |
| private static boolean yccInited = false; |
| |
| public static ColorSpace getYCC() { |
| if (!yccInited) { |
| try { |
| YCC = ColorSpace.getInstance(ColorSpace.CS_PYCC); |
| } catch (IllegalArgumentException e) { |
| // PYCC.pf may not always be installed |
| } finally { |
| yccInited = true; |
| } |
| } |
| return YCC; |
| } |
| } |
| |
| // Default value for ImageWriteParam |
| public static final float DEFAULT_QUALITY = 0.75F; |
| |
| /** |
| * Returns <code>true</code> if the given <code>ColorSpace</code> |
| * object is an instance of ICC_ColorSpace but is not one of the |
| * standard <code>ColorSpaces</code> returned by |
| * <code>ColorSpace.getInstance()</code>. |
| */ |
| static boolean isNonStandardICC(ColorSpace cs) { |
| boolean retval = false; |
| if ((cs instanceof ICC_ColorSpace) |
| && (!cs.isCS_sRGB()) |
| && (!cs.equals(ColorSpace.getInstance(ColorSpace.CS_CIEXYZ))) |
| && (!cs.equals(ColorSpace.getInstance(ColorSpace.CS_GRAY))) |
| && (!cs.equals(ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB))) |
| && (!cs.equals(ColorSpace.getInstance(ColorSpace.CS_PYCC))) |
| ) { |
| retval = true; |
| } |
| return retval; |
| } |
| |
| |
| /** |
| * Returns <code>true</code> if the given imageType can be used |
| * in a JFIF file. If <code>input</code> is true, then the |
| * image type is considered before colorspace conversion. |
| */ |
| static boolean isJFIFcompliant(ImageTypeSpecifier imageType, |
| boolean input) { |
| ColorModel cm = imageType.getColorModel(); |
| // Can't have alpha |
| if (cm.hasAlpha()) { |
| return false; |
| } |
| // Gray is OK, always |
| int numComponents = imageType.getNumComponents(); |
| if (numComponents == 1) { |
| return true; |
| } |
| |
| // If it isn't gray, it must have 3 channels |
| if (numComponents != 3) { |
| return false; |
| } |
| |
| if (input) { |
| // Must be RGB |
| if (cm.getColorSpace().getType() == ColorSpace.TYPE_RGB) { |
| return true; |
| } |
| } else { |
| // Must be YCbCr |
| if (cm.getColorSpace().getType() == ColorSpace.TYPE_YCbCr) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Given an image type, return the Adobe transform corresponding to |
| * that type, or ADOBE_IMPOSSIBLE if the image type is incompatible |
| * with an Adobe marker segment. If <code>input</code> is true, then |
| * the image type is considered before colorspace conversion. |
| */ |
| static int transformForType(ImageTypeSpecifier imageType, boolean input) { |
| int retval = ADOBE_IMPOSSIBLE; |
| ColorModel cm = imageType.getColorModel(); |
| switch (cm.getColorSpace().getType()) { |
| case ColorSpace.TYPE_GRAY: |
| retval = ADOBE_UNKNOWN; |
| break; |
| case ColorSpace.TYPE_RGB: |
| retval = input ? ADOBE_YCC : ADOBE_UNKNOWN; |
| break; |
| case ColorSpace.TYPE_YCbCr: |
| retval = ADOBE_YCC; |
| break; |
| case ColorSpace.TYPE_CMYK: |
| retval = input ? ADOBE_YCCK : ADOBE_IMPOSSIBLE; |
| } |
| return retval; |
| } |
| |
| /** |
| * Converts an ImageWriteParam (i.e. IJG) non-linear quality value |
| * to a float suitable for passing to JPEGQTable.getScaledInstance(). |
| */ |
| static float convertToLinearQuality(float quality) { |
| // The following is converted from the IJG code. |
| if (quality <= 0.0F) { |
| quality = 0.01F; |
| } |
| |
| if (quality > 1.00F) { |
| quality = 1.00F; |
| } |
| |
| if (quality < 0.5F) { |
| quality = 0.5F / quality; |
| } else { |
| quality = 2.0F - (quality * 2.0F); |
| } |
| |
| return quality; |
| } |
| |
| /** |
| * Return an array of default, visually lossless quantization tables. |
| */ |
| static JPEGQTable [] getDefaultQTables() { |
| JPEGQTable [] qTables = new JPEGQTable[2]; |
| qTables[0] = JPEGQTable.K1Div2Luminance; |
| qTables[1] = JPEGQTable.K2Div2Chrominance; |
| return qTables; |
| } |
| |
| /** |
| * Return an array of default Huffman tables. |
| */ |
| static JPEGHuffmanTable [] getDefaultHuffmanTables(boolean wantDC) { |
| JPEGHuffmanTable [] tables = new JPEGHuffmanTable[2]; |
| if (wantDC) { |
| tables[0] = JPEGHuffmanTable.StdDCLuminance; |
| tables[1] = JPEGHuffmanTable.StdDCChrominance; |
| } else { |
| tables[0] = JPEGHuffmanTable.StdACLuminance; |
| tables[1] = JPEGHuffmanTable.StdACChrominance; |
| } |
| return tables; |
| } |
| |
| } |