/*
 * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.awt.image;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;

/**
 * This class provides utilities for converting between the standard
 * rgb colorspace specification and the equivalent value for a pixel
 * of a given surface type.  The class was designed for use by the
 * SurfaceType objects, since the conversion between pixel values
 * and rgb values is inherently tied to the type of surface we are
 * dealing with.  Some conversions cannot be done automatically,
 * however (for example, the AnyInt or AnyDCM surface types), so
 * we require the caller to pass in a ColorModel object so that
 * we can calculate the pixel values in these generic cases as well.
 */
public class PixelConverter {

    /**
     * Default object, used as a fallback for any surface types where
     * we do not know enough about the surface to calculate the
     * conversions directly.  We use the ColorModel object to assist
     * us in these cases.
     */
    public static final PixelConverter instance = new PixelConverter();


    protected int alphaMask = 0;

    protected PixelConverter() {}

    public int rgbToPixel(int rgb, ColorModel cm) {
        Object obj = cm.getDataElements(rgb, null);
        switch (cm.getTransferType()) {
        case DataBuffer.TYPE_BYTE:
            byte[] bytearr = (byte[]) obj;
            int pix = 0;

            switch(bytearr.length) {
            default: // bytearr.length >= 4
                pix = bytearr[3] << 24;
                // FALLSTHROUGH
            case 3:
                pix |= (bytearr[2] & 0xff) << 16;
                // FALLSTHROUGH
            case 2:
                pix |= (bytearr[1] & 0xff) << 8;
                // FALLSTHROUGH
            case 1:
                pix |= (bytearr[0] & 0xff);
            }

            return pix;
        case DataBuffer.TYPE_SHORT:
        case DataBuffer.TYPE_USHORT:
            short[] shortarr = (short[]) obj;

            return (((shortarr.length > 1) ? shortarr[1] << 16 : 0) |
                    shortarr[0] & 0xffff);
        case DataBuffer.TYPE_INT:
            return ((int[]) obj)[0];
        default:
            return rgb;
        }
    }

    public int pixelToRgb(int pixel, ColorModel cm) {
        // REMIND: Not yet implemented
        return pixel;
    }

    public final int getAlphaMask() {
        return alphaMask;
    }


    /**
     * Subclasses of PixelConverter.  These subclasses are
     * specific to surface types where we can definitively
     * calculate the conversions.  Note that some conversions
     * are lossy; that is, we cannot necessarily convert a
     * value and then convert it back and wind up with the
     * original value.  For example, an rgb value  that has
     * an alpha != 1 cannot be converted to an Xrgb pixel
     * without losing the information in the alpha component.
     *
     * The conversion strategies associated with the ThreeByte*
     * and FourByte* surface types swap the components around
     * due to the ordering used when the bytes are stored.  The
     * low order byte of a packed-byte pixel will be the first
     * byte stored and the high order byte will be the last byte
     * stored.  For example, the ThreeByteBgr surface type is
     * associated with an Xrgb conversion object because the
     * three bytes are stored as follows:
     *   pixels[0] = b;    // low order byte of an Xrgb pixel
     *   pixels[1] = g;
     *   pixels[2] = r;    // high order byte of an Xrgb pixel
     */

    public static class Rgbx extends PixelConverter {
        public static final PixelConverter instance = new Rgbx();

        private Rgbx() {}

        public int rgbToPixel(int rgb, ColorModel cm) {
            return (rgb << 8);
        }

        public int pixelToRgb(int pixel, ColorModel cm) {
            return (0xff000000 | (pixel >> 8));
        }
    }
    public static class Xrgb extends PixelConverter {
        public static final PixelConverter instance = new Xrgb();

        private Xrgb() {}

        public int rgbToPixel(int rgb, ColorModel cm) {
            return rgb;
        }

        public int pixelToRgb(int pixel, ColorModel cm) {
            return (0xff000000 | pixel);
        }
    }
    public static class Argb extends PixelConverter {
        public static final PixelConverter instance = new Argb();

        private Argb() {
            alphaMask = 0xff000000;
        }

        public int rgbToPixel(int rgb, ColorModel cm) {
            return rgb;
        }

        public int pixelToRgb(int pixel, ColorModel cm) {
            return pixel;
        }
    }
    public static class Ushort565Rgb extends PixelConverter {
        public static final PixelConverter instance = new Ushort565Rgb();

        private Ushort565Rgb() {}

        public int rgbToPixel(int rgb, ColorModel cm) {
            return (((rgb >> (16 + 3 - 11)) & 0xf800) |
                    ((rgb >> ( 8 + 2 -  5)) & 0x07e0) |
                    ((rgb >> ( 0 + 3 -  0)) & 0x001f));
        }

