/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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.
*/
/**
* 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.
*/
protected PixelConverter() {}
switch (cm.getTransferType()) {
case DataBuffer.TYPE_BYTE:
int pix = 0;
default: // bytearr.length >= 4
// FALLSTHROUGH
case 3:
// FALLSTHROUGH
case 2:
// FALLSTHROUGH
case 1:
}
return pix;
case DataBuffer.TYPE_SHORT:
case DataBuffer.TYPE_USHORT:
case DataBuffer.TYPE_INT:
return ((int[]) obj)[0];
default:
return rgb;
}
}
// 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
*/
private Rgbx() {}
return (rgb << 8);
}
}
}
private Xrgb() {}
return rgb;
}
return (0xff000000 | pixel);
}
}
private Argb() {
alphaMask = 0xff000000;
}
return rgb;
}
return pixel;
}
}
private Ushort565Rgb() {}
}
int r, g, b;
r = (r << 3) | (r >> 2);
g = (g << 2) | (g >> 4);
b = (pixel ) & 0x1f;
b = (b << 3) | (b >> 2);
return (0xff000000 | (r << 16) | (g << 8) | (b));
}
}
private Ushort555Rgbx() {}
}
int r, g, b;
r = (r << 3) | (r >> 2);
g = (g << 3) | (g >> 2);
b = (b << 3) | (b >> 2);
return (0xff000000 | (r << 16) | (g << 8) | (b));
}
}
private Ushort555Rgb() {}
}
int r, g, b;
r = (r << 3) | (r >> 2);
g = (g << 3) | (g >> 2);
b = (pixel ) & 0x1f;
b = (b << 3) | (b >> 2);
return (0xff000000 | (r << 16) | (g << 8) | (b));
}
}
private Ushort4444Argb() {
alphaMask = 0xf000;
}
// use upper 4 bits for each color
// 0xAaRrGgBb -> 0x0000ARGB
return (a | r | g | b);
}
int a, r, g, b;
// replicate 4 bits for each color
// 0xARGB -> 0xAARRGGBB
a = pixel & 0xf000;
r = pixel & 0x0f00;
g = pixel & 0x00f0;
b = pixel & 0x000f;
return (a | r | g | b);
}
}
private Xbgr() {}
(rgb & 0xff00) |
}
return (0xff000000 |
(pixel & 0xff00) |
}
}
private Bgrx() {}
return ((rgb << 24) |
}
return (0xff000000 |
(pixel >>> 24));
}
}
private Rgba() {
alphaMask = 0x000000ff;
}
}
}
}
private RgbaPre() {
alphaMask = 0x000000ff;
}
}
int a = rgb >>> 24;
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));
}
int a = pixel & 0xff;
if ((a == 0xff) || (a == 0)) {
}
int r = pixel >>> 24;
r = ((r << 8) - r) / a;
g = ((g << 8) - g) / a;
b = ((b << 8) - b) / a;
return ((r << 24) | (g << 16) | (b << 8) | (a));
}
}
private ArgbPre() {
alphaMask = 0xff000000;
}
return rgb;
}
int a = rgb >>> 24;
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));
}
int a = pixel >>> 24;
if ((a == 0xff) || (a == 0)) {
return pixel;
}
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));
}
}
private ArgbBm() {}
}
}
}
private ByteGray() {}
0.5);
}
}
}
private UshortGray() {}
return (int) (red * USHORT_RED_MULT +
grn * USHORT_GRN_MULT +
blu * USHORT_BLU_MULT +
0.5);
}
}
}
}