001    /*
002     * PromotionRGB24
003     * 
004     * Copyright (c) 2001, 2002, 2003 Marco Schmidt.
005     * All rights reserved.
006     */
007    
008    package net.sourceforge.jiu.color.promotion;
009    
010    import net.sourceforge.jiu.data.BilevelImage;
011    import net.sourceforge.jiu.data.Gray8Image;
012    import net.sourceforge.jiu.data.MemoryRGB24Image;
013    import net.sourceforge.jiu.data.Palette;
014    import net.sourceforge.jiu.data.Paletted8Image;
015    import net.sourceforge.jiu.data.PixelImage;
016    import net.sourceforge.jiu.data.RGB24Image;
017    import net.sourceforge.jiu.data.RGBIndex;
018    import net.sourceforge.jiu.ops.ImageToImageOperation;
019    import net.sourceforge.jiu.ops.MissingParameterException;
020    import net.sourceforge.jiu.ops.WrongParameterException;
021    
022    /**
023     * Converts several image types to RGB.
024     * Promoting is a lossless operation that will only lead to an output image
025     * that holds the same image in a way that demands more memory.
026     * <p>
027     * If you give an image implementing RGB24Image to this operation, a
028     * WrongParameterException will be thrown.
029     * This operation could also return the input image, but this might lead
030     * to the wrong impression that a copy of the input was produced which
031     * can be modified without changing the original.
032     *
033     * @author Marco Schmidt
034     */
035    public class PromotionRGB24 extends ImageToImageOperation
036    {
037            private void prepare(PixelImage in) throws
038                    MissingParameterException,
039                    WrongParameterException
040            {
041                    if (in == null)
042                    {
043                            throw new MissingParameterException("Missing input image.");
044                    }
045                    if (!
046                         (
047                          (in instanceof BilevelImage) || 
048                          (in instanceof Paletted8Image) || 
049                          (in instanceof Gray8Image)
050                         )
051                       )
052                    {
053                            throw new WrongParameterException("Unsupported input image type: " + in.getClass().getName());
054                    }
055                    PixelImage out = getOutputImage();
056                    if (out == null)
057                    {
058                            setOutputImage(new MemoryRGB24Image(in.getWidth(), in.getHeight()));
059                    }
060                    else
061                    {
062                            if (!(out instanceof RGB24Image))
063                            {
064                                    throw new WrongParameterException("Specified output image type must be of class RGB24Image; got " + in.getClass().getName());
065                            }
066                            if (in.getWidth() != out.getWidth())
067                            {
068                                    throw new WrongParameterException("Specified output image must have same width as input image.");
069                            }
070                            if (in.getHeight() != out.getHeight())
071                            {
072                                    throw new WrongParameterException("Specified output image must have same height as input image.");
073                            }
074                    }
075            }
076    
077            private void process(BilevelImage in, RGB24Image out)
078            {
079                    final int HEIGHT = in.getHeight();
080                    final byte MAX = (byte)255;
081                    final byte MIN = (byte)0;
082                    for (int y = 0; y < HEIGHT; y++)
083                    {
084                            for (int x = 0; x < in.getWidth(); x++)
085                            {
086                                    if (in.isBlack(x, y))
087                                    {
088                                            out.putByteSample(RGBIndex.INDEX_RED, x, y, MIN);
089                                            out.putByteSample(RGBIndex.INDEX_GREEN, x, y, MIN);
090                                            out.putByteSample(RGBIndex.INDEX_BLUE, x, y, MIN);
091                                    }
092                                    else
093                                    {
094                                            out.putByteSample(RGBIndex.INDEX_RED, x, y, MAX);
095                                            out.putByteSample(RGBIndex.INDEX_GREEN, x, y, MAX);
096                                            out.putByteSample(RGBIndex.INDEX_BLUE, x, y, MAX);
097                                    }
098                            }
099                            setProgress(y, HEIGHT);
100                    }
101            }
102    
103            private void process(Paletted8Image in, RGB24Image out)
104            {
105                    final int WIDTH = in.getWidth();
106                    final int HEIGHT = in.getHeight();
107                    final Palette PAL = in.getPalette();
108                    for (int y = 0; y < HEIGHT; y++)
109                    {
110                            for (int x = 0; x < in.getWidth(); x++)
111                            {
112                                    int value = in.getSample(0, x, y);
113                                    out.putSample(RGBIndex.INDEX_RED, x, y, PAL.getSample(RGBIndex.INDEX_RED, value));
114                                    out.putSample(RGBIndex.INDEX_GREEN, x, y, PAL.getSample(RGBIndex.INDEX_GREEN, value));
115                                    out.putSample(RGBIndex.INDEX_BLUE, x, y, PAL.getSample(RGBIndex.INDEX_BLUE, value));
116                            }
117                            setProgress(y, HEIGHT);
118                    }
119            }
120    
121            private void process(Gray8Image in, RGB24Image out)
122            {
123                    final int WIDTH = in.getWidth();
124                    final int HEIGHT = in.getHeight();
125                    for (int y = 0; y < HEIGHT; y++)
126                    {
127                            for (int x = 0; x < WIDTH; x++)
128                            {
129                                    int value = in.getSample(0, x, y);
130                                    out.putSample(RGBIndex.INDEX_RED, x, y, value);
131                                    out.putSample(RGBIndex.INDEX_GREEN, x, y, value);
132                                    out.putSample(RGBIndex.INDEX_BLUE, x, y, value);
133                            }
134                            setProgress(y, HEIGHT);
135                    }
136            }
137    
138            public void process() throws
139                    MissingParameterException,
140                    WrongParameterException
141            {
142                    PixelImage in = getInputImage();
143                    prepare(in);
144                    RGB24Image out = (RGB24Image)getOutputImage();
145                    if (in instanceof BilevelImage)
146                    {
147                            process((BilevelImage)in, out);
148                    }
149                    else
150                    if (in instanceof Gray8Image)
151                    {
152                            process((Gray8Image)in, out);
153                    }
154                    else
155                    if (in instanceof Paletted8Image)
156                    {
157                            process((Paletted8Image)in, out);
158                    }
159            }
160    }