001    /*
002     * ReduceRGB
003     *
004     * Copyright (c) 2003 Marco Schmidt.
005     * All rights reserved.
006     */
007    
008    package net.sourceforge.jiu.color.reduction;
009    
010    import net.sourceforge.jiu.data.PixelImage;
011    import net.sourceforge.jiu.data.RGB24Image;
012    import net.sourceforge.jiu.data.RGB48Image;
013    import net.sourceforge.jiu.ops.ImageToImageOperation;
014    import net.sourceforge.jiu.ops.MissingParameterException;
015    import net.sourceforge.jiu.ops.WrongParameterException;
016    
017    /**
018     * Reduces the color depth of RGB truecolor images.
019     * This class uses a simple approach, it just drops some of the 
020     * lowest bits and scales the value back to eight or sixteen bits per sample.
021     * <h3>Supported image classes</h3>
022     * This class works with {@link net.sourceforge.jiu.data.RGB24Image}
023     * and {@link net.sourceforge.jiu.data.RGB48Image}.
024     * <h3>Usage example</h3>
025     * Reduce a 24 bits per pixel RGB image to 15 bits per pixel:
026     * <pre>
027     * RGB24Image inputImage = ...; // initialize
028     * ReduceRGB reduce = new ReduceRGB();
029     * reduce.setBits(5);
030     * reduce.setInputImage(inputImage);
031     * reduce.process();
032     * PixelImage reducedImage = reduce.getOutputImage();
033     * </pre>
034     * @author Marco Schmidt
035     * @since 0.12.0
036     * @see net.sourceforge.jiu.color.reduction.ReduceShadesOfGray
037     */
038    public class ReduceRGB extends ImageToImageOperation
039    {
040            /**
041             * Number of significant bits per channel in the destination RGB image.
042             */
043            private Integer destBits;
044    
045            /*private byte[] createByteLut(int inDepth)
046            {
047                    int outDepth = destBits.intValue();
048                    lut = new int[1 << inDepth];
049                    final int SHIFT = inDepth - outDepth;
050                    final int MAX_IN_VALUE = (1 << inDepth) - 1;
051                    final int MAX_OUT_VALUE = (1 << outDepth) - 1;
052                    for (int i = 0; i < lut.length; i++)
053                    {
054                            int value = i >> SHIFT;
055                            lut[i] = (value * MAX_IN_VALUE) / MAX_OUT_VALUE;
056                    }
057            }*/
058    
059    
060            public void process() throws MissingParameterException, WrongParameterException
061            {
062                    if (destBits == null)
063                    {
064                            throw new MissingParameterException("The number of destination bits has not been specified.");
065                    }
066                    ensureInputImageIsAvailable();
067                    ensureImagesHaveSameResolution();
068                    PixelImage in = getInputImage();
069                    boolean rgb24 = in instanceof RGB24Image;
070                    boolean rgb48 = in instanceof RGB48Image;
071                    if (!(rgb24 || rgb48))
072                    {
073                            throw new WrongParameterException("Input image must be either RGB24Image or RGB48Image.");
074                    }
075                    PixelImage out = getOutputImage();
076                    int bits = destBits.intValue();
077                    if (bits <= 8)
078                    {
079                    }
080                    else
081                    if (bits <= 16)
082                    {
083                    }
084                    else
085                    {
086                    }
087            }
088    
089            /**
090             * Specifies the number of bits the output image is supposed to have.
091             * @param bits number of bits in output image, from 1 to 15
092             * @throws IllegalArgumentException if bits is smaller than 1 or larger than 15
093             */
094            public void setBits(int bits)
095            {
096                    if (bits < 1)
097                    {
098                            throw new IllegalArgumentException("Number of bits must be 1 or larger.");
099                    }
100                    if (bits > 15)
101                    {
102                            throw new IllegalArgumentException("Number of bits must be 15 or smaller.");
103                    }
104                    destBits = new Integer(bits);
105            }
106    }