001    /*
002     * RGBQuantizer
003     * 
004     * Copyright (c) 2001, 2002 Marco Schmidt.
005     * All rights reserved.
006     */
007    
008    package net.sourceforge.jiu.color.quantization;
009    
010    import net.sourceforge.jiu.data.Palette;
011    
012    /**
013     * An interface for an RGB color quantizer.
014     * Color quantizers take an input image and produce an output image
015     * that looks like the original but uses less colors.
016     * Keeping the error (the difference between input and output image) as small 
017     * as possible is important - the more similar input and output are, the better.
018     * <p>
019     * Similarity between to pixels (or, more accurately, the colors of two pixels)
020     * can be defined by their distance in color space.
021     * Imagine two colors given by <em>(r<sub>1</sub>, g<sub>1</sub>, b<sub>1</sub>)</em>
022     * and
023     * <em>(r<sub>2</sub>, g<sub>2</sub>, b<sub>2</sub>)</em>.
024     * The distance can then be defined as 
025     * <em>sqrt((r<sub>1</sub> - r<sub>2</sub>)<sup>2</sup> + 
026     *  (g<sub>1</sub> - g<sub>2</sub>)<sup>2</sup> + (b<sub>1</sub> - b<sub>2</sub>)<sup>2</sup>)</em>
027     * (with <em>sqrt</em> being the square root).
028     * <p>
029     * A quantizer has two main tasks:
030     * <ol>
031     * <li><strong>Find a palette.</strong>
032     *  Some quantizers create <em>custom</em> palettes for a
033     *  given input (e.g. {@link MedianCutQuantizer} or {@link OctreeColorQuantizer}, 
034     *  other quantizers use fixed palettes (e.g. {@link UniformPaletteQuantizer}).
035     *  Using a custom palette typically results in a better output image 
036     *  (it is more similar because it takes into consideration the content
037     *  of the input).
038     * However, using <em>fixed</em> palettes requires less CPU time and memory and
039     * is sufficient in many cases from a point of view of output quality.
040     * <p>
041     * If a quantizer does use a fixed palette, this first step obviously is not
042     * so much about finding the palette but about specifying it.
043     *  </li>
044     * <li><strong>Map the input image to the palette.</strong>
045     *  For each pixel in the truecolor input image the mapping procedure must
046     *  find the color in the palette that is closest to that input pixel
047     *  so that the difference between source and destination pixel
048     *  is as small as possible.
049     * <p>
050     * The code that does the mapping from the original to any given palette
051     * could be shared among quantizers - after all, the goal is always the same,
052     * picking the palette entry with the smallest distance in color space
053     * to the original pixel.
054     * However, sometimes the data structures built while finding the palette
055     * can be reused for faster mapping from the original to output.
056     * This is the case for both the MedianCutQuantizer and the OctreeColorQuantizer.
057     * </li>
058     * </ol>
059     * <p>
060     * Dithering methods like error diffusion dithering
061     * may be used to increase
062     * the quality of the output.
063     * Note however that dithering introduces noise that makes the quantized image harder to
064     * compress and in some cases unusable for post-processing (the noise may be an obstacle for
065     * image processing algorithms).
066     * <p>
067     * This quantizer interface was designed with JIU's error diffusion dithering operation 
068     * {@link net.sourceforge.jiu.color.dithering.ErrorDiffusionDithering} in mind.
069     * 
070     *
071     * @author Marco Schmidt
072     */
073    public interface RGBQuantizer
074    {
075            /**
076             * Return a Palette object with the list of colors to be used in the quantization
077             * process.
078             * That palette may be fixed or created specifically for a given input image.
079             * @return Palette object for destination image
080             */
081            Palette createPalette();
082    
083            /**
084             * This method maps a triplet of intensity values to its quantized counterpart 
085             * and returns the palette index of that quantized color.
086             * The index values for the two arrays are taken from RGBIndex.
087             * @param origRgb the three samples red, green and blue for which a good match is searched in the palette
088             * @param quantizedRgb will hold the three samples found to be closest to origRgb after the call to this method
089             * @return int index in the palette of the match quantizedRgb
090             */
091            int map(int[] origRgb, int[] quantizedRgb);
092    }