mirror of
https://github.com/2003scape/deep-c-rsc.git
synced 2024-03-22 05:49:51 -04:00
404 lines
16 KiB
Java
404 lines
16 KiB
Java
![]() |
/*
|
||
|
* This file is modified by Ivan Maidanski <ivmai@ivmaisoft.com>
|
||
|
* Project name: JCGO-SUNAWT (http://www.ivmaisoft.com/jcgo/)
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* @(#)BufImgSurfaceData.java 1.29 03/01/23
|
||
|
*
|
||
|
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
|
||
|
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||
|
*/
|
||
|
|
||
|
package sun.awt.image;
|
||
|
|
||
|
import java.awt.Color;
|
||
|
import java.awt.Rectangle;
|
||
|
import java.awt.GraphicsConfiguration;
|
||
|
import java.awt.image.ColorModel;
|
||
|
import java.awt.image.SampleModel;
|
||
|
import java.awt.image.DirectColorModel;
|
||
|
import java.awt.image.IndexColorModel;
|
||
|
import java.awt.image.Raster;
|
||
|
import java.awt.image.BufferedImage;
|
||
|
|
||
|
import sun.java2d.SurfaceData;
|
||
|
import sun.java2d.SunGraphics2D;
|
||
|
import sun.java2d.loops.SurfaceType;
|
||
|
import sun.java2d.loops.CompositeType;
|
||
|
import sun.java2d.loops.RenderLoops;
|
||
|
|
||
|
public class BufImgSurfaceData extends SurfaceData {
|
||
|
BufferedImage bufImg;
|
||
|
private BufferedImageGraphicsConfig graphicsConfig;
|
||
|
RenderLoops solidloops;
|
||
|
|
||
|
private static native void initIDs();
|
||
|
|
||
|
private static final int DCM_RGBX_RED_MASK = 0xff000000;
|
||
|
private static final int DCM_RGBX_GREEN_MASK = 0x00ff0000;
|
||
|
private static final int DCM_RGBX_BLUE_MASK = 0x0000ff00;
|
||
|
private static final int DCM_555X_RED_MASK = 0xF800;
|
||
|
private static final int DCM_555X_GREEN_MASK = 0x07C0;
|
||
|
private static final int DCM_555X_BLUE_MASK = 0x003E;
|
||
|
private static final int DCM_4444_RED_MASK = 0x0f00;
|
||
|
private static final int DCM_4444_GREEN_MASK = 0x00f0;
|
||
|
private static final int DCM_4444_BLUE_MASK = 0x000f;
|
||
|
private static final int DCM_4444_ALPHA_MASK = 0xf000;
|
||
|
private static final int DCM_ARGBBM_ALPHA_MASK = 0x01000000;
|
||
|
private static final int DCM_ARGBBM_RED_MASK = 0x00ff0000;
|
||
|
private static final int DCM_ARGBBM_GREEN_MASK = 0x0000ff00;
|
||
|
private static final int DCM_ARGBBM_BLUE_MASK = 0x000000ff;
|
||
|
|
||
|
static {
|
||
|
initIDs();
|
||
|
}
|
||
|
|
||
|
private static native SurfaceData
|
||
|
getSurfaceData(BufferedImage bufImg);
|
||
|
private static native void
|
||
|
setSurfaceData(BufferedImage bufImg, SurfaceData sData);
|
||
|
|
||
|
public static SurfaceData createData(BufferedImage bufImg) {
|
||
|
if (bufImg == null) {
|
||
|
throw new NullPointerException("BufferedImage cannot be null");
|
||
|
}
|
||
|
SurfaceData sData = getSurfaceData(bufImg);
|
||
|
if (sData != null) {
|
||
|
return sData;
|
||
|
}
|
||
|
ColorModel cm = bufImg.getColorModel();
|
||
|
int type = bufImg.getType();
|
||
|
// REMIND: Check the image type and pick an appropriate subclass
|
||
|
switch (type) {
|
||
|
case BufferedImage.TYPE_INT_BGR:
|
||
|
sData = createDataIC(bufImg, SurfaceType.IntBgr);
|
||
|
break;
|
||
|
case BufferedImage.TYPE_INT_RGB:
|
||
|
sData = createDataIC(bufImg, SurfaceType.IntRgb);
|
||
|
break;
|
||
|
case BufferedImage.TYPE_INT_ARGB:
|
||
|
sData = createDataIC(bufImg, SurfaceType.IntArgb);
|
||
|
break;
|
||
|
case BufferedImage.TYPE_INT_ARGB_PRE:
|
||
|
sData = createDataIC(bufImg, SurfaceType.IntArgbPre);
|
||
|
break;
|
||
|
case BufferedImage.TYPE_3BYTE_BGR:
|
||
|
sData = createDataBC(bufImg, SurfaceType.ThreeByteBgr, 2);
|
||
|
break;
|
||
|
case BufferedImage.TYPE_4BYTE_ABGR:
|
||
|
sData = createDataBC(bufImg, SurfaceType.FourByteAbgr, 3);
|
||
|
break;
|
||
|
case BufferedImage.TYPE_4BYTE_ABGR_PRE:
|
||
|
sData = createDataBC(bufImg, SurfaceType.FourByteAbgrPre, 3);
|
||
|
break;
|
||
|
case BufferedImage.TYPE_USHORT_565_RGB:
|
||
|
sData = createDataSC(bufImg, SurfaceType.Ushort565Rgb, null);
|
||
|
break;
|
||
|
case BufferedImage.TYPE_USHORT_555_RGB:
|
||
|
sData = createDataSC(bufImg, SurfaceType.Ushort555Rgb, null);
|
||
|
break;
|
||
|
case BufferedImage.TYPE_BYTE_INDEXED:
|
||
|
{
|
||
|
SurfaceType sType;
|
||
|
switch (cm.getTransparency()) {
|
||
|
case OPAQUE:
|
||
|
if (isOpaqueGray((IndexColorModel)cm)) {
|
||
|
sType = SurfaceType.Index8Gray;
|
||
|
} else {
|
||
|
sType = SurfaceType.ByteIndexedOpaque;
|
||
|
}
|
||
|
break;
|
||
|
case BITMASK:
|
||
|
sType = SurfaceType.ByteIndexedBm;
|
||
|
break;
|
||
|
case TRANSLUCENT:
|
||
|
sType = SurfaceType.ByteIndexed;
|
||
|
break;
|
||
|
default:
|
||
|
throw new InternalError("Unrecognized transparency");
|
||
|
}
|
||
|
sData = createDataBC(bufImg, sType, 0);
|
||
|
}
|
||
|
break;
|
||
|
case BufferedImage.TYPE_BYTE_GRAY:
|
||
|
sData = createDataBC(bufImg, SurfaceType.ByteGray, 0);
|
||
|
break;
|
||
|
case BufferedImage.TYPE_USHORT_GRAY:
|
||
|
sData = createDataSC(bufImg, SurfaceType.UshortGray, null);
|
||
|
break;
|
||
|
case BufferedImage.TYPE_BYTE_BINARY:
|
||
|
{
|
||
|
SurfaceType sType;
|
||
|
SampleModel sm = bufImg.getRaster().getSampleModel();
|
||
|
switch (sm.getSampleSize(0)) {
|
||
|
case 1:
|
||
|
sType = SurfaceType.ByteBinary1Bit;
|
||
|
break;
|
||
|
case 2:
|
||
|
sType = SurfaceType.ByteBinary2Bit;
|
||
|
break;
|
||
|
case 4:
|
||
|
sType = SurfaceType.ByteBinary4Bit;
|
||
|
break;
|
||
|
default:
|
||
|
throw new InternalError("Unrecognized pixel size");
|
||
|
}
|
||
|
sData = createDataBP(bufImg, sType);
|
||
|
}
|
||
|
break;
|
||
|
case BufferedImage.TYPE_CUSTOM:
|
||
|
default:
|
||
|
{
|
||
|
Raster raster = bufImg.getRaster();
|
||
|
int numBands = raster.getNumBands();
|
||
|
if (raster instanceof IntegerComponentRaster &&
|
||
|
raster.getNumDataElements() == 1 &&
|
||
|
((IntegerComponentRaster)raster).getPixelStride() == 1)
|
||
|
{
|
||
|
SurfaceType sType = SurfaceType.AnyInt;
|
||
|
if (cm instanceof DirectColorModel) {
|
||
|
DirectColorModel dcm = (DirectColorModel) cm;
|
||
|
int aMask = dcm.getAlphaMask();
|
||
|
int rMask = dcm.getRedMask();
|
||
|
int gMask = dcm.getGreenMask();
|
||
|
int bMask = dcm.getBlueMask();
|
||
|
if (numBands == 3 &&
|
||
|
aMask == 0 &&
|
||
|
rMask == DCM_RGBX_RED_MASK &&
|
||
|
gMask == DCM_RGBX_GREEN_MASK &&
|
||
|
bMask == DCM_RGBX_BLUE_MASK)
|
||
|
{
|
||
|
sType = SurfaceType.IntRgbx;
|
||
|
} else if (numBands == 4 &&
|
||
|
aMask == DCM_ARGBBM_ALPHA_MASK &&
|
||
|
rMask == DCM_ARGBBM_RED_MASK &&
|
||
|
gMask == DCM_ARGBBM_GREEN_MASK &&
|
||
|
bMask == DCM_ARGBBM_BLUE_MASK)
|
||
|
{
|
||
|
sType = SurfaceType.IntArgbBm;
|
||
|
} else {
|
||
|
sType = SurfaceType.AnyDcm;
|
||
|
}
|
||
|
}
|
||
|
sData = createDataIC(bufImg, sType);
|
||
|
break;
|
||
|
} else if (raster instanceof ShortComponentRaster &&
|
||
|
raster.getNumDataElements() == 1 &&
|
||
|
((ShortComponentRaster)raster).getPixelStride() == 1)
|
||
|
{
|
||
|
SurfaceType sType = SurfaceType.AnyShort;
|
||
|
IndexColorModel icm = null;
|
||
|
if (cm instanceof DirectColorModel) {
|
||
|
DirectColorModel dcm = (DirectColorModel) cm;
|
||
|
int aMask = dcm.getAlphaMask();
|
||
|
int rMask = dcm.getRedMask();
|
||
|
int gMask = dcm.getGreenMask();
|
||
|
int bMask = dcm.getBlueMask();
|
||
|
if (numBands == 3 &&
|
||
|
aMask == 0 &&
|
||
|
rMask == DCM_555X_RED_MASK &&
|
||
|
gMask == DCM_555X_GREEN_MASK &&
|
||
|
bMask == DCM_555X_BLUE_MASK)
|
||
|
{
|
||
|
sType = SurfaceType.Ushort555Rgbx;
|
||
|
} else
|
||
|
if (numBands == 4 &&
|
||
|
aMask == DCM_4444_ALPHA_MASK &&
|
||
|
rMask == DCM_4444_RED_MASK &&
|
||
|
gMask == DCM_4444_GREEN_MASK &&
|
||
|
bMask == DCM_4444_BLUE_MASK)
|
||
|
{
|
||
|
sType = SurfaceType.Ushort4444Argb;
|
||
|
}
|
||
|
} else if (cm instanceof IndexColorModel) {
|
||
|
icm = (IndexColorModel)cm;
|
||
|
if (icm.getPixelSize() == 12) {
|
||
|
if (isOpaqueGray(icm)) {
|
||
|
sType = SurfaceType.Index12Gray;
|
||
|
} else {
|
||
|
sType = SurfaceType.UshortIndexed;
|
||
|
}
|
||
|
} else {
|
||
|
icm = null;
|
||
|
}
|
||
|
}
|
||
|
sData = createDataSC(bufImg, sType, icm);
|
||
|
break;
|
||
|
}
|
||
|
sData = new BufImgSurfaceData(bufImg, SurfaceType.Custom);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
((BufImgSurfaceData) sData).initSolidLoops();
|
||
|
setSurfaceData(bufImg, sData);
|
||
|
return sData;
|
||
|
}
|
||
|
|
||
|
public static SurfaceData createData(Raster ras, ColorModel cm) {
|
||
|
throw new InternalError("SurfaceData not implemented for Raster/CM");
|
||
|
}
|
||
|
|
||
|
public static SurfaceData createDataIC(BufferedImage bImg,
|
||
|
SurfaceType sType) {
|
||
|
BufImgSurfaceData bisd = new BufImgSurfaceData(bImg, sType);
|
||
|
IntegerComponentRaster icRaster =
|
||
|
(IntegerComponentRaster)bImg.getRaster();
|
||
|
bisd.initRaster(icRaster.getDataStorage(),
|
||
|
icRaster.getDataOffset(0) * 4,
|
||
|
icRaster.getWidth(),
|
||
|
icRaster.getHeight(),
|
||
|
icRaster.getPixelStride() * 4,
|
||
|
icRaster.getScanlineStride() * 4,
|
||
|
null);
|
||
|
return bisd;
|
||
|
}
|
||
|
|
||
|
public static SurfaceData createDataSC(BufferedImage bImg,
|
||
|
SurfaceType sType,
|
||
|
IndexColorModel icm) {
|
||
|
BufImgSurfaceData bisd = new BufImgSurfaceData(bImg, sType);
|
||
|
ShortComponentRaster scRaster =
|
||
|
(ShortComponentRaster)bImg.getRaster();
|
||
|
bisd.initRaster(scRaster.getDataStorage(),
|
||
|
scRaster.getDataOffset(0) * 2,
|
||
|
scRaster.getWidth(),
|
||
|
scRaster.getHeight(),
|
||
|
scRaster.getPixelStride() * 2,
|
||
|
scRaster.getScanlineStride() * 2,
|
||
|
icm);
|
||
|
return bisd;
|
||
|
}
|
||
|
|
||
|
public static SurfaceData createDataBC(BufferedImage bImg,
|
||
|
SurfaceType sType,
|
||
|
int primaryBank) {
|
||
|
BufImgSurfaceData bisd = new BufImgSurfaceData(bImg, sType);
|
||
|
ByteComponentRaster bcRaster =
|
||
|
(ByteComponentRaster)bImg.getRaster();
|
||
|
ColorModel cm = bImg.getColorModel();
|
||
|
IndexColorModel icm = ((cm instanceof IndexColorModel)
|
||
|
? (IndexColorModel) cm
|
||
|
: null);
|
||
|
bisd.initRaster(bcRaster.getDataStorage(),
|
||
|
bcRaster.getDataOffset(primaryBank),
|
||
|
bcRaster.getWidth(),
|
||
|
bcRaster.getHeight(),
|
||
|
bcRaster.getPixelStride(),
|
||
|
bcRaster.getScanlineStride(),
|
||
|
icm);
|
||
|
return bisd;
|
||
|
}
|
||
|
|
||
|
public static SurfaceData createDataBP(BufferedImage bImg,
|
||
|
SurfaceType sType) {
|
||
|
BufImgSurfaceData bisd = new BufImgSurfaceData(bImg, sType);
|
||
|
BytePackedRaster bpRaster =
|
||
|
(BytePackedRaster)bImg.getRaster();
|
||
|
ColorModel cm = bImg.getColorModel();
|
||
|
IndexColorModel icm = ((cm instanceof IndexColorModel)
|
||
|
? (IndexColorModel) cm
|
||
|
: null);
|
||
|
/* REMIND: bit offset needs to be implemented correctly */
|
||
|
bisd.initRaster(bpRaster.getDataStorage(),
|
||
|
bpRaster.getDataBitOffset() / 8,
|
||
|
bpRaster.getWidth(),
|
||
|
bpRaster.getHeight(),
|
||
|
0,
|
||
|
bpRaster.getScanlineStride(),
|
||
|
icm);
|
||
|
return bisd;
|
||
|
}
|
||
|
|
||
|
public void lock() {
|
||
|
// BufferedImages cannot change configuration once constructed
|
||
|
}
|
||
|
|
||
|
public void unlock() {
|
||
|
// BufferedImages cannot change configuration once constructed
|
||
|
}
|
||
|
|
||
|
public RenderLoops getRenderLoops(SunGraphics2D sg2d) {
|
||
|
if (sg2d.paintState == sg2d.PAINT_SOLIDCOLOR &&
|
||
|
sg2d.compositeState == sg2d.COMP_ISCOPY)
|
||
|
{
|
||
|
return solidloops;
|
||
|
}
|
||
|
return super.getRenderLoops(sg2d);
|
||
|
}
|
||
|
|
||
|
public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
|
||
|
return bufImg.getRaster();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Initializes the native Ops pointer.
|
||
|
*/
|
||
|
protected native void initRaster(Object theArray,
|
||
|
int offset,
|
||
|
int width,
|
||
|
int height,
|
||
|
int pixStr,
|
||
|
int scanStr,
|
||
|
IndexColorModel icm);
|
||
|
|
||
|
public BufImgSurfaceData(BufferedImage bufImg, SurfaceType sType) {
|
||
|
super(sType, bufImg.getColorModel());
|
||
|
this.bufImg = bufImg;
|
||
|
}
|
||
|
|
||
|
public void initSolidLoops() {
|
||
|
this.solidloops = getSolidLoops(getSurfaceType());
|
||
|
}
|
||
|
|
||
|
private static final int CACHE_SIZE = 5;
|
||
|
private static RenderLoops loopcache[] = new RenderLoops[CACHE_SIZE];
|
||
|
private static SurfaceType typecache[] = new SurfaceType[CACHE_SIZE];
|
||
|
public static synchronized RenderLoops getSolidLoops(SurfaceType type) {
|
||
|
for (int i = CACHE_SIZE - 1; i >= 0; i--) {
|
||
|
SurfaceType t = typecache[i];
|
||
|
if (t == type) {
|
||
|
return loopcache[i];
|
||
|
} else if (t == null) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
RenderLoops l = makeRenderLoops(SurfaceType.OpaqueColor,
|
||
|
CompositeType.SrcNoEa,
|
||
|
type);
|
||
|
System.arraycopy(loopcache, 1, loopcache, 0, CACHE_SIZE-1);
|
||
|
System.arraycopy(typecache, 1, typecache, 0, CACHE_SIZE-1);
|
||
|
loopcache[CACHE_SIZE - 1] = l;
|
||
|
typecache[CACHE_SIZE - 1] = type;
|
||
|
return l;
|
||
|
}
|
||
|
|
||
|
public SurfaceData getReplacement() {
|
||
|
if (bufImg instanceof OffScreenImage) {
|
||
|
return ((OffScreenImage)bufImg).restoreContents();
|
||
|
} else {
|
||
|
// BufImgSurfaceData objects should never be lost, so simply
|
||
|
// return the same surfaceData object
|
||
|
return this;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public synchronized GraphicsConfiguration getDeviceConfiguration() {
|
||
|
if (graphicsConfig == null) {
|
||
|
graphicsConfig = BufferedImageGraphicsConfig.getConfig(bufImg);
|
||
|
}
|
||
|
return graphicsConfig;
|
||
|
}
|
||
|
|
||
|
public java.awt.Rectangle getBounds() {
|
||
|
return new Rectangle(bufImg.getWidth(), bufImg.getHeight());
|
||
|
}
|
||
|
|
||
|
protected void checkCustomComposite() {
|
||
|
// BufferedImages always allow Custom Composite objects since
|
||
|
// their pixels are immediately retrievable anyway.
|
||
|
}
|
||
|
|
||
|
public static native void freeNativeICMData(IndexColorModel icm);
|
||
|
}
|