001    /*
002     * PromotionRGB48
003     * 
004     * Copyright (c) 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.Gray16Image;
012    import net.sourceforge.jiu.data.Gray8Image;
013    import net.sourceforge.jiu.data.MemoryRGB48Image;
014    import net.sourceforge.jiu.data.Palette;
015    import net.sourceforge.jiu.data.Paletted8Image;
016    import net.sourceforge.jiu.data.PixelImage;
017    import net.sourceforge.jiu.data.RGB24Image;
018    import net.sourceforge.jiu.data.RGB48Image;
019    import net.sourceforge.jiu.data.RGBIndex;
020    import net.sourceforge.jiu.ops.ImageToImageOperation;
021    import net.sourceforge.jiu.ops.MissingParameterException;
022    import net.sourceforge.jiu.ops.WrongParameterException;
023    
024    /**
025     * Converts several image types to {@link net.sourceforge.jiu.data.RGB48Image}.
026     * Promotion is a lossless operation that will only lead to an output image
027     * that holds the same image in a way that demands more memory.
028     * <p>
029     * If you give an image implementing RGB24Image to this operation, a
030     * WrongParameterException will be thrown.
031     * This operation could also return the input image, but this might lead
032     * to the wrong impression that a copy of the input was produced which
033     * can be modified without changing the original.
034     * @author Marco Schmidt
035     * @since 0.12.0
036     */
037    public class PromotionRGB48 extends ImageToImageOperation
038    {
039            private void prepare(PixelImage in) throws
040                    MissingParameterException,
041                    WrongParameterException
042            {
043                    if (!
044                         (
045                          (in instanceof BilevelImage) || 
046                          (in instanceof Paletted8Image) || 
047                              (in instanceof Gray16Image)|| 
048                              (in instanceof Gray8Image) ||
049                              (in instanceof RGB24Image)
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 MemoryRGB48Image(in.getWidth(), in.getHeight()));
059                    }
060                    else
061                    {
062                            if (!(out instanceof RGB48Image))
063                            {
064                                    throw new WrongParameterException("Specified output image type " +
065                                            "must be of class RGB48Image; got " + in.getClass().getName());
066                            }
067                            ensureImagesHaveSameResolution();
068                    }
069            }
070    
071            private void process(BilevelImage in, RGB48Image out)
072            {
073                    final int HEIGHT = in.getHeight();
074                    final short MAX = (short)65535;
075                    final short MIN = (short)0;
076                    for (int y = 0; y < HEIGHT; y++)
077                    {
078                            for (int x = 0; x < in.getWidth(); x++)
079                            {
080                                    if (in.isBlack(x, y))
081                                    {
082                                            out.putShortSample(RGBIndex.INDEX_RED, x, y, MIN);
083                                            out.putShortSample(RGBIndex.INDEX_GREEN, x, y, MIN);
084                                            out.putShortSample(RGBIndex.INDEX_BLUE, x, y, MIN);
085                                    }
086                                    else
087                                    {
088                                            out.putShortSample(RGBIndex.INDEX_RED, x, y, MAX);
089                                            out.putShortSample(RGBIndex.INDEX_GREEN, x, y, MAX);
090                                            out.putShortSample(RGBIndex.INDEX_BLUE, x, y, MAX);
091                                    }
092                            }
093                            setProgress(y, HEIGHT);
094                    }
095            }
096    
097            private void process(Paletted8Image in, RGB48Image out)
098            {
099                    final int WIDTH = in.getWidth();
100                    final int HEIGHT = in.getHeight();
101                    final Palette PAL = in.getPalette();
102                    for (int y = 0; y < HEIGHT; y++)
103                    {
104                            for (int x = 0; x < in.getWidth(); x++)
105                            {
106                                    int value = in.getSample(0, x, y);
107                                    int red = PAL.getSample(RGBIndex.INDEX_RED, value);
108                                    int green = PAL.getSample(RGBIndex.INDEX_GREEN, value);
109                                    int blue = PAL.getSample(RGBIndex.INDEX_BLUE, value);
110                                    out.putSample(RGBIndex.INDEX_RED, x, y, red | red << 8);
111                                    out.putSample(RGBIndex.INDEX_GREEN, x, y, green | green << 8);
112                                    out.putSample(RGBIndex.INDEX_BLUE, x, y, blue | blue << 8);
113                            }
114                            setProgress(y, HEIGHT);
115                    }
116            }
117    
118            private void process(Gray16Image in, RGB48Image out)
119            {
120                    final int WIDTH = in.getWidth();
121                    final int HEIGHT = in.getHeight();
122                    for (int y = 0; y < HEIGHT; y++)
123                    {
124                            for (int x = 0; x < WIDTH; x++)
125                            {
126                                    int value = in.getSample(0, x, y);
127                                    out.putSample(RGBIndex.INDEX_RED, x, y, value);
128                                    out.putSample(RGBIndex.INDEX_GREEN, x, y, value);
129                                    out.putSample(RGBIndex.INDEX_BLUE, x, y, value);
130                            }
131                            setProgress(y, HEIGHT);
132                    }
133            }
134    
135            private void process(Gray8Image in, RGB48Image out)
136            {
137                    final int WIDTH = in.getWidth();
138                    final int HEIGHT = in.getHeight();
139                    for (int y = 0; y < HEIGHT; y++)
140                    {
141                            for (int x = 0; x < WIDTH; x++)
142                            {
143                                    int value = in.getSample(0, x, y);
144                                    value = value | value << 8;
145                                    out.putSample(RGBIndex.INDEX_RED, x, y, value);
146                                    out.putSample(RGBIndex.INDEX_GREEN, x, y, value);
147                                    out.putSample(RGBIndex.INDEX_BLUE, x, y, value);
148                            }
149                            setProgress(y, HEIGHT);
150                    }
151            }
152    
153            private void process(RGB24Image in, RGB48Image out)
154            {
155                    final int WIDTH = in.getWidth();
156                    final int HEIGHT = in.getHeight();
157                    for (int y = 0; y < HEIGHT; y++)
158                    {
159                            for (int x = 0; x < WIDTH; x++)
160                            {
161                                    int red = in.getSample(RGBIndex.INDEX_RED, x, y);
162                                    red = red << 8 | red;
163                                    int green = in.getSample(RGBIndex.INDEX_GREEN, x, y);
164                                    green = green << 8 | green;
165                                    int blue = in.getSample(RGBIndex.INDEX_BLUE, x, y);
166                                    blue = blue << 8 | blue;
167                                    out.putSample(RGBIndex.INDEX_RED, x, y, red);
168                                    out.putSample(RGBIndex.INDEX_GREEN, x, y, green);
169                                    out.putSample(RGBIndex.INDEX_BLUE, x, y, blue);
170                            }
171                            setProgress(y, HEIGHT);
172                    }
173            }
174    
175            public void process() throws
176                    MissingParameterException,
177                    WrongParameterException
178            {
179                    ensureInputImageIsAvailable();
180                    PixelImage in = getInputImage();
181                    prepare(in);
182                    RGB48Image out = (RGB48Image)getOutputImage();
183                    if (in instanceof BilevelImage)
184                    {
185                            process((BilevelImage)in, out);
186                    }
187                    else
188                    if (in instanceof Gray16Image)
189                    {
190                            process((Gray16Image)in, out);
191                    }
192                    else
193                    if (in instanceof Gray8Image)
194                    {
195                            process((Gray8Image)in, out);
196                    }
197                    else
198                    if (in instanceof Paletted8Image)
199                    {
200                            process((Paletted8Image)in, out);
201                    }
202                    else
203                    if (in instanceof RGB24Image)
204                    {
205                            process((RGB24Image)in, out);
206                    }
207            }
208    }