0N/A/*
2362N/A * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.awt.image;
0N/Aimport java.awt.image.ColorModel;
0N/Aimport java.awt.image.DataBuffer;
0N/A
0N/A/**
0N/A * This class provides utilities for converting between the standard
0N/A * rgb colorspace specification and the equivalent value for a pixel
0N/A * of a given surface type. The class was designed for use by the
0N/A * SurfaceType objects, since the conversion between pixel values
0N/A * and rgb values is inherently tied to the type of surface we are
0N/A * dealing with. Some conversions cannot be done automatically,
0N/A * however (for example, the AnyInt or AnyDCM surface types), so
0N/A * we require the caller to pass in a ColorModel object so that
0N/A * we can calculate the pixel values in these generic cases as well.
0N/A */
0N/Apublic class PixelConverter {
0N/A
0N/A /**
0N/A * Default object, used as a fallback for any surface types where
0N/A * we do not know enough about the surface to calculate the
0N/A * conversions directly. We use the ColorModel object to assist
0N/A * us in these cases.
0N/A */
0N/A public static final PixelConverter instance = new PixelConverter();
0N/A
0N/A
0N/A protected int alphaMask = 0;
0N/A
0N/A protected PixelConverter() {}
0N/A
0N/A public int rgbToPixel(int rgb, ColorModel cm) {
0N/A Object obj = cm.getDataElements(rgb, null);
0N/A switch (cm.getTransferType()) {
0N/A case DataBuffer.TYPE_BYTE:
0N/A byte[] bytearr = (byte[]) obj;
0N/A int pix = 0;
0N/A
0N/A switch(bytearr.length) {
0N/A default: // bytearr.length >= 4
0N/A pix = bytearr[3] << 24;
0N/A // FALLSTHROUGH
0N/A case 3:
0N/A pix |= (bytearr[2] & 0xff) << 16;
0N/A // FALLSTHROUGH
0N/A case 2:
0N/A pix |= (bytearr[1] & 0xff) << 8;
0N/A // FALLSTHROUGH
0N/A case 1:
0N/A pix |= (bytearr[0] & 0xff);
0N/A }
0N/A
0N/A return pix;
0N/A case DataBuffer.TYPE_SHORT:
0N/A case DataBuffer.TYPE_USHORT:
0N/A short[] shortarr = (short[]) obj;
0N/A
0N/A return (((shortarr.length > 1) ? shortarr[1] << 16 : 0) |
0N/A shortarr[0] & 0xffff);
0N/A case DataBuffer.TYPE_INT:
0N/A return ((int[]) obj)[0];
0N/A default:
0N/A return rgb;
0N/A }
0N/A }
0N/A
0N/A public int pixelToRgb(int pixel, ColorModel cm) {
0N/A // REMIND: Not yet implemented
0N/A return pixel;
0N/A }
0N/A
0N/A public final int getAlphaMask() {
0N/A return alphaMask;
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Subclasses of PixelConverter. These subclasses are
0N/A * specific to surface types where we can definitively
0N/A * calculate the conversions. Note that some conversions
0N/A * are lossy; that is, we cannot necessarily convert a
0N/A * value and then convert it back and wind up with the
0N/A * original value. For example, an rgb value that has
0N/A * an alpha != 1 cannot be converted to an Xrgb pixel
0N/A * without losing the information in the alpha component.
0N/A *
0N/A * The conversion strategies associated with the ThreeByte*
0N/A * and FourByte* surface types swap the components around
0N/A * due to the ordering used when the bytes are stored. The
0N/A * low order byte of a packed-byte pixel will be the first
0N/A * byte stored and the high order byte will be the last byte
0N/A * stored. For example, the ThreeByteBgr surface type is
0N/A * associated with an Xrgb conversion object because the
0N/A * three bytes are stored as follows:
0N/A * pixels[0] = b; // low order byte of an Xrgb pixel
0N/A * pixels[1] = g;
0N/A * pixels[2] = r; // high order byte of an Xrgb pixel
0N/A */
0N/A
0N/A public static class Rgbx extends PixelConverter {
0N/A public static final PixelConverter instance = new Rgbx();
0N/A
0N/A private Rgbx() {}
0N/A
0N/A public int rgbToPixel(int rgb, ColorModel cm) {
0N/A return (rgb << 8);
0N/A }
0N/A
0N/A public int pixelToRgb(int pixel, ColorModel cm) {
0N/A return (0xff000000 | (pixel >> 8));
0N/A }
0N/A }
0N/A public static class Xrgb extends PixelConverter {
0N/A public static final PixelConverter instance = new Xrgb();
0N/A
0N/A private Xrgb() {}
0N/A
0N/A public int rgbToPixel(int rgb, ColorModel cm) {
0N/A return rgb;
0N/A }
0N/A
0N/A public int pixelToRgb(int pixel, ColorModel cm) {
0N/A return (0xff000000 | pixel);
0N/A }
0N/A }
0N/A public static class Argb extends PixelConverter {
0N/A public static final PixelConverter instance = new Argb();
0N/A
0N/A private Argb() {
0N/A alphaMask = 0xff000000;
0N/A }
0N/A
0N/A public int rgbToPixel(int rgb, ColorModel cm) {
0N/A return rgb;
0N/A }
0N/A
0N/A public int pixelToRgb(int pixel, ColorModel cm) {
0N/A return pixel;
0N/A }
0N/A }
0N/A public static class Ushort565Rgb extends PixelConverter {
0N/A public static final PixelConverter instance = new Ushort565Rgb();
0N/A
0N/A private Ushort565Rgb() {}
0N/A
0N/A public int rgbToPixel(int rgb, ColorModel cm) {
0N/A return (((rgb >> (16 + 3 - 11)) & 0xf800) |
0N/A ((rgb >> ( 8 + 2 - 5)) & 0x07e0) |
0N/A ((rgb >> ( 0 + 3 - 0)) & 0x001f));
0N/A }
0N/A
0N/A public int pixelToRgb(int pixel, ColorModel cm) {
0N/A int r, g, b;
0N/A r = (pixel >> 11) & 0x1f;
0N/A r = (r << 3) | (r >> 2);
0N/A g = (pixel >> 5) & 0x3f;
0N/A g = (g << 2) | (g >> 4);
0N/A b = (pixel ) & 0x1f;
0N/A b = (b << 3) | (b >> 2);
0N/A return (0xff000000 | (r << 16) | (g << 8) | (b));
0N/A }
0N/A }
0N/A public static class Ushort555Rgbx extends PixelConverter {
0N/A public static final PixelConverter instance = new Ushort555Rgbx();
0N/A
0N/A private Ushort555Rgbx() {}
0N/A
0N/A public int rgbToPixel(int rgb, ColorModel cm) {
0N/A return (((rgb >> (16 + 3 - 11)) & 0xf800) |
0N/A ((rgb >> ( 8 + 3 - 6)) & 0x07c0) |
0N/A ((rgb >> ( 0 + 3 - 1)) & 0x003e));
0N/A }
0N/A
0N/A public int pixelToRgb(int pixel, ColorModel cm) {
0N/A int r, g, b;
0N/A r = (pixel >> 11) & 0x1f;
0N/A r = (r << 3) | (r >> 2);
0N/A g = (pixel >> 6) & 0x1f;
0N/A g = (g << 3) | (g >> 2);
0N/A b = (pixel >> 1) & 0x1f;
0N/A b = (b << 3) | (b >> 2);
0N/A return (0xff000000 | (r << 16) | (g << 8) | (b));
0N/A }
0N/A }
0N/A public static class Ushort555Rgb extends PixelConverter {
0N/A public static final PixelConverter instance = new Ushort555Rgb();
0N/A
0N/A private Ushort555Rgb() {}
0N/A
0N/A public int rgbToPixel(int rgb, ColorModel cm) {
0N/A return (((rgb >> (16 + 3 - 10)) & 0x7c00) |
0N/A ((rgb >> ( 8 + 3 - 5)) & 0x03e0) |
0N/A ((rgb >> ( 0 + 3 - 0)) & 0x001f));
0N/A }
0N/A
0N/A public int pixelToRgb(int pixel, ColorModel cm) {
0N/A int r, g, b;
0N/A r = (pixel >> 10) & 0x1f;
0N/A r = (r << 3) | (r >> 2);
0N/A g = (pixel >> 5) & 0x1f;
0N/A g = (g << 3) | (g >> 2);
0N/A b = (pixel ) & 0x1f;
0N/A b = (b << 3) | (b >> 2);
0N/A return (0xff000000 | (r << 16) | (g << 8) | (b));
0N/A }
0N/A }
0N/A public static class Ushort4444Argb extends PixelConverter {
0N/A public static final PixelConverter instance = new Ushort4444Argb();
0N/A
0N/A private Ushort4444Argb() {
0N/A alphaMask = 0xf000;
0N/A }
0N/A
0N/A public int rgbToPixel(int rgb, ColorModel cm) {
0N/A // use upper 4 bits for each color
0N/A // 0xAaRrGgBb -> 0x0000ARGB
0N/A int a = (rgb >> 16) & 0xf000;
0N/A int r = (rgb >> 12) & 0x0f00;
0N/A int g = (rgb >> 8) & 0x00f0;
0N/A int b = (rgb >> 4) & 0x000f;
0N/A
0N/A return (a | r | g | b);
0N/A }
0N/A
0N/A public int pixelToRgb(int pixel, ColorModel cm) {
0N/A int a, r, g, b;
0N/A // replicate 4 bits for each color
0N/A // 0xARGB -> 0xAARRGGBB
0N/A a = pixel & 0xf000;
0N/A a = ((pixel << 16) | (pixel << 12)) & 0xff000000;
0N/A r = pixel & 0x0f00;
0N/A r = ((pixel << 12) | (pixel << 8)) & 0x00ff0000;
0N/A g = pixel & 0x00f0;
0N/A g = ((pixel << 8) | (pixel << 4)) & 0x0000ff00;
0N/A b = pixel & 0x000f;
0N/A b = ((pixel << 4) | (pixel << 0)) & 0x000000ff;
0N/A
0N/A return (a | r | g | b);
0N/A }
0N/A }
0N/A public static class Xbgr extends PixelConverter {
0N/A public static final PixelConverter instance = new Xbgr();
0N/A
0N/A private Xbgr() {}
0N/A
0N/A public int rgbToPixel(int rgb, ColorModel cm) {
0N/A return (((rgb & 0xff) << 16) |
0N/A (rgb & 0xff00) |
0N/A ((rgb >> 16) & 0xff));
0N/A }
0N/A
0N/A public int pixelToRgb(int pixel, ColorModel cm) {
0N/A return (0xff000000 |
0N/A ((pixel & 0xff) << 16) |
0N/A (pixel & 0xff00) |
0N/A ((pixel >> 16) & 0xff));
0N/A }
0N/A }
0N/A public static class Bgrx extends PixelConverter {
0N/A public static final PixelConverter instance = new Bgrx();
0N/A
0N/A private Bgrx() {}
0N/A
0N/A public int rgbToPixel(int rgb, ColorModel cm) {
0N/A return ((rgb << 24) |
0N/A ((rgb & 0xff00) << 8) |
0N/A ((rgb >> 8) & 0xff00));
0N/A }
0N/A
0N/A public int pixelToRgb(int pixel, ColorModel cm) {
0N/A return (0xff000000 |
0N/A ((pixel & 0xff00) << 8) |
0N/A ((pixel >> 8) & 0xff00) |
0N/A (pixel >>> 24));
0N/A }
0N/A }
0N/A public static class Rgba extends PixelConverter {
0N/A public static final PixelConverter instance = new Rgba();
0N/A
0N/A private Rgba() {
0N/A alphaMask = 0x000000ff;
0N/A }
0N/A
0N/A public int rgbToPixel(int rgb, ColorModel cm) {
0N/A return ((rgb << 8) | (rgb >>> 24));
0N/A }
0N/A
0N/A public int pixelToRgb(int pixel, ColorModel cm) {
0N/A return ((pixel << 24) | (pixel >>> 8));
0N/A }
0N/A }
0N/A public static class RgbaPre extends PixelConverter {
0N/A public static final PixelConverter instance = new RgbaPre();
0N/A
0N/A private RgbaPre() {
0N/A alphaMask = 0x000000ff;
0N/A }
0N/A
0N/A public int rgbToPixel(int rgb, ColorModel cm) {
0N/A if ((rgb >> 24) == -1) {
0N/A return ((rgb << 8) | (rgb >>> 24));
0N/A }
0N/A int a = rgb >>> 24;
0N/A int r = (rgb >> 16) & 0xff;
0N/A int g = (rgb >> 8) & 0xff;
0N/A int b = (rgb ) & 0xff;
0N/A int a2 = a + (a >> 7);
0N/A r = (r * a2) >> 8;
0N/A g = (g * a2) >> 8;
0N/A b = (b * a2) >> 8;
0N/A return ((r << 24) | (g << 16) | (b << 8) | (a));
0N/A }
0N/A
0N/A public int pixelToRgb(int pixel, ColorModel cm) {
0N/A int a = pixel & 0xff;
0N/A if ((a == 0xff) || (a == 0)) {
0N/A return ((pixel >>> 8) | (pixel << 24));
0N/A }
0N/A int r = pixel >>> 24;
0N/A int g = (pixel >> 16) & 0xff;
0N/A int b = (pixel >> 8) & 0xff;
0N/A r = ((r << 8) - r) / a;
0N/A g = ((g << 8) - g) / a;
0N/A b = ((b << 8) - b) / a;
0N/A return ((r << 24) | (g << 16) | (b << 8) | (a));
0N/A }
0N/A }
0N/A public static class ArgbPre extends PixelConverter {
0N/A public static final PixelConverter instance = new ArgbPre();
0N/A
0N/A private ArgbPre() {
0N/A alphaMask = 0xff000000;
0N/A }
0N/A
0N/A public int rgbToPixel(int rgb, ColorModel cm) {
0N/A if ((rgb >> 24) == -1) {
0N/A return rgb;
0N/A }
0N/A int a = rgb >>> 24;
0N/A int r = (rgb >> 16) & 0xff;
0N/A int g = (rgb >> 8) & 0xff;
0N/A int b = (rgb ) & 0xff;
0N/A int a2 = a + (a >> 7);
0N/A r = (r * a2) >> 8;
0N/A g = (g * a2) >> 8;
0N/A b = (b * a2) >> 8;
0N/A return ((a << 24) | (r << 16) | (g << 8) | (b));
0N/A }
0N/A
0N/A public int pixelToRgb(int pixel, ColorModel cm) {
0N/A int a = pixel >>> 24;
0N/A if ((a == 0xff) || (a == 0)) {
0N/A return pixel;
0N/A }
0N/A int r = (pixel >> 16) & 0xff;
0N/A int g = (pixel >> 8) & 0xff;
0N/A int b = (pixel ) & 0xff;
0N/A r = ((r << 8) - r) / a;
0N/A g = ((g << 8) - g) / a;
0N/A b = ((b << 8) - b) / a;
0N/A return ((a << 24) | (r << 16) | (g << 8) | (b));
0N/A }
0N/A }
0N/A public static class ArgbBm extends PixelConverter {
0N/A public static final PixelConverter instance = new ArgbBm();
0N/A
0N/A private ArgbBm() {}
0N/A
0N/A public int rgbToPixel(int rgb, ColorModel cm) {
0N/A return (rgb | ((rgb >> 31) << 24));
0N/A }
0N/A
0N/A public int pixelToRgb(int pixel, ColorModel cm) {
0N/A return ((pixel << 7) >> 7);
0N/A }
0N/A }
0N/A public static class ByteGray extends PixelConverter {
0N/A static final double RED_MULT = 0.299;
0N/A static final double GRN_MULT = 0.587;
0N/A static final double BLU_MULT = 0.114;
0N/A public static final PixelConverter instance = new ByteGray();
0N/A
0N/A private ByteGray() {}
0N/A
0N/A public int rgbToPixel(int rgb, ColorModel cm) {
0N/A int red = (rgb >> 16) & 0xff;
0N/A int grn = (rgb >> 8) & 0xff;
0N/A int blu = (rgb ) & 0xff;
0N/A return (int) (red * RED_MULT +
0N/A grn * GRN_MULT +
0N/A blu * BLU_MULT +
0N/A 0.5);
0N/A }
0N/A
0N/A public int pixelToRgb(int pixel, ColorModel cm) {
0N/A return ((((((0xff << 8) | pixel) << 8) | pixel) << 8) | pixel);
0N/A }
0N/A }
0N/A public static class UshortGray extends ByteGray {
0N/A static final double SHORT_MULT = 257.0; // (65535.0 / 255.0);
0N/A static final double USHORT_RED_MULT = RED_MULT * SHORT_MULT;
0N/A static final double USHORT_GRN_MULT = GRN_MULT * SHORT_MULT;
0N/A static final double USHORT_BLU_MULT = BLU_MULT * SHORT_MULT;
0N/A public static final PixelConverter instance = new UshortGray();
0N/A
0N/A private UshortGray() {}
0N/A
0N/A public int rgbToPixel(int rgb, ColorModel cm) {
0N/A int red = (rgb >> 16) & 0xff;
0N/A int grn = (rgb >> 8) & 0xff;
0N/A int blu = (rgb ) & 0xff;
0N/A return (int) (red * USHORT_RED_MULT +
0N/A grn * USHORT_GRN_MULT +
0N/A blu * USHORT_BLU_MULT +
0N/A 0.5);
0N/A }
0N/A
0N/A public int pixelToRgb(int pixel, ColorModel cm) {
0N/A pixel = pixel >> 8;
0N/A return ((((((0xff << 8) | pixel) << 8) | pixel) << 8) | pixel);
0N/A }
0N/A }
0N/A}