/* JPEGEncodeParam.java --
   Copyright (C) 2007 Free Software Foundation, Inc.

   This file is part of GNU Classpath.

   GNU Classpath is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   GNU Classpath 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 for more details.

   You should have received a copy of the GNU General Public License
   along with GNU Classpath; see the file COPYING.  If not, write to the
   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
   02110-1301 USA.

   Linking this library statically or dynamically with other modules is
   making a combined work based on this library.  Thus, the terms and
   conditions of the GNU General Public License cover the whole
   combination.

   As a special exception, the copyright holders of this library give you
   permission to link this library with independent modules to produce an
   executable, regardless of the license terms of these independent
   modules, and to copy and distribute the resulting executable under
   terms of your choice, provided that you also meet, for each linked
   independent module, the terms and conditions of the license of that
   module.  An independent module is a module which is not derived from
   or based on this library.  If you modify this library, you may extend
   this exception to your version of the library, but you are not
   obligated to do so.  If you do not wish to do so, delete this
   exception statement from your version. */

package com.sun.image.codec.jpeg;

/**
 * <p>
 * JPEGEncodeParam encapsulates tables and options necessary to control encoding
 * of JPEG data streams. Parameters are either set explicitly by the application
 * for encoding, or read from another JPEG header.
 * </p>
 * <p>
 * When working with BufferedImages, the codec will attempt to match the encoded
 * JPEG COLOR_ID with the ColorModel in the BufferedImage. This is not always
 * possible (the default mappings are listed below). In cases where unsupported
 * conversions are required (or odd image colorspaces are in use) the user must
 * either convert the image data to a known ColorSpace or encode the data from a
 * raster. When encoding rasters no colorspace adjustments are made, so the user
 * must do any conversions required to get to the encoded COLOR_ID. The COLOR_ID
 * for the encoded images is used to control the JPEG codec's inital values for
 * Huffman and Quantization Tables as well as subsampling factors. It is also
 * used to determine what color conversion should be performed to obtain the
 * best encoding.
 * </p>
 * <p>
 * Note: The color ids described herein are simply enumerated values that
 * influence data processing by the JPEG codec. JPEG compression is, by
 * definition, color blind. These values are used as hints when compressing JPEG
 * data. Through these values the JPEG codec can perform some default rotation
 * of data into spaces that will aid in getting better compression ratios.
 * </p>
 * <p>
 * Example behavior is described below. Since these mappings are likely to
 * change in the future it is strongly recommended that you make use of the @see
 * JPEGImageEncoder.getDefaultParamBlock calls and check the encodedColorID for
 * your particular BufferedImage. In extreme cases is may be necessary for the
 * user to convert the image to the desired colorspace, and encode it from a
 * Raster. In this case the API programmer must specify the colorID of the data
 * in the Raster and no color conversion will take place.
 * </p>
 *
 * ENCODING:
 *
 * <pre>
 * BufferedImage Type/Instance   JPEG (Encoded) Color ID
 * ===========================   =======================
 * TYPE_GRAY                     COLOR_ID_GRAYSCALE
 * TYPE_RGB                      COLOR_ID_YCbCr
 * TYPE_YCbCr                    COLOR_ID_YCbCr
 * TYPE_YCbCr/CS_PYCC            COLOR_ID_PYCC
 * TYPE_CMYK                     COLOR_ID_CMYK
 * TYPE_RGB (w/ alpha)           COLOR_ID_YCbCrA
 * TYPE_YCbCr (w/ alpha)         COLOR_ID_YCbCrA
 * TYPE_YCbCr/CS_PYCC (w/ alpha) COLOR_ID_PYCCA
 * ** Any Other **               COLOR_ID_UNKNOWN
 * </pre>
 * <p>
 * When the user wants more control than the BufferedImage conversions provide,
 * the user must encode the data from a Raster. In this case the data undergoes
 * no color conversion at all. It is the user's responsibility to perform the
 * desired conversions. If you intend to write a JFIF image (by including the
 * APP0_MARKER) the encoded COLOR_ID must be one of: COLOR_ID_UNKNOWN,
 * COLOR_ID_GRAYSCALE, COLOR_ID_YCbCr, or COLOR_ID_CMYK. In all other instances
 * an ImageformatException will be thrown.
 * </p>
 * <p>
 * IMPORTANT: an Alpha RGB BufferedImage will not map to a valid JFIF stream,
 * you must strip off the alpha prior to encoding if you want a JFIF file. If
 * the APP0 marker is set and you do not strip off the Alpha, an
 * ImageFormatException will be thrown.
 * </p>
 * <p>
 * Note that the classes in the com.sun.image.codec.jpeg package are not part of
 * the core Java APIs. They are a part of Sun's JDK and JRE distributions.
 * Although other licensees may choose to distribute these classes, developers
 * cannot depend on their availability in non-Sun implementations. We expect
 * that equivalent functionality will eventually be available in a core API or
 * standard extension.
 * </p>
 */
public interface JPEGEncodeParam extends JPEGDecodeParam {

    /**
     * Set the horizontal subsample factor for the given component. Note that
     * the subsample factor is the number of input pixels that contribute to
     * each output pixel (usually 2 for YCC).
     *
     * @param component
     *            The component being specified.
     * @param subsample
     *            The subsampling factor being specified.
     */
    public void setHorizontalSubsampling(int component, int subsample);