        public int pixelToRgb(int pixel, ColorModel cm) {
            int r, g, b;
            r = (pixel >> 11) & 0x1f;
            r = (r << 3) | (r >> 2);
            g = (pixel >>  5) & 0x3f;
            g = (g << 2) | (g >> 4);
            b = (pixel      ) & 0x1f;
            b = (b << 3) | (b >> 2);
            return (0xff000000 | (r << 16) | (g << 8) | (b));
        }
    }
    public static class Ushort555Rgbx extends PixelConverter {
        public static final PixelConverter instance = new Ushort555Rgbx();

        private Ushort555Rgbx() {}

        public int rgbToPixel(int rgb, ColorModel cm) {
            return (((rgb >> (16 + 3 - 11)) & 0xf800) |
                    ((rgb >> ( 8 + 3 -  6)) & 0x07c0) |
                    ((rgb >> ( 0 + 3 -  1)) & 0x003e));
        }

        public int pixelToRgb(int pixel, ColorModel cm) {
            int r, g, b;
            r = (pixel >> 11) & 0x1f;
            r = (r << 3) | (r >> 2);
            g = (pixel >>  6) & 0x1f;
            g = (g << 3) | (g >> 2);
            b = (pixel >>  1) & 0x1f;
            b = (b << 3) | (b >> 2);
            return (0xff000000 | (r << 16) | (g << 8) | (b));
        }
    }
    public static class Ushort555Rgb extends PixelConverter {
        public static final PixelConverter instance = new Ushort555Rgb();

        private Ushort555Rgb() {}

        public int rgbToPixel(int rgb, ColorModel cm) {
            return (((rgb >> (16 + 3 - 10)) & 0x7c00) |
                    ((rgb >> ( 8 + 3 -  5)) & 0x03e0) |
                    ((rgb >> ( 0 + 3 -  0)) & 0x001f));
        }

        public int pixelToRgb(int pixel, ColorModel cm) {
            int r, g, b;
            r = (pixel >> 10) & 0x1f;
            r = (r << 3) | (r >> 2);
            g = (pixel >>  5) & 0x1f;
            g = (g << 3) | (g >> 2);
            b = (pixel      ) & 0x1f;
            b = (b << 3) | (b >> 2);
            return (0xff000000 | (r << 16) | (g << 8) | (b));
        }
    }
    public static class Ushort4444Argb extends PixelConverter {
        public static final PixelConverter instance = new Ushort4444Argb();

        private Ushort4444Argb() {
            alphaMask = 0xf000;
        }

        public int rgbToPixel(int rgb, ColorModel cm) {
            // use upper 4 bits for each color
            // 0xAaRrGgBb -> 0x0000ARGB
            int a = (rgb >> 16) & 0xf000;
            int r = (rgb >> 12) & 0x0f00;
            int g = (rgb >>  8) & 0x00f0;
            int b = (rgb >>  4) & 0x000f;

            return (a | r | g | b);
        }

        public int pixelToRgb(int pixel, ColorModel cm) {
            int a, r, g, b;
            // replicate 4 bits for each color
            // 0xARGB -> 0xAARRGGBB
            a = pixel & 0xf000;
            a = ((pixel << 16) | (pixel << 12)) & 0xff000000;
            r = pixel & 0x0f00;
            r = ((pixel << 12) | (pixel <<  8)) & 0x00ff0000;
            g = pixel & 0x00f0;
            g = ((pixel <<  8) | (pixel <<  4)) & 0x0000ff00;
            b = pixel & 0x000f;
            b = ((pixel <<  4) | (pixel <<  0)) & 0x000000ff;

            return (a | r | g | b);
        }
    }
    public static class Xbgr extends PixelConverter {
        public static final PixelConverter instance = new Xbgr();

        private Xbgr() {}

        public int rgbToPixel(int rgb, ColorModel cm) {
            return (((rgb & 0xff) << 16) |
                    (rgb & 0xff00) |
                    ((rgb >> 16) & 0xff));
        }

        public int pixelToRgb(int pixel, ColorModel cm) {
            return (0xff000000 |
                    ((pixel & 0xff) << 16) |
                    (pixel & 0xff00) |
                    ((pixel >> 16) & 0xff));
        }
    }
    public static class Bgrx extends PixelConverter {
        public static final PixelConverter instance = new Bgrx();

        private Bgrx() {}

        public int rgbToPixel(int rgb, ColorModel cm) {
            return ((rgb << 24) |
                    ((rgb & 0xff00) << 8) |
                    ((rgb >> 8) & 0xff00));
        }

        public int pixelToRgb(int pixel, ColorModel cm) {
            return (0xff000000                   |
                    ((pixel & 0xff00) << 8) |
                    ((pixel >> 8) & 0xff00) |
                    (pixel >>> 24));
        }
    }
    public static class Rgba extends PixelConverter {
        public static final PixelConverter instance = new Rgba();

        private Rgba() {
            alphaMask = 0x000000ff;
        }

        public int rgbToPixel(int rgb, ColorModel cm) {
            return ((rgb << 8) | (rgb >>> 24));
        }

