/*
 * Copyright (c) 2000, 2002, 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.metadata.IIOMetadataFormatImpl;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.plugins.jpeg.JPEGQTable;
import javax.imageio.plugins.jpeg.JPEGHuffmanTable;

import java.awt.image.ColorModel;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
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 = "Sun Microsystems, Inc.";
    public static final String version = "0.5";
    // Names of the formats we can read or write
    public static final String [] names = {"JPEG", "jpeg", "JPG", "jpg"};
    public static final String [] suffixes = {"jpg", "jpeg"};
    public 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 */
    public static final int [] [] bandOffsets = {{0},
                                          {0, 1},
                                          {0, 1, 2},
                                          {0, 1, 2, 3}};

    public 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;
    }

}
