Use Tree Navigation
public static class

PixelConverter.Ushort555Rgbx

extends PixelConverter
/*
 * 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);
       
}
   
}
}