        public int pixelToRgb(int pixel, ColorModel cm) {
            return ((pixel << 24) | (pixel >>> 8));
        }
    }
    public static class RgbaPre extends PixelConverter {
        public static final PixelConverter instance = new RgbaPre();

        private RgbaPre() {
            alphaMask = 0x000000ff;
        }

        public int rgbToPixel(int rgb, ColorModel cm) {
            if ((rgb >> 24) == -1) {
                return ((rgb << 8) | (rgb >>> 24));
            }
            int a = rgb >>> 24;
            int r = (rgb >> 16) & 0xff;
            int g = (rgb >>  8) & 0xff;
            int b = (rgb      ) & 0xff;
            int a2 = a + (a >> 7);
            r = (r * a2) >> 8;
            g = (g * a2) >> 8;
            b = (b * a2) >> 8;
            return ((r << 24) | (g << 16) | (b << 8) | (a));
        }

        public int pixelToRgb(int pixel, ColorModel cm) {
            int a = pixel & 0xff;
            if ((a == 0xff) || (a == 0)) {
                return ((pixel >>> 8) | (pixel << 24));
            }
            int r = pixel >>> 24;
            int g = (pixel >> 16) & 0xff;
            int b = (pixel >>  8) & 0xff;
            r = ((r << 8) - r) / a;
            g = ((g << 8) - g) / a;
            b = ((b << 8) - b) / a;
            return ((r << 24) | (g << 16) | (b << 8) | (a));
        }
    }
    public static class ArgbPre extends PixelConverter {
        public static final PixelConverter instance = new ArgbPre();

        private ArgbPre() {
            alphaMask = 0xff000000;
        }

        public int rgbToPixel(int rgb, ColorModel cm) {
            if ((rgb >> 24) == -1) {
                return rgb;
            }
            int a = rgb >>> 24;
            int r = (rgb >> 16) & 0xff;
            int g = (rgb >>  8) & 0xff;
            int b = (rgb      ) & 0xff;
            int a2 = a + (a >> 7);
            r = (r * a2) >> 8;
            g = (g * a2) >> 8;
            b = (b * a2) >> 8;
            return ((a << 24) | (r << 16) | (g << 8) | (b));
        }

        public int pixelToRgb(int pixel, ColorModel cm) {
            int a = pixel >>> 24;
            if ((a == 0xff) || (a == 0)) {
                return pixel;
            }
            int r = (pixel >> 16) & 0xff;
            int g = (pixel >>  8) & 0xff;
            int b = (pixel      ) & 0xff;
            r = ((r << 8) - r) / a;
            g = ((g << 8) - g) / a;
            b = ((b << 8) - b) / a;
            return ((a << 24) | (r << 16) | (g << 8) | (b));
        }
    }
    public static class ArgbBm extends PixelConverter {
        public static final PixelConverter instance = new ArgbBm();

        private ArgbBm() {}

        public int rgbToPixel(int rgb, ColorModel cm) {
            return (rgb | ((rgb >> 31) << 24));
        }

        public int pixelToRgb(int pixel, ColorModel cm) {
            return ((pixel << 7) >> 7);
        }
    }
    public static class ByteGray extends PixelConverter {
        static final double RED_MULT = 0.299;
        static final double GRN_MULT = 0.587;
        static final double BLU_MULT = 0.114;
        public static final PixelConverter instance = new ByteGray();

        private ByteGray() {}

        public int rgbToPixel(int rgb, ColorModel cm) {
            int red = (rgb >> 16) & 0xff;
            int grn = (rgb >>  8) & 0xff;
            int blu = (rgb      ) & 0xff;
            return (int) (red * RED_MULT +
                          grn * GRN_MULT +
                          blu * BLU_MULT +
                          0.5);
        }

        public int pixelToRgb(int pixel, ColorModel cm) {
            return ((((((0xff << 8) | pixel) << 8) | pixel) << 8) | pixel);
        }
    }
    public static class UshortGray extends ByteGray {
        static final double SHORT_MULT = 257.0; // (65535.0 / 255.0);
        static final double USHORT_RED_MULT = RED_MULT * SHORT_MULT;
        static final double USHORT_GRN_MULT = GRN_MULT * SHORT_MULT;
        static final double USHORT_BLU_MULT = BLU_MULT * SHORT_MULT;
        public static final PixelConverter instance = new UshortGray();

        private UshortGray() {}

        public int rgbToPixel(int rgb, ColorModel cm) {
            int red = (rgb >> 16) & 0xff;
            int grn = (rgb >>  8) & 0xff;
            int blu = (rgb      ) & 0xff;
            return (int) (red * USHORT_RED_MULT +
                          grn * USHORT_GRN_MULT +
                          blu * USHORT_BLU_MULT +
                          0.5);
        }

        public int pixelToRgb(int pixel, ColorModel cm) {
            pixel = pixel >> 8;
            return ((((((0xff << 8) | pixel) << 8) | pixel) << 8) | pixel);
        }
    }
}