    /**
     * Set the vertical subsample factor for the given component. Note that the
     * subsample factor is the number of input pixels that contribute to each
     * output pixel (usually 2 for YCC).
     *
     * @param component
     *            The component being specified.
     * @param subsample
     *            The subsampling factor being specified.
     */
    public void setVerticalSubsampling(int component, int subsample);

    /**
     * Sets the coefficient quantization tables at index passed. tableNum must
     * range in value from 0 - 3.
     *
     * @param qtable
     *            that will be used.
     * @param tableNum
     *            the index of the table to be set.
     */
    public void setQTable(int tableNum, JPEGQTable qTable);

    /**
     * Sets the DC Huffman coding table at index to the table provided.
     *
     * @param huffTable
     *            JPEGHuffmanTable that will be assigned to index tableNum.
     * @param tableNum
     *            - the index of the table to be set.
     * @exception IllegalArgumentException
     *                - thrown if the tableNum is out of range. Index must range
     *                in value from 0 - 3.
     */
    public void setDCHuffmanTable(int tableNum, JPEGHuffmanTable huffTable);

    /**
     * Sets the AC Huffman coding table at index to the table provided.
     *
     * @param huffTable
     *            JPEGHuffmanTable that will be assigned to index tableNum.
     * @param tableNum
     *            - the index of the table to be set.
     * @exception IllegalArgumentException
     *                - thrown if the tableNum is out of range. Index must range
     *                in value from 0 - 3.
     */
    public void setACHuffmanTable(int tableNum, JPEGHuffmanTable huffTable);

    /**
     * Sets the mapping between a component and it's DC Huffman Table.
     *
     * @param component
     *            The component to set the mapping for
     * @param table
     *            The DC Huffman table to use for component
     */
    public void setDCHuffmanComponentMapping(int component, int table);

    /**
     * Sets the mapping between a component and it's AC Huffman Table.
     *
     * @param component
     *            The component to set the mapping for
     * @param table
     *            The AC Huffman table to use for component
     */
    public void setACHuffmanComponentMapping(int component, int table);

    /**
     * Sets the mapping between a component and it's Quantization Table.
     *
     * @param component
     *            The component to set the mapping for
     * @param table
     *            The Quantization Table to use for component
     */
    public void setQTableComponentMapping(int component, int table);

    /**
     * Set the flag indicating the validity of the table information in the
     * ParamBlock. This is used to indicate if tables should be included when
     * encoding.
     */
    public void setImageInfoValid(boolean flag);

    /**
     * Set the flag indicating the validity of the image information in the
     * ParamBlock. This is used to indicates if image data should be written
     * when encoding.
     */
    public void setTableInfoValid(boolean flag);

    /**
     * Sets the marker data to be written to the output data stream. This
     * removes any existing marker data in the JPEParm object. This can be used
     * to remove the default APP0 marker by calling it with data set to null.
     *
     * @param marker
     *            The marker to set the data for.
     * @param data
     *            the new set of data to be written.
     */
    public void setMarkerData(int marker, byte[][] data);

    /**
     * Appends 'data' to the array of byte[] associated with marker. This will
     * result in additional instance of the marker being written (one for each
     * byte[] in the array.).
     *
     * @param marker
     *            The marker to add and instance of.
     * @param data
     *            the data to be written.
     */
    public void addMarkerData(int marker, byte[] data);

    /**
     * Set the MCUs per restart, or 0 for no restart markers.
     *
     * @param restartInterval
     *            number MCUs per restart marker.
     */
    public void setRestartInterval(int restartInterval);

    /**
     * Set the pixel size units This value is copied into the APP0 marker (if
     * that marker is written). This value isn't used by the JPEG code.
     *
     * @param unit
     *            One of the DENSITY_UNIT_* values.
     */
    public void setDensityUnit(int unit);

    /**
     * Set the horizontal pixel density. This value is written into the APP0
     * marker. It isn't used by the JPEG code.
     *
     * @param density
     *            the horizontal pixel density, in units described by @see
     *            JPEGParam.getDensityUnit.
     */
    public void setXDensity(int density);

    /**
     * Set the vertical pixel density. This value is copied into the JFIF APP0
     * marker. It isn't used by the JPEG code.
     *
     * @param density
     *            The vertical pixel density, in units described by @see
     *            JPEGParam.getDensityUnit.
     */
    public void setYDensity(int density);

    /**
     * This creates new Quantization tables that replace the currently installed
     * Quantization tables. It also updates the Component QTable mapping to the
     * default for the current encoded COLOR_ID.
     *
     * The Created Quantization table varies from very high compression, very
     * low quality, (0.0) to low compression, very high quality (1.0) based on
     * the quality parameter.
     *
     * At a quality level of 1.0 the table will be all 1's which will lead to no
     * loss of data due to quantization (however chrominance subsampling, if
     * used, and roundoff error in the DCT will still degrade the image some
     * what).
     *
     * This is a linear manipulation of the standard chrominance Q-Table.
     *
     * Some guidelines: 0.75 high quality 0.5 medium quality 0.25 low quality
     *
     * @param quality
     *            0.0-1.0 setting of desired quality level.
     * @param forceBaseline
     *            force baseline quantization table
     */
    public void setQuality(float quality, boolean forceBaseline);
}
