001    /*
002     * PromotionGray16
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.MemoryGray16Image;
014    import net.sourceforge.jiu.data.PixelImage;
015    import net.sourceforge.jiu.ops.ImageToImageOperation;
016    import net.sourceforge.jiu.ops.MissingParameterException;
017    import net.sourceforge.jiu.ops.WrongParameterException;
018    
019    /**
020     * Converts BilevelImage and Gray8Image objects to Gray16Image objects.
021     * Promotion is a lossless operation that will lead to an output image
022     * that holds the same image in a way that demands more memory.
023     * @author Marco Schmidt
024     * @since 0.11.0
025     */
026    public class PromotionGray16 extends ImageToImageOperation
027    {
028            private void prepare(PixelImage in) throws
029                    MissingParameterException,
030                    WrongParameterException
031            {
032                    if (in == null)
033                    {
034                            throw new MissingParameterException("Missing input image.");
035                    }
036                    if (!
037                         (
038                          (in instanceof BilevelImage) ||
039                          (in instanceof Gray8Image)
040                         )
041                       )
042                    {
043                            throw new WrongParameterException("Unsupported input image type: " + in.getClass().getName());
044                    }
045                    PixelImage out = getOutputImage();
046                    if (out == null)
047                    {
048                            setOutputImage(new MemoryGray16Image(in.getWidth(), in.getHeight()));
049                    }
050                    else
051                    {
052                            if (!(out instanceof Gray16Image))
053                            {
054                                    throw new WrongParameterException("Specified output image type must be of class Gray16Image; got " + in.getClass().getName());
055                            }
056                            if (in.getWidth() != out.getWidth())
057                            {
058                                    throw new WrongParameterException("Specified output image must have same width as input image.");
059                            }
060                            if (in.getHeight() != out.getHeight())
061                            {
062                                    throw new WrongParameterException("Specified output image must have same height as input image.");
063                            }
064                    }
065            }
066    
067            private void process(BilevelImage in, Gray16Image out)
068            {
069                    final int WIDTH = in.getWidth();
070                    final int HEIGHT = in.getHeight();
071                    final short MAX = (short)out.getMaxSample(0);
072                    final short MIN = 0;
073                    for (int y = 0; y < HEIGHT; y++)
074                    {
075                            for (int x = 0; x < WIDTH; x++)
076                            {
077                                    if (in.isBlack(x, y))
078                                    {
079                                            out.putShortSample(0, x, y, MIN);
080                                    }
081                                    else
082                                    {
083                                            out.putShortSample(0, x, y, MAX);
084                                    }
085                            }
086                            setProgress(y, HEIGHT);
087                    }
088            }
089    
090            private void process(Gray8Image in, Gray16Image out)
091            {
092                    final int WIDTH = in.getWidth();
093                    final int HEIGHT = in.getHeight();
094                    for (int y = 0; y < HEIGHT; y++)
095                    {
096                            for (int x = 0; x < WIDTH; x++)
097                            {
098                                    int sample = in.getSample(x, y);
099                                    out.putSample(x, y, sample | (sample << 8));
100                            }
101                            setProgress(y, HEIGHT);
102                    }
103            }
104    
105            public void process() throws
106                    MissingParameterException,
107                    WrongParameterException
108            {
109                    PixelImage in = getInputImage();
110                    prepare(in);
111                    Gray16Image out = (Gray16Image)getOutputImage();
112                    if (in instanceof BilevelImage)
113                    {
114                            process((BilevelImage)in, out);
115                    }
116                    else
117                    if (in instanceof Gray8Image)
118                    {
119                            process((Gray8Image)in, out);
120                    }
121            }
122    